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