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