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