xref: /illumos-gate/usr/src/cmd/lp/lib/lp/files.c (revision e4fb8a5f)
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
is_printer_uri(char * value)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
chownmod(char * path,uid_t owner,gid_t group,mode_t mode)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
fdprintf(int fd,char * fmt,...)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 *
fdgets(char * buf,int len,int fd)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
fdputs(char * buf,int fd)108 fdputs(char *buf, int fd)
109 {
110 	return (fdprintf(fd, "%s", buf));
111 }
112 
113 int
fdputc(char c,int fd)114 fdputc(char c, int fd)
115 {
116 	if (fd == 1)
117 		fflush(stdout);
118 	return (write(fd, &c, 1));
119 }
120 
121 int
open_locked(char * path,char * type,mode_t mode)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 *
open_lpfile(char * path,char * type,mode_t mode)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
close_lpfile(FILE * fp)217 close_lpfile(FILE *fp)
218 {
219 	return (fclose(fp));
220 }
221 
222 /*
223  * chown_lppath()
224  */
225 
226 int
chown_lppath(char * path)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
rmfile(char * path)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 *
loadline(char * path)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 *
loadstring(char * path)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
dumpstring(char * path,char * str)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