version 1.1.1.2, 2012/05/29 12:26:49
|
version 1.1.1.3, 2013/07/22 10:46:11
|
Line 1
|
Line 1
|
/* |
/* |
* Copyright (c) 1999-2005, 2007, 2009-2011 | * Copyright (c) 1999-2005, 2007, 2009-2013 |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
Line 22
|
Line 22
|
#include <config.h> |
#include <config.h> |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
|
#include <sys/time.h> |
#include <sys/time.h> |
#ifdef HAVE_FLOCK |
#ifdef HAVE_FLOCK |
# include <sys/file.h> |
# include <sys/file.h> |
#endif /* HAVE_FLOCK */ |
#endif /* HAVE_FLOCK */ |
#include <stdio.h> | #ifdef STDC_HEADERS |
#ifdef HAVE_STDBOOL_H | # include <stdlib.h> |
# include <stdbool.h> | # include <stddef.h> |
#else |
#else |
# include "compat/stdbool.h" | #ifdef HAVE_STRING_H |
#endif | # include <stdlib.h> |
| # endif |
| #endif /* STDC_HEADERS */ |
#ifdef HAVE_STRING_H |
#ifdef HAVE_STRING_H |
|
# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) |
|
# include <memory.h> |
|
# endif |
# include <string.h> |
# include <string.h> |
#endif /* HAVE_STRING_H */ |
#endif /* HAVE_STRING_H */ |
#ifdef HAVE_STRINGS_H |
#ifdef HAVE_STRINGS_H |
# include <strings.h> |
# include <strings.h> |
#endif /* HAVE_STRINGS_H */ | #endif /* HAVE_STRING_H */ |
| #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) |
| # include <malloc.h> |
| #endif /* HAVE_MALLOC_H && !STDC_HEADERS */ |
#include <ctype.h> |
#include <ctype.h> |
#include <limits.h> |
|
#ifdef HAVE_UNISTD_H |
#ifdef HAVE_UNISTD_H |
# include <unistd.h> |
# include <unistd.h> |
#endif /* HAVE_UNISTD_H */ |
#endif /* HAVE_UNISTD_H */ |
#include <fcntl.h> |
#include <fcntl.h> |
|
#ifdef HAVE_STDBOOL_H |
|
# include <stdbool.h> |
|
#else |
|
# include "compat/stdbool.h" |
|
#endif |
#if TIME_WITH_SYS_TIME |
#if TIME_WITH_SYS_TIME |
# include <time.h> |
# include <time.h> |
#endif |
#endif |
Line 56
|
Line 67
|
#include "fileops.h" |
#include "fileops.h" |
#include "sudo_debug.h" |
#include "sudo_debug.h" |
|
|
#ifndef LINE_MAX |
|
# define LINE_MAX 2048 |
|
#endif |
|
|
|
/* |
/* |
* Update the access and modify times on an fd or file. |
* Update the access and modify times on an fd or file. |
*/ |
*/ |
Line 152 lock_file(int fd, int lockit)
|
Line 159 lock_file(int fd, int lockit)
|
#endif |
#endif |
|
|
/* |
/* |
* Read a line of input, remove comments and strip off leading | * Read a line of input, honoring line continuation chars. |
* and trailing spaces. Returns static storage that is reused. | * Remove comments and strips off leading and trailing spaces. |
| * Returns the line length and updates the buf and bufsize pointers. |
| * XXX - just use a struct w/ state, including getline buffer? |
| * could also make comment char and line continuation configurable |
*/ |
*/ |
char * | ssize_t |
sudo_parseln(FILE *fp) | sudo_parseln(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp) |
{ |
{ |
size_t len; | size_t len, linesize = 0, total = 0; |
char *cp = NULL; | char *cp, *line = NULL; |
static char buf[LINE_MAX]; | bool continued; |
debug_decl(sudo_parseln, SUDO_DEBUG_UTIL) |
debug_decl(sudo_parseln, SUDO_DEBUG_UTIL) |
|
|
if (fgets(buf, sizeof(buf), fp) != NULL) { | do { |
/* Remove comments */ | continued = false; |
if ((cp = strchr(buf, '#')) != NULL) | len = getline(&line, &linesize, fp); |
| if (len == -1) |
| break; |
| if (lineno != NULL) |
| (*lineno)++; |
| |
| /* Remove trailing newline(s) if present. */ |
| while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) |
| line[--len] = '\0'; |
| |
| /* Remove comments or check for line continuation (but not both) */ |
| if ((cp = strchr(line, '#')) != NULL) { |
*cp = '\0'; |
*cp = '\0'; |
|
len = (size_t)(cp - line); |
|
} else if (len > 0 && line[len - 1] == '\\' && (len == 1 || line[len - 2] != '\\')) { |
|
line[--len] = '\0'; |
|
continued = true; |
|
} |
|
|
/* Trim leading and trailing whitespace/newline */ | /* Trim leading and trailing whitespace */ |
len = strlen(buf); | if (!continued) { |
while (len > 0 && isspace((unsigned char)buf[len - 1])) | while (len > 0 && isblank((unsigned char)line[len - 1])) |
buf[--len] = '\0'; | line[--len] = '\0'; |
for (cp = buf; isblank((unsigned char)*cp); cp++) | } |
continue; | for (cp = line; isblank((unsigned char)*cp); cp++) |
} | len--; |
debug_return_str(cp); | |
| if (*bufp == NULL || total + len >= *bufsizep) { |
| void *tmp; |
| size_t size = total + len + 1; |
| |
| if (size < 64) { |
| size = 64; |
| } else if (size <= 0x80000000) { |
| /* Round up to next highest power of two. */ |
| size--; |
| size |= size >> 1; |
| size |= size >> 2; |
| size |= size >> 4; |
| size |= size >> 8; |
| size |= size >> 16; |
| size++; |
| } |
| if ((tmp = realloc(*bufp, size)) == NULL) |
| break; |
| *bufp = tmp; |
| *bufsizep = size; |
| } |
| memcpy(*bufp + total, cp, len + 1); |
| total += len; |
| } while (continued); |
| free(line); |
| if (len == -1 && total == 0) |
| debug_return_size_t((size_t)-1); |
| debug_return_size_t(total); |
} |
} |