1: #define MAINLINE
   2: #include "parms.h"
   3: #include "structs.h"
   4: #include "newsgate.h"
   5: 
   6: #ifdef  RCSIDENT
   7: static char rcsid[] = "$Header: newsinput.c,v 1.7.0.6 85/10/01 23:06:08 notes Rel $";
   8: #endif	RCSIDENT
   9: 
  10: /*
  11:  *	newsinput
  12:  *
  13:  *	A total re-coding of the original.  Makes use of the
  14:  *	work that Lou Salkind and Tw Cook have done.  Lou rearranged
  15:  *	a bunch of stuff and Tw put the notes headers into the
  16:  *	news header.
  17:  */
  18: 
  19: static char title[TITLEN + 1];              /* hold titles */
  20: extern char fromsys[SYSSZ + 1];             /* gave it to us */
  21: static struct when_f    entered;            /* date written */
  22: extern char origsys[SYSSZ + 1];             /* originator */
  23: extern char authname[NAMESZ + 1];           /* author */
  24: static int  has_suffix = 0;             /* had -(nf) suffix */
  25: 
  26: #define dprintf     if (0) printf
  27: 
  28: 
  29: main (argc, argv)
  30: int     argc;
  31: char  **argv;
  32: {
  33:     FILE * rawnews;
  34:     FILE * body;
  35:     char    pathname[BUFSIZ];
  36:     struct io_f io;
  37:     struct hbuf header;
  38:     char    nf[WDLEN];
  39:     struct nflist_f *nfptr;             /* expand newsgroups */
  40:     int     c;
  41:     int     onechar;
  42:     char   *tail;
  43:     int     fid;                    /* for close */
  44: 
  45: 
  46:     setuid (geteuid ());                /* force to "notes" */
  47:     startup (argc, argv);               /* comon init */
  48:     rawnews = stdin;                    /* usually here */
  49:     for (fid = 3; fid < 20; fid++)          /* close all extras */
  50:     close (fid);
  51: 
  52: /*
  53:  *	Parse the Header.  Follow all the USENET standards
  54:  *	for doing this.  Result is left in a fun little
  55:  *	structure.
  56:  *	Internalize some of the information to help us figure out
  57:  *	some things quickly.
  58:  */
  59: 
  60:     if (!newsheader (&header, rawnews, TRUE))       /* read the headers */
  61:     {
  62:     printf ("Incoming News mangled more than usual\n");
  63:     exit (BAD);
  64:     }
  65: 
  66: /*
  67:  *	Parse things like origsys, fromsys, author, date written
  68:  */
  69:     parsepath (header.path, header.from);       /* systems, authors */
  70:     parsetime (header.subdate, &entered);       /* submitted */
  71:     sprintf (pathname, "/tmp/nfxx%d", getpid ());
  72:     dprintf ("Origsys: %s\n", origsys);
  73:     dprintf ("fromsys: %s\n", fromsys);
  74:     dprintf ("Date Written:");
  75: #ifdef  notdef
  76:     prdate (&entered);
  77: #endif
  78:     dprintf ("\nauthor: %s\n", authname);
  79: /*
  80:  *	See if this might be a control message. Notes readers don't
  81:  *	care to see these.
  82:  *
  83:  *	News code also recognizes titles with first 5 characters set
  84:  *	to "cmsg " as control messages. We should clean them up too.
  85:  */
  86:     if (header.ctlmsg[0] != '\0')           /* is control */
  87:     {
  88:     printf ("Control message (ignored): %s\n", header.ctlmsg);
  89:     exit (0);                   /* "success" */
  90:     }
  91: /*
  92:  *	Save the body of the article somewhere safe (like not in
  93:  *	memory).
  94:  */
  95:     if ((body = fopen (pathname, "w")) == NULL)     /* failed */
  96:     {
  97:     printf ("Had problems creating/opening file %s\n", pathname);
  98:     exit (BAD);                 /* die */
  99:     }
 100:     while ((onechar = getc (rawnews)) != EOF)       /* save it */
 101:     putc (onechar, body);
 102:     fflush (body);                  /* make sure */
 103:     fclose (body);                  /* and close it */
 104: 
 105: /*
 106:  *	Now run through the specified list of newsgroups,
 107:  *	re-scan the body and such each time.
 108:  */
 109: 
 110:     expand (header.nbuf);               /* expand groups */
 111:     while ((nfptr = nextgroup ()) != (struct nflist_f *) NULL)
 112:     {
 113: 
 114:     newsgroup (nfptr -> nf_name, nf, NEWSNF);   /* map it */
 115:     dprintf ("Newsgroup %s maps to notesfile %s\n", nfptr -> nf_name, nf);
 116:     tail = rindex (nfptr -> nf_name, '.');      /* catch ctl msgs */
 117:     if (tail != (char *) NULL && !strcmp (tail, CTL))/* it is one */
 118:     {
 119:         char    pbuf[256];              /* for title fixing */
 120: 
 121:         strcpy (nf, NFMAINT);           /* map it */
 122:         dprintf ("Control newsgroup %s mapped to %s\n",
 123:             nfptr -> nf_name, nf);
 124:         sprintf (pbuf, "%s:%s", nfptr -> nf_name, header.title);
 125:         strncpy (header.title, pbuf, BUFLEN);   /* prefix title */
 126:         header.title[BUFLEN - 1] = '\0';        /* ensure terminater */
 127:     }
 128: 
 129:     if ((body = fopen (pathname, "r")) == NULL)
 130:     {
 131:         goto failed;                /* shit */
 132:     }
 133:     if (init (&io, nf) < 0)             /* open the nf */
 134:     {
 135:         char    pbuf[512];
 136:         char    tbuf[128];
 137: #ifdef AUTOCREATE
 138:         sprintf (pbuf,
 139:             "Notesfile: %s\nNewsgroup: %s\n\nCreated by newsinput\n",
 140:             nf, nfptr -> nf_name);
 141:         sprintf (tbuf, "New NF: %s", nf);
 142:         nfcomment (NFMAINT, pbuf, tbuf, TRUE, 0);
 143:         buildnf (nf, Mstdir, 0, 1, 1);      /* open and networked */
 144:         x (init (&io, nf) < 0, "newsinput: open newly created notesfile");
 145: #else
 146:         sprintf (pbuf, "Notesfile: %s, newsgroup %s\n",
 147:             nf, nfptr -> nf_name);
 148:         sprintf (tbuf, "New newsgroup %s", nfptr -> nf_name);
 149:         nfcomment (NFMAINT, pbuf, tbuf, 0, 0);
 150:         printf ("Inserting into %s\n", NEWNEWS);
 151:         strcpy (nf, NEWNEWS);           /* Change newsgroup */
 152:         if (init (&io, nf) < 0)
 153:         exit (BAD);             /* Give up */
 154:         printf ("Open of %s suceeded\n", nf);
 155: #endif AUTOCREATE
 156:     }
 157: 
 158:     if (nfgen (&io, &header, body, pathname) < 0)   /* not from notes */
 159:     {
 160:         dprintf ("Nfgen returns failure\n");
 161:         fclose (body);              /* give bnewsgen */
 162:         body = fopen (pathname, "r");       /* a clean copy */
 163:         if (bnewsgen (&io, &header, body) < 0)  /* or news */
 164:         {
 165:         dprintf ("bnewsgen returns failure\n");
 166:         goto failed;                /* drop out */
 167:         }
 168:     }
 169:     fclose (body);                  /* ready for loop */
 170:     finish (&io);
 171:     }
 172: 
 173:     unlink (pathname);
 174:     exit (GOOD);
 175: 
 176: /*
 177:  *	jump here on totally screwed up article.
 178:  */
 179: failed:
 180:     dprintf ("Jumped to failed\n");
 181:     unlink (pathname);                  /* body of article */
 182:     exit (BAD);
 183: }
 184: 
 185: /*
 186:  *	nfgen(&io,&header,&FILE,pathname)
 187:  *
 188:  *	parse a notesfile-generated article.  Check the fields of
 189:  *	header and look for # lines in the body of the article to
 190:  *	determine if it came from notes.
 191:  *
 192:  *	returns:	0 no permission for author
 193:  *			> 0 signifies note or response where it wound up
 194:  *			-1 if the article wasn't generated by notes
 195:  */
 196: 
 197: nfgen (io, header, body, pathname)
 198: struct io_f *io;
 199: struct hbuf *header;
 200: FILE * body;
 201: char   *pathname;
 202: {
 203:     register int    i;
 204:     register char  *p;
 205:     struct note_f   note;
 206:     struct note_f   note2;
 207:     struct id_f respid;
 208:     struct daddr_f  where;
 209:     struct when_f   whentime;
 210:     struct auth_f   auth;               /* author */
 211:     int     oldstyle = 0;
 212:     int     found;
 213:     char    line[CMDLEN];               /* scratch */
 214:     char   *suffix;
 215:     int     notenum;
 216:     int     status;
 217:     int     fosterstat;                 /* for foster parents */
 218:     int     count;
 219:     char    hline1[BUFLEN];             /* in-text header */
 220:     char    hline2[BUFLEN];             /* in-text header 2 */
 221:     int     onechar;                    /* scratch character */
 222:     char    field1[100],                /* scanf tmps */
 223:             field2[100];
 224: 
 225: /*
 226:  * Check for titles ending in "- nf".
 227:  * We always remove these.
 228:  */
 229:     suffix = rindex (header -> title, '-');     /* find last */
 230:     if (!strcmp (suffix, NFSUFFIX) || !strcmp (suffix, OLDSUFFIX))
 231:     {
 232:     if (--suffix > header -> title)         /* if we can */
 233:         *suffix = '\0';             /* strip "- (nf)" */
 234:     has_suffix++;                   /* flag it */
 235:     }
 236: /*
 237:  *	at this point we should check for embodied #N.... lines and
 238:  *	remove them.  This is conditional on having a "- (nf)" in the
 239:  *	title of the note.
 240:  */
 241: 
 242:     strcpy (hline1, "");                /* empty these */
 243:     strcpy (hline2, "");
 244:     if (has_suffix)                 /* look for embedded */
 245:     {
 246:     long    position,               /* place marker */
 247:             ftell ();               /* for types */
 248: 
 249:     position = ftell (body);            /* save it */
 250:     while (fgets (hline1, sizeof hline1, body) != NULL)
 251:         if (hline1[0] == '#')
 252:         break;                  /* found one */
 253:     if (hline1[0] != '#')               /* actually didn't */
 254:     {
 255:         fseek (body, position, 0);          /* rewind */
 256:         strcpy (hline1, "");            /* empty it */
 257:     }
 258:     else
 259:     {                       /* grab line 2 */
 260:         fgets (hline2, sizeof hline2, body);
 261:         while ((onechar = getc (body)) != '\n' && onechar != EOF)
 262:         ;                   /* zap separator line */
 263:     }
 264:     }
 265: 
 266:     if (strlen (header -> nline1) == 0)         /* no new headers */
 267:     {
 268:     /*
 269: 	 * No notes header in the B news article header...
 270: 	 * If title ends with "- nf", look for the
 271: 	 * header in the body of the text.
 272: 	 * (for backwards compatability)
 273: 	 */
 274:     if (has_suffix == 0)                /* not from notes */
 275:     {
 276:         dprintf ("No NFSUFFIX and no header lines\n");
 277:         return (-1);
 278:     }
 279:     oldstyle = 1;
 280:     found = 0;
 281:     if (hline1[0] == '#')               /* got them earlier */
 282:     {
 283:         strcpy (header -> nline1, hline1);      /* first line */
 284:         strcpy (header -> nline2, hline2);      /* second line */
 285:         found++;                    /* and mark it */
 286:     }
 287:     while (!found &&                /* search body */
 288:         fgets (header -> nline1, sizeof header -> nline1, body))
 289:     {
 290:         if (header -> nline1[0] == '#')     /* bingo */
 291:         {
 292:         found++;
 293:         break;
 294:         }
 295:     }
 296:     if (!found ||
 297:         fgets (header -> nline2, sizeof header -> nline2, body) == NULL)
 298:     {
 299:         dprintf ("no header lines in text body\n");
 300:         return (-1);                /* not from notes */
 301:     }
 302:     }
 303: 
 304: /*
 305:  * We now have the header lines.
 306:  * Check validity and do the appropriate action.
 307:  */
 308:     if (header -> nline1[0] != '#')
 309:     {
 310:     dprintf ("Invalid first header line\n");
 311:     return (-1);
 312:     }
 313:     dprintf ("First line is: %s\n", header -> nline1);
 314:     dprintf ("Second line is: %s\n", header -> nline2);
 315:     strncpy (title, header -> title, TITLEN);       /* get title */
 316:     title[TITLEN - 1] = '\0';               /* terminate for sure */
 317: 
 318:     switch (header -> nline1[1])            /* parse it */
 319:     {
 320:     case 'N':                   /* base note */
 321:         if (sscanf (header -> nline1, "#N:%99[^:]:%ld:%o:%d", field1,
 322:             &note.n_id.uniqid, &status, &count) != 4)
 323:         {
 324:         return (-1);                /* no good */
 325:         }
 326:         strncpy (note.n_id.sys, field1, SYSSZ); /* copy */
 327:         note.n_id.sys[SYSSZ - 1] = '\0';        /* and terminate */
 328:         status |= FRMNEWS;              /* it's been there */
 329: 
 330:         /*
 331: 	     * parse the second header line
 332: 	     */
 333: 
 334:         p = header -> nline2;
 335:         for (i = 0; (i < HOMESYSSZ - 1) && (*p != '!' && *p != '\0'); i++)
 336:         auth.asystem[i] = *p++;         /* get the author */
 337:         auth.asystem[i] = '\0';         /* terminate */
 338:         while (*p != '!' && *p != '\0')
 339:         p++;                    /* skip to end of system */
 340:         if (*p == '!')
 341:         p++;                    /* skip the ! */
 342:         for (i = 0; (i < NAMESZ - 1) && (*p != ' ' && *p != '\0'); i++)
 343:         auth.aname[i] = *p++;           /* get the author */
 344:         auth.aname[i] = '\0';           /* terminate */
 345:         auth.aid = Anonuid;
 346: 
 347:         while (*p != ' ' && *p)
 348:         p++;                    /* drop rest of author */
 349:         while (*p == ' ')               /* find the date */
 350:         p++;
 351:         parsetime (p, &note.n_date);        /* and parse it */
 352: 
 353:         getperms (io, 1, note.n_id.sys);        /* check permissions */
 354:         if (allow (io, WRITOK) == 0)        /* not a chance */
 355:         return (0);             /* sort of success */
 356: 
 357:         locknf (io, DSCRLOCK);          /* MUTEX */
 358:         if ((notenum = chknote (io, &note.n_id, &note2)) == 0)
 359:         {                       /* not in data base */
 360:         pagein (io, body, &where);      /* grab text */
 361:         status |= FRMNEWS;          /* through news */
 362:         strcpy (note.n_from, fromsys);      /* who gave it to us */
 363:         i = putnote (io, &where, title, status, &note, &auth,
 364:             NOPOLICY, NOLOCKIT, NOADDID, fromsys, ADDTIME);
 365:         io -> nnotrcvd++;           /* count it */
 366:         unlocknf (io, DSCRLOCK);        /* MUTEX done */
 367:         return (i);             /* return notenum */
 368:         }
 369:         if ((note2.n_stat & ORPHND) && (status & ORPHND) == 0)
 370:         {                       /* replace foster */
 371:                             /* with true parent */
 372:         pagein (io, body, &note2.n_addr);   /* the text */
 373:         gettime (&note2.n_rcvd);        /* update timestamp */
 374:         gettime (&note2.n_lmod);        /* time stamp it */
 375:         copyauth (&auth, &note2.n_auth);    /* correct author */
 376:         note2.n_stat = status | FRMNEWS;    /* and status bits */
 377:         strncpy (note2.ntitle, title, TITLEN);
 378:         note2.n_date = entered;
 379:         strcpy (note2.n_from, fromsys);
 380:         putnrec (io, notenum, &note2);      /* and replace */
 381:         io -> adopted++;            /* count adoption */
 382:         io -> nnotrcvd++;           /* count in */
 383:         unlocknf (io, DSCRLOCK);
 384:         printf ("Orphaned response chain adopted\n");
 385:         return (notenum);           /* note number */
 386:         }
 387:         else
 388:         printf ("Duplicate note handed back by news\n");
 389:         unlocknf (io, DSCRLOCK);
 390:         return (0);                 /* mark resolved */
 391: 
 392:     case 'R':                   /* response */
 393:         if (sscanf (header -> nline1, "#R:%99[^:]:%ld:%99[^:]:%ld:%o:%d",
 394:             field1, &note.n_id.uniqid, field2,
 395:             &respid.uniqid, &status, &count) != 6)
 396:         {
 397:         return (-1);                /* no good */
 398:         }
 399:         strncpy (note.n_id.sys, field1, SYSSZ); /* copy them */
 400:         strncpy (respid.sys, field2, SYSSZ);    /* both and */
 401:         note.n_id.sys[SYSSZ - 1] = respid.sys[SYSSZ - 1] = '\0';/* stop */
 402:         status |= FRMNEWS;              /* it's been there */
 403: 
 404:         getperms (io, 1, respid.sys);       /* check modes */
 405:         if (allow (io, RESPOK) == 0)        /* not a chance */
 406:         return (0);             /* resolved */
 407: 
 408:         p = header -> nline2;           /* second line */
 409:         for (i = 0; (i < HOMESYSSZ - 1) && (*p != '!' && *p != '\0'); i++)
 410:         auth.asystem[i] = *p++;         /* get the author */
 411:         auth.asystem[i] = '\0';         /* terminate */
 412:         while (*p != '!' && *p != '\0')
 413:         p++;                    /* skip to end of system */
 414:         if (*p == '!')
 415:         p++;                    /* skip the ! */
 416:         for (i = 0; (i < NAMESZ - 1) && (*p != ' ' && *p != '\0'); i++)
 417:         auth.aname[i] = *p++;           /* parse author */
 418:         auth.aname[i] = '\0';           /* terminate */
 419:         auth.aid = Anonuid;             /* default */
 420:         while (*p != ' ' && *p)
 421:         p++;                    /* rest of author */
 422:         while (*p == ' ')               /* find the date */
 423:         p++;
 424:         parsetime (p, &entered);            /* and parse it */
 425: 
 426:         locknf (io, DSCRLOCK);          /* MUTEX */
 427:         notenum = chknote (io, &note.n_id, &note2);
 428:         if (notenum == 0)               /* found parent? */
 429:         {                       /* build foster */
 430:         printf ("Orphaned response handed in by news\n");
 431:         strcpy (note.n_from, fromsys);      /* make basic info */
 432:         note.n_nresp = 0;
 433:         note.n_auth.aid = Anonuid;
 434:         strcpy (note.n_auth.aname, "Unknown");
 435:         strcpy (note.n_auth.asystem, note.n_id.sys);/* system */
 436:         note.n_date = entered;
 437:         gettime (&whentime);            /* current time */
 438:         fosterstat = ORPHND | FRMNEWS;      /* combo there */
 439: #ifdef  notdef
 440:         strcpy (note.ntitle, "(Orphan) ");  /* prefix */
 441: #else
 442:         strcpy (note.ntitle, "");       /* empty */
 443: #endif
 444:         i = strlen (note.ntitle);       /* index */
 445:         for (p = header -> title; i < TITLEN && *p; i++, p++)/* rest of title */
 446:             note.ntitle[i] = *p;        /* basic title */
 447:         if (i < TITLEN)
 448:             note.ntitle[i] = '\0';      /* null it */
 449:         else
 450:             note.ntitle[TITLEN - 1] = '\0'; /* null */
 451:         where.addr = 0;             /* no text */
 452:         where.textlen = 0;          /* still no text */
 453:         notenum = putnote (io, &where, note.ntitle, fosterstat,
 454:             &note, &note.n_auth, NOPOLICY, NOLOCKIT, NOADDID,
 455:             fromsys, ADDTIME);      /* insert him */
 456:         io -> norphans++;           /* orphan census */
 457:         getnrec (io, notenum, &note2);      /* get good one */
 458:         }
 459: /*
 460:  *	At this point we know we have a parent because if there wasn't
 461:  *	one before, we built a foster parent.
 462:  */
 463:         if (chkresp (io, &respid, &note2, notenum) == 0)
 464:         {                       /* none, insert it */
 465:         status |= FRMNEWS;
 466:         pagein (io, body, &where);
 467:         i = putresp (io, &where, status, notenum, &entered, &auth,
 468:             &note, NOLOCKIT, &respid, NOADDID, fromsys,
 469:             ADDTIME, &whentime);
 470:         io -> nrsprcvd++;           /* count him in */
 471:         unlocknf (io, DSCRLOCK);        /* UNMUTEX */
 472:         return (i);             /* resp number */
 473:         }
 474:         else
 475:         printf ("Duplicate response handed back by news\n");
 476:         unlocknf (io, DSCRLOCK);
 477:         return (0);                 /* resolved */
 478: 
 479:     default:                    /* bad news */
 480:         return (-1);
 481:     }                           /* NOTREACHED */
 482:     return (0);
 483: }
 484: 
 485: /*
 486:  *	bnewsgen(&io,&header,&FILE)
 487:  *
 488:  *	parse an article that came through B-news.  We've already
 489:  *	checked to see if it was a notesfile generated article
 490:  *	so all we have to do is decide if it's a note/response
 491:  *	and put it in the appropriate place.
 492:  */
 493: 
 494: bnewsgen (io, header, body)
 495: struct io_f *io;
 496: struct hbuf *header;
 497: FILE * body;
 498: {
 499:     register int    i;
 500:     char   *p;
 501:     struct note_f   note;
 502:     struct note_f   note2;
 503:     struct when_f   whentime;
 504:     struct daddr_f  where;
 505:     int     notenum;
 506:     int     status;
 507:     char    pbuf[BUFLEN];               /* scratch */
 508:     long    newsseq;
 509:     char    newssys[SYSSZ];
 510:     struct id_f newsid;
 511:     struct auth_f   auth;
 512:     char   *lead,
 513:            *trail;                  /* references */
 514:     char    basesys[SYSSZ];             /* references */
 515:     long    baseseq;                    /* ditto */
 516:     struct id_f baseid;                 /* ditto ditto */
 517:     char    field1[100],                /* scanf tmps */
 518:             field2[100];
 519: 
 520:     getperms (io, 1, origsys);
 521:     if (allow (io, WRITOK) == 0)            /* let him* */
 522:     {
 523:     printf ("System %s not allowed to write notes\n", origsys);
 524:     return (0);                 /* NO! */
 525:     }
 526: 
 527:     i = sscanf (header -> ident, "<%ld@%99[^>]>", &newsseq, field1, pbuf);
 528:     if (i < 2)                      /* try old */
 529:     {
 530:     i = sscanf (header -> ident, "%99[^.].%ld", field1, &newsseq);
 531:     }
 532:     if (i < 2)                      /* no id */
 533:     {
 534: #ifdef  NFMAINT
 535:     char    pbuf[BUFSIZ];
 536: 
 537:     sprintf (pbuf,
 538:         "Message-ID: %s\nPath: %s\nFrom: %s\nNewsgroups: %s\n",
 539:         header -> ident, header -> path,
 540:         header -> from, header -> nbuf);
 541:     nfcomment (NFMAINT, pbuf, "Unfathomable Article ID", 0, 0);
 542: #endif	NFMAINT
 543:     dprintf ("can't fathom article ID: %s\n", header -> ident);
 544:     return (-1);                    /* mark bogus */
 545:     }
 546:     strncpy (newssys, field1, SYSSZ);           /* copy */
 547:     newssys[SYSSZ - 1] = '\0';              /* and truncate */
 548: 
 549:     note.n_date = entered;
 550:     strcpy (note.n_from, fromsys);
 551:     strncpy (auth.aname, authname, NAMESZ);     /* fill in author */
 552:     strncpy (auth.asystem, origsys, HOMESYSSZ);     /* system */
 553:     auth.asystem[HOMESYSSZ - 1] = auth.aname[NAMESZ - 1] = '\0';
 554:     auth.aid = Anonuid;
 555:     status = FRMNEWS;                   /* came through news */
 556:     strncpy (title, header -> title, TITLEN);       /* move new title */
 557:     title[TITLEN - 1] = '\0';               /* sure it stops */
 558: 
 559:     locknf (io, DSCRLOCK);              /* MUTEX */
 560: /*
 561:  *	first thing is to see if it's a base note somewhere.
 562:  */
 563:     strcpy (newsid.sys, newssys);           /* build uniq id */
 564:     strcpy (note.n_id.sys, newssys);            /* build descriptor */
 565:     note.n_id.uniqid = newsid.uniqid = newsseq;
 566:     notenum = chknote (io, &note.n_id, &note2);     /* try normal */
 567:     if (notenum == 0)                   /* try -100 trick */
 568:     {
 569:     note.n_id.uniqid = newsid.uniqid = newsseq * -100;
 570:     notenum = chknote (io, &note.n_id, &note2);
 571:     }
 572:     if (notenum != 0)
 573:     {
 574:     if (!(note2.n_stat & ORPHND))
 575:     {
 576:         printf ("Duplicate news article received\n");
 577:         io -> nnotdrop++;               /* count as dropped */
 578:         unlocknf (io, DSCRLOCK);
 579:         return (0);                 /* done with it */
 580:     }
 581:     /*
 582: 	 *	 replace foster parent
 583: 	 */
 584:     pagein (io, body, &note2.n_addr);       /* collect text */
 585:     gettime (&note2.n_rcvd);            /* current tod */
 586:     gettime (&note2.n_lmod);            /* last touched */
 587:     copyauth (&auth, note2.n_auth);         /* fill in author */
 588:     note2.n_stat |= FRMNEWS;            /* brand it */
 589:     strncpy (note2.ntitle, title, TITLEN);      /* move title */
 590:     note2.n_date = entered;
 591:     strcpy (note2.n_from, fromsys);         /* who sent it to us */
 592:     putnrec (io, notenum, &note2);          /* and replace */
 593:     io -> adopted++;                /* count it */
 594:     io -> nnotrcvd++;               /* count in */
 595:     unlocknf (io, DSCRLOCK);
 596:     printf ("Orphaned Response Chain adopted\n");
 597:     return (notenum);               /* correctly placed */
 598:     }
 599: 
 600: /*
 601:  *	See if we can turn this into a response to some base note.
 602:  *	First priority is to match it to any of the articles listed
 603:  *	in a References field if there is one.
 604:  */
 605: 
 606:     notenum = 0;                    /* init to not found */
 607:     if (header -> followid[0])              /* references */
 608:     {
 609:     trail = header -> followid;
 610:     while ((lead = index (trail, '<')) && (trail = index (lead, '>')))
 611:     {                       /* delimited id */
 612:         i = sscanf (lead, "<%ld@%99[^>]>", &baseseq, field1, pbuf);
 613:         if (i < 2)                  /* try old format */
 614:         i = sscanf (lead, "%99[^.].%ld", field1, &baseseq);
 615:         if (i < 2)
 616:         continue;               /* try next one */
 617:         strncpy (basesys, field1, SYSSZ);
 618:         basesys[SYSSZ - 1] = '\0';          /* and truncate */
 619: 
 620:         strcpy (baseid.sys, basesys);       /* build goal */
 621:         baseid.uniqid = baseseq;            /* try notes source */
 622:         if ((notenum = chknote (io, &baseid, &note2)))/* WANT ASSIGN */
 623:         break;                  /* yes! */
 624: 
 625:         baseid.uniqid = baseseq * -100;     /* try news source */
 626:         if ((notenum = chknote (io, &baseid, &note2)))/* WANT ASSIGN */
 627:         break;                  /* yes! */
 628: 
 629:         notenum = 0;                /* ensure "unfound" */
 630:     }
 631:     }
 632: 
 633: /*
 634:  *	If References did any good, "notenum" is positive non-zero.
 635:  *	Otherwise it didn't help out at all and we have to resort to
 636:  *	parsing the title for "re:" prefixes
 637:  *	If we can find a base title, use the title search code to
 638:  *	scan for it.
 639:  */
 640: 
 641:     if (notenum == 0 &&                 /* not found */
 642:         !strncmp (header -> title, "re: ", 4) ||    /* and looks like */
 643:         !strncmp (header -> title, "Re: ", 4) ||    /* a response */
 644:         !strncmp (header -> title, "RE: ", 4))
 645:     {
 646:     dprintf ("Looking at titles\n");
 647:     p = header -> title;
 648:     do
 649:     {
 650:         for (p += 3; *p == ' ' || *p == '\t'; p++); /* drop spaces */
 651:     } while (!strncmp (p, "re: ", 4) ||
 652:         !strncmp (p, "Re: ", 4) ||
 653:         !strncmp (p, "RE: ", 4));
 654:     strncpy (io -> xstring, p, TITLEN);     /* load it */
 655:     io -> xstring[TITLEN - 1] = '\0';       /* and terminate it */
 656:     notenum = findtitle (io, io -> descr.d_nnote, FALSE);/* start at back */
 657:     if (notenum > 0)                /* found one */
 658:         getnrec (io, notenum, &note2);      /* get a ptr to it */
 659:     }
 660: 
 661: /*
 662:  *	OK. By now, we have a "notenum" if the article can be pegged
 663:  *	as a response to one of our notes.
 664:  *	Otherwise, notenum==0 and we'll have to turn it into
 665:  *	a base note.
 666:  */
 667: 
 668:     if (notenum > 0)
 669:     {
 670:     dprintf ("Looking in response chain for note %d\n", notenum);
 671:     if (!chkresp (io, &newsid, &note2, notenum))
 672:     {                       /* no copy here */
 673:         pagein (io, body, &where);
 674:         gettime (&whentime);
 675:         i = putresp (io, &where, status, notenum, &entered, &auth, &note,
 676:             NOLOCKIT, &newsid, NOADDID, fromsys, ADDTIME, &whentime);
 677:         unlocknf (io, DSCRLOCK);            /* un-MUTEX */
 678:         return (i);
 679:     }
 680:     else
 681:     {                       /* copy there */
 682:         unlocknf (io, DSCRLOCK);            /* all done */
 683:         printf ("Duplicate Response handed back by news\n");
 684:         io -> nrspdrop++;               /* bong it */
 685:         return (0);                 /* count as done */
 686:     }
 687:     }
 688: /*
 689:  *	If we are going to do things this way, here is the point
 690:  *	where we should check about turning a news-generated
 691:  *	article into an orphaned response.
 692:  *
 693:  *	Basically, look for a non-empty references line and
 694:  *	make a foster parent with the first article id on that
 695:  *	line.
 696:  */
 697: 
 698: /*
 699:  *	by this point, it's obvious that we can't turn the note into
 700:  *	a response.  We can skip the check to see if it is already
 701:  *	there because we did that at the very top of this loop
 702:  *	and since we've locked the notesfile up while we're doing this,
 703:  *	we know that nobody added a note.
 704:  */
 705:     dprintf ("Processing article as a base note\n");
 706:     pagein (io, body, &where);
 707:     notenum = putnote (io, &where, title, status, &note,
 708:         &auth, NOPOLICY, NOLOCKIT, NOADDID, fromsys, ADDTIME);
 709:     io -> nnotrcvd++;                   /* count it */
 710:     unlocknf (io, DSCRLOCK);
 711:     return (notenum);
 712: }

Defined functions

bnewsgen defined in line 494; used 1 times
main defined in line 29; never used
nfgen defined in line 197; used 1 times

Defined variables

entered defined in line 21; used 9 times
has_suffix defined in line 24; used 3 times
rcsid defined in line 7; never used
title defined in line 19; used 20 times

Defined macros

MAINLINE defined in line 1; never used
dprintf defined in line 26; used 18 times
Last modified: 1985-10-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1834
Valid CSS Valid XHTML 1.0 Strict