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