1: #include "parms.h"
   2: #include "structs.h"
   3: #include <sysexits.h>                   /* bsd only? */
   4: 
   5: #ifdef  RCSIDENT
   6: static char *rcsid = "$Header: nfmail.c,v 1.7.0.8 85/10/20 11:09:09 notes Rel $";
   7: #endif	RCSIDENT
   8: 
   9: /*
  10:  *	nfmail
  11:  *
  12:  *	A simple program which goes through standard input, which
  13:  *	should be a formatted mail article with headers, and
  14:  *	parses out the "Subject:" line.  We then turn around and
  15:  *	use it to invoke "nfpipe" and send the letter to the appropriate
  16:  *	notesfile (specified on the nfmail command line).
  17:  *
  18:  *	Original coding:	Wayne Hamilton,	U of Illinois CSO (I think)
  19:  *	Modified:		Stuart Cracraft, SRI International
  20:  *
  21:  */
  22: 
  23: 
  24: char   *getadr ();
  25: FILE * popen ();
  26: 
  27: #define IGNORESIZE 256
  28: 
  29: static char title[BUFSIZ] = "No Subject Line";
  30: 
  31: /*
  32:  *	next three variables declared in "parsepath".
  33:  */
  34: extern char fromsys[SYSSZ + 1];             /* gave it to us */
  35: extern char origsys[SYSSZ + 1];             /* started here */
  36: extern char authname[NAMESZ + 1];           /* author */
  37: 
  38: char    Nfpipe[BUFSIZ];                 /* nfpipe pathname */
  39: char    tmpname[BUFSIZ];                /* scratch file */
  40: 
  41: char    system_rc[] = "/usr/lib/Mail.rc";
  42: 
  43: #define MAX_IGNORE  32
  44: char    ignore[MAX_IGNORE][IGNORESIZE];
  45: int     ignore_cnt = 0;
  46: 
  47: int     AnchorSearch = TRUE;
  48: 
  49: main (argc, argv)
  50: char  **argv;
  51: {
  52:     register    FILE * Ftmp;
  53:     char    command[BUFSIZ],
  54:             from[BUFSIZ],
  55:             oldfrom[BUFSIZ],
  56:             buf[BUFSIZ];
  57:     int     gotsubj = FALSE,
  58:             gotfrom = FALSE,
  59:             gotoldfrom = FALSE;
  60:     int     stripheader = FALSE;            /* leave headers in */
  61:     int     letterstatus = 0;               /* director msg? */
  62:     int     tossit;
  63:     char   *myrc = 0;
  64:     char   *home;
  65:     int     i;
  66:     char   *p,
  67:            *q,
  68:            *skipwhite ();
  69: 
  70:     struct io_f io;
  71:     struct daddr_f  where;
  72:     struct when_f   entered;
  73:     struct id_f respid;
  74:     struct auth_f   auth;
  75:     struct when_f   whentime;
  76:     int     notenum;
  77:     int     status;
  78:     struct note_f   note;
  79: 
  80:     startup (argc, argv);
  81:     argc--;                     /* blast command */
  82:     argv++;
  83:     from[0] = oldfrom[0] = '\0';            /* zero them */
  84: 
  85:     while (argc != 0)
  86:     {
  87: 
  88:     if (strncmp (*argv, "-s\0", 3) == 0)        /* strip headers */
  89:     {
  90:         argc--;
  91:         argv++;
  92:         stripheader = TRUE;
  93:         continue;
  94:     }
  95:     if (strncmp (*argv, "-F\0", 3) == 0)        /* floating match */
  96:     {
  97:         argv++;
  98:         argc--;                 /* to next arg */
  99:         AnchorSearch = FALSE;           /* floating search */
 100:         continue;
 101:     }
 102:     if (strncmp (*argv, "-d\0", 3) == 0)        /* enable dirmsg */
 103:     {
 104:         argc--;
 105:         argv++;
 106:         letterstatus |= DIRMES;
 107:         continue;
 108:     }
 109:     if (strncmp (*argv, "-m\0", 3) == 0)        /* specify .mailrc */
 110:     {
 111:         argc--;
 112:         argv++;
 113:         if (argc != 0)
 114:         {
 115:         getignore (*argv);
 116:         }
 117:         else
 118:         {
 119:         fprintf (stderr, "Need to specifiy -m file\n");
 120:         goto usage;
 121:         }
 122:         argc--;
 123:         argv++;
 124:         continue;                   /* next arg */
 125:     }
 126:     break;                      /* not an arg */
 127:     }
 128: 
 129: 
 130:     if (!argc)
 131:     {
 132: usage:
 133:     fprintf (stderr, "Usage: %s [-F] [-s] [-m .mailrc-file] <notesfile>\n",
 134:         Invokedas);
 135:     exit (EX_USAGE);
 136:     }
 137: 
 138: /*
 139:  *	build ourselves a scratch file.  If we can't, then pass the
 140:  *	mail on with a default title.
 141:  */
 142: 
 143:     sprintf (tmpname, "/tmp/nfm%05d", getpid ());
 144:     sprintf (Nfpipe, "%s/nfpipe", BIN);
 145:     if ((Ftmp = fopen (tmpname, "w")) == NULL)
 146:     {
 147:     fprintf (stderr, "nfmail: can't fopen temp file, but the mail gets thru\n");
 148:     sprintf (command, "%s %s -t \"Mail to %s\"", Nfpipe, *argv, *argv);
 149:     dopipe (command, stdin);
 150:     unlink (tmpname);               /* ... remove scratch file */
 151:     exit (EX_OK);                   /* and leave */
 152:     }
 153: 
 154: /*
 155:  *	Step through the system Mail.rc file and pilfer the ignore commands.
 156:  *	Then, process the .mailrc file in the home directory if there is one.
 157:  */
 158:     getignore (system_rc);
 159: 
 160: /*
 161:  *	read through the mail looking for the subject line.
 162:  */
 163: 
 164:     while (gets (buf) != NULL)
 165:     {
 166:     if (!buf[0])
 167:         break;                  /* header's end */
 168:     if (buf[0] == '\t')             /* continuation */
 169:         goto doit;                  /* use same "tossit" */
 170: 
 171:     tossit = stripheader;
 172:     if (!strncmp (buf, "Subject: ", 9))     /* check for title */
 173:     {
 174:         if (!gotsubj)               /* only first one */
 175:         {
 176:         strcpy (title, buf + 9);
 177:         gotsubj = TRUE;
 178:         }
 179:         tossit = FALSE;
 180:         goto doit;                  /* skip other tests */
 181:     }
 182:     if (!strncmp (buf, "From: ", 6))        /* author */
 183:     {                       /* grab user name */
 184:         if (!gotfrom)               /* only once */
 185:         {
 186:         strcpy (from, buf + 6);
 187:         gotfrom = TRUE;
 188:         }
 189:         tossit = FALSE;             /* keep all from lines */
 190:         goto doit;
 191:     }
 192:     if (!strncmp (buf, "From", 4) || !strncmp (buf, ">From", 5))
 193:     {
 194:         if (!gotoldfrom)
 195:         {
 196:         strcpy (oldfrom, buf + 5);      /* save it */
 197:         gotoldfrom++;
 198:         }
 199:         tossit = FALSE;             /* save all addresses */
 200:     }
 201:     else
 202:         if (stripheader && !shouldignore (buf))
 203:         tossit = FALSE;             /* "ignore" only when stripping */
 204: 
 205: doit:                           /* for continuation lines */
 206:     if (tossit == FALSE)
 207:         fprintf (Ftmp, "%s\n", buf);        /* send the header line also */
 208:     }                           /* of header parsing loop */
 209: 
 210:     putc ('\n', Ftmp);                  /* blank after headers */
 211:     copy (stdin, Ftmp);
 212:     fclose (Ftmp);
 213: 
 214:     if ((Ftmp = fopen (tmpname, "r")) == NULL)
 215:     {
 216:     unlink (tmpname);               /* ... remove scratch file */
 217:     fprintf (stderr, "nfmail: can't re-fopen temp file %s\n", tmpname);
 218:     exit (EX_UNAVAILABLE);
 219:     }
 220: 
 221: /*
 222:  *	Now that we have collected the letter and parsed such banalities
 223:  *	as the title and the author and stripped any header lines that we
 224:  *	don't care to hear about, it's time to put the letter into
 225:  *	the notesfile.  We use routines scammed from our news/notes gateway
 226:  *	code to look at the title and determine if it's a response to
 227:  *	a previous letter.  This allows us to have the correct linkage
 228:  *	for mail sent to a notesfile....
 229:  */
 230: 
 231:     if ((i = init (&io, *argv)) < 0)
 232:     {
 233:     unlink (tmpname);               /* zap scratch file */
 234:     fprintf (stderr, "%s: can't open notesfile %s (retcode %d)\n",
 235:         Invokedas, *argv, i);
 236:     /*
 237: 	 * Should have a better scheme for knowing why can't open
 238: 	 */
 239:     exit (EX_UNAVAILABLE);              /* bad nf or such */
 240:     }
 241:     p = title;
 242:     while (*p && (*p == ' ' || *p == '\t'))     /* leading trash */
 243:     p++;                        /* skip */
 244:     if (!strncmp (p, "re: ", 4) ||          /* it looks like */
 245:         !strncmp (p, "Re: ", 4) ||          /* a response */
 246:         !strncmp (p, "RE: ", 4))
 247:     {
 248:     do
 249:     {
 250:         for (p += 3; *p == ' ' || *p == '\t'; p++); /* drop spaces */
 251:     } while (!strncmp (p, "re: ", 4) ||
 252:         !strncmp (p, "Re: ", 4) ||
 253:         !strncmp (p, "RE: ", 4));
 254:     strncpy (io.xstring, p, TITLEN);        /* load it */
 255:     io.xstring[TITLEN - 1] = '\0';          /* and terminate it */
 256:     notenum = findtitle (&io, io.descr.d_nnote, AnchorSearch);/* start at back */
 257:     }
 258:     else
 259:     {
 260:     notenum = 0;                    /* has to be new */
 261:     }
 262: 
 263: /*
 264:  *	OK. By now, we have a "notenum" if the article can be pegged
 265:  *	as a response to one of our notes.
 266:  *	Otherwise, notenum==0 and we'll have to turn it into
 267:  *	a base note.
 268:  */
 269: 
 270:     gettime (&whentime);
 271:     gettime (&entered);
 272:     /*
 273:      *	load the user's name
 274:      */
 275:     if (from[0] != '\0')                /* got one */
 276:     {
 277:     p = q = from;
 278:     while ((p = index (p, '<')) != (char *) NULL)
 279:         q = ++p;                    /* get innermost <..> */
 280:     p = index (q, '>');
 281:     if (p != (char *) NULL)
 282:         *p = '\0';                  /* zap */
 283:     parsepath (q, (char *) NULL);           /* actually break it */
 284:     }
 285:     else
 286:     {
 287:     if (oldfrom[0] != '\0')
 288:     {
 289:         parsepath (oldfrom, (char *) NULL);     /* try for something */
 290:     }
 291:     else
 292:     {
 293:         strcpy (authname, "MAILER-DAEMON");     /* general catch-all */
 294:         origsys[0] = '\0';              /* local */
 295:     }
 296:     }
 297:     strncpy (auth.aname, authname, NAMESZ);     /* user */
 298:     if (origsys[0] == '\0')
 299:     strncpy (auth.asystem, Authsystem, HOMESYSSZ);  /* local host */
 300:     else
 301:     strncpy (auth.asystem, origsys, HOMESYSSZ); /* system */
 302:     auth.aname[NAMESZ - 1] = auth.asystem[HOMESYSSZ - 1] = '\0';/* chop */
 303:     auth.aid = Anonuid;                 /* uid (none) */
 304: #ifdef  DEBUG
 305:     printf ("parse path returns the following:\n");
 306:     printf ("authname: %s\n", authname);
 307:     printf ("origsys: %s\n", origsys);
 308:     printf ("fromsys: %s\n", fromsys);
 309: #endif	DEBUG
 310:     if (notenum > 0)
 311:     {
 312:     pagein (&io, Ftmp, &where);
 313:     i = putresp (&io, &where, putresp, notenum, &entered, &auth, &note,
 314:         LOCKIT, &respid, ADDID, System, ADDTIME, &whentime);
 315:     }
 316:     else
 317:     {
 318:     for (p = &title[0]; *p && (*p == ' ' || *p == '\t');)
 319:         p++;                    /* strip blanks */
 320:     for (i = 0; i < TITLEN; i++)            /* shift down */
 321:     {
 322:         if ((title[i] = *p++) == '\0')      /* want assignment */
 323:         break;                  /* end */
 324:     }
 325:     title[TITLEN - 1] = '\0';           /* terminate for sure */
 326:     pagein (&io, Ftmp, &where);
 327:     gettime (&note.n_date);
 328:     notenum = putnote (&io, &where, title, letterstatus, &note,
 329:         &auth, NOPOLICY, LOCKIT, ADDID, System, ADDTIME);
 330:     }
 331: 
 332:     finish (&io);                   /* update numbers and close */
 333:     fclose (Ftmp);                  /* close and ... */
 334:     unlink (tmpname);                   /* ... remove scratch file */
 335:     exit (EX_OK);
 336: }
 337: 
 338: 
 339: char   *skipwhite (p)
 340: char   *p;
 341: {
 342:     while (*p == ' ' || *p == '\t' || *p == '\n')
 343:     p++;
 344:     return (p);
 345: }
 346: 
 347: 
 348: /*
 349:  *	Get all the "ignore" commands from the file. Do nothing if the file
 350:  *	does not exist.
 351:  */
 352: getignore (name)
 353: char   *name;
 354: {
 355:     FILE * f;
 356:     char    buff[IGNORESIZE];
 357:     char   *p,
 358:            *q;
 359: 
 360:     if ((f = fopen (name, "r")) == 0)
 361:     return (0);
 362: 
 363:     while (!feof (f))
 364:     {
 365:     p = buff;
 366:     fgets (buff, IGNORESIZE, f);
 367:     p = skipwhite (p);
 368: 
 369:     if (strncmp (p, "ignore", 6) == 0)
 370:     {
 371:         p = skipwhite (p + 6);
 372: 
 373: /*
 374:  *	Collect the tags of the ignore command
 375:  */
 376: 
 377:         while (*p != 0)
 378:         {
 379:         if (ignore_cnt >= MAX_IGNORE)
 380:         {
 381:             fprintf (stderr, "%s: too many ignore tags\n", Invokedas);
 382:             exit (EX_DATAERR);
 383:         }
 384:         p = skipwhite (p);
 385:         for (q = ignore[ignore_cnt];
 386:             *p != ' ' && *p != '\t' && *p != '\n' && *p != 0;
 387:             *(q++) = *(p++)
 388:             );
 389:         *q = 0;
 390:         if (!shouldignore (ignore[ignore_cnt]))
 391:         {
 392:             ignore_cnt++;
 393:         }
 394:         p = skipwhite (p);
 395:         }
 396:     }
 397:     }
 398: 
 399:     fclose (f);
 400:     return (0);
 401: }
 402: 
 403: 
 404: 
 405: /*
 406:  *	Should we ignore this line?
 407:  */
 408: shouldignore (p)
 409: char   *p;
 410: {
 411:     int     i;
 412: 
 413:     for (i = 0; i < ignore_cnt; i++)
 414:     if (strncmp (p, ignore[i], strlen (ignore[i])) == 0)
 415:         return (1);
 416:     return (0);
 417: }
 418: 
 419: /*
 420:  *	simple command feeds what is left of the file "File" into
 421:  *	a pipe feeding stdin of "command".
 422:  *
 423:  */
 424: 
 425: dopipe (command, File) char *command;
 426: FILE * File;
 427: {
 428:     register    FILE * Pipe;
 429: 
 430:     if ((Pipe = popen (command, "w")) == NULL)
 431:     {
 432:     fprintf (stderr, "%s: can't popen (%s)!?\n", Invokedas, command);
 433:     exit (EX_UNAVAILABLE);
 434:     }
 435: 
 436:     copy (File, Pipe);
 437:     pclose (Pipe);
 438: }
 439: 
 440: /*
 441:  *	copy rest of file "File" to "To".
 442:  */
 443: 
 444: copy (From, To) FILE * From, *To;
 445: {
 446:     register int    c;
 447: 
 448:     while ((c = getc (From)) != EOF)
 449:     putc (c, To);
 450: }

Defined functions

copy defined in line 444; used 2 times
dopipe defined in line 425; used 1 times
getignore defined in line 352; used 2 times
main defined in line 49; never used
shouldignore defined in line 408; used 2 times
skipwhite defined in line 339; used 5 times

Defined variables

AnchorSearch defined in line 47; used 2 times
Nfpipe defined in line 38; used 2 times
ignore defined in line 44; used 4 times
ignore_cnt defined in line 45; used 5 times
rcsid defined in line 6; never used
system_rc defined in line 41; used 1 times
title defined in line 29; used 6 times
tmpname defined in line 39; used 8 times

Defined macros

IGNORESIZE defined in line 27; used 3 times
MAX_IGNORE defined in line 43; used 2 times
Last modified: 1985-10-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1476
Valid CSS Valid XHTML 1.0 Strict