4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI"
33 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
35 #include "sys/types.h"
48 #define SHELL "/bin/sh"
59 static void print_sdn (int, char *, SCALED
);
60 static void print_l (int, char *, char **);
61 static void print_str (int, char *, char *);
63 #ifdef LP_USE_PAPI_ATTR
64 static int addPrintersPPD(char *name
, PRINTER
*prbufp
);
65 static int copyPPDFile(char *ppd
, char *printersPPD
);
66 static int unzipPPDFile(char *ppd
, char *printersPPD
);
71 static void print_sdn(),
75 #ifdef LP_USE_PAPI_ATTR
76 static int addPrintersPPD();
77 static int copyPPDFile();
78 static int unzipPPDFile();
83 unsigned long ignprinter
= 0;
87 ** putprinter() - WRITE PRINTER STRUCTURE TO DISK FILES
91 putprinter(char *name
, PRINTER
*prbufp
)
95 register char * speed
;
103 struct stat statbuf1
,
109 if (!name
|| !*name
) {
114 if (STREQU(NAME_ALL
, name
)) {
120 * First go through the structure and see if we have
123 if (!okprinter(name
, prbufp
, 1)) {
128 if (!Lp_A_Printers
|| !Lp_A_Interfaces
) {
129 getadminpaths (LPUSER
);
130 if (!Lp_A_Printers
|| !Lp_A_Interfaces
)
135 * Create the parent directory for this printer
136 * if it doesn't yet exist.
138 if (!(path
= getprinterfile(name
, (char *)0)))
140 if (Stat(path
, &statbuf1
) == 0) {
141 if (!S_ISDIR(statbuf1
.st_mode
)) {
146 } else if (errno
!= ENOENT
|| mkdir_lpdir(path
, MODE_DIR
) == -1) {
153 * Create the copy of the interface program, unless
154 * that would be silly or not desired.
155 * Conversely, make sure the interface program doesn't
156 * exist for a remote printer.
158 if (prbufp
->remote
) {
159 if (!(path
= makepath(Lp_A_Interfaces
, name
, (char *)0)))
164 if (prbufp
->interface
&& (ignprinter
& BAD_INTERFACE
) == 0) {
165 if (Stat(prbufp
->interface
, &statbuf1
) == -1)
167 if (!(path
= makepath(Lp_A_Interfaces
, name
, (char *)0)))
170 Stat(path
, &statbuf2
) == -1
171 || statbuf1
.st_dev
!= statbuf2
.st_dev
172 || statbuf1
.st_ino
!= statbuf2
.st_ino
176 if ((fdin
= open_locked(prbufp
->interface
, "r", 0)) < 0) {
180 if ((fdout
= open_locked(path
, "w", MODE_EXEC
)) < 0) {
185 while ((n
= read(fdin
, buf
, BUFSIZ
)) > 0)
186 write (fdout
, buf
, n
);
193 #ifdef LP_USE_PAPI_ATTR
195 * Handle PPD (Postscript Printer Definition) file for printer
196 * if this printer has been configured with one
198 if ((prbufp
->ppd
!= NULL
) && (ppdopt
))
200 if (addPrintersPPD(name
, prbufp
) != 0)
202 /* failed to added the printers PPD file */
209 * If this printer is dialed up, remove any baud rates
210 * from the stty option list and move the last one to
211 * the ".speed" member if the ".speed" member isn't already
212 * set. Conversely, if this printer is directly connected,
213 * move any value from the ".speed" member to the stty list.
216 stty
= (prbufp
->stty
? Strdup(prbufp
->stty
) : 0);
218 speed
= Strdup(prbufp
->speed
);
222 if (prbufp
->dial_info
&& stty
) {
223 register char *newstty
,
229 if (!(q
= newstty
= Malloc(strlen(stty
) + 1))) {
234 newstty
[0] = 0; /* start with empty copy */
237 p
= strtok(stty
, " ");
239 p
= strtok((char *)0, " ")
242 if (strspn(p
, "0123456789") == len
) {
244 * If "prbufp->speed" isn't set, then
245 * use the speed we just found. Don't
246 * check "speed", because if more than
247 * one speed was given in the list, we
250 if (!prbufp
->speed
) {
258 * Not a speed, so copy it to the
271 } else if (!prbufp
->dial_info
&& speed
) {
272 register char *newstty
;
274 newstty
= Malloc(strlen(stty
) + 1 + strlen(speed
) + 1);
283 strcpy (newstty
, stty
);
284 strcat (newstty
, " ");
285 strcat (newstty
, speed
);
288 strcpy (newstty
, speed
);
297 * Open the configuration file and write out the printer
301 if (!(path
= getprinterfile(name
, CONFIGFILE
))) {
308 if ((fdout
= open_locked(path
, "w", MODE_READ
)) < 0) {
319 for (fld
= 0; fld
< PR_MAX
; fld
++) {
320 if (prbufp
->remote
&& !prtrheadings
[fld
].okremote
)
325 #define HEAD prtrheadings[fld].v
331 switch (prbufp
->banner
) {
342 (void)fdprintf(fdout
, "%s %s\n", HEAD
, ptr
);
347 print_sdn(fdout
, HEAD
, prbufp
->cpi
);
351 if (!emptylist(prbufp
->char_sets
))
352 print_l(fdout
, HEAD
, prbufp
->char_sets
);
357 * Put out the header even if the list is empty,
358 * to distinguish no input types from the default.
360 print_l(fdout
, HEAD
, prbufp
->input_types
);
364 print_str(fdout
, HEAD
, prbufp
->device
);
368 print_str(fdout
, HEAD
, prbufp
->dial_info
);
372 print_str(fdout
, HEAD
, prbufp
->fault_rec
);
376 print_str(fdout
, HEAD
, prbufp
->interface
);
380 print_sdn(fdout
, HEAD
, prbufp
->lpi
);
384 print_sdn(fdout
, HEAD
, prbufp
->plen
);
388 if (prbufp
->login
& LOG_IN
)
389 (void)fdprintf(fdout
, "%s\n", HEAD
);
394 char **printer_types
;
397 * For backward compatibility for those who
398 * use only "->printer_type", we have to play
401 if (prbufp
->printer_type
&& !prbufp
->printer_types
)
402 printer_types
= getlist(
403 prbufp
->printer_type
,
408 printer_types
= prbufp
->printer_types
;
410 if (!printer_types
|| !*printer_types
)
411 print_str(fdout
, HEAD
, NAME_UNKNOWN
);
413 print_l(fdout
, HEAD
, printer_types
);
415 if (printer_types
!= prbufp
->printer_types
)
416 freelist (printer_types
);
421 print_str(fdout
, HEAD
, prbufp
->remote
);
425 print_str(fdout
, HEAD
, speed
);
429 print_str(fdout
, HEAD
, stty
);
433 print_sdn(fdout
, HEAD
, prbufp
->pwid
);
436 #if defined(CAN_DO_MODULES)
439 * Put out the header even if the list is empty,
440 * to distinguish no modules from the default.
442 print_l(fdout
, HEAD
, prbufp
->modules
);
447 print_l(fdout
, HEAD
, prbufp
->options
);
452 print_str(fdout
, HEAD
, prbufp
->ppd
);
469 * If we have a description of the printer,
470 * write it out to a separate file.
472 if (prbufp
->description
) {
474 if (!(path
= getprinterfile(name
, COMMENTFILE
)))
477 if (dumpstring(path
, prbufp
->description
) == -1) {
486 * Now write out the alert condition.
489 prbufp
->fault_alert
.shcmd
490 && putalert(Lp_A_Printers
, name
, &(prbufp
->fault_alert
)) == -1
498 ** print_sdn() - PRINT SCALED DECIMAL NUMBER WITH HEADER
499 ** print_l() - PRINT (char **) LIST WITH HEADER
500 ** print_str() - PRINT STRING WITH HEADER
504 print_sdn(int fd
, char *head
, SCALED sdn
)
509 (void)fdprintf (fd
, "%s ", head
);
510 fdprintsdn (fd
, sdn
);
516 print_l(int fd
, char *head
, char **list
)
518 (void)fdprintf (fd
, "%s ", head
);
519 printlist_setup (0, 0, LP_SEP
, 0);
520 fdprintlist (fd
, list
);
521 printlist_unsetup ();
527 print_str(int fd
, char *head
, char *str
)
532 (void)fdprintf (fd
, "%s %s\n", head
, str
);
538 #ifdef LP_USE_PAPI_ATTR
540 * Function: addPrintersPPD()
542 * Description: Handle PPD (Postscript Printer Definition) file for this
543 * printer if it has been configured with one
548 addPrintersPPD(char *name
, PRINTER
*prbufp
)
557 (void) snprintf(buf
, sizeof (buf
), "%s.ppd", name
);
560 /* make sure the PPD file doesn't exist for a remote printer */
561 if (!(path
= makepath(ETCDIR
, "ppd", buf
, (char *)0)))
571 if ((result
== 0) && (prbufp
->ppd
!= NULL
))
573 ppd
= strdup(prbufp
->ppd
);
581 /* Check the PPD file given exists */
583 if (Stat(ppd
, &statbuf
) == -1)
586 * The given ppd files does not exist, but
587 * check if there is a zipped version of the
588 * file that we can use instead
590 if (strstr(ppd
, PPDZIP
) != NULL
)
592 /* this is a zipped file so exit */
598 strlen(ppd
)+strlen(PPDZIP
)+2);
601 ppd
= strcat(ppd
, PPDZIP
);
602 if (Stat(ppd
, &statbuf
) == -1)
605 * this zipped version
606 * of the file does not
621 * Create the copy of the PPD file for this printer
622 * unless that would be silly or not desired
627 if (!(path
= makepath(ETCDIR
, "ppd", buf
, (char *)0)))
634 * At this point we may have a zipped or unzipped ppd file, if
635 * it's unzipped just copy it otherwise unzip it to the
636 * printer's ppd file (/etc/lp/ppd/<printer>.ppd)
641 if (strstr(ppd
, PPDZIP
) == NULL
)
643 result
= copyPPDFile(ppd
, path
);
647 result
= unzipPPDFile(ppd
, path
);
650 (void) chown_lppath(path
);
651 (void) chmod(path
, 0644);
665 } /* addPrintersPPD() */
669 * Function: copyPPDFile()
671 * Description: Copy the given ppd file to the printer's file in /etc/lp/ppd
676 copyPPDFile(char *ppd
, char *printersPPD
)
685 if ((ppd
!= NULL
) && (printersPPD
!= NULL
))
687 if ((fdin
= open_locked(ppd
, "r", 0)) < 0)
693 fdout
= open_locked(printersPPD
, "w", MODE_EXEC
);
703 while ((n
= read(fdin
, buf
, BUFSIZ
)) > 0)
705 write(fdout
, buf
, n
);
717 } /* copyPPDFile() */
722 * Function: unzipPPDFile()
724 * Description: Unzip the given ppd file to the printer's file in /etc/lp/ppd.
725 * This is done by forking and running the unzip utility on the
731 unzipPPDFile(char *ppd
, char *printersPPD
)
735 char *cmdLine
= NULL
;
741 if ((ppd
!= NULL
) && (printersPPD
!= NULL
))
755 /* child process - so execute something */
757 clSize
= strlen("/usr/bin/rm -f ") +
758 strlen(printersPPD
) +
759 strlen("/usr/bin/gzip -dc ") +
761 strlen(printersPPD
) + 20;
762 cmdLine
= malloc(clSize
);
766 (void) snprintf(cmdLine
, clSize
,
767 "/usr/bin/rm -f %s; /usr/bin/gzip -dc %s > %s",
770 result
= execl(SHELL
, SHELL
, "-c",
779 /* parent process, child pid is in childPID */
781 while (wait(&stat
) != childPID
);
783 if ((stat
& 0xff00) == 0)
793 } /* unzipPPDFile() */