1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Internet Printing Protocol functions for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2021 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
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 "cups-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
17*5e7646d2SAndroid Build Coastguard Worker #include <regex.h>
18*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
19*5e7646d2SAndroid Build Coastguard Worker # include <io.h>
20*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
21*5e7646d2SAndroid Build Coastguard Worker
22*5e7646d2SAndroid Build Coastguard Worker
23*5e7646d2SAndroid Build Coastguard Worker /*
24*5e7646d2SAndroid Build Coastguard Worker * Local functions...
25*5e7646d2SAndroid Build Coastguard Worker */
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker static ipp_attribute_t *ipp_add_attr(ipp_t *ipp, const char *name,
28*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group_tag, ipp_tag_t value_tag,
29*5e7646d2SAndroid Build Coastguard Worker int num_values);
30*5e7646d2SAndroid Build Coastguard Worker static void ipp_free_values(ipp_attribute_t *attr, int element,
31*5e7646d2SAndroid Build Coastguard Worker int count);
32*5e7646d2SAndroid Build Coastguard Worker static char *ipp_get_code(const char *locale, char *buffer, size_t bufsize) _CUPS_NONNULL(1,2);
33*5e7646d2SAndroid Build Coastguard Worker static char *ipp_lang_code(const char *locale, char *buffer, size_t bufsize) _CUPS_NONNULL(1,2);
34*5e7646d2SAndroid Build Coastguard Worker static size_t ipp_length(ipp_t *ipp, int collection);
35*5e7646d2SAndroid Build Coastguard Worker static ssize_t ipp_read_http(http_t *http, ipp_uchar_t *buffer,
36*5e7646d2SAndroid Build Coastguard Worker size_t length);
37*5e7646d2SAndroid Build Coastguard Worker static ssize_t ipp_read_file(int *fd, ipp_uchar_t *buffer,
38*5e7646d2SAndroid Build Coastguard Worker size_t length);
39*5e7646d2SAndroid Build Coastguard Worker static void ipp_set_error(ipp_status_t status, const char *format,
40*5e7646d2SAndroid Build Coastguard Worker ...);
41*5e7646d2SAndroid Build Coastguard Worker static _ipp_value_t *ipp_set_value(ipp_t *ipp, ipp_attribute_t **attr,
42*5e7646d2SAndroid Build Coastguard Worker int element);
43*5e7646d2SAndroid Build Coastguard Worker static ssize_t ipp_write_file(int *fd, ipp_uchar_t *buffer,
44*5e7646d2SAndroid Build Coastguard Worker size_t length);
45*5e7646d2SAndroid Build Coastguard Worker
46*5e7646d2SAndroid Build Coastguard Worker
47*5e7646d2SAndroid Build Coastguard Worker /*
48*5e7646d2SAndroid Build Coastguard Worker * '_cupsBufferGet()' - Get a read/write buffer.
49*5e7646d2SAndroid Build Coastguard Worker */
50*5e7646d2SAndroid Build Coastguard Worker
51*5e7646d2SAndroid Build Coastguard Worker char * /* O - Buffer */
_cupsBufferGet(size_t size)52*5e7646d2SAndroid Build Coastguard Worker _cupsBufferGet(size_t size) /* I - Size required */
53*5e7646d2SAndroid Build Coastguard Worker {
54*5e7646d2SAndroid Build Coastguard Worker _cups_buffer_t *buffer; /* Current buffer */
55*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals();
56*5e7646d2SAndroid Build Coastguard Worker /* Global data */
57*5e7646d2SAndroid Build Coastguard Worker
58*5e7646d2SAndroid Build Coastguard Worker
59*5e7646d2SAndroid Build Coastguard Worker for (buffer = cg->cups_buffers; buffer; buffer = buffer->next)
60*5e7646d2SAndroid Build Coastguard Worker if (!buffer->used && buffer->size >= size)
61*5e7646d2SAndroid Build Coastguard Worker break;
62*5e7646d2SAndroid Build Coastguard Worker
63*5e7646d2SAndroid Build Coastguard Worker if (!buffer)
64*5e7646d2SAndroid Build Coastguard Worker {
65*5e7646d2SAndroid Build Coastguard Worker if ((buffer = malloc(sizeof(_cups_buffer_t) + size - 1)) == NULL)
66*5e7646d2SAndroid Build Coastguard Worker return (NULL);
67*5e7646d2SAndroid Build Coastguard Worker
68*5e7646d2SAndroid Build Coastguard Worker buffer->next = cg->cups_buffers;
69*5e7646d2SAndroid Build Coastguard Worker buffer->size = size;
70*5e7646d2SAndroid Build Coastguard Worker cg->cups_buffers = buffer;
71*5e7646d2SAndroid Build Coastguard Worker }
72*5e7646d2SAndroid Build Coastguard Worker
73*5e7646d2SAndroid Build Coastguard Worker buffer->used = 1;
74*5e7646d2SAndroid Build Coastguard Worker
75*5e7646d2SAndroid Build Coastguard Worker return (buffer->d);
76*5e7646d2SAndroid Build Coastguard Worker }
77*5e7646d2SAndroid Build Coastguard Worker
78*5e7646d2SAndroid Build Coastguard Worker
79*5e7646d2SAndroid Build Coastguard Worker /*
80*5e7646d2SAndroid Build Coastguard Worker * '_cupsBufferRelease()' - Release a read/write buffer.
81*5e7646d2SAndroid Build Coastguard Worker */
82*5e7646d2SAndroid Build Coastguard Worker
83*5e7646d2SAndroid Build Coastguard Worker void
_cupsBufferRelease(char * b)84*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease(char *b) /* I - Buffer to release */
85*5e7646d2SAndroid Build Coastguard Worker {
86*5e7646d2SAndroid Build Coastguard Worker _cups_buffer_t *buffer; /* Buffer */
87*5e7646d2SAndroid Build Coastguard Worker
88*5e7646d2SAndroid Build Coastguard Worker
89*5e7646d2SAndroid Build Coastguard Worker /*
90*5e7646d2SAndroid Build Coastguard Worker * Mark this buffer as unused...
91*5e7646d2SAndroid Build Coastguard Worker */
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker buffer = (_cups_buffer_t *)(b - offsetof(_cups_buffer_t, d));
94*5e7646d2SAndroid Build Coastguard Worker buffer->used = 0;
95*5e7646d2SAndroid Build Coastguard Worker }
96*5e7646d2SAndroid Build Coastguard Worker
97*5e7646d2SAndroid Build Coastguard Worker
98*5e7646d2SAndroid Build Coastguard Worker /*
99*5e7646d2SAndroid Build Coastguard Worker * 'ippAddBoolean()' - Add a boolean attribute to an IPP message.
100*5e7646d2SAndroid Build Coastguard Worker *
101*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
102*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
103*5e7646d2SAndroid Build Coastguard Worker *
104*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
105*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
106*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
107*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
108*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
109*5e7646d2SAndroid Build Coastguard Worker */
110*5e7646d2SAndroid Build Coastguard Worker
111*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddBoolean(ipp_t * ipp,ipp_tag_t group,const char * name,char value)112*5e7646d2SAndroid Build Coastguard Worker ippAddBoolean(ipp_t *ipp, /* I - IPP message */
113*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
114*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
115*5e7646d2SAndroid Build Coastguard Worker char value) /* I - Value of attribute */
116*5e7646d2SAndroid Build Coastguard Worker {
117*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
118*5e7646d2SAndroid Build Coastguard Worker
119*5e7646d2SAndroid Build Coastguard Worker
120*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddBoolean(ipp=%p, group=%02x(%s), name=\"%s\", value=%d)", (void *)ipp, group, ippTagString(group), name, value));
121*5e7646d2SAndroid Build Coastguard Worker
122*5e7646d2SAndroid Build Coastguard Worker /*
123*5e7646d2SAndroid Build Coastguard Worker * Range check input...
124*5e7646d2SAndroid Build Coastguard Worker */
125*5e7646d2SAndroid Build Coastguard Worker
126*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
127*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE)
128*5e7646d2SAndroid Build Coastguard Worker return (NULL);
129*5e7646d2SAndroid Build Coastguard Worker
130*5e7646d2SAndroid Build Coastguard Worker /*
131*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
132*5e7646d2SAndroid Build Coastguard Worker */
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_BOOLEAN, 1)) == NULL)
135*5e7646d2SAndroid Build Coastguard Worker return (NULL);
136*5e7646d2SAndroid Build Coastguard Worker
137*5e7646d2SAndroid Build Coastguard Worker attr->values[0].boolean = value;
138*5e7646d2SAndroid Build Coastguard Worker
139*5e7646d2SAndroid Build Coastguard Worker return (attr);
140*5e7646d2SAndroid Build Coastguard Worker }
141*5e7646d2SAndroid Build Coastguard Worker
142*5e7646d2SAndroid Build Coastguard Worker
143*5e7646d2SAndroid Build Coastguard Worker /*
144*5e7646d2SAndroid Build Coastguard Worker * 'ippAddBooleans()' - Add an array of boolean values.
145*5e7646d2SAndroid Build Coastguard Worker *
146*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
147*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
148*5e7646d2SAndroid Build Coastguard Worker *
149*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
150*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
151*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
152*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
153*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
154*5e7646d2SAndroid Build Coastguard Worker */
155*5e7646d2SAndroid Build Coastguard Worker
156*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddBooleans(ipp_t * ipp,ipp_tag_t group,const char * name,int num_values,const char * values)157*5e7646d2SAndroid Build Coastguard Worker ippAddBooleans(ipp_t *ipp, /* I - IPP message */
158*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
159*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
160*5e7646d2SAndroid Build Coastguard Worker int num_values, /* I - Number of values */
161*5e7646d2SAndroid Build Coastguard Worker const char *values) /* I - Values */
162*5e7646d2SAndroid Build Coastguard Worker {
163*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
164*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
165*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker
168*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddBooleans(ipp=%p, group=%02x(%s), name=\"%s\", num_values=%d, values=%p)", (void *)ipp, group, ippTagString(group), name, num_values, (void *)values));
169*5e7646d2SAndroid Build Coastguard Worker
170*5e7646d2SAndroid Build Coastguard Worker /*
171*5e7646d2SAndroid Build Coastguard Worker * Range check input...
172*5e7646d2SAndroid Build Coastguard Worker */
173*5e7646d2SAndroid Build Coastguard Worker
174*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
175*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
176*5e7646d2SAndroid Build Coastguard Worker num_values < 1)
177*5e7646d2SAndroid Build Coastguard Worker return (NULL);
178*5e7646d2SAndroid Build Coastguard Worker
179*5e7646d2SAndroid Build Coastguard Worker /*
180*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
181*5e7646d2SAndroid Build Coastguard Worker */
182*5e7646d2SAndroid Build Coastguard Worker
183*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_BOOLEAN, num_values)) == NULL)
184*5e7646d2SAndroid Build Coastguard Worker return (NULL);
185*5e7646d2SAndroid Build Coastguard Worker
186*5e7646d2SAndroid Build Coastguard Worker if (values)
187*5e7646d2SAndroid Build Coastguard Worker {
188*5e7646d2SAndroid Build Coastguard Worker for (i = num_values, value = attr->values;
189*5e7646d2SAndroid Build Coastguard Worker i > 0;
190*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
191*5e7646d2SAndroid Build Coastguard Worker value->boolean = *values++;
192*5e7646d2SAndroid Build Coastguard Worker }
193*5e7646d2SAndroid Build Coastguard Worker
194*5e7646d2SAndroid Build Coastguard Worker return (attr);
195*5e7646d2SAndroid Build Coastguard Worker }
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker
198*5e7646d2SAndroid Build Coastguard Worker /*
199*5e7646d2SAndroid Build Coastguard Worker * 'ippAddCollection()' - Add a collection value.
200*5e7646d2SAndroid Build Coastguard Worker *
201*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
202*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
203*5e7646d2SAndroid Build Coastguard Worker *
204*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
205*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
206*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
207*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
208*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
209*5e7646d2SAndroid Build Coastguard Worker *
210*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.1.19/macOS 10.3@
211*5e7646d2SAndroid Build Coastguard Worker */
212*5e7646d2SAndroid Build Coastguard Worker
213*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddCollection(ipp_t * ipp,ipp_tag_t group,const char * name,ipp_t * value)214*5e7646d2SAndroid Build Coastguard Worker ippAddCollection(ipp_t *ipp, /* I - IPP message */
215*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
216*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
217*5e7646d2SAndroid Build Coastguard Worker ipp_t *value) /* I - Value */
218*5e7646d2SAndroid Build Coastguard Worker {
219*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
220*5e7646d2SAndroid Build Coastguard Worker
221*5e7646d2SAndroid Build Coastguard Worker
222*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddCollection(ipp=%p, group=%02x(%s), name=\"%s\", value=%p)", (void *)ipp, group, ippTagString(group), name, (void *)value));
223*5e7646d2SAndroid Build Coastguard Worker
224*5e7646d2SAndroid Build Coastguard Worker /*
225*5e7646d2SAndroid Build Coastguard Worker * Range check input...
226*5e7646d2SAndroid Build Coastguard Worker */
227*5e7646d2SAndroid Build Coastguard Worker
228*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
229*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE)
230*5e7646d2SAndroid Build Coastguard Worker return (NULL);
231*5e7646d2SAndroid Build Coastguard Worker
232*5e7646d2SAndroid Build Coastguard Worker /*
233*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
234*5e7646d2SAndroid Build Coastguard Worker */
235*5e7646d2SAndroid Build Coastguard Worker
236*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_BEGIN_COLLECTION, 1)) == NULL)
237*5e7646d2SAndroid Build Coastguard Worker return (NULL);
238*5e7646d2SAndroid Build Coastguard Worker
239*5e7646d2SAndroid Build Coastguard Worker attr->values[0].collection = value;
240*5e7646d2SAndroid Build Coastguard Worker
241*5e7646d2SAndroid Build Coastguard Worker if (value)
242*5e7646d2SAndroid Build Coastguard Worker value->use ++;
243*5e7646d2SAndroid Build Coastguard Worker
244*5e7646d2SAndroid Build Coastguard Worker return (attr);
245*5e7646d2SAndroid Build Coastguard Worker }
246*5e7646d2SAndroid Build Coastguard Worker
247*5e7646d2SAndroid Build Coastguard Worker
248*5e7646d2SAndroid Build Coastguard Worker /*
249*5e7646d2SAndroid Build Coastguard Worker * 'ippAddCollections()' - Add an array of collection values.
250*5e7646d2SAndroid Build Coastguard Worker *
251*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
252*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
253*5e7646d2SAndroid Build Coastguard Worker *
254*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
255*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
256*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
257*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
258*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
259*5e7646d2SAndroid Build Coastguard Worker *
260*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.1.19/macOS 10.3@
261*5e7646d2SAndroid Build Coastguard Worker */
262*5e7646d2SAndroid Build Coastguard Worker
263*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddCollections(ipp_t * ipp,ipp_tag_t group,const char * name,int num_values,const ipp_t ** values)264*5e7646d2SAndroid Build Coastguard Worker ippAddCollections(
265*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
266*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
267*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
268*5e7646d2SAndroid Build Coastguard Worker int num_values, /* I - Number of values */
269*5e7646d2SAndroid Build Coastguard Worker const ipp_t **values) /* I - Values */
270*5e7646d2SAndroid Build Coastguard Worker {
271*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
272*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
273*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
274*5e7646d2SAndroid Build Coastguard Worker
275*5e7646d2SAndroid Build Coastguard Worker
276*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddCollections(ipp=%p, group=%02x(%s), name=\"%s\", num_values=%d, values=%p)", (void *)ipp, group, ippTagString(group), name, num_values, (void *)values));
277*5e7646d2SAndroid Build Coastguard Worker
278*5e7646d2SAndroid Build Coastguard Worker /*
279*5e7646d2SAndroid Build Coastguard Worker * Range check input...
280*5e7646d2SAndroid Build Coastguard Worker */
281*5e7646d2SAndroid Build Coastguard Worker
282*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
283*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
284*5e7646d2SAndroid Build Coastguard Worker num_values < 1)
285*5e7646d2SAndroid Build Coastguard Worker return (NULL);
286*5e7646d2SAndroid Build Coastguard Worker
287*5e7646d2SAndroid Build Coastguard Worker /*
288*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
289*5e7646d2SAndroid Build Coastguard Worker */
290*5e7646d2SAndroid Build Coastguard Worker
291*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_BEGIN_COLLECTION,
292*5e7646d2SAndroid Build Coastguard Worker num_values)) == NULL)
293*5e7646d2SAndroid Build Coastguard Worker return (NULL);
294*5e7646d2SAndroid Build Coastguard Worker
295*5e7646d2SAndroid Build Coastguard Worker if (values)
296*5e7646d2SAndroid Build Coastguard Worker {
297*5e7646d2SAndroid Build Coastguard Worker for (i = num_values, value = attr->values;
298*5e7646d2SAndroid Build Coastguard Worker i > 0;
299*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
300*5e7646d2SAndroid Build Coastguard Worker {
301*5e7646d2SAndroid Build Coastguard Worker value->collection = (ipp_t *)*values++;
302*5e7646d2SAndroid Build Coastguard Worker value->collection->use ++;
303*5e7646d2SAndroid Build Coastguard Worker }
304*5e7646d2SAndroid Build Coastguard Worker }
305*5e7646d2SAndroid Build Coastguard Worker
306*5e7646d2SAndroid Build Coastguard Worker return (attr);
307*5e7646d2SAndroid Build Coastguard Worker }
308*5e7646d2SAndroid Build Coastguard Worker
309*5e7646d2SAndroid Build Coastguard Worker
310*5e7646d2SAndroid Build Coastguard Worker /*
311*5e7646d2SAndroid Build Coastguard Worker * 'ippAddDate()' - Add a dateTime attribute to an IPP message.
312*5e7646d2SAndroid Build Coastguard Worker *
313*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
314*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
315*5e7646d2SAndroid Build Coastguard Worker *
316*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
317*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
318*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
319*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
320*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
321*5e7646d2SAndroid Build Coastguard Worker */
322*5e7646d2SAndroid Build Coastguard Worker
323*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddDate(ipp_t * ipp,ipp_tag_t group,const char * name,const ipp_uchar_t * value)324*5e7646d2SAndroid Build Coastguard Worker ippAddDate(ipp_t *ipp, /* I - IPP message */
325*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
326*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
327*5e7646d2SAndroid Build Coastguard Worker const ipp_uchar_t *value) /* I - Value */
328*5e7646d2SAndroid Build Coastguard Worker {
329*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
330*5e7646d2SAndroid Build Coastguard Worker
331*5e7646d2SAndroid Build Coastguard Worker
332*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddDate(ipp=%p, group=%02x(%s), name=\"%s\", value=%p)", (void *)ipp, group, ippTagString(group), name, (void *)value));
333*5e7646d2SAndroid Build Coastguard Worker
334*5e7646d2SAndroid Build Coastguard Worker /*
335*5e7646d2SAndroid Build Coastguard Worker * Range check input...
336*5e7646d2SAndroid Build Coastguard Worker */
337*5e7646d2SAndroid Build Coastguard Worker
338*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || !value || group < IPP_TAG_ZERO ||
339*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE)
340*5e7646d2SAndroid Build Coastguard Worker return (NULL);
341*5e7646d2SAndroid Build Coastguard Worker
342*5e7646d2SAndroid Build Coastguard Worker /*
343*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
344*5e7646d2SAndroid Build Coastguard Worker */
345*5e7646d2SAndroid Build Coastguard Worker
346*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_DATE, 1)) == NULL)
347*5e7646d2SAndroid Build Coastguard Worker return (NULL);
348*5e7646d2SAndroid Build Coastguard Worker
349*5e7646d2SAndroid Build Coastguard Worker memcpy(attr->values[0].date, value, 11);
350*5e7646d2SAndroid Build Coastguard Worker
351*5e7646d2SAndroid Build Coastguard Worker return (attr);
352*5e7646d2SAndroid Build Coastguard Worker }
353*5e7646d2SAndroid Build Coastguard Worker
354*5e7646d2SAndroid Build Coastguard Worker
355*5e7646d2SAndroid Build Coastguard Worker /*
356*5e7646d2SAndroid Build Coastguard Worker * 'ippAddInteger()' - Add a integer attribute to an IPP message.
357*5e7646d2SAndroid Build Coastguard Worker *
358*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
359*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
360*5e7646d2SAndroid Build Coastguard Worker *
361*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
362*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
363*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
364*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
365*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
366*5e7646d2SAndroid Build Coastguard Worker *
367*5e7646d2SAndroid Build Coastguard Worker * Supported values include enum (@code IPP_TAG_ENUM@) and integer
368*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_INTEGER@).
369*5e7646d2SAndroid Build Coastguard Worker */
370*5e7646d2SAndroid Build Coastguard Worker
371*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddInteger(ipp_t * ipp,ipp_tag_t group,ipp_tag_t value_tag,const char * name,int value)372*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(ipp_t *ipp, /* I - IPP message */
373*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
374*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag, /* I - Type of attribute */
375*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
376*5e7646d2SAndroid Build Coastguard Worker int value) /* I - Value of attribute */
377*5e7646d2SAndroid Build Coastguard Worker {
378*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
379*5e7646d2SAndroid Build Coastguard Worker
380*5e7646d2SAndroid Build Coastguard Worker
381*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddInteger(ipp=%p, group=%02x(%s), type=%02x(%s), name=\"%s\", value=%d)", (void *)ipp, group, ippTagString(group), value_tag, ippTagString(value_tag), name, value));
382*5e7646d2SAndroid Build Coastguard Worker
383*5e7646d2SAndroid Build Coastguard Worker value_tag &= IPP_TAG_CUPS_MASK;
384*5e7646d2SAndroid Build Coastguard Worker
385*5e7646d2SAndroid Build Coastguard Worker /*
386*5e7646d2SAndroid Build Coastguard Worker * Special-case for legacy usage: map out-of-band attributes to new ippAddOutOfBand
387*5e7646d2SAndroid Build Coastguard Worker * function...
388*5e7646d2SAndroid Build Coastguard Worker */
389*5e7646d2SAndroid Build Coastguard Worker
390*5e7646d2SAndroid Build Coastguard Worker if (value_tag >= IPP_TAG_UNSUPPORTED_VALUE && value_tag <= IPP_TAG_ADMINDEFINE)
391*5e7646d2SAndroid Build Coastguard Worker return (ippAddOutOfBand(ipp, group, value_tag, name));
392*5e7646d2SAndroid Build Coastguard Worker
393*5e7646d2SAndroid Build Coastguard Worker /*
394*5e7646d2SAndroid Build Coastguard Worker * Range check input...
395*5e7646d2SAndroid Build Coastguard Worker */
396*5e7646d2SAndroid Build Coastguard Worker
397*5e7646d2SAndroid Build Coastguard Worker #if 0
398*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
399*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
400*5e7646d2SAndroid Build Coastguard Worker (value_tag != IPP_TAG_INTEGER && value_tag != IPP_TAG_ENUM))
401*5e7646d2SAndroid Build Coastguard Worker return (NULL);
402*5e7646d2SAndroid Build Coastguard Worker #else
403*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
404*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE)
405*5e7646d2SAndroid Build Coastguard Worker return (NULL);
406*5e7646d2SAndroid Build Coastguard Worker #endif /* 0 */
407*5e7646d2SAndroid Build Coastguard Worker
408*5e7646d2SAndroid Build Coastguard Worker /*
409*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
410*5e7646d2SAndroid Build Coastguard Worker */
411*5e7646d2SAndroid Build Coastguard Worker
412*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, value_tag, 1)) == NULL)
413*5e7646d2SAndroid Build Coastguard Worker return (NULL);
414*5e7646d2SAndroid Build Coastguard Worker
415*5e7646d2SAndroid Build Coastguard Worker attr->values[0].integer = value;
416*5e7646d2SAndroid Build Coastguard Worker
417*5e7646d2SAndroid Build Coastguard Worker return (attr);
418*5e7646d2SAndroid Build Coastguard Worker }
419*5e7646d2SAndroid Build Coastguard Worker
420*5e7646d2SAndroid Build Coastguard Worker
421*5e7646d2SAndroid Build Coastguard Worker /*
422*5e7646d2SAndroid Build Coastguard Worker * 'ippAddIntegers()' - Add an array of integer values.
423*5e7646d2SAndroid Build Coastguard Worker *
424*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
425*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
426*5e7646d2SAndroid Build Coastguard Worker *
427*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
428*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
429*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
430*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
431*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
432*5e7646d2SAndroid Build Coastguard Worker *
433*5e7646d2SAndroid Build Coastguard Worker * Supported values include enum (@code IPP_TAG_ENUM@) and integer
434*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_INTEGER@).
435*5e7646d2SAndroid Build Coastguard Worker */
436*5e7646d2SAndroid Build Coastguard Worker
437*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddIntegers(ipp_t * ipp,ipp_tag_t group,ipp_tag_t value_tag,const char * name,int num_values,const int * values)438*5e7646d2SAndroid Build Coastguard Worker ippAddIntegers(ipp_t *ipp, /* I - IPP message */
439*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
440*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag, /* I - Type of attribute */
441*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
442*5e7646d2SAndroid Build Coastguard Worker int num_values, /* I - Number of values */
443*5e7646d2SAndroid Build Coastguard Worker const int *values) /* I - Values */
444*5e7646d2SAndroid Build Coastguard Worker {
445*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
446*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
447*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
448*5e7646d2SAndroid Build Coastguard Worker
449*5e7646d2SAndroid Build Coastguard Worker
450*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddIntegers(ipp=%p, group=%02x(%s), type=%02x(%s), name=\"%s\", num_values=%d, values=%p)", (void *)ipp, group, ippTagString(group), value_tag, ippTagString(value_tag), name, num_values, (void *)values));
451*5e7646d2SAndroid Build Coastguard Worker
452*5e7646d2SAndroid Build Coastguard Worker value_tag &= IPP_TAG_CUPS_MASK;
453*5e7646d2SAndroid Build Coastguard Worker
454*5e7646d2SAndroid Build Coastguard Worker /*
455*5e7646d2SAndroid Build Coastguard Worker * Range check input...
456*5e7646d2SAndroid Build Coastguard Worker */
457*5e7646d2SAndroid Build Coastguard Worker
458*5e7646d2SAndroid Build Coastguard Worker #if 0
459*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
460*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
461*5e7646d2SAndroid Build Coastguard Worker (value_tag != IPP_TAG_INTEGER && value_tag != IPP_TAG_ENUM) ||
462*5e7646d2SAndroid Build Coastguard Worker num_values < 1)
463*5e7646d2SAndroid Build Coastguard Worker return (NULL);
464*5e7646d2SAndroid Build Coastguard Worker #else
465*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
466*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
467*5e7646d2SAndroid Build Coastguard Worker num_values < 1)
468*5e7646d2SAndroid Build Coastguard Worker return (NULL);
469*5e7646d2SAndroid Build Coastguard Worker #endif /* 0 */
470*5e7646d2SAndroid Build Coastguard Worker
471*5e7646d2SAndroid Build Coastguard Worker /*
472*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
473*5e7646d2SAndroid Build Coastguard Worker */
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, value_tag, num_values)) == NULL)
476*5e7646d2SAndroid Build Coastguard Worker return (NULL);
477*5e7646d2SAndroid Build Coastguard Worker
478*5e7646d2SAndroid Build Coastguard Worker if (values)
479*5e7646d2SAndroid Build Coastguard Worker {
480*5e7646d2SAndroid Build Coastguard Worker for (i = num_values, value = attr->values;
481*5e7646d2SAndroid Build Coastguard Worker i > 0;
482*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
483*5e7646d2SAndroid Build Coastguard Worker value->integer = *values++;
484*5e7646d2SAndroid Build Coastguard Worker }
485*5e7646d2SAndroid Build Coastguard Worker
486*5e7646d2SAndroid Build Coastguard Worker return (attr);
487*5e7646d2SAndroid Build Coastguard Worker }
488*5e7646d2SAndroid Build Coastguard Worker
489*5e7646d2SAndroid Build Coastguard Worker
490*5e7646d2SAndroid Build Coastguard Worker /*
491*5e7646d2SAndroid Build Coastguard Worker * 'ippAddOctetString()' - Add an octetString value to an IPP message.
492*5e7646d2SAndroid Build Coastguard Worker *
493*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
494*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
495*5e7646d2SAndroid Build Coastguard Worker *
496*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
497*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
498*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
499*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
500*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
501*5e7646d2SAndroid Build Coastguard Worker *
502*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
503*5e7646d2SAndroid Build Coastguard Worker */
504*5e7646d2SAndroid Build Coastguard Worker
505*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddOctetString(ipp_t * ipp,ipp_tag_t group,const char * name,const void * data,int datalen)506*5e7646d2SAndroid Build Coastguard Worker ippAddOctetString(ipp_t *ipp, /* I - IPP message */
507*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
508*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
509*5e7646d2SAndroid Build Coastguard Worker const void *data, /* I - octetString data */
510*5e7646d2SAndroid Build Coastguard Worker int datalen) /* I - Length of data in bytes */
511*5e7646d2SAndroid Build Coastguard Worker {
512*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
513*5e7646d2SAndroid Build Coastguard Worker
514*5e7646d2SAndroid Build Coastguard Worker
515*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
516*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
517*5e7646d2SAndroid Build Coastguard Worker datalen < 0 || datalen > IPP_MAX_LENGTH)
518*5e7646d2SAndroid Build Coastguard Worker return (NULL);
519*5e7646d2SAndroid Build Coastguard Worker
520*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_STRING, 1)) == NULL)
521*5e7646d2SAndroid Build Coastguard Worker return (NULL);
522*5e7646d2SAndroid Build Coastguard Worker
523*5e7646d2SAndroid Build Coastguard Worker /*
524*5e7646d2SAndroid Build Coastguard Worker * Initialize the attribute data...
525*5e7646d2SAndroid Build Coastguard Worker */
526*5e7646d2SAndroid Build Coastguard Worker
527*5e7646d2SAndroid Build Coastguard Worker attr->values[0].unknown.length = datalen;
528*5e7646d2SAndroid Build Coastguard Worker
529*5e7646d2SAndroid Build Coastguard Worker if (data)
530*5e7646d2SAndroid Build Coastguard Worker {
531*5e7646d2SAndroid Build Coastguard Worker if ((attr->values[0].unknown.data = malloc((size_t)datalen)) == NULL)
532*5e7646d2SAndroid Build Coastguard Worker {
533*5e7646d2SAndroid Build Coastguard Worker ippDeleteAttribute(ipp, attr);
534*5e7646d2SAndroid Build Coastguard Worker return (NULL);
535*5e7646d2SAndroid Build Coastguard Worker }
536*5e7646d2SAndroid Build Coastguard Worker
537*5e7646d2SAndroid Build Coastguard Worker memcpy(attr->values[0].unknown.data, data, (size_t)datalen);
538*5e7646d2SAndroid Build Coastguard Worker }
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker /*
541*5e7646d2SAndroid Build Coastguard Worker * Return the new attribute...
542*5e7646d2SAndroid Build Coastguard Worker */
543*5e7646d2SAndroid Build Coastguard Worker
544*5e7646d2SAndroid Build Coastguard Worker return (attr);
545*5e7646d2SAndroid Build Coastguard Worker }
546*5e7646d2SAndroid Build Coastguard Worker
547*5e7646d2SAndroid Build Coastguard Worker
548*5e7646d2SAndroid Build Coastguard Worker /*
549*5e7646d2SAndroid Build Coastguard Worker * 'ippAddOutOfBand()' - Add an out-of-band value to an IPP message.
550*5e7646d2SAndroid Build Coastguard Worker *
551*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
552*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
553*5e7646d2SAndroid Build Coastguard Worker *
554*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
555*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
556*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
557*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
558*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
559*5e7646d2SAndroid Build Coastguard Worker *
560*5e7646d2SAndroid Build Coastguard Worker * Supported out-of-band values include unsupported-value
561*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_UNSUPPORTED_VALUE@), default (@code IPP_TAG_DEFAULT@), unknown
562*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_UNKNOWN@), no-value (@code IPP_TAG_NOVALUE@), not-settable
563*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_NOTSETTABLE@), delete-attribute (@code IPP_TAG_DELETEATTR@), and
564*5e7646d2SAndroid Build Coastguard Worker * admin-define (@code IPP_TAG_ADMINDEFINE@).
565*5e7646d2SAndroid Build Coastguard Worker *
566*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
567*5e7646d2SAndroid Build Coastguard Worker */
568*5e7646d2SAndroid Build Coastguard Worker
569*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddOutOfBand(ipp_t * ipp,ipp_tag_t group,ipp_tag_t value_tag,const char * name)570*5e7646d2SAndroid Build Coastguard Worker ippAddOutOfBand(ipp_t *ipp, /* I - IPP message */
571*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
572*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag, /* I - Type of attribute */
573*5e7646d2SAndroid Build Coastguard Worker const char *name) /* I - Name of attribute */
574*5e7646d2SAndroid Build Coastguard Worker {
575*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddOutOfBand(ipp=%p, group=%02x(%s), value_tag=%02x(%s), name=\"%s\")", (void *)ipp, group, ippTagString(group), value_tag, ippTagString(value_tag), name));
576*5e7646d2SAndroid Build Coastguard Worker
577*5e7646d2SAndroid Build Coastguard Worker value_tag &= IPP_TAG_CUPS_MASK;
578*5e7646d2SAndroid Build Coastguard Worker
579*5e7646d2SAndroid Build Coastguard Worker /*
580*5e7646d2SAndroid Build Coastguard Worker * Range check input...
581*5e7646d2SAndroid Build Coastguard Worker */
582*5e7646d2SAndroid Build Coastguard Worker
583*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
584*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
585*5e7646d2SAndroid Build Coastguard Worker (value_tag != IPP_TAG_UNSUPPORTED_VALUE &&
586*5e7646d2SAndroid Build Coastguard Worker value_tag != IPP_TAG_DEFAULT &&
587*5e7646d2SAndroid Build Coastguard Worker value_tag != IPP_TAG_UNKNOWN &&
588*5e7646d2SAndroid Build Coastguard Worker value_tag != IPP_TAG_NOVALUE &&
589*5e7646d2SAndroid Build Coastguard Worker value_tag != IPP_TAG_NOTSETTABLE &&
590*5e7646d2SAndroid Build Coastguard Worker value_tag != IPP_TAG_DELETEATTR &&
591*5e7646d2SAndroid Build Coastguard Worker value_tag != IPP_TAG_ADMINDEFINE))
592*5e7646d2SAndroid Build Coastguard Worker return (NULL);
593*5e7646d2SAndroid Build Coastguard Worker
594*5e7646d2SAndroid Build Coastguard Worker /*
595*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
596*5e7646d2SAndroid Build Coastguard Worker */
597*5e7646d2SAndroid Build Coastguard Worker
598*5e7646d2SAndroid Build Coastguard Worker return (ipp_add_attr(ipp, name, group, value_tag, 1));
599*5e7646d2SAndroid Build Coastguard Worker }
600*5e7646d2SAndroid Build Coastguard Worker
601*5e7646d2SAndroid Build Coastguard Worker
602*5e7646d2SAndroid Build Coastguard Worker /*
603*5e7646d2SAndroid Build Coastguard Worker * 'ippAddRange()' - Add a range of values to an IPP message.
604*5e7646d2SAndroid Build Coastguard Worker *
605*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
606*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
607*5e7646d2SAndroid Build Coastguard Worker *
608*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
609*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
610*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
611*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
612*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
613*5e7646d2SAndroid Build Coastguard Worker *
614*5e7646d2SAndroid Build Coastguard Worker * The @code lower@ parameter must be less than or equal to the @code upper@ parameter.
615*5e7646d2SAndroid Build Coastguard Worker */
616*5e7646d2SAndroid Build Coastguard Worker
617*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddRange(ipp_t * ipp,ipp_tag_t group,const char * name,int lower,int upper)618*5e7646d2SAndroid Build Coastguard Worker ippAddRange(ipp_t *ipp, /* I - IPP message */
619*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
620*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
621*5e7646d2SAndroid Build Coastguard Worker int lower, /* I - Lower value */
622*5e7646d2SAndroid Build Coastguard Worker int upper) /* I - Upper value */
623*5e7646d2SAndroid Build Coastguard Worker {
624*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
625*5e7646d2SAndroid Build Coastguard Worker
626*5e7646d2SAndroid Build Coastguard Worker
627*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddRange(ipp=%p, group=%02x(%s), name=\"%s\", lower=%d, upper=%d)", (void *)ipp, group, ippTagString(group), name, lower, upper));
628*5e7646d2SAndroid Build Coastguard Worker
629*5e7646d2SAndroid Build Coastguard Worker /*
630*5e7646d2SAndroid Build Coastguard Worker * Range check input...
631*5e7646d2SAndroid Build Coastguard Worker */
632*5e7646d2SAndroid Build Coastguard Worker
633*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
634*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE)
635*5e7646d2SAndroid Build Coastguard Worker return (NULL);
636*5e7646d2SAndroid Build Coastguard Worker
637*5e7646d2SAndroid Build Coastguard Worker /*
638*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
639*5e7646d2SAndroid Build Coastguard Worker */
640*5e7646d2SAndroid Build Coastguard Worker
641*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_RANGE, 1)) == NULL)
642*5e7646d2SAndroid Build Coastguard Worker return (NULL);
643*5e7646d2SAndroid Build Coastguard Worker
644*5e7646d2SAndroid Build Coastguard Worker attr->values[0].range.lower = lower;
645*5e7646d2SAndroid Build Coastguard Worker attr->values[0].range.upper = upper;
646*5e7646d2SAndroid Build Coastguard Worker
647*5e7646d2SAndroid Build Coastguard Worker return (attr);
648*5e7646d2SAndroid Build Coastguard Worker }
649*5e7646d2SAndroid Build Coastguard Worker
650*5e7646d2SAndroid Build Coastguard Worker
651*5e7646d2SAndroid Build Coastguard Worker /*
652*5e7646d2SAndroid Build Coastguard Worker * 'ippAddRanges()' - Add ranges of values to an IPP message.
653*5e7646d2SAndroid Build Coastguard Worker *
654*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
655*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
656*5e7646d2SAndroid Build Coastguard Worker *
657*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
658*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
659*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
660*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
661*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
662*5e7646d2SAndroid Build Coastguard Worker */
663*5e7646d2SAndroid Build Coastguard Worker
664*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddRanges(ipp_t * ipp,ipp_tag_t group,const char * name,int num_values,const int * lower,const int * upper)665*5e7646d2SAndroid Build Coastguard Worker ippAddRanges(ipp_t *ipp, /* I - IPP message */
666*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
667*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
668*5e7646d2SAndroid Build Coastguard Worker int num_values, /* I - Number of values */
669*5e7646d2SAndroid Build Coastguard Worker const int *lower, /* I - Lower values */
670*5e7646d2SAndroid Build Coastguard Worker const int *upper) /* I - Upper values */
671*5e7646d2SAndroid Build Coastguard Worker {
672*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
673*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
674*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
675*5e7646d2SAndroid Build Coastguard Worker
676*5e7646d2SAndroid Build Coastguard Worker
677*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddRanges(ipp=%p, group=%02x(%s), name=\"%s\", num_values=%d, lower=%p, upper=%p)", (void *)ipp, group, ippTagString(group), name, num_values, (void *)lower, (void *)upper));
678*5e7646d2SAndroid Build Coastguard Worker
679*5e7646d2SAndroid Build Coastguard Worker /*
680*5e7646d2SAndroid Build Coastguard Worker * Range check input...
681*5e7646d2SAndroid Build Coastguard Worker */
682*5e7646d2SAndroid Build Coastguard Worker
683*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
684*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
685*5e7646d2SAndroid Build Coastguard Worker num_values < 1)
686*5e7646d2SAndroid Build Coastguard Worker return (NULL);
687*5e7646d2SAndroid Build Coastguard Worker
688*5e7646d2SAndroid Build Coastguard Worker /*
689*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
690*5e7646d2SAndroid Build Coastguard Worker */
691*5e7646d2SAndroid Build Coastguard Worker
692*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_RANGE, num_values)) == NULL)
693*5e7646d2SAndroid Build Coastguard Worker return (NULL);
694*5e7646d2SAndroid Build Coastguard Worker
695*5e7646d2SAndroid Build Coastguard Worker if (lower && upper)
696*5e7646d2SAndroid Build Coastguard Worker {
697*5e7646d2SAndroid Build Coastguard Worker for (i = num_values, value = attr->values;
698*5e7646d2SAndroid Build Coastguard Worker i > 0;
699*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
700*5e7646d2SAndroid Build Coastguard Worker {
701*5e7646d2SAndroid Build Coastguard Worker value->range.lower = *lower++;
702*5e7646d2SAndroid Build Coastguard Worker value->range.upper = *upper++;
703*5e7646d2SAndroid Build Coastguard Worker }
704*5e7646d2SAndroid Build Coastguard Worker }
705*5e7646d2SAndroid Build Coastguard Worker
706*5e7646d2SAndroid Build Coastguard Worker return (attr);
707*5e7646d2SAndroid Build Coastguard Worker }
708*5e7646d2SAndroid Build Coastguard Worker
709*5e7646d2SAndroid Build Coastguard Worker
710*5e7646d2SAndroid Build Coastguard Worker /*
711*5e7646d2SAndroid Build Coastguard Worker * 'ippAddResolution()' - Add a resolution value to an IPP message.
712*5e7646d2SAndroid Build Coastguard Worker *
713*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
714*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
715*5e7646d2SAndroid Build Coastguard Worker *
716*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
717*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
718*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
719*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
720*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
721*5e7646d2SAndroid Build Coastguard Worker */
722*5e7646d2SAndroid Build Coastguard Worker
723*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddResolution(ipp_t * ipp,ipp_tag_t group,const char * name,ipp_res_t units,int xres,int yres)724*5e7646d2SAndroid Build Coastguard Worker ippAddResolution(ipp_t *ipp, /* I - IPP message */
725*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
726*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
727*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units, /* I - Units for resolution */
728*5e7646d2SAndroid Build Coastguard Worker int xres, /* I - X resolution */
729*5e7646d2SAndroid Build Coastguard Worker int yres) /* I - Y resolution */
730*5e7646d2SAndroid Build Coastguard Worker {
731*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
732*5e7646d2SAndroid Build Coastguard Worker
733*5e7646d2SAndroid Build Coastguard Worker
734*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddResolution(ipp=%p, group=%02x(%s), name=\"%s\", units=%d, xres=%d, yres=%d)", (void *)ipp, group,
735*5e7646d2SAndroid Build Coastguard Worker ippTagString(group), name, units, xres, yres));
736*5e7646d2SAndroid Build Coastguard Worker
737*5e7646d2SAndroid Build Coastguard Worker /*
738*5e7646d2SAndroid Build Coastguard Worker * Range check input...
739*5e7646d2SAndroid Build Coastguard Worker */
740*5e7646d2SAndroid Build Coastguard Worker
741*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
742*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
743*5e7646d2SAndroid Build Coastguard Worker units < IPP_RES_PER_INCH || units > IPP_RES_PER_CM ||
744*5e7646d2SAndroid Build Coastguard Worker xres < 0 || yres < 0)
745*5e7646d2SAndroid Build Coastguard Worker return (NULL);
746*5e7646d2SAndroid Build Coastguard Worker
747*5e7646d2SAndroid Build Coastguard Worker /*
748*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
749*5e7646d2SAndroid Build Coastguard Worker */
750*5e7646d2SAndroid Build Coastguard Worker
751*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_RESOLUTION, 1)) == NULL)
752*5e7646d2SAndroid Build Coastguard Worker return (NULL);
753*5e7646d2SAndroid Build Coastguard Worker
754*5e7646d2SAndroid Build Coastguard Worker attr->values[0].resolution.xres = xres;
755*5e7646d2SAndroid Build Coastguard Worker attr->values[0].resolution.yres = yres;
756*5e7646d2SAndroid Build Coastguard Worker attr->values[0].resolution.units = units;
757*5e7646d2SAndroid Build Coastguard Worker
758*5e7646d2SAndroid Build Coastguard Worker return (attr);
759*5e7646d2SAndroid Build Coastguard Worker }
760*5e7646d2SAndroid Build Coastguard Worker
761*5e7646d2SAndroid Build Coastguard Worker
762*5e7646d2SAndroid Build Coastguard Worker /*
763*5e7646d2SAndroid Build Coastguard Worker * 'ippAddResolutions()' - Add resolution values to an IPP message.
764*5e7646d2SAndroid Build Coastguard Worker *
765*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
766*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
767*5e7646d2SAndroid Build Coastguard Worker *
768*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
769*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
770*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
771*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
772*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
773*5e7646d2SAndroid Build Coastguard Worker */
774*5e7646d2SAndroid Build Coastguard Worker
775*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddResolutions(ipp_t * ipp,ipp_tag_t group,const char * name,int num_values,ipp_res_t units,const int * xres,const int * yres)776*5e7646d2SAndroid Build Coastguard Worker ippAddResolutions(ipp_t *ipp, /* I - IPP message */
777*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
778*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
779*5e7646d2SAndroid Build Coastguard Worker int num_values,/* I - Number of values */
780*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units, /* I - Units for resolution */
781*5e7646d2SAndroid Build Coastguard Worker const int *xres, /* I - X resolutions */
782*5e7646d2SAndroid Build Coastguard Worker const int *yres) /* I - Y resolutions */
783*5e7646d2SAndroid Build Coastguard Worker {
784*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
785*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
786*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
787*5e7646d2SAndroid Build Coastguard Worker
788*5e7646d2SAndroid Build Coastguard Worker
789*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddResolutions(ipp=%p, group=%02x(%s), name=\"%s\", num_value=%d, units=%d, xres=%p, yres=%p)", (void *)ipp, group, ippTagString(group), name, num_values, units, (void *)xres, (void *)yres));
790*5e7646d2SAndroid Build Coastguard Worker
791*5e7646d2SAndroid Build Coastguard Worker /*
792*5e7646d2SAndroid Build Coastguard Worker * Range check input...
793*5e7646d2SAndroid Build Coastguard Worker */
794*5e7646d2SAndroid Build Coastguard Worker
795*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
796*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
797*5e7646d2SAndroid Build Coastguard Worker num_values < 1 ||
798*5e7646d2SAndroid Build Coastguard Worker units < IPP_RES_PER_INCH || units > IPP_RES_PER_CM)
799*5e7646d2SAndroid Build Coastguard Worker return (NULL);
800*5e7646d2SAndroid Build Coastguard Worker
801*5e7646d2SAndroid Build Coastguard Worker /*
802*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
803*5e7646d2SAndroid Build Coastguard Worker */
804*5e7646d2SAndroid Build Coastguard Worker
805*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, IPP_TAG_RESOLUTION, num_values)) == NULL)
806*5e7646d2SAndroid Build Coastguard Worker return (NULL);
807*5e7646d2SAndroid Build Coastguard Worker
808*5e7646d2SAndroid Build Coastguard Worker if (xres && yres)
809*5e7646d2SAndroid Build Coastguard Worker {
810*5e7646d2SAndroid Build Coastguard Worker for (i = num_values, value = attr->values;
811*5e7646d2SAndroid Build Coastguard Worker i > 0;
812*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
813*5e7646d2SAndroid Build Coastguard Worker {
814*5e7646d2SAndroid Build Coastguard Worker value->resolution.xres = *xres++;
815*5e7646d2SAndroid Build Coastguard Worker value->resolution.yres = *yres++;
816*5e7646d2SAndroid Build Coastguard Worker value->resolution.units = units;
817*5e7646d2SAndroid Build Coastguard Worker }
818*5e7646d2SAndroid Build Coastguard Worker }
819*5e7646d2SAndroid Build Coastguard Worker
820*5e7646d2SAndroid Build Coastguard Worker return (attr);
821*5e7646d2SAndroid Build Coastguard Worker }
822*5e7646d2SAndroid Build Coastguard Worker
823*5e7646d2SAndroid Build Coastguard Worker
824*5e7646d2SAndroid Build Coastguard Worker /*
825*5e7646d2SAndroid Build Coastguard Worker * 'ippAddSeparator()' - Add a group separator to an IPP message.
826*5e7646d2SAndroid Build Coastguard Worker *
827*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
828*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
829*5e7646d2SAndroid Build Coastguard Worker */
830*5e7646d2SAndroid Build Coastguard Worker
831*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddSeparator(ipp_t * ipp)832*5e7646d2SAndroid Build Coastguard Worker ippAddSeparator(ipp_t *ipp) /* I - IPP message */
833*5e7646d2SAndroid Build Coastguard Worker {
834*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddSeparator(ipp=%p)", (void *)ipp));
835*5e7646d2SAndroid Build Coastguard Worker
836*5e7646d2SAndroid Build Coastguard Worker /*
837*5e7646d2SAndroid Build Coastguard Worker * Range check input...
838*5e7646d2SAndroid Build Coastguard Worker */
839*5e7646d2SAndroid Build Coastguard Worker
840*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
841*5e7646d2SAndroid Build Coastguard Worker return (NULL);
842*5e7646d2SAndroid Build Coastguard Worker
843*5e7646d2SAndroid Build Coastguard Worker /*
844*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
845*5e7646d2SAndroid Build Coastguard Worker */
846*5e7646d2SAndroid Build Coastguard Worker
847*5e7646d2SAndroid Build Coastguard Worker return (ipp_add_attr(ipp, NULL, IPP_TAG_ZERO, IPP_TAG_ZERO, 0));
848*5e7646d2SAndroid Build Coastguard Worker }
849*5e7646d2SAndroid Build Coastguard Worker
850*5e7646d2SAndroid Build Coastguard Worker
851*5e7646d2SAndroid Build Coastguard Worker /*
852*5e7646d2SAndroid Build Coastguard Worker * 'ippAddString()' - Add a language-encoded string to an IPP message.
853*5e7646d2SAndroid Build Coastguard Worker *
854*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
855*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
856*5e7646d2SAndroid Build Coastguard Worker *
857*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
858*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
859*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
860*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
861*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
862*5e7646d2SAndroid Build Coastguard Worker *
863*5e7646d2SAndroid Build Coastguard Worker * Supported string values include charset (@code IPP_TAG_CHARSET@), keyword
864*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_KEYWORD@), language (@code IPP_TAG_LANGUAGE@), mimeMediaType
865*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_MIMETYPE@), name (@code IPP_TAG_NAME@), nameWithLanguage
866*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_NAMELANG), text (@code IPP_TAG_TEXT@), textWithLanguage
867*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_TEXTLANG@), uri (@code IPP_TAG_URI@), and uriScheme
868*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_URISCHEME@).
869*5e7646d2SAndroid Build Coastguard Worker *
870*5e7646d2SAndroid Build Coastguard Worker * The @code language@ parameter must be non-@code NULL@ for nameWithLanguage and
871*5e7646d2SAndroid Build Coastguard Worker * textWithLanguage string values and must be @code NULL@ for all other string values.
872*5e7646d2SAndroid Build Coastguard Worker */
873*5e7646d2SAndroid Build Coastguard Worker
874*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddString(ipp_t * ipp,ipp_tag_t group,ipp_tag_t value_tag,const char * name,const char * language,const char * value)875*5e7646d2SAndroid Build Coastguard Worker ippAddString(ipp_t *ipp, /* I - IPP message */
876*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
877*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag, /* I - Type of attribute */
878*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
879*5e7646d2SAndroid Build Coastguard Worker const char *language, /* I - Language code */
880*5e7646d2SAndroid Build Coastguard Worker const char *value) /* I - Value */
881*5e7646d2SAndroid Build Coastguard Worker {
882*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t temp_tag; /* Temporary value tag (masked) */
883*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
884*5e7646d2SAndroid Build Coastguard Worker char code[IPP_MAX_LANGUAGE];
885*5e7646d2SAndroid Build Coastguard Worker /* Charset/language code buffer */
886*5e7646d2SAndroid Build Coastguard Worker
887*5e7646d2SAndroid Build Coastguard Worker
888*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddString(ipp=%p, group=%02x(%s), value_tag=%02x(%s), name=\"%s\", language=\"%s\", value=\"%s\")", (void *)ipp, group, ippTagString(group), value_tag, ippTagString(value_tag), name, language, value));
889*5e7646d2SAndroid Build Coastguard Worker
890*5e7646d2SAndroid Build Coastguard Worker /*
891*5e7646d2SAndroid Build Coastguard Worker * Range check input...
892*5e7646d2SAndroid Build Coastguard Worker */
893*5e7646d2SAndroid Build Coastguard Worker
894*5e7646d2SAndroid Build Coastguard Worker temp_tag = (ipp_tag_t)((int)value_tag & IPP_TAG_CUPS_MASK);
895*5e7646d2SAndroid Build Coastguard Worker
896*5e7646d2SAndroid Build Coastguard Worker #if 0
897*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
898*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
899*5e7646d2SAndroid Build Coastguard Worker (temp_tag < IPP_TAG_TEXT && temp_tag != IPP_TAG_TEXTLANG &&
900*5e7646d2SAndroid Build Coastguard Worker temp_tag != IPP_TAG_NAMELANG) || temp_tag > IPP_TAG_MIMETYPE)
901*5e7646d2SAndroid Build Coastguard Worker return (NULL);
902*5e7646d2SAndroid Build Coastguard Worker
903*5e7646d2SAndroid Build Coastguard Worker if ((temp_tag == IPP_TAG_TEXTLANG || temp_tag == IPP_TAG_NAMELANG)
904*5e7646d2SAndroid Build Coastguard Worker != (language != NULL))
905*5e7646d2SAndroid Build Coastguard Worker return (NULL);
906*5e7646d2SAndroid Build Coastguard Worker #else
907*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
908*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE)
909*5e7646d2SAndroid Build Coastguard Worker return (NULL);
910*5e7646d2SAndroid Build Coastguard Worker #endif /* 0 */
911*5e7646d2SAndroid Build Coastguard Worker
912*5e7646d2SAndroid Build Coastguard Worker /*
913*5e7646d2SAndroid Build Coastguard Worker * See if we need to map charset, language, or locale values...
914*5e7646d2SAndroid Build Coastguard Worker */
915*5e7646d2SAndroid Build Coastguard Worker
916*5e7646d2SAndroid Build Coastguard Worker if (language && ((int)value_tag & IPP_TAG_CUPS_CONST) &&
917*5e7646d2SAndroid Build Coastguard Worker strcmp(language, ipp_lang_code(language, code, sizeof(code))))
918*5e7646d2SAndroid Build Coastguard Worker value_tag = temp_tag; /* Don't do a fast copy */
919*5e7646d2SAndroid Build Coastguard Worker else if (value && value_tag == (ipp_tag_t)(IPP_TAG_CHARSET | IPP_TAG_CUPS_CONST) &&
920*5e7646d2SAndroid Build Coastguard Worker strcmp(value, ipp_get_code(value, code, sizeof(code))))
921*5e7646d2SAndroid Build Coastguard Worker value_tag = temp_tag; /* Don't do a fast copy */
922*5e7646d2SAndroid Build Coastguard Worker else if (value && value_tag == (ipp_tag_t)(IPP_TAG_LANGUAGE | IPP_TAG_CUPS_CONST) &&
923*5e7646d2SAndroid Build Coastguard Worker strcmp(value, ipp_lang_code(value, code, sizeof(code))))
924*5e7646d2SAndroid Build Coastguard Worker value_tag = temp_tag; /* Don't do a fast copy */
925*5e7646d2SAndroid Build Coastguard Worker
926*5e7646d2SAndroid Build Coastguard Worker /*
927*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
928*5e7646d2SAndroid Build Coastguard Worker */
929*5e7646d2SAndroid Build Coastguard Worker
930*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, value_tag, 1)) == NULL)
931*5e7646d2SAndroid Build Coastguard Worker return (NULL);
932*5e7646d2SAndroid Build Coastguard Worker
933*5e7646d2SAndroid Build Coastguard Worker /*
934*5e7646d2SAndroid Build Coastguard Worker * Initialize the attribute data...
935*5e7646d2SAndroid Build Coastguard Worker */
936*5e7646d2SAndroid Build Coastguard Worker
937*5e7646d2SAndroid Build Coastguard Worker if ((int)value_tag & IPP_TAG_CUPS_CONST)
938*5e7646d2SAndroid Build Coastguard Worker {
939*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.language = (char *)language;
940*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text = (char *)value;
941*5e7646d2SAndroid Build Coastguard Worker }
942*5e7646d2SAndroid Build Coastguard Worker else
943*5e7646d2SAndroid Build Coastguard Worker {
944*5e7646d2SAndroid Build Coastguard Worker if (language)
945*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.language = _cupsStrAlloc(ipp_lang_code(language, code,
946*5e7646d2SAndroid Build Coastguard Worker sizeof(code)));
947*5e7646d2SAndroid Build Coastguard Worker
948*5e7646d2SAndroid Build Coastguard Worker if (value)
949*5e7646d2SAndroid Build Coastguard Worker {
950*5e7646d2SAndroid Build Coastguard Worker if (value_tag == IPP_TAG_CHARSET)
951*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text = _cupsStrAlloc(ipp_get_code(value, code,
952*5e7646d2SAndroid Build Coastguard Worker sizeof(code)));
953*5e7646d2SAndroid Build Coastguard Worker else if (value_tag == IPP_TAG_LANGUAGE)
954*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text = _cupsStrAlloc(ipp_lang_code(value, code,
955*5e7646d2SAndroid Build Coastguard Worker sizeof(code)));
956*5e7646d2SAndroid Build Coastguard Worker else
957*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text = _cupsStrAlloc(value);
958*5e7646d2SAndroid Build Coastguard Worker }
959*5e7646d2SAndroid Build Coastguard Worker }
960*5e7646d2SAndroid Build Coastguard Worker
961*5e7646d2SAndroid Build Coastguard Worker return (attr);
962*5e7646d2SAndroid Build Coastguard Worker }
963*5e7646d2SAndroid Build Coastguard Worker
964*5e7646d2SAndroid Build Coastguard Worker
965*5e7646d2SAndroid Build Coastguard Worker /*
966*5e7646d2SAndroid Build Coastguard Worker * 'ippAddStringf()' - Add a formatted string to an IPP message.
967*5e7646d2SAndroid Build Coastguard Worker *
968*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
969*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
970*5e7646d2SAndroid Build Coastguard Worker *
971*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
972*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document
973*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_DOCUMENT@), event notification
974*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_EVENT_NOTIFICATION@), operation (@code IPP_TAG_OPERATION@),
975*5e7646d2SAndroid Build Coastguard Worker * printer (@code IPP_TAG_PRINTER@), subscription (@code IPP_TAG_SUBSCRIPTION@),
976*5e7646d2SAndroid Build Coastguard Worker * or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
977*5e7646d2SAndroid Build Coastguard Worker *
978*5e7646d2SAndroid Build Coastguard Worker * Supported string values include charset (@code IPP_TAG_CHARSET@), keyword
979*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_KEYWORD@), language (@code IPP_TAG_LANGUAGE@), mimeMediaType
980*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_MIMETYPE@), name (@code IPP_TAG_NAME@), nameWithLanguage
981*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_NAMELANG), text (@code IPP_TAG_TEXT@), textWithLanguage
982*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_TEXTLANG@), uri (@code IPP_TAG_URI@), and uriScheme
983*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_URISCHEME@).
984*5e7646d2SAndroid Build Coastguard Worker *
985*5e7646d2SAndroid Build Coastguard Worker * The @code language@ parameter must be non-@code NULL@ for nameWithLanguage
986*5e7646d2SAndroid Build Coastguard Worker * and textWithLanguage string values and must be @code NULL@ for all other
987*5e7646d2SAndroid Build Coastguard Worker * string values.
988*5e7646d2SAndroid Build Coastguard Worker *
989*5e7646d2SAndroid Build Coastguard Worker * The @code format@ parameter uses formatting characters compatible with the
990*5e7646d2SAndroid Build Coastguard Worker * printf family of standard functions. Additional arguments follow it as
991*5e7646d2SAndroid Build Coastguard Worker * needed. The formatted string is truncated as needed to the maximum length of
992*5e7646d2SAndroid Build Coastguard Worker * the corresponding value type.
993*5e7646d2SAndroid Build Coastguard Worker *
994*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
995*5e7646d2SAndroid Build Coastguard Worker */
996*5e7646d2SAndroid Build Coastguard Worker
997*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddStringf(ipp_t * ipp,ipp_tag_t group,ipp_tag_t value_tag,const char * name,const char * language,const char * format,...)998*5e7646d2SAndroid Build Coastguard Worker ippAddStringf(ipp_t *ipp, /* I - IPP message */
999*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
1000*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag, /* I - Type of attribute */
1001*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
1002*5e7646d2SAndroid Build Coastguard Worker const char *language, /* I - Language code (@code NULL@ for default) */
1003*5e7646d2SAndroid Build Coastguard Worker const char *format, /* I - Printf-style format string */
1004*5e7646d2SAndroid Build Coastguard Worker ...) /* I - Additional arguments as needed */
1005*5e7646d2SAndroid Build Coastguard Worker {
1006*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
1007*5e7646d2SAndroid Build Coastguard Worker va_list ap; /* Argument pointer */
1008*5e7646d2SAndroid Build Coastguard Worker
1009*5e7646d2SAndroid Build Coastguard Worker
1010*5e7646d2SAndroid Build Coastguard Worker va_start(ap, format);
1011*5e7646d2SAndroid Build Coastguard Worker attr = ippAddStringfv(ipp, group, value_tag, name, language, format, ap);
1012*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
1013*5e7646d2SAndroid Build Coastguard Worker
1014*5e7646d2SAndroid Build Coastguard Worker return (attr);
1015*5e7646d2SAndroid Build Coastguard Worker }
1016*5e7646d2SAndroid Build Coastguard Worker
1017*5e7646d2SAndroid Build Coastguard Worker
1018*5e7646d2SAndroid Build Coastguard Worker /*
1019*5e7646d2SAndroid Build Coastguard Worker * 'ippAddStringfv()' - Add a formatted string to an IPP message.
1020*5e7646d2SAndroid Build Coastguard Worker *
1021*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
1022*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
1023*5e7646d2SAndroid Build Coastguard Worker *
1024*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
1025*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document
1026*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_DOCUMENT@), event notification
1027*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_EVENT_NOTIFICATION@), operation (@code IPP_TAG_OPERATION@),
1028*5e7646d2SAndroid Build Coastguard Worker * printer (@code IPP_TAG_PRINTER@), subscription (@code IPP_TAG_SUBSCRIPTION@),
1029*5e7646d2SAndroid Build Coastguard Worker * or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
1030*5e7646d2SAndroid Build Coastguard Worker *
1031*5e7646d2SAndroid Build Coastguard Worker * Supported string values include charset (@code IPP_TAG_CHARSET@), keyword
1032*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_KEYWORD@), language (@code IPP_TAG_LANGUAGE@), mimeMediaType
1033*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_MIMETYPE@), name (@code IPP_TAG_NAME@), nameWithLanguage
1034*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_NAMELANG), text (@code IPP_TAG_TEXT@), textWithLanguage
1035*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_TEXTLANG@), uri (@code IPP_TAG_URI@), and uriScheme
1036*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_URISCHEME@).
1037*5e7646d2SAndroid Build Coastguard Worker *
1038*5e7646d2SAndroid Build Coastguard Worker * The @code language@ parameter must be non-@code NULL@ for nameWithLanguage
1039*5e7646d2SAndroid Build Coastguard Worker * and textWithLanguage string values and must be @code NULL@ for all other
1040*5e7646d2SAndroid Build Coastguard Worker * string values.
1041*5e7646d2SAndroid Build Coastguard Worker *
1042*5e7646d2SAndroid Build Coastguard Worker * The @code format@ parameter uses formatting characters compatible with the
1043*5e7646d2SAndroid Build Coastguard Worker * printf family of standard functions. Additional arguments are passed in the
1044*5e7646d2SAndroid Build Coastguard Worker * stdarg pointer @code ap@. The formatted string is truncated as needed to the
1045*5e7646d2SAndroid Build Coastguard Worker * maximum length of the corresponding value type.
1046*5e7646d2SAndroid Build Coastguard Worker *
1047*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
1048*5e7646d2SAndroid Build Coastguard Worker */
1049*5e7646d2SAndroid Build Coastguard Worker
1050*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddStringfv(ipp_t * ipp,ipp_tag_t group,ipp_tag_t value_tag,const char * name,const char * language,const char * format,va_list ap)1051*5e7646d2SAndroid Build Coastguard Worker ippAddStringfv(ipp_t *ipp, /* I - IPP message */
1052*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
1053*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag, /* I - Type of attribute */
1054*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
1055*5e7646d2SAndroid Build Coastguard Worker const char *language, /* I - Language code (@code NULL@ for default) */
1056*5e7646d2SAndroid Build Coastguard Worker const char *format, /* I - Printf-style format string */
1057*5e7646d2SAndroid Build Coastguard Worker va_list ap) /* I - Additional arguments */
1058*5e7646d2SAndroid Build Coastguard Worker {
1059*5e7646d2SAndroid Build Coastguard Worker char buffer[IPP_MAX_TEXT + 4];
1060*5e7646d2SAndroid Build Coastguard Worker /* Formatted text string */
1061*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes, /* Length of formatted value */
1062*5e7646d2SAndroid Build Coastguard Worker max_bytes; /* Maximum number of bytes for value */
1063*5e7646d2SAndroid Build Coastguard Worker
1064*5e7646d2SAndroid Build Coastguard Worker
1065*5e7646d2SAndroid Build Coastguard Worker /*
1066*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1067*5e7646d2SAndroid Build Coastguard Worker */
1068*5e7646d2SAndroid Build Coastguard Worker
1069*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
1070*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
1071*5e7646d2SAndroid Build Coastguard Worker (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG &&
1072*5e7646d2SAndroid Build Coastguard Worker value_tag != IPP_TAG_NAMELANG) || value_tag > IPP_TAG_MIMETYPE ||
1073*5e7646d2SAndroid Build Coastguard Worker !format)
1074*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1075*5e7646d2SAndroid Build Coastguard Worker
1076*5e7646d2SAndroid Build Coastguard Worker if ((value_tag == IPP_TAG_TEXTLANG || value_tag == IPP_TAG_NAMELANG)
1077*5e7646d2SAndroid Build Coastguard Worker != (language != NULL))
1078*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1079*5e7646d2SAndroid Build Coastguard Worker
1080*5e7646d2SAndroid Build Coastguard Worker /*
1081*5e7646d2SAndroid Build Coastguard Worker * Format the string...
1082*5e7646d2SAndroid Build Coastguard Worker */
1083*5e7646d2SAndroid Build Coastguard Worker
1084*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(format, "%s"))
1085*5e7646d2SAndroid Build Coastguard Worker {
1086*5e7646d2SAndroid Build Coastguard Worker /*
1087*5e7646d2SAndroid Build Coastguard Worker * Optimize the simple case...
1088*5e7646d2SAndroid Build Coastguard Worker */
1089*5e7646d2SAndroid Build Coastguard Worker
1090*5e7646d2SAndroid Build Coastguard Worker const char *s = va_arg(ap, char *);
1091*5e7646d2SAndroid Build Coastguard Worker
1092*5e7646d2SAndroid Build Coastguard Worker if (!s)
1093*5e7646d2SAndroid Build Coastguard Worker s = "(null)";
1094*5e7646d2SAndroid Build Coastguard Worker
1095*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)strlen(s);
1096*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, s, sizeof(buffer));
1097*5e7646d2SAndroid Build Coastguard Worker }
1098*5e7646d2SAndroid Build Coastguard Worker else
1099*5e7646d2SAndroid Build Coastguard Worker {
1100*5e7646d2SAndroid Build Coastguard Worker /*
1101*5e7646d2SAndroid Build Coastguard Worker * Do a full formatting of the message...
1102*5e7646d2SAndroid Build Coastguard Worker */
1103*5e7646d2SAndroid Build Coastguard Worker
1104*5e7646d2SAndroid Build Coastguard Worker if ((bytes = vsnprintf(buffer, sizeof(buffer), format, ap)) < 0)
1105*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1106*5e7646d2SAndroid Build Coastguard Worker }
1107*5e7646d2SAndroid Build Coastguard Worker
1108*5e7646d2SAndroid Build Coastguard Worker /*
1109*5e7646d2SAndroid Build Coastguard Worker * Limit the length of the string...
1110*5e7646d2SAndroid Build Coastguard Worker */
1111*5e7646d2SAndroid Build Coastguard Worker
1112*5e7646d2SAndroid Build Coastguard Worker switch (value_tag)
1113*5e7646d2SAndroid Build Coastguard Worker {
1114*5e7646d2SAndroid Build Coastguard Worker default :
1115*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
1116*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
1117*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_TEXT;
1118*5e7646d2SAndroid Build Coastguard Worker break;
1119*5e7646d2SAndroid Build Coastguard Worker
1120*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
1121*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
1122*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_NAME;
1123*5e7646d2SAndroid Build Coastguard Worker break;
1124*5e7646d2SAndroid Build Coastguard Worker
1125*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
1126*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_CHARSET;
1127*5e7646d2SAndroid Build Coastguard Worker break;
1128*5e7646d2SAndroid Build Coastguard Worker
1129*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
1130*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_KEYWORD;
1131*5e7646d2SAndroid Build Coastguard Worker break;
1132*5e7646d2SAndroid Build Coastguard Worker
1133*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
1134*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_LANGUAGE;
1135*5e7646d2SAndroid Build Coastguard Worker break;
1136*5e7646d2SAndroid Build Coastguard Worker
1137*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
1138*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_MIMETYPE;
1139*5e7646d2SAndroid Build Coastguard Worker break;
1140*5e7646d2SAndroid Build Coastguard Worker
1141*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
1142*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_URI;
1143*5e7646d2SAndroid Build Coastguard Worker break;
1144*5e7646d2SAndroid Build Coastguard Worker
1145*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
1146*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_URISCHEME;
1147*5e7646d2SAndroid Build Coastguard Worker break;
1148*5e7646d2SAndroid Build Coastguard Worker }
1149*5e7646d2SAndroid Build Coastguard Worker
1150*5e7646d2SAndroid Build Coastguard Worker if (bytes >= max_bytes)
1151*5e7646d2SAndroid Build Coastguard Worker {
1152*5e7646d2SAndroid Build Coastguard Worker char *bufmax, /* Buffer at max_bytes */
1153*5e7646d2SAndroid Build Coastguard Worker *bufptr; /* Pointer into buffer */
1154*5e7646d2SAndroid Build Coastguard Worker
1155*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer + strlen(buffer) - 1;
1156*5e7646d2SAndroid Build Coastguard Worker bufmax = buffer + max_bytes - 1;
1157*5e7646d2SAndroid Build Coastguard Worker
1158*5e7646d2SAndroid Build Coastguard Worker while (bufptr > bufmax)
1159*5e7646d2SAndroid Build Coastguard Worker {
1160*5e7646d2SAndroid Build Coastguard Worker if (*bufptr & 0x80)
1161*5e7646d2SAndroid Build Coastguard Worker {
1162*5e7646d2SAndroid Build Coastguard Worker while ((*bufptr & 0xc0) == 0x80 && bufptr > buffer)
1163*5e7646d2SAndroid Build Coastguard Worker bufptr --;
1164*5e7646d2SAndroid Build Coastguard Worker }
1165*5e7646d2SAndroid Build Coastguard Worker
1166*5e7646d2SAndroid Build Coastguard Worker bufptr --;
1167*5e7646d2SAndroid Build Coastguard Worker }
1168*5e7646d2SAndroid Build Coastguard Worker
1169*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
1170*5e7646d2SAndroid Build Coastguard Worker }
1171*5e7646d2SAndroid Build Coastguard Worker
1172*5e7646d2SAndroid Build Coastguard Worker /*
1173*5e7646d2SAndroid Build Coastguard Worker * Add the formatted string and return...
1174*5e7646d2SAndroid Build Coastguard Worker */
1175*5e7646d2SAndroid Build Coastguard Worker
1176*5e7646d2SAndroid Build Coastguard Worker return (ippAddString(ipp, group, value_tag, name, language, buffer));
1177*5e7646d2SAndroid Build Coastguard Worker }
1178*5e7646d2SAndroid Build Coastguard Worker
1179*5e7646d2SAndroid Build Coastguard Worker
1180*5e7646d2SAndroid Build Coastguard Worker /*
1181*5e7646d2SAndroid Build Coastguard Worker * 'ippAddStrings()' - Add language-encoded strings to an IPP message.
1182*5e7646d2SAndroid Build Coastguard Worker *
1183*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
1184*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
1185*5e7646d2SAndroid Build Coastguard Worker *
1186*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
1187*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
1188*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
1189*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
1190*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
1191*5e7646d2SAndroid Build Coastguard Worker *
1192*5e7646d2SAndroid Build Coastguard Worker * Supported string values include charset (@code IPP_TAG_CHARSET@), keyword
1193*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_KEYWORD@), language (@code IPP_TAG_LANGUAGE@), mimeMediaType
1194*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_MIMETYPE@), name (@code IPP_TAG_NAME@), nameWithLanguage
1195*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_NAMELANG), text (@code IPP_TAG_TEXT@), textWithLanguage
1196*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_TEXTLANG@), uri (@code IPP_TAG_URI@), and uriScheme
1197*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_URISCHEME@).
1198*5e7646d2SAndroid Build Coastguard Worker *
1199*5e7646d2SAndroid Build Coastguard Worker * The @code language@ parameter must be non-@code NULL@ for nameWithLanguage and
1200*5e7646d2SAndroid Build Coastguard Worker * textWithLanguage string values and must be @code NULL@ for all other string values.
1201*5e7646d2SAndroid Build Coastguard Worker */
1202*5e7646d2SAndroid Build Coastguard Worker
1203*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippAddStrings(ipp_t * ipp,ipp_tag_t group,ipp_tag_t value_tag,const char * name,int num_values,const char * language,const char * const * values)1204*5e7646d2SAndroid Build Coastguard Worker ippAddStrings(
1205*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
1206*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group, /* I - IPP group */
1207*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag, /* I - Type of attribute */
1208*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
1209*5e7646d2SAndroid Build Coastguard Worker int num_values, /* I - Number of values */
1210*5e7646d2SAndroid Build Coastguard Worker const char *language, /* I - Language code (@code NULL@ for default) */
1211*5e7646d2SAndroid Build Coastguard Worker const char * const *values) /* I - Values */
1212*5e7646d2SAndroid Build Coastguard Worker {
1213*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
1214*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t temp_tag; /* Temporary value tag (masked) */
1215*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
1216*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
1217*5e7646d2SAndroid Build Coastguard Worker char code[32]; /* Language/charset value buffer */
1218*5e7646d2SAndroid Build Coastguard Worker
1219*5e7646d2SAndroid Build Coastguard Worker
1220*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippAddStrings(ipp=%p, group=%02x(%s), value_tag=%02x(%s), name=\"%s\", num_values=%d, language=\"%s\", values=%p)", (void *)ipp, group, ippTagString(group), value_tag, ippTagString(value_tag), name, num_values, language, (void *)values));
1221*5e7646d2SAndroid Build Coastguard Worker
1222*5e7646d2SAndroid Build Coastguard Worker /*
1223*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1224*5e7646d2SAndroid Build Coastguard Worker */
1225*5e7646d2SAndroid Build Coastguard Worker
1226*5e7646d2SAndroid Build Coastguard Worker temp_tag = (ipp_tag_t)((int)value_tag & IPP_TAG_CUPS_MASK);
1227*5e7646d2SAndroid Build Coastguard Worker
1228*5e7646d2SAndroid Build Coastguard Worker #if 0
1229*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
1230*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
1231*5e7646d2SAndroid Build Coastguard Worker (temp_tag < IPP_TAG_TEXT && temp_tag != IPP_TAG_TEXTLANG &&
1232*5e7646d2SAndroid Build Coastguard Worker temp_tag != IPP_TAG_NAMELANG) || temp_tag > IPP_TAG_MIMETYPE ||
1233*5e7646d2SAndroid Build Coastguard Worker num_values < 1)
1234*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1235*5e7646d2SAndroid Build Coastguard Worker
1236*5e7646d2SAndroid Build Coastguard Worker if ((temp_tag == IPP_TAG_TEXTLANG || temp_tag == IPP_TAG_NAMELANG)
1237*5e7646d2SAndroid Build Coastguard Worker != (language != NULL))
1238*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1239*5e7646d2SAndroid Build Coastguard Worker #else
1240*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name || group < IPP_TAG_ZERO ||
1241*5e7646d2SAndroid Build Coastguard Worker group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
1242*5e7646d2SAndroid Build Coastguard Worker num_values < 1)
1243*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1244*5e7646d2SAndroid Build Coastguard Worker #endif /* 0 */
1245*5e7646d2SAndroid Build Coastguard Worker
1246*5e7646d2SAndroid Build Coastguard Worker /*
1247*5e7646d2SAndroid Build Coastguard Worker * See if we need to map charset, language, or locale values...
1248*5e7646d2SAndroid Build Coastguard Worker */
1249*5e7646d2SAndroid Build Coastguard Worker
1250*5e7646d2SAndroid Build Coastguard Worker if (language && ((int)value_tag & IPP_TAG_CUPS_CONST) &&
1251*5e7646d2SAndroid Build Coastguard Worker strcmp(language, ipp_lang_code(language, code, sizeof(code))))
1252*5e7646d2SAndroid Build Coastguard Worker value_tag = temp_tag; /* Don't do a fast copy */
1253*5e7646d2SAndroid Build Coastguard Worker else if (values && value_tag == (ipp_tag_t)(IPP_TAG_CHARSET | IPP_TAG_CUPS_CONST))
1254*5e7646d2SAndroid Build Coastguard Worker {
1255*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_values; i ++)
1256*5e7646d2SAndroid Build Coastguard Worker if (strcmp(values[i], ipp_get_code(values[i], code, sizeof(code))))
1257*5e7646d2SAndroid Build Coastguard Worker {
1258*5e7646d2SAndroid Build Coastguard Worker value_tag = temp_tag; /* Don't do a fast copy */
1259*5e7646d2SAndroid Build Coastguard Worker break;
1260*5e7646d2SAndroid Build Coastguard Worker }
1261*5e7646d2SAndroid Build Coastguard Worker }
1262*5e7646d2SAndroid Build Coastguard Worker else if (values && value_tag == (ipp_tag_t)(IPP_TAG_LANGUAGE | IPP_TAG_CUPS_CONST))
1263*5e7646d2SAndroid Build Coastguard Worker {
1264*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_values; i ++)
1265*5e7646d2SAndroid Build Coastguard Worker if (strcmp(values[i], ipp_lang_code(values[i], code, sizeof(code))))
1266*5e7646d2SAndroid Build Coastguard Worker {
1267*5e7646d2SAndroid Build Coastguard Worker value_tag = temp_tag; /* Don't do a fast copy */
1268*5e7646d2SAndroid Build Coastguard Worker break;
1269*5e7646d2SAndroid Build Coastguard Worker }
1270*5e7646d2SAndroid Build Coastguard Worker }
1271*5e7646d2SAndroid Build Coastguard Worker
1272*5e7646d2SAndroid Build Coastguard Worker /*
1273*5e7646d2SAndroid Build Coastguard Worker * Create the attribute...
1274*5e7646d2SAndroid Build Coastguard Worker */
1275*5e7646d2SAndroid Build Coastguard Worker
1276*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp_add_attr(ipp, name, group, value_tag, num_values)) == NULL)
1277*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1278*5e7646d2SAndroid Build Coastguard Worker
1279*5e7646d2SAndroid Build Coastguard Worker /*
1280*5e7646d2SAndroid Build Coastguard Worker * Initialize the attribute data...
1281*5e7646d2SAndroid Build Coastguard Worker */
1282*5e7646d2SAndroid Build Coastguard Worker
1283*5e7646d2SAndroid Build Coastguard Worker for (i = num_values, value = attr->values;
1284*5e7646d2SAndroid Build Coastguard Worker i > 0;
1285*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
1286*5e7646d2SAndroid Build Coastguard Worker {
1287*5e7646d2SAndroid Build Coastguard Worker if (language)
1288*5e7646d2SAndroid Build Coastguard Worker {
1289*5e7646d2SAndroid Build Coastguard Worker if (value == attr->values)
1290*5e7646d2SAndroid Build Coastguard Worker {
1291*5e7646d2SAndroid Build Coastguard Worker if ((int)value_tag & IPP_TAG_CUPS_CONST)
1292*5e7646d2SAndroid Build Coastguard Worker value->string.language = (char *)language;
1293*5e7646d2SAndroid Build Coastguard Worker else
1294*5e7646d2SAndroid Build Coastguard Worker value->string.language = _cupsStrAlloc(ipp_lang_code(language, code,
1295*5e7646d2SAndroid Build Coastguard Worker sizeof(code)));
1296*5e7646d2SAndroid Build Coastguard Worker }
1297*5e7646d2SAndroid Build Coastguard Worker else
1298*5e7646d2SAndroid Build Coastguard Worker value->string.language = attr->values[0].string.language;
1299*5e7646d2SAndroid Build Coastguard Worker }
1300*5e7646d2SAndroid Build Coastguard Worker
1301*5e7646d2SAndroid Build Coastguard Worker if (values)
1302*5e7646d2SAndroid Build Coastguard Worker {
1303*5e7646d2SAndroid Build Coastguard Worker if ((int)value_tag & IPP_TAG_CUPS_CONST)
1304*5e7646d2SAndroid Build Coastguard Worker value->string.text = (char *)*values++;
1305*5e7646d2SAndroid Build Coastguard Worker else if (value_tag == IPP_TAG_CHARSET)
1306*5e7646d2SAndroid Build Coastguard Worker value->string.text = _cupsStrAlloc(ipp_get_code(*values++, code, sizeof(code)));
1307*5e7646d2SAndroid Build Coastguard Worker else if (value_tag == IPP_TAG_LANGUAGE)
1308*5e7646d2SAndroid Build Coastguard Worker value->string.text = _cupsStrAlloc(ipp_lang_code(*values++, code, sizeof(code)));
1309*5e7646d2SAndroid Build Coastguard Worker else
1310*5e7646d2SAndroid Build Coastguard Worker value->string.text = _cupsStrAlloc(*values++);
1311*5e7646d2SAndroid Build Coastguard Worker }
1312*5e7646d2SAndroid Build Coastguard Worker }
1313*5e7646d2SAndroid Build Coastguard Worker
1314*5e7646d2SAndroid Build Coastguard Worker return (attr);
1315*5e7646d2SAndroid Build Coastguard Worker }
1316*5e7646d2SAndroid Build Coastguard Worker
1317*5e7646d2SAndroid Build Coastguard Worker
1318*5e7646d2SAndroid Build Coastguard Worker /*
1319*5e7646d2SAndroid Build Coastguard Worker * 'ippContainsInteger()' - Determine whether an attribute contains the
1320*5e7646d2SAndroid Build Coastguard Worker * specified value or is within the list of ranges.
1321*5e7646d2SAndroid Build Coastguard Worker *
1322*5e7646d2SAndroid Build Coastguard Worker * Returns non-zero when the attribute contains either a matching integer or
1323*5e7646d2SAndroid Build Coastguard Worker * enum value, or the value falls within one of the rangeOfInteger values for
1324*5e7646d2SAndroid Build Coastguard Worker * the attribute.
1325*5e7646d2SAndroid Build Coastguard Worker *
1326*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
1327*5e7646d2SAndroid Build Coastguard Worker */
1328*5e7646d2SAndroid Build Coastguard Worker
1329*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on a match, 0 on no match */
ippContainsInteger(ipp_attribute_t * attr,int value)1330*5e7646d2SAndroid Build Coastguard Worker ippContainsInteger(
1331*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - Attribute */
1332*5e7646d2SAndroid Build Coastguard Worker int value) /* I - Integer/enum value */
1333*5e7646d2SAndroid Build Coastguard Worker {
1334*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
1335*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *avalue; /* Current attribute value */
1336*5e7646d2SAndroid Build Coastguard Worker
1337*5e7646d2SAndroid Build Coastguard Worker
1338*5e7646d2SAndroid Build Coastguard Worker /*
1339*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1340*5e7646d2SAndroid Build Coastguard Worker */
1341*5e7646d2SAndroid Build Coastguard Worker
1342*5e7646d2SAndroid Build Coastguard Worker if (!attr)
1343*5e7646d2SAndroid Build Coastguard Worker return (0);
1344*5e7646d2SAndroid Build Coastguard Worker
1345*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag != IPP_TAG_INTEGER && attr->value_tag != IPP_TAG_ENUM &&
1346*5e7646d2SAndroid Build Coastguard Worker attr->value_tag != IPP_TAG_RANGE)
1347*5e7646d2SAndroid Build Coastguard Worker return (0);
1348*5e7646d2SAndroid Build Coastguard Worker
1349*5e7646d2SAndroid Build Coastguard Worker /*
1350*5e7646d2SAndroid Build Coastguard Worker * Compare...
1351*5e7646d2SAndroid Build Coastguard Worker */
1352*5e7646d2SAndroid Build Coastguard Worker
1353*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag == IPP_TAG_RANGE)
1354*5e7646d2SAndroid Build Coastguard Worker {
1355*5e7646d2SAndroid Build Coastguard Worker for (i = attr->num_values, avalue = attr->values; i > 0; i --, avalue ++)
1356*5e7646d2SAndroid Build Coastguard Worker if (value >= avalue->range.lower && value <= avalue->range.upper)
1357*5e7646d2SAndroid Build Coastguard Worker return (1);
1358*5e7646d2SAndroid Build Coastguard Worker }
1359*5e7646d2SAndroid Build Coastguard Worker else
1360*5e7646d2SAndroid Build Coastguard Worker {
1361*5e7646d2SAndroid Build Coastguard Worker for (i = attr->num_values, avalue = attr->values; i > 0; i --, avalue ++)
1362*5e7646d2SAndroid Build Coastguard Worker if (value == avalue->integer)
1363*5e7646d2SAndroid Build Coastguard Worker return (1);
1364*5e7646d2SAndroid Build Coastguard Worker }
1365*5e7646d2SAndroid Build Coastguard Worker
1366*5e7646d2SAndroid Build Coastguard Worker return (0);
1367*5e7646d2SAndroid Build Coastguard Worker }
1368*5e7646d2SAndroid Build Coastguard Worker
1369*5e7646d2SAndroid Build Coastguard Worker
1370*5e7646d2SAndroid Build Coastguard Worker /*
1371*5e7646d2SAndroid Build Coastguard Worker * 'ippContainsString()' - Determine whether an attribute contains the
1372*5e7646d2SAndroid Build Coastguard Worker * specified string value.
1373*5e7646d2SAndroid Build Coastguard Worker *
1374*5e7646d2SAndroid Build Coastguard Worker * Returns non-zero when the attribute contains a matching charset, keyword,
1375*5e7646d2SAndroid Build Coastguard Worker * naturalLanguage, mimeMediaType, name, text, uri, or uriScheme value.
1376*5e7646d2SAndroid Build Coastguard Worker *
1377*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
1378*5e7646d2SAndroid Build Coastguard Worker */
1379*5e7646d2SAndroid Build Coastguard Worker
1380*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on a match, 0 on no match */
ippContainsString(ipp_attribute_t * attr,const char * value)1381*5e7646d2SAndroid Build Coastguard Worker ippContainsString(
1382*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - Attribute */
1383*5e7646d2SAndroid Build Coastguard Worker const char *value) /* I - String value */
1384*5e7646d2SAndroid Build Coastguard Worker {
1385*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
1386*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *avalue; /* Current attribute value */
1387*5e7646d2SAndroid Build Coastguard Worker
1388*5e7646d2SAndroid Build Coastguard Worker
1389*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippContainsString(attr=%p, value=\"%s\")", (void *)attr, value));
1390*5e7646d2SAndroid Build Coastguard Worker
1391*5e7646d2SAndroid Build Coastguard Worker /*
1392*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1393*5e7646d2SAndroid Build Coastguard Worker */
1394*5e7646d2SAndroid Build Coastguard Worker
1395*5e7646d2SAndroid Build Coastguard Worker if (!attr || !value)
1396*5e7646d2SAndroid Build Coastguard Worker {
1397*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippContainsString: Returning 0 (bad input)");
1398*5e7646d2SAndroid Build Coastguard Worker return (0);
1399*5e7646d2SAndroid Build Coastguard Worker }
1400*5e7646d2SAndroid Build Coastguard Worker
1401*5e7646d2SAndroid Build Coastguard Worker /*
1402*5e7646d2SAndroid Build Coastguard Worker * Compare...
1403*5e7646d2SAndroid Build Coastguard Worker */
1404*5e7646d2SAndroid Build Coastguard Worker
1405*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippContainsString: attr %s, %s with %d values.",
1406*5e7646d2SAndroid Build Coastguard Worker attr->name, ippTagString(attr->value_tag),
1407*5e7646d2SAndroid Build Coastguard Worker attr->num_values));
1408*5e7646d2SAndroid Build Coastguard Worker
1409*5e7646d2SAndroid Build Coastguard Worker switch (attr->value_tag & IPP_TAG_CUPS_MASK)
1410*5e7646d2SAndroid Build Coastguard Worker {
1411*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
1412*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
1413*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
1414*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
1415*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
1416*5e7646d2SAndroid Build Coastguard Worker for (i = attr->num_values, avalue = attr->values;
1417*5e7646d2SAndroid Build Coastguard Worker i > 0;
1418*5e7646d2SAndroid Build Coastguard Worker i --, avalue ++)
1419*5e7646d2SAndroid Build Coastguard Worker {
1420*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippContainsString: value[%d]=\"%s\"",
1421*5e7646d2SAndroid Build Coastguard Worker attr->num_values - i, avalue->string.text));
1422*5e7646d2SAndroid Build Coastguard Worker
1423*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(value, avalue->string.text))
1424*5e7646d2SAndroid Build Coastguard Worker {
1425*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippContainsString: Returning 1 (match)");
1426*5e7646d2SAndroid Build Coastguard Worker return (1);
1427*5e7646d2SAndroid Build Coastguard Worker }
1428*5e7646d2SAndroid Build Coastguard Worker }
1429*5e7646d2SAndroid Build Coastguard Worker
1430*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
1431*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
1432*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
1433*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
1434*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
1435*5e7646d2SAndroid Build Coastguard Worker for (i = attr->num_values, avalue = attr->values;
1436*5e7646d2SAndroid Build Coastguard Worker i > 0;
1437*5e7646d2SAndroid Build Coastguard Worker i --, avalue ++)
1438*5e7646d2SAndroid Build Coastguard Worker {
1439*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippContainsString: value[%d]=\"%s\"",
1440*5e7646d2SAndroid Build Coastguard Worker attr->num_values - i, avalue->string.text));
1441*5e7646d2SAndroid Build Coastguard Worker
1442*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(value, avalue->string.text))
1443*5e7646d2SAndroid Build Coastguard Worker {
1444*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippContainsString: Returning 1 (match)");
1445*5e7646d2SAndroid Build Coastguard Worker return (1);
1446*5e7646d2SAndroid Build Coastguard Worker }
1447*5e7646d2SAndroid Build Coastguard Worker }
1448*5e7646d2SAndroid Build Coastguard Worker
1449*5e7646d2SAndroid Build Coastguard Worker default :
1450*5e7646d2SAndroid Build Coastguard Worker break;
1451*5e7646d2SAndroid Build Coastguard Worker }
1452*5e7646d2SAndroid Build Coastguard Worker
1453*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippContainsString: Returning 0 (no match)");
1454*5e7646d2SAndroid Build Coastguard Worker
1455*5e7646d2SAndroid Build Coastguard Worker return (0);
1456*5e7646d2SAndroid Build Coastguard Worker }
1457*5e7646d2SAndroid Build Coastguard Worker
1458*5e7646d2SAndroid Build Coastguard Worker
1459*5e7646d2SAndroid Build Coastguard Worker /*
1460*5e7646d2SAndroid Build Coastguard Worker * 'ippCopyAttribute()' - Copy an attribute.
1461*5e7646d2SAndroid Build Coastguard Worker *
1462*5e7646d2SAndroid Build Coastguard Worker * The specified attribute, @code attr@, is copied to the destination IPP message.
1463*5e7646d2SAndroid Build Coastguard Worker * When @code quickcopy@ is non-zero, a "shallow" reference copy of the attribute is
1464*5e7646d2SAndroid Build Coastguard Worker * created - this should only be done as long as the original source IPP message will
1465*5e7646d2SAndroid Build Coastguard Worker * not be freed for the life of the destination.
1466*5e7646d2SAndroid Build Coastguard Worker *
1467*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
1468*5e7646d2SAndroid Build Coastguard Worker */
1469*5e7646d2SAndroid Build Coastguard Worker
1470*5e7646d2SAndroid Build Coastguard Worker
1471*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - New attribute */
ippCopyAttribute(ipp_t * dst,ipp_attribute_t * srcattr,int quickcopy)1472*5e7646d2SAndroid Build Coastguard Worker ippCopyAttribute(
1473*5e7646d2SAndroid Build Coastguard Worker ipp_t *dst, /* I - Destination IPP message */
1474*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *srcattr, /* I - Attribute to copy */
1475*5e7646d2SAndroid Build Coastguard Worker int quickcopy) /* I - 1 for a referenced copy, 0 for normal */
1476*5e7646d2SAndroid Build Coastguard Worker {
1477*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
1478*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t srctag; /* Source value tag */
1479*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *dstattr; /* Destination attribute */
1480*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *srcval, /* Source value */
1481*5e7646d2SAndroid Build Coastguard Worker *dstval; /* Destination value */
1482*5e7646d2SAndroid Build Coastguard Worker
1483*5e7646d2SAndroid Build Coastguard Worker
1484*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippCopyAttribute(dst=%p, srcattr=%p, quickcopy=%d)", (void *)dst, (void *)srcattr, quickcopy));
1485*5e7646d2SAndroid Build Coastguard Worker
1486*5e7646d2SAndroid Build Coastguard Worker /*
1487*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1488*5e7646d2SAndroid Build Coastguard Worker */
1489*5e7646d2SAndroid Build Coastguard Worker
1490*5e7646d2SAndroid Build Coastguard Worker if (!dst || !srcattr)
1491*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1492*5e7646d2SAndroid Build Coastguard Worker
1493*5e7646d2SAndroid Build Coastguard Worker /*
1494*5e7646d2SAndroid Build Coastguard Worker * Copy it...
1495*5e7646d2SAndroid Build Coastguard Worker */
1496*5e7646d2SAndroid Build Coastguard Worker
1497*5e7646d2SAndroid Build Coastguard Worker quickcopy = (quickcopy && (srcattr->value_tag & IPP_TAG_CUPS_CONST)) ? IPP_TAG_CUPS_CONST : 0;
1498*5e7646d2SAndroid Build Coastguard Worker srctag = srcattr->value_tag & IPP_TAG_CUPS_MASK;
1499*5e7646d2SAndroid Build Coastguard Worker
1500*5e7646d2SAndroid Build Coastguard Worker switch (srctag)
1501*5e7646d2SAndroid Build Coastguard Worker {
1502*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ZERO :
1503*5e7646d2SAndroid Build Coastguard Worker dstattr = ippAddSeparator(dst);
1504*5e7646d2SAndroid Build Coastguard Worker break;
1505*5e7646d2SAndroid Build Coastguard Worker
1506*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNSUPPORTED_VALUE :
1507*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DEFAULT :
1508*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNKNOWN :
1509*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOVALUE :
1510*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOTSETTABLE :
1511*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DELETEATTR :
1512*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ADMINDEFINE :
1513*5e7646d2SAndroid Build Coastguard Worker dstattr = ippAddOutOfBand(dst, srcattr->group_tag, srctag, srcattr->name);
1514*5e7646d2SAndroid Build Coastguard Worker break;
1515*5e7646d2SAndroid Build Coastguard Worker
1516*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
1517*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
1518*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
1519*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DATE :
1520*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
1521*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
1522*5e7646d2SAndroid Build Coastguard Worker if ((dstattr = ipp_add_attr(dst, srcattr->name, srcattr->group_tag, srctag, srcattr->num_values)) != NULL)
1523*5e7646d2SAndroid Build Coastguard Worker memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t));
1524*5e7646d2SAndroid Build Coastguard Worker break;
1525*5e7646d2SAndroid Build Coastguard Worker
1526*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
1527*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
1528*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESERVED_STRING :
1529*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
1530*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
1531*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
1532*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
1533*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
1534*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
1535*5e7646d2SAndroid Build Coastguard Worker if ((dstattr = ippAddStrings(dst, srcattr->group_tag, (ipp_tag_t)(srctag | quickcopy), srcattr->name, srcattr->num_values, NULL, NULL)) == NULL)
1536*5e7646d2SAndroid Build Coastguard Worker break;
1537*5e7646d2SAndroid Build Coastguard Worker
1538*5e7646d2SAndroid Build Coastguard Worker if (quickcopy)
1539*5e7646d2SAndroid Build Coastguard Worker {
1540*5e7646d2SAndroid Build Coastguard Worker /*
1541*5e7646d2SAndroid Build Coastguard Worker * Can safely quick-copy these string values...
1542*5e7646d2SAndroid Build Coastguard Worker */
1543*5e7646d2SAndroid Build Coastguard Worker
1544*5e7646d2SAndroid Build Coastguard Worker memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t));
1545*5e7646d2SAndroid Build Coastguard Worker }
1546*5e7646d2SAndroid Build Coastguard Worker else
1547*5e7646d2SAndroid Build Coastguard Worker {
1548*5e7646d2SAndroid Build Coastguard Worker /*
1549*5e7646d2SAndroid Build Coastguard Worker * Otherwise do a normal reference counted copy...
1550*5e7646d2SAndroid Build Coastguard Worker */
1551*5e7646d2SAndroid Build Coastguard Worker
1552*5e7646d2SAndroid Build Coastguard Worker for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++)
1553*5e7646d2SAndroid Build Coastguard Worker dstval->string.text = _cupsStrAlloc(srcval->string.text);
1554*5e7646d2SAndroid Build Coastguard Worker }
1555*5e7646d2SAndroid Build Coastguard Worker break;
1556*5e7646d2SAndroid Build Coastguard Worker
1557*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
1558*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
1559*5e7646d2SAndroid Build Coastguard Worker if ((dstattr = ippAddStrings(dst, srcattr->group_tag, (ipp_tag_t)(srctag | quickcopy), srcattr->name, srcattr->num_values, NULL, NULL)) == NULL)
1560*5e7646d2SAndroid Build Coastguard Worker break;
1561*5e7646d2SAndroid Build Coastguard Worker
1562*5e7646d2SAndroid Build Coastguard Worker if (quickcopy)
1563*5e7646d2SAndroid Build Coastguard Worker {
1564*5e7646d2SAndroid Build Coastguard Worker /*
1565*5e7646d2SAndroid Build Coastguard Worker * Can safely quick-copy these string values...
1566*5e7646d2SAndroid Build Coastguard Worker */
1567*5e7646d2SAndroid Build Coastguard Worker
1568*5e7646d2SAndroid Build Coastguard Worker memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t));
1569*5e7646d2SAndroid Build Coastguard Worker }
1570*5e7646d2SAndroid Build Coastguard Worker else if (srcattr->value_tag & IPP_TAG_CUPS_CONST)
1571*5e7646d2SAndroid Build Coastguard Worker {
1572*5e7646d2SAndroid Build Coastguard Worker /*
1573*5e7646d2SAndroid Build Coastguard Worker * Otherwise do a normal reference counted copy...
1574*5e7646d2SAndroid Build Coastguard Worker */
1575*5e7646d2SAndroid Build Coastguard Worker
1576*5e7646d2SAndroid Build Coastguard Worker for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++)
1577*5e7646d2SAndroid Build Coastguard Worker {
1578*5e7646d2SAndroid Build Coastguard Worker if (srcval == srcattr->values)
1579*5e7646d2SAndroid Build Coastguard Worker dstval->string.language = _cupsStrAlloc(srcval->string.language);
1580*5e7646d2SAndroid Build Coastguard Worker else
1581*5e7646d2SAndroid Build Coastguard Worker dstval->string.language = dstattr->values[0].string.language;
1582*5e7646d2SAndroid Build Coastguard Worker
1583*5e7646d2SAndroid Build Coastguard Worker dstval->string.text = _cupsStrAlloc(srcval->string.text);
1584*5e7646d2SAndroid Build Coastguard Worker }
1585*5e7646d2SAndroid Build Coastguard Worker }
1586*5e7646d2SAndroid Build Coastguard Worker break;
1587*5e7646d2SAndroid Build Coastguard Worker
1588*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
1589*5e7646d2SAndroid Build Coastguard Worker if ((dstattr = ippAddCollections(dst, srcattr->group_tag, srcattr->name, srcattr->num_values, NULL)) == NULL)
1590*5e7646d2SAndroid Build Coastguard Worker break;
1591*5e7646d2SAndroid Build Coastguard Worker
1592*5e7646d2SAndroid Build Coastguard Worker for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++)
1593*5e7646d2SAndroid Build Coastguard Worker {
1594*5e7646d2SAndroid Build Coastguard Worker dstval->collection = srcval->collection;
1595*5e7646d2SAndroid Build Coastguard Worker srcval->collection->use ++;
1596*5e7646d2SAndroid Build Coastguard Worker }
1597*5e7646d2SAndroid Build Coastguard Worker break;
1598*5e7646d2SAndroid Build Coastguard Worker
1599*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
1600*5e7646d2SAndroid Build Coastguard Worker default :
1601*5e7646d2SAndroid Build Coastguard Worker if ((dstattr = ipp_add_attr(dst, srcattr->name, srcattr->group_tag, srctag, srcattr->num_values)) == NULL)
1602*5e7646d2SAndroid Build Coastguard Worker break;
1603*5e7646d2SAndroid Build Coastguard Worker
1604*5e7646d2SAndroid Build Coastguard Worker for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++)
1605*5e7646d2SAndroid Build Coastguard Worker {
1606*5e7646d2SAndroid Build Coastguard Worker dstval->unknown.length = srcval->unknown.length;
1607*5e7646d2SAndroid Build Coastguard Worker
1608*5e7646d2SAndroid Build Coastguard Worker if (dstval->unknown.length > 0)
1609*5e7646d2SAndroid Build Coastguard Worker {
1610*5e7646d2SAndroid Build Coastguard Worker if ((dstval->unknown.data = malloc((size_t)dstval->unknown.length)) == NULL)
1611*5e7646d2SAndroid Build Coastguard Worker dstval->unknown.length = 0;
1612*5e7646d2SAndroid Build Coastguard Worker else
1613*5e7646d2SAndroid Build Coastguard Worker memcpy(dstval->unknown.data, srcval->unknown.data, (size_t)dstval->unknown.length);
1614*5e7646d2SAndroid Build Coastguard Worker }
1615*5e7646d2SAndroid Build Coastguard Worker }
1616*5e7646d2SAndroid Build Coastguard Worker break; /* anti-compiler-warning-code */
1617*5e7646d2SAndroid Build Coastguard Worker }
1618*5e7646d2SAndroid Build Coastguard Worker
1619*5e7646d2SAndroid Build Coastguard Worker return (dstattr);
1620*5e7646d2SAndroid Build Coastguard Worker }
1621*5e7646d2SAndroid Build Coastguard Worker
1622*5e7646d2SAndroid Build Coastguard Worker
1623*5e7646d2SAndroid Build Coastguard Worker /*
1624*5e7646d2SAndroid Build Coastguard Worker * 'ippCopyAttributes()' - Copy attributes from one IPP message to another.
1625*5e7646d2SAndroid Build Coastguard Worker *
1626*5e7646d2SAndroid Build Coastguard Worker * Zero or more attributes are copied from the source IPP message, @code src@, to the
1627*5e7646d2SAndroid Build Coastguard Worker * destination IPP message, @code dst@. When @code quickcopy@ is non-zero, a "shallow"
1628*5e7646d2SAndroid Build Coastguard Worker * reference copy of the attribute is created - this should only be done as long as the
1629*5e7646d2SAndroid Build Coastguard Worker * original source IPP message will not be freed for the life of the destination.
1630*5e7646d2SAndroid Build Coastguard Worker *
1631*5e7646d2SAndroid Build Coastguard Worker * The @code cb@ and @code context@ parameters provide a generic way to "filter" the
1632*5e7646d2SAndroid Build Coastguard Worker * attributes that are copied - the function must return 1 to copy the attribute or
1633*5e7646d2SAndroid Build Coastguard Worker * 0 to skip it. The function may also choose to do a partial copy of the source attribute
1634*5e7646d2SAndroid Build Coastguard Worker * itself.
1635*5e7646d2SAndroid Build Coastguard Worker *
1636*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
1637*5e7646d2SAndroid Build Coastguard Worker */
1638*5e7646d2SAndroid Build Coastguard Worker
1639*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on error */
ippCopyAttributes(ipp_t * dst,ipp_t * src,int quickcopy,ipp_copycb_t cb,void * context)1640*5e7646d2SAndroid Build Coastguard Worker ippCopyAttributes(
1641*5e7646d2SAndroid Build Coastguard Worker ipp_t *dst, /* I - Destination IPP message */
1642*5e7646d2SAndroid Build Coastguard Worker ipp_t *src, /* I - Source IPP message */
1643*5e7646d2SAndroid Build Coastguard Worker int quickcopy, /* I - 1 for a referenced copy, 0 for normal */
1644*5e7646d2SAndroid Build Coastguard Worker ipp_copycb_t cb, /* I - Copy callback or @code NULL@ for none */
1645*5e7646d2SAndroid Build Coastguard Worker void *context) /* I - Context pointer */
1646*5e7646d2SAndroid Build Coastguard Worker {
1647*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *srcattr; /* Source attribute */
1648*5e7646d2SAndroid Build Coastguard Worker
1649*5e7646d2SAndroid Build Coastguard Worker
1650*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippCopyAttributes(dst=%p, src=%p, quickcopy=%d, cb=%p, context=%p)", (void *)dst, (void *)src, quickcopy, (void *)cb, context));
1651*5e7646d2SAndroid Build Coastguard Worker
1652*5e7646d2SAndroid Build Coastguard Worker /*
1653*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1654*5e7646d2SAndroid Build Coastguard Worker */
1655*5e7646d2SAndroid Build Coastguard Worker
1656*5e7646d2SAndroid Build Coastguard Worker if (!dst || !src)
1657*5e7646d2SAndroid Build Coastguard Worker return (0);
1658*5e7646d2SAndroid Build Coastguard Worker
1659*5e7646d2SAndroid Build Coastguard Worker /*
1660*5e7646d2SAndroid Build Coastguard Worker * Loop through source attributes and copy as needed...
1661*5e7646d2SAndroid Build Coastguard Worker */
1662*5e7646d2SAndroid Build Coastguard Worker
1663*5e7646d2SAndroid Build Coastguard Worker for (srcattr = src->attrs; srcattr; srcattr = srcattr->next)
1664*5e7646d2SAndroid Build Coastguard Worker if (!cb || (*cb)(context, dst, srcattr))
1665*5e7646d2SAndroid Build Coastguard Worker if (!ippCopyAttribute(dst, srcattr, quickcopy))
1666*5e7646d2SAndroid Build Coastguard Worker return (0);
1667*5e7646d2SAndroid Build Coastguard Worker
1668*5e7646d2SAndroid Build Coastguard Worker return (1);
1669*5e7646d2SAndroid Build Coastguard Worker }
1670*5e7646d2SAndroid Build Coastguard Worker
1671*5e7646d2SAndroid Build Coastguard Worker
1672*5e7646d2SAndroid Build Coastguard Worker /*
1673*5e7646d2SAndroid Build Coastguard Worker * 'ippDateToTime()' - Convert from RFC 2579 Date/Time format to time in
1674*5e7646d2SAndroid Build Coastguard Worker * seconds.
1675*5e7646d2SAndroid Build Coastguard Worker */
1676*5e7646d2SAndroid Build Coastguard Worker
1677*5e7646d2SAndroid Build Coastguard Worker time_t /* O - UNIX time value */
ippDateToTime(const ipp_uchar_t * date)1678*5e7646d2SAndroid Build Coastguard Worker ippDateToTime(const ipp_uchar_t *date) /* I - RFC 2579 date info */
1679*5e7646d2SAndroid Build Coastguard Worker {
1680*5e7646d2SAndroid Build Coastguard Worker struct tm unixdate; /* UNIX date/time info */
1681*5e7646d2SAndroid Build Coastguard Worker time_t t; /* Computed time */
1682*5e7646d2SAndroid Build Coastguard Worker
1683*5e7646d2SAndroid Build Coastguard Worker
1684*5e7646d2SAndroid Build Coastguard Worker if (!date)
1685*5e7646d2SAndroid Build Coastguard Worker return (0);
1686*5e7646d2SAndroid Build Coastguard Worker
1687*5e7646d2SAndroid Build Coastguard Worker memset(&unixdate, 0, sizeof(unixdate));
1688*5e7646d2SAndroid Build Coastguard Worker
1689*5e7646d2SAndroid Build Coastguard Worker /*
1690*5e7646d2SAndroid Build Coastguard Worker * RFC-2579 date/time format is:
1691*5e7646d2SAndroid Build Coastguard Worker *
1692*5e7646d2SAndroid Build Coastguard Worker * Byte(s) Description
1693*5e7646d2SAndroid Build Coastguard Worker * ------- -----------
1694*5e7646d2SAndroid Build Coastguard Worker * 0-1 Year (0 to 65535)
1695*5e7646d2SAndroid Build Coastguard Worker * 2 Month (1 to 12)
1696*5e7646d2SAndroid Build Coastguard Worker * 3 Day (1 to 31)
1697*5e7646d2SAndroid Build Coastguard Worker * 4 Hours (0 to 23)
1698*5e7646d2SAndroid Build Coastguard Worker * 5 Minutes (0 to 59)
1699*5e7646d2SAndroid Build Coastguard Worker * 6 Seconds (0 to 60, 60 = "leap second")
1700*5e7646d2SAndroid Build Coastguard Worker * 7 Deciseconds (0 to 9)
1701*5e7646d2SAndroid Build Coastguard Worker * 8 +/- UTC
1702*5e7646d2SAndroid Build Coastguard Worker * 9 UTC hours (0 to 11)
1703*5e7646d2SAndroid Build Coastguard Worker * 10 UTC minutes (0 to 59)
1704*5e7646d2SAndroid Build Coastguard Worker */
1705*5e7646d2SAndroid Build Coastguard Worker
1706*5e7646d2SAndroid Build Coastguard Worker unixdate.tm_year = ((date[0] << 8) | date[1]) - 1900;
1707*5e7646d2SAndroid Build Coastguard Worker unixdate.tm_mon = date[2] - 1;
1708*5e7646d2SAndroid Build Coastguard Worker unixdate.tm_mday = date[3];
1709*5e7646d2SAndroid Build Coastguard Worker unixdate.tm_hour = date[4];
1710*5e7646d2SAndroid Build Coastguard Worker unixdate.tm_min = date[5];
1711*5e7646d2SAndroid Build Coastguard Worker unixdate.tm_sec = date[6];
1712*5e7646d2SAndroid Build Coastguard Worker
1713*5e7646d2SAndroid Build Coastguard Worker t = mktime(&unixdate);
1714*5e7646d2SAndroid Build Coastguard Worker
1715*5e7646d2SAndroid Build Coastguard Worker if (date[8] == '-')
1716*5e7646d2SAndroid Build Coastguard Worker t += date[9] * 3600 + date[10] * 60;
1717*5e7646d2SAndroid Build Coastguard Worker else
1718*5e7646d2SAndroid Build Coastguard Worker t -= date[9] * 3600 + date[10] * 60;
1719*5e7646d2SAndroid Build Coastguard Worker
1720*5e7646d2SAndroid Build Coastguard Worker return (t);
1721*5e7646d2SAndroid Build Coastguard Worker }
1722*5e7646d2SAndroid Build Coastguard Worker
1723*5e7646d2SAndroid Build Coastguard Worker
1724*5e7646d2SAndroid Build Coastguard Worker /*
1725*5e7646d2SAndroid Build Coastguard Worker * 'ippDelete()' - Delete an IPP message.
1726*5e7646d2SAndroid Build Coastguard Worker */
1727*5e7646d2SAndroid Build Coastguard Worker
1728*5e7646d2SAndroid Build Coastguard Worker void
ippDelete(ipp_t * ipp)1729*5e7646d2SAndroid Build Coastguard Worker ippDelete(ipp_t *ipp) /* I - IPP message */
1730*5e7646d2SAndroid Build Coastguard Worker {
1731*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* Current attribute */
1732*5e7646d2SAndroid Build Coastguard Worker *next; /* Next attribute */
1733*5e7646d2SAndroid Build Coastguard Worker
1734*5e7646d2SAndroid Build Coastguard Worker
1735*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippDelete(ipp=%p)", (void *)ipp));
1736*5e7646d2SAndroid Build Coastguard Worker
1737*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
1738*5e7646d2SAndroid Build Coastguard Worker return;
1739*5e7646d2SAndroid Build Coastguard Worker
1740*5e7646d2SAndroid Build Coastguard Worker ipp->use --;
1741*5e7646d2SAndroid Build Coastguard Worker if (ipp->use > 0)
1742*5e7646d2SAndroid Build Coastguard Worker {
1743*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4debug_retain: %p IPP message (use=%d)", (void *)ipp, ipp->use));
1744*5e7646d2SAndroid Build Coastguard Worker return;
1745*5e7646d2SAndroid Build Coastguard Worker }
1746*5e7646d2SAndroid Build Coastguard Worker
1747*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4debug_free: %p IPP message", (void *)ipp));
1748*5e7646d2SAndroid Build Coastguard Worker
1749*5e7646d2SAndroid Build Coastguard Worker for (attr = ipp->attrs; attr != NULL; attr = next)
1750*5e7646d2SAndroid Build Coastguard Worker {
1751*5e7646d2SAndroid Build Coastguard Worker next = attr->next;
1752*5e7646d2SAndroid Build Coastguard Worker
1753*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4debug_free: %p %s %s%s (%d values)", (void *)attr, attr->name, attr->num_values > 1 ? "1setOf " : "", ippTagString(attr->value_tag), attr->num_values));
1754*5e7646d2SAndroid Build Coastguard Worker
1755*5e7646d2SAndroid Build Coastguard Worker ipp_free_values(attr, 0, attr->num_values);
1756*5e7646d2SAndroid Build Coastguard Worker
1757*5e7646d2SAndroid Build Coastguard Worker if (attr->name)
1758*5e7646d2SAndroid Build Coastguard Worker _cupsStrFree(attr->name);
1759*5e7646d2SAndroid Build Coastguard Worker
1760*5e7646d2SAndroid Build Coastguard Worker free(attr);
1761*5e7646d2SAndroid Build Coastguard Worker }
1762*5e7646d2SAndroid Build Coastguard Worker
1763*5e7646d2SAndroid Build Coastguard Worker free(ipp);
1764*5e7646d2SAndroid Build Coastguard Worker }
1765*5e7646d2SAndroid Build Coastguard Worker
1766*5e7646d2SAndroid Build Coastguard Worker
1767*5e7646d2SAndroid Build Coastguard Worker /*
1768*5e7646d2SAndroid Build Coastguard Worker * 'ippDeleteAttribute()' - Delete a single attribute in an IPP message.
1769*5e7646d2SAndroid Build Coastguard Worker *
1770*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.1.19/macOS 10.3@
1771*5e7646d2SAndroid Build Coastguard Worker */
1772*5e7646d2SAndroid Build Coastguard Worker
1773*5e7646d2SAndroid Build Coastguard Worker void
ippDeleteAttribute(ipp_t * ipp,ipp_attribute_t * attr)1774*5e7646d2SAndroid Build Coastguard Worker ippDeleteAttribute(
1775*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
1776*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr) /* I - Attribute to delete */
1777*5e7646d2SAndroid Build Coastguard Worker {
1778*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *current, /* Current attribute */
1779*5e7646d2SAndroid Build Coastguard Worker *prev; /* Previous attribute */
1780*5e7646d2SAndroid Build Coastguard Worker
1781*5e7646d2SAndroid Build Coastguard Worker
1782*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippDeleteAttribute(ipp=%p, attr=%p(%s))", (void *)ipp, (void *)attr, attr ? attr->name : "(null)"));
1783*5e7646d2SAndroid Build Coastguard Worker
1784*5e7646d2SAndroid Build Coastguard Worker /*
1785*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1786*5e7646d2SAndroid Build Coastguard Worker */
1787*5e7646d2SAndroid Build Coastguard Worker
1788*5e7646d2SAndroid Build Coastguard Worker if (!attr)
1789*5e7646d2SAndroid Build Coastguard Worker return;
1790*5e7646d2SAndroid Build Coastguard Worker
1791*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4debug_free: %p %s %s%s (%d values)", (void *)attr, attr->name, attr->num_values > 1 ? "1setOf " : "", ippTagString(attr->value_tag), attr->num_values));
1792*5e7646d2SAndroid Build Coastguard Worker
1793*5e7646d2SAndroid Build Coastguard Worker /*
1794*5e7646d2SAndroid Build Coastguard Worker * Find the attribute in the list...
1795*5e7646d2SAndroid Build Coastguard Worker */
1796*5e7646d2SAndroid Build Coastguard Worker
1797*5e7646d2SAndroid Build Coastguard Worker if (ipp)
1798*5e7646d2SAndroid Build Coastguard Worker {
1799*5e7646d2SAndroid Build Coastguard Worker for (current = ipp->attrs, prev = NULL;
1800*5e7646d2SAndroid Build Coastguard Worker current;
1801*5e7646d2SAndroid Build Coastguard Worker prev = current, current = current->next)
1802*5e7646d2SAndroid Build Coastguard Worker if (current == attr)
1803*5e7646d2SAndroid Build Coastguard Worker {
1804*5e7646d2SAndroid Build Coastguard Worker /*
1805*5e7646d2SAndroid Build Coastguard Worker * Found it, remove the attribute from the list...
1806*5e7646d2SAndroid Build Coastguard Worker */
1807*5e7646d2SAndroid Build Coastguard Worker
1808*5e7646d2SAndroid Build Coastguard Worker if (prev)
1809*5e7646d2SAndroid Build Coastguard Worker prev->next = current->next;
1810*5e7646d2SAndroid Build Coastguard Worker else
1811*5e7646d2SAndroid Build Coastguard Worker ipp->attrs = current->next;
1812*5e7646d2SAndroid Build Coastguard Worker
1813*5e7646d2SAndroid Build Coastguard Worker if (current == ipp->last)
1814*5e7646d2SAndroid Build Coastguard Worker ipp->last = prev;
1815*5e7646d2SAndroid Build Coastguard Worker
1816*5e7646d2SAndroid Build Coastguard Worker break;
1817*5e7646d2SAndroid Build Coastguard Worker }
1818*5e7646d2SAndroid Build Coastguard Worker
1819*5e7646d2SAndroid Build Coastguard Worker if (!current)
1820*5e7646d2SAndroid Build Coastguard Worker return;
1821*5e7646d2SAndroid Build Coastguard Worker }
1822*5e7646d2SAndroid Build Coastguard Worker
1823*5e7646d2SAndroid Build Coastguard Worker /*
1824*5e7646d2SAndroid Build Coastguard Worker * Free memory used by the attribute...
1825*5e7646d2SAndroid Build Coastguard Worker */
1826*5e7646d2SAndroid Build Coastguard Worker
1827*5e7646d2SAndroid Build Coastguard Worker ipp_free_values(attr, 0, attr->num_values);
1828*5e7646d2SAndroid Build Coastguard Worker
1829*5e7646d2SAndroid Build Coastguard Worker if (attr->name)
1830*5e7646d2SAndroid Build Coastguard Worker _cupsStrFree(attr->name);
1831*5e7646d2SAndroid Build Coastguard Worker
1832*5e7646d2SAndroid Build Coastguard Worker free(attr);
1833*5e7646d2SAndroid Build Coastguard Worker }
1834*5e7646d2SAndroid Build Coastguard Worker
1835*5e7646d2SAndroid Build Coastguard Worker
1836*5e7646d2SAndroid Build Coastguard Worker /*
1837*5e7646d2SAndroid Build Coastguard Worker * 'ippDeleteValues()' - Delete values in an attribute.
1838*5e7646d2SAndroid Build Coastguard Worker *
1839*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies the first value to delete, starting at
1840*5e7646d2SAndroid Build Coastguard Worker * 0. It must be less than the number of values returned by @link ippGetCount@.
1841*5e7646d2SAndroid Build Coastguard Worker *
1842*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
1843*5e7646d2SAndroid Build Coastguard Worker *
1844*5e7646d2SAndroid Build Coastguard Worker * Deleting all values in an attribute deletes the attribute.
1845*5e7646d2SAndroid Build Coastguard Worker *
1846*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
1847*5e7646d2SAndroid Build Coastguard Worker */
1848*5e7646d2SAndroid Build Coastguard Worker
1849*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippDeleteValues(ipp_t * ipp,ipp_attribute_t ** attr,int element,int count)1850*5e7646d2SAndroid Build Coastguard Worker ippDeleteValues(
1851*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
1852*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - Attribute */
1853*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Index of first value to delete (0-based) */
1854*5e7646d2SAndroid Build Coastguard Worker int count) /* I - Number of values to delete */
1855*5e7646d2SAndroid Build Coastguard Worker {
1856*5e7646d2SAndroid Build Coastguard Worker /*
1857*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1858*5e7646d2SAndroid Build Coastguard Worker */
1859*5e7646d2SAndroid Build Coastguard Worker
1860*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr ||
1861*5e7646d2SAndroid Build Coastguard Worker element < 0 || element >= (*attr)->num_values || count <= 0 ||
1862*5e7646d2SAndroid Build Coastguard Worker (element + count) >= (*attr)->num_values)
1863*5e7646d2SAndroid Build Coastguard Worker return (0);
1864*5e7646d2SAndroid Build Coastguard Worker
1865*5e7646d2SAndroid Build Coastguard Worker /*
1866*5e7646d2SAndroid Build Coastguard Worker * If we are deleting all values, just delete the attribute entirely.
1867*5e7646d2SAndroid Build Coastguard Worker */
1868*5e7646d2SAndroid Build Coastguard Worker
1869*5e7646d2SAndroid Build Coastguard Worker if (count == (*attr)->num_values)
1870*5e7646d2SAndroid Build Coastguard Worker {
1871*5e7646d2SAndroid Build Coastguard Worker ippDeleteAttribute(ipp, *attr);
1872*5e7646d2SAndroid Build Coastguard Worker *attr = NULL;
1873*5e7646d2SAndroid Build Coastguard Worker return (1);
1874*5e7646d2SAndroid Build Coastguard Worker }
1875*5e7646d2SAndroid Build Coastguard Worker
1876*5e7646d2SAndroid Build Coastguard Worker /*
1877*5e7646d2SAndroid Build Coastguard Worker * Otherwise free the values in question and return.
1878*5e7646d2SAndroid Build Coastguard Worker */
1879*5e7646d2SAndroid Build Coastguard Worker
1880*5e7646d2SAndroid Build Coastguard Worker ipp_free_values(*attr, element, count);
1881*5e7646d2SAndroid Build Coastguard Worker
1882*5e7646d2SAndroid Build Coastguard Worker return (1);
1883*5e7646d2SAndroid Build Coastguard Worker }
1884*5e7646d2SAndroid Build Coastguard Worker
1885*5e7646d2SAndroid Build Coastguard Worker
1886*5e7646d2SAndroid Build Coastguard Worker /*
1887*5e7646d2SAndroid Build Coastguard Worker * 'ippFindAttribute()' - Find a named attribute in a request.
1888*5e7646d2SAndroid Build Coastguard Worker *
1889*5e7646d2SAndroid Build Coastguard Worker * Starting with CUPS 2.0, the attribute name can contain a hierarchical list
1890*5e7646d2SAndroid Build Coastguard Worker * of attribute and member names separated by slashes, for example
1891*5e7646d2SAndroid Build Coastguard Worker * "media-col/media-size".
1892*5e7646d2SAndroid Build Coastguard Worker */
1893*5e7646d2SAndroid Build Coastguard Worker
1894*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - Matching attribute */
ippFindAttribute(ipp_t * ipp,const char * name,ipp_tag_t type)1895*5e7646d2SAndroid Build Coastguard Worker ippFindAttribute(ipp_t *ipp, /* I - IPP message */
1896*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
1897*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t type) /* I - Type of attribute */
1898*5e7646d2SAndroid Build Coastguard Worker {
1899*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippFindAttribute(ipp=%p, name=\"%s\", type=%02x(%s))", (void *)ipp, name, type, ippTagString(type)));
1900*5e7646d2SAndroid Build Coastguard Worker
1901*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name)
1902*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1903*5e7646d2SAndroid Build Coastguard Worker
1904*5e7646d2SAndroid Build Coastguard Worker /*
1905*5e7646d2SAndroid Build Coastguard Worker * Reset the current pointer...
1906*5e7646d2SAndroid Build Coastguard Worker */
1907*5e7646d2SAndroid Build Coastguard Worker
1908*5e7646d2SAndroid Build Coastguard Worker ipp->current = NULL;
1909*5e7646d2SAndroid Build Coastguard Worker ipp->atend = 0;
1910*5e7646d2SAndroid Build Coastguard Worker
1911*5e7646d2SAndroid Build Coastguard Worker /*
1912*5e7646d2SAndroid Build Coastguard Worker * Search for the attribute...
1913*5e7646d2SAndroid Build Coastguard Worker */
1914*5e7646d2SAndroid Build Coastguard Worker
1915*5e7646d2SAndroid Build Coastguard Worker return (ippFindNextAttribute(ipp, name, type));
1916*5e7646d2SAndroid Build Coastguard Worker }
1917*5e7646d2SAndroid Build Coastguard Worker
1918*5e7646d2SAndroid Build Coastguard Worker
1919*5e7646d2SAndroid Build Coastguard Worker /*
1920*5e7646d2SAndroid Build Coastguard Worker * 'ippFindNextAttribute()' - Find the next named attribute in a request.
1921*5e7646d2SAndroid Build Coastguard Worker *
1922*5e7646d2SAndroid Build Coastguard Worker * Starting with CUPS 2.0, the attribute name can contain a hierarchical list
1923*5e7646d2SAndroid Build Coastguard Worker * of attribute and member names separated by slashes, for example
1924*5e7646d2SAndroid Build Coastguard Worker * "media-col/media-size".
1925*5e7646d2SAndroid Build Coastguard Worker */
1926*5e7646d2SAndroid Build Coastguard Worker
1927*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - Matching attribute */
ippFindNextAttribute(ipp_t * ipp,const char * name,ipp_tag_t type)1928*5e7646d2SAndroid Build Coastguard Worker ippFindNextAttribute(ipp_t *ipp, /* I - IPP message */
1929*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Name of attribute */
1930*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t type) /* I - Type of attribute */
1931*5e7646d2SAndroid Build Coastguard Worker {
1932*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* Current atttribute */
1933*5e7646d2SAndroid Build Coastguard Worker *childattr; /* Child attribute */
1934*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag; /* Value tag */
1935*5e7646d2SAndroid Build Coastguard Worker char parent[1024], /* Parent attribute name */
1936*5e7646d2SAndroid Build Coastguard Worker *child = NULL; /* Child attribute name */
1937*5e7646d2SAndroid Build Coastguard Worker
1938*5e7646d2SAndroid Build Coastguard Worker
1939*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippFindNextAttribute(ipp=%p, name=\"%s\", type=%02x(%s))", (void *)ipp, name, type, ippTagString(type)));
1940*5e7646d2SAndroid Build Coastguard Worker
1941*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !name)
1942*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1943*5e7646d2SAndroid Build Coastguard Worker
1944*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("3ippFindNextAttribute: atend=%d", ipp->atend));
1945*5e7646d2SAndroid Build Coastguard Worker
1946*5e7646d2SAndroid Build Coastguard Worker if (ipp->atend)
1947*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1948*5e7646d2SAndroid Build Coastguard Worker
1949*5e7646d2SAndroid Build Coastguard Worker if (strchr(name, '/'))
1950*5e7646d2SAndroid Build Coastguard Worker {
1951*5e7646d2SAndroid Build Coastguard Worker /*
1952*5e7646d2SAndroid Build Coastguard Worker * Search for child attribute...
1953*5e7646d2SAndroid Build Coastguard Worker */
1954*5e7646d2SAndroid Build Coastguard Worker
1955*5e7646d2SAndroid Build Coastguard Worker strlcpy(parent, name, sizeof(parent));
1956*5e7646d2SAndroid Build Coastguard Worker if ((child = strchr(parent, '/')) == NULL)
1957*5e7646d2SAndroid Build Coastguard Worker {
1958*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("3ippFindNextAttribute: Attribute name too long.");
1959*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1960*5e7646d2SAndroid Build Coastguard Worker }
1961*5e7646d2SAndroid Build Coastguard Worker
1962*5e7646d2SAndroid Build Coastguard Worker *child++ = '\0';
1963*5e7646d2SAndroid Build Coastguard Worker
1964*5e7646d2SAndroid Build Coastguard Worker if (ipp->current && ipp->current->name && ipp->current->value_tag == IPP_TAG_BEGIN_COLLECTION && !strcmp(parent, ipp->current->name))
1965*5e7646d2SAndroid Build Coastguard Worker {
1966*5e7646d2SAndroid Build Coastguard Worker while (ipp->curindex < ipp->current->num_values)
1967*5e7646d2SAndroid Build Coastguard Worker {
1968*5e7646d2SAndroid Build Coastguard Worker if ((childattr = ippFindNextAttribute(ipp->current->values[ipp->curindex].collection, child, type)) != NULL)
1969*5e7646d2SAndroid Build Coastguard Worker return (childattr);
1970*5e7646d2SAndroid Build Coastguard Worker
1971*5e7646d2SAndroid Build Coastguard Worker ipp->curindex ++;
1972*5e7646d2SAndroid Build Coastguard Worker if (ipp->curindex < ipp->current->num_values && ipp->current->values[ipp->curindex].collection)
1973*5e7646d2SAndroid Build Coastguard Worker ipp->current->values[ipp->curindex].collection->current = NULL;
1974*5e7646d2SAndroid Build Coastguard Worker }
1975*5e7646d2SAndroid Build Coastguard Worker
1976*5e7646d2SAndroid Build Coastguard Worker ipp->prev = ipp->current;
1977*5e7646d2SAndroid Build Coastguard Worker ipp->current = ipp->current->next;
1978*5e7646d2SAndroid Build Coastguard Worker ipp->curindex = 0;
1979*5e7646d2SAndroid Build Coastguard Worker
1980*5e7646d2SAndroid Build Coastguard Worker if (!ipp->current)
1981*5e7646d2SAndroid Build Coastguard Worker {
1982*5e7646d2SAndroid Build Coastguard Worker ipp->atend = 1;
1983*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1984*5e7646d2SAndroid Build Coastguard Worker }
1985*5e7646d2SAndroid Build Coastguard Worker }
1986*5e7646d2SAndroid Build Coastguard Worker
1987*5e7646d2SAndroid Build Coastguard Worker if (!ipp->current)
1988*5e7646d2SAndroid Build Coastguard Worker {
1989*5e7646d2SAndroid Build Coastguard Worker ipp->prev = NULL;
1990*5e7646d2SAndroid Build Coastguard Worker ipp->current = ipp->attrs;
1991*5e7646d2SAndroid Build Coastguard Worker ipp->curindex = 0;
1992*5e7646d2SAndroid Build Coastguard Worker }
1993*5e7646d2SAndroid Build Coastguard Worker
1994*5e7646d2SAndroid Build Coastguard Worker name = parent;
1995*5e7646d2SAndroid Build Coastguard Worker attr = ipp->current;
1996*5e7646d2SAndroid Build Coastguard Worker }
1997*5e7646d2SAndroid Build Coastguard Worker else if (ipp->current)
1998*5e7646d2SAndroid Build Coastguard Worker {
1999*5e7646d2SAndroid Build Coastguard Worker ipp->prev = ipp->current;
2000*5e7646d2SAndroid Build Coastguard Worker attr = ipp->current->next;
2001*5e7646d2SAndroid Build Coastguard Worker }
2002*5e7646d2SAndroid Build Coastguard Worker else
2003*5e7646d2SAndroid Build Coastguard Worker {
2004*5e7646d2SAndroid Build Coastguard Worker ipp->prev = NULL;
2005*5e7646d2SAndroid Build Coastguard Worker attr = ipp->attrs;
2006*5e7646d2SAndroid Build Coastguard Worker }
2007*5e7646d2SAndroid Build Coastguard Worker
2008*5e7646d2SAndroid Build Coastguard Worker for (; attr != NULL; ipp->prev = attr, attr = attr->next)
2009*5e7646d2SAndroid Build Coastguard Worker {
2010*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4ippFindAttribute: attr=%p, name=\"%s\"", (void *)attr, attr->name));
2011*5e7646d2SAndroid Build Coastguard Worker
2012*5e7646d2SAndroid Build Coastguard Worker value_tag = (ipp_tag_t)(attr->value_tag & IPP_TAG_CUPS_MASK);
2013*5e7646d2SAndroid Build Coastguard Worker
2014*5e7646d2SAndroid Build Coastguard Worker if (attr->name != NULL && _cups_strcasecmp(attr->name, name) == 0 &&
2015*5e7646d2SAndroid Build Coastguard Worker (value_tag == type || type == IPP_TAG_ZERO || name == parent ||
2016*5e7646d2SAndroid Build Coastguard Worker (value_tag == IPP_TAG_TEXTLANG && type == IPP_TAG_TEXT) ||
2017*5e7646d2SAndroid Build Coastguard Worker (value_tag == IPP_TAG_NAMELANG && type == IPP_TAG_NAME)))
2018*5e7646d2SAndroid Build Coastguard Worker {
2019*5e7646d2SAndroid Build Coastguard Worker ipp->current = attr;
2020*5e7646d2SAndroid Build Coastguard Worker
2021*5e7646d2SAndroid Build Coastguard Worker if (name == parent && attr->value_tag == IPP_TAG_BEGIN_COLLECTION)
2022*5e7646d2SAndroid Build Coastguard Worker {
2023*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2024*5e7646d2SAndroid Build Coastguard Worker
2025*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
2026*5e7646d2SAndroid Build Coastguard Worker {
2027*5e7646d2SAndroid Build Coastguard Worker if ((childattr = ippFindAttribute(attr->values[i].collection, child, type)) != NULL)
2028*5e7646d2SAndroid Build Coastguard Worker {
2029*5e7646d2SAndroid Build Coastguard Worker attr->values[0].collection->curindex = i;
2030*5e7646d2SAndroid Build Coastguard Worker return (childattr);
2031*5e7646d2SAndroid Build Coastguard Worker }
2032*5e7646d2SAndroid Build Coastguard Worker }
2033*5e7646d2SAndroid Build Coastguard Worker }
2034*5e7646d2SAndroid Build Coastguard Worker else
2035*5e7646d2SAndroid Build Coastguard Worker return (attr);
2036*5e7646d2SAndroid Build Coastguard Worker }
2037*5e7646d2SAndroid Build Coastguard Worker }
2038*5e7646d2SAndroid Build Coastguard Worker
2039*5e7646d2SAndroid Build Coastguard Worker ipp->current = NULL;
2040*5e7646d2SAndroid Build Coastguard Worker ipp->prev = NULL;
2041*5e7646d2SAndroid Build Coastguard Worker ipp->atend = 1;
2042*5e7646d2SAndroid Build Coastguard Worker
2043*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2044*5e7646d2SAndroid Build Coastguard Worker }
2045*5e7646d2SAndroid Build Coastguard Worker
2046*5e7646d2SAndroid Build Coastguard Worker
2047*5e7646d2SAndroid Build Coastguard Worker /*
2048*5e7646d2SAndroid Build Coastguard Worker * 'ippFirstAttribute()' - Return the first attribute in the message.
2049*5e7646d2SAndroid Build Coastguard Worker *
2050*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2051*5e7646d2SAndroid Build Coastguard Worker */
2052*5e7646d2SAndroid Build Coastguard Worker
2053*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - First attribute or @code NULL@ if none */
ippFirstAttribute(ipp_t * ipp)2054*5e7646d2SAndroid Build Coastguard Worker ippFirstAttribute(ipp_t *ipp) /* I - IPP message */
2055*5e7646d2SAndroid Build Coastguard Worker {
2056*5e7646d2SAndroid Build Coastguard Worker /*
2057*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2058*5e7646d2SAndroid Build Coastguard Worker */
2059*5e7646d2SAndroid Build Coastguard Worker
2060*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
2061*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2062*5e7646d2SAndroid Build Coastguard Worker
2063*5e7646d2SAndroid Build Coastguard Worker /*
2064*5e7646d2SAndroid Build Coastguard Worker * Return the first attribute...
2065*5e7646d2SAndroid Build Coastguard Worker */
2066*5e7646d2SAndroid Build Coastguard Worker
2067*5e7646d2SAndroid Build Coastguard Worker return (ipp->current = ipp->attrs);
2068*5e7646d2SAndroid Build Coastguard Worker }
2069*5e7646d2SAndroid Build Coastguard Worker
2070*5e7646d2SAndroid Build Coastguard Worker
2071*5e7646d2SAndroid Build Coastguard Worker /*
2072*5e7646d2SAndroid Build Coastguard Worker * 'ippGetBoolean()' - Get a boolean value for an attribute.
2073*5e7646d2SAndroid Build Coastguard Worker *
2074*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to get from 0 to
2075*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@ - 1.
2076*5e7646d2SAndroid Build Coastguard Worker *
2077*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2078*5e7646d2SAndroid Build Coastguard Worker */
2079*5e7646d2SAndroid Build Coastguard Worker
2080*5e7646d2SAndroid Build Coastguard Worker int /* O - Boolean value or 0 on error */
ippGetBoolean(ipp_attribute_t * attr,int element)2081*5e7646d2SAndroid Build Coastguard Worker ippGetBoolean(ipp_attribute_t *attr, /* I - IPP attribute */
2082*5e7646d2SAndroid Build Coastguard Worker int element) /* I - Value number (0-based) */
2083*5e7646d2SAndroid Build Coastguard Worker {
2084*5e7646d2SAndroid Build Coastguard Worker /*
2085*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2086*5e7646d2SAndroid Build Coastguard Worker */
2087*5e7646d2SAndroid Build Coastguard Worker
2088*5e7646d2SAndroid Build Coastguard Worker if (!attr || attr->value_tag != IPP_TAG_BOOLEAN ||
2089*5e7646d2SAndroid Build Coastguard Worker element < 0 || element >= attr->num_values)
2090*5e7646d2SAndroid Build Coastguard Worker return (0);
2091*5e7646d2SAndroid Build Coastguard Worker
2092*5e7646d2SAndroid Build Coastguard Worker /*
2093*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2094*5e7646d2SAndroid Build Coastguard Worker */
2095*5e7646d2SAndroid Build Coastguard Worker
2096*5e7646d2SAndroid Build Coastguard Worker return (attr->values[element].boolean);
2097*5e7646d2SAndroid Build Coastguard Worker }
2098*5e7646d2SAndroid Build Coastguard Worker
2099*5e7646d2SAndroid Build Coastguard Worker
2100*5e7646d2SAndroid Build Coastguard Worker /*
2101*5e7646d2SAndroid Build Coastguard Worker * 'ippGetCollection()' - Get a collection value for an attribute.
2102*5e7646d2SAndroid Build Coastguard Worker *
2103*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to get from 0 to
2104*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@ - 1.
2105*5e7646d2SAndroid Build Coastguard Worker *
2106*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2107*5e7646d2SAndroid Build Coastguard Worker */
2108*5e7646d2SAndroid Build Coastguard Worker
2109*5e7646d2SAndroid Build Coastguard Worker ipp_t * /* O - Collection value or @code NULL@ on error */
ippGetCollection(ipp_attribute_t * attr,int element)2110*5e7646d2SAndroid Build Coastguard Worker ippGetCollection(
2111*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - IPP attribute */
2112*5e7646d2SAndroid Build Coastguard Worker int element) /* I - Value number (0-based) */
2113*5e7646d2SAndroid Build Coastguard Worker {
2114*5e7646d2SAndroid Build Coastguard Worker /*
2115*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2116*5e7646d2SAndroid Build Coastguard Worker */
2117*5e7646d2SAndroid Build Coastguard Worker
2118*5e7646d2SAndroid Build Coastguard Worker if (!attr || attr->value_tag != IPP_TAG_BEGIN_COLLECTION ||
2119*5e7646d2SAndroid Build Coastguard Worker element < 0 || element >= attr->num_values)
2120*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2121*5e7646d2SAndroid Build Coastguard Worker
2122*5e7646d2SAndroid Build Coastguard Worker /*
2123*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2124*5e7646d2SAndroid Build Coastguard Worker */
2125*5e7646d2SAndroid Build Coastguard Worker
2126*5e7646d2SAndroid Build Coastguard Worker return (attr->values[element].collection);
2127*5e7646d2SAndroid Build Coastguard Worker }
2128*5e7646d2SAndroid Build Coastguard Worker
2129*5e7646d2SAndroid Build Coastguard Worker
2130*5e7646d2SAndroid Build Coastguard Worker /*
2131*5e7646d2SAndroid Build Coastguard Worker * 'ippGetCount()' - Get the number of values in an attribute.
2132*5e7646d2SAndroid Build Coastguard Worker *
2133*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2134*5e7646d2SAndroid Build Coastguard Worker */
2135*5e7646d2SAndroid Build Coastguard Worker
2136*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of values or 0 on error */
ippGetCount(ipp_attribute_t * attr)2137*5e7646d2SAndroid Build Coastguard Worker ippGetCount(ipp_attribute_t *attr) /* I - IPP attribute */
2138*5e7646d2SAndroid Build Coastguard Worker {
2139*5e7646d2SAndroid Build Coastguard Worker /*
2140*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2141*5e7646d2SAndroid Build Coastguard Worker */
2142*5e7646d2SAndroid Build Coastguard Worker
2143*5e7646d2SAndroid Build Coastguard Worker if (!attr)
2144*5e7646d2SAndroid Build Coastguard Worker return (0);
2145*5e7646d2SAndroid Build Coastguard Worker
2146*5e7646d2SAndroid Build Coastguard Worker /*
2147*5e7646d2SAndroid Build Coastguard Worker * Return the number of values...
2148*5e7646d2SAndroid Build Coastguard Worker */
2149*5e7646d2SAndroid Build Coastguard Worker
2150*5e7646d2SAndroid Build Coastguard Worker return (attr->num_values);
2151*5e7646d2SAndroid Build Coastguard Worker }
2152*5e7646d2SAndroid Build Coastguard Worker
2153*5e7646d2SAndroid Build Coastguard Worker
2154*5e7646d2SAndroid Build Coastguard Worker /*
2155*5e7646d2SAndroid Build Coastguard Worker * 'ippGetDate()' - Get a dateTime value for an attribute.
2156*5e7646d2SAndroid Build Coastguard Worker *
2157*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to get from 0 to
2158*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@ - 1.
2159*5e7646d2SAndroid Build Coastguard Worker *
2160*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2161*5e7646d2SAndroid Build Coastguard Worker */
2162*5e7646d2SAndroid Build Coastguard Worker
2163*5e7646d2SAndroid Build Coastguard Worker const ipp_uchar_t * /* O - dateTime value or @code NULL@ */
ippGetDate(ipp_attribute_t * attr,int element)2164*5e7646d2SAndroid Build Coastguard Worker ippGetDate(ipp_attribute_t *attr, /* I - IPP attribute */
2165*5e7646d2SAndroid Build Coastguard Worker int element) /* I - Value number (0-based) */
2166*5e7646d2SAndroid Build Coastguard Worker {
2167*5e7646d2SAndroid Build Coastguard Worker /*
2168*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2169*5e7646d2SAndroid Build Coastguard Worker */
2170*5e7646d2SAndroid Build Coastguard Worker
2171*5e7646d2SAndroid Build Coastguard Worker if (!attr || attr->value_tag != IPP_TAG_DATE ||
2172*5e7646d2SAndroid Build Coastguard Worker element < 0 || element >= attr->num_values)
2173*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2174*5e7646d2SAndroid Build Coastguard Worker
2175*5e7646d2SAndroid Build Coastguard Worker /*
2176*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2177*5e7646d2SAndroid Build Coastguard Worker */
2178*5e7646d2SAndroid Build Coastguard Worker
2179*5e7646d2SAndroid Build Coastguard Worker return (attr->values[element].date);
2180*5e7646d2SAndroid Build Coastguard Worker }
2181*5e7646d2SAndroid Build Coastguard Worker
2182*5e7646d2SAndroid Build Coastguard Worker
2183*5e7646d2SAndroid Build Coastguard Worker /*
2184*5e7646d2SAndroid Build Coastguard Worker * 'ippGetGroupTag()' - Get the group associated with an attribute.
2185*5e7646d2SAndroid Build Coastguard Worker *
2186*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2187*5e7646d2SAndroid Build Coastguard Worker */
2188*5e7646d2SAndroid Build Coastguard Worker
2189*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t /* O - Group tag or @code IPP_TAG_ZERO@ on error */
ippGetGroupTag(ipp_attribute_t * attr)2190*5e7646d2SAndroid Build Coastguard Worker ippGetGroupTag(ipp_attribute_t *attr) /* I - IPP attribute */
2191*5e7646d2SAndroid Build Coastguard Worker {
2192*5e7646d2SAndroid Build Coastguard Worker /*
2193*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2194*5e7646d2SAndroid Build Coastguard Worker */
2195*5e7646d2SAndroid Build Coastguard Worker
2196*5e7646d2SAndroid Build Coastguard Worker if (!attr)
2197*5e7646d2SAndroid Build Coastguard Worker return (IPP_TAG_ZERO);
2198*5e7646d2SAndroid Build Coastguard Worker
2199*5e7646d2SAndroid Build Coastguard Worker /*
2200*5e7646d2SAndroid Build Coastguard Worker * Return the group...
2201*5e7646d2SAndroid Build Coastguard Worker */
2202*5e7646d2SAndroid Build Coastguard Worker
2203*5e7646d2SAndroid Build Coastguard Worker return (attr->group_tag);
2204*5e7646d2SAndroid Build Coastguard Worker }
2205*5e7646d2SAndroid Build Coastguard Worker
2206*5e7646d2SAndroid Build Coastguard Worker
2207*5e7646d2SAndroid Build Coastguard Worker /*
2208*5e7646d2SAndroid Build Coastguard Worker * 'ippGetInteger()' - Get the integer/enum value for an attribute.
2209*5e7646d2SAndroid Build Coastguard Worker *
2210*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to get from 0 to
2211*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@ - 1.
2212*5e7646d2SAndroid Build Coastguard Worker *
2213*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2214*5e7646d2SAndroid Build Coastguard Worker */
2215*5e7646d2SAndroid Build Coastguard Worker
2216*5e7646d2SAndroid Build Coastguard Worker int /* O - Value or 0 on error */
ippGetInteger(ipp_attribute_t * attr,int element)2217*5e7646d2SAndroid Build Coastguard Worker ippGetInteger(ipp_attribute_t *attr, /* I - IPP attribute */
2218*5e7646d2SAndroid Build Coastguard Worker int element) /* I - Value number (0-based) */
2219*5e7646d2SAndroid Build Coastguard Worker {
2220*5e7646d2SAndroid Build Coastguard Worker /*
2221*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2222*5e7646d2SAndroid Build Coastguard Worker */
2223*5e7646d2SAndroid Build Coastguard Worker
2224*5e7646d2SAndroid Build Coastguard Worker if (!attr || (attr->value_tag != IPP_TAG_INTEGER && attr->value_tag != IPP_TAG_ENUM) ||
2225*5e7646d2SAndroid Build Coastguard Worker element < 0 || element >= attr->num_values)
2226*5e7646d2SAndroid Build Coastguard Worker return (0);
2227*5e7646d2SAndroid Build Coastguard Worker
2228*5e7646d2SAndroid Build Coastguard Worker /*
2229*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2230*5e7646d2SAndroid Build Coastguard Worker */
2231*5e7646d2SAndroid Build Coastguard Worker
2232*5e7646d2SAndroid Build Coastguard Worker return (attr->values[element].integer);
2233*5e7646d2SAndroid Build Coastguard Worker }
2234*5e7646d2SAndroid Build Coastguard Worker
2235*5e7646d2SAndroid Build Coastguard Worker
2236*5e7646d2SAndroid Build Coastguard Worker /*
2237*5e7646d2SAndroid Build Coastguard Worker * 'ippGetName()' - Get the attribute name.
2238*5e7646d2SAndroid Build Coastguard Worker *
2239*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2240*5e7646d2SAndroid Build Coastguard Worker */
2241*5e7646d2SAndroid Build Coastguard Worker
2242*5e7646d2SAndroid Build Coastguard Worker const char * /* O - Attribute name or @code NULL@ for separators */
ippGetName(ipp_attribute_t * attr)2243*5e7646d2SAndroid Build Coastguard Worker ippGetName(ipp_attribute_t *attr) /* I - IPP attribute */
2244*5e7646d2SAndroid Build Coastguard Worker {
2245*5e7646d2SAndroid Build Coastguard Worker /*
2246*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2247*5e7646d2SAndroid Build Coastguard Worker */
2248*5e7646d2SAndroid Build Coastguard Worker
2249*5e7646d2SAndroid Build Coastguard Worker if (!attr)
2250*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2251*5e7646d2SAndroid Build Coastguard Worker
2252*5e7646d2SAndroid Build Coastguard Worker /*
2253*5e7646d2SAndroid Build Coastguard Worker * Return the name...
2254*5e7646d2SAndroid Build Coastguard Worker */
2255*5e7646d2SAndroid Build Coastguard Worker
2256*5e7646d2SAndroid Build Coastguard Worker return (attr->name);
2257*5e7646d2SAndroid Build Coastguard Worker }
2258*5e7646d2SAndroid Build Coastguard Worker
2259*5e7646d2SAndroid Build Coastguard Worker
2260*5e7646d2SAndroid Build Coastguard Worker /*
2261*5e7646d2SAndroid Build Coastguard Worker * 'ippGetOctetString()' - Get an octetString value from an IPP attribute.
2262*5e7646d2SAndroid Build Coastguard Worker *
2263*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to get from 0 to
2264*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@ - 1.
2265*5e7646d2SAndroid Build Coastguard Worker *
2266*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
2267*5e7646d2SAndroid Build Coastguard Worker */
2268*5e7646d2SAndroid Build Coastguard Worker
2269*5e7646d2SAndroid Build Coastguard Worker void * /* O - Pointer to octetString data */
ippGetOctetString(ipp_attribute_t * attr,int element,int * datalen)2270*5e7646d2SAndroid Build Coastguard Worker ippGetOctetString(
2271*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - IPP attribute */
2272*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
2273*5e7646d2SAndroid Build Coastguard Worker int *datalen) /* O - Length of octetString data */
2274*5e7646d2SAndroid Build Coastguard Worker {
2275*5e7646d2SAndroid Build Coastguard Worker /*
2276*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2277*5e7646d2SAndroid Build Coastguard Worker */
2278*5e7646d2SAndroid Build Coastguard Worker
2279*5e7646d2SAndroid Build Coastguard Worker if (!attr || attr->value_tag != IPP_TAG_STRING ||
2280*5e7646d2SAndroid Build Coastguard Worker element < 0 || element >= attr->num_values)
2281*5e7646d2SAndroid Build Coastguard Worker {
2282*5e7646d2SAndroid Build Coastguard Worker if (datalen)
2283*5e7646d2SAndroid Build Coastguard Worker *datalen = 0;
2284*5e7646d2SAndroid Build Coastguard Worker
2285*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2286*5e7646d2SAndroid Build Coastguard Worker }
2287*5e7646d2SAndroid Build Coastguard Worker
2288*5e7646d2SAndroid Build Coastguard Worker /*
2289*5e7646d2SAndroid Build Coastguard Worker * Return the values...
2290*5e7646d2SAndroid Build Coastguard Worker */
2291*5e7646d2SAndroid Build Coastguard Worker
2292*5e7646d2SAndroid Build Coastguard Worker if (datalen)
2293*5e7646d2SAndroid Build Coastguard Worker *datalen = attr->values[element].unknown.length;
2294*5e7646d2SAndroid Build Coastguard Worker
2295*5e7646d2SAndroid Build Coastguard Worker return (attr->values[element].unknown.data);
2296*5e7646d2SAndroid Build Coastguard Worker }
2297*5e7646d2SAndroid Build Coastguard Worker
2298*5e7646d2SAndroid Build Coastguard Worker
2299*5e7646d2SAndroid Build Coastguard Worker /*
2300*5e7646d2SAndroid Build Coastguard Worker * 'ippGetOperation()' - Get the operation ID in an IPP message.
2301*5e7646d2SAndroid Build Coastguard Worker *
2302*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2303*5e7646d2SAndroid Build Coastguard Worker */
2304*5e7646d2SAndroid Build Coastguard Worker
2305*5e7646d2SAndroid Build Coastguard Worker ipp_op_t /* O - Operation ID or 0 on error */
ippGetOperation(ipp_t * ipp)2306*5e7646d2SAndroid Build Coastguard Worker ippGetOperation(ipp_t *ipp) /* I - IPP request message */
2307*5e7646d2SAndroid Build Coastguard Worker {
2308*5e7646d2SAndroid Build Coastguard Worker /*
2309*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2310*5e7646d2SAndroid Build Coastguard Worker */
2311*5e7646d2SAndroid Build Coastguard Worker
2312*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
2313*5e7646d2SAndroid Build Coastguard Worker return ((ipp_op_t)0);
2314*5e7646d2SAndroid Build Coastguard Worker
2315*5e7646d2SAndroid Build Coastguard Worker /*
2316*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2317*5e7646d2SAndroid Build Coastguard Worker */
2318*5e7646d2SAndroid Build Coastguard Worker
2319*5e7646d2SAndroid Build Coastguard Worker return (ipp->request.op.operation_id);
2320*5e7646d2SAndroid Build Coastguard Worker }
2321*5e7646d2SAndroid Build Coastguard Worker
2322*5e7646d2SAndroid Build Coastguard Worker
2323*5e7646d2SAndroid Build Coastguard Worker /*
2324*5e7646d2SAndroid Build Coastguard Worker * 'ippGetRange()' - Get a rangeOfInteger value from an attribute.
2325*5e7646d2SAndroid Build Coastguard Worker *
2326*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to get from 0 to
2327*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@ - 1.
2328*5e7646d2SAndroid Build Coastguard Worker *
2329*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2330*5e7646d2SAndroid Build Coastguard Worker */
2331*5e7646d2SAndroid Build Coastguard Worker
2332*5e7646d2SAndroid Build Coastguard Worker int /* O - Lower value of range or 0 */
ippGetRange(ipp_attribute_t * attr,int element,int * uppervalue)2333*5e7646d2SAndroid Build Coastguard Worker ippGetRange(ipp_attribute_t *attr, /* I - IPP attribute */
2334*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
2335*5e7646d2SAndroid Build Coastguard Worker int *uppervalue)/* O - Upper value of range */
2336*5e7646d2SAndroid Build Coastguard Worker {
2337*5e7646d2SAndroid Build Coastguard Worker /*
2338*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2339*5e7646d2SAndroid Build Coastguard Worker */
2340*5e7646d2SAndroid Build Coastguard Worker
2341*5e7646d2SAndroid Build Coastguard Worker if (!attr || attr->value_tag != IPP_TAG_RANGE ||
2342*5e7646d2SAndroid Build Coastguard Worker element < 0 || element >= attr->num_values)
2343*5e7646d2SAndroid Build Coastguard Worker {
2344*5e7646d2SAndroid Build Coastguard Worker if (uppervalue)
2345*5e7646d2SAndroid Build Coastguard Worker *uppervalue = 0;
2346*5e7646d2SAndroid Build Coastguard Worker
2347*5e7646d2SAndroid Build Coastguard Worker return (0);
2348*5e7646d2SAndroid Build Coastguard Worker }
2349*5e7646d2SAndroid Build Coastguard Worker
2350*5e7646d2SAndroid Build Coastguard Worker /*
2351*5e7646d2SAndroid Build Coastguard Worker * Return the values...
2352*5e7646d2SAndroid Build Coastguard Worker */
2353*5e7646d2SAndroid Build Coastguard Worker
2354*5e7646d2SAndroid Build Coastguard Worker if (uppervalue)
2355*5e7646d2SAndroid Build Coastguard Worker *uppervalue = attr->values[element].range.upper;
2356*5e7646d2SAndroid Build Coastguard Worker
2357*5e7646d2SAndroid Build Coastguard Worker return (attr->values[element].range.lower);
2358*5e7646d2SAndroid Build Coastguard Worker }
2359*5e7646d2SAndroid Build Coastguard Worker
2360*5e7646d2SAndroid Build Coastguard Worker
2361*5e7646d2SAndroid Build Coastguard Worker /*
2362*5e7646d2SAndroid Build Coastguard Worker * 'ippGetRequestId()' - Get the request ID from an IPP message.
2363*5e7646d2SAndroid Build Coastguard Worker *
2364*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2365*5e7646d2SAndroid Build Coastguard Worker */
2366*5e7646d2SAndroid Build Coastguard Worker
2367*5e7646d2SAndroid Build Coastguard Worker int /* O - Request ID or 0 on error */
ippGetRequestId(ipp_t * ipp)2368*5e7646d2SAndroid Build Coastguard Worker ippGetRequestId(ipp_t *ipp) /* I - IPP message */
2369*5e7646d2SAndroid Build Coastguard Worker {
2370*5e7646d2SAndroid Build Coastguard Worker /*
2371*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2372*5e7646d2SAndroid Build Coastguard Worker */
2373*5e7646d2SAndroid Build Coastguard Worker
2374*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
2375*5e7646d2SAndroid Build Coastguard Worker return (0);
2376*5e7646d2SAndroid Build Coastguard Worker
2377*5e7646d2SAndroid Build Coastguard Worker /*
2378*5e7646d2SAndroid Build Coastguard Worker * Return the request ID...
2379*5e7646d2SAndroid Build Coastguard Worker */
2380*5e7646d2SAndroid Build Coastguard Worker
2381*5e7646d2SAndroid Build Coastguard Worker return (ipp->request.any.request_id);
2382*5e7646d2SAndroid Build Coastguard Worker }
2383*5e7646d2SAndroid Build Coastguard Worker
2384*5e7646d2SAndroid Build Coastguard Worker
2385*5e7646d2SAndroid Build Coastguard Worker /*
2386*5e7646d2SAndroid Build Coastguard Worker * 'ippGetResolution()' - Get a resolution value for an attribute.
2387*5e7646d2SAndroid Build Coastguard Worker *
2388*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to get from 0 to
2389*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@ - 1.
2390*5e7646d2SAndroid Build Coastguard Worker *
2391*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2392*5e7646d2SAndroid Build Coastguard Worker */
2393*5e7646d2SAndroid Build Coastguard Worker
2394*5e7646d2SAndroid Build Coastguard Worker int /* O - Horizontal/cross feed resolution or 0 */
ippGetResolution(ipp_attribute_t * attr,int element,int * yres,ipp_res_t * units)2395*5e7646d2SAndroid Build Coastguard Worker ippGetResolution(
2396*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - IPP attribute */
2397*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
2398*5e7646d2SAndroid Build Coastguard Worker int *yres, /* O - Vertical/feed resolution */
2399*5e7646d2SAndroid Build Coastguard Worker ipp_res_t *units) /* O - Units for resolution */
2400*5e7646d2SAndroid Build Coastguard Worker {
2401*5e7646d2SAndroid Build Coastguard Worker /*
2402*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2403*5e7646d2SAndroid Build Coastguard Worker */
2404*5e7646d2SAndroid Build Coastguard Worker
2405*5e7646d2SAndroid Build Coastguard Worker if (!attr || attr->value_tag != IPP_TAG_RESOLUTION ||
2406*5e7646d2SAndroid Build Coastguard Worker element < 0 || element >= attr->num_values)
2407*5e7646d2SAndroid Build Coastguard Worker {
2408*5e7646d2SAndroid Build Coastguard Worker if (yres)
2409*5e7646d2SAndroid Build Coastguard Worker *yres = 0;
2410*5e7646d2SAndroid Build Coastguard Worker
2411*5e7646d2SAndroid Build Coastguard Worker if (units)
2412*5e7646d2SAndroid Build Coastguard Worker *units = (ipp_res_t)0;
2413*5e7646d2SAndroid Build Coastguard Worker
2414*5e7646d2SAndroid Build Coastguard Worker return (0);
2415*5e7646d2SAndroid Build Coastguard Worker }
2416*5e7646d2SAndroid Build Coastguard Worker
2417*5e7646d2SAndroid Build Coastguard Worker /*
2418*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2419*5e7646d2SAndroid Build Coastguard Worker */
2420*5e7646d2SAndroid Build Coastguard Worker
2421*5e7646d2SAndroid Build Coastguard Worker if (yres)
2422*5e7646d2SAndroid Build Coastguard Worker *yres = attr->values[element].resolution.yres;
2423*5e7646d2SAndroid Build Coastguard Worker
2424*5e7646d2SAndroid Build Coastguard Worker if (units)
2425*5e7646d2SAndroid Build Coastguard Worker *units = attr->values[element].resolution.units;
2426*5e7646d2SAndroid Build Coastguard Worker
2427*5e7646d2SAndroid Build Coastguard Worker return (attr->values[element].resolution.xres);
2428*5e7646d2SAndroid Build Coastguard Worker }
2429*5e7646d2SAndroid Build Coastguard Worker
2430*5e7646d2SAndroid Build Coastguard Worker
2431*5e7646d2SAndroid Build Coastguard Worker /*
2432*5e7646d2SAndroid Build Coastguard Worker * 'ippGetState()' - Get the IPP message state.
2433*5e7646d2SAndroid Build Coastguard Worker *
2434*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2435*5e7646d2SAndroid Build Coastguard Worker */
2436*5e7646d2SAndroid Build Coastguard Worker
2437*5e7646d2SAndroid Build Coastguard Worker ipp_state_t /* O - IPP message state value */
ippGetState(ipp_t * ipp)2438*5e7646d2SAndroid Build Coastguard Worker ippGetState(ipp_t *ipp) /* I - IPP message */
2439*5e7646d2SAndroid Build Coastguard Worker {
2440*5e7646d2SAndroid Build Coastguard Worker /*
2441*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2442*5e7646d2SAndroid Build Coastguard Worker */
2443*5e7646d2SAndroid Build Coastguard Worker
2444*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
2445*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_IDLE);
2446*5e7646d2SAndroid Build Coastguard Worker
2447*5e7646d2SAndroid Build Coastguard Worker /*
2448*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2449*5e7646d2SAndroid Build Coastguard Worker */
2450*5e7646d2SAndroid Build Coastguard Worker
2451*5e7646d2SAndroid Build Coastguard Worker return (ipp->state);
2452*5e7646d2SAndroid Build Coastguard Worker }
2453*5e7646d2SAndroid Build Coastguard Worker
2454*5e7646d2SAndroid Build Coastguard Worker
2455*5e7646d2SAndroid Build Coastguard Worker /*
2456*5e7646d2SAndroid Build Coastguard Worker * 'ippGetStatusCode()' - Get the status code from an IPP response or event message.
2457*5e7646d2SAndroid Build Coastguard Worker *
2458*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2459*5e7646d2SAndroid Build Coastguard Worker */
2460*5e7646d2SAndroid Build Coastguard Worker
2461*5e7646d2SAndroid Build Coastguard Worker ipp_status_t /* O - Status code in IPP message */
ippGetStatusCode(ipp_t * ipp)2462*5e7646d2SAndroid Build Coastguard Worker ippGetStatusCode(ipp_t *ipp) /* I - IPP response or event message */
2463*5e7646d2SAndroid Build Coastguard Worker {
2464*5e7646d2SAndroid Build Coastguard Worker /*
2465*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2466*5e7646d2SAndroid Build Coastguard Worker */
2467*5e7646d2SAndroid Build Coastguard Worker
2468*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
2469*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATUS_ERROR_INTERNAL);
2470*5e7646d2SAndroid Build Coastguard Worker
2471*5e7646d2SAndroid Build Coastguard Worker /*
2472*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2473*5e7646d2SAndroid Build Coastguard Worker */
2474*5e7646d2SAndroid Build Coastguard Worker
2475*5e7646d2SAndroid Build Coastguard Worker return (ipp->request.status.status_code);
2476*5e7646d2SAndroid Build Coastguard Worker }
2477*5e7646d2SAndroid Build Coastguard Worker
2478*5e7646d2SAndroid Build Coastguard Worker
2479*5e7646d2SAndroid Build Coastguard Worker /*
2480*5e7646d2SAndroid Build Coastguard Worker * 'ippGetString()' - Get the string and optionally the language code for an attribute.
2481*5e7646d2SAndroid Build Coastguard Worker *
2482*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to get from 0 to
2483*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@ - 1.
2484*5e7646d2SAndroid Build Coastguard Worker *
2485*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2486*5e7646d2SAndroid Build Coastguard Worker */
2487*5e7646d2SAndroid Build Coastguard Worker
2488*5e7646d2SAndroid Build Coastguard Worker const char *
ippGetString(ipp_attribute_t * attr,int element,const char ** language)2489*5e7646d2SAndroid Build Coastguard Worker ippGetString(ipp_attribute_t *attr, /* I - IPP attribute */
2490*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
2491*5e7646d2SAndroid Build Coastguard Worker const char **language)/* O - Language code (@code NULL@ for don't care) */
2492*5e7646d2SAndroid Build Coastguard Worker {
2493*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t tag; /* Value tag */
2494*5e7646d2SAndroid Build Coastguard Worker
2495*5e7646d2SAndroid Build Coastguard Worker
2496*5e7646d2SAndroid Build Coastguard Worker /*
2497*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2498*5e7646d2SAndroid Build Coastguard Worker */
2499*5e7646d2SAndroid Build Coastguard Worker
2500*5e7646d2SAndroid Build Coastguard Worker tag = ippGetValueTag(attr);
2501*5e7646d2SAndroid Build Coastguard Worker
2502*5e7646d2SAndroid Build Coastguard Worker if (!attr || element < 0 || element >= attr->num_values || (tag != IPP_TAG_TEXTLANG && tag != IPP_TAG_NAMELANG && (tag < IPP_TAG_TEXT || tag > IPP_TAG_MIMETYPE)))
2503*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2504*5e7646d2SAndroid Build Coastguard Worker
2505*5e7646d2SAndroid Build Coastguard Worker /*
2506*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2507*5e7646d2SAndroid Build Coastguard Worker */
2508*5e7646d2SAndroid Build Coastguard Worker
2509*5e7646d2SAndroid Build Coastguard Worker if (language)
2510*5e7646d2SAndroid Build Coastguard Worker *language = attr->values[element].string.language;
2511*5e7646d2SAndroid Build Coastguard Worker
2512*5e7646d2SAndroid Build Coastguard Worker return (attr->values[element].string.text);
2513*5e7646d2SAndroid Build Coastguard Worker }
2514*5e7646d2SAndroid Build Coastguard Worker
2515*5e7646d2SAndroid Build Coastguard Worker
2516*5e7646d2SAndroid Build Coastguard Worker /*
2517*5e7646d2SAndroid Build Coastguard Worker * 'ippGetValueTag()' - Get the value tag for an attribute.
2518*5e7646d2SAndroid Build Coastguard Worker *
2519*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2520*5e7646d2SAndroid Build Coastguard Worker */
2521*5e7646d2SAndroid Build Coastguard Worker
2522*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t /* O - Value tag or @code IPP_TAG_ZERO@ on error */
ippGetValueTag(ipp_attribute_t * attr)2523*5e7646d2SAndroid Build Coastguard Worker ippGetValueTag(ipp_attribute_t *attr) /* I - IPP attribute */
2524*5e7646d2SAndroid Build Coastguard Worker {
2525*5e7646d2SAndroid Build Coastguard Worker /*
2526*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2527*5e7646d2SAndroid Build Coastguard Worker */
2528*5e7646d2SAndroid Build Coastguard Worker
2529*5e7646d2SAndroid Build Coastguard Worker if (!attr)
2530*5e7646d2SAndroid Build Coastguard Worker return (IPP_TAG_ZERO);
2531*5e7646d2SAndroid Build Coastguard Worker
2532*5e7646d2SAndroid Build Coastguard Worker /*
2533*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2534*5e7646d2SAndroid Build Coastguard Worker */
2535*5e7646d2SAndroid Build Coastguard Worker
2536*5e7646d2SAndroid Build Coastguard Worker return (attr->value_tag & IPP_TAG_CUPS_MASK);
2537*5e7646d2SAndroid Build Coastguard Worker }
2538*5e7646d2SAndroid Build Coastguard Worker
2539*5e7646d2SAndroid Build Coastguard Worker
2540*5e7646d2SAndroid Build Coastguard Worker /*
2541*5e7646d2SAndroid Build Coastguard Worker * 'ippGetVersion()' - Get the major and minor version number from an IPP message.
2542*5e7646d2SAndroid Build Coastguard Worker *
2543*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2544*5e7646d2SAndroid Build Coastguard Worker */
2545*5e7646d2SAndroid Build Coastguard Worker
2546*5e7646d2SAndroid Build Coastguard Worker int /* O - Major version number or 0 on error */
ippGetVersion(ipp_t * ipp,int * minor)2547*5e7646d2SAndroid Build Coastguard Worker ippGetVersion(ipp_t *ipp, /* I - IPP message */
2548*5e7646d2SAndroid Build Coastguard Worker int *minor) /* O - Minor version number or @code NULL@ for don't care */
2549*5e7646d2SAndroid Build Coastguard Worker {
2550*5e7646d2SAndroid Build Coastguard Worker /*
2551*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2552*5e7646d2SAndroid Build Coastguard Worker */
2553*5e7646d2SAndroid Build Coastguard Worker
2554*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
2555*5e7646d2SAndroid Build Coastguard Worker {
2556*5e7646d2SAndroid Build Coastguard Worker if (minor)
2557*5e7646d2SAndroid Build Coastguard Worker *minor = 0;
2558*5e7646d2SAndroid Build Coastguard Worker
2559*5e7646d2SAndroid Build Coastguard Worker return (0);
2560*5e7646d2SAndroid Build Coastguard Worker }
2561*5e7646d2SAndroid Build Coastguard Worker
2562*5e7646d2SAndroid Build Coastguard Worker /*
2563*5e7646d2SAndroid Build Coastguard Worker * Return the value...
2564*5e7646d2SAndroid Build Coastguard Worker */
2565*5e7646d2SAndroid Build Coastguard Worker
2566*5e7646d2SAndroid Build Coastguard Worker if (minor)
2567*5e7646d2SAndroid Build Coastguard Worker *minor = ipp->request.any.version[1];
2568*5e7646d2SAndroid Build Coastguard Worker
2569*5e7646d2SAndroid Build Coastguard Worker return (ipp->request.any.version[0]);
2570*5e7646d2SAndroid Build Coastguard Worker }
2571*5e7646d2SAndroid Build Coastguard Worker
2572*5e7646d2SAndroid Build Coastguard Worker
2573*5e7646d2SAndroid Build Coastguard Worker /*
2574*5e7646d2SAndroid Build Coastguard Worker * 'ippLength()' - Compute the length of an IPP message.
2575*5e7646d2SAndroid Build Coastguard Worker */
2576*5e7646d2SAndroid Build Coastguard Worker
2577*5e7646d2SAndroid Build Coastguard Worker size_t /* O - Size of IPP message */
ippLength(ipp_t * ipp)2578*5e7646d2SAndroid Build Coastguard Worker ippLength(ipp_t *ipp) /* I - IPP message */
2579*5e7646d2SAndroid Build Coastguard Worker {
2580*5e7646d2SAndroid Build Coastguard Worker return (ipp_length(ipp, 0));
2581*5e7646d2SAndroid Build Coastguard Worker }
2582*5e7646d2SAndroid Build Coastguard Worker
2583*5e7646d2SAndroid Build Coastguard Worker
2584*5e7646d2SAndroid Build Coastguard Worker /*
2585*5e7646d2SAndroid Build Coastguard Worker * 'ippNextAttribute()' - Return the next attribute in the message.
2586*5e7646d2SAndroid Build Coastguard Worker *
2587*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
2588*5e7646d2SAndroid Build Coastguard Worker */
2589*5e7646d2SAndroid Build Coastguard Worker
2590*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t * /* O - Next attribute or @code NULL@ if none */
ippNextAttribute(ipp_t * ipp)2591*5e7646d2SAndroid Build Coastguard Worker ippNextAttribute(ipp_t *ipp) /* I - IPP message */
2592*5e7646d2SAndroid Build Coastguard Worker {
2593*5e7646d2SAndroid Build Coastguard Worker /*
2594*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2595*5e7646d2SAndroid Build Coastguard Worker */
2596*5e7646d2SAndroid Build Coastguard Worker
2597*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !ipp->current)
2598*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2599*5e7646d2SAndroid Build Coastguard Worker
2600*5e7646d2SAndroid Build Coastguard Worker /*
2601*5e7646d2SAndroid Build Coastguard Worker * Return the next attribute...
2602*5e7646d2SAndroid Build Coastguard Worker */
2603*5e7646d2SAndroid Build Coastguard Worker
2604*5e7646d2SAndroid Build Coastguard Worker return (ipp->current = ipp->current->next);
2605*5e7646d2SAndroid Build Coastguard Worker }
2606*5e7646d2SAndroid Build Coastguard Worker
2607*5e7646d2SAndroid Build Coastguard Worker
2608*5e7646d2SAndroid Build Coastguard Worker /*
2609*5e7646d2SAndroid Build Coastguard Worker * 'ippNew()' - Allocate a new IPP message.
2610*5e7646d2SAndroid Build Coastguard Worker */
2611*5e7646d2SAndroid Build Coastguard Worker
2612*5e7646d2SAndroid Build Coastguard Worker ipp_t * /* O - New IPP message */
ippNew(void)2613*5e7646d2SAndroid Build Coastguard Worker ippNew(void)
2614*5e7646d2SAndroid Build Coastguard Worker {
2615*5e7646d2SAndroid Build Coastguard Worker ipp_t *temp; /* New IPP message */
2616*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals();
2617*5e7646d2SAndroid Build Coastguard Worker /* Global data */
2618*5e7646d2SAndroid Build Coastguard Worker
2619*5e7646d2SAndroid Build Coastguard Worker
2620*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("ippNew()");
2621*5e7646d2SAndroid Build Coastguard Worker
2622*5e7646d2SAndroid Build Coastguard Worker if ((temp = (ipp_t *)calloc(1, sizeof(ipp_t))) != NULL)
2623*5e7646d2SAndroid Build Coastguard Worker {
2624*5e7646d2SAndroid Build Coastguard Worker /*
2625*5e7646d2SAndroid Build Coastguard Worker * Set default version - usually 2.0...
2626*5e7646d2SAndroid Build Coastguard Worker */
2627*5e7646d2SAndroid Build Coastguard Worker
2628*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4debug_alloc: %p IPP message", (void *)temp));
2629*5e7646d2SAndroid Build Coastguard Worker
2630*5e7646d2SAndroid Build Coastguard Worker if (cg->server_version == 0)
2631*5e7646d2SAndroid Build Coastguard Worker _cupsSetDefaults();
2632*5e7646d2SAndroid Build Coastguard Worker
2633*5e7646d2SAndroid Build Coastguard Worker temp->request.any.version[0] = (ipp_uchar_t)(cg->server_version / 10);
2634*5e7646d2SAndroid Build Coastguard Worker temp->request.any.version[1] = (ipp_uchar_t)(cg->server_version % 10);
2635*5e7646d2SAndroid Build Coastguard Worker temp->use = 1;
2636*5e7646d2SAndroid Build Coastguard Worker }
2637*5e7646d2SAndroid Build Coastguard Worker
2638*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippNew: Returning %p", (void *)temp));
2639*5e7646d2SAndroid Build Coastguard Worker
2640*5e7646d2SAndroid Build Coastguard Worker return (temp);
2641*5e7646d2SAndroid Build Coastguard Worker }
2642*5e7646d2SAndroid Build Coastguard Worker
2643*5e7646d2SAndroid Build Coastguard Worker
2644*5e7646d2SAndroid Build Coastguard Worker /*
2645*5e7646d2SAndroid Build Coastguard Worker * 'ippNewRequest()' - Allocate a new IPP request message.
2646*5e7646d2SAndroid Build Coastguard Worker *
2647*5e7646d2SAndroid Build Coastguard Worker * The new request message is initialized with the "attributes-charset" and
2648*5e7646d2SAndroid Build Coastguard Worker * "attributes-natural-language" attributes added. The
2649*5e7646d2SAndroid Build Coastguard Worker * "attributes-natural-language" value is derived from the current locale.
2650*5e7646d2SAndroid Build Coastguard Worker *
2651*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
2652*5e7646d2SAndroid Build Coastguard Worker */
2653*5e7646d2SAndroid Build Coastguard Worker
2654*5e7646d2SAndroid Build Coastguard Worker ipp_t * /* O - IPP request message */
ippNewRequest(ipp_op_t op)2655*5e7646d2SAndroid Build Coastguard Worker ippNewRequest(ipp_op_t op) /* I - Operation code */
2656*5e7646d2SAndroid Build Coastguard Worker {
2657*5e7646d2SAndroid Build Coastguard Worker ipp_t *request; /* IPP request message */
2658*5e7646d2SAndroid Build Coastguard Worker cups_lang_t *language; /* Current language localization */
2659*5e7646d2SAndroid Build Coastguard Worker static int request_id = 0; /* Current request ID */
2660*5e7646d2SAndroid Build Coastguard Worker static _cups_mutex_t request_mutex = _CUPS_MUTEX_INITIALIZER;
2661*5e7646d2SAndroid Build Coastguard Worker /* Mutex for request ID */
2662*5e7646d2SAndroid Build Coastguard Worker
2663*5e7646d2SAndroid Build Coastguard Worker
2664*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippNewRequest(op=%02x(%s))", op, ippOpString(op)));
2665*5e7646d2SAndroid Build Coastguard Worker
2666*5e7646d2SAndroid Build Coastguard Worker /*
2667*5e7646d2SAndroid Build Coastguard Worker * Create a new IPP message...
2668*5e7646d2SAndroid Build Coastguard Worker */
2669*5e7646d2SAndroid Build Coastguard Worker
2670*5e7646d2SAndroid Build Coastguard Worker if ((request = ippNew()) == NULL)
2671*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2672*5e7646d2SAndroid Build Coastguard Worker
2673*5e7646d2SAndroid Build Coastguard Worker /*
2674*5e7646d2SAndroid Build Coastguard Worker * Set the operation and request ID...
2675*5e7646d2SAndroid Build Coastguard Worker */
2676*5e7646d2SAndroid Build Coastguard Worker
2677*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&request_mutex);
2678*5e7646d2SAndroid Build Coastguard Worker
2679*5e7646d2SAndroid Build Coastguard Worker request->request.op.operation_id = op;
2680*5e7646d2SAndroid Build Coastguard Worker request->request.op.request_id = ++request_id;
2681*5e7646d2SAndroid Build Coastguard Worker
2682*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&request_mutex);
2683*5e7646d2SAndroid Build Coastguard Worker
2684*5e7646d2SAndroid Build Coastguard Worker /*
2685*5e7646d2SAndroid Build Coastguard Worker * Use UTF-8 as the character set...
2686*5e7646d2SAndroid Build Coastguard Worker */
2687*5e7646d2SAndroid Build Coastguard Worker
2688*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
2689*5e7646d2SAndroid Build Coastguard Worker "attributes-charset", NULL, "utf-8");
2690*5e7646d2SAndroid Build Coastguard Worker
2691*5e7646d2SAndroid Build Coastguard Worker /*
2692*5e7646d2SAndroid Build Coastguard Worker * Get the language from the current locale...
2693*5e7646d2SAndroid Build Coastguard Worker */
2694*5e7646d2SAndroid Build Coastguard Worker
2695*5e7646d2SAndroid Build Coastguard Worker language = cupsLangDefault();
2696*5e7646d2SAndroid Build Coastguard Worker
2697*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
2698*5e7646d2SAndroid Build Coastguard Worker "attributes-natural-language", NULL, language->language);
2699*5e7646d2SAndroid Build Coastguard Worker
2700*5e7646d2SAndroid Build Coastguard Worker /*
2701*5e7646d2SAndroid Build Coastguard Worker * Return the new request...
2702*5e7646d2SAndroid Build Coastguard Worker */
2703*5e7646d2SAndroid Build Coastguard Worker
2704*5e7646d2SAndroid Build Coastguard Worker return (request);
2705*5e7646d2SAndroid Build Coastguard Worker }
2706*5e7646d2SAndroid Build Coastguard Worker
2707*5e7646d2SAndroid Build Coastguard Worker
2708*5e7646d2SAndroid Build Coastguard Worker /*
2709*5e7646d2SAndroid Build Coastguard Worker * 'ippNewResponse()' - Allocate a new IPP response message.
2710*5e7646d2SAndroid Build Coastguard Worker *
2711*5e7646d2SAndroid Build Coastguard Worker * The new response message is initialized with the same "version-number",
2712*5e7646d2SAndroid Build Coastguard Worker * "request-id", "attributes-charset", and "attributes-natural-language" as the
2713*5e7646d2SAndroid Build Coastguard Worker * provided request message. If the "attributes-charset" or
2714*5e7646d2SAndroid Build Coastguard Worker * "attributes-natural-language" attributes are missing from the request,
2715*5e7646d2SAndroid Build Coastguard Worker * 'utf-8' and a value derived from the current locale are substituted,
2716*5e7646d2SAndroid Build Coastguard Worker * respectively.
2717*5e7646d2SAndroid Build Coastguard Worker *
2718*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
2719*5e7646d2SAndroid Build Coastguard Worker */
2720*5e7646d2SAndroid Build Coastguard Worker
2721*5e7646d2SAndroid Build Coastguard Worker ipp_t * /* O - IPP response message */
ippNewResponse(ipp_t * request)2722*5e7646d2SAndroid Build Coastguard Worker ippNewResponse(ipp_t *request) /* I - IPP request message */
2723*5e7646d2SAndroid Build Coastguard Worker {
2724*5e7646d2SAndroid Build Coastguard Worker ipp_t *response; /* IPP response message */
2725*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Current attribute */
2726*5e7646d2SAndroid Build Coastguard Worker
2727*5e7646d2SAndroid Build Coastguard Worker
2728*5e7646d2SAndroid Build Coastguard Worker /*
2729*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2730*5e7646d2SAndroid Build Coastguard Worker */
2731*5e7646d2SAndroid Build Coastguard Worker
2732*5e7646d2SAndroid Build Coastguard Worker if (!request)
2733*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2734*5e7646d2SAndroid Build Coastguard Worker
2735*5e7646d2SAndroid Build Coastguard Worker /*
2736*5e7646d2SAndroid Build Coastguard Worker * Create a new IPP message...
2737*5e7646d2SAndroid Build Coastguard Worker */
2738*5e7646d2SAndroid Build Coastguard Worker
2739*5e7646d2SAndroid Build Coastguard Worker if ((response = ippNew()) == NULL)
2740*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2741*5e7646d2SAndroid Build Coastguard Worker
2742*5e7646d2SAndroid Build Coastguard Worker /*
2743*5e7646d2SAndroid Build Coastguard Worker * Copy the request values over to the response...
2744*5e7646d2SAndroid Build Coastguard Worker */
2745*5e7646d2SAndroid Build Coastguard Worker
2746*5e7646d2SAndroid Build Coastguard Worker response->request.status.version[0] = request->request.op.version[0];
2747*5e7646d2SAndroid Build Coastguard Worker response->request.status.version[1] = request->request.op.version[1];
2748*5e7646d2SAndroid Build Coastguard Worker response->request.status.request_id = request->request.op.request_id;
2749*5e7646d2SAndroid Build Coastguard Worker
2750*5e7646d2SAndroid Build Coastguard Worker /*
2751*5e7646d2SAndroid Build Coastguard Worker * The first attribute MUST be attributes-charset...
2752*5e7646d2SAndroid Build Coastguard Worker */
2753*5e7646d2SAndroid Build Coastguard Worker
2754*5e7646d2SAndroid Build Coastguard Worker attr = request->attrs;
2755*5e7646d2SAndroid Build Coastguard Worker
2756*5e7646d2SAndroid Build Coastguard Worker if (attr && attr->name && !strcmp(attr->name, "attributes-charset") &&
2757*5e7646d2SAndroid Build Coastguard Worker attr->group_tag == IPP_TAG_OPERATION &&
2758*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_CHARSET &&
2759*5e7646d2SAndroid Build Coastguard Worker attr->num_values == 1)
2760*5e7646d2SAndroid Build Coastguard Worker {
2761*5e7646d2SAndroid Build Coastguard Worker /*
2762*5e7646d2SAndroid Build Coastguard Worker * Copy charset from request...
2763*5e7646d2SAndroid Build Coastguard Worker */
2764*5e7646d2SAndroid Build Coastguard Worker
2765*5e7646d2SAndroid Build Coastguard Worker ippAddString(response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
2766*5e7646d2SAndroid Build Coastguard Worker "attributes-charset", NULL, attr->values[0].string.text);
2767*5e7646d2SAndroid Build Coastguard Worker }
2768*5e7646d2SAndroid Build Coastguard Worker else
2769*5e7646d2SAndroid Build Coastguard Worker {
2770*5e7646d2SAndroid Build Coastguard Worker /*
2771*5e7646d2SAndroid Build Coastguard Worker * Use "utf-8" as the default...
2772*5e7646d2SAndroid Build Coastguard Worker */
2773*5e7646d2SAndroid Build Coastguard Worker
2774*5e7646d2SAndroid Build Coastguard Worker ippAddString(response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
2775*5e7646d2SAndroid Build Coastguard Worker "attributes-charset", NULL, "utf-8");
2776*5e7646d2SAndroid Build Coastguard Worker }
2777*5e7646d2SAndroid Build Coastguard Worker
2778*5e7646d2SAndroid Build Coastguard Worker /*
2779*5e7646d2SAndroid Build Coastguard Worker * Then attributes-natural-language...
2780*5e7646d2SAndroid Build Coastguard Worker */
2781*5e7646d2SAndroid Build Coastguard Worker
2782*5e7646d2SAndroid Build Coastguard Worker if (attr)
2783*5e7646d2SAndroid Build Coastguard Worker attr = attr->next;
2784*5e7646d2SAndroid Build Coastguard Worker
2785*5e7646d2SAndroid Build Coastguard Worker if (attr && attr->name &&
2786*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "attributes-natural-language") &&
2787*5e7646d2SAndroid Build Coastguard Worker attr->group_tag == IPP_TAG_OPERATION &&
2788*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_LANGUAGE &&
2789*5e7646d2SAndroid Build Coastguard Worker attr->num_values == 1)
2790*5e7646d2SAndroid Build Coastguard Worker {
2791*5e7646d2SAndroid Build Coastguard Worker /*
2792*5e7646d2SAndroid Build Coastguard Worker * Copy language from request...
2793*5e7646d2SAndroid Build Coastguard Worker */
2794*5e7646d2SAndroid Build Coastguard Worker
2795*5e7646d2SAndroid Build Coastguard Worker ippAddString(response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
2796*5e7646d2SAndroid Build Coastguard Worker "attributes-natural-language", NULL,
2797*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text);
2798*5e7646d2SAndroid Build Coastguard Worker }
2799*5e7646d2SAndroid Build Coastguard Worker else
2800*5e7646d2SAndroid Build Coastguard Worker {
2801*5e7646d2SAndroid Build Coastguard Worker /*
2802*5e7646d2SAndroid Build Coastguard Worker * Use the language from the current locale...
2803*5e7646d2SAndroid Build Coastguard Worker */
2804*5e7646d2SAndroid Build Coastguard Worker
2805*5e7646d2SAndroid Build Coastguard Worker cups_lang_t *language = cupsLangDefault();
2806*5e7646d2SAndroid Build Coastguard Worker /* Current locale */
2807*5e7646d2SAndroid Build Coastguard Worker
2808*5e7646d2SAndroid Build Coastguard Worker ippAddString(response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
2809*5e7646d2SAndroid Build Coastguard Worker "attributes-natural-language", NULL, language->language);
2810*5e7646d2SAndroid Build Coastguard Worker }
2811*5e7646d2SAndroid Build Coastguard Worker
2812*5e7646d2SAndroid Build Coastguard Worker return (response);
2813*5e7646d2SAndroid Build Coastguard Worker }
2814*5e7646d2SAndroid Build Coastguard Worker
2815*5e7646d2SAndroid Build Coastguard Worker
2816*5e7646d2SAndroid Build Coastguard Worker /*
2817*5e7646d2SAndroid Build Coastguard Worker * 'ippRead()' - Read data for an IPP message from a HTTP connection.
2818*5e7646d2SAndroid Build Coastguard Worker */
2819*5e7646d2SAndroid Build Coastguard Worker
2820*5e7646d2SAndroid Build Coastguard Worker ipp_state_t /* O - Current state */
ippRead(http_t * http,ipp_t * ipp)2821*5e7646d2SAndroid Build Coastguard Worker ippRead(http_t *http, /* I - HTTP connection */
2822*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp) /* I - IPP data */
2823*5e7646d2SAndroid Build Coastguard Worker {
2824*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippRead(http=%p, ipp=%p), data_remaining=" CUPS_LLFMT, (void *)http, (void *)ipp, CUPS_LLCAST (http ? http->data_remaining : -1)));
2825*5e7646d2SAndroid Build Coastguard Worker
2826*5e7646d2SAndroid Build Coastguard Worker if (!http)
2827*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
2828*5e7646d2SAndroid Build Coastguard Worker
2829*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippRead: http->state=%d, http->used=%d", http->state, http->used));
2830*5e7646d2SAndroid Build Coastguard Worker
2831*5e7646d2SAndroid Build Coastguard Worker return (ippReadIO(http, (ipp_iocb_t)ipp_read_http, http->blocking, NULL,
2832*5e7646d2SAndroid Build Coastguard Worker ipp));
2833*5e7646d2SAndroid Build Coastguard Worker }
2834*5e7646d2SAndroid Build Coastguard Worker
2835*5e7646d2SAndroid Build Coastguard Worker
2836*5e7646d2SAndroid Build Coastguard Worker /*
2837*5e7646d2SAndroid Build Coastguard Worker * 'ippReadFile()' - Read data for an IPP message from a file.
2838*5e7646d2SAndroid Build Coastguard Worker *
2839*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.1.19/macOS 10.3@
2840*5e7646d2SAndroid Build Coastguard Worker */
2841*5e7646d2SAndroid Build Coastguard Worker
2842*5e7646d2SAndroid Build Coastguard Worker ipp_state_t /* O - Current state */
ippReadFile(int fd,ipp_t * ipp)2843*5e7646d2SAndroid Build Coastguard Worker ippReadFile(int fd, /* I - HTTP data */
2844*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp) /* I - IPP data */
2845*5e7646d2SAndroid Build Coastguard Worker {
2846*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippReadFile(fd=%d, ipp=%p)", fd, (void *)ipp));
2847*5e7646d2SAndroid Build Coastguard Worker
2848*5e7646d2SAndroid Build Coastguard Worker return (ippReadIO(&fd, (ipp_iocb_t)ipp_read_file, 1, NULL, ipp));
2849*5e7646d2SAndroid Build Coastguard Worker }
2850*5e7646d2SAndroid Build Coastguard Worker
2851*5e7646d2SAndroid Build Coastguard Worker
2852*5e7646d2SAndroid Build Coastguard Worker /*
2853*5e7646d2SAndroid Build Coastguard Worker * 'ippReadIO()' - Read data for an IPP message.
2854*5e7646d2SAndroid Build Coastguard Worker *
2855*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
2856*5e7646d2SAndroid Build Coastguard Worker */
2857*5e7646d2SAndroid Build Coastguard Worker
2858*5e7646d2SAndroid Build Coastguard Worker ipp_state_t /* O - Current state */
ippReadIO(void * src,ipp_iocb_t cb,int blocking,ipp_t * parent,ipp_t * ipp)2859*5e7646d2SAndroid Build Coastguard Worker ippReadIO(void *src, /* I - Data source */
2860*5e7646d2SAndroid Build Coastguard Worker ipp_iocb_t cb, /* I - Read callback function */
2861*5e7646d2SAndroid Build Coastguard Worker int blocking, /* I - Use blocking IO? */
2862*5e7646d2SAndroid Build Coastguard Worker ipp_t *parent, /* I - Parent request, if any */
2863*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp) /* I - IPP data */
2864*5e7646d2SAndroid Build Coastguard Worker {
2865*5e7646d2SAndroid Build Coastguard Worker int n; /* Length of data */
2866*5e7646d2SAndroid Build Coastguard Worker unsigned char *buffer, /* Data buffer */
2867*5e7646d2SAndroid Build Coastguard Worker string[IPP_MAX_TEXT],
2868*5e7646d2SAndroid Build Coastguard Worker /* Small string buffer */
2869*5e7646d2SAndroid Build Coastguard Worker *bufptr, /* Pointer into buffer */
2870*5e7646d2SAndroid Build Coastguard Worker *bufend; /* End of buffer */
2871*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr = NULL; /* Current attribute */
2872*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t tag; /* Current tag */
2873*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag; /* Current value tag */
2874*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
2875*5e7646d2SAndroid Build Coastguard Worker
2876*5e7646d2SAndroid Build Coastguard Worker
2877*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippReadIO(src=%p, cb=%p, blocking=%d, parent=%p, ipp=%p)", (void *)src, (void *)cb, blocking, (void *)parent, (void *)ipp));
2878*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: ipp->state=%d", ipp ? ipp->state : IPP_STATE_ERROR));
2879*5e7646d2SAndroid Build Coastguard Worker
2880*5e7646d2SAndroid Build Coastguard Worker if (!src || !ipp)
2881*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
2882*5e7646d2SAndroid Build Coastguard Worker
2883*5e7646d2SAndroid Build Coastguard Worker if ((buffer = (unsigned char *)_cupsBufferGet(IPP_BUF_SIZE)) == NULL)
2884*5e7646d2SAndroid Build Coastguard Worker {
2885*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to get read buffer.");
2886*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
2887*5e7646d2SAndroid Build Coastguard Worker }
2888*5e7646d2SAndroid Build Coastguard Worker
2889*5e7646d2SAndroid Build Coastguard Worker switch (ipp->state)
2890*5e7646d2SAndroid Build Coastguard Worker {
2891*5e7646d2SAndroid Build Coastguard Worker case IPP_STATE_IDLE :
2892*5e7646d2SAndroid Build Coastguard Worker ipp->state ++; /* Avoid common problem... */
2893*5e7646d2SAndroid Build Coastguard Worker
2894*5e7646d2SAndroid Build Coastguard Worker case IPP_STATE_HEADER :
2895*5e7646d2SAndroid Build Coastguard Worker if (parent == NULL)
2896*5e7646d2SAndroid Build Coastguard Worker {
2897*5e7646d2SAndroid Build Coastguard Worker /*
2898*5e7646d2SAndroid Build Coastguard Worker * Get the request header...
2899*5e7646d2SAndroid Build Coastguard Worker */
2900*5e7646d2SAndroid Build Coastguard Worker
2901*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, 8) < 8)
2902*5e7646d2SAndroid Build Coastguard Worker {
2903*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read header.");
2904*5e7646d2SAndroid Build Coastguard Worker goto rollback;
2905*5e7646d2SAndroid Build Coastguard Worker }
2906*5e7646d2SAndroid Build Coastguard Worker
2907*5e7646d2SAndroid Build Coastguard Worker /*
2908*5e7646d2SAndroid Build Coastguard Worker * Then copy the request header over...
2909*5e7646d2SAndroid Build Coastguard Worker */
2910*5e7646d2SAndroid Build Coastguard Worker
2911*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.version[0] = buffer[0];
2912*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.version[1] = buffer[1];
2913*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.op_status = (buffer[2] << 8) | buffer[3];
2914*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.request_id = (((((buffer[4] << 8) | buffer[5]) << 8) |
2915*5e7646d2SAndroid Build Coastguard Worker buffer[6]) << 8) | buffer[7];
2916*5e7646d2SAndroid Build Coastguard Worker
2917*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: version=%d.%d", buffer[0], buffer[1]));
2918*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: op_status=%04x",
2919*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.op_status));
2920*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: request_id=%d",
2921*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.request_id));
2922*5e7646d2SAndroid Build Coastguard Worker }
2923*5e7646d2SAndroid Build Coastguard Worker
2924*5e7646d2SAndroid Build Coastguard Worker ipp->state = IPP_STATE_ATTRIBUTE;
2925*5e7646d2SAndroid Build Coastguard Worker ipp->current = NULL;
2926*5e7646d2SAndroid Build Coastguard Worker ipp->curtag = IPP_TAG_ZERO;
2927*5e7646d2SAndroid Build Coastguard Worker ipp->prev = ipp->last;
2928*5e7646d2SAndroid Build Coastguard Worker
2929*5e7646d2SAndroid Build Coastguard Worker /*
2930*5e7646d2SAndroid Build Coastguard Worker * If blocking is disabled, stop here...
2931*5e7646d2SAndroid Build Coastguard Worker */
2932*5e7646d2SAndroid Build Coastguard Worker
2933*5e7646d2SAndroid Build Coastguard Worker if (!blocking)
2934*5e7646d2SAndroid Build Coastguard Worker break;
2935*5e7646d2SAndroid Build Coastguard Worker
2936*5e7646d2SAndroid Build Coastguard Worker case IPP_STATE_ATTRIBUTE :
2937*5e7646d2SAndroid Build Coastguard Worker for (;;)
2938*5e7646d2SAndroid Build Coastguard Worker {
2939*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, 1) < 1)
2940*5e7646d2SAndroid Build Coastguard Worker {
2941*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Callback returned EOF/error");
2942*5e7646d2SAndroid Build Coastguard Worker goto rollback;
2943*5e7646d2SAndroid Build Coastguard Worker }
2944*5e7646d2SAndroid Build Coastguard Worker
2945*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: ipp->current=%p, ipp->prev=%p", (void *)ipp->current, (void *)ipp->prev));
2946*5e7646d2SAndroid Build Coastguard Worker
2947*5e7646d2SAndroid Build Coastguard Worker /*
2948*5e7646d2SAndroid Build Coastguard Worker * Read this attribute...
2949*5e7646d2SAndroid Build Coastguard Worker */
2950*5e7646d2SAndroid Build Coastguard Worker
2951*5e7646d2SAndroid Build Coastguard Worker tag = (ipp_tag_t)buffer[0];
2952*5e7646d2SAndroid Build Coastguard Worker if (tag == IPP_TAG_EXTENSION)
2953*5e7646d2SAndroid Build Coastguard Worker {
2954*5e7646d2SAndroid Build Coastguard Worker /*
2955*5e7646d2SAndroid Build Coastguard Worker * Read 32-bit "extension" tag...
2956*5e7646d2SAndroid Build Coastguard Worker */
2957*5e7646d2SAndroid Build Coastguard Worker
2958*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, 4) < 4)
2959*5e7646d2SAndroid Build Coastguard Worker {
2960*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Callback returned EOF/error");
2961*5e7646d2SAndroid Build Coastguard Worker goto rollback;
2962*5e7646d2SAndroid Build Coastguard Worker }
2963*5e7646d2SAndroid Build Coastguard Worker
2964*5e7646d2SAndroid Build Coastguard Worker tag = (ipp_tag_t)((((((buffer[0] << 8) | buffer[1]) << 8) |
2965*5e7646d2SAndroid Build Coastguard Worker buffer[2]) << 8) | buffer[3]);
2966*5e7646d2SAndroid Build Coastguard Worker
2967*5e7646d2SAndroid Build Coastguard Worker if (tag & IPP_TAG_CUPS_CONST)
2968*5e7646d2SAndroid Build Coastguard Worker {
2969*5e7646d2SAndroid Build Coastguard Worker /*
2970*5e7646d2SAndroid Build Coastguard Worker * Fail if the high bit is set in the tag...
2971*5e7646d2SAndroid Build Coastguard Worker */
2972*5e7646d2SAndroid Build Coastguard Worker
2973*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("IPP extension tag larger than 0x7FFFFFFF."), 1);
2974*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad tag 0x%x.", tag));
2975*5e7646d2SAndroid Build Coastguard Worker goto rollback;
2976*5e7646d2SAndroid Build Coastguard Worker }
2977*5e7646d2SAndroid Build Coastguard Worker }
2978*5e7646d2SAndroid Build Coastguard Worker
2979*5e7646d2SAndroid Build Coastguard Worker if (tag == IPP_TAG_END)
2980*5e7646d2SAndroid Build Coastguard Worker {
2981*5e7646d2SAndroid Build Coastguard Worker /*
2982*5e7646d2SAndroid Build Coastguard Worker * No more attributes left...
2983*5e7646d2SAndroid Build Coastguard Worker */
2984*5e7646d2SAndroid Build Coastguard Worker
2985*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("2ippReadIO: IPP_TAG_END.");
2986*5e7646d2SAndroid Build Coastguard Worker
2987*5e7646d2SAndroid Build Coastguard Worker ipp->state = IPP_STATE_DATA;
2988*5e7646d2SAndroid Build Coastguard Worker break;
2989*5e7646d2SAndroid Build Coastguard Worker }
2990*5e7646d2SAndroid Build Coastguard Worker else if (tag == IPP_TAG_ZERO || (tag == IPP_TAG_OPERATION && ipp->curtag != IPP_TAG_ZERO))
2991*5e7646d2SAndroid Build Coastguard Worker {
2992*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Invalid group tag."), 1);
2993*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad tag 0x%02x.", tag));
2994*5e7646d2SAndroid Build Coastguard Worker goto rollback;
2995*5e7646d2SAndroid Build Coastguard Worker }
2996*5e7646d2SAndroid Build Coastguard Worker else if (tag < IPP_TAG_UNSUPPORTED_VALUE)
2997*5e7646d2SAndroid Build Coastguard Worker {
2998*5e7646d2SAndroid Build Coastguard Worker /*
2999*5e7646d2SAndroid Build Coastguard Worker * Group tag... Set the current group and continue...
3000*5e7646d2SAndroid Build Coastguard Worker */
3001*5e7646d2SAndroid Build Coastguard Worker
3002*5e7646d2SAndroid Build Coastguard Worker if (parent)
3003*5e7646d2SAndroid Build Coastguard Worker {
3004*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Invalid group tag."), 1);
3005*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad tag 0x%02x.", tag));
3006*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3007*5e7646d2SAndroid Build Coastguard Worker }
3008*5e7646d2SAndroid Build Coastguard Worker else if (ipp->curtag == tag)
3009*5e7646d2SAndroid Build Coastguard Worker ipp->prev = ippAddSeparator(ipp);
3010*5e7646d2SAndroid Build Coastguard Worker else if (ipp->current)
3011*5e7646d2SAndroid Build Coastguard Worker ipp->prev = ipp->current;
3012*5e7646d2SAndroid Build Coastguard Worker
3013*5e7646d2SAndroid Build Coastguard Worker ipp->curtag = tag;
3014*5e7646d2SAndroid Build Coastguard Worker ipp->current = NULL;
3015*5e7646d2SAndroid Build Coastguard Worker attr = NULL;
3016*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: group tag=%x(%s), ipp->prev=%p", tag, ippTagString(tag), (void *)ipp->prev));
3017*5e7646d2SAndroid Build Coastguard Worker continue;
3018*5e7646d2SAndroid Build Coastguard Worker }
3019*5e7646d2SAndroid Build Coastguard Worker
3020*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: value tag=%x(%s)", tag,
3021*5e7646d2SAndroid Build Coastguard Worker ippTagString(tag)));
3022*5e7646d2SAndroid Build Coastguard Worker
3023*5e7646d2SAndroid Build Coastguard Worker /*
3024*5e7646d2SAndroid Build Coastguard Worker * Get the name...
3025*5e7646d2SAndroid Build Coastguard Worker */
3026*5e7646d2SAndroid Build Coastguard Worker
3027*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, 2) < 2)
3028*5e7646d2SAndroid Build Coastguard Worker {
3029*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: unable to read name length.");
3030*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3031*5e7646d2SAndroid Build Coastguard Worker }
3032*5e7646d2SAndroid Build Coastguard Worker
3033*5e7646d2SAndroid Build Coastguard Worker n = (buffer[0] << 8) | buffer[1];
3034*5e7646d2SAndroid Build Coastguard Worker
3035*5e7646d2SAndroid Build Coastguard Worker if (n >= IPP_BUF_SIZE)
3036*5e7646d2SAndroid Build Coastguard Worker {
3037*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("IPP name larger than 32767 bytes."), 1);
3038*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad name length %d.", n));
3039*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3040*5e7646d2SAndroid Build Coastguard Worker }
3041*5e7646d2SAndroid Build Coastguard Worker
3042*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: name length=%d", n));
3043*5e7646d2SAndroid Build Coastguard Worker
3044*5e7646d2SAndroid Build Coastguard Worker if (n && parent)
3045*5e7646d2SAndroid Build Coastguard Worker {
3046*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Invalid named IPP attribute in collection."), 1);
3047*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: bad attribute name in collection.");
3048*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3049*5e7646d2SAndroid Build Coastguard Worker }
3050*5e7646d2SAndroid Build Coastguard Worker else if (n == 0 && tag != IPP_TAG_MEMBERNAME && tag != IPP_TAG_END_COLLECTION)
3051*5e7646d2SAndroid Build Coastguard Worker {
3052*5e7646d2SAndroid Build Coastguard Worker /*
3053*5e7646d2SAndroid Build Coastguard Worker * More values for current attribute...
3054*5e7646d2SAndroid Build Coastguard Worker */
3055*5e7646d2SAndroid Build Coastguard Worker
3056*5e7646d2SAndroid Build Coastguard Worker if (ipp->current == NULL)
3057*5e7646d2SAndroid Build Coastguard Worker {
3058*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("IPP attribute has no name."), 1);
3059*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Attribute without name and no current.");
3060*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3061*5e7646d2SAndroid Build Coastguard Worker }
3062*5e7646d2SAndroid Build Coastguard Worker
3063*5e7646d2SAndroid Build Coastguard Worker attr = ipp->current;
3064*5e7646d2SAndroid Build Coastguard Worker value_tag = (ipp_tag_t)(attr->value_tag & IPP_TAG_CUPS_MASK);
3065*5e7646d2SAndroid Build Coastguard Worker
3066*5e7646d2SAndroid Build Coastguard Worker /*
3067*5e7646d2SAndroid Build Coastguard Worker * Make sure we aren't adding a new value of a different
3068*5e7646d2SAndroid Build Coastguard Worker * type...
3069*5e7646d2SAndroid Build Coastguard Worker */
3070*5e7646d2SAndroid Build Coastguard Worker
3071*5e7646d2SAndroid Build Coastguard Worker if (value_tag == IPP_TAG_ZERO)
3072*5e7646d2SAndroid Build Coastguard Worker {
3073*5e7646d2SAndroid Build Coastguard Worker /*
3074*5e7646d2SAndroid Build Coastguard Worker * Setting the value of a collection member...
3075*5e7646d2SAndroid Build Coastguard Worker */
3076*5e7646d2SAndroid Build Coastguard Worker
3077*5e7646d2SAndroid Build Coastguard Worker attr->value_tag = tag;
3078*5e7646d2SAndroid Build Coastguard Worker }
3079*5e7646d2SAndroid Build Coastguard Worker else if (value_tag == IPP_TAG_TEXTLANG ||
3080*5e7646d2SAndroid Build Coastguard Worker value_tag == IPP_TAG_NAMELANG ||
3081*5e7646d2SAndroid Build Coastguard Worker (value_tag >= IPP_TAG_TEXT &&
3082*5e7646d2SAndroid Build Coastguard Worker value_tag <= IPP_TAG_MIMETYPE))
3083*5e7646d2SAndroid Build Coastguard Worker {
3084*5e7646d2SAndroid Build Coastguard Worker /*
3085*5e7646d2SAndroid Build Coastguard Worker * String values can sometimes come across in different
3086*5e7646d2SAndroid Build Coastguard Worker * forms; accept sets of differing values...
3087*5e7646d2SAndroid Build Coastguard Worker */
3088*5e7646d2SAndroid Build Coastguard Worker
3089*5e7646d2SAndroid Build Coastguard Worker if (tag != IPP_TAG_TEXTLANG && tag != IPP_TAG_NAMELANG &&
3090*5e7646d2SAndroid Build Coastguard Worker (tag < IPP_TAG_TEXT || tag > IPP_TAG_MIMETYPE) &&
3091*5e7646d2SAndroid Build Coastguard Worker tag != IPP_TAG_NOVALUE)
3092*5e7646d2SAndroid Build Coastguard Worker {
3093*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3094*5e7646d2SAndroid Build Coastguard Worker _("IPP 1setOf attribute with incompatible value "
3095*5e7646d2SAndroid Build Coastguard Worker "tags."), 1);
3096*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: 1setOf value tag %x(%s) != %x(%s)",
3097*5e7646d2SAndroid Build Coastguard Worker value_tag, ippTagString(value_tag), tag,
3098*5e7646d2SAndroid Build Coastguard Worker ippTagString(tag)));
3099*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3100*5e7646d2SAndroid Build Coastguard Worker }
3101*5e7646d2SAndroid Build Coastguard Worker
3102*5e7646d2SAndroid Build Coastguard Worker if (value_tag != tag)
3103*5e7646d2SAndroid Build Coastguard Worker {
3104*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: Converting %s attribute from %s to %s.",
3105*5e7646d2SAndroid Build Coastguard Worker attr->name, ippTagString(value_tag), ippTagString(tag)));
3106*5e7646d2SAndroid Build Coastguard Worker ippSetValueTag(ipp, &attr, tag);
3107*5e7646d2SAndroid Build Coastguard Worker }
3108*5e7646d2SAndroid Build Coastguard Worker }
3109*5e7646d2SAndroid Build Coastguard Worker else if (value_tag == IPP_TAG_INTEGER ||
3110*5e7646d2SAndroid Build Coastguard Worker value_tag == IPP_TAG_RANGE)
3111*5e7646d2SAndroid Build Coastguard Worker {
3112*5e7646d2SAndroid Build Coastguard Worker /*
3113*5e7646d2SAndroid Build Coastguard Worker * Integer and rangeOfInteger values can sometimes be mixed; accept
3114*5e7646d2SAndroid Build Coastguard Worker * sets of differing values...
3115*5e7646d2SAndroid Build Coastguard Worker */
3116*5e7646d2SAndroid Build Coastguard Worker
3117*5e7646d2SAndroid Build Coastguard Worker if (tag != IPP_TAG_INTEGER && tag != IPP_TAG_RANGE)
3118*5e7646d2SAndroid Build Coastguard Worker {
3119*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3120*5e7646d2SAndroid Build Coastguard Worker _("IPP 1setOf attribute with incompatible value "
3121*5e7646d2SAndroid Build Coastguard Worker "tags."), 1);
3122*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: 1setOf value tag %x(%s) != %x(%s)",
3123*5e7646d2SAndroid Build Coastguard Worker value_tag, ippTagString(value_tag), tag,
3124*5e7646d2SAndroid Build Coastguard Worker ippTagString(tag)));
3125*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3126*5e7646d2SAndroid Build Coastguard Worker }
3127*5e7646d2SAndroid Build Coastguard Worker
3128*5e7646d2SAndroid Build Coastguard Worker if (value_tag == IPP_TAG_INTEGER && tag == IPP_TAG_RANGE)
3129*5e7646d2SAndroid Build Coastguard Worker {
3130*5e7646d2SAndroid Build Coastguard Worker /*
3131*5e7646d2SAndroid Build Coastguard Worker * Convert integer values to rangeOfInteger values...
3132*5e7646d2SAndroid Build Coastguard Worker */
3133*5e7646d2SAndroid Build Coastguard Worker
3134*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: Converting %s attribute to "
3135*5e7646d2SAndroid Build Coastguard Worker "rangeOfInteger.", attr->name));
3136*5e7646d2SAndroid Build Coastguard Worker ippSetValueTag(ipp, &attr, IPP_TAG_RANGE);
3137*5e7646d2SAndroid Build Coastguard Worker }
3138*5e7646d2SAndroid Build Coastguard Worker }
3139*5e7646d2SAndroid Build Coastguard Worker else if (value_tag != tag)
3140*5e7646d2SAndroid Build Coastguard Worker {
3141*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3142*5e7646d2SAndroid Build Coastguard Worker _("IPP 1setOf attribute with incompatible value "
3143*5e7646d2SAndroid Build Coastguard Worker "tags."), 1);
3144*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: value tag %x(%s) != %x(%s)",
3145*5e7646d2SAndroid Build Coastguard Worker value_tag, ippTagString(value_tag), tag,
3146*5e7646d2SAndroid Build Coastguard Worker ippTagString(tag)));
3147*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3148*5e7646d2SAndroid Build Coastguard Worker }
3149*5e7646d2SAndroid Build Coastguard Worker
3150*5e7646d2SAndroid Build Coastguard Worker /*
3151*5e7646d2SAndroid Build Coastguard Worker * Finally, reallocate the attribute array as needed...
3152*5e7646d2SAndroid Build Coastguard Worker */
3153*5e7646d2SAndroid Build Coastguard Worker
3154*5e7646d2SAndroid Build Coastguard Worker if ((value = ipp_set_value(ipp, &attr, attr->num_values)) == NULL)
3155*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3156*5e7646d2SAndroid Build Coastguard Worker }
3157*5e7646d2SAndroid Build Coastguard Worker else if (tag == IPP_TAG_MEMBERNAME)
3158*5e7646d2SAndroid Build Coastguard Worker {
3159*5e7646d2SAndroid Build Coastguard Worker /*
3160*5e7646d2SAndroid Build Coastguard Worker * Name must be length 0!
3161*5e7646d2SAndroid Build Coastguard Worker */
3162*5e7646d2SAndroid Build Coastguard Worker
3163*5e7646d2SAndroid Build Coastguard Worker if (n)
3164*5e7646d2SAndroid Build Coastguard Worker {
3165*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("IPP member name is not empty."), 1);
3166*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: member name not empty.");
3167*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3168*5e7646d2SAndroid Build Coastguard Worker }
3169*5e7646d2SAndroid Build Coastguard Worker else if (!parent)
3170*5e7646d2SAndroid Build Coastguard Worker {
3171*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("IPP member attribute outside of collection."), 1);
3172*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: member attribute outside of collection.");
3173*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3174*5e7646d2SAndroid Build Coastguard Worker }
3175*5e7646d2SAndroid Build Coastguard Worker
3176*5e7646d2SAndroid Build Coastguard Worker if (ipp->current)
3177*5e7646d2SAndroid Build Coastguard Worker ipp->prev = ipp->current;
3178*5e7646d2SAndroid Build Coastguard Worker
3179*5e7646d2SAndroid Build Coastguard Worker attr = ipp->current = ipp_add_attr(ipp, NULL, ipp->curtag, IPP_TAG_ZERO, 1);
3180*5e7646d2SAndroid Build Coastguard Worker if (!attr)
3181*5e7646d2SAndroid Build Coastguard Worker {
3182*5e7646d2SAndroid Build Coastguard Worker _cupsSetHTTPError(HTTP_STATUS_ERROR);
3183*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: unable to allocate attribute.");
3184*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3185*5e7646d2SAndroid Build Coastguard Worker }
3186*5e7646d2SAndroid Build Coastguard Worker
3187*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: membername, ipp->current=%p, ipp->prev=%p", (void *)ipp->current, (void *)ipp->prev));
3188*5e7646d2SAndroid Build Coastguard Worker
3189*5e7646d2SAndroid Build Coastguard Worker value = attr->values;
3190*5e7646d2SAndroid Build Coastguard Worker }
3191*5e7646d2SAndroid Build Coastguard Worker else if (tag != IPP_TAG_END_COLLECTION)
3192*5e7646d2SAndroid Build Coastguard Worker {
3193*5e7646d2SAndroid Build Coastguard Worker /*
3194*5e7646d2SAndroid Build Coastguard Worker * New attribute; read the name and add it...
3195*5e7646d2SAndroid Build Coastguard Worker */
3196*5e7646d2SAndroid Build Coastguard Worker
3197*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, (size_t)n) < n)
3198*5e7646d2SAndroid Build Coastguard Worker {
3199*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: unable to read name.");
3200*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3201*5e7646d2SAndroid Build Coastguard Worker }
3202*5e7646d2SAndroid Build Coastguard Worker
3203*5e7646d2SAndroid Build Coastguard Worker buffer[n] = '\0';
3204*5e7646d2SAndroid Build Coastguard Worker
3205*5e7646d2SAndroid Build Coastguard Worker if (ipp->current)
3206*5e7646d2SAndroid Build Coastguard Worker ipp->prev = ipp->current;
3207*5e7646d2SAndroid Build Coastguard Worker
3208*5e7646d2SAndroid Build Coastguard Worker if ((attr = ipp->current = ipp_add_attr(ipp, (char *)buffer, ipp->curtag, tag,
3209*5e7646d2SAndroid Build Coastguard Worker 1)) == NULL)
3210*5e7646d2SAndroid Build Coastguard Worker {
3211*5e7646d2SAndroid Build Coastguard Worker _cupsSetHTTPError(HTTP_STATUS_ERROR);
3212*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: unable to allocate attribute.");
3213*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3214*5e7646d2SAndroid Build Coastguard Worker }
3215*5e7646d2SAndroid Build Coastguard Worker
3216*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: name=\"%s\", ipp->current=%p, ipp->prev=%p", buffer, (void *)ipp->current, (void *)ipp->prev));
3217*5e7646d2SAndroid Build Coastguard Worker
3218*5e7646d2SAndroid Build Coastguard Worker value = attr->values;
3219*5e7646d2SAndroid Build Coastguard Worker }
3220*5e7646d2SAndroid Build Coastguard Worker else
3221*5e7646d2SAndroid Build Coastguard Worker {
3222*5e7646d2SAndroid Build Coastguard Worker attr = NULL;
3223*5e7646d2SAndroid Build Coastguard Worker value = NULL;
3224*5e7646d2SAndroid Build Coastguard Worker }
3225*5e7646d2SAndroid Build Coastguard Worker
3226*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, 2) < 2)
3227*5e7646d2SAndroid Build Coastguard Worker {
3228*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: unable to read value length.");
3229*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3230*5e7646d2SAndroid Build Coastguard Worker }
3231*5e7646d2SAndroid Build Coastguard Worker
3232*5e7646d2SAndroid Build Coastguard Worker n = (buffer[0] << 8) | buffer[1];
3233*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: value length=%d", n));
3234*5e7646d2SAndroid Build Coastguard Worker
3235*5e7646d2SAndroid Build Coastguard Worker if (n >= IPP_BUF_SIZE)
3236*5e7646d2SAndroid Build Coastguard Worker {
3237*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3238*5e7646d2SAndroid Build Coastguard Worker _("IPP value larger than 32767 bytes."), 1);
3239*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad value length %d.", n));
3240*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3241*5e7646d2SAndroid Build Coastguard Worker }
3242*5e7646d2SAndroid Build Coastguard Worker
3243*5e7646d2SAndroid Build Coastguard Worker switch (tag)
3244*5e7646d2SAndroid Build Coastguard Worker {
3245*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
3246*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
3247*5e7646d2SAndroid Build Coastguard Worker if (n != 4)
3248*5e7646d2SAndroid Build Coastguard Worker {
3249*5e7646d2SAndroid Build Coastguard Worker if (tag == IPP_TAG_INTEGER)
3250*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3251*5e7646d2SAndroid Build Coastguard Worker _("IPP integer value not 4 bytes."), 1);
3252*5e7646d2SAndroid Build Coastguard Worker else
3253*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3254*5e7646d2SAndroid Build Coastguard Worker _("IPP enum value not 4 bytes."), 1);
3255*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad integer value length %d.", n));
3256*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3257*5e7646d2SAndroid Build Coastguard Worker }
3258*5e7646d2SAndroid Build Coastguard Worker
3259*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, 4) < 4)
3260*5e7646d2SAndroid Build Coastguard Worker {
3261*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read integer value.");
3262*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3263*5e7646d2SAndroid Build Coastguard Worker }
3264*5e7646d2SAndroid Build Coastguard Worker
3265*5e7646d2SAndroid Build Coastguard Worker n = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
3266*5e7646d2SAndroid Build Coastguard Worker buffer[3];
3267*5e7646d2SAndroid Build Coastguard Worker
3268*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag == IPP_TAG_RANGE)
3269*5e7646d2SAndroid Build Coastguard Worker value->range.lower = value->range.upper = n;
3270*5e7646d2SAndroid Build Coastguard Worker else
3271*5e7646d2SAndroid Build Coastguard Worker value->integer = n;
3272*5e7646d2SAndroid Build Coastguard Worker break;
3273*5e7646d2SAndroid Build Coastguard Worker
3274*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
3275*5e7646d2SAndroid Build Coastguard Worker if (n != 1)
3276*5e7646d2SAndroid Build Coastguard Worker {
3277*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("IPP boolean value not 1 byte."),
3278*5e7646d2SAndroid Build Coastguard Worker 1);
3279*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad boolean value length %d.", n));
3280*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3281*5e7646d2SAndroid Build Coastguard Worker }
3282*5e7646d2SAndroid Build Coastguard Worker
3283*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, 1) < 1)
3284*5e7646d2SAndroid Build Coastguard Worker {
3285*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read boolean value.");
3286*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3287*5e7646d2SAndroid Build Coastguard Worker }
3288*5e7646d2SAndroid Build Coastguard Worker
3289*5e7646d2SAndroid Build Coastguard Worker value->boolean = (char)buffer[0];
3290*5e7646d2SAndroid Build Coastguard Worker break;
3291*5e7646d2SAndroid Build Coastguard Worker
3292*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNSUPPORTED_VALUE :
3293*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DEFAULT :
3294*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNKNOWN :
3295*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOVALUE :
3296*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOTSETTABLE :
3297*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DELETEATTR :
3298*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ADMINDEFINE :
3299*5e7646d2SAndroid Build Coastguard Worker /*
3300*5e7646d2SAndroid Build Coastguard Worker * These value types are not supposed to have values, however
3301*5e7646d2SAndroid Build Coastguard Worker * some vendors (Brother) do not implement IPP correctly and so
3302*5e7646d2SAndroid Build Coastguard Worker * we need to map non-empty values to text...
3303*5e7646d2SAndroid Build Coastguard Worker */
3304*5e7646d2SAndroid Build Coastguard Worker
3305*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag == tag)
3306*5e7646d2SAndroid Build Coastguard Worker {
3307*5e7646d2SAndroid Build Coastguard Worker if (n == 0)
3308*5e7646d2SAndroid Build Coastguard Worker break;
3309*5e7646d2SAndroid Build Coastguard Worker
3310*5e7646d2SAndroid Build Coastguard Worker attr->value_tag = IPP_TAG_TEXT;
3311*5e7646d2SAndroid Build Coastguard Worker }
3312*5e7646d2SAndroid Build Coastguard Worker
3313*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
3314*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
3315*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESERVED_STRING :
3316*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
3317*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
3318*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
3319*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
3320*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
3321*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
3322*5e7646d2SAndroid Build Coastguard Worker if (n > 0)
3323*5e7646d2SAndroid Build Coastguard Worker {
3324*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, (size_t)n) < n)
3325*5e7646d2SAndroid Build Coastguard Worker {
3326*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: unable to read string value.");
3327*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3328*5e7646d2SAndroid Build Coastguard Worker }
3329*5e7646d2SAndroid Build Coastguard Worker }
3330*5e7646d2SAndroid Build Coastguard Worker
3331*5e7646d2SAndroid Build Coastguard Worker buffer[n] = '\0';
3332*5e7646d2SAndroid Build Coastguard Worker value->string.text = _cupsStrAlloc((char *)buffer);
3333*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: value=\"%s\"", value->string.text));
3334*5e7646d2SAndroid Build Coastguard Worker break;
3335*5e7646d2SAndroid Build Coastguard Worker
3336*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DATE :
3337*5e7646d2SAndroid Build Coastguard Worker if (n != 11)
3338*5e7646d2SAndroid Build Coastguard Worker {
3339*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("IPP date value not 11 bytes."), 1);
3340*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad date value length %d.", n));
3341*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3342*5e7646d2SAndroid Build Coastguard Worker }
3343*5e7646d2SAndroid Build Coastguard Worker
3344*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, value->date, 11) < 11)
3345*5e7646d2SAndroid Build Coastguard Worker {
3346*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read date value.");
3347*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3348*5e7646d2SAndroid Build Coastguard Worker }
3349*5e7646d2SAndroid Build Coastguard Worker break;
3350*5e7646d2SAndroid Build Coastguard Worker
3351*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
3352*5e7646d2SAndroid Build Coastguard Worker if (n != 9)
3353*5e7646d2SAndroid Build Coastguard Worker {
3354*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3355*5e7646d2SAndroid Build Coastguard Worker _("IPP resolution value not 9 bytes."), 1);
3356*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad resolution value length %d.", n));
3357*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3358*5e7646d2SAndroid Build Coastguard Worker }
3359*5e7646d2SAndroid Build Coastguard Worker
3360*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, 9) < 9)
3361*5e7646d2SAndroid Build Coastguard Worker {
3362*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read resolution value.");
3363*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3364*5e7646d2SAndroid Build Coastguard Worker }
3365*5e7646d2SAndroid Build Coastguard Worker
3366*5e7646d2SAndroid Build Coastguard Worker value->resolution.xres =
3367*5e7646d2SAndroid Build Coastguard Worker (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
3368*5e7646d2SAndroid Build Coastguard Worker buffer[3];
3369*5e7646d2SAndroid Build Coastguard Worker value->resolution.yres =
3370*5e7646d2SAndroid Build Coastguard Worker (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) |
3371*5e7646d2SAndroid Build Coastguard Worker buffer[7];
3372*5e7646d2SAndroid Build Coastguard Worker value->resolution.units =
3373*5e7646d2SAndroid Build Coastguard Worker (ipp_res_t)buffer[8];
3374*5e7646d2SAndroid Build Coastguard Worker break;
3375*5e7646d2SAndroid Build Coastguard Worker
3376*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
3377*5e7646d2SAndroid Build Coastguard Worker if (n != 8)
3378*5e7646d2SAndroid Build Coastguard Worker {
3379*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3380*5e7646d2SAndroid Build Coastguard Worker _("IPP rangeOfInteger value not 8 bytes."), 1);
3381*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad rangeOfInteger value length "
3382*5e7646d2SAndroid Build Coastguard Worker "%d.", n));
3383*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3384*5e7646d2SAndroid Build Coastguard Worker }
3385*5e7646d2SAndroid Build Coastguard Worker
3386*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, 8) < 8)
3387*5e7646d2SAndroid Build Coastguard Worker {
3388*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read range value.");
3389*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3390*5e7646d2SAndroid Build Coastguard Worker }
3391*5e7646d2SAndroid Build Coastguard Worker
3392*5e7646d2SAndroid Build Coastguard Worker value->range.lower =
3393*5e7646d2SAndroid Build Coastguard Worker (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
3394*5e7646d2SAndroid Build Coastguard Worker buffer[3];
3395*5e7646d2SAndroid Build Coastguard Worker value->range.upper =
3396*5e7646d2SAndroid Build Coastguard Worker (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) |
3397*5e7646d2SAndroid Build Coastguard Worker buffer[7];
3398*5e7646d2SAndroid Build Coastguard Worker break;
3399*5e7646d2SAndroid Build Coastguard Worker
3400*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
3401*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
3402*5e7646d2SAndroid Build Coastguard Worker if (n < 4)
3403*5e7646d2SAndroid Build Coastguard Worker {
3404*5e7646d2SAndroid Build Coastguard Worker if (tag == IPP_TAG_TEXTLANG)
3405*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3406*5e7646d2SAndroid Build Coastguard Worker _("IPP textWithLanguage value less than "
3407*5e7646d2SAndroid Build Coastguard Worker "minimum 4 bytes."), 1);
3408*5e7646d2SAndroid Build Coastguard Worker else
3409*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3410*5e7646d2SAndroid Build Coastguard Worker _("IPP nameWithLanguage value less than "
3411*5e7646d2SAndroid Build Coastguard Worker "minimum 4 bytes."), 1);
3412*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad stringWithLanguage value "
3413*5e7646d2SAndroid Build Coastguard Worker "length %d.", n));
3414*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3415*5e7646d2SAndroid Build Coastguard Worker }
3416*5e7646d2SAndroid Build Coastguard Worker
3417*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, buffer, (size_t)n) < n)
3418*5e7646d2SAndroid Build Coastguard Worker {
3419*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read string w/language "
3420*5e7646d2SAndroid Build Coastguard Worker "value.");
3421*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3422*5e7646d2SAndroid Build Coastguard Worker }
3423*5e7646d2SAndroid Build Coastguard Worker
3424*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
3425*5e7646d2SAndroid Build Coastguard Worker bufend = buffer + n;
3426*5e7646d2SAndroid Build Coastguard Worker
3427*5e7646d2SAndroid Build Coastguard Worker /*
3428*5e7646d2SAndroid Build Coastguard Worker * text-with-language and name-with-language are composite
3429*5e7646d2SAndroid Build Coastguard Worker * values:
3430*5e7646d2SAndroid Build Coastguard Worker *
3431*5e7646d2SAndroid Build Coastguard Worker * language-length
3432*5e7646d2SAndroid Build Coastguard Worker * language
3433*5e7646d2SAndroid Build Coastguard Worker * text-length
3434*5e7646d2SAndroid Build Coastguard Worker * text
3435*5e7646d2SAndroid Build Coastguard Worker */
3436*5e7646d2SAndroid Build Coastguard Worker
3437*5e7646d2SAndroid Build Coastguard Worker n = (bufptr[0] << 8) | bufptr[1];
3438*5e7646d2SAndroid Build Coastguard Worker
3439*5e7646d2SAndroid Build Coastguard Worker if ((bufptr + 2 + n + 2) > bufend || n >= (int)sizeof(string))
3440*5e7646d2SAndroid Build Coastguard Worker {
3441*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3442*5e7646d2SAndroid Build Coastguard Worker _("IPP language length overflows value."), 1);
3443*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad language value length %d.",
3444*5e7646d2SAndroid Build Coastguard Worker n));
3445*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3446*5e7646d2SAndroid Build Coastguard Worker }
3447*5e7646d2SAndroid Build Coastguard Worker else if (n >= IPP_MAX_LANGUAGE)
3448*5e7646d2SAndroid Build Coastguard Worker {
3449*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3450*5e7646d2SAndroid Build Coastguard Worker _("IPP language length too large."), 1);
3451*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad language value length %d.",
3452*5e7646d2SAndroid Build Coastguard Worker n));
3453*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3454*5e7646d2SAndroid Build Coastguard Worker }
3455*5e7646d2SAndroid Build Coastguard Worker
3456*5e7646d2SAndroid Build Coastguard Worker memcpy(string, bufptr + 2, (size_t)n);
3457*5e7646d2SAndroid Build Coastguard Worker string[n] = '\0';
3458*5e7646d2SAndroid Build Coastguard Worker
3459*5e7646d2SAndroid Build Coastguard Worker value->string.language = _cupsStrAlloc((char *)string);
3460*5e7646d2SAndroid Build Coastguard Worker
3461*5e7646d2SAndroid Build Coastguard Worker bufptr += 2 + n;
3462*5e7646d2SAndroid Build Coastguard Worker n = (bufptr[0] << 8) | bufptr[1];
3463*5e7646d2SAndroid Build Coastguard Worker
3464*5e7646d2SAndroid Build Coastguard Worker if ((bufptr + 2 + n) > bufend)
3465*5e7646d2SAndroid Build Coastguard Worker {
3466*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3467*5e7646d2SAndroid Build Coastguard Worker _("IPP string length overflows value."), 1);
3468*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad string value length %d.", n));
3469*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3470*5e7646d2SAndroid Build Coastguard Worker }
3471*5e7646d2SAndroid Build Coastguard Worker
3472*5e7646d2SAndroid Build Coastguard Worker bufptr[2 + n] = '\0';
3473*5e7646d2SAndroid Build Coastguard Worker value->string.text = _cupsStrAlloc((char *)bufptr + 2);
3474*5e7646d2SAndroid Build Coastguard Worker break;
3475*5e7646d2SAndroid Build Coastguard Worker
3476*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
3477*5e7646d2SAndroid Build Coastguard Worker /*
3478*5e7646d2SAndroid Build Coastguard Worker * Oh, boy, here comes a collection value, so read it...
3479*5e7646d2SAndroid Build Coastguard Worker */
3480*5e7646d2SAndroid Build Coastguard Worker
3481*5e7646d2SAndroid Build Coastguard Worker value->collection = ippNew();
3482*5e7646d2SAndroid Build Coastguard Worker
3483*5e7646d2SAndroid Build Coastguard Worker if (n > 0)
3484*5e7646d2SAndroid Build Coastguard Worker {
3485*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3486*5e7646d2SAndroid Build Coastguard Worker _("IPP begCollection value not 0 bytes."), 1);
3487*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: begCollection tag with value length "
3488*5e7646d2SAndroid Build Coastguard Worker "> 0.");
3489*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3490*5e7646d2SAndroid Build Coastguard Worker }
3491*5e7646d2SAndroid Build Coastguard Worker
3492*5e7646d2SAndroid Build Coastguard Worker if (ippReadIO(src, cb, 1, ipp, value->collection) == IPP_STATE_ERROR)
3493*5e7646d2SAndroid Build Coastguard Worker {
3494*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read collection value.");
3495*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3496*5e7646d2SAndroid Build Coastguard Worker }
3497*5e7646d2SAndroid Build Coastguard Worker break;
3498*5e7646d2SAndroid Build Coastguard Worker
3499*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_END_COLLECTION :
3500*5e7646d2SAndroid Build Coastguard Worker if (n > 0)
3501*5e7646d2SAndroid Build Coastguard Worker {
3502*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3503*5e7646d2SAndroid Build Coastguard Worker _("IPP endCollection value not 0 bytes."), 1);
3504*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: endCollection tag with value length "
3505*5e7646d2SAndroid Build Coastguard Worker "> 0.");
3506*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3507*5e7646d2SAndroid Build Coastguard Worker }
3508*5e7646d2SAndroid Build Coastguard Worker
3509*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
3510*5e7646d2SAndroid Build Coastguard Worker
3511*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: endCollection tag...");
3512*5e7646d2SAndroid Build Coastguard Worker return (ipp->state = IPP_STATE_DATA);
3513*5e7646d2SAndroid Build Coastguard Worker
3514*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MEMBERNAME :
3515*5e7646d2SAndroid Build Coastguard Worker /*
3516*5e7646d2SAndroid Build Coastguard Worker * The value the name of the member in the collection, which
3517*5e7646d2SAndroid Build Coastguard Worker * we need to carry over...
3518*5e7646d2SAndroid Build Coastguard Worker */
3519*5e7646d2SAndroid Build Coastguard Worker
3520*5e7646d2SAndroid Build Coastguard Worker if (!attr)
3521*5e7646d2SAndroid Build Coastguard Worker {
3522*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3523*5e7646d2SAndroid Build Coastguard Worker _("IPP memberName with no attribute."), 1);
3524*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Member name without attribute.");
3525*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3526*5e7646d2SAndroid Build Coastguard Worker }
3527*5e7646d2SAndroid Build Coastguard Worker else if (n == 0)
3528*5e7646d2SAndroid Build Coastguard Worker {
3529*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3530*5e7646d2SAndroid Build Coastguard Worker _("IPP memberName value is empty."), 1);
3531*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Empty member name value.");
3532*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3533*5e7646d2SAndroid Build Coastguard Worker }
3534*5e7646d2SAndroid Build Coastguard Worker else if ((*cb)(src, buffer, (size_t)n) < n)
3535*5e7646d2SAndroid Build Coastguard Worker {
3536*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read member name value.");
3537*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3538*5e7646d2SAndroid Build Coastguard Worker }
3539*5e7646d2SAndroid Build Coastguard Worker
3540*5e7646d2SAndroid Build Coastguard Worker buffer[n] = '\0';
3541*5e7646d2SAndroid Build Coastguard Worker attr->name = _cupsStrAlloc((char *)buffer);
3542*5e7646d2SAndroid Build Coastguard Worker
3543*5e7646d2SAndroid Build Coastguard Worker /*
3544*5e7646d2SAndroid Build Coastguard Worker * Since collection members are encoded differently than
3545*5e7646d2SAndroid Build Coastguard Worker * regular attributes, make sure we don't start with an
3546*5e7646d2SAndroid Build Coastguard Worker * empty value...
3547*5e7646d2SAndroid Build Coastguard Worker */
3548*5e7646d2SAndroid Build Coastguard Worker
3549*5e7646d2SAndroid Build Coastguard Worker attr->num_values --;
3550*5e7646d2SAndroid Build Coastguard Worker
3551*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippReadIO: member name=\"%s\"", attr->name));
3552*5e7646d2SAndroid Build Coastguard Worker break;
3553*5e7646d2SAndroid Build Coastguard Worker
3554*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
3555*5e7646d2SAndroid Build Coastguard Worker default : /* Other unsupported values */
3556*5e7646d2SAndroid Build Coastguard Worker if (tag == IPP_TAG_STRING && n > IPP_MAX_LENGTH)
3557*5e7646d2SAndroid Build Coastguard Worker {
3558*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
3559*5e7646d2SAndroid Build Coastguard Worker _("IPP octetString length too large."), 1);
3560*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: bad octetString value length %d.",
3561*5e7646d2SAndroid Build Coastguard Worker n));
3562*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3563*5e7646d2SAndroid Build Coastguard Worker }
3564*5e7646d2SAndroid Build Coastguard Worker
3565*5e7646d2SAndroid Build Coastguard Worker value->unknown.length = n;
3566*5e7646d2SAndroid Build Coastguard Worker
3567*5e7646d2SAndroid Build Coastguard Worker if (n > 0)
3568*5e7646d2SAndroid Build Coastguard Worker {
3569*5e7646d2SAndroid Build Coastguard Worker if ((value->unknown.data = malloc((size_t)n)) == NULL)
3570*5e7646d2SAndroid Build Coastguard Worker {
3571*5e7646d2SAndroid Build Coastguard Worker _cupsSetHTTPError(HTTP_STATUS_ERROR);
3572*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to allocate value");
3573*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3574*5e7646d2SAndroid Build Coastguard Worker }
3575*5e7646d2SAndroid Build Coastguard Worker
3576*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(src, value->unknown.data, (size_t)n) < n)
3577*5e7646d2SAndroid Build Coastguard Worker {
3578*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippReadIO: Unable to read unsupported value.");
3579*5e7646d2SAndroid Build Coastguard Worker goto rollback;
3580*5e7646d2SAndroid Build Coastguard Worker }
3581*5e7646d2SAndroid Build Coastguard Worker }
3582*5e7646d2SAndroid Build Coastguard Worker else
3583*5e7646d2SAndroid Build Coastguard Worker value->unknown.data = NULL;
3584*5e7646d2SAndroid Build Coastguard Worker break;
3585*5e7646d2SAndroid Build Coastguard Worker }
3586*5e7646d2SAndroid Build Coastguard Worker
3587*5e7646d2SAndroid Build Coastguard Worker /*
3588*5e7646d2SAndroid Build Coastguard Worker * If blocking is disabled, stop here...
3589*5e7646d2SAndroid Build Coastguard Worker */
3590*5e7646d2SAndroid Build Coastguard Worker
3591*5e7646d2SAndroid Build Coastguard Worker if (!blocking)
3592*5e7646d2SAndroid Build Coastguard Worker break;
3593*5e7646d2SAndroid Build Coastguard Worker }
3594*5e7646d2SAndroid Build Coastguard Worker break;
3595*5e7646d2SAndroid Build Coastguard Worker
3596*5e7646d2SAndroid Build Coastguard Worker case IPP_STATE_DATA :
3597*5e7646d2SAndroid Build Coastguard Worker break;
3598*5e7646d2SAndroid Build Coastguard Worker
3599*5e7646d2SAndroid Build Coastguard Worker default :
3600*5e7646d2SAndroid Build Coastguard Worker break; /* anti-compiler-warning-code */
3601*5e7646d2SAndroid Build Coastguard Worker }
3602*5e7646d2SAndroid Build Coastguard Worker
3603*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippReadIO: returning ipp->state=%d.", ipp->state));
3604*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
3605*5e7646d2SAndroid Build Coastguard Worker
3606*5e7646d2SAndroid Build Coastguard Worker return (ipp->state);
3607*5e7646d2SAndroid Build Coastguard Worker
3608*5e7646d2SAndroid Build Coastguard Worker // If we get here, there was an error that required us to roll back the last
3609*5e7646d2SAndroid Build Coastguard Worker // attribute read in order to keep the IPP message valid...
3610*5e7646d2SAndroid Build Coastguard Worker rollback:
3611*5e7646d2SAndroid Build Coastguard Worker
3612*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
3613*5e7646d2SAndroid Build Coastguard Worker
3614*5e7646d2SAndroid Build Coastguard Worker if (attr)
3615*5e7646d2SAndroid Build Coastguard Worker ippDeleteAttribute(ipp, attr);
3616*5e7646d2SAndroid Build Coastguard Worker
3617*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
3618*5e7646d2SAndroid Build Coastguard Worker }
3619*5e7646d2SAndroid Build Coastguard Worker
3620*5e7646d2SAndroid Build Coastguard Worker
3621*5e7646d2SAndroid Build Coastguard Worker /*
3622*5e7646d2SAndroid Build Coastguard Worker * 'ippSetBoolean()' - Set a boolean value in an attribute.
3623*5e7646d2SAndroid Build Coastguard Worker *
3624*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
3625*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
3626*5e7646d2SAndroid Build Coastguard Worker *
3627*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
3628*5e7646d2SAndroid Build Coastguard Worker *
3629*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
3630*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
3631*5e7646d2SAndroid Build Coastguard Worker *
3632*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
3633*5e7646d2SAndroid Build Coastguard Worker */
3634*5e7646d2SAndroid Build Coastguard Worker
3635*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetBoolean(ipp_t * ipp,ipp_attribute_t ** attr,int element,int boolvalue)3636*5e7646d2SAndroid Build Coastguard Worker ippSetBoolean(ipp_t *ipp, /* I - IPP message */
3637*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
3638*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
3639*5e7646d2SAndroid Build Coastguard Worker int boolvalue)/* I - Boolean value */
3640*5e7646d2SAndroid Build Coastguard Worker {
3641*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
3642*5e7646d2SAndroid Build Coastguard Worker
3643*5e7646d2SAndroid Build Coastguard Worker
3644*5e7646d2SAndroid Build Coastguard Worker /*
3645*5e7646d2SAndroid Build Coastguard Worker * Range check input...
3646*5e7646d2SAndroid Build Coastguard Worker */
3647*5e7646d2SAndroid Build Coastguard Worker
3648*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_BOOLEAN ||
3649*5e7646d2SAndroid Build Coastguard Worker element < 0 || element > (*attr)->num_values)
3650*5e7646d2SAndroid Build Coastguard Worker return (0);
3651*5e7646d2SAndroid Build Coastguard Worker
3652*5e7646d2SAndroid Build Coastguard Worker /*
3653*5e7646d2SAndroid Build Coastguard Worker * Set the value and return...
3654*5e7646d2SAndroid Build Coastguard Worker */
3655*5e7646d2SAndroid Build Coastguard Worker
3656*5e7646d2SAndroid Build Coastguard Worker if ((value = ipp_set_value(ipp, attr, element)) != NULL)
3657*5e7646d2SAndroid Build Coastguard Worker value->boolean = (char)boolvalue;
3658*5e7646d2SAndroid Build Coastguard Worker
3659*5e7646d2SAndroid Build Coastguard Worker return (value != NULL);
3660*5e7646d2SAndroid Build Coastguard Worker }
3661*5e7646d2SAndroid Build Coastguard Worker
3662*5e7646d2SAndroid Build Coastguard Worker
3663*5e7646d2SAndroid Build Coastguard Worker /*
3664*5e7646d2SAndroid Build Coastguard Worker * 'ippSetCollection()' - Set a collection value in an attribute.
3665*5e7646d2SAndroid Build Coastguard Worker *
3666*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
3667*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
3668*5e7646d2SAndroid Build Coastguard Worker *
3669*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
3670*5e7646d2SAndroid Build Coastguard Worker *
3671*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
3672*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
3673*5e7646d2SAndroid Build Coastguard Worker *
3674*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
3675*5e7646d2SAndroid Build Coastguard Worker */
3676*5e7646d2SAndroid Build Coastguard Worker
3677*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetCollection(ipp_t * ipp,ipp_attribute_t ** attr,int element,ipp_t * colvalue)3678*5e7646d2SAndroid Build Coastguard Worker ippSetCollection(
3679*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
3680*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
3681*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
3682*5e7646d2SAndroid Build Coastguard Worker ipp_t *colvalue) /* I - Collection value */
3683*5e7646d2SAndroid Build Coastguard Worker {
3684*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
3685*5e7646d2SAndroid Build Coastguard Worker
3686*5e7646d2SAndroid Build Coastguard Worker
3687*5e7646d2SAndroid Build Coastguard Worker /*
3688*5e7646d2SAndroid Build Coastguard Worker * Range check input...
3689*5e7646d2SAndroid Build Coastguard Worker */
3690*5e7646d2SAndroid Build Coastguard Worker
3691*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_BEGIN_COLLECTION ||
3692*5e7646d2SAndroid Build Coastguard Worker element < 0 || element > (*attr)->num_values || !colvalue)
3693*5e7646d2SAndroid Build Coastguard Worker return (0);
3694*5e7646d2SAndroid Build Coastguard Worker
3695*5e7646d2SAndroid Build Coastguard Worker /*
3696*5e7646d2SAndroid Build Coastguard Worker * Set the value and return...
3697*5e7646d2SAndroid Build Coastguard Worker */
3698*5e7646d2SAndroid Build Coastguard Worker
3699*5e7646d2SAndroid Build Coastguard Worker if ((value = ipp_set_value(ipp, attr, element)) != NULL)
3700*5e7646d2SAndroid Build Coastguard Worker {
3701*5e7646d2SAndroid Build Coastguard Worker if (value->collection)
3702*5e7646d2SAndroid Build Coastguard Worker ippDelete(value->collection);
3703*5e7646d2SAndroid Build Coastguard Worker
3704*5e7646d2SAndroid Build Coastguard Worker value->collection = colvalue;
3705*5e7646d2SAndroid Build Coastguard Worker colvalue->use ++;
3706*5e7646d2SAndroid Build Coastguard Worker }
3707*5e7646d2SAndroid Build Coastguard Worker
3708*5e7646d2SAndroid Build Coastguard Worker return (value != NULL);
3709*5e7646d2SAndroid Build Coastguard Worker }
3710*5e7646d2SAndroid Build Coastguard Worker
3711*5e7646d2SAndroid Build Coastguard Worker
3712*5e7646d2SAndroid Build Coastguard Worker /*
3713*5e7646d2SAndroid Build Coastguard Worker * 'ippSetDate()' - Set a dateTime value in an attribute.
3714*5e7646d2SAndroid Build Coastguard Worker *
3715*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
3716*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
3717*5e7646d2SAndroid Build Coastguard Worker *
3718*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
3719*5e7646d2SAndroid Build Coastguard Worker *
3720*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
3721*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
3722*5e7646d2SAndroid Build Coastguard Worker *
3723*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
3724*5e7646d2SAndroid Build Coastguard Worker */
3725*5e7646d2SAndroid Build Coastguard Worker
3726*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetDate(ipp_t * ipp,ipp_attribute_t ** attr,int element,const ipp_uchar_t * datevalue)3727*5e7646d2SAndroid Build Coastguard Worker ippSetDate(ipp_t *ipp, /* I - IPP message */
3728*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
3729*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
3730*5e7646d2SAndroid Build Coastguard Worker const ipp_uchar_t *datevalue)/* I - dateTime value */
3731*5e7646d2SAndroid Build Coastguard Worker {
3732*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
3733*5e7646d2SAndroid Build Coastguard Worker
3734*5e7646d2SAndroid Build Coastguard Worker
3735*5e7646d2SAndroid Build Coastguard Worker /*
3736*5e7646d2SAndroid Build Coastguard Worker * Range check input...
3737*5e7646d2SAndroid Build Coastguard Worker */
3738*5e7646d2SAndroid Build Coastguard Worker
3739*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_DATE && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || !datevalue)
3740*5e7646d2SAndroid Build Coastguard Worker return (0);
3741*5e7646d2SAndroid Build Coastguard Worker
3742*5e7646d2SAndroid Build Coastguard Worker /*
3743*5e7646d2SAndroid Build Coastguard Worker * Set the value and return...
3744*5e7646d2SAndroid Build Coastguard Worker */
3745*5e7646d2SAndroid Build Coastguard Worker
3746*5e7646d2SAndroid Build Coastguard Worker if ((value = ipp_set_value(ipp, attr, element)) != NULL)
3747*5e7646d2SAndroid Build Coastguard Worker memcpy(value->date, datevalue, sizeof(value->date));
3748*5e7646d2SAndroid Build Coastguard Worker
3749*5e7646d2SAndroid Build Coastguard Worker return (value != NULL);
3750*5e7646d2SAndroid Build Coastguard Worker }
3751*5e7646d2SAndroid Build Coastguard Worker
3752*5e7646d2SAndroid Build Coastguard Worker
3753*5e7646d2SAndroid Build Coastguard Worker /*
3754*5e7646d2SAndroid Build Coastguard Worker * 'ippSetGroupTag()' - Set the group tag of an attribute.
3755*5e7646d2SAndroid Build Coastguard Worker *
3756*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
3757*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
3758*5e7646d2SAndroid Build Coastguard Worker *
3759*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
3760*5e7646d2SAndroid Build Coastguard Worker *
3761*5e7646d2SAndroid Build Coastguard Worker * The @code group@ parameter specifies the IPP attribute group tag: none
3762*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_ZERO@, for member attributes), document (@code IPP_TAG_DOCUMENT@),
3763*5e7646d2SAndroid Build Coastguard Worker * event notification (@code IPP_TAG_EVENT_NOTIFICATION@), operation
3764*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_OPERATION@), printer (@code IPP_TAG_PRINTER@), subscription
3765*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_SUBSCRIPTION@), or unsupported (@code IPP_TAG_UNSUPPORTED_GROUP@).
3766*5e7646d2SAndroid Build Coastguard Worker *
3767*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
3768*5e7646d2SAndroid Build Coastguard Worker */
3769*5e7646d2SAndroid Build Coastguard Worker
3770*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetGroupTag(ipp_t * ipp,ipp_attribute_t ** attr,ipp_tag_t group_tag)3771*5e7646d2SAndroid Build Coastguard Worker ippSetGroupTag(
3772*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
3773*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - Attribute */
3774*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group_tag) /* I - Group tag */
3775*5e7646d2SAndroid Build Coastguard Worker {
3776*5e7646d2SAndroid Build Coastguard Worker /*
3777*5e7646d2SAndroid Build Coastguard Worker * Range check input - group tag must be 0x01 to 0x0F, per RFC 8011...
3778*5e7646d2SAndroid Build Coastguard Worker */
3779*5e7646d2SAndroid Build Coastguard Worker
3780*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr ||
3781*5e7646d2SAndroid Build Coastguard Worker group_tag < IPP_TAG_ZERO || group_tag == IPP_TAG_END ||
3782*5e7646d2SAndroid Build Coastguard Worker group_tag >= IPP_TAG_UNSUPPORTED_VALUE)
3783*5e7646d2SAndroid Build Coastguard Worker return (0);
3784*5e7646d2SAndroid Build Coastguard Worker
3785*5e7646d2SAndroid Build Coastguard Worker /*
3786*5e7646d2SAndroid Build Coastguard Worker * Set the group tag and return...
3787*5e7646d2SAndroid Build Coastguard Worker */
3788*5e7646d2SAndroid Build Coastguard Worker
3789*5e7646d2SAndroid Build Coastguard Worker (*attr)->group_tag = group_tag;
3790*5e7646d2SAndroid Build Coastguard Worker
3791*5e7646d2SAndroid Build Coastguard Worker return (1);
3792*5e7646d2SAndroid Build Coastguard Worker }
3793*5e7646d2SAndroid Build Coastguard Worker
3794*5e7646d2SAndroid Build Coastguard Worker
3795*5e7646d2SAndroid Build Coastguard Worker /*
3796*5e7646d2SAndroid Build Coastguard Worker * 'ippSetInteger()' - Set an integer or enum value in an attribute.
3797*5e7646d2SAndroid Build Coastguard Worker *
3798*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
3799*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
3800*5e7646d2SAndroid Build Coastguard Worker *
3801*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
3802*5e7646d2SAndroid Build Coastguard Worker *
3803*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
3804*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
3805*5e7646d2SAndroid Build Coastguard Worker *
3806*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
3807*5e7646d2SAndroid Build Coastguard Worker */
3808*5e7646d2SAndroid Build Coastguard Worker
3809*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetInteger(ipp_t * ipp,ipp_attribute_t ** attr,int element,int intvalue)3810*5e7646d2SAndroid Build Coastguard Worker ippSetInteger(ipp_t *ipp, /* I - IPP message */
3811*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
3812*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
3813*5e7646d2SAndroid Build Coastguard Worker int intvalue) /* I - Integer/enum value */
3814*5e7646d2SAndroid Build Coastguard Worker {
3815*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
3816*5e7646d2SAndroid Build Coastguard Worker
3817*5e7646d2SAndroid Build Coastguard Worker
3818*5e7646d2SAndroid Build Coastguard Worker /*
3819*5e7646d2SAndroid Build Coastguard Worker * Range check input...
3820*5e7646d2SAndroid Build Coastguard Worker */
3821*5e7646d2SAndroid Build Coastguard Worker
3822*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_INTEGER && (*attr)->value_tag != IPP_TAG_ENUM && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values)
3823*5e7646d2SAndroid Build Coastguard Worker return (0);
3824*5e7646d2SAndroid Build Coastguard Worker
3825*5e7646d2SAndroid Build Coastguard Worker /*
3826*5e7646d2SAndroid Build Coastguard Worker * Set the value and return...
3827*5e7646d2SAndroid Build Coastguard Worker */
3828*5e7646d2SAndroid Build Coastguard Worker
3829*5e7646d2SAndroid Build Coastguard Worker if ((value = ipp_set_value(ipp, attr, element)) != NULL)
3830*5e7646d2SAndroid Build Coastguard Worker {
3831*5e7646d2SAndroid Build Coastguard Worker if ((*attr)->value_tag != IPP_TAG_ENUM)
3832*5e7646d2SAndroid Build Coastguard Worker (*attr)->value_tag = IPP_TAG_INTEGER;
3833*5e7646d2SAndroid Build Coastguard Worker
3834*5e7646d2SAndroid Build Coastguard Worker value->integer = intvalue;
3835*5e7646d2SAndroid Build Coastguard Worker }
3836*5e7646d2SAndroid Build Coastguard Worker
3837*5e7646d2SAndroid Build Coastguard Worker return (value != NULL);
3838*5e7646d2SAndroid Build Coastguard Worker }
3839*5e7646d2SAndroid Build Coastguard Worker
3840*5e7646d2SAndroid Build Coastguard Worker
3841*5e7646d2SAndroid Build Coastguard Worker /*
3842*5e7646d2SAndroid Build Coastguard Worker * 'ippSetName()' - Set the name of an attribute.
3843*5e7646d2SAndroid Build Coastguard Worker *
3844*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
3845*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
3846*5e7646d2SAndroid Build Coastguard Worker *
3847*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
3848*5e7646d2SAndroid Build Coastguard Worker *
3849*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
3850*5e7646d2SAndroid Build Coastguard Worker */
3851*5e7646d2SAndroid Build Coastguard Worker
3852*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetName(ipp_t * ipp,ipp_attribute_t ** attr,const char * name)3853*5e7646d2SAndroid Build Coastguard Worker ippSetName(ipp_t *ipp, /* I - IPP message */
3854*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
3855*5e7646d2SAndroid Build Coastguard Worker const char *name) /* I - Attribute name */
3856*5e7646d2SAndroid Build Coastguard Worker {
3857*5e7646d2SAndroid Build Coastguard Worker char *temp; /* Temporary name value */
3858*5e7646d2SAndroid Build Coastguard Worker
3859*5e7646d2SAndroid Build Coastguard Worker
3860*5e7646d2SAndroid Build Coastguard Worker /*
3861*5e7646d2SAndroid Build Coastguard Worker * Range check input...
3862*5e7646d2SAndroid Build Coastguard Worker */
3863*5e7646d2SAndroid Build Coastguard Worker
3864*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr)
3865*5e7646d2SAndroid Build Coastguard Worker return (0);
3866*5e7646d2SAndroid Build Coastguard Worker
3867*5e7646d2SAndroid Build Coastguard Worker /*
3868*5e7646d2SAndroid Build Coastguard Worker * Set the value and return...
3869*5e7646d2SAndroid Build Coastguard Worker */
3870*5e7646d2SAndroid Build Coastguard Worker
3871*5e7646d2SAndroid Build Coastguard Worker if ((temp = _cupsStrAlloc(name)) != NULL)
3872*5e7646d2SAndroid Build Coastguard Worker {
3873*5e7646d2SAndroid Build Coastguard Worker if ((*attr)->name)
3874*5e7646d2SAndroid Build Coastguard Worker _cupsStrFree((*attr)->name);
3875*5e7646d2SAndroid Build Coastguard Worker
3876*5e7646d2SAndroid Build Coastguard Worker (*attr)->name = temp;
3877*5e7646d2SAndroid Build Coastguard Worker }
3878*5e7646d2SAndroid Build Coastguard Worker
3879*5e7646d2SAndroid Build Coastguard Worker return (temp != NULL);
3880*5e7646d2SAndroid Build Coastguard Worker }
3881*5e7646d2SAndroid Build Coastguard Worker
3882*5e7646d2SAndroid Build Coastguard Worker
3883*5e7646d2SAndroid Build Coastguard Worker /*
3884*5e7646d2SAndroid Build Coastguard Worker * 'ippSetOctetString()' - Set an octetString value in an IPP attribute.
3885*5e7646d2SAndroid Build Coastguard Worker *
3886*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
3887*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
3888*5e7646d2SAndroid Build Coastguard Worker *
3889*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
3890*5e7646d2SAndroid Build Coastguard Worker *
3891*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
3892*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
3893*5e7646d2SAndroid Build Coastguard Worker *
3894*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
3895*5e7646d2SAndroid Build Coastguard Worker */
3896*5e7646d2SAndroid Build Coastguard Worker
3897*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetOctetString(ipp_t * ipp,ipp_attribute_t ** attr,int element,const void * data,int datalen)3898*5e7646d2SAndroid Build Coastguard Worker ippSetOctetString(
3899*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
3900*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
3901*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
3902*5e7646d2SAndroid Build Coastguard Worker const void *data, /* I - Pointer to octetString data */
3903*5e7646d2SAndroid Build Coastguard Worker int datalen) /* I - Length of octetString data */
3904*5e7646d2SAndroid Build Coastguard Worker {
3905*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
3906*5e7646d2SAndroid Build Coastguard Worker
3907*5e7646d2SAndroid Build Coastguard Worker
3908*5e7646d2SAndroid Build Coastguard Worker /*
3909*5e7646d2SAndroid Build Coastguard Worker * Range check input...
3910*5e7646d2SAndroid Build Coastguard Worker */
3911*5e7646d2SAndroid Build Coastguard Worker
3912*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_STRING && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || datalen < 0 || datalen > IPP_MAX_LENGTH)
3913*5e7646d2SAndroid Build Coastguard Worker return (0);
3914*5e7646d2SAndroid Build Coastguard Worker
3915*5e7646d2SAndroid Build Coastguard Worker /*
3916*5e7646d2SAndroid Build Coastguard Worker * Set the value and return...
3917*5e7646d2SAndroid Build Coastguard Worker */
3918*5e7646d2SAndroid Build Coastguard Worker
3919*5e7646d2SAndroid Build Coastguard Worker if ((value = ipp_set_value(ipp, attr, element)) != NULL)
3920*5e7646d2SAndroid Build Coastguard Worker {
3921*5e7646d2SAndroid Build Coastguard Worker if ((int)((*attr)->value_tag) & IPP_TAG_CUPS_CONST)
3922*5e7646d2SAndroid Build Coastguard Worker {
3923*5e7646d2SAndroid Build Coastguard Worker /*
3924*5e7646d2SAndroid Build Coastguard Worker * Just copy the pointer...
3925*5e7646d2SAndroid Build Coastguard Worker */
3926*5e7646d2SAndroid Build Coastguard Worker
3927*5e7646d2SAndroid Build Coastguard Worker value->unknown.data = (void *)data;
3928*5e7646d2SAndroid Build Coastguard Worker value->unknown.length = datalen;
3929*5e7646d2SAndroid Build Coastguard Worker }
3930*5e7646d2SAndroid Build Coastguard Worker else
3931*5e7646d2SAndroid Build Coastguard Worker {
3932*5e7646d2SAndroid Build Coastguard Worker /*
3933*5e7646d2SAndroid Build Coastguard Worker * Copy the data...
3934*5e7646d2SAndroid Build Coastguard Worker */
3935*5e7646d2SAndroid Build Coastguard Worker
3936*5e7646d2SAndroid Build Coastguard Worker (*attr)->value_tag = IPP_TAG_STRING;
3937*5e7646d2SAndroid Build Coastguard Worker
3938*5e7646d2SAndroid Build Coastguard Worker if (value->unknown.data)
3939*5e7646d2SAndroid Build Coastguard Worker {
3940*5e7646d2SAndroid Build Coastguard Worker /*
3941*5e7646d2SAndroid Build Coastguard Worker * Free previous data...
3942*5e7646d2SAndroid Build Coastguard Worker */
3943*5e7646d2SAndroid Build Coastguard Worker
3944*5e7646d2SAndroid Build Coastguard Worker free(value->unknown.data);
3945*5e7646d2SAndroid Build Coastguard Worker
3946*5e7646d2SAndroid Build Coastguard Worker value->unknown.data = NULL;
3947*5e7646d2SAndroid Build Coastguard Worker value->unknown.length = 0;
3948*5e7646d2SAndroid Build Coastguard Worker }
3949*5e7646d2SAndroid Build Coastguard Worker
3950*5e7646d2SAndroid Build Coastguard Worker if (datalen > 0)
3951*5e7646d2SAndroid Build Coastguard Worker {
3952*5e7646d2SAndroid Build Coastguard Worker void *temp; /* Temporary data pointer */
3953*5e7646d2SAndroid Build Coastguard Worker
3954*5e7646d2SAndroid Build Coastguard Worker if ((temp = malloc((size_t)datalen)) != NULL)
3955*5e7646d2SAndroid Build Coastguard Worker {
3956*5e7646d2SAndroid Build Coastguard Worker memcpy(temp, data, (size_t)datalen);
3957*5e7646d2SAndroid Build Coastguard Worker
3958*5e7646d2SAndroid Build Coastguard Worker value->unknown.data = temp;
3959*5e7646d2SAndroid Build Coastguard Worker value->unknown.length = datalen;
3960*5e7646d2SAndroid Build Coastguard Worker }
3961*5e7646d2SAndroid Build Coastguard Worker else
3962*5e7646d2SAndroid Build Coastguard Worker return (0);
3963*5e7646d2SAndroid Build Coastguard Worker }
3964*5e7646d2SAndroid Build Coastguard Worker }
3965*5e7646d2SAndroid Build Coastguard Worker }
3966*5e7646d2SAndroid Build Coastguard Worker
3967*5e7646d2SAndroid Build Coastguard Worker return (value != NULL);
3968*5e7646d2SAndroid Build Coastguard Worker }
3969*5e7646d2SAndroid Build Coastguard Worker
3970*5e7646d2SAndroid Build Coastguard Worker
3971*5e7646d2SAndroid Build Coastguard Worker /*
3972*5e7646d2SAndroid Build Coastguard Worker * 'ippSetOperation()' - Set the operation ID in an IPP request message.
3973*5e7646d2SAndroid Build Coastguard Worker *
3974*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
3975*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
3976*5e7646d2SAndroid Build Coastguard Worker *
3977*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
3978*5e7646d2SAndroid Build Coastguard Worker */
3979*5e7646d2SAndroid Build Coastguard Worker
3980*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetOperation(ipp_t * ipp,ipp_op_t op)3981*5e7646d2SAndroid Build Coastguard Worker ippSetOperation(ipp_t *ipp, /* I - IPP request message */
3982*5e7646d2SAndroid Build Coastguard Worker ipp_op_t op) /* I - Operation ID */
3983*5e7646d2SAndroid Build Coastguard Worker {
3984*5e7646d2SAndroid Build Coastguard Worker /*
3985*5e7646d2SAndroid Build Coastguard Worker * Range check input...
3986*5e7646d2SAndroid Build Coastguard Worker */
3987*5e7646d2SAndroid Build Coastguard Worker
3988*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
3989*5e7646d2SAndroid Build Coastguard Worker return (0);
3990*5e7646d2SAndroid Build Coastguard Worker
3991*5e7646d2SAndroid Build Coastguard Worker /*
3992*5e7646d2SAndroid Build Coastguard Worker * Set the operation and return...
3993*5e7646d2SAndroid Build Coastguard Worker */
3994*5e7646d2SAndroid Build Coastguard Worker
3995*5e7646d2SAndroid Build Coastguard Worker ipp->request.op.operation_id = op;
3996*5e7646d2SAndroid Build Coastguard Worker
3997*5e7646d2SAndroid Build Coastguard Worker return (1);
3998*5e7646d2SAndroid Build Coastguard Worker }
3999*5e7646d2SAndroid Build Coastguard Worker
4000*5e7646d2SAndroid Build Coastguard Worker
4001*5e7646d2SAndroid Build Coastguard Worker /*
4002*5e7646d2SAndroid Build Coastguard Worker * 'ippSetRange()' - Set a rangeOfInteger value in an attribute.
4003*5e7646d2SAndroid Build Coastguard Worker *
4004*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
4005*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
4006*5e7646d2SAndroid Build Coastguard Worker *
4007*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
4008*5e7646d2SAndroid Build Coastguard Worker *
4009*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
4010*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
4011*5e7646d2SAndroid Build Coastguard Worker *
4012*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
4013*5e7646d2SAndroid Build Coastguard Worker */
4014*5e7646d2SAndroid Build Coastguard Worker
4015*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetRange(ipp_t * ipp,ipp_attribute_t ** attr,int element,int lowervalue,int uppervalue)4016*5e7646d2SAndroid Build Coastguard Worker ippSetRange(ipp_t *ipp, /* I - IPP message */
4017*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
4018*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
4019*5e7646d2SAndroid Build Coastguard Worker int lowervalue, /* I - Lower bound for range */
4020*5e7646d2SAndroid Build Coastguard Worker int uppervalue) /* I - Upper bound for range */
4021*5e7646d2SAndroid Build Coastguard Worker {
4022*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
4023*5e7646d2SAndroid Build Coastguard Worker
4024*5e7646d2SAndroid Build Coastguard Worker
4025*5e7646d2SAndroid Build Coastguard Worker /*
4026*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4027*5e7646d2SAndroid Build Coastguard Worker */
4028*5e7646d2SAndroid Build Coastguard Worker
4029*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_RANGE && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || lowervalue > uppervalue)
4030*5e7646d2SAndroid Build Coastguard Worker return (0);
4031*5e7646d2SAndroid Build Coastguard Worker
4032*5e7646d2SAndroid Build Coastguard Worker /*
4033*5e7646d2SAndroid Build Coastguard Worker * Set the value and return...
4034*5e7646d2SAndroid Build Coastguard Worker */
4035*5e7646d2SAndroid Build Coastguard Worker
4036*5e7646d2SAndroid Build Coastguard Worker if ((value = ipp_set_value(ipp, attr, element)) != NULL)
4037*5e7646d2SAndroid Build Coastguard Worker {
4038*5e7646d2SAndroid Build Coastguard Worker (*attr)->value_tag = IPP_TAG_RANGE;
4039*5e7646d2SAndroid Build Coastguard Worker value->range.lower = lowervalue;
4040*5e7646d2SAndroid Build Coastguard Worker value->range.upper = uppervalue;
4041*5e7646d2SAndroid Build Coastguard Worker }
4042*5e7646d2SAndroid Build Coastguard Worker
4043*5e7646d2SAndroid Build Coastguard Worker return (value != NULL);
4044*5e7646d2SAndroid Build Coastguard Worker }
4045*5e7646d2SAndroid Build Coastguard Worker
4046*5e7646d2SAndroid Build Coastguard Worker
4047*5e7646d2SAndroid Build Coastguard Worker /*
4048*5e7646d2SAndroid Build Coastguard Worker * 'ippSetRequestId()' - Set the request ID in an IPP message.
4049*5e7646d2SAndroid Build Coastguard Worker *
4050*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
4051*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
4052*5e7646d2SAndroid Build Coastguard Worker *
4053*5e7646d2SAndroid Build Coastguard Worker * The @code request_id@ parameter must be greater than 0.
4054*5e7646d2SAndroid Build Coastguard Worker *
4055*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
4056*5e7646d2SAndroid Build Coastguard Worker */
4057*5e7646d2SAndroid Build Coastguard Worker
4058*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetRequestId(ipp_t * ipp,int request_id)4059*5e7646d2SAndroid Build Coastguard Worker ippSetRequestId(ipp_t *ipp, /* I - IPP message */
4060*5e7646d2SAndroid Build Coastguard Worker int request_id) /* I - Request ID */
4061*5e7646d2SAndroid Build Coastguard Worker {
4062*5e7646d2SAndroid Build Coastguard Worker /*
4063*5e7646d2SAndroid Build Coastguard Worker * Range check input; not checking request_id values since ipptool wants to send
4064*5e7646d2SAndroid Build Coastguard Worker * invalid values for conformance testing and a bad request_id does not affect the
4065*5e7646d2SAndroid Build Coastguard Worker * encoding of a message...
4066*5e7646d2SAndroid Build Coastguard Worker */
4067*5e7646d2SAndroid Build Coastguard Worker
4068*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
4069*5e7646d2SAndroid Build Coastguard Worker return (0);
4070*5e7646d2SAndroid Build Coastguard Worker
4071*5e7646d2SAndroid Build Coastguard Worker /*
4072*5e7646d2SAndroid Build Coastguard Worker * Set the request ID and return...
4073*5e7646d2SAndroid Build Coastguard Worker */
4074*5e7646d2SAndroid Build Coastguard Worker
4075*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.request_id = request_id;
4076*5e7646d2SAndroid Build Coastguard Worker
4077*5e7646d2SAndroid Build Coastguard Worker return (1);
4078*5e7646d2SAndroid Build Coastguard Worker }
4079*5e7646d2SAndroid Build Coastguard Worker
4080*5e7646d2SAndroid Build Coastguard Worker
4081*5e7646d2SAndroid Build Coastguard Worker /*
4082*5e7646d2SAndroid Build Coastguard Worker * 'ippSetResolution()' - Set a resolution value in an attribute.
4083*5e7646d2SAndroid Build Coastguard Worker *
4084*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
4085*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
4086*5e7646d2SAndroid Build Coastguard Worker *
4087*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
4088*5e7646d2SAndroid Build Coastguard Worker *
4089*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
4090*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
4091*5e7646d2SAndroid Build Coastguard Worker *
4092*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
4093*5e7646d2SAndroid Build Coastguard Worker */
4094*5e7646d2SAndroid Build Coastguard Worker
4095*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetResolution(ipp_t * ipp,ipp_attribute_t ** attr,int element,ipp_res_t unitsvalue,int xresvalue,int yresvalue)4096*5e7646d2SAndroid Build Coastguard Worker ippSetResolution(
4097*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
4098*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
4099*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
4100*5e7646d2SAndroid Build Coastguard Worker ipp_res_t unitsvalue, /* I - Resolution units */
4101*5e7646d2SAndroid Build Coastguard Worker int xresvalue, /* I - Horizontal/cross feed resolution */
4102*5e7646d2SAndroid Build Coastguard Worker int yresvalue) /* I - Vertical/feed resolution */
4103*5e7646d2SAndroid Build Coastguard Worker {
4104*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
4105*5e7646d2SAndroid Build Coastguard Worker
4106*5e7646d2SAndroid Build Coastguard Worker
4107*5e7646d2SAndroid Build Coastguard Worker /*
4108*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4109*5e7646d2SAndroid Build Coastguard Worker */
4110*5e7646d2SAndroid Build Coastguard Worker
4111*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_RESOLUTION && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || xresvalue <= 0 || yresvalue <= 0 || unitsvalue < IPP_RES_PER_INCH || unitsvalue > IPP_RES_PER_CM)
4112*5e7646d2SAndroid Build Coastguard Worker return (0);
4113*5e7646d2SAndroid Build Coastguard Worker
4114*5e7646d2SAndroid Build Coastguard Worker /*
4115*5e7646d2SAndroid Build Coastguard Worker * Set the value and return...
4116*5e7646d2SAndroid Build Coastguard Worker */
4117*5e7646d2SAndroid Build Coastguard Worker
4118*5e7646d2SAndroid Build Coastguard Worker if ((value = ipp_set_value(ipp, attr, element)) != NULL)
4119*5e7646d2SAndroid Build Coastguard Worker {
4120*5e7646d2SAndroid Build Coastguard Worker (*attr)->value_tag = IPP_TAG_RESOLUTION;
4121*5e7646d2SAndroid Build Coastguard Worker value->resolution.units = unitsvalue;
4122*5e7646d2SAndroid Build Coastguard Worker value->resolution.xres = xresvalue;
4123*5e7646d2SAndroid Build Coastguard Worker value->resolution.yres = yresvalue;
4124*5e7646d2SAndroid Build Coastguard Worker }
4125*5e7646d2SAndroid Build Coastguard Worker
4126*5e7646d2SAndroid Build Coastguard Worker return (value != NULL);
4127*5e7646d2SAndroid Build Coastguard Worker }
4128*5e7646d2SAndroid Build Coastguard Worker
4129*5e7646d2SAndroid Build Coastguard Worker
4130*5e7646d2SAndroid Build Coastguard Worker /*
4131*5e7646d2SAndroid Build Coastguard Worker * 'ippSetState()' - Set the current state of the IPP message.
4132*5e7646d2SAndroid Build Coastguard Worker *
4133*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
4134*5e7646d2SAndroid Build Coastguard Worker */
4135*5e7646d2SAndroid Build Coastguard Worker
4136*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetState(ipp_t * ipp,ipp_state_t state)4137*5e7646d2SAndroid Build Coastguard Worker ippSetState(ipp_t *ipp, /* I - IPP message */
4138*5e7646d2SAndroid Build Coastguard Worker ipp_state_t state) /* I - IPP state value */
4139*5e7646d2SAndroid Build Coastguard Worker {
4140*5e7646d2SAndroid Build Coastguard Worker /*
4141*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4142*5e7646d2SAndroid Build Coastguard Worker */
4143*5e7646d2SAndroid Build Coastguard Worker
4144*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
4145*5e7646d2SAndroid Build Coastguard Worker return (0);
4146*5e7646d2SAndroid Build Coastguard Worker
4147*5e7646d2SAndroid Build Coastguard Worker /*
4148*5e7646d2SAndroid Build Coastguard Worker * Set the state and return...
4149*5e7646d2SAndroid Build Coastguard Worker */
4150*5e7646d2SAndroid Build Coastguard Worker
4151*5e7646d2SAndroid Build Coastguard Worker ipp->state = state;
4152*5e7646d2SAndroid Build Coastguard Worker ipp->current = NULL;
4153*5e7646d2SAndroid Build Coastguard Worker
4154*5e7646d2SAndroid Build Coastguard Worker return (1);
4155*5e7646d2SAndroid Build Coastguard Worker }
4156*5e7646d2SAndroid Build Coastguard Worker
4157*5e7646d2SAndroid Build Coastguard Worker
4158*5e7646d2SAndroid Build Coastguard Worker /*
4159*5e7646d2SAndroid Build Coastguard Worker * 'ippSetStatusCode()' - Set the status code in an IPP response or event message.
4160*5e7646d2SAndroid Build Coastguard Worker *
4161*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
4162*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
4163*5e7646d2SAndroid Build Coastguard Worker *
4164*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
4165*5e7646d2SAndroid Build Coastguard Worker */
4166*5e7646d2SAndroid Build Coastguard Worker
4167*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetStatusCode(ipp_t * ipp,ipp_status_t status)4168*5e7646d2SAndroid Build Coastguard Worker ippSetStatusCode(ipp_t *ipp, /* I - IPP response or event message */
4169*5e7646d2SAndroid Build Coastguard Worker ipp_status_t status) /* I - Status code */
4170*5e7646d2SAndroid Build Coastguard Worker {
4171*5e7646d2SAndroid Build Coastguard Worker /*
4172*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4173*5e7646d2SAndroid Build Coastguard Worker */
4174*5e7646d2SAndroid Build Coastguard Worker
4175*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
4176*5e7646d2SAndroid Build Coastguard Worker return (0);
4177*5e7646d2SAndroid Build Coastguard Worker
4178*5e7646d2SAndroid Build Coastguard Worker /*
4179*5e7646d2SAndroid Build Coastguard Worker * Set the status code and return...
4180*5e7646d2SAndroid Build Coastguard Worker */
4181*5e7646d2SAndroid Build Coastguard Worker
4182*5e7646d2SAndroid Build Coastguard Worker ipp->request.status.status_code = status;
4183*5e7646d2SAndroid Build Coastguard Worker
4184*5e7646d2SAndroid Build Coastguard Worker return (1);
4185*5e7646d2SAndroid Build Coastguard Worker }
4186*5e7646d2SAndroid Build Coastguard Worker
4187*5e7646d2SAndroid Build Coastguard Worker
4188*5e7646d2SAndroid Build Coastguard Worker /*
4189*5e7646d2SAndroid Build Coastguard Worker * 'ippSetString()' - Set a string value in an attribute.
4190*5e7646d2SAndroid Build Coastguard Worker *
4191*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
4192*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
4193*5e7646d2SAndroid Build Coastguard Worker *
4194*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
4195*5e7646d2SAndroid Build Coastguard Worker *
4196*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
4197*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
4198*5e7646d2SAndroid Build Coastguard Worker *
4199*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
4200*5e7646d2SAndroid Build Coastguard Worker */
4201*5e7646d2SAndroid Build Coastguard Worker
4202*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetString(ipp_t * ipp,ipp_attribute_t ** attr,int element,const char * strvalue)4203*5e7646d2SAndroid Build Coastguard Worker ippSetString(ipp_t *ipp, /* I - IPP message */
4204*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
4205*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
4206*5e7646d2SAndroid Build Coastguard Worker const char *strvalue) /* I - String value */
4207*5e7646d2SAndroid Build Coastguard Worker {
4208*5e7646d2SAndroid Build Coastguard Worker char *temp; /* Temporary string */
4209*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
4210*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag; /* Value tag */
4211*5e7646d2SAndroid Build Coastguard Worker
4212*5e7646d2SAndroid Build Coastguard Worker
4213*5e7646d2SAndroid Build Coastguard Worker /*
4214*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4215*5e7646d2SAndroid Build Coastguard Worker */
4216*5e7646d2SAndroid Build Coastguard Worker
4217*5e7646d2SAndroid Build Coastguard Worker if (attr && *attr)
4218*5e7646d2SAndroid Build Coastguard Worker value_tag = (*attr)->value_tag & IPP_TAG_CUPS_MASK;
4219*5e7646d2SAndroid Build Coastguard Worker else
4220*5e7646d2SAndroid Build Coastguard Worker value_tag = IPP_TAG_ZERO;
4221*5e7646d2SAndroid Build Coastguard Worker
4222*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr || (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG && value_tag != IPP_TAG_NAMELANG && value_tag != IPP_TAG_NOVALUE && value_tag != IPP_TAG_UNKNOWN) || value_tag > IPP_TAG_MIMETYPE || element < 0 || element > (*attr)->num_values || !strvalue)
4223*5e7646d2SAndroid Build Coastguard Worker return (0);
4224*5e7646d2SAndroid Build Coastguard Worker
4225*5e7646d2SAndroid Build Coastguard Worker /*
4226*5e7646d2SAndroid Build Coastguard Worker * Set the value and return...
4227*5e7646d2SAndroid Build Coastguard Worker */
4228*5e7646d2SAndroid Build Coastguard Worker
4229*5e7646d2SAndroid Build Coastguard Worker if ((value = ipp_set_value(ipp, attr, element)) != NULL)
4230*5e7646d2SAndroid Build Coastguard Worker {
4231*5e7646d2SAndroid Build Coastguard Worker if (value_tag == IPP_TAG_NOVALUE || value_tag == IPP_TAG_UNKNOWN)
4232*5e7646d2SAndroid Build Coastguard Worker (*attr)->value_tag = IPP_TAG_KEYWORD;
4233*5e7646d2SAndroid Build Coastguard Worker
4234*5e7646d2SAndroid Build Coastguard Worker if (element > 0)
4235*5e7646d2SAndroid Build Coastguard Worker value->string.language = (*attr)->values[0].string.language;
4236*5e7646d2SAndroid Build Coastguard Worker
4237*5e7646d2SAndroid Build Coastguard Worker if ((int)((*attr)->value_tag) & IPP_TAG_CUPS_CONST)
4238*5e7646d2SAndroid Build Coastguard Worker value->string.text = (char *)strvalue;
4239*5e7646d2SAndroid Build Coastguard Worker else if ((temp = _cupsStrAlloc(strvalue)) != NULL)
4240*5e7646d2SAndroid Build Coastguard Worker {
4241*5e7646d2SAndroid Build Coastguard Worker if (value->string.text)
4242*5e7646d2SAndroid Build Coastguard Worker _cupsStrFree(value->string.text);
4243*5e7646d2SAndroid Build Coastguard Worker
4244*5e7646d2SAndroid Build Coastguard Worker value->string.text = temp;
4245*5e7646d2SAndroid Build Coastguard Worker }
4246*5e7646d2SAndroid Build Coastguard Worker else
4247*5e7646d2SAndroid Build Coastguard Worker return (0);
4248*5e7646d2SAndroid Build Coastguard Worker }
4249*5e7646d2SAndroid Build Coastguard Worker
4250*5e7646d2SAndroid Build Coastguard Worker return (value != NULL);
4251*5e7646d2SAndroid Build Coastguard Worker }
4252*5e7646d2SAndroid Build Coastguard Worker
4253*5e7646d2SAndroid Build Coastguard Worker
4254*5e7646d2SAndroid Build Coastguard Worker /*
4255*5e7646d2SAndroid Build Coastguard Worker * 'ippSetStringf()' - Set a formatted string value of an attribute.
4256*5e7646d2SAndroid Build Coastguard Worker *
4257*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
4258*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
4259*5e7646d2SAndroid Build Coastguard Worker *
4260*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
4261*5e7646d2SAndroid Build Coastguard Worker *
4262*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
4263*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
4264*5e7646d2SAndroid Build Coastguard Worker *
4265*5e7646d2SAndroid Build Coastguard Worker * The @code format@ parameter uses formatting characters compatible with the
4266*5e7646d2SAndroid Build Coastguard Worker * printf family of standard functions. Additional arguments follow it as
4267*5e7646d2SAndroid Build Coastguard Worker * needed. The formatted string is truncated as needed to the maximum length of
4268*5e7646d2SAndroid Build Coastguard Worker * the corresponding value type.
4269*5e7646d2SAndroid Build Coastguard Worker *
4270*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
4271*5e7646d2SAndroid Build Coastguard Worker */
4272*5e7646d2SAndroid Build Coastguard Worker
4273*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetStringf(ipp_t * ipp,ipp_attribute_t ** attr,int element,const char * format,...)4274*5e7646d2SAndroid Build Coastguard Worker ippSetStringf(ipp_t *ipp, /* I - IPP message */
4275*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
4276*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
4277*5e7646d2SAndroid Build Coastguard Worker const char *format, /* I - Printf-style format string */
4278*5e7646d2SAndroid Build Coastguard Worker ...) /* I - Additional arguments as needed */
4279*5e7646d2SAndroid Build Coastguard Worker {
4280*5e7646d2SAndroid Build Coastguard Worker int ret; /* Return value */
4281*5e7646d2SAndroid Build Coastguard Worker va_list ap; /* Pointer to additional arguments */
4282*5e7646d2SAndroid Build Coastguard Worker
4283*5e7646d2SAndroid Build Coastguard Worker
4284*5e7646d2SAndroid Build Coastguard Worker va_start(ap, format);
4285*5e7646d2SAndroid Build Coastguard Worker ret = ippSetStringfv(ipp, attr, element, format, ap);
4286*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
4287*5e7646d2SAndroid Build Coastguard Worker
4288*5e7646d2SAndroid Build Coastguard Worker return (ret);
4289*5e7646d2SAndroid Build Coastguard Worker }
4290*5e7646d2SAndroid Build Coastguard Worker
4291*5e7646d2SAndroid Build Coastguard Worker
4292*5e7646d2SAndroid Build Coastguard Worker /*
4293*5e7646d2SAndroid Build Coastguard Worker * 'ippSetStringf()' - Set a formatted string value of an attribute.
4294*5e7646d2SAndroid Build Coastguard Worker *
4295*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
4296*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
4297*5e7646d2SAndroid Build Coastguard Worker *
4298*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
4299*5e7646d2SAndroid Build Coastguard Worker *
4300*5e7646d2SAndroid Build Coastguard Worker * The @code element@ parameter specifies which value to set from 0 to
4301*5e7646d2SAndroid Build Coastguard Worker * @code ippGetCount(attr)@.
4302*5e7646d2SAndroid Build Coastguard Worker *
4303*5e7646d2SAndroid Build Coastguard Worker * The @code format@ parameter uses formatting characters compatible with the
4304*5e7646d2SAndroid Build Coastguard Worker * printf family of standard functions. Additional arguments follow it as
4305*5e7646d2SAndroid Build Coastguard Worker * needed. The formatted string is truncated as needed to the maximum length of
4306*5e7646d2SAndroid Build Coastguard Worker * the corresponding value type.
4307*5e7646d2SAndroid Build Coastguard Worker *
4308*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
4309*5e7646d2SAndroid Build Coastguard Worker */
4310*5e7646d2SAndroid Build Coastguard Worker
4311*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetStringfv(ipp_t * ipp,ipp_attribute_t ** attr,int element,const char * format,va_list ap)4312*5e7646d2SAndroid Build Coastguard Worker ippSetStringfv(ipp_t *ipp, /* I - IPP message */
4313*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
4314*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Value number (0-based) */
4315*5e7646d2SAndroid Build Coastguard Worker const char *format, /* I - Printf-style format string */
4316*5e7646d2SAndroid Build Coastguard Worker va_list ap) /* I - Pointer to additional arguments */
4317*5e7646d2SAndroid Build Coastguard Worker {
4318*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag; /* Value tag */
4319*5e7646d2SAndroid Build Coastguard Worker char buffer[IPP_MAX_TEXT + 4];
4320*5e7646d2SAndroid Build Coastguard Worker /* Formatted text string */
4321*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes, /* Length of formatted value */
4322*5e7646d2SAndroid Build Coastguard Worker max_bytes; /* Maximum number of bytes for value */
4323*5e7646d2SAndroid Build Coastguard Worker
4324*5e7646d2SAndroid Build Coastguard Worker
4325*5e7646d2SAndroid Build Coastguard Worker /*
4326*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4327*5e7646d2SAndroid Build Coastguard Worker */
4328*5e7646d2SAndroid Build Coastguard Worker
4329*5e7646d2SAndroid Build Coastguard Worker if (attr && *attr)
4330*5e7646d2SAndroid Build Coastguard Worker value_tag = (*attr)->value_tag & IPP_TAG_CUPS_MASK;
4331*5e7646d2SAndroid Build Coastguard Worker else
4332*5e7646d2SAndroid Build Coastguard Worker value_tag = IPP_TAG_ZERO;
4333*5e7646d2SAndroid Build Coastguard Worker
4334*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr || (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG && value_tag != IPP_TAG_NAMELANG && value_tag != IPP_TAG_NOVALUE && value_tag != IPP_TAG_UNKNOWN) || value_tag > IPP_TAG_MIMETYPE || !format)
4335*5e7646d2SAndroid Build Coastguard Worker return (0);
4336*5e7646d2SAndroid Build Coastguard Worker
4337*5e7646d2SAndroid Build Coastguard Worker /*
4338*5e7646d2SAndroid Build Coastguard Worker * Format the string...
4339*5e7646d2SAndroid Build Coastguard Worker */
4340*5e7646d2SAndroid Build Coastguard Worker
4341*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(format, "%s"))
4342*5e7646d2SAndroid Build Coastguard Worker {
4343*5e7646d2SAndroid Build Coastguard Worker /*
4344*5e7646d2SAndroid Build Coastguard Worker * Optimize the simple case...
4345*5e7646d2SAndroid Build Coastguard Worker */
4346*5e7646d2SAndroid Build Coastguard Worker
4347*5e7646d2SAndroid Build Coastguard Worker const char *s = va_arg(ap, char *);
4348*5e7646d2SAndroid Build Coastguard Worker
4349*5e7646d2SAndroid Build Coastguard Worker if (!s)
4350*5e7646d2SAndroid Build Coastguard Worker s = "(null)";
4351*5e7646d2SAndroid Build Coastguard Worker
4352*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)strlen(s);
4353*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, s, sizeof(buffer));
4354*5e7646d2SAndroid Build Coastguard Worker }
4355*5e7646d2SAndroid Build Coastguard Worker else
4356*5e7646d2SAndroid Build Coastguard Worker {
4357*5e7646d2SAndroid Build Coastguard Worker /*
4358*5e7646d2SAndroid Build Coastguard Worker * Do a full formatting of the message...
4359*5e7646d2SAndroid Build Coastguard Worker */
4360*5e7646d2SAndroid Build Coastguard Worker
4361*5e7646d2SAndroid Build Coastguard Worker if ((bytes = vsnprintf(buffer, sizeof(buffer), format, ap)) < 0)
4362*5e7646d2SAndroid Build Coastguard Worker return (0);
4363*5e7646d2SAndroid Build Coastguard Worker }
4364*5e7646d2SAndroid Build Coastguard Worker
4365*5e7646d2SAndroid Build Coastguard Worker /*
4366*5e7646d2SAndroid Build Coastguard Worker * Limit the length of the string...
4367*5e7646d2SAndroid Build Coastguard Worker */
4368*5e7646d2SAndroid Build Coastguard Worker
4369*5e7646d2SAndroid Build Coastguard Worker switch (value_tag)
4370*5e7646d2SAndroid Build Coastguard Worker {
4371*5e7646d2SAndroid Build Coastguard Worker default :
4372*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
4373*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
4374*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_TEXT;
4375*5e7646d2SAndroid Build Coastguard Worker break;
4376*5e7646d2SAndroid Build Coastguard Worker
4377*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
4378*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
4379*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_NAME;
4380*5e7646d2SAndroid Build Coastguard Worker break;
4381*5e7646d2SAndroid Build Coastguard Worker
4382*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
4383*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_CHARSET;
4384*5e7646d2SAndroid Build Coastguard Worker break;
4385*5e7646d2SAndroid Build Coastguard Worker
4386*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOVALUE :
4387*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNKNOWN :
4388*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
4389*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_KEYWORD;
4390*5e7646d2SAndroid Build Coastguard Worker break;
4391*5e7646d2SAndroid Build Coastguard Worker
4392*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
4393*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_LANGUAGE;
4394*5e7646d2SAndroid Build Coastguard Worker break;
4395*5e7646d2SAndroid Build Coastguard Worker
4396*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
4397*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_MIMETYPE;
4398*5e7646d2SAndroid Build Coastguard Worker break;
4399*5e7646d2SAndroid Build Coastguard Worker
4400*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
4401*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_URI;
4402*5e7646d2SAndroid Build Coastguard Worker break;
4403*5e7646d2SAndroid Build Coastguard Worker
4404*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
4405*5e7646d2SAndroid Build Coastguard Worker max_bytes = IPP_MAX_URISCHEME;
4406*5e7646d2SAndroid Build Coastguard Worker break;
4407*5e7646d2SAndroid Build Coastguard Worker }
4408*5e7646d2SAndroid Build Coastguard Worker
4409*5e7646d2SAndroid Build Coastguard Worker if (bytes >= max_bytes)
4410*5e7646d2SAndroid Build Coastguard Worker {
4411*5e7646d2SAndroid Build Coastguard Worker char *bufmax, /* Buffer at max_bytes */
4412*5e7646d2SAndroid Build Coastguard Worker *bufptr; /* Pointer into buffer */
4413*5e7646d2SAndroid Build Coastguard Worker
4414*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer + strlen(buffer) - 1;
4415*5e7646d2SAndroid Build Coastguard Worker bufmax = buffer + max_bytes - 1;
4416*5e7646d2SAndroid Build Coastguard Worker
4417*5e7646d2SAndroid Build Coastguard Worker while (bufptr > bufmax)
4418*5e7646d2SAndroid Build Coastguard Worker {
4419*5e7646d2SAndroid Build Coastguard Worker if (*bufptr & 0x80)
4420*5e7646d2SAndroid Build Coastguard Worker {
4421*5e7646d2SAndroid Build Coastguard Worker while ((*bufptr & 0xc0) == 0x80 && bufptr > buffer)
4422*5e7646d2SAndroid Build Coastguard Worker bufptr --;
4423*5e7646d2SAndroid Build Coastguard Worker }
4424*5e7646d2SAndroid Build Coastguard Worker
4425*5e7646d2SAndroid Build Coastguard Worker bufptr --;
4426*5e7646d2SAndroid Build Coastguard Worker }
4427*5e7646d2SAndroid Build Coastguard Worker
4428*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
4429*5e7646d2SAndroid Build Coastguard Worker }
4430*5e7646d2SAndroid Build Coastguard Worker
4431*5e7646d2SAndroid Build Coastguard Worker /*
4432*5e7646d2SAndroid Build Coastguard Worker * Set the formatted string and return...
4433*5e7646d2SAndroid Build Coastguard Worker */
4434*5e7646d2SAndroid Build Coastguard Worker
4435*5e7646d2SAndroid Build Coastguard Worker return (ippSetString(ipp, attr, element, buffer));
4436*5e7646d2SAndroid Build Coastguard Worker }
4437*5e7646d2SAndroid Build Coastguard Worker
4438*5e7646d2SAndroid Build Coastguard Worker
4439*5e7646d2SAndroid Build Coastguard Worker /*
4440*5e7646d2SAndroid Build Coastguard Worker * 'ippSetValueTag()' - Set the value tag of an attribute.
4441*5e7646d2SAndroid Build Coastguard Worker *
4442*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
4443*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
4444*5e7646d2SAndroid Build Coastguard Worker *
4445*5e7646d2SAndroid Build Coastguard Worker * The @code attr@ parameter may be modified as a result of setting the value.
4446*5e7646d2SAndroid Build Coastguard Worker *
4447*5e7646d2SAndroid Build Coastguard Worker * Integer (@code IPP_TAG_INTEGER@) values can be promoted to rangeOfInteger
4448*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_RANGE@) values, the various string tags can be promoted to name
4449*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_NAME@) or nameWithLanguage (@code IPP_TAG_NAMELANG@) values, text
4450*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_TEXT@) values can be promoted to textWithLanguage
4451*5e7646d2SAndroid Build Coastguard Worker * (@code IPP_TAG_TEXTLANG@) values, and all values can be demoted to the various
4452*5e7646d2SAndroid Build Coastguard Worker * out-of-band value tags such as no-value (@code IPP_TAG_NOVALUE@). All other changes
4453*5e7646d2SAndroid Build Coastguard Worker * will be rejected.
4454*5e7646d2SAndroid Build Coastguard Worker *
4455*5e7646d2SAndroid Build Coastguard Worker * Promoting a string attribute to nameWithLanguage or textWithLanguage adds the language
4456*5e7646d2SAndroid Build Coastguard Worker * code in the "attributes-natural-language" attribute or, if not present, the language
4457*5e7646d2SAndroid Build Coastguard Worker * code for the current locale.
4458*5e7646d2SAndroid Build Coastguard Worker *
4459*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
4460*5e7646d2SAndroid Build Coastguard Worker */
4461*5e7646d2SAndroid Build Coastguard Worker
4462*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetValueTag(ipp_t * ipp,ipp_attribute_t ** attr,ipp_tag_t value_tag)4463*5e7646d2SAndroid Build Coastguard Worker ippSetValueTag(
4464*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - IPP message */
4465*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
4466*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag) /* I - Value tag */
4467*5e7646d2SAndroid Build Coastguard Worker {
4468*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
4469*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
4470*5e7646d2SAndroid Build Coastguard Worker int integer; /* Current integer value */
4471*5e7646d2SAndroid Build Coastguard Worker cups_lang_t *language; /* Current language */
4472*5e7646d2SAndroid Build Coastguard Worker char code[32]; /* Language code */
4473*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t temp_tag; /* Temporary value tag */
4474*5e7646d2SAndroid Build Coastguard Worker
4475*5e7646d2SAndroid Build Coastguard Worker
4476*5e7646d2SAndroid Build Coastguard Worker /*
4477*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4478*5e7646d2SAndroid Build Coastguard Worker */
4479*5e7646d2SAndroid Build Coastguard Worker
4480*5e7646d2SAndroid Build Coastguard Worker if (!ipp || !attr || !*attr)
4481*5e7646d2SAndroid Build Coastguard Worker return (0);
4482*5e7646d2SAndroid Build Coastguard Worker
4483*5e7646d2SAndroid Build Coastguard Worker /*
4484*5e7646d2SAndroid Build Coastguard Worker * If there is no change, return immediately...
4485*5e7646d2SAndroid Build Coastguard Worker */
4486*5e7646d2SAndroid Build Coastguard Worker
4487*5e7646d2SAndroid Build Coastguard Worker if (value_tag == (*attr)->value_tag)
4488*5e7646d2SAndroid Build Coastguard Worker return (1);
4489*5e7646d2SAndroid Build Coastguard Worker
4490*5e7646d2SAndroid Build Coastguard Worker /*
4491*5e7646d2SAndroid Build Coastguard Worker * Otherwise implement changes as needed...
4492*5e7646d2SAndroid Build Coastguard Worker */
4493*5e7646d2SAndroid Build Coastguard Worker
4494*5e7646d2SAndroid Build Coastguard Worker temp_tag = (ipp_tag_t)((int)((*attr)->value_tag) & IPP_TAG_CUPS_MASK);
4495*5e7646d2SAndroid Build Coastguard Worker
4496*5e7646d2SAndroid Build Coastguard Worker switch (value_tag)
4497*5e7646d2SAndroid Build Coastguard Worker {
4498*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNSUPPORTED_VALUE :
4499*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DEFAULT :
4500*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNKNOWN :
4501*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOVALUE :
4502*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOTSETTABLE :
4503*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DELETEATTR :
4504*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ADMINDEFINE :
4505*5e7646d2SAndroid Build Coastguard Worker /*
4506*5e7646d2SAndroid Build Coastguard Worker * Free any existing values...
4507*5e7646d2SAndroid Build Coastguard Worker */
4508*5e7646d2SAndroid Build Coastguard Worker
4509*5e7646d2SAndroid Build Coastguard Worker if ((*attr)->num_values > 0)
4510*5e7646d2SAndroid Build Coastguard Worker ipp_free_values(*attr, 0, (*attr)->num_values);
4511*5e7646d2SAndroid Build Coastguard Worker
4512*5e7646d2SAndroid Build Coastguard Worker /*
4513*5e7646d2SAndroid Build Coastguard Worker * Set out-of-band value...
4514*5e7646d2SAndroid Build Coastguard Worker */
4515*5e7646d2SAndroid Build Coastguard Worker
4516*5e7646d2SAndroid Build Coastguard Worker (*attr)->value_tag = value_tag;
4517*5e7646d2SAndroid Build Coastguard Worker break;
4518*5e7646d2SAndroid Build Coastguard Worker
4519*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
4520*5e7646d2SAndroid Build Coastguard Worker if (temp_tag != IPP_TAG_INTEGER)
4521*5e7646d2SAndroid Build Coastguard Worker return (0);
4522*5e7646d2SAndroid Build Coastguard Worker
4523*5e7646d2SAndroid Build Coastguard Worker for (i = (*attr)->num_values, value = (*attr)->values;
4524*5e7646d2SAndroid Build Coastguard Worker i > 0;
4525*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
4526*5e7646d2SAndroid Build Coastguard Worker {
4527*5e7646d2SAndroid Build Coastguard Worker integer = value->integer;
4528*5e7646d2SAndroid Build Coastguard Worker value->range.lower = value->range.upper = integer;
4529*5e7646d2SAndroid Build Coastguard Worker }
4530*5e7646d2SAndroid Build Coastguard Worker
4531*5e7646d2SAndroid Build Coastguard Worker (*attr)->value_tag = IPP_TAG_RANGE;
4532*5e7646d2SAndroid Build Coastguard Worker break;
4533*5e7646d2SAndroid Build Coastguard Worker
4534*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
4535*5e7646d2SAndroid Build Coastguard Worker if (temp_tag != IPP_TAG_KEYWORD)
4536*5e7646d2SAndroid Build Coastguard Worker return (0);
4537*5e7646d2SAndroid Build Coastguard Worker
4538*5e7646d2SAndroid Build Coastguard Worker (*attr)->value_tag = (ipp_tag_t)(IPP_TAG_NAME | ((*attr)->value_tag & IPP_TAG_CUPS_CONST));
4539*5e7646d2SAndroid Build Coastguard Worker break;
4540*5e7646d2SAndroid Build Coastguard Worker
4541*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
4542*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
4543*5e7646d2SAndroid Build Coastguard Worker if (value_tag == IPP_TAG_NAMELANG && (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD))
4544*5e7646d2SAndroid Build Coastguard Worker return (0);
4545*5e7646d2SAndroid Build Coastguard Worker
4546*5e7646d2SAndroid Build Coastguard Worker if (value_tag == IPP_TAG_TEXTLANG && temp_tag != IPP_TAG_TEXT)
4547*5e7646d2SAndroid Build Coastguard Worker return (0);
4548*5e7646d2SAndroid Build Coastguard Worker
4549*5e7646d2SAndroid Build Coastguard Worker if (ipp->attrs && ipp->attrs->next && ipp->attrs->next->name &&
4550*5e7646d2SAndroid Build Coastguard Worker !strcmp(ipp->attrs->next->name, "attributes-natural-language") && (ipp->attrs->next->value_tag & IPP_TAG_CUPS_MASK) == IPP_TAG_LANGUAGE)
4551*5e7646d2SAndroid Build Coastguard Worker {
4552*5e7646d2SAndroid Build Coastguard Worker /*
4553*5e7646d2SAndroid Build Coastguard Worker * Use the language code from the IPP message...
4554*5e7646d2SAndroid Build Coastguard Worker */
4555*5e7646d2SAndroid Build Coastguard Worker
4556*5e7646d2SAndroid Build Coastguard Worker (*attr)->values[0].string.language =
4557*5e7646d2SAndroid Build Coastguard Worker _cupsStrAlloc(ipp->attrs->next->values[0].string.text);
4558*5e7646d2SAndroid Build Coastguard Worker }
4559*5e7646d2SAndroid Build Coastguard Worker else
4560*5e7646d2SAndroid Build Coastguard Worker {
4561*5e7646d2SAndroid Build Coastguard Worker /*
4562*5e7646d2SAndroid Build Coastguard Worker * Otherwise, use the language code corresponding to the locale...
4563*5e7646d2SAndroid Build Coastguard Worker */
4564*5e7646d2SAndroid Build Coastguard Worker
4565*5e7646d2SAndroid Build Coastguard Worker language = cupsLangDefault();
4566*5e7646d2SAndroid Build Coastguard Worker (*attr)->values[0].string.language = _cupsStrAlloc(ipp_lang_code(language->language,
4567*5e7646d2SAndroid Build Coastguard Worker code,
4568*5e7646d2SAndroid Build Coastguard Worker sizeof(code)));
4569*5e7646d2SAndroid Build Coastguard Worker }
4570*5e7646d2SAndroid Build Coastguard Worker
4571*5e7646d2SAndroid Build Coastguard Worker for (i = (*attr)->num_values - 1, value = (*attr)->values + 1;
4572*5e7646d2SAndroid Build Coastguard Worker i > 0;
4573*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
4574*5e7646d2SAndroid Build Coastguard Worker value->string.language = (*attr)->values[0].string.language;
4575*5e7646d2SAndroid Build Coastguard Worker
4576*5e7646d2SAndroid Build Coastguard Worker if ((int)(*attr)->value_tag & IPP_TAG_CUPS_CONST)
4577*5e7646d2SAndroid Build Coastguard Worker {
4578*5e7646d2SAndroid Build Coastguard Worker /*
4579*5e7646d2SAndroid Build Coastguard Worker * Make copies of all values...
4580*5e7646d2SAndroid Build Coastguard Worker */
4581*5e7646d2SAndroid Build Coastguard Worker
4582*5e7646d2SAndroid Build Coastguard Worker for (i = (*attr)->num_values, value = (*attr)->values;
4583*5e7646d2SAndroid Build Coastguard Worker i > 0;
4584*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
4585*5e7646d2SAndroid Build Coastguard Worker value->string.text = _cupsStrAlloc(value->string.text);
4586*5e7646d2SAndroid Build Coastguard Worker }
4587*5e7646d2SAndroid Build Coastguard Worker
4588*5e7646d2SAndroid Build Coastguard Worker (*attr)->value_tag = IPP_TAG_NAMELANG;
4589*5e7646d2SAndroid Build Coastguard Worker break;
4590*5e7646d2SAndroid Build Coastguard Worker
4591*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
4592*5e7646d2SAndroid Build Coastguard Worker if (temp_tag == IPP_TAG_NAME || temp_tag == IPP_TAG_NAMELANG)
4593*5e7646d2SAndroid Build Coastguard Worker break; /* Silently "allow" name -> keyword */
4594*5e7646d2SAndroid Build Coastguard Worker
4595*5e7646d2SAndroid Build Coastguard Worker default :
4596*5e7646d2SAndroid Build Coastguard Worker return (0);
4597*5e7646d2SAndroid Build Coastguard Worker }
4598*5e7646d2SAndroid Build Coastguard Worker
4599*5e7646d2SAndroid Build Coastguard Worker return (1);
4600*5e7646d2SAndroid Build Coastguard Worker }
4601*5e7646d2SAndroid Build Coastguard Worker
4602*5e7646d2SAndroid Build Coastguard Worker
4603*5e7646d2SAndroid Build Coastguard Worker /*
4604*5e7646d2SAndroid Build Coastguard Worker * 'ippSetVersion()' - Set the version number in an IPP message.
4605*5e7646d2SAndroid Build Coastguard Worker *
4606*5e7646d2SAndroid Build Coastguard Worker * The @code ipp@ parameter refers to an IPP message previously created using
4607*5e7646d2SAndroid Build Coastguard Worker * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
4608*5e7646d2SAndroid Build Coastguard Worker *
4609*5e7646d2SAndroid Build Coastguard Worker * The valid version numbers are currently 1.0, 1.1, 2.0, 2.1, and 2.2.
4610*5e7646d2SAndroid Build Coastguard Worker *
4611*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.6/macOS 10.8@
4612*5e7646d2SAndroid Build Coastguard Worker */
4613*5e7646d2SAndroid Build Coastguard Worker
4614*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
ippSetVersion(ipp_t * ipp,int major,int minor)4615*5e7646d2SAndroid Build Coastguard Worker ippSetVersion(ipp_t *ipp, /* I - IPP message */
4616*5e7646d2SAndroid Build Coastguard Worker int major, /* I - Major version number (major.minor) */
4617*5e7646d2SAndroid Build Coastguard Worker int minor) /* I - Minor version number (major.minor) */
4618*5e7646d2SAndroid Build Coastguard Worker {
4619*5e7646d2SAndroid Build Coastguard Worker /*
4620*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4621*5e7646d2SAndroid Build Coastguard Worker */
4622*5e7646d2SAndroid Build Coastguard Worker
4623*5e7646d2SAndroid Build Coastguard Worker if (!ipp || major < 0 || minor < 0)
4624*5e7646d2SAndroid Build Coastguard Worker return (0);
4625*5e7646d2SAndroid Build Coastguard Worker
4626*5e7646d2SAndroid Build Coastguard Worker /*
4627*5e7646d2SAndroid Build Coastguard Worker * Set the version number...
4628*5e7646d2SAndroid Build Coastguard Worker */
4629*5e7646d2SAndroid Build Coastguard Worker
4630*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.version[0] = (ipp_uchar_t)major;
4631*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.version[1] = (ipp_uchar_t)minor;
4632*5e7646d2SAndroid Build Coastguard Worker
4633*5e7646d2SAndroid Build Coastguard Worker return (1);
4634*5e7646d2SAndroid Build Coastguard Worker }
4635*5e7646d2SAndroid Build Coastguard Worker
4636*5e7646d2SAndroid Build Coastguard Worker
4637*5e7646d2SAndroid Build Coastguard Worker /*
4638*5e7646d2SAndroid Build Coastguard Worker * 'ippTimeToDate()' - Convert from time in seconds to RFC 2579 format.
4639*5e7646d2SAndroid Build Coastguard Worker */
4640*5e7646d2SAndroid Build Coastguard Worker
4641*5e7646d2SAndroid Build Coastguard Worker const ipp_uchar_t * /* O - RFC-2579 date/time data */
ippTimeToDate(time_t t)4642*5e7646d2SAndroid Build Coastguard Worker ippTimeToDate(time_t t) /* I - Time in seconds */
4643*5e7646d2SAndroid Build Coastguard Worker {
4644*5e7646d2SAndroid Build Coastguard Worker struct tm unixdate; /* UNIX unixdate/time info */
4645*5e7646d2SAndroid Build Coastguard Worker ipp_uchar_t *date = _cupsGlobals()->ipp_date;
4646*5e7646d2SAndroid Build Coastguard Worker /* RFC-2579 date/time data */
4647*5e7646d2SAndroid Build Coastguard Worker
4648*5e7646d2SAndroid Build Coastguard Worker
4649*5e7646d2SAndroid Build Coastguard Worker /*
4650*5e7646d2SAndroid Build Coastguard Worker * RFC-2579 date/time format is:
4651*5e7646d2SAndroid Build Coastguard Worker *
4652*5e7646d2SAndroid Build Coastguard Worker * Byte(s) Description
4653*5e7646d2SAndroid Build Coastguard Worker * ------- -----------
4654*5e7646d2SAndroid Build Coastguard Worker * 0-1 Year (0 to 65535)
4655*5e7646d2SAndroid Build Coastguard Worker * 2 Month (1 to 12)
4656*5e7646d2SAndroid Build Coastguard Worker * 3 Day (1 to 31)
4657*5e7646d2SAndroid Build Coastguard Worker * 4 Hours (0 to 23)
4658*5e7646d2SAndroid Build Coastguard Worker * 5 Minutes (0 to 59)
4659*5e7646d2SAndroid Build Coastguard Worker * 6 Seconds (0 to 60, 60 = "leap second")
4660*5e7646d2SAndroid Build Coastguard Worker * 7 Deciseconds (0 to 9)
4661*5e7646d2SAndroid Build Coastguard Worker * 8 +/- UTC
4662*5e7646d2SAndroid Build Coastguard Worker * 9 UTC hours (0 to 11)
4663*5e7646d2SAndroid Build Coastguard Worker * 10 UTC minutes (0 to 59)
4664*5e7646d2SAndroid Build Coastguard Worker */
4665*5e7646d2SAndroid Build Coastguard Worker
4666*5e7646d2SAndroid Build Coastguard Worker gmtime_r(&t, &unixdate);
4667*5e7646d2SAndroid Build Coastguard Worker unixdate.tm_year += 1900;
4668*5e7646d2SAndroid Build Coastguard Worker
4669*5e7646d2SAndroid Build Coastguard Worker date[0] = (ipp_uchar_t)(unixdate.tm_year >> 8);
4670*5e7646d2SAndroid Build Coastguard Worker date[1] = (ipp_uchar_t)(unixdate.tm_year);
4671*5e7646d2SAndroid Build Coastguard Worker date[2] = (ipp_uchar_t)(unixdate.tm_mon + 1);
4672*5e7646d2SAndroid Build Coastguard Worker date[3] = (ipp_uchar_t)unixdate.tm_mday;
4673*5e7646d2SAndroid Build Coastguard Worker date[4] = (ipp_uchar_t)unixdate.tm_hour;
4674*5e7646d2SAndroid Build Coastguard Worker date[5] = (ipp_uchar_t)unixdate.tm_min;
4675*5e7646d2SAndroid Build Coastguard Worker date[6] = (ipp_uchar_t)unixdate.tm_sec;
4676*5e7646d2SAndroid Build Coastguard Worker date[7] = 0;
4677*5e7646d2SAndroid Build Coastguard Worker date[8] = '+';
4678*5e7646d2SAndroid Build Coastguard Worker date[9] = 0;
4679*5e7646d2SAndroid Build Coastguard Worker date[10] = 0;
4680*5e7646d2SAndroid Build Coastguard Worker
4681*5e7646d2SAndroid Build Coastguard Worker return (date);
4682*5e7646d2SAndroid Build Coastguard Worker }
4683*5e7646d2SAndroid Build Coastguard Worker
4684*5e7646d2SAndroid Build Coastguard Worker
4685*5e7646d2SAndroid Build Coastguard Worker /*
4686*5e7646d2SAndroid Build Coastguard Worker * 'ippValidateAttribute()' - Validate the contents of an attribute.
4687*5e7646d2SAndroid Build Coastguard Worker *
4688*5e7646d2SAndroid Build Coastguard Worker * This function validates the contents of an attribute based on the name and
4689*5e7646d2SAndroid Build Coastguard Worker * value tag. 1 is returned if the attribute is valid, 0 otherwise. On
4690*5e7646d2SAndroid Build Coastguard Worker * failure, @link cupsLastErrorString@ is set to a human-readable message.
4691*5e7646d2SAndroid Build Coastguard Worker *
4692*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
4693*5e7646d2SAndroid Build Coastguard Worker */
4694*5e7646d2SAndroid Build Coastguard Worker
4695*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 if valid, 0 otherwise */
ippValidateAttribute(ipp_attribute_t * attr)4696*5e7646d2SAndroid Build Coastguard Worker ippValidateAttribute(
4697*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr) /* I - Attribute */
4698*5e7646d2SAndroid Build Coastguard Worker {
4699*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
4700*5e7646d2SAndroid Build Coastguard Worker char scheme[64], /* Scheme from URI */
4701*5e7646d2SAndroid Build Coastguard Worker userpass[256], /* Username/password from URI */
4702*5e7646d2SAndroid Build Coastguard Worker hostname[256], /* Hostname from URI */
4703*5e7646d2SAndroid Build Coastguard Worker resource[1024]; /* Resource from URI */
4704*5e7646d2SAndroid Build Coastguard Worker int port, /* Port number from URI */
4705*5e7646d2SAndroid Build Coastguard Worker uri_status; /* URI separation status */
4706*5e7646d2SAndroid Build Coastguard Worker const char *ptr; /* Pointer into string */
4707*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *colattr; /* Collection attribute */
4708*5e7646d2SAndroid Build Coastguard Worker regex_t re; /* Regular expression */
4709*5e7646d2SAndroid Build Coastguard Worker ipp_uchar_t *date; /* Current date value */
4710*5e7646d2SAndroid Build Coastguard Worker
4711*5e7646d2SAndroid Build Coastguard Worker
4712*5e7646d2SAndroid Build Coastguard Worker /*
4713*5e7646d2SAndroid Build Coastguard Worker * Skip separators.
4714*5e7646d2SAndroid Build Coastguard Worker */
4715*5e7646d2SAndroid Build Coastguard Worker
4716*5e7646d2SAndroid Build Coastguard Worker if (!attr->name)
4717*5e7646d2SAndroid Build Coastguard Worker return (1);
4718*5e7646d2SAndroid Build Coastguard Worker
4719*5e7646d2SAndroid Build Coastguard Worker /*
4720*5e7646d2SAndroid Build Coastguard Worker * Validate the attribute name.
4721*5e7646d2SAndroid Build Coastguard Worker */
4722*5e7646d2SAndroid Build Coastguard Worker
4723*5e7646d2SAndroid Build Coastguard Worker for (ptr = attr->name; *ptr; ptr ++)
4724*5e7646d2SAndroid Build Coastguard Worker if (!isalnum(*ptr & 255) && *ptr != '-' && *ptr != '.' && *ptr != '_')
4725*5e7646d2SAndroid Build Coastguard Worker break;
4726*5e7646d2SAndroid Build Coastguard Worker
4727*5e7646d2SAndroid Build Coastguard Worker if (*ptr || ptr == attr->name)
4728*5e7646d2SAndroid Build Coastguard Worker {
4729*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad attribute name - invalid character (RFC 8011 section 5.1.4)."), attr->name);
4730*5e7646d2SAndroid Build Coastguard Worker return (0);
4731*5e7646d2SAndroid Build Coastguard Worker }
4732*5e7646d2SAndroid Build Coastguard Worker
4733*5e7646d2SAndroid Build Coastguard Worker if ((ptr - attr->name) > 255)
4734*5e7646d2SAndroid Build Coastguard Worker {
4735*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad attribute name - bad length %d (RFC 8011 section 5.1.4)."), attr->name, (int)(ptr - attr->name));
4736*5e7646d2SAndroid Build Coastguard Worker return (0);
4737*5e7646d2SAndroid Build Coastguard Worker }
4738*5e7646d2SAndroid Build Coastguard Worker
4739*5e7646d2SAndroid Build Coastguard Worker switch (attr->value_tag)
4740*5e7646d2SAndroid Build Coastguard Worker {
4741*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
4742*5e7646d2SAndroid Build Coastguard Worker break;
4743*5e7646d2SAndroid Build Coastguard Worker
4744*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
4745*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4746*5e7646d2SAndroid Build Coastguard Worker {
4747*5e7646d2SAndroid Build Coastguard Worker if (attr->values[i].boolean != 0 &&
4748*5e7646d2SAndroid Build Coastguard Worker attr->values[i].boolean != 1)
4749*5e7646d2SAndroid Build Coastguard Worker {
4750*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad boolean value %d (RFC 8011 section 5.1.21)."), attr->name, attr->values[i].boolean);
4751*5e7646d2SAndroid Build Coastguard Worker return (0);
4752*5e7646d2SAndroid Build Coastguard Worker }
4753*5e7646d2SAndroid Build Coastguard Worker }
4754*5e7646d2SAndroid Build Coastguard Worker break;
4755*5e7646d2SAndroid Build Coastguard Worker
4756*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
4757*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4758*5e7646d2SAndroid Build Coastguard Worker {
4759*5e7646d2SAndroid Build Coastguard Worker if (attr->values[i].integer < 1)
4760*5e7646d2SAndroid Build Coastguard Worker {
4761*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad enum value %d - out of range (RFC 8011 section 5.1.5)."), attr->name, attr->values[i].integer);
4762*5e7646d2SAndroid Build Coastguard Worker return (0);
4763*5e7646d2SAndroid Build Coastguard Worker }
4764*5e7646d2SAndroid Build Coastguard Worker }
4765*5e7646d2SAndroid Build Coastguard Worker break;
4766*5e7646d2SAndroid Build Coastguard Worker
4767*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
4768*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4769*5e7646d2SAndroid Build Coastguard Worker {
4770*5e7646d2SAndroid Build Coastguard Worker if (attr->values[i].unknown.length > IPP_MAX_OCTETSTRING)
4771*5e7646d2SAndroid Build Coastguard Worker {
4772*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad octetString value - bad length %d (RFC 8011 section 5.1.20)."), attr->name, attr->values[i].unknown.length);
4773*5e7646d2SAndroid Build Coastguard Worker return (0);
4774*5e7646d2SAndroid Build Coastguard Worker }
4775*5e7646d2SAndroid Build Coastguard Worker }
4776*5e7646d2SAndroid Build Coastguard Worker break;
4777*5e7646d2SAndroid Build Coastguard Worker
4778*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DATE :
4779*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4780*5e7646d2SAndroid Build Coastguard Worker {
4781*5e7646d2SAndroid Build Coastguard Worker date = attr->values[i].date;
4782*5e7646d2SAndroid Build Coastguard Worker
4783*5e7646d2SAndroid Build Coastguard Worker if (date[2] < 1 || date[2] > 12)
4784*5e7646d2SAndroid Build Coastguard Worker {
4785*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime month %u (RFC 8011 section 5.1.15)."), attr->name, date[2]);
4786*5e7646d2SAndroid Build Coastguard Worker return (0);
4787*5e7646d2SAndroid Build Coastguard Worker }
4788*5e7646d2SAndroid Build Coastguard Worker
4789*5e7646d2SAndroid Build Coastguard Worker if (date[3] < 1 || date[3] > 31)
4790*5e7646d2SAndroid Build Coastguard Worker {
4791*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime day %u (RFC 8011 section 5.1.15)."), attr->name, date[3]);
4792*5e7646d2SAndroid Build Coastguard Worker return (0);
4793*5e7646d2SAndroid Build Coastguard Worker }
4794*5e7646d2SAndroid Build Coastguard Worker
4795*5e7646d2SAndroid Build Coastguard Worker if (date[4] > 23)
4796*5e7646d2SAndroid Build Coastguard Worker {
4797*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime hours %u (RFC 8011 section 5.1.15)."), attr->name, date[4]);
4798*5e7646d2SAndroid Build Coastguard Worker return (0);
4799*5e7646d2SAndroid Build Coastguard Worker }
4800*5e7646d2SAndroid Build Coastguard Worker
4801*5e7646d2SAndroid Build Coastguard Worker if (date[5] > 59)
4802*5e7646d2SAndroid Build Coastguard Worker {
4803*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime minutes %u (RFC 8011 section 5.1.15)."), attr->name, date[5]);
4804*5e7646d2SAndroid Build Coastguard Worker return (0);
4805*5e7646d2SAndroid Build Coastguard Worker }
4806*5e7646d2SAndroid Build Coastguard Worker
4807*5e7646d2SAndroid Build Coastguard Worker if (date[6] > 60)
4808*5e7646d2SAndroid Build Coastguard Worker {
4809*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime seconds %u (RFC 8011 section 5.1.15)."), attr->name, date[6]);
4810*5e7646d2SAndroid Build Coastguard Worker return (0);
4811*5e7646d2SAndroid Build Coastguard Worker }
4812*5e7646d2SAndroid Build Coastguard Worker
4813*5e7646d2SAndroid Build Coastguard Worker if (date[7] > 9)
4814*5e7646d2SAndroid Build Coastguard Worker {
4815*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime deciseconds %u (RFC 8011 section 5.1.15)."), attr->name, date[7]);
4816*5e7646d2SAndroid Build Coastguard Worker return (0);
4817*5e7646d2SAndroid Build Coastguard Worker }
4818*5e7646d2SAndroid Build Coastguard Worker
4819*5e7646d2SAndroid Build Coastguard Worker if (date[8] != '-' && date[8] != '+')
4820*5e7646d2SAndroid Build Coastguard Worker {
4821*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime UTC sign '%c' (RFC 8011 section 5.1.15)."), attr->name, date[8]);
4822*5e7646d2SAndroid Build Coastguard Worker return (0);
4823*5e7646d2SAndroid Build Coastguard Worker }
4824*5e7646d2SAndroid Build Coastguard Worker
4825*5e7646d2SAndroid Build Coastguard Worker if (date[9] > 11)
4826*5e7646d2SAndroid Build Coastguard Worker {
4827*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime UTC hours %u (RFC 8011 section 5.1.15)."), attr->name, date[9]);
4828*5e7646d2SAndroid Build Coastguard Worker return (0);
4829*5e7646d2SAndroid Build Coastguard Worker }
4830*5e7646d2SAndroid Build Coastguard Worker
4831*5e7646d2SAndroid Build Coastguard Worker if (date[10] > 59)
4832*5e7646d2SAndroid Build Coastguard Worker {
4833*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime UTC minutes %u (RFC 8011 section 5.1.15)."), attr->name, date[10]);
4834*5e7646d2SAndroid Build Coastguard Worker return (0);
4835*5e7646d2SAndroid Build Coastguard Worker }
4836*5e7646d2SAndroid Build Coastguard Worker }
4837*5e7646d2SAndroid Build Coastguard Worker break;
4838*5e7646d2SAndroid Build Coastguard Worker
4839*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
4840*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4841*5e7646d2SAndroid Build Coastguard Worker {
4842*5e7646d2SAndroid Build Coastguard Worker if (attr->values[i].resolution.xres <= 0)
4843*5e7646d2SAndroid Build Coastguard Worker {
4844*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad resolution value %dx%d%s - cross feed resolution must be positive (RFC 8011 section 5.1.16)."), attr->name, attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == IPP_RES_PER_CM ? "dpcm" : "unknown");
4845*5e7646d2SAndroid Build Coastguard Worker return (0);
4846*5e7646d2SAndroid Build Coastguard Worker }
4847*5e7646d2SAndroid Build Coastguard Worker
4848*5e7646d2SAndroid Build Coastguard Worker if (attr->values[i].resolution.yres <= 0)
4849*5e7646d2SAndroid Build Coastguard Worker {
4850*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad resolution value %dx%d%s - feed resolution must be positive (RFC 8011 section 5.1.16)."), attr->name, attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == IPP_RES_PER_CM ? "dpcm" : "unknown");
4851*5e7646d2SAndroid Build Coastguard Worker return (0);
4852*5e7646d2SAndroid Build Coastguard Worker }
4853*5e7646d2SAndroid Build Coastguard Worker
4854*5e7646d2SAndroid Build Coastguard Worker if (attr->values[i].resolution.units != IPP_RES_PER_INCH && attr->values[i].resolution.units != IPP_RES_PER_CM)
4855*5e7646d2SAndroid Build Coastguard Worker {
4856*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad resolution value %dx%d%s - bad units value (RFC 8011 section 5.1.16)."), attr->name, attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == IPP_RES_PER_CM ? "dpcm" : "unknown");
4857*5e7646d2SAndroid Build Coastguard Worker return (0);
4858*5e7646d2SAndroid Build Coastguard Worker }
4859*5e7646d2SAndroid Build Coastguard Worker }
4860*5e7646d2SAndroid Build Coastguard Worker break;
4861*5e7646d2SAndroid Build Coastguard Worker
4862*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
4863*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4864*5e7646d2SAndroid Build Coastguard Worker {
4865*5e7646d2SAndroid Build Coastguard Worker if (attr->values[i].range.lower > attr->values[i].range.upper)
4866*5e7646d2SAndroid Build Coastguard Worker {
4867*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad rangeOfInteger value %d-%d - lower greater than upper (RFC 8011 section 5.1.14)."), attr->name, attr->values[i].range.lower, attr->values[i].range.upper);
4868*5e7646d2SAndroid Build Coastguard Worker return (0);
4869*5e7646d2SAndroid Build Coastguard Worker }
4870*5e7646d2SAndroid Build Coastguard Worker }
4871*5e7646d2SAndroid Build Coastguard Worker break;
4872*5e7646d2SAndroid Build Coastguard Worker
4873*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
4874*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4875*5e7646d2SAndroid Build Coastguard Worker {
4876*5e7646d2SAndroid Build Coastguard Worker for (colattr = attr->values[i].collection->attrs;
4877*5e7646d2SAndroid Build Coastguard Worker colattr;
4878*5e7646d2SAndroid Build Coastguard Worker colattr = colattr->next)
4879*5e7646d2SAndroid Build Coastguard Worker {
4880*5e7646d2SAndroid Build Coastguard Worker if (!ippValidateAttribute(colattr))
4881*5e7646d2SAndroid Build Coastguard Worker return (0);
4882*5e7646d2SAndroid Build Coastguard Worker }
4883*5e7646d2SAndroid Build Coastguard Worker }
4884*5e7646d2SAndroid Build Coastguard Worker break;
4885*5e7646d2SAndroid Build Coastguard Worker
4886*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
4887*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
4888*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4889*5e7646d2SAndroid Build Coastguard Worker {
4890*5e7646d2SAndroid Build Coastguard Worker for (ptr = attr->values[i].string.text; *ptr; ptr ++)
4891*5e7646d2SAndroid Build Coastguard Worker {
4892*5e7646d2SAndroid Build Coastguard Worker if ((*ptr & 0xe0) == 0xc0)
4893*5e7646d2SAndroid Build Coastguard Worker {
4894*5e7646d2SAndroid Build Coastguard Worker if ((ptr[1] & 0xc0) != 0x80)
4895*5e7646d2SAndroid Build Coastguard Worker break;
4896*5e7646d2SAndroid Build Coastguard Worker
4897*5e7646d2SAndroid Build Coastguard Worker ptr ++;
4898*5e7646d2SAndroid Build Coastguard Worker }
4899*5e7646d2SAndroid Build Coastguard Worker else if ((*ptr & 0xf0) == 0xe0)
4900*5e7646d2SAndroid Build Coastguard Worker {
4901*5e7646d2SAndroid Build Coastguard Worker if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80)
4902*5e7646d2SAndroid Build Coastguard Worker break;
4903*5e7646d2SAndroid Build Coastguard Worker
4904*5e7646d2SAndroid Build Coastguard Worker ptr += 2;
4905*5e7646d2SAndroid Build Coastguard Worker }
4906*5e7646d2SAndroid Build Coastguard Worker else if ((*ptr & 0xf8) == 0xf0)
4907*5e7646d2SAndroid Build Coastguard Worker {
4908*5e7646d2SAndroid Build Coastguard Worker if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80 || (ptr[3] & 0xc0) != 0x80)
4909*5e7646d2SAndroid Build Coastguard Worker break;
4910*5e7646d2SAndroid Build Coastguard Worker
4911*5e7646d2SAndroid Build Coastguard Worker ptr += 3;
4912*5e7646d2SAndroid Build Coastguard Worker }
4913*5e7646d2SAndroid Build Coastguard Worker else if (*ptr & 0x80)
4914*5e7646d2SAndroid Build Coastguard Worker break;
4915*5e7646d2SAndroid Build Coastguard Worker else if ((*ptr < ' ' && *ptr != '\n' && *ptr != '\r' && *ptr != '\t') || *ptr == 0x7f)
4916*5e7646d2SAndroid Build Coastguard Worker break;
4917*5e7646d2SAndroid Build Coastguard Worker }
4918*5e7646d2SAndroid Build Coastguard Worker
4919*5e7646d2SAndroid Build Coastguard Worker if (*ptr)
4920*5e7646d2SAndroid Build Coastguard Worker {
4921*5e7646d2SAndroid Build Coastguard Worker if (*ptr < ' ' || *ptr == 0x7f)
4922*5e7646d2SAndroid Build Coastguard Worker {
4923*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad control character (PWG 5100.14 section 8.3)."), attr->name, attr->values[i].string.text);
4924*5e7646d2SAndroid Build Coastguard Worker return (0);
4925*5e7646d2SAndroid Build Coastguard Worker }
4926*5e7646d2SAndroid Build Coastguard Worker else
4927*5e7646d2SAndroid Build Coastguard Worker {
4928*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad UTF-8 sequence (RFC 8011 section 5.1.2)."), attr->name, attr->values[i].string.text);
4929*5e7646d2SAndroid Build Coastguard Worker return (0);
4930*5e7646d2SAndroid Build Coastguard Worker }
4931*5e7646d2SAndroid Build Coastguard Worker }
4932*5e7646d2SAndroid Build Coastguard Worker
4933*5e7646d2SAndroid Build Coastguard Worker if ((ptr - attr->values[i].string.text) > (IPP_MAX_TEXT - 1))
4934*5e7646d2SAndroid Build Coastguard Worker {
4935*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad length %d (RFC 8011 section 5.1.2)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text));
4936*5e7646d2SAndroid Build Coastguard Worker return (0);
4937*5e7646d2SAndroid Build Coastguard Worker }
4938*5e7646d2SAndroid Build Coastguard Worker }
4939*5e7646d2SAndroid Build Coastguard Worker break;
4940*5e7646d2SAndroid Build Coastguard Worker
4941*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
4942*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
4943*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4944*5e7646d2SAndroid Build Coastguard Worker {
4945*5e7646d2SAndroid Build Coastguard Worker for (ptr = attr->values[i].string.text; *ptr; ptr ++)
4946*5e7646d2SAndroid Build Coastguard Worker {
4947*5e7646d2SAndroid Build Coastguard Worker if ((*ptr & 0xe0) == 0xc0)
4948*5e7646d2SAndroid Build Coastguard Worker {
4949*5e7646d2SAndroid Build Coastguard Worker if ((ptr[1] & 0xc0) != 0x80)
4950*5e7646d2SAndroid Build Coastguard Worker break;
4951*5e7646d2SAndroid Build Coastguard Worker
4952*5e7646d2SAndroid Build Coastguard Worker ptr ++;
4953*5e7646d2SAndroid Build Coastguard Worker }
4954*5e7646d2SAndroid Build Coastguard Worker else if ((*ptr & 0xf0) == 0xe0)
4955*5e7646d2SAndroid Build Coastguard Worker {
4956*5e7646d2SAndroid Build Coastguard Worker if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80)
4957*5e7646d2SAndroid Build Coastguard Worker break;
4958*5e7646d2SAndroid Build Coastguard Worker
4959*5e7646d2SAndroid Build Coastguard Worker ptr += 2;
4960*5e7646d2SAndroid Build Coastguard Worker }
4961*5e7646d2SAndroid Build Coastguard Worker else if ((*ptr & 0xf8) == 0xf0)
4962*5e7646d2SAndroid Build Coastguard Worker {
4963*5e7646d2SAndroid Build Coastguard Worker if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80 || (ptr[3] & 0xc0) != 0x80)
4964*5e7646d2SAndroid Build Coastguard Worker break;
4965*5e7646d2SAndroid Build Coastguard Worker
4966*5e7646d2SAndroid Build Coastguard Worker ptr += 3;
4967*5e7646d2SAndroid Build Coastguard Worker }
4968*5e7646d2SAndroid Build Coastguard Worker else if (*ptr & 0x80)
4969*5e7646d2SAndroid Build Coastguard Worker break;
4970*5e7646d2SAndroid Build Coastguard Worker else if (*ptr < ' ' || *ptr == 0x7f)
4971*5e7646d2SAndroid Build Coastguard Worker break;
4972*5e7646d2SAndroid Build Coastguard Worker }
4973*5e7646d2SAndroid Build Coastguard Worker
4974*5e7646d2SAndroid Build Coastguard Worker if (*ptr)
4975*5e7646d2SAndroid Build Coastguard Worker {
4976*5e7646d2SAndroid Build Coastguard Worker if (*ptr < ' ' || *ptr == 0x7f)
4977*5e7646d2SAndroid Build Coastguard Worker {
4978*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad control character (PWG 5100.14 section 8.1)."), attr->name, attr->values[i].string.text);
4979*5e7646d2SAndroid Build Coastguard Worker return (0);
4980*5e7646d2SAndroid Build Coastguard Worker }
4981*5e7646d2SAndroid Build Coastguard Worker else
4982*5e7646d2SAndroid Build Coastguard Worker {
4983*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad UTF-8 sequence (RFC 8011 section 5.1.3)."), attr->name, attr->values[i].string.text);
4984*5e7646d2SAndroid Build Coastguard Worker return (0);
4985*5e7646d2SAndroid Build Coastguard Worker }
4986*5e7646d2SAndroid Build Coastguard Worker }
4987*5e7646d2SAndroid Build Coastguard Worker
4988*5e7646d2SAndroid Build Coastguard Worker if ((ptr - attr->values[i].string.text) > (IPP_MAX_NAME - 1))
4989*5e7646d2SAndroid Build Coastguard Worker {
4990*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad length %d (RFC 8011 section 5.1.3)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text));
4991*5e7646d2SAndroid Build Coastguard Worker return (0);
4992*5e7646d2SAndroid Build Coastguard Worker }
4993*5e7646d2SAndroid Build Coastguard Worker }
4994*5e7646d2SAndroid Build Coastguard Worker break;
4995*5e7646d2SAndroid Build Coastguard Worker
4996*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
4997*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4998*5e7646d2SAndroid Build Coastguard Worker {
4999*5e7646d2SAndroid Build Coastguard Worker for (ptr = attr->values[i].string.text; *ptr; ptr ++)
5000*5e7646d2SAndroid Build Coastguard Worker {
5001*5e7646d2SAndroid Build Coastguard Worker if (!isalnum(*ptr & 255) && *ptr != '-' && *ptr != '.' &&
5002*5e7646d2SAndroid Build Coastguard Worker *ptr != '_')
5003*5e7646d2SAndroid Build Coastguard Worker break;
5004*5e7646d2SAndroid Build Coastguard Worker }
5005*5e7646d2SAndroid Build Coastguard Worker
5006*5e7646d2SAndroid Build Coastguard Worker if (*ptr || ptr == attr->values[i].string.text)
5007*5e7646d2SAndroid Build Coastguard Worker {
5008*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad keyword value \"%s\" - invalid character (RFC 8011 section 5.1.4)."), attr->name, attr->values[i].string.text);
5009*5e7646d2SAndroid Build Coastguard Worker return (0);
5010*5e7646d2SAndroid Build Coastguard Worker }
5011*5e7646d2SAndroid Build Coastguard Worker
5012*5e7646d2SAndroid Build Coastguard Worker if ((ptr - attr->values[i].string.text) > (IPP_MAX_KEYWORD - 1))
5013*5e7646d2SAndroid Build Coastguard Worker {
5014*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad keyword value \"%s\" - bad length %d (RFC 8011 section 5.1.4)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text));
5015*5e7646d2SAndroid Build Coastguard Worker return (0);
5016*5e7646d2SAndroid Build Coastguard Worker }
5017*5e7646d2SAndroid Build Coastguard Worker }
5018*5e7646d2SAndroid Build Coastguard Worker break;
5019*5e7646d2SAndroid Build Coastguard Worker
5020*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
5021*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
5022*5e7646d2SAndroid Build Coastguard Worker {
5023*5e7646d2SAndroid Build Coastguard Worker uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, sizeof(resource));
5024*5e7646d2SAndroid Build Coastguard Worker
5025*5e7646d2SAndroid Build Coastguard Worker if (uri_status < HTTP_URI_STATUS_OK)
5026*5e7646d2SAndroid Build Coastguard Worker {
5027*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad URI value \"%s\" - %s (RFC 8011 section 5.1.6)."), attr->name, attr->values[i].string.text, httpURIStatusString(uri_status));
5028*5e7646d2SAndroid Build Coastguard Worker return (0);
5029*5e7646d2SAndroid Build Coastguard Worker }
5030*5e7646d2SAndroid Build Coastguard Worker
5031*5e7646d2SAndroid Build Coastguard Worker if (strlen(attr->values[i].string.text) > (IPP_MAX_URI - 1))
5032*5e7646d2SAndroid Build Coastguard Worker {
5033*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad URI value \"%s\" - bad length %d (RFC 8011 section 5.1.6)."), attr->name, attr->values[i].string.text, (int)strlen(attr->values[i].string.text));
5034*5e7646d2SAndroid Build Coastguard Worker }
5035*5e7646d2SAndroid Build Coastguard Worker }
5036*5e7646d2SAndroid Build Coastguard Worker break;
5037*5e7646d2SAndroid Build Coastguard Worker
5038*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
5039*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
5040*5e7646d2SAndroid Build Coastguard Worker {
5041*5e7646d2SAndroid Build Coastguard Worker ptr = attr->values[i].string.text;
5042*5e7646d2SAndroid Build Coastguard Worker if (islower(*ptr & 255))
5043*5e7646d2SAndroid Build Coastguard Worker {
5044*5e7646d2SAndroid Build Coastguard Worker for (ptr ++; *ptr; ptr ++)
5045*5e7646d2SAndroid Build Coastguard Worker {
5046*5e7646d2SAndroid Build Coastguard Worker if (!islower(*ptr & 255) && !isdigit(*ptr & 255) &&
5047*5e7646d2SAndroid Build Coastguard Worker *ptr != '+' && *ptr != '-' && *ptr != '.')
5048*5e7646d2SAndroid Build Coastguard Worker break;
5049*5e7646d2SAndroid Build Coastguard Worker }
5050*5e7646d2SAndroid Build Coastguard Worker }
5051*5e7646d2SAndroid Build Coastguard Worker
5052*5e7646d2SAndroid Build Coastguard Worker if (*ptr || ptr == attr->values[i].string.text)
5053*5e7646d2SAndroid Build Coastguard Worker {
5054*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad uriScheme value \"%s\" - bad characters (RFC 8011 section 5.1.7)."), attr->name, attr->values[i].string.text);
5055*5e7646d2SAndroid Build Coastguard Worker return (0);
5056*5e7646d2SAndroid Build Coastguard Worker }
5057*5e7646d2SAndroid Build Coastguard Worker
5058*5e7646d2SAndroid Build Coastguard Worker if ((ptr - attr->values[i].string.text) > (IPP_MAX_URISCHEME - 1))
5059*5e7646d2SAndroid Build Coastguard Worker {
5060*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad uriScheme value \"%s\" - bad length %d (RFC 8011 section 5.1.7)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text));
5061*5e7646d2SAndroid Build Coastguard Worker return (0);
5062*5e7646d2SAndroid Build Coastguard Worker }
5063*5e7646d2SAndroid Build Coastguard Worker }
5064*5e7646d2SAndroid Build Coastguard Worker break;
5065*5e7646d2SAndroid Build Coastguard Worker
5066*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
5067*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
5068*5e7646d2SAndroid Build Coastguard Worker {
5069*5e7646d2SAndroid Build Coastguard Worker for (ptr = attr->values[i].string.text; *ptr; ptr ++)
5070*5e7646d2SAndroid Build Coastguard Worker {
5071*5e7646d2SAndroid Build Coastguard Worker if (!isprint(*ptr & 255) || isupper(*ptr & 255) ||
5072*5e7646d2SAndroid Build Coastguard Worker isspace(*ptr & 255))
5073*5e7646d2SAndroid Build Coastguard Worker break;
5074*5e7646d2SAndroid Build Coastguard Worker }
5075*5e7646d2SAndroid Build Coastguard Worker
5076*5e7646d2SAndroid Build Coastguard Worker if (*ptr || ptr == attr->values[i].string.text)
5077*5e7646d2SAndroid Build Coastguard Worker {
5078*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad charset value \"%s\" - bad characters (RFC 8011 section 5.1.8)."), attr->name, attr->values[i].string.text);
5079*5e7646d2SAndroid Build Coastguard Worker return (0);
5080*5e7646d2SAndroid Build Coastguard Worker }
5081*5e7646d2SAndroid Build Coastguard Worker
5082*5e7646d2SAndroid Build Coastguard Worker if ((ptr - attr->values[i].string.text) > (IPP_MAX_CHARSET - 1))
5083*5e7646d2SAndroid Build Coastguard Worker {
5084*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad charset value \"%s\" - bad length %d (RFC 8011 section 5.1.8)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text));
5085*5e7646d2SAndroid Build Coastguard Worker return (0);
5086*5e7646d2SAndroid Build Coastguard Worker }
5087*5e7646d2SAndroid Build Coastguard Worker }
5088*5e7646d2SAndroid Build Coastguard Worker break;
5089*5e7646d2SAndroid Build Coastguard Worker
5090*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
5091*5e7646d2SAndroid Build Coastguard Worker /*
5092*5e7646d2SAndroid Build Coastguard Worker * The following regular expression is derived from the ABNF for
5093*5e7646d2SAndroid Build Coastguard Worker * language tags in RFC 4646. All I can say is that this is the
5094*5e7646d2SAndroid Build Coastguard Worker * easiest way to check the values...
5095*5e7646d2SAndroid Build Coastguard Worker */
5096*5e7646d2SAndroid Build Coastguard Worker
5097*5e7646d2SAndroid Build Coastguard Worker if ((i = regcomp(&re,
5098*5e7646d2SAndroid Build Coastguard Worker "^("
5099*5e7646d2SAndroid Build Coastguard Worker "(([a-z]{2,3}(-[a-z][a-z][a-z]){0,3})|[a-z]{4,8})"
5100*5e7646d2SAndroid Build Coastguard Worker /* language */
5101*5e7646d2SAndroid Build Coastguard Worker "(-[a-z][a-z][a-z][a-z]){0,1}" /* script */
5102*5e7646d2SAndroid Build Coastguard Worker "(-([a-z][a-z]|[0-9][0-9][0-9])){0,1}" /* region */
5103*5e7646d2SAndroid Build Coastguard Worker "(-([a-z]{5,8}|[0-9][0-9][0-9]))*" /* variant */
5104*5e7646d2SAndroid Build Coastguard Worker "(-[a-wy-z](-[a-z0-9]{2,8})+)*" /* extension */
5105*5e7646d2SAndroid Build Coastguard Worker "(-x(-[a-z0-9]{1,8})+)*" /* privateuse */
5106*5e7646d2SAndroid Build Coastguard Worker "|"
5107*5e7646d2SAndroid Build Coastguard Worker "x(-[a-z0-9]{1,8})+" /* privateuse */
5108*5e7646d2SAndroid Build Coastguard Worker "|"
5109*5e7646d2SAndroid Build Coastguard Worker "[a-z]{1,3}(-[a-z][0-9]{2,8}){1,2}" /* grandfathered */
5110*5e7646d2SAndroid Build Coastguard Worker ")$",
5111*5e7646d2SAndroid Build Coastguard Worker REG_NOSUB | REG_EXTENDED)) != 0)
5112*5e7646d2SAndroid Build Coastguard Worker {
5113*5e7646d2SAndroid Build Coastguard Worker char temp[256]; /* Temporary error string */
5114*5e7646d2SAndroid Build Coastguard Worker
5115*5e7646d2SAndroid Build Coastguard Worker regerror(i, &re, temp, sizeof(temp));
5116*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_INTERNAL, _("Unable to compile naturalLanguage regular expression: %s."), temp);
5117*5e7646d2SAndroid Build Coastguard Worker return (0);
5118*5e7646d2SAndroid Build Coastguard Worker }
5119*5e7646d2SAndroid Build Coastguard Worker
5120*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
5121*5e7646d2SAndroid Build Coastguard Worker {
5122*5e7646d2SAndroid Build Coastguard Worker if (regexec(&re, attr->values[i].string.text, 0, NULL, 0))
5123*5e7646d2SAndroid Build Coastguard Worker {
5124*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad naturalLanguage value \"%s\" - bad characters (RFC 8011 section 5.1.9)."), attr->name, attr->values[i].string.text);
5125*5e7646d2SAndroid Build Coastguard Worker regfree(&re);
5126*5e7646d2SAndroid Build Coastguard Worker return (0);
5127*5e7646d2SAndroid Build Coastguard Worker }
5128*5e7646d2SAndroid Build Coastguard Worker
5129*5e7646d2SAndroid Build Coastguard Worker if (strlen(attr->values[i].string.text) > (IPP_MAX_LANGUAGE - 1))
5130*5e7646d2SAndroid Build Coastguard Worker {
5131*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad naturalLanguage value \"%s\" - bad length %d (RFC 8011 section 5.1.9)."), attr->name, attr->values[i].string.text, (int)strlen(attr->values[i].string.text));
5132*5e7646d2SAndroid Build Coastguard Worker regfree(&re);
5133*5e7646d2SAndroid Build Coastguard Worker return (0);
5134*5e7646d2SAndroid Build Coastguard Worker }
5135*5e7646d2SAndroid Build Coastguard Worker }
5136*5e7646d2SAndroid Build Coastguard Worker
5137*5e7646d2SAndroid Build Coastguard Worker regfree(&re);
5138*5e7646d2SAndroid Build Coastguard Worker break;
5139*5e7646d2SAndroid Build Coastguard Worker
5140*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
5141*5e7646d2SAndroid Build Coastguard Worker /*
5142*5e7646d2SAndroid Build Coastguard Worker * The following regular expression is derived from the ABNF for
5143*5e7646d2SAndroid Build Coastguard Worker * MIME media types in RFC 2045 and 4288. All I can say is that this is
5144*5e7646d2SAndroid Build Coastguard Worker * the easiest way to check the values...
5145*5e7646d2SAndroid Build Coastguard Worker */
5146*5e7646d2SAndroid Build Coastguard Worker
5147*5e7646d2SAndroid Build Coastguard Worker if ((i = regcomp(&re,
5148*5e7646d2SAndroid Build Coastguard Worker "^"
5149*5e7646d2SAndroid Build Coastguard Worker "[-a-zA-Z0-9!#$&.+^_]{1,127}" /* type-name */
5150*5e7646d2SAndroid Build Coastguard Worker "/"
5151*5e7646d2SAndroid Build Coastguard Worker "[-a-zA-Z0-9!#$&.+^_]{1,127}" /* subtype-name */
5152*5e7646d2SAndroid Build Coastguard Worker "(;[-a-zA-Z0-9!#$&.+^_]{1,127}=" /* parameter= */
5153*5e7646d2SAndroid Build Coastguard Worker "([-a-zA-Z0-9!#$&.+^_]{1,127}|\"[^\"]*\"))*"
5154*5e7646d2SAndroid Build Coastguard Worker /* value */
5155*5e7646d2SAndroid Build Coastguard Worker "$",
5156*5e7646d2SAndroid Build Coastguard Worker REG_NOSUB | REG_EXTENDED)) != 0)
5157*5e7646d2SAndroid Build Coastguard Worker {
5158*5e7646d2SAndroid Build Coastguard Worker char temp[256]; /* Temporary error string */
5159*5e7646d2SAndroid Build Coastguard Worker
5160*5e7646d2SAndroid Build Coastguard Worker regerror(i, &re, temp, sizeof(temp));
5161*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("Unable to compile mimeMediaType regular expression: %s."), temp);
5162*5e7646d2SAndroid Build Coastguard Worker return (0);
5163*5e7646d2SAndroid Build Coastguard Worker }
5164*5e7646d2SAndroid Build Coastguard Worker
5165*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
5166*5e7646d2SAndroid Build Coastguard Worker {
5167*5e7646d2SAndroid Build Coastguard Worker if (regexec(&re, attr->values[i].string.text, 0, NULL, 0))
5168*5e7646d2SAndroid Build Coastguard Worker {
5169*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad mimeMediaType value \"%s\" - bad characters (RFC 8011 section 5.1.10)."), attr->name, attr->values[i].string.text);
5170*5e7646d2SAndroid Build Coastguard Worker regfree(&re);
5171*5e7646d2SAndroid Build Coastguard Worker return (0);
5172*5e7646d2SAndroid Build Coastguard Worker }
5173*5e7646d2SAndroid Build Coastguard Worker
5174*5e7646d2SAndroid Build Coastguard Worker if (strlen(attr->values[i].string.text) > (IPP_MAX_MIMETYPE - 1))
5175*5e7646d2SAndroid Build Coastguard Worker {
5176*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad mimeMediaType value \"%s\" - bad length %d (RFC 8011 section 5.1.10)."), attr->name, attr->values[i].string.text, (int)strlen(attr->values[i].string.text));
5177*5e7646d2SAndroid Build Coastguard Worker regfree(&re);
5178*5e7646d2SAndroid Build Coastguard Worker return (0);
5179*5e7646d2SAndroid Build Coastguard Worker }
5180*5e7646d2SAndroid Build Coastguard Worker }
5181*5e7646d2SAndroid Build Coastguard Worker
5182*5e7646d2SAndroid Build Coastguard Worker regfree(&re);
5183*5e7646d2SAndroid Build Coastguard Worker break;
5184*5e7646d2SAndroid Build Coastguard Worker
5185*5e7646d2SAndroid Build Coastguard Worker default :
5186*5e7646d2SAndroid Build Coastguard Worker break;
5187*5e7646d2SAndroid Build Coastguard Worker }
5188*5e7646d2SAndroid Build Coastguard Worker
5189*5e7646d2SAndroid Build Coastguard Worker return (1);
5190*5e7646d2SAndroid Build Coastguard Worker }
5191*5e7646d2SAndroid Build Coastguard Worker
5192*5e7646d2SAndroid Build Coastguard Worker
5193*5e7646d2SAndroid Build Coastguard Worker /*
5194*5e7646d2SAndroid Build Coastguard Worker * 'ippValidateAttributes()' - Validate all attributes in an IPP message.
5195*5e7646d2SAndroid Build Coastguard Worker *
5196*5e7646d2SAndroid Build Coastguard Worker * This function validates the contents of the IPP message, including each
5197*5e7646d2SAndroid Build Coastguard Worker * attribute. Like @link ippValidateAttribute@, @link cupsLastErrorString@ is
5198*5e7646d2SAndroid Build Coastguard Worker * set to a human-readable message on failure.
5199*5e7646d2SAndroid Build Coastguard Worker *
5200*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.7/macOS 10.9@
5201*5e7646d2SAndroid Build Coastguard Worker */
5202*5e7646d2SAndroid Build Coastguard Worker
5203*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 if valid, 0 otherwise */
ippValidateAttributes(ipp_t * ipp)5204*5e7646d2SAndroid Build Coastguard Worker ippValidateAttributes(ipp_t *ipp) /* I - IPP message */
5205*5e7646d2SAndroid Build Coastguard Worker {
5206*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Current attribute */
5207*5e7646d2SAndroid Build Coastguard Worker
5208*5e7646d2SAndroid Build Coastguard Worker
5209*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
5210*5e7646d2SAndroid Build Coastguard Worker return (1);
5211*5e7646d2SAndroid Build Coastguard Worker
5212*5e7646d2SAndroid Build Coastguard Worker for (attr = ipp->attrs; attr; attr = attr->next)
5213*5e7646d2SAndroid Build Coastguard Worker if (!ippValidateAttribute(attr))
5214*5e7646d2SAndroid Build Coastguard Worker return (0);
5215*5e7646d2SAndroid Build Coastguard Worker
5216*5e7646d2SAndroid Build Coastguard Worker return (1);
5217*5e7646d2SAndroid Build Coastguard Worker }
5218*5e7646d2SAndroid Build Coastguard Worker
5219*5e7646d2SAndroid Build Coastguard Worker
5220*5e7646d2SAndroid Build Coastguard Worker /*
5221*5e7646d2SAndroid Build Coastguard Worker * 'ippWrite()' - Write data for an IPP message to a HTTP connection.
5222*5e7646d2SAndroid Build Coastguard Worker */
5223*5e7646d2SAndroid Build Coastguard Worker
5224*5e7646d2SAndroid Build Coastguard Worker ipp_state_t /* O - Current state */
ippWrite(http_t * http,ipp_t * ipp)5225*5e7646d2SAndroid Build Coastguard Worker ippWrite(http_t *http, /* I - HTTP connection */
5226*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp) /* I - IPP data */
5227*5e7646d2SAndroid Build Coastguard Worker {
5228*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippWrite(http=%p, ipp=%p)", (void *)http, (void *)ipp));
5229*5e7646d2SAndroid Build Coastguard Worker
5230*5e7646d2SAndroid Build Coastguard Worker if (!http)
5231*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5232*5e7646d2SAndroid Build Coastguard Worker
5233*5e7646d2SAndroid Build Coastguard Worker return (ippWriteIO(http, (ipp_iocb_t)httpWrite2, http->blocking, NULL, ipp));
5234*5e7646d2SAndroid Build Coastguard Worker }
5235*5e7646d2SAndroid Build Coastguard Worker
5236*5e7646d2SAndroid Build Coastguard Worker
5237*5e7646d2SAndroid Build Coastguard Worker /*
5238*5e7646d2SAndroid Build Coastguard Worker * 'ippWriteFile()' - Write data for an IPP message to a file.
5239*5e7646d2SAndroid Build Coastguard Worker *
5240*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.1.19/macOS 10.3@
5241*5e7646d2SAndroid Build Coastguard Worker */
5242*5e7646d2SAndroid Build Coastguard Worker
5243*5e7646d2SAndroid Build Coastguard Worker ipp_state_t /* O - Current state */
ippWriteFile(int fd,ipp_t * ipp)5244*5e7646d2SAndroid Build Coastguard Worker ippWriteFile(int fd, /* I - HTTP data */
5245*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp) /* I - IPP data */
5246*5e7646d2SAndroid Build Coastguard Worker {
5247*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippWriteFile(fd=%d, ipp=%p)", fd, (void *)ipp));
5248*5e7646d2SAndroid Build Coastguard Worker
5249*5e7646d2SAndroid Build Coastguard Worker ipp->state = IPP_STATE_IDLE;
5250*5e7646d2SAndroid Build Coastguard Worker
5251*5e7646d2SAndroid Build Coastguard Worker return (ippWriteIO(&fd, (ipp_iocb_t)ipp_write_file, 1, NULL, ipp));
5252*5e7646d2SAndroid Build Coastguard Worker }
5253*5e7646d2SAndroid Build Coastguard Worker
5254*5e7646d2SAndroid Build Coastguard Worker
5255*5e7646d2SAndroid Build Coastguard Worker /*
5256*5e7646d2SAndroid Build Coastguard Worker * 'ippWriteIO()' - Write data for an IPP message.
5257*5e7646d2SAndroid Build Coastguard Worker *
5258*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
5259*5e7646d2SAndroid Build Coastguard Worker */
5260*5e7646d2SAndroid Build Coastguard Worker
5261*5e7646d2SAndroid Build Coastguard Worker ipp_state_t /* O - Current state */
ippWriteIO(void * dst,ipp_iocb_t cb,int blocking,ipp_t * parent,ipp_t * ipp)5262*5e7646d2SAndroid Build Coastguard Worker ippWriteIO(void *dst, /* I - Destination */
5263*5e7646d2SAndroid Build Coastguard Worker ipp_iocb_t cb, /* I - Write callback function */
5264*5e7646d2SAndroid Build Coastguard Worker int blocking, /* I - Use blocking IO? */
5265*5e7646d2SAndroid Build Coastguard Worker ipp_t *parent, /* I - Parent IPP message */
5266*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp) /* I - IPP data */
5267*5e7646d2SAndroid Build Coastguard Worker {
5268*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
5269*5e7646d2SAndroid Build Coastguard Worker int n; /* Length of data */
5270*5e7646d2SAndroid Build Coastguard Worker unsigned char *buffer, /* Data buffer */
5271*5e7646d2SAndroid Build Coastguard Worker *bufptr; /* Pointer into buffer */
5272*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Current attribute */
5273*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
5274*5e7646d2SAndroid Build Coastguard Worker
5275*5e7646d2SAndroid Build Coastguard Worker
5276*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ippWriteIO(dst=%p, cb=%p, blocking=%d, parent=%p, ipp=%p)", (void *)dst, (void *)cb, blocking, (void *)parent, (void *)ipp));
5277*5e7646d2SAndroid Build Coastguard Worker
5278*5e7646d2SAndroid Build Coastguard Worker if (!dst || !ipp)
5279*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5280*5e7646d2SAndroid Build Coastguard Worker
5281*5e7646d2SAndroid Build Coastguard Worker if ((buffer = (unsigned char *)_cupsBufferGet(IPP_BUF_SIZE)) == NULL)
5282*5e7646d2SAndroid Build Coastguard Worker {
5283*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Unable to get write buffer");
5284*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5285*5e7646d2SAndroid Build Coastguard Worker }
5286*5e7646d2SAndroid Build Coastguard Worker
5287*5e7646d2SAndroid Build Coastguard Worker switch (ipp->state)
5288*5e7646d2SAndroid Build Coastguard Worker {
5289*5e7646d2SAndroid Build Coastguard Worker case IPP_STATE_IDLE :
5290*5e7646d2SAndroid Build Coastguard Worker ipp->state ++; /* Avoid common problem... */
5291*5e7646d2SAndroid Build Coastguard Worker
5292*5e7646d2SAndroid Build Coastguard Worker case IPP_STATE_HEADER :
5293*5e7646d2SAndroid Build Coastguard Worker if (parent == NULL)
5294*5e7646d2SAndroid Build Coastguard Worker {
5295*5e7646d2SAndroid Build Coastguard Worker /*
5296*5e7646d2SAndroid Build Coastguard Worker * Send the request header:
5297*5e7646d2SAndroid Build Coastguard Worker *
5298*5e7646d2SAndroid Build Coastguard Worker * Version = 2 bytes
5299*5e7646d2SAndroid Build Coastguard Worker * Operation/Status Code = 2 bytes
5300*5e7646d2SAndroid Build Coastguard Worker * Request ID = 4 bytes
5301*5e7646d2SAndroid Build Coastguard Worker * Total = 8 bytes
5302*5e7646d2SAndroid Build Coastguard Worker */
5303*5e7646d2SAndroid Build Coastguard Worker
5304*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5305*5e7646d2SAndroid Build Coastguard Worker
5306*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = ipp->request.any.version[0];
5307*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = ipp->request.any.version[1];
5308*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(ipp->request.any.op_status >> 8);
5309*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)ipp->request.any.op_status;
5310*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(ipp->request.any.request_id >> 24);
5311*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(ipp->request.any.request_id >> 16);
5312*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(ipp->request.any.request_id >> 8);
5313*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)ipp->request.any.request_id;
5314*5e7646d2SAndroid Build Coastguard Worker
5315*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: version=%d.%d", buffer[0], buffer[1]));
5316*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: op_status=%04x",
5317*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.op_status));
5318*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: request_id=%d",
5319*5e7646d2SAndroid Build Coastguard Worker ipp->request.any.request_id));
5320*5e7646d2SAndroid Build Coastguard Worker
5321*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5322*5e7646d2SAndroid Build Coastguard Worker {
5323*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP header...");
5324*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5325*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5326*5e7646d2SAndroid Build Coastguard Worker }
5327*5e7646d2SAndroid Build Coastguard Worker }
5328*5e7646d2SAndroid Build Coastguard Worker
5329*5e7646d2SAndroid Build Coastguard Worker /*
5330*5e7646d2SAndroid Build Coastguard Worker * Reset the state engine to point to the first attribute
5331*5e7646d2SAndroid Build Coastguard Worker * in the request/response, with no current group.
5332*5e7646d2SAndroid Build Coastguard Worker */
5333*5e7646d2SAndroid Build Coastguard Worker
5334*5e7646d2SAndroid Build Coastguard Worker ipp->state = IPP_STATE_ATTRIBUTE;
5335*5e7646d2SAndroid Build Coastguard Worker ipp->current = ipp->attrs;
5336*5e7646d2SAndroid Build Coastguard Worker ipp->curtag = IPP_TAG_ZERO;
5337*5e7646d2SAndroid Build Coastguard Worker
5338*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippWriteIO: ipp->current=%p", (void *)ipp->current));
5339*5e7646d2SAndroid Build Coastguard Worker
5340*5e7646d2SAndroid Build Coastguard Worker /*
5341*5e7646d2SAndroid Build Coastguard Worker * If blocking is disabled, stop here...
5342*5e7646d2SAndroid Build Coastguard Worker */
5343*5e7646d2SAndroid Build Coastguard Worker
5344*5e7646d2SAndroid Build Coastguard Worker if (!blocking)
5345*5e7646d2SAndroid Build Coastguard Worker break;
5346*5e7646d2SAndroid Build Coastguard Worker
5347*5e7646d2SAndroid Build Coastguard Worker case IPP_STATE_ATTRIBUTE :
5348*5e7646d2SAndroid Build Coastguard Worker while (ipp->current != NULL)
5349*5e7646d2SAndroid Build Coastguard Worker {
5350*5e7646d2SAndroid Build Coastguard Worker /*
5351*5e7646d2SAndroid Build Coastguard Worker * Write this attribute...
5352*5e7646d2SAndroid Build Coastguard Worker */
5353*5e7646d2SAndroid Build Coastguard Worker
5354*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5355*5e7646d2SAndroid Build Coastguard Worker attr = ipp->current;
5356*5e7646d2SAndroid Build Coastguard Worker
5357*5e7646d2SAndroid Build Coastguard Worker ipp->current = ipp->current->next;
5358*5e7646d2SAndroid Build Coastguard Worker
5359*5e7646d2SAndroid Build Coastguard Worker if (!parent)
5360*5e7646d2SAndroid Build Coastguard Worker {
5361*5e7646d2SAndroid Build Coastguard Worker if (ipp->curtag != attr->group_tag)
5362*5e7646d2SAndroid Build Coastguard Worker {
5363*5e7646d2SAndroid Build Coastguard Worker /*
5364*5e7646d2SAndroid Build Coastguard Worker * Send a group tag byte...
5365*5e7646d2SAndroid Build Coastguard Worker */
5366*5e7646d2SAndroid Build Coastguard Worker
5367*5e7646d2SAndroid Build Coastguard Worker ipp->curtag = attr->group_tag;
5368*5e7646d2SAndroid Build Coastguard Worker
5369*5e7646d2SAndroid Build Coastguard Worker if (attr->group_tag == IPP_TAG_ZERO)
5370*5e7646d2SAndroid Build Coastguard Worker continue;
5371*5e7646d2SAndroid Build Coastguard Worker
5372*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: wrote group tag=%x(%s)",
5373*5e7646d2SAndroid Build Coastguard Worker attr->group_tag, ippTagString(attr->group_tag)));
5374*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->group_tag;
5375*5e7646d2SAndroid Build Coastguard Worker }
5376*5e7646d2SAndroid Build Coastguard Worker else if (attr->group_tag == IPP_TAG_ZERO)
5377*5e7646d2SAndroid Build Coastguard Worker continue;
5378*5e7646d2SAndroid Build Coastguard Worker }
5379*5e7646d2SAndroid Build Coastguard Worker
5380*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippWriteIO: %s (%s%s)", attr->name,
5381*5e7646d2SAndroid Build Coastguard Worker attr->num_values > 1 ? "1setOf " : "",
5382*5e7646d2SAndroid Build Coastguard Worker ippTagString(attr->value_tag)));
5383*5e7646d2SAndroid Build Coastguard Worker
5384*5e7646d2SAndroid Build Coastguard Worker /*
5385*5e7646d2SAndroid Build Coastguard Worker * Write the attribute tag and name.
5386*5e7646d2SAndroid Build Coastguard Worker *
5387*5e7646d2SAndroid Build Coastguard Worker * The attribute name length does not include the trailing nul
5388*5e7646d2SAndroid Build Coastguard Worker * character in the source string.
5389*5e7646d2SAndroid Build Coastguard Worker *
5390*5e7646d2SAndroid Build Coastguard Worker * Collection values (parent != NULL) are written differently...
5391*5e7646d2SAndroid Build Coastguard Worker */
5392*5e7646d2SAndroid Build Coastguard Worker
5393*5e7646d2SAndroid Build Coastguard Worker if (parent == NULL)
5394*5e7646d2SAndroid Build Coastguard Worker {
5395*5e7646d2SAndroid Build Coastguard Worker /*
5396*5e7646d2SAndroid Build Coastguard Worker * Get the length of the attribute name, and make sure it won't
5397*5e7646d2SAndroid Build Coastguard Worker * overflow the buffer...
5398*5e7646d2SAndroid Build Coastguard Worker */
5399*5e7646d2SAndroid Build Coastguard Worker
5400*5e7646d2SAndroid Build Coastguard Worker if ((n = (int)strlen(attr->name)) > (IPP_BUF_SIZE - 8))
5401*5e7646d2SAndroid Build Coastguard Worker {
5402*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippWriteIO: Attribute name too long (%d)", n));
5403*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5404*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5405*5e7646d2SAndroid Build Coastguard Worker }
5406*5e7646d2SAndroid Build Coastguard Worker
5407*5e7646d2SAndroid Build Coastguard Worker /*
5408*5e7646d2SAndroid Build Coastguard Worker * Write the value tag, name length, and name string...
5409*5e7646d2SAndroid Build Coastguard Worker */
5410*5e7646d2SAndroid Build Coastguard Worker
5411*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: writing value tag=%x(%s)",
5412*5e7646d2SAndroid Build Coastguard Worker attr->value_tag, ippTagString(attr->value_tag)));
5413*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: writing name=%d,\"%s\"", n,
5414*5e7646d2SAndroid Build Coastguard Worker attr->name));
5415*5e7646d2SAndroid Build Coastguard Worker
5416*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag > 0xff)
5417*5e7646d2SAndroid Build Coastguard Worker {
5418*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = IPP_TAG_EXTENSION;
5419*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(attr->value_tag >> 24);
5420*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(attr->value_tag >> 16);
5421*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(attr->value_tag >> 8);
5422*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5423*5e7646d2SAndroid Build Coastguard Worker }
5424*5e7646d2SAndroid Build Coastguard Worker else
5425*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5426*5e7646d2SAndroid Build Coastguard Worker
5427*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(n >> 8);
5428*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)n;
5429*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, attr->name, (size_t)n);
5430*5e7646d2SAndroid Build Coastguard Worker bufptr += n;
5431*5e7646d2SAndroid Build Coastguard Worker }
5432*5e7646d2SAndroid Build Coastguard Worker else
5433*5e7646d2SAndroid Build Coastguard Worker {
5434*5e7646d2SAndroid Build Coastguard Worker /*
5435*5e7646d2SAndroid Build Coastguard Worker * Get the length of the attribute name, and make sure it won't
5436*5e7646d2SAndroid Build Coastguard Worker * overflow the buffer...
5437*5e7646d2SAndroid Build Coastguard Worker */
5438*5e7646d2SAndroid Build Coastguard Worker
5439*5e7646d2SAndroid Build Coastguard Worker if ((n = (int)strlen(attr->name)) > (IPP_BUF_SIZE - 12))
5440*5e7646d2SAndroid Build Coastguard Worker {
5441*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippWriteIO: Attribute name too long (%d)", n));
5442*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5443*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5444*5e7646d2SAndroid Build Coastguard Worker }
5445*5e7646d2SAndroid Build Coastguard Worker
5446*5e7646d2SAndroid Build Coastguard Worker /*
5447*5e7646d2SAndroid Build Coastguard Worker * Write the member name tag, name length, name string, value tag,
5448*5e7646d2SAndroid Build Coastguard Worker * and empty name for the collection member attribute...
5449*5e7646d2SAndroid Build Coastguard Worker */
5450*5e7646d2SAndroid Build Coastguard Worker
5451*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: writing value tag=%x(memberName)",
5452*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_MEMBERNAME));
5453*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: writing name=%d,\"%s\"", n,
5454*5e7646d2SAndroid Build Coastguard Worker attr->name));
5455*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: writing value tag=%x(%s)",
5456*5e7646d2SAndroid Build Coastguard Worker attr->value_tag, ippTagString(attr->value_tag)));
5457*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("2ippWriteIO: writing name=0,\"\"");
5458*5e7646d2SAndroid Build Coastguard Worker
5459*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = IPP_TAG_MEMBERNAME;
5460*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5461*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5462*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(n >> 8);
5463*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)n;
5464*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, attr->name, (size_t)n);
5465*5e7646d2SAndroid Build Coastguard Worker bufptr += n;
5466*5e7646d2SAndroid Build Coastguard Worker
5467*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag > 0xff)
5468*5e7646d2SAndroid Build Coastguard Worker {
5469*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = IPP_TAG_EXTENSION;
5470*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(attr->value_tag >> 24);
5471*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(attr->value_tag >> 16);
5472*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(attr->value_tag >> 8);
5473*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5474*5e7646d2SAndroid Build Coastguard Worker }
5475*5e7646d2SAndroid Build Coastguard Worker else
5476*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5477*5e7646d2SAndroid Build Coastguard Worker
5478*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5479*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5480*5e7646d2SAndroid Build Coastguard Worker }
5481*5e7646d2SAndroid Build Coastguard Worker
5482*5e7646d2SAndroid Build Coastguard Worker /*
5483*5e7646d2SAndroid Build Coastguard Worker * Now write the attribute value(s)...
5484*5e7646d2SAndroid Build Coastguard Worker */
5485*5e7646d2SAndroid Build Coastguard Worker
5486*5e7646d2SAndroid Build Coastguard Worker switch (attr->value_tag & ~IPP_TAG_CUPS_CONST)
5487*5e7646d2SAndroid Build Coastguard Worker {
5488*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNSUPPORTED_VALUE :
5489*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DEFAULT :
5490*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNKNOWN :
5491*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOVALUE :
5492*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOTSETTABLE :
5493*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DELETEATTR :
5494*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ADMINDEFINE :
5495*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5496*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5497*5e7646d2SAndroid Build Coastguard Worker break;
5498*5e7646d2SAndroid Build Coastguard Worker
5499*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
5500*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
5501*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
5502*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
5503*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
5504*5e7646d2SAndroid Build Coastguard Worker {
5505*5e7646d2SAndroid Build Coastguard Worker if ((IPP_BUF_SIZE - (bufptr - buffer)) < 9)
5506*5e7646d2SAndroid Build Coastguard Worker {
5507*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5508*5e7646d2SAndroid Build Coastguard Worker {
5509*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5510*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5511*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5512*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5513*5e7646d2SAndroid Build Coastguard Worker }
5514*5e7646d2SAndroid Build Coastguard Worker
5515*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5516*5e7646d2SAndroid Build Coastguard Worker }
5517*5e7646d2SAndroid Build Coastguard Worker
5518*5e7646d2SAndroid Build Coastguard Worker if (i)
5519*5e7646d2SAndroid Build Coastguard Worker {
5520*5e7646d2SAndroid Build Coastguard Worker /*
5521*5e7646d2SAndroid Build Coastguard Worker * Arrays and sets are done by sending additional
5522*5e7646d2SAndroid Build Coastguard Worker * values with a zero-length name...
5523*5e7646d2SAndroid Build Coastguard Worker */
5524*5e7646d2SAndroid Build Coastguard Worker
5525*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5526*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5527*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5528*5e7646d2SAndroid Build Coastguard Worker }
5529*5e7646d2SAndroid Build Coastguard Worker
5530*5e7646d2SAndroid Build Coastguard Worker /*
5531*5e7646d2SAndroid Build Coastguard Worker * Integers and enumerations are both 4-byte signed
5532*5e7646d2SAndroid Build Coastguard Worker * (twos-complement) values.
5533*5e7646d2SAndroid Build Coastguard Worker *
5534*5e7646d2SAndroid Build Coastguard Worker * Put the 2-byte length and 4-byte value into the buffer...
5535*5e7646d2SAndroid Build Coastguard Worker */
5536*5e7646d2SAndroid Build Coastguard Worker
5537*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5538*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 4;
5539*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->integer >> 24);
5540*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->integer >> 16);
5541*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->integer >> 8);
5542*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)value->integer;
5543*5e7646d2SAndroid Build Coastguard Worker }
5544*5e7646d2SAndroid Build Coastguard Worker break;
5545*5e7646d2SAndroid Build Coastguard Worker
5546*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
5547*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
5548*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
5549*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
5550*5e7646d2SAndroid Build Coastguard Worker {
5551*5e7646d2SAndroid Build Coastguard Worker if ((IPP_BUF_SIZE - (bufptr - buffer)) < 6)
5552*5e7646d2SAndroid Build Coastguard Worker {
5553*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5554*5e7646d2SAndroid Build Coastguard Worker {
5555*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5556*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5557*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5558*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5559*5e7646d2SAndroid Build Coastguard Worker }
5560*5e7646d2SAndroid Build Coastguard Worker
5561*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5562*5e7646d2SAndroid Build Coastguard Worker }
5563*5e7646d2SAndroid Build Coastguard Worker
5564*5e7646d2SAndroid Build Coastguard Worker if (i)
5565*5e7646d2SAndroid Build Coastguard Worker {
5566*5e7646d2SAndroid Build Coastguard Worker /*
5567*5e7646d2SAndroid Build Coastguard Worker * Arrays and sets are done by sending additional
5568*5e7646d2SAndroid Build Coastguard Worker * values with a zero-length name...
5569*5e7646d2SAndroid Build Coastguard Worker */
5570*5e7646d2SAndroid Build Coastguard Worker
5571*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5572*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5573*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5574*5e7646d2SAndroid Build Coastguard Worker }
5575*5e7646d2SAndroid Build Coastguard Worker
5576*5e7646d2SAndroid Build Coastguard Worker /*
5577*5e7646d2SAndroid Build Coastguard Worker * Boolean values are 1-byte; 0 = false, 1 = true.
5578*5e7646d2SAndroid Build Coastguard Worker *
5579*5e7646d2SAndroid Build Coastguard Worker * Put the 2-byte length and 1-byte value into the buffer...
5580*5e7646d2SAndroid Build Coastguard Worker */
5581*5e7646d2SAndroid Build Coastguard Worker
5582*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5583*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 1;
5584*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)value->boolean;
5585*5e7646d2SAndroid Build Coastguard Worker }
5586*5e7646d2SAndroid Build Coastguard Worker break;
5587*5e7646d2SAndroid Build Coastguard Worker
5588*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
5589*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
5590*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
5591*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
5592*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
5593*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
5594*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
5595*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
5596*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
5597*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
5598*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
5599*5e7646d2SAndroid Build Coastguard Worker {
5600*5e7646d2SAndroid Build Coastguard Worker if (i)
5601*5e7646d2SAndroid Build Coastguard Worker {
5602*5e7646d2SAndroid Build Coastguard Worker /*
5603*5e7646d2SAndroid Build Coastguard Worker * Arrays and sets are done by sending additional
5604*5e7646d2SAndroid Build Coastguard Worker * values with a zero-length name...
5605*5e7646d2SAndroid Build Coastguard Worker */
5606*5e7646d2SAndroid Build Coastguard Worker
5607*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: writing value tag=%x(%s)",
5608*5e7646d2SAndroid Build Coastguard Worker attr->value_tag,
5609*5e7646d2SAndroid Build Coastguard Worker ippTagString(attr->value_tag)));
5610*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: writing name=0,\"\""));
5611*5e7646d2SAndroid Build Coastguard Worker
5612*5e7646d2SAndroid Build Coastguard Worker if ((IPP_BUF_SIZE - (bufptr - buffer)) < 3)
5613*5e7646d2SAndroid Build Coastguard Worker {
5614*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5615*5e7646d2SAndroid Build Coastguard Worker {
5616*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5617*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5618*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5619*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5620*5e7646d2SAndroid Build Coastguard Worker }
5621*5e7646d2SAndroid Build Coastguard Worker
5622*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5623*5e7646d2SAndroid Build Coastguard Worker }
5624*5e7646d2SAndroid Build Coastguard Worker
5625*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5626*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5627*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5628*5e7646d2SAndroid Build Coastguard Worker }
5629*5e7646d2SAndroid Build Coastguard Worker
5630*5e7646d2SAndroid Build Coastguard Worker if (value->string.text != NULL)
5631*5e7646d2SAndroid Build Coastguard Worker n = (int)strlen(value->string.text);
5632*5e7646d2SAndroid Build Coastguard Worker else
5633*5e7646d2SAndroid Build Coastguard Worker n = 0;
5634*5e7646d2SAndroid Build Coastguard Worker
5635*5e7646d2SAndroid Build Coastguard Worker if (n > (IPP_BUF_SIZE - 2))
5636*5e7646d2SAndroid Build Coastguard Worker {
5637*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippWriteIO: String too long (%d)", n));
5638*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5639*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5640*5e7646d2SAndroid Build Coastguard Worker }
5641*5e7646d2SAndroid Build Coastguard Worker
5642*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: writing string=%d,\"%s\"", n,
5643*5e7646d2SAndroid Build Coastguard Worker value->string.text));
5644*5e7646d2SAndroid Build Coastguard Worker
5645*5e7646d2SAndroid Build Coastguard Worker if ((int)(IPP_BUF_SIZE - (bufptr - buffer)) < (n + 2))
5646*5e7646d2SAndroid Build Coastguard Worker {
5647*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5648*5e7646d2SAndroid Build Coastguard Worker {
5649*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5650*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5651*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5652*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5653*5e7646d2SAndroid Build Coastguard Worker }
5654*5e7646d2SAndroid Build Coastguard Worker
5655*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5656*5e7646d2SAndroid Build Coastguard Worker }
5657*5e7646d2SAndroid Build Coastguard Worker
5658*5e7646d2SAndroid Build Coastguard Worker /*
5659*5e7646d2SAndroid Build Coastguard Worker * All simple strings consist of the 2-byte length and
5660*5e7646d2SAndroid Build Coastguard Worker * character data without the trailing nul normally found
5661*5e7646d2SAndroid Build Coastguard Worker * in C strings. Also, strings cannot be longer than IPP_MAX_LENGTH
5662*5e7646d2SAndroid Build Coastguard Worker * bytes since the 2-byte length is a signed (twos-complement)
5663*5e7646d2SAndroid Build Coastguard Worker * value.
5664*5e7646d2SAndroid Build Coastguard Worker *
5665*5e7646d2SAndroid Build Coastguard Worker * Put the 2-byte length and string characters in the buffer.
5666*5e7646d2SAndroid Build Coastguard Worker */
5667*5e7646d2SAndroid Build Coastguard Worker
5668*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(n >> 8);
5669*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)n;
5670*5e7646d2SAndroid Build Coastguard Worker
5671*5e7646d2SAndroid Build Coastguard Worker if (n > 0)
5672*5e7646d2SAndroid Build Coastguard Worker {
5673*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, value->string.text, (size_t)n);
5674*5e7646d2SAndroid Build Coastguard Worker bufptr += n;
5675*5e7646d2SAndroid Build Coastguard Worker }
5676*5e7646d2SAndroid Build Coastguard Worker }
5677*5e7646d2SAndroid Build Coastguard Worker break;
5678*5e7646d2SAndroid Build Coastguard Worker
5679*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DATE :
5680*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
5681*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
5682*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
5683*5e7646d2SAndroid Build Coastguard Worker {
5684*5e7646d2SAndroid Build Coastguard Worker if ((IPP_BUF_SIZE - (bufptr - buffer)) < 16)
5685*5e7646d2SAndroid Build Coastguard Worker {
5686*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5687*5e7646d2SAndroid Build Coastguard Worker {
5688*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5689*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5690*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5691*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5692*5e7646d2SAndroid Build Coastguard Worker }
5693*5e7646d2SAndroid Build Coastguard Worker
5694*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5695*5e7646d2SAndroid Build Coastguard Worker }
5696*5e7646d2SAndroid Build Coastguard Worker
5697*5e7646d2SAndroid Build Coastguard Worker if (i)
5698*5e7646d2SAndroid Build Coastguard Worker {
5699*5e7646d2SAndroid Build Coastguard Worker /*
5700*5e7646d2SAndroid Build Coastguard Worker * Arrays and sets are done by sending additional
5701*5e7646d2SAndroid Build Coastguard Worker * values with a zero-length name...
5702*5e7646d2SAndroid Build Coastguard Worker */
5703*5e7646d2SAndroid Build Coastguard Worker
5704*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5705*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5706*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5707*5e7646d2SAndroid Build Coastguard Worker }
5708*5e7646d2SAndroid Build Coastguard Worker
5709*5e7646d2SAndroid Build Coastguard Worker /*
5710*5e7646d2SAndroid Build Coastguard Worker * Date values consist of a 2-byte length and an
5711*5e7646d2SAndroid Build Coastguard Worker * 11-byte date/time structure defined by RFC 1903.
5712*5e7646d2SAndroid Build Coastguard Worker *
5713*5e7646d2SAndroid Build Coastguard Worker * Put the 2-byte length and 11-byte date/time
5714*5e7646d2SAndroid Build Coastguard Worker * structure in the buffer.
5715*5e7646d2SAndroid Build Coastguard Worker */
5716*5e7646d2SAndroid Build Coastguard Worker
5717*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5718*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 11;
5719*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, value->date, 11);
5720*5e7646d2SAndroid Build Coastguard Worker bufptr += 11;
5721*5e7646d2SAndroid Build Coastguard Worker }
5722*5e7646d2SAndroid Build Coastguard Worker break;
5723*5e7646d2SAndroid Build Coastguard Worker
5724*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
5725*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
5726*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
5727*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
5728*5e7646d2SAndroid Build Coastguard Worker {
5729*5e7646d2SAndroid Build Coastguard Worker if ((IPP_BUF_SIZE - (bufptr - buffer)) < 14)
5730*5e7646d2SAndroid Build Coastguard Worker {
5731*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5732*5e7646d2SAndroid Build Coastguard Worker {
5733*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5734*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5735*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5736*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5737*5e7646d2SAndroid Build Coastguard Worker }
5738*5e7646d2SAndroid Build Coastguard Worker
5739*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5740*5e7646d2SAndroid Build Coastguard Worker }
5741*5e7646d2SAndroid Build Coastguard Worker
5742*5e7646d2SAndroid Build Coastguard Worker if (i)
5743*5e7646d2SAndroid Build Coastguard Worker {
5744*5e7646d2SAndroid Build Coastguard Worker /*
5745*5e7646d2SAndroid Build Coastguard Worker * Arrays and sets are done by sending additional
5746*5e7646d2SAndroid Build Coastguard Worker * values with a zero-length name...
5747*5e7646d2SAndroid Build Coastguard Worker */
5748*5e7646d2SAndroid Build Coastguard Worker
5749*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5750*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5751*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5752*5e7646d2SAndroid Build Coastguard Worker }
5753*5e7646d2SAndroid Build Coastguard Worker
5754*5e7646d2SAndroid Build Coastguard Worker /*
5755*5e7646d2SAndroid Build Coastguard Worker * Resolution values consist of a 2-byte length,
5756*5e7646d2SAndroid Build Coastguard Worker * 4-byte horizontal resolution value, 4-byte vertical
5757*5e7646d2SAndroid Build Coastguard Worker * resolution value, and a 1-byte units value.
5758*5e7646d2SAndroid Build Coastguard Worker *
5759*5e7646d2SAndroid Build Coastguard Worker * Put the 2-byte length and resolution value data
5760*5e7646d2SAndroid Build Coastguard Worker * into the buffer.
5761*5e7646d2SAndroid Build Coastguard Worker */
5762*5e7646d2SAndroid Build Coastguard Worker
5763*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5764*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 9;
5765*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->resolution.xres >> 24);
5766*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->resolution.xres >> 16);
5767*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->resolution.xres >> 8);
5768*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)value->resolution.xres;
5769*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->resolution.yres >> 24);
5770*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->resolution.yres >> 16);
5771*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->resolution.yres >> 8);
5772*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)value->resolution.yres;
5773*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)value->resolution.units;
5774*5e7646d2SAndroid Build Coastguard Worker }
5775*5e7646d2SAndroid Build Coastguard Worker break;
5776*5e7646d2SAndroid Build Coastguard Worker
5777*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
5778*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
5779*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
5780*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
5781*5e7646d2SAndroid Build Coastguard Worker {
5782*5e7646d2SAndroid Build Coastguard Worker if ((IPP_BUF_SIZE - (bufptr - buffer)) < 13)
5783*5e7646d2SAndroid Build Coastguard Worker {
5784*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5785*5e7646d2SAndroid Build Coastguard Worker {
5786*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5787*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5788*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5789*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5790*5e7646d2SAndroid Build Coastguard Worker }
5791*5e7646d2SAndroid Build Coastguard Worker
5792*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5793*5e7646d2SAndroid Build Coastguard Worker }
5794*5e7646d2SAndroid Build Coastguard Worker
5795*5e7646d2SAndroid Build Coastguard Worker if (i)
5796*5e7646d2SAndroid Build Coastguard Worker {
5797*5e7646d2SAndroid Build Coastguard Worker /*
5798*5e7646d2SAndroid Build Coastguard Worker * Arrays and sets are done by sending additional
5799*5e7646d2SAndroid Build Coastguard Worker * values with a zero-length name...
5800*5e7646d2SAndroid Build Coastguard Worker */
5801*5e7646d2SAndroid Build Coastguard Worker
5802*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5803*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5804*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5805*5e7646d2SAndroid Build Coastguard Worker }
5806*5e7646d2SAndroid Build Coastguard Worker
5807*5e7646d2SAndroid Build Coastguard Worker /*
5808*5e7646d2SAndroid Build Coastguard Worker * Range values consist of a 2-byte length,
5809*5e7646d2SAndroid Build Coastguard Worker * 4-byte lower value, and 4-byte upper value.
5810*5e7646d2SAndroid Build Coastguard Worker *
5811*5e7646d2SAndroid Build Coastguard Worker * Put the 2-byte length and range value data
5812*5e7646d2SAndroid Build Coastguard Worker * into the buffer.
5813*5e7646d2SAndroid Build Coastguard Worker */
5814*5e7646d2SAndroid Build Coastguard Worker
5815*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5816*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 8;
5817*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->range.lower >> 24);
5818*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->range.lower >> 16);
5819*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->range.lower >> 8);
5820*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)value->range.lower;
5821*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->range.upper >> 24);
5822*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->range.upper >> 16);
5823*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(value->range.upper >> 8);
5824*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)value->range.upper;
5825*5e7646d2SAndroid Build Coastguard Worker }
5826*5e7646d2SAndroid Build Coastguard Worker break;
5827*5e7646d2SAndroid Build Coastguard Worker
5828*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
5829*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
5830*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
5831*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
5832*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
5833*5e7646d2SAndroid Build Coastguard Worker {
5834*5e7646d2SAndroid Build Coastguard Worker if (i)
5835*5e7646d2SAndroid Build Coastguard Worker {
5836*5e7646d2SAndroid Build Coastguard Worker /*
5837*5e7646d2SAndroid Build Coastguard Worker * Arrays and sets are done by sending additional
5838*5e7646d2SAndroid Build Coastguard Worker * values with a zero-length name...
5839*5e7646d2SAndroid Build Coastguard Worker */
5840*5e7646d2SAndroid Build Coastguard Worker
5841*5e7646d2SAndroid Build Coastguard Worker if ((IPP_BUF_SIZE - (bufptr - buffer)) < 3)
5842*5e7646d2SAndroid Build Coastguard Worker {
5843*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5844*5e7646d2SAndroid Build Coastguard Worker {
5845*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5846*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5847*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5848*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5849*5e7646d2SAndroid Build Coastguard Worker }
5850*5e7646d2SAndroid Build Coastguard Worker
5851*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5852*5e7646d2SAndroid Build Coastguard Worker }
5853*5e7646d2SAndroid Build Coastguard Worker
5854*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5855*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5856*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5857*5e7646d2SAndroid Build Coastguard Worker }
5858*5e7646d2SAndroid Build Coastguard Worker
5859*5e7646d2SAndroid Build Coastguard Worker /*
5860*5e7646d2SAndroid Build Coastguard Worker * textWithLanguage and nameWithLanguage values consist
5861*5e7646d2SAndroid Build Coastguard Worker * of a 2-byte length for both strings and their
5862*5e7646d2SAndroid Build Coastguard Worker * individual lengths, a 2-byte length for the
5863*5e7646d2SAndroid Build Coastguard Worker * character string, the character string without the
5864*5e7646d2SAndroid Build Coastguard Worker * trailing nul, a 2-byte length for the character
5865*5e7646d2SAndroid Build Coastguard Worker * set string, and the character set string without
5866*5e7646d2SAndroid Build Coastguard Worker * the trailing nul.
5867*5e7646d2SAndroid Build Coastguard Worker */
5868*5e7646d2SAndroid Build Coastguard Worker
5869*5e7646d2SAndroid Build Coastguard Worker n = 4;
5870*5e7646d2SAndroid Build Coastguard Worker
5871*5e7646d2SAndroid Build Coastguard Worker if (value->string.language != NULL)
5872*5e7646d2SAndroid Build Coastguard Worker n += (int)strlen(value->string.language);
5873*5e7646d2SAndroid Build Coastguard Worker
5874*5e7646d2SAndroid Build Coastguard Worker if (value->string.text != NULL)
5875*5e7646d2SAndroid Build Coastguard Worker n += (int)strlen(value->string.text);
5876*5e7646d2SAndroid Build Coastguard Worker
5877*5e7646d2SAndroid Build Coastguard Worker if (n > (IPP_BUF_SIZE - 2))
5878*5e7646d2SAndroid Build Coastguard Worker {
5879*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippWriteIO: text/nameWithLanguage value "
5880*5e7646d2SAndroid Build Coastguard Worker "too long (%d)", n));
5881*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5882*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5883*5e7646d2SAndroid Build Coastguard Worker }
5884*5e7646d2SAndroid Build Coastguard Worker
5885*5e7646d2SAndroid Build Coastguard Worker if ((int)(IPP_BUF_SIZE - (bufptr - buffer)) < (n + 2))
5886*5e7646d2SAndroid Build Coastguard Worker {
5887*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5888*5e7646d2SAndroid Build Coastguard Worker {
5889*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5890*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5891*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5892*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5893*5e7646d2SAndroid Build Coastguard Worker }
5894*5e7646d2SAndroid Build Coastguard Worker
5895*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5896*5e7646d2SAndroid Build Coastguard Worker }
5897*5e7646d2SAndroid Build Coastguard Worker
5898*5e7646d2SAndroid Build Coastguard Worker /* Length of entire value */
5899*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(n >> 8);
5900*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)n;
5901*5e7646d2SAndroid Build Coastguard Worker
5902*5e7646d2SAndroid Build Coastguard Worker /* Length of language */
5903*5e7646d2SAndroid Build Coastguard Worker if (value->string.language != NULL)
5904*5e7646d2SAndroid Build Coastguard Worker n = (int)strlen(value->string.language);
5905*5e7646d2SAndroid Build Coastguard Worker else
5906*5e7646d2SAndroid Build Coastguard Worker n = 0;
5907*5e7646d2SAndroid Build Coastguard Worker
5908*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(n >> 8);
5909*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)n;
5910*5e7646d2SAndroid Build Coastguard Worker
5911*5e7646d2SAndroid Build Coastguard Worker /* Language */
5912*5e7646d2SAndroid Build Coastguard Worker if (n > 0)
5913*5e7646d2SAndroid Build Coastguard Worker {
5914*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, value->string.language, (size_t)n);
5915*5e7646d2SAndroid Build Coastguard Worker bufptr += n;
5916*5e7646d2SAndroid Build Coastguard Worker }
5917*5e7646d2SAndroid Build Coastguard Worker
5918*5e7646d2SAndroid Build Coastguard Worker /* Length of text */
5919*5e7646d2SAndroid Build Coastguard Worker if (value->string.text != NULL)
5920*5e7646d2SAndroid Build Coastguard Worker n = (int)strlen(value->string.text);
5921*5e7646d2SAndroid Build Coastguard Worker else
5922*5e7646d2SAndroid Build Coastguard Worker n = 0;
5923*5e7646d2SAndroid Build Coastguard Worker
5924*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(n >> 8);
5925*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)n;
5926*5e7646d2SAndroid Build Coastguard Worker
5927*5e7646d2SAndroid Build Coastguard Worker /* Text */
5928*5e7646d2SAndroid Build Coastguard Worker if (n > 0)
5929*5e7646d2SAndroid Build Coastguard Worker {
5930*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, value->string.text, (size_t)n);
5931*5e7646d2SAndroid Build Coastguard Worker bufptr += n;
5932*5e7646d2SAndroid Build Coastguard Worker }
5933*5e7646d2SAndroid Build Coastguard Worker }
5934*5e7646d2SAndroid Build Coastguard Worker break;
5935*5e7646d2SAndroid Build Coastguard Worker
5936*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
5937*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
5938*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
5939*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
5940*5e7646d2SAndroid Build Coastguard Worker {
5941*5e7646d2SAndroid Build Coastguard Worker /*
5942*5e7646d2SAndroid Build Coastguard Worker * Collections are written with the begin-collection
5943*5e7646d2SAndroid Build Coastguard Worker * tag first with a value of 0 length, followed by the
5944*5e7646d2SAndroid Build Coastguard Worker * attributes in the collection, then the end-collection
5945*5e7646d2SAndroid Build Coastguard Worker * value...
5946*5e7646d2SAndroid Build Coastguard Worker */
5947*5e7646d2SAndroid Build Coastguard Worker
5948*5e7646d2SAndroid Build Coastguard Worker if ((IPP_BUF_SIZE - (bufptr - buffer)) < 5)
5949*5e7646d2SAndroid Build Coastguard Worker {
5950*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5951*5e7646d2SAndroid Build Coastguard Worker {
5952*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5953*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5954*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5955*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5956*5e7646d2SAndroid Build Coastguard Worker }
5957*5e7646d2SAndroid Build Coastguard Worker
5958*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5959*5e7646d2SAndroid Build Coastguard Worker }
5960*5e7646d2SAndroid Build Coastguard Worker
5961*5e7646d2SAndroid Build Coastguard Worker if (i)
5962*5e7646d2SAndroid Build Coastguard Worker {
5963*5e7646d2SAndroid Build Coastguard Worker /*
5964*5e7646d2SAndroid Build Coastguard Worker * Arrays and sets are done by sending additional
5965*5e7646d2SAndroid Build Coastguard Worker * values with a zero-length name...
5966*5e7646d2SAndroid Build Coastguard Worker */
5967*5e7646d2SAndroid Build Coastguard Worker
5968*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
5969*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5970*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5971*5e7646d2SAndroid Build Coastguard Worker }
5972*5e7646d2SAndroid Build Coastguard Worker
5973*5e7646d2SAndroid Build Coastguard Worker /*
5974*5e7646d2SAndroid Build Coastguard Worker * Write a data length of 0 and flush the buffer...
5975*5e7646d2SAndroid Build Coastguard Worker */
5976*5e7646d2SAndroid Build Coastguard Worker
5977*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5978*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
5979*5e7646d2SAndroid Build Coastguard Worker
5980*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
5981*5e7646d2SAndroid Build Coastguard Worker {
5982*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
5983*5e7646d2SAndroid Build Coastguard Worker "attribute...");
5984*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
5985*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
5986*5e7646d2SAndroid Build Coastguard Worker }
5987*5e7646d2SAndroid Build Coastguard Worker
5988*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
5989*5e7646d2SAndroid Build Coastguard Worker
5990*5e7646d2SAndroid Build Coastguard Worker /*
5991*5e7646d2SAndroid Build Coastguard Worker * Then write the collection attribute...
5992*5e7646d2SAndroid Build Coastguard Worker */
5993*5e7646d2SAndroid Build Coastguard Worker
5994*5e7646d2SAndroid Build Coastguard Worker value->collection->state = IPP_STATE_IDLE;
5995*5e7646d2SAndroid Build Coastguard Worker
5996*5e7646d2SAndroid Build Coastguard Worker if (ippWriteIO(dst, cb, 1, ipp,
5997*5e7646d2SAndroid Build Coastguard Worker value->collection) == IPP_STATE_ERROR)
5998*5e7646d2SAndroid Build Coastguard Worker {
5999*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Unable to write collection value");
6000*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
6001*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
6002*5e7646d2SAndroid Build Coastguard Worker }
6003*5e7646d2SAndroid Build Coastguard Worker }
6004*5e7646d2SAndroid Build Coastguard Worker break;
6005*5e7646d2SAndroid Build Coastguard Worker
6006*5e7646d2SAndroid Build Coastguard Worker default :
6007*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
6008*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
6009*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
6010*5e7646d2SAndroid Build Coastguard Worker {
6011*5e7646d2SAndroid Build Coastguard Worker if (i)
6012*5e7646d2SAndroid Build Coastguard Worker {
6013*5e7646d2SAndroid Build Coastguard Worker /*
6014*5e7646d2SAndroid Build Coastguard Worker * Arrays and sets are done by sending additional
6015*5e7646d2SAndroid Build Coastguard Worker * values with a zero-length name...
6016*5e7646d2SAndroid Build Coastguard Worker */
6017*5e7646d2SAndroid Build Coastguard Worker
6018*5e7646d2SAndroid Build Coastguard Worker if ((IPP_BUF_SIZE - (bufptr - buffer)) < 3)
6019*5e7646d2SAndroid Build Coastguard Worker {
6020*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
6021*5e7646d2SAndroid Build Coastguard Worker {
6022*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
6023*5e7646d2SAndroid Build Coastguard Worker "attribute...");
6024*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
6025*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
6026*5e7646d2SAndroid Build Coastguard Worker }
6027*5e7646d2SAndroid Build Coastguard Worker
6028*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
6029*5e7646d2SAndroid Build Coastguard Worker }
6030*5e7646d2SAndroid Build Coastguard Worker
6031*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)attr->value_tag;
6032*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
6033*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 0;
6034*5e7646d2SAndroid Build Coastguard Worker }
6035*5e7646d2SAndroid Build Coastguard Worker
6036*5e7646d2SAndroid Build Coastguard Worker /*
6037*5e7646d2SAndroid Build Coastguard Worker * An unknown value might some new value that a
6038*5e7646d2SAndroid Build Coastguard Worker * vendor has come up with. It consists of a
6039*5e7646d2SAndroid Build Coastguard Worker * 2-byte length and the bytes in the unknown
6040*5e7646d2SAndroid Build Coastguard Worker * value buffer.
6041*5e7646d2SAndroid Build Coastguard Worker */
6042*5e7646d2SAndroid Build Coastguard Worker
6043*5e7646d2SAndroid Build Coastguard Worker n = value->unknown.length;
6044*5e7646d2SAndroid Build Coastguard Worker
6045*5e7646d2SAndroid Build Coastguard Worker if (n > (IPP_BUF_SIZE - 2))
6046*5e7646d2SAndroid Build Coastguard Worker {
6047*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1ippWriteIO: Data length too long (%d)",
6048*5e7646d2SAndroid Build Coastguard Worker n));
6049*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
6050*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
6051*5e7646d2SAndroid Build Coastguard Worker }
6052*5e7646d2SAndroid Build Coastguard Worker
6053*5e7646d2SAndroid Build Coastguard Worker if ((int)(IPP_BUF_SIZE - (bufptr - buffer)) < (n + 2))
6054*5e7646d2SAndroid Build Coastguard Worker {
6055*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
6056*5e7646d2SAndroid Build Coastguard Worker {
6057*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP "
6058*5e7646d2SAndroid Build Coastguard Worker "attribute...");
6059*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
6060*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
6061*5e7646d2SAndroid Build Coastguard Worker }
6062*5e7646d2SAndroid Build Coastguard Worker
6063*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
6064*5e7646d2SAndroid Build Coastguard Worker }
6065*5e7646d2SAndroid Build Coastguard Worker
6066*5e7646d2SAndroid Build Coastguard Worker /* Length of unknown value */
6067*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)(n >> 8);
6068*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (ipp_uchar_t)n;
6069*5e7646d2SAndroid Build Coastguard Worker
6070*5e7646d2SAndroid Build Coastguard Worker /* Value */
6071*5e7646d2SAndroid Build Coastguard Worker if (n > 0)
6072*5e7646d2SAndroid Build Coastguard Worker {
6073*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, value->unknown.data, (size_t)n);
6074*5e7646d2SAndroid Build Coastguard Worker bufptr += n;
6075*5e7646d2SAndroid Build Coastguard Worker }
6076*5e7646d2SAndroid Build Coastguard Worker }
6077*5e7646d2SAndroid Build Coastguard Worker break;
6078*5e7646d2SAndroid Build Coastguard Worker }
6079*5e7646d2SAndroid Build Coastguard Worker
6080*5e7646d2SAndroid Build Coastguard Worker /*
6081*5e7646d2SAndroid Build Coastguard Worker * Write the data out...
6082*5e7646d2SAndroid Build Coastguard Worker */
6083*5e7646d2SAndroid Build Coastguard Worker
6084*5e7646d2SAndroid Build Coastguard Worker if (bufptr > buffer)
6085*5e7646d2SAndroid Build Coastguard Worker {
6086*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)(bufptr - buffer)) < 0)
6087*5e7646d2SAndroid Build Coastguard Worker {
6088*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP attribute...");
6089*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
6090*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
6091*5e7646d2SAndroid Build Coastguard Worker }
6092*5e7646d2SAndroid Build Coastguard Worker
6093*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ippWriteIO: wrote %d bytes",
6094*5e7646d2SAndroid Build Coastguard Worker (int)(bufptr - buffer)));
6095*5e7646d2SAndroid Build Coastguard Worker }
6096*5e7646d2SAndroid Build Coastguard Worker
6097*5e7646d2SAndroid Build Coastguard Worker /*
6098*5e7646d2SAndroid Build Coastguard Worker * If blocking is disabled and we aren't at the end of the attribute
6099*5e7646d2SAndroid Build Coastguard Worker * list, stop here...
6100*5e7646d2SAndroid Build Coastguard Worker */
6101*5e7646d2SAndroid Build Coastguard Worker
6102*5e7646d2SAndroid Build Coastguard Worker if (!blocking && ipp->current)
6103*5e7646d2SAndroid Build Coastguard Worker break;
6104*5e7646d2SAndroid Build Coastguard Worker }
6105*5e7646d2SAndroid Build Coastguard Worker
6106*5e7646d2SAndroid Build Coastguard Worker if (ipp->current == NULL)
6107*5e7646d2SAndroid Build Coastguard Worker {
6108*5e7646d2SAndroid Build Coastguard Worker /*
6109*5e7646d2SAndroid Build Coastguard Worker * Done with all of the attributes; add the end-of-attributes
6110*5e7646d2SAndroid Build Coastguard Worker * tag or end-collection attribute...
6111*5e7646d2SAndroid Build Coastguard Worker */
6112*5e7646d2SAndroid Build Coastguard Worker
6113*5e7646d2SAndroid Build Coastguard Worker if (parent == NULL)
6114*5e7646d2SAndroid Build Coastguard Worker {
6115*5e7646d2SAndroid Build Coastguard Worker buffer[0] = IPP_TAG_END;
6116*5e7646d2SAndroid Build Coastguard Worker n = 1;
6117*5e7646d2SAndroid Build Coastguard Worker }
6118*5e7646d2SAndroid Build Coastguard Worker else
6119*5e7646d2SAndroid Build Coastguard Worker {
6120*5e7646d2SAndroid Build Coastguard Worker buffer[0] = IPP_TAG_END_COLLECTION;
6121*5e7646d2SAndroid Build Coastguard Worker buffer[1] = 0; /* empty name */
6122*5e7646d2SAndroid Build Coastguard Worker buffer[2] = 0;
6123*5e7646d2SAndroid Build Coastguard Worker buffer[3] = 0; /* empty value */
6124*5e7646d2SAndroid Build Coastguard Worker buffer[4] = 0;
6125*5e7646d2SAndroid Build Coastguard Worker n = 5;
6126*5e7646d2SAndroid Build Coastguard Worker }
6127*5e7646d2SAndroid Build Coastguard Worker
6128*5e7646d2SAndroid Build Coastguard Worker if ((*cb)(dst, buffer, (size_t)n) < 0)
6129*5e7646d2SAndroid Build Coastguard Worker {
6130*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1ippWriteIO: Could not write IPP end-tag...");
6131*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
6132*5e7646d2SAndroid Build Coastguard Worker return (IPP_STATE_ERROR);
6133*5e7646d2SAndroid Build Coastguard Worker }
6134*5e7646d2SAndroid Build Coastguard Worker
6135*5e7646d2SAndroid Build Coastguard Worker ipp->state = IPP_STATE_DATA;
6136*5e7646d2SAndroid Build Coastguard Worker }
6137*5e7646d2SAndroid Build Coastguard Worker break;
6138*5e7646d2SAndroid Build Coastguard Worker
6139*5e7646d2SAndroid Build Coastguard Worker case IPP_STATE_DATA :
6140*5e7646d2SAndroid Build Coastguard Worker break;
6141*5e7646d2SAndroid Build Coastguard Worker
6142*5e7646d2SAndroid Build Coastguard Worker default :
6143*5e7646d2SAndroid Build Coastguard Worker break; /* anti-compiler-warning-code */
6144*5e7646d2SAndroid Build Coastguard Worker }
6145*5e7646d2SAndroid Build Coastguard Worker
6146*5e7646d2SAndroid Build Coastguard Worker _cupsBufferRelease((char *)buffer);
6147*5e7646d2SAndroid Build Coastguard Worker
6148*5e7646d2SAndroid Build Coastguard Worker return (ipp->state);
6149*5e7646d2SAndroid Build Coastguard Worker }
6150*5e7646d2SAndroid Build Coastguard Worker
6151*5e7646d2SAndroid Build Coastguard Worker
6152*5e7646d2SAndroid Build Coastguard Worker /*
6153*5e7646d2SAndroid Build Coastguard Worker * 'ipp_add_attr()' - Add a new attribute to the message.
6154*5e7646d2SAndroid Build Coastguard Worker */
6155*5e7646d2SAndroid Build Coastguard Worker
6156*5e7646d2SAndroid Build Coastguard Worker static ipp_attribute_t * /* O - New attribute */
ipp_add_attr(ipp_t * ipp,const char * name,ipp_tag_t group_tag,ipp_tag_t value_tag,int num_values)6157*5e7646d2SAndroid Build Coastguard Worker ipp_add_attr(ipp_t *ipp, /* I - IPP message */
6158*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Attribute name or NULL */
6159*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group_tag, /* I - Group tag or IPP_TAG_ZERO */
6160*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag, /* I - Value tag or IPP_TAG_ZERO */
6161*5e7646d2SAndroid Build Coastguard Worker int num_values) /* I - Number of values */
6162*5e7646d2SAndroid Build Coastguard Worker {
6163*5e7646d2SAndroid Build Coastguard Worker int alloc_values; /* Number of values to allocate */
6164*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* New attribute */
6165*5e7646d2SAndroid Build Coastguard Worker
6166*5e7646d2SAndroid Build Coastguard Worker
6167*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4ipp_add_attr(ipp=%p, name=\"%s\", group_tag=0x%x, value_tag=0x%x, num_values=%d)", (void *)ipp, name, group_tag, value_tag, num_values));
6168*5e7646d2SAndroid Build Coastguard Worker
6169*5e7646d2SAndroid Build Coastguard Worker /*
6170*5e7646d2SAndroid Build Coastguard Worker * Range check input...
6171*5e7646d2SAndroid Build Coastguard Worker */
6172*5e7646d2SAndroid Build Coastguard Worker
6173*5e7646d2SAndroid Build Coastguard Worker if (!ipp || num_values < 0)
6174*5e7646d2SAndroid Build Coastguard Worker return (NULL);
6175*5e7646d2SAndroid Build Coastguard Worker
6176*5e7646d2SAndroid Build Coastguard Worker /*
6177*5e7646d2SAndroid Build Coastguard Worker * Allocate memory, rounding the allocation up as needed...
6178*5e7646d2SAndroid Build Coastguard Worker */
6179*5e7646d2SAndroid Build Coastguard Worker
6180*5e7646d2SAndroid Build Coastguard Worker if (num_values <= 1)
6181*5e7646d2SAndroid Build Coastguard Worker alloc_values = 1;
6182*5e7646d2SAndroid Build Coastguard Worker else
6183*5e7646d2SAndroid Build Coastguard Worker alloc_values = (num_values + IPP_MAX_VALUES - 1) & ~(IPP_MAX_VALUES - 1);
6184*5e7646d2SAndroid Build Coastguard Worker
6185*5e7646d2SAndroid Build Coastguard Worker attr = calloc(sizeof(ipp_attribute_t) +
6186*5e7646d2SAndroid Build Coastguard Worker (size_t)(alloc_values - 1) * sizeof(_ipp_value_t), 1);
6187*5e7646d2SAndroid Build Coastguard Worker
6188*5e7646d2SAndroid Build Coastguard Worker if (attr)
6189*5e7646d2SAndroid Build Coastguard Worker {
6190*5e7646d2SAndroid Build Coastguard Worker /*
6191*5e7646d2SAndroid Build Coastguard Worker * Initialize attribute...
6192*5e7646d2SAndroid Build Coastguard Worker */
6193*5e7646d2SAndroid Build Coastguard Worker
6194*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4debug_alloc: %p %s %s%s (%d values)", (void *)attr, name, num_values > 1 ? "1setOf " : "", ippTagString(value_tag), num_values));
6195*5e7646d2SAndroid Build Coastguard Worker
6196*5e7646d2SAndroid Build Coastguard Worker if (name)
6197*5e7646d2SAndroid Build Coastguard Worker attr->name = _cupsStrAlloc(name);
6198*5e7646d2SAndroid Build Coastguard Worker
6199*5e7646d2SAndroid Build Coastguard Worker attr->group_tag = group_tag;
6200*5e7646d2SAndroid Build Coastguard Worker attr->value_tag = value_tag;
6201*5e7646d2SAndroid Build Coastguard Worker attr->num_values = num_values;
6202*5e7646d2SAndroid Build Coastguard Worker
6203*5e7646d2SAndroid Build Coastguard Worker /*
6204*5e7646d2SAndroid Build Coastguard Worker * Add it to the end of the linked list...
6205*5e7646d2SAndroid Build Coastguard Worker */
6206*5e7646d2SAndroid Build Coastguard Worker
6207*5e7646d2SAndroid Build Coastguard Worker if (ipp->last)
6208*5e7646d2SAndroid Build Coastguard Worker ipp->last->next = attr;
6209*5e7646d2SAndroid Build Coastguard Worker else
6210*5e7646d2SAndroid Build Coastguard Worker ipp->attrs = attr;
6211*5e7646d2SAndroid Build Coastguard Worker
6212*5e7646d2SAndroid Build Coastguard Worker ipp->prev = ipp->last;
6213*5e7646d2SAndroid Build Coastguard Worker ipp->last = ipp->current = attr;
6214*5e7646d2SAndroid Build Coastguard Worker }
6215*5e7646d2SAndroid Build Coastguard Worker
6216*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5ipp_add_attr: Returning %p", (void *)attr));
6217*5e7646d2SAndroid Build Coastguard Worker
6218*5e7646d2SAndroid Build Coastguard Worker return (attr);
6219*5e7646d2SAndroid Build Coastguard Worker }
6220*5e7646d2SAndroid Build Coastguard Worker
6221*5e7646d2SAndroid Build Coastguard Worker
6222*5e7646d2SAndroid Build Coastguard Worker /*
6223*5e7646d2SAndroid Build Coastguard Worker * 'ipp_free_values()' - Free attribute values.
6224*5e7646d2SAndroid Build Coastguard Worker */
6225*5e7646d2SAndroid Build Coastguard Worker
6226*5e7646d2SAndroid Build Coastguard Worker static void
ipp_free_values(ipp_attribute_t * attr,int element,int count)6227*5e7646d2SAndroid Build Coastguard Worker ipp_free_values(ipp_attribute_t *attr, /* I - Attribute to free values from */
6228*5e7646d2SAndroid Build Coastguard Worker int element,/* I - First value to free */
6229*5e7646d2SAndroid Build Coastguard Worker int count) /* I - Number of values to free */
6230*5e7646d2SAndroid Build Coastguard Worker {
6231*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
6232*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
6233*5e7646d2SAndroid Build Coastguard Worker
6234*5e7646d2SAndroid Build Coastguard Worker
6235*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4ipp_free_values(attr=%p, element=%d, count=%d)", (void *)attr, element, count));
6236*5e7646d2SAndroid Build Coastguard Worker
6237*5e7646d2SAndroid Build Coastguard Worker if (!(attr->value_tag & IPP_TAG_CUPS_CONST))
6238*5e7646d2SAndroid Build Coastguard Worker {
6239*5e7646d2SAndroid Build Coastguard Worker /*
6240*5e7646d2SAndroid Build Coastguard Worker * Free values as needed...
6241*5e7646d2SAndroid Build Coastguard Worker */
6242*5e7646d2SAndroid Build Coastguard Worker
6243*5e7646d2SAndroid Build Coastguard Worker switch (attr->value_tag)
6244*5e7646d2SAndroid Build Coastguard Worker {
6245*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
6246*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
6247*5e7646d2SAndroid Build Coastguard Worker if (element == 0 && count == attr->num_values &&
6248*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.language)
6249*5e7646d2SAndroid Build Coastguard Worker {
6250*5e7646d2SAndroid Build Coastguard Worker _cupsStrFree(attr->values[0].string.language);
6251*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.language = NULL;
6252*5e7646d2SAndroid Build Coastguard Worker }
6253*5e7646d2SAndroid Build Coastguard Worker /* Fall through to other string values */
6254*5e7646d2SAndroid Build Coastguard Worker
6255*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
6256*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
6257*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESERVED_STRING :
6258*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
6259*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
6260*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
6261*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
6262*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
6263*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
6264*5e7646d2SAndroid Build Coastguard Worker for (i = count, value = attr->values + element;
6265*5e7646d2SAndroid Build Coastguard Worker i > 0;
6266*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
6267*5e7646d2SAndroid Build Coastguard Worker {
6268*5e7646d2SAndroid Build Coastguard Worker _cupsStrFree(value->string.text);
6269*5e7646d2SAndroid Build Coastguard Worker value->string.text = NULL;
6270*5e7646d2SAndroid Build Coastguard Worker }
6271*5e7646d2SAndroid Build Coastguard Worker break;
6272*5e7646d2SAndroid Build Coastguard Worker
6273*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNSUPPORTED_VALUE :
6274*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DEFAULT :
6275*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNKNOWN :
6276*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOVALUE :
6277*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOTSETTABLE :
6278*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DELETEATTR :
6279*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ADMINDEFINE :
6280*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
6281*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
6282*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
6283*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DATE :
6284*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
6285*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
6286*5e7646d2SAndroid Build Coastguard Worker break;
6287*5e7646d2SAndroid Build Coastguard Worker
6288*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
6289*5e7646d2SAndroid Build Coastguard Worker for (i = count, value = attr->values + element;
6290*5e7646d2SAndroid Build Coastguard Worker i > 0;
6291*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
6292*5e7646d2SAndroid Build Coastguard Worker {
6293*5e7646d2SAndroid Build Coastguard Worker ippDelete(value->collection);
6294*5e7646d2SAndroid Build Coastguard Worker value->collection = NULL;
6295*5e7646d2SAndroid Build Coastguard Worker }
6296*5e7646d2SAndroid Build Coastguard Worker break;
6297*5e7646d2SAndroid Build Coastguard Worker
6298*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
6299*5e7646d2SAndroid Build Coastguard Worker default :
6300*5e7646d2SAndroid Build Coastguard Worker for (i = count, value = attr->values + element;
6301*5e7646d2SAndroid Build Coastguard Worker i > 0;
6302*5e7646d2SAndroid Build Coastguard Worker i --, value ++)
6303*5e7646d2SAndroid Build Coastguard Worker {
6304*5e7646d2SAndroid Build Coastguard Worker if (value->unknown.data)
6305*5e7646d2SAndroid Build Coastguard Worker {
6306*5e7646d2SAndroid Build Coastguard Worker free(value->unknown.data);
6307*5e7646d2SAndroid Build Coastguard Worker value->unknown.data = NULL;
6308*5e7646d2SAndroid Build Coastguard Worker }
6309*5e7646d2SAndroid Build Coastguard Worker }
6310*5e7646d2SAndroid Build Coastguard Worker break;
6311*5e7646d2SAndroid Build Coastguard Worker }
6312*5e7646d2SAndroid Build Coastguard Worker }
6313*5e7646d2SAndroid Build Coastguard Worker
6314*5e7646d2SAndroid Build Coastguard Worker /*
6315*5e7646d2SAndroid Build Coastguard Worker * If we are not freeing values from the end, move the remaining values up...
6316*5e7646d2SAndroid Build Coastguard Worker */
6317*5e7646d2SAndroid Build Coastguard Worker
6318*5e7646d2SAndroid Build Coastguard Worker if ((element + count) < attr->num_values)
6319*5e7646d2SAndroid Build Coastguard Worker memmove(attr->values + element, attr->values + element + count,
6320*5e7646d2SAndroid Build Coastguard Worker (size_t)(attr->num_values - count - element) * sizeof(_ipp_value_t));
6321*5e7646d2SAndroid Build Coastguard Worker
6322*5e7646d2SAndroid Build Coastguard Worker attr->num_values -= count;
6323*5e7646d2SAndroid Build Coastguard Worker }
6324*5e7646d2SAndroid Build Coastguard Worker
6325*5e7646d2SAndroid Build Coastguard Worker
6326*5e7646d2SAndroid Build Coastguard Worker /*
6327*5e7646d2SAndroid Build Coastguard Worker * 'ipp_get_code()' - Convert a C locale/charset name into an IPP language/charset code.
6328*5e7646d2SAndroid Build Coastguard Worker *
6329*5e7646d2SAndroid Build Coastguard Worker * This typically converts strings of the form "ll_CC", "ll-REGION", and "CHARSET_NUMBER"
6330*5e7646d2SAndroid Build Coastguard Worker * to "ll-cc", "ll-region", and "charset-number", respectively.
6331*5e7646d2SAndroid Build Coastguard Worker */
6332*5e7646d2SAndroid Build Coastguard Worker
6333*5e7646d2SAndroid Build Coastguard Worker static char * /* O - Language code string */
ipp_get_code(const char * value,char * buffer,size_t bufsize)6334*5e7646d2SAndroid Build Coastguard Worker ipp_get_code(const char *value, /* I - Locale/charset string */
6335*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* I - String buffer */
6336*5e7646d2SAndroid Build Coastguard Worker size_t bufsize) /* I - Size of string buffer */
6337*5e7646d2SAndroid Build Coastguard Worker {
6338*5e7646d2SAndroid Build Coastguard Worker char *bufptr, /* Pointer into buffer */
6339*5e7646d2SAndroid Build Coastguard Worker *bufend; /* End of buffer */
6340*5e7646d2SAndroid Build Coastguard Worker
6341*5e7646d2SAndroid Build Coastguard Worker
6342*5e7646d2SAndroid Build Coastguard Worker /*
6343*5e7646d2SAndroid Build Coastguard Worker * Convert values to lowercase and change _ to - as needed...
6344*5e7646d2SAndroid Build Coastguard Worker */
6345*5e7646d2SAndroid Build Coastguard Worker
6346*5e7646d2SAndroid Build Coastguard Worker for (bufptr = buffer, bufend = buffer + bufsize - 1;
6347*5e7646d2SAndroid Build Coastguard Worker *value && bufptr < bufend;
6348*5e7646d2SAndroid Build Coastguard Worker value ++)
6349*5e7646d2SAndroid Build Coastguard Worker if (*value == '_')
6350*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '-';
6351*5e7646d2SAndroid Build Coastguard Worker else
6352*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (char)_cups_tolower(*value);
6353*5e7646d2SAndroid Build Coastguard Worker
6354*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
6355*5e7646d2SAndroid Build Coastguard Worker
6356*5e7646d2SAndroid Build Coastguard Worker /*
6357*5e7646d2SAndroid Build Coastguard Worker * Return the converted string...
6358*5e7646d2SAndroid Build Coastguard Worker */
6359*5e7646d2SAndroid Build Coastguard Worker
6360*5e7646d2SAndroid Build Coastguard Worker return (buffer);
6361*5e7646d2SAndroid Build Coastguard Worker }
6362*5e7646d2SAndroid Build Coastguard Worker
6363*5e7646d2SAndroid Build Coastguard Worker
6364*5e7646d2SAndroid Build Coastguard Worker /*
6365*5e7646d2SAndroid Build Coastguard Worker * 'ipp_lang_code()' - Convert a C locale name into an IPP language code.
6366*5e7646d2SAndroid Build Coastguard Worker *
6367*5e7646d2SAndroid Build Coastguard Worker * This typically converts strings of the form "ll_CC" and "ll-REGION" to "ll-cc" and
6368*5e7646d2SAndroid Build Coastguard Worker * "ll-region", respectively. It also converts the "C" (POSIX) locale to "en".
6369*5e7646d2SAndroid Build Coastguard Worker */
6370*5e7646d2SAndroid Build Coastguard Worker
6371*5e7646d2SAndroid Build Coastguard Worker static char * /* O - Language code string */
ipp_lang_code(const char * locale,char * buffer,size_t bufsize)6372*5e7646d2SAndroid Build Coastguard Worker ipp_lang_code(const char *locale, /* I - Locale string */
6373*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* I - String buffer */
6374*5e7646d2SAndroid Build Coastguard Worker size_t bufsize) /* I - Size of string buffer */
6375*5e7646d2SAndroid Build Coastguard Worker {
6376*5e7646d2SAndroid Build Coastguard Worker /*
6377*5e7646d2SAndroid Build Coastguard Worker * Map POSIX ("C") locale to generic English, otherwise convert the locale string as-is.
6378*5e7646d2SAndroid Build Coastguard Worker */
6379*5e7646d2SAndroid Build Coastguard Worker
6380*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(locale, "c"))
6381*5e7646d2SAndroid Build Coastguard Worker {
6382*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, "en", bufsize);
6383*5e7646d2SAndroid Build Coastguard Worker return (buffer);
6384*5e7646d2SAndroid Build Coastguard Worker }
6385*5e7646d2SAndroid Build Coastguard Worker else
6386*5e7646d2SAndroid Build Coastguard Worker return (ipp_get_code(locale, buffer, bufsize));
6387*5e7646d2SAndroid Build Coastguard Worker }
6388*5e7646d2SAndroid Build Coastguard Worker
6389*5e7646d2SAndroid Build Coastguard Worker
6390*5e7646d2SAndroid Build Coastguard Worker /*
6391*5e7646d2SAndroid Build Coastguard Worker * 'ipp_length()' - Compute the length of an IPP message or collection value.
6392*5e7646d2SAndroid Build Coastguard Worker */
6393*5e7646d2SAndroid Build Coastguard Worker
6394*5e7646d2SAndroid Build Coastguard Worker static size_t /* O - Size of IPP message */
ipp_length(ipp_t * ipp,int collection)6395*5e7646d2SAndroid Build Coastguard Worker ipp_length(ipp_t *ipp, /* I - IPP message or collection */
6396*5e7646d2SAndroid Build Coastguard Worker int collection) /* I - 1 if a collection, 0 otherwise */
6397*5e7646d2SAndroid Build Coastguard Worker {
6398*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
6399*5e7646d2SAndroid Build Coastguard Worker size_t bytes; /* Number of bytes */
6400*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Current attribute */
6401*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group; /* Current group */
6402*5e7646d2SAndroid Build Coastguard Worker _ipp_value_t *value; /* Current value */
6403*5e7646d2SAndroid Build Coastguard Worker
6404*5e7646d2SAndroid Build Coastguard Worker
6405*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("3ipp_length(ipp=%p, collection=%d)", (void *)ipp, collection));
6406*5e7646d2SAndroid Build Coastguard Worker
6407*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
6408*5e7646d2SAndroid Build Coastguard Worker {
6409*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("4ipp_length: Returning 0 bytes");
6410*5e7646d2SAndroid Build Coastguard Worker return (0);
6411*5e7646d2SAndroid Build Coastguard Worker }
6412*5e7646d2SAndroid Build Coastguard Worker
6413*5e7646d2SAndroid Build Coastguard Worker /*
6414*5e7646d2SAndroid Build Coastguard Worker * Start with 8 bytes for the IPP message header...
6415*5e7646d2SAndroid Build Coastguard Worker */
6416*5e7646d2SAndroid Build Coastguard Worker
6417*5e7646d2SAndroid Build Coastguard Worker bytes = collection ? 0 : 8;
6418*5e7646d2SAndroid Build Coastguard Worker
6419*5e7646d2SAndroid Build Coastguard Worker /*
6420*5e7646d2SAndroid Build Coastguard Worker * Then add the lengths of each attribute...
6421*5e7646d2SAndroid Build Coastguard Worker */
6422*5e7646d2SAndroid Build Coastguard Worker
6423*5e7646d2SAndroid Build Coastguard Worker group = IPP_TAG_ZERO;
6424*5e7646d2SAndroid Build Coastguard Worker
6425*5e7646d2SAndroid Build Coastguard Worker for (attr = ipp->attrs; attr != NULL; attr = attr->next)
6426*5e7646d2SAndroid Build Coastguard Worker {
6427*5e7646d2SAndroid Build Coastguard Worker if (attr->group_tag != group && !collection)
6428*5e7646d2SAndroid Build Coastguard Worker {
6429*5e7646d2SAndroid Build Coastguard Worker group = attr->group_tag;
6430*5e7646d2SAndroid Build Coastguard Worker if (group == IPP_TAG_ZERO)
6431*5e7646d2SAndroid Build Coastguard Worker continue;
6432*5e7646d2SAndroid Build Coastguard Worker
6433*5e7646d2SAndroid Build Coastguard Worker bytes ++; /* Group tag */
6434*5e7646d2SAndroid Build Coastguard Worker }
6435*5e7646d2SAndroid Build Coastguard Worker
6436*5e7646d2SAndroid Build Coastguard Worker if (!attr->name)
6437*5e7646d2SAndroid Build Coastguard Worker continue;
6438*5e7646d2SAndroid Build Coastguard Worker
6439*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5ipp_length: attr->name=\"%s\", attr->num_values=%d, "
6440*5e7646d2SAndroid Build Coastguard Worker "bytes=" CUPS_LLFMT, attr->name, attr->num_values, CUPS_LLCAST bytes));
6441*5e7646d2SAndroid Build Coastguard Worker
6442*5e7646d2SAndroid Build Coastguard Worker if ((attr->value_tag & ~IPP_TAG_CUPS_CONST) < IPP_TAG_EXTENSION)
6443*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)attr->num_values;/* Value tag for each value */
6444*5e7646d2SAndroid Build Coastguard Worker else
6445*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)(5 * attr->num_values);
6446*5e7646d2SAndroid Build Coastguard Worker /* Value tag for each value */
6447*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)(2 * attr->num_values);
6448*5e7646d2SAndroid Build Coastguard Worker /* Name lengths */
6449*5e7646d2SAndroid Build Coastguard Worker bytes += strlen(attr->name); /* Name */
6450*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)(2 * attr->num_values);
6451*5e7646d2SAndroid Build Coastguard Worker /* Value lengths */
6452*5e7646d2SAndroid Build Coastguard Worker
6453*5e7646d2SAndroid Build Coastguard Worker if (collection)
6454*5e7646d2SAndroid Build Coastguard Worker bytes += 5; /* Add membername overhead */
6455*5e7646d2SAndroid Build Coastguard Worker
6456*5e7646d2SAndroid Build Coastguard Worker switch (attr->value_tag & ~IPP_TAG_CUPS_CONST)
6457*5e7646d2SAndroid Build Coastguard Worker {
6458*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNSUPPORTED_VALUE :
6459*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DEFAULT :
6460*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNKNOWN :
6461*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOVALUE :
6462*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOTSETTABLE :
6463*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DELETEATTR :
6464*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ADMINDEFINE :
6465*5e7646d2SAndroid Build Coastguard Worker break;
6466*5e7646d2SAndroid Build Coastguard Worker
6467*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
6468*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
6469*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)(4 * attr->num_values);
6470*5e7646d2SAndroid Build Coastguard Worker break;
6471*5e7646d2SAndroid Build Coastguard Worker
6472*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
6473*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)attr->num_values;
6474*5e7646d2SAndroid Build Coastguard Worker break;
6475*5e7646d2SAndroid Build Coastguard Worker
6476*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
6477*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
6478*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
6479*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
6480*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
6481*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
6482*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
6483*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
6484*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
6485*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
6486*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
6487*5e7646d2SAndroid Build Coastguard Worker if (value->string.text)
6488*5e7646d2SAndroid Build Coastguard Worker bytes += strlen(value->string.text);
6489*5e7646d2SAndroid Build Coastguard Worker break;
6490*5e7646d2SAndroid Build Coastguard Worker
6491*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DATE :
6492*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)(11 * attr->num_values);
6493*5e7646d2SAndroid Build Coastguard Worker break;
6494*5e7646d2SAndroid Build Coastguard Worker
6495*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
6496*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)(9 * attr->num_values);
6497*5e7646d2SAndroid Build Coastguard Worker break;
6498*5e7646d2SAndroid Build Coastguard Worker
6499*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
6500*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)(8 * attr->num_values);
6501*5e7646d2SAndroid Build Coastguard Worker break;
6502*5e7646d2SAndroid Build Coastguard Worker
6503*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
6504*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
6505*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)(4 * attr->num_values);
6506*5e7646d2SAndroid Build Coastguard Worker /* Charset + text length */
6507*5e7646d2SAndroid Build Coastguard Worker
6508*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
6509*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
6510*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
6511*5e7646d2SAndroid Build Coastguard Worker {
6512*5e7646d2SAndroid Build Coastguard Worker if (value->string.language)
6513*5e7646d2SAndroid Build Coastguard Worker bytes += strlen(value->string.language);
6514*5e7646d2SAndroid Build Coastguard Worker
6515*5e7646d2SAndroid Build Coastguard Worker if (value->string.text)
6516*5e7646d2SAndroid Build Coastguard Worker bytes += strlen(value->string.text);
6517*5e7646d2SAndroid Build Coastguard Worker }
6518*5e7646d2SAndroid Build Coastguard Worker break;
6519*5e7646d2SAndroid Build Coastguard Worker
6520*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
6521*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
6522*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
6523*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
6524*5e7646d2SAndroid Build Coastguard Worker bytes += ipp_length(value->collection, 1);
6525*5e7646d2SAndroid Build Coastguard Worker break;
6526*5e7646d2SAndroid Build Coastguard Worker
6527*5e7646d2SAndroid Build Coastguard Worker default :
6528*5e7646d2SAndroid Build Coastguard Worker for (i = 0, value = attr->values;
6529*5e7646d2SAndroid Build Coastguard Worker i < attr->num_values;
6530*5e7646d2SAndroid Build Coastguard Worker i ++, value ++)
6531*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)value->unknown.length;
6532*5e7646d2SAndroid Build Coastguard Worker break;
6533*5e7646d2SAndroid Build Coastguard Worker }
6534*5e7646d2SAndroid Build Coastguard Worker }
6535*5e7646d2SAndroid Build Coastguard Worker
6536*5e7646d2SAndroid Build Coastguard Worker /*
6537*5e7646d2SAndroid Build Coastguard Worker * Finally, add 1 byte for the "end of attributes" tag or 5 bytes
6538*5e7646d2SAndroid Build Coastguard Worker * for the "end of collection" tag and return...
6539*5e7646d2SAndroid Build Coastguard Worker */
6540*5e7646d2SAndroid Build Coastguard Worker
6541*5e7646d2SAndroid Build Coastguard Worker if (collection)
6542*5e7646d2SAndroid Build Coastguard Worker bytes += 5;
6543*5e7646d2SAndroid Build Coastguard Worker else
6544*5e7646d2SAndroid Build Coastguard Worker bytes ++;
6545*5e7646d2SAndroid Build Coastguard Worker
6546*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4ipp_length: Returning " CUPS_LLFMT " bytes", CUPS_LLCAST bytes));
6547*5e7646d2SAndroid Build Coastguard Worker
6548*5e7646d2SAndroid Build Coastguard Worker return (bytes);
6549*5e7646d2SAndroid Build Coastguard Worker }
6550*5e7646d2SAndroid Build Coastguard Worker
6551*5e7646d2SAndroid Build Coastguard Worker
6552*5e7646d2SAndroid Build Coastguard Worker /*
6553*5e7646d2SAndroid Build Coastguard Worker * 'ipp_read_http()' - Semi-blocking read on a HTTP connection...
6554*5e7646d2SAndroid Build Coastguard Worker */
6555*5e7646d2SAndroid Build Coastguard Worker
6556*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes read */
ipp_read_http(http_t * http,ipp_uchar_t * buffer,size_t length)6557*5e7646d2SAndroid Build Coastguard Worker ipp_read_http(http_t *http, /* I - Client connection */
6558*5e7646d2SAndroid Build Coastguard Worker ipp_uchar_t *buffer, /* O - Buffer for data */
6559*5e7646d2SAndroid Build Coastguard Worker size_t length) /* I - Total length */
6560*5e7646d2SAndroid Build Coastguard Worker {
6561*5e7646d2SAndroid Build Coastguard Worker ssize_t tbytes, /* Total bytes read */
6562*5e7646d2SAndroid Build Coastguard Worker bytes; /* Bytes read this pass */
6563*5e7646d2SAndroid Build Coastguard Worker
6564*5e7646d2SAndroid Build Coastguard Worker
6565*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7ipp_read_http(http=%p, buffer=%p, length=%d)", (void *)http, (void *)buffer, (int)length));
6566*5e7646d2SAndroid Build Coastguard Worker
6567*5e7646d2SAndroid Build Coastguard Worker /*
6568*5e7646d2SAndroid Build Coastguard Worker * Loop until all bytes are read...
6569*5e7646d2SAndroid Build Coastguard Worker */
6570*5e7646d2SAndroid Build Coastguard Worker
6571*5e7646d2SAndroid Build Coastguard Worker for (tbytes = 0, bytes = 0;
6572*5e7646d2SAndroid Build Coastguard Worker tbytes < (int)length;
6573*5e7646d2SAndroid Build Coastguard Worker tbytes += bytes, buffer += bytes)
6574*5e7646d2SAndroid Build Coastguard Worker {
6575*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9ipp_read_http: tbytes=" CUPS_LLFMT ", http->state=%d", CUPS_LLCAST tbytes, http->state));
6576*5e7646d2SAndroid Build Coastguard Worker
6577*5e7646d2SAndroid Build Coastguard Worker if (http->state == HTTP_STATE_WAITING)
6578*5e7646d2SAndroid Build Coastguard Worker break;
6579*5e7646d2SAndroid Build Coastguard Worker
6580*5e7646d2SAndroid Build Coastguard Worker if (http->used == 0 && !http->blocking)
6581*5e7646d2SAndroid Build Coastguard Worker {
6582*5e7646d2SAndroid Build Coastguard Worker /*
6583*5e7646d2SAndroid Build Coastguard Worker * Wait up to 10 seconds for more data on non-blocking sockets...
6584*5e7646d2SAndroid Build Coastguard Worker */
6585*5e7646d2SAndroid Build Coastguard Worker
6586*5e7646d2SAndroid Build Coastguard Worker if (!httpWait(http, 10000))
6587*5e7646d2SAndroid Build Coastguard Worker {
6588*5e7646d2SAndroid Build Coastguard Worker /*
6589*5e7646d2SAndroid Build Coastguard Worker * Signal no data...
6590*5e7646d2SAndroid Build Coastguard Worker */
6591*5e7646d2SAndroid Build Coastguard Worker
6592*5e7646d2SAndroid Build Coastguard Worker bytes = -1;
6593*5e7646d2SAndroid Build Coastguard Worker break;
6594*5e7646d2SAndroid Build Coastguard Worker }
6595*5e7646d2SAndroid Build Coastguard Worker }
6596*5e7646d2SAndroid Build Coastguard Worker else if (http->used == 0 && http->timeout_value > 0)
6597*5e7646d2SAndroid Build Coastguard Worker {
6598*5e7646d2SAndroid Build Coastguard Worker /*
6599*5e7646d2SAndroid Build Coastguard Worker * Wait up to timeout seconds for more data on blocking sockets...
6600*5e7646d2SAndroid Build Coastguard Worker */
6601*5e7646d2SAndroid Build Coastguard Worker
6602*5e7646d2SAndroid Build Coastguard Worker if (!httpWait(http, (int)(1000 * http->timeout_value)))
6603*5e7646d2SAndroid Build Coastguard Worker {
6604*5e7646d2SAndroid Build Coastguard Worker /*
6605*5e7646d2SAndroid Build Coastguard Worker * Signal no data...
6606*5e7646d2SAndroid Build Coastguard Worker */
6607*5e7646d2SAndroid Build Coastguard Worker
6608*5e7646d2SAndroid Build Coastguard Worker bytes = -1;
6609*5e7646d2SAndroid Build Coastguard Worker break;
6610*5e7646d2SAndroid Build Coastguard Worker }
6611*5e7646d2SAndroid Build Coastguard Worker }
6612*5e7646d2SAndroid Build Coastguard Worker
6613*5e7646d2SAndroid Build Coastguard Worker if ((bytes = httpRead2(http, (char *)buffer, length - (size_t)tbytes)) < 0)
6614*5e7646d2SAndroid Build Coastguard Worker {
6615*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
6616*5e7646d2SAndroid Build Coastguard Worker break;
6617*5e7646d2SAndroid Build Coastguard Worker #else
6618*5e7646d2SAndroid Build Coastguard Worker if (errno != EAGAIN && errno != EINTR)
6619*5e7646d2SAndroid Build Coastguard Worker break;
6620*5e7646d2SAndroid Build Coastguard Worker
6621*5e7646d2SAndroid Build Coastguard Worker bytes = 0;
6622*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
6623*5e7646d2SAndroid Build Coastguard Worker }
6624*5e7646d2SAndroid Build Coastguard Worker else if (bytes == 0)
6625*5e7646d2SAndroid Build Coastguard Worker break;
6626*5e7646d2SAndroid Build Coastguard Worker }
6627*5e7646d2SAndroid Build Coastguard Worker
6628*5e7646d2SAndroid Build Coastguard Worker /*
6629*5e7646d2SAndroid Build Coastguard Worker * Return the number of bytes read...
6630*5e7646d2SAndroid Build Coastguard Worker */
6631*5e7646d2SAndroid Build Coastguard Worker
6632*5e7646d2SAndroid Build Coastguard Worker if (tbytes == 0 && bytes < 0)
6633*5e7646d2SAndroid Build Coastguard Worker tbytes = -1;
6634*5e7646d2SAndroid Build Coastguard Worker
6635*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("8ipp_read_http: Returning " CUPS_LLFMT " bytes", CUPS_LLCAST tbytes));
6636*5e7646d2SAndroid Build Coastguard Worker
6637*5e7646d2SAndroid Build Coastguard Worker return (tbytes);
6638*5e7646d2SAndroid Build Coastguard Worker }
6639*5e7646d2SAndroid Build Coastguard Worker
6640*5e7646d2SAndroid Build Coastguard Worker
6641*5e7646d2SAndroid Build Coastguard Worker /*
6642*5e7646d2SAndroid Build Coastguard Worker * 'ipp_read_file()' - Read IPP data from a file.
6643*5e7646d2SAndroid Build Coastguard Worker */
6644*5e7646d2SAndroid Build Coastguard Worker
6645*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes read */
ipp_read_file(int * fd,ipp_uchar_t * buffer,size_t length)6646*5e7646d2SAndroid Build Coastguard Worker ipp_read_file(int *fd, /* I - File descriptor */
6647*5e7646d2SAndroid Build Coastguard Worker ipp_uchar_t *buffer, /* O - Read buffer */
6648*5e7646d2SAndroid Build Coastguard Worker size_t length) /* I - Number of bytes to read */
6649*5e7646d2SAndroid Build Coastguard Worker {
6650*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
6651*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)read(*fd, buffer, (unsigned)length));
6652*5e7646d2SAndroid Build Coastguard Worker #else
6653*5e7646d2SAndroid Build Coastguard Worker return (read(*fd, buffer, length));
6654*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
6655*5e7646d2SAndroid Build Coastguard Worker }
6656*5e7646d2SAndroid Build Coastguard Worker
6657*5e7646d2SAndroid Build Coastguard Worker
6658*5e7646d2SAndroid Build Coastguard Worker /*
6659*5e7646d2SAndroid Build Coastguard Worker * 'ipp_set_error()' - Set a formatted, localized error string.
6660*5e7646d2SAndroid Build Coastguard Worker */
6661*5e7646d2SAndroid Build Coastguard Worker
6662*5e7646d2SAndroid Build Coastguard Worker static void
ipp_set_error(ipp_status_t status,const char * format,...)6663*5e7646d2SAndroid Build Coastguard Worker ipp_set_error(ipp_status_t status, /* I - Status code */
6664*5e7646d2SAndroid Build Coastguard Worker const char *format, /* I - Printf-style error string */
6665*5e7646d2SAndroid Build Coastguard Worker ...) /* I - Additional arguments as needed */
6666*5e7646d2SAndroid Build Coastguard Worker {
6667*5e7646d2SAndroid Build Coastguard Worker va_list ap; /* Pointer to additional args */
6668*5e7646d2SAndroid Build Coastguard Worker char buffer[2048]; /* Message buffer */
6669*5e7646d2SAndroid Build Coastguard Worker cups_lang_t *lang = cupsLangDefault();
6670*5e7646d2SAndroid Build Coastguard Worker /* Current language */
6671*5e7646d2SAndroid Build Coastguard Worker
6672*5e7646d2SAndroid Build Coastguard Worker
6673*5e7646d2SAndroid Build Coastguard Worker va_start(ap, format);
6674*5e7646d2SAndroid Build Coastguard Worker vsnprintf(buffer, sizeof(buffer), _cupsLangString(lang, format), ap);
6675*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
6676*5e7646d2SAndroid Build Coastguard Worker
6677*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(status, buffer, 0);
6678*5e7646d2SAndroid Build Coastguard Worker }
6679*5e7646d2SAndroid Build Coastguard Worker
6680*5e7646d2SAndroid Build Coastguard Worker
6681*5e7646d2SAndroid Build Coastguard Worker /*
6682*5e7646d2SAndroid Build Coastguard Worker * 'ipp_set_value()' - Get the value element from an attribute, expanding it as
6683*5e7646d2SAndroid Build Coastguard Worker * needed.
6684*5e7646d2SAndroid Build Coastguard Worker */
6685*5e7646d2SAndroid Build Coastguard Worker
6686*5e7646d2SAndroid Build Coastguard Worker static _ipp_value_t * /* O - IPP value element or NULL on error */
ipp_set_value(ipp_t * ipp,ipp_attribute_t ** attr,int element)6687*5e7646d2SAndroid Build Coastguard Worker ipp_set_value(ipp_t *ipp, /* IO - IPP message */
6688*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t **attr, /* IO - IPP attribute */
6689*5e7646d2SAndroid Build Coastguard Worker int element) /* I - Value number (0-based) */
6690*5e7646d2SAndroid Build Coastguard Worker {
6691*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *temp, /* New attribute pointer */
6692*5e7646d2SAndroid Build Coastguard Worker *current, /* Current attribute in list */
6693*5e7646d2SAndroid Build Coastguard Worker *prev; /* Previous attribute in list */
6694*5e7646d2SAndroid Build Coastguard Worker int alloc_values; /* Allocated values */
6695*5e7646d2SAndroid Build Coastguard Worker
6696*5e7646d2SAndroid Build Coastguard Worker
6697*5e7646d2SAndroid Build Coastguard Worker /*
6698*5e7646d2SAndroid Build Coastguard Worker * If we are setting an existing value element, return it...
6699*5e7646d2SAndroid Build Coastguard Worker */
6700*5e7646d2SAndroid Build Coastguard Worker
6701*5e7646d2SAndroid Build Coastguard Worker temp = *attr;
6702*5e7646d2SAndroid Build Coastguard Worker
6703*5e7646d2SAndroid Build Coastguard Worker if (temp->num_values <= 1)
6704*5e7646d2SAndroid Build Coastguard Worker alloc_values = 1;
6705*5e7646d2SAndroid Build Coastguard Worker else
6706*5e7646d2SAndroid Build Coastguard Worker alloc_values = (temp->num_values + IPP_MAX_VALUES - 1) &
6707*5e7646d2SAndroid Build Coastguard Worker ~(IPP_MAX_VALUES - 1);
6708*5e7646d2SAndroid Build Coastguard Worker
6709*5e7646d2SAndroid Build Coastguard Worker if (element < alloc_values)
6710*5e7646d2SAndroid Build Coastguard Worker {
6711*5e7646d2SAndroid Build Coastguard Worker if (element >= temp->num_values)
6712*5e7646d2SAndroid Build Coastguard Worker temp->num_values = element + 1;
6713*5e7646d2SAndroid Build Coastguard Worker
6714*5e7646d2SAndroid Build Coastguard Worker return (temp->values + element);
6715*5e7646d2SAndroid Build Coastguard Worker }
6716*5e7646d2SAndroid Build Coastguard Worker
6717*5e7646d2SAndroid Build Coastguard Worker /*
6718*5e7646d2SAndroid Build Coastguard Worker * Otherwise re-allocate the attribute - we allocate in groups of IPP_MAX_VALUE
6719*5e7646d2SAndroid Build Coastguard Worker * values when num_values > 1.
6720*5e7646d2SAndroid Build Coastguard Worker */
6721*5e7646d2SAndroid Build Coastguard Worker
6722*5e7646d2SAndroid Build Coastguard Worker if (alloc_values < IPP_MAX_VALUES)
6723*5e7646d2SAndroid Build Coastguard Worker alloc_values = IPP_MAX_VALUES;
6724*5e7646d2SAndroid Build Coastguard Worker else
6725*5e7646d2SAndroid Build Coastguard Worker alloc_values += IPP_MAX_VALUES;
6726*5e7646d2SAndroid Build Coastguard Worker
6727*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4ipp_set_value: Reallocating for up to %d values.",
6728*5e7646d2SAndroid Build Coastguard Worker alloc_values));
6729*5e7646d2SAndroid Build Coastguard Worker
6730*5e7646d2SAndroid Build Coastguard Worker /*
6731*5e7646d2SAndroid Build Coastguard Worker * Reallocate memory...
6732*5e7646d2SAndroid Build Coastguard Worker */
6733*5e7646d2SAndroid Build Coastguard Worker
6734*5e7646d2SAndroid Build Coastguard Worker if ((temp = realloc(temp, sizeof(ipp_attribute_t) + (size_t)(alloc_values - 1) * sizeof(_ipp_value_t))) == NULL)
6735*5e7646d2SAndroid Build Coastguard Worker {
6736*5e7646d2SAndroid Build Coastguard Worker _cupsSetHTTPError(HTTP_STATUS_ERROR);
6737*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("4ipp_set_value: Unable to resize attribute.");
6738*5e7646d2SAndroid Build Coastguard Worker return (NULL);
6739*5e7646d2SAndroid Build Coastguard Worker }
6740*5e7646d2SAndroid Build Coastguard Worker
6741*5e7646d2SAndroid Build Coastguard Worker /*
6742*5e7646d2SAndroid Build Coastguard Worker * Zero the new memory...
6743*5e7646d2SAndroid Build Coastguard Worker */
6744*5e7646d2SAndroid Build Coastguard Worker
6745*5e7646d2SAndroid Build Coastguard Worker memset(temp->values + temp->num_values, 0, (size_t)(alloc_values - temp->num_values) * sizeof(_ipp_value_t));
6746*5e7646d2SAndroid Build Coastguard Worker
6747*5e7646d2SAndroid Build Coastguard Worker if (temp != *attr)
6748*5e7646d2SAndroid Build Coastguard Worker {
6749*5e7646d2SAndroid Build Coastguard Worker /*
6750*5e7646d2SAndroid Build Coastguard Worker * Reset pointers in the list...
6751*5e7646d2SAndroid Build Coastguard Worker */
6752*5e7646d2SAndroid Build Coastguard Worker
6753*5e7646d2SAndroid Build Coastguard Worker #ifndef __clang_analyzer__
6754*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4debug_free: %p %s", (void *)*attr, temp->name));
6755*5e7646d2SAndroid Build Coastguard Worker #endif /* !__clang_analyzer__ */
6756*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4debug_alloc: %p %s %s%s (%d)", (void *)temp, temp->name, temp->num_values > 1 ? "1setOf " : "", ippTagString(temp->value_tag), temp->num_values));
6757*5e7646d2SAndroid Build Coastguard Worker
6758*5e7646d2SAndroid Build Coastguard Worker if (ipp->current == *attr && ipp->prev)
6759*5e7646d2SAndroid Build Coastguard Worker {
6760*5e7646d2SAndroid Build Coastguard Worker /*
6761*5e7646d2SAndroid Build Coastguard Worker * Use current "previous" pointer...
6762*5e7646d2SAndroid Build Coastguard Worker */
6763*5e7646d2SAndroid Build Coastguard Worker
6764*5e7646d2SAndroid Build Coastguard Worker prev = ipp->prev;
6765*5e7646d2SAndroid Build Coastguard Worker }
6766*5e7646d2SAndroid Build Coastguard Worker else
6767*5e7646d2SAndroid Build Coastguard Worker {
6768*5e7646d2SAndroid Build Coastguard Worker /*
6769*5e7646d2SAndroid Build Coastguard Worker * Find this attribute in the linked list...
6770*5e7646d2SAndroid Build Coastguard Worker */
6771*5e7646d2SAndroid Build Coastguard Worker
6772*5e7646d2SAndroid Build Coastguard Worker for (prev = NULL, current = ipp->attrs;
6773*5e7646d2SAndroid Build Coastguard Worker current && current != *attr;
6774*5e7646d2SAndroid Build Coastguard Worker prev = current, current = current->next);
6775*5e7646d2SAndroid Build Coastguard Worker
6776*5e7646d2SAndroid Build Coastguard Worker if (!current)
6777*5e7646d2SAndroid Build Coastguard Worker {
6778*5e7646d2SAndroid Build Coastguard Worker /*
6779*5e7646d2SAndroid Build Coastguard Worker * This is a serious error!
6780*5e7646d2SAndroid Build Coastguard Worker */
6781*5e7646d2SAndroid Build Coastguard Worker
6782*5e7646d2SAndroid Build Coastguard Worker *attr = temp;
6783*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
6784*5e7646d2SAndroid Build Coastguard Worker _("IPP attribute is not a member of the message."), 1);
6785*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("4ipp_set_value: Unable to find attribute in message.");
6786*5e7646d2SAndroid Build Coastguard Worker return (NULL);
6787*5e7646d2SAndroid Build Coastguard Worker }
6788*5e7646d2SAndroid Build Coastguard Worker }
6789*5e7646d2SAndroid Build Coastguard Worker
6790*5e7646d2SAndroid Build Coastguard Worker if (prev)
6791*5e7646d2SAndroid Build Coastguard Worker prev->next = temp;
6792*5e7646d2SAndroid Build Coastguard Worker else
6793*5e7646d2SAndroid Build Coastguard Worker ipp->attrs = temp;
6794*5e7646d2SAndroid Build Coastguard Worker
6795*5e7646d2SAndroid Build Coastguard Worker ipp->current = temp;
6796*5e7646d2SAndroid Build Coastguard Worker ipp->prev = prev;
6797*5e7646d2SAndroid Build Coastguard Worker
6798*5e7646d2SAndroid Build Coastguard Worker if (ipp->last == *attr)
6799*5e7646d2SAndroid Build Coastguard Worker ipp->last = temp;
6800*5e7646d2SAndroid Build Coastguard Worker
6801*5e7646d2SAndroid Build Coastguard Worker *attr = temp;
6802*5e7646d2SAndroid Build Coastguard Worker }
6803*5e7646d2SAndroid Build Coastguard Worker
6804*5e7646d2SAndroid Build Coastguard Worker /*
6805*5e7646d2SAndroid Build Coastguard Worker * Return the value element...
6806*5e7646d2SAndroid Build Coastguard Worker */
6807*5e7646d2SAndroid Build Coastguard Worker
6808*5e7646d2SAndroid Build Coastguard Worker if (element >= temp->num_values)
6809*5e7646d2SAndroid Build Coastguard Worker temp->num_values = element + 1;
6810*5e7646d2SAndroid Build Coastguard Worker
6811*5e7646d2SAndroid Build Coastguard Worker return (temp->values + element);
6812*5e7646d2SAndroid Build Coastguard Worker }
6813*5e7646d2SAndroid Build Coastguard Worker
6814*5e7646d2SAndroid Build Coastguard Worker
6815*5e7646d2SAndroid Build Coastguard Worker /*
6816*5e7646d2SAndroid Build Coastguard Worker * 'ipp_write_file()' - Write IPP data to a file.
6817*5e7646d2SAndroid Build Coastguard Worker */
6818*5e7646d2SAndroid Build Coastguard Worker
6819*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes written */
ipp_write_file(int * fd,ipp_uchar_t * buffer,size_t length)6820*5e7646d2SAndroid Build Coastguard Worker ipp_write_file(int *fd, /* I - File descriptor */
6821*5e7646d2SAndroid Build Coastguard Worker ipp_uchar_t *buffer, /* I - Data to write */
6822*5e7646d2SAndroid Build Coastguard Worker size_t length) /* I - Number of bytes to write */
6823*5e7646d2SAndroid Build Coastguard Worker {
6824*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
6825*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)write(*fd, buffer, (unsigned)length));
6826*5e7646d2SAndroid Build Coastguard Worker #else
6827*5e7646d2SAndroid Build Coastguard Worker return (write(*fd, buffer, length));
6828*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
6829*5e7646d2SAndroid Build Coastguard Worker }
6830