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