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 2005 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 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */ 33 34 #include "stdio.h" 35 #include "fcntl.h" 36 #include "string.h" 37 #include "errno.h" 38 #include "pwd.h" 39 #include "sys/types.h" 40 #include "sys/stat.h" 41 #include "stdlib.h" 42 #include <stdarg.h> 43 #include <unistd.h> 44 #include "pwd.h" 45 46 #include "lp.h" 47 48 int 49 is_printer_uri(char *value) 50 { 51 if (value == NULL) 52 return (-1); 53 54 if ((value[0] == '/') && (access(value, F_OK) == 0)) 55 return (-1); /* a valid path */ 56 57 if (strstr(value, "://") == NULL) 58 return (-1); /* not in uri form */ 59 60 return (0); 61 } 62 63 fdprintf(int fd, char *fmt, ...) 64 { 65 char buf[BUFSIZ]; 66 va_list ap; 67 68 if (fd == 1) 69 fflush(stdout); 70 va_start(ap, fmt); 71 vsnprintf(buf, sizeof (buf), fmt, ap); 72 va_end(ap); 73 return (Write(fd, buf, (int)strlen(buf))); 74 } 75 76 char * 77 fdgets(char *buf, int len, int fd) 78 { 79 char tmp; 80 int count = 0; 81 82 memset(buf, NULL, len); 83 while ((count < len) && (Read(fd, &tmp, 1) > 0)) 84 if ((buf[count++] = tmp) == '\n') break; 85 86 if (count != 0) 87 return (buf); 88 return (NULL); 89 } 90 91 fdputs(char *buf, int fd) 92 { 93 return (fdprintf(fd, "%s", buf)); 94 } 95 96 fdputc(char c, int fd) 97 { 98 if (fd == 1) 99 fflush(stdout); 100 return (write(fd, &c, 1)); 101 } 102 103 104 int 105 open_locked(char *path, char *type, mode_t mode) 106 { 107 struct flock l; 108 int fd, 109 oflag, 110 create, 111 truncate = 0; 112 113 if (!path || !type) { 114 errno = EINVAL; 115 return (-1); 116 } 117 118 #define plus (type[1] == '+') 119 switch (type[0]) { 120 case 'w': 121 oflag = plus? O_RDWR : O_WRONLY; 122 create = 1; 123 truncate = 1; 124 break; 125 case 'a': 126 oflag = (plus? O_RDWR : O_WRONLY) | O_APPEND; 127 create = 1; 128 break; 129 case 'r': 130 oflag = plus? O_RDWR : O_RDONLY; 131 create = 0; 132 break; 133 default: 134 errno = EINVAL; 135 return (-1); 136 } 137 if ((fd = Open(path, oflag, mode)) == -1) 138 if (errno == ENOENT && create) { 139 int old_umask = umask(0); 140 int save_errno; 141 142 if ((fd = Open(path, oflag|O_CREAT, mode)) != -1) 143 chown_lppath(path); 144 save_errno = errno; 145 if (old_umask) 146 umask(old_umask); 147 errno = save_errno; 148 } 149 150 if (fd == -1) 151 switch (errno) { 152 case ENOTDIR: 153 errno = EACCES; 154 /* FALLTHROUGH */ 155 default: 156 return (-1); 157 } 158 159 l.l_type = (oflag & (O_WRONLY|O_RDWR)? F_WRLCK : F_RDLCK); 160 l.l_whence = 1; 161 l.l_start = 0; 162 l.l_len = 0; 163 if (Fcntl(fd, F_SETLK, &l) == -1) { 164 /* 165 * Early UNIX op. sys. have wrong errno. 166 */ 167 if (errno == EACCES) 168 errno = EAGAIN; 169 Close(fd); 170 return (-1); 171 } 172 173 if (truncate) { 174 if ((lseek(fd, 0, SEEK_SET) == (off_t)-1) || 175 (ftruncate(fd, 0) == -1)) { 176 Close(fd); 177 return (-1); 178 } 179 } 180 181 return (fd); 182 } 183 184 185 FILE * 186 open_lpfile(char *path, char *type, mode_t mode) 187 { 188 FILE *fp = NULL; 189 int fd; 190 191 if ((fd = open_locked(path, type, mode)) >= 0) { 192 errno = 0; /* fdopen() may fail and not set errno */ 193 if (!(fp = fdopen(fd, type))) { 194 Close(fd); 195 } 196 } 197 return (fp); 198 } 199 int 200 close_lpfile(FILE *fp) 201 { 202 return (fclose(fp)); 203 } 204 205 /* 206 * chown_lppath() 207 */ 208 209 int 210 chown_lppath(char *path) 211 { 212 static uid_t lp_uid; 213 214 static gid_t lp_gid; 215 216 static int gotids = 0; 217 218 struct passwd *ppw; 219 220 221 if (!gotids) { 222 if (!(ppw = getpwnam(LPUSER))) 223 ppw = getpwnam(ROOTUSER); 224 endpwent(); 225 if (!ppw) 226 return (-1); 227 lp_uid = ppw->pw_uid; 228 lp_gid = ppw->pw_gid; 229 gotids = 1; 230 } 231 return (Chown(path, lp_uid, lp_gid)); 232 } 233 234 /* 235 * rmfile() - UNLINK FILE BUT NO COMPLAINT IF NOT THERE 236 */ 237 238 int 239 rmfile(char *path) 240 { 241 return (Unlink(path) == 0 || errno == ENOENT); 242 } 243 244 /* 245 * loadline() - LOAD A ONE-LINE CHARACTER STRING FROM FILE 246 */ 247 248 char * 249 loadline(char *path) 250 { 251 int fd; 252 register char *ret; 253 register int len; 254 char buf[BUFSIZ]; 255 256 if ((fd = open_locked(path, "r", MODE_READ)) < 0) 257 return (0); 258 259 if (fdgets(buf, BUFSIZ, fd)) { 260 if ((len = strlen(buf)) && buf[len - 1] == '\n') 261 buf[--len] = 0; 262 if ((ret = Malloc(len + 1))) 263 strcpy(ret, buf); 264 } else { 265 errno = 0; 266 ret = 0; 267 } 268 269 close(fd); 270 return (ret); 271 } 272 273 /* 274 * loadstring() - LOAD A CHARACTER STRING FROM FILE 275 */ 276 277 char * 278 loadstring(char *path) 279 { 280 int fd; 281 register char *ret; 282 register int len; 283 284 if ((fd = open_locked(path, "r", MODE_READ)) < 0) 285 return (0); 286 287 if ((ret = sop_up_rest(fd, (char *)0))) { 288 if ((len = strlen(ret)) && ret[len - 1] == '\n') 289 ret[len - 1] = 0; 290 } else 291 errno = 0; 292 293 close(fd); 294 return (ret); 295 } 296 297 /* 298 * dumpstring() - DUMP CHARACTER STRING TO FILE 299 */ 300 301 int 302 dumpstring(char *path, char *str) 303 { 304 int fd; 305 306 if (!str) 307 return (rmfile(path)); 308 309 if ((fd = open_locked(path, "w", MODE_READ)) < 0) 310 return (-1); 311 fdprintf(fd, "%s\n", str); 312 close(fd); 313 return (0); 314 } 315