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