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