]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - support/nfs/cacheio.c
Remove some warnings that were introduced by commit 6ca440c
[nfs-utils.git] / support / nfs / cacheio.c
index d7ad4293762f4b6dd583fec668cb0ea9df47b733..55fa45d7e620c458917d0015c3af19fbf39bc452 100644 (file)
 
 #include <nfslib.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <ctype.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <time.h>
+#include <errno.h>
 
 void qword_add(char **bpp, int *lp, char *str)
 {
@@ -87,13 +89,47 @@ void qword_addhex(char **bpp, int *lp, char *buf, int blen)
        *lp = len;
 }
 
+void qword_addint(char **bpp, int *lp, int n)
+{
+       int len;
+
+       len = snprintf(*bpp, *lp, "%d ", n);
+       if (len > *lp)
+               len = *lp;
+       *bpp += len;
+       *lp -= len;
+}
+
+void qword_adduint(char **bpp, int *lp, unsigned int n)
+{
+       int len;
+
+       len = snprintf(*bpp, *lp, "%u ", n);
+       if (len > *lp)
+               len = *lp;
+       *bpp += len;
+       *lp -= len;
+}
+
+void qword_addeol(char **bpp, int *lp)
+{
+       if (*lp <= 0)
+               return;
+       **bpp = '\n';
+       (*bpp)++;
+       (*lp)--;
+}
+
 static char qword_buf[8192];
 void qword_print(FILE *f, char *str)
 {
        char *bp = qword_buf;
        int len = sizeof(qword_buf);
        qword_add(&bp, &len, str);
-       fwrite(qword_buf, bp-qword_buf, 1, f);
+       if (fwrite(qword_buf, bp-qword_buf, 1, f) != 1) {
+               xlog_warn("qword_print: fwrite failed: errno %d (%s)",
+                       errno, strerror(errno));
+       }
 }
 
 void qword_printhex(FILE *f, char *str, int slen)
@@ -101,7 +137,10 @@ void qword_printhex(FILE *f, char *str, int slen)
        char *bp = qword_buf;
        int len = sizeof(qword_buf);
        qword_addhex(&bp, &len, str, slen);
-       fwrite(qword_buf, bp-qword_buf, 1, f);
+       if (fwrite(qword_buf, bp-qword_buf, 1, f) != 1) {
+               xlog_warn("qword_printhex: fwrite failed: errno %d (%s)",
+                       errno, strerror(errno));
+       }
 }
 
 void qword_printint(FILE *f, int num)
@@ -109,10 +148,32 @@ void qword_printint(FILE *f, int num)
        fprintf(f, "%d ", num);
 }
 
-void qword_eol(FILE *f)
+void qword_printuint(FILE *f, unsigned int num)
 {
+       fprintf(f, "%u ", num);
+}
+
+int qword_eol(FILE *f)
+{
+       int err;
+
        fprintf(f,"\n");
+       err = fflush(f);
+       if (err) {
+               xlog_warn("qword_eol: fflush failed: errno %d (%s)",
+                           errno, strerror(errno));
+       }
+       /*
+        * We must send one line (and one line only) in a single write
+        * call.  In case of a write error, libc may accumulate the
+        * unwritten data and try to write it again later, resulting in a
+        * multi-line write.  So we must explicitly ask it to throw away
+        * any such cached data.  But we return any original error
+        * indication to the caller.
+        */
+       __fpurge(f);
        fflush(f);
+       return err;
 }
 
 
@@ -180,23 +241,39 @@ int qword_get_int(char **bpp, int *anint)
        return 0;
 }
 
+int qword_get_uint(char **bpp, unsigned int *anint)
+{
+       char buf[50];
+       char *ep;
+       unsigned int rv;
+       int len = qword_get(bpp, buf, 50);
+       if (len < 0) return -1;
+       if (len ==0) return -1;
+       rv = strtoul(buf, &ep, 0);
+       if (*ep) return -1;
+       *anint = rv;
+       return 0;
+}
+
+#define READLINE_BUFFER_INCREMENT 2048
+
 int readline(int fd, char **buf, int *lenp)
 {
        /* read a line into *buf, which is malloced *len long
         * realloc if needed until we find a \n
         * nul out the \n and return
-        * 0 of eof, 1 of success 
+        * 0 on eof, 1 on success
         */
-       int len = *lenp;
+       int len;
 
-       if (len == 0) {
-               char *b = malloc(128);
+       if (*lenp == 0) {
+               char *b = malloc(READLINE_BUFFER_INCREMENT);
                if (b == NULL)
                        return 0;
                *buf = b;
-               *lenp = 128;
+               *lenp = READLINE_BUFFER_INCREMENT;
        }
-       len = read(fd, *buf, len);
+       len = read(fd, *buf, *lenp);
        if (len <= 0)
                return 0;
        while ((*buf)[len-1] != '\n') {
@@ -205,7 +282,7 @@ int readline(int fd, char **buf, int *lenp)
         */
                char *new;
                int nl;
-               *lenp *= 2;
+               *lenp += READLINE_BUFFER_INCREMENT;
                new = realloc(*buf, *lenp);
                if (new == NULL)
                        return 0;
@@ -227,9 +304,8 @@ int readline(int fd, char **buf, int *lenp)
 int
 check_new_cache(void)
 {
-       struct stat stb;
-       return  (stat("/proc/fs/nfs/filehandle", &stb) == 0) ||
-               (stat("/proc/fs/nfsd/filehandle", &stb) == 0);
+       return  (access("/proc/fs/nfs/filehandle", F_OK) == 0) ||
+               (access("/proc/fs/nfsd/filehandle", F_OK) == 0);
 }      
 
 
@@ -247,21 +323,25 @@ cache_flush(int force)
        int c;
        char stime[20];
        char path[200];
+       time_t now;
        /* Note: the order of these caches is important.
-        * The need to be flushed in dependancy order. So
+        * They need to be flushed in dependancy order. So
         * a cache that references items in another cache,
         * as nfsd.fh entries reference items in nfsd.export,
         * must be flushed before the cache that it references.
         */
        static char *cachelist[] = {
                "auth.unix.ip",
+               "auth.unix.gid",
                "nfsd.fh",
                "nfsd.export",
                NULL
        };
-       stb.st_mtime = time(0);
-       if (!force)
-               stat(_PATH_ETAB, &stb);
+       now = time(0);
+       if (force ||
+           stat(_PATH_ETAB, &stb) != 0 ||
+           stb.st_mtime > now)
+               stb.st_mtime = time(0);
        
        sprintf(stime, "%ld\n", stb.st_mtime);
        for (c=0; cachelist[c]; c++) {
@@ -269,7 +349,10 @@ cache_flush(int force)
                sprintf(path, "/proc/net/rpc/%s/flush", cachelist[c]);
                fd = open(path, O_RDWR);
                if (fd >= 0) {
-                       write(fd, stime, strlen(stime));
+                       if (write(fd, stime, strlen(stime)) != strlen(stime)) {
+                               xlog_warn("Writing to '%s' failed: errno %d (%s)",
+                               path, errno, strerror(errno));
+                       }
                        close(fd);
                }
        }