]> diplodocus.org Git - nmh/blobdiff - sbr/seq_save.c
mhlsbr.c: Don't strchr(3) non-string NUL-less buffer.
[nmh] / sbr / seq_save.c
index 3c53e4bc1914678638db8e545acffe281981af9b..ac7b53e96f7b5b96b9577f1d4efdb6b2e6d30223 100644 (file)
@@ -1,6 +1,4 @@
-
-/*
- * seq_save.c -- 1) synchronize sequences
+/* seq_save.c -- 1) synchronize sequences
  *            -- 2) save public sequences
  *
  * This code is Copyright (c) 2002, by the authors of nmh.  See the
@@ -10,6 +8,8 @@
 
 #include <h/mh.h>
 #include <h/signals.h>
+#include "lock_file.h"
+#include "m_mktemp.h"
 
 
 /*
 void
 seq_save (struct msgs *mp)
 {
-    int i;
+    size_t i;
     char flags, *cp, attr[BUFSIZ], seqfile[PATH_MAX];
     FILE *fp;
     sigset_t set, oset;
 
     /* check if sequence information has changed */
     if (!(mp->msgflags & SEQMOD)) {
-       if (mp->seqhandle)
+       if (mp->seqhandle) {
            lkfclosedata (mp->seqhandle, mp->seqname);
+           mp->seqhandle = NULL;
+           free(mp->seqname);
+           mp->seqname = NULL;
+       }
        return;
     }
     mp->msgflags &= ~SEQMOD;
@@ -50,11 +54,12 @@ seq_save (struct msgs *mp)
     else
        snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq);
 
-    for (i = 0; mp->msgattrs[i]; i++) {
-       snprintf (attr, sizeof(attr), "atr-%s-%s", mp->msgattrs[i], mp->foldpath);
+    for (i = 0; i < svector_size (mp->msgattrs); i++) {
+       snprintf (attr, sizeof(attr), "atr-%s-%s",
+                 svector_at (mp->msgattrs, i), mp->foldpath);
 
        /* get space separated list of sequence ranges */
-       if (!(cp = seq_list(mp, mp->msgattrs[i]))) {
+       if (!(cp = seq_list(mp, svector_at (mp->msgattrs, i)))) {
            context_del (attr);                 /* delete sequence from context */
            continue;
        }
@@ -72,6 +77,8 @@ priv:
            context_del (attr);                 /* delete sequence from context */
 
            if (!fp) {
+               int failed_to_lock = 0;
+
                /*
                 * Attempt to open file for public sequences.
                 * If that fails (probably because folder is
@@ -84,11 +91,19 @@ priv:
                    free(mp->seqname);
                    mp->seqname = NULL;
                    rewind(fp);
-                   ftruncate(fileno(fp), 0);
-               } else if ((fp = lkfopendata (seqfile, "w")) == NULL
-                       && (unlink (seqfile) == -1 ||
-                           (fp = lkfopendata (seqfile, "w")) == NULL)) {
-                   admonish (attr, "unable to write");
+                   if (ftruncate(fileno(fp), 0) < 0) {
+                       advise ("sequence file", "ftruncate");
+                   }
+               } else if ((fp = lkfopendata (seqfile, "w", &failed_to_lock))
+                          == NULL
+                       && (m_unlink (seqfile) == -1 ||
+                           (fp = lkfopendata (seqfile, "w", &failed_to_lock))
+                           == NULL)) {
+                   if (failed_to_lock) {
+                       admonish (attr, "unable to lock");
+                   } else {
+                       admonish (attr, "unable to write");
+                   }
                    goto priv;
                }
 
@@ -100,7 +115,7 @@ priv:
                sigaddset(&set, SIGTERM);
                sigprocmask (SIG_BLOCK, &set, &oset);
            }
-           fprintf (fp, "%s: %s\n", mp->msgattrs[i], cp);
+           fprintf (fp, "%s: %s\n", svector_at (mp->msgattrs, i), cp);
        }
     }
 
@@ -113,7 +128,7 @@ priv:
         * public sequences, then remove that file.
         */
        if (!is_readonly(mp))
-           unlink (seqfile);
+           (void) m_unlink (seqfile);
     }
 
     /*