]> git.ipfire.org Git - thirdparty/cups.git/blame - systemv/cancel.c
Greatly simplify the man page handling.
[thirdparty/cups.git] / systemv / cancel.c
CommitLineData
ef416fc2 1/*
503b54c9 2 * "cancel" command for CUPS.
ef416fc2 3 *
8e52928c
MS
4 * Copyright © 2007-2018 by Apple Inc.
5 * Copyright © 1997-2006 by Easy Software Products.
ef416fc2 6 *
8e52928c
MS
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
8 * information.
ef416fc2 9 */
10
11/*
12 * Include necessary headers...
13 */
14
71e16022 15#include <cups/cups-private.h>
ef416fc2 16
17
8e52928c
MS
18/*
19 * Local functions...
20 */
21
22static void usage(void) _CUPS_NORETURN;
23
24
ef416fc2 25/*
26 * 'main()' - Parse options and cancel jobs.
27 */
28
29int /* O - Exit status */
30main(int argc, /* I - Number of command-line arguments */
31 char *argv[]) /* I - Command-line arguments */
32{
33 http_t *http; /* HTTP connection to server */
34 int i; /* Looping var */
35 int job_id; /* Job ID */
36 int num_dests; /* Number of destinations */
37 cups_dest_t *dests; /* Destinations */
bdbfacc7
MS
38 char *opt, /* Option pointer */
39 *dest, /* Destination printer */
ef416fc2 40 *job, /* Job ID pointer */
41 *user; /* Cancel jobs for a user */
42 int purge; /* Purge or cancel jobs? */
43 char uri[1024]; /* Printer or job URI */
44 ipp_t *request; /* IPP request */
45 ipp_t *response; /* IPP response */
46 ipp_op_t op; /* Operation */
ef416fc2 47
48
07725fee 49 _cupsSetLocale(argv);
d09495fa 50
ef416fc2 51 /*
52 * Setup to cancel individual print jobs...
53 */
54
fa73b229 55 op = IPP_CANCEL_JOB;
56 purge = 0;
fa73b229 57 dest = NULL;
58 user = NULL;
59 http = NULL;
60 num_dests = 0;
61 dests = NULL;
ef416fc2 62
63
64 /*
65 * Process command-line arguments...
66 */
67
68 for (i = 1; i < argc; i ++)
bdbfacc7 69 {
8e52928c
MS
70 if (!strcmp(argv[i], "--help"))
71 usage();
72 else if (argv[i][0] == '-' && argv[i][1])
db8b865d 73 {
bdbfacc7 74 for (opt = argv[i] + 1; *opt; opt ++)
ef416fc2 75 {
bdbfacc7
MS
76 switch (*opt)
77 {
78 case 'E' : /* Encrypt */
ef416fc2 79#ifdef HAVE_SSL
bdbfacc7 80 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
ef416fc2 81
bdbfacc7
MS
82 if (http)
83 httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
ef416fc2 84#else
bdbfacc7 85 _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
ef416fc2 86#endif /* HAVE_SSL */
bdbfacc7
MS
87 break;
88
89 case 'U' : /* Username */
90 if (opt[1] != '\0')
91 {
92 cupsSetUser(opt + 1);
93 opt += strlen(opt) - 1;
94 }
95 else
fa73b229 96 {
bdbfacc7
MS
97 i ++;
98 if (i >= argc)
99 {
100 _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), argv[0]);
8e52928c 101 usage();
bdbfacc7
MS
102 }
103
104 cupsSetUser(argv[i]);
fa73b229 105 }
bdbfacc7 106 break;
fa73b229 107
bdbfacc7
MS
108 case 'a' : /* Cancel all jobs */
109 op = purge ? IPP_PURGE_JOBS : IPP_CANCEL_JOBS;
110 break;
88f9aafc 111
bdbfacc7
MS
112 case 'h' : /* Connect to host */
113 if (http != NULL)
114 {
115 httpClose(http);
116 http = NULL;
117 }
ef416fc2 118
bdbfacc7
MS
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]);
8e52928c 131 usage();
bdbfacc7
MS
132 }
133 else
134 cupsSetServer(argv[i]);
135 }
136 break;
ef416fc2 137
bdbfacc7
MS
138 case 'u' : /* Username */
139 op = IPP_CANCEL_MY_JOBS;
ef416fc2 140
bdbfacc7 141 if (opt[1] != '\0')
ef416fc2 142 {
bdbfacc7
MS
143 user = opt + 1;
144 opt += strlen(opt) - 1;
145 }
ef416fc2 146 else
bdbfacc7
MS
147 {
148 i ++;
149
150 if (i >= argc)
151 {
152 _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-u\" option."), argv[0]);
8e52928c 153 usage();
bdbfacc7
MS
154 }
155 else
156 user = argv[i];
157 }
158 break;
ef416fc2 159
bdbfacc7
MS
160 case 'x' : /* Purge job(s) */
161 purge = 1;
ef416fc2 162
bdbfacc7
MS
163 if (op == IPP_CANCEL_JOBS)
164 op = IPP_PURGE_JOBS;
165 break;
ef416fc2 166
bdbfacc7
MS
167 default :
168 _cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), argv[0], *opt);
169 return (1);
170 }
ef416fc2 171 }
db8b865d 172 }
ef416fc2 173 else
174 {
175 /*
176 * Cancel a job or printer...
177 */
178
179 if (num_dests == 0)
180 num_dests = cupsGetDests(&dests);
181
bd7854cb 182 if (!strcmp(argv[i], "-"))
ef416fc2 183 {
184 /*
185 * Delete the current job...
186 */
187
188 dest = "";
189 job_id = 0;
190 }
191 else if (cupsGetDest(argv[i], NULL, num_dests, dests) != NULL)
192 {
193 /*
194 * Delete the current job on the named destination...
195 */
196
197 dest = argv[i];
198 job_id = 0;
199 }
200 else if ((job = strrchr(argv[i], '-')) != NULL && isdigit(job[1] & 255))
201 {
202 /*
203 * Delete the specified job ID.
204 */
205
206 dest = NULL;
207 op = IPP_CANCEL_JOB;
208 job_id = atoi(job + 1);
209 }
210 else if (isdigit(argv[i][0] & 255))
211 {
212 /*
213 * Delete the specified job ID.
214 */
215
216 dest = NULL;
217 op = IPP_CANCEL_JOB;
218 job_id = atoi(argv[i]);
219 }
220 else
221 {
222 /*
223 * Bad printer name!
224 */
225
fa73b229 226 _cupsLangPrintf(stderr,
0837b7e8 227 _("%s: Error - unknown destination \"%s\"."),
fa73b229 228 argv[0], argv[i]);
ef416fc2 229 return (1);
230 }
231
232 /*
233 * For Solaris LP compatibility, ignore a destination name after
234 * cancelling a specific job ID...
235 */
236
237 if (job_id && (i + 1) < argc &&
238 cupsGetDest(argv[i + 1], NULL, num_dests, dests) != NULL)
239 i ++;
240
241 /*
242 * Open a connection to the server...
243 */
244
245 if (http == NULL)
246 if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
247 cupsEncryption())) == NULL)
248 {
fa73b229 249 _cupsLangPrintf(stderr,
84315f46 250 _("%s: Unable to connect to server."), argv[0]);
ef416fc2 251 return (1);
252 }
253
254 /*
255 * Build an IPP request, which requires the following
256 * attributes:
257 *
258 * attributes-charset
259 * attributes-natural-language
260 * printer-uri + job-id *or* job-uri
261 * [requesting-user-name]
262 */
263
fa73b229 264 request = ippNewRequest(op);
ef416fc2 265
266 if (dest)
267 {
a4d04587 268 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
269 "localhost", 0, "/printers/%s", dest);
ef416fc2 270 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
271 "printer-uri", NULL, uri);
272 ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
273 job_id);
274 }
275 else
276 {
277 sprintf(uri, "ipp://localhost/jobs/%d", job_id);
278 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
279 uri);
280 }
281
282 if (user)
283 {
284 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
285 "requesting-user-name", NULL, user);
286 ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
db8b865d
MS
287
288 if (op == IPP_CANCEL_JOBS)
289 op = IPP_CANCEL_MY_JOBS;
ef416fc2 290 }
291 else
292 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
293 "requesting-user-name", NULL, cupsUser());
294
db8b865d 295 if (purge)
68c4690a 296 ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", (char)purge);
ef416fc2 297
298 /*
299 * Do the request and get back a response...
300 */
301
db8b865d 302 if (op == IPP_CANCEL_JOBS && (!user || _cups_strcasecmp(user, cupsUser())))
ef416fc2 303 response = cupsDoRequest(http, request, "/admin/");
304 else
305 response = cupsDoRequest(http, request, "/jobs/");
306
307 if (response == NULL ||
308 response->request.status.status_code > IPP_OK_CONFLICT)
309 {
0837b7e8 310 _cupsLangPrintf(stderr, _("%s: %s failed: %s"), argv[0],
ef416fc2 311 op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job",
bd7854cb 312 cupsLastErrorString());
ef416fc2 313
314 if (response)
315 ippDelete(response);
316
317 return (1);
318 }
319
320 ippDelete(response);
321 }
bdbfacc7 322 }
ef416fc2 323
242b936a 324 if (num_dests == 0 && op != IPP_CANCEL_JOB)
ef416fc2 325 {
326 /*
327 * Open a connection to the server...
328 */
329
330 if (http == NULL)
331 if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
332 cupsEncryption())) == NULL)
333 {
0837b7e8 334 _cupsLangPrintf(stderr, _("%s: Unable to contact server."), argv[0]);
ef416fc2 335 return (1);
336 }
337
338 /*
339 * Build an IPP request, which requires the following
340 * attributes:
341 *
342 * attributes-charset
343 * attributes-natural-language
344 * printer-uri + job-id *or* job-uri
345 * [requesting-user-name]
346 */
347
fa73b229 348 request = ippNewRequest(op);
ef416fc2 349
350 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
351 "printer-uri", NULL, "ipp://localhost/printers/");
352
353 if (user)
354 {
355 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
356 "requesting-user-name", NULL, user);
357 ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
358 }
359 else
360 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
361 "requesting-user-name", NULL, cupsUser());
362
68c4690a 363 ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", (char)purge);
ef416fc2 364
365 /*
366 * Do the request and get back a response...
367 */
368
369 response = cupsDoRequest(http, request, "/admin/");
370
371 if (response == NULL ||
372 response->request.status.status_code > IPP_OK_CONFLICT)
373 {
0837b7e8 374 _cupsLangPrintf(stderr, _("%s: %s failed: %s"), argv[0],
ef416fc2 375 op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job",
fa73b229 376 cupsLastErrorString());
ef416fc2 377
378 if (response)
379 ippDelete(response);
380
381 return (1);
382 }
383
384 ippDelete(response);
385 }
386
387 return (0);
388}
8e52928c
MS
389
390
391/*
392 * 'usage()' - Show program usage and exit.
393 */
394
395static void
396usage(void)
397{
398 _cupsLangPuts(stdout, _("Usage: cancel [options] [id]\n"
399 " cancel [options] [destination]\n"
400 " cancel [options] [destination-id]"));
401 _cupsLangPuts(stdout, _("Options:"));
402 _cupsLangPuts(stdout, _("-a Cancel all jobs"));
403 _cupsLangPuts(stdout, _("-E Encrypt the connection to the server"));
404 _cupsLangPuts(stdout, _("-h server[:port] Connect to the named server and port"));
405 _cupsLangPuts(stdout, _("-u owner Specify the owner to use for jobs"));
406 _cupsLangPuts(stdout, _("-U username Specify the username to use for authentication"));
407 _cupsLangPuts(stdout, _("-x Purge jobs rather than just canceling"));
408
409 exit(1);
410}