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( 171 "priority must be between 0 and 39.\n")); 172 exit(1); 173 } 174 papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, 175 "job-priority", i); 176 } 177 break; 178 case 'r': /* "raw" mode */ 179 papiAttributeListAddString(&list, PAPI_ATTR_EXCL, 180 "document-format", 181 "application/octet-stream"); 182 papiAttributeListAddString(&list, PAPI_ATTR_APPEND, 183 "stty", "raw"); 184 break; 185 case 's': /* suppress message */ 186 silent = 1; 187 break; 188 case 't': /* title */ 189 papiAttributeListAddString(&list, PAPI_ATTR_EXCL, 190 "job-name", optarg); 191 break; 192 case 'V': /* validate */ 193 validate = 1; 194 break; 195 case 'w': 196 papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL, 197 "rfc-1179-mail", 1); 198 break; 199 case 'y': /* lp "modes" */ 200 papiAttributeListAddString(&list, PAPI_ATTR_APPEND, 201 "lp-modes", optarg); 202 break; 203 case 'E': 204 encryption = PAPI_ENCRYPT_REQUIRED; 205 break; 206 default: 207 usage(av[0]); 208 } 209 210 /* convert "banner", "nobanner" to "job-sheet" */ 211 if (papiAttributeListGetBoolean(list, NULL, "banner", &b) == PAPI_OK) { 212 (void) papiAttributeListDelete(&list, "banner"); 213 if (b == PAPI_FALSE) 214 papiAttributeListAddString(&list, PAPI_ATTR_EXCL, 215 "job-sheets", "none"); 216 } 217 218 if ((printer == NULL) && 219 ((printer = getenv("PRINTER")) == NULL) && 220 ((printer = getenv("LPDEST")) == NULL)) 221 printer = DEFAULT_DEST; 222 223 if (((optind + 1) == ac) && (strcmp(av[optind], "-") == 0)) 224 optind = ac; 225 226 if (modify == -1) { 227 char *document_format = "text/plain"; 228 229 if (optind != ac) { 230 /* get the mime type of the file data */ 231 #ifdef MAGIC_MIME 232 magic_t ms = NULL; 233 234 if ((ms = magic_open(MAGIC_MIME)) != NULL) { 235 document_format = magic_file(ms, av[optind]); 236 magic_close(ms); 237 } 238 #else 239 if (is_postscript(av[optind]) == 1) 240 document_format = "application/postscript"; 241 #endif 242 } else { 243 if (is_postscript_stream(0, prefetch, &prefetch_len) 244 == 1) 245 document_format = "application/postscript"; 246 } 247 248 papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, "copies", 1); 249 papiAttributeListAddString(&list, PAPI_ATTR_EXCL, 250 "document-format", document_format); 251 papiAttributeListAddString(&list, PAPI_ATTR_EXCL, 252 "job-sheets", "standard"); 253 } 254 255 status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback, 256 encryption, NULL); 257 if (status != PAPI_OK) { 258 fprintf(stderr, gettext( 259 "Failed to contact service for %s: %s\n"), printer, 260 verbose_papi_message(svc, status)); 261 exit(1); 262 } 263 264 if (dump != 0) { 265 printf("requesting attributes:\n"); 266 papiAttributeListPrint(stdout, list, "\t"); 267 printf("\n"); 268 } 269 270 if (modify != -1) 271 status = papiJobModify(svc, printer, modify, list, &job); 272 else if (optind == ac) /* no file list, use stdin */ 273 status = jobSubmitSTDIN(svc, printer, prefetch, prefetch_len, 274 list, &job); 275 else if (validate == 1) /* validate the request can be processed */ 276 status = papiJobValidate(svc, printer, list, 277 NULL, &av[optind], &job); 278 else if (copy == 0) /* reference the files in the job, default */ 279 status = papiJobSubmitByReference(svc, printer, list, 280 NULL, &av[optind], &job); 281 else /* copy the files before return, -c */ 282 status = papiJobSubmit(svc, printer, list, 283 NULL, &av[optind], &job); 284 285 papiAttributeListFree(list); 286 287 if (status != PAPI_OK) { 288 fprintf(stderr, gettext("%s: %s\n"), printer, 289 verbose_papi_message(svc, status)); 290 papiJobFree(job); 291 papiServiceDestroy(svc); 292 exit(1); 293 } 294 295 if (((silent == 0) || (dump != 0)) && 296 ((list = papiJobGetAttributeList(job)) != NULL)) { 297 int32_t id = -1; 298 299 if (printer == NULL) 300 papiAttributeListGetString(list, NULL, 301 "printer-name", &printer); 302 303 papiAttributeListGetInteger(list, NULL, 304 "job-id-requested", &id); 305 if (id == -1) { 306 papiAttributeListGetInteger(list, NULL, "job-id", &id); 307 } 308 309 printf(gettext("request id is %s-%d "), printer, id); 310 if (ac != optind) 311 printf("(%d file(s))\n", ac - optind); 312 else 313 printf("(standard input)\n"); 314 315 if (dump != 0) { 316 printf("job attributes:\n"); 317 papiAttributeListPrint(stdout, list, "\t"); 318 printf("\n"); 319 } 320 } 321 322 papiJobFree(job); 323 papiServiceDestroy(svc); 324 325 return (0); 326 } 327