Annotation of src/usr.bin/sudo/fileops.c, Revision 1.7
1.1 millert 1: /*
1.6 millert 2: * Copyright (c) 1999-2005, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 millert 3: *
1.4 millert 4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.3 millert 15: *
16: * Sponsored in part by the Defense Advanced Research Projects
17: * Agency (DARPA) and Air Force Research Laboratory, Air Force
18: * Materiel Command, USAF, under agreement number F39502-99-1-0512.
1.1 millert 19: */
20:
1.5 millert 21: #include <config.h>
1.1 millert 22:
1.2 millert 23: #include <sys/types.h>
24: #include <sys/param.h>
1.4 millert 25: #include <sys/time.h>
1.2 millert 26: #ifdef HAVE_FLOCK
27: # include <sys/file.h>
28: #endif /* HAVE_FLOCK */
1.1 millert 29: #include <stdio.h>
1.6 millert 30: #ifdef HAVE_STRING_H
31: # include <string.h>
32: #else
33: # ifdef HAVE_STRINGS_H
34: # include <strings.h>
35: # endif
36: #endif /* HAVE_STRING_H */
37: #include <ctype.h>
38: #include <limits.h>
1.1 millert 39: #ifdef HAVE_UNISTD_H
1.2 millert 40: # include <unistd.h>
1.1 millert 41: #endif /* HAVE_UNISTD_H */
42: #include <fcntl.h>
1.5 millert 43: #if TIME_WITH_SYS_TIME
44: # include <time.h>
45: #endif
46: #ifndef HAVE_TIMESPEC
47: # include <emul/timespec.h>
48: #endif
1.1 millert 49:
50: #include "sudo.h"
51:
1.6 millert 52: #ifndef LINE_MAX
53: # define LINE_MAX 2048
54: #endif
55:
1.1 millert 56: #ifndef lint
1.7 ! millert 57: __unused static const char rcsid[] = "$Sudo: fileops.c,v 1.17 2009/03/12 00:03:04 millert Exp $";
1.1 millert 58: #endif /* lint */
59:
60: /*
1.4 millert 61: * Update the access and modify times on an fd or file.
1.1 millert 62: */
63: int
1.4 millert 64: touch(fd, path, tsp)
65: int fd;
1.1 millert 66: char *path;
1.4 millert 67: struct timespec *tsp;
1.1 millert 68: {
1.4 millert 69: struct timeval times[2];
1.1 millert 70:
1.4 millert 71: if (tsp != NULL) {
72: times[0].tv_sec = times[1].tv_sec = tsp->tv_sec;
73: times[0].tv_usec = times[1].tv_usec = tsp->tv_nsec / 1000;
74: }
75:
76: #if defined(HAVE_FUTIME) || defined(HAVE_FUTIMES)
77: if (fd != -1)
78: return(futimes(fd, tsp ? times : NULL));
79: else
80: #endif
81: if (path != NULL)
82: return(utimes(path, tsp ? times : NULL));
83: else
84: return(-1);
1.1 millert 85: }
86:
87: /*
88: * Lock/unlock a file.
89: */
90: #ifdef HAVE_LOCKF
91: int
92: lock_file(fd, lockit)
93: int fd;
94: int lockit;
95: {
96: int op = 0;
97:
98: switch (lockit) {
99: case SUDO_LOCK:
100: op = F_LOCK;
101: break;
102: case SUDO_TLOCK:
103: op = F_TLOCK;
104: break;
105: case SUDO_UNLOCK:
106: op = F_ULOCK;
107: break;
108: }
109: return(lockf(fd, op, 0) == 0);
110: }
111: #elif HAVE_FLOCK
112: int
113: lock_file(fd, lockit)
114: int fd;
115: int lockit;
116: {
117: int op = 0;
118:
119: switch (lockit) {
120: case SUDO_LOCK:
121: op = LOCK_EX;
122: break;
123: case SUDO_TLOCK:
124: op = LOCK_EX | LOCK_NB;
125: break;
126: case SUDO_UNLOCK:
1.2 millert 127: op = LOCK_UN;
1.1 millert 128: break;
129: }
130: return(flock(fd, op) == 0);
131: }
132: #else
133: int
134: lock_file(fd, lockit)
135: int fd;
136: int lockit;
137: {
138: #ifdef F_SETLK
139: int func;
140: struct flock lock;
141:
142: lock.l_start = 0;
143: lock.l_len = 0;
144: lock.l_pid = getpid();
145: lock.l_type = (lockit == SUDO_UNLOCK) ? F_UNLCK : F_WRLCK;
146: lock.l_whence = SEEK_SET;
147: func = (lockit == SUDO_TLOCK) ? F_SETLK : F_SETLKW;
148:
149: return(fcntl(fd, func, &lock) == 0);
150: #else
151: return(TRUE);
152: #endif
153: }
154: #endif
1.6 millert 155:
156: /*
157: * Read a line of input, remove comments and strip off leading
158: * and trailing spaces. Returns static storage that is reused.
159: */
160: char *
161: sudo_parseln(fp)
162: FILE *fp;
163: {
164: size_t len;
165: char *cp = NULL;
166: static char buf[LINE_MAX];
167:
168: if (fgets(buf, sizeof(buf), fp) != NULL) {
169: /* Remove comments */
170: if ((cp = strchr(buf, '#')) != NULL)
171: *cp = '\0';
172:
173: /* Trim leading and trailing whitespace/newline */
174: len = strlen(buf);
1.7 ! millert 175: while (len > 0 && isspace((unsigned char)buf[len - 1]))
1.6 millert 176: buf[--len] = '\0';
177: for (cp = buf; isblank(*cp); cp++)
178: continue;
179: }
180: return(cp);
181: }