Annotation of 43BSDTahoe/new/notes/src/bnewshead.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * header.c - header functions plus some other goodies
        !             3:  *
        !             4:  *     TAKEN FROM BNEWS 2.10 6/24/83
        !             5:  *
        !             6:  */
        !             7: 
        !             8: #ifdef RCSIDENT
        !             9: static char *SccsId = "@(#)header.c    2.20    6/24/83";
        !            10: static char *RCSid = "$Header: bnewshead.c,v 1.7.0.1 85/03/06 20:03:00 notes Rel $";
        !            11: #endif RCSIDENT
        !            12: 
        !            13: #include <stdio.h>
        !            14: #include <sys/types.h>
        !            15: #include       "parms.h"                               /* from notes */
        !            16: #include       "structs.h"                             /* ditto */
        !            17:                                                        /* above maybe unused */
        !            18: #include       "newsgate.h"
        !            19: 
        !            20: 
        !            21: char   *hfgets ();
        !            22: 
        !            23: static int  seenrelay;
        !            24: static char bfr[PATHLEN];                              /* header buffer */
        !            25: 
        !            26: /*
        !            27:  * Read header from file fp into *hp.  If wholething is FALSE,
        !            28:  * it's an incremental read, otherwise start from scratch.
        !            29:  * Return (FILE *) if header okay, else NULL.
        !            30:  */
        !            31: 
        !            32: newsheader (hp, fp, wholething)
        !            33: register struct hbuf   *hp;
        !            34: FILE * fp;
        !            35: int     wholething;
        !            36: {
        !            37:     register int    len;
        !            38: 
        !            39:     if (wholething)                                    /* from scratch */
        !            40:        bclear ((char *) hp, sizeof (*hp));
        !            41: 
        !            42:     seenrelay = 0;
        !            43: 
        !            44: /*
        !            45:  *     Check that it's a B news style header.
        !            46:  */
        !            47:     if (((hfgets (bfr, PATHLEN, fp) != NULL &&
        !            48:                    *bfr >= 'A' && *bfr <= 'Z') && index (bfr, ':')))
        !            49:        if (frmread (fp, hp))
        !            50:            goto strip;
        !            51: 
        !            52: /*
        !            53:  * It's not.  Try A news (begins with PROTO).
        !            54:  */
        !            55:     if (*bfr != PROTO)
        !            56:        return (0);
        !            57: 
        !            58: /*
        !            59:  *     Read in an A news format article.
        !            60:  */
        !            61:     strncpy (hp -> oident, &(bfr[1]), NAMELEN);                /* file name */
        !            62:     if (!nstrip (hp -> oident))
        !            63:        return (0);
        !            64:     hfgets (hp -> nbuf, BUFLEN, fp);                   /* newsgroup list */
        !            65:     if (!nstrip (hp -> nbuf))
        !            66:        return (0);
        !            67:     ngcat (hp -> nbuf);                                        /* trailing delim */
        !            68:     hfgets (hp -> path, PATHLEN, fp);                  /* source path */
        !            69:     if (!nstrip (hp -> path))
        !            70:        return (0);
        !            71:     hfgets (hp -> subdate, DATELEN, fp);               /* date */
        !            72:     if (!nstrip (hp -> subdate))
        !            73:        return (0);
        !            74:     hfgets (hp -> title, BUFLEN, fp);                  /* title */
        !            75:     if (!nstrip (hp -> title))
        !            76:        return (0);
        !            77: 
        !            78: /*
        !            79:  * strip off sys! from front of path.
        !            80:  */
        !            81: strip: 
        !            82:     strcpy (bfr, System);
        !            83:     if (strncmp (bfr, hp -> path, (len = strlen (bfr))) == 0
        !            84:            && index (NETCHRS, hp -> path[len]))
        !            85:        strcpy (hp -> path, &(hp -> path[len + 1]));
        !            86: 
        !            87:     if (wholething && hp -> from[0] == '\0')           /* intuit the from: */
        !            88:        intuitfrom (hp);                                /* if wasn't there */
        !            89: 
        !            90:     if (wholething)                                    /* Get message ID's. */
        !            91:        fixid (hp);
        !            92:     return (1);
        !            93: }
        !            94: 
        !            95: 
        !            96: /*
        !            97:  * Get header info from mail-format file.
        !            98:  * Return non-zero on success.
        !            99:  */
        !           100: 
        !           101: #include <ctype.h>
        !           102: #define FROM           1
        !           103: #define NEWSGROUP      2
        !           104: #define TITLE          3
        !           105: #define SUBMIT         4
        !           106: #define RECEIVE                5
        !           107: #define EXPIRE         6
        !           108: #define ARTICLEID      7
        !           109: #define MESSAGEID      8
        !           110: #define REPLYTO                9
        !           111: #define FOLLOWID       10
        !           112: #define CONTROL                11
        !           113: #define SENDER         12
        !           114: #define FOLLOWTO       13
        !           115: #define PATH           14
        !           116: #define POSTVERSION    15
        !           117: #define RELAYVERSION   16
        !           118: #define DISTRIBUTION   17
        !           119: #define ORGANIZATION   18
        !           120: #define NUMLINES       19
        !           121: #define KEYWORDS       20
        !           122: #define APPROVED       21
        !           123: 
        !           124: #define        NLINE1          22
        !           125: #define        NLINE2          23
        !           126: 
        !           127: #define OTHER          99
        !           128: 
        !           129: 
        !           130: char   *malloc ();
        !           131: 
        !           132: frmread (fp, hp)
        !           133: register    FILE * fp;
        !           134: register struct hbuf   *hp;
        !           135: {
        !           136:     int     unreccnt = 0;
        !           137:     register int    i;
        !           138:     long    curpos;
        !           139:     int     hdrlineno = 0;
        !           140:     int     iu;
        !           141: 
        !           142:     for (iu = 0; iu < NUNREC; iu++)
        !           143:        hp -> unrec[iu] = NULL;
        !           144: 
        !           145:     i = type (bfr);
        !           146:     do
        !           147:     {
        !           148:        curpos = ftell (fp);
        !           149:        hdrlineno++;
        !           150:        switch (i)
        !           151:        {
        !           152:            case PATH: 
        !           153:                getfield (hp -> path);
        !           154:                break;
        !           155:            case FROM: 
        !           156:                getfield (hp -> from);
        !           157:                break;
        !           158:            case NEWSGROUP: 
        !           159:                getfield (hp -> nbuf);
        !           160:                break;
        !           161:            case TITLE: 
        !           162:                getfield (hp -> title);
        !           163:                break;
        !           164:            case SUBMIT: 
        !           165:                getfield (hp -> subdate);
        !           166:                break;
        !           167:            case RECEIVE: 
        !           168:                getfield (hp -> recdate);
        !           169:                break;
        !           170:            case EXPIRE: 
        !           171:                getfield (hp -> expdate);
        !           172:                break;
        !           173:            case ARTICLEID: 
        !           174:                getfield (hp -> oident);
        !           175:                break;
        !           176:            case MESSAGEID: 
        !           177:                getfield (hp -> ident);
        !           178:                break;
        !           179:            case REPLYTO: 
        !           180:                getfield (hp -> replyto);
        !           181:                break;
        !           182:            case FOLLOWID: 
        !           183:                getfield (hp -> followid);
        !           184:                break;
        !           185:            case SENDER: 
        !           186:                getfield (hp -> sender);
        !           187:                break;
        !           188:            case FOLLOWTO: 
        !           189:                getfield (hp -> followto);
        !           190:                break;
        !           191:            case CONTROL: 
        !           192:                getfield (hp -> ctlmsg);
        !           193:                break;
        !           194:            case POSTVERSION: 
        !           195:                getfield (hp -> postversion);
        !           196:                break;
        !           197:            case DISTRIBUTION: 
        !           198:                getfield (hp -> distribution);
        !           199:                break;
        !           200:            case ORGANIZATION: 
        !           201:                getfield (hp -> organization);
        !           202:                break;
        !           203:            case NUMLINES: 
        !           204:                getfield (hp -> numlines);
        !           205:                hp -> intnumlines = atoi (hp -> numlines);
        !           206:                break;
        !           207:            case KEYWORDS: 
        !           208:                getfield (hp -> keywords);
        !           209:                break;
        !           210:            case APPROVED: 
        !           211:                getfield (hp -> approved);
        !           212:                break;
        !           213:            case NLINE1:                                /* notes-specific */
        !           214:                getfield (hp -> nline1);
        !           215:                break;
        !           216:            case NLINE2:                                /* notes-specific */
        !           217:                getfield (hp -> nline2);
        !           218:                break;
        !           219:            case RELAYVERSION: 
        !           220:                /* 
        !           221:                 * Only believe a relay version if it's the first
        !           222:                 * line, otherwise it probably got passed through
        !           223:                 * by some old neighbor.
        !           224:                 */
        !           225:                if (hdrlineno == 1)
        !           226:                {
        !           227:                    getfield (hp -> relayversion);
        !           228:                    seenrelay = 1;
        !           229:                }
        !           230:                break;
        !           231:            case OTHER: 
        !           232:                if (unreccnt < NUNREC)
        !           233:                {
        !           234:                    hp -> unrec[unreccnt] = malloc (strlen (bfr) + 1);
        !           235:                    strcpy (hp -> unrec[unreccnt], bfr);
        !           236:                    unreccnt++;
        !           237:                }
        !           238:                break;
        !           239:        }
        !           240:     } while ((i = type (hfgets (bfr, LBUFLEN, fp))) > 0);
        !           241: 
        !           242:     if (*bfr != '\n')
        !           243:     {
        !           244:        printf ("Bizzaro header line: %s\n", bfr);
        !           245:        return (0);
        !           246:     }
        !           247: 
        !           248: /*
        !           249:  *     Check to see if the REQUIRED headers are present.  If so, return
        !           250:  *     that we found a message. Otherwise barf.
        !           251:  */
        !           252:     if ((hp -> from[0] || hp -> path[0]) &&
        !           253:            hp -> subdate[0] &&
        !           254:            (hp -> ident[0] || hp -> oident[0]))
        !           255:     {
        !           256:        return TRUE;
        !           257:     }
        !           258:     return FALSE;
        !           259: }
        !           260: 
        !           261: /*
        !           262:  * There was no From: line in the message (because it was generated by
        !           263:  * an old news program).  Guess what it should have been and create it.
        !           264:  */
        !           265: 
        !           266: intuitfrom (hp)
        !           267: register struct hbuf   *hp;
        !           268: {
        !           269:     char   *tp;
        !           270:     char   *user,
        !           271:            *host,
        !           272:            *fullname;
        !           273:     char   *tailpath ();
        !           274:     char   *at,
        !           275:            *dot;
        !           276: 
        !           277:     tp = tailpath (hp);
        !           278:     user = rindex (tp, '!');
        !           279:     if (user == NULL)
        !           280:        user = tp;
        !           281:     else
        !           282:        *user++ = '\0';
        !           283: 
        !           284:     /* Check for an existing Internet address on the end. */
        !           285:     at = index (user, '@');
        !           286:     if (at)
        !           287:     {
        !           288:        dot = index (at, '.');
        !           289:        if (dot)
        !           290:        {
        !           291:            strcpy (hp -> from, user);
        !           292:            return;
        !           293:        }
        !           294: /* @ signs are illegal except for the biggie, so */
        !           295:        *at = '%';
        !           296:     }
        !           297: 
        !           298:     if (tp[0] == '.')
        !           299:        host = index (tp, '!') + 1;
        !           300:     else
        !           301:        if (user == tp)
        !           302:            host = System;
        !           303:        else
        !           304:            host = tp;
        !           305: 
        !           306:     tp = index (host, '@');
        !           307:     if (tp != NULL)
        !           308:        *tp = 0;
        !           309:     sprintf (hp -> from, "%s@%s.%s", user, host, DFLTDOMAIN);
        !           310: 
        !           311:     fullname = index (hp -> path, '(');
        !           312:     if (fullname != NULL)
        !           313:     {
        !           314:        fullname--;
        !           315:        strcat (hp -> from, fullname);
        !           316:        *fullname = 0;
        !           317:     }
        !           318: }
        !           319: 
        !           320: /*
        !           321:  * If the message has only one of ident/oident, guess what
        !           322:  * the other one should be and fill them both in.
        !           323:  */
        !           324: 
        !           325: fixid (hp)
        !           326: register struct hbuf   *hp;
        !           327: {
        !           328:     char    lbuf[100];
        !           329:     char   *p;
        !           330: #ifdef OLD
        !           331:     char   *q;
        !           332: #endif OLD
        !           333: 
        !           334:     if (hp -> ident[0] == '\0' && hp -> oident[0] != '\0')
        !           335:     {
        !           336:        strcpy (lbuf, hp -> oident);
        !           337:        p = index (lbuf, '.');
        !           338:        if (p == 0)
        !           339:        {
        !           340:            strcpy (hp -> ident, hp -> oident);
        !           341:            return;
        !           342:        }
        !           343:        *p++ = '\0';
        !           344:        /* 
        !           345:         * It may seem strange that we hardwire ".UUCP" in
        !           346:         * here instead of DFLTDOMAIN.  However, we are trying
        !           347:         * to guess what the domain was on the posting system,
        !           348:         * not the local system.  Since we don't really know
        !           349:         * what the posting system does, we just go with the
        !           350:         * majority - almost everyone will be a .UUCP if they
        !           351:         * didn't fill in their Message-ID.
        !           352:         */
        !           353:        sprintf (hp -> ident, "<%s@%s%s>", p, lbuf, ".UUCP");
        !           354:     }
        !           355: 
        !           356: #ifdef OLD
        !           357:     if (hp -> oident[0] == '\0' && hp -> ident[0] != '\0')
        !           358:     {
        !           359:        strcpy (lbuf, hp -> ident);
        !           360:        p = index (lbuf, '@');
        !           361:        if (p == 0)
        !           362:        {
        !           363:            strcpy (hp -> oident, hp -> ident);
        !           364:            return;
        !           365:        }
        !           366:        *p++ = '\0';
        !           367:        q = index (p, '.');
        !           368:        if (!q)
        !           369:            q = index (p, '>');
        !           370:        if (q)
        !           371:            *q++ = '\0';
        !           372:        p[SNLN] = '\0';
        !           373:        sprintf (hp -> oident, "%s.%s", p, lbuf + 1);
        !           374:     }
        !           375: #endif
        !           376: }
        !           377: 
        !           378: /*
        !           379:  * Get the given field of a header (char * parm) from bfr, but only
        !           380:  * if there's something actually there (after the colon).  Don't
        !           381:  * bother if we already have an entry for this field.
        !           382:  */
        !           383: 
        !           384: getfield (hpfield)
        !           385: char   *hpfield;
        !           386: {
        !           387:     char   *ptr;
        !           388: 
        !           389:     if (hpfield[0])
        !           390:        return;
        !           391:     for (ptr = index (bfr, ':'); isspace (*++ptr);)
        !           392:        ;
        !           393:     if (*ptr != '\0')
        !           394:     {
        !           395:        strcpy (hpfield, ptr);
        !           396:        nstrip (hpfield);
        !           397:     }
        !           398:     return;
        !           399: }
        !           400: 
        !           401: 
        !           402: /*
        !           403:  *     Determine the type of the header
        !           404:  */
        !           405: 
        !           406: #define        its(type) (!strncmp(ptr,type,strlen(type)))
        !           407: 
        !           408: type (ptr)
        !           409: char   *ptr;
        !           410: {
        !           411:     char   *colon,
        !           412:            *space;
        !           413: 
        !           414:     if (!isalpha (*ptr) && strncmp (ptr, "From ", 5))
        !           415:        return FALSE;
        !           416:     colon = index (ptr, ':');
        !           417:     space = index (ptr, ' ');
        !           418:     if (!colon || colon + 1 != space)
        !           419:        return FALSE;
        !           420:     if (its ("From: "))
        !           421:        if (index (ptr, '@') && !index (ptr, '!') && seenrelay)
        !           422:            return FROM;
        !           423:        else
        !           424:            return PATH;
        !           425:     if (its ("Path: "))
        !           426:        return PATH;
        !           427:     if (its ("Newsgroups: "))
        !           428:        return NEWSGROUP;
        !           429:     if (its ("Subject: ") || its ("Title: "))
        !           430:        return TITLE;
        !           431:     if (its ("Posted: ") || its ("Date: "))
        !           432:        return SUBMIT;
        !           433:     if (its ("Date-Received: ") || its ("Received: "))
        !           434:        return RECEIVE;
        !           435:     if (its ("Expires: "))
        !           436:        return EXPIRE;
        !           437:     if (its ("Article-I.D.: "))
        !           438:        return ARTICLEID;
        !           439:     if (its ("Message-ID: "))
        !           440:        return MESSAGEID;
        !           441:     if (its ("Reply-To: "))
        !           442:        return REPLYTO;
        !           443:     if (its ("References: "))
        !           444:        return FOLLOWID;
        !           445:     if (its ("Control: "))
        !           446:        return CONTROL;
        !           447:     if (its ("Sender: "))
        !           448:        return SENDER;
        !           449:     if (its ("Followup-To: "))
        !           450:        return FOLLOWTO;
        !           451:     if (its ("Posting-Version: "))
        !           452:        return POSTVERSION;
        !           453:     if (its ("Relay-Version: "))
        !           454:        return RELAYVERSION;
        !           455:     if (its ("Distribution: "))
        !           456:        return DISTRIBUTION;
        !           457:     if (its ("Organization: "))
        !           458:        return ORGANIZATION;
        !           459:     if (its ("Lines: "))
        !           460:        return NUMLINES;
        !           461:     if (its ("Keywords: "))
        !           462:        return KEYWORDS;
        !           463:     if (its ("Approved: "))
        !           464:        return APPROVED;
        !           465:     if (its ("Nf-ID: "))
        !           466:        return NLINE1;
        !           467:     if (its ("Nf-From: "))
        !           468:        return NLINE2;
        !           469:     return OTHER;
        !           470: }
        !           471: 
        !           472: /*
        !           473:  * Set nc bytes, starting at cp, to zero.
        !           474:  */
        !           475: 
        !           476: bclear (cp, nc)
        !           477: register char  *cp;
        !           478: register int    nc;
        !           479: {
        !           480:     while (nc--)
        !           481:        *cp++ = 0;
        !           482: }
        !           483: 
        !           484: /*
        !           485:  * Strip trailing newlines, blanks, and tabs from 's'.
        !           486:  * Return TRUE if newline was found, else FALSE.
        !           487:  */
        !           488: 
        !           489: nstrip (s)
        !           490: register char  *s;
        !           491: {
        !           492:     register char  *p;
        !           493:     register int    rc;
        !           494: 
        !           495:     rc = FALSE;
        !           496:     p = s;
        !           497:     while (*p)
        !           498:        if (*p++ == '\n')
        !           499:            rc = TRUE;
        !           500:     while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t'));
        !           501:     *++p = '\0';
        !           502:     return (rc);
        !           503: }
        !           504: 
        !           505: /*
        !           506:  * Append NGDELIM to string.
        !           507:  */
        !           508: 
        !           509: ngcat (s)
        !           510: register char  *s;
        !           511: {
        !           512:     if (*s)
        !           513:     {
        !           514:        while (*s++);
        !           515:        s -= 2;
        !           516:        if (*s++ == NGDELIM)
        !           517:            return;
        !           518:     }
        !           519:     *s++ = NGDELIM;
        !           520:     *s = '\0';
        !           521: }
        !           522: 
        !           523: /*
        !           524:  * Return a compact representation of the person who posted the given
        !           525:  * message.  A sender or internet name will be used, otherwise
        !           526:  * the last part of the path is used preceeded by an optional ".."
        !           527:  */
        !           528: char   *
        !           529:         tailpath (hp)
        !           530: struct hbuf *hp;
        !           531: {
        !           532:     char   *p,
        !           533:            *r;
        !           534:     static char resultbuf[BUFLEN];
        !           535:     char    pathbuf[PATHLEN];
        !           536:     char   *malloc ();
        !           537: 
        !           538:     /* 
        !           539:      * This only happens for articles posted by old news software
        !           540:      * in non-internet format.
        !           541:      */
        !           542:     resultbuf[0] = '\0';
        !           543:     strcpy (pathbuf, hp -> path);
        !           544:     p = index (pathbuf, ' ');
        !           545:     if (p)
        !           546:        *p = '\0';                                      /* Chop off trailing " (name)" */
        !           547:     r = rindex (pathbuf, '!');
        !           548:     if (r == 0)
        !           549:     {
        !           550:        r = pathbuf;
        !           551:     }
        !           552:     else
        !           553:     {
        !           554:        while (r > pathbuf && *--r != '!')
        !           555:            ;
        !           556:        if (r > pathbuf)
        !           557:        {
        !           558:            r++;
        !           559:            strcpy (resultbuf, "..!");
        !           560:        }
        !           561:     }
        !           562:     strcat (resultbuf, r);
        !           563:     return resultbuf;
        !           564: }
        !           565: 
        !           566: 
        !           567: 
        !           568: /*
        !           569:  * hfgets is like fgets, but deals with continuation lines.
        !           570:  * It also ensures that even if a line that is too long is
        !           571:  * received, the remainder of the line is thrown away
        !           572:  * instead of treated like a second line.
        !           573:  */
        !           574: 
        !           575: char   *hfgets (buf, len, fp)
        !           576: char   *buf;
        !           577: int     len;
        !           578: FILE * fp;
        !           579: {
        !           580:     register int    c;
        !           581:     register char  *cp,
        !           582:                    *tp;
        !           583: 
        !           584:     cp = fgets (buf, len, fp);
        !           585:     if (cp == NULL)
        !           586:        return NULL;
        !           587: 
        !           588:     tp = cp + strlen (cp);
        !           589:     if (tp[-1] != '\n')
        !           590:     {
        !           591:        /* 
        !           592:         * Line too long - part read didn't fit into a newline
        !           593:         */
        !           594:        while ((c = getc (fp)) != '\n' && c != EOF)
        !           595:            ;
        !           596:     }
        !           597:     else
        !           598:        *--tp = '\0';                                   /* clobber newline */
        !           599: 
        !           600:     while ((c = getc (fp)) == ' ' || c == '\t')                /* continuation */
        !           601:     {
        !           602:        /* 
        !           603:         * Continuation line.
        !           604:         */
        !           605:        while ((c = getc (fp)) == ' ' || c == '\t')     /* skip white space */
        !           606:            ;
        !           607:        if (tp - cp < len)
        !           608:        {
        !           609:            *tp++ = ' ';
        !           610:            *tp++ = c;
        !           611:        }
        !           612:        while ((c = getc (fp)) != '\n' && c != EOF)
        !           613:            if (tp - cp < len)
        !           614:                *tp++ = c;
        !           615:     }
        !           616:     *tp++ = '\n';
        !           617:     *tp++ = '\0';
        !           618:     if (c != EOF)
        !           619:        ungetc (c, fp);                                 /* push back char */
        !           620:     return cp;
        !           621: }

unix.superglobalmegacorp.com

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