|
|
1.1 ! root 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: ¬e.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, ¬e.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, ¬e.n_id, ¬e2)) == 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, ¬e, &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, ¬e2.n_addr); /* the text */ ! 373: gettime (¬e2.n_rcvd); /* update timestamp */ ! 374: gettime (¬e2.n_lmod); /* time stamp it */ ! 375: copyauth (&auth, ¬e2.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, ¬e2); /* 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, ¬e.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, ¬e.n_id, ¬e2); ! 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: ¬e, ¬e.n_auth, NOPOLICY, NOLOCKIT, NOADDID, ! 455: fromsys, ADDTIME); /* insert him */ ! 456: io -> norphans++; /* orphan census */ ! 457: getnrec (io, notenum, ¬e2); /* 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, ¬e2, notenum) == 0) ! 464: { /* none, insert it */ ! 465: status |= FRMNEWS; ! 466: pagein (io, body, &where); ! 467: i = putresp (io, &where, status, notenum, &entered, &auth, ! 468: ¬e, 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, ¬e.n_id, ¬e2); /* try normal */ ! 567: if (notenum == 0) /* try -100 trick */ ! 568: { ! 569: note.n_id.uniqid = newsid.uniqid = newsseq * -100; ! 570: notenum = chknote (io, ¬e.n_id, ¬e2); ! 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, ¬e2.n_addr); /* collect text */ ! 585: gettime (¬e2.n_rcvd); /* current tod */ ! 586: gettime (¬e2.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, ¬e2); /* 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, ¬e2)))/* WANT ASSIGN */ ! 623: break; /* yes! */ ! 624: ! 625: baseid.uniqid = baseseq * -100; /* try news source */ ! 626: if ((notenum = chknote (io, &baseid, ¬e2)))/* 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, ¬e2); /* 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, ¬e2, notenum)) ! 672: { /* no copy here */ ! 673: pagein (io, body, &where); ! 674: gettime (&whentime); ! 675: i = putresp (io, &where, status, notenum, &entered, &auth, ¬e, ! 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, ¬e, ! 708: &auth, NOPOLICY, NOLOCKIT, NOADDID, fromsys, ADDTIME); ! 709: io -> nnotrcvd++; /* count it */ ! 710: unlocknf (io, DSCRLOCK); ! 711: return (notenum); ! 712: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.