12264Sjacobs /*
22264Sjacobs * CDDL HEADER START
32264Sjacobs *
42264Sjacobs * The contents of this file are subject to the terms of the
52264Sjacobs * Common Development and Distribution License (the "License").
62264Sjacobs * You may not use this file except in compliance with the License.
72264Sjacobs *
82264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92264Sjacobs * or http://www.opensolaris.org/os/licensing.
102264Sjacobs * See the License for the specific language governing permissions
112264Sjacobs * and limitations under the License.
122264Sjacobs *
132264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each
142264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152264Sjacobs * If applicable, add the following below this CDDL HEADER, with the
162264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying
172264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner]
182264Sjacobs *
192264Sjacobs * CDDL HEADER END
202264Sjacobs */
212264Sjacobs
222264Sjacobs /*
237109Sps29005 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
242264Sjacobs * Use is subject to license terms.
252264Sjacobs *
262264Sjacobs */
272264Sjacobs
282264Sjacobs /* $Id: lpr.c 146 2006-03-24 00:26:54Z njacobs $ */
292264Sjacobs
302264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI"
312264Sjacobs
322264Sjacobs #include <stdio.h>
332264Sjacobs #include <stdlib.h>
342264Sjacobs #include <unistd.h>
352264Sjacobs #include <string.h>
362264Sjacobs #include <locale.h>
372264Sjacobs #include <libintl.h>
382264Sjacobs #include <papi.h>
392264Sjacobs #include "common.h"
402264Sjacobs
412264Sjacobs #ifdef HAVE_LIBMAGIC /* for mimetype auto-detection */
422264Sjacobs #include <magic.h>
432264Sjacobs #endif /* HAVE_LIBMAGIC */
442264Sjacobs
452264Sjacobs static void
usage(char * program)462264Sjacobs usage(char *program)
472264Sjacobs {
482264Sjacobs char *name;
492264Sjacobs
502264Sjacobs if ((name = strrchr(program, '/')) == NULL)
512264Sjacobs name = program;
522264Sjacobs else
532264Sjacobs name++;
542264Sjacobs
552264Sjacobs fprintf(stdout,
562264Sjacobs gettext("Usage: %s [-P printer] [-# copies] [-C class] "
572264Sjacobs "[-J job] [-T title] "
582264Sjacobs "[-p [-i indent] [-w width]] "
592264Sjacobs "[-1|-2|-3|-4 font] [-m] [-h] [-s] "
602264Sjacobs "[-filter_option] [file ..]\n"), name);
612264Sjacobs exit(1);
622264Sjacobs }
632264Sjacobs
642264Sjacobs int
main(int ac,char * av[])652264Sjacobs main(int ac, char *av[])
662264Sjacobs {
672264Sjacobs papi_status_t status;
682264Sjacobs papi_service_t svc = NULL;
692264Sjacobs papi_attribute_t **list = NULL;
702264Sjacobs papi_job_t job = NULL;
712264Sjacobs int exit_code = 0;
722264Sjacobs char *printer = NULL;
73*7253Sjacobs char prefetch[3];
74*7253Sjacobs int prefetch_len = sizeof (prefetch);
752264Sjacobs papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
762264Sjacobs int dump = 0;
772264Sjacobs int validate = 0;
782264Sjacobs int remove = 0;
792264Sjacobs int copy = 1; /* default is to copy the data */
803125Sjacobs char *document_format = "text/plain";
812264Sjacobs int c;
822264Sjacobs
832264Sjacobs (void) setlocale(LC_ALL, "");
842264Sjacobs (void) textdomain("SUNW_OST_OSCMD");
852264Sjacobs
862264Sjacobs while ((c = getopt(ac, av,
872264Sjacobs "EP:#:C:DVJ:T:w:i:hplrstdgvcfmn1:2:3:4:")) != EOF)
882264Sjacobs switch (c) {
892264Sjacobs case 'E':
902264Sjacobs encryption = PAPI_ENCRYPT_REQUIRED;
912264Sjacobs break;
922264Sjacobs case 'P':
932264Sjacobs printer = optarg;
942264Sjacobs break;
952264Sjacobs case '#':
962264Sjacobs papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
972264Sjacobs "copies", atoi(optarg));
982264Sjacobs break;
992264Sjacobs case 'C':
1002264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1012264Sjacobs "rfc-1179-class", optarg);
1022264Sjacobs break;
1032264Sjacobs case 'D':
1042264Sjacobs dump = 1;
1052264Sjacobs break;
1062264Sjacobs case 'J':
1072264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1082264Sjacobs "job-name", optarg);
1092264Sjacobs break;
1102264Sjacobs case 'T':
1112264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1122264Sjacobs "pr-title", optarg);
1132264Sjacobs break;
1142264Sjacobs case 'p':
1152264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1162264Sjacobs "document-format", "application/x-pr");
1172264Sjacobs papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
1182264Sjacobs "pr-filter", 1);
1192264Sjacobs break;
1202264Sjacobs case 'i':
1212264Sjacobs papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
1222264Sjacobs "pr-indent", atoi(optarg));
1232264Sjacobs break;
1242264Sjacobs case 'w':
1252264Sjacobs papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
1262264Sjacobs "pr-width", atoi(optarg));
1272264Sjacobs break;
1282264Sjacobs case 'h':
1292264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1302264Sjacobs "job-sheets", "none");
1312264Sjacobs break;
1322264Sjacobs case 'l':
1332264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1342264Sjacobs "document-format", "application/octet-stream");
1352264Sjacobs break;
1362264Sjacobs case 'o':
1372264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1382264Sjacobs "document-format", "application/postscript");
1392264Sjacobs break;
1402264Sjacobs case 'c':
1412264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1422264Sjacobs "document-format", "application/x-cif");
1432264Sjacobs break;
1442264Sjacobs case 'd':
1452264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1462264Sjacobs "document-format", "application/x-dvi");
1472264Sjacobs break;
1482264Sjacobs case 'f':
1492264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1502264Sjacobs "document-format", "application/x-fortran");
1512264Sjacobs break;
1522264Sjacobs case 'g':
1532264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1542264Sjacobs "document-format", "application/x-plot");
1552264Sjacobs break;
1562264Sjacobs case 'n':
1572264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1582264Sjacobs "document-format", "application/x-ditroff");
1592264Sjacobs break;
1602264Sjacobs case 't':
1612264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1622264Sjacobs "document-format", "application/x-troff");
1632264Sjacobs break;
1642264Sjacobs case 'v':
1652264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1662264Sjacobs "document-format", "application/x-raster");
1672264Sjacobs break;
1682264Sjacobs case 'm':
1692264Sjacobs papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
1702264Sjacobs "rfc-1179-mail", 1);
1712264Sjacobs break;
1722264Sjacobs case 'r':
1732264Sjacobs remove = 1;
1742264Sjacobs break;
1752264Sjacobs case 's':
1762264Sjacobs copy = 0;
1772264Sjacobs break;
1782264Sjacobs case 'V': /* validate */
1792264Sjacobs validate = 1;
1802264Sjacobs break;
1812264Sjacobs case '1':
1822264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1832264Sjacobs "rfc-1179-font-r", optarg);
1842264Sjacobs break;
1852264Sjacobs case '2':
1862264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1872264Sjacobs "rfc-1179-font-i", optarg);
1882264Sjacobs break;
1892264Sjacobs case '3':
1902264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1912264Sjacobs "rfc-1179-font-b", optarg);
1922264Sjacobs break;
1932264Sjacobs case '4':
1942264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
1952264Sjacobs "rfc-1179-font-s", optarg);
1962264Sjacobs break;
1972264Sjacobs default:
1982264Sjacobs usage(av[0]);
1992264Sjacobs }
2002264Sjacobs
2012264Sjacobs if ((printer == NULL) &&
2022264Sjacobs ((printer = getenv("PRINTER")) == NULL) &&
2032264Sjacobs ((printer = getenv("LPDEST")) == NULL))
2042264Sjacobs printer = DEFAULT_DEST;
2052264Sjacobs
2062660Sjacobs if (((optind + 1) == ac) && (strcmp(av[optind], "-") == 0))
2072660Sjacobs optind = ac;
2082660Sjacobs
2092264Sjacobs if (optind != ac) {
2102264Sjacobs /* get the mime type of the file data */
2113125Sjacobs #ifdef MAGIC_MIME
2122264Sjacobs magic_t ms;
2132264Sjacobs
2142264Sjacobs if ((ms = magic_open(MAGIC_MIME)) != NULL) {
2152264Sjacobs document_format = magic_file(ms, av[optind]);
2162264Sjacobs magic_close(ms);
2172264Sjacobs }
2183125Sjacobs #else
2193125Sjacobs if (is_postscript(av[optind]) == 1)
2203125Sjacobs document_format = "application/postscript";
2213125Sjacobs #endif
222*7253Sjacobs } else {
223*7253Sjacobs if (is_postscript_stream(0, prefetch, &prefetch_len) == 1)
224*7253Sjacobs document_format = "application/postscript";
2252264Sjacobs }
2262264Sjacobs
2272264Sjacobs papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, "copies", 1);
2282264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
2292264Sjacobs "document-format", document_format);
2302264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
2312264Sjacobs "job-sheets", "standard");
2322264Sjacobs
2332264Sjacobs status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback,
2342264Sjacobs encryption, NULL);
2352264Sjacobs if (status != PAPI_OK) {
2362264Sjacobs fprintf(stderr, gettext(
2372264Sjacobs "Failed to contact service for %s: %s\n"), printer,
2382264Sjacobs verbose_papi_message(svc, status));
2392264Sjacobs exit(1);
2402264Sjacobs }
2412264Sjacobs
2422264Sjacobs if (validate == 1) /* validate the request can be processed */
2432264Sjacobs status = papiJobValidate(svc, printer, list,
2442264Sjacobs NULL, &av[optind], &job);
2452264Sjacobs else if (optind == ac) /* no file list, use stdin */
246*7253Sjacobs status = jobSubmitSTDIN(svc, printer, prefetch, prefetch_len,
247*7253Sjacobs list, &job);
2482264Sjacobs else if (copy == 0) /* reference the files in the job, default */
2492264Sjacobs status = papiJobSubmitByReference(svc, printer, list,
2502264Sjacobs NULL, &av[optind], &job);
2512264Sjacobs else /* copy the files before return, -c */
2522264Sjacobs status = papiJobSubmit(svc, printer, list,
2532264Sjacobs NULL, &av[optind], &job);
2542264Sjacobs
2552264Sjacobs papiAttributeListFree(list);
2562264Sjacobs
2572264Sjacobs if (status != PAPI_OK) {
2582264Sjacobs fprintf(stderr, gettext("%s: %s\n"), printer,
2592264Sjacobs verbose_papi_message(svc, status));
2602264Sjacobs papiJobFree(job);
2612264Sjacobs papiServiceDestroy(svc);
2622264Sjacobs exit(1);
2632264Sjacobs }
2642264Sjacobs
2652264Sjacobs if (dump != 0) {
2662264Sjacobs list = papiJobGetAttributeList(job);
2672264Sjacobs printf("job attributes:\n");
2682264Sjacobs papiAttributeListPrint(stdout, list, "\t");
2692264Sjacobs printf("\n");
2702264Sjacobs }
2712264Sjacobs
2722264Sjacobs papiJobFree(job);
2732264Sjacobs papiServiceDestroy(svc);
2742264Sjacobs
2752264Sjacobs return (exit_code);
2762264Sjacobs }
277