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 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 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