1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * IPP data file parsing functions.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include "ipp-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "string-private.h"
17*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker
20*5e7646d2SAndroid Build Coastguard Worker /*
21*5e7646d2SAndroid Build Coastguard Worker * Local functions...
22*5e7646d2SAndroid Build Coastguard Worker */
23*5e7646d2SAndroid Build Coastguard Worker
24*5e7646d2SAndroid Build Coastguard Worker static ipp_t *parse_collection(_ipp_file_t *f, _ipp_vars_t *v, void *user_data);
25*5e7646d2SAndroid Build Coastguard Worker static int parse_value(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, ipp_t *ipp, ipp_attribute_t **attr, int element);
26*5e7646d2SAndroid Build Coastguard Worker static void report_error(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, const char *message, ...) _CUPS_FORMAT(4, 5);
27*5e7646d2SAndroid Build Coastguard Worker
28*5e7646d2SAndroid Build Coastguard Worker
29*5e7646d2SAndroid Build Coastguard Worker /*
30*5e7646d2SAndroid Build Coastguard Worker * '_ippFileParse()' - Parse an IPP data file.
31*5e7646d2SAndroid Build Coastguard Worker */
32*5e7646d2SAndroid Build Coastguard Worker
33*5e7646d2SAndroid Build Coastguard Worker ipp_t * /* O - IPP attributes or @code NULL@ on failure */
_ippFileParse(_ipp_vars_t * v,const char * filename,void * user_data)34*5e7646d2SAndroid Build Coastguard Worker _ippFileParse(
35*5e7646d2SAndroid Build Coastguard Worker _ipp_vars_t *v, /* I - Variables */
36*5e7646d2SAndroid Build Coastguard Worker const char *filename, /* I - Name of file to parse */
37*5e7646d2SAndroid Build Coastguard Worker void *user_data) /* I - User data pointer */
38*5e7646d2SAndroid Build Coastguard Worker {
39*5e7646d2SAndroid Build Coastguard Worker _ipp_file_t f; /* IPP data file information */
40*5e7646d2SAndroid Build Coastguard Worker ipp_t *attrs = NULL; /* Active IPP message */
41*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr = NULL; /* Current attribute */
42*5e7646d2SAndroid Build Coastguard Worker char token[1024]; /* Token string */
43*5e7646d2SAndroid Build Coastguard Worker ipp_t *ignored = NULL; /* Ignored attributes */
44*5e7646d2SAndroid Build Coastguard Worker
45*5e7646d2SAndroid Build Coastguard Worker
46*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ippFileParse(v=%p, filename=\"%s\", user_data=%p)", (void *)v, filename, user_data));
47*5e7646d2SAndroid Build Coastguard Worker
48*5e7646d2SAndroid Build Coastguard Worker /*
49*5e7646d2SAndroid Build Coastguard Worker * Initialize file info...
50*5e7646d2SAndroid Build Coastguard Worker */
51*5e7646d2SAndroid Build Coastguard Worker
52*5e7646d2SAndroid Build Coastguard Worker memset(&f, 0, sizeof(f));
53*5e7646d2SAndroid Build Coastguard Worker f.filename = filename;
54*5e7646d2SAndroid Build Coastguard Worker f.linenum = 1;
55*5e7646d2SAndroid Build Coastguard Worker
56*5e7646d2SAndroid Build Coastguard Worker if ((f.fp = cupsFileOpen(filename, "r")) == NULL)
57*5e7646d2SAndroid Build Coastguard Worker {
58*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileParse: Unable to open \"%s\": %s", filename, strerror(errno)));
59*5e7646d2SAndroid Build Coastguard Worker return (0);
60*5e7646d2SAndroid Build Coastguard Worker }
61*5e7646d2SAndroid Build Coastguard Worker
62*5e7646d2SAndroid Build Coastguard Worker /*
63*5e7646d2SAndroid Build Coastguard Worker * Do the callback with a NULL token to setup any initial state...
64*5e7646d2SAndroid Build Coastguard Worker */
65*5e7646d2SAndroid Build Coastguard Worker
66*5e7646d2SAndroid Build Coastguard Worker (*v->tokencb)(&f, v, user_data, NULL);
67*5e7646d2SAndroid Build Coastguard Worker
68*5e7646d2SAndroid Build Coastguard Worker /*
69*5e7646d2SAndroid Build Coastguard Worker * Read data file, using the callback function as needed...
70*5e7646d2SAndroid Build Coastguard Worker */
71*5e7646d2SAndroid Build Coastguard Worker
72*5e7646d2SAndroid Build Coastguard Worker while (_ippFileReadToken(&f, token, sizeof(token)))
73*5e7646d2SAndroid Build Coastguard Worker {
74*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(token, "DEFINE") || !_cups_strcasecmp(token, "DEFINE-DEFAULT"))
75*5e7646d2SAndroid Build Coastguard Worker {
76*5e7646d2SAndroid Build Coastguard Worker char name[128], /* Variable name */
77*5e7646d2SAndroid Build Coastguard Worker value[1024], /* Variable value */
78*5e7646d2SAndroid Build Coastguard Worker temp[1024]; /* Temporary string */
79*5e7646d2SAndroid Build Coastguard Worker
80*5e7646d2SAndroid Build Coastguard Worker attr = NULL;
81*5e7646d2SAndroid Build Coastguard Worker
82*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(&f, name, sizeof(name)) && _ippFileReadToken(&f, temp, sizeof(temp)))
83*5e7646d2SAndroid Build Coastguard Worker {
84*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(token, "DEFINE-DEFAULT") || !_ippVarsGet(v, name))
85*5e7646d2SAndroid Build Coastguard Worker {
86*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(v, value, temp, sizeof(value));
87*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(v, name, value);
88*5e7646d2SAndroid Build Coastguard Worker }
89*5e7646d2SAndroid Build Coastguard Worker }
90*5e7646d2SAndroid Build Coastguard Worker else
91*5e7646d2SAndroid Build Coastguard Worker {
92*5e7646d2SAndroid Build Coastguard Worker report_error(&f, v, user_data, "Missing %s name and/or value on line %d of \"%s\".", token, f.linenum, f.filename);
93*5e7646d2SAndroid Build Coastguard Worker break;
94*5e7646d2SAndroid Build Coastguard Worker }
95*5e7646d2SAndroid Build Coastguard Worker }
96*5e7646d2SAndroid Build Coastguard Worker else if (f.attrs && !_cups_strcasecmp(token, "ATTR"))
97*5e7646d2SAndroid Build Coastguard Worker {
98*5e7646d2SAndroid Build Coastguard Worker /*
99*5e7646d2SAndroid Build Coastguard Worker * Attribute definition...
100*5e7646d2SAndroid Build Coastguard Worker */
101*5e7646d2SAndroid Build Coastguard Worker
102*5e7646d2SAndroid Build Coastguard Worker char syntax[128], /* Attribute syntax (value tag) */
103*5e7646d2SAndroid Build Coastguard Worker name[128]; /* Attribute name */
104*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag; /* Value tag */
105*5e7646d2SAndroid Build Coastguard Worker
106*5e7646d2SAndroid Build Coastguard Worker attr = NULL;
107*5e7646d2SAndroid Build Coastguard Worker
108*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(&f, syntax, sizeof(syntax)))
109*5e7646d2SAndroid Build Coastguard Worker {
110*5e7646d2SAndroid Build Coastguard Worker report_error(&f, v, user_data, "Missing ATTR syntax on line %d of \"%s\".", f.linenum, f.filename);
111*5e7646d2SAndroid Build Coastguard Worker break;
112*5e7646d2SAndroid Build Coastguard Worker }
113*5e7646d2SAndroid Build Coastguard Worker else if ((value_tag = ippTagValue(syntax)) < IPP_TAG_UNSUPPORTED_VALUE)
114*5e7646d2SAndroid Build Coastguard Worker {
115*5e7646d2SAndroid Build Coastguard Worker report_error(&f, v, user_data, "Bad ATTR syntax \"%s\" on line %d of \"%s\".", syntax, f.linenum, f.filename);
116*5e7646d2SAndroid Build Coastguard Worker break;
117*5e7646d2SAndroid Build Coastguard Worker }
118*5e7646d2SAndroid Build Coastguard Worker
119*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(&f, name, sizeof(name)) || !name[0])
120*5e7646d2SAndroid Build Coastguard Worker {
121*5e7646d2SAndroid Build Coastguard Worker report_error(&f, v, user_data, "Missing ATTR name on line %d of \"%s\".", f.linenum, f.filename);
122*5e7646d2SAndroid Build Coastguard Worker break;
123*5e7646d2SAndroid Build Coastguard Worker }
124*5e7646d2SAndroid Build Coastguard Worker
125*5e7646d2SAndroid Build Coastguard Worker if (!v->attrcb || (*v->attrcb)(&f, user_data, name))
126*5e7646d2SAndroid Build Coastguard Worker {
127*5e7646d2SAndroid Build Coastguard Worker /*
128*5e7646d2SAndroid Build Coastguard Worker * Add this attribute...
129*5e7646d2SAndroid Build Coastguard Worker */
130*5e7646d2SAndroid Build Coastguard Worker
131*5e7646d2SAndroid Build Coastguard Worker attrs = f.attrs;
132*5e7646d2SAndroid Build Coastguard Worker }
133*5e7646d2SAndroid Build Coastguard Worker else
134*5e7646d2SAndroid Build Coastguard Worker {
135*5e7646d2SAndroid Build Coastguard Worker /*
136*5e7646d2SAndroid Build Coastguard Worker * Ignore this attribute...
137*5e7646d2SAndroid Build Coastguard Worker */
138*5e7646d2SAndroid Build Coastguard Worker
139*5e7646d2SAndroid Build Coastguard Worker if (!ignored)
140*5e7646d2SAndroid Build Coastguard Worker ignored = ippNew();
141*5e7646d2SAndroid Build Coastguard Worker
142*5e7646d2SAndroid Build Coastguard Worker attrs = ignored;
143*5e7646d2SAndroid Build Coastguard Worker }
144*5e7646d2SAndroid Build Coastguard Worker
145*5e7646d2SAndroid Build Coastguard Worker if (value_tag < IPP_TAG_INTEGER)
146*5e7646d2SAndroid Build Coastguard Worker {
147*5e7646d2SAndroid Build Coastguard Worker /*
148*5e7646d2SAndroid Build Coastguard Worker * Add out-of-band attribute - no value string needed...
149*5e7646d2SAndroid Build Coastguard Worker */
150*5e7646d2SAndroid Build Coastguard Worker
151*5e7646d2SAndroid Build Coastguard Worker ippAddOutOfBand(attrs, f.group_tag, value_tag, name);
152*5e7646d2SAndroid Build Coastguard Worker }
153*5e7646d2SAndroid Build Coastguard Worker else
154*5e7646d2SAndroid Build Coastguard Worker {
155*5e7646d2SAndroid Build Coastguard Worker /*
156*5e7646d2SAndroid Build Coastguard Worker * Add attribute with one or more values...
157*5e7646d2SAndroid Build Coastguard Worker */
158*5e7646d2SAndroid Build Coastguard Worker
159*5e7646d2SAndroid Build Coastguard Worker attr = ippAddString(attrs, f.group_tag, value_tag, name, NULL, NULL);
160*5e7646d2SAndroid Build Coastguard Worker
161*5e7646d2SAndroid Build Coastguard Worker if (!parse_value(&f, v, user_data, attrs, &attr, 0))
162*5e7646d2SAndroid Build Coastguard Worker break;
163*5e7646d2SAndroid Build Coastguard Worker }
164*5e7646d2SAndroid Build Coastguard Worker
165*5e7646d2SAndroid Build Coastguard Worker }
166*5e7646d2SAndroid Build Coastguard Worker else if (attr && !_cups_strcasecmp(token, ","))
167*5e7646d2SAndroid Build Coastguard Worker {
168*5e7646d2SAndroid Build Coastguard Worker /*
169*5e7646d2SAndroid Build Coastguard Worker * Additional value...
170*5e7646d2SAndroid Build Coastguard Worker */
171*5e7646d2SAndroid Build Coastguard Worker
172*5e7646d2SAndroid Build Coastguard Worker if (!parse_value(&f, v, user_data, attrs, &attr, ippGetCount(attr)))
173*5e7646d2SAndroid Build Coastguard Worker break;
174*5e7646d2SAndroid Build Coastguard Worker }
175*5e7646d2SAndroid Build Coastguard Worker else
176*5e7646d2SAndroid Build Coastguard Worker {
177*5e7646d2SAndroid Build Coastguard Worker /*
178*5e7646d2SAndroid Build Coastguard Worker * Something else...
179*5e7646d2SAndroid Build Coastguard Worker */
180*5e7646d2SAndroid Build Coastguard Worker
181*5e7646d2SAndroid Build Coastguard Worker attr = NULL;
182*5e7646d2SAndroid Build Coastguard Worker attrs = NULL;
183*5e7646d2SAndroid Build Coastguard Worker
184*5e7646d2SAndroid Build Coastguard Worker if (!(*v->tokencb)(&f, v, user_data, token))
185*5e7646d2SAndroid Build Coastguard Worker break;
186*5e7646d2SAndroid Build Coastguard Worker }
187*5e7646d2SAndroid Build Coastguard Worker }
188*5e7646d2SAndroid Build Coastguard Worker
189*5e7646d2SAndroid Build Coastguard Worker /*
190*5e7646d2SAndroid Build Coastguard Worker * Close the file and free ignored attributes, then return any attributes we
191*5e7646d2SAndroid Build Coastguard Worker * kept...
192*5e7646d2SAndroid Build Coastguard Worker */
193*5e7646d2SAndroid Build Coastguard Worker
194*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(f.fp);
195*5e7646d2SAndroid Build Coastguard Worker ippDelete(ignored);
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker return (f.attrs);
198*5e7646d2SAndroid Build Coastguard Worker }
199*5e7646d2SAndroid Build Coastguard Worker
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker /*
202*5e7646d2SAndroid Build Coastguard Worker * '_ippFileReadToken()' - Read a token from an IPP data file.
203*5e7646d2SAndroid Build Coastguard Worker */
204*5e7646d2SAndroid Build Coastguard Worker
205*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
_ippFileReadToken(_ipp_file_t * f,char * token,size_t tokensize)206*5e7646d2SAndroid Build Coastguard Worker _ippFileReadToken(_ipp_file_t *f, /* I - File to read from */
207*5e7646d2SAndroid Build Coastguard Worker char *token, /* I - Token string buffer */
208*5e7646d2SAndroid Build Coastguard Worker size_t tokensize)/* I - Size of token string buffer */
209*5e7646d2SAndroid Build Coastguard Worker {
210*5e7646d2SAndroid Build Coastguard Worker int ch, /* Character from file */
211*5e7646d2SAndroid Build Coastguard Worker quote = 0; /* Quoting character */
212*5e7646d2SAndroid Build Coastguard Worker char *tokptr = token, /* Pointer into token buffer */
213*5e7646d2SAndroid Build Coastguard Worker *tokend = token + tokensize - 1;/* End of token buffer */
214*5e7646d2SAndroid Build Coastguard Worker
215*5e7646d2SAndroid Build Coastguard Worker
216*5e7646d2SAndroid Build Coastguard Worker /*
217*5e7646d2SAndroid Build Coastguard Worker * Skip whitespace and comments...
218*5e7646d2SAndroid Build Coastguard Worker */
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp)));
221*5e7646d2SAndroid Build Coastguard Worker
222*5e7646d2SAndroid Build Coastguard Worker while ((ch = cupsFileGetChar(f->fp)) != EOF)
223*5e7646d2SAndroid Build Coastguard Worker {
224*5e7646d2SAndroid Build Coastguard Worker if (_cups_isspace(ch))
225*5e7646d2SAndroid Build Coastguard Worker {
226*5e7646d2SAndroid Build Coastguard Worker /*
227*5e7646d2SAndroid Build Coastguard Worker * Whitespace...
228*5e7646d2SAndroid Build Coastguard Worker */
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker if (ch == '\n')
231*5e7646d2SAndroid Build Coastguard Worker {
232*5e7646d2SAndroid Build Coastguard Worker f->linenum ++;
233*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: LF in leading whitespace, linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp)));
234*5e7646d2SAndroid Build Coastguard Worker }
235*5e7646d2SAndroid Build Coastguard Worker }
236*5e7646d2SAndroid Build Coastguard Worker else if (ch == '#')
237*5e7646d2SAndroid Build Coastguard Worker {
238*5e7646d2SAndroid Build Coastguard Worker /*
239*5e7646d2SAndroid Build Coastguard Worker * Comment...
240*5e7646d2SAndroid Build Coastguard Worker */
241*5e7646d2SAndroid Build Coastguard Worker
242*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_ippFileReadToken: Skipping comment in leading whitespace...");
243*5e7646d2SAndroid Build Coastguard Worker
244*5e7646d2SAndroid Build Coastguard Worker while ((ch = cupsFileGetChar(f->fp)) != EOF)
245*5e7646d2SAndroid Build Coastguard Worker {
246*5e7646d2SAndroid Build Coastguard Worker if (ch == '\n')
247*5e7646d2SAndroid Build Coastguard Worker break;
248*5e7646d2SAndroid Build Coastguard Worker }
249*5e7646d2SAndroid Build Coastguard Worker
250*5e7646d2SAndroid Build Coastguard Worker if (ch == '\n')
251*5e7646d2SAndroid Build Coastguard Worker {
252*5e7646d2SAndroid Build Coastguard Worker f->linenum ++;
253*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: LF at end of comment, linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp)));
254*5e7646d2SAndroid Build Coastguard Worker }
255*5e7646d2SAndroid Build Coastguard Worker else
256*5e7646d2SAndroid Build Coastguard Worker break;
257*5e7646d2SAndroid Build Coastguard Worker }
258*5e7646d2SAndroid Build Coastguard Worker else
259*5e7646d2SAndroid Build Coastguard Worker break;
260*5e7646d2SAndroid Build Coastguard Worker }
261*5e7646d2SAndroid Build Coastguard Worker
262*5e7646d2SAndroid Build Coastguard Worker if (ch == EOF)
263*5e7646d2SAndroid Build Coastguard Worker {
264*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_ippFileReadToken: EOF");
265*5e7646d2SAndroid Build Coastguard Worker return (0);
266*5e7646d2SAndroid Build Coastguard Worker }
267*5e7646d2SAndroid Build Coastguard Worker
268*5e7646d2SAndroid Build Coastguard Worker /*
269*5e7646d2SAndroid Build Coastguard Worker * Read a token...
270*5e7646d2SAndroid Build Coastguard Worker */
271*5e7646d2SAndroid Build Coastguard Worker
272*5e7646d2SAndroid Build Coastguard Worker while (ch != EOF)
273*5e7646d2SAndroid Build Coastguard Worker {
274*5e7646d2SAndroid Build Coastguard Worker if (ch == '\n')
275*5e7646d2SAndroid Build Coastguard Worker {
276*5e7646d2SAndroid Build Coastguard Worker f->linenum ++;
277*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: LF in token, linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp)));
278*5e7646d2SAndroid Build Coastguard Worker }
279*5e7646d2SAndroid Build Coastguard Worker
280*5e7646d2SAndroid Build Coastguard Worker if (ch == quote)
281*5e7646d2SAndroid Build Coastguard Worker {
282*5e7646d2SAndroid Build Coastguard Worker /*
283*5e7646d2SAndroid Build Coastguard Worker * End of quoted text...
284*5e7646d2SAndroid Build Coastguard Worker */
285*5e7646d2SAndroid Build Coastguard Worker
286*5e7646d2SAndroid Build Coastguard Worker *tokptr = '\0';
287*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: Returning \"%s\" at closing quote.", token));
288*5e7646d2SAndroid Build Coastguard Worker return (1);
289*5e7646d2SAndroid Build Coastguard Worker }
290*5e7646d2SAndroid Build Coastguard Worker else if (!quote && _cups_isspace(ch))
291*5e7646d2SAndroid Build Coastguard Worker {
292*5e7646d2SAndroid Build Coastguard Worker /*
293*5e7646d2SAndroid Build Coastguard Worker * End of unquoted text...
294*5e7646d2SAndroid Build Coastguard Worker */
295*5e7646d2SAndroid Build Coastguard Worker
296*5e7646d2SAndroid Build Coastguard Worker *tokptr = '\0';
297*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: Returning \"%s\" before whitespace.", token));
298*5e7646d2SAndroid Build Coastguard Worker return (1);
299*5e7646d2SAndroid Build Coastguard Worker }
300*5e7646d2SAndroid Build Coastguard Worker else if (!quote && (ch == '\'' || ch == '\"'))
301*5e7646d2SAndroid Build Coastguard Worker {
302*5e7646d2SAndroid Build Coastguard Worker /*
303*5e7646d2SAndroid Build Coastguard Worker * Start of quoted text or regular expression...
304*5e7646d2SAndroid Build Coastguard Worker */
305*5e7646d2SAndroid Build Coastguard Worker
306*5e7646d2SAndroid Build Coastguard Worker quote = ch;
307*5e7646d2SAndroid Build Coastguard Worker
308*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: Start of quoted string, quote=%c, pos=%ld", quote, (long)cupsFileTell(f->fp)));
309*5e7646d2SAndroid Build Coastguard Worker }
310*5e7646d2SAndroid Build Coastguard Worker else if (!quote && ch == '#')
311*5e7646d2SAndroid Build Coastguard Worker {
312*5e7646d2SAndroid Build Coastguard Worker /*
313*5e7646d2SAndroid Build Coastguard Worker * Start of comment...
314*5e7646d2SAndroid Build Coastguard Worker */
315*5e7646d2SAndroid Build Coastguard Worker
316*5e7646d2SAndroid Build Coastguard Worker cupsFileSeek(f->fp, cupsFileTell(f->fp) - 1);
317*5e7646d2SAndroid Build Coastguard Worker *tokptr = '\0';
318*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: Returning \"%s\" before comment.", token));
319*5e7646d2SAndroid Build Coastguard Worker return (1);
320*5e7646d2SAndroid Build Coastguard Worker }
321*5e7646d2SAndroid Build Coastguard Worker else if (!quote && (ch == '{' || ch == '}' || ch == ','))
322*5e7646d2SAndroid Build Coastguard Worker {
323*5e7646d2SAndroid Build Coastguard Worker /*
324*5e7646d2SAndroid Build Coastguard Worker * Delimiter...
325*5e7646d2SAndroid Build Coastguard Worker */
326*5e7646d2SAndroid Build Coastguard Worker
327*5e7646d2SAndroid Build Coastguard Worker if (tokptr > token)
328*5e7646d2SAndroid Build Coastguard Worker {
329*5e7646d2SAndroid Build Coastguard Worker /*
330*5e7646d2SAndroid Build Coastguard Worker * Return the preceding token first...
331*5e7646d2SAndroid Build Coastguard Worker */
332*5e7646d2SAndroid Build Coastguard Worker
333*5e7646d2SAndroid Build Coastguard Worker cupsFileSeek(f->fp, cupsFileTell(f->fp) - 1);
334*5e7646d2SAndroid Build Coastguard Worker }
335*5e7646d2SAndroid Build Coastguard Worker else
336*5e7646d2SAndroid Build Coastguard Worker {
337*5e7646d2SAndroid Build Coastguard Worker /*
338*5e7646d2SAndroid Build Coastguard Worker * Return this delimiter by itself...
339*5e7646d2SAndroid Build Coastguard Worker */
340*5e7646d2SAndroid Build Coastguard Worker
341*5e7646d2SAndroid Build Coastguard Worker *tokptr++ = (char)ch;
342*5e7646d2SAndroid Build Coastguard Worker }
343*5e7646d2SAndroid Build Coastguard Worker
344*5e7646d2SAndroid Build Coastguard Worker *tokptr = '\0';
345*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: Returning \"%s\".", token));
346*5e7646d2SAndroid Build Coastguard Worker return (1);
347*5e7646d2SAndroid Build Coastguard Worker }
348*5e7646d2SAndroid Build Coastguard Worker else
349*5e7646d2SAndroid Build Coastguard Worker {
350*5e7646d2SAndroid Build Coastguard Worker if (ch == '\\')
351*5e7646d2SAndroid Build Coastguard Worker {
352*5e7646d2SAndroid Build Coastguard Worker /*
353*5e7646d2SAndroid Build Coastguard Worker * Quoted character...
354*5e7646d2SAndroid Build Coastguard Worker */
355*5e7646d2SAndroid Build Coastguard Worker
356*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: Quoted character at pos=%ld", (long)cupsFileTell(f->fp)));
357*5e7646d2SAndroid Build Coastguard Worker
358*5e7646d2SAndroid Build Coastguard Worker if ((ch = cupsFileGetChar(f->fp)) == EOF)
359*5e7646d2SAndroid Build Coastguard Worker {
360*5e7646d2SAndroid Build Coastguard Worker *token = '\0';
361*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_ippFileReadToken: EOF");
362*5e7646d2SAndroid Build Coastguard Worker return (0);
363*5e7646d2SAndroid Build Coastguard Worker }
364*5e7646d2SAndroid Build Coastguard Worker else if (ch == '\n')
365*5e7646d2SAndroid Build Coastguard Worker {
366*5e7646d2SAndroid Build Coastguard Worker f->linenum ++;
367*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: quoted LF, linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp)));
368*5e7646d2SAndroid Build Coastguard Worker }
369*5e7646d2SAndroid Build Coastguard Worker else if (ch == 'a')
370*5e7646d2SAndroid Build Coastguard Worker ch = '\a';
371*5e7646d2SAndroid Build Coastguard Worker else if (ch == 'b')
372*5e7646d2SAndroid Build Coastguard Worker ch = '\b';
373*5e7646d2SAndroid Build Coastguard Worker else if (ch == 'f')
374*5e7646d2SAndroid Build Coastguard Worker ch = '\f';
375*5e7646d2SAndroid Build Coastguard Worker else if (ch == 'n')
376*5e7646d2SAndroid Build Coastguard Worker ch = '\n';
377*5e7646d2SAndroid Build Coastguard Worker else if (ch == 'r')
378*5e7646d2SAndroid Build Coastguard Worker ch = '\r';
379*5e7646d2SAndroid Build Coastguard Worker else if (ch == 't')
380*5e7646d2SAndroid Build Coastguard Worker ch = '\t';
381*5e7646d2SAndroid Build Coastguard Worker else if (ch == 'v')
382*5e7646d2SAndroid Build Coastguard Worker ch = '\v';
383*5e7646d2SAndroid Build Coastguard Worker }
384*5e7646d2SAndroid Build Coastguard Worker
385*5e7646d2SAndroid Build Coastguard Worker if (tokptr < tokend)
386*5e7646d2SAndroid Build Coastguard Worker {
387*5e7646d2SAndroid Build Coastguard Worker /*
388*5e7646d2SAndroid Build Coastguard Worker * Add to current token...
389*5e7646d2SAndroid Build Coastguard Worker */
390*5e7646d2SAndroid Build Coastguard Worker
391*5e7646d2SAndroid Build Coastguard Worker *tokptr++ = (char)ch;
392*5e7646d2SAndroid Build Coastguard Worker }
393*5e7646d2SAndroid Build Coastguard Worker else
394*5e7646d2SAndroid Build Coastguard Worker {
395*5e7646d2SAndroid Build Coastguard Worker /*
396*5e7646d2SAndroid Build Coastguard Worker * Token too long...
397*5e7646d2SAndroid Build Coastguard Worker */
398*5e7646d2SAndroid Build Coastguard Worker
399*5e7646d2SAndroid Build Coastguard Worker *tokptr = '\0';
400*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: Too long: \"%s\".", token));
401*5e7646d2SAndroid Build Coastguard Worker return (0);
402*5e7646d2SAndroid Build Coastguard Worker }
403*5e7646d2SAndroid Build Coastguard Worker }
404*5e7646d2SAndroid Build Coastguard Worker
405*5e7646d2SAndroid Build Coastguard Worker /*
406*5e7646d2SAndroid Build Coastguard Worker * Get the next character...
407*5e7646d2SAndroid Build Coastguard Worker */
408*5e7646d2SAndroid Build Coastguard Worker
409*5e7646d2SAndroid Build Coastguard Worker ch = cupsFileGetChar(f->fp);
410*5e7646d2SAndroid Build Coastguard Worker }
411*5e7646d2SAndroid Build Coastguard Worker
412*5e7646d2SAndroid Build Coastguard Worker *tokptr = '\0';
413*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ippFileReadToken: Returning \"%s\" at EOF.", token));
414*5e7646d2SAndroid Build Coastguard Worker
415*5e7646d2SAndroid Build Coastguard Worker return (tokptr > token);
416*5e7646d2SAndroid Build Coastguard Worker }
417*5e7646d2SAndroid Build Coastguard Worker
418*5e7646d2SAndroid Build Coastguard Worker
419*5e7646d2SAndroid Build Coastguard Worker /*
420*5e7646d2SAndroid Build Coastguard Worker * 'parse_collection()' - Parse an IPP collection value.
421*5e7646d2SAndroid Build Coastguard Worker */
422*5e7646d2SAndroid Build Coastguard Worker
423*5e7646d2SAndroid Build Coastguard Worker static ipp_t * /* O - Collection value or @code NULL@ on error */
parse_collection(_ipp_file_t * f,_ipp_vars_t * v,void * user_data)424*5e7646d2SAndroid Build Coastguard Worker parse_collection(
425*5e7646d2SAndroid Build Coastguard Worker _ipp_file_t *f, /* I - IPP data file */
426*5e7646d2SAndroid Build Coastguard Worker _ipp_vars_t *v, /* I - IPP variables */
427*5e7646d2SAndroid Build Coastguard Worker void *user_data) /* I - User data pointer */
428*5e7646d2SAndroid Build Coastguard Worker {
429*5e7646d2SAndroid Build Coastguard Worker ipp_t *col = ippNew(); /* Collection value */
430*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr = NULL; /* Current member attribute */
431*5e7646d2SAndroid Build Coastguard Worker char token[1024]; /* Token string */
432*5e7646d2SAndroid Build Coastguard Worker
433*5e7646d2SAndroid Build Coastguard Worker
434*5e7646d2SAndroid Build Coastguard Worker /*
435*5e7646d2SAndroid Build Coastguard Worker * Parse the collection value...
436*5e7646d2SAndroid Build Coastguard Worker */
437*5e7646d2SAndroid Build Coastguard Worker
438*5e7646d2SAndroid Build Coastguard Worker while (_ippFileReadToken(f, token, sizeof(token)))
439*5e7646d2SAndroid Build Coastguard Worker {
440*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(token, "}"))
441*5e7646d2SAndroid Build Coastguard Worker {
442*5e7646d2SAndroid Build Coastguard Worker /*
443*5e7646d2SAndroid Build Coastguard Worker * End of collection value...
444*5e7646d2SAndroid Build Coastguard Worker */
445*5e7646d2SAndroid Build Coastguard Worker
446*5e7646d2SAndroid Build Coastguard Worker break;
447*5e7646d2SAndroid Build Coastguard Worker }
448*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "MEMBER"))
449*5e7646d2SAndroid Build Coastguard Worker {
450*5e7646d2SAndroid Build Coastguard Worker /*
451*5e7646d2SAndroid Build Coastguard Worker * Member attribute definition...
452*5e7646d2SAndroid Build Coastguard Worker */
453*5e7646d2SAndroid Build Coastguard Worker
454*5e7646d2SAndroid Build Coastguard Worker char syntax[128], /* Attribute syntax (value tag) */
455*5e7646d2SAndroid Build Coastguard Worker name[128]; /* Attribute name */
456*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag; /* Value tag */
457*5e7646d2SAndroid Build Coastguard Worker
458*5e7646d2SAndroid Build Coastguard Worker attr = NULL;
459*5e7646d2SAndroid Build Coastguard Worker
460*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, syntax, sizeof(syntax)))
461*5e7646d2SAndroid Build Coastguard Worker {
462*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Missing MEMBER syntax on line %d of \"%s\".", f->linenum, f->filename);
463*5e7646d2SAndroid Build Coastguard Worker ippDelete(col);
464*5e7646d2SAndroid Build Coastguard Worker col = NULL;
465*5e7646d2SAndroid Build Coastguard Worker break;
466*5e7646d2SAndroid Build Coastguard Worker }
467*5e7646d2SAndroid Build Coastguard Worker else if ((value_tag = ippTagValue(syntax)) < IPP_TAG_UNSUPPORTED_VALUE)
468*5e7646d2SAndroid Build Coastguard Worker {
469*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Bad MEMBER syntax \"%s\" on line %d of \"%s\".", syntax, f->linenum, f->filename);
470*5e7646d2SAndroid Build Coastguard Worker ippDelete(col);
471*5e7646d2SAndroid Build Coastguard Worker col = NULL;
472*5e7646d2SAndroid Build Coastguard Worker break;
473*5e7646d2SAndroid Build Coastguard Worker }
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, name, sizeof(name)) || !name[0])
476*5e7646d2SAndroid Build Coastguard Worker {
477*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Missing MEMBER name on line %d of \"%s\".", f->linenum, f->filename);
478*5e7646d2SAndroid Build Coastguard Worker ippDelete(col);
479*5e7646d2SAndroid Build Coastguard Worker col = NULL;
480*5e7646d2SAndroid Build Coastguard Worker break;
481*5e7646d2SAndroid Build Coastguard Worker }
482*5e7646d2SAndroid Build Coastguard Worker
483*5e7646d2SAndroid Build Coastguard Worker if (value_tag < IPP_TAG_INTEGER)
484*5e7646d2SAndroid Build Coastguard Worker {
485*5e7646d2SAndroid Build Coastguard Worker /*
486*5e7646d2SAndroid Build Coastguard Worker * Add out-of-band attribute - no value string needed...
487*5e7646d2SAndroid Build Coastguard Worker */
488*5e7646d2SAndroid Build Coastguard Worker
489*5e7646d2SAndroid Build Coastguard Worker ippAddOutOfBand(col, IPP_TAG_ZERO, value_tag, name);
490*5e7646d2SAndroid Build Coastguard Worker }
491*5e7646d2SAndroid Build Coastguard Worker else
492*5e7646d2SAndroid Build Coastguard Worker {
493*5e7646d2SAndroid Build Coastguard Worker /*
494*5e7646d2SAndroid Build Coastguard Worker * Add attribute with one or more values...
495*5e7646d2SAndroid Build Coastguard Worker */
496*5e7646d2SAndroid Build Coastguard Worker
497*5e7646d2SAndroid Build Coastguard Worker attr = ippAddString(col, IPP_TAG_ZERO, value_tag, name, NULL, NULL);
498*5e7646d2SAndroid Build Coastguard Worker
499*5e7646d2SAndroid Build Coastguard Worker if (!parse_value(f, v, user_data, col, &attr, 0))
500*5e7646d2SAndroid Build Coastguard Worker {
501*5e7646d2SAndroid Build Coastguard Worker ippDelete(col);
502*5e7646d2SAndroid Build Coastguard Worker col = NULL;
503*5e7646d2SAndroid Build Coastguard Worker break;
504*5e7646d2SAndroid Build Coastguard Worker }
505*5e7646d2SAndroid Build Coastguard Worker }
506*5e7646d2SAndroid Build Coastguard Worker
507*5e7646d2SAndroid Build Coastguard Worker }
508*5e7646d2SAndroid Build Coastguard Worker else if (attr && !_cups_strcasecmp(token, ","))
509*5e7646d2SAndroid Build Coastguard Worker {
510*5e7646d2SAndroid Build Coastguard Worker /*
511*5e7646d2SAndroid Build Coastguard Worker * Additional value...
512*5e7646d2SAndroid Build Coastguard Worker */
513*5e7646d2SAndroid Build Coastguard Worker
514*5e7646d2SAndroid Build Coastguard Worker if (!parse_value(f, v, user_data, col, &attr, ippGetCount(attr)))
515*5e7646d2SAndroid Build Coastguard Worker {
516*5e7646d2SAndroid Build Coastguard Worker ippDelete(col);
517*5e7646d2SAndroid Build Coastguard Worker col = NULL;
518*5e7646d2SAndroid Build Coastguard Worker break;
519*5e7646d2SAndroid Build Coastguard Worker }
520*5e7646d2SAndroid Build Coastguard Worker }
521*5e7646d2SAndroid Build Coastguard Worker else
522*5e7646d2SAndroid Build Coastguard Worker {
523*5e7646d2SAndroid Build Coastguard Worker /*
524*5e7646d2SAndroid Build Coastguard Worker * Something else...
525*5e7646d2SAndroid Build Coastguard Worker */
526*5e7646d2SAndroid Build Coastguard Worker
527*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Unknown directive \"%s\" on line %d of \"%s\".", token, f->linenum, f->filename);
528*5e7646d2SAndroid Build Coastguard Worker ippDelete(col);
529*5e7646d2SAndroid Build Coastguard Worker col = NULL;
530*5e7646d2SAndroid Build Coastguard Worker attr = NULL;
531*5e7646d2SAndroid Build Coastguard Worker break;
532*5e7646d2SAndroid Build Coastguard Worker
533*5e7646d2SAndroid Build Coastguard Worker }
534*5e7646d2SAndroid Build Coastguard Worker }
535*5e7646d2SAndroid Build Coastguard Worker
536*5e7646d2SAndroid Build Coastguard Worker return (col);
537*5e7646d2SAndroid Build Coastguard Worker }
538*5e7646d2SAndroid Build Coastguard Worker
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker /*
541*5e7646d2SAndroid Build Coastguard Worker * 'parse_value()' - Parse an IPP value.
542*5e7646d2SAndroid Build Coastguard Worker */
543*5e7646d2SAndroid Build Coastguard Worker
544*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 on success or 0 on error */
parse_value(_ipp_file_t * f,_ipp_vars_t * v,void * user_data,ipp_t * ipp,ipp_attribute_t ** attr,int element)545*5e7646d2SAndroid Build Coastguard Worker parse_value(_ipp_file_t *f, /* I - IPP data file */
546*5e7646d2SAndroid Build Coastguard Worker _ipp_vars_t *v, /* I - IPP variables */
547*5e7646d2SAndroid Build Coastguard Worker void *user_data,/* I - User data pointer */
548*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
549*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
550*5e7646d2SAndroid Build Coastguard Worker int element) /* I - Element number */
551*5e7646d2SAndroid Build Coastguard Worker {
552*5e7646d2SAndroid Build Coastguard Worker char value[2049], /* Value string */
553*5e7646d2SAndroid Build Coastguard Worker *valueptr, /* Pointer into value string */
554*5e7646d2SAndroid Build Coastguard Worker temp[2049], /* Temporary string */
555*5e7646d2SAndroid Build Coastguard Worker *tempptr; /* Pointer into temporary string */
556*5e7646d2SAndroid Build Coastguard Worker size_t valuelen; /* Length of value */
557*5e7646d2SAndroid Build Coastguard Worker
558*5e7646d2SAndroid Build Coastguard Worker
559*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
560*5e7646d2SAndroid Build Coastguard Worker {
561*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Missing value on line %d of \"%s\".", f->linenum, f->filename);
562*5e7646d2SAndroid Build Coastguard Worker return (0);
563*5e7646d2SAndroid Build Coastguard Worker }
564*5e7646d2SAndroid Build Coastguard Worker
565*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(v, value, temp, sizeof(value));
566*5e7646d2SAndroid Build Coastguard Worker
567*5e7646d2SAndroid Build Coastguard Worker switch (ippGetValueTag(*attr))
568*5e7646d2SAndroid Build Coastguard Worker {
569*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
570*5e7646d2SAndroid Build Coastguard Worker return (ippSetBoolean(ipp, attr, element, !_cups_strcasecmp(value, "true")));
571*5e7646d2SAndroid Build Coastguard Worker
572*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
573*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
574*5e7646d2SAndroid Build Coastguard Worker return (ippSetInteger(ipp, attr, element, (int)strtol(value, NULL, 0)));
575*5e7646d2SAndroid Build Coastguard Worker
576*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DATE :
577*5e7646d2SAndroid Build Coastguard Worker {
578*5e7646d2SAndroid Build Coastguard Worker int year, /* Year */
579*5e7646d2SAndroid Build Coastguard Worker month, /* Month */
580*5e7646d2SAndroid Build Coastguard Worker day, /* Day of month */
581*5e7646d2SAndroid Build Coastguard Worker hour, /* Hour */
582*5e7646d2SAndroid Build Coastguard Worker minute, /* Minute */
583*5e7646d2SAndroid Build Coastguard Worker second, /* Second */
584*5e7646d2SAndroid Build Coastguard Worker utc_offset = 0; /* Timezone offset from UTC */
585*5e7646d2SAndroid Build Coastguard Worker ipp_uchar_t date[11]; /* dateTime value */
586*5e7646d2SAndroid Build Coastguard Worker
587*5e7646d2SAndroid Build Coastguard Worker if (*value == 'P')
588*5e7646d2SAndroid Build Coastguard Worker {
589*5e7646d2SAndroid Build Coastguard Worker /*
590*5e7646d2SAndroid Build Coastguard Worker * Time period...
591*5e7646d2SAndroid Build Coastguard Worker */
592*5e7646d2SAndroid Build Coastguard Worker
593*5e7646d2SAndroid Build Coastguard Worker time_t curtime; /* Current time in seconds */
594*5e7646d2SAndroid Build Coastguard Worker int period = 0, /* Current period value */
595*5e7646d2SAndroid Build Coastguard Worker saw_T = 0; /* Saw time separator */
596*5e7646d2SAndroid Build Coastguard Worker
597*5e7646d2SAndroid Build Coastguard Worker curtime = time(NULL);
598*5e7646d2SAndroid Build Coastguard Worker
599*5e7646d2SAndroid Build Coastguard Worker for (valueptr = value + 1; *valueptr; valueptr ++)
600*5e7646d2SAndroid Build Coastguard Worker {
601*5e7646d2SAndroid Build Coastguard Worker if (isdigit(*valueptr & 255))
602*5e7646d2SAndroid Build Coastguard Worker {
603*5e7646d2SAndroid Build Coastguard Worker period = (int)strtol(valueptr, &valueptr, 10);
604*5e7646d2SAndroid Build Coastguard Worker
605*5e7646d2SAndroid Build Coastguard Worker if (!valueptr || period < 0)
606*5e7646d2SAndroid Build Coastguard Worker {
607*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Bad dateTime value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
608*5e7646d2SAndroid Build Coastguard Worker return (0);
609*5e7646d2SAndroid Build Coastguard Worker }
610*5e7646d2SAndroid Build Coastguard Worker }
611*5e7646d2SAndroid Build Coastguard Worker
612*5e7646d2SAndroid Build Coastguard Worker if (*valueptr == 'Y')
613*5e7646d2SAndroid Build Coastguard Worker {
614*5e7646d2SAndroid Build Coastguard Worker curtime += 365 * 86400 * period;
615*5e7646d2SAndroid Build Coastguard Worker period = 0;
616*5e7646d2SAndroid Build Coastguard Worker }
617*5e7646d2SAndroid Build Coastguard Worker else if (*valueptr == 'M')
618*5e7646d2SAndroid Build Coastguard Worker {
619*5e7646d2SAndroid Build Coastguard Worker if (saw_T)
620*5e7646d2SAndroid Build Coastguard Worker curtime += 60 * period;
621*5e7646d2SAndroid Build Coastguard Worker else
622*5e7646d2SAndroid Build Coastguard Worker curtime += 30 * 86400 * period;
623*5e7646d2SAndroid Build Coastguard Worker
624*5e7646d2SAndroid Build Coastguard Worker period = 0;
625*5e7646d2SAndroid Build Coastguard Worker }
626*5e7646d2SAndroid Build Coastguard Worker else if (*valueptr == 'D')
627*5e7646d2SAndroid Build Coastguard Worker {
628*5e7646d2SAndroid Build Coastguard Worker curtime += 86400 * period;
629*5e7646d2SAndroid Build Coastguard Worker period = 0;
630*5e7646d2SAndroid Build Coastguard Worker }
631*5e7646d2SAndroid Build Coastguard Worker else if (*valueptr == 'H')
632*5e7646d2SAndroid Build Coastguard Worker {
633*5e7646d2SAndroid Build Coastguard Worker curtime += 3600 * period;
634*5e7646d2SAndroid Build Coastguard Worker period = 0;
635*5e7646d2SAndroid Build Coastguard Worker }
636*5e7646d2SAndroid Build Coastguard Worker else if (*valueptr == 'S')
637*5e7646d2SAndroid Build Coastguard Worker {
638*5e7646d2SAndroid Build Coastguard Worker curtime += period;
639*5e7646d2SAndroid Build Coastguard Worker period = 0;
640*5e7646d2SAndroid Build Coastguard Worker }
641*5e7646d2SAndroid Build Coastguard Worker else if (*valueptr == 'T')
642*5e7646d2SAndroid Build Coastguard Worker {
643*5e7646d2SAndroid Build Coastguard Worker saw_T = 1;
644*5e7646d2SAndroid Build Coastguard Worker period = 0;
645*5e7646d2SAndroid Build Coastguard Worker }
646*5e7646d2SAndroid Build Coastguard Worker else
647*5e7646d2SAndroid Build Coastguard Worker {
648*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Bad dateTime value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
649*5e7646d2SAndroid Build Coastguard Worker return (0);
650*5e7646d2SAndroid Build Coastguard Worker }
651*5e7646d2SAndroid Build Coastguard Worker }
652*5e7646d2SAndroid Build Coastguard Worker
653*5e7646d2SAndroid Build Coastguard Worker return (ippSetDate(ipp, attr, element, ippTimeToDate(curtime)));
654*5e7646d2SAndroid Build Coastguard Worker }
655*5e7646d2SAndroid Build Coastguard Worker else if (sscanf(value, "%d-%d-%dT%d:%d:%d%d", &year, &month, &day, &hour, &minute, &second, &utc_offset) < 6)
656*5e7646d2SAndroid Build Coastguard Worker {
657*5e7646d2SAndroid Build Coastguard Worker /*
658*5e7646d2SAndroid Build Coastguard Worker * Date/time value did not parse...
659*5e7646d2SAndroid Build Coastguard Worker */
660*5e7646d2SAndroid Build Coastguard Worker
661*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Bad dateTime value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
662*5e7646d2SAndroid Build Coastguard Worker return (0);
663*5e7646d2SAndroid Build Coastguard Worker }
664*5e7646d2SAndroid Build Coastguard Worker
665*5e7646d2SAndroid Build Coastguard Worker date[0] = (ipp_uchar_t)(year >> 8);
666*5e7646d2SAndroid Build Coastguard Worker date[1] = (ipp_uchar_t)(year & 255);
667*5e7646d2SAndroid Build Coastguard Worker date[2] = (ipp_uchar_t)month;
668*5e7646d2SAndroid Build Coastguard Worker date[3] = (ipp_uchar_t)day;
669*5e7646d2SAndroid Build Coastguard Worker date[4] = (ipp_uchar_t)hour;
670*5e7646d2SAndroid Build Coastguard Worker date[5] = (ipp_uchar_t)minute;
671*5e7646d2SAndroid Build Coastguard Worker date[6] = (ipp_uchar_t)second;
672*5e7646d2SAndroid Build Coastguard Worker date[7] = 0;
673*5e7646d2SAndroid Build Coastguard Worker if (utc_offset < 0)
674*5e7646d2SAndroid Build Coastguard Worker {
675*5e7646d2SAndroid Build Coastguard Worker utc_offset = -utc_offset;
676*5e7646d2SAndroid Build Coastguard Worker date[8] = (ipp_uchar_t)'-';
677*5e7646d2SAndroid Build Coastguard Worker }
678*5e7646d2SAndroid Build Coastguard Worker else
679*5e7646d2SAndroid Build Coastguard Worker {
680*5e7646d2SAndroid Build Coastguard Worker date[8] = (ipp_uchar_t)'+';
681*5e7646d2SAndroid Build Coastguard Worker }
682*5e7646d2SAndroid Build Coastguard Worker
683*5e7646d2SAndroid Build Coastguard Worker date[9] = (ipp_uchar_t)(utc_offset / 100);
684*5e7646d2SAndroid Build Coastguard Worker date[10] = (ipp_uchar_t)(utc_offset % 100);
685*5e7646d2SAndroid Build Coastguard Worker
686*5e7646d2SAndroid Build Coastguard Worker return (ippSetDate(ipp, attr, element, date));
687*5e7646d2SAndroid Build Coastguard Worker }
688*5e7646d2SAndroid Build Coastguard Worker
689*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
690*5e7646d2SAndroid Build Coastguard Worker {
691*5e7646d2SAndroid Build Coastguard Worker int xres, /* X resolution */
692*5e7646d2SAndroid Build Coastguard Worker yres; /* Y resolution */
693*5e7646d2SAndroid Build Coastguard Worker char *ptr; /* Pointer into value */
694*5e7646d2SAndroid Build Coastguard Worker
695*5e7646d2SAndroid Build Coastguard Worker xres = yres = (int)strtol(value, (char **)&ptr, 10);
696*5e7646d2SAndroid Build Coastguard Worker if (ptr > value && xres > 0)
697*5e7646d2SAndroid Build Coastguard Worker {
698*5e7646d2SAndroid Build Coastguard Worker if (*ptr == 'x')
699*5e7646d2SAndroid Build Coastguard Worker yres = (int)strtol(ptr + 1, (char **)&ptr, 10);
700*5e7646d2SAndroid Build Coastguard Worker }
701*5e7646d2SAndroid Build Coastguard Worker
702*5e7646d2SAndroid Build Coastguard Worker if (ptr <= value || xres <= 0 || yres <= 0 || !ptr || (_cups_strcasecmp(ptr, "dpi") && _cups_strcasecmp(ptr, "dpc") && _cups_strcasecmp(ptr, "dpcm") && _cups_strcasecmp(ptr, "other")))
703*5e7646d2SAndroid Build Coastguard Worker {
704*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Bad resolution value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
705*5e7646d2SAndroid Build Coastguard Worker return (0);
706*5e7646d2SAndroid Build Coastguard Worker }
707*5e7646d2SAndroid Build Coastguard Worker
708*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(ptr, "dpi"))
709*5e7646d2SAndroid Build Coastguard Worker return (ippSetResolution(ipp, attr, element, IPP_RES_PER_INCH, xres, yres));
710*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ptr, "dpc") || !_cups_strcasecmp(ptr, "dpcm"))
711*5e7646d2SAndroid Build Coastguard Worker return (ippSetResolution(ipp, attr, element, IPP_RES_PER_CM, xres, yres));
712*5e7646d2SAndroid Build Coastguard Worker else
713*5e7646d2SAndroid Build Coastguard Worker return (ippSetResolution(ipp, attr, element, (ipp_res_t)0, xres, yres));
714*5e7646d2SAndroid Build Coastguard Worker }
715*5e7646d2SAndroid Build Coastguard Worker
716*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
717*5e7646d2SAndroid Build Coastguard Worker {
718*5e7646d2SAndroid Build Coastguard Worker int lower, /* Lower value */
719*5e7646d2SAndroid Build Coastguard Worker upper; /* Upper value */
720*5e7646d2SAndroid Build Coastguard Worker
721*5e7646d2SAndroid Build Coastguard Worker if (sscanf(value, "%d-%d", &lower, &upper) != 2)
722*5e7646d2SAndroid Build Coastguard Worker {
723*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Bad rangeOfInteger value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
724*5e7646d2SAndroid Build Coastguard Worker return (0);
725*5e7646d2SAndroid Build Coastguard Worker }
726*5e7646d2SAndroid Build Coastguard Worker
727*5e7646d2SAndroid Build Coastguard Worker return (ippSetRange(ipp, attr, element, lower, upper));
728*5e7646d2SAndroid Build Coastguard Worker }
729*5e7646d2SAndroid Build Coastguard Worker
730*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
731*5e7646d2SAndroid Build Coastguard Worker valuelen = strlen(value);
732*5e7646d2SAndroid Build Coastguard Worker
733*5e7646d2SAndroid Build Coastguard Worker if (value[0] == '<' && value[strlen(value) - 1] == '>')
734*5e7646d2SAndroid Build Coastguard Worker {
735*5e7646d2SAndroid Build Coastguard Worker if (valuelen & 1)
736*5e7646d2SAndroid Build Coastguard Worker {
737*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Bad octetString value on line %d of \"%s\".", f->linenum, f->filename);
738*5e7646d2SAndroid Build Coastguard Worker return (0);
739*5e7646d2SAndroid Build Coastguard Worker }
740*5e7646d2SAndroid Build Coastguard Worker
741*5e7646d2SAndroid Build Coastguard Worker valueptr = value + 1;
742*5e7646d2SAndroid Build Coastguard Worker tempptr = temp;
743*5e7646d2SAndroid Build Coastguard Worker
744*5e7646d2SAndroid Build Coastguard Worker while (*valueptr && *valueptr != '>')
745*5e7646d2SAndroid Build Coastguard Worker {
746*5e7646d2SAndroid Build Coastguard Worker if (!isxdigit(valueptr[0] & 255) || !isxdigit(valueptr[1] & 255))
747*5e7646d2SAndroid Build Coastguard Worker {
748*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Bad octetString value on line %d of \"%s\".", f->linenum, f->filename);
749*5e7646d2SAndroid Build Coastguard Worker return (0);
750*5e7646d2SAndroid Build Coastguard Worker }
751*5e7646d2SAndroid Build Coastguard Worker
752*5e7646d2SAndroid Build Coastguard Worker if (valueptr[0] >= '0' && valueptr[0] <= '9')
753*5e7646d2SAndroid Build Coastguard Worker *tempptr = (char)((valueptr[0] - '0') << 4);
754*5e7646d2SAndroid Build Coastguard Worker else
755*5e7646d2SAndroid Build Coastguard Worker *tempptr = (char)((tolower(valueptr[0]) - 'a' + 10) << 4);
756*5e7646d2SAndroid Build Coastguard Worker
757*5e7646d2SAndroid Build Coastguard Worker if (valueptr[1] >= '0' && valueptr[1] <= '9')
758*5e7646d2SAndroid Build Coastguard Worker *tempptr |= (valueptr[1] - '0');
759*5e7646d2SAndroid Build Coastguard Worker else
760*5e7646d2SAndroid Build Coastguard Worker *tempptr |= (tolower(valueptr[1]) - 'a' + 10);
761*5e7646d2SAndroid Build Coastguard Worker
762*5e7646d2SAndroid Build Coastguard Worker tempptr ++;
763*5e7646d2SAndroid Build Coastguard Worker }
764*5e7646d2SAndroid Build Coastguard Worker
765*5e7646d2SAndroid Build Coastguard Worker return (ippSetOctetString(ipp, attr, element, temp, (int)(tempptr - temp)));
766*5e7646d2SAndroid Build Coastguard Worker }
767*5e7646d2SAndroid Build Coastguard Worker else
768*5e7646d2SAndroid Build Coastguard Worker return (ippSetOctetString(ipp, attr, element, value, (int)valuelen));
769*5e7646d2SAndroid Build Coastguard Worker
770*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
771*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
772*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
773*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
774*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
775*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
776*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
777*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
778*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
779*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
780*5e7646d2SAndroid Build Coastguard Worker return (ippSetString(ipp, attr, element, value));
781*5e7646d2SAndroid Build Coastguard Worker
782*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
783*5e7646d2SAndroid Build Coastguard Worker {
784*5e7646d2SAndroid Build Coastguard Worker int status; /* Add status */
785*5e7646d2SAndroid Build Coastguard Worker ipp_t *col; /* Collection value */
786*5e7646d2SAndroid Build Coastguard Worker
787*5e7646d2SAndroid Build Coastguard Worker if (strcmp(value, "{"))
788*5e7646d2SAndroid Build Coastguard Worker {
789*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Bad collection value on line %d of \"%s\".", f->linenum, f->filename);
790*5e7646d2SAndroid Build Coastguard Worker return (0);
791*5e7646d2SAndroid Build Coastguard Worker }
792*5e7646d2SAndroid Build Coastguard Worker
793*5e7646d2SAndroid Build Coastguard Worker if ((col = parse_collection(f, v, user_data)) == NULL)
794*5e7646d2SAndroid Build Coastguard Worker return (0);
795*5e7646d2SAndroid Build Coastguard Worker
796*5e7646d2SAndroid Build Coastguard Worker status = ippSetCollection(ipp, attr, element, col);
797*5e7646d2SAndroid Build Coastguard Worker ippDelete(col);
798*5e7646d2SAndroid Build Coastguard Worker
799*5e7646d2SAndroid Build Coastguard Worker return (status);
800*5e7646d2SAndroid Build Coastguard Worker }
801*5e7646d2SAndroid Build Coastguard Worker
802*5e7646d2SAndroid Build Coastguard Worker default :
803*5e7646d2SAndroid Build Coastguard Worker report_error(f, v, user_data, "Unsupported value on line %d of \"%s\".", f->linenum, f->filename);
804*5e7646d2SAndroid Build Coastguard Worker return (0);
805*5e7646d2SAndroid Build Coastguard Worker }
806*5e7646d2SAndroid Build Coastguard Worker }
807*5e7646d2SAndroid Build Coastguard Worker
808*5e7646d2SAndroid Build Coastguard Worker
809*5e7646d2SAndroid Build Coastguard Worker /*
810*5e7646d2SAndroid Build Coastguard Worker * 'report_error()' - Report an error.
811*5e7646d2SAndroid Build Coastguard Worker */
812*5e7646d2SAndroid Build Coastguard Worker
813*5e7646d2SAndroid Build Coastguard Worker static void
report_error(_ipp_file_t * f,_ipp_vars_t * v,void * user_data,const char * message,...)814*5e7646d2SAndroid Build Coastguard Worker report_error(
815*5e7646d2SAndroid Build Coastguard Worker _ipp_file_t *f, /* I - IPP data file */
816*5e7646d2SAndroid Build Coastguard Worker _ipp_vars_t *v, /* I - Error callback function, if any */
817*5e7646d2SAndroid Build Coastguard Worker void *user_data, /* I - User data pointer */
818*5e7646d2SAndroid Build Coastguard Worker const char *message, /* I - Printf-style message */
819*5e7646d2SAndroid Build Coastguard Worker ...) /* I - Additional arguments as needed */
820*5e7646d2SAndroid Build Coastguard Worker {
821*5e7646d2SAndroid Build Coastguard Worker char buffer[8192]; /* Formatted string */
822*5e7646d2SAndroid Build Coastguard Worker va_list ap; /* Argument pointer */
823*5e7646d2SAndroid Build Coastguard Worker
824*5e7646d2SAndroid Build Coastguard Worker
825*5e7646d2SAndroid Build Coastguard Worker va_start(ap, message);
826*5e7646d2SAndroid Build Coastguard Worker vsnprintf(buffer, sizeof(buffer), message, ap);
827*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
828*5e7646d2SAndroid Build Coastguard Worker
829*5e7646d2SAndroid Build Coastguard Worker if (v->errorcb)
830*5e7646d2SAndroid Build Coastguard Worker (*v->errorcb)(f, user_data, buffer);
831*5e7646d2SAndroid Build Coastguard Worker else
832*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "%s\n", buffer);
833*5e7646d2SAndroid Build Coastguard Worker }
834