Add/update copyright notice in all source code files.
[mmh] / uip / annosbr.c
1
2 /*
3  * annosbr.c -- prepend annotation to messages
4  *
5  * $Id$
6  *
7  * This code is Copyright (c) 2002, by the authors of nmh.  See the
8  * COPYRIGHT file in the root directory of the nmh distribution for
9  * complete copyright information.
10  */
11
12 #include <h/mh.h>
13 #include <h/tws.h>
14 #include <fcntl.h>
15 #include <errno.h>
16
17 extern int  errno;
18
19 /*
20  * static prototypes
21  */
22 static int annosbr (int, char *, char *, char *, int, int);
23
24
25 int
26 annotate (char *file, char *comp, char *text, int inplace, int datesw)
27 {
28     int i, fd;
29
30     /* open and lock the file to be annotated */
31     if ((fd = lkopen (file, O_RDWR, 0)) == NOTOK) {
32         switch (errno) {
33             case ENOENT: 
34                 break;
35
36             default: 
37                 admonish (file, "unable to lock and open");
38                 break;
39         }
40         return 1;
41     }
42
43     i = annosbr (fd, file, comp, text, inplace, datesw);
44     lkclose (fd, file);
45     return i;
46 }
47
48
49 static int
50 annosbr (int fd, char *file, char *comp, char *text, int inplace, int datesw)
51 {
52     int mode, tmpfd;
53     char *cp, *sp;
54     char buffer[BUFSIZ], tmpfil[BUFSIZ];
55     struct stat st;
56     FILE *tmp;
57
58     mode = fstat (fd, &st) != NOTOK ? (st.st_mode & 0777) : m_gmprot ();
59
60     strncpy (tmpfil, m_scratch (file, "annotate"), sizeof(tmpfil));
61
62     if ((tmp = fopen (tmpfil, "w")) == NULL) {
63         admonish (tmpfil, "unable to create");
64         return 1;
65     }
66     chmod (tmpfil, mode);
67
68     if (datesw)
69         fprintf (tmp, "%s: %s\n", comp, dtimenow (0));
70     if ((cp = text)) {
71         do {
72             while (*cp == ' ' || *cp == '\t')
73                 cp++;
74             sp = cp;
75             while (*cp && *cp++ != '\n')
76                 continue;
77             if (cp - sp)
78                 fprintf (tmp, "%s: %*.*s", comp, cp - sp, cp - sp, sp);
79         } while (*cp);
80         if (cp[-1] != '\n' && cp != text)
81             putc ('\n', tmp);
82     }
83     fflush (tmp);
84     cpydata (fd, fileno (tmp), file, tmpfil);
85     fclose (tmp);
86
87     if (inplace) {
88         if ((tmpfd = open (tmpfil, O_RDONLY)) == NOTOK)
89             adios (tmpfil, "unable to open for re-reading");
90         lseek (fd, (off_t) 0, SEEK_SET);
91         cpydata (tmpfd, fd, tmpfil, file);
92         close (tmpfd);
93         unlink (tmpfil);
94     } else {
95         strncpy (buffer, m_backup (file), sizeof(buffer));
96         if (rename (file, buffer) == NOTOK) {
97             switch (errno) {
98                 case ENOENT:    /* unlinked early - no annotations */
99                     unlink (tmpfil);
100                     break;
101
102                 default:
103                     admonish (buffer, "unable to rename %s to", file);
104                     break;
105             }
106             return 1;
107         }
108         if (rename (tmpfil, file) == NOTOK) {
109             admonish (file, "unable to rename %s to", tmpfil);
110             return 1;
111         }
112     }
113
114     return 0;
115 }