]> diplodocus.org Git - nmh/blobdiff - uip/mhcachesbr.c
lock_file.c: close(2) file descriptor on failure, avoiding leak.
[nmh] / uip / mhcachesbr.c
index c1af218018af4b061f9534d6c7d7df1a62772e53..b740e231e2e2ad58fc142136c95acbf4286281c1 100644 (file)
@@ -1,44 +1,35 @@
-
-/*
- * mhcachesbr.c -- routines to manipulate the MIME content cache
+/* mhcachesbr.c -- routines to manipulate the MIME content cache
  *
- * $Id$
+ * This code is Copyright (c) 2002, by the authors of nmh.  See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information.
  */
 
 #include <h/mh.h>
 #include <fcntl.h>
-#include <h/signals.h>
 #include <h/md5.h>
-#include <errno.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <zotnet/mts/mts.h>
-#include <zotnet/tws/tws.h>
+#include <h/mts.h>
+#include <h/tws.h>
 #include <h/mime.h>
 #include <h/mhparse.h>
 #include <h/mhcachesbr.h>
+#include <h/utils.h>
+#include "mhmisc.h"
+#include "sbr/lock_file.h"
+#include "sbr/m_mktemp.h"
 
-#ifdef TIME_WITH_SYS_TIME
+#ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
-# include <time.h>
-#else
-# ifdef TM_IN_SYS_TIME
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
 #endif
+#include <time.h>
 
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(CACHE, caches);
+#undef X
+struct swit *cache_policy = caches;
 
-
-extern int errno;
 extern int debugsw;
 
-extern pid_t xpid;     /* mhshowsbr.c or mhbuildsbr.c */
-
 /* cache policies */
 int rcachesw = CACHE_ASK;
 int wcachesw = CACHE_ASK;
@@ -50,23 +41,6 @@ int wcachesw = CACHE_ASK;
 char *cache_public;
 char *cache_private;
 
-
-/* mhparse.c (OR) mhbuildsbr.c */
-int pidcheck (int);
-
-/* mhmisc.c */
-int part_ok (CT, int);
-int type_ok (CT, int);
-int make_intermediates (char *);
-void content_error (char *, CT, char *, ...);
-void flush_errors (void);
-
-/*
- * prototypes
- */
-void cache_all_messages (CT *);
-int find_cache (CT, int, int *, char *, char *, int);
-
 /*
  * static prototypes
  */
@@ -110,30 +84,22 @@ cache_content (CT ct)
 {
     int        cachetype;
     char *file, cachefile[BUFSIZ];
-    CE ce = ct->c_cefile;
+    CE ce = &ct->c_cefile;
 
     if (!ct->c_id) {
-       advise (NULL, "no %s: field in %s", ID_FIELD, ct->c_file);
+       inform("no %s: field in %s", ID_FIELD, ct->c_file);
        return;
     }
 
     if (!ce) {
-       advise (NULL, "unable to decode %s", ct->c_file);
+       inform("unable to decode %s", ct->c_file);
        return;
     }
 
-/* THIS NEEDS TO BE FIXED */
-#if 0
-    if (ct->c_ceopenfnx == openMail) {
-       advise (NULL, "a radish may no know Greek, but I do...");
-       return;
-    }
-#endif
-
     if (find_cache (NULL, wcachesw != CACHE_NEVER ? wcachesw : CACHE_ASK,
                    &cachetype, ct->c_id, cachefile, sizeof(cachefile))
            == NOTOK) {
-       advise (NULL, "unable to cache %s's contents", ct->c_file);
+       inform("unable to cache %s's contents", ct->c_file);
        return;
     }
     if (wcachesw != CACHE_NEVER && wcachesw != CACHE_ASK) {
@@ -162,16 +128,18 @@ cache_content (CT ct)
 
            while ((cc = fread (buffer, sizeof(*buffer), sizeof(buffer), gp))
                       > 0)
-               fwrite (buffer, sizeof(*buffer), cc, fp);
+               if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) {
+                   advise ("cache_content", "fwrite");
+               }
            fflush (fp);
 
            if (ferror (gp)) {
                admonish (ce->ce_file, "error reading");
-               unlink (cachefile);
+               (void) m_unlink (cachefile);
            } else {
                if (ferror (fp)) {
                    admonish (cachefile, "error writing");
-                   unlink (cachefile);
+                   (void) m_unlink (cachefile);
                }
            }
            fclose (fp);
@@ -213,7 +181,7 @@ find_cache (CT ct, int policy, int *writing, char *id,
        case CACHE_PUBLIC:
            if (cache_private
                    && !writing
-                   && find_cache_aux (writing ? 2 : 0, cache_private, id,
+                   && find_cache_aux (0, cache_private, id,
                                       buffer, buflen) == OK) {
                if (access (buffer, R_OK) != NOTOK) {
 got_private:
@@ -250,20 +218,13 @@ got_it:
        int len, buflen;
        char *bp, query[BUFSIZ];
 
-       if (xpid) {
-           if (xpid < 0)
-               xpid = -xpid;
-           pidcheck (pidwait (xpid, NOTOK));
-           xpid = 0;
-       }
-
        /* Get buffer ready to go */
        bp = query;
        buflen = sizeof(query);
 
        /* Now, construct query */
        if (writing) {
-           snprintf (bp, buflen, "Make cached, publically-accessible copy");
+           snprintf (bp, buflen, "Make cached, publicly-accessible copy");
        } else {
            struct stat st;
 
@@ -290,14 +251,14 @@ got_it:
        snprintf (bp, buflen, "\n    in file %s? ", buffer);
 
        /* Now, check answer */
-       if (!getanswer (query))
+       if (!read_yes_or_no_if_tty (query))
            status = NOTOK;
     }
 
     if (status == OK && writing) {
        if (*writing && strchr(buffer, '/'))
            make_intermediates (buffer);
-       unlink (buffer);
+       (void) m_unlink (buffer);
     }
 
     free (id);
@@ -312,14 +273,11 @@ find_cache_aux (int writing, char *directory, char *id,
     int        mask, usemap;
     char mapfile[BUFSIZ], mapname[BUFSIZ];
     FILE *fp;
+    int failed_to_lock = 0;
     static int partno, pid;
     static time_t clock = 0;
 
-#ifdef BSD42
-    usemap = strchr (id, '/') ? 1 : 0;
-#else
     usemap = 1;
-#endif
 
     if (debugsw)
        fprintf (stderr, "find_cache_aux %s usemap=%d\n", directory, usemap);
@@ -370,19 +328,22 @@ use_raw:
 
     make_intermediates (mapfile);
     mask = umask (writing == 2 ? 0077 : 0);
-    if (!(fp = lkfopen (mapfile, "a")) && errno == ENOENT) {
+    if (!(fp = lkfopendata (mapfile, "a", &failed_to_lock)) && errno == ENOENT) {
        int fd;
 
        if ((fd = creat (mapfile, 0666)) != NOTOK) {
            close (fd);
-           fp = lkfopen (mapfile, "a");
+           fp = lkfopendata (mapfile, "a", &failed_to_lock);
+            if (failed_to_lock) {
+               adios (mapfile, "failed to lock");
+            }
        }
     }
     umask (mask);
     if (!fp)
        return NOTOK;
     fprintf (fp, "%s: %s\n", mapname, id);
-    lkfclose (fp, mapfile);
+    lkfclosedata (fp, mapfile);
 
 done_map:
     if (*mapname == '/')
@@ -400,27 +361,31 @@ static int
 find_cache_aux2 (char *mapfile, char *id, char *mapname, int namelen)
 {
     int        state;
-    char buf[BUFSIZ], name[NAMESZ];
+    char buf[NMH_BUFSIZ], name[NAMESZ];
     FILE *fp;
+    m_getfld_state_t gstate;
+    int failed_to_lock = 0;
 
-    if (!(fp = lkfopen (mapfile, "r")))
+    if (!(fp = lkfopendata (mapfile, "r", &failed_to_lock)))
        return NOTOK;
 
-    for (state = FLD;;) {
+    gstate = m_getfld_state_init(fp);
+    for (;;) {
        int result;
        char *cp, *dp;
+       int bufsz = sizeof buf;
 
-       switch (state = m_getfld (state, name, buf, sizeof(buf), fp)) {
+       switch (state = m_getfld2(&gstate, name, buf, &bufsz)) {
            case FLD:
            case FLDPLUS:
-           case FLDEOF:
                strncpy (mapname, name, namelen);
                if (state != FLDPLUS)
                    cp = buf;
                else {
-                   cp = add (buf, NULL);
+                   cp = mh_xstrdup(buf);
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, buf, sizeof(buf), fp);
+                       bufsz = sizeof buf;
+                       state = m_getfld2(&gstate, name, buf, &bufsz);
                        cp = add (buf, cp);
                    }
                }
@@ -433,22 +398,20 @@ find_cache_aux2 (char *mapfile, char *id, char *mapname, int namelen)
                result = strcmp (id, dp);
                free (dp);
                if (result == 0) {
-                   lkfclose (fp, mapfile);
+                   lkfclosedata (fp, mapfile);
                    return OK;
                }
-               if (state != FLDEOF)
-                   continue;
-               /* else fall... */
+               continue;
 
            case BODY:
-           case BODYEOF:
            case FILEEOF:
            default:
                break;
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
-    lkfclose (fp, mapfile);
+    lkfclosedata (fp, mapfile);
     return NOTOK;
 }