xref: /aosp_15_r20/external/libcups/systemv/lp.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * "lp" command for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2007-2019 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
8*5e7646d2SAndroid Build Coastguard Worker  * information.
9*5e7646d2SAndroid Build Coastguard Worker  */
10*5e7646d2SAndroid Build Coastguard Worker 
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker  */
14*5e7646d2SAndroid Build Coastguard Worker 
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
16*5e7646d2SAndroid Build Coastguard Worker 
17*5e7646d2SAndroid Build Coastguard Worker 
18*5e7646d2SAndroid Build Coastguard Worker /*
19*5e7646d2SAndroid Build Coastguard Worker  * Local functions.
20*5e7646d2SAndroid Build Coastguard Worker  */
21*5e7646d2SAndroid Build Coastguard Worker 
22*5e7646d2SAndroid Build Coastguard Worker static int	restart_job(const char *command, int job_id);
23*5e7646d2SAndroid Build Coastguard Worker static int	set_job_attrs(const char *command, int job_id, int num_options, cups_option_t *options);
24*5e7646d2SAndroid Build Coastguard Worker static void	usage(void) _CUPS_NORETURN;
25*5e7646d2SAndroid Build Coastguard Worker 
26*5e7646d2SAndroid Build Coastguard Worker 
27*5e7646d2SAndroid Build Coastguard Worker /*
28*5e7646d2SAndroid Build Coastguard Worker  * 'main()' - Parse options and send files for printing.
29*5e7646d2SAndroid Build Coastguard Worker  */
30*5e7646d2SAndroid Build Coastguard Worker 
31*5e7646d2SAndroid Build Coastguard Worker int
main(int argc,char * argv[])32*5e7646d2SAndroid Build Coastguard Worker main(int  argc,				/* I - Number of command-line arguments */
33*5e7646d2SAndroid Build Coastguard Worker      char *argv[])			/* I - Command-line arguments */
34*5e7646d2SAndroid Build Coastguard Worker {
35*5e7646d2SAndroid Build Coastguard Worker   int		i, j;			/* Looping vars */
36*5e7646d2SAndroid Build Coastguard Worker   int		job_id;			/* Job ID */
37*5e7646d2SAndroid Build Coastguard Worker   char		*printer,		/* Printer name */
38*5e7646d2SAndroid Build Coastguard Worker 		*instance,		/* Instance name */
39*5e7646d2SAndroid Build Coastguard Worker 		*opt,			/* Option pointer */
40*5e7646d2SAndroid Build Coastguard Worker 		*val,			/* Option value */
41*5e7646d2SAndroid Build Coastguard Worker 		*title;			/* Job title */
42*5e7646d2SAndroid Build Coastguard Worker   int		priority;		/* Job priority (1-100) */
43*5e7646d2SAndroid Build Coastguard Worker   int		num_copies;		/* Number of copies per file */
44*5e7646d2SAndroid Build Coastguard Worker   int		num_files;		/* Number of files to print */
45*5e7646d2SAndroid Build Coastguard Worker   const char	*files[1000];		/* Files to print */
46*5e7646d2SAndroid Build Coastguard Worker   cups_dest_t	*dest;			/* Selected destination */
47*5e7646d2SAndroid Build Coastguard Worker   int		num_options;		/* Number of options */
48*5e7646d2SAndroid Build Coastguard Worker   cups_option_t	*options;		/* Options */
49*5e7646d2SAndroid Build Coastguard Worker   int		end_options;		/* No more options? */
50*5e7646d2SAndroid Build Coastguard Worker   int		silent;			/* Silent or verbose output? */
51*5e7646d2SAndroid Build Coastguard Worker   char		buffer[8192];		/* Copy buffer */
52*5e7646d2SAndroid Build Coastguard Worker 
53*5e7646d2SAndroid Build Coastguard Worker 
54*5e7646d2SAndroid Build Coastguard Worker #ifdef __sun
55*5e7646d2SAndroid Build Coastguard Worker  /*
56*5e7646d2SAndroid Build Coastguard Worker   * Solaris does some rather strange things to re-queue remote print
57*5e7646d2SAndroid Build Coastguard Worker   * jobs.  On bootup, the "lp" command is run as "printd" to re-spool
58*5e7646d2SAndroid Build Coastguard Worker   * any remote jobs in /var/spool/print.  Since CUPS doesn't need this
59*5e7646d2SAndroid Build Coastguard Worker   * nonsense, we just need to add the necessary check here to prevent
60*5e7646d2SAndroid Build Coastguard Worker   * lp from causing boot problems...
61*5e7646d2SAndroid Build Coastguard Worker   */
62*5e7646d2SAndroid Build Coastguard Worker 
63*5e7646d2SAndroid Build Coastguard Worker   if ((val = strrchr(argv[0], '/')) != NULL)
64*5e7646d2SAndroid Build Coastguard Worker     val ++;
65*5e7646d2SAndroid Build Coastguard Worker   else
66*5e7646d2SAndroid Build Coastguard Worker     val = argv[0];
67*5e7646d2SAndroid Build Coastguard Worker 
68*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(val, "printd"))
69*5e7646d2SAndroid Build Coastguard Worker     return (0);
70*5e7646d2SAndroid Build Coastguard Worker #endif /* __sun */
71*5e7646d2SAndroid Build Coastguard Worker 
72*5e7646d2SAndroid Build Coastguard Worker   _cupsSetLocale(argv);
73*5e7646d2SAndroid Build Coastguard Worker 
74*5e7646d2SAndroid Build Coastguard Worker   silent      = 0;
75*5e7646d2SAndroid Build Coastguard Worker   printer     = NULL;
76*5e7646d2SAndroid Build Coastguard Worker   dest        = NULL;
77*5e7646d2SAndroid Build Coastguard Worker   num_options = 0;
78*5e7646d2SAndroid Build Coastguard Worker   options     = NULL;
79*5e7646d2SAndroid Build Coastguard Worker   num_files   = 0;
80*5e7646d2SAndroid Build Coastguard Worker   title       = NULL;
81*5e7646d2SAndroid Build Coastguard Worker   job_id      = 0;
82*5e7646d2SAndroid Build Coastguard Worker   end_options = 0;
83*5e7646d2SAndroid Build Coastguard Worker 
84*5e7646d2SAndroid Build Coastguard Worker   for (i = 1; i < argc; i ++)
85*5e7646d2SAndroid Build Coastguard Worker   {
86*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(argv[i], "--help"))
87*5e7646d2SAndroid Build Coastguard Worker       usage();
88*5e7646d2SAndroid Build Coastguard Worker     else if (argv[i][0] == '-' && argv[i][1] && !end_options)
89*5e7646d2SAndroid Build Coastguard Worker     {
90*5e7646d2SAndroid Build Coastguard Worker       for (opt = argv[i] + 1; *opt; opt ++)
91*5e7646d2SAndroid Build Coastguard Worker       {
92*5e7646d2SAndroid Build Coastguard Worker         switch (*opt)
93*5e7646d2SAndroid Build Coastguard Worker 	{
94*5e7646d2SAndroid Build Coastguard Worker 	  case 'E' : /* Encrypt */
95*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SSL
96*5e7646d2SAndroid Build Coastguard Worker 	      cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
97*5e7646d2SAndroid Build Coastguard Worker #else
98*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
99*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SSL */
100*5e7646d2SAndroid Build Coastguard Worker 	      break;
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker 	  case 'U' : /* Username */
103*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
104*5e7646d2SAndroid Build Coastguard Worker 	      {
105*5e7646d2SAndroid Build Coastguard Worker 		cupsSetUser(opt + 1);
106*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
107*5e7646d2SAndroid Build Coastguard Worker 	      }
108*5e7646d2SAndroid Build Coastguard Worker 	      else
109*5e7646d2SAndroid Build Coastguard Worker 	      {
110*5e7646d2SAndroid Build Coastguard Worker 		i ++;
111*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
112*5e7646d2SAndroid Build Coastguard Worker 		{
113*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), argv[0]);
114*5e7646d2SAndroid Build Coastguard Worker 		  usage();
115*5e7646d2SAndroid Build Coastguard Worker 		}
116*5e7646d2SAndroid Build Coastguard Worker 
117*5e7646d2SAndroid Build Coastguard Worker 		cupsSetUser(argv[i]);
118*5e7646d2SAndroid Build Coastguard Worker 	      }
119*5e7646d2SAndroid Build Coastguard Worker 	      break;
120*5e7646d2SAndroid Build Coastguard Worker 
121*5e7646d2SAndroid Build Coastguard Worker 	  case 'c' : /* Copy to spool dir (always enabled) */
122*5e7646d2SAndroid Build Coastguard Worker 	      break;
123*5e7646d2SAndroid Build Coastguard Worker 
124*5e7646d2SAndroid Build Coastguard Worker 	  case 'd' : /* Destination printer or class */
125*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
126*5e7646d2SAndroid Build Coastguard Worker 	      {
127*5e7646d2SAndroid Build Coastguard Worker 		printer = opt + 1;
128*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
129*5e7646d2SAndroid Build Coastguard Worker 	      }
130*5e7646d2SAndroid Build Coastguard Worker 	      else
131*5e7646d2SAndroid Build Coastguard Worker 	      {
132*5e7646d2SAndroid Build Coastguard Worker 		i ++;
133*5e7646d2SAndroid Build Coastguard Worker 
134*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
135*5e7646d2SAndroid Build Coastguard Worker 		{
136*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected destination after \"-d\" option."), argv[0]);
137*5e7646d2SAndroid Build Coastguard Worker 		  usage();
138*5e7646d2SAndroid Build Coastguard Worker 		}
139*5e7646d2SAndroid Build Coastguard Worker 
140*5e7646d2SAndroid Build Coastguard Worker 		printer = argv[i];
141*5e7646d2SAndroid Build Coastguard Worker 	      }
142*5e7646d2SAndroid Build Coastguard Worker 
143*5e7646d2SAndroid Build Coastguard Worker 	      if ((instance = strrchr(printer, '/')) != NULL)
144*5e7646d2SAndroid Build Coastguard Worker 		*instance++ = '\0';
145*5e7646d2SAndroid Build Coastguard Worker 
146*5e7646d2SAndroid Build Coastguard Worker 	      if ((dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, printer,
147*5e7646d2SAndroid Build Coastguard Worker 					   instance)) != NULL)
148*5e7646d2SAndroid Build Coastguard Worker 	      {
149*5e7646d2SAndroid Build Coastguard Worker 		for (j = 0; j < dest->num_options; j ++)
150*5e7646d2SAndroid Build Coastguard Worker 		  if (cupsGetOption(dest->options[j].name, num_options,
151*5e7646d2SAndroid Build Coastguard Worker 				    options) == NULL)
152*5e7646d2SAndroid Build Coastguard Worker 		    num_options = cupsAddOption(dest->options[j].name,
153*5e7646d2SAndroid Build Coastguard Worker 						dest->options[j].value,
154*5e7646d2SAndroid Build Coastguard Worker 						num_options, &options);
155*5e7646d2SAndroid Build Coastguard Worker 	      }
156*5e7646d2SAndroid Build Coastguard Worker 	      else if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
157*5e7646d2SAndroid Build Coastguard Worker 		       cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
158*5e7646d2SAndroid Build Coastguard Worker 	      {
159*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stderr,
160*5e7646d2SAndroid Build Coastguard Worker 				_("%s: Error - add '/version=1.1' to server "
161*5e7646d2SAndroid Build Coastguard Worker 				  "name."), argv[0]);
162*5e7646d2SAndroid Build Coastguard Worker 		return (1);
163*5e7646d2SAndroid Build Coastguard Worker 	      }
164*5e7646d2SAndroid Build Coastguard Worker 	      else if (cupsLastError() == IPP_STATUS_ERROR_NOT_FOUND)
165*5e7646d2SAndroid Build Coastguard Worker 	      {
166*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stderr,
167*5e7646d2SAndroid Build Coastguard Worker 				_("%s: Error - The printer or class does not exist."), argv[0]);
168*5e7646d2SAndroid Build Coastguard Worker 		return (1);
169*5e7646d2SAndroid Build Coastguard Worker 	      }
170*5e7646d2SAndroid Build Coastguard Worker 	      break;
171*5e7646d2SAndroid Build Coastguard Worker 
172*5e7646d2SAndroid Build Coastguard Worker 	  case 'f' : /* Form */
173*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
174*5e7646d2SAndroid Build Coastguard Worker 	      {
175*5e7646d2SAndroid Build Coastguard Worker 	        opt += strlen(opt) - 1;
176*5e7646d2SAndroid Build Coastguard Worker 	      }
177*5e7646d2SAndroid Build Coastguard Worker 	      else
178*5e7646d2SAndroid Build Coastguard Worker 	      {
179*5e7646d2SAndroid Build Coastguard Worker 		i ++;
180*5e7646d2SAndroid Build Coastguard Worker 
181*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
182*5e7646d2SAndroid Build Coastguard Worker 		{
183*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected form after \"-f\" option."), argv[0]);
184*5e7646d2SAndroid Build Coastguard Worker 		  usage();
185*5e7646d2SAndroid Build Coastguard Worker 		}
186*5e7646d2SAndroid Build Coastguard Worker 	      }
187*5e7646d2SAndroid Build Coastguard Worker 
188*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stderr, _("%s: Warning - form option ignored."), argv[0]);
189*5e7646d2SAndroid Build Coastguard Worker 	      break;
190*5e7646d2SAndroid Build Coastguard Worker 
191*5e7646d2SAndroid Build Coastguard Worker 	  case 'h' : /* Destination host */
192*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
193*5e7646d2SAndroid Build Coastguard Worker 	      {
194*5e7646d2SAndroid Build Coastguard Worker 		cupsSetServer(opt + 1);
195*5e7646d2SAndroid Build Coastguard Worker 	        opt += strlen(opt) - 1;
196*5e7646d2SAndroid Build Coastguard Worker 	      }
197*5e7646d2SAndroid Build Coastguard Worker 	      else
198*5e7646d2SAndroid Build Coastguard Worker 	      {
199*5e7646d2SAndroid Build Coastguard Worker 		i ++;
200*5e7646d2SAndroid Build Coastguard Worker 
201*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
202*5e7646d2SAndroid Build Coastguard Worker 		{
203*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected hostname after \"-h\" option."), argv[0]);
204*5e7646d2SAndroid Build Coastguard Worker 		  usage();
205*5e7646d2SAndroid Build Coastguard Worker 		}
206*5e7646d2SAndroid Build Coastguard Worker 
207*5e7646d2SAndroid Build Coastguard Worker 		cupsSetServer(argv[i]);
208*5e7646d2SAndroid Build Coastguard Worker 	      }
209*5e7646d2SAndroid Build Coastguard Worker 	      break;
210*5e7646d2SAndroid Build Coastguard Worker 
211*5e7646d2SAndroid Build Coastguard Worker 	  case 'i' : /* Change job */
212*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
213*5e7646d2SAndroid Build Coastguard Worker 	      {
214*5e7646d2SAndroid Build Coastguard Worker 		val = opt + 1;
215*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
216*5e7646d2SAndroid Build Coastguard Worker 	      }
217*5e7646d2SAndroid Build Coastguard Worker 	      else
218*5e7646d2SAndroid Build Coastguard Worker 	      {
219*5e7646d2SAndroid Build Coastguard Worker 		i ++;
220*5e7646d2SAndroid Build Coastguard Worker 
221*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
222*5e7646d2SAndroid Build Coastguard Worker 		{
223*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Expected job ID after \"-i\" option."), argv[0]);
224*5e7646d2SAndroid Build Coastguard Worker 		  usage();
225*5e7646d2SAndroid Build Coastguard Worker 		}
226*5e7646d2SAndroid Build Coastguard Worker 
227*5e7646d2SAndroid Build Coastguard Worker 		val = argv[i];
228*5e7646d2SAndroid Build Coastguard Worker 	      }
229*5e7646d2SAndroid Build Coastguard Worker 
230*5e7646d2SAndroid Build Coastguard Worker 	      if (num_files > 0)
231*5e7646d2SAndroid Build Coastguard Worker 	      {
232*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stderr, _("%s: Error - cannot print files and alter jobs simultaneously."), argv[0]);
233*5e7646d2SAndroid Build Coastguard Worker 		return (1);
234*5e7646d2SAndroid Build Coastguard Worker 	      }
235*5e7646d2SAndroid Build Coastguard Worker 
236*5e7646d2SAndroid Build Coastguard Worker 	      if (strrchr(val, '-') != NULL)
237*5e7646d2SAndroid Build Coastguard Worker 		job_id = atoi(strrchr(val, '-') + 1);
238*5e7646d2SAndroid Build Coastguard Worker 	      else
239*5e7646d2SAndroid Build Coastguard Worker 		job_id = atoi(val);
240*5e7646d2SAndroid Build Coastguard Worker 
241*5e7646d2SAndroid Build Coastguard Worker 	      if (job_id < 0)
242*5e7646d2SAndroid Build Coastguard Worker 	      {
243*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stderr, _("%s: Error - bad job ID."), argv[0]);
244*5e7646d2SAndroid Build Coastguard Worker 		break;
245*5e7646d2SAndroid Build Coastguard Worker 	      }
246*5e7646d2SAndroid Build Coastguard Worker 	      break;
247*5e7646d2SAndroid Build Coastguard Worker 
248*5e7646d2SAndroid Build Coastguard Worker 	  case 'm' : /* Send email when job is done */
249*5e7646d2SAndroid Build Coastguard Worker #ifdef __sun
250*5e7646d2SAndroid Build Coastguard Worker 	  case 'p' : /* Notify on completion */
251*5e7646d2SAndroid Build Coastguard Worker #endif /* __sun */
252*5e7646d2SAndroid Build Coastguard Worker 	  case 'w' : /* Write to console or email */
253*5e7646d2SAndroid Build Coastguard Worker 	      {
254*5e7646d2SAndroid Build Coastguard Worker 		char	email[1024];	/* EMail address */
255*5e7646d2SAndroid Build Coastguard Worker 
256*5e7646d2SAndroid Build Coastguard Worker 
257*5e7646d2SAndroid Build Coastguard Worker 		snprintf(email, sizeof(email), "mailto:%s@%s", cupsUser(), httpGetHostname(NULL, buffer, sizeof(buffer)));
258*5e7646d2SAndroid Build Coastguard Worker 		num_options = cupsAddOption("notify-recipient-uri", email, num_options, &options);
259*5e7646d2SAndroid Build Coastguard Worker 	      }
260*5e7646d2SAndroid Build Coastguard Worker 
261*5e7646d2SAndroid Build Coastguard Worker 	      silent = 1;
262*5e7646d2SAndroid Build Coastguard Worker 	      break;
263*5e7646d2SAndroid Build Coastguard Worker 
264*5e7646d2SAndroid Build Coastguard Worker 	  case 'n' : /* Number of copies */
265*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
266*5e7646d2SAndroid Build Coastguard Worker 	      {
267*5e7646d2SAndroid Build Coastguard Worker 		num_copies = atoi(opt + 1);
268*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
269*5e7646d2SAndroid Build Coastguard Worker 	      }
270*5e7646d2SAndroid Build Coastguard Worker 	      else
271*5e7646d2SAndroid Build Coastguard Worker 	      {
272*5e7646d2SAndroid Build Coastguard Worker 		i ++;
273*5e7646d2SAndroid Build Coastguard Worker 
274*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
275*5e7646d2SAndroid Build Coastguard Worker 		{
276*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected copies after \"-n\" option."), argv[0]);
277*5e7646d2SAndroid Build Coastguard Worker 		  usage();
278*5e7646d2SAndroid Build Coastguard Worker 		}
279*5e7646d2SAndroid Build Coastguard Worker 
280*5e7646d2SAndroid Build Coastguard Worker 		num_copies = atoi(argv[i]);
281*5e7646d2SAndroid Build Coastguard Worker 	      }
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker 	      if (num_copies < 1)
284*5e7646d2SAndroid Build Coastguard Worker 	      {
285*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stderr, _("%s: Error - copies must be 1 or more."), argv[0]);
286*5e7646d2SAndroid Build Coastguard Worker 		return (1);
287*5e7646d2SAndroid Build Coastguard Worker 	      }
288*5e7646d2SAndroid Build Coastguard Worker 
289*5e7646d2SAndroid Build Coastguard Worker 	      num_options = cupsAddIntegerOption("copies", num_copies, num_options, &options);
290*5e7646d2SAndroid Build Coastguard Worker 	      break;
291*5e7646d2SAndroid Build Coastguard Worker 
292*5e7646d2SAndroid Build Coastguard Worker 	  case 'o' : /* Option */
293*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
294*5e7646d2SAndroid Build Coastguard Worker 	      {
295*5e7646d2SAndroid Build Coastguard Worker 		num_options = cupsParseOptions(opt + 1, num_options, &options);
296*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
297*5e7646d2SAndroid Build Coastguard Worker 	      }
298*5e7646d2SAndroid Build Coastguard Worker 	      else
299*5e7646d2SAndroid Build Coastguard Worker 	      {
300*5e7646d2SAndroid Build Coastguard Worker 		i ++;
301*5e7646d2SAndroid Build Coastguard Worker 
302*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
303*5e7646d2SAndroid Build Coastguard Worker 		{
304*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected option=value after \"-o\" option."), argv[0]);
305*5e7646d2SAndroid Build Coastguard Worker 		  usage();
306*5e7646d2SAndroid Build Coastguard Worker 		}
307*5e7646d2SAndroid Build Coastguard Worker 
308*5e7646d2SAndroid Build Coastguard Worker 		num_options = cupsParseOptions(argv[i], num_options, &options);
309*5e7646d2SAndroid Build Coastguard Worker 	      }
310*5e7646d2SAndroid Build Coastguard Worker 	      break;
311*5e7646d2SAndroid Build Coastguard Worker 
312*5e7646d2SAndroid Build Coastguard Worker #ifndef __sun
313*5e7646d2SAndroid Build Coastguard Worker 	  case 'p' : /* Queue priority */
314*5e7646d2SAndroid Build Coastguard Worker #endif /* !__sun */
315*5e7646d2SAndroid Build Coastguard Worker 	  case 'q' : /* Queue priority */
316*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
317*5e7646d2SAndroid Build Coastguard Worker 	      {
318*5e7646d2SAndroid Build Coastguard Worker 		priority = atoi(opt + 1);
319*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
320*5e7646d2SAndroid Build Coastguard Worker 	      }
321*5e7646d2SAndroid Build Coastguard Worker 	      else
322*5e7646d2SAndroid Build Coastguard Worker 	      {
323*5e7646d2SAndroid Build Coastguard Worker 		if ((i + 1) >= argc)
324*5e7646d2SAndroid Build Coastguard Worker 		{
325*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected priority after \"-%c\" option."), argv[0], *opt);
326*5e7646d2SAndroid Build Coastguard Worker 		  usage();
327*5e7646d2SAndroid Build Coastguard Worker 		}
328*5e7646d2SAndroid Build Coastguard Worker 
329*5e7646d2SAndroid Build Coastguard Worker 		i ++;
330*5e7646d2SAndroid Build Coastguard Worker 
331*5e7646d2SAndroid Build Coastguard Worker 		priority = atoi(argv[i]);
332*5e7646d2SAndroid Build Coastguard Worker 	      }
333*5e7646d2SAndroid Build Coastguard Worker 
334*5e7646d2SAndroid Build Coastguard Worker 	     /*
335*5e7646d2SAndroid Build Coastguard Worker 	      * For 100% Solaris compatibility, need to add:
336*5e7646d2SAndroid Build Coastguard Worker 	      *
337*5e7646d2SAndroid Build Coastguard Worker 	      *   priority = 99 * (39 - priority) / 39 + 1;
338*5e7646d2SAndroid Build Coastguard Worker 	      *
339*5e7646d2SAndroid Build Coastguard Worker 	      * However, to keep CUPS lp the same across all platforms
340*5e7646d2SAndroid Build Coastguard Worker 	      * we will break compatibility this far...
341*5e7646d2SAndroid Build Coastguard Worker 	      */
342*5e7646d2SAndroid Build Coastguard Worker 
343*5e7646d2SAndroid Build Coastguard Worker 	      if (priority < 1 || priority > 100)
344*5e7646d2SAndroid Build Coastguard Worker 	      {
345*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stderr, _("%s: Error - priority must be between 1 and 100."), argv[0]);
346*5e7646d2SAndroid Build Coastguard Worker 		return (1);
347*5e7646d2SAndroid Build Coastguard Worker 	      }
348*5e7646d2SAndroid Build Coastguard Worker 
349*5e7646d2SAndroid Build Coastguard Worker 	      num_options = cupsAddIntegerOption("job-priority", priority, num_options, &options);
350*5e7646d2SAndroid Build Coastguard Worker 	      break;
351*5e7646d2SAndroid Build Coastguard Worker 
352*5e7646d2SAndroid Build Coastguard Worker 	  case 's' : /* Silent */
353*5e7646d2SAndroid Build Coastguard Worker 	      silent = 1;
354*5e7646d2SAndroid Build Coastguard Worker 	      break;
355*5e7646d2SAndroid Build Coastguard Worker 
356*5e7646d2SAndroid Build Coastguard Worker 	  case 't' : /* Title */
357*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
358*5e7646d2SAndroid Build Coastguard Worker 	      {
359*5e7646d2SAndroid Build Coastguard Worker 		title = opt + 1;
360*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
361*5e7646d2SAndroid Build Coastguard Worker 	      }
362*5e7646d2SAndroid Build Coastguard Worker 	      else
363*5e7646d2SAndroid Build Coastguard Worker 	      {
364*5e7646d2SAndroid Build Coastguard Worker 		i ++;
365*5e7646d2SAndroid Build Coastguard Worker 
366*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
367*5e7646d2SAndroid Build Coastguard Worker 		{
368*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected title after \"-t\" option."), argv[0]);
369*5e7646d2SAndroid Build Coastguard Worker 		  usage();
370*5e7646d2SAndroid Build Coastguard Worker 		}
371*5e7646d2SAndroid Build Coastguard Worker 
372*5e7646d2SAndroid Build Coastguard Worker 		title = argv[i];
373*5e7646d2SAndroid Build Coastguard Worker 	      }
374*5e7646d2SAndroid Build Coastguard Worker 	      break;
375*5e7646d2SAndroid Build Coastguard Worker 
376*5e7646d2SAndroid Build Coastguard Worker 	  case 'y' : /* mode-list */
377*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
378*5e7646d2SAndroid Build Coastguard Worker 	      {
379*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
380*5e7646d2SAndroid Build Coastguard Worker 	      }
381*5e7646d2SAndroid Build Coastguard Worker 	      else
382*5e7646d2SAndroid Build Coastguard Worker 	      {
383*5e7646d2SAndroid Build Coastguard Worker 		i ++;
384*5e7646d2SAndroid Build Coastguard Worker 
385*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
386*5e7646d2SAndroid Build Coastguard Worker 		{
387*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected mode list after \"-y\" option."), argv[0]);
388*5e7646d2SAndroid Build Coastguard Worker 		  usage();
389*5e7646d2SAndroid Build Coastguard Worker 		}
390*5e7646d2SAndroid Build Coastguard Worker 	      }
391*5e7646d2SAndroid Build Coastguard Worker 
392*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stderr, _("%s: Warning - mode option ignored."), argv[0]);
393*5e7646d2SAndroid Build Coastguard Worker 	      break;
394*5e7646d2SAndroid Build Coastguard Worker 
395*5e7646d2SAndroid Build Coastguard Worker 	  case 'H' : /* Hold job */
396*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
397*5e7646d2SAndroid Build Coastguard Worker 	      {
398*5e7646d2SAndroid Build Coastguard Worker 		val = opt + 1;
399*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
400*5e7646d2SAndroid Build Coastguard Worker 	      }
401*5e7646d2SAndroid Build Coastguard Worker 	      else
402*5e7646d2SAndroid Build Coastguard Worker 	      {
403*5e7646d2SAndroid Build Coastguard Worker 		i ++;
404*5e7646d2SAndroid Build Coastguard Worker 
405*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
406*5e7646d2SAndroid Build Coastguard Worker 		{
407*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected hold name after \"-H\" option."), argv[0]);
408*5e7646d2SAndroid Build Coastguard Worker 		  usage();
409*5e7646d2SAndroid Build Coastguard Worker 		}
410*5e7646d2SAndroid Build Coastguard Worker 
411*5e7646d2SAndroid Build Coastguard Worker 		val = argv[i];
412*5e7646d2SAndroid Build Coastguard Worker 	      }
413*5e7646d2SAndroid Build Coastguard Worker 
414*5e7646d2SAndroid Build Coastguard Worker 	      if (!strcmp(val, "hold"))
415*5e7646d2SAndroid Build Coastguard Worker 		num_options = cupsAddOption("job-hold-until", "indefinite", num_options, &options);
416*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(val, "resume") || !strcmp(val, "release"))
417*5e7646d2SAndroid Build Coastguard Worker 		num_options = cupsAddOption("job-hold-until", "no-hold", num_options, &options);
418*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(val, "immediate"))
419*5e7646d2SAndroid Build Coastguard Worker 	      {
420*5e7646d2SAndroid Build Coastguard Worker 		num_options = cupsAddOption("job-hold-until", "no-hold", num_options, &options);
421*5e7646d2SAndroid Build Coastguard Worker 		num_options = cupsAddOption("job-priority", "100", num_options, &options);
422*5e7646d2SAndroid Build Coastguard Worker 	      }
423*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(val, "restart"))
424*5e7646d2SAndroid Build Coastguard Worker 	      {
425*5e7646d2SAndroid Build Coastguard Worker 		if (job_id < 1)
426*5e7646d2SAndroid Build Coastguard Worker 		{
427*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Need job ID (\"-i jobid\") before \"-H restart\"."), argv[0]);
428*5e7646d2SAndroid Build Coastguard Worker 		  return (1);
429*5e7646d2SAndroid Build Coastguard Worker 		}
430*5e7646d2SAndroid Build Coastguard Worker 
431*5e7646d2SAndroid Build Coastguard Worker 		if (restart_job(argv[0], job_id))
432*5e7646d2SAndroid Build Coastguard Worker 		  return (1);
433*5e7646d2SAndroid Build Coastguard Worker 	      }
434*5e7646d2SAndroid Build Coastguard Worker 	      else
435*5e7646d2SAndroid Build Coastguard Worker 		num_options = cupsAddOption("job-hold-until", val, num_options, &options);
436*5e7646d2SAndroid Build Coastguard Worker 	      break;
437*5e7646d2SAndroid Build Coastguard Worker 
438*5e7646d2SAndroid Build Coastguard Worker 	  case 'P' : /* Page list */
439*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
440*5e7646d2SAndroid Build Coastguard Worker 	      {
441*5e7646d2SAndroid Build Coastguard Worker 		val = opt + 1;
442*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
443*5e7646d2SAndroid Build Coastguard Worker 	      }
444*5e7646d2SAndroid Build Coastguard Worker 	      else
445*5e7646d2SAndroid Build Coastguard Worker 	      {
446*5e7646d2SAndroid Build Coastguard Worker 		i ++;
447*5e7646d2SAndroid Build Coastguard Worker 
448*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
449*5e7646d2SAndroid Build Coastguard Worker 		{
450*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected page list after \"-P\" option."), argv[0]);
451*5e7646d2SAndroid Build Coastguard Worker 		  usage();
452*5e7646d2SAndroid Build Coastguard Worker 		}
453*5e7646d2SAndroid Build Coastguard Worker 
454*5e7646d2SAndroid Build Coastguard Worker 		val = argv[i];
455*5e7646d2SAndroid Build Coastguard Worker 	      }
456*5e7646d2SAndroid Build Coastguard Worker 
457*5e7646d2SAndroid Build Coastguard Worker 	      num_options = cupsAddOption("page-ranges", val, num_options, &options);
458*5e7646d2SAndroid Build Coastguard Worker 	      break;
459*5e7646d2SAndroid Build Coastguard Worker 
460*5e7646d2SAndroid Build Coastguard Worker 	  case 'S' : /* character set */
461*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
462*5e7646d2SAndroid Build Coastguard Worker 	      {
463*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
464*5e7646d2SAndroid Build Coastguard Worker 	      }
465*5e7646d2SAndroid Build Coastguard Worker 	      else
466*5e7646d2SAndroid Build Coastguard Worker 	      {
467*5e7646d2SAndroid Build Coastguard Worker 		i ++;
468*5e7646d2SAndroid Build Coastguard Worker 
469*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
470*5e7646d2SAndroid Build Coastguard Worker 		{
471*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected character set after \"-S\" option."), argv[0]);
472*5e7646d2SAndroid Build Coastguard Worker 		  usage();
473*5e7646d2SAndroid Build Coastguard Worker 		}
474*5e7646d2SAndroid Build Coastguard Worker 	      }
475*5e7646d2SAndroid Build Coastguard Worker 
476*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stderr, _("%s: Warning - character set option ignored."), argv[0]);
477*5e7646d2SAndroid Build Coastguard Worker 	      break;
478*5e7646d2SAndroid Build Coastguard Worker 
479*5e7646d2SAndroid Build Coastguard Worker 	  case 'T' : /* Content-Type */
480*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
481*5e7646d2SAndroid Build Coastguard Worker 	      {
482*5e7646d2SAndroid Build Coastguard Worker 		opt += strlen(opt) - 1;
483*5e7646d2SAndroid Build Coastguard Worker 	      }
484*5e7646d2SAndroid Build Coastguard Worker 	      else
485*5e7646d2SAndroid Build Coastguard Worker 	      {
486*5e7646d2SAndroid Build Coastguard Worker 		i ++;
487*5e7646d2SAndroid Build Coastguard Worker 
488*5e7646d2SAndroid Build Coastguard Worker 		if (i >= argc)
489*5e7646d2SAndroid Build Coastguard Worker 		{
490*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stderr, _("%s: Error - expected content type after \"-T\" option."), argv[0]);
491*5e7646d2SAndroid Build Coastguard Worker 		  usage();
492*5e7646d2SAndroid Build Coastguard Worker 		}
493*5e7646d2SAndroid Build Coastguard Worker 	      }
494*5e7646d2SAndroid Build Coastguard Worker 
495*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stderr, _("%s: Warning - content type option ignored."), argv[0]);
496*5e7646d2SAndroid Build Coastguard Worker 	      break;
497*5e7646d2SAndroid Build Coastguard Worker 
498*5e7646d2SAndroid Build Coastguard Worker 	  case '-' : /* Stop processing options */
499*5e7646d2SAndroid Build Coastguard Worker 	      if (opt[1] != '\0')
500*5e7646d2SAndroid Build Coastguard Worker 	      {
501*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stderr, _("%s: Error - unknown option \"%s\"."), argv[0], argv[i]);
502*5e7646d2SAndroid Build Coastguard Worker 		usage();
503*5e7646d2SAndroid Build Coastguard Worker 	      }
504*5e7646d2SAndroid Build Coastguard Worker 
505*5e7646d2SAndroid Build Coastguard Worker 	      end_options = 1;
506*5e7646d2SAndroid Build Coastguard Worker 	      break;
507*5e7646d2SAndroid Build Coastguard Worker 
508*5e7646d2SAndroid Build Coastguard Worker 	  default :
509*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), argv[0], *opt);
510*5e7646d2SAndroid Build Coastguard Worker 	      usage();
511*5e7646d2SAndroid Build Coastguard Worker 	}
512*5e7646d2SAndroid Build Coastguard Worker       }
513*5e7646d2SAndroid Build Coastguard Worker     }
514*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[i], "-"))
515*5e7646d2SAndroid Build Coastguard Worker     {
516*5e7646d2SAndroid Build Coastguard Worker       if (num_files || job_id)
517*5e7646d2SAndroid Build Coastguard Worker       {
518*5e7646d2SAndroid Build Coastguard Worker         _cupsLangPrintf(stderr,
519*5e7646d2SAndroid Build Coastguard Worker 			_("%s: Error - cannot print from stdin if files or a "
520*5e7646d2SAndroid Build Coastguard Worker 		          "job ID are provided."), argv[0]);
521*5e7646d2SAndroid Build Coastguard Worker 	return (1);
522*5e7646d2SAndroid Build Coastguard Worker       }
523*5e7646d2SAndroid Build Coastguard Worker 
524*5e7646d2SAndroid Build Coastguard Worker       break;
525*5e7646d2SAndroid Build Coastguard Worker     }
526*5e7646d2SAndroid Build Coastguard Worker     else if (num_files < 1000 && job_id == 0)
527*5e7646d2SAndroid Build Coastguard Worker     {
528*5e7646d2SAndroid Build Coastguard Worker      /*
529*5e7646d2SAndroid Build Coastguard Worker       * Print a file...
530*5e7646d2SAndroid Build Coastguard Worker       */
531*5e7646d2SAndroid Build Coastguard Worker 
532*5e7646d2SAndroid Build Coastguard Worker       if (access(argv[i], R_OK) != 0)
533*5e7646d2SAndroid Build Coastguard Worker       {
534*5e7646d2SAndroid Build Coastguard Worker         _cupsLangPrintf(stderr, _("%s: Error - unable to access \"%s\" - %s"), argv[0], argv[i], strerror(errno));
535*5e7646d2SAndroid Build Coastguard Worker         return (1);
536*5e7646d2SAndroid Build Coastguard Worker       }
537*5e7646d2SAndroid Build Coastguard Worker 
538*5e7646d2SAndroid Build Coastguard Worker       files[num_files] = argv[i];
539*5e7646d2SAndroid Build Coastguard Worker       num_files ++;
540*5e7646d2SAndroid Build Coastguard Worker 
541*5e7646d2SAndroid Build Coastguard Worker       if (title == NULL)
542*5e7646d2SAndroid Build Coastguard Worker       {
543*5e7646d2SAndroid Build Coastguard Worker         if ((title = strrchr(argv[i], '/')) != NULL)
544*5e7646d2SAndroid Build Coastguard Worker 	  title ++;
545*5e7646d2SAndroid Build Coastguard Worker 	else
546*5e7646d2SAndroid Build Coastguard Worker           title = argv[i];
547*5e7646d2SAndroid Build Coastguard Worker       }
548*5e7646d2SAndroid Build Coastguard Worker     }
549*5e7646d2SAndroid Build Coastguard Worker     else
550*5e7646d2SAndroid Build Coastguard Worker     {
551*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stderr, _("%s: Error - too many files - \"%s\"."), argv[0], argv[i]);
552*5e7646d2SAndroid Build Coastguard Worker     }
553*5e7646d2SAndroid Build Coastguard Worker   }
554*5e7646d2SAndroid Build Coastguard Worker 
555*5e7646d2SAndroid Build Coastguard Worker  /*
556*5e7646d2SAndroid Build Coastguard Worker   * See if we are altering an existing job...
557*5e7646d2SAndroid Build Coastguard Worker   */
558*5e7646d2SAndroid Build Coastguard Worker 
559*5e7646d2SAndroid Build Coastguard Worker   if (job_id)
560*5e7646d2SAndroid Build Coastguard Worker     return (set_job_attrs(argv[0], job_id, num_options, options));
561*5e7646d2SAndroid Build Coastguard Worker 
562*5e7646d2SAndroid Build Coastguard Worker  /*
563*5e7646d2SAndroid Build Coastguard Worker   * See if we have any files to print; if not, print from stdin...
564*5e7646d2SAndroid Build Coastguard Worker   */
565*5e7646d2SAndroid Build Coastguard Worker 
566*5e7646d2SAndroid Build Coastguard Worker   if (printer == NULL)
567*5e7646d2SAndroid Build Coastguard Worker   {
568*5e7646d2SAndroid Build Coastguard Worker     if ((dest = cupsGetNamedDest(NULL, NULL, NULL)) != NULL)
569*5e7646d2SAndroid Build Coastguard Worker     {
570*5e7646d2SAndroid Build Coastguard Worker       printer = dest->name;
571*5e7646d2SAndroid Build Coastguard Worker 
572*5e7646d2SAndroid Build Coastguard Worker       for (j = 0; j < dest->num_options; j ++)
573*5e7646d2SAndroid Build Coastguard Worker 	if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
574*5e7646d2SAndroid Build Coastguard Worker 	  num_options = cupsAddOption(dest->options[j].name,
575*5e7646d2SAndroid Build Coastguard Worker 		                      dest->options[j].value,
576*5e7646d2SAndroid Build Coastguard Worker 				      num_options, &options);
577*5e7646d2SAndroid Build Coastguard Worker     }
578*5e7646d2SAndroid Build Coastguard Worker     else if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
579*5e7646d2SAndroid Build Coastguard Worker 	     cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
580*5e7646d2SAndroid Build Coastguard Worker     {
581*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stderr,
582*5e7646d2SAndroid Build Coastguard Worker 		      _("%s: Error - add '/version=1.1' to server "
583*5e7646d2SAndroid Build Coastguard Worker 			"name."), argv[0]);
584*5e7646d2SAndroid Build Coastguard Worker       return (1);
585*5e7646d2SAndroid Build Coastguard Worker     }
586*5e7646d2SAndroid Build Coastguard Worker   }
587*5e7646d2SAndroid Build Coastguard Worker 
588*5e7646d2SAndroid Build Coastguard Worker   if (printer == NULL)
589*5e7646d2SAndroid Build Coastguard Worker   {
590*5e7646d2SAndroid Build Coastguard Worker     if (!cupsGetNamedDest(NULL, NULL, NULL) && cupsLastError() == IPP_STATUS_ERROR_NOT_FOUND)
591*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stderr, _("%s: Error - %s"), argv[0], cupsLastErrorString());
592*5e7646d2SAndroid Build Coastguard Worker     else
593*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stderr, _("%s: Error - scheduler not responding."), argv[0]);
594*5e7646d2SAndroid Build Coastguard Worker 
595*5e7646d2SAndroid Build Coastguard Worker     return (1);
596*5e7646d2SAndroid Build Coastguard Worker   }
597*5e7646d2SAndroid Build Coastguard Worker 
598*5e7646d2SAndroid Build Coastguard Worker   if (num_files > 0)
599*5e7646d2SAndroid Build Coastguard Worker     job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);
600*5e7646d2SAndroid Build Coastguard Worker   else if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer,
601*5e7646d2SAndroid Build Coastguard Worker                                    title ? title : "(stdin)",
602*5e7646d2SAndroid Build Coastguard Worker                                    num_options, options)) > 0)
603*5e7646d2SAndroid Build Coastguard Worker   {
604*5e7646d2SAndroid Build Coastguard Worker     http_status_t	status;		/* Write status */
605*5e7646d2SAndroid Build Coastguard Worker     const char		*format;	/* Document format */
606*5e7646d2SAndroid Build Coastguard Worker     ssize_t		bytes;		/* Bytes read */
607*5e7646d2SAndroid Build Coastguard Worker 
608*5e7646d2SAndroid Build Coastguard Worker     if (cupsGetOption("raw", num_options, options))
609*5e7646d2SAndroid Build Coastguard Worker       format = CUPS_FORMAT_RAW;
610*5e7646d2SAndroid Build Coastguard Worker     else if ((format = cupsGetOption("document-format", num_options,
611*5e7646d2SAndroid Build Coastguard Worker                                      options)) == NULL)
612*5e7646d2SAndroid Build Coastguard Worker       format = CUPS_FORMAT_AUTO;
613*5e7646d2SAndroid Build Coastguard Worker 
614*5e7646d2SAndroid Build Coastguard Worker     status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id, NULL,
615*5e7646d2SAndroid Build Coastguard Worker                                format, 1);
616*5e7646d2SAndroid Build Coastguard Worker 
617*5e7646d2SAndroid Build Coastguard Worker     while (status == HTTP_CONTINUE &&
618*5e7646d2SAndroid Build Coastguard Worker            (bytes = read(0, buffer, sizeof(buffer))) > 0)
619*5e7646d2SAndroid Build Coastguard Worker       status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, (size_t)bytes);
620*5e7646d2SAndroid Build Coastguard Worker 
621*5e7646d2SAndroid Build Coastguard Worker     if (status != HTTP_CONTINUE)
622*5e7646d2SAndroid Build Coastguard Worker     {
623*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stderr, _("%s: Error - unable to queue from stdin - %s."),
624*5e7646d2SAndroid Build Coastguard Worker 		      argv[0], httpStatus(status));
625*5e7646d2SAndroid Build Coastguard Worker       cupsFinishDocument(CUPS_HTTP_DEFAULT, printer);
626*5e7646d2SAndroid Build Coastguard Worker       cupsCancelJob2(CUPS_HTTP_DEFAULT, printer, job_id, 0);
627*5e7646d2SAndroid Build Coastguard Worker       return (1);
628*5e7646d2SAndroid Build Coastguard Worker     }
629*5e7646d2SAndroid Build Coastguard Worker 
630*5e7646d2SAndroid Build Coastguard Worker     if (cupsFinishDocument(CUPS_HTTP_DEFAULT, printer) != IPP_OK)
631*5e7646d2SAndroid Build Coastguard Worker     {
632*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
633*5e7646d2SAndroid Build Coastguard Worker       cupsCancelJob2(CUPS_HTTP_DEFAULT, printer, job_id, 0);
634*5e7646d2SAndroid Build Coastguard Worker       return (1);
635*5e7646d2SAndroid Build Coastguard Worker     }
636*5e7646d2SAndroid Build Coastguard Worker   }
637*5e7646d2SAndroid Build Coastguard Worker 
638*5e7646d2SAndroid Build Coastguard Worker   if (job_id < 1)
639*5e7646d2SAndroid Build Coastguard Worker   {
640*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
641*5e7646d2SAndroid Build Coastguard Worker     return (1);
642*5e7646d2SAndroid Build Coastguard Worker   }
643*5e7646d2SAndroid Build Coastguard Worker   else if (!silent)
644*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPrintf(stdout, _("request id is %s-%d (%d file(s))"),
645*5e7646d2SAndroid Build Coastguard Worker 		    printer, job_id, num_files);
646*5e7646d2SAndroid Build Coastguard Worker 
647*5e7646d2SAndroid Build Coastguard Worker   return (0);
648*5e7646d2SAndroid Build Coastguard Worker }
649*5e7646d2SAndroid Build Coastguard Worker 
650*5e7646d2SAndroid Build Coastguard Worker 
651*5e7646d2SAndroid Build Coastguard Worker /*
652*5e7646d2SAndroid Build Coastguard Worker  * 'restart_job()' - Restart a job.
653*5e7646d2SAndroid Build Coastguard Worker  */
654*5e7646d2SAndroid Build Coastguard Worker 
655*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Exit status */
restart_job(const char * command,int job_id)656*5e7646d2SAndroid Build Coastguard Worker restart_job(const char *command,	/* I - Command name */
657*5e7646d2SAndroid Build Coastguard Worker             int        job_id)		/* I - Job ID */
658*5e7646d2SAndroid Build Coastguard Worker {
659*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request;		/* IPP request */
660*5e7646d2SAndroid Build Coastguard Worker   char		uri[HTTP_MAX_URI];	/* URI for job */
661*5e7646d2SAndroid Build Coastguard Worker 
662*5e7646d2SAndroid Build Coastguard Worker 
663*5e7646d2SAndroid Build Coastguard Worker   request = ippNewRequest(IPP_RESTART_JOB);
664*5e7646d2SAndroid Build Coastguard Worker 
665*5e7646d2SAndroid Build Coastguard Worker   snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
666*5e7646d2SAndroid Build Coastguard Worker 
667*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
668*5e7646d2SAndroid Build Coastguard Worker                "job-uri", NULL, uri);
669*5e7646d2SAndroid Build Coastguard Worker 
670*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
671*5e7646d2SAndroid Build Coastguard Worker                "requesting-user-name", NULL, cupsUser());
672*5e7646d2SAndroid Build Coastguard Worker 
673*5e7646d2SAndroid Build Coastguard Worker   ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/jobs"));
674*5e7646d2SAndroid Build Coastguard Worker 
675*5e7646d2SAndroid Build Coastguard Worker   if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
676*5e7646d2SAndroid Build Coastguard Worker       cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
677*5e7646d2SAndroid Build Coastguard Worker   {
678*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPrintf(stderr,
679*5e7646d2SAndroid Build Coastguard Worker 		    _("%s: Error - add '/version=1.1' to server "
680*5e7646d2SAndroid Build Coastguard Worker 		      "name."), command);
681*5e7646d2SAndroid Build Coastguard Worker     return (1);
682*5e7646d2SAndroid Build Coastguard Worker   }
683*5e7646d2SAndroid Build Coastguard Worker   else if (cupsLastError() > IPP_OK_CONFLICT)
684*5e7646d2SAndroid Build Coastguard Worker   {
685*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
686*5e7646d2SAndroid Build Coastguard Worker     return (1);
687*5e7646d2SAndroid Build Coastguard Worker   }
688*5e7646d2SAndroid Build Coastguard Worker 
689*5e7646d2SAndroid Build Coastguard Worker   return (0);
690*5e7646d2SAndroid Build Coastguard Worker }
691*5e7646d2SAndroid Build Coastguard Worker 
692*5e7646d2SAndroid Build Coastguard Worker 
693*5e7646d2SAndroid Build Coastguard Worker /*
694*5e7646d2SAndroid Build Coastguard Worker  * 'set_job_attrs()' - Set job attributes.
695*5e7646d2SAndroid Build Coastguard Worker  */
696*5e7646d2SAndroid Build Coastguard Worker 
697*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Exit status */
set_job_attrs(const char * command,int job_id,int num_options,cups_option_t * options)698*5e7646d2SAndroid Build Coastguard Worker set_job_attrs(
699*5e7646d2SAndroid Build Coastguard Worker     const char    *command,		/* I - Command name */
700*5e7646d2SAndroid Build Coastguard Worker     int           job_id,		/* I - Job ID */
701*5e7646d2SAndroid Build Coastguard Worker     int           num_options,		/* I - Number of options */
702*5e7646d2SAndroid Build Coastguard Worker     cups_option_t *options)		/* I - Options */
703*5e7646d2SAndroid Build Coastguard Worker {
704*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request;		/* IPP request */
705*5e7646d2SAndroid Build Coastguard Worker   char		uri[HTTP_MAX_URI];	/* URI for job */
706*5e7646d2SAndroid Build Coastguard Worker 
707*5e7646d2SAndroid Build Coastguard Worker 
708*5e7646d2SAndroid Build Coastguard Worker   if (num_options == 0)
709*5e7646d2SAndroid Build Coastguard Worker     return (0);
710*5e7646d2SAndroid Build Coastguard Worker 
711*5e7646d2SAndroid Build Coastguard Worker   request = ippNewRequest(IPP_SET_JOB_ATTRIBUTES);
712*5e7646d2SAndroid Build Coastguard Worker 
713*5e7646d2SAndroid Build Coastguard Worker   snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
714*5e7646d2SAndroid Build Coastguard Worker 
715*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
716*5e7646d2SAndroid Build Coastguard Worker                "job-uri", NULL, uri);
717*5e7646d2SAndroid Build Coastguard Worker 
718*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
719*5e7646d2SAndroid Build Coastguard Worker                "requesting-user-name", NULL, cupsUser());
720*5e7646d2SAndroid Build Coastguard Worker 
721*5e7646d2SAndroid Build Coastguard Worker   cupsEncodeOptions(request, num_options, options);
722*5e7646d2SAndroid Build Coastguard Worker 
723*5e7646d2SAndroid Build Coastguard Worker   ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/jobs"));
724*5e7646d2SAndroid Build Coastguard Worker 
725*5e7646d2SAndroid Build Coastguard Worker   if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
726*5e7646d2SAndroid Build Coastguard Worker       cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
727*5e7646d2SAndroid Build Coastguard Worker   {
728*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPrintf(stderr,
729*5e7646d2SAndroid Build Coastguard Worker 		    _("%s: Error - add '/version=1.1' to server "
730*5e7646d2SAndroid Build Coastguard Worker 		      "name."), command);
731*5e7646d2SAndroid Build Coastguard Worker     return (1);
732*5e7646d2SAndroid Build Coastguard Worker   }
733*5e7646d2SAndroid Build Coastguard Worker   else if (cupsLastError() > IPP_OK_CONFLICT)
734*5e7646d2SAndroid Build Coastguard Worker   {
735*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
736*5e7646d2SAndroid Build Coastguard Worker     return (1);
737*5e7646d2SAndroid Build Coastguard Worker   }
738*5e7646d2SAndroid Build Coastguard Worker 
739*5e7646d2SAndroid Build Coastguard Worker   return (0);
740*5e7646d2SAndroid Build Coastguard Worker }
741*5e7646d2SAndroid Build Coastguard Worker 
742*5e7646d2SAndroid Build Coastguard Worker 
743*5e7646d2SAndroid Build Coastguard Worker /*
744*5e7646d2SAndroid Build Coastguard Worker  * 'usage()' - Show program usage and exit.
745*5e7646d2SAndroid Build Coastguard Worker  */
746*5e7646d2SAndroid Build Coastguard Worker 
747*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)748*5e7646d2SAndroid Build Coastguard Worker usage(void)
749*5e7646d2SAndroid Build Coastguard Worker {
750*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("Usage: lp [options] [--] [file(s)]\n"
751*5e7646d2SAndroid Build Coastguard Worker                           "       lp [options] -i id"));
752*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("Options:"));
753*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-c                      Make a copy of the print file(s)"));
754*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-d destination          Specify the destination"));
755*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-E                      Encrypt the connection to the server"));
756*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-h server[:port]        Connect to the named server and port"));
757*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-H HH:MM                Hold the job until the specified UTC time"));
758*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-H hold                 Hold the job until released/resumed"));
759*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-H immediate            Print the job as soon as possible"));
760*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-H restart              Reprint the job"));
761*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-H resume               Resume a held job"));
762*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-i id                   Specify an existing job ID to modify"));
763*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-m                      Send an email notification when the job completes"));
764*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-n num-copies           Specify the number of copies to print"));
765*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-o option[=value]       Specify a printer-specific option"));
766*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-o job-sheets=standard  Print a banner page with the job"));
767*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-o media=size           Specify the media size to use"));
768*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-o number-up=N          Specify that input pages should be printed N-up (1, 2, 4, 6, 9, and 16 are supported)"));
769*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-o orientation-requested=N\n"
770*5e7646d2SAndroid Build Coastguard Worker                           "                        Specify portrait (3) or landscape (4) orientation"));
771*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-o print-quality=N      Specify the print quality - draft (3), normal (4), or best (5)"));
772*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-o sides=one-sided      Specify 1-sided printing"));
773*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-o sides=two-sided-long-edge\n"
774*5e7646d2SAndroid Build Coastguard Worker                           "                        Specify 2-sided portrait printing"));
775*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-o sides=two-sided-short-edge\n"
776*5e7646d2SAndroid Build Coastguard Worker                           "                        Specify 2-sided landscape printing"));
777*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-P page-list            Specify a list of pages to print"));
778*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-q priority             Specify the priority from low (1) to high (100)"));
779*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-s                      Be silent"));
780*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-t title                Specify the job title"));
781*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-U username             Specify the username to use for authentication"));
782*5e7646d2SAndroid Build Coastguard Worker 
783*5e7646d2SAndroid Build Coastguard Worker 
784*5e7646d2SAndroid Build Coastguard Worker   exit(1);
785*5e7646d2SAndroid Build Coastguard Worker }
786