]> diplodocus.org Git - nmh/blob - uip/annosbr.c
Bring these changes over from the branch.
[nmh] / 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 }