Added -clobber switch to mhstore(1) [Bug #11160].
[mmh] / docs / historical / mh-6.8.5 / zotnet / mf / uminc.c
1 /* uminc.c - uucp to mmdf inc */
2 #ifndef lint
3 static char Id[] = "@(#)$Id: uminc.c,v 1.2 1993/08/25 17:31:30 jromine Exp $";
4 #endif
5
6 #include "mf.h"
7 #include <stdio.h>
8 #include "../mts/mts.h"
9 #include <errno.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12
13
14 static int  mmdf = NOTOK;
15 static int  uucp = NOTOK;
16 static char mmdfbox[LINESIZ];
17 static char uucpbox[LINESIZ];
18
19
20 off_t    lseek ();
21
22 /* \f */
23
24 main (argc, argv)
25 int     argc;
26 char   *argv[];
27 {
28     int     fd,
29             tmp;
30     struct stat st1,
31                 st2;
32
33     mts_init (*argv);
34     sprintf (uucpbox, "%s/%s", UUCPDIR, UUCPFIL);
35     if (stat (uucpbox, &st1) == NOTOK || st1.st_size == 0L)
36         exit (0);
37     if ((uucp = lkopen (uucpbox, 0)) == NOTOK)
38         die ("unable to lock and open %s", uucpbox);
39     tmp = tmp_open (&fd);
40
41     switch (fd = uucp2mmdf (uucp, fd, FALSE)) {
42         case MFOK: 
43             break;
44
45         case MFPRM: 
46             die ("internal error while filtering UUCP mail");
47
48         case MFSIO: 
49             die ("no free file pointers -- you lose");
50
51         case MFERR: 
52             die ("i/o error while filtering UUCP mail");
53
54         case MFROM: 
55         case MFHDR: 
56         case MFTXT: 
57             fprintf (stderr, "UUCP mailbox in bad format, patched...\n");
58             break;
59     }
60
61     sprintf (mmdfbox, "%s/%s", MAILDIR, MAILFIL);
62     mmdf = mbx_open (mmdfbox);
63     mbx_copy (tmp, mmdf);
64     close (tmp);
65     lkclose (mmdf, mmdfbox), mmdf = NOTOK;
66
67     if (stat (uucpbox, &st2) != NOTOK && st1.st_mtime != st2.st_mtime)
68         fprintf (stderr, "UUCP mailbox has been updated... (%s)\n",
69                 "so it won't be removed");
70     else
71         if (unlink (uucpbox) == NOTOK)
72             if ((fd = creat (uucpbox, st1.st_mode & ~S_IFMT)) != NOTOK)
73                 close (fd);
74             else
75                 fprintf (stderr, "unable to remove or zero UUCP mailbox\n");
76     lkclose (uucp, uucpbox), uucp = NOTOK;
77
78     exit (0);
79 }
80
81 /* \f */
82
83 static int  mbx_open (file)
84 char   *file;
85 {
86     int     clear,
87             count,
88             fd;
89     extern int  errno;
90     struct stat stbuf;
91
92     for (clear = FALSE, count = 2; count > 0; count--)
93         if ((fd = lkopen (file, 6)) == NOTOK)
94             switch (errno) {
95                 case ENOENT: 
96                     mbx_create (file);
97                     clear++;
98                     break;
99
100                 case ETXTBSY: 
101                     sleep (5);
102                     break;
103
104                 default: 
105                     goto openerr;
106             }
107         else {
108             if (fstat (fd, &stbuf) == NOTOK)
109                 die ("unable to stat MMDF mailbox '%s'", file);
110             clear = stbuf.st_size == 0L;
111             break;
112         }
113
114     if (fd == NOTOK) {
115 openerr: 
116         if (errno == ETXTBSY)
117             die ("your MMDF mailbox '%s' is busy", file);
118         else
119             die ("unable to open MMDF mailbox '%s'", file);
120     }
121     if (!clear)
122         mbx_chk (fd, file);
123
124     return fd;
125 }
126
127 /* \f */
128
129 static  mbx_create (file)
130 char   *file;
131 {
132     int     fd;
133
134     if ((fd = creat (file, MBXMODE)) == NOTOK)
135         die ("unable to create MMDF mailbox '%s'", file);
136
137     close (fd);
138 }
139
140
141 static  mbx_chk (fd, file)
142 int     fd;
143 char   *file;
144 {
145     int     count;
146     char    ldelim[20];
147
148     count = strlen (mmdlm2);
149
150     if (lseek (fd, (off_t) - count, 2) == (off_t) NOTOK
151             || read (fd, ldelim, count) != count)
152         die ("error reading MMDF mailbox '%s'", file);
153     ldelim[count] = NULL;
154
155     if (strcmp (ldelim, mmdlm2)) {
156         fprintf (stderr,
157                 "MMDF mailbox '%s' has bad delimiter, patching...\n",
158                 file);
159         if (write (fd, mmdlm2, count) != count)
160             die ("error writing MMDF mailbox '%s'", file);
161     }
162 }
163
164 /* \f */
165
166 static  mbx_copy (in, out)
167 int     in,
168         out;
169 {
170     int     i;
171     char    buffer[BUFSIZ];
172
173     lseek (in, (off_t)0, 0);
174
175     while ((i = read (in, buffer, sizeof buffer)) > 0)
176         if (write (out, buffer, i) != i)
177             die ("error writing MMDF mailbox");
178     if (i < 0)
179         die ("error reading temporary file");
180
181     close (in);
182     close (out);
183 }
184
185 /* \f */
186
187 static int  tmp_open (mbx_fd)
188 int    *mbx_fd;
189 {
190     int     fd;
191     char    tmpfil[LINESIZ];
192
193     strcpy (tmpfil, "/tmp/umincXXXXXX");
194     unlink (mktemp (tmpfil));
195     if ((fd = creat (tmpfil, TMPMODE)) == NOTOK)
196         die ("unable to create temporary file '%s'", tmpfil);
197     close (fd);
198
199     if ((fd = open (tmpfil, 2)) == NOTOK)
200         die ("unable to create temporary file '%s'", tmpfil);
201     unlink (tmpfil);
202
203     if ((*mbx_fd = dup (fd)) == NOTOK)
204         die ("unable to duplicate fd for temporary file '%s'", tmpfil);
205
206     return fd;
207 }
208
209 /* \f */
210
211 static  die (fmt, a, b, c, d)
212 char   *fmt,
213        *a,
214        *b,
215        *c,
216        *d;
217 {
218     lkclose (mmdf, mmdfbox), mmdf = NOTOK;
219     lkclose (uucp, uucpbox), uucp = NOTOK;
220
221     fflush (stdout);
222     fprintf (stderr, fmt, a, b, c, d);
223     putc ('\n', stderr);
224
225     exit (1);
226 }