]>
git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/ipp-var.c
2 * "$Id: ipp-var.c 6889 2007-08-29 22:23:35Z mike $"
4 * CGI <-> IPP variable routines for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2008 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products.
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/".
17 * cgiGetAttributes() - Get the list of attributes that are needed
18 * by the template file.
19 * cgiGetIPPObjects() - Get the objects in an IPP response.
20 * cgiMoveJobs() - Move one or more jobs.
21 * cgiPrintTestPage() - Print a test page.
22 * cgiRewriteURL() - Rewrite a printer URI into a web browser URL...
23 * cgiSetIPPObjectVars() - Set CGI variables from an IPP object.
24 * cgiSetIPPVars() - Set CGI variables from an IPP response.
25 * cgiShowIPPError() - Show the last IPP error message.
26 * cgiShowJobs() - Show print jobs.
27 * cgiText() - Return localized text.
31 * Include necessary headers...
34 #include "cgi-private.h"
38 * 'cgiGetAttributes()' - Get the list of attributes that are needed
39 * by the template file.
43 cgiGetAttributes(ipp_t
*request
, /* I - IPP request */
44 const char *tmpl
) /* I - Base filename */
46 int num_attrs
; /* Number of attributes */
47 char *attrs
[1000]; /* Attributes */
48 int i
; /* Looping var */
49 char filename
[1024], /* Filename */
50 locale
[16]; /* Locale name */
51 const char *directory
, /* Directory */
53 FILE *in
; /* Input file */
54 int ch
; /* Character from file */
55 char name
[255], /* Name of variable */
56 *nameptr
; /* Pointer into name */
60 * Convert the language to a locale name...
63 if ((lang
= getenv("LANG")) != NULL
)
65 for (i
= 0; lang
[i
] && i
< 15; i
++)
66 if (isalnum(lang
[i
] & 255))
67 locale
[i
] = tolower(lang
[i
]);
77 * See if we have a template file for this language...
80 directory
= cgiGetTemplateDir();
82 snprintf(filename
, sizeof(filename
), "%s/%s/%s", directory
, locale
, tmpl
);
83 if (access(filename
, 0))
87 snprintf(filename
, sizeof(filename
), "%s/%s/%s", directory
, locale
, tmpl
);
88 if (access(filename
, 0))
89 snprintf(filename
, sizeof(filename
), "%s/%s", directory
, tmpl
);
93 * Open the template file...
96 if ((in
= fopen(filename
, "r")) == NULL
)
100 * Loop through the file adding attribute names as needed...
104 attrs
[0] = NULL
; /* Eliminate compiler warning */
106 while ((ch
= getc(in
)) != EOF
)
109 else if (ch
== '{' && num_attrs
< (sizeof(attrs
) / sizeof(attrs
[0])))
115 for (nameptr
= name
; (ch
= getc(in
)) != EOF
;)
116 if (strchr("}]<>=! \t\n", ch
))
118 else if (nameptr
> name
&& ch
== '?')
120 else if (nameptr
< (name
+ sizeof(name
) - 1))
130 if (!strncmp(name
, "printer_state_history", 21))
131 strcpy(name
, "printer_state_history");
134 * Possibly add it to the list of attributes...
137 for (i
= 0; i
< num_attrs
; i
++)
138 if (!strcmp(attrs
[i
], name
))
143 attrs
[num_attrs
] = strdup(name
);
149 * If we have attributes, add a requested-attributes attribute to the
155 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
156 "requested-attributes", num_attrs
, NULL
, (const char **)attrs
);
158 for (i
= 0; i
< num_attrs
; i
++)
167 * 'cgiGetIPPObjects()' - Get the objects in an IPP response.
170 cups_array_t
* /* O - Array of objects */
171 cgiGetIPPObjects(ipp_t
*response
, /* I - IPP response */
172 void *search
) /* I - Search filter */
174 int i
; /* Looping var */
175 cups_array_t
*objs
; /* Array of objects */
176 ipp_attribute_t
*attr
, /* Current attribute */
177 *first
; /* First attribute for object */
178 ipp_tag_t group
; /* Current group tag */
179 int add
; /* Add this object to the array? */
185 for (add
= 0, first
= NULL
, objs
= cupsArrayNew(NULL
, NULL
),
186 group
= IPP_TAG_ZERO
, attr
= response
->attrs
;
190 if (attr
->group_tag
!= group
)
192 group
= attr
->group_tag
;
194 if (group
!= IPP_TAG_ZERO
&& group
!= IPP_TAG_OPERATION
)
199 else if (add
&& first
)
201 cupsArrayAdd(objs
, first
);
208 if (attr
->name
&& attr
->group_tag
!= IPP_TAG_OPERATION
&& !add
)
213 * Add all objects if there is no search...
221 * Check the search string against the string and integer values.
224 switch (attr
->value_tag
)
226 case IPP_TAG_TEXTLANG
:
227 case IPP_TAG_NAMELANG
:
230 case IPP_TAG_KEYWORD
:
232 case IPP_TAG_MIMETYPE
:
233 for (i
= 0; !add
&& i
< attr
->num_values
; i
++)
234 if (cgiDoSearch(search
, attr
->values
[i
].string
.text
))
238 case IPP_TAG_INTEGER
:
239 for (i
= 0; !add
&& i
< attr
->num_values
; i
++)
241 char buf
[255]; /* Number buffer */
244 sprintf(buf
, "%d", attr
->values
[i
].integer
);
246 if (cgiDoSearch(search
, buf
))
259 cupsArrayAdd(objs
, first
);
266 * 'cgiMoveJobs()' - Move one or more jobs.
268 * At least one of dest or job_id must be non-zero/NULL.
272 cgiMoveJobs(http_t
*http
, /* I - Connection to server */
273 const char *dest
, /* I - Destination or NULL */
274 int job_id
) /* I - Job ID or 0 for all */
276 int i
; /* Looping var */
277 const char *user
; /* Username */
278 ipp_t
*request
, /* IPP request */
279 *response
; /* IPP response */
280 ipp_attribute_t
*attr
; /* Current attribute */
281 const char *name
; /* Destination name */
282 const char *job_printer_uri
; /* JOB_PRINTER_URI form variable */
283 char current_dest
[1024]; /* Current destination */
287 * See who is logged in...
290 if ((user
= getenv("REMOTE_USER")) == NULL
)
294 * See if the user has already selected a new destination...
297 if ((job_printer_uri
= cgiGetVariable("JOB_PRINTER_URI")) == NULL
)
300 * Make sure necessary form variables are set...
305 char temp
[255]; /* Temporary string */
308 sprintf(temp
, "%d", job_id
);
309 cgiSetVariable("JOB_ID", temp
);
313 cgiSetVariable("PRINTER_NAME", dest
);
316 * No new destination specified, show the user what the available
317 * printers/classes are...
323 * Get the current destination for job N...
326 char job_uri
[1024]; /* Job URI */
329 request
= ippNewRequest(IPP_GET_JOB_ATTRIBUTES
);
331 snprintf(job_uri
, sizeof(job_uri
), "ipp://localhost/jobs/%d", job_id
);
332 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "job-uri",
334 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
335 "requested-attributes", NULL
, "job-printer-uri");
337 if ((response
= cupsDoRequest(http
, request
, "/")) != NULL
)
339 if ((attr
= ippFindAttribute(response
, "job-printer-uri",
340 IPP_TAG_URI
)) != NULL
)
343 * Pull the name from the URI...
346 strlcpy(current_dest
, strrchr(attr
->values
[0].string
.text
, '/') + 1,
347 sizeof(current_dest
));
357 * Couldn't get the current destination...
360 cgiStartHTML(cgiText(_("Move Job")));
361 cgiShowIPPError(_("Unable to find destination for job!"));
368 * Get the list of available destinations...
371 request
= ippNewRequest(CUPS_GET_PRINTERS
);
373 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
374 "requested-attributes", NULL
, "printer-uri-supported");
376 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
,
377 "requesting-user-name", NULL
, user
);
379 if ((response
= cupsDoRequest(http
, request
, "/")) != NULL
)
381 for (i
= 0, attr
= ippFindAttribute(response
, "printer-uri-supported",
384 attr
= ippFindNextAttribute(response
, "printer-uri-supported",
388 * Pull the name from the URI...
391 name
= strrchr(attr
->values
[0].string
.text
, '/') + 1;
394 * If the name is not the same as the current destination, add it!
397 if (strcasecmp(name
, dest
))
399 cgiSetArray("JOB_PRINTER_URI", i
, attr
->values
[0].string
.text
);
400 cgiSetArray("JOB_PRINTER_NAME", i
, name
);
413 cgiStartHTML(cgiText(_("Move Job")));
415 cgiStartHTML(cgiText(_("Move All Jobs")));
417 cgiCopyTemplateLang("job-move.tmpl");
422 * Try moving the job or jobs...
425 char uri
[1024], /* Job/printer URI */
426 resource
[1024], /* Post resource */
427 refresh
[1024]; /* Refresh URL */
428 const char *job_printer_name
; /* New printer name */
431 request
= ippNewRequest(CUPS_MOVE_JOB
);
439 snprintf(resource
, sizeof(resource
), "/jobs/%d", job_id
);
441 snprintf(uri
, sizeof(uri
), "ipp://localhost/jobs/%d", job_id
);
442 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "job-uri",
448 * Move all active jobs on a destination...
451 snprintf(resource
, sizeof(resource
), "/%s/%s",
452 cgiGetVariable("SECTION"), dest
);
454 httpAssembleURIf(HTTP_URI_CODING_ALL
, uri
, sizeof(uri
), "ipp", NULL
,
455 "localhost", ippPort(), "/%s/%s",
456 cgiGetVariable("SECTION"), dest
);
457 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
461 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "job-printer-uri",
462 NULL
, job_printer_uri
);
464 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
,
465 "requesting-user-name", NULL
, user
);
467 ippDelete(cupsDoRequest(http
, request
, resource
));
470 * Show the results...
473 job_printer_name
= strrchr(job_printer_uri
, '/') + 1;
475 if (cupsLastError() <= IPP_OK_CONFLICT
)
477 cgiRewriteURL(job_printer_uri
, resource
, sizeof(resource
), NULL
);
478 cgiFormEncode(uri
, resource
, sizeof(uri
));
479 snprintf(refresh
, sizeof(refresh
), "2;URL=%s", uri
);
480 cgiSetVariable("refresh_page", refresh
);
484 cgiStartHTML(cgiText(_("Move Job")));
486 cgiStartHTML(cgiText(_("Move All Jobs")));
488 if (cupsLastError() > IPP_OK_CONFLICT
)
491 cgiShowIPPError(_("Unable to move job"));
493 cgiShowIPPError(_("Unable to move jobs"));
497 cgiSetVariable("JOB_PRINTER_NAME", job_printer_name
);
498 cgiCopyTemplateLang("job-moved.tmpl");
507 * 'cgiPrintTestPage()' - Print a test page.
511 cgiPrintTestPage(http_t
*http
, /* I - Connection to server */
512 const char *dest
) /* I - Destination printer/class */
514 ipp_t
*request
, /* IPP request */
515 *response
; /* IPP response */
516 char uri
[HTTP_MAX_URI
], /* Printer URI */
517 resource
[1024], /* POST resource path */
518 refresh
[1024], /* Refresh URL */
519 filename
[1024]; /* Test page filename */
520 const char *datadir
; /* CUPS_DATADIR env var */
521 const char *user
; /* Username */
525 * See who is logged in...
528 if ((user
= getenv("REMOTE_USER")) == NULL
)
532 * Locate the test page file...
535 if ((datadir
= getenv("CUPS_DATADIR")) == NULL
)
536 datadir
= CUPS_DATADIR
;
538 snprintf(filename
, sizeof(filename
), "%s/data/testprint.ps", datadir
);
541 * Point to the printer/class...
544 snprintf(resource
, sizeof(resource
), "/%s/%s", cgiGetVariable("SECTION"),
547 httpAssembleURIf(HTTP_URI_CODING_ALL
, uri
, sizeof(uri
), "ipp", NULL
,
548 "localhost", ippPort(), "/%s/%s", cgiGetVariable("SECTION"),
552 * Build an IPP_PRINT_JOB request, which requires the following
556 * attributes-natural-language
558 * requesting-user-name
562 request
= ippNewRequest(IPP_PRINT_JOB
);
564 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
567 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
,
568 "requesting-user-name", NULL
, user
);
570 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "job-name",
573 ippAddString(request
, IPP_TAG_JOB
, IPP_TAG_MIMETYPE
, "document-format",
574 NULL
, "application/postscript");
577 * Do the request and get back a response...
580 if ((response
= cupsDoFileRequest(http
, request
, resource
,
583 cgiSetIPPVars(response
, NULL
, NULL
, NULL
, 0);
588 if (cupsLastError() <= IPP_OK_CONFLICT
)
591 * Automatically reload the printer status page...
594 cgiFormEncode(uri
, resource
, sizeof(uri
));
595 snprintf(refresh
, sizeof(refresh
), "2;URL=%s", uri
);
596 cgiSetVariable("refresh_page", refresh
);
599 cgiStartHTML(cgiText(_("Print Test Page")));
601 if (cupsLastError() > IPP_OK_CONFLICT
)
602 cgiShowIPPError(_("Unable to print test page:"));
605 cgiSetVariable("PRINTER_NAME", dest
);
607 cgiCopyTemplateLang("test-page.tmpl");
615 * 'cgiRewriteURL()' - Rewrite a printer URI into a web browser URL...
618 char * /* O - New URL */
619 cgiRewriteURL(const char *uri
, /* I - Current URI */
620 char *url
, /* O - New URL */
621 int urlsize
, /* I - Size of URL buffer */
622 const char *newresource
) /* I - Replacement resource */
624 char method
[HTTP_MAX_URI
],
625 userpass
[HTTP_MAX_URI
],
626 hostname
[HTTP_MAX_URI
],
627 rawresource
[HTTP_MAX_URI
],
628 resource
[HTTP_MAX_URI
],
629 /* URI components... */
630 *rawptr
, /* Pointer into rawresource */
631 *resptr
; /* Pointer into resource */
632 int port
; /* Port number */
633 static int ishttps
= -1; /* Using encryption? */
634 static const char *server
; /* Name of server */
635 static char servername
[1024];
636 /* Local server name */
637 static const char hexchars
[] = "0123456789ABCDEF";
638 /* Hexadecimal conversion characters */
642 * Check if we have been called before...
648 * No, initialize static vars for the conversion...
650 * First get the server name associated with the client interface as
651 * well as the locally configured hostname. We'll check *both* of
652 * these to see if the printer URL is local...
655 if ((server
= getenv("SERVER_NAME")) == NULL
)
658 httpGetHostname(NULL
, servername
, sizeof(servername
));
661 * Then flag whether we are using SSL on this connection...
664 ishttps
= getenv("HTTPS") != NULL
;
668 * Convert the URI to a URL...
671 httpSeparateURI(HTTP_URI_CODING_ALL
, uri
, method
, sizeof(method
), userpass
,
672 sizeof(userpass
), hostname
, sizeof(hostname
), &port
,
673 rawresource
, sizeof(rawresource
));
675 if (!strcmp(method
, "ipp") ||
676 !strcmp(method
, "http") ||
677 !strcmp(method
, "https"))
682 * Force the specified resource name instead of the one in the URL...
685 strlcpy(resource
, newresource
, sizeof(resource
));
690 * Rewrite the resource string so it doesn't contain any
694 for (rawptr
= rawresource
, resptr
= resource
; *rawptr
; rawptr
++)
695 if ((*rawptr
& 128) || *rawptr
== '%' || *rawptr
== ' ' ||
696 *rawptr
== '#' || *rawptr
== '?' ||
697 *rawptr
== '.') /* For MSIE */
699 if (resptr
< (resource
+ sizeof(resource
) - 3))
702 *resptr
++ = hexchars
[(*rawptr
>> 4) & 15];
703 *resptr
++ = hexchars
[*rawptr
& 15];
706 else if (resptr
< (resource
+ sizeof(resource
) - 1))
713 * Map local access to a local URI...
716 if (!strcasecmp(hostname
, "localhost") ||
717 !strncasecmp(hostname
, "localhost.", 10) ||
718 !strcasecmp(hostname
, server
) ||
719 !strcasecmp(hostname
, servername
))
722 * Make URI relative to the current server...
725 strlcpy(url
, resource
, urlsize
);
730 * Rewrite URI with HTTP/HTTPS scheme...
734 snprintf(url
, urlsize
, "%s://%s@%s:%d%s",
735 ishttps
? "https" : "http",
736 userpass
, hostname
, port
, resource
);
738 snprintf(url
, urlsize
, "%s://%s:%d%s",
739 ishttps
? "https" : "http",
740 hostname
, port
, resource
);
744 strlcpy(url
, uri
, urlsize
);
751 * 'cgiSetIPPObjectVars()' - Set CGI variables from an IPP object.
754 ipp_attribute_t
* /* O - Next object */
756 ipp_attribute_t
*obj
, /* I - Response data to be copied... */
757 const char *prefix
, /* I - Prefix for name or NULL */
758 int element
) /* I - Parent element number */
760 ipp_attribute_t
*attr
; /* Attribute in response... */
761 int i
; /* Looping var */
762 char name
[1024], /* Name of attribute */
763 *nameptr
, /* Pointer into name */
764 value
[16384], /* Value(s) */
765 *valptr
; /* Pointer into value */
766 struct tm
*date
; /* Date information */
769 fprintf(stderr
, "DEBUG2: cgiSetIPPObjectVars(obj=%p, prefix=\"%s\", "
771 obj
, prefix
? prefix
: "(null)", element
);
774 * Set common CGI template variables...
778 cgiSetServerVersion();
781 * Loop through the attributes and set them for the template...
784 for (attr
= obj
; attr
&& attr
->group_tag
!= IPP_TAG_ZERO
; attr
= attr
->next
)
787 * Copy the attribute name, substituting "_" for "-"...
795 snprintf(name
, sizeof(name
), "%s.", prefix
);
796 nameptr
= name
+ strlen(name
);
801 for (i
= 0; attr
->name
[i
] && nameptr
< (name
+ sizeof(name
) - 1); i
++)
802 if (attr
->name
[i
] == '-')
805 *nameptr
++ = attr
->name
[i
];
810 * Add "job_printer_name" variable if we have a "job_printer_uri"
814 if (!strcmp(name
, "job_printer_uri"))
816 if ((valptr
= strrchr(attr
->values
[0].string
.text
, '/')) == NULL
)
821 cgiSetArray("job_printer_name", element
, valptr
);
825 * Localize event names in "notify_events" variable...
828 if (!strcmp(name
, "notify_events"))
830 size_t remaining
; /* Remaining bytes in buffer */
836 for (i
= 0; i
< attr
->num_values
; i
++)
838 if (valptr
>= (value
+ sizeof(value
) - 3))
847 remaining
= sizeof(value
) - (valptr
- value
);
849 if (!strcmp(attr
->values
[i
].string
.text
, "printer-stopped"))
850 strlcpy(valptr
, _("Printer Paused"), remaining
);
851 else if (!strcmp(attr
->values
[i
].string
.text
, "printer-added"))
852 strlcpy(valptr
, _("Printer Added"), remaining
);
853 else if (!strcmp(attr
->values
[i
].string
.text
, "printer-modified"))
854 strlcpy(valptr
, _("Printer Modified"), remaining
);
855 else if (!strcmp(attr
->values
[i
].string
.text
, "printer-deleted"))
856 strlcpy(valptr
, _("Printer Deleted"), remaining
);
857 else if (!strcmp(attr
->values
[i
].string
.text
, "job-created"))
858 strlcpy(valptr
, _("Job Created"), remaining
);
859 else if (!strcmp(attr
->values
[i
].string
.text
, "job-completed"))
860 strlcpy(valptr
, _("Job Completed"), remaining
);
861 else if (!strcmp(attr
->values
[i
].string
.text
, "job-stopped"))
862 strlcpy(valptr
, _("Job Stopped"), remaining
);
863 else if (!strcmp(attr
->values
[i
].string
.text
, "job-config-changed"))
864 strlcpy(valptr
, _("Job Options Changed"), remaining
);
865 else if (!strcmp(attr
->values
[i
].string
.text
, "server-restarted"))
866 strlcpy(valptr
, _("Server Restarted"), remaining
);
867 else if (!strcmp(attr
->values
[i
].string
.text
, "server-started"))
868 strlcpy(valptr
, _("Server Started"), remaining
);
869 else if (!strcmp(attr
->values
[i
].string
.text
, "server-stopped"))
870 strlcpy(valptr
, _("Server Stopped"), remaining
);
871 else if (!strcmp(attr
->values
[i
].string
.text
, "server-audit"))
872 strlcpy(valptr
, _("Server Security Auditing"), remaining
);
874 strlcpy(valptr
, attr
->values
[i
].string
.text
, remaining
);
876 valptr
+= strlen(valptr
);
879 cgiSetArray("notify_events", element
, value
);
884 * Add "notify_printer_name" variable if we have a "notify_printer_uri"
888 if (!strcmp(name
, "notify_printer_uri"))
890 if ((valptr
= strrchr(attr
->values
[0].string
.text
, '/')) == NULL
)
895 cgiSetArray("notify_printer_name", element
, valptr
);
899 * Add "notify_recipient_name" variable if we have a "notify_recipient_uri"
900 * attribute, and rewrite recipient URI...
903 if (!strcmp(name
, "notify_recipient_uri"))
905 char uri
[1024], /* New URI */
906 scheme
[32], /* Scheme portion of URI */
907 userpass
[256], /* Username/password portion of URI */
908 host
[1024], /* Hostname portion of URI */
909 resource
[1024], /* Resource portion of URI */
910 *options
; /* Options in URI */
911 int port
; /* Port number */
914 httpSeparateURI(HTTP_URI_CODING_ALL
, attr
->values
[0].string
.text
,
915 scheme
, sizeof(scheme
), userpass
, sizeof(userpass
),
916 host
, sizeof(host
), &port
, resource
, sizeof(resource
));
918 if (!strcmp(scheme
, "rss"))
921 * RSS notification...
924 if ((options
= strchr(resource
, '?')) != NULL
)
930 * Link to remote feed...
933 httpAssembleURI(HTTP_URI_CODING_ALL
, uri
, sizeof(uri
), "http",
934 userpass
, host
, port
, resource
);
935 strlcpy(name
, uri
, sizeof(name
));
940 * Link to local feed...
943 snprintf(uri
, sizeof(uri
), "/rss%s", resource
);
944 strlcpy(name
, resource
+ 1, sizeof(name
));
953 strlcpy(uri
, attr
->values
[0].string
.text
, sizeof(uri
));
954 strlcpy(name
, resource
, sizeof(name
));
957 cgiSetArray("notify_recipient_uri", element
, uri
);
958 cgiSetArray("notify_recipient_name", element
, name
);
963 * Add "admin_uri" variable if we have a "printer_uri_supported"
967 if (!strcmp(name
, "printer_uri_supported"))
969 cgiRewriteURL(attr
->values
[0].string
.text
, value
, sizeof(value
),
972 cgiSetArray("admin_uri", element
, value
);
979 value
[0] = '\0'; /* Initially an empty string */
980 valptr
= value
; /* Start at the beginning */
982 for (i
= 0; i
< attr
->num_values
; i
++)
985 strlcat(valptr
, ", ", sizeof(value
) - (valptr
- value
));
987 valptr
+= strlen(valptr
);
989 switch (attr
->value_tag
)
991 case IPP_TAG_INTEGER
:
993 if (strncmp(name
, "time_at_", 8) == 0)
995 time_t t
; /* Temporary time value */
997 t
= (time_t)attr
->values
[i
].integer
;
998 date
= localtime(&t
);
1000 strftime(valptr
, sizeof(value
) - (valptr
- value
), "%c", date
);
1003 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1004 "%d", attr
->values
[i
].integer
);
1007 case IPP_TAG_BOOLEAN
:
1008 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1009 "%d", attr
->values
[i
].boolean
);
1012 case IPP_TAG_NOVALUE
:
1013 strlcat(valptr
, "novalue", sizeof(value
) - (valptr
- value
));
1016 case IPP_TAG_RANGE
:
1017 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1018 "%d-%d", attr
->values
[i
].range
.lower
,
1019 attr
->values
[i
].range
.upper
);
1022 case IPP_TAG_RESOLUTION
:
1023 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1024 "%dx%d%s", attr
->values
[i
].resolution
.xres
,
1025 attr
->values
[i
].resolution
.yres
,
1026 attr
->values
[i
].resolution
.units
== IPP_RES_PER_INCH
?
1031 if (strchr(attr
->values
[i
].string
.text
, ':') &&
1032 strcmp(name
, "device_uri"))
1038 if (!strcmp(name
, "member_uris"))
1040 char url
[1024]; /* URL for class member... */
1043 cgiRewriteURL(attr
->values
[i
].string
.text
, url
,
1046 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1047 "<A HREF=\"%s\">%s</A>", url
,
1048 strrchr(attr
->values
[i
].string
.text
, '/') + 1);
1051 cgiRewriteURL(attr
->values
[i
].string
.text
, valptr
,
1052 sizeof(value
) - (valptr
- value
), NULL
);
1056 case IPP_TAG_STRING
:
1059 case IPP_TAG_KEYWORD
:
1060 case IPP_TAG_CHARSET
:
1061 case IPP_TAG_LANGUAGE
:
1062 case IPP_TAG_MIMETYPE
:
1063 strlcat(valptr
, attr
->values
[i
].string
.text
,
1064 sizeof(value
) - (valptr
- value
));
1067 case IPP_TAG_BEGIN_COLLECTION
:
1068 snprintf(value
, sizeof(value
), "%s%d", name
, i
+ 1);
1069 cgiSetIPPVars(attr
->values
[i
].collection
, NULL
, NULL
, value
,
1074 break; /* anti-compiler-warning-code */
1079 * Add the element...
1082 if (attr
->value_tag
!= IPP_TAG_BEGIN_COLLECTION
)
1084 cgiSetArray(name
, element
, value
);
1086 fprintf(stderr
, "DEBUG2: %s[%d]=\"%s\"\n", name
, element
, value
);
1090 return (attr
? attr
->next
: NULL
);
1095 * 'cgiSetIPPVars()' - Set CGI variables from an IPP response.
1098 int /* O - Maximum number of elements */
1099 cgiSetIPPVars(ipp_t
*response
, /* I - Response data to be copied... */
1100 const char *filter_name
, /* I - Filter name */
1101 const char *filter_value
, /* I - Filter value */
1102 const char *prefix
, /* I - Prefix for name or NULL */
1103 int parent_el
) /* I - Parent element number */
1105 int element
; /* Element in CGI array */
1106 ipp_attribute_t
*attr
, /* Attribute in response... */
1107 *filter
; /* Filtering attribute */
1110 fprintf(stderr
, "DEBUG2: cgiSetIPPVars(response=%p, filter_name=\"%s\", "
1111 "filter_value=\"%s\", prefix=\"%s\", parent_el=%d)\n",
1112 response
, filter_name
? filter_name
: "(null)",
1113 filter_value
? filter_value
: "(null)",
1114 prefix
? prefix
: "(null)", parent_el
);
1117 * Set common CGI template variables...
1121 cgiSetServerVersion();
1124 * Loop through the attributes and set them for the template...
1127 attr
= response
->attrs
;
1130 while (attr
&& attr
->group_tag
== IPP_TAG_OPERATION
)
1133 for (element
= parent_el
; attr
; element
++)
1136 * Copy attributes to a separator...
1139 while (attr
&& attr
->group_tag
== IPP_TAG_ZERO
)
1148 filter
!= NULL
&& filter
->group_tag
!= IPP_TAG_ZERO
;
1149 filter
= filter
->next
)
1150 if (filter
->name
&& !strcmp(filter
->name
, filter_name
) &&
1151 (filter
->value_tag
== IPP_TAG_STRING
||
1152 (filter
->value_tag
>= IPP_TAG_TEXTLANG
&&
1153 filter
->value_tag
<= IPP_TAG_MIMETYPE
)) &&
1154 filter
->values
[0].string
.text
!= NULL
&&
1155 !strcasecmp(filter
->values
[0].string
.text
, filter_value
))
1159 return (element
+ 1);
1161 if (filter
->group_tag
== IPP_TAG_ZERO
)
1169 attr
= cgiSetIPPObjectVars(attr
, prefix
, element
);
1172 fprintf(stderr
, "DEBUG2: Returing %d from cgiSetIPPVars()...\n", element
);
1179 * 'cgiShowIPPError()' - Show the last IPP error message.
1181 * The caller must still call cgiStartHTML() and cgiEndHTML().
1185 cgiShowIPPError(const char *message
) /* I - Contextual message */
1187 cgiSetVariable("MESSAGE", cgiText(message
));
1188 cgiSetVariable("ERROR", cupsLastErrorString());
1189 cgiCopyTemplateLang("error.tmpl");
1194 * 'cgiShowJobs()' - Show print jobs.
1198 cgiShowJobs(http_t
*http
, /* I - Connection to server */
1199 const char *dest
) /* I - Destination name or NULL */
1201 int i
; /* Looping var */
1202 const char *which_jobs
; /* Which jobs to show */
1203 ipp_t
*request
, /* IPP request */
1204 *response
; /* IPP response */
1205 cups_array_t
*jobs
; /* Array of job objects */
1206 ipp_attribute_t
*job
; /* Job object */
1207 int ascending
, /* Order of jobs (0 = descending) */
1208 first
, /* First job to show */
1209 count
; /* Number of jobs */
1210 const char *var
; /* Form variable */
1211 void *search
; /* Search data */
1212 char url
[1024], /* Printer URI */
1213 val
[1024]; /* Form variable */
1217 * Build an IPP_GET_JOBS request, which requires the following
1220 * attributes-charset
1221 * attributes-natural-language
1225 request
= ippNewRequest(IPP_GET_JOBS
);
1229 httpAssembleURIf(HTTP_URI_CODING_ALL
, url
, sizeof(url
), "ipp", NULL
,
1230 "localhost", ippPort(), "/printers/%s", dest
);
1231 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
1235 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "job-uri", NULL
,
1236 "ipp://localhost/jobs");
1238 if ((which_jobs
= cgiGetVariable("which_jobs")) != NULL
)
1239 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
, "which-jobs",
1242 cgiGetAttributes(request
, "jobs.tmpl");
1245 * Do the request and get back a response...
1248 if ((response
= cupsDoRequest(http
, request
, "/")) != NULL
)
1251 * Get a list of matching job objects.
1254 if ((var
= cgiGetVariable("QUERY")) != NULL
&&
1255 !cgiGetVariable("CLEAR"))
1256 search
= cgiCompileSearch(var
);
1260 jobs
= cgiGetIPPObjects(response
, search
);
1261 count
= cupsArrayCount(jobs
);
1264 cgiFreeSearch(search
);
1267 * Figure out which jobs to display...
1270 if ((var
= cgiGetVariable("FIRST")) != NULL
)
1276 first
= count
- CUPS_PAGE_MAX
;
1278 first
= (first
/ CUPS_PAGE_MAX
) * CUPS_PAGE_MAX
;
1283 sprintf(val
, "%d", count
);
1284 cgiSetVariable("TOTAL", val
);
1286 if ((var
= cgiGetVariable("ORDER")) != NULL
)
1287 ascending
= !strcasecmp(var
, "asc");
1290 ascending
= !which_jobs
|| !strcasecmp(which_jobs
, "not-completed");
1291 cgiSetVariable("ORDER", ascending
? "asc" : "dec");
1296 for (i
= 0, job
= (ipp_attribute_t
*)cupsArrayIndex(jobs
, first
);
1297 i
< CUPS_PAGE_MAX
&& job
;
1298 i
++, job
= (ipp_attribute_t
*)cupsArrayNext(jobs
))
1299 cgiSetIPPObjectVars(job
, NULL
, i
);
1303 for (i
= 0, job
= (ipp_attribute_t
*)cupsArrayIndex(jobs
, count
- first
- 1);
1304 i
< CUPS_PAGE_MAX
&& job
;
1305 i
++, job
= (ipp_attribute_t
*)cupsArrayPrev(jobs
))
1306 cgiSetIPPObjectVars(job
, NULL
, i
);
1310 * Save navigation URLs...
1314 snprintf(val
, sizeof(val
), "/%s/%s", cgiGetVariable("SECTION"), dest
);
1316 strlcpy(val
, "/jobs/", sizeof(val
));
1318 cgiSetVariable("THISURL", val
);
1322 sprintf(val
, "%d", first
- CUPS_PAGE_MAX
);
1323 cgiSetVariable("PREV", val
);
1326 if ((first
+ CUPS_PAGE_MAX
) < count
)
1328 sprintf(val
, "%d", first
+ CUPS_PAGE_MAX
);
1329 cgiSetVariable("NEXT", val
);
1333 * Then show everything...
1337 cgiSetVariable("SEARCH_DEST", dest
);
1339 cgiCopyTemplateLang("search.tmpl");
1341 cgiCopyTemplateLang("jobs-header.tmpl");
1344 cgiCopyTemplateLang("pager.tmpl");
1346 cgiCopyTemplateLang("jobs.tmpl");
1349 cgiCopyTemplateLang("pager.tmpl");
1351 cupsArrayDelete(jobs
);
1352 ippDelete(response
);
1358 * 'cgiText()' - Return localized text.
1361 const char * /* O - Localized message */
1362 cgiText(const char *message
) /* I - Message */
1364 static cups_lang_t
*language
= NULL
;
1369 language
= cupsLangDefault();
1371 return (_cupsLangString(language
, message
));
1376 * End of "$Id: ipp-var.c 6889 2007-08-29 22:23:35Z mike $".