1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*0Sstevel@tonic-gate /* All Rights Reserved */ 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate /* 27*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28*0Sstevel@tonic-gate * Use is subject to license terms. 29*0Sstevel@tonic-gate */ 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */ 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate #include "sys/types.h" 36*0Sstevel@tonic-gate #include "sys/stat.h" 37*0Sstevel@tonic-gate #include "stdio.h" 38*0Sstevel@tonic-gate #include "string.h" 39*0Sstevel@tonic-gate #include "errno.h" 40*0Sstevel@tonic-gate #include "stdlib.h" 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate #include "lp.h" 43*0Sstevel@tonic-gate #include "printers.h" 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate #include <unistd.h> 46*0Sstevel@tonic-gate #include <sys/wait.h> 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate #define SHELL "/bin/sh" 49*0Sstevel@tonic-gate #define PPDZIP ".gz" 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate extern struct { 52*0Sstevel@tonic-gate char *v; 53*0Sstevel@tonic-gate short len, 54*0Sstevel@tonic-gate okremote; 55*0Sstevel@tonic-gate } prtrheadings[]; 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate #if defined(__STDC__) 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate static void print_sdn (int, char *, SCALED); 60*0Sstevel@tonic-gate static void print_l (int, char *, char **); 61*0Sstevel@tonic-gate static void print_str (int, char *, char *); 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 64*0Sstevel@tonic-gate static int addPrintersPPD(char *name, PRINTER *prbufp); 65*0Sstevel@tonic-gate static int copyPPDFile(char *ppd, char *printersPPD); 66*0Sstevel@tonic-gate static int unzipPPDFile(char *ppd, char *printersPPD); 67*0Sstevel@tonic-gate #endif 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate #else 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate static void print_sdn(), 72*0Sstevel@tonic-gate print_l(), 73*0Sstevel@tonic-gate print_str(); 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 76*0Sstevel@tonic-gate static int addPrintersPPD(); 77*0Sstevel@tonic-gate static int copyPPDFile(); 78*0Sstevel@tonic-gate static int unzipPPDFile(); 79*0Sstevel@tonic-gate #endif 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate #endif 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate unsigned long ignprinter = 0; 84*0Sstevel@tonic-gate int ppdopt = 0; 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate /** 87*0Sstevel@tonic-gate ** putprinter() - WRITE PRINTER STRUCTURE TO DISK FILES 88*0Sstevel@tonic-gate **/ 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate int 91*0Sstevel@tonic-gate putprinter(char *name, PRINTER *prbufp) 92*0Sstevel@tonic-gate { 93*0Sstevel@tonic-gate register char * path; 94*0Sstevel@tonic-gate register char * stty; 95*0Sstevel@tonic-gate register char * speed; 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate int fdin, fdout; 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate int fld; 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate char buf[BUFSIZ]; 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate struct stat statbuf1, 104*0Sstevel@tonic-gate statbuf2; 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate badprinter = 0; 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate if (!name || !*name) { 110*0Sstevel@tonic-gate errno = EINVAL; 111*0Sstevel@tonic-gate return (-1); 112*0Sstevel@tonic-gate } 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate if (STREQU(NAME_ALL, name)) { 115*0Sstevel@tonic-gate errno = EINVAL; 116*0Sstevel@tonic-gate return (-1); 117*0Sstevel@tonic-gate } 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate /* 120*0Sstevel@tonic-gate * First go through the structure and see if we have 121*0Sstevel@tonic-gate * anything strange. 122*0Sstevel@tonic-gate */ 123*0Sstevel@tonic-gate if (!okprinter(name, prbufp, 1)) { 124*0Sstevel@tonic-gate errno = EINVAL; 125*0Sstevel@tonic-gate return (-1); 126*0Sstevel@tonic-gate } 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate if (!Lp_A_Printers || !Lp_A_Interfaces) { 129*0Sstevel@tonic-gate getadminpaths (LPUSER); 130*0Sstevel@tonic-gate if (!Lp_A_Printers || !Lp_A_Interfaces) 131*0Sstevel@tonic-gate return (0); 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate /* 135*0Sstevel@tonic-gate * Create the parent directory for this printer 136*0Sstevel@tonic-gate * if it doesn't yet exist. 137*0Sstevel@tonic-gate */ 138*0Sstevel@tonic-gate if (!(path = getprinterfile(name, (char *)0))) 139*0Sstevel@tonic-gate return (-1); 140*0Sstevel@tonic-gate if (Stat(path, &statbuf1) == 0) { 141*0Sstevel@tonic-gate if (!(statbuf1.st_mode & S_IFDIR)) { 142*0Sstevel@tonic-gate Free (path); 143*0Sstevel@tonic-gate errno = ENOTDIR; 144*0Sstevel@tonic-gate return (-1); 145*0Sstevel@tonic-gate } 146*0Sstevel@tonic-gate } else if (errno != ENOENT || mkdir_lpdir(path, MODE_DIR) == -1) { 147*0Sstevel@tonic-gate Free (path); 148*0Sstevel@tonic-gate return (-1); 149*0Sstevel@tonic-gate } 150*0Sstevel@tonic-gate Free (path); 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gate /* 153*0Sstevel@tonic-gate * Create the copy of the interface program, unless 154*0Sstevel@tonic-gate * that would be silly or not desired. 155*0Sstevel@tonic-gate * Conversely, make sure the interface program doesn't 156*0Sstevel@tonic-gate * exist for a remote printer. 157*0Sstevel@tonic-gate */ 158*0Sstevel@tonic-gate if (prbufp->remote) { 159*0Sstevel@tonic-gate if (!(path = makepath(Lp_A_Interfaces, name, (char *)0))) 160*0Sstevel@tonic-gate return (-1); 161*0Sstevel@tonic-gate (void)rmfile (path); 162*0Sstevel@tonic-gate Free (path); 163*0Sstevel@tonic-gate } 164*0Sstevel@tonic-gate if (prbufp->interface && (ignprinter & BAD_INTERFACE) == 0) { 165*0Sstevel@tonic-gate if (Stat(prbufp->interface, &statbuf1) == -1) 166*0Sstevel@tonic-gate return (-1); 167*0Sstevel@tonic-gate if (!(path = makepath(Lp_A_Interfaces, name, (char *)0))) 168*0Sstevel@tonic-gate return (-1); 169*0Sstevel@tonic-gate if ( 170*0Sstevel@tonic-gate Stat(path, &statbuf2) == -1 171*0Sstevel@tonic-gate || statbuf1.st_dev != statbuf2.st_dev 172*0Sstevel@tonic-gate || statbuf1.st_ino != statbuf2.st_ino 173*0Sstevel@tonic-gate ) { 174*0Sstevel@tonic-gate register int n; 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate if ((fdin = open_locked(prbufp->interface, "r", 0)) < 0) { 177*0Sstevel@tonic-gate Free (path); 178*0Sstevel@tonic-gate return (-1); 179*0Sstevel@tonic-gate } 180*0Sstevel@tonic-gate if ((fdout = open_locked(path, "w", MODE_EXEC)) < 0) { 181*0Sstevel@tonic-gate Free (path); 182*0Sstevel@tonic-gate close(fdin); 183*0Sstevel@tonic-gate return (-1); 184*0Sstevel@tonic-gate } 185*0Sstevel@tonic-gate while ((n = read(fdin, buf, BUFSIZ)) > 0) 186*0Sstevel@tonic-gate write (fdout, buf, n); 187*0Sstevel@tonic-gate close(fdout); 188*0Sstevel@tonic-gate close(fdin); 189*0Sstevel@tonic-gate } 190*0Sstevel@tonic-gate Free (path); 191*0Sstevel@tonic-gate } 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 194*0Sstevel@tonic-gate /* 195*0Sstevel@tonic-gate * Handle PPD (Postscript Printer Definition) file for printer 196*0Sstevel@tonic-gate * if this printer has been configured with one 197*0Sstevel@tonic-gate */ 198*0Sstevel@tonic-gate if ((prbufp->ppd != NULL) && (ppdopt)) 199*0Sstevel@tonic-gate { 200*0Sstevel@tonic-gate if (addPrintersPPD(name, prbufp) != 0) 201*0Sstevel@tonic-gate { 202*0Sstevel@tonic-gate /* failed to added the printers PPD file */ 203*0Sstevel@tonic-gate return (-1); 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate #endif 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate /* 209*0Sstevel@tonic-gate * If this printer is dialed up, remove any baud rates 210*0Sstevel@tonic-gate * from the stty option list and move the last one to 211*0Sstevel@tonic-gate * the ".speed" member if the ".speed" member isn't already 212*0Sstevel@tonic-gate * set. Conversely, if this printer is directly connected, 213*0Sstevel@tonic-gate * move any value from the ".speed" member to the stty list. 214*0Sstevel@tonic-gate */ 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate stty = (prbufp->stty? Strdup(prbufp->stty) : 0); 217*0Sstevel@tonic-gate if (prbufp->speed) 218*0Sstevel@tonic-gate speed = Strdup(prbufp->speed); 219*0Sstevel@tonic-gate else 220*0Sstevel@tonic-gate speed = 0; 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate if (prbufp->dial_info && stty) { 223*0Sstevel@tonic-gate register char *newstty, 224*0Sstevel@tonic-gate *p, 225*0Sstevel@tonic-gate *q; 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate register int len; 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate if (!(q = newstty = Malloc(strlen(stty) + 1))) { 230*0Sstevel@tonic-gate Free (stty); 231*0Sstevel@tonic-gate errno = ENOMEM; 232*0Sstevel@tonic-gate return (-1); 233*0Sstevel@tonic-gate } 234*0Sstevel@tonic-gate newstty[0] = 0; /* start with empty copy */ 235*0Sstevel@tonic-gate 236*0Sstevel@tonic-gate for ( 237*0Sstevel@tonic-gate p = strtok(stty, " "); 238*0Sstevel@tonic-gate p; 239*0Sstevel@tonic-gate p = strtok((char *)0, " ") 240*0Sstevel@tonic-gate ) { 241*0Sstevel@tonic-gate len = strlen(p); 242*0Sstevel@tonic-gate if (strspn(p, "0123456789") == len) { 243*0Sstevel@tonic-gate /* 244*0Sstevel@tonic-gate * If "prbufp->speed" isn't set, then 245*0Sstevel@tonic-gate * use the speed we just found. Don't 246*0Sstevel@tonic-gate * check "speed", because if more than 247*0Sstevel@tonic-gate * one speed was given in the list, we 248*0Sstevel@tonic-gate * want the last one. 249*0Sstevel@tonic-gate */ 250*0Sstevel@tonic-gate if (!prbufp->speed) { 251*0Sstevel@tonic-gate if (speed) 252*0Sstevel@tonic-gate Free (speed); 253*0Sstevel@tonic-gate speed = Strdup(p); 254*0Sstevel@tonic-gate } 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate } else { 257*0Sstevel@tonic-gate /* 258*0Sstevel@tonic-gate * Not a speed, so copy it to the 259*0Sstevel@tonic-gate * new stty string. 260*0Sstevel@tonic-gate */ 261*0Sstevel@tonic-gate if (q != newstty) 262*0Sstevel@tonic-gate *q++ = ' '; 263*0Sstevel@tonic-gate strcpy (q, p); 264*0Sstevel@tonic-gate q += len; 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate Free (stty); 269*0Sstevel@tonic-gate stty = newstty; 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate } else if (!prbufp->dial_info && speed) { 272*0Sstevel@tonic-gate register char *newstty; 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate newstty = Malloc(strlen(stty) + 1 + strlen(speed) + 1); 275*0Sstevel@tonic-gate if (!newstty) { 276*0Sstevel@tonic-gate if (stty) 277*0Sstevel@tonic-gate Free (stty); 278*0Sstevel@tonic-gate errno = ENOMEM; 279*0Sstevel@tonic-gate return (-1); 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate if (stty) { 283*0Sstevel@tonic-gate strcpy (newstty, stty); 284*0Sstevel@tonic-gate strcat (newstty, " "); 285*0Sstevel@tonic-gate strcat (newstty, speed); 286*0Sstevel@tonic-gate Free (stty); 287*0Sstevel@tonic-gate } else 288*0Sstevel@tonic-gate strcpy (newstty, speed); 289*0Sstevel@tonic-gate Free (speed); 290*0Sstevel@tonic-gate speed = 0; 291*0Sstevel@tonic-gate 292*0Sstevel@tonic-gate stty = newstty; 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate } 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate /* 297*0Sstevel@tonic-gate * Open the configuration file and write out the printer 298*0Sstevel@tonic-gate * configuration. 299*0Sstevel@tonic-gate */ 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate if (!(path = getprinterfile(name, CONFIGFILE))) { 302*0Sstevel@tonic-gate if (stty) 303*0Sstevel@tonic-gate Free (stty); 304*0Sstevel@tonic-gate if (speed) 305*0Sstevel@tonic-gate Free (speed); 306*0Sstevel@tonic-gate return (-1); 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate if ((fdout = open_locked(path, "w", MODE_READ)) < 0) { 309*0Sstevel@tonic-gate Free (path); 310*0Sstevel@tonic-gate if (stty) 311*0Sstevel@tonic-gate Free (stty); 312*0Sstevel@tonic-gate if (speed) 313*0Sstevel@tonic-gate Free (speed); 314*0Sstevel@tonic-gate return (-1); 315*0Sstevel@tonic-gate } 316*0Sstevel@tonic-gate Free (path); 317*0Sstevel@tonic-gate 318*0Sstevel@tonic-gate errno = 0; 319*0Sstevel@tonic-gate for (fld = 0; fld < PR_MAX; fld++) { 320*0Sstevel@tonic-gate if (prbufp->remote && !prtrheadings[fld].okremote) 321*0Sstevel@tonic-gate continue; 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate switch (fld) { 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gate #define HEAD prtrheadings[fld].v 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gate case PR_BAN: 328*0Sstevel@tonic-gate { 329*0Sstevel@tonic-gate char *ptr = NAME_ON; 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate switch (prbufp->banner) { 332*0Sstevel@tonic-gate case BAN_ALWAYS: 333*0Sstevel@tonic-gate ptr = NAME_ON; 334*0Sstevel@tonic-gate break; 335*0Sstevel@tonic-gate case BAN_NEVER: 336*0Sstevel@tonic-gate ptr = NAME_OFF; 337*0Sstevel@tonic-gate break; 338*0Sstevel@tonic-gate case BAN_OPTIONAL: 339*0Sstevel@tonic-gate ptr = NAME_OPTIONAL; 340*0Sstevel@tonic-gate break; 341*0Sstevel@tonic-gate } 342*0Sstevel@tonic-gate (void)fdprintf(fdout, "%s %s\n", HEAD, ptr); 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate break; 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate case PR_CPI: 347*0Sstevel@tonic-gate print_sdn(fdout, HEAD, prbufp->cpi); 348*0Sstevel@tonic-gate break; 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate case PR_CS: 351*0Sstevel@tonic-gate if (!emptylist(prbufp->char_sets)) 352*0Sstevel@tonic-gate print_l(fdout, HEAD, prbufp->char_sets); 353*0Sstevel@tonic-gate break; 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate case PR_ITYPES: 356*0Sstevel@tonic-gate /* 357*0Sstevel@tonic-gate * Put out the header even if the list is empty, 358*0Sstevel@tonic-gate * to distinguish no input types from the default. 359*0Sstevel@tonic-gate */ 360*0Sstevel@tonic-gate print_l(fdout, HEAD, prbufp->input_types); 361*0Sstevel@tonic-gate break; 362*0Sstevel@tonic-gate 363*0Sstevel@tonic-gate case PR_DEV: 364*0Sstevel@tonic-gate print_str(fdout, HEAD, prbufp->device); 365*0Sstevel@tonic-gate break; 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate case PR_DIAL: 368*0Sstevel@tonic-gate print_str(fdout, HEAD, prbufp->dial_info); 369*0Sstevel@tonic-gate break; 370*0Sstevel@tonic-gate 371*0Sstevel@tonic-gate case PR_RECOV: 372*0Sstevel@tonic-gate print_str(fdout, HEAD, prbufp->fault_rec); 373*0Sstevel@tonic-gate break; 374*0Sstevel@tonic-gate 375*0Sstevel@tonic-gate case PR_INTFC: 376*0Sstevel@tonic-gate print_str(fdout, HEAD, prbufp->interface); 377*0Sstevel@tonic-gate break; 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate case PR_LPI: 380*0Sstevel@tonic-gate print_sdn(fdout, HEAD, prbufp->lpi); 381*0Sstevel@tonic-gate break; 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate case PR_LEN: 384*0Sstevel@tonic-gate print_sdn(fdout, HEAD, prbufp->plen); 385*0Sstevel@tonic-gate break; 386*0Sstevel@tonic-gate 387*0Sstevel@tonic-gate case PR_LOGIN: 388*0Sstevel@tonic-gate if (prbufp->login & LOG_IN) 389*0Sstevel@tonic-gate (void)fdprintf(fdout, "%s\n", HEAD); 390*0Sstevel@tonic-gate break; 391*0Sstevel@tonic-gate 392*0Sstevel@tonic-gate case PR_PTYPE: 393*0Sstevel@tonic-gate { 394*0Sstevel@tonic-gate char **printer_types; 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate /* 397*0Sstevel@tonic-gate * For backward compatibility for those who 398*0Sstevel@tonic-gate * use only "->printer_type", we have to play 399*0Sstevel@tonic-gate * some games here. 400*0Sstevel@tonic-gate */ 401*0Sstevel@tonic-gate if (prbufp->printer_type && !prbufp->printer_types) 402*0Sstevel@tonic-gate printer_types = getlist( 403*0Sstevel@tonic-gate prbufp->printer_type, 404*0Sstevel@tonic-gate LP_WS, 405*0Sstevel@tonic-gate LP_SEP 406*0Sstevel@tonic-gate ); 407*0Sstevel@tonic-gate else 408*0Sstevel@tonic-gate printer_types = prbufp->printer_types; 409*0Sstevel@tonic-gate 410*0Sstevel@tonic-gate if (!printer_types || !*printer_types) 411*0Sstevel@tonic-gate print_str(fdout, HEAD, NAME_UNKNOWN); 412*0Sstevel@tonic-gate else 413*0Sstevel@tonic-gate print_l(fdout, HEAD, printer_types); 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate if (printer_types != prbufp->printer_types) 416*0Sstevel@tonic-gate freelist (printer_types); 417*0Sstevel@tonic-gate break; 418*0Sstevel@tonic-gate } 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gate case PR_REMOTE: 421*0Sstevel@tonic-gate print_str(fdout, HEAD, prbufp->remote); 422*0Sstevel@tonic-gate break; 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gate case PR_SPEED: 425*0Sstevel@tonic-gate print_str(fdout, HEAD, speed); 426*0Sstevel@tonic-gate break; 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate case PR_STTY: 429*0Sstevel@tonic-gate print_str(fdout, HEAD, stty); 430*0Sstevel@tonic-gate break; 431*0Sstevel@tonic-gate 432*0Sstevel@tonic-gate case PR_WIDTH: 433*0Sstevel@tonic-gate print_sdn(fdout, HEAD, prbufp->pwid); 434*0Sstevel@tonic-gate break; 435*0Sstevel@tonic-gate 436*0Sstevel@tonic-gate #if defined(CAN_DO_MODULES) 437*0Sstevel@tonic-gate case PR_MODULES: 438*0Sstevel@tonic-gate /* 439*0Sstevel@tonic-gate * Put out the header even if the list is empty, 440*0Sstevel@tonic-gate * to distinguish no modules from the default. 441*0Sstevel@tonic-gate */ 442*0Sstevel@tonic-gate print_l(fdout, HEAD, prbufp->modules); 443*0Sstevel@tonic-gate break; 444*0Sstevel@tonic-gate #endif 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate case PR_OPTIONS: 447*0Sstevel@tonic-gate print_l(fdout, HEAD, prbufp->options); 448*0Sstevel@tonic-gate break; 449*0Sstevel@tonic-gate 450*0Sstevel@tonic-gate case PR_PPD: 451*0Sstevel@tonic-gate { 452*0Sstevel@tonic-gate print_str(fdout, HEAD, prbufp->ppd); 453*0Sstevel@tonic-gate break; 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate } 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate } 458*0Sstevel@tonic-gate if (stty) 459*0Sstevel@tonic-gate Free (stty); 460*0Sstevel@tonic-gate if (speed) 461*0Sstevel@tonic-gate Free (speed); 462*0Sstevel@tonic-gate if (errno != 0) { 463*0Sstevel@tonic-gate close(fdout); 464*0Sstevel@tonic-gate return (-1); 465*0Sstevel@tonic-gate } 466*0Sstevel@tonic-gate close(fdout); 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate /* 469*0Sstevel@tonic-gate * If we have a description of the printer, 470*0Sstevel@tonic-gate * write it out to a separate file. 471*0Sstevel@tonic-gate */ 472*0Sstevel@tonic-gate if (prbufp->description) { 473*0Sstevel@tonic-gate 474*0Sstevel@tonic-gate if (!(path = getprinterfile(name, COMMENTFILE))) 475*0Sstevel@tonic-gate return (-1); 476*0Sstevel@tonic-gate 477*0Sstevel@tonic-gate if (dumpstring(path, prbufp->description) == -1) { 478*0Sstevel@tonic-gate Free (path); 479*0Sstevel@tonic-gate return (-1); 480*0Sstevel@tonic-gate } 481*0Sstevel@tonic-gate Free (path); 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate } 484*0Sstevel@tonic-gate 485*0Sstevel@tonic-gate /* 486*0Sstevel@tonic-gate * Now write out the alert condition. 487*0Sstevel@tonic-gate */ 488*0Sstevel@tonic-gate if ( 489*0Sstevel@tonic-gate prbufp->fault_alert.shcmd 490*0Sstevel@tonic-gate && putalert(Lp_A_Printers, name, &(prbufp->fault_alert)) == -1 491*0Sstevel@tonic-gate ) 492*0Sstevel@tonic-gate return (-1); 493*0Sstevel@tonic-gate 494*0Sstevel@tonic-gate return (0); 495*0Sstevel@tonic-gate } 496*0Sstevel@tonic-gate 497*0Sstevel@tonic-gate /** 498*0Sstevel@tonic-gate ** print_sdn() - PRINT SCALED DECIMAL NUMBER WITH HEADER 499*0Sstevel@tonic-gate ** print_l() - PRINT (char **) LIST WITH HEADER 500*0Sstevel@tonic-gate ** print_str() - PRINT STRING WITH HEADER 501*0Sstevel@tonic-gate **/ 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate static void 504*0Sstevel@tonic-gate print_sdn(int fd, char *head, SCALED sdn) 505*0Sstevel@tonic-gate { 506*0Sstevel@tonic-gate if (sdn.val <= 0) 507*0Sstevel@tonic-gate return; 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gate (void)fdprintf (fd, "%s ", head); 510*0Sstevel@tonic-gate fdprintsdn (fd, sdn); 511*0Sstevel@tonic-gate 512*0Sstevel@tonic-gate return; 513*0Sstevel@tonic-gate } 514*0Sstevel@tonic-gate 515*0Sstevel@tonic-gate static void 516*0Sstevel@tonic-gate print_l(int fd, char *head, char **list) 517*0Sstevel@tonic-gate { 518*0Sstevel@tonic-gate (void)fdprintf (fd, "%s ", head); 519*0Sstevel@tonic-gate printlist_setup (0, 0, LP_SEP, 0); 520*0Sstevel@tonic-gate fdprintlist (fd, list); 521*0Sstevel@tonic-gate printlist_unsetup (); 522*0Sstevel@tonic-gate 523*0Sstevel@tonic-gate return; 524*0Sstevel@tonic-gate } 525*0Sstevel@tonic-gate 526*0Sstevel@tonic-gate static void 527*0Sstevel@tonic-gate print_str(int fd, char *head, char *str) 528*0Sstevel@tonic-gate { 529*0Sstevel@tonic-gate if (!str || !*str) 530*0Sstevel@tonic-gate return; 531*0Sstevel@tonic-gate 532*0Sstevel@tonic-gate (void)fdprintf (fd, "%s %s\n", head, str); 533*0Sstevel@tonic-gate 534*0Sstevel@tonic-gate return; 535*0Sstevel@tonic-gate } 536*0Sstevel@tonic-gate 537*0Sstevel@tonic-gate 538*0Sstevel@tonic-gate #ifdef LP_USE_PAPI_ATTR 539*0Sstevel@tonic-gate /* 540*0Sstevel@tonic-gate * Function: addPrintersPPD() 541*0Sstevel@tonic-gate * 542*0Sstevel@tonic-gate * Description: Handle PPD (Postscript Printer Definition) file for this 543*0Sstevel@tonic-gate * printer if it has been configured with one 544*0Sstevel@tonic-gate * 545*0Sstevel@tonic-gate */ 546*0Sstevel@tonic-gate 547*0Sstevel@tonic-gate static int 548*0Sstevel@tonic-gate addPrintersPPD(char *name, PRINTER *prbufp) 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate { 551*0Sstevel@tonic-gate int result = 0; 552*0Sstevel@tonic-gate char *path = NULL; 553*0Sstevel@tonic-gate char *ppd = NULL; 554*0Sstevel@tonic-gate char buf[BUFSIZ]; 555*0Sstevel@tonic-gate struct stat statbuf; 556*0Sstevel@tonic-gate 557*0Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "%s.ppd", name); 558*0Sstevel@tonic-gate if (prbufp->remote) 559*0Sstevel@tonic-gate { 560*0Sstevel@tonic-gate /* make sure the PPD file doesn't exist for a remote printer */ 561*0Sstevel@tonic-gate if (!(path = makepath(ETCDIR, "ppd", buf, (char *)0))) 562*0Sstevel@tonic-gate { 563*0Sstevel@tonic-gate result = -1; 564*0Sstevel@tonic-gate } 565*0Sstevel@tonic-gate else 566*0Sstevel@tonic-gate { 567*0Sstevel@tonic-gate (void) rmfile(path); 568*0Sstevel@tonic-gate } 569*0Sstevel@tonic-gate } 570*0Sstevel@tonic-gate 571*0Sstevel@tonic-gate if ((result == 0) && (prbufp->ppd != NULL)) 572*0Sstevel@tonic-gate { 573*0Sstevel@tonic-gate ppd = strdup(prbufp->ppd); 574*0Sstevel@tonic-gate 575*0Sstevel@tonic-gate if (ppd == NULL) 576*0Sstevel@tonic-gate { 577*0Sstevel@tonic-gate result = -1; 578*0Sstevel@tonic-gate } 579*0Sstevel@tonic-gate else 580*0Sstevel@tonic-gate { 581*0Sstevel@tonic-gate /* Check the PPD file given exists */ 582*0Sstevel@tonic-gate 583*0Sstevel@tonic-gate if (Stat(ppd, &statbuf) == -1) 584*0Sstevel@tonic-gate { 585*0Sstevel@tonic-gate /* 586*0Sstevel@tonic-gate * The given ppd files does not exist, but 587*0Sstevel@tonic-gate * check if there is a zipped version of the 588*0Sstevel@tonic-gate * file that we can use instead 589*0Sstevel@tonic-gate */ 590*0Sstevel@tonic-gate if (strstr(ppd, PPDZIP) != NULL) 591*0Sstevel@tonic-gate { 592*0Sstevel@tonic-gate /* this is a zipped file so exit */ 593*0Sstevel@tonic-gate result = -1; 594*0Sstevel@tonic-gate } 595*0Sstevel@tonic-gate else 596*0Sstevel@tonic-gate { 597*0Sstevel@tonic-gate ppd = Realloc(ppd, 598*0Sstevel@tonic-gate strlen(ppd)+strlen(PPDZIP)+2); 599*0Sstevel@tonic-gate if (ppd != NULL) 600*0Sstevel@tonic-gate { 601*0Sstevel@tonic-gate ppd = strcat(ppd, PPDZIP); 602*0Sstevel@tonic-gate if (Stat(ppd, &statbuf) == -1) 603*0Sstevel@tonic-gate { 604*0Sstevel@tonic-gate /* 605*0Sstevel@tonic-gate * this zipped version 606*0Sstevel@tonic-gate * of the file does not 607*0Sstevel@tonic-gate * exist either 608*0Sstevel@tonic-gate */ 609*0Sstevel@tonic-gate result = -1; 610*0Sstevel@tonic-gate } 611*0Sstevel@tonic-gate } 612*0Sstevel@tonic-gate else 613*0Sstevel@tonic-gate { 614*0Sstevel@tonic-gate result = -1; 615*0Sstevel@tonic-gate } 616*0Sstevel@tonic-gate } 617*0Sstevel@tonic-gate } 618*0Sstevel@tonic-gate } 619*0Sstevel@tonic-gate 620*0Sstevel@tonic-gate /* 621*0Sstevel@tonic-gate * Create the copy of the PPD file for this printer 622*0Sstevel@tonic-gate * unless that would be silly or not desired 623*0Sstevel@tonic-gate */ 624*0Sstevel@tonic-gate 625*0Sstevel@tonic-gate if (result == 0) 626*0Sstevel@tonic-gate { 627*0Sstevel@tonic-gate if (!(path = makepath(ETCDIR, "ppd", buf, (char *)0))) 628*0Sstevel@tonic-gate { 629*0Sstevel@tonic-gate result = -1; 630*0Sstevel@tonic-gate } 631*0Sstevel@tonic-gate } 632*0Sstevel@tonic-gate 633*0Sstevel@tonic-gate /* 634*0Sstevel@tonic-gate * At this point we may have a zipped or unzipped ppd file, if 635*0Sstevel@tonic-gate * it's unzipped just copy it otherwise unzip it to the 636*0Sstevel@tonic-gate * printer's ppd file (/etc/lp/ppd/<printer>.ppd) 637*0Sstevel@tonic-gate */ 638*0Sstevel@tonic-gate 639*0Sstevel@tonic-gate if (result == 0) 640*0Sstevel@tonic-gate { 641*0Sstevel@tonic-gate if (strstr(ppd, PPDZIP) == NULL) 642*0Sstevel@tonic-gate { 643*0Sstevel@tonic-gate result = copyPPDFile(ppd, path); 644*0Sstevel@tonic-gate } 645*0Sstevel@tonic-gate else 646*0Sstevel@tonic-gate { 647*0Sstevel@tonic-gate result = unzipPPDFile(ppd, path); 648*0Sstevel@tonic-gate } 649*0Sstevel@tonic-gate 650*0Sstevel@tonic-gate (void) chown_lppath(path); 651*0Sstevel@tonic-gate (void) chmod(path, 0644); 652*0Sstevel@tonic-gate } 653*0Sstevel@tonic-gate 654*0Sstevel@tonic-gate if (ppd != NULL) 655*0Sstevel@tonic-gate { 656*0Sstevel@tonic-gate Free(ppd); 657*0Sstevel@tonic-gate } 658*0Sstevel@tonic-gate if (path != NULL) 659*0Sstevel@tonic-gate { 660*0Sstevel@tonic-gate Free(path); 661*0Sstevel@tonic-gate } 662*0Sstevel@tonic-gate } 663*0Sstevel@tonic-gate 664*0Sstevel@tonic-gate return (result); 665*0Sstevel@tonic-gate } /* addPrintersPPD() */ 666*0Sstevel@tonic-gate 667*0Sstevel@tonic-gate 668*0Sstevel@tonic-gate /* 669*0Sstevel@tonic-gate * Function: copyPPDFile() 670*0Sstevel@tonic-gate * 671*0Sstevel@tonic-gate * Description: Copy the given ppd file to the printer's file in /etc/lp/ppd 672*0Sstevel@tonic-gate * 673*0Sstevel@tonic-gate */ 674*0Sstevel@tonic-gate 675*0Sstevel@tonic-gate static int 676*0Sstevel@tonic-gate copyPPDFile(char *ppd, char *printersPPD) 677*0Sstevel@tonic-gate 678*0Sstevel@tonic-gate { 679*0Sstevel@tonic-gate int result = 0; 680*0Sstevel@tonic-gate register int n = 0; 681*0Sstevel@tonic-gate int fdin = 0; 682*0Sstevel@tonic-gate int fdout = 0; 683*0Sstevel@tonic-gate char buf[BUFSIZ]; 684*0Sstevel@tonic-gate 685*0Sstevel@tonic-gate if ((ppd != NULL) && (printersPPD != NULL)) 686*0Sstevel@tonic-gate { 687*0Sstevel@tonic-gate if ((fdin = open_locked(ppd, "r", 0)) < 0) 688*0Sstevel@tonic-gate { 689*0Sstevel@tonic-gate result = -1; 690*0Sstevel@tonic-gate } 691*0Sstevel@tonic-gate else 692*0Sstevel@tonic-gate { 693*0Sstevel@tonic-gate fdout = open_locked(printersPPD, "w", MODE_EXEC); 694*0Sstevel@tonic-gate if (fdout < 0) 695*0Sstevel@tonic-gate { 696*0Sstevel@tonic-gate close(fdin); 697*0Sstevel@tonic-gate result = -1; 698*0Sstevel@tonic-gate } 699*0Sstevel@tonic-gate } 700*0Sstevel@tonic-gate 701*0Sstevel@tonic-gate if (result == 0) 702*0Sstevel@tonic-gate { 703*0Sstevel@tonic-gate while ((n = read(fdin, buf, BUFSIZ)) > 0) 704*0Sstevel@tonic-gate { 705*0Sstevel@tonic-gate write(fdout, buf, n); 706*0Sstevel@tonic-gate } 707*0Sstevel@tonic-gate close(fdout); 708*0Sstevel@tonic-gate close(fdin); 709*0Sstevel@tonic-gate } 710*0Sstevel@tonic-gate } 711*0Sstevel@tonic-gate else 712*0Sstevel@tonic-gate { 713*0Sstevel@tonic-gate result = -1; 714*0Sstevel@tonic-gate } 715*0Sstevel@tonic-gate 716*0Sstevel@tonic-gate return (result); 717*0Sstevel@tonic-gate } /* copyPPDFile() */ 718*0Sstevel@tonic-gate 719*0Sstevel@tonic-gate 720*0Sstevel@tonic-gate 721*0Sstevel@tonic-gate /* 722*0Sstevel@tonic-gate * Function: unzipPPDFile() 723*0Sstevel@tonic-gate * 724*0Sstevel@tonic-gate * Description: Unzip the given ppd file to the printer's file in /etc/lp/ppd. 725*0Sstevel@tonic-gate * This is done by forking and running the unzip utility on the 726*0Sstevel@tonic-gate * zipped ppd file. 727*0Sstevel@tonic-gate * 728*0Sstevel@tonic-gate */ 729*0Sstevel@tonic-gate 730*0Sstevel@tonic-gate static int 731*0Sstevel@tonic-gate unzipPPDFile(char *ppd, char *printersPPD) 732*0Sstevel@tonic-gate 733*0Sstevel@tonic-gate { 734*0Sstevel@tonic-gate int result = -1; 735*0Sstevel@tonic-gate char *cmdLine = NULL; 736*0Sstevel@tonic-gate pid_t childPID = 0; 737*0Sstevel@tonic-gate int stat = 0; 738*0Sstevel@tonic-gate int clSize = 0; 739*0Sstevel@tonic-gate 740*0Sstevel@tonic-gate 741*0Sstevel@tonic-gate if ((ppd != NULL) && (printersPPD != NULL)) 742*0Sstevel@tonic-gate { 743*0Sstevel@tonic-gate childPID = fork(); 744*0Sstevel@tonic-gate 745*0Sstevel@tonic-gate switch (childPID) 746*0Sstevel@tonic-gate { 747*0Sstevel@tonic-gate case -1: 748*0Sstevel@tonic-gate { 749*0Sstevel@tonic-gate /* return error */ 750*0Sstevel@tonic-gate break; 751*0Sstevel@tonic-gate } 752*0Sstevel@tonic-gate 753*0Sstevel@tonic-gate case 0: 754*0Sstevel@tonic-gate { 755*0Sstevel@tonic-gate /* child process - so execute something */ 756*0Sstevel@tonic-gate 757*0Sstevel@tonic-gate clSize = strlen("/usr/bin/rm -f ") + 758*0Sstevel@tonic-gate strlen(printersPPD) + 759*0Sstevel@tonic-gate strlen("/usr/bin/gzip -dc ") + 760*0Sstevel@tonic-gate strlen(ppd) + 761*0Sstevel@tonic-gate strlen(printersPPD) + 20; 762*0Sstevel@tonic-gate cmdLine = malloc(clSize); 763*0Sstevel@tonic-gate if (cmdLine != NULL) 764*0Sstevel@tonic-gate { 765*0Sstevel@tonic-gate 766*0Sstevel@tonic-gate (void) snprintf(cmdLine, clSize, 767*0Sstevel@tonic-gate "/usr/bin/rm -f %s; /usr/bin/gzip -dc %s > %s", 768*0Sstevel@tonic-gate printersPPD, ppd, 769*0Sstevel@tonic-gate printersPPD); 770*0Sstevel@tonic-gate result = execl(SHELL, SHELL, "-c", 771*0Sstevel@tonic-gate cmdLine, NULL); 772*0Sstevel@tonic-gate exit(result); 773*0Sstevel@tonic-gate } 774*0Sstevel@tonic-gate break; 775*0Sstevel@tonic-gate } 776*0Sstevel@tonic-gate 777*0Sstevel@tonic-gate default: 778*0Sstevel@tonic-gate { 779*0Sstevel@tonic-gate /* parent process, child pid is in childPID */ 780*0Sstevel@tonic-gate 781*0Sstevel@tonic-gate while (wait(&stat) != childPID); 782*0Sstevel@tonic-gate 783*0Sstevel@tonic-gate if ((stat & 0xff00) == 0) 784*0Sstevel@tonic-gate { 785*0Sstevel@tonic-gate result = 0; 786*0Sstevel@tonic-gate } 787*0Sstevel@tonic-gate break; 788*0Sstevel@tonic-gate } 789*0Sstevel@tonic-gate } 790*0Sstevel@tonic-gate } 791*0Sstevel@tonic-gate 792*0Sstevel@tonic-gate return (result); 793*0Sstevel@tonic-gate } /* unzipPPDFile() */ 794*0Sstevel@tonic-gate #endif 795