42
47
#include <sys/wait.h>
44
49
#include "extern.h"
47
55
* Mail -- a mail program
49
57
* More user commands.
51
static int igcomp __P((const void *, const void *));
59
static int igcomp __P((const void *, const void *));
60
static int save1 __P((char [], int, char *, struct ignoretab *, int, int));
61
static char *snarf __P((char [], int *, int));
62
static int delm __P((int []));
64
static void clob1 __P((int));
66
static int ignore1 __P((char *[], struct ignoretab *, char *));
67
static int igshow __P((struct ignoretab *, char *));
68
static void unignore_one __P((const char *, struct ignoretab *));
69
static int unignore1 __P((char *[], struct ignoretab *, char *));
54
72
* If any arguments were given, go to the next applicable argument
156
return save1(str, 0, "copy", saveignore, CONV_NONE);
187
return save1(str, 0, "copy", saveignore, CONV_NONE, 0);
196
return save1(str, 0, "copy", saveignore, CONV_NONE, 1);
160
200
* Save/copy the indicated messages at the end of the passed file name.
161
201
* If mark is true, mark the message "saved."
164
save1(str, mark, cmd, ignore, convert)
204
save1(str, mark, cmd, ignore, convert, sender_record)
171
211
struct message *mp;
212
char *file = NULL, *disp;
217
off_t mstats[2], tstats[2];
178
220
msgvec = (int *)salloc((msgcount + 2) * sizeof *msgvec);
179
if ((file = snarf(str, &f)) == NULL)
222
for (cp = str; *cp && blankchar(*cp & 0377); cp++);
225
if ((file = snarf(str, &f, convert != CONV_TOFILE)) == NULL)
182
229
*msgvec = first(0, MMNORM);
183
230
if (*msgvec == 0) {
184
printf("No messages to %s.\n", cmd);
231
printf(catgets(catd, CATSET, 23,
232
"No messages to %s.\n"), cmd);
189
237
if (f && getmsglist(str, msgvec, 0) < 0)
240
if ((cp = nameof(&message[*msgvec - 1], 0)) == NULL) {
241
printf(catgets(catd, CATSET, 24,
242
"Cannot determine message sender to %s.\n"),
246
for (cq = cp; *cq && *cq != '@'; cq++);
248
if (value("outfolder")) {
249
file = salloc(strlen(cp) + 2);
251
strcpy(&file[1], cp);
191
255
if ((file = expand(file)) == NULL)
193
257
if (access(file, 0) >= 0) {
259
disp = catgets(catd, CATSET, 25, "[Appended]");
200
if ((obuf = Fopen(file, "a")) == (FILE *)NULL) {
205
/* always insert a newline since some other mail readers
206
* (notably Netscape 4.7) use this folder convention
262
disp = catgets(catd, CATSET, 26, "[New file]");
264
if ((obuf = Fopen(file, "a+")) == NULL) {
265
if ((obuf = Fopen(file, "wx")) == NULL) {
270
if (!newfile && fseek(obuf, -2L, SEEK_END) == 0) {
274
switch (fread(buf, sizeof *buf, 2, obuf)) {
276
if (buf[1] != '\n') {
299
tstats[0] = tstats[1] = 0;
210
300
for (ip = msgvec; *ip && ip-msgvec < msgcount; ip++) {
211
301
mp = &message[*ip - 1];
213
if (send_message(mp, obuf, ignore, NULL, convert) < 0) {
302
if (send_message(mp, obuf, ignore, NULL, convert, mstats) < 0) {
219
309
mp->m_flag |= MSAVED;
310
tstats[0] += mstats[0];
311
tstats[1] += mstats[1];
222
314
if (ferror(obuf))
225
printf("%s %s\n", file, disp);
317
printf("\"%s\" %s ", file, disp);
319
printf("%lu", (long)tstats[0]);
321
printf(catgets(catd, CATSET, 27, "binary"));
322
printf("/%lu\n", (long)tstats[1]);
230
327
* Write the indicated messages at the end of the passed
231
328
* file name, minus header and trailing blank line.
232
* NEW: This is the MIME save function.
329
* This is the MIME save function.
240
return save1(str, 0, "write", allignore, CONV_TOFILE);
337
return save1(str, 0, "write", allignore, CONV_TOFILE, 0);
244
341
* Snarf the file from the end of the command line and
245
342
* return a pointer to it. If there is no file attached,
246
* just return NULL. Put a null in front of the file
343
* return the mbox file. Put a null in front of the file
247
344
* name so that the message list processing won't see it,
248
345
* unless the file name is the only thing on the line, in
249
346
* which case, return 0 in the reference flag variable.
350
snarf(linebuf, flag, usembox)
260
cp = strlen(linebuf) + linebuf - 1;
263
* Strip away trailing blanks.
266
while (cp > linebuf && isspace(*cp))
271
* Now search for the beginning of the file name.
274
while (cp > linebuf && !isspace(*cp))
277
printf("No file specified.\n");
357
if ((cp = laststring(linebuf, flag, 0)) == NULL) {
362
printf(catgets(catd, CATSET, 28,
363
"No file specified.\n"));
406
printf("Okie dokie");
490
printf(catgets(catd, CATSET, 31, "Okie dokie"));
410
494
if (WCOREDUMP(wait_status))
411
printf(" -- Core dumped.\n");
495
printf(catgets(catd, CATSET, 32, " -- Core dumped.\n"));
413
printf(" -- Can't dump core.\n");
497
printf(catgets(catd, CATSET, 33, " -- Can't dump core.\n"));
508
592
if (*list == NULL)
509
593
return igshow(tab, which);
510
594
for (ap = list; *ap != 0; ap++) {
511
istrcpy(field, *ap, BUFSIZ);
512
field[BUFSIZ-1]='\0';
513
if (member(field, tab))
599
field = ac_alloc(sz + 1);
600
i_strcpy(field, *ap, sz + 1);
602
if (member(field, tab)) {
516
igp = (struct ignore *) calloc(1, sizeof (struct ignore));
517
igp->i_field = calloc((unsigned) strlen(field) + 1,
607
igp = (struct ignore *)scalloc(1, sizeof (struct ignore));
608
igp->i_field = smalloc(strlen(field) + 1);
519
609
strcpy(igp->i_field, field);
520
610
igp->i_link = tab->i_head[h];
521
611
tab->i_head[h] = igp;
563
655
return (strcmp(*(char **)l, *(char **)r));
662
return unignore1((char **)v, ignore, "ignored");
669
return unignore1((char **)v, ignore + 1, "retained");
676
return unignore1((char **)v, saveignore, "ignored");
683
return unignore1((char **)v, saveignore + 1, "retained");
687
unignore_one(name, tab)
689
struct ignoretab *tab;
691
struct ignore *ip, *iq = NULL;
694
for (ip = tab->i_head[h]; ip; ip = ip->i_link) {
695
if (asccasecmp(ip->i_field, name)) {
698
iq->i_link = ip->i_link;
700
tab->i_head[h] = NULL;
709
unignore1(list, tab, which)
711
struct ignoretab *tab;
714
if (tab->i_count == 0) {
715
printf(catgets(catd, CATSET, 34,
716
"No fields currently being %s.\n"), which);
720
unignore_one(*list++, tab);