]>
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 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
++)
165 * 'cgiGetIPPObjects()' - Get the objects in an IPP response.
168 cups_array_t
* /* O - Array of objects */
169 cgiGetIPPObjects(ipp_t
*response
, /* I - IPP response */
170 void *search
) /* I - Search filter */
172 int i
; /* Looping var */
173 cups_array_t
*objs
; /* Array of objects */
174 ipp_attribute_t
*attr
, /* Current attribute */
175 *first
; /* First attribute for object */
176 ipp_tag_t group
; /* Current group tag */
177 int add
; /* Add this object to the array? */
183 for (add
= 0, first
= NULL
, objs
= cupsArrayNew(NULL
, NULL
),
184 group
= IPP_TAG_ZERO
, attr
= response
->attrs
;
188 if (attr
->group_tag
!= group
)
190 group
= attr
->group_tag
;
192 if (group
!= IPP_TAG_ZERO
&& group
!= IPP_TAG_OPERATION
)
197 else if (add
&& first
)
199 cupsArrayAdd(objs
, first
);
206 if (attr
->name
&& attr
->group_tag
!= IPP_TAG_OPERATION
&& !add
)
211 * Add all objects if there is no search...
219 * Check the search string against the string and integer values.
222 switch (attr
->value_tag
)
224 case IPP_TAG_TEXTLANG
:
225 case IPP_TAG_NAMELANG
:
228 case IPP_TAG_KEYWORD
:
230 case IPP_TAG_MIMETYPE
:
231 for (i
= 0; !add
&& i
< attr
->num_values
; i
++)
232 if (cgiDoSearch(search
, attr
->values
[i
].string
.text
))
236 case IPP_TAG_INTEGER
:
237 for (i
= 0; !add
&& i
< attr
->num_values
; i
++)
239 char buf
[255]; /* Number buffer */
242 sprintf(buf
, "%d", attr
->values
[i
].integer
);
244 if (cgiDoSearch(search
, buf
))
257 cupsArrayAdd(objs
, first
);
264 * 'cgiMoveJobs()' - Move one or more jobs.
266 * At least one of dest or job_id must be non-zero/NULL.
270 cgiMoveJobs(http_t
*http
, /* I - Connection to server */
271 const char *dest
, /* I - Destination or NULL */
272 int job_id
) /* I - Job ID or 0 for all */
274 int i
; /* Looping var */
275 const char *user
; /* Username */
276 ipp_t
*request
, /* IPP request */
277 *response
; /* IPP response */
278 ipp_attribute_t
*attr
; /* Current attribute */
279 const char *name
; /* Destination name */
280 const char *job_printer_uri
; /* JOB_PRINTER_URI form variable */
281 char current_dest
[1024]; /* Current destination */
285 * See who is logged in...
288 if ((user
= getenv("REMOTE_USER")) == NULL
)
292 * See if the user has already selected a new destination...
295 if ((job_printer_uri
= cgiGetVariable("JOB_PRINTER_URI")) == NULL
)
298 * Make sure necessary form variables are set...
303 char temp
[255]; /* Temporary string */
306 sprintf(temp
, "%d", job_id
);
307 cgiSetVariable("JOB_ID", temp
);
311 cgiSetVariable("PRINTER_NAME", dest
);
314 * No new destination specified, show the user what the available
315 * printers/classes are...
321 * Get the current destination for job N...
324 char job_uri
[1024]; /* Job URI */
327 request
= ippNewRequest(IPP_GET_JOB_ATTRIBUTES
);
329 snprintf(job_uri
, sizeof(job_uri
), "ipp://localhost/jobs/%d", job_id
);
330 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "job-uri",
332 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
333 "requested-attributes", NULL
, "job-printer-uri");
335 if ((response
= cupsDoRequest(http
, request
, "/")) != NULL
)
337 if ((attr
= ippFindAttribute(response
, "job-printer-uri",
338 IPP_TAG_URI
)) != NULL
)
341 * Pull the name from the URI...
344 strlcpy(current_dest
, strrchr(attr
->values
[0].string
.text
, '/') + 1,
345 sizeof(current_dest
));
355 * Couldn't get the current destination...
358 cgiStartHTML(cgiText(_("Move Job")));
359 cgiShowIPPError(_("Unable to find destination for job!"));
366 * Get the list of available destinations...
369 request
= ippNewRequest(CUPS_GET_PRINTERS
);
371 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
372 "requested-attributes", NULL
, "printer-uri-supported");
374 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
,
375 "requesting-user-name", NULL
, user
);
377 if ((response
= cupsDoRequest(http
, request
, "/")) != NULL
)
379 for (i
= 0, attr
= ippFindAttribute(response
, "printer-uri-supported",
382 attr
= ippFindNextAttribute(response
, "printer-uri-supported",
386 * Pull the name from the URI...
389 name
= strrchr(attr
->values
[0].string
.text
, '/') + 1;
392 * If the name is not the same as the current destination, add it!
395 if (strcasecmp(name
, dest
))
397 cgiSetArray("JOB_PRINTER_URI", i
, attr
->values
[0].string
.text
);
398 cgiSetArray("JOB_PRINTER_NAME", i
, name
);
411 cgiStartHTML(cgiText(_("Move Job")));
413 cgiStartHTML(cgiText(_("Move All Jobs")));
415 cgiCopyTemplateLang("job-move.tmpl");
420 * Try moving the job or jobs...
423 char uri
[1024], /* Job/printer URI */
424 resource
[1024], /* Post resource */
425 refresh
[1024]; /* Refresh URL */
426 const char *job_printer_name
; /* New printer name */
429 request
= ippNewRequest(CUPS_MOVE_JOB
);
437 snprintf(resource
, sizeof(resource
), "/jobs/%d", job_id
);
439 snprintf(uri
, sizeof(uri
), "ipp://localhost/jobs/%d", job_id
);
440 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "job-uri",
446 * Move all active jobs on a destination...
449 snprintf(resource
, sizeof(resource
), "/%s/%s",
450 cgiGetVariable("SECTION"), dest
);
452 httpAssembleURIf(HTTP_URI_CODING_ALL
, uri
, sizeof(uri
), "ipp", NULL
,
453 "localhost", ippPort(), "/%s/%s",
454 cgiGetVariable("SECTION"), dest
);
455 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
459 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "job-printer-uri",
460 NULL
, job_printer_uri
);
462 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
,
463 "requesting-user-name", NULL
, user
);
465 ippDelete(cupsDoRequest(http
, request
, resource
));
468 * Show the results...
471 job_printer_name
= strrchr(job_printer_uri
, '/') + 1;
473 if (cupsLastError() <= IPP_OK_CONFLICT
)
475 cgiRewriteURL(job_printer_uri
, resource
, sizeof(resource
), NULL
);
476 cgiFormEncode(uri
, resource
, sizeof(uri
));
477 snprintf(refresh
, sizeof(refresh
), "2;URL=%s", uri
);
478 cgiSetVariable("refresh_page", refresh
);
482 cgiStartHTML(cgiText(_("Move Job")));
484 cgiStartHTML(cgiText(_("Move All Jobs")));
486 if (cupsLastError() > IPP_OK_CONFLICT
)
489 cgiShowIPPError(_("Unable to move job"));
491 cgiShowIPPError(_("Unable to move jobs"));
495 cgiSetVariable("JOB_PRINTER_NAME", job_printer_name
);
496 cgiCopyTemplateLang("job-moved.tmpl");
505 * 'cgiPrintTestPage()' - Print a test page.
509 cgiPrintTestPage(http_t
*http
, /* I - Connection to server */
510 const char *dest
) /* I - Destination printer/class */
512 ipp_t
*request
, /* IPP request */
513 *response
; /* IPP response */
514 char uri
[HTTP_MAX_URI
], /* Printer URI */
515 resource
[1024], /* POST resource path */
516 refresh
[1024], /* Refresh URL */
517 filename
[1024]; /* Test page filename */
518 const char *datadir
; /* CUPS_DATADIR env var */
519 const char *user
; /* Username */
523 * See who is logged in...
526 if ((user
= getenv("REMOTE_USER")) == NULL
)
530 * Locate the test page file...
533 if ((datadir
= getenv("CUPS_DATADIR")) == NULL
)
534 datadir
= CUPS_DATADIR
;
536 snprintf(filename
, sizeof(filename
), "%s/data/testprint.ps", datadir
);
539 * Point to the printer/class...
542 snprintf(resource
, sizeof(resource
), "/%s/%s", cgiGetVariable("SECTION"),
545 httpAssembleURIf(HTTP_URI_CODING_ALL
, uri
, sizeof(uri
), "ipp", NULL
,
546 "localhost", ippPort(), "/%s/%s", cgiGetVariable("SECTION"),
550 * Build an IPP_PRINT_JOB request, which requires the following
554 * attributes-natural-language
556 * requesting-user-name
560 request
= ippNewRequest(IPP_PRINT_JOB
);
562 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
565 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
,
566 "requesting-user-name", NULL
, user
);
568 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "job-name",
571 ippAddString(request
, IPP_TAG_JOB
, IPP_TAG_MIMETYPE
, "document-format",
572 NULL
, "application/postscript");
575 * Do the request and get back a response...
578 if ((response
= cupsDoFileRequest(http
, request
, resource
,
581 cgiSetIPPVars(response
, NULL
, NULL
, NULL
, 0);
586 if (cupsLastError() <= IPP_OK_CONFLICT
)
589 * Automatically reload the printer status page...
592 cgiFormEncode(uri
, resource
, sizeof(uri
));
593 snprintf(refresh
, sizeof(refresh
), "2;URL=%s", uri
);
594 cgiSetVariable("refresh_page", refresh
);
597 cgiStartHTML(cgiText(_("Print Test Page")));
599 if (cupsLastError() > IPP_OK_CONFLICT
)
600 cgiShowIPPError(_("Unable to print test page:"));
603 cgiSetVariable("PRINTER_NAME", dest
);
605 cgiCopyTemplateLang("test-page.tmpl");
613 * 'cgiRewriteURL()' - Rewrite a printer URI into a web browser URL...
616 char * /* O - New URL */
617 cgiRewriteURL(const char *uri
, /* I - Current URI */
618 char *url
, /* O - New URL */
619 int urlsize
, /* I - Size of URL buffer */
620 const char *newresource
) /* I - Replacement resource */
622 char method
[HTTP_MAX_URI
],
623 userpass
[HTTP_MAX_URI
],
624 hostname
[HTTP_MAX_URI
],
625 rawresource
[HTTP_MAX_URI
],
626 resource
[HTTP_MAX_URI
],
627 /* URI components... */
628 *rawptr
, /* Pointer into rawresource */
629 *resptr
; /* Pointer into resource */
630 int port
; /* Port number */
631 static int ishttps
= -1; /* Using encryption? */
632 static const char *server
; /* Name of server */
633 static char servername
[1024];
634 /* Local server name */
635 static const char hexchars
[] = "0123456789ABCDEF";
636 /* Hexadecimal conversion characters */
640 * Check if we have been called before...
646 * No, initialize static vars for the conversion...
648 * First get the server name associated with the client interface as
649 * well as the locally configured hostname. We'll check *both* of
650 * these to see if the printer URL is local...
653 if ((server
= getenv("SERVER_NAME")) == NULL
)
656 httpGetHostname(NULL
, servername
, sizeof(servername
));
659 * Then flag whether we are using SSL on this connection...
662 ishttps
= getenv("HTTPS") != NULL
;
666 * Convert the URI to a URL...
669 httpSeparateURI(HTTP_URI_CODING_ALL
, uri
, method
, sizeof(method
), userpass
,
670 sizeof(userpass
), hostname
, sizeof(hostname
), &port
,
671 rawresource
, sizeof(rawresource
));
673 if (!strcmp(method
, "ipp") ||
674 !strcmp(method
, "http") ||
675 !strcmp(method
, "https"))
680 * Force the specified resource name instead of the one in the URL...
683 strlcpy(resource
, newresource
, sizeof(resource
));
688 * Rewrite the resource string so it doesn't contain any
692 for (rawptr
= rawresource
, resptr
= resource
; *rawptr
; rawptr
++)
693 if ((*rawptr
& 128) || *rawptr
== '%' || *rawptr
== ' ' ||
694 *rawptr
== '#' || *rawptr
== '?' ||
695 *rawptr
== '.') /* For MSIE */
697 if (resptr
< (resource
+ sizeof(resource
) - 3))
700 *resptr
++ = hexchars
[(*rawptr
>> 4) & 15];
701 *resptr
++ = hexchars
[*rawptr
& 15];
704 else if (resptr
< (resource
+ sizeof(resource
) - 1))
711 * Map local access to a local URI...
714 if (!strcasecmp(hostname
, "localhost") ||
715 !strncasecmp(hostname
, "localhost.", 10) ||
716 !strcasecmp(hostname
, server
) ||
717 !strcasecmp(hostname
, servername
))
720 * Make URI relative to the current server...
723 strlcpy(url
, resource
, urlsize
);
728 * Rewrite URI with HTTP/HTTPS scheme...
732 snprintf(url
, urlsize
, "%s://%s@%s:%d%s",
733 ishttps
? "https" : "http",
734 userpass
, hostname
, port
, resource
);
736 snprintf(url
, urlsize
, "%s://%s:%d%s",
737 ishttps
? "https" : "http",
738 hostname
, port
, resource
);
742 strlcpy(url
, uri
, urlsize
);
749 * 'cgiSetIPPObjectVars()' - Set CGI variables from an IPP object.
752 ipp_attribute_t
* /* O - Next object */
754 ipp_attribute_t
*obj
, /* I - Response data to be copied... */
755 const char *prefix
, /* I - Prefix for name or NULL */
756 int element
) /* I - Parent element number */
758 ipp_attribute_t
*attr
; /* Attribute in response... */
759 int i
; /* Looping var */
760 char name
[1024], /* Name of attribute */
761 *nameptr
, /* Pointer into name */
762 value
[16384], /* Value(s) */
763 *valptr
; /* Pointer into value */
764 struct tm
*date
; /* Date information */
767 fprintf(stderr
, "DEBUG2: cgiSetIPPObjectVars(obj=%p, prefix=\"%s\", "
769 obj
, prefix
? prefix
: "(null)", element
);
772 * Set common CGI template variables...
776 cgiSetServerVersion();
779 * Loop through the attributes and set them for the template...
782 for (attr
= obj
; attr
&& attr
->group_tag
!= IPP_TAG_ZERO
; attr
= attr
->next
)
785 * Copy the attribute name, substituting "_" for "-"...
793 snprintf(name
, sizeof(name
), "%s.", prefix
);
794 nameptr
= name
+ strlen(name
);
799 for (i
= 0; attr
->name
[i
] && nameptr
< (name
+ sizeof(name
) - 1); i
++)
800 if (attr
->name
[i
] == '-')
803 *nameptr
++ = attr
->name
[i
];
808 * Add "job_printer_name" variable if we have a "job_printer_uri"
812 if (!strcmp(name
, "job_printer_uri"))
814 if ((valptr
= strrchr(attr
->values
[0].string
.text
, '/')) == NULL
)
819 cgiSetArray("job_printer_name", element
, valptr
);
823 * Localize event names in "notify_events" variable...
826 if (!strcmp(name
, "notify_events"))
828 size_t remaining
; /* Remaining bytes in buffer */
834 for (i
= 0; i
< attr
->num_values
; i
++)
836 if (valptr
>= (value
+ sizeof(value
) - 3))
845 remaining
= sizeof(value
) - (valptr
- value
);
847 if (!strcmp(attr
->values
[i
].string
.text
, "printer-stopped"))
848 strlcpy(valptr
, _("Printer Stopped"), remaining
);
849 else if (!strcmp(attr
->values
[i
].string
.text
, "printer-added"))
850 strlcpy(valptr
, _("Printer Added"), remaining
);
851 else if (!strcmp(attr
->values
[i
].string
.text
, "printer-modified"))
852 strlcpy(valptr
, _("Printer Modified"), remaining
);
853 else if (!strcmp(attr
->values
[i
].string
.text
, "printer-deleted"))
854 strlcpy(valptr
, _("Printer Deleted"), remaining
);
855 else if (!strcmp(attr
->values
[i
].string
.text
, "job-created"))
856 strlcpy(valptr
, _("Job Created"), remaining
);
857 else if (!strcmp(attr
->values
[i
].string
.text
, "job-completed"))
858 strlcpy(valptr
, _("Job Completed"), remaining
);
859 else if (!strcmp(attr
->values
[i
].string
.text
, "job-stopped"))
860 strlcpy(valptr
, _("Job Stopped"), remaining
);
861 else if (!strcmp(attr
->values
[i
].string
.text
, "job-config-changed"))
862 strlcpy(valptr
, _("Job Options Changed"), remaining
);
863 else if (!strcmp(attr
->values
[i
].string
.text
, "server-restarted"))
864 strlcpy(valptr
, _("Server Restarted"), remaining
);
865 else if (!strcmp(attr
->values
[i
].string
.text
, "server-started"))
866 strlcpy(valptr
, _("Server Started"), remaining
);
867 else if (!strcmp(attr
->values
[i
].string
.text
, "server-stopped"))
868 strlcpy(valptr
, _("Server Stopped"), remaining
);
869 else if (!strcmp(attr
->values
[i
].string
.text
, "server-audit"))
870 strlcpy(valptr
, _("Server Security Auditing"), remaining
);
872 strlcpy(valptr
, attr
->values
[i
].string
.text
, remaining
);
874 valptr
+= strlen(valptr
);
877 cgiSetArray("notify_events", element
, value
);
882 * Add "notify_printer_name" variable if we have a "notify_printer_uri"
886 if (!strcmp(name
, "notify_printer_uri"))
888 if ((valptr
= strrchr(attr
->values
[0].string
.text
, '/')) == NULL
)
893 cgiSetArray("notify_printer_name", element
, valptr
);
897 * Add "notify_recipient_name" variable if we have a "notify_recipient_uri"
898 * attribute, and rewrite recipient URI...
901 if (!strcmp(name
, "notify_recipient_uri"))
903 char uri
[1024], /* New URI */
904 scheme
[32], /* Scheme portion of URI */
905 userpass
[256], /* Username/password portion of URI */
906 host
[1024], /* Hostname portion of URI */
907 resource
[1024], /* Resource portion of URI */
908 *options
; /* Options in URI */
909 int port
; /* Port number */
912 httpSeparateURI(HTTP_URI_CODING_ALL
, attr
->values
[0].string
.text
,
913 scheme
, sizeof(scheme
), userpass
, sizeof(userpass
),
914 host
, sizeof(host
), &port
, resource
, sizeof(resource
));
916 if (!strcmp(scheme
, "rss"))
919 * RSS notification...
922 if ((options
= strchr(resource
, '?')) != NULL
)
928 * Link to remote feed...
931 httpAssembleURI(HTTP_URI_CODING_ALL
, uri
, sizeof(uri
), "http",
932 userpass
, host
, port
, resource
);
933 strlcpy(name
, uri
, sizeof(name
));
938 * Link to local feed...
941 snprintf(uri
, sizeof(uri
), "/rss%s", resource
);
942 strlcpy(name
, resource
+ 1, sizeof(name
));
951 strlcpy(uri
, attr
->values
[0].string
.text
, sizeof(uri
));
952 strlcpy(name
, resource
, sizeof(name
));
955 cgiSetArray("notify_recipient_uri", element
, uri
);
956 cgiSetArray("notify_recipient_name", element
, name
);
961 * Add "admin_uri" variable if we have a "printer_uri_supported"
965 if (!strcmp(name
, "printer_uri_supported"))
967 cgiRewriteURL(attr
->values
[0].string
.text
, value
, sizeof(value
),
970 cgiSetArray("admin_uri", element
, value
);
977 value
[0] = '\0'; /* Initially an empty string */
978 valptr
= value
; /* Start at the beginning */
980 for (i
= 0; i
< attr
->num_values
; i
++)
983 strlcat(valptr
, ", ", sizeof(value
) - (valptr
- value
));
985 valptr
+= strlen(valptr
);
987 switch (attr
->value_tag
)
989 case IPP_TAG_INTEGER
:
991 if (strncmp(name
, "time_at_", 8) == 0)
993 time_t t
; /* Temporary time value */
995 t
= (time_t)attr
->values
[i
].integer
;
996 date
= localtime(&t
);
998 strftime(valptr
, sizeof(value
) - (valptr
- value
), "%c", date
);
1001 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1002 "%d", attr
->values
[i
].integer
);
1005 case IPP_TAG_BOOLEAN
:
1006 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1007 "%d", attr
->values
[i
].boolean
);
1010 case IPP_TAG_NOVALUE
:
1011 strlcat(valptr
, "novalue", sizeof(value
) - (valptr
- value
));
1014 case IPP_TAG_RANGE
:
1015 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1016 "%d-%d", attr
->values
[i
].range
.lower
,
1017 attr
->values
[i
].range
.upper
);
1020 case IPP_TAG_RESOLUTION
:
1021 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1022 "%dx%d%s", attr
->values
[i
].resolution
.xres
,
1023 attr
->values
[i
].resolution
.yres
,
1024 attr
->values
[i
].resolution
.units
== IPP_RES_PER_INCH
?
1029 if (strchr(attr
->values
[i
].string
.text
, ':') &&
1030 strcmp(name
, "device_uri"))
1036 if (!strcmp(name
, "member_uris"))
1038 char url
[1024]; /* URL for class member... */
1041 cgiRewriteURL(attr
->values
[i
].string
.text
, url
,
1044 snprintf(valptr
, sizeof(value
) - (valptr
- value
),
1045 "<A HREF=\"%s\">%s</A>", url
,
1046 strrchr(attr
->values
[i
].string
.text
, '/') + 1);
1049 cgiRewriteURL(attr
->values
[i
].string
.text
, valptr
,
1050 sizeof(value
) - (valptr
- value
), NULL
);
1054 case IPP_TAG_STRING
:
1057 case IPP_TAG_KEYWORD
:
1058 case IPP_TAG_CHARSET
:
1059 case IPP_TAG_LANGUAGE
:
1060 case IPP_TAG_MIMETYPE
:
1061 strlcat(valptr
, attr
->values
[i
].string
.text
,
1062 sizeof(value
) - (valptr
- value
));
1065 case IPP_TAG_BEGIN_COLLECTION
:
1066 snprintf(value
, sizeof(value
), "%s%d", name
, i
+ 1);
1067 cgiSetIPPVars(attr
->values
[i
].collection
, NULL
, NULL
, value
,
1072 break; /* anti-compiler-warning-code */
1077 * Add the element...
1080 if (attr
->value_tag
!= IPP_TAG_BEGIN_COLLECTION
)
1082 cgiSetArray(name
, element
, value
);
1084 fprintf(stderr
, "DEBUG2: %s[%d]=\"%s\"\n", name
, element
, value
);
1088 return (attr
? attr
->next
: NULL
);
1093 * 'cgiSetIPPVars()' - Set CGI variables from an IPP response.
1096 int /* O - Maximum number of elements */
1097 cgiSetIPPVars(ipp_t
*response
, /* I - Response data to be copied... */
1098 const char *filter_name
, /* I - Filter name */
1099 const char *filter_value
, /* I - Filter value */
1100 const char *prefix
, /* I - Prefix for name or NULL */
1101 int parent_el
) /* I - Parent element number */
1103 int element
; /* Element in CGI array */
1104 ipp_attribute_t
*attr
, /* Attribute in response... */
1105 *filter
; /* Filtering attribute */
1108 fprintf(stderr
, "DEBUG2: cgiSetIPPVars(response=%p, filter_name=\"%s\", "
1109 "filter_value=\"%s\", prefix=\"%s\", parent_el=%d)\n",
1110 response
, filter_name
? filter_name
: "(null)",
1111 filter_value
? filter_value
: "(null)",
1112 prefix
? prefix
: "(null)", parent_el
);
1115 * Set common CGI template variables...
1119 cgiSetServerVersion();
1122 * Loop through the attributes and set them for the template...
1125 attr
= response
->attrs
;
1128 while (attr
&& attr
->group_tag
== IPP_TAG_OPERATION
)
1131 for (element
= parent_el
; attr
; element
++)
1134 * Copy attributes to a separator...
1137 while (attr
&& attr
->group_tag
== IPP_TAG_ZERO
)
1146 filter
!= NULL
&& filter
->group_tag
!= IPP_TAG_ZERO
;
1147 filter
= filter
->next
)
1148 if (filter
->name
&& !strcmp(filter
->name
, filter_name
) &&
1149 (filter
->value_tag
== IPP_TAG_STRING
||
1150 (filter
->value_tag
>= IPP_TAG_TEXTLANG
&&
1151 filter
->value_tag
<= IPP_TAG_MIMETYPE
)) &&
1152 filter
->values
[0].string
.text
!= NULL
&&
1153 !strcasecmp(filter
->values
[0].string
.text
, filter_value
))
1157 return (element
+ 1);
1159 if (filter
->group_tag
== IPP_TAG_ZERO
)
1167 attr
= cgiSetIPPObjectVars(attr
, prefix
, element
);
1170 fprintf(stderr
, "DEBUG2: Returing %d from cgiSetIPPVars()...\n", element
);
1177 * 'cgiShowIPPError()' - Show the last IPP error message.
1179 * The caller must still call cgiStartHTML() and cgiEndHTML().
1183 cgiShowIPPError(const char *message
) /* I - Contextual message */
1185 cgiSetVariable("MESSAGE", cgiText(message
));
1186 cgiSetVariable("ERROR", cupsLastErrorString());
1187 cgiCopyTemplateLang("error.tmpl");
1192 * 'cgiShowJobs()' - Show print jobs.
1196 cgiShowJobs(http_t
*http
, /* I - Connection to server */
1197 const char *dest
) /* I - Destination name or NULL */
1199 int i
; /* Looping var */
1200 const char *which_jobs
; /* Which jobs to show */
1201 ipp_t
*request
, /* IPP request */
1202 *response
; /* IPP response */
1203 cups_array_t
*jobs
; /* Array of job objects */
1204 ipp_attribute_t
*job
; /* Job object */
1205 int ascending
, /* Order of jobs (0 = descending) */
1206 first
, /* First job to show */
1207 count
; /* Number of jobs */
1208 const char *var
; /* Form variable */
1209 void *search
; /* Search data */
1210 char url
[1024], /* Printer URI */
1211 val
[1024]; /* Form variable */
1215 * Build an IPP_GET_JOBS request, which requires the following
1218 * attributes-charset
1219 * attributes-natural-language
1223 request
= ippNewRequest(IPP_GET_JOBS
);
1227 httpAssembleURIf(HTTP_URI_CODING_ALL
, url
, sizeof(url
), "ipp", NULL
,
1228 "localhost", ippPort(), "/printers/%s", dest
);
1229 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
1233 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "job-uri", NULL
,
1234 "ipp://localhost/jobs");
1236 if ((which_jobs
= cgiGetVariable("which_jobs")) != NULL
)
1237 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
, "which-jobs",
1240 cgiGetAttributes(request
, "jobs.tmpl");
1243 * Do the request and get back a response...
1246 if ((response
= cupsDoRequest(http
, request
, "/")) != NULL
)
1249 * Get a list of matching job objects.
1252 if ((var
= cgiGetVariable("QUERY")) != NULL
&&
1253 !cgiGetVariable("CLEAR"))
1254 search
= cgiCompileSearch(var
);
1258 jobs
= cgiGetIPPObjects(response
, search
);
1259 count
= cupsArrayCount(jobs
);
1262 cgiFreeSearch(search
);
1265 * Figure out which jobs to display...
1268 if ((var
= cgiGetVariable("FIRST")) != NULL
)
1274 first
= count
- CUPS_PAGE_MAX
;
1276 first
= (first
/ CUPS_PAGE_MAX
) * CUPS_PAGE_MAX
;
1281 sprintf(val
, "%d", count
);
1282 cgiSetVariable("TOTAL", val
);
1284 if ((var
= cgiGetVariable("ORDER")) != NULL
)
1285 ascending
= !strcasecmp(var
, "asc");
1288 ascending
= !which_jobs
|| !strcasecmp(which_jobs
, "not-completed");
1289 cgiSetVariable("ORDER", ascending
? "asc" : "dec");
1294 for (i
= 0, job
= (ipp_attribute_t
*)cupsArrayIndex(jobs
, first
);
1295 i
< CUPS_PAGE_MAX
&& job
;
1296 i
++, job
= (ipp_attribute_t
*)cupsArrayNext(jobs
))
1297 cgiSetIPPObjectVars(job
, NULL
, i
);
1301 for (i
= 0, job
= (ipp_attribute_t
*)cupsArrayIndex(jobs
, count
- first
- 1);
1302 i
< CUPS_PAGE_MAX
&& job
;
1303 i
++, job
= (ipp_attribute_t
*)cupsArrayPrev(jobs
))
1304 cgiSetIPPObjectVars(job
, NULL
, i
);
1308 * Save navigation URLs...
1312 snprintf(val
, sizeof(val
), "/%s/%s", cgiGetVariable("SECTION"), dest
);
1314 strlcpy(val
, "/jobs/", sizeof(val
));
1316 cgiSetVariable("THISURL", val
);
1320 sprintf(val
, "%d", first
- CUPS_PAGE_MAX
);
1321 cgiSetVariable("PREV", val
);
1324 if ((first
+ CUPS_PAGE_MAX
) < count
)
1326 sprintf(val
, "%d", first
+ CUPS_PAGE_MAX
);
1327 cgiSetVariable("NEXT", val
);
1331 * Then show everything...
1335 cgiSetVariable("SEARCH_DEST", dest
);
1337 cgiCopyTemplateLang("search.tmpl");
1339 cgiCopyTemplateLang("jobs-header.tmpl");
1342 cgiCopyTemplateLang("pager.tmpl");
1344 cgiCopyTemplateLang("jobs.tmpl");
1347 cgiCopyTemplateLang("pager.tmpl");
1349 cupsArrayDelete(jobs
);
1350 ippDelete(response
);
1356 * 'cgiText()' - Return localized text.
1359 const char * /* O - Localized message */
1360 cgiText(const char *message
) /* I - Message */
1362 static cups_lang_t
*language
= NULL
;
1367 language
= cupsLangDefault();
1369 return (_cupsLangString(language
, message
));
1374 * End of "$Id: ipp-var.c 6889 2007-08-29 22:23:35Z mike $".