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