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