r23796: main COPYING file for samba4, plus some formatting varients
[samba.git] / source4 / lib / util / util_file.c
index 246b03b4aa4cbb17a3baf4e4676d0256fc0b4dff..df4cb902f0bf9b8c95d9de5cbe88e308ba1a2784 100644 (file)
@@ -7,7 +7,7 @@
  * 
  * This program is free software; you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
+ * Software Foundation; either version 3 of the License, or (at your option)
  * any later version.
  * 
  * This program is distributed in the hope that it will be useful, but WITHOUT
 #include "system/shmem.h"
 #include "system/filesys.h"
 
-/****************************************************************************
+/**
+ * @file
+ * @brief File-related utility functions
+ */
+
+/**
 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,XFILE *f)
+**/
+_PUBLIC_ char *fgets_slash(char *s2,int maxlen,XFILE *f)
 {
   char *s=s2;
   int len = 0;
@@ -77,6 +82,7 @@ char *fgets_slash(char *s2,int maxlen,XFILE *f)
        case ' ':
          if (start_of_line)
            break;
+         /* fall through */
        default:
          start_of_line = False;
          s[len++] = c;
@@ -98,8 +104,10 @@ char *fgets_slash(char *s2,int maxlen,XFILE *f)
   return(s);
 }
 
-/* Read one line (data until next newline or eof) and allocate it */
-char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint)
+/**
+ * Read one line (data until next newline or eof) and allocate it 
+ */
+_PUBLIC_ char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint)
 {
        char *data = NULL;
        ssize_t alloc_size = 0, offset = 0, ret;
@@ -117,6 +125,10 @@ char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint)
 
                ret = read(fd, data + offset, hint);
 
+               if (ret == 0) {
+                       return NULL;
+               }
+
                if (ret == -1) {
                        talloc_free(data);
                        return NULL;
@@ -146,11 +158,10 @@ char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint)
 }
 
 
-/****************************************************************************
+/**
 load a file into memory from a fd.
-****************************************************************************/ 
-
-char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx)
+**/
+_PUBLIC_ char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx)
 {
        struct stat sbuf;
        char *p;
@@ -171,10 +182,10 @@ char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx)
        return p;
 }
 
-/****************************************************************************
+/**
 load a file into memory
-****************************************************************************/
-char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx)
+**/
+_PUBLIC_ char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx)
 {
        int fd;
        char *p;
@@ -192,10 +203,10 @@ char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx)
 }
 
 
-/*******************************************************************
+/**
 mmap (if possible) or read a file
-********************************************************************/
-void *map_file(const char *fname, size_t size)
+**/
+_PUBLIC_ void *map_file(const char *fname, size_t size)
 {
        size_t s2 = 0;
        void *p = NULL;
@@ -228,9 +239,10 @@ void *map_file(const char *fname, size_t size)
 }
 
 
-/****************************************************************************
+/**
 parse a buffer into lines
-****************************************************************************/
+'p' will be freed on error, and otherwise will be made a child of the returned array
+**/
 static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
 {
        int i;
@@ -248,10 +260,9 @@ static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *
                return NULL;
        }       
        
-       talloc_reference(ret, p);
+       talloc_steal(ret, p);
        
        memset(ret, 0, sizeof(ret[0])*(i+2));
-       if (numlines) *numlines = i;
 
        ret[0] = p;
        for (s = p, i=0; s < p+size; s++) {
@@ -263,57 +274,54 @@ static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *
                if (s[0] == '\r') s[0] = 0;
        }
 
+       /* remove any blank lines at the end */
+       while (i > 0 && ret[i-1][0] == 0) {
+               i--;
+       }
+
+       if (numlines) *numlines = i;
+
        return ret;
 }
 
 
-/****************************************************************************
+/**
 load a file into memory and return an array of pointers to lines in the file
 must be freed with talloc_free(). 
-****************************************************************************/
-char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx)
+**/
+_PUBLIC_ char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx)
 {
        char *p;
-       char **lines;
        size_t size;
 
        p = file_load(fname, &size, mem_ctx);
        if (!p) return NULL;
 
-       lines = file_lines_parse(p, size, numlines, mem_ctx);
-
-       talloc_free(p);
-
-       return lines;
+       return file_lines_parse(p, size, numlines, mem_ctx);
 }
 
-/****************************************************************************
+/**
 load a fd into memory and return an array of pointers to lines in the file
 must be freed with talloc_free(). If convert is true calls unix_to_dos on
 the list.
-****************************************************************************/
-char **fd_lines_load(int fd, int *numlines, TALLOC_CTX *mem_ctx)
+**/
+_PUBLIC_ char **fd_lines_load(int fd, int *numlines, TALLOC_CTX *mem_ctx)
 {
        char *p;
-       char **lines;
        size_t size;
 
        p = fd_load(fd, &size, mem_ctx);
        if (!p) return NULL;
 
-       lines = file_lines_parse(p, size, numlines, mem_ctx);
-
-       talloc_free(p);
-
-       return lines;
+       return file_lines_parse(p, size, numlines, mem_ctx);
 }
 
 
-/****************************************************************************
+/**
 take a list of lines and modify them to produce a list where \ continues
 a line
-****************************************************************************/
-void file_lines_slashcont(char **lines)
+**/
+_PUBLIC_ void file_lines_slashcont(char **lines)
 {
        int i, j;
 
@@ -332,10 +340,10 @@ void file_lines_slashcont(char **lines)
        }
 }
 
-/*
+/**
   save a lump of data into a file. Mostly used for debugging 
 */
-BOOL file_save(const char *fname, const void *packet, size_t length)
+_PUBLIC_ BOOL file_save(const char *fname, const void *packet, size_t length)
 {
        int fd;
        fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
@@ -349,31 +357,22 @@ BOOL file_save(const char *fname, const void *packet, size_t length)
        return True;
 }
 
-/*
-  see if a file exists
-*/
-BOOL file_exists(const char *path)
-{
-       struct stat st;
-       return (stat(path, &st) == 0);
-}
-
-int vfdprintf(int fd, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0)
+_PUBLIC_ int vfdprintf(int fd, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0)
 {
        char *p;
        int len, ret;
        va_list ap2;
 
-       VA_COPY(ap2, ap);
-
+       va_copy(ap2, ap);
        len = vasprintf(&p, format, ap2);
+       va_end(ap2);
        if (len <= 0) return len;
        ret = write(fd, p, len);
        SAFE_FREE(p);
        return ret;
 }
 
-int fdprintf(int fd, const char *format, ...) _PRINTF_ATTRIBUTE(2,3)
+_PUBLIC_ int fdprintf(int fd, const char *format, ...) _PRINTF_ATTRIBUTE(2,3)
 {
        va_list ap;
        int ret;
@@ -383,3 +382,24 @@ int fdprintf(int fd, const char *format, ...) _PRINTF_ATTRIBUTE(2,3)
        va_end(ap);
        return ret;
 }
+
+
+/*
+  try to determine if the filesystem supports large files
+*/
+_PUBLIC_ bool large_file_support(const char *path)
+{
+       int fd;
+       ssize_t ret;
+       char c;
+
+       fd = open(path, O_RDWR|O_CREAT, 0600);
+       unlink(path);
+       if (fd == -1) {
+               /* have to assume large files are OK */
+               return true;
+       }
+       ret = pread(fd, &c, 1, ((uint64_t)1)<<32);
+       close(fd);
+       return ret == 0;
+}