Updated docs/README-ATTACHMENTS, mainly to reflect that no setup is
[mmh] / docs / historical / mh-6.8.5 / uip / RCS / burst.c,v
1 head    1.7;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.7
9 date    92.12.15.00.20.22;      author jromine; state Exp;
10 branches;
11 next    1.6;
12
13 1.6
14 date    92.11.04.00.39.40;      author jromine; state Exp;
15 branches;
16 next    1.5;
17
18 1.5
19 date    92.10.29.03.49.31;      author jromine; state Exp;
20 branches;
21 next    1.4;
22
23 1.4
24 date    92.01.31.22.07.23;      author jromine; state Exp;
25 branches;
26 next    1.3;
27
28 1.3
29 date    90.04.05.15.00.42;      author sources; state Exp;
30 branches;
31 next    1.2;
32
33 1.2
34 date    90.02.06.13.16.51;      author sources; state Exp;
35 branches;
36 next    1.1;
37
38 1.1
39 date    90.02.06.13.16.32;      author sources; state Exp;
40 branches;
41 next    ;
42
43
44 desc
45 @@
46
47
48 1.7
49 log
50 @endif sugar
51 @
52 text
53 @/* burst.c - explode digests into individual messages */
54 #ifndef lint
55 static char ident[] = "@@(#)$Id: burst.c,v 1.6 1992/11/04 00:39:40 jromine Exp jromine $";
56 #endif  /* lint */
57
58 #include "../h/mh.h"
59 #include <stdio.h>
60 #include <sys/types.h>
61 #include <sys/stat.h>
62 #ifdef LOCALE
63 #include        <locale.h>
64 #endif
65
66 static  cpybrst(), burst();
67 /* \f */
68
69 static struct swit switches[] = {
70 #define INPLSW  0
71     "inplace", 0,
72 #define NINPLSW 1
73     "noinplace", 0,
74
75 #define QIETSW  2
76     "quiet", 0,
77 #define NQIETSW 3
78     "noquiet", 0,
79
80 #define VERBSW  4
81     "verbose", 0,
82 #define NVERBSW 5
83     "noverbose", 0,
84
85 #define HELPSW  6
86     "help", 4,
87
88     NULL, 0
89 };
90
91 /* \f */
92
93 static char delim3[] = "-------";
94
95
96 static struct msgs *mp;
97
98 struct smsg {
99     long    s_start;
100     long    s_stop;
101 };
102
103 /* \f */
104
105 /* ARGSUSED */
106
107 main (argc, argv)
108 int     argc;
109 char  **argv;
110 {
111     int     inplace = 0,
112             quietsw = 0,
113             verbosw = 0,
114             msgp = 0,
115             hi,
116             msgnum;
117     char   *cp,
118            *maildir,
119            *folder = NULL,
120             buf[100],
121           **ap,
122           **argp,
123            *arguments[MAXARGS],
124            *msgs[MAXARGS];
125     struct smsg *smsgs;
126
127 #ifdef LOCALE
128         setlocale(LC_ALL, "");
129 #endif
130     invo_name = r1bindex (argv[0], '/');
131     if ((cp = m_find (invo_name)) != NULL) {
132         ap = brkstring (cp = getcpy (cp), " ", "\n");
133         ap = copyip (ap, arguments);
134     }
135     else
136         ap = arguments;
137     (void) copyip (argv + 1, ap);
138     argp = arguments;
139
140 /* \f */
141
142     while (cp = *argp++) {
143         if (*cp == '-')
144             switch (smatch (++cp, switches)) {
145                 case AMBIGSW: 
146                     ambigsw (cp, switches);
147                     done (1);
148                 case UNKWNSW: 
149                     adios (NULLCP, "-%s unknown\n", cp);
150                 case HELPSW: 
151                     (void) sprintf (buf, "%s [+folder] [msgs] [switches]",
152                             invo_name);
153                     help (buf, switches);
154                     done (1);
155
156                 case INPLSW: 
157                     inplace++;
158                     continue;
159                 case NINPLSW: 
160                     inplace = 0;
161                     continue;
162
163                 case QIETSW: 
164                     quietsw++;
165                     continue;
166                 case NQIETSW: 
167                     quietsw = 0;
168                     continue;
169
170                 case VERBSW: 
171                     verbosw++;
172                     continue;
173                 case NVERBSW: 
174                     verbosw = 0;
175                     continue;
176             }
177         if (*cp == '+' || *cp == '@@') {
178             if (folder)
179                 adios (NULLCP, "only one folder at a time!");
180             else
181                 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
182         }
183         else
184             msgs[msgp++] = cp;
185     }
186
187 /* \f */
188
189     if (!m_find ("path"))
190         free (path ("./", TFOLDER));
191     if (!msgp)
192         msgs[msgp++] = "cur";
193     if (!folder)
194         folder = m_getfolder ();
195     maildir = m_maildir (folder);
196
197     if (chdir (maildir) == NOTOK)
198         adios (maildir, "unable to change directory to");
199     if (!(mp = m_gmsg (folder)))
200         adios (NULLCP, "unable to read folder %s", folder);
201     if (mp -> hghmsg == 0)
202         adios (NULLCP, "no messages in %s", folder);
203
204     for (msgnum = 0; msgnum < msgp; msgnum++)
205         if (!m_convert (mp, msgs[msgnum]))
206             done (1);
207     m_setseq (mp);
208
209     smsgs = (struct smsg   *)
210                 calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs);
211     if (smsgs == NULL)
212         adios (NULLCP, "unable to allocate burst storage");
213
214     hi = mp -> hghmsg + 1;
215     for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
216         if (mp -> msgstats[msgnum] & SELECTED)
217             burst (smsgs, msgnum, inplace, quietsw, verbosw);
218
219     free ((char *) smsgs);
220
221     m_replace (pfolder, folder);
222     if (inplace) {
223         if (mp -> lowsel != mp -> curmsg)
224             m_setcur (mp, mp -> lowsel);
225     }
226     else
227         if (hi <= mp -> hghmsg)
228             m_setcur (mp, hi);
229     m_sync (mp);
230     m_update ();
231
232     done (0);
233 }
234
235 /* \f */
236
237 static  burst (smsgs, msgnum, inplace, quietsw, verbosw)
238 register struct smsg *smsgs;
239 int     msgnum,
240         inplace,
241         quietsw,
242         verbosw;
243 {
244     int     i,
245             j,
246             ld3,
247             wasdlm,
248             mode,
249             msgp;
250     register long   pos;
251     register char   c,
252                     cc,
253                    *msgnam;
254     char    buffer[BUFSIZ],
255             f1[BUFSIZ],
256             f2[BUFSIZ],
257             f3[BUFSIZ];
258     struct stat st;
259     register    FILE *in,
260                      *out;
261
262     ld3 = strlen (delim3);
263
264     if ((in = fopen (msgnam = m_name (msgnum), "r")) == NULL)
265         adios (msgnam, "unable to read message");
266
267     mode = fstat (fileno (in), &st) != NOTOK ? (st.st_mode & 0777)
268         : m_gmprot ();
269     for (msgp = 0, pos = 0L; msgp <= MAXFOLDER;) {
270         while (fgets (buffer, sizeof buffer, in) != NULL
271                 && buffer[0] == '\n')
272             pos += (long) strlen (buffer);
273         if (feof (in))
274             break;
275         (void) fseek (in, pos, 0);
276         smsgs[msgp].s_start = pos;
277
278         for (c = 0;
279                 fgets (buffer, sizeof buffer, in) != NULL;
280                 c = buffer[0])
281             if (strncmp (buffer, delim3, ld3) == 0
282                     && (msgp == 1 || c == '\n')
283                     && ((cc = peekc (in)) == '\n' || cc == EOF))
284                 break;
285             else
286                 pos += (long) strlen (buffer);
287
288         wasdlm = strncmp (buffer, delim3, ld3) == 0;
289         if (smsgs[msgp].s_start != pos)
290             smsgs[msgp++].s_stop = (c == '\n' && wasdlm) ? pos - 1 : pos;
291         if (feof (in)) {
292 #ifdef  notdef
293             if (wasdlm) {
294                 smsgs[msgp - 1].s_stop -= ((long) strlen (buffer) + 1);
295                 msgp++;         /* fake "End of XXX Digest" */
296             }
297 #endif
298             break;
299         }
300         pos += (long) strlen (buffer);
301     }
302
303 /* \f */
304
305     switch (msgp--) {           /* toss "End of XXX Digest" */
306         case 0: 
307             adios (NULLCP, "burst() botch -- you lose big");
308
309         case 1: 
310             if (!quietsw)
311                 admonish (NULLCP, "message %d not in digest format", msgnum);
312             (void) fclose (in);
313             return;
314
315         default: 
316             if (verbosw)
317                 printf ("%d message%s exploded from digest %d\n",
318                         msgp, msgp != 1 ? "s" : "", msgnum);
319             break;
320     }
321     /* msgp now contains the number of new msgs to be created */
322
323     if ((mp = m_remsg (mp, 0, mp -> hghmsg + msgp)) == NULL)
324         adios (NULLCP, "unable to allocate folder storage");
325
326 /* \f */
327
328     j = mp -> hghmsg;           /* old value */
329     mp -> hghmsg += msgp;
330     mp -> nummsg += msgp;
331     if (mp -> hghsel > msgnum)
332         mp -> hghsel += msgp;
333
334     if (inplace)
335         for (i = mp -> hghmsg; j > msgnum; i--, j--) {
336             (void) strcpy (f1, m_name (i));
337             (void) strcpy (f2, m_name (j));
338             if (mp -> msgstats[j] & EXISTS) {
339                 if (verbosw)
340                     printf ("message %d becomes message %d\n", j, i);
341
342                 if (rename (f2, f1) == NOTOK)
343                     admonish (f1, "unable to rename %s to", f2);
344                 mp -> msgstats[i] = mp -> msgstats[j];
345                 mp -> msgstats[j] = 0;
346                 mp -> msgflags |= SEQMOD;
347             }
348         }
349     
350     mp -> msgstats[msgnum] &= ~SELECTED;
351     i = inplace ? msgnum + msgp : mp -> hghmsg; /* new hghmsg is hghmsg+msgp */
352     for (j = msgp; j >= (inplace ? 0 : 1); i--, j--) {
353         (void) strcpy (f1, m_name (i));
354         (void) strcpy (f2, m_scratch ("", invo_name));
355         if (verbosw && i != msgnum)
356             printf ("message %d of digest %d becomes message %d\n",
357                     j, msgnum, i);
358
359         if ((out = fopen (f2, "w")) == NULL)
360             adios (f2, "unable to write message");
361         (void) chmod (f2, mode);
362         (void) fseek (in, pos = smsgs[j].s_start, 0);
363         cpybrst (in, out, msgnam, f2,
364                 (int) (smsgs[j].s_stop - smsgs[j].s_start));
365         (void) fclose (out);
366
367         if (i == msgnum) {
368             (void) strcpy (f3, m_backup (f1));
369             if (rename (f1, f3) == NOTOK)
370                 admonish (f3, "unable to rename %s to", f1);
371         }
372         if (rename (f2, f1) == NOTOK)
373             admonish (f1, "unable to rename %s to", f2);
374         mp -> msgstats[i] = mp -> msgstats[msgnum];
375         mp -> msgflags |= SEQMOD;
376     }
377
378     (void) fclose (in);
379 }
380
381
382 /* \f */
383
384 #define S1      0
385 #define S2      1
386 #define S3      2
387
388 static cpybrst (in, out, ifile, ofile, len)
389 register FILE   *in,
390                 *out;
391 register char   *ifile,
392                 *ofile;
393 register int    len;
394 {
395     register int    c,
396                     state;
397
398     for (state = S1; (c = fgetc (in)) != EOF && len > 0; len--) {
399         if (c == 0)
400             continue;
401         switch (state) {
402             case S1: 
403                 switch (c) {
404                     case '-': 
405                         state = S3;
406                         break;
407
408                     default: 
409                         state = S2;
410                     case '\n': 
411                         (void) fputc (c, out);
412                         break;
413                 }
414                 break;
415
416             case S2: 
417                 switch (c) {
418                     case '\n': 
419                         state = S1;
420                     default: 
421                         (void) fputc (c, out);
422                         break;
423                 }
424                 break;
425
426             case S3: 
427                 switch (c) {
428                     case ' ': 
429                         state = S2;
430                         break;
431
432                     default: 
433                         state = c == '\n' ? S1 : S2;
434                         (void) fputc ('-', out);
435                         (void) fputc (c, out);
436                         break;
437                 }
438                 break;
439         }
440     }
441
442     if (ferror (in) && !feof (in))
443         adios (ifile, "error reading");
444     if (ferror (out))
445         adios (ofile, "error writing");
446 }
447 @
448
449
450 1.6
451 log
452 @LOCALE
453 @
454 text
455 @d3 2
456 a4 2
457 static char ident[] = "@@(#)$Id: burst.c,v 1.5 1992/10/29 03:49:31 jromine Exp jromine $";
458 #endif  lint
459 @
460
461
462 1.5
463 log
464 @fix burst -- previously it was losing the last message(!)
465 @
466 text
467 @d3 1
468 a3 1
469 static char ident[] = "@@(#)$Id: burst.c,v 1.4 1992/01/31 22:07:23 jromine Exp jromine $";
470 d10 3
471 d75 3
472 @
473
474
475 1.4
476 log
477 @kerberos
478 @
479 text
480 @d3 1
481 a3 1
482 static char ident[] = "@@(#)$Id: burst.c,v 1.3 1990/04/05 15:00:42 sources Exp jromine $";
483 d194 1
484 d211 1
485 a211 1
486     for (msgp = 1, pos = 0L; msgp <= MAXFOLDER;) {
487 d224 2
488 a225 2
489                     && peekc (in) == '\n'
490                     && (msgp == 1 || c == '\n'))
491 d232 1
492 a232 1
493             smsgs[msgp++].s_stop = c == '\n' && wasdlm ? pos - 1 : pos;
494 d234 1
495 d239 1
496 d247 1
497 a247 1
498     switch (--msgp) {           /* toss "End of XXX Digest" */
499 d260 1
500 a260 3
501                         msgp - 1, msgp - 1 != 1 ? "s" : "", msgnum);
502             if (msgp == 2)      /* XXX */
503                 msgp++;
504 d263 1
505 d270 3
506 a272 4
507     msgp--;
508     j = mp -> hghmsg;
509     mp -> hghmsg += msgp - 1;
510     mp -> nummsg += msgp - 1;
511 d274 1
512 a274 1
513         mp -> hghsel += msgp - 1;
514 d276 1
515 a276 1
516     if (inplace && msgp > 1)
517 d293 2
518 a294 2
519     i = inplace ? msgnum + msgp - 1 : mp -> hghmsg;
520     for (j = msgp; j >= (inplace ? 1 : 2); i--, j--) {
521 @
522
523
524 1.3
525 log
526 @add ID
527 @
528 text
529 @d3 1
530 a3 1
531 static char ident[] = "@@(#)$Id:$";
532 d33 1
533 a33 1
534     NULL, NULL
535 d219 1
536 a219 1
537         for (c = NULL;
538 d286 1
539 a286 1
540                 mp -> msgstats[j] = NULL;
541 d340 1
542 a340 1
543         if (c == NULL)
544 @
545
546
547 1.2
548 log
549 @ANSI Compilance
550 @
551 text
552 @d2 3
553 @
554
555
556 1.1
557 log
558 @Initial revision
559 @
560 text
561 @d8 1
562 @