1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * "cupsaccept", "cupsdisable", "cupsenable", and "cupsreject" commands for
3*5e7646d2SAndroid Build Coastguard Worker * CUPS.
4*5e7646d2SAndroid Build Coastguard Worker *
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2018 by Apple Inc.
6*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2006 by Easy Software Products.
7*5e7646d2SAndroid Build Coastguard Worker *
8*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
9*5e7646d2SAndroid Build Coastguard Worker * information.
10*5e7646d2SAndroid Build Coastguard Worker */
11*5e7646d2SAndroid Build Coastguard Worker
12*5e7646d2SAndroid Build Coastguard Worker /*
13*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
14*5e7646d2SAndroid Build Coastguard Worker */
15*5e7646d2SAndroid Build Coastguard Worker
16*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
17*5e7646d2SAndroid Build Coastguard Worker
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker /*
20*5e7646d2SAndroid Build Coastguard Worker * Local functions...
21*5e7646d2SAndroid Build Coastguard Worker */
22*5e7646d2SAndroid Build Coastguard Worker
23*5e7646d2SAndroid Build Coastguard Worker static void usage(const char *command) _CUPS_NORETURN;
24*5e7646d2SAndroid Build Coastguard Worker
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker /*
27*5e7646d2SAndroid Build Coastguard Worker * 'main()' - Parse options and accept/reject jobs or disable/enable printers.
28*5e7646d2SAndroid Build Coastguard Worker */
29*5e7646d2SAndroid Build Coastguard Worker
30*5e7646d2SAndroid Build Coastguard Worker int /* O - Exit status */
main(int argc,char * argv[])31*5e7646d2SAndroid Build Coastguard Worker main(int argc, /* I - Number of command-line arguments */
32*5e7646d2SAndroid Build Coastguard Worker char *argv[]) /* I - Command-line arguments */
33*5e7646d2SAndroid Build Coastguard Worker {
34*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
35*5e7646d2SAndroid Build Coastguard Worker char *command, /* Command to do */
36*5e7646d2SAndroid Build Coastguard Worker *opt, /* Option pointer */
37*5e7646d2SAndroid Build Coastguard Worker uri[1024], /* Printer URI */
38*5e7646d2SAndroid Build Coastguard Worker *reason; /* Reason for reject/disable */
39*5e7646d2SAndroid Build Coastguard Worker ipp_t *request; /* IPP request */
40*5e7646d2SAndroid Build Coastguard Worker ipp_op_t op; /* Operation */
41*5e7646d2SAndroid Build Coastguard Worker int cancel; /* Cancel jobs? */
42*5e7646d2SAndroid Build Coastguard Worker
43*5e7646d2SAndroid Build Coastguard Worker
44*5e7646d2SAndroid Build Coastguard Worker _cupsSetLocale(argv);
45*5e7646d2SAndroid Build Coastguard Worker
46*5e7646d2SAndroid Build Coastguard Worker /*
47*5e7646d2SAndroid Build Coastguard Worker * See what operation we're supposed to do...
48*5e7646d2SAndroid Build Coastguard Worker */
49*5e7646d2SAndroid Build Coastguard Worker
50*5e7646d2SAndroid Build Coastguard Worker if ((command = strrchr(argv[0], '/')) != NULL)
51*5e7646d2SAndroid Build Coastguard Worker command ++;
52*5e7646d2SAndroid Build Coastguard Worker else
53*5e7646d2SAndroid Build Coastguard Worker command = argv[0];
54*5e7646d2SAndroid Build Coastguard Worker
55*5e7646d2SAndroid Build Coastguard Worker cancel = 0;
56*5e7646d2SAndroid Build Coastguard Worker
57*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(command, "cupsaccept"))
58*5e7646d2SAndroid Build Coastguard Worker op = CUPS_ACCEPT_JOBS;
59*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(command, "cupsreject"))
60*5e7646d2SAndroid Build Coastguard Worker op = CUPS_REJECT_JOBS;
61*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(command, "cupsdisable"))
62*5e7646d2SAndroid Build Coastguard Worker op = IPP_PAUSE_PRINTER;
63*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(command, "cupsenable"))
64*5e7646d2SAndroid Build Coastguard Worker op = IPP_RESUME_PRINTER;
65*5e7646d2SAndroid Build Coastguard Worker else
66*5e7646d2SAndroid Build Coastguard Worker {
67*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Don't know what to do."), command);
68*5e7646d2SAndroid Build Coastguard Worker return (1);
69*5e7646d2SAndroid Build Coastguard Worker }
70*5e7646d2SAndroid Build Coastguard Worker
71*5e7646d2SAndroid Build Coastguard Worker reason = NULL;
72*5e7646d2SAndroid Build Coastguard Worker
73*5e7646d2SAndroid Build Coastguard Worker /*
74*5e7646d2SAndroid Build Coastguard Worker * Process command-line arguments...
75*5e7646d2SAndroid Build Coastguard Worker */
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < argc; i ++)
78*5e7646d2SAndroid Build Coastguard Worker {
79*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(argv[i], "--help"))
80*5e7646d2SAndroid Build Coastguard Worker usage(command);
81*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(argv[i], "--hold"))
82*5e7646d2SAndroid Build Coastguard Worker op = IPP_HOLD_NEW_JOBS;
83*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(argv[i], "--release"))
84*5e7646d2SAndroid Build Coastguard Worker op = IPP_RELEASE_HELD_NEW_JOBS;
85*5e7646d2SAndroid Build Coastguard Worker else if (argv[i][0] == '-')
86*5e7646d2SAndroid Build Coastguard Worker {
87*5e7646d2SAndroid Build Coastguard Worker for (opt = argv[i] + 1; *opt; opt ++)
88*5e7646d2SAndroid Build Coastguard Worker {
89*5e7646d2SAndroid Build Coastguard Worker switch (*opt)
90*5e7646d2SAndroid Build Coastguard Worker {
91*5e7646d2SAndroid Build Coastguard Worker case 'E' : /* Encrypt */
92*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SSL
93*5e7646d2SAndroid Build Coastguard Worker cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
94*5e7646d2SAndroid Build Coastguard Worker #else
95*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), command);
96*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SSL */
97*5e7646d2SAndroid Build Coastguard Worker break;
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker case 'U' : /* Username */
100*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
101*5e7646d2SAndroid Build Coastguard Worker {
102*5e7646d2SAndroid Build Coastguard Worker cupsSetUser(opt + 1);
103*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
104*5e7646d2SAndroid Build Coastguard Worker }
105*5e7646d2SAndroid Build Coastguard Worker else
106*5e7646d2SAndroid Build Coastguard Worker {
107*5e7646d2SAndroid Build Coastguard Worker i ++;
108*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
109*5e7646d2SAndroid Build Coastguard Worker {
110*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), command);
111*5e7646d2SAndroid Build Coastguard Worker usage(command);
112*5e7646d2SAndroid Build Coastguard Worker }
113*5e7646d2SAndroid Build Coastguard Worker
114*5e7646d2SAndroid Build Coastguard Worker cupsSetUser(argv[i]);
115*5e7646d2SAndroid Build Coastguard Worker }
116*5e7646d2SAndroid Build Coastguard Worker break;
117*5e7646d2SAndroid Build Coastguard Worker
118*5e7646d2SAndroid Build Coastguard Worker case 'c' : /* Cancel jobs */
119*5e7646d2SAndroid Build Coastguard Worker cancel = 1;
120*5e7646d2SAndroid Build Coastguard Worker break;
121*5e7646d2SAndroid Build Coastguard Worker
122*5e7646d2SAndroid Build Coastguard Worker case 'h' : /* Connect to host */
123*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
124*5e7646d2SAndroid Build Coastguard Worker {
125*5e7646d2SAndroid Build Coastguard Worker cupsSetServer(opt + 1);
126*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
127*5e7646d2SAndroid Build Coastguard Worker }
128*5e7646d2SAndroid Build Coastguard Worker else
129*5e7646d2SAndroid Build Coastguard Worker {
130*5e7646d2SAndroid Build Coastguard Worker i ++;
131*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
132*5e7646d2SAndroid Build Coastguard Worker {
133*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - expected hostname after \"-h\" option."), command);
134*5e7646d2SAndroid Build Coastguard Worker usage(command);
135*5e7646d2SAndroid Build Coastguard Worker }
136*5e7646d2SAndroid Build Coastguard Worker
137*5e7646d2SAndroid Build Coastguard Worker cupsSetServer(argv[i]);
138*5e7646d2SAndroid Build Coastguard Worker }
139*5e7646d2SAndroid Build Coastguard Worker break;
140*5e7646d2SAndroid Build Coastguard Worker
141*5e7646d2SAndroid Build Coastguard Worker case 'r' : /* Reason for cancellation */
142*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
143*5e7646d2SAndroid Build Coastguard Worker {
144*5e7646d2SAndroid Build Coastguard Worker reason = opt + 1;
145*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
146*5e7646d2SAndroid Build Coastguard Worker }
147*5e7646d2SAndroid Build Coastguard Worker else
148*5e7646d2SAndroid Build Coastguard Worker {
149*5e7646d2SAndroid Build Coastguard Worker i ++;
150*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
151*5e7646d2SAndroid Build Coastguard Worker {
152*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - expected reason text after \"-r\" option."), command);
153*5e7646d2SAndroid Build Coastguard Worker usage(command);
154*5e7646d2SAndroid Build Coastguard Worker }
155*5e7646d2SAndroid Build Coastguard Worker
156*5e7646d2SAndroid Build Coastguard Worker reason = argv[i];
157*5e7646d2SAndroid Build Coastguard Worker }
158*5e7646d2SAndroid Build Coastguard Worker break;
159*5e7646d2SAndroid Build Coastguard Worker
160*5e7646d2SAndroid Build Coastguard Worker default :
161*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), command, *opt);
162*5e7646d2SAndroid Build Coastguard Worker usage(command);
163*5e7646d2SAndroid Build Coastguard Worker }
164*5e7646d2SAndroid Build Coastguard Worker }
165*5e7646d2SAndroid Build Coastguard Worker }
166*5e7646d2SAndroid Build Coastguard Worker else
167*5e7646d2SAndroid Build Coastguard Worker {
168*5e7646d2SAndroid Build Coastguard Worker /*
169*5e7646d2SAndroid Build Coastguard Worker * Accept/disable/enable/reject a destination...
170*5e7646d2SAndroid Build Coastguard Worker */
171*5e7646d2SAndroid Build Coastguard Worker
172*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(op);
173*5e7646d2SAndroid Build Coastguard Worker
174*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
175*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, "/printers/%s", argv[i]);
176*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
177*5e7646d2SAndroid Build Coastguard Worker "printer-uri", NULL, uri);
178*5e7646d2SAndroid Build Coastguard Worker
179*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
180*5e7646d2SAndroid Build Coastguard Worker "requesting-user-name", NULL, cupsUser());
181*5e7646d2SAndroid Build Coastguard Worker
182*5e7646d2SAndroid Build Coastguard Worker if (reason != NULL)
183*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
184*5e7646d2SAndroid Build Coastguard Worker "printer-state-message", NULL, reason);
185*5e7646d2SAndroid Build Coastguard Worker
186*5e7646d2SAndroid Build Coastguard Worker /*
187*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
188*5e7646d2SAndroid Build Coastguard Worker */
189*5e7646d2SAndroid Build Coastguard Worker
190*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/"));
191*5e7646d2SAndroid Build Coastguard Worker
192*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() > IPP_OK_CONFLICT)
193*5e7646d2SAndroid Build Coastguard Worker {
194*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
195*5e7646d2SAndroid Build Coastguard Worker _("%s: Operation failed: %s"),
196*5e7646d2SAndroid Build Coastguard Worker command, ippErrorString(cupsLastError()));
197*5e7646d2SAndroid Build Coastguard Worker return (1);
198*5e7646d2SAndroid Build Coastguard Worker }
199*5e7646d2SAndroid Build Coastguard Worker
200*5e7646d2SAndroid Build Coastguard Worker /*
201*5e7646d2SAndroid Build Coastguard Worker * Cancel all jobs if requested...
202*5e7646d2SAndroid Build Coastguard Worker */
203*5e7646d2SAndroid Build Coastguard Worker
204*5e7646d2SAndroid Build Coastguard Worker if (cancel)
205*5e7646d2SAndroid Build Coastguard Worker {
206*5e7646d2SAndroid Build Coastguard Worker /*
207*5e7646d2SAndroid Build Coastguard Worker * Build an IPP_PURGE_JOBS request, which requires the following
208*5e7646d2SAndroid Build Coastguard Worker * attributes:
209*5e7646d2SAndroid Build Coastguard Worker *
210*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
211*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
212*5e7646d2SAndroid Build Coastguard Worker * printer-uri
213*5e7646d2SAndroid Build Coastguard Worker */
214*5e7646d2SAndroid Build Coastguard Worker
215*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(IPP_PURGE_JOBS);
216*5e7646d2SAndroid Build Coastguard Worker
217*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
218*5e7646d2SAndroid Build Coastguard Worker "printer-uri", NULL, uri);
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/"));
221*5e7646d2SAndroid Build Coastguard Worker
222*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() > IPP_OK_CONFLICT)
223*5e7646d2SAndroid Build Coastguard Worker {
224*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
225*5e7646d2SAndroid Build Coastguard Worker return (1);
226*5e7646d2SAndroid Build Coastguard Worker }
227*5e7646d2SAndroid Build Coastguard Worker }
228*5e7646d2SAndroid Build Coastguard Worker }
229*5e7646d2SAndroid Build Coastguard Worker }
230*5e7646d2SAndroid Build Coastguard Worker
231*5e7646d2SAndroid Build Coastguard Worker return (0);
232*5e7646d2SAndroid Build Coastguard Worker }
233*5e7646d2SAndroid Build Coastguard Worker
234*5e7646d2SAndroid Build Coastguard Worker
235*5e7646d2SAndroid Build Coastguard Worker /*
236*5e7646d2SAndroid Build Coastguard Worker * 'usage()' - Show program usage and exit.
237*5e7646d2SAndroid Build Coastguard Worker */
238*5e7646d2SAndroid Build Coastguard Worker
239*5e7646d2SAndroid Build Coastguard Worker static void
usage(const char * command)240*5e7646d2SAndroid Build Coastguard Worker usage(const char *command) /* I - Command name */
241*5e7646d2SAndroid Build Coastguard Worker {
242*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stdout, _("Usage: %s [options] destination(s)"), command);
243*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("Options:"));
244*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-E Encrypt the connection to the server"));
245*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-h server[:port] Connect to the named server and port"));
246*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-r reason Specify a reason message that others can see"));
247*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-U username Specify the username to use for authentication"));
248*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(command, "cupsdisable"))
249*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("--hold Hold new jobs"));
250*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(command, "cupsenable"))
251*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("--release Release previously held jobs"));
252*5e7646d2SAndroid Build Coastguard Worker
253*5e7646d2SAndroid Build Coastguard Worker exit(1);
254*5e7646d2SAndroid Build Coastguard Worker }
255