diff options
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/system.c | 102 | ||||
-rw-r--r-- | source3/lib/util_file.c | 102 |
2 files changed, 105 insertions, 99 deletions
diff --git a/source3/lib/system.c b/source3/lib/system.c index 8ac07e26a5..3354ee0bbc 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -952,37 +952,29 @@ static char **extract_args(const char *command) /************************************************************************** Wrapper for popen. Safer as it doesn't search a path. Modified from the glibc sources. + modified by tridge to return a file descriptor. We must kick our FILE* habit ****************************************************************************/ - typedef struct _popen_list { - FILE *fp; + int fd; pid_t child_pid; struct _popen_list *next; } popen_list; static popen_list *popen_chain; -FILE *sys_popen(const char *command, const char *mode, BOOL paranoid) +int sys_popen(const char *command) { int parent_end, child_end; int pipe_fds[2]; - popen_list *entry = NULL; + popen_list *entry = NULL; char **argl = NULL; if (pipe(pipe_fds) < 0) - return NULL; + return -1; - if (mode[0] == 'r' && mode[1] == '\0') { - parent_end = pipe_fds[0]; - child_end = pipe_fds[1]; - } else if (mode[0] == 'w' && mode[1] == '\0') { - parent_end = pipe_fds[1]; - child_end = pipe_fds[0]; - } else { - errno = EINVAL; - goto err_exit; - } + parent_end = pipe_fds[0]; + child_end = pipe_fds[1]; if (!*command) { errno = EINVAL; @@ -999,69 +991,9 @@ FILE *sys_popen(const char *command, const char *mode, BOOL paranoid) if(!(argl = extract_args(command))) goto err_exit; - if(paranoid) { - /* - * Do some basic paranioa checks. Do a stat on the parent - * directory and ensure it's not world writable. Do a stat - * on the file itself and ensure it's owned by root and not - * world writable. Note this does *not* prevent symlink races, - * but is a generic "don't let the admin screw themselves" - * check. - */ - - SMB_STRUCT_STAT st; - pstring dir_name; - char *ptr = strrchr(argl[0], '/'); - - if(sys_stat(argl[0], &st) != 0) - goto err_exit; - - if((st.st_uid != (uid_t)0) || (st.st_mode & S_IWOTH)) { - errno = EACCES; - goto err_exit; - } - - if(!ptr) { - /* - * No '/' in name - use current directory. - */ - pstrcpy(dir_name, "."); - } else { - - /* - * Copy into a pstring and do the checks - * again (in case we were length tuncated). - */ - - pstrcpy(dir_name, argl[0]); - ptr = strrchr(dir_name, '/'); - if(!ptr) { - errno = EINVAL; - goto err_exit; - } - if(strcmp(dir_name, "/") != 0) - *ptr = '\0'; - if(!dir_name[0]) - pstrcpy(dir_name, "."); - } - - if(sys_stat(argl[0], &st) != 0) - goto err_exit; - - if(!S_ISDIR(st.st_mode) || (st.st_mode & S_IWOTH)) { - errno = EACCES; - goto err_exit; - } - } - entry->child_pid = fork(); if (entry->child_pid == -1) { - - /* - * Error ! - */ - goto err_exit; } @@ -1071,7 +1003,7 @@ FILE *sys_popen(const char *command, const char *mode, BOOL paranoid) * Child ! */ - int child_std_end = (mode[0] == 'r') ? STDOUT_FILENO : STDIN_FILENO; + int child_std_end = STDOUT_FILENO; popen_list *p; close(parent_end); @@ -1087,7 +1019,7 @@ FILE *sys_popen(const char *command, const char *mode, BOOL paranoid) */ for (p = popen_chain; p; p = p->next) - close(fileno(p->fp)); + close(p->fd); execv(argl[0], argl); _exit (127); @@ -1100,16 +1032,11 @@ FILE *sys_popen(const char *command, const char *mode, BOOL paranoid) close (child_end); free((char *)argl); - /* - * Create the FILE * representing this fd. - */ - entry->fp = fdopen(parent_end, mode); - /* Link into popen_chain. */ entry->next = popen_chain; popen_chain = entry; - return entry->fp; + return entry->fd; err_exit: @@ -1119,14 +1046,13 @@ err_exit: free((char *)argl); close(pipe_fds[0]); close(pipe_fds[1]); - return NULL; + return -1; } /************************************************************************** Wrapper for pclose. Modified from the glibc sources. ****************************************************************************/ - -int sys_pclose( FILE *fp) +int sys_pclose(int fd) { int wstatus; popen_list **ptr = &popen_chain; @@ -1136,7 +1062,7 @@ int sys_pclose( FILE *fp) /* Unlink from popen_chain. */ for ( ; *ptr != NULL; ptr = &(*ptr)->next) { - if ((*ptr)->fp == fp) { + if ((*ptr)->fd == fd) { entry = *ptr; *ptr = (*ptr)->next; status = 0; @@ -1144,7 +1070,7 @@ int sys_pclose( FILE *fp) } } - if (status < 0 || close(fileno(entry->fp)) < 0) + if (status < 0 || close(entry->fd) < 0) return -1; /* diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c index d533e6428f..1ef713b105 100644 --- a/source3/lib/util_file.c +++ b/source3/lib/util_file.c @@ -329,35 +329,83 @@ char *fgets_slash(char *s2,int maxlen,FILE *f) /**************************************************************************** -load a file into memory and return an array of pointers to lines in the file -must be freed with file_lines_free() +load from a pipe into memory ****************************************************************************/ -char **file_lines_load(char *fname, int *numlines) +char *file_pload(char *syscmd, size_t *size) { - int fd, i; + int fd, n; + char *p; + pstring buf; + size_t total; + + fd = sys_popen(syscmd); + if (fd == -1) return NULL; + + p = NULL; + total = 0; + + while ((n = read(fd, buf, sizeof(buf))) > 0) { + p = Realloc(p, total + n + 1); + if (!p) { + close(fd); + return NULL; + } + memcpy(p+total, buf, n); + total += n; + } + p[total] = 0; + + sys_pclose(fd); + + if (size) *size = total; + + return p; +} + + +/**************************************************************************** +load a file into memory +****************************************************************************/ +char *file_load(char *fname, size_t *size) +{ + int fd; SMB_STRUCT_STAT sbuf; - char *p, *s, **ret; - size_t size; + char *p; fd = open(fname,O_RDONLY); if (fd == -1) return NULL; if (sys_fstat(fd, &sbuf) != 0) return NULL; - size = sbuf.st_size; - if (size == 0) return NULL; + if (sbuf.st_size == 0) return NULL; - p = (char *)malloc(size+1); + p = (char *)malloc(sbuf.st_size+1); if (!p) return NULL; - if (read(fd, p, size) != size) { + if (read(fd, p, sbuf.st_size) != sbuf.st_size) { free(p); return NULL; } - p[size] = 0; + p[sbuf.st_size] = 0; close(fd); + if (size) *size = sbuf.st_size; + + return p; +} + + +/**************************************************************************** +parse a buffer into lines +****************************************************************************/ +static char **file_lines_parse(char *p, size_t size, int *numlines) +{ + int i; + char *s, **ret; + + if (!p) return NULL; + for (s = p, i=0; s < p+size; s++) { if (s[0] == '\n') i++; } @@ -383,6 +431,38 @@ char **file_lines_load(char *fname, int *numlines) return ret; } + +/**************************************************************************** +load a file into memory and return an array of pointers to lines in the file +must be freed with file_lines_free() +****************************************************************************/ +char **file_lines_load(char *fname, int *numlines) +{ + char *p; + size_t size; + + p = file_load(fname, &size); + if (!p) return NULL; + + return file_lines_parse(p, size, numlines); +} + + +/**************************************************************************** +load a pipe into memory and return an array of pointers to lines in the data +must be freed with file_lines_free() +****************************************************************************/ +char **file_lines_pload(char *syscmd, int *numlines) +{ + char *p; + size_t size; + + p = file_pload(syscmd, &size); + if (!p) return NULL; + + return file_lines_parse(p, size, numlines); +} + /**************************************************************************** free lines loaded with file_lines_load ****************************************************************************/ |