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