1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * "lpmove" command for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
16*5e7646d2SAndroid Build Coastguard Worker
17*5e7646d2SAndroid Build Coastguard Worker
18*5e7646d2SAndroid Build Coastguard Worker /*
19*5e7646d2SAndroid Build Coastguard Worker * Local functions...
20*5e7646d2SAndroid Build Coastguard Worker */
21*5e7646d2SAndroid Build Coastguard Worker
22*5e7646d2SAndroid Build Coastguard Worker static int move_job(http_t *http, const char *src, int jobid, const char *dest);
23*5e7646d2SAndroid Build Coastguard Worker static void usage(void) _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 show status information.
28*5e7646d2SAndroid Build Coastguard Worker */
29*5e7646d2SAndroid Build Coastguard Worker
30*5e7646d2SAndroid Build Coastguard Worker int
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 http_t *http; /* Connection to server */
36*5e7646d2SAndroid Build Coastguard Worker const char *opt, /* Option pointer */
37*5e7646d2SAndroid Build Coastguard Worker *job; /* Job name */
38*5e7646d2SAndroid Build Coastguard Worker int jobid; /* Job ID */
39*5e7646d2SAndroid Build Coastguard Worker int num_dests; /* Number of destinations */
40*5e7646d2SAndroid Build Coastguard Worker cups_dest_t *dests; /* Destinations */
41*5e7646d2SAndroid Build Coastguard Worker const char *src, /* Original queue */
42*5e7646d2SAndroid Build Coastguard Worker *dest; /* New destination */
43*5e7646d2SAndroid Build Coastguard Worker
44*5e7646d2SAndroid Build Coastguard Worker
45*5e7646d2SAndroid Build Coastguard Worker _cupsSetLocale(argv);
46*5e7646d2SAndroid Build Coastguard Worker
47*5e7646d2SAndroid Build Coastguard Worker dest = NULL;
48*5e7646d2SAndroid Build Coastguard Worker dests = NULL;
49*5e7646d2SAndroid Build Coastguard Worker job = NULL;
50*5e7646d2SAndroid Build Coastguard Worker jobid = 0;
51*5e7646d2SAndroid Build Coastguard Worker num_dests = 0;
52*5e7646d2SAndroid Build Coastguard Worker src = NULL;
53*5e7646d2SAndroid Build Coastguard Worker
54*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < argc; i ++)
55*5e7646d2SAndroid Build Coastguard Worker {
56*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(argv[i], "--help"))
57*5e7646d2SAndroid Build Coastguard Worker usage();
58*5e7646d2SAndroid Build Coastguard Worker else if (argv[i][0] == '-')
59*5e7646d2SAndroid Build Coastguard Worker {
60*5e7646d2SAndroid Build Coastguard Worker for (opt = argv[i] + 1; *opt; opt ++)
61*5e7646d2SAndroid Build Coastguard Worker {
62*5e7646d2SAndroid Build Coastguard Worker switch (*opt)
63*5e7646d2SAndroid Build Coastguard Worker {
64*5e7646d2SAndroid Build Coastguard Worker case 'E' : /* Encrypt */
65*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SSL
66*5e7646d2SAndroid Build Coastguard Worker cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
67*5e7646d2SAndroid Build Coastguard Worker
68*5e7646d2SAndroid Build Coastguard Worker #else
69*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
70*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SSL */
71*5e7646d2SAndroid Build Coastguard Worker break;
72*5e7646d2SAndroid Build Coastguard Worker
73*5e7646d2SAndroid Build Coastguard Worker case 'h' : /* Connect to host */
74*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
75*5e7646d2SAndroid Build Coastguard Worker {
76*5e7646d2SAndroid Build Coastguard Worker cupsSetServer(opt + 1);
77*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
78*5e7646d2SAndroid Build Coastguard Worker }
79*5e7646d2SAndroid Build Coastguard Worker else
80*5e7646d2SAndroid Build Coastguard Worker {
81*5e7646d2SAndroid Build Coastguard Worker i ++;
82*5e7646d2SAndroid Build Coastguard Worker
83*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
84*5e7646d2SAndroid Build Coastguard Worker {
85*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("Error: need hostname after \"-h\" option."));
86*5e7646d2SAndroid Build Coastguard Worker usage();
87*5e7646d2SAndroid Build Coastguard Worker }
88*5e7646d2SAndroid Build Coastguard Worker
89*5e7646d2SAndroid Build Coastguard Worker cupsSetServer(argv[i]);
90*5e7646d2SAndroid Build Coastguard Worker }
91*5e7646d2SAndroid Build Coastguard Worker break;
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker default :
94*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Unknown option \"%c\"."), argv[0], *opt);
95*5e7646d2SAndroid Build Coastguard Worker usage();
96*5e7646d2SAndroid Build Coastguard Worker }
97*5e7646d2SAndroid Build Coastguard Worker }
98*5e7646d2SAndroid Build Coastguard Worker }
99*5e7646d2SAndroid Build Coastguard Worker else if (!jobid && !src)
100*5e7646d2SAndroid Build Coastguard Worker {
101*5e7646d2SAndroid Build Coastguard Worker if (num_dests == 0)
102*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsGetDests(&dests);
103*5e7646d2SAndroid Build Coastguard Worker
104*5e7646d2SAndroid Build Coastguard Worker if ((job = strrchr(argv[i], '-')) != NULL &&
105*5e7646d2SAndroid Build Coastguard Worker cupsGetDest(argv[i], NULL, num_dests, dests) == NULL)
106*5e7646d2SAndroid Build Coastguard Worker jobid = atoi(job + 1);
107*5e7646d2SAndroid Build Coastguard Worker else if (isdigit(argv[i][0] & 255) &&
108*5e7646d2SAndroid Build Coastguard Worker !cupsGetDest(argv[i], NULL, num_dests, dests))
109*5e7646d2SAndroid Build Coastguard Worker jobid = atoi(argv[i]);
110*5e7646d2SAndroid Build Coastguard Worker else
111*5e7646d2SAndroid Build Coastguard Worker src = argv[i];
112*5e7646d2SAndroid Build Coastguard Worker }
113*5e7646d2SAndroid Build Coastguard Worker else if (dest == NULL)
114*5e7646d2SAndroid Build Coastguard Worker dest = argv[i];
115*5e7646d2SAndroid Build Coastguard Worker else
116*5e7646d2SAndroid Build Coastguard Worker {
117*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("lpmove: Unknown argument \"%s\"."), argv[i]);
118*5e7646d2SAndroid Build Coastguard Worker usage();
119*5e7646d2SAndroid Build Coastguard Worker }
120*5e7646d2SAndroid Build Coastguard Worker }
121*5e7646d2SAndroid Build Coastguard Worker
122*5e7646d2SAndroid Build Coastguard Worker if ((!jobid && !src) || !dest)
123*5e7646d2SAndroid Build Coastguard Worker usage();
124*5e7646d2SAndroid Build Coastguard Worker
125*5e7646d2SAndroid Build Coastguard Worker http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
126*5e7646d2SAndroid Build Coastguard Worker
127*5e7646d2SAndroid Build Coastguard Worker if (http == NULL)
128*5e7646d2SAndroid Build Coastguard Worker {
129*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("lpmove: Unable to connect to server: %s"),
130*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
131*5e7646d2SAndroid Build Coastguard Worker return (1);
132*5e7646d2SAndroid Build Coastguard Worker }
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker return (move_job(http, src, jobid, dest));
135*5e7646d2SAndroid Build Coastguard Worker }
136*5e7646d2SAndroid Build Coastguard Worker
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker /*
139*5e7646d2SAndroid Build Coastguard Worker * 'move_job()' - Move a job.
140*5e7646d2SAndroid Build Coastguard Worker */
141*5e7646d2SAndroid Build Coastguard Worker
142*5e7646d2SAndroid Build Coastguard Worker static int /* O - 0 on success, 1 on error */
move_job(http_t * http,const char * src,int jobid,const char * dest)143*5e7646d2SAndroid Build Coastguard Worker move_job(http_t *http, /* I - HTTP connection to server */
144*5e7646d2SAndroid Build Coastguard Worker const char *src, /* I - Source queue */
145*5e7646d2SAndroid Build Coastguard Worker int jobid, /* I - Job ID */
146*5e7646d2SAndroid Build Coastguard Worker const char *dest) /* I - Destination queue */
147*5e7646d2SAndroid Build Coastguard Worker {
148*5e7646d2SAndroid Build Coastguard Worker ipp_t *request; /* IPP Request */
149*5e7646d2SAndroid Build Coastguard Worker char job_uri[HTTP_MAX_URI], /* job-uri */
150*5e7646d2SAndroid Build Coastguard Worker printer_uri[HTTP_MAX_URI]; /* job-printer-uri */
151*5e7646d2SAndroid Build Coastguard Worker
152*5e7646d2SAndroid Build Coastguard Worker
153*5e7646d2SAndroid Build Coastguard Worker if (!http)
154*5e7646d2SAndroid Build Coastguard Worker return (1);
155*5e7646d2SAndroid Build Coastguard Worker
156*5e7646d2SAndroid Build Coastguard Worker /*
157*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS_MOVE_JOB request, which requires the following
158*5e7646d2SAndroid Build Coastguard Worker * attributes:
159*5e7646d2SAndroid Build Coastguard Worker *
160*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
161*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
162*5e7646d2SAndroid Build Coastguard Worker * job-uri/printer-uri
163*5e7646d2SAndroid Build Coastguard Worker * job-printer-uri
164*5e7646d2SAndroid Build Coastguard Worker * requesting-user-name
165*5e7646d2SAndroid Build Coastguard Worker */
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_MOVE_JOB);
168*5e7646d2SAndroid Build Coastguard Worker
169*5e7646d2SAndroid Build Coastguard Worker if (jobid)
170*5e7646d2SAndroid Build Coastguard Worker {
171*5e7646d2SAndroid Build Coastguard Worker snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", jobid);
172*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
173*5e7646d2SAndroid Build Coastguard Worker job_uri);
174*5e7646d2SAndroid Build Coastguard Worker }
175*5e7646d2SAndroid Build Coastguard Worker else
176*5e7646d2SAndroid Build Coastguard Worker {
177*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
178*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, "/printers/%s", src);
179*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
180*5e7646d2SAndroid Build Coastguard Worker job_uri);
181*5e7646d2SAndroid Build Coastguard Worker }
182*5e7646d2SAndroid Build Coastguard Worker
183*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
184*5e7646d2SAndroid Build Coastguard Worker NULL, cupsUser());
185*5e7646d2SAndroid Build Coastguard Worker
186*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
187*5e7646d2SAndroid Build Coastguard Worker "ipp", NULL, "localhost", 0, "/printers/%s", dest);
188*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri",
189*5e7646d2SAndroid Build Coastguard Worker NULL, printer_uri);
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker /*
192*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
193*5e7646d2SAndroid Build Coastguard Worker */
194*5e7646d2SAndroid Build Coastguard Worker
195*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(http, request, "/jobs"));
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() > IPP_OK_CONFLICT)
198*5e7646d2SAndroid Build Coastguard Worker {
199*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, "lpmove: %s", cupsLastErrorString());
200*5e7646d2SAndroid Build Coastguard Worker return (1);
201*5e7646d2SAndroid Build Coastguard Worker }
202*5e7646d2SAndroid Build Coastguard Worker else
203*5e7646d2SAndroid Build Coastguard Worker return (0);
204*5e7646d2SAndroid Build Coastguard Worker }
205*5e7646d2SAndroid Build Coastguard Worker
206*5e7646d2SAndroid Build Coastguard Worker
207*5e7646d2SAndroid Build Coastguard Worker /*
208*5e7646d2SAndroid Build Coastguard Worker * 'usage()' - Show program usage and exit.
209*5e7646d2SAndroid Build Coastguard Worker */
210*5e7646d2SAndroid Build Coastguard Worker
211*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)212*5e7646d2SAndroid Build Coastguard Worker usage(void)
213*5e7646d2SAndroid Build Coastguard Worker {
214*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("Usage: lpmove [options] job destination\n"
215*5e7646d2SAndroid Build Coastguard Worker " lpmove [options] source-destination destination"));
216*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("Options:"));
217*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-E Encrypt the connection to the server"));
218*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-h server[:port] Connect to the named server and port"));
219*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-U username Specify the username to use for authentication"));
220*5e7646d2SAndroid Build Coastguard Worker
221*5e7646d2SAndroid Build Coastguard Worker exit(1);
222*5e7646d2SAndroid Build Coastguard Worker }
223