xref: /aosp_15_r20/external/libcups/cgi-bin/ipp-var.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * CGI <-> IPP variable routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2007-2016 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright 1997-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker  */
9*5e7646d2SAndroid Build Coastguard Worker 
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker  */
13*5e7646d2SAndroid Build Coastguard Worker 
14*5e7646d2SAndroid Build Coastguard Worker #include "cgi-private.h"
15*5e7646d2SAndroid Build Coastguard Worker 
16*5e7646d2SAndroid Build Coastguard Worker 
17*5e7646d2SAndroid Build Coastguard Worker /*
18*5e7646d2SAndroid Build Coastguard Worker  * 'cgiGetAttributes()' - Get the list of attributes that are needed
19*5e7646d2SAndroid Build Coastguard Worker  *                        by the template file.
20*5e7646d2SAndroid Build Coastguard Worker  */
21*5e7646d2SAndroid Build Coastguard Worker 
22*5e7646d2SAndroid Build Coastguard Worker void
cgiGetAttributes(ipp_t * request,const char * tmpl)23*5e7646d2SAndroid Build Coastguard Worker cgiGetAttributes(ipp_t      *request,	/* I - IPP request */
24*5e7646d2SAndroid Build Coastguard Worker                  const char *tmpl)	/* I - Base filename */
25*5e7646d2SAndroid Build Coastguard Worker {
26*5e7646d2SAndroid Build Coastguard Worker   int		num_attrs;		/* Number of attributes */
27*5e7646d2SAndroid Build Coastguard Worker   char		*attrs[1000];		/* Attributes */
28*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
29*5e7646d2SAndroid Build Coastguard Worker   char		filename[1024],		/* Filename */
30*5e7646d2SAndroid Build Coastguard Worker 		locale[16];		/* Locale name */
31*5e7646d2SAndroid Build Coastguard Worker   const char	*directory,		/* Directory */
32*5e7646d2SAndroid Build Coastguard Worker 		*lang;			/* Language */
33*5e7646d2SAndroid Build Coastguard Worker   FILE		*in;			/* Input file */
34*5e7646d2SAndroid Build Coastguard Worker   int		ch;			/* Character from file */
35*5e7646d2SAndroid Build Coastguard Worker   char		name[255],		/* Name of variable */
36*5e7646d2SAndroid Build Coastguard Worker 		*nameptr;		/* Pointer into name */
37*5e7646d2SAndroid Build Coastguard Worker 
38*5e7646d2SAndroid Build Coastguard Worker 
39*5e7646d2SAndroid Build Coastguard Worker  /*
40*5e7646d2SAndroid Build Coastguard Worker   * Convert the language to a locale name...
41*5e7646d2SAndroid Build Coastguard Worker   */
42*5e7646d2SAndroid Build Coastguard Worker 
43*5e7646d2SAndroid Build Coastguard Worker   if ((lang = getenv("LANG")) != NULL)
44*5e7646d2SAndroid Build Coastguard Worker   {
45*5e7646d2SAndroid Build Coastguard Worker     for (i = 0; lang[i] && i < 15; i ++)
46*5e7646d2SAndroid Build Coastguard Worker       if (isalnum(lang[i] & 255))
47*5e7646d2SAndroid Build Coastguard Worker         locale[i] = (char)tolower(lang[i]);
48*5e7646d2SAndroid Build Coastguard Worker       else
49*5e7646d2SAndroid Build Coastguard Worker         locale[i] = '_';
50*5e7646d2SAndroid Build Coastguard Worker 
51*5e7646d2SAndroid Build Coastguard Worker     locale[i] = '\0';
52*5e7646d2SAndroid Build Coastguard Worker   }
53*5e7646d2SAndroid Build Coastguard Worker   else
54*5e7646d2SAndroid Build Coastguard Worker     locale[0] = '\0';
55*5e7646d2SAndroid Build Coastguard Worker 
56*5e7646d2SAndroid Build Coastguard Worker  /*
57*5e7646d2SAndroid Build Coastguard Worker   * See if we have a template file for this language...
58*5e7646d2SAndroid Build Coastguard Worker   */
59*5e7646d2SAndroid Build Coastguard Worker 
60*5e7646d2SAndroid Build Coastguard Worker   directory = cgiGetTemplateDir();
61*5e7646d2SAndroid Build Coastguard Worker 
62*5e7646d2SAndroid Build Coastguard Worker   snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
63*5e7646d2SAndroid Build Coastguard Worker   if (access(filename, 0))
64*5e7646d2SAndroid Build Coastguard Worker   {
65*5e7646d2SAndroid Build Coastguard Worker     locale[2] = '\0';
66*5e7646d2SAndroid Build Coastguard Worker 
67*5e7646d2SAndroid Build Coastguard Worker     snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
68*5e7646d2SAndroid Build Coastguard Worker     if (access(filename, 0))
69*5e7646d2SAndroid Build Coastguard Worker       snprintf(filename, sizeof(filename), "%s/%s", directory, tmpl);
70*5e7646d2SAndroid Build Coastguard Worker   }
71*5e7646d2SAndroid Build Coastguard Worker 
72*5e7646d2SAndroid Build Coastguard Worker  /*
73*5e7646d2SAndroid Build Coastguard Worker   * Open the template file...
74*5e7646d2SAndroid Build Coastguard Worker   */
75*5e7646d2SAndroid Build Coastguard Worker 
76*5e7646d2SAndroid Build Coastguard Worker   if ((in = fopen(filename, "r")) == NULL)
77*5e7646d2SAndroid Build Coastguard Worker     return;
78*5e7646d2SAndroid Build Coastguard Worker 
79*5e7646d2SAndroid Build Coastguard Worker  /*
80*5e7646d2SAndroid Build Coastguard Worker   * Loop through the file adding attribute names as needed...
81*5e7646d2SAndroid Build Coastguard Worker   */
82*5e7646d2SAndroid Build Coastguard Worker 
83*5e7646d2SAndroid Build Coastguard Worker   num_attrs = 0;
84*5e7646d2SAndroid Build Coastguard Worker   attrs[0]  = NULL;			/* Eliminate compiler warning */
85*5e7646d2SAndroid Build Coastguard Worker 
86*5e7646d2SAndroid Build Coastguard Worker   while ((ch = getc(in)) != EOF)
87*5e7646d2SAndroid Build Coastguard Worker     if (ch == '\\')
88*5e7646d2SAndroid Build Coastguard Worker       getc(in);
89*5e7646d2SAndroid Build Coastguard Worker     else if (ch == '{' && num_attrs < (int)(sizeof(attrs) / sizeof(attrs[0])))
90*5e7646d2SAndroid Build Coastguard Worker     {
91*5e7646d2SAndroid Build Coastguard Worker      /*
92*5e7646d2SAndroid Build Coastguard Worker       * Grab the name...
93*5e7646d2SAndroid Build Coastguard Worker       */
94*5e7646d2SAndroid Build Coastguard Worker 
95*5e7646d2SAndroid Build Coastguard Worker       for (nameptr = name; (ch = getc(in)) != EOF;)
96*5e7646d2SAndroid Build Coastguard Worker         if (strchr("}]<>=!~ \t\n", ch))
97*5e7646d2SAndroid Build Coastguard Worker           break;
98*5e7646d2SAndroid Build Coastguard Worker         else if (nameptr > name && ch == '?')
99*5e7646d2SAndroid Build Coastguard Worker 	  break;
100*5e7646d2SAndroid Build Coastguard Worker 	else if (nameptr < (name + sizeof(name) - 1))
101*5e7646d2SAndroid Build Coastguard Worker 	{
102*5e7646d2SAndroid Build Coastguard Worker 	  if (ch == '_')
103*5e7646d2SAndroid Build Coastguard Worker 	    *nameptr++ = '-';
104*5e7646d2SAndroid Build Coastguard Worker 	  else
105*5e7646d2SAndroid Build Coastguard Worker             *nameptr++ = (char)ch;
106*5e7646d2SAndroid Build Coastguard Worker 	}
107*5e7646d2SAndroid Build Coastguard Worker 
108*5e7646d2SAndroid Build Coastguard Worker       *nameptr = '\0';
109*5e7646d2SAndroid Build Coastguard Worker 
110*5e7646d2SAndroid Build Coastguard Worker       if (!strncmp(name, "printer_state_history", 21))
111*5e7646d2SAndroid Build Coastguard Worker         strlcpy(name, "printer_state_history", sizeof(name));
112*5e7646d2SAndroid Build Coastguard Worker 
113*5e7646d2SAndroid Build Coastguard Worker      /*
114*5e7646d2SAndroid Build Coastguard Worker       * Possibly add it to the list of attributes...
115*5e7646d2SAndroid Build Coastguard Worker       */
116*5e7646d2SAndroid Build Coastguard Worker 
117*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < num_attrs; i ++)
118*5e7646d2SAndroid Build Coastguard Worker         if (!strcmp(attrs[i], name))
119*5e7646d2SAndroid Build Coastguard Worker 	  break;
120*5e7646d2SAndroid Build Coastguard Worker 
121*5e7646d2SAndroid Build Coastguard Worker       if (i >= num_attrs)
122*5e7646d2SAndroid Build Coastguard Worker       {
123*5e7646d2SAndroid Build Coastguard Worker 	attrs[num_attrs] = strdup(name);
124*5e7646d2SAndroid Build Coastguard Worker 	num_attrs ++;
125*5e7646d2SAndroid Build Coastguard Worker       }
126*5e7646d2SAndroid Build Coastguard Worker     }
127*5e7646d2SAndroid Build Coastguard Worker 
128*5e7646d2SAndroid Build Coastguard Worker  /*
129*5e7646d2SAndroid Build Coastguard Worker   * If we have attributes, add a requested-attributes attribute to the
130*5e7646d2SAndroid Build Coastguard Worker   * request...
131*5e7646d2SAndroid Build Coastguard Worker   */
132*5e7646d2SAndroid Build Coastguard Worker 
133*5e7646d2SAndroid Build Coastguard Worker   if (num_attrs > 0)
134*5e7646d2SAndroid Build Coastguard Worker   {
135*5e7646d2SAndroid Build Coastguard Worker     ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
136*5e7646d2SAndroid Build Coastguard Worker                   "requested-attributes", num_attrs, NULL, (const char **)attrs);
137*5e7646d2SAndroid Build Coastguard Worker 
138*5e7646d2SAndroid Build Coastguard Worker     for (i = 0; i < num_attrs; i ++)
139*5e7646d2SAndroid Build Coastguard Worker       free(attrs[i]);
140*5e7646d2SAndroid Build Coastguard Worker   }
141*5e7646d2SAndroid Build Coastguard Worker 
142*5e7646d2SAndroid Build Coastguard Worker   fclose(in);
143*5e7646d2SAndroid Build Coastguard Worker }
144*5e7646d2SAndroid Build Coastguard Worker 
145*5e7646d2SAndroid Build Coastguard Worker 
146*5e7646d2SAndroid Build Coastguard Worker /*
147*5e7646d2SAndroid Build Coastguard Worker  * 'cgiGetIPPObjects()' - Get the objects in an IPP response.
148*5e7646d2SAndroid Build Coastguard Worker  */
149*5e7646d2SAndroid Build Coastguard Worker 
150*5e7646d2SAndroid Build Coastguard Worker cups_array_t *				/* O - Array of objects */
cgiGetIPPObjects(ipp_t * response,void * search)151*5e7646d2SAndroid Build Coastguard Worker cgiGetIPPObjects(ipp_t *response,	/* I - IPP response */
152*5e7646d2SAndroid Build Coastguard Worker                  void  *search)		/* I - Search filter */
153*5e7646d2SAndroid Build Coastguard Worker {
154*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
155*5e7646d2SAndroid Build Coastguard Worker   cups_array_t		*objs;		/* Array of objects */
156*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t	*attr,		/* Current attribute */
157*5e7646d2SAndroid Build Coastguard Worker 			*first;		/* First attribute for object */
158*5e7646d2SAndroid Build Coastguard Worker   ipp_tag_t		group;		/* Current group tag */
159*5e7646d2SAndroid Build Coastguard Worker   int			add;		/* Add this object to the array? */
160*5e7646d2SAndroid Build Coastguard Worker 
161*5e7646d2SAndroid Build Coastguard Worker 
162*5e7646d2SAndroid Build Coastguard Worker   if (!response)
163*5e7646d2SAndroid Build Coastguard Worker     return (0);
164*5e7646d2SAndroid Build Coastguard Worker 
165*5e7646d2SAndroid Build Coastguard Worker   for (add = 0, first = NULL, objs = cupsArrayNew(NULL, NULL),
166*5e7646d2SAndroid Build Coastguard Worker            group = IPP_TAG_ZERO, attr = response->attrs;
167*5e7646d2SAndroid Build Coastguard Worker        attr;
168*5e7646d2SAndroid Build Coastguard Worker        attr = attr->next)
169*5e7646d2SAndroid Build Coastguard Worker   {
170*5e7646d2SAndroid Build Coastguard Worker     if (attr->group_tag != group)
171*5e7646d2SAndroid Build Coastguard Worker     {
172*5e7646d2SAndroid Build Coastguard Worker       group = attr->group_tag;
173*5e7646d2SAndroid Build Coastguard Worker 
174*5e7646d2SAndroid Build Coastguard Worker       if (group != IPP_TAG_ZERO && group != IPP_TAG_OPERATION)
175*5e7646d2SAndroid Build Coastguard Worker       {
176*5e7646d2SAndroid Build Coastguard Worker         first = attr;
177*5e7646d2SAndroid Build Coastguard Worker 	add   = 0;
178*5e7646d2SAndroid Build Coastguard Worker       }
179*5e7646d2SAndroid Build Coastguard Worker       else if (add && first)
180*5e7646d2SAndroid Build Coastguard Worker       {
181*5e7646d2SAndroid Build Coastguard Worker         cupsArrayAdd(objs, first);
182*5e7646d2SAndroid Build Coastguard Worker 
183*5e7646d2SAndroid Build Coastguard Worker 	add   = 0;
184*5e7646d2SAndroid Build Coastguard Worker 	first = NULL;
185*5e7646d2SAndroid Build Coastguard Worker       }
186*5e7646d2SAndroid Build Coastguard Worker     }
187*5e7646d2SAndroid Build Coastguard Worker 
188*5e7646d2SAndroid Build Coastguard Worker     if (attr->name && attr->group_tag != IPP_TAG_OPERATION && !add)
189*5e7646d2SAndroid Build Coastguard Worker     {
190*5e7646d2SAndroid Build Coastguard Worker       if (!search)
191*5e7646d2SAndroid Build Coastguard Worker       {
192*5e7646d2SAndroid Build Coastguard Worker        /*
193*5e7646d2SAndroid Build Coastguard Worker         * Add all objects if there is no search...
194*5e7646d2SAndroid Build Coastguard Worker 	*/
195*5e7646d2SAndroid Build Coastguard Worker 
196*5e7646d2SAndroid Build Coastguard Worker         add = 1;
197*5e7646d2SAndroid Build Coastguard Worker       }
198*5e7646d2SAndroid Build Coastguard Worker       else
199*5e7646d2SAndroid Build Coastguard Worker       {
200*5e7646d2SAndroid Build Coastguard Worker        /*
201*5e7646d2SAndroid Build Coastguard Worker         * Check the search string against the string and integer values.
202*5e7646d2SAndroid Build Coastguard Worker 	*/
203*5e7646d2SAndroid Build Coastguard Worker 
204*5e7646d2SAndroid Build Coastguard Worker         switch (attr->value_tag)
205*5e7646d2SAndroid Build Coastguard Worker 	{
206*5e7646d2SAndroid Build Coastguard Worker 	  case IPP_TAG_TEXTLANG :
207*5e7646d2SAndroid Build Coastguard Worker 	  case IPP_TAG_NAMELANG :
208*5e7646d2SAndroid Build Coastguard Worker 	  case IPP_TAG_TEXT :
209*5e7646d2SAndroid Build Coastguard Worker 	  case IPP_TAG_NAME :
210*5e7646d2SAndroid Build Coastguard Worker 	  case IPP_TAG_KEYWORD :
211*5e7646d2SAndroid Build Coastguard Worker 	  case IPP_TAG_URI :
212*5e7646d2SAndroid Build Coastguard Worker 	  case IPP_TAG_MIMETYPE :
213*5e7646d2SAndroid Build Coastguard Worker 	      for (i = 0; !add && i < attr->num_values; i ++)
214*5e7646d2SAndroid Build Coastguard Worker 		if (cgiDoSearch(search, attr->values[i].string.text))
215*5e7646d2SAndroid Build Coastguard Worker 		  add = 1;
216*5e7646d2SAndroid Build Coastguard Worker 	      break;
217*5e7646d2SAndroid Build Coastguard Worker 
218*5e7646d2SAndroid Build Coastguard Worker           case IPP_TAG_INTEGER :
219*5e7646d2SAndroid Build Coastguard Worker 	      if (!strncmp(ippGetName(attr), "time-at-", 8))
220*5e7646d2SAndroid Build Coastguard Worker 	        break;			/* Ignore time-at-xxx */
221*5e7646d2SAndroid Build Coastguard Worker 
222*5e7646d2SAndroid Build Coastguard Worker 	      for (i = 0; !add && i < attr->num_values; i ++)
223*5e7646d2SAndroid Build Coastguard Worker 	      {
224*5e7646d2SAndroid Build Coastguard Worker 	        char	buf[255];	/* Number buffer */
225*5e7646d2SAndroid Build Coastguard Worker 
226*5e7646d2SAndroid Build Coastguard Worker 
227*5e7646d2SAndroid Build Coastguard Worker                 snprintf(buf, sizeof(buf), "%d", attr->values[i].integer);
228*5e7646d2SAndroid Build Coastguard Worker 
229*5e7646d2SAndroid Build Coastguard Worker 		if (cgiDoSearch(search, buf))
230*5e7646d2SAndroid Build Coastguard Worker 		  add = 1;
231*5e7646d2SAndroid Build Coastguard Worker 	      }
232*5e7646d2SAndroid Build Coastguard Worker 	      break;
233*5e7646d2SAndroid Build Coastguard Worker 
234*5e7646d2SAndroid Build Coastguard Worker           default :
235*5e7646d2SAndroid Build Coastguard Worker 	      break;
236*5e7646d2SAndroid Build Coastguard Worker 	}
237*5e7646d2SAndroid Build Coastguard Worker       }
238*5e7646d2SAndroid Build Coastguard Worker     }
239*5e7646d2SAndroid Build Coastguard Worker   }
240*5e7646d2SAndroid Build Coastguard Worker 
241*5e7646d2SAndroid Build Coastguard Worker   if (add && first)
242*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(objs, first);
243*5e7646d2SAndroid Build Coastguard Worker 
244*5e7646d2SAndroid Build Coastguard Worker   return (objs);
245*5e7646d2SAndroid Build Coastguard Worker }
246*5e7646d2SAndroid Build Coastguard Worker 
247*5e7646d2SAndroid Build Coastguard Worker 
248*5e7646d2SAndroid Build Coastguard Worker /*
249*5e7646d2SAndroid Build Coastguard Worker  * 'cgiMoveJobs()' - Move one or more jobs.
250*5e7646d2SAndroid Build Coastguard Worker  *
251*5e7646d2SAndroid Build Coastguard Worker  * At least one of dest or job_id must be non-zero/NULL.
252*5e7646d2SAndroid Build Coastguard Worker  */
253*5e7646d2SAndroid Build Coastguard Worker 
254*5e7646d2SAndroid Build Coastguard Worker void
cgiMoveJobs(http_t * http,const char * dest,int job_id)255*5e7646d2SAndroid Build Coastguard Worker cgiMoveJobs(http_t     *http,		/* I - Connection to server */
256*5e7646d2SAndroid Build Coastguard Worker             const char *dest,		/* I - Destination or NULL */
257*5e7646d2SAndroid Build Coastguard Worker             int        job_id)		/* I - Job ID or 0 for all */
258*5e7646d2SAndroid Build Coastguard Worker {
259*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
260*5e7646d2SAndroid Build Coastguard Worker   const char	*user;			/* Username */
261*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request,		/* IPP request */
262*5e7646d2SAndroid Build Coastguard Worker 		*response;		/* IPP response */
263*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t *attr;		/* Current attribute */
264*5e7646d2SAndroid Build Coastguard Worker   const char	*name;			/* Destination name */
265*5e7646d2SAndroid Build Coastguard Worker   const char	*job_printer_uri;	/* JOB_PRINTER_URI form variable */
266*5e7646d2SAndroid Build Coastguard Worker   char		current_dest[1024];	/* Current destination */
267*5e7646d2SAndroid Build Coastguard Worker 
268*5e7646d2SAndroid Build Coastguard Worker 
269*5e7646d2SAndroid Build Coastguard Worker  /*
270*5e7646d2SAndroid Build Coastguard Worker   * Make sure we have a username...
271*5e7646d2SAndroid Build Coastguard Worker   */
272*5e7646d2SAndroid Build Coastguard Worker 
273*5e7646d2SAndroid Build Coastguard Worker   if ((user = getenv("REMOTE_USER")) == NULL)
274*5e7646d2SAndroid Build Coastguard Worker   {
275*5e7646d2SAndroid Build Coastguard Worker     puts("Status: 401\n");
276*5e7646d2SAndroid Build Coastguard Worker     exit(0);
277*5e7646d2SAndroid Build Coastguard Worker   }
278*5e7646d2SAndroid Build Coastguard Worker 
279*5e7646d2SAndroid Build Coastguard Worker  /*
280*5e7646d2SAndroid Build Coastguard Worker   * See if the user has already selected a new destination...
281*5e7646d2SAndroid Build Coastguard Worker   */
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker   if ((job_printer_uri = cgiGetVariable("JOB_PRINTER_URI")) == NULL)
284*5e7646d2SAndroid Build Coastguard Worker   {
285*5e7646d2SAndroid Build Coastguard Worker    /*
286*5e7646d2SAndroid Build Coastguard Worker     * Make sure necessary form variables are set...
287*5e7646d2SAndroid Build Coastguard Worker     */
288*5e7646d2SAndroid Build Coastguard Worker 
289*5e7646d2SAndroid Build Coastguard Worker     if (job_id)
290*5e7646d2SAndroid Build Coastguard Worker     {
291*5e7646d2SAndroid Build Coastguard Worker       char	temp[255];		/* Temporary string */
292*5e7646d2SAndroid Build Coastguard Worker 
293*5e7646d2SAndroid Build Coastguard Worker 
294*5e7646d2SAndroid Build Coastguard Worker       snprintf(temp, sizeof(temp), "%d", job_id);
295*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("JOB_ID", temp);
296*5e7646d2SAndroid Build Coastguard Worker     }
297*5e7646d2SAndroid Build Coastguard Worker 
298*5e7646d2SAndroid Build Coastguard Worker     if (dest)
299*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("PRINTER_NAME", dest);
300*5e7646d2SAndroid Build Coastguard Worker 
301*5e7646d2SAndroid Build Coastguard Worker    /*
302*5e7646d2SAndroid Build Coastguard Worker     * No new destination specified, show the user what the available
303*5e7646d2SAndroid Build Coastguard Worker     * printers/classes are...
304*5e7646d2SAndroid Build Coastguard Worker     */
305*5e7646d2SAndroid Build Coastguard Worker 
306*5e7646d2SAndroid Build Coastguard Worker     if (!dest)
307*5e7646d2SAndroid Build Coastguard Worker     {
308*5e7646d2SAndroid Build Coastguard Worker      /*
309*5e7646d2SAndroid Build Coastguard Worker       * Get the current destination for job N...
310*5e7646d2SAndroid Build Coastguard Worker       */
311*5e7646d2SAndroid Build Coastguard Worker 
312*5e7646d2SAndroid Build Coastguard Worker       char	job_uri[1024];		/* Job URI */
313*5e7646d2SAndroid Build Coastguard Worker 
314*5e7646d2SAndroid Build Coastguard Worker 
315*5e7646d2SAndroid Build Coastguard Worker       request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES);
316*5e7646d2SAndroid Build Coastguard Worker 
317*5e7646d2SAndroid Build Coastguard Worker       snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", job_id);
318*5e7646d2SAndroid Build Coastguard Worker       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
319*5e7646d2SAndroid Build Coastguard Worker                    NULL, job_uri);
320*5e7646d2SAndroid Build Coastguard Worker       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
321*5e7646d2SAndroid Build Coastguard Worker                    "requested-attributes", NULL, "job-printer-uri");
322*5e7646d2SAndroid Build Coastguard Worker 
323*5e7646d2SAndroid Build Coastguard Worker       if ((response = cupsDoRequest(http, request, "/")) != NULL)
324*5e7646d2SAndroid Build Coastguard Worker       {
325*5e7646d2SAndroid Build Coastguard Worker         if ((attr = ippFindAttribute(response, "job-printer-uri",
326*5e7646d2SAndroid Build Coastguard Worker 	                             IPP_TAG_URI)) != NULL)
327*5e7646d2SAndroid Build Coastguard Worker 	{
328*5e7646d2SAndroid Build Coastguard Worker 	 /*
329*5e7646d2SAndroid Build Coastguard Worker 	  * Pull the name from the URI...
330*5e7646d2SAndroid Build Coastguard Worker 	  */
331*5e7646d2SAndroid Build Coastguard Worker 
332*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(current_dest, strrchr(attr->values[0].string.text, '/') + 1,
333*5e7646d2SAndroid Build Coastguard Worker 	          sizeof(current_dest));
334*5e7646d2SAndroid Build Coastguard Worker           dest = current_dest;
335*5e7646d2SAndroid Build Coastguard Worker 	}
336*5e7646d2SAndroid Build Coastguard Worker 
337*5e7646d2SAndroid Build Coastguard Worker         ippDelete(response);
338*5e7646d2SAndroid Build Coastguard Worker       }
339*5e7646d2SAndroid Build Coastguard Worker 
340*5e7646d2SAndroid Build Coastguard Worker       if (!dest)
341*5e7646d2SAndroid Build Coastguard Worker       {
342*5e7646d2SAndroid Build Coastguard Worker        /*
343*5e7646d2SAndroid Build Coastguard Worker         * Couldn't get the current destination...
344*5e7646d2SAndroid Build Coastguard Worker 	*/
345*5e7646d2SAndroid Build Coastguard Worker 
346*5e7646d2SAndroid Build Coastguard Worker         cgiStartHTML(cgiText(_("Move Job")));
347*5e7646d2SAndroid Build Coastguard Worker 	cgiShowIPPError(_("Unable to find destination for job"));
348*5e7646d2SAndroid Build Coastguard Worker 	cgiEndHTML();
349*5e7646d2SAndroid Build Coastguard Worker 	return;
350*5e7646d2SAndroid Build Coastguard Worker       }
351*5e7646d2SAndroid Build Coastguard Worker     }
352*5e7646d2SAndroid Build Coastguard Worker 
353*5e7646d2SAndroid Build Coastguard Worker    /*
354*5e7646d2SAndroid Build Coastguard Worker     * Get the list of available destinations...
355*5e7646d2SAndroid Build Coastguard Worker     */
356*5e7646d2SAndroid Build Coastguard Worker 
357*5e7646d2SAndroid Build Coastguard Worker     request = ippNewRequest(CUPS_GET_PRINTERS);
358*5e7646d2SAndroid Build Coastguard Worker 
359*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
360*5e7646d2SAndroid Build Coastguard Worker                  "requested-attributes", NULL, "printer-uri-supported");
361*5e7646d2SAndroid Build Coastguard Worker 
362*5e7646d2SAndroid Build Coastguard Worker     if (user)
363*5e7646d2SAndroid Build Coastguard Worker       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
364*5e7646d2SAndroid Build Coastguard Worker 		   "requesting-user-name", NULL, user);
365*5e7646d2SAndroid Build Coastguard Worker 
366*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type",
367*5e7646d2SAndroid Build Coastguard Worker                   CUPS_PRINTER_LOCAL);
368*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask",
369*5e7646d2SAndroid Build Coastguard Worker                   CUPS_PRINTER_SCANNER);
370*5e7646d2SAndroid Build Coastguard Worker 
371*5e7646d2SAndroid Build Coastguard Worker     if ((response = cupsDoRequest(http, request, "/")) != NULL)
372*5e7646d2SAndroid Build Coastguard Worker     {
373*5e7646d2SAndroid Build Coastguard Worker       for (i = 0, attr = ippFindAttribute(response, "printer-uri-supported",
374*5e7646d2SAndroid Build Coastguard Worker                                           IPP_TAG_URI);
375*5e7646d2SAndroid Build Coastguard Worker            attr;
376*5e7646d2SAndroid Build Coastguard Worker 	   attr = ippFindNextAttribute(response, "printer-uri-supported",
377*5e7646d2SAndroid Build Coastguard Worker 	                               IPP_TAG_URI))
378*5e7646d2SAndroid Build Coastguard Worker       {
379*5e7646d2SAndroid Build Coastguard Worker        /*
380*5e7646d2SAndroid Build Coastguard Worker 	* Pull the name from the URI...
381*5e7646d2SAndroid Build Coastguard Worker 	*/
382*5e7646d2SAndroid Build Coastguard Worker 
383*5e7646d2SAndroid Build Coastguard Worker 	name = strrchr(attr->values[0].string.text, '/') + 1;
384*5e7646d2SAndroid Build Coastguard Worker 
385*5e7646d2SAndroid Build Coastguard Worker        /*
386*5e7646d2SAndroid Build Coastguard Worker         * If the name is not the same as the current destination, add it!
387*5e7646d2SAndroid Build Coastguard Worker 	*/
388*5e7646d2SAndroid Build Coastguard Worker 
389*5e7646d2SAndroid Build Coastguard Worker         if (_cups_strcasecmp(name, dest))
390*5e7646d2SAndroid Build Coastguard Worker 	{
391*5e7646d2SAndroid Build Coastguard Worker 	  cgiSetArray("JOB_PRINTER_URI", i, attr->values[0].string.text);
392*5e7646d2SAndroid Build Coastguard Worker 	  cgiSetArray("JOB_PRINTER_NAME", i, name);
393*5e7646d2SAndroid Build Coastguard Worker 	  i ++;
394*5e7646d2SAndroid Build Coastguard Worker 	}
395*5e7646d2SAndroid Build Coastguard Worker       }
396*5e7646d2SAndroid Build Coastguard Worker 
397*5e7646d2SAndroid Build Coastguard Worker       ippDelete(response);
398*5e7646d2SAndroid Build Coastguard Worker     }
399*5e7646d2SAndroid Build Coastguard Worker 
400*5e7646d2SAndroid Build Coastguard Worker    /*
401*5e7646d2SAndroid Build Coastguard Worker     * Show the form...
402*5e7646d2SAndroid Build Coastguard Worker     */
403*5e7646d2SAndroid Build Coastguard Worker 
404*5e7646d2SAndroid Build Coastguard Worker     if (job_id)
405*5e7646d2SAndroid Build Coastguard Worker       cgiStartHTML(cgiText(_("Move Job")));
406*5e7646d2SAndroid Build Coastguard Worker     else
407*5e7646d2SAndroid Build Coastguard Worker       cgiStartHTML(cgiText(_("Move All Jobs")));
408*5e7646d2SAndroid Build Coastguard Worker 
409*5e7646d2SAndroid Build Coastguard Worker     if (cgiGetSize("JOB_PRINTER_NAME") > 0)
410*5e7646d2SAndroid Build Coastguard Worker       cgiCopyTemplateLang("job-move.tmpl");
411*5e7646d2SAndroid Build Coastguard Worker     else
412*5e7646d2SAndroid Build Coastguard Worker     {
413*5e7646d2SAndroid Build Coastguard Worker       if (job_id)
414*5e7646d2SAndroid Build Coastguard Worker 	cgiSetVariable("MESSAGE", cgiText(_("Unable to move job")));
415*5e7646d2SAndroid Build Coastguard Worker       else
416*5e7646d2SAndroid Build Coastguard Worker 	cgiSetVariable("MESSAGE", cgiText(_("Unable to move jobs")));
417*5e7646d2SAndroid Build Coastguard Worker 
418*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("ERROR", cgiText(_("No destinations added.")));
419*5e7646d2SAndroid Build Coastguard Worker       cgiCopyTemplateLang("error.tmpl");
420*5e7646d2SAndroid Build Coastguard Worker     }
421*5e7646d2SAndroid Build Coastguard Worker   }
422*5e7646d2SAndroid Build Coastguard Worker   else
423*5e7646d2SAndroid Build Coastguard Worker   {
424*5e7646d2SAndroid Build Coastguard Worker    /*
425*5e7646d2SAndroid Build Coastguard Worker     * Try moving the job or jobs...
426*5e7646d2SAndroid Build Coastguard Worker     */
427*5e7646d2SAndroid Build Coastguard Worker 
428*5e7646d2SAndroid Build Coastguard Worker     char	uri[1024],		/* Job/printer URI */
429*5e7646d2SAndroid Build Coastguard Worker 		resource[1024],		/* Post resource */
430*5e7646d2SAndroid Build Coastguard Worker 		refresh[1024];		/* Refresh URL */
431*5e7646d2SAndroid Build Coastguard Worker     const char	*job_printer_name;	/* New printer name */
432*5e7646d2SAndroid Build Coastguard Worker 
433*5e7646d2SAndroid Build Coastguard Worker 
434*5e7646d2SAndroid Build Coastguard Worker     request = ippNewRequest(CUPS_MOVE_JOB);
435*5e7646d2SAndroid Build Coastguard Worker 
436*5e7646d2SAndroid Build Coastguard Worker     if (job_id)
437*5e7646d2SAndroid Build Coastguard Worker     {
438*5e7646d2SAndroid Build Coastguard Worker      /*
439*5e7646d2SAndroid Build Coastguard Worker       * Move 1 job...
440*5e7646d2SAndroid Build Coastguard Worker       */
441*5e7646d2SAndroid Build Coastguard Worker 
442*5e7646d2SAndroid Build Coastguard Worker       snprintf(resource, sizeof(resource), "/jobs/%d", job_id);
443*5e7646d2SAndroid Build Coastguard Worker 
444*5e7646d2SAndroid Build Coastguard Worker       snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
445*5e7646d2SAndroid Build Coastguard Worker       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
446*5e7646d2SAndroid Build Coastguard Worker                    NULL, uri);
447*5e7646d2SAndroid Build Coastguard Worker     }
448*5e7646d2SAndroid Build Coastguard Worker     else
449*5e7646d2SAndroid Build Coastguard Worker     {
450*5e7646d2SAndroid Build Coastguard Worker      /*
451*5e7646d2SAndroid Build Coastguard Worker       * Move all active jobs on a destination...
452*5e7646d2SAndroid Build Coastguard Worker       */
453*5e7646d2SAndroid Build Coastguard Worker 
454*5e7646d2SAndroid Build Coastguard Worker       snprintf(resource, sizeof(resource), "/%s/%s",
455*5e7646d2SAndroid Build Coastguard Worker                cgiGetVariable("SECTION"), dest);
456*5e7646d2SAndroid Build Coastguard Worker 
457*5e7646d2SAndroid Build Coastguard Worker       httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
458*5e7646d2SAndroid Build Coastguard Worker                        "localhost", ippPort(), "/%s/%s",
459*5e7646d2SAndroid Build Coastguard Worker 		       cgiGetVariable("SECTION"), dest);
460*5e7646d2SAndroid Build Coastguard Worker       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
461*5e7646d2SAndroid Build Coastguard Worker                    NULL, uri);
462*5e7646d2SAndroid Build Coastguard Worker     }
463*5e7646d2SAndroid Build Coastguard Worker 
464*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-printer-uri",
465*5e7646d2SAndroid Build Coastguard Worker                  NULL, job_printer_uri);
466*5e7646d2SAndroid Build Coastguard Worker 
467*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
468*5e7646d2SAndroid Build Coastguard Worker                  "requesting-user-name", NULL, user);
469*5e7646d2SAndroid Build Coastguard Worker 
470*5e7646d2SAndroid Build Coastguard Worker     ippDelete(cupsDoRequest(http, request, resource));
471*5e7646d2SAndroid Build Coastguard Worker 
472*5e7646d2SAndroid Build Coastguard Worker    /*
473*5e7646d2SAndroid Build Coastguard Worker     * Show the results...
474*5e7646d2SAndroid Build Coastguard Worker     */
475*5e7646d2SAndroid Build Coastguard Worker 
476*5e7646d2SAndroid Build Coastguard Worker     job_printer_name = strrchr(job_printer_uri, '/') + 1;
477*5e7646d2SAndroid Build Coastguard Worker 
478*5e7646d2SAndroid Build Coastguard Worker     if (cupsLastError() <= IPP_OK_CONFLICT)
479*5e7646d2SAndroid Build Coastguard Worker     {
480*5e7646d2SAndroid Build Coastguard Worker       const char *path = strstr(job_printer_uri, "/printers/");
481*5e7646d2SAndroid Build Coastguard Worker       if (!path)
482*5e7646d2SAndroid Build Coastguard Worker       {
483*5e7646d2SAndroid Build Coastguard Worker         path = strstr(job_printer_uri, "/classes/");
484*5e7646d2SAndroid Build Coastguard Worker         cgiSetVariable("IS_CLASS", "YES");
485*5e7646d2SAndroid Build Coastguard Worker       }
486*5e7646d2SAndroid Build Coastguard Worker 
487*5e7646d2SAndroid Build Coastguard Worker       if (path)
488*5e7646d2SAndroid Build Coastguard Worker       {
489*5e7646d2SAndroid Build Coastguard Worker         cgiFormEncode(uri, path, sizeof(uri));
490*5e7646d2SAndroid Build Coastguard Worker         snprintf(refresh, sizeof(refresh), "2;URL=%s", uri);
491*5e7646d2SAndroid Build Coastguard Worker 	cgiSetVariable("refresh_page", refresh);
492*5e7646d2SAndroid Build Coastguard Worker       }
493*5e7646d2SAndroid Build Coastguard Worker     }
494*5e7646d2SAndroid Build Coastguard Worker 
495*5e7646d2SAndroid Build Coastguard Worker     if (job_id)
496*5e7646d2SAndroid Build Coastguard Worker       cgiStartHTML(cgiText(_("Move Job")));
497*5e7646d2SAndroid Build Coastguard Worker     else
498*5e7646d2SAndroid Build Coastguard Worker       cgiStartHTML(cgiText(_("Move All Jobs")));
499*5e7646d2SAndroid Build Coastguard Worker 
500*5e7646d2SAndroid Build Coastguard Worker     if (cupsLastError() > IPP_OK_CONFLICT)
501*5e7646d2SAndroid Build Coastguard Worker     {
502*5e7646d2SAndroid Build Coastguard Worker       if (job_id)
503*5e7646d2SAndroid Build Coastguard Worker 	cgiShowIPPError(_("Unable to move job"));
504*5e7646d2SAndroid Build Coastguard Worker       else
505*5e7646d2SAndroid Build Coastguard Worker         cgiShowIPPError(_("Unable to move jobs"));
506*5e7646d2SAndroid Build Coastguard Worker     }
507*5e7646d2SAndroid Build Coastguard Worker     else
508*5e7646d2SAndroid Build Coastguard Worker     {
509*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("JOB_PRINTER_NAME", job_printer_name);
510*5e7646d2SAndroid Build Coastguard Worker       cgiCopyTemplateLang("job-moved.tmpl");
511*5e7646d2SAndroid Build Coastguard Worker     }
512*5e7646d2SAndroid Build Coastguard Worker   }
513*5e7646d2SAndroid Build Coastguard Worker 
514*5e7646d2SAndroid Build Coastguard Worker   cgiEndHTML();
515*5e7646d2SAndroid Build Coastguard Worker }
516*5e7646d2SAndroid Build Coastguard Worker 
517*5e7646d2SAndroid Build Coastguard Worker 
518*5e7646d2SAndroid Build Coastguard Worker /*
519*5e7646d2SAndroid Build Coastguard Worker  * 'cgiPrintCommand()' - Print a CUPS command job.
520*5e7646d2SAndroid Build Coastguard Worker  */
521*5e7646d2SAndroid Build Coastguard Worker 
522*5e7646d2SAndroid Build Coastguard Worker void
cgiPrintCommand(http_t * http,const char * dest,const char * command,const char * title)523*5e7646d2SAndroid Build Coastguard Worker cgiPrintCommand(http_t     *http,	/* I - Connection to server */
524*5e7646d2SAndroid Build Coastguard Worker                 const char *dest,	/* I - Destination printer */
525*5e7646d2SAndroid Build Coastguard Worker                 const char *command,	/* I - Command to send */
526*5e7646d2SAndroid Build Coastguard Worker 		const char *title)	/* I - Page/job title */
527*5e7646d2SAndroid Build Coastguard Worker {
528*5e7646d2SAndroid Build Coastguard Worker   int		job_id;			/* Command file job */
529*5e7646d2SAndroid Build Coastguard Worker   char		uri[HTTP_MAX_URI],	/* Job URI */
530*5e7646d2SAndroid Build Coastguard Worker 		resource[1024],		/* Printer resource path */
531*5e7646d2SAndroid Build Coastguard Worker 		refresh[1024],		/* Refresh URL */
532*5e7646d2SAndroid Build Coastguard Worker 		command_file[1024];	/* Command "file" */
533*5e7646d2SAndroid Build Coastguard Worker   http_status_t	status;			/* Document status */
534*5e7646d2SAndroid Build Coastguard Worker   cups_option_t	hold_option;		/* job-hold-until option */
535*5e7646d2SAndroid Build Coastguard Worker   const char	*user;			/* User name */
536*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request,		/* Get-Job-Attributes request */
537*5e7646d2SAndroid Build Coastguard Worker 		*response;		/* Get-Job-Attributes response */
538*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t *attr;		/* Current job attribute */
539*5e7646d2SAndroid Build Coastguard Worker   static const char * const job_attrs[] =/* Job attributes we want */
540*5e7646d2SAndroid Build Coastguard Worker 		{
541*5e7646d2SAndroid Build Coastguard Worker 		  "job-state",
542*5e7646d2SAndroid Build Coastguard Worker 		  "job-printer-state-message"
543*5e7646d2SAndroid Build Coastguard Worker 		};
544*5e7646d2SAndroid Build Coastguard Worker 
545*5e7646d2SAndroid Build Coastguard Worker 
546*5e7646d2SAndroid Build Coastguard Worker  /*
547*5e7646d2SAndroid Build Coastguard Worker   * Create the CUPS command file...
548*5e7646d2SAndroid Build Coastguard Worker   */
549*5e7646d2SAndroid Build Coastguard Worker 
550*5e7646d2SAndroid Build Coastguard Worker   snprintf(command_file, sizeof(command_file), "#CUPS-COMMAND\n%s\n", command);
551*5e7646d2SAndroid Build Coastguard Worker 
552*5e7646d2SAndroid Build Coastguard Worker  /*
553*5e7646d2SAndroid Build Coastguard Worker   * Show status...
554*5e7646d2SAndroid Build Coastguard Worker   */
555*5e7646d2SAndroid Build Coastguard Worker 
556*5e7646d2SAndroid Build Coastguard Worker   if (cgiSupportsMultipart())
557*5e7646d2SAndroid Build Coastguard Worker   {
558*5e7646d2SAndroid Build Coastguard Worker     cgiStartMultipart();
559*5e7646d2SAndroid Build Coastguard Worker     cgiStartHTML(title);
560*5e7646d2SAndroid Build Coastguard Worker     cgiCopyTemplateLang("command.tmpl");
561*5e7646d2SAndroid Build Coastguard Worker     cgiEndHTML();
562*5e7646d2SAndroid Build Coastguard Worker     fflush(stdout);
563*5e7646d2SAndroid Build Coastguard Worker   }
564*5e7646d2SAndroid Build Coastguard Worker 
565*5e7646d2SAndroid Build Coastguard Worker  /*
566*5e7646d2SAndroid Build Coastguard Worker   * Send the command file job...
567*5e7646d2SAndroid Build Coastguard Worker   */
568*5e7646d2SAndroid Build Coastguard Worker 
569*5e7646d2SAndroid Build Coastguard Worker   hold_option.name  = "job-hold-until";
570*5e7646d2SAndroid Build Coastguard Worker   hold_option.value = "no-hold";
571*5e7646d2SAndroid Build Coastguard Worker 
572*5e7646d2SAndroid Build Coastguard Worker   if ((user = getenv("REMOTE_USER")) != NULL)
573*5e7646d2SAndroid Build Coastguard Worker     cupsSetUser(user);
574*5e7646d2SAndroid Build Coastguard Worker   else
575*5e7646d2SAndroid Build Coastguard Worker     cupsSetUser("anonymous");
576*5e7646d2SAndroid Build Coastguard Worker 
577*5e7646d2SAndroid Build Coastguard Worker   if ((job_id = cupsCreateJob(http, dest, title,
578*5e7646d2SAndroid Build Coastguard Worker 			      1, &hold_option)) < 1)
579*5e7646d2SAndroid Build Coastguard Worker   {
580*5e7646d2SAndroid Build Coastguard Worker     cgiSetVariable("MESSAGE", cgiText(_("Unable to send command to printer driver")));
581*5e7646d2SAndroid Build Coastguard Worker     cgiSetVariable("ERROR", cupsLastErrorString());
582*5e7646d2SAndroid Build Coastguard Worker     cgiStartHTML(title);
583*5e7646d2SAndroid Build Coastguard Worker     cgiCopyTemplateLang("error.tmpl");
584*5e7646d2SAndroid Build Coastguard Worker     cgiEndHTML();
585*5e7646d2SAndroid Build Coastguard Worker 
586*5e7646d2SAndroid Build Coastguard Worker     if (cgiSupportsMultipart())
587*5e7646d2SAndroid Build Coastguard Worker       cgiEndMultipart();
588*5e7646d2SAndroid Build Coastguard Worker     return;
589*5e7646d2SAndroid Build Coastguard Worker   }
590*5e7646d2SAndroid Build Coastguard Worker 
591*5e7646d2SAndroid Build Coastguard Worker   status = cupsStartDocument(http, dest, job_id, NULL, CUPS_FORMAT_COMMAND, 1);
592*5e7646d2SAndroid Build Coastguard Worker   if (status == HTTP_CONTINUE)
593*5e7646d2SAndroid Build Coastguard Worker     status = cupsWriteRequestData(http, command_file,
594*5e7646d2SAndroid Build Coastguard Worker 				  strlen(command_file));
595*5e7646d2SAndroid Build Coastguard Worker   if (status == HTTP_CONTINUE)
596*5e7646d2SAndroid Build Coastguard Worker     cupsFinishDocument(http, dest);
597*5e7646d2SAndroid Build Coastguard Worker 
598*5e7646d2SAndroid Build Coastguard Worker   if (cupsLastError() >= IPP_REDIRECTION_OTHER_SITE)
599*5e7646d2SAndroid Build Coastguard Worker   {
600*5e7646d2SAndroid Build Coastguard Worker     cgiSetVariable("MESSAGE", cgiText(_("Unable to send command to printer driver")));
601*5e7646d2SAndroid Build Coastguard Worker     cgiSetVariable("ERROR", cupsLastErrorString());
602*5e7646d2SAndroid Build Coastguard Worker     cgiStartHTML(title);
603*5e7646d2SAndroid Build Coastguard Worker     cgiCopyTemplateLang("error.tmpl");
604*5e7646d2SAndroid Build Coastguard Worker     cgiEndHTML();
605*5e7646d2SAndroid Build Coastguard Worker 
606*5e7646d2SAndroid Build Coastguard Worker     if (cgiSupportsMultipart())
607*5e7646d2SAndroid Build Coastguard Worker       cgiEndMultipart();
608*5e7646d2SAndroid Build Coastguard Worker 
609*5e7646d2SAndroid Build Coastguard Worker     cupsCancelJob(dest, job_id);
610*5e7646d2SAndroid Build Coastguard Worker     return;
611*5e7646d2SAndroid Build Coastguard Worker   }
612*5e7646d2SAndroid Build Coastguard Worker 
613*5e7646d2SAndroid Build Coastguard Worker  /*
614*5e7646d2SAndroid Build Coastguard Worker   * Wait for the job to complete...
615*5e7646d2SAndroid Build Coastguard Worker   */
616*5e7646d2SAndroid Build Coastguard Worker 
617*5e7646d2SAndroid Build Coastguard Worker   if (cgiSupportsMultipart())
618*5e7646d2SAndroid Build Coastguard Worker   {
619*5e7646d2SAndroid Build Coastguard Worker     for (;;)
620*5e7646d2SAndroid Build Coastguard Worker     {
621*5e7646d2SAndroid Build Coastguard Worker      /*
622*5e7646d2SAndroid Build Coastguard Worker       * Get the current job state...
623*5e7646d2SAndroid Build Coastguard Worker       */
624*5e7646d2SAndroid Build Coastguard Worker 
625*5e7646d2SAndroid Build Coastguard Worker       snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
626*5e7646d2SAndroid Build Coastguard Worker       request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES);
627*5e7646d2SAndroid Build Coastguard Worker       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
628*5e7646d2SAndroid Build Coastguard Worker 		   NULL, uri);
629*5e7646d2SAndroid Build Coastguard Worker       if (user)
630*5e7646d2SAndroid Build Coastguard Worker 	ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
631*5e7646d2SAndroid Build Coastguard Worker 		     "requesting-user-name", NULL, user);
632*5e7646d2SAndroid Build Coastguard Worker       ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
633*5e7646d2SAndroid Build Coastguard Worker 		    "requested-attributes", 2, NULL, job_attrs);
634*5e7646d2SAndroid Build Coastguard Worker 
635*5e7646d2SAndroid Build Coastguard Worker       if ((response = cupsDoRequest(http, request, "/")) != NULL)
636*5e7646d2SAndroid Build Coastguard Worker 	cgiSetIPPVars(response, NULL, NULL, NULL, 0);
637*5e7646d2SAndroid Build Coastguard Worker 
638*5e7646d2SAndroid Build Coastguard Worker       attr = ippFindAttribute(response, "job-state", IPP_TAG_ENUM);
639*5e7646d2SAndroid Build Coastguard Worker       if (!attr || attr->values[0].integer >= IPP_JOB_STOPPED ||
640*5e7646d2SAndroid Build Coastguard Worker           attr->values[0].integer == IPP_JOB_HELD)
641*5e7646d2SAndroid Build Coastguard Worker       {
642*5e7646d2SAndroid Build Coastguard Worker 	ippDelete(response);
643*5e7646d2SAndroid Build Coastguard Worker 	break;
644*5e7646d2SAndroid Build Coastguard Worker       }
645*5e7646d2SAndroid Build Coastguard Worker 
646*5e7646d2SAndroid Build Coastguard Worker      /*
647*5e7646d2SAndroid Build Coastguard Worker       * Job not complete, so update the status...
648*5e7646d2SAndroid Build Coastguard Worker       */
649*5e7646d2SAndroid Build Coastguard Worker 
650*5e7646d2SAndroid Build Coastguard Worker       ippDelete(response);
651*5e7646d2SAndroid Build Coastguard Worker 
652*5e7646d2SAndroid Build Coastguard Worker       cgiStartHTML(title);
653*5e7646d2SAndroid Build Coastguard Worker       cgiCopyTemplateLang("command.tmpl");
654*5e7646d2SAndroid Build Coastguard Worker       cgiEndHTML();
655*5e7646d2SAndroid Build Coastguard Worker       fflush(stdout);
656*5e7646d2SAndroid Build Coastguard Worker 
657*5e7646d2SAndroid Build Coastguard Worker       sleep(5);
658*5e7646d2SAndroid Build Coastguard Worker     }
659*5e7646d2SAndroid Build Coastguard Worker   }
660*5e7646d2SAndroid Build Coastguard Worker 
661*5e7646d2SAndroid Build Coastguard Worker  /*
662*5e7646d2SAndroid Build Coastguard Worker   * Send the final page that reloads the printer's page...
663*5e7646d2SAndroid Build Coastguard Worker   */
664*5e7646d2SAndroid Build Coastguard Worker 
665*5e7646d2SAndroid Build Coastguard Worker   snprintf(resource, sizeof(resource), "/printers/%s", dest);
666*5e7646d2SAndroid Build Coastguard Worker 
667*5e7646d2SAndroid Build Coastguard Worker   cgiFormEncode(uri, resource, sizeof(uri));
668*5e7646d2SAndroid Build Coastguard Worker   snprintf(refresh, sizeof(refresh), "5;URL=%s", uri);
669*5e7646d2SAndroid Build Coastguard Worker   cgiSetVariable("refresh_page", refresh);
670*5e7646d2SAndroid Build Coastguard Worker 
671*5e7646d2SAndroid Build Coastguard Worker   cgiStartHTML(title);
672*5e7646d2SAndroid Build Coastguard Worker   cgiCopyTemplateLang("command.tmpl");
673*5e7646d2SAndroid Build Coastguard Worker   cgiEndHTML();
674*5e7646d2SAndroid Build Coastguard Worker 
675*5e7646d2SAndroid Build Coastguard Worker   if (cgiSupportsMultipart())
676*5e7646d2SAndroid Build Coastguard Worker     cgiEndMultipart();
677*5e7646d2SAndroid Build Coastguard Worker }
678*5e7646d2SAndroid Build Coastguard Worker 
679*5e7646d2SAndroid Build Coastguard Worker 
680*5e7646d2SAndroid Build Coastguard Worker /*
681*5e7646d2SAndroid Build Coastguard Worker  * 'cgiPrintTestPage()' - Print a test page.
682*5e7646d2SAndroid Build Coastguard Worker  */
683*5e7646d2SAndroid Build Coastguard Worker 
684*5e7646d2SAndroid Build Coastguard Worker void
cgiPrintTestPage(http_t * http,const char * dest)685*5e7646d2SAndroid Build Coastguard Worker cgiPrintTestPage(http_t     *http,	/* I - Connection to server */
686*5e7646d2SAndroid Build Coastguard Worker                  const char *dest)	/* I - Destination printer/class */
687*5e7646d2SAndroid Build Coastguard Worker {
688*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request,		/* IPP request */
689*5e7646d2SAndroid Build Coastguard Worker 		*response;		/* IPP response */
690*5e7646d2SAndroid Build Coastguard Worker   char		uri[HTTP_MAX_URI],	/* Printer URI */
691*5e7646d2SAndroid Build Coastguard Worker 		resource[1024],		/* POST resource path */
692*5e7646d2SAndroid Build Coastguard Worker 		refresh[1024],		/* Refresh URL */
693*5e7646d2SAndroid Build Coastguard Worker 		filename[1024];		/* Test page filename */
694*5e7646d2SAndroid Build Coastguard Worker   const char	*datadir;		/* CUPS_DATADIR env var */
695*5e7646d2SAndroid Build Coastguard Worker   const char	*user;			/* Username */
696*5e7646d2SAndroid Build Coastguard Worker 
697*5e7646d2SAndroid Build Coastguard Worker 
698*5e7646d2SAndroid Build Coastguard Worker  /*
699*5e7646d2SAndroid Build Coastguard Worker   * See who is logged in...
700*5e7646d2SAndroid Build Coastguard Worker   */
701*5e7646d2SAndroid Build Coastguard Worker 
702*5e7646d2SAndroid Build Coastguard Worker   user = getenv("REMOTE_USER");
703*5e7646d2SAndroid Build Coastguard Worker 
704*5e7646d2SAndroid Build Coastguard Worker  /*
705*5e7646d2SAndroid Build Coastguard Worker   * Locate the test page file...
706*5e7646d2SAndroid Build Coastguard Worker   */
707*5e7646d2SAndroid Build Coastguard Worker 
708*5e7646d2SAndroid Build Coastguard Worker   if ((datadir = getenv("CUPS_DATADIR")) == NULL)
709*5e7646d2SAndroid Build Coastguard Worker     datadir = CUPS_DATADIR;
710*5e7646d2SAndroid Build Coastguard Worker 
711*5e7646d2SAndroid Build Coastguard Worker   snprintf(filename, sizeof(filename), "%s/data/testprint", datadir);
712*5e7646d2SAndroid Build Coastguard Worker 
713*5e7646d2SAndroid Build Coastguard Worker  /*
714*5e7646d2SAndroid Build Coastguard Worker   * Point to the printer/class...
715*5e7646d2SAndroid Build Coastguard Worker   */
716*5e7646d2SAndroid Build Coastguard Worker 
717*5e7646d2SAndroid Build Coastguard Worker   snprintf(resource, sizeof(resource), "/%s/%s", cgiGetVariable("SECTION"),
718*5e7646d2SAndroid Build Coastguard Worker            dest);
719*5e7646d2SAndroid Build Coastguard Worker 
720*5e7646d2SAndroid Build Coastguard Worker   httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
721*5e7646d2SAndroid Build Coastguard Worker                    "localhost", ippPort(), "/%s/%s", cgiGetVariable("SECTION"),
722*5e7646d2SAndroid Build Coastguard Worker 		   dest);
723*5e7646d2SAndroid Build Coastguard Worker 
724*5e7646d2SAndroid Build Coastguard Worker  /*
725*5e7646d2SAndroid Build Coastguard Worker   * Build an IPP_PRINT_JOB request, which requires the following
726*5e7646d2SAndroid Build Coastguard Worker   * attributes:
727*5e7646d2SAndroid Build Coastguard Worker   *
728*5e7646d2SAndroid Build Coastguard Worker   *    attributes-charset
729*5e7646d2SAndroid Build Coastguard Worker   *    attributes-natural-language
730*5e7646d2SAndroid Build Coastguard Worker   *    printer-uri
731*5e7646d2SAndroid Build Coastguard Worker   *    requesting-user-name
732*5e7646d2SAndroid Build Coastguard Worker   */
733*5e7646d2SAndroid Build Coastguard Worker 
734*5e7646d2SAndroid Build Coastguard Worker   request = ippNewRequest(IPP_PRINT_JOB);
735*5e7646d2SAndroid Build Coastguard Worker 
736*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
737*5e7646d2SAndroid Build Coastguard Worker                NULL, uri);
738*5e7646d2SAndroid Build Coastguard Worker 
739*5e7646d2SAndroid Build Coastguard Worker   if (user)
740*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
741*5e7646d2SAndroid Build Coastguard Worker 		 "requesting-user-name", NULL, user);
742*5e7646d2SAndroid Build Coastguard Worker 
743*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
744*5e7646d2SAndroid Build Coastguard Worker                NULL, "Test Page");
745*5e7646d2SAndroid Build Coastguard Worker 
746*5e7646d2SAndroid Build Coastguard Worker  /*
747*5e7646d2SAndroid Build Coastguard Worker   * Do the request and get back a response...
748*5e7646d2SAndroid Build Coastguard Worker   */
749*5e7646d2SAndroid Build Coastguard Worker 
750*5e7646d2SAndroid Build Coastguard Worker   if ((response = cupsDoFileRequest(http, request, resource,
751*5e7646d2SAndroid Build Coastguard Worker                                     filename)) != NULL)
752*5e7646d2SAndroid Build Coastguard Worker   {
753*5e7646d2SAndroid Build Coastguard Worker     cgiSetIPPVars(response, NULL, NULL, NULL, 0);
754*5e7646d2SAndroid Build Coastguard Worker 
755*5e7646d2SAndroid Build Coastguard Worker     ippDelete(response);
756*5e7646d2SAndroid Build Coastguard Worker   }
757*5e7646d2SAndroid Build Coastguard Worker 
758*5e7646d2SAndroid Build Coastguard Worker   if (cupsLastError() <= IPP_OK_CONFLICT)
759*5e7646d2SAndroid Build Coastguard Worker   {
760*5e7646d2SAndroid Build Coastguard Worker    /*
761*5e7646d2SAndroid Build Coastguard Worker     * Automatically reload the printer status page...
762*5e7646d2SAndroid Build Coastguard Worker     */
763*5e7646d2SAndroid Build Coastguard Worker 
764*5e7646d2SAndroid Build Coastguard Worker     cgiFormEncode(uri, resource, sizeof(uri));
765*5e7646d2SAndroid Build Coastguard Worker     snprintf(refresh, sizeof(refresh), "2;URL=%s", uri);
766*5e7646d2SAndroid Build Coastguard Worker     cgiSetVariable("refresh_page", refresh);
767*5e7646d2SAndroid Build Coastguard Worker   }
768*5e7646d2SAndroid Build Coastguard Worker   else if (cupsLastError() == IPP_NOT_AUTHORIZED)
769*5e7646d2SAndroid Build Coastguard Worker   {
770*5e7646d2SAndroid Build Coastguard Worker     puts("Status: 401\n");
771*5e7646d2SAndroid Build Coastguard Worker     exit(0);
772*5e7646d2SAndroid Build Coastguard Worker   }
773*5e7646d2SAndroid Build Coastguard Worker 
774*5e7646d2SAndroid Build Coastguard Worker   cgiStartHTML(cgiText(_("Print Test Page")));
775*5e7646d2SAndroid Build Coastguard Worker 
776*5e7646d2SAndroid Build Coastguard Worker   if (cupsLastError() > IPP_OK_CONFLICT)
777*5e7646d2SAndroid Build Coastguard Worker     cgiShowIPPError(_("Unable to print test page"));
778*5e7646d2SAndroid Build Coastguard Worker   else
779*5e7646d2SAndroid Build Coastguard Worker   {
780*5e7646d2SAndroid Build Coastguard Worker     cgiSetVariable("PRINTER_NAME", dest);
781*5e7646d2SAndroid Build Coastguard Worker 
782*5e7646d2SAndroid Build Coastguard Worker     cgiCopyTemplateLang("test-page.tmpl");
783*5e7646d2SAndroid Build Coastguard Worker   }
784*5e7646d2SAndroid Build Coastguard Worker 
785*5e7646d2SAndroid Build Coastguard Worker   cgiEndHTML();
786*5e7646d2SAndroid Build Coastguard Worker }
787*5e7646d2SAndroid Build Coastguard Worker 
788*5e7646d2SAndroid Build Coastguard Worker 
789*5e7646d2SAndroid Build Coastguard Worker /*
790*5e7646d2SAndroid Build Coastguard Worker  * 'cgiRewriteURL()' - Rewrite a printer URI into a web browser URL...
791*5e7646d2SAndroid Build Coastguard Worker  */
792*5e7646d2SAndroid Build Coastguard Worker 
793*5e7646d2SAndroid Build Coastguard Worker char *					/* O - New URL */
cgiRewriteURL(const char * uri,char * url,int urlsize,const char * newresource)794*5e7646d2SAndroid Build Coastguard Worker cgiRewriteURL(const char *uri,		/* I - Current URI */
795*5e7646d2SAndroid Build Coastguard Worker               char       *url,		/* O - New URL */
796*5e7646d2SAndroid Build Coastguard Worker 	      int        urlsize,	/* I - Size of URL buffer */
797*5e7646d2SAndroid Build Coastguard Worker 	      const char *newresource)	/* I - Replacement resource */
798*5e7646d2SAndroid Build Coastguard Worker {
799*5e7646d2SAndroid Build Coastguard Worker   char			scheme[HTTP_MAX_URI],
800*5e7646d2SAndroid Build Coastguard Worker 			userpass[HTTP_MAX_URI],
801*5e7646d2SAndroid Build Coastguard Worker 			hostname[HTTP_MAX_URI],
802*5e7646d2SAndroid Build Coastguard Worker 			rawresource[HTTP_MAX_URI],
803*5e7646d2SAndroid Build Coastguard Worker 			resource[HTTP_MAX_URI],
804*5e7646d2SAndroid Build Coastguard Worker 					/* URI components... */
805*5e7646d2SAndroid Build Coastguard Worker 			*rawptr,	/* Pointer into rawresource */
806*5e7646d2SAndroid Build Coastguard Worker 			*resptr;	/* Pointer into resource */
807*5e7646d2SAndroid Build Coastguard Worker   int			port;		/* Port number */
808*5e7646d2SAndroid Build Coastguard Worker   static int		ishttps = -1;	/* Using encryption? */
809*5e7646d2SAndroid Build Coastguard Worker   static const char	*server;	/* Name of server */
810*5e7646d2SAndroid Build Coastguard Worker   static char		servername[1024];
811*5e7646d2SAndroid Build Coastguard Worker 					/* Local server name */
812*5e7646d2SAndroid Build Coastguard Worker   static const char	hexchars[] = "0123456789ABCDEF";
813*5e7646d2SAndroid Build Coastguard Worker 					/* Hexadecimal conversion characters */
814*5e7646d2SAndroid Build Coastguard Worker 
815*5e7646d2SAndroid Build Coastguard Worker 
816*5e7646d2SAndroid Build Coastguard Worker  /*
817*5e7646d2SAndroid Build Coastguard Worker   * Check if we have been called before...
818*5e7646d2SAndroid Build Coastguard Worker   */
819*5e7646d2SAndroid Build Coastguard Worker 
820*5e7646d2SAndroid Build Coastguard Worker   if (ishttps < 0)
821*5e7646d2SAndroid Build Coastguard Worker   {
822*5e7646d2SAndroid Build Coastguard Worker    /*
823*5e7646d2SAndroid Build Coastguard Worker     * No, initialize static vars for the conversion...
824*5e7646d2SAndroid Build Coastguard Worker     *
825*5e7646d2SAndroid Build Coastguard Worker     * First get the server name associated with the client interface as
826*5e7646d2SAndroid Build Coastguard Worker     * well as the locally configured hostname.  We'll check *both* of
827*5e7646d2SAndroid Build Coastguard Worker     * these to see if the printer URL is local...
828*5e7646d2SAndroid Build Coastguard Worker     */
829*5e7646d2SAndroid Build Coastguard Worker 
830*5e7646d2SAndroid Build Coastguard Worker     if ((server = getenv("SERVER_NAME")) == NULL)
831*5e7646d2SAndroid Build Coastguard Worker       server = "";
832*5e7646d2SAndroid Build Coastguard Worker 
833*5e7646d2SAndroid Build Coastguard Worker     httpGetHostname(NULL, servername, sizeof(servername));
834*5e7646d2SAndroid Build Coastguard Worker 
835*5e7646d2SAndroid Build Coastguard Worker    /*
836*5e7646d2SAndroid Build Coastguard Worker     * Then flag whether we are using SSL on this connection...
837*5e7646d2SAndroid Build Coastguard Worker     */
838*5e7646d2SAndroid Build Coastguard Worker 
839*5e7646d2SAndroid Build Coastguard Worker     ishttps = getenv("HTTPS") != NULL;
840*5e7646d2SAndroid Build Coastguard Worker   }
841*5e7646d2SAndroid Build Coastguard Worker 
842*5e7646d2SAndroid Build Coastguard Worker  /*
843*5e7646d2SAndroid Build Coastguard Worker   * Convert the URI to a URL...
844*5e7646d2SAndroid Build Coastguard Worker   */
845*5e7646d2SAndroid Build Coastguard Worker 
846*5e7646d2SAndroid Build Coastguard Worker   httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass,
847*5e7646d2SAndroid Build Coastguard Worker                   sizeof(userpass), hostname, sizeof(hostname), &port,
848*5e7646d2SAndroid Build Coastguard Worker 		  rawresource, sizeof(rawresource));
849*5e7646d2SAndroid Build Coastguard Worker 
850*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(scheme, "ipp") ||
851*5e7646d2SAndroid Build Coastguard Worker       !strcmp(scheme, "http") ||
852*5e7646d2SAndroid Build Coastguard Worker       !strcmp(scheme, "https"))
853*5e7646d2SAndroid Build Coastguard Worker   {
854*5e7646d2SAndroid Build Coastguard Worker     if (newresource)
855*5e7646d2SAndroid Build Coastguard Worker     {
856*5e7646d2SAndroid Build Coastguard Worker      /*
857*5e7646d2SAndroid Build Coastguard Worker       * Force the specified resource name instead of the one in the URL...
858*5e7646d2SAndroid Build Coastguard Worker       */
859*5e7646d2SAndroid Build Coastguard Worker 
860*5e7646d2SAndroid Build Coastguard Worker       strlcpy(resource, newresource, sizeof(resource));
861*5e7646d2SAndroid Build Coastguard Worker     }
862*5e7646d2SAndroid Build Coastguard Worker     else
863*5e7646d2SAndroid Build Coastguard Worker     {
864*5e7646d2SAndroid Build Coastguard Worker      /*
865*5e7646d2SAndroid Build Coastguard Worker       * Rewrite the resource string so it doesn't contain any
866*5e7646d2SAndroid Build Coastguard Worker       * illegal chars...
867*5e7646d2SAndroid Build Coastguard Worker       */
868*5e7646d2SAndroid Build Coastguard Worker 
869*5e7646d2SAndroid Build Coastguard Worker       for (rawptr = rawresource, resptr = resource; *rawptr; rawptr ++)
870*5e7646d2SAndroid Build Coastguard Worker 	if ((*rawptr & 128) || *rawptr == '%' || *rawptr == ' ' ||
871*5e7646d2SAndroid Build Coastguard Worker 	    *rawptr == '#' || *rawptr == '?' ||
872*5e7646d2SAndroid Build Coastguard Worker 	    *rawptr == '.') /* For MSIE */
873*5e7646d2SAndroid Build Coastguard Worker 	{
874*5e7646d2SAndroid Build Coastguard Worker 	  if (resptr < (resource + sizeof(resource) - 3))
875*5e7646d2SAndroid Build Coastguard Worker 	  {
876*5e7646d2SAndroid Build Coastguard Worker 	    *resptr++ = '%';
877*5e7646d2SAndroid Build Coastguard Worker 	    *resptr++ = hexchars[(*rawptr >> 4) & 15];
878*5e7646d2SAndroid Build Coastguard Worker 	    *resptr++ = hexchars[*rawptr & 15];
879*5e7646d2SAndroid Build Coastguard Worker 	  }
880*5e7646d2SAndroid Build Coastguard Worker 	}
881*5e7646d2SAndroid Build Coastguard Worker 	else if (resptr < (resource + sizeof(resource) - 1))
882*5e7646d2SAndroid Build Coastguard Worker 	  *resptr++ = *rawptr;
883*5e7646d2SAndroid Build Coastguard Worker 
884*5e7646d2SAndroid Build Coastguard Worker       *resptr = '\0';
885*5e7646d2SAndroid Build Coastguard Worker     }
886*5e7646d2SAndroid Build Coastguard Worker 
887*5e7646d2SAndroid Build Coastguard Worker    /*
888*5e7646d2SAndroid Build Coastguard Worker     * Map local access to a local URI...
889*5e7646d2SAndroid Build Coastguard Worker     */
890*5e7646d2SAndroid Build Coastguard Worker 
891*5e7646d2SAndroid Build Coastguard Worker     if (!_cups_strcasecmp(hostname, "127.0.0.1") ||
892*5e7646d2SAndroid Build Coastguard Worker 	!_cups_strcasecmp(hostname, "[::1]") ||
893*5e7646d2SAndroid Build Coastguard Worker 	!_cups_strcasecmp(hostname, "localhost") ||
894*5e7646d2SAndroid Build Coastguard Worker 	!_cups_strncasecmp(hostname, "localhost.", 10) ||
895*5e7646d2SAndroid Build Coastguard Worker 	!_cups_strcasecmp(hostname, server) ||
896*5e7646d2SAndroid Build Coastguard Worker 	!_cups_strcasecmp(hostname, servername))
897*5e7646d2SAndroid Build Coastguard Worker     {
898*5e7646d2SAndroid Build Coastguard Worker      /*
899*5e7646d2SAndroid Build Coastguard Worker       * Make URI relative to the current server...
900*5e7646d2SAndroid Build Coastguard Worker       */
901*5e7646d2SAndroid Build Coastguard Worker 
902*5e7646d2SAndroid Build Coastguard Worker       strlcpy(url, resource, (size_t)urlsize);
903*5e7646d2SAndroid Build Coastguard Worker     }
904*5e7646d2SAndroid Build Coastguard Worker     else
905*5e7646d2SAndroid Build Coastguard Worker     {
906*5e7646d2SAndroid Build Coastguard Worker      /*
907*5e7646d2SAndroid Build Coastguard Worker       * Rewrite URI with HTTP/HTTPS scheme...
908*5e7646d2SAndroid Build Coastguard Worker       */
909*5e7646d2SAndroid Build Coastguard Worker 
910*5e7646d2SAndroid Build Coastguard Worker       if (userpass[0])
911*5e7646d2SAndroid Build Coastguard Worker 	snprintf(url, (size_t)urlsize, "%s://%s@%s:%d%s", ishttps ? "https" : "http", userpass, hostname, port, resource);
912*5e7646d2SAndroid Build Coastguard Worker       else
913*5e7646d2SAndroid Build Coastguard Worker 	snprintf(url, (size_t)urlsize, "%s://%s:%d%s", ishttps ? "https" : "http", hostname, port, resource);
914*5e7646d2SAndroid Build Coastguard Worker     }
915*5e7646d2SAndroid Build Coastguard Worker   }
916*5e7646d2SAndroid Build Coastguard Worker   else
917*5e7646d2SAndroid Build Coastguard Worker     strlcpy(url, uri, (size_t)urlsize);
918*5e7646d2SAndroid Build Coastguard Worker 
919*5e7646d2SAndroid Build Coastguard Worker   return (url);
920*5e7646d2SAndroid Build Coastguard Worker }
921*5e7646d2SAndroid Build Coastguard Worker 
922*5e7646d2SAndroid Build Coastguard Worker 
923*5e7646d2SAndroid Build Coastguard Worker /*
924*5e7646d2SAndroid Build Coastguard Worker  * 'cgiSetIPPObjectVars()' - Set CGI variables from an IPP object.
925*5e7646d2SAndroid Build Coastguard Worker  */
926*5e7646d2SAndroid Build Coastguard Worker 
927*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *			/* O - Next object */
cgiSetIPPObjectVars(ipp_attribute_t * obj,const char * prefix,int element)928*5e7646d2SAndroid Build Coastguard Worker cgiSetIPPObjectVars(
929*5e7646d2SAndroid Build Coastguard Worker     ipp_attribute_t *obj,		/* I - Response data to be copied... */
930*5e7646d2SAndroid Build Coastguard Worker     const char      *prefix,		/* I - Prefix for name or NULL */
931*5e7646d2SAndroid Build Coastguard Worker     int             element)		/* I - Parent element number */
932*5e7646d2SAndroid Build Coastguard Worker {
933*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t	*attr;		/* Attribute in response... */
934*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
935*5e7646d2SAndroid Build Coastguard Worker   char			name[1024],	/* Name of attribute */
936*5e7646d2SAndroid Build Coastguard Worker 			*nameptr,	/* Pointer into name */
937*5e7646d2SAndroid Build Coastguard Worker 			value[16384],	/* Value(s) */
938*5e7646d2SAndroid Build Coastguard Worker 			*valptr;	/* Pointer into value */
939*5e7646d2SAndroid Build Coastguard Worker 
940*5e7646d2SAndroid Build Coastguard Worker 
941*5e7646d2SAndroid Build Coastguard Worker   fprintf(stderr, "DEBUG2: cgiSetIPPObjectVars(obj=%p, prefix=\"%s\", "
942*5e7646d2SAndroid Build Coastguard Worker                   "element=%d)\n",
943*5e7646d2SAndroid Build Coastguard Worker           obj, prefix ? prefix : "(null)", element);
944*5e7646d2SAndroid Build Coastguard Worker 
945*5e7646d2SAndroid Build Coastguard Worker  /*
946*5e7646d2SAndroid Build Coastguard Worker   * Set common CGI template variables...
947*5e7646d2SAndroid Build Coastguard Worker   */
948*5e7646d2SAndroid Build Coastguard Worker 
949*5e7646d2SAndroid Build Coastguard Worker   if (!prefix)
950*5e7646d2SAndroid Build Coastguard Worker     cgiSetServerVersion();
951*5e7646d2SAndroid Build Coastguard Worker 
952*5e7646d2SAndroid Build Coastguard Worker  /*
953*5e7646d2SAndroid Build Coastguard Worker   * Loop through the attributes and set them for the template...
954*5e7646d2SAndroid Build Coastguard Worker   */
955*5e7646d2SAndroid Build Coastguard Worker 
956*5e7646d2SAndroid Build Coastguard Worker   for (attr = obj; attr && attr->group_tag != IPP_TAG_ZERO; attr = attr->next)
957*5e7646d2SAndroid Build Coastguard Worker   {
958*5e7646d2SAndroid Build Coastguard Worker    /*
959*5e7646d2SAndroid Build Coastguard Worker     * Copy the attribute name, substituting "_" for "-"...
960*5e7646d2SAndroid Build Coastguard Worker     */
961*5e7646d2SAndroid Build Coastguard Worker 
962*5e7646d2SAndroid Build Coastguard Worker     if (!attr->name)
963*5e7646d2SAndroid Build Coastguard Worker       continue;
964*5e7646d2SAndroid Build Coastguard Worker 
965*5e7646d2SAndroid Build Coastguard Worker     if (prefix)
966*5e7646d2SAndroid Build Coastguard Worker     {
967*5e7646d2SAndroid Build Coastguard Worker       snprintf(name, sizeof(name), "%s.", prefix);
968*5e7646d2SAndroid Build Coastguard Worker       nameptr = name + strlen(name);
969*5e7646d2SAndroid Build Coastguard Worker     }
970*5e7646d2SAndroid Build Coastguard Worker     else
971*5e7646d2SAndroid Build Coastguard Worker       nameptr = name;
972*5e7646d2SAndroid Build Coastguard Worker 
973*5e7646d2SAndroid Build Coastguard Worker     for (i = 0; attr->name[i] && nameptr < (name + sizeof(name) - 1); i ++)
974*5e7646d2SAndroid Build Coastguard Worker       if (attr->name[i] == '-')
975*5e7646d2SAndroid Build Coastguard Worker 	*nameptr++ = '_';
976*5e7646d2SAndroid Build Coastguard Worker       else
977*5e7646d2SAndroid Build Coastguard Worker         *nameptr++ = attr->name[i];
978*5e7646d2SAndroid Build Coastguard Worker 
979*5e7646d2SAndroid Build Coastguard Worker     *nameptr = '\0';
980*5e7646d2SAndroid Build Coastguard Worker 
981*5e7646d2SAndroid Build Coastguard Worker    /*
982*5e7646d2SAndroid Build Coastguard Worker     * Add "job_printer_name" variable if we have a "job_printer_uri"
983*5e7646d2SAndroid Build Coastguard Worker     * attribute...
984*5e7646d2SAndroid Build Coastguard Worker     */
985*5e7646d2SAndroid Build Coastguard Worker 
986*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(name, "job_printer_uri"))
987*5e7646d2SAndroid Build Coastguard Worker     {
988*5e7646d2SAndroid Build Coastguard Worker       if ((valptr = strrchr(attr->values[0].string.text, '/')) == NULL)
989*5e7646d2SAndroid Build Coastguard Worker 	valptr = "unknown";
990*5e7646d2SAndroid Build Coastguard Worker       else
991*5e7646d2SAndroid Build Coastguard Worker 	valptr ++;
992*5e7646d2SAndroid Build Coastguard Worker 
993*5e7646d2SAndroid Build Coastguard Worker       cgiSetArray("job_printer_name", element, valptr);
994*5e7646d2SAndroid Build Coastguard Worker     }
995*5e7646d2SAndroid Build Coastguard Worker 
996*5e7646d2SAndroid Build Coastguard Worker    /*
997*5e7646d2SAndroid Build Coastguard Worker     * Localize event names in "notify_events" variable...
998*5e7646d2SAndroid Build Coastguard Worker     */
999*5e7646d2SAndroid Build Coastguard Worker 
1000*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(name, "notify_events"))
1001*5e7646d2SAndroid Build Coastguard Worker     {
1002*5e7646d2SAndroid Build Coastguard Worker       size_t	remaining;		/* Remaining bytes in buffer */
1003*5e7646d2SAndroid Build Coastguard Worker 
1004*5e7646d2SAndroid Build Coastguard Worker 
1005*5e7646d2SAndroid Build Coastguard Worker       value[0] = '\0';
1006*5e7646d2SAndroid Build Coastguard Worker       valptr   = value;
1007*5e7646d2SAndroid Build Coastguard Worker 
1008*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < attr->num_values; i ++)
1009*5e7646d2SAndroid Build Coastguard Worker       {
1010*5e7646d2SAndroid Build Coastguard Worker         if (valptr >= (value + sizeof(value) - 3))
1011*5e7646d2SAndroid Build Coastguard Worker 	  break;
1012*5e7646d2SAndroid Build Coastguard Worker 
1013*5e7646d2SAndroid Build Coastguard Worker         if (i)
1014*5e7646d2SAndroid Build Coastguard Worker 	{
1015*5e7646d2SAndroid Build Coastguard Worker 	  *valptr++ = ',';
1016*5e7646d2SAndroid Build Coastguard Worker 	  *valptr++ = ' ';
1017*5e7646d2SAndroid Build Coastguard Worker         }
1018*5e7646d2SAndroid Build Coastguard Worker 
1019*5e7646d2SAndroid Build Coastguard Worker         remaining = sizeof(value) - (size_t)(valptr - value);
1020*5e7646d2SAndroid Build Coastguard Worker 
1021*5e7646d2SAndroid Build Coastguard Worker         if (!strcmp(attr->values[i].string.text, "printer-stopped"))
1022*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Printer Paused"), remaining);
1023*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "printer-added"))
1024*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Printer Added"), remaining);
1025*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "printer-modified"))
1026*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Printer Modified"), remaining);
1027*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "printer-deleted"))
1028*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Printer Deleted"), remaining);
1029*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "job-created"))
1030*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Job Created"), remaining);
1031*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "job-completed"))
1032*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Job Completed"), remaining);
1033*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "job-stopped"))
1034*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Job Stopped"), remaining);
1035*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "job-config-changed"))
1036*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Job Options Changed"), remaining);
1037*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "server-restarted"))
1038*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Server Restarted"), remaining);
1039*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "server-started"))
1040*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Server Started"), remaining);
1041*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "server-stopped"))
1042*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Server Stopped"), remaining);
1043*5e7646d2SAndroid Build Coastguard Worker 	else if (!strcmp(attr->values[i].string.text, "server-audit"))
1044*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(valptr, _("Server Security Auditing"), remaining);
1045*5e7646d2SAndroid Build Coastguard Worker 	else
1046*5e7646d2SAndroid Build Coastguard Worker           strlcpy(valptr, attr->values[i].string.text, remaining);
1047*5e7646d2SAndroid Build Coastguard Worker 
1048*5e7646d2SAndroid Build Coastguard Worker         valptr += strlen(valptr);
1049*5e7646d2SAndroid Build Coastguard Worker       }
1050*5e7646d2SAndroid Build Coastguard Worker 
1051*5e7646d2SAndroid Build Coastguard Worker       cgiSetArray("notify_events", element, value);
1052*5e7646d2SAndroid Build Coastguard Worker       continue;
1053*5e7646d2SAndroid Build Coastguard Worker     }
1054*5e7646d2SAndroid Build Coastguard Worker 
1055*5e7646d2SAndroid Build Coastguard Worker    /*
1056*5e7646d2SAndroid Build Coastguard Worker     * Add "notify_printer_name" variable if we have a "notify_printer_uri"
1057*5e7646d2SAndroid Build Coastguard Worker     * attribute...
1058*5e7646d2SAndroid Build Coastguard Worker     */
1059*5e7646d2SAndroid Build Coastguard Worker 
1060*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(name, "notify_printer_uri"))
1061*5e7646d2SAndroid Build Coastguard Worker     {
1062*5e7646d2SAndroid Build Coastguard Worker       if ((valptr = strrchr(attr->values[0].string.text, '/')) == NULL)
1063*5e7646d2SAndroid Build Coastguard Worker 	valptr = "unknown";
1064*5e7646d2SAndroid Build Coastguard Worker       else
1065*5e7646d2SAndroid Build Coastguard Worker 	valptr ++;
1066*5e7646d2SAndroid Build Coastguard Worker 
1067*5e7646d2SAndroid Build Coastguard Worker       cgiSetArray("notify_printer_name", element, valptr);
1068*5e7646d2SAndroid Build Coastguard Worker     }
1069*5e7646d2SAndroid Build Coastguard Worker 
1070*5e7646d2SAndroid Build Coastguard Worker    /*
1071*5e7646d2SAndroid Build Coastguard Worker     * Add "notify_recipient_name" variable if we have a "notify_recipient_uri"
1072*5e7646d2SAndroid Build Coastguard Worker     * attribute, and rewrite recipient URI...
1073*5e7646d2SAndroid Build Coastguard Worker     */
1074*5e7646d2SAndroid Build Coastguard Worker 
1075*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(name, "notify_recipient_uri"))
1076*5e7646d2SAndroid Build Coastguard Worker     {
1077*5e7646d2SAndroid Build Coastguard Worker       char	uri[1024],		/* New URI */
1078*5e7646d2SAndroid Build Coastguard Worker 		scheme[32],		/* Scheme portion of URI */
1079*5e7646d2SAndroid Build Coastguard Worker 		userpass[256],		/* Username/password portion of URI */
1080*5e7646d2SAndroid Build Coastguard Worker 		host[1024],		/* Hostname portion of URI */
1081*5e7646d2SAndroid Build Coastguard Worker 		resource[1024],		/* Resource portion of URI */
1082*5e7646d2SAndroid Build Coastguard Worker 		*options;		/* Options in URI */
1083*5e7646d2SAndroid Build Coastguard Worker       int	port;			/* Port number */
1084*5e7646d2SAndroid Build Coastguard Worker 
1085*5e7646d2SAndroid Build Coastguard Worker 
1086*5e7646d2SAndroid Build Coastguard Worker       httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text,
1087*5e7646d2SAndroid Build Coastguard Worker                       scheme, sizeof(scheme), userpass, sizeof(userpass),
1088*5e7646d2SAndroid Build Coastguard Worker 		      host, sizeof(host), &port, resource, sizeof(resource));
1089*5e7646d2SAndroid Build Coastguard Worker 
1090*5e7646d2SAndroid Build Coastguard Worker       if (!strcmp(scheme, "rss"))
1091*5e7646d2SAndroid Build Coastguard Worker       {
1092*5e7646d2SAndroid Build Coastguard Worker        /*
1093*5e7646d2SAndroid Build Coastguard Worker         * RSS notification...
1094*5e7646d2SAndroid Build Coastguard Worker 	*/
1095*5e7646d2SAndroid Build Coastguard Worker 
1096*5e7646d2SAndroid Build Coastguard Worker         if ((options = strchr(resource, '?')) != NULL)
1097*5e7646d2SAndroid Build Coastguard Worker 	  *options = '\0';
1098*5e7646d2SAndroid Build Coastguard Worker 
1099*5e7646d2SAndroid Build Coastguard Worker         if (host[0])
1100*5e7646d2SAndroid Build Coastguard Worker 	{
1101*5e7646d2SAndroid Build Coastguard Worker 	 /*
1102*5e7646d2SAndroid Build Coastguard Worker 	  * Link to remote feed...
1103*5e7646d2SAndroid Build Coastguard Worker 	  */
1104*5e7646d2SAndroid Build Coastguard Worker 
1105*5e7646d2SAndroid Build Coastguard Worker 	  httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "http",
1106*5e7646d2SAndroid Build Coastguard Worker 	                  userpass, host, port, resource);
1107*5e7646d2SAndroid Build Coastguard Worker           strlcpy(name, uri, sizeof(name));
1108*5e7646d2SAndroid Build Coastguard Worker 	}
1109*5e7646d2SAndroid Build Coastguard Worker 	else
1110*5e7646d2SAndroid Build Coastguard Worker 	{
1111*5e7646d2SAndroid Build Coastguard Worker 	 /*
1112*5e7646d2SAndroid Build Coastguard Worker 	  * Link to local feed...
1113*5e7646d2SAndroid Build Coastguard Worker 	  */
1114*5e7646d2SAndroid Build Coastguard Worker 
1115*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(uri, sizeof(uri), "/rss%s", resource);
1116*5e7646d2SAndroid Build Coastguard Worker           strlcpy(name, resource + 1, sizeof(name));
1117*5e7646d2SAndroid Build Coastguard Worker 	}
1118*5e7646d2SAndroid Build Coastguard Worker       }
1119*5e7646d2SAndroid Build Coastguard Worker       else
1120*5e7646d2SAndroid Build Coastguard Worker       {
1121*5e7646d2SAndroid Build Coastguard Worker        /*
1122*5e7646d2SAndroid Build Coastguard Worker         * Other...
1123*5e7646d2SAndroid Build Coastguard Worker 	*/
1124*5e7646d2SAndroid Build Coastguard Worker 
1125*5e7646d2SAndroid Build Coastguard Worker         strlcpy(uri, attr->values[0].string.text, sizeof(uri));
1126*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(name, resource, sizeof(name));
1127*5e7646d2SAndroid Build Coastguard Worker       }
1128*5e7646d2SAndroid Build Coastguard Worker 
1129*5e7646d2SAndroid Build Coastguard Worker       cgiSetArray("notify_recipient_uri", element, uri);
1130*5e7646d2SAndroid Build Coastguard Worker       cgiSetArray("notify_recipient_name", element, name);
1131*5e7646d2SAndroid Build Coastguard Worker       continue;
1132*5e7646d2SAndroid Build Coastguard Worker     }
1133*5e7646d2SAndroid Build Coastguard Worker 
1134*5e7646d2SAndroid Build Coastguard Worker    /*
1135*5e7646d2SAndroid Build Coastguard Worker     * Add "admin_uri" variable if we have a "printer_uri_supported"
1136*5e7646d2SAndroid Build Coastguard Worker     * attribute...
1137*5e7646d2SAndroid Build Coastguard Worker     */
1138*5e7646d2SAndroid Build Coastguard Worker 
1139*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(name, "printer_uri_supported"))
1140*5e7646d2SAndroid Build Coastguard Worker     {
1141*5e7646d2SAndroid Build Coastguard Worker       cgiRewriteURL(attr->values[0].string.text, value, sizeof(value),
1142*5e7646d2SAndroid Build Coastguard Worker 	            "/admin/");
1143*5e7646d2SAndroid Build Coastguard Worker 
1144*5e7646d2SAndroid Build Coastguard Worker       cgiSetArray("admin_uri", element, value);
1145*5e7646d2SAndroid Build Coastguard Worker     }
1146*5e7646d2SAndroid Build Coastguard Worker 
1147*5e7646d2SAndroid Build Coastguard Worker    /*
1148*5e7646d2SAndroid Build Coastguard Worker     * Copy values...
1149*5e7646d2SAndroid Build Coastguard Worker     */
1150*5e7646d2SAndroid Build Coastguard Worker 
1151*5e7646d2SAndroid Build Coastguard Worker     value[0] = '\0';	/* Initially an empty string */
1152*5e7646d2SAndroid Build Coastguard Worker     valptr   = value; /* Start at the beginning */
1153*5e7646d2SAndroid Build Coastguard Worker 
1154*5e7646d2SAndroid Build Coastguard Worker     for (i = 0; i < attr->num_values; i ++)
1155*5e7646d2SAndroid Build Coastguard Worker     {
1156*5e7646d2SAndroid Build Coastguard Worker       if (i)
1157*5e7646d2SAndroid Build Coastguard Worker 	strlcat(valptr, ", ", sizeof(value) - (size_t)(valptr - value));
1158*5e7646d2SAndroid Build Coastguard Worker 
1159*5e7646d2SAndroid Build Coastguard Worker       valptr += strlen(valptr);
1160*5e7646d2SAndroid Build Coastguard Worker 
1161*5e7646d2SAndroid Build Coastguard Worker       switch (attr->value_tag)
1162*5e7646d2SAndroid Build Coastguard Worker       {
1163*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_INTEGER :
1164*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_ENUM :
1165*5e7646d2SAndroid Build Coastguard Worker 	    if (strncmp(name, "time_at_", 8) == 0)
1166*5e7646d2SAndroid Build Coastguard Worker 	      _cupsStrDate(valptr, sizeof(value) - (size_t)(valptr - value), (time_t)ippGetInteger(attr, i));
1167*5e7646d2SAndroid Build Coastguard Worker 	    else
1168*5e7646d2SAndroid Build Coastguard Worker 	      snprintf(valptr, sizeof(value) - (size_t)(valptr - value), "%d", ippGetInteger(attr, i));
1169*5e7646d2SAndroid Build Coastguard Worker 	    break;
1170*5e7646d2SAndroid Build Coastguard Worker 
1171*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_BOOLEAN :
1172*5e7646d2SAndroid Build Coastguard Worker 	    snprintf(valptr, sizeof(value) - (size_t)(valptr - value),
1173*5e7646d2SAndroid Build Coastguard Worker 	             "%d", attr->values[i].boolean);
1174*5e7646d2SAndroid Build Coastguard Worker 	    break;
1175*5e7646d2SAndroid Build Coastguard Worker 
1176*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_NOVALUE :
1177*5e7646d2SAndroid Build Coastguard Worker 	    strlcat(valptr, "novalue", sizeof(value) - (size_t)(valptr - value));
1178*5e7646d2SAndroid Build Coastguard Worker 	    break;
1179*5e7646d2SAndroid Build Coastguard Worker 
1180*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_RANGE :
1181*5e7646d2SAndroid Build Coastguard Worker 	    snprintf(valptr, sizeof(value) - (size_t)(valptr - value),
1182*5e7646d2SAndroid Build Coastguard Worker 	             "%d-%d", attr->values[i].range.lower,
1183*5e7646d2SAndroid Build Coastguard Worker 		     attr->values[i].range.upper);
1184*5e7646d2SAndroid Build Coastguard Worker 	    break;
1185*5e7646d2SAndroid Build Coastguard Worker 
1186*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_RESOLUTION :
1187*5e7646d2SAndroid Build Coastguard Worker 	    snprintf(valptr, sizeof(value) - (size_t)(valptr - value),
1188*5e7646d2SAndroid Build Coastguard Worker 	             "%dx%d%s", attr->values[i].resolution.xres,
1189*5e7646d2SAndroid Build Coastguard Worker 		     attr->values[i].resolution.yres,
1190*5e7646d2SAndroid Build Coastguard Worker 		     attr->values[i].resolution.units == IPP_RES_PER_INCH ?
1191*5e7646d2SAndroid Build Coastguard Worker 			 "dpi" : "dpcm");
1192*5e7646d2SAndroid Build Coastguard Worker 	    break;
1193*5e7646d2SAndroid Build Coastguard Worker 
1194*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_URI :
1195*5e7646d2SAndroid Build Coastguard Worker 	    if (strchr(attr->values[i].string.text, ':') &&
1196*5e7646d2SAndroid Build Coastguard Worker 	        strcmp(name, "device_uri"))
1197*5e7646d2SAndroid Build Coastguard Worker 	    {
1198*5e7646d2SAndroid Build Coastguard Worker 	     /*
1199*5e7646d2SAndroid Build Coastguard Worker 	      * Rewrite URIs...
1200*5e7646d2SAndroid Build Coastguard Worker 	      */
1201*5e7646d2SAndroid Build Coastguard Worker 
1202*5e7646d2SAndroid Build Coastguard Worker 	      cgiRewriteURL(attr->values[i].string.text, valptr, (int)(sizeof(value) - (size_t)(valptr - value)), NULL);
1203*5e7646d2SAndroid Build Coastguard Worker               break;
1204*5e7646d2SAndroid Build Coastguard Worker             }
1205*5e7646d2SAndroid Build Coastguard Worker 
1206*5e7646d2SAndroid Build Coastguard Worker         case IPP_TAG_STRING :
1207*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_TEXT :
1208*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_NAME :
1209*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_KEYWORD :
1210*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_CHARSET :
1211*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_LANGUAGE :
1212*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_MIMETYPE :
1213*5e7646d2SAndroid Build Coastguard Worker 	    strlcat(valptr, attr->values[i].string.text,
1214*5e7646d2SAndroid Build Coastguard Worker 	            sizeof(value) - (size_t)(valptr - value));
1215*5e7646d2SAndroid Build Coastguard Worker 	    break;
1216*5e7646d2SAndroid Build Coastguard Worker 
1217*5e7646d2SAndroid Build Coastguard Worker         case IPP_TAG_BEGIN_COLLECTION :
1218*5e7646d2SAndroid Build Coastguard Worker 	    snprintf(value, sizeof(value), "%s%d", name, i + 1);
1219*5e7646d2SAndroid Build Coastguard Worker             cgiSetIPPVars(attr->values[i].collection, NULL, NULL, value,
1220*5e7646d2SAndroid Build Coastguard Worker 	                  element);
1221*5e7646d2SAndroid Build Coastguard Worker             break;
1222*5e7646d2SAndroid Build Coastguard Worker 
1223*5e7646d2SAndroid Build Coastguard Worker         default :
1224*5e7646d2SAndroid Build Coastguard Worker 	    break; /* anti-compiler-warning-code */
1225*5e7646d2SAndroid Build Coastguard Worker       }
1226*5e7646d2SAndroid Build Coastguard Worker     }
1227*5e7646d2SAndroid Build Coastguard Worker 
1228*5e7646d2SAndroid Build Coastguard Worker    /*
1229*5e7646d2SAndroid Build Coastguard Worker     * Add the element...
1230*5e7646d2SAndroid Build Coastguard Worker     */
1231*5e7646d2SAndroid Build Coastguard Worker 
1232*5e7646d2SAndroid Build Coastguard Worker     if (attr->value_tag != IPP_TAG_BEGIN_COLLECTION)
1233*5e7646d2SAndroid Build Coastguard Worker     {
1234*5e7646d2SAndroid Build Coastguard Worker       cgiSetArray(name, element, value);
1235*5e7646d2SAndroid Build Coastguard Worker 
1236*5e7646d2SAndroid Build Coastguard Worker       fprintf(stderr, "DEBUG2: %s[%d]=\"%s\"\n", name, element, value);
1237*5e7646d2SAndroid Build Coastguard Worker     }
1238*5e7646d2SAndroid Build Coastguard Worker   }
1239*5e7646d2SAndroid Build Coastguard Worker 
1240*5e7646d2SAndroid Build Coastguard Worker   return (attr ? attr->next : NULL);
1241*5e7646d2SAndroid Build Coastguard Worker }
1242*5e7646d2SAndroid Build Coastguard Worker 
1243*5e7646d2SAndroid Build Coastguard Worker 
1244*5e7646d2SAndroid Build Coastguard Worker /*
1245*5e7646d2SAndroid Build Coastguard Worker  * 'cgiSetIPPVars()' - Set CGI variables from an IPP response.
1246*5e7646d2SAndroid Build Coastguard Worker  */
1247*5e7646d2SAndroid Build Coastguard Worker 
1248*5e7646d2SAndroid Build Coastguard Worker int					/* O - Maximum number of elements */
cgiSetIPPVars(ipp_t * response,const char * filter_name,const char * filter_value,const char * prefix,int parent_el)1249*5e7646d2SAndroid Build Coastguard Worker cgiSetIPPVars(ipp_t      *response,	/* I - Response data to be copied... */
1250*5e7646d2SAndroid Build Coastguard Worker               const char *filter_name,	/* I - Filter name */
1251*5e7646d2SAndroid Build Coastguard Worker 	      const char *filter_value,	/* I - Filter value */
1252*5e7646d2SAndroid Build Coastguard Worker 	      const char *prefix,	/* I - Prefix for name or NULL */
1253*5e7646d2SAndroid Build Coastguard Worker 	      int        parent_el)	/* I - Parent element number */
1254*5e7646d2SAndroid Build Coastguard Worker {
1255*5e7646d2SAndroid Build Coastguard Worker   int			element;	/* Element in CGI array */
1256*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t	*attr,		/* Attribute in response... */
1257*5e7646d2SAndroid Build Coastguard Worker 			*filter;	/* Filtering attribute */
1258*5e7646d2SAndroid Build Coastguard Worker 
1259*5e7646d2SAndroid Build Coastguard Worker 
1260*5e7646d2SAndroid Build Coastguard Worker   fprintf(stderr, "DEBUG2: cgiSetIPPVars(response=%p, filter_name=\"%s\", "
1261*5e7646d2SAndroid Build Coastguard Worker                   "filter_value=\"%s\", prefix=\"%s\", parent_el=%d)\n",
1262*5e7646d2SAndroid Build Coastguard Worker           response, filter_name ? filter_name : "(null)",
1263*5e7646d2SAndroid Build Coastguard Worker 	  filter_value ? filter_value : "(null)",
1264*5e7646d2SAndroid Build Coastguard Worker 	  prefix ? prefix : "(null)", parent_el);
1265*5e7646d2SAndroid Build Coastguard Worker 
1266*5e7646d2SAndroid Build Coastguard Worker  /*
1267*5e7646d2SAndroid Build Coastguard Worker   * Set common CGI template variables...
1268*5e7646d2SAndroid Build Coastguard Worker   */
1269*5e7646d2SAndroid Build Coastguard Worker 
1270*5e7646d2SAndroid Build Coastguard Worker   if (!prefix)
1271*5e7646d2SAndroid Build Coastguard Worker     cgiSetServerVersion();
1272*5e7646d2SAndroid Build Coastguard Worker 
1273*5e7646d2SAndroid Build Coastguard Worker  /*
1274*5e7646d2SAndroid Build Coastguard Worker   * Loop through the attributes and set them for the template...
1275*5e7646d2SAndroid Build Coastguard Worker   */
1276*5e7646d2SAndroid Build Coastguard Worker 
1277*5e7646d2SAndroid Build Coastguard Worker   attr = response->attrs;
1278*5e7646d2SAndroid Build Coastguard Worker 
1279*5e7646d2SAndroid Build Coastguard Worker   if (!prefix)
1280*5e7646d2SAndroid Build Coastguard Worker     while (attr && attr->group_tag == IPP_TAG_OPERATION)
1281*5e7646d2SAndroid Build Coastguard Worker       attr = attr->next;
1282*5e7646d2SAndroid Build Coastguard Worker 
1283*5e7646d2SAndroid Build Coastguard Worker   for (element = parent_el; attr; element ++)
1284*5e7646d2SAndroid Build Coastguard Worker   {
1285*5e7646d2SAndroid Build Coastguard Worker    /*
1286*5e7646d2SAndroid Build Coastguard Worker     * Copy attributes to a separator...
1287*5e7646d2SAndroid Build Coastguard Worker     */
1288*5e7646d2SAndroid Build Coastguard Worker 
1289*5e7646d2SAndroid Build Coastguard Worker     while (attr && attr->group_tag == IPP_TAG_ZERO)
1290*5e7646d2SAndroid Build Coastguard Worker       attr= attr->next;
1291*5e7646d2SAndroid Build Coastguard Worker 
1292*5e7646d2SAndroid Build Coastguard Worker     if (!attr)
1293*5e7646d2SAndroid Build Coastguard Worker       break;
1294*5e7646d2SAndroid Build Coastguard Worker 
1295*5e7646d2SAndroid Build Coastguard Worker     if (filter_name)
1296*5e7646d2SAndroid Build Coastguard Worker     {
1297*5e7646d2SAndroid Build Coastguard Worker       for (filter = attr;
1298*5e7646d2SAndroid Build Coastguard Worker            filter != NULL && filter->group_tag != IPP_TAG_ZERO;
1299*5e7646d2SAndroid Build Coastguard Worker            filter = filter->next)
1300*5e7646d2SAndroid Build Coastguard Worker         if (filter->name && !strcmp(filter->name, filter_name) &&
1301*5e7646d2SAndroid Build Coastguard Worker 	    (filter->value_tag == IPP_TAG_STRING ||
1302*5e7646d2SAndroid Build Coastguard Worker 	     (filter->value_tag >= IPP_TAG_TEXTLANG &&
1303*5e7646d2SAndroid Build Coastguard Worker 	      filter->value_tag <= IPP_TAG_MIMETYPE)) &&
1304*5e7646d2SAndroid Build Coastguard Worker 	    filter->values[0].string.text != NULL &&
1305*5e7646d2SAndroid Build Coastguard Worker 	    !_cups_strcasecmp(filter->values[0].string.text, filter_value))
1306*5e7646d2SAndroid Build Coastguard Worker 	  break;
1307*5e7646d2SAndroid Build Coastguard Worker 
1308*5e7646d2SAndroid Build Coastguard Worker       if (!filter)
1309*5e7646d2SAndroid Build Coastguard Worker         return (element + 1);
1310*5e7646d2SAndroid Build Coastguard Worker 
1311*5e7646d2SAndroid Build Coastguard Worker       if (filter->group_tag == IPP_TAG_ZERO)
1312*5e7646d2SAndroid Build Coastguard Worker       {
1313*5e7646d2SAndroid Build Coastguard Worker         attr = filter;
1314*5e7646d2SAndroid Build Coastguard Worker 	element --;
1315*5e7646d2SAndroid Build Coastguard Worker 	continue;
1316*5e7646d2SAndroid Build Coastguard Worker       }
1317*5e7646d2SAndroid Build Coastguard Worker     }
1318*5e7646d2SAndroid Build Coastguard Worker 
1319*5e7646d2SAndroid Build Coastguard Worker     attr = cgiSetIPPObjectVars(attr, prefix, element);
1320*5e7646d2SAndroid Build Coastguard Worker   }
1321*5e7646d2SAndroid Build Coastguard Worker 
1322*5e7646d2SAndroid Build Coastguard Worker   fprintf(stderr, "DEBUG2: Returning %d from cgiSetIPPVars()...\n", element);
1323*5e7646d2SAndroid Build Coastguard Worker 
1324*5e7646d2SAndroid Build Coastguard Worker   return (element);
1325*5e7646d2SAndroid Build Coastguard Worker }
1326*5e7646d2SAndroid Build Coastguard Worker 
1327*5e7646d2SAndroid Build Coastguard Worker 
1328*5e7646d2SAndroid Build Coastguard Worker /*
1329*5e7646d2SAndroid Build Coastguard Worker  * 'cgiShowIPPError()' - Show the last IPP error message.
1330*5e7646d2SAndroid Build Coastguard Worker  *
1331*5e7646d2SAndroid Build Coastguard Worker  * The caller must still call cgiStartHTML() and cgiEndHTML().
1332*5e7646d2SAndroid Build Coastguard Worker  */
1333*5e7646d2SAndroid Build Coastguard Worker 
1334*5e7646d2SAndroid Build Coastguard Worker void
cgiShowIPPError(const char * message)1335*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(const char *message)	/* I - Contextual message */
1336*5e7646d2SAndroid Build Coastguard Worker {
1337*5e7646d2SAndroid Build Coastguard Worker   cgiSetVariable("MESSAGE", cgiText(message));
1338*5e7646d2SAndroid Build Coastguard Worker   cgiSetVariable("ERROR", cupsLastErrorString());
1339*5e7646d2SAndroid Build Coastguard Worker   cgiCopyTemplateLang("error.tmpl");
1340*5e7646d2SAndroid Build Coastguard Worker }
1341*5e7646d2SAndroid Build Coastguard Worker 
1342*5e7646d2SAndroid Build Coastguard Worker 
1343*5e7646d2SAndroid Build Coastguard Worker /*
1344*5e7646d2SAndroid Build Coastguard Worker  * 'cgiShowJobs()' - Show print jobs.
1345*5e7646d2SAndroid Build Coastguard Worker  */
1346*5e7646d2SAndroid Build Coastguard Worker 
1347*5e7646d2SAndroid Build Coastguard Worker void
cgiShowJobs(http_t * http,const char * dest)1348*5e7646d2SAndroid Build Coastguard Worker cgiShowJobs(http_t     *http,		/* I - Connection to server */
1349*5e7646d2SAndroid Build Coastguard Worker             const char *dest)		/* I - Destination name or NULL */
1350*5e7646d2SAndroid Build Coastguard Worker {
1351*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
1352*5e7646d2SAndroid Build Coastguard Worker   const char		*which_jobs;	/* Which jobs to show */
1353*5e7646d2SAndroid Build Coastguard Worker   ipp_t			*request,	/* IPP request */
1354*5e7646d2SAndroid Build Coastguard Worker 			*response;	/* IPP response */
1355*5e7646d2SAndroid Build Coastguard Worker   cups_array_t		*jobs;		/* Array of job objects */
1356*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t	*job;		/* Job object */
1357*5e7646d2SAndroid Build Coastguard Worker   int			first,		/* First job to show */
1358*5e7646d2SAndroid Build Coastguard Worker 			count;		/* Number of jobs */
1359*5e7646d2SAndroid Build Coastguard Worker   const char		*var,		/* Form variable */
1360*5e7646d2SAndroid Build Coastguard Worker 			*query,		/* Query string */
1361*5e7646d2SAndroid Build Coastguard Worker 			*section;	/* Section in web interface */
1362*5e7646d2SAndroid Build Coastguard Worker   void			*search;	/* Search data */
1363*5e7646d2SAndroid Build Coastguard Worker   char			url[1024],	/* Printer URI */
1364*5e7646d2SAndroid Build Coastguard Worker 			val[1024];	/* Form variable */
1365*5e7646d2SAndroid Build Coastguard Worker 
1366*5e7646d2SAndroid Build Coastguard Worker 
1367*5e7646d2SAndroid Build Coastguard Worker  /*
1368*5e7646d2SAndroid Build Coastguard Worker   * Build an IPP_GET_JOBS request, which requires the following
1369*5e7646d2SAndroid Build Coastguard Worker   * attributes:
1370*5e7646d2SAndroid Build Coastguard Worker   *
1371*5e7646d2SAndroid Build Coastguard Worker   *    attributes-charset
1372*5e7646d2SAndroid Build Coastguard Worker   *    attributes-natural-language
1373*5e7646d2SAndroid Build Coastguard Worker   *    printer-uri
1374*5e7646d2SAndroid Build Coastguard Worker   */
1375*5e7646d2SAndroid Build Coastguard Worker 
1376*5e7646d2SAndroid Build Coastguard Worker   request = ippNewRequest(IPP_GET_JOBS);
1377*5e7646d2SAndroid Build Coastguard Worker 
1378*5e7646d2SAndroid Build Coastguard Worker   if (dest)
1379*5e7646d2SAndroid Build Coastguard Worker   {
1380*5e7646d2SAndroid Build Coastguard Worker     httpAssembleURIf(HTTP_URI_CODING_ALL, url, sizeof(url), "ipp", NULL,
1381*5e7646d2SAndroid Build Coastguard Worker                      "localhost", ippPort(), "/printers/%s", dest);
1382*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1383*5e7646d2SAndroid Build Coastguard Worker                  NULL, url);
1384*5e7646d2SAndroid Build Coastguard Worker   }
1385*5e7646d2SAndroid Build Coastguard Worker   else
1386*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
1387*5e7646d2SAndroid Build Coastguard Worker         	 "ipp://localhost/");
1388*5e7646d2SAndroid Build Coastguard Worker 
1389*5e7646d2SAndroid Build Coastguard Worker   if ((which_jobs = cgiGetVariable("which_jobs")) != NULL && *which_jobs)
1390*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs",
1391*5e7646d2SAndroid Build Coastguard Worker                  NULL, which_jobs);
1392*5e7646d2SAndroid Build Coastguard Worker 
1393*5e7646d2SAndroid Build Coastguard Worker   if ((var = cgiGetVariable("FIRST")) != NULL)
1394*5e7646d2SAndroid Build Coastguard Worker   {
1395*5e7646d2SAndroid Build Coastguard Worker     if ((first = atoi(var)) < 0)
1396*5e7646d2SAndroid Build Coastguard Worker       first = 0;
1397*5e7646d2SAndroid Build Coastguard Worker   }
1398*5e7646d2SAndroid Build Coastguard Worker   else
1399*5e7646d2SAndroid Build Coastguard Worker     first = 0;
1400*5e7646d2SAndroid Build Coastguard Worker 
1401*5e7646d2SAndroid Build Coastguard Worker   if (first > 0)
1402*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "first-index", first + 1);
1403*5e7646d2SAndroid Build Coastguard Worker 
1404*5e7646d2SAndroid Build Coastguard Worker   cgiGetAttributes(request, "jobs.tmpl");
1405*5e7646d2SAndroid Build Coastguard Worker 
1406*5e7646d2SAndroid Build Coastguard Worker  /*
1407*5e7646d2SAndroid Build Coastguard Worker   * Do the request and get back a response...
1408*5e7646d2SAndroid Build Coastguard Worker   */
1409*5e7646d2SAndroid Build Coastguard Worker 
1410*5e7646d2SAndroid Build Coastguard Worker   if ((response = cupsDoRequest(http, request, "/")) != NULL)
1411*5e7646d2SAndroid Build Coastguard Worker   {
1412*5e7646d2SAndroid Build Coastguard Worker    /*
1413*5e7646d2SAndroid Build Coastguard Worker     * Get a list of matching job objects.
1414*5e7646d2SAndroid Build Coastguard Worker     */
1415*5e7646d2SAndroid Build Coastguard Worker 
1416*5e7646d2SAndroid Build Coastguard Worker     if ((query = cgiGetVariable("QUERY")) != NULL &&
1417*5e7646d2SAndroid Build Coastguard Worker         !cgiGetVariable("CLEAR"))
1418*5e7646d2SAndroid Build Coastguard Worker       search = cgiCompileSearch(query);
1419*5e7646d2SAndroid Build Coastguard Worker     else
1420*5e7646d2SAndroid Build Coastguard Worker     {
1421*5e7646d2SAndroid Build Coastguard Worker       query  = NULL;
1422*5e7646d2SAndroid Build Coastguard Worker       search = NULL;
1423*5e7646d2SAndroid Build Coastguard Worker     }
1424*5e7646d2SAndroid Build Coastguard Worker 
1425*5e7646d2SAndroid Build Coastguard Worker     jobs  = cgiGetIPPObjects(response, search);
1426*5e7646d2SAndroid Build Coastguard Worker     count = cupsArrayCount(jobs) + first;
1427*5e7646d2SAndroid Build Coastguard Worker 
1428*5e7646d2SAndroid Build Coastguard Worker     if (search)
1429*5e7646d2SAndroid Build Coastguard Worker       cgiFreeSearch(search);
1430*5e7646d2SAndroid Build Coastguard Worker 
1431*5e7646d2SAndroid Build Coastguard Worker    /*
1432*5e7646d2SAndroid Build Coastguard Worker     * Figure out which jobs to display...
1433*5e7646d2SAndroid Build Coastguard Worker     */
1434*5e7646d2SAndroid Build Coastguard Worker 
1435*5e7646d2SAndroid Build Coastguard Worker     section = cgiGetVariable("SECTION");
1436*5e7646d2SAndroid Build Coastguard Worker 
1437*5e7646d2SAndroid Build Coastguard Worker     cgiClearVariables();
1438*5e7646d2SAndroid Build Coastguard Worker 
1439*5e7646d2SAndroid Build Coastguard Worker     if (query)
1440*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("QUERY", query);
1441*5e7646d2SAndroid Build Coastguard Worker 
1442*5e7646d2SAndroid Build Coastguard Worker     cgiSetVariable("SECTION", section);
1443*5e7646d2SAndroid Build Coastguard Worker 
1444*5e7646d2SAndroid Build Coastguard Worker     snprintf(val, sizeof(val), "%d", count);
1445*5e7646d2SAndroid Build Coastguard Worker     cgiSetVariable("TOTAL", val);
1446*5e7646d2SAndroid Build Coastguard Worker 
1447*5e7646d2SAndroid Build Coastguard Worker     if (which_jobs)
1448*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("WHICH_JOBS", which_jobs);
1449*5e7646d2SAndroid Build Coastguard Worker 
1450*5e7646d2SAndroid Build Coastguard Worker     for (i = 0, job = (ipp_attribute_t *)cupsArrayFirst(jobs);
1451*5e7646d2SAndroid Build Coastguard Worker 	 i < CUPS_PAGE_MAX && job;
1452*5e7646d2SAndroid Build Coastguard Worker 	 i ++, job = (ipp_attribute_t *)cupsArrayNext(jobs))
1453*5e7646d2SAndroid Build Coastguard Worker       cgiSetIPPObjectVars(job, NULL, i);
1454*5e7646d2SAndroid Build Coastguard Worker 
1455*5e7646d2SAndroid Build Coastguard Worker    /*
1456*5e7646d2SAndroid Build Coastguard Worker     * Save navigation URLs...
1457*5e7646d2SAndroid Build Coastguard Worker     */
1458*5e7646d2SAndroid Build Coastguard Worker 
1459*5e7646d2SAndroid Build Coastguard Worker     if (dest)
1460*5e7646d2SAndroid Build Coastguard Worker     {
1461*5e7646d2SAndroid Build Coastguard Worker       snprintf(val, sizeof(val), "/%s/%s", section, dest);
1462*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("PRINTER_NAME", dest);
1463*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("PRINTER_URI_SUPPORTED", val);
1464*5e7646d2SAndroid Build Coastguard Worker     }
1465*5e7646d2SAndroid Build Coastguard Worker     else
1466*5e7646d2SAndroid Build Coastguard Worker       strlcpy(val, "/jobs/", sizeof(val));
1467*5e7646d2SAndroid Build Coastguard Worker 
1468*5e7646d2SAndroid Build Coastguard Worker     cgiSetVariable("THISURL", val);
1469*5e7646d2SAndroid Build Coastguard Worker 
1470*5e7646d2SAndroid Build Coastguard Worker     if (first > 0)
1471*5e7646d2SAndroid Build Coastguard Worker     {
1472*5e7646d2SAndroid Build Coastguard Worker       snprintf(val, sizeof(val), "%d", first - CUPS_PAGE_MAX);
1473*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("PREV", val);
1474*5e7646d2SAndroid Build Coastguard Worker     }
1475*5e7646d2SAndroid Build Coastguard Worker 
1476*5e7646d2SAndroid Build Coastguard Worker     if ((first + CUPS_PAGE_MAX) < count)
1477*5e7646d2SAndroid Build Coastguard Worker     {
1478*5e7646d2SAndroid Build Coastguard Worker       snprintf(val, sizeof(val), "%d", first + CUPS_PAGE_MAX);
1479*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("NEXT", val);
1480*5e7646d2SAndroid Build Coastguard Worker     }
1481*5e7646d2SAndroid Build Coastguard Worker 
1482*5e7646d2SAndroid Build Coastguard Worker     if (count > CUPS_PAGE_MAX)
1483*5e7646d2SAndroid Build Coastguard Worker     {
1484*5e7646d2SAndroid Build Coastguard Worker       snprintf(val, sizeof(val), "%d", CUPS_PAGE_MAX * (count / CUPS_PAGE_MAX));
1485*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("LAST", val);
1486*5e7646d2SAndroid Build Coastguard Worker     }
1487*5e7646d2SAndroid Build Coastguard Worker 
1488*5e7646d2SAndroid Build Coastguard Worker    /*
1489*5e7646d2SAndroid Build Coastguard Worker     * Then show everything...
1490*5e7646d2SAndroid Build Coastguard Worker     */
1491*5e7646d2SAndroid Build Coastguard Worker 
1492*5e7646d2SAndroid Build Coastguard Worker     if (dest)
1493*5e7646d2SAndroid Build Coastguard Worker       cgiSetVariable("SEARCH_DEST", dest);
1494*5e7646d2SAndroid Build Coastguard Worker 
1495*5e7646d2SAndroid Build Coastguard Worker     cgiCopyTemplateLang("search.tmpl");
1496*5e7646d2SAndroid Build Coastguard Worker 
1497*5e7646d2SAndroid Build Coastguard Worker     cgiCopyTemplateLang("jobs-header.tmpl");
1498*5e7646d2SAndroid Build Coastguard Worker 
1499*5e7646d2SAndroid Build Coastguard Worker     if (count > CUPS_PAGE_MAX)
1500*5e7646d2SAndroid Build Coastguard Worker       cgiCopyTemplateLang("pager.tmpl");
1501*5e7646d2SAndroid Build Coastguard Worker 
1502*5e7646d2SAndroid Build Coastguard Worker     cgiCopyTemplateLang("jobs.tmpl");
1503*5e7646d2SAndroid Build Coastguard Worker 
1504*5e7646d2SAndroid Build Coastguard Worker     if (count > CUPS_PAGE_MAX)
1505*5e7646d2SAndroid Build Coastguard Worker       cgiCopyTemplateLang("pager.tmpl");
1506*5e7646d2SAndroid Build Coastguard Worker 
1507*5e7646d2SAndroid Build Coastguard Worker     cupsArrayDelete(jobs);
1508*5e7646d2SAndroid Build Coastguard Worker     ippDelete(response);
1509*5e7646d2SAndroid Build Coastguard Worker   }
1510*5e7646d2SAndroid Build Coastguard Worker }
1511*5e7646d2SAndroid Build Coastguard Worker 
1512*5e7646d2SAndroid Build Coastguard Worker 
1513*5e7646d2SAndroid Build Coastguard Worker /*
1514*5e7646d2SAndroid Build Coastguard Worker  * 'cgiText()' - Return localized text.
1515*5e7646d2SAndroid Build Coastguard Worker  */
1516*5e7646d2SAndroid Build Coastguard Worker 
1517*5e7646d2SAndroid Build Coastguard Worker const char *				/* O - Localized message */
cgiText(const char * message)1518*5e7646d2SAndroid Build Coastguard Worker cgiText(const char *message)		/* I - Message */
1519*5e7646d2SAndroid Build Coastguard Worker {
1520*5e7646d2SAndroid Build Coastguard Worker   static cups_lang_t	*language = NULL;
1521*5e7646d2SAndroid Build Coastguard Worker 					/* Language */
1522*5e7646d2SAndroid Build Coastguard Worker 
1523*5e7646d2SAndroid Build Coastguard Worker 
1524*5e7646d2SAndroid Build Coastguard Worker   if (!language)
1525*5e7646d2SAndroid Build Coastguard Worker     language = cupsLangDefault();
1526*5e7646d2SAndroid Build Coastguard Worker 
1527*5e7646d2SAndroid Build Coastguard Worker   return (_cupsLangString(language, message));
1528*5e7646d2SAndroid Build Coastguard Worker }
1529