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