1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 *
25 */
26
27 /* $Id: lp.c 179 2006-07-17 18:24:07Z njacobs $ */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <locale.h>
34 #include <libintl.h>
35 #include <papi.h>
36 #include "common.h"
37 #include <pwd.h>
38 #include <grp.h>
39 #include <sys/types.h>
40 #ifdef HAVE_LIBMAGIC /* for mimetype auto-detection */
41 #include <magic.h>
42 #endif /* HAVE_LIBMAGIC */
43
44 static void
usage(char * program)45 usage(char *program)
46 {
47 char *name;
48
49 if ((name = strrchr(program, '/')) == NULL)
50 name = program;
51 else
52 name++;
53
54 fprintf(stdout,
55 gettext("Usage: %s [-c] [-m] [-p] [-s] [-w] [-d destination] "
56 "[-f form-name] [-H special-handling] [-n number] "
57 "[-o option] [-P page-list] [-q priority-level] "
58 "[-S character-set | print-wheel] [-t title] [-v] "
59 "[-T content-type [-r]] [-y mode-list] [file...]\n"),
60 name);
61 exit(1);
62 }
63
64 int
main(int ac,char * av[])65 main(int ac, char *av[])
66 {
67 papi_status_t status;
68 papi_service_t svc = NULL;
69 papi_attribute_t **list = NULL;
70 papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
71 papi_job_t job = NULL;
72 char prefetch[3];
73 int prefetch_len = sizeof (prefetch);
74 char *printer = NULL;
75 char b = PAPI_TRUE;
76 int copy = 0;
77 int silent = 0;
78 int dump = 0;
79 int validate = 0;
80 int modify = -1;
81 int c;
82 uid_t ruid;
83 struct passwd *pw;
84
85 (void) setlocale(LC_ALL, "");
86 (void) textdomain("SUNW_OST_OSCMD");
87
88 ruid = getuid();
89 if ((pw = getpwuid(ruid)) != NULL)
90 (void) initgroups(pw->pw_name, pw->pw_gid);
91 (void) setuid(ruid);
92
93
94 while ((c = getopt(ac, av, "DEH:P:S:T:cd:f:i:mn:o:pq:rst:Vwy:")) != EOF)
95 switch (c) {
96 case 'H': /* handling */
97 if (strcasecmp(optarg, "hold") == 0)
98 papiAttributeListAddString(&list,
99 PAPI_ATTR_EXCL,
100 "job-hold-until", "indefinite");
101 else if (strcasecmp(optarg, "immediate") == 0)
102 papiAttributeListAddString(&list,
103 PAPI_ATTR_EXCL,
104 "job-hold-until", "no-hold");
105 else
106 papiAttributeListAddString(&list,
107 PAPI_ATTR_EXCL,
108 "job-hold-until", optarg);
109 break;
110 case 'P': { /* page list */
111 char buf[BUFSIZ];
112
113 snprintf(buf, sizeof (buf), "page-ranges=%s", optarg);
114 papiAttributeListFromString(&list,
115 PAPI_ATTR_EXCL, buf);
116 }
117 break;
118 case 'S': /* charset */
119 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
120 "lp-charset", optarg);
121 break;
122 case 'T': /* type */
123 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
124 "document-format",
125 lp_type_to_mime_type(optarg));
126 break;
127 case 'D': /* dump */
128 dump = 1;
129 break;
130 case 'c': /* copy */
131 copy = 1;
132 break;
133 case 'd': /* destination */
134 printer = optarg;
135 break;
136 case 'f': /* form */
137 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
138 "form", optarg);
139 break;
140 case 'i': /* modify job */
141 if ((get_printer_id(optarg, &printer, &modify) < 0) ||
142 (modify < 0)) {
143 fprintf(stderr,
144 gettext("invalid request id: %s\n"),
145 optarg);
146 exit(1);
147 }
148 break;
149 case 'm': /* mail when complete */
150 papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
151 "rfc-1179-mail", 1);
152 break;
153 case 'n': /* copies */
154 papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
155 "copies", atoi(optarg));
156 break;
157 case 'o': /* lp "options" */
158 papiAttributeListFromString(&list,
159 PAPI_ATTR_REPLACE, optarg);
160 break;
161 case 'p': /* Solaris - notification */
162 papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
163 "rfc-1179-mail", 1);
164 break;
165 case 'q': { /* priority */
166 int i = atoi(optarg);
167
168 i = 100 - (i * 2.5);
169 if ((i < 1) || (i > 100)) {
170 fprintf(stderr, gettext("UX:lp: "));
171 fprintf(stderr, gettext("ERROR: "));
172 fprintf(stderr, gettext("Bad priority"
173 " value \"%s\"."), optarg);
174 fprintf(stderr, gettext("\n "));
175 fprintf(stderr, gettext("TO FIX"));
176 fprintf(stderr, gettext(": "));
177 fprintf(stderr, gettext("Use an integer value"
178 " from 0 to 39."));
179 fprintf(stderr, gettext("\n"));
180 exit(1);
181 }
182 papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
183 "job-priority", i);
184 }
185 break;
186 case 'r': /* "raw" mode */
187 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
188 "document-format",
189 "application/octet-stream");
190 papiAttributeListAddString(&list, PAPI_ATTR_APPEND,
191 "stty", "raw");
192 break;
193 case 's': /* suppress message */
194 silent = 1;
195 break;
196 case 't': /* title */
197 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
198 "job-name", optarg);
199 break;
200 case 'V': /* validate */
201 validate = 1;
202 break;
203 case 'w':
204 papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
205 "rfc-1179-mail", 1);
206 break;
207 case 'y': /* lp "modes" */
208 papiAttributeListAddString(&list, PAPI_ATTR_APPEND,
209 "lp-modes", optarg);
210 break;
211 case 'E':
212 encryption = PAPI_ENCRYPT_REQUIRED;
213 break;
214 default:
215 usage(av[0]);
216 }
217
218 /* convert "banner", "nobanner" to "job-sheet" */
219 if (papiAttributeListGetBoolean(list, NULL, "banner", &b) == PAPI_OK) {
220 (void) papiAttributeListDelete(&list, "banner");
221 if (b == PAPI_FALSE)
222 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
223 "job-sheets", "none");
224 }
225
226 if ((printer == NULL) &&
227 ((printer = getenv("PRINTER")) == NULL) &&
228 ((printer = getenv("LPDEST")) == NULL))
229 printer = DEFAULT_DEST;
230
231 if (((optind + 1) == ac) && (strcmp(av[optind], "-") == 0))
232 optind = ac;
233
234 if (modify == -1) {
235 char *document_format = "text/plain";
236
237 if (optind != ac) {
238 /* get the mime type of the file data */
239 #ifdef MAGIC_MIME
240 magic_t ms = NULL;
241
242 if ((ms = magic_open(MAGIC_MIME)) != NULL) {
243 document_format = magic_file(ms, av[optind]);
244 magic_close(ms);
245 }
246 #else
247 if (is_postscript(av[optind]) == 1)
248 document_format = "application/postscript";
249 #endif
250 } else {
251 if (is_postscript_stream(0, prefetch, &prefetch_len)
252 == 1)
253 document_format = "application/postscript";
254 }
255
256 papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, "copies", 1);
257 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
258 "document-format", document_format);
259 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
260 "job-sheets", "standard");
261 }
262
263 status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback,
264 encryption, NULL);
265 if (status != PAPI_OK) {
266 fprintf(stderr, gettext(
267 "Failed to contact service for %s: %s\n"), printer,
268 verbose_papi_message(svc, status));
269 exit(1);
270 }
271
272 if (dump != 0) {
273 printf("requesting attributes:\n");
274 papiAttributeListPrint(stdout, list, "\t");
275 printf("\n");
276 }
277
278 if (modify != -1)
279 status = papiJobModify(svc, printer, modify, list, &job);
280 else if (optind == ac) /* no file list, use stdin */
281 status = jobSubmitSTDIN(svc, printer, prefetch, prefetch_len,
282 list, &job);
283 else if (validate == 1) /* validate the request can be processed */
284 status = papiJobValidate(svc, printer, list,
285 NULL, &av[optind], &job);
286 else if (copy == 0) /* reference the files in the job, default */
287 status = papiJobSubmitByReference(svc, printer, list,
288 NULL, &av[optind], &job);
289 else /* copy the files before return, -c */
290 status = papiJobSubmit(svc, printer, list,
291 NULL, &av[optind], &job);
292
293 papiAttributeListFree(list);
294
295 if (status != PAPI_OK) {
296 fprintf(stderr, gettext("%s: %s\n"), printer,
297 verbose_papi_message(svc, status));
298 papiJobFree(job);
299 papiServiceDestroy(svc);
300 exit(1);
301 }
302
303 if (((silent == 0) || (dump != 0)) &&
304 ((list = papiJobGetAttributeList(job)) != NULL)) {
305 int32_t id = -1;
306
307 if (printer == NULL)
308 papiAttributeListGetString(list, NULL,
309 "printer-name", &printer);
310
311 papiAttributeListGetInteger(list, NULL,
312 "job-id-requested", &id);
313 if (id == -1) {
314 papiAttributeListGetInteger(list, NULL, "job-id", &id);
315 }
316
317 printf(gettext("request id is %s-%d "), printer, id);
318 if (ac != optind)
319 printf("(%d file(s))\n", ac - optind);
320 else
321 printf("(standard input)\n");
322
323 if (dump != 0) {
324 printf("job attributes:\n");
325 papiAttributeListPrint(stdout, list, "\t");
326 printf("\n");
327 }
328 }
329
330 papiJobFree(job);
331 papiServiceDestroy(svc);
332
333 return (0);
334 }
335