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