|
|
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.