]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
1106b00e | 2 | * "$Id: ipp-support.c 9371 2010-11-17 06:21:32Z mike $" |
ef416fc2 | 3 | * |
71e16022 | 4 | * Internet Printing Protocol support functions for CUPS. |
ef416fc2 | 5 | * |
3e7fe0ca | 6 | * Copyright 2007-2012 by Apple Inc. |
b94498cf | 7 | * Copyright 1997-2007 by Easy Software Products, all rights reserved. |
ef416fc2 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 10 | * property of Apple Inc. and are protected by Federal copyright |
11 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
12 | * which should have been included with this file. If this file is | |
13 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
ef416fc2 | 14 | * |
15 | * This file is subject to the Apple OS-Developed Software exception. | |
16 | * | |
17 | * Contents: | |
18 | * | |
a2326b5b MS |
19 | * ippAttributeString() - Convert the attribute's value to a string. |
20 | * ippEnumString() - Return a string corresponding to the enum value. | |
21 | * ippEnumValue() - Return the value associated with a given enum | |
22 | * string. | |
23 | * ippErrorString() - Return a name for the given status code. | |
24 | * ippErrorValue() - Return a status code for the given name. | |
25 | * ippOpString() - Return a name for the given operation id. | |
26 | * ippOpValue() - Return an operation id for the given name. | |
27 | * ippPort() - Return the default IPP port number. | |
28 | * ippSetPort() - Set the default port number. | |
29 | * ippTagString() - Return the tag name corresponding to a tag value. | |
30 | * ippTagValue() - Return the tag value corresponding to a tag name. | |
31 | * ipp_col_string() - Convert a collection to a string. | |
ef416fc2 | 32 | */ |
33 | ||
34 | /* | |
35 | * Include necessary headers... | |
36 | */ | |
37 | ||
71e16022 | 38 | #include "cups-private.h" |
ef416fc2 | 39 | |
40 | ||
41 | /* | |
42 | * Local globals... | |
43 | */ | |
44 | ||
45 | static const char * const ipp_status_oks[] = /* "OK" status codes */ | |
a2326b5b | 46 | { /* (name) = abandoned standard value */ |
ef416fc2 | 47 | "successful-ok", |
48 | "successful-ok-ignored-or-substituted-attributes", | |
49 | "successful-ok-conflicting-attributes", | |
50 | "successful-ok-ignored-subscriptions", | |
a2326b5b | 51 | "(successful-ok-ignored-notifications)", |
ef416fc2 | 52 | "successful-ok-too-many-events", |
a2326b5b | 53 | "(successful-ok-but-cancel-subscription)", |
bd7854cb | 54 | "successful-ok-events-complete" |
ef416fc2 | 55 | }, |
56 | * const ipp_status_400s[] = /* Client errors */ | |
a2326b5b | 57 | { /* (name) = abandoned standard value */ |
ef416fc2 | 58 | "client-error-bad-request", |
59 | "client-error-forbidden", | |
60 | "client-error-not-authenticated", | |
61 | "client-error-not-authorized", | |
62 | "client-error-not-possible", | |
63 | "client-error-timeout", | |
64 | "client-error-not-found", | |
65 | "client-error-gone", | |
66 | "client-error-request-entity-too-large", | |
67 | "client-error-request-value-too-long", | |
68 | "client-error-document-format-not-supported", | |
69 | "client-error-attributes-or-values-not-supported", | |
70 | "client-error-uri-scheme-not-supported", | |
71 | "client-error-charset-not-supported", | |
72 | "client-error-conflicting-attributes", | |
73 | "client-error-compression-not-supported", | |
74 | "client-error-compression-error", | |
75 | "client-error-document-format-error", | |
76 | "client-error-document-access-error", | |
77 | "client-error-attributes-not-settable", | |
78 | "client-error-ignored-all-subscriptions", | |
79 | "client-error-too-many-subscriptions", | |
a2326b5b MS |
80 | "(client-error-ignored-all-notifications)", |
81 | "(client-error-client-print-support-file-not-found)" | |
ef416fc2 | 82 | }, |
83 | * const ipp_status_500s[] = /* Server errors */ | |
84 | { | |
85 | "server-error-internal-error", | |
86 | "server-error-operation-not-supported", | |
87 | "server-error-service-unavailable", | |
88 | "server-error-version-not-supported", | |
89 | "server-error-device-error", | |
90 | "server-error-temporary-error", | |
91 | "server-error-not-accepting-jobs", | |
92 | "server-error-busy", | |
93 | "server-error-job-canceled", | |
94 | "server-error-multiple-document-jobs-not-supported", | |
a2326b5b MS |
95 | "server-error-printer-is-deactivated", |
96 | "server-error-too-many-jobs", | |
97 | "server-error-too-many-documents" | |
7cf5915e MS |
98 | }, |
99 | * const ipp_status_1000s[] = /* CUPS internal */ | |
100 | { | |
101 | "cups-authorization-canceled", | |
102 | "cups-pki-error", | |
103 | "cups-upgrade-required" | |
ef416fc2 | 104 | }; |
a2326b5b | 105 | static const char * const ipp_std_ops[] = |
ef416fc2 | 106 | { |
107 | /* 0x0000 - 0x000f */ | |
d7225fc2 MS |
108 | "0x00", |
109 | "0x01", | |
aaf19ab0 MS |
110 | "Print-Job", |
111 | "Print-URI", | |
112 | "Validate-Job", | |
113 | "Create-Job", | |
114 | "Send-Document", | |
115 | "Send-URI", | |
116 | "Cancel-Job", | |
117 | "Get-Job-Attributes", | |
118 | "Get-Jobs", | |
119 | "Get-Printer-Attributes", | |
120 | "Hold-Job", | |
121 | "Release-Job", | |
122 | "Restart-Job", | |
d7225fc2 | 123 | "0x0f", |
ef416fc2 | 124 | |
125 | /* 0x0010 - 0x001f */ | |
aaf19ab0 MS |
126 | "Pause-Printer", |
127 | "Resume-Printer", | |
128 | "Purge-Jobs", | |
129 | "Set-Printer-Attributes", | |
ef416fc2 | 130 | "Set-Job-Attributes", |
131 | "Get-Printer-Supported-Values", | |
132 | "Create-Printer-Subscription", | |
133 | "Create-Job-Subscription", | |
134 | "Get-Subscription-Attributes", | |
aaf19ab0 MS |
135 | "Get-Subscriptions", |
136 | "Renew-Subscription", | |
137 | "Cancel-Subscription", | |
138 | "Get-Notifications", | |
a2326b5b MS |
139 | "(Send-Notifications)", |
140 | "(Get-Resource-Attributes)", | |
141 | "(Get-Resource-Data)", | |
ef416fc2 | 142 | |
143 | /* 0x0020 - 0x002f */ | |
a2326b5b MS |
144 | "(Get-Resources)", |
145 | "(Get-Printer-Support-Files)", | |
ef416fc2 | 146 | "Enable-Printer", |
147 | "Disable-Printer", | |
148 | "Pause-Printer-After-Current-Job", | |
149 | "Hold-New-Jobs", | |
150 | "Release-Held-New-Jobs", | |
151 | "Deactivate-Printer", | |
152 | "Activate-Printer", | |
153 | "Restart-Printer", | |
154 | "Shutdown-Printer", | |
155 | "Startup-Printer", | |
156 | "Reprocess-Job", | |
157 | "Cancel-Current-Job", | |
158 | "Suspend-Current-Job", | |
159 | "Resume-Job", | |
160 | ||
aaf19ab0 | 161 | /* 0x0030 - 0x003b */ |
ef416fc2 | 162 | "Promote-Job", |
aaf19ab0 | 163 | "Schedule-Job-After", |
d7225fc2 | 164 | "0x32", |
aaf19ab0 MS |
165 | "Cancel-Document", |
166 | "Get-Document-Attributes", | |
167 | "Get-Documents", | |
168 | "Delete-Document", | |
169 | "Set-Document-Attributes", | |
170 | "Cancel-Jobs", | |
171 | "Cancel-My-Jobs", | |
172 | "Resubmit-Job", | |
771bd8cb MS |
173 | "Close-Job", |
174 | "Identify-Printer" | |
ef416fc2 | 175 | }, |
176 | * const ipp_cups_ops[] = | |
177 | { | |
178 | "CUPS-Get-Default", | |
179 | "CUPS-Get-Printers", | |
480ef0fe | 180 | "CUPS-Add-Modify-Printer", |
ef416fc2 | 181 | "CUPS-Delete-Printer", |
182 | "CUPS-Get-Classes", | |
480ef0fe | 183 | "CUPS-Add-Modify-Class", |
ef416fc2 | 184 | "CUPS-Delete-Class", |
185 | "CUPS-Accept-Jobs", | |
186 | "CUPS-Reject-Jobs", | |
187 | "CUPS-Set-Default", | |
188 | "CUPS-Get-Devices", | |
189 | "CUPS-Get-PPDs", | |
190 | "CUPS-Move-Job", | |
b94498cf | 191 | "CUPS-Authenticate-Job", |
192 | "CUPS-Get-PPD" | |
2e4ff8af MS |
193 | }, |
194 | * const ipp_cups_ops2[] = | |
195 | { | |
196 | "CUPS-Get-Document" | |
1ff0402e MS |
197 | }, |
198 | * const ipp_tag_names[] = | |
199 | { /* Value/group tag names */ | |
200 | "zero", /* 0x00 */ | |
201 | "operation-attributes-tag", | |
202 | /* 0x01 */ | |
203 | "job-attributes-tag", /* 0x02 */ | |
204 | "end-of-attributes-tag", | |
205 | /* 0x03 */ | |
206 | "printer-attributes-tag", | |
207 | /* 0x04 */ | |
208 | "unsupported-attributes-tag", | |
209 | /* 0x05 */ | |
210 | "subscription-attributes-tag", | |
211 | /* 0x06 */ | |
212 | "event-notification-attributes-tag", | |
213 | /* 0x07 */ | |
a2326b5b MS |
214 | "(resource-attributes-tag)", |
215 | /* 0x08 */ | |
d7225fc2 MS |
216 | "document-attributes-tag", |
217 | /* 0x09 */ | |
218 | "0x0a", /* 0x0a */ | |
219 | "0x0b", /* 0x0b */ | |
220 | "0x0c", /* 0x0c */ | |
221 | "0x0d", /* 0x0d */ | |
222 | "0x0e", /* 0x0e */ | |
223 | "0x0f", /* 0x0f */ | |
1ff0402e MS |
224 | "unsupported", /* 0x10 */ |
225 | "default", /* 0x11 */ | |
226 | "unknown", /* 0x12 */ | |
227 | "no-value", /* 0x13 */ | |
d7225fc2 | 228 | "0x14", /* 0x14 */ |
1ff0402e MS |
229 | "not-settable", /* 0x15 */ |
230 | "delete-attribute", /* 0x16 */ | |
231 | "admin-define", /* 0x17 */ | |
d7225fc2 MS |
232 | "0x18", /* 0x18 */ |
233 | "0x19", /* 0x19 */ | |
234 | "0x1a", /* 0x1a */ | |
235 | "0x1b", /* 0x1b */ | |
236 | "0x1c", /* 0x1c */ | |
237 | "0x1d", /* 0x1d */ | |
238 | "0x1e", /* 0x1e */ | |
239 | "0x1f", /* 0x1f */ | |
240 | "0x20", /* 0x20 */ | |
1ff0402e MS |
241 | "integer", /* 0x21 */ |
242 | "boolean", /* 0x22 */ | |
243 | "enum", /* 0x23 */ | |
d7225fc2 MS |
244 | "0x24", /* 0x24 */ |
245 | "0x25", /* 0x25 */ | |
246 | "0x26", /* 0x26 */ | |
247 | "0x27", /* 0x27 */ | |
248 | "0x28", /* 0x28 */ | |
249 | "0x29", /* 0x29 */ | |
250 | "0x2a", /* 0x2a */ | |
251 | "0x2b", /* 0x2b */ | |
252 | "0x2c", /* 0x2c */ | |
253 | "0x2d", /* 0x2d */ | |
254 | "0x2e", /* 0x2e */ | |
255 | "0x2f", /* 0x2f */ | |
1ff0402e MS |
256 | "octetString", /* 0x30 */ |
257 | "dateTime", /* 0x31 */ | |
258 | "resolution", /* 0x32 */ | |
259 | "rangeOfInteger", /* 0x33 */ | |
f8b3a85b | 260 | "collection", /* 0x34 */ |
1ff0402e MS |
261 | "textWithLanguage", /* 0x35 */ |
262 | "nameWithLanguage", /* 0x36 */ | |
263 | "endCollection", /* 0x37 */ | |
d7225fc2 MS |
264 | "0x38", /* 0x38 */ |
265 | "0x39", /* 0x39 */ | |
266 | "0x3a", /* 0x3a */ | |
267 | "0x3b", /* 0x3b */ | |
268 | "0x3c", /* 0x3c */ | |
269 | "0x3d", /* 0x3d */ | |
270 | "0x3e", /* 0x3e */ | |
271 | "0x3f", /* 0x3f */ | |
272 | "0x40", /* 0x40 */ | |
1ff0402e MS |
273 | "textWithoutLanguage",/* 0x41 */ |
274 | "nameWithoutLanguage",/* 0x42 */ | |
d7225fc2 | 275 | "0x43", /* 0x43 */ |
1ff0402e MS |
276 | "keyword", /* 0x44 */ |
277 | "uri", /* 0x45 */ | |
278 | "uriScheme", /* 0x46 */ | |
279 | "charset", /* 0x47 */ | |
280 | "naturalLanguage", /* 0x48 */ | |
281 | "mimeMediaType", /* 0x49 */ | |
282 | "memberAttrName" /* 0x4a */ | |
ef416fc2 | 283 | }; |
a2326b5b MS |
284 | static const char * const ipp_document_states[] = |
285 | { /* document-state-enums */ | |
286 | "pending", | |
287 | "4", | |
288 | "processing", | |
289 | "6", | |
290 | "canceled", | |
291 | "aborted", | |
292 | "completed" | |
293 | }, | |
294 | * const ipp_finishings[] = | |
295 | { /* finishings enums */ | |
296 | "none", | |
297 | "staple", | |
298 | "punch", | |
299 | "cover", | |
300 | "bind", | |
301 | "saddle-stitch", | |
302 | "edge-stitch", | |
303 | "fold", | |
304 | "trim", | |
305 | "bale", | |
306 | "booklet-maker", | |
307 | "jog-offset", | |
308 | "15", | |
309 | "16", | |
310 | "17", | |
311 | "18", | |
312 | "19", | |
313 | "staple-top-left", | |
314 | "staple-bottom-left", | |
315 | "staple-top-right", | |
316 | "staple-bottom-right", | |
317 | "edge-stitch-left", | |
318 | "edge-stitch-top", | |
319 | "edge-stitch-right", | |
320 | "edge-stitch-bottom", | |
321 | "staple-dual-left", | |
322 | "staple-dual-top", | |
323 | "staple-dual-right", | |
324 | "staple-dual-bottom", | |
325 | "32", | |
326 | "33", | |
327 | "34", | |
328 | "35", | |
329 | "36", | |
330 | "37", | |
331 | "38", | |
332 | "39", | |
333 | "40", | |
334 | "41", | |
335 | "42", | |
336 | "43", | |
337 | "44", | |
338 | "45", | |
339 | "46", | |
340 | "47", | |
341 | "48", | |
342 | "49", | |
343 | "bind-left", | |
344 | "bind-top", | |
345 | "bind-right", | |
346 | "bind-bottom", | |
347 | "54", | |
348 | "55", | |
349 | "56", | |
350 | "57", | |
351 | "58", | |
352 | "59", | |
353 | "trim-after-pages", | |
354 | "trim-after-documents", | |
355 | "trim-after-copies", | |
356 | "trim-after-job" | |
357 | }, | |
358 | * const ipp_job_collation_types[] = | |
359 | { /* job-collation-type enums */ | |
360 | "uncollated-sheets", | |
361 | "collated-documents", | |
362 | "uncollated-documents" | |
363 | }, | |
364 | * const ipp_job_states[] = | |
365 | { /* job-state enums */ | |
366 | "pending", | |
367 | "pending-held", | |
368 | "processing", | |
369 | "processing-stopped", | |
370 | "canceled", | |
371 | "aborted", | |
372 | "completed" | |
373 | }, | |
374 | * const ipp_orientation_requesteds[] = | |
375 | { /* orientation-requested enums */ | |
376 | "portrait", | |
377 | "landscape", | |
378 | "reverse-landscape", | |
379 | "reverse-portrait" | |
380 | }, | |
381 | * const ipp_print_qualities[] = | |
382 | { /* print-quality enums */ | |
383 | "draft", | |
384 | "normal", | |
385 | "high" | |
386 | }, | |
387 | * const ipp_printer_states[] = | |
388 | { /* printer-state enums */ | |
389 | "idle", | |
390 | "processing", | |
391 | "stopped", | |
392 | }; | |
aaf19ab0 MS |
393 | |
394 | ||
395 | /* | |
396 | * Local functions... | |
397 | */ | |
398 | ||
399 | static size_t ipp_col_string(ipp_t *col, char *buffer, size_t bufsize); | |
400 | ||
401 | ||
402 | /* | |
a2326b5b | 403 | * 'ippAttributeString()' - Convert the attribute's value to a string. |
aaf19ab0 MS |
404 | * |
405 | * Returns the number of bytes that would be written, not including the | |
406 | * trailing nul. The buffer pointer can be NULL to get the required length, | |
407 | * just like (v)snprintf. | |
a2326b5b MS |
408 | * |
409 | * @since CUPS 1.6@ | |
aaf19ab0 MS |
410 | */ |
411 | ||
412 | size_t /* O - Number of bytes less nul */ | |
a2326b5b MS |
413 | ippAttributeString( |
414 | ipp_attribute_t *attr, /* I - Attribute */ | |
415 | char *buffer, /* I - String buffer or NULL */ | |
416 | size_t bufsize) /* I - Size of string buffer */ | |
aaf19ab0 MS |
417 | { |
418 | int i; /* Looping var */ | |
419 | char *bufptr, /* Pointer into buffer */ | |
420 | *bufend, /* End of buffer */ | |
421 | temp[256]; /* Temporary string */ | |
422 | const char *ptr; /* Pointer into string */ | |
a2326b5b | 423 | _ipp_value_t *val; /* Current value */ |
aaf19ab0 MS |
424 | |
425 | ||
426 | if (!attr || !attr->name) | |
427 | { | |
428 | if (buffer) | |
429 | *buffer = '\0'; | |
430 | ||
431 | return (0); | |
432 | } | |
433 | ||
434 | bufptr = buffer; | |
435 | if (buffer) | |
436 | bufend = buffer + bufsize - 1; | |
437 | else | |
438 | bufend = NULL; | |
439 | ||
440 | for (i = attr->num_values, val = attr->values; i > 0; i --, val ++) | |
441 | { | |
442 | if (val > attr->values) | |
443 | { | |
7cf5915e | 444 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
445 | *bufptr++ = ','; |
446 | else | |
447 | bufptr ++; | |
448 | } | |
449 | ||
1106b00e | 450 | switch (attr->value_tag & ~IPP_TAG_COPY) |
aaf19ab0 MS |
451 | { |
452 | case IPP_TAG_ENUM : | |
a2326b5b | 453 | ptr = ippEnumString(attr->name, val->integer); |
aaf19ab0 | 454 | |
a2326b5b MS |
455 | if (buffer && bufptr < bufend) |
456 | strlcpy(bufptr, ptr, bufend - bufptr + 1); | |
9b66acc5 | 457 | |
a2326b5b MS |
458 | bufptr += strlen(ptr); |
459 | break; | |
aaf19ab0 MS |
460 | |
461 | case IPP_TAG_INTEGER : | |
7cf5915e | 462 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
463 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "%d", val->integer); |
464 | else | |
465 | bufptr += snprintf(temp, sizeof(temp), "%d", val->integer); | |
466 | break; | |
467 | ||
468 | case IPP_TAG_BOOLEAN : | |
7cf5915e | 469 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
470 | strlcpy(bufptr, val->boolean ? "true" : "false", |
471 | bufend - bufptr + 1); | |
472 | ||
473 | bufptr += val->boolean ? 4 : 5; | |
474 | break; | |
475 | ||
476 | case IPP_TAG_RANGE : | |
7cf5915e | 477 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
478 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "%d-%d", |
479 | val->range.lower, val->range.upper); | |
480 | else | |
481 | bufptr += snprintf(temp, sizeof(temp), "%d-%d", val->range.lower, | |
482 | val->range.upper); | |
483 | break; | |
484 | ||
485 | case IPP_TAG_RESOLUTION : | |
7cf5915e | 486 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
487 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "%dx%d%s", |
488 | val->resolution.xres, val->resolution.yres, | |
489 | val->resolution.units == IPP_RES_PER_INCH ? | |
3e7fe0ca | 490 | "dpi" : "dpcm"); |
aaf19ab0 MS |
491 | else |
492 | bufptr += snprintf(temp, sizeof(temp), "%dx%d%s", | |
493 | val->resolution.xres, val->resolution.yres, | |
494 | val->resolution.units == IPP_RES_PER_INCH ? | |
3e7fe0ca | 495 | "dpi" : "dpcm"); |
aaf19ab0 MS |
496 | break; |
497 | ||
498 | case IPP_TAG_DATE : | |
499 | { | |
500 | unsigned year; /* Year */ | |
501 | ||
502 | year = (val->date[0] << 8) + val->date[1]; | |
503 | ||
504 | if (val->date[9] == 0 && val->date[10] == 0) | |
505 | snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02uZ", | |
506 | year, val->date[2], val->date[3], val->date[4], | |
507 | val->date[5], val->date[6]); | |
508 | else | |
509 | snprintf(temp, sizeof(temp), | |
510 | "%04u-%02u-%02uT%02u:%02u:%02u%c%02u%02u", | |
511 | year, val->date[2], val->date[3], val->date[4], | |
512 | val->date[5], val->date[6], val->date[8], val->date[9], | |
513 | val->date[10]); | |
514 | ||
7cf5915e | 515 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
516 | strlcpy(bufptr, temp, bufend - bufptr + 1); |
517 | ||
518 | bufptr += strlen(temp); | |
519 | } | |
520 | break; | |
521 | ||
522 | case IPP_TAG_TEXT : | |
523 | case IPP_TAG_NAME : | |
524 | case IPP_TAG_KEYWORD : | |
525 | case IPP_TAG_CHARSET : | |
526 | case IPP_TAG_URI : | |
d7225fc2 | 527 | case IPP_TAG_URISCHEME : |
aaf19ab0 MS |
528 | case IPP_TAG_MIMETYPE : |
529 | case IPP_TAG_LANGUAGE : | |
530 | case IPP_TAG_TEXTLANG : | |
531 | case IPP_TAG_NAMELANG : | |
7cf5915e MS |
532 | if (!val->string.text) |
533 | break; | |
534 | ||
aaf19ab0 MS |
535 | for (ptr = val->string.text; *ptr; ptr ++) |
536 | { | |
a2326b5b | 537 | if (*ptr == '\\' || *ptr == '\"' || *ptr == '[') |
aaf19ab0 | 538 | { |
7cf5915e | 539 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
540 | *bufptr = '\\'; |
541 | bufptr ++; | |
542 | } | |
543 | ||
7cf5915e | 544 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
545 | *bufptr = *ptr; |
546 | bufptr ++; | |
547 | } | |
a2326b5b MS |
548 | |
549 | if (val->string.language) | |
550 | { | |
551 | /* | |
552 | * Add "[language]" to end of string... | |
553 | */ | |
554 | ||
555 | if (buffer && bufptr < bufend) | |
556 | *bufptr = '['; | |
557 | bufptr ++; | |
558 | ||
559 | if (buffer && bufptr < bufend) | |
560 | strlcpy(bufptr, val->string.language, bufend - bufptr); | |
561 | bufptr += strlen(val->string.language); | |
562 | ||
563 | if (buffer && bufptr < bufend) | |
564 | *bufptr = ']'; | |
565 | bufptr ++; | |
566 | } | |
aaf19ab0 MS |
567 | break; |
568 | ||
569 | case IPP_TAG_BEGIN_COLLECTION : | |
7cf5915e | 570 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
571 | bufptr += ipp_col_string(val->collection, bufptr, |
572 | bufend - bufptr + 1); | |
573 | else | |
574 | bufptr += ipp_col_string(val->collection, NULL, 0); | |
575 | break; | |
576 | ||
577 | case IPP_TAG_STRING : | |
578 | for (ptr = val->string.text; *ptr; ptr ++) | |
579 | { | |
7cf5915e | 580 | if (*ptr == '\\' || _cups_isspace(*ptr)) |
aaf19ab0 | 581 | { |
7cf5915e | 582 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
583 | *bufptr = '\\'; |
584 | bufptr ++; | |
585 | ||
7cf5915e | 586 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
587 | *bufptr = *ptr; |
588 | bufptr ++; | |
589 | } | |
590 | else if (!isprint(*ptr & 255)) | |
591 | { | |
7cf5915e | 592 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
593 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "\\%03o", |
594 | *ptr & 255); | |
595 | else | |
596 | bufptr += snprintf(temp, sizeof(temp), "\\%03o", | |
597 | *ptr & 255); | |
598 | } | |
599 | else | |
600 | { | |
7cf5915e | 601 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
602 | *bufptr = *ptr; |
603 | bufptr ++; | |
604 | } | |
605 | } | |
606 | break; | |
607 | ||
608 | default : | |
609 | ptr = ippTagString(attr->value_tag); | |
7cf5915e | 610 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
611 | strlcpy(bufptr, ptr, bufend - bufptr + 1); |
612 | bufptr += strlen(ptr); | |
613 | break; | |
614 | } | |
615 | } | |
616 | ||
7cf5915e | 617 | if (buffer && bufptr < bufend) |
aaf19ab0 MS |
618 | *bufptr = '\0'; |
619 | else if (bufend) | |
620 | *bufend = '\0'; | |
621 | ||
622 | return (bufptr - buffer); | |
623 | } | |
ef416fc2 | 624 | |
625 | ||
a2326b5b MS |
626 | /* |
627 | * 'ippEnumString()' - Return a string corresponding to the enum value. | |
628 | */ | |
629 | ||
630 | const char * /* O - Enum string */ | |
631 | ippEnumString(const char *attrname, /* I - Attribute name */ | |
632 | int enumvalue) /* I - Enum value */ | |
633 | { | |
634 | _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ | |
635 | ||
636 | ||
637 | /* | |
638 | * Check for standard enum values... | |
639 | */ | |
640 | ||
641 | if (!strcmp(attrname, "document-state") && | |
642 | enumvalue >= 3 && | |
643 | enumvalue <= (3 + (int)(sizeof(ipp_document_states) / | |
644 | sizeof(ipp_document_states[0])))) | |
645 | return (ipp_document_states[enumvalue - 3]); | |
646 | else if ((!strcmp(attrname, "finishings") || | |
647 | !strcmp(attrname, "finishings-actual") || | |
648 | !strcmp(attrname, "finishings-default") || | |
649 | !strcmp(attrname, "finishings-ready") || | |
650 | !strcmp(attrname, "finishings-supported")) && | |
651 | enumvalue >= 3 && | |
652 | enumvalue <= (3 + (int)(sizeof(ipp_finishings) / sizeof(ipp_finishings[0])))) | |
653 | return (ipp_finishings[enumvalue - 3]); | |
654 | else if ((!strcmp(attrname, "job-collation-type") || | |
655 | !strcmp(attrname, "job-collation-type-actual")) && | |
656 | enumvalue >= 3 && | |
657 | enumvalue <= (3 + (int)(sizeof(ipp_job_collation_types) / | |
658 | sizeof(ipp_job_collation_types[0])))) | |
659 | return (ipp_job_collation_types[enumvalue - 3]); | |
660 | else if (!strcmp(attrname, "job-state") && | |
661 | enumvalue >= IPP_JOB_PENDING && enumvalue <= IPP_JOB_COMPLETED) | |
662 | return (ipp_job_states[enumvalue - IPP_JOB_PENDING]); | |
663 | else if (!strcmp(attrname, "operations-supported")) | |
664 | return (ippOpString((ipp_op_t)enumvalue)); | |
665 | else if ((!strcmp(attrname, "orientation-requested") || | |
666 | !strcmp(attrname, "orientation-requested-actual") || | |
667 | !strcmp(attrname, "orientation-requested-default") || | |
668 | !strcmp(attrname, "orientation-requested-supported")) && | |
669 | enumvalue >= 3 && | |
670 | enumvalue <= (3 + (int)(sizeof(ipp_orientation_requesteds) / | |
671 | sizeof(ipp_orientation_requesteds[0])))) | |
672 | return (ipp_orientation_requesteds[enumvalue - 3]); | |
673 | else if ((!strcmp(attrname, "print-quality") || | |
674 | !strcmp(attrname, "print-quality-actual") || | |
675 | !strcmp(attrname, "print-quality-default") || | |
676 | !strcmp(attrname, "print-quality-supported")) && | |
677 | enumvalue >= 3 && | |
678 | enumvalue <= (3 + (int)(sizeof(ipp_print_qualities) / | |
679 | sizeof(ipp_print_qualities[0])))) | |
680 | return (ipp_print_qualities[enumvalue - 3]); | |
681 | else if (!strcmp(attrname, "printer-state") && | |
682 | enumvalue >= IPP_PRINTER_IDLE && enumvalue <= IPP_PRINTER_STOPPED) | |
683 | return (ipp_printer_states[enumvalue - IPP_PRINTER_IDLE]); | |
684 | ||
685 | /* | |
686 | * Not a standard enum value, just return the decimal equivalent... | |
687 | */ | |
688 | ||
689 | snprintf(cg->ipp_unknown, sizeof(cg->ipp_unknown), "%d", enumvalue); | |
690 | return (cg->ipp_unknown); | |
691 | } | |
692 | ||
693 | ||
694 | /* | |
695 | * 'ippEnumValue()' - Return the value associated with a given enum string. | |
696 | */ | |
697 | ||
698 | int /* O - Enum value or -1 if unknown */ | |
699 | ippEnumValue(const char *attrname, /* I - Attribute name */ | |
700 | const char *enumstring) /* I - Enum string */ | |
701 | { | |
702 | int i, /* Looping var */ | |
703 | num_strings; /* Number of strings to compare */ | |
704 | const char * const *strings; /* Strings to compare */ | |
705 | ||
706 | ||
707 | /* | |
708 | * If the string is just a number, return it... | |
709 | */ | |
710 | ||
711 | if (isdigit(*enumstring & 255)) | |
712 | return (strtol(enumstring, NULL, 0)); | |
713 | ||
714 | /* | |
715 | * Otherwise look up the string... | |
716 | */ | |
717 | ||
718 | if (!strcmp(attrname, "document-state")) | |
719 | { | |
720 | num_strings = (int)(sizeof(ipp_document_states) / sizeof(ipp_document_states[0])); | |
721 | strings = ipp_document_states; | |
722 | } | |
723 | else if (!strcmp(attrname, "finishings") || | |
724 | !strcmp(attrname, "finishings-actual") || | |
725 | !strcmp(attrname, "finishings-default") || | |
726 | !strcmp(attrname, "finishings-ready") || | |
727 | !strcmp(attrname, "finishings-supported")) | |
728 | { | |
729 | num_strings = (int)(sizeof(ipp_finishings) / sizeof(ipp_finishings[0])); | |
730 | strings = ipp_finishings; | |
731 | } | |
732 | else if (!strcmp(attrname, "job-collation-type") || | |
733 | !strcmp(attrname, "job-collation-type-actual")) | |
734 | { | |
735 | num_strings = (int)(sizeof(ipp_job_collation_types) / | |
736 | sizeof(ipp_job_collation_types[0])); | |
737 | strings = ipp_job_collation_types; | |
738 | } | |
739 | else if (!strcmp(attrname, "job-state")) | |
740 | { | |
741 | num_strings = (int)(sizeof(ipp_job_states) / sizeof(ipp_job_states[0])); | |
742 | strings = ipp_job_states; | |
743 | } | |
744 | else if (!strcmp(attrname, "operations-supported")) | |
745 | return (ippOpValue(enumstring)); | |
746 | else if (!strcmp(attrname, "orientation-requested") || | |
747 | !strcmp(attrname, "orientation-requested-actual") || | |
748 | !strcmp(attrname, "orientation-requested-default") || | |
749 | !strcmp(attrname, "orientation-requested-supported")) | |
750 | { | |
751 | num_strings = (int)(sizeof(ipp_orientation_requesteds) / | |
752 | sizeof(ipp_orientation_requesteds[0])); | |
753 | strings = ipp_orientation_requesteds; | |
754 | } | |
755 | else if (!strcmp(attrname, "print-quality") || | |
756 | !strcmp(attrname, "print-quality-actual") || | |
757 | !strcmp(attrname, "print-quality-default") || | |
758 | !strcmp(attrname, "print-quality-supported")) | |
759 | { | |
760 | num_strings = (int)(sizeof(ipp_print_qualities) / sizeof(ipp_print_qualities[0])); | |
761 | strings = ipp_print_qualities; | |
762 | } | |
763 | else if (!strcmp(attrname, "printer-state")) | |
764 | { | |
765 | num_strings = (int)(sizeof(ipp_printer_states) / sizeof(ipp_printer_states[0])); | |
766 | strings = ipp_printer_states; | |
767 | } | |
768 | else | |
769 | return (-1); | |
770 | ||
771 | for (i = 0; i < num_strings; i ++) | |
772 | if (!strcmp(enumstring, strings[i])) | |
773 | return (i + 3); | |
774 | ||
775 | return (-1); | |
776 | } | |
777 | ||
778 | ||
ef416fc2 | 779 | /* |
780 | * 'ippErrorString()' - Return a name for the given status code. | |
781 | */ | |
782 | ||
783 | const char * /* O - Text string */ | |
784 | ippErrorString(ipp_status_t error) /* I - Error status */ | |
785 | { | |
786 | _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ | |
787 | ||
788 | ||
789 | /* | |
790 | * See if the error code is a known value... | |
791 | */ | |
792 | ||
bd7854cb | 793 | if (error >= IPP_OK && error <= IPP_OK_EVENTS_COMPLETE) |
ef416fc2 | 794 | return (ipp_status_oks[error]); |
795 | else if (error == IPP_REDIRECTION_OTHER_SITE) | |
796 | return ("redirection-other-site"); | |
b94498cf | 797 | else if (error == CUPS_SEE_OTHER) |
798 | return ("cups-see-other"); | |
ef416fc2 | 799 | else if (error >= IPP_BAD_REQUEST && error <= IPP_PRINT_SUPPORT_FILE_NOT_FOUND) |
800 | return (ipp_status_400s[error - IPP_BAD_REQUEST]); | |
801 | else if (error >= IPP_INTERNAL_ERROR && error <= IPP_PRINTER_IS_DEACTIVATED) | |
802 | return (ipp_status_500s[error - IPP_INTERNAL_ERROR]); | |
6c48a6ca MS |
803 | else if (error >= IPP_AUTHENTICATION_CANCELED && error <= IPP_UPGRADE_REQUIRED) |
804 | return (ipp_status_1000s[error - IPP_AUTHENTICATION_CANCELED]); | |
ef416fc2 | 805 | |
806 | /* | |
d7225fc2 | 807 | * No, build an "0xxxxx" error string... |
ef416fc2 | 808 | */ |
809 | ||
d7225fc2 | 810 | sprintf(cg->ipp_unknown, "0x%04x", error); |
ef416fc2 | 811 | |
812 | return (cg->ipp_unknown); | |
813 | } | |
814 | ||
815 | ||
816 | /* | |
817 | * 'ippErrorValue()' - Return a status code for the given name. | |
818 | * | |
426c6a59 | 819 | * @since CUPS 1.2/Mac OS X 10.5@ |
ef416fc2 | 820 | */ |
821 | ||
822 | ipp_status_t /* O - IPP status code */ | |
823 | ippErrorValue(const char *name) /* I - Name */ | |
824 | { | |
825 | int i; | |
826 | ||
827 | ||
828 | for (i = 0; i < (sizeof(ipp_status_oks) / sizeof(ipp_status_oks[0])); i ++) | |
88f9aafc | 829 | if (!_cups_strcasecmp(name, ipp_status_oks[i])) |
ef416fc2 | 830 | return ((ipp_status_t)i); |
831 | ||
88f9aafc | 832 | if (!_cups_strcasecmp(name, "redirection-other-site")) |
ef416fc2 | 833 | return (IPP_REDIRECTION_OTHER_SITE); |
834 | ||
88f9aafc | 835 | if (!_cups_strcasecmp(name, "cups-see-other")) |
b94498cf | 836 | return (CUPS_SEE_OTHER); |
837 | ||
ef416fc2 | 838 | for (i = 0; i < (sizeof(ipp_status_400s) / sizeof(ipp_status_400s[0])); i ++) |
88f9aafc | 839 | if (!_cups_strcasecmp(name, ipp_status_400s[i])) |
ef416fc2 | 840 | return ((ipp_status_t)(i + 0x400)); |
841 | ||
842 | for (i = 0; i < (sizeof(ipp_status_500s) / sizeof(ipp_status_500s[0])); i ++) | |
88f9aafc | 843 | if (!_cups_strcasecmp(name, ipp_status_500s[i])) |
ef416fc2 | 844 | return ((ipp_status_t)(i + 0x500)); |
845 | ||
7cf5915e | 846 | for (i = 0; i < (sizeof(ipp_status_1000s) / sizeof(ipp_status_1000s[0])); i ++) |
88f9aafc | 847 | if (!_cups_strcasecmp(name, ipp_status_1000s[i])) |
7cf5915e MS |
848 | return ((ipp_status_t)(i + 0x1000)); |
849 | ||
ef416fc2 | 850 | return ((ipp_status_t)-1); |
851 | } | |
852 | ||
853 | ||
854 | /* | |
855 | * 'ippOpString()' - Return a name for the given operation id. | |
856 | * | |
426c6a59 | 857 | * @since CUPS 1.2/Mac OS X 10.5@ |
ef416fc2 | 858 | */ |
859 | ||
860 | const char * /* O - Name */ | |
861 | ippOpString(ipp_op_t op) /* I - Operation ID */ | |
862 | { | |
863 | _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ | |
864 | ||
865 | ||
866 | /* | |
867 | * See if the operation ID is a known value... | |
868 | */ | |
869 | ||
aaf19ab0 | 870 | if (op >= IPP_PRINT_JOB && op <= IPP_CLOSE_JOB) |
ef416fc2 | 871 | return (ipp_std_ops[op]); |
872 | else if (op == IPP_PRIVATE) | |
873 | return ("windows-ext"); | |
b94498cf | 874 | else if (op >= CUPS_GET_DEFAULT && op <= CUPS_GET_PPD) |
ef416fc2 | 875 | return (ipp_cups_ops[op - CUPS_GET_DEFAULT]); |
2e4ff8af MS |
876 | else if (op == CUPS_GET_DOCUMENT) |
877 | return (ipp_cups_ops2[0]); | |
ef416fc2 | 878 | |
879 | /* | |
d7225fc2 | 880 | * No, build an "0xxxxx" operation string... |
ef416fc2 | 881 | */ |
882 | ||
9b66acc5 | 883 | sprintf(cg->ipp_unknown, "0x%04x", op); |
ef416fc2 | 884 | |
885 | return (cg->ipp_unknown); | |
886 | } | |
887 | ||
888 | ||
889 | /* | |
890 | * 'ippOpValue()' - Return an operation id for the given name. | |
891 | * | |
426c6a59 | 892 | * @since CUPS 1.2/Mac OS X 10.5@ |
ef416fc2 | 893 | */ |
894 | ||
895 | ipp_op_t /* O - Operation ID */ | |
896 | ippOpValue(const char *name) /* I - Textual name */ | |
897 | { | |
898 | int i; | |
899 | ||
900 | ||
9b66acc5 MS |
901 | if (!strncmp(name, "0x", 2)) |
902 | return ((ipp_op_t)strtol(name + 2, NULL, 16)); | |
903 | ||
ef416fc2 | 904 | for (i = 0; i < (sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])); i ++) |
88f9aafc | 905 | if (!_cups_strcasecmp(name, ipp_std_ops[i])) |
ef416fc2 | 906 | return ((ipp_op_t)i); |
907 | ||
88f9aafc | 908 | if (!_cups_strcasecmp(name, "windows-ext")) |
ef416fc2 | 909 | return (IPP_PRIVATE); |
910 | ||
911 | for (i = 0; i < (sizeof(ipp_cups_ops) / sizeof(ipp_cups_ops[0])); i ++) | |
88f9aafc | 912 | if (!_cups_strcasecmp(name, ipp_cups_ops[i])) |
ef416fc2 | 913 | return ((ipp_op_t)(i + 0x4001)); |
914 | ||
2e4ff8af | 915 | for (i = 0; i < (sizeof(ipp_cups_ops2) / sizeof(ipp_cups_ops2[0])); i ++) |
88f9aafc | 916 | if (!_cups_strcasecmp(name, ipp_cups_ops2[i])) |
2e4ff8af MS |
917 | return ((ipp_op_t)(i + 0x4027)); |
918 | ||
88f9aafc | 919 | if (!_cups_strcasecmp(name, "CUPS-Add-Class")) |
480ef0fe | 920 | return (CUPS_ADD_MODIFY_CLASS); |
921 | ||
88f9aafc | 922 | if (!_cups_strcasecmp(name, "CUPS-Add-Printer")) |
480ef0fe | 923 | return (CUPS_ADD_MODIFY_PRINTER); |
924 | ||
ef416fc2 | 925 | return ((ipp_op_t)-1); |
926 | } | |
927 | ||
928 | ||
929 | /* | |
930 | * 'ippPort()' - Return the default IPP port number. | |
931 | */ | |
932 | ||
933 | int /* O - Port number */ | |
934 | ippPort(void) | |
935 | { | |
ef416fc2 | 936 | _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ |
937 | ||
938 | ||
d09495fa | 939 | DEBUG_puts("ippPort()"); |
940 | ||
941 | if (!cg->ipp_port) | |
e07d4801 | 942 | _cupsSetDefaults(); |
d09495fa | 943 | |
e07d4801 | 944 | DEBUG_printf(("1ippPort: Returning %d...", cg->ipp_port)); |
d09495fa | 945 | |
ef416fc2 | 946 | return (cg->ipp_port); |
947 | } | |
948 | ||
949 | ||
950 | /* | |
951 | * 'ippSetPort()' - Set the default port number. | |
952 | */ | |
953 | ||
954 | void | |
955 | ippSetPort(int p) /* I - Port number to use */ | |
956 | { | |
e07d4801 | 957 | DEBUG_printf(("ippSetPort(p=%d)", p)); |
d09495fa | 958 | |
ef416fc2 | 959 | _cupsGlobals()->ipp_port = p; |
960 | } | |
961 | ||
962 | ||
963 | /* | |
1ff0402e MS |
964 | * 'ippTagString()' - Return the tag name corresponding to a tag value. |
965 | * | |
966 | * The returned names are defined in RFC 2911 and 3382. | |
967 | * | |
178cb736 | 968 | * @since CUPS 1.4/Mac OS X 10.6@ |
1ff0402e MS |
969 | */ |
970 | ||
971 | const char * /* O - Tag name */ | |
972 | ippTagString(ipp_tag_t tag) /* I - Tag value */ | |
973 | { | |
ed6e7faf MS |
974 | tag &= IPP_TAG_MASK; |
975 | ||
1ff0402e MS |
976 | if (tag < (ipp_tag_t)(sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0]))) |
977 | return (ipp_tag_names[tag]); | |
978 | else | |
979 | return ("UNKNOWN"); | |
980 | } | |
981 | ||
982 | ||
983 | /* | |
984 | * 'ippTagValue()' - Return the tag value corresponding to a tag name. | |
985 | * | |
986 | * The tag names are defined in RFC 2911 and 3382. | |
987 | * | |
178cb736 | 988 | * @since CUPS 1.4/Mac OS X 10.6@ |
1ff0402e MS |
989 | */ |
990 | ||
991 | ipp_tag_t /* O - Tag value */ | |
992 | ippTagValue(const char *name) /* I - Tag name */ | |
993 | { | |
994 | int i; /* Looping var */ | |
995 | ||
996 | ||
997 | for (i = 0; i < (sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])); i ++) | |
88f9aafc | 998 | if (!_cups_strcasecmp(name, ipp_tag_names[i])) |
1ff0402e MS |
999 | return ((ipp_tag_t)i); |
1000 | ||
88f9aafc | 1001 | if (!_cups_strcasecmp(name, "operation")) |
1ff0402e | 1002 | return (IPP_TAG_OPERATION); |
88f9aafc | 1003 | else if (!_cups_strcasecmp(name, "job")) |
1ff0402e | 1004 | return (IPP_TAG_JOB); |
88f9aafc | 1005 | else if (!_cups_strcasecmp(name, "printer")) |
1ff0402e | 1006 | return (IPP_TAG_PRINTER); |
88f9aafc | 1007 | else if (!_cups_strcasecmp(name, "unsupported")) |
5a6b583a | 1008 | return (IPP_TAG_UNSUPPORTED_GROUP); |
88f9aafc | 1009 | else if (!_cups_strcasecmp(name, "subscription")) |
1ff0402e | 1010 | return (IPP_TAG_SUBSCRIPTION); |
88f9aafc | 1011 | else if (!_cups_strcasecmp(name, "event")) |
5a6b583a | 1012 | return (IPP_TAG_EVENT_NOTIFICATION); |
88f9aafc | 1013 | else if (!_cups_strcasecmp(name, "language")) |
1ff0402e | 1014 | return (IPP_TAG_LANGUAGE); |
88f9aafc | 1015 | else if (!_cups_strcasecmp(name, "mimetype")) |
1ff0402e | 1016 | return (IPP_TAG_MIMETYPE); |
88f9aafc | 1017 | else if (!_cups_strcasecmp(name, "name")) |
1ff0402e | 1018 | return (IPP_TAG_NAME); |
88f9aafc | 1019 | else if (!_cups_strcasecmp(name, "text")) |
1ff0402e | 1020 | return (IPP_TAG_TEXT); |
88f9aafc | 1021 | else if (!_cups_strcasecmp(name, "begCollection")) |
5a6b583a | 1022 | return (IPP_TAG_BEGIN_COLLECTION); |
1ff0402e MS |
1023 | else |
1024 | return (IPP_TAG_ZERO); | |
1025 | } | |
1026 | ||
1027 | ||
1028 | /* | |
1106b00e MS |
1029 | * 'ipp_col_string()' - Convert a collection to a string. |
1030 | */ | |
1031 | ||
1032 | static size_t /* O - Number of bytes */ | |
1033 | ipp_col_string(ipp_t *col, /* I - Collection attribute */ | |
1034 | char *buffer, /* I - Buffer or NULL */ | |
1035 | size_t bufsize) /* I - Size of buffer */ | |
1036 | { | |
1037 | char *bufptr, /* Position in buffer */ | |
1038 | *bufend, /* End of buffer */ | |
9c80ffa2 | 1039 | prefix = '{', /* Prefix character */ |
1106b00e MS |
1040 | temp[256]; /* Temporary string */ |
1041 | ipp_attribute_t *attr; /* Current member attribute */ | |
1042 | ||
1043 | ||
1044 | bufptr = buffer; | |
1045 | bufend = buffer + bufsize - 1; | |
1046 | ||
1106b00e MS |
1047 | for (attr = col->attrs; attr; attr = attr->next) |
1048 | { | |
1049 | if (!attr->name) | |
1050 | continue; | |
1051 | ||
9c80ffa2 MS |
1052 | if (buffer && bufptr < bufend) |
1053 | *bufptr = prefix; | |
1054 | bufptr ++; | |
1055 | prefix = ' '; | |
1056 | ||
1106b00e MS |
1057 | if (buffer && bufptr < bufend) |
1058 | bufptr += snprintf(bufptr, bufend - bufptr + 1, "%s=", attr->name); | |
1059 | else | |
1060 | bufptr += strlen(attr->name) + 1; | |
1061 | ||
1062 | if (buffer && bufptr < bufend) | |
a2326b5b | 1063 | bufptr += ippAttributeString(attr, bufptr, bufend - bufptr + 1); |
1106b00e | 1064 | else |
a2326b5b | 1065 | bufptr += ippAttributeString(attr, temp, sizeof(temp)); |
1106b00e MS |
1066 | } |
1067 | ||
9c80ffa2 MS |
1068 | if (prefix == '{') |
1069 | { | |
1070 | if (buffer && bufptr < bufend) | |
1071 | *bufptr = prefix; | |
1072 | bufptr ++; | |
1073 | } | |
1074 | ||
1106b00e MS |
1075 | if (buffer && bufptr < bufend) |
1076 | *bufptr = '}'; | |
1077 | bufptr ++; | |
1078 | ||
1079 | return (bufptr - buffer); | |
1080 | } | |
1081 | ||
1082 | ||
1083 | /* | |
1084 | * End of "$Id: ipp-support.c 9371 2010-11-17 06:21:32Z mike $". | |
ef416fc2 | 1085 | */ |