X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=source3%2Flib%2Futil_file.c;h=549766b13750c21c97a4f8ba6291805cf46b8662;hp=0d6e77b010db4cae303b03a5f14f18bdf72e14a0;hb=ae9bac99fa9cda2e480afa10a7c00b37ad4fd255;hpb=613860a3aa3523642b01b8eaa62db7e08612a584 diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c index 0d6e77b010d..549766b1375 100644 --- a/source3/lib/util_file.c +++ b/source3/lib/util_file.c @@ -1,5 +1,6 @@ /* - * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup + * Unix SMB/CIFS implementation. + * SMB parameters and setup * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. * * This program is free software; you can redistribute it and/or modify it under @@ -19,8 +20,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - static int gotalarm; /*************************************************************** @@ -51,7 +50,7 @@ BOOL do_file_lock(int fd, int waitsecs, int type) lock.l_len = 1; lock.l_pid = 0; - alarm(5); + alarm(waitsecs); ret = fcntl(fd, SMB_F_SETLKW, &lock); alarm(0); CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL); @@ -125,7 +124,7 @@ void *startfilepwent(char *pfile, char *s_readbuf, int bufsize, } DEBUG(10, ("startfilepwent: opening file %s\n", pfile)); - fp = fopen(pfile, update ? "r+b" : "rb"); + fp = sys_fopen(pfile, update ? "r+b" : "rb"); if (fp == NULL) { DEBUG(0, ("startfilepwent: unable to open file %s\n", pfile)); @@ -217,6 +216,12 @@ int getfileline(void *vp, char *linebuf, int linebuf_size) */ linebuf_len = strlen(linebuf); + if (linebuf_len == 0) + { + linebuf[0] = '\0'; + return 0; + } + if (linebuf[linebuf_len - 1] != '\n') { c = '\0'; @@ -249,7 +254,7 @@ int getfileline(void *vp, char *linebuf, int linebuf_size) continue; } - p = (unsigned char *) strchr(linebuf, ':'); + p = (unsigned char *) strchr_m(linebuf, ':'); if (p == NULL) { DEBUG(0, ("getfileline: malformed line entry (no :)\n")); @@ -266,29 +271,31 @@ read a line from a file with possible \ continuation chars. Blanks at the start or end of a line are stripped. The string will be allocated if s2 is NULL ****************************************************************************/ -char *fgets_slash(char *s2,int maxlen,FILE *f) +char *fgets_slash(char *s2,int maxlen,XFILE *f) { char *s=s2; int len = 0; int c; BOOL start_of_line = True; - if (feof(f)) + if (x_feof(f)) return(NULL); + if (maxlen <2) return(NULL); + if (!s2) { maxlen = MIN(maxlen,8); - s = (char *)Realloc(s,maxlen); + s = (char *)malloc(maxlen); } - if (!s || maxlen < 2) return(NULL); + if (!s) return(NULL); *s = 0; while (len < maxlen-1) { - c = getc(f); + c = x_getc(f); switch (c) { case '\r': @@ -307,7 +314,7 @@ char *fgets_slash(char *s2,int maxlen,FILE *f) return(s); case EOF: if (len <= 0 && !s2) - free(s); + SAFE_FREE(s); return(len>0?s:NULL); case ' ': if (start_of_line) @@ -319,11 +326,270 @@ char *fgets_slash(char *s2,int maxlen,FILE *f) } if (!s2 && len > maxlen-3) { + char *t; + maxlen *= 2; - s = (char *)Realloc(s,maxlen); - if (!s) return(NULL); + t = (char *)Realloc(s,maxlen); + if (!t) { + DEBUG(0,("fgets_slash: failed to expand buffer!\n")); + SAFE_FREE(s); + return(NULL); + } else s = t; } } return(s); } + +/**************************************************************************** +load from a pipe into memory +****************************************************************************/ +char *file_pload(char *syscmd, size_t *size) +{ + int fd, n; + char *p, *tp; + 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) { + tp = Realloc(p, total + n + 1); + if (!tp) { + DEBUG(0,("file_pload: failed to exand buffer!\n")); + close(fd); + SAFE_FREE(p); + return NULL; + } else p = tp; + memcpy(p+total, buf, n); + total += n; + } + if (p) p[total] = 0; + + sys_pclose(fd); + + if (size) *size = total; + + return p; +} + +/**************************************************************************** +load a file into memory from a fd. +****************************************************************************/ + +char *fd_load(int fd, size_t *size) +{ + SMB_STRUCT_STAT sbuf; + char *p; + + if (sys_fstat(fd, &sbuf) != 0) return NULL; + + p = (char *)malloc(sbuf.st_size+1); + if (!p) return NULL; + + if (read(fd, p, sbuf.st_size) != sbuf.st_size) { + SAFE_FREE(p); + return NULL; + } + p[sbuf.st_size] = 0; + + if (size) *size = sbuf.st_size; + + return p; +} + +/**************************************************************************** +load a file into memory +****************************************************************************/ +char *file_load(const char *fname, size_t *size) +{ + int fd; + char *p; + + if (!fname || !*fname) return NULL; + + fd = open(fname,O_RDONLY); + if (fd == -1) return NULL; + + p = fd_load(fd, size); + + close(fd); + + return p; +} + + +/******************************************************************* +mmap (if possible) or read a file +********************************************************************/ +void *map_file(char *fname, size_t size) +{ + size_t s2 = 0; + void *p = NULL; +#ifdef HAVE_MMAP + if (lp_use_mmap()) { + int fd; + fd = open(fname, O_RDONLY, 0); + if (fd == -1) { + DEBUG(1,("Failed to load %s - %s\n", fname, strerror(errno))); + return NULL; + } + p = mmap(NULL, size, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0); + close(fd); + if (p == MAP_FAILED) { + DEBUG(1,("Failed to mmap %s - %s\n", fname, strerror(errno))); + return NULL; + } + } +#endif + if (!p) { + p = file_load(fname, &s2); + if (!p || s2 != size) { + DEBUG(1,("incorrect size for %s - got %d expected %d\n", + fname, s2, size)); + if (p) free(p); + return NULL; + } + } + + 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++; + } + + ret = (char **)malloc(sizeof(ret[0])*(i+2)); + if (!ret) { + SAFE_FREE(p); + return NULL; + } + memset(ret, 0, sizeof(ret[0])*(i+2)); + if (numlines) *numlines = i; + + ret[0] = p; + for (s = p, i=0; s < p+size; s++) { + if (s[0] == '\n') { + s[0] = 0; + i++; + ret[i] = s+1; + } + if (s[0] == '\r') s[0] = 0; + } + + 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(const 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 fd into memory and return an array of pointers to lines in the file +must be freed with file_lines_free(). If convert is true calls unix_to_dos on +the list. +****************************************************************************/ +char **fd_lines_load(int fd, int *numlines) +{ + char *p; + size_t size; + + p = fd_load(fd, &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 +****************************************************************************/ +void file_lines_free(char **lines) +{ + if (!lines) return; + SAFE_FREE(lines[0]); + SAFE_FREE(lines); +} + + +/**************************************************************************** +take a lislist of lines and modify them to produce a list where \ continues +a line +****************************************************************************/ +void file_lines_slashcont(char **lines) +{ + int i, j; + + for (i=0; lines[i];) { + int len = strlen(lines[i]); + if (lines[i][len-1] == '\\') { + lines[i][len-1] = ' '; + if (lines[i+1]) { + char *p = &lines[i][len]; + while (p < lines[i+1]) *p++ = ' '; + for (j = i+1; lines[j]; j++) lines[j] = lines[j+1]; + } + } else { + i++; + } + } +} + +/* + save a lump of data into a file. Mostly used for debugging +*/ +BOOL file_save(const char *fname, void *packet, size_t length) +{ + int fd; + fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd == -1) { + return False; + } + if (write(fd, packet, length) != length) { + return False; + } + close(fd); + return True; +}