1 /*
2  * "lprm" command for CUPS.
3  *
4  * Copyright © 2007-2018 by Apple Inc.
5  * Copyright © 1997-2006 by Easy Software Products.
6  *
7  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
8  * information.
9  */
10 
11 /*
12  * Include necessary headers...
13  */
14 
15 #include <cups/cups-private.h>
16 
17 
18 /*
19  * Local functions...
20  */
21 
22 static void	usage(void) _CUPS_NORETURN;
23 
24 
25 /*
26  * 'main()' - Parse options and cancel jobs.
27  */
28 
29 int				/* O - Exit status */
main(int argc,char * argv[])30 main(int  argc,			/* I - Number of command-line arguments */
31      char *argv[])		/* I - Command-line arguments */
32 {
33   int		i;		/* Looping var */
34   int		job_id;		/* Job ID */
35   const char	*name;		/* Destination printer */
36   char		*instance,	/* Pointer to instance name */
37 		*opt;		/* Option pointer */
38   cups_dest_t	*dest,		/* Destination */
39 		*defdest;	/* Default destination */
40   int		did_cancel;	/* Did we cancel something? */
41 
42 
43   _cupsSetLocale(argv);
44 
45  /*
46   * Setup to cancel individual print jobs...
47   */
48 
49   did_cancel = 0;
50   defdest    = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL);
51   name       = defdest ? defdest->name : NULL;
52 
53  /*
54   * Process command-line arguments...
55   */
56 
57   for (i = 1; i < argc; i ++)
58   {
59     if (!strcmp(argv[i], "--help"))
60       usage();
61     else if (argv[i][0] == '-' && argv[i][1] != '\0')
62     {
63       for (opt = argv[i] + 1; *opt; opt ++)
64       {
65 	switch (*opt)
66 	{
67 	  case 'E' : /* Encrypt */
68 #ifdef HAVE_SSL
69 	      cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
70 #else
71 	      _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
72 #endif /* HAVE_SSL */
73 	      break;
74 
75 	  case 'P' : /* Cancel jobs on a printer */
76 	      if (opt[1] != '\0')
77 	      {
78 		name = opt + 1;
79 		opt += strlen(opt) - 1;
80 	      }
81 	      else
82 	      {
83 		i ++;
84 		name = argv[i];
85 	      }
86 
87 	      if ((instance = strchr(name, '/')) != NULL)
88 		*instance = '\0';
89 
90 	      if ((dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, name, NULL)) == NULL)
91 	      {
92 		_cupsLangPrintf(stderr, _("%s: Error - unknown destination \"%s\"."), argv[0], name);
93 		goto error;
94 	      }
95 
96 	      cupsFreeDests(1, dest);
97 	      break;
98 
99 	  case 'U' : /* Username */
100 	      if (opt[1] != '\0')
101 	      {
102 		cupsSetUser(opt + 1);
103 		opt += strlen(opt) - 1;
104 	      }
105 	      else
106 	      {
107 		i ++;
108 		if (i >= argc)
109 		{
110 		  _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), argv[0]);
111 		  usage();
112 		}
113 
114 		cupsSetUser(argv[i]);
115 	      }
116 	      break;
117 
118 	  case 'h' : /* Connect to host */
119 	      if (opt[1] != '\0')
120 	      {
121 		cupsSetServer(opt + 1);
122 		opt += strlen(opt) - 1;
123 	      }
124 	      else
125 	      {
126 		i ++;
127 
128 		if (i >= argc)
129 		{
130 		  _cupsLangPrintf(stderr, _("%s: Error - expected hostname after \"-h\" option."), argv[0]);
131 		  usage();
132 		}
133 		else
134 		  cupsSetServer(argv[i]);
135 	      }
136 
137 	      if (defdest)
138 		cupsFreeDests(1, defdest);
139 
140 	      defdest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL);
141 	      name    = defdest ? defdest->name : NULL;
142 	      break;
143 
144 	  default :
145 	      _cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), argv[0], *opt);
146 	      usage();
147 	}
148       }
149     }
150     else
151     {
152      /*
153       * Cancel a job or printer...
154       */
155 
156       if ((dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[i], NULL)) != NULL)
157         cupsFreeDests(1, dest);
158 
159       if (dest)
160       {
161         name   = argv[i];
162         job_id = 0;
163       }
164       else if (isdigit(argv[i][0] & 255))
165       {
166         name   = NULL;
167         job_id = atoi(argv[i]);
168       }
169       else if (!strcmp(argv[i], "-"))
170       {
171        /*
172         * Cancel all jobs
173         */
174 
175         job_id = -1;
176       }
177       else
178       {
179 	_cupsLangPrintf(stderr, _("%s: Error - unknown destination \"%s\"."),
180 			argv[0], argv[i]);
181 	goto error;
182       }
183 
184       if (cupsCancelJob2(CUPS_HTTP_DEFAULT, name, job_id, 0) != IPP_OK)
185       {
186         _cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
187 	goto error;
188       }
189 
190       did_cancel = 1;
191     }
192   }
193 
194  /*
195   * If nothing has been canceled yet, cancel the current job on the specified
196   * (or default) printer...
197   */
198 
199   if (!did_cancel && cupsCancelJob2(CUPS_HTTP_DEFAULT, name, 0, 0) != IPP_OK)
200     {
201       _cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
202       goto error;
203     }
204 
205   if (defdest)
206     cupsFreeDests(1, defdest);
207 
208   return (0);
209 
210  /*
211   * If we get here there was an error, so clean up...
212   */
213 
214   error:
215 
216   if (defdest)
217     cupsFreeDests(1, defdest);
218 
219   return (1);
220 }
221 
222 
223 /*
224  * 'usage()' - Show program usage and exit.
225  */
226 
227 static void
usage(void)228 usage(void)
229 {
230   _cupsLangPuts(stdout, _("Usage: lprm [options] [id]\n"
231                           "       lprm [options] -"));
232   _cupsLangPuts(stdout, _("Options:"));
233   _cupsLangPuts(stdout, _("-                       Cancel all jobs"));
234   _cupsLangPuts(stdout, _("-E                      Encrypt the connection to the server"));
235   _cupsLangPuts(stdout, _("-h server[:port]        Connect to the named server and port"));
236   _cupsLangPuts(stdout, _("-P destination          Specify the destination"));
237   _cupsLangPuts(stdout, _("-U username             Specify the username to use for authentication"));
238 
239   exit(1);
240 }
241