Annotation of 43BSDTahoe/new/notes/src/newsinput.c, revision 1.1.1.1

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:                        &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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.