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