]>
git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/ipp-var.c
4 * IPP variable routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2005 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * ippGetAttributes() - Get the list of attributes that are needed
27 * by the template file.
28 * ippGetTemplateDir() - Get the templates directory...
29 * ippRewriteURL() - Rewrite a printer URI into a web browser URL...
30 * ippSetServerVersion() - Set the server name and CUPS version...
31 * ippSetCGIVars() - Set CGI variables from an IPP response.
35 * Include necessary headers...
42 * 'ippGetAttributes()' - Get the list of attributes that are needed
43 * by the template file.
47 ippGetAttributes(ipp_t
*request
, /* I - IPP request */
48 const char *directory
, /* I - Directory */
49 const char *tmpl
, /* I - Base filename */
50 const char *lang
) /* I - Language */
52 int num_attrs
; /* Number of attributes */
53 char *attrs
[1000]; /* Attributes */
54 int i
; /* Looping var */
55 char filename
[1024], /* Filename */
56 locale
[16]; /* Locale name */
57 FILE *in
; /* Input file */
58 int ch
; /* Character from file */
59 char name
[255], /* Name of variable */
60 *nameptr
; /* Pointer into name */
64 * Convert the language to a locale name...
69 for (i
= 0; lang
[i
] && i
< 15; i
++)
70 if (isalnum(lang
[i
] & 255))
71 locale
[i
] = tolower(lang
[i
]);
81 * See if we have a template file for this language...
84 snprintf(filename
, sizeof(filename
), "%s/%s/%s", directory
, locale
, tmpl
);
85 if (access(filename
, 0))
89 snprintf(filename
, sizeof(filename
), "%s/%s/%s", directory
, locale
, tmpl
);
90 if (access(filename
, 0))
91 snprintf(filename
, sizeof(filename
), "%s/%s", directory
, tmpl
);
95 * Open the template file...
98 if ((in
= fopen(filename
, "r")) == NULL
)
102 * Loop through the file adding attribute names as needed...
107 while ((ch
= getc(in
)) != EOF
)
110 else if (ch
== '{' && num_attrs
< (sizeof(attrs
) / sizeof(attrs
[0])))
116 for (nameptr
= name
; (ch
= getc(in
)) != EOF
;)
117 if (strchr("}]<>=! \t\n", ch
))
119 else if (nameptr
> name
&& ch
== '?')
121 else if (nameptr
< (name
+ sizeof(name
) - 1))
131 if (!strncmp(name
, "printer_state_history", 21))
132 strcpy(name
, "printer_state_history");
135 * Possibly add it to the list of attributes...
138 for (i
= 0; i
< num_attrs
; i
++)
139 if (!strcmp(attrs
[i
], name
))
144 attrs
[num_attrs
] = strdup(name
);
150 * If we have attributes, add a requested-attributes attribute to the
156 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
157 "requested-attributes", num_attrs
, NULL
, (const char **)attrs
);
159 for (i
= 0; i
< num_attrs
; i
++)
166 * 'ippGetTemplateDir()' - Get the templates directory...
169 char * /* O - Template directory */
170 ippGetTemplateDir(void)
172 const char *datadir
; /* CUPS_DATADIR env var */
173 static char templates
[1024] = ""; /* Template directory */
179 * Build the template directory pathname...
182 if ((datadir
= getenv("CUPS_DATADIR")) == NULL
)
183 datadir
= CUPS_DATADIR
;
185 snprintf(templates
, sizeof(templates
), "%s/templates", datadir
);
193 * 'ippRewriteURL()' - Rewrite a printer URI into a web browser URL...
196 char * /* O - New URL */
197 ippRewriteURL(const char *uri
, /* I - Current URI */
198 char *url
, /* O - New URL */
199 int urlsize
, /* I - Size of URL buffer */
200 const char *newresource
) /* I - Replacement resource */
202 char method
[HTTP_MAX_URI
],
203 userpass
[HTTP_MAX_URI
],
204 hostname
[HTTP_MAX_URI
],
205 rawresource
[HTTP_MAX_URI
],
206 resource
[HTTP_MAX_URI
],
207 /* URI components... */
208 *rawptr
, /* Pointer into rawresource */
209 *resptr
; /* Pointer into resource */
210 int port
; /* Port number */
211 static int ishttps
= -1; /* Using encryption? */
212 static const char *server
; /* Name of server */
213 static char servername
[1024];
214 /* Local server name */
215 static const char hexchars
[] = "0123456789ABCDEF";
216 /* Hexadecimal conversion characters */
220 * Check if we have been called before...
226 * No, initialize static vars for the conversion...
228 * First get the server name associated with the client interface as
229 * well as the locally configured hostname. We'll check *both* of
230 * these to see if the printer URL is local...
233 server
= getenv("SERVER_NAME");
234 gethostname(servername
, sizeof(servername
));
237 * Then flag whether we are using SSL on this connection...
240 ishttps
= getenv("HTTPS") != NULL
;
244 * Convert the URI to a URL...
247 httpSeparate(uri
, method
, userpass
, hostname
, &port
, rawresource
);
249 if (strcmp(method
, "ipp") == 0 ||
250 strcmp(method
, "http") == 0)
255 * Force the specified resource name instead of the one in the URL...
258 strlcpy(resource
, newresource
, sizeof(resource
));
263 * Rewrite the resource string so it doesn't contain any
267 for (rawptr
= rawresource
, resptr
= resource
; *rawptr
; rawptr
++)
268 if ((*rawptr
& 128) || *rawptr
== '%' || *rawptr
== ' ' ||
269 *rawptr
== '#' || *rawptr
== '?' ||
270 *rawptr
== '.') /* For MSIE */
272 if (resptr
< (resource
+ sizeof(resource
) - 3))
275 *resptr
++ = hexchars
[(*rawptr
>> 4) & 15];
276 *resptr
++ = hexchars
[*rawptr
& 15];
279 else if (resptr
< (resource
+ sizeof(resource
) - 1))
286 * Map local access to a local URI...
289 if (strcasecmp(hostname
, server
) == 0 ||
290 strcasecmp(hostname
, servername
) == 0)
293 * Make URI relative to the current server...
296 strlcpy(url
, resource
, urlsize
);
301 * Rewrite URI with HTTP/HTTPS scheme...
305 snprintf(url
, urlsize
, "%s://%s@%s:%d%s",
306 ishttps
? "https" : "http",
307 userpass
, hostname
, port
, resource
);
309 snprintf(url
, urlsize
, "%s://%s:%d%s",
310 ishttps
? "https" : "http",
311 hostname
, port
, resource
);
315 strlcpy(url
, uri
, urlsize
);
322 * 'ippSetServerVersion()' - Set the server name and CUPS version...
326 ippSetServerVersion(void)
328 cgiSetVariable("SERVER_NAME", getenv("SERVER_NAME"));
329 cgiSetVariable("REMOTE_USER", getenv("REMOTE_USER"));
330 cgiSetVariable("CUPS_VERSION", CUPS_SVERSION
);
333 setlocale(LC_TIME
, "");
339 * 'ippSetCGIVars()' - Set CGI variables from an IPP response.
342 int /* O - Maximum number of elements */
343 ippSetCGIVars(ipp_t
*response
, /* I - Response data to be copied... */
344 const char *filter_name
, /* I - Filter name */
345 const char *filter_value
, /* I - Filter value */
346 const char *prefix
, /* I - Prefix for name or NULL */
347 int parent_el
) /* I - Parent element number */
349 int element
; /* Element in CGI array */
350 ipp_attribute_t
*attr
, /* Attribute in response... */
351 *filter
; /* Filtering attribute */
352 int i
; /* Looping var */
353 char name
[1024], /* Name of attribute */
354 *nameptr
, /* Pointer into name */
355 value
[16384], /* Value(s) */
356 *valptr
; /* Pointer into value */
357 struct tm
*date
; /* Date information */
360 fprintf(stderr
, "DEBUG2: ippSetCGIVars(response=%p, filter_name=\"%s\", filter_value=\"%s\", prefix=\"%s\", parent_el=%d)\n",
361 response
, filter_name
, filter_value
, prefix
, parent_el
);
364 * Set common CGI template variables...
368 ippSetServerVersion();
371 * Loop through the attributes and set them for the template...
374 attr
= response
->attrs
;
377 while (attr
&& attr
->group_tag
== IPP_TAG_OPERATION
)
380 for (element
= parent_el
; attr
!= NULL
; attr
= attr
->next
, element
++)
383 * Copy attributes to a separator...
389 filter
!= NULL
&& filter
->group_tag
!= IPP_TAG_ZERO
;
390 filter
= filter
->next
)
391 if (filter
->name
&& !strcmp(filter
->name
, filter_name
) &&
392 (filter
->value_tag
== IPP_TAG_STRING
||
393 (filter
->value_tag
>= IPP_TAG_TEXTLANG
&&
394 filter
->value_tag
<= IPP_TAG_MIMETYPE
)) &&
395 filter
->values
[0].string
.text
!= NULL
&&
396 !strcasecmp(filter
->values
[0].string
.text
, filter_value
))
400 return (element
+ 1);
402 if (filter
->group_tag
== IPP_TAG_ZERO
)
410 for (; attr
!= NULL
&& attr
->group_tag
!= IPP_TAG_ZERO
; attr
= attr
->next
)
413 * Copy the attribute name, substituting "_" for "-"...
416 if (attr
->name
== NULL
)
421 snprintf(name
, sizeof(name
), "%s.", prefix
);
422 nameptr
= name
+ strlen(name
);
427 for (i
= 0; attr
->name
[i
] && nameptr
< (name
+ sizeof(name
) - 1); i
++)
428 if (attr
->name
[i
] == '-')
431 *nameptr
++ = attr
->name
[i
];
436 * Add "job_printer_name" variable if we have a "job_printer_uri"
440 if (!strcmp(name
, "job_printer_uri"))
442 if ((valptr
= strrchr(attr
->values
[0].string
.text
, '/')) == NULL
)
447 cgiSetArray("job_printer_name", element
, valptr
);
451 * Add "admin_uri" variable if we have a "printer_uri_supported"
455 if (!strcmp(name
, "printer_uri_supported"))
457 ippRewriteURL(attr
->values
[0].string
.text
, value
, sizeof(value
),
460 cgiSetArray("admin_uri", element
, value
);
467 value
[0] = '\0'; /* Initially an empty string */
468 valptr
= value
; /* Start at the beginning */
470 for (i
= 0; i
< attr
->num_values
; i
++)
473 strlcat(valptr
, ",", sizeof(value
) - (valptr
- value
));
475 valptr
+= strlen(valptr
);
477 switch (attr
->value_tag
)
479 case IPP_TAG_INTEGER
:
481 if (strncmp(name
, "time_at_", 8) == 0)
483 time_t t
; /* Temporary time value */
485 t
= (time_t)attr
->values
[i
].integer
;
486 date
= localtime(&t
);
488 strftime(valptr
, sizeof(value
) - (valptr
- value
),
489 CUPS_STRFTIME_FORMAT
, date
);
492 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
493 "%d", attr
->values
[i
].integer
);
496 case IPP_TAG_BOOLEAN
:
497 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
498 "%d", attr
->values
[i
].boolean
);
501 case IPP_TAG_NOVALUE
:
502 strlcat(valptr
, "novalue", sizeof(value
) - (valptr
- value
));
506 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
507 "%d-%d", attr
->values
[i
].range
.lower
,
508 attr
->values
[i
].range
.upper
);
511 case IPP_TAG_RESOLUTION
:
512 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
513 "%dx%d%s", attr
->values
[i
].resolution
.xres
,
514 attr
->values
[i
].resolution
.yres
,
515 attr
->values
[i
].resolution
.units
== IPP_RES_PER_INCH
?
520 if (strchr(attr
->values
[i
].string
.text
, ':') != NULL
)
526 ippRewriteURL(attr
->values
[i
].string
.text
, valptr
,
527 sizeof(value
) - (valptr
- value
), NULL
);
531 case IPP_TAG_STRING
:
534 case IPP_TAG_KEYWORD
:
535 case IPP_TAG_CHARSET
:
536 case IPP_TAG_LANGUAGE
:
537 case IPP_TAG_MIMETYPE
:
538 strlcat(valptr
, attr
->values
[i
].string
.text
,
539 sizeof(value
) - (valptr
- value
));
542 case IPP_TAG_BEGIN_COLLECTION
:
543 snprintf(value
, sizeof(value
), "%s%d", name
, i
+ 1);
544 ippSetCGIVars(attr
->values
[i
].collection
, filter_name
,
545 filter_value
, value
, element
);
549 break; /* anti-compiler-warning-code */
557 if (attr
->value_tag
!= IPP_TAG_BEGIN_COLLECTION
)
559 cgiSetArray(name
, element
, value
);
561 fprintf(stderr
, "DEBUG2: %s[%d]=\"%s\"\n", name
, element
, value
);
569 fprintf(stderr
, "DEBUG2: Returing %d from ippSetCGIVars()...\n", element
+ 1);
571 return (element
+ 1);