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