Home | History | Annotate | Download | only in lp
      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