Revert manifest to default one
[external/cups.git] / cups / ipp-support.c
1 /*
2  * "$Id: ipp-support.c 10108 2011-11-04 22:22:22Z mike $"
3  *
4  *   Internet Printing Protocol support functions for CUPS.
5  *
6  *   Copyright 2007-2011 by Apple Inc.
7  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
8  *
9  *   These coded instructions, statements, and computer programs are the
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/".
14  *
15  *   This file is subject to the Apple OS-Developed Software exception.
16  *
17  * Contents:
18  *
19  *   _ippAttrString() - Convert the attribute's value to a string.
20  *   ippErrorString() - Return a name for the given status code.
21  *   ippErrorValue()  - Return a status code for the given name.
22  *   ippOpString()    - Return a name for the given operation id.
23  *   ippOpValue()     - Return an operation id for the given name.
24  *   ippPort()        - Return the default IPP port number.
25  *   ippSetPort()     - Set the default port number.
26  *   ippTagString()   - Return the tag name corresponding to a tag value.
27  *   ippTagValue()    - Return the tag value corresponding to a tag name.
28  *   ipp_col_string() - Convert a collection to a string.
29  */
30
31 /*
32  * Include necessary headers...
33  */
34
35 #include "cups-private.h"
36
37
38 /*
39  * Local globals...
40  */
41
42 static const char * const ipp_status_oks[] =    /* "OK" status codes */
43                 {
44                   "successful-ok",
45                   "successful-ok-ignored-or-substituted-attributes",
46                   "successful-ok-conflicting-attributes",
47                   "successful-ok-ignored-subscriptions",
48                   "successful-ok-ignored-notifications",
49                   "successful-ok-too-many-events",
50                   "successful-ok-but-cancel-subscription",
51                   "successful-ok-events-complete"
52                 },
53                 * const ipp_status_400s[] =     /* Client errors */
54                 {
55                   "client-error-bad-request",
56                   "client-error-forbidden",
57                   "client-error-not-authenticated",
58                   "client-error-not-authorized",
59                   "client-error-not-possible",
60                   "client-error-timeout",
61                   "client-error-not-found",
62                   "client-error-gone",
63                   "client-error-request-entity-too-large",
64                   "client-error-request-value-too-long",
65                   "client-error-document-format-not-supported",
66                   "client-error-attributes-or-values-not-supported",
67                   "client-error-uri-scheme-not-supported",
68                   "client-error-charset-not-supported",
69                   "client-error-conflicting-attributes",
70                   "client-error-compression-not-supported",
71                   "client-error-compression-error",
72                   "client-error-document-format-error",
73                   "client-error-document-access-error",
74                   "client-error-attributes-not-settable",
75                   "client-error-ignored-all-subscriptions",
76                   "client-error-too-many-subscriptions",
77                   "client-error-ignored-all-notifications",
78                   "client-error-print-support-file-not-found"
79                 },
80                 * const ipp_status_500s[] =             /* Server errors */
81                 {
82                   "server-error-internal-error",
83                   "server-error-operation-not-supported",
84                   "server-error-service-unavailable",
85                   "server-error-version-not-supported",
86                   "server-error-device-error",
87                   "server-error-temporary-error",
88                   "server-error-not-accepting-jobs",
89                   "server-error-busy",
90                   "server-error-job-canceled",
91                   "server-error-multiple-document-jobs-not-supported",
92                   "server-error-printer-is-deactivated",
93                   "server-error-too-many-jobs",
94                   "server-error-too-many-documents"
95                 },
96                 * const ipp_status_1000s[] =            /* CUPS internal */
97                 {
98                   "cups-authorization-canceled",
99                   "cups-pki-error",
100                   "cups-upgrade-required"
101                 };
102 static char     * const ipp_std_ops[] =
103                 {
104                   /* 0x0000 - 0x000f */
105                   "0x00",
106                   "0x01",
107                   "Print-Job",
108                   "Print-URI",
109                   "Validate-Job",
110                   "Create-Job",
111                   "Send-Document",
112                   "Send-URI",
113                   "Cancel-Job",
114                   "Get-Job-Attributes",
115                   "Get-Jobs",
116                   "Get-Printer-Attributes",
117                   "Hold-Job",
118                   "Release-Job",
119                   "Restart-Job",
120                   "0x0f",
121
122                   /* 0x0010 - 0x001f */
123                   "Pause-Printer",
124                   "Resume-Printer",
125                   "Purge-Jobs",
126                   "Set-Printer-Attributes",
127                   "Set-Job-Attributes",
128                   "Get-Printer-Supported-Values",
129                   "Create-Printer-Subscription",
130                   "Create-Job-Subscription",
131                   "Get-Subscription-Attributes",
132                   "Get-Subscriptions",
133                   "Renew-Subscription",
134                   "Cancel-Subscription",
135                   "Get-Notifications",
136                   "Send-Notifications",
137                   "0x1e",
138                   "0x1f",
139
140                   /* 0x0020 - 0x002f */
141                   "0x20",
142                   "Get-Printer-Support-Files",
143                   "Enable-Printer",
144                   "Disable-Printer",
145                   "Pause-Printer-After-Current-Job",
146                   "Hold-New-Jobs",
147                   "Release-Held-New-Jobs",
148                   "Deactivate-Printer",
149                   "Activate-Printer",
150                   "Restart-Printer",
151                   "Shutdown-Printer",
152                   "Startup-Printer",
153                   "Reprocess-Job",
154                   "Cancel-Current-Job",
155                   "Suspend-Current-Job",
156                   "Resume-Job",
157
158                   /* 0x0030 - 0x003b */
159                   "Promote-Job",
160                   "Schedule-Job-After",
161                   "0x32",
162                   "Cancel-Document",
163                   "Get-Document-Attributes",
164                   "Get-Documents",
165                   "Delete-Document",
166                   "Set-Document-Attributes",
167                   "Cancel-Jobs",
168                   "Cancel-My-Jobs",
169                   "Resubmit-Job",
170                   "Close-Job",
171                   "Identify-Printer"
172                 },
173                 * const ipp_cups_ops[] =
174                 {
175                   "CUPS-Get-Default",
176                   "CUPS-Get-Printers",
177                   "CUPS-Add-Modify-Printer",
178                   "CUPS-Delete-Printer",
179                   "CUPS-Get-Classes",
180                   "CUPS-Add-Modify-Class",
181                   "CUPS-Delete-Class",
182                   "CUPS-Accept-Jobs",
183                   "CUPS-Reject-Jobs",
184                   "CUPS-Set-Default",
185                   "CUPS-Get-Devices",
186                   "CUPS-Get-PPDs",
187                   "CUPS-Move-Job",
188                   "CUPS-Authenticate-Job",
189                   "CUPS-Get-PPD"
190                 },
191                 * const ipp_cups_ops2[] =
192                 {
193                   "CUPS-Get-Document"
194                 },
195                 * const ipp_tag_names[] =
196                 {                       /* Value/group tag names */
197                   "zero",               /* 0x00 */
198                   "operation-attributes-tag",
199                                         /* 0x01 */
200                   "job-attributes-tag", /* 0x02 */
201                   "end-of-attributes-tag",
202                                         /* 0x03 */
203                   "printer-attributes-tag",
204                                         /* 0x04 */
205                   "unsupported-attributes-tag",
206                                         /* 0x05 */
207                   "subscription-attributes-tag",
208                                         /* 0x06 */
209                   "event-notification-attributes-tag",
210                                         /* 0x07 */
211                   "0x08",               /* 0x08 */
212                   "document-attributes-tag",
213                                         /* 0x09 */
214                   "0x0a",               /* 0x0a */
215                   "0x0b",               /* 0x0b */
216                   "0x0c",               /* 0x0c */
217                   "0x0d",               /* 0x0d */
218                   "0x0e",               /* 0x0e */
219                   "0x0f",               /* 0x0f */
220                   "unsupported",        /* 0x10 */
221                   "default",            /* 0x11 */
222                   "unknown",            /* 0x12 */
223                   "no-value",           /* 0x13 */
224                   "0x14",               /* 0x14 */
225                   "not-settable",       /* 0x15 */
226                   "delete-attribute",   /* 0x16 */
227                   "admin-define",       /* 0x17 */
228                   "0x18",               /* 0x18 */
229                   "0x19",               /* 0x19 */
230                   "0x1a",               /* 0x1a */
231                   "0x1b",               /* 0x1b */
232                   "0x1c",               /* 0x1c */
233                   "0x1d",               /* 0x1d */
234                   "0x1e",               /* 0x1e */
235                   "0x1f",               /* 0x1f */
236                   "0x20",               /* 0x20 */
237                   "integer",            /* 0x21 */
238                   "boolean",            /* 0x22 */
239                   "enum",               /* 0x23 */
240                   "0x24",               /* 0x24 */
241                   "0x25",               /* 0x25 */
242                   "0x26",               /* 0x26 */
243                   "0x27",               /* 0x27 */
244                   "0x28",               /* 0x28 */
245                   "0x29",               /* 0x29 */
246                   "0x2a",               /* 0x2a */
247                   "0x2b",               /* 0x2b */
248                   "0x2c",               /* 0x2c */
249                   "0x2d",               /* 0x2d */
250                   "0x2e",               /* 0x2e */
251                   "0x2f",               /* 0x2f */
252                   "octetString",        /* 0x30 */
253                   "dateTime",           /* 0x31 */
254                   "resolution",         /* 0x32 */
255                   "rangeOfInteger",     /* 0x33 */
256                   "collection",         /* 0x34 */
257                   "textWithLanguage",   /* 0x35 */
258                   "nameWithLanguage",   /* 0x36 */
259                   "endCollection",      /* 0x37 */
260                   "0x38",               /* 0x38 */
261                   "0x39",               /* 0x39 */
262                   "0x3a",               /* 0x3a */
263                   "0x3b",               /* 0x3b */
264                   "0x3c",               /* 0x3c */
265                   "0x3d",               /* 0x3d */
266                   "0x3e",               /* 0x3e */
267                   "0x3f",               /* 0x3f */
268                   "0x40",               /* 0x40 */
269                   "textWithoutLanguage",/* 0x41 */
270                   "nameWithoutLanguage",/* 0x42 */
271                   "0x43",               /* 0x43 */
272                   "keyword",            /* 0x44 */
273                   "uri",                /* 0x45 */
274                   "uriScheme",          /* 0x46 */
275                   "charset",            /* 0x47 */
276                   "naturalLanguage",    /* 0x48 */
277                   "mimeMediaType",      /* 0x49 */
278                   "memberAttrName"      /* 0x4a */
279                 };
280 static const char * const job_states[] =
281 {                                       /* job-state enums */
282   "pending",
283   "pending-held",
284   "processing",
285   "processing-stopped",
286   "canceled",
287   "aborted",
288   "completed"
289 };
290 static const char * const printer_states[] =
291 {                                       /* printer-state enums */
292   "idle",
293   "processing",
294   "stopped",
295 };
296
297
298 /*
299  * Local functions...
300  */
301
302 static size_t   ipp_col_string(ipp_t *col, char *buffer, size_t bufsize);
303
304
305 /*
306  * '_ippAttrString()' - Convert the attribute's value to a string.
307  *
308  * Returns the number of bytes that would be written, not including the
309  * trailing nul. The buffer pointer can be NULL to get the required length,
310  * just like (v)snprintf.
311  */
312
313 size_t                                  /* O - Number of bytes less nul */
314 _ippAttrString(ipp_attribute_t *attr,   /* I - Attribute */
315                char            *buffer, /* I - String buffer or NULL */
316                size_t          bufsize) /* I - Size of string buffer */
317 {
318   int           i;                      /* Looping var */
319   char          *bufptr,                /* Pointer into buffer */
320                 *bufend,                /* End of buffer */
321                 temp[256];              /* Temporary string */
322   const char    *ptr;                   /* Pointer into string */
323   ipp_value_t   *val;                   /* Current value */
324
325
326   if (!attr || !attr->name)
327   {
328     if (buffer)
329       *buffer = '\0';
330
331     return (0);
332   }
333
334   bufptr = buffer;
335   if (buffer)
336     bufend = buffer + bufsize - 1;
337   else
338     bufend = NULL;
339
340   for (i = attr->num_values, val = attr->values; i > 0; i --, val ++)
341   {
342     if (val > attr->values)
343     {
344       if (buffer && bufptr < bufend)
345         *bufptr++ = ',';
346       else
347         bufptr ++;
348     }
349
350     switch (attr->value_tag & ~IPP_TAG_COPY)
351     {
352       case IPP_TAG_ENUM :
353           if (!strcmp(attr->name, "printer-state") &&
354               val->integer >= IPP_PRINTER_IDLE &&
355               val->integer <= IPP_PRINTER_STOPPED)
356           {
357             ptr = printer_states[val->integer - IPP_PRINTER_IDLE];
358
359             if (buffer && bufptr < bufend)
360               strlcpy(bufptr, ptr, bufend - bufptr + 1);
361
362             bufptr += strlen(ptr);
363             break;
364           }
365           else if (!strcmp(attr->name, "job-state") &&
366                    val->integer >= IPP_JOB_PENDING &&
367                    val->integer <= IPP_JOB_COMPLETED)
368           {
369             ptr = job_states[val->integer - IPP_JOB_PENDING];
370
371             if (buffer && bufptr < bufend)
372               strlcpy(bufptr, ptr, bufend - bufptr + 1);
373
374             bufptr += strlen(ptr);
375             break;
376           }
377           else if (!strcmp(attr->name, "operations-supported"))
378           {
379             ptr = ippOpString(val->integer);
380
381             if (buffer && bufptr < bufend)
382               strlcpy(bufptr, ptr, bufend - bufptr + 1);
383
384             bufptr += strlen(ptr);
385             break;
386           }
387
388       case IPP_TAG_INTEGER :
389           if (buffer && bufptr < bufend)
390             bufptr += snprintf(bufptr, bufend - bufptr + 1, "%d", val->integer);
391           else
392             bufptr += snprintf(temp, sizeof(temp), "%d", val->integer);
393           break;
394
395       case IPP_TAG_BOOLEAN :
396           if (buffer && bufptr < bufend)
397             strlcpy(bufptr, val->boolean ? "true" : "false",
398                     bufend - bufptr + 1);
399
400           bufptr += val->boolean ? 4 : 5;
401           break;
402
403       case IPP_TAG_RANGE :
404           if (buffer && bufptr < bufend)
405             bufptr += snprintf(bufptr, bufend - bufptr + 1, "%d-%d",
406                                val->range.lower, val->range.upper);
407           else
408             bufptr += snprintf(temp, sizeof(temp), "%d-%d", val->range.lower,
409                                val->range.upper);
410           break;
411
412       case IPP_TAG_RESOLUTION :
413           if (buffer && bufptr < bufend)
414             bufptr += snprintf(bufptr, bufend - bufptr + 1, "%dx%d%s",
415                                val->resolution.xres, val->resolution.yres,
416                                val->resolution.units == IPP_RES_PER_INCH ?
417                                    "dpi" : "dpc");
418           else
419             bufptr += snprintf(temp, sizeof(temp), "%dx%d%s",
420                                val->resolution.xres, val->resolution.yres,
421                                val->resolution.units == IPP_RES_PER_INCH ?
422                                    "dpi" : "dpc");
423           break;
424
425       case IPP_TAG_DATE :
426           {
427             unsigned year;              /* Year */
428
429             year = (val->date[0] << 8) + val->date[1];
430
431             if (val->date[9] == 0 && val->date[10] == 0)
432               snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02uZ",
433                        year, val->date[2], val->date[3], val->date[4],
434                        val->date[5], val->date[6]);
435             else
436               snprintf(temp, sizeof(temp),
437                        "%04u-%02u-%02uT%02u:%02u:%02u%c%02u%02u",
438                        year, val->date[2], val->date[3], val->date[4],
439                        val->date[5], val->date[6], val->date[8], val->date[9],
440                        val->date[10]);
441
442             if (buffer && bufptr < bufend)
443               strlcpy(bufptr, temp, bufend - bufptr + 1);
444
445             bufptr += strlen(temp);
446           }
447           break;
448
449       case IPP_TAG_TEXT :
450       case IPP_TAG_NAME :
451       case IPP_TAG_KEYWORD :
452       case IPP_TAG_CHARSET :
453       case IPP_TAG_URI :
454       case IPP_TAG_URISCHEME :
455       case IPP_TAG_MIMETYPE :
456       case IPP_TAG_LANGUAGE :
457       case IPP_TAG_TEXTLANG :
458       case IPP_TAG_NAMELANG :
459           if (!val->string.text)
460             break;
461
462           for (ptr = val->string.text; *ptr; ptr ++)
463           {
464             if (*ptr == '\\' || *ptr == '\"')
465             {
466               if (buffer && bufptr < bufend)
467                 *bufptr = '\\';
468               bufptr ++;
469             }
470
471             if (buffer && bufptr < bufend)
472               *bufptr = *ptr;
473             bufptr ++;
474           }
475           break;
476
477       case IPP_TAG_BEGIN_COLLECTION :
478           if (buffer && bufptr < bufend)
479             bufptr += ipp_col_string(val->collection, bufptr,
480                                      bufend - bufptr + 1);
481           else
482             bufptr += ipp_col_string(val->collection, NULL, 0);
483           break;
484
485       case IPP_TAG_STRING :
486           for (ptr = val->string.text; *ptr; ptr ++)
487           {
488             if (*ptr == '\\' || _cups_isspace(*ptr))
489             {
490               if (buffer && bufptr < bufend)
491                 *bufptr = '\\';
492               bufptr ++;
493
494               if (buffer && bufptr < bufend)
495                 *bufptr = *ptr;
496               bufptr ++;
497             }
498             else if (!isprint(*ptr & 255))
499             {
500               if (buffer && bufptr < bufend)
501                 bufptr += snprintf(bufptr, bufend - bufptr + 1, "\\%03o",
502                                    *ptr & 255);
503               else
504                 bufptr += snprintf(temp, sizeof(temp), "\\%03o",
505                                    *ptr & 255);
506             }
507             else
508             {
509               if (buffer && bufptr < bufend)
510                 *bufptr = *ptr;
511               bufptr ++;
512             }
513           }
514           break;
515
516       default :
517           ptr = ippTagString(attr->value_tag);
518           if (buffer && bufptr < bufend)
519             strlcpy(bufptr, ptr, bufend - bufptr + 1);
520           bufptr += strlen(ptr);
521           break;
522     }
523   }
524
525   if (buffer && bufptr < bufend)
526     *bufptr = '\0';
527   else if (bufend)
528     *bufend = '\0';
529
530   return (bufptr - buffer);
531 }
532
533
534 /*
535  * 'ippErrorString()' - Return a name for the given status code.
536  */
537
538 const char *                            /* O - Text string */
539 ippErrorString(ipp_status_t error)      /* I - Error status */
540 {
541   _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
542
543
544  /*
545   * See if the error code is a known value...
546   */
547
548   if (error >= IPP_OK && error <= IPP_OK_EVENTS_COMPLETE)
549     return (ipp_status_oks[error]);
550   else if (error == IPP_REDIRECTION_OTHER_SITE)
551     return ("redirection-other-site");
552   else if (error == CUPS_SEE_OTHER)
553     return ("cups-see-other");
554   else if (error >= IPP_BAD_REQUEST && error <= IPP_PRINT_SUPPORT_FILE_NOT_FOUND)
555     return (ipp_status_400s[error - IPP_BAD_REQUEST]);
556   else if (error >= IPP_INTERNAL_ERROR && error <= IPP_PRINTER_IS_DEACTIVATED)
557     return (ipp_status_500s[error - IPP_INTERNAL_ERROR]);
558   else if (error >= IPP_AUTHENTICATION_CANCELED && error <= IPP_UPGRADE_REQUIRED)
559     return (ipp_status_1000s[error - IPP_AUTHENTICATION_CANCELED]);
560
561  /*
562   * No, build an "0xxxxx" error string...
563   */
564
565   sprintf(cg->ipp_unknown, "0x%04x", error);
566
567   return (cg->ipp_unknown);
568 }
569
570
571 /*
572  * 'ippErrorValue()' - Return a status code for the given name.
573  *
574  * @since CUPS 1.2/Mac OS X 10.5@
575  */
576
577 ipp_status_t                            /* O - IPP status code */
578 ippErrorValue(const char *name)         /* I - Name */
579 {
580   int           i;
581
582
583   for (i = 0; i < (sizeof(ipp_status_oks) / sizeof(ipp_status_oks[0])); i ++)
584     if (!_cups_strcasecmp(name, ipp_status_oks[i]))
585       return ((ipp_status_t)i);
586
587   if (!_cups_strcasecmp(name, "redirection-other-site"))
588     return (IPP_REDIRECTION_OTHER_SITE);
589
590   if (!_cups_strcasecmp(name, "cups-see-other"))
591     return (CUPS_SEE_OTHER);
592
593   for (i = 0; i < (sizeof(ipp_status_400s) / sizeof(ipp_status_400s[0])); i ++)
594     if (!_cups_strcasecmp(name, ipp_status_400s[i]))
595       return ((ipp_status_t)(i + 0x400));
596
597   for (i = 0; i < (sizeof(ipp_status_500s) / sizeof(ipp_status_500s[0])); i ++)
598     if (!_cups_strcasecmp(name, ipp_status_500s[i]))
599       return ((ipp_status_t)(i + 0x500));
600
601   for (i = 0; i < (sizeof(ipp_status_1000s) / sizeof(ipp_status_1000s[0])); i ++)
602     if (!_cups_strcasecmp(name, ipp_status_1000s[i]))
603       return ((ipp_status_t)(i + 0x1000));
604
605   return ((ipp_status_t)-1);
606 }
607
608
609 /*
610  * 'ippOpString()' - Return a name for the given operation id.
611  *
612  * @since CUPS 1.2/Mac OS X 10.5@
613  */
614
615 const char *                            /* O - Name */
616 ippOpString(ipp_op_t op)                /* I - Operation ID */
617 {
618   _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
619
620
621  /*
622   * See if the operation ID is a known value...
623   */
624
625   if (op >= IPP_PRINT_JOB && op <= IPP_CLOSE_JOB)
626     return (ipp_std_ops[op]);
627   else if (op == IPP_PRIVATE)
628     return ("windows-ext");
629   else if (op >= CUPS_GET_DEFAULT && op <= CUPS_GET_PPD)
630     return (ipp_cups_ops[op - CUPS_GET_DEFAULT]);
631   else if (op == CUPS_GET_DOCUMENT)
632     return (ipp_cups_ops2[0]);
633
634  /*
635   * No, build an "0xxxxx" operation string...
636   */
637
638   sprintf(cg->ipp_unknown, "0x%04x", op);
639
640   return (cg->ipp_unknown);
641 }
642
643
644 /*
645  * 'ippOpValue()' - Return an operation id for the given name.
646  *
647  * @since CUPS 1.2/Mac OS X 10.5@
648  */
649
650 ipp_op_t                                /* O - Operation ID */
651 ippOpValue(const char *name)            /* I - Textual name */
652 {
653   int           i;
654
655
656   if (!strncmp(name, "0x", 2))
657     return ((ipp_op_t)strtol(name + 2, NULL, 16));
658
659   for (i = 0; i < (sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])); i ++)
660     if (!_cups_strcasecmp(name, ipp_std_ops[i]))
661       return ((ipp_op_t)i);
662
663   if (!_cups_strcasecmp(name, "windows-ext"))
664     return (IPP_PRIVATE);
665
666   for (i = 0; i < (sizeof(ipp_cups_ops) / sizeof(ipp_cups_ops[0])); i ++)
667     if (!_cups_strcasecmp(name, ipp_cups_ops[i]))
668       return ((ipp_op_t)(i + 0x4001));
669
670   for (i = 0; i < (sizeof(ipp_cups_ops2) / sizeof(ipp_cups_ops2[0])); i ++)
671     if (!_cups_strcasecmp(name, ipp_cups_ops2[i]))
672       return ((ipp_op_t)(i + 0x4027));
673
674   if (!_cups_strcasecmp(name, "CUPS-Add-Class"))
675     return (CUPS_ADD_MODIFY_CLASS);
676
677   if (!_cups_strcasecmp(name, "CUPS-Add-Printer"))
678     return (CUPS_ADD_MODIFY_PRINTER);
679
680   return ((ipp_op_t)-1);
681 }
682
683
684 /*
685  * 'ippPort()' - Return the default IPP port number.
686  */
687
688 int                                     /* O - Port number */
689 ippPort(void)
690 {
691   _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
692
693
694   DEBUG_puts("ippPort()");
695
696   if (!cg->ipp_port)
697     _cupsSetDefaults();
698
699   DEBUG_printf(("1ippPort: Returning %d...", cg->ipp_port));
700
701   return (cg->ipp_port);
702 }
703
704
705 /*
706  * 'ippSetPort()' - Set the default port number.
707  */
708
709 void
710 ippSetPort(int p)                       /* I - Port number to use */
711 {
712   DEBUG_printf(("ippSetPort(p=%d)", p));
713
714   _cupsGlobals()->ipp_port = p;
715 }
716
717
718 /*
719  * 'ippTagString()' - Return the tag name corresponding to a tag value.
720  *
721  * The returned names are defined in RFC 2911 and 3382.
722  *
723  * @since CUPS 1.4/Mac OS X 10.6@
724  */
725
726 const char *                            /* O - Tag name */
727 ippTagString(ipp_tag_t tag)             /* I - Tag value */
728 {
729   tag &= IPP_TAG_MASK;
730
731   if (tag < (ipp_tag_t)(sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])))
732     return (ipp_tag_names[tag]);
733   else
734     return ("UNKNOWN");
735 }
736
737
738 /*
739  * 'ippTagValue()' - Return the tag value corresponding to a tag name.
740  *
741  * The tag names are defined in RFC 2911 and 3382.
742  *
743  * @since CUPS 1.4/Mac OS X 10.6@
744  */
745
746 ipp_tag_t                               /* O - Tag value */
747 ippTagValue(const char *name)           /* I - Tag name */
748 {
749   int   i;                              /* Looping var */
750
751
752   for (i = 0; i < (sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])); i ++)
753     if (!_cups_strcasecmp(name, ipp_tag_names[i]))
754       return ((ipp_tag_t)i);
755
756   if (!_cups_strcasecmp(name, "operation"))
757     return (IPP_TAG_OPERATION);
758   else if (!_cups_strcasecmp(name, "job"))
759     return (IPP_TAG_JOB);
760   else if (!_cups_strcasecmp(name, "printer"))
761     return (IPP_TAG_PRINTER);
762   else if (!_cups_strcasecmp(name, "unsupported"))
763     return (IPP_TAG_UNSUPPORTED_GROUP);
764   else if (!_cups_strcasecmp(name, "subscription"))
765     return (IPP_TAG_SUBSCRIPTION);
766   else if (!_cups_strcasecmp(name, "event"))
767     return (IPP_TAG_EVENT_NOTIFICATION);
768   else if (!_cups_strcasecmp(name, "language"))
769     return (IPP_TAG_LANGUAGE);
770   else if (!_cups_strcasecmp(name, "mimetype"))
771     return (IPP_TAG_MIMETYPE);
772   else if (!_cups_strcasecmp(name, "name"))
773     return (IPP_TAG_NAME);
774   else if (!_cups_strcasecmp(name, "text"))
775     return (IPP_TAG_TEXT);
776   else if (!_cups_strcasecmp(name, "begCollection"))
777     return (IPP_TAG_BEGIN_COLLECTION);
778   else
779     return (IPP_TAG_ZERO);
780 }
781
782
783 /*
784  * 'ipp_col_string()' - Convert a collection to a string.
785  */
786
787 static size_t                           /* O - Number of bytes */
788 ipp_col_string(ipp_t  *col,             /* I - Collection attribute */
789                char   *buffer,          /* I - Buffer or NULL */
790                size_t bufsize)          /* I - Size of buffer */
791 {
792   char                  *bufptr,        /* Position in buffer */
793                         *bufend,        /* End of buffer */
794                         temp[256];      /* Temporary string */
795   ipp_attribute_t       *attr;          /* Current member attribute */
796
797
798   bufptr = buffer;
799   bufend = buffer + bufsize - 1;
800
801   if (buffer && bufptr < bufend)
802     *bufptr = '{';
803   bufptr ++;
804
805   for (attr = col->attrs; attr; attr = attr->next)
806   {
807     if (!attr->name)
808       continue;
809
810     if (buffer && bufptr < bufend)
811       bufptr += snprintf(bufptr, bufend - bufptr + 1, "%s=", attr->name);
812     else
813       bufptr += strlen(attr->name) + 1;
814
815     if (buffer && bufptr < bufend)
816       bufptr += _ippAttrString(attr, bufptr, bufend - bufptr + 1);
817     else
818       bufptr += _ippAttrString(attr, temp, sizeof(temp));
819   }
820
821   if (buffer && bufptr < bufend)
822     *bufptr = '}';
823   bufptr ++;
824
825   return (bufptr - buffer);
826 }
827
828
829 /*
830  * End of "$Id: ipp-support.c 10108 2011-11-04 22:22:22Z mike $".
831  */