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