-
-/*
- * annosbr.c -- prepend annotation to messages
- *
- * $Id$
+/* annosbr.c -- prepend annotation to messages
*
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
#include <h/mh.h>
#include <h/tws.h>
#include <h/utils.h>
+#include "sbr/lock_file.h"
+#include "sbr/m_mktemp.h"
#include <fcntl.h>
-#include <errno.h>
#include <utime.h>
/*
* static prototypes
*/
-static int annosbr (int, char *, char *, char *, int, int, int, int);
+static int annosbr (int, char *, char *, char *, bool, bool, int, bool);
/*
* This "local" global and the annopreserve() function are a hack that allows additional
static int preserve_actime_and_modtime = 0; /* set to preserve access and modification times on annotated message */
int
-annotate (char *file, char *comp, char *text, int inplace, int datesw, int delete, int append)
+annotate (char *file, char *comp, char *text, bool inplace, bool datesw, int delete, bool append)
{
int i, fd;
struct utimbuf b;
struct stat s;
+ int failed_to_lock = 0;
/* open and lock the file to be annotated */
- if ((fd = lkopen (file, O_RDWR, 0)) == NOTOK) {
+ if ((fd = lkopendata (file, O_RDWR, 0, &failed_to_lock)) == NOTOK) {
switch (errno) {
case ENOENT:
break;
default:
- admonish (file, "unable to lock and open");
+ if (failed_to_lock) {
+ admonish (file, "unable to lock");
+ } else {
+ admonish (file, "unable to open");
+ }
break;
}
return 1;
}
if (stat(file, &s) == -1) {
- advise("can't get access and modification times for %s", file);
+ inform("can't get access and modification times for %s", file);
preserve_actime_and_modtime = 0;
}
i = annosbr (fd, file, comp, text, inplace, datesw, delete, append);
if (preserve_actime_and_modtime && utime(file, &b) == -1)
- advise("can't set access and modification times for %s", file);
+ inform("can't set access and modification times for %s", file);
- lkclose (fd, file);
+ lkclosedata (fd, file);
return i;
}
/*
* Produce a listing of all header fields (annotations) whose field name matches
- * comp. Number the listing if number is set. Treate the field bodies as path
+ * comp. Number the listing if number is set. Treat the field bodies as path
* names and just output the last component unless text is non-NULL. We don't
* care what text is set to.
*/
int n; /* number of bytes written */
char *sp; /* another miscellaneous character pointer */
- if ((fp = fopen(file, "r")) == (FILE *)0)
+ if ((fp = fopen(file, "r")) == NULL)
adios(file, "unable to open");
/*
for (n = 0, cp = field; (c = getc(fp)) != EOF; *cp++ = c) {
if (c == '\n' && (c = getc(fp)) != ' ' && c != '\t') {
(void)ungetc(c, fp);
- c = '\n';
break;
}
if (number)
(void)printf("%d\t", ++count);
- if (text == (char *)0 && (sp = strrchr(cp, '/')) != (char *)0)
+ if (text == NULL && (sp = strrchr(cp, '/')))
cp = sp + 1;
- (void)printf("%s\n", cp);
+ puts(cp);
}
} while (*field != '\0' && *field != '-');
free(field);
(void)fclose(fp);
-
- return;
}
/*
annopreserve(int preserve)
{
preserve_actime_and_modtime = preserve;
- return;
}
static int
-annosbr (int fd, char *file, char *comp, char *text, int inplace, int datesw, int delete, int append)
+annosbr (int fd, char *file, char *comp, char *text, bool inplace, bool datesw, int delete, bool append)
{
int mode, tmpfd;
char *cp, *sp;
FILE *tmp;
int c; /* current character */
int count; /* header field (annotation) counter */
- char *field; /* buffer for header field */
- int field_size; /* size of field buffer */
- FILE *fp; /* file pointer made from locked file descriptor */
+ char *field = NULL; /* buffer for header field */
+ int field_size = 0; /* size of field buffer */
+ FILE *fp = NULL; /* file pointer made from locked file descriptor */
int length; /* length of field name */
int n; /* number of bytes written */
- mode = fstat (fd, &st) != NOTOK ? (st.st_mode & 0777) : m_gmprot ();
-
- strncpy (tmpfil, m_scratch (file, "annotate"), sizeof(tmpfil));
+ mode = fstat (fd, &st) != NOTOK ? (int) (st.st_mode & 0777) : m_gmprot ();
- if ((tmp = fopen (tmpfil, "w")) == NULL) {
- admonish (tmpfil, "unable to create");
- return 1;
+ if ((cp = m_mktemp2(file, "annotate", NULL, &tmp)) == NULL) {
+ adios(NULL, "unable to create temporary file in %s", get_temp_dir());
}
+ strncpy (tmpfil, cp, sizeof(tmpfil));
chmod (tmpfil, mode);
/*
* as they're read in. This buffer is grown as needed later.
*/
- if (delete >= -1 || append != 0) {
- if ((fp = fdopen(fd, "r")) == (FILE *)0)
+ if (delete >= -1 || append) {
+ if ((fp = fdopen(fd, "r")) == NULL)
adios(NULL, "unable to fdopen file.");
field = (char *)mh_xmalloc(field_size = 256);
if (strncasecmp(field, comp, length) == 0 && field[length] == ':') {
if (delete == 0) {
- if (text == (char *)0)
+ if (text == NULL)
break;
for (cp = field + length + 1; *cp == ' ' || *cp == '\t'; cp++)
break;
}
else {
- if ((sp = strrchr(cp, '/')) != (char *)0)
+ if ((sp = strrchr(cp, '/')) != NULL)
cp = sp + 1;
if (strcmp(cp, text) == 0)
while (*cp && *cp++ != '\n')
continue;
if (cp - sp)
- fprintf (tmp, "%s: %*.*s", comp, cp - sp, cp - sp, sp);
+ fprintf (tmp, "%s: %*.*s", comp, (int)(cp - sp), (int)(cp - sp), sp);
} while (*cp);
if (cp[-1] != '\n' && cp != text)
putc ('\n', tmp);
* copying routine uses the descriptor, not the pointer.
*/
- if (append || delete >= -1) {
- if (lseek(fd, (off_t)ftell(fp), SEEK_SET) == (off_t)-1)
- adios(NULL, "can't seek.");
- }
+ if (fp && lseek(fd, (off_t)ftell(fp), SEEK_SET) == (off_t)-1)
+ adios(NULL, "can't seek.");
cpydata (fd, fileno (tmp), file, tmpfil);
fclose (tmp);
if ((tmpfd = open (tmpfil, O_RDONLY)) == NOTOK)
adios (tmpfil, "unable to open for re-reading");
- lseek (fd, (off_t) 0, SEEK_SET);
+ lseek(fd, 0, SEEK_SET);
/*
* We're making the file shorter if we're deleting a header field
cpydata (tmpfd, fd, tmpfil, file);
close (tmpfd);
- unlink (tmpfil);
+ (void) m_unlink (tmpfil);
} else {
strncpy (buffer, m_backup (file), sizeof(buffer));
if (rename (file, buffer) == NOTOK) {
switch (errno) {
case ENOENT: /* unlinked early - no annotations */
- unlink (tmpfil);
+ (void) m_unlink (tmpfil);
break;
default:
* lkclose() fail, but that failure is ignored so it's not a problem.
*/
- if (delete >= -1)
+ if (fp)
(void)fclose(fp);
return 0;