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 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 */
27
28 /* $Id: lpr.c 146 2006-03-24 00:26:54Z njacobs $ */
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <locale.h>
37 #include <libintl.h>
38 #include <papi.h>
39 #include "common.h"
40
41 #ifdef HAVE_LIBMAGIC /* for mimetype auto-detection */
42 #include <magic.h>
43 #endif /* HAVE_LIBMAGIC */
44
45 static void
usage(char * program)46 usage(char *program)
47 {
48 char *name;
49
50 if ((name = strrchr(program, '/')) == NULL)
51 name = program;
52 else
53 name++;
54
55 fprintf(stdout,
56 gettext("Usage: %s [-P printer] [-# copies] [-C class] "
57 "[-J job] [-T title] "
58 "[-p [-i indent] [-w width]] "
59 "[-1|-2|-3|-4 font] [-m] [-h] [-s] "
60 "[-filter_option] [file ..]\n"), 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_job_t job = NULL;
71 int exit_code = 0;
72 char *printer = NULL;
73 char prefetch[3];
74 int prefetch_len = sizeof (prefetch);
75 papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
76 int dump = 0;
77 int validate = 0;
78 int remove = 0;
79 int copy = 1; /* default is to copy the data */
80 char *document_format = "text/plain";
81 int c;
82
83 (void) setlocale(LC_ALL, "");
84 (void) textdomain("SUNW_OST_OSCMD");
85
86 while ((c = getopt(ac, av,
87 "EP:#:C:DVJ:T:w:i:hplrstdgvcfmn1:2:3:4:")) != EOF)
88 switch (c) {
89 case 'E':
90 encryption = PAPI_ENCRYPT_REQUIRED;
91 break;
92 case 'P':
93 printer = optarg;
94 break;
95 case '#':
96 papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
97 "copies", atoi(optarg));
98 break;
99 case 'C':
100 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
101 "rfc-1179-class", optarg);
102 break;
103 case 'D':
104 dump = 1;
105 break;
106 case 'J':
107 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
108 "job-name", optarg);
109 break;
110 case 'T':
111 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
112 "pr-title", optarg);
113 break;
114 case 'p':
115 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
116 "document-format", "application/x-pr");
117 papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
118 "pr-filter", 1);
119 break;
120 case 'i':
121 papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
122 "pr-indent", atoi(optarg));
123 break;
124 case 'w':
125 papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
126 "pr-width", atoi(optarg));
127 break;
128 case 'h':
129 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
130 "job-sheets", "none");
131 break;
132 case 'l':
133 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
134 "document-format", "application/octet-stream");
135 break;
136 case 'o':
137 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
138 "document-format", "application/postscript");
139 break;
140 case 'c':
141 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
142 "document-format", "application/x-cif");
143 break;
144 case 'd':
145 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
146 "document-format", "application/x-dvi");
147 break;
148 case 'f':
149 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
150 "document-format", "application/x-fortran");
151 break;
152 case 'g':
153 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
154 "document-format", "application/x-plot");
155 break;
156 case 'n':
157 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
158 "document-format", "application/x-ditroff");
159 break;
160 case 't':
161 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
162 "document-format", "application/x-troff");
163 break;
164 case 'v':
165 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
166 "document-format", "application/x-raster");
167 break;
168 case 'm':
169 papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
170 "rfc-1179-mail", 1);
171 break;
172 case 'r':
173 remove = 1;
174 break;
175 case 's':
176 copy = 0;
177 break;
178 case 'V': /* validate */
179 validate = 1;
180 break;
181 case '1':
182 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
183 "rfc-1179-font-r", optarg);
184 break;
185 case '2':
186 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
187 "rfc-1179-font-i", optarg);
188 break;
189 case '3':
190 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
191 "rfc-1179-font-b", optarg);
192 break;
193 case '4':
194 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
195 "rfc-1179-font-s", optarg);
196 break;
197 default:
198 usage(av[0]);
199 }
200
201 if ((printer == NULL) &&
202 ((printer = getenv("PRINTER")) == NULL) &&
203 ((printer = getenv("LPDEST")) == NULL))
204 printer = DEFAULT_DEST;
205
206 if (((optind + 1) == ac) && (strcmp(av[optind], "-") == 0))
207 optind = ac;
208
209 if (optind != ac) {
210 /* get the mime type of the file data */
211 #ifdef MAGIC_MIME
212 magic_t ms;
213
214 if ((ms = magic_open(MAGIC_MIME)) != NULL) {
215 document_format = magic_file(ms, av[optind]);
216 magic_close(ms);
217 }
218 #else
219 if (is_postscript(av[optind]) == 1)
220 document_format = "application/postscript";
221 #endif
222 } else {
223 if (is_postscript_stream(0, prefetch, &prefetch_len) == 1)
224 document_format = "application/postscript";
225 }
226
227 papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, "copies", 1);
228 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
229 "document-format", document_format);
230 papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
231 "job-sheets", "standard");
232
233 status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback,
234 encryption, NULL);
235 if (status != PAPI_OK) {
236 fprintf(stderr, gettext(
237 "Failed to contact service for %s: %s\n"), printer,
238 verbose_papi_message(svc, status));
239 exit(1);
240 }
241
242 if (validate == 1) /* validate the request can be processed */
243 status = papiJobValidate(svc, printer, list,
244 NULL, &av[optind], &job);
245 else if (optind == ac) /* no file list, use stdin */
246 status = jobSubmitSTDIN(svc, printer, prefetch, prefetch_len,
247 list, &job);
248 else if (copy == 0) /* reference the files in the job, default */
249 status = papiJobSubmitByReference(svc, printer, list,
250 NULL, &av[optind], &job);
251 else /* copy the files before return, -c */
252 status = papiJobSubmit(svc, printer, list,
253 NULL, &av[optind], &job);
254
255 papiAttributeListFree(list);
256
257 if (status != PAPI_OK) {
258 fprintf(stderr, gettext("%s: %s\n"), printer,
259 verbose_papi_message(svc, status));
260 papiJobFree(job);
261 papiServiceDestroy(svc);
262 exit(1);
263 }
264
265 if (dump != 0) {
266 list = papiJobGetAttributeList(job);
267 printf("job attributes:\n");
268 papiAttributeListPrint(stdout, list, "\t");
269 printf("\n");
270 }
271
272 papiJobFree(job);
273 papiServiceDestroy(svc);
274
275 return (exit_code);
276 }
277