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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */ 31 32 #include "stdio.h" 33 #include "string.h" 34 #include "errno.h" 35 #include "sys/types.h" 36 #include "stdlib.h" 37 38 #include "lp.h" 39 #include "printers.h" 40 41 extern struct { 42 char *v; 43 short len, 44 okremote; 45 } prtrheadings[]; 46 47 /* 48 * getpentry() - EXTRACT ONE PRINTER ENTRY FROM DISK FILE 49 */ 50 51 char * 52 getpentry(char *name, int want_fld) 53 { 54 static long lastdir = -1; 55 char buf[BUFSIZ]; 56 int fld; 57 int fd; 58 register char * p; 59 register char * path; 60 int isNameAll; 61 char * option_entry = NULL; 62 63 64 65 if (!name || !*name) { 66 errno = EINVAL; 67 return (0); 68 } 69 70 /* 71 * Getting ``all''? If so, jump into the directory 72 * wherever we left off. 73 */ 74 isNameAll = STREQU(NAME_ALL, name); 75 for (; ; ) { 76 /* 77 * fix for bug 1117241 78 * occasionally when a printer is removed, a printer directory 79 * is left behind, but the CONFIGFILE is removed. In this 80 * case this directory terminates the search for additional 81 * printers as we have been returning 0 in this case. 82 * Now, we loop back and try the next directory until 83 * we have no more directories or we find a directory with 84 * a CONFIGFILE 85 */ 86 if (isNameAll) { 87 if (!(name = next_dir(Lp_A_Printers, &lastdir))) 88 return (0); 89 } else 90 lastdir = -1; 91 92 /* 93 * Get the printer configuration information. 94 */ 95 96 path = getprinterfile(name, CONFIGFILE); 97 if (!path) { 98 if (isNameAll) 99 Free(name); 100 return (0); 101 } 102 103 if ((fd = open_locked(path, "r", 0)) < 0) { 104 Free(path); 105 106 /* 107 * go around to loop again for 108 * NAME_ALL case 109 */ 110 111 if (!isNameAll) /* fix for bug 1117241 */ 112 return (0); 113 else 114 Free(name); 115 } 116 else 117 break; 118 } 119 Free(path); 120 121 /* 122 * Read the file. 123 */ 124 errno = 0; 125 while (fdgets(buf, BUFSIZ, fd) != NULL) { 126 127 buf[strlen(buf) - 1] = 0; 128 129 for (fld = 0; fld < PR_MAX; fld++) 130 if (prtrheadings[fld].v && 131 prtrheadings[fld].len && 132 STRNEQU( 133 buf, 134 prtrheadings[fld].v, 135 prtrheadings[fld].len)) { 136 137 p = buf + prtrheadings[fld].len; 138 while (*p && *p == ' ') 139 p++; 140 break; 141 } 142 143 /* 144 * To allow future extensions to not impact applications 145 * using old versions of this routine, ignore strange 146 * fields. 147 */ 148 if (fld >= PR_MAX) 149 continue; 150 151 if (fld == want_fld) { 152 if ((option_entry = strdup(p)) == NULL) { 153 return (0); 154 } 155 } 156 157 158 } 159 if (errno != 0) { 160 int save_errno = errno; 161 close(fd); 162 errno = save_errno; 163 return (0); 164 } 165 close(fd); 166 167 return (option_entry); 168 } 169