# 2.11BSD#431 - /usr/src/new/notes/src/nfmail.c

##### Functions

    copy              X
    dopipe            X
    getignore         X
    main              X
    shouldignore      X
    skipwhite         X

##### Variables

    AnchorSearch      X
    Debug             X
    Nfpipe            X
    ignore            X
    ignore_cnt        X
    system_rc         X
    tmpname           X

##### Macros

    EX_DATAERR        X
    EX_OK             X
    EX_UNAVAILABLE    X
    EX_USAGE          X
    IGNORESIZE        X
    MAX_IGNORE        X

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

#### Defined functions

copy defined in line 511; used 2 times

- in line 251, 503

dopipe defined in line 492; used 1 times

- in line 160

getignore defined in line 392; used 2 times

- in line 126, 168

main defined in line 60; never used
shouldignore defined in line 465; used 2 times

- in line 226, 436

skipwhite defined in line 379; used 5 times

- in line 79, 413-417(2), 430, 440

#### Defined variables

AnchorSearch defined in line 58; used 2 times

- in line 110, 296

Debug defined in line 39; used 8 times

- in line 179, 185, 236, 244, 403, 447, 474, 480

Nfpipe defined in line 49; used 2 times

- in line 155-159(2)

ignore defined in line 55; used 6 times

- in line 431-436(2), 453, 471-475(3)

ignore_cnt defined in line 56; used 6 times

- in line 425, 431-438(3), 452, 470

rcsid defined in line 13; never used
system_rc defined in line 52; used 1 times

- in line 168

title defined in line 36; used 6 times

- in line 195, 281, 358-368(4)

tmpname defined in line 50; used 8 times

- in line 154-161(3), 254-257(3), 273, 374

#### Defined macros

EX_DATAERR defined in line 8; used 1 times

- in line 428

EX_OK defined in line 6; used 2 times

- in line 162, 375

EX_UNAVAILABLE defined in line 9; used 3 times

- in line 258, 279, 500

EX_USAGE defined in line 7; used 1 times

- in line 146

IGNORESIZE defined in line 34; used 3 times

- in line 55, 396, 412

MAX_IGNORE defined in line 54; used 2 times

- in line 55, 425

Last modified: 1996-10-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1646 |