Annotation of 43BSD/contrib/news/src/header.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * This software is Copyright (c) 1986 by Rick Adams.
        !             3:  *
        !             4:  * Permission is hereby granted to copy, reproduce, redistribute or
        !             5:  * otherwise use this software as long as: there is no monetary
        !             6:  * profit gained specifically from the use or reproduction or this
        !             7:  * software, it is not sold, rented, traded or otherwise marketed, and
        !             8:  * this copyright notice is included prominently in any copy
        !             9:  * made.
        !            10:  *
        !            11:  * The author make no claims as to the fitness or correctness of
        !            12:  * this software for any use whatsoever, and it is provided as is. 
        !            13:  * Any use of this software is at the user's own risk.
        !            14:  *
        !            15:  * header.c - header functions plus some other goodies
        !            16:  */
        !            17: 
        !            18: #ifdef SCCSID
        !            19: static char    *SccsId = "@(#)header.c 2.41    3/19/86";
        !            20: #endif /* SCCSID */
        !            21: 
        !            22: #include <stdio.h>
        !            23: #include "params.h"
        !            24: 
        !            25: char *hfgets();
        !            26: 
        !            27: char *news_version = NEWS_VERSION;
        !            28: 
        !            29: /*
        !            30:  * Read header from file fp into *hp.  If wholething is FALSE,
        !            31:  * it's an incremental read, otherwise start from scratch.
        !            32:  * Return (FILE *) if header okay, else NULL.
        !            33:  */
        !            34: FILE *
        !            35: hread(hp, fp, wholething)
        !            36: register struct hbuf *hp;
        !            37: FILE *fp;
        !            38: int wholething;
        !            39: {
        !            40:        register int    len;
        !            41:        register int    i;
        !            42: #ifdef OLD
        !            43:        char *p;
        !            44: #endif /* OLD */
        !            45: 
        !            46:        if (wholething) {
        !            47:                for(i=0;i<NUNREC;i++)
        !            48:                        if (hp->unrec[i] != NULL)
        !            49:                                free(hp->unrec[i]);
        !            50:                        else
        !            51:                                break;
        !            52:                bzero((char *)hp, sizeof (*hp));
        !            53:                for (i=0;i<NUNREC;i++)
        !            54:                        hp->unrec[i] = NULL;
        !            55:        }
        !            56: 
        !            57:        /* Check that it's a B news style header. */
        !            58:        if (hfgets(bfr, PATHLEN, fp) != NULL && isalpha(bfr[0])
        !            59:            && index(bfr, ':'))
        !            60:                if (frmread(fp, hp))
        !            61:                        goto strip;
        !            62: 
        !            63:        if (!nstrip(bfr+1))
        !            64:                return NULL;
        !            65: 
        !            66:        /* It's not.  Try A news (begins with PROTO). */
        !            67:        if (bfr[0] != PROTO)
        !            68:                return NULL;
        !            69: #ifndef OLD
        !            70:        logerr("Can not process A news format article without OLD defined");
        !            71: #else /* OLD */
        !            72:        /* Read in an A news format article. */
        !            73:        p = index(bfr+1, '.');
        !            74:        if (p == NULL) {
        !            75:                (void) strcpy(hp->ident, bfr+1);
        !            76:                return NULL;
        !            77:        }
        !            78:        *p++ = '\0';
        !            79:        (void) sprintf(hp->ident, "<%s@%s%s>", p, bfr+1, ".UUCP");
        !            80: 
        !            81:        /* Newsgroup List */
        !            82:        if (hfgets(hp->nbuf, BUFLEN, fp) == NULL || !nstrip(hp->nbuf))
        !            83:                return NULL;
        !            84:        /* source path */
        !            85:        if (hfgets(hp->path, PATHLEN, fp) == NULL || !nstrip(hp->path))
        !            86:                return NULL;
        !            87:        /* date */
        !            88:        if (hfgets(hp->subdate, DATELEN, fp) == NULL || !nstrip(hp->subdate))
        !            89:                return NULL;
        !            90:        /* title */
        !            91:        if (hfgets(hp->title, BUFLEN, fp) == NULL || !nstrip(hp->title))
        !            92:                return NULL;
        !            93: #endif /* OLD */
        !            94: 
        !            95: strip: /* strip off sys! from front of path. */
        !            96:        if (strncmp(FULLSYSNAME, hp->path, (len = strlen(FULLSYSNAME))) == 0
        !            97:                && index(NETCHRS, hp->path[len]))
        !            98:                (void) strcpy(hp->path, &(hp->path[len+1]));
        !            99:        lcase(hp->nbuf);
        !           100: 
        !           101:        /* Intuit the From: line if only a path was given. */
        !           102:        if (wholething) {
        !           103: #ifdef OLD
        !           104:                if (hp->from[0] == '\0')
        !           105:                        intuitfrom(hp);
        !           106:                else
        !           107: #endif /* OLD */
        !           108:                        fixfrom(hp);
        !           109:        }
        !           110: 
        !           111:        return fp;
        !           112: }
        !           113: 
        !           114: 
        !           115: /*
        !           116:  * Get header info from mail-format file.
        !           117:  * Return non-zero on success.
        !           118:  */
        !           119: #include <ctype.h>
        !           120: #define FROM           1
        !           121: #define NEWSGROUP      2
        !           122: #define TITLE          3
        !           123: #define SUBMIT         4
        !           124: #define RECEIVE                5
        !           125: #define EXPIRE         6
        !           126: #define ARTICLEID      7
        !           127: #define MESSAGEID      8
        !           128: #define REPLYTO                9
        !           129: #define FOLLOWID       10
        !           130: #define CONTROL                11
        !           131: #define SENDER         12
        !           132: #define FOLLOWTO       13
        !           133: #define PATH           14
        !           134: #define POSTVERSION    15
        !           135: #define RELAYVERSION   16
        !           136: #define DISTRIBUTION   17
        !           137: #define ORGANIZATION   18
        !           138: #define NUMLINES       19
        !           139: #define KEYWORDS       20
        !           140: #define APPROVED       21
        !           141: #define NFID           22
        !           142: #define NFFROM         23
        !           143: #define XREF           24
        !           144: #define SUMMARY                25
        !           145: #define XPATH          26
        !           146: #define OTHER          99
        !           147: 
        !           148: char *malloc();
        !           149: 
        !           150: frmread(fp, hp)
        !           151: register FILE *fp;
        !           152: register struct hbuf *hp;
        !           153: {
        !           154:        int     unreccnt = 0;
        !           155:        register int    i;
        !           156:        long    curpos;
        !           157: 
        !           158:        i = type(bfr);
        !           159:        do {
        !           160:                curpos = ftell(fp);
        !           161:                switch (i) {
        !           162:                case PATH:
        !           163:                        getfield(hp->path, sizeof(hp->path));
        !           164:                        break;
        !           165:                case FROM:
        !           166:                        getfield(hp->from, sizeof(hp->from));
        !           167:                        break;
        !           168:                case NEWSGROUP:
        !           169:                        getfield(hp->nbuf, sizeof(hp->nbuf));
        !           170:                        break;
        !           171:                case TITLE:
        !           172:                        getfield(hp->title, sizeof(hp->title));
        !           173:                        break;
        !           174:                case SUBMIT:
        !           175:                        getfield(hp->subdate, sizeof(hp->subdate));
        !           176:                        break;
        !           177:                case EXPIRE:
        !           178:                        getfield(hp->expdate, sizeof(hp->expdate));
        !           179:                        break;
        !           180: #ifdef OLD
        !           181:                case ARTICLEID:
        !           182:                        /* Believe Message-ID in preference to Article-ID */
        !           183:                        if (hp->ident[0] == '\0') {
        !           184:                                register char *p;
        !           185:                                char msgb[NAMELEN];
        !           186:                                getfield(msgb, sizeof msgb);
        !           187:                                p = index(msgb, '.');
        !           188:                                if (p == NULL) {
        !           189:                                        (void) strcpy(hp->ident, msgb);
        !           190:                                } else {
        !           191:                                        *p++ = '\0';
        !           192:                                        (void) sprintf(hp->ident, "<%s@%s%s>", p, msgb, ".UUCP");
        !           193:                                }
        !           194:                        }
        !           195:                        break;
        !           196: #endif /* OLD */
        !           197:                case MESSAGEID:
        !           198:                        getfield(hp->ident, sizeof(hp->ident));
        !           199:                        break;
        !           200:                case REPLYTO:
        !           201:                        getfield(hp->replyto, sizeof(hp->replyto));
        !           202:                        break;
        !           203:                case FOLLOWID:
        !           204:                        getfield(hp->followid, sizeof(hp->followid));
        !           205:                        break;
        !           206:                case SENDER:
        !           207:                        getfield(hp->sender, sizeof(hp->sender));
        !           208:                        break;
        !           209:                case FOLLOWTO:
        !           210:                        getfield(hp->followto, sizeof(hp->followto));
        !           211:                        break;
        !           212:                case CONTROL:
        !           213:                        getfield(hp->ctlmsg, sizeof(hp->ctlmsg));
        !           214:                        break;
        !           215:                case DISTRIBUTION:
        !           216:                        getfield(hp->distribution, sizeof(hp->distribution));
        !           217:                        break;
        !           218:                case ORGANIZATION:
        !           219:                        getfield(hp->organization, sizeof(hp->organization));
        !           220:                        break;
        !           221:                case NUMLINES:
        !           222:                        getfield(hp->numlines, sizeof(hp->numlines));
        !           223:                        hp->intnumlines = atoi(hp->numlines);
        !           224:                        break;
        !           225:                case KEYWORDS:
        !           226:                        getfield(hp->keywords, sizeof(hp->keywords));
        !           227:                        break;
        !           228:                case APPROVED:
        !           229:                        getfield(hp->approved, sizeof(hp->approved));
        !           230:                        break;
        !           231:                case NFID:
        !           232:                        getfield(hp->nf_id, sizeof(hp->nf_id));
        !           233:                        break;
        !           234:                case NFFROM:
        !           235:                        getfield(hp->nf_from, sizeof(hp->nf_from));
        !           236:                        break;
        !           237:                /* discard these lines */
        !           238:                case XREF:
        !           239:                case XPATH:
        !           240:                case RELAYVERSION:
        !           241:                case POSTVERSION:
        !           242:                case RECEIVE:
        !           243:                        break;
        !           244:                case SUMMARY:
        !           245:                        getfield(hp->summary, sizeof(hp->summary));
        !           246:                        break;
        !           247:                case OTHER:
        !           248:                        if (unreccnt < NUNREC) {
        !           249:                                if ((hp->unrec[unreccnt] = malloc((unsigned)(strlen(bfr) + 1))) != NULL ) {
        !           250:                                        (void) strcpy(hp->unrec[unreccnt], bfr);
        !           251:                                        (void) nstrip(hp->unrec[unreccnt]);
        !           252:                                        unreccnt++;
        !           253:                                } else
        !           254:                                        xerror("frmread: out of memory");
        !           255:                        }
        !           256:                        break;
        !           257:                }
        !           258:        } while ((i = type(hfgets(bfr, LBUFLEN, fp))) > 0);
        !           259: 
        !           260:        if (*bfr != '\n')
        !           261:                fseek(fp, curpos, 0);
        !           262:        if ((hp->from[0] || hp->path[0]) && hp->subdate[0] && hp->ident[0])
        !           263:                return TRUE;
        !           264:        return FALSE;
        !           265: }
        !           266: 
        !           267: #ifdef OLD
        !           268: /*
        !           269:  * There was no From: line in the message (because it was generated by
        !           270:  * an old news program).  Guess what it should have been and create it.
        !           271:  */
        !           272: intuitfrom(hp)
        !           273: register struct hbuf *hp;
        !           274: {
        !           275:        char *tp;
        !           276:        char *user, *host;
        !           277:        char *tailpath(), *rindex();
        !           278:        char *at, *dot;
        !           279:        char pathbuf[PATHLEN];
        !           280:        char fullname[BUFLEN];
        !           281: 
        !           282:        tp = tailpath(hp);
        !           283:        user = rindex(tp, '!');
        !           284:        if (user == NULL)
        !           285:                user = tp;
        !           286:        else
        !           287:                *user++ = '\0';
        !           288: 
        !           289:        /* Check for an existing Internet address on the end. */
        !           290:        at = index(user, '@');
        !           291:        if (at) {
        !           292:                dot = index(at, '.');
        !           293:                if (dot) {
        !           294:                        (void) strcpy(hp->from, user);
        !           295:                        return;
        !           296:                }
        !           297:                /* @ signs are illegal except for the biggie, so */
        !           298:                *at = '%';
        !           299:        }
        !           300: 
        !           301:        if (tp[0] == '.')
        !           302:                host = index(tp, '!') + 1;
        !           303:        else if (user == tp)
        !           304:                host = FULLSYSNAME;
        !           305:        else
        !           306:                host = tp;
        !           307: 
        !           308:        tp = index(host, '@');
        !           309:        if (tp != NULL)
        !           310:                *tp = 0;
        !           311:        (void) sprintf(hp->from, "%s@%s%s", user, host, MYDOMAIN);
        !           312: 
        !           313:        skin(pathbuf, fullname, hp->path);      /* remove RFC822-style comments */
        !           314:        if (fullname[0] != '\0') {
        !           315:                strcat(hp->from, " (");
        !           316:                (void) strcat(hp->from, fullname);
        !           317:                strcat(hp->from, ")");
        !           318:        }
        !           319:        strcpy(hp->path, pathbuf);      /* and stick it back in */
        !           320: }
        !           321: #endif /* OLD */
        !           322: 
        !           323: /*
        !           324:  * Canonicalize the "From:" line into the form
        !           325:  *
        !           326:  * From: <mail-address> (full-name)
        !           327:  *
        !           328:  * RFC822 doesn't require the comment to be at the end of the string
        !           329:  * like that.
        !           330:  */
        !           331: fixfrom(hp)
        !           332: register struct hbuf *hp;
        !           333: {
        !           334:        char frombuf[PATHLEN];
        !           335:        char fullname[BUFLEN];
        !           336: 
        !           337:        skin(frombuf, fullname, hp->from);      /* remove RFC822-style comments */
        !           338:        if (fullname[0] != '\0') {
        !           339:                strcat(frombuf, " (");
        !           340:                strcat(frombuf, fullname);
        !           341:                strcat(frombuf, ")");
        !           342:        }
        !           343:        strcpy(hp->from, frombuf);      /* stick the canonicalized "from" back in */
        !           344: }
        !           345: 
        !           346: skin(name, fullname, hfield)
        !           347: char *name;
        !           348: char *fullname;
        !           349: char *hfield;
        !           350: {
        !           351:        register int c;
        !           352:        register char *cp, *cp2;
        !           353:        char *bufend;
        !           354:        int gotlt, parenlev, lastsp;
        !           355:        int seenfullname = FALSE;
        !           356: 
        !           357:        *fullname = '\0';       /* no full name yet */
        !           358:        if (strpbrk(hfield, "(< ") == NULL) {           /* include ',' ?? */
        !           359:                strcpy(name, hfield);
        !           360:                return;
        !           361:        }
        !           362:        gotlt = 0;
        !           363:        parenlev = 0;
        !           364:        lastsp = 0;
        !           365:        bufend = name;
        !           366:        for (cp = hfield, cp2 = bufend; c = *cp++; ) {
        !           367:                switch (c) {
        !           368:                case '(':
        !           369:                        /*
        !           370:                         * Start of a "comment".
        !           371:                         * Ignore it, or save it in "fullname" if we haven't
        !           372:                         * seen a comment yet.
        !           373:                         */
        !           374:                        parenlev++;
        !           375:                        while ((c = *cp) != 0) {
        !           376:                                cp++;
        !           377:                                switch (c) {
        !           378:                                case '\\':
        !           379:                                        if ((c = *cp) == 0)
        !           380:                                                goto outcm;
        !           381:                                        cp++;
        !           382:                                        break;
        !           383:                                case '(':
        !           384:                                        parenlev++;
        !           385:                                        break;
        !           386:                                case ')':
        !           387:                                        parenlev--;
        !           388:                                        if (parenlev == 0)
        !           389:                                                goto outcm;
        !           390:                                        break;
        !           391:                                }
        !           392:                                if (!seenfullname)
        !           393:                                        *fullname++ = c;
        !           394:                        }
        !           395:                outcm:
        !           396:                        parenlev = 0;
        !           397:                        lastsp = 0;
        !           398:                        if (!seenfullname) {
        !           399:                                *fullname = '\0';
        !           400:                                seenfullname = TRUE;    /* only extract first comment */
        !           401:                        }
        !           402:                        break;
        !           403: 
        !           404:                case '"':
        !           405:                        /*
        !           406:                         * Start of a "quoted-string".
        !           407:                         * Copy it in its entirety.
        !           408:                         */
        !           409:                        while ((c = *cp) != 0) {
        !           410:                                cp++;
        !           411:                                switch (c) {
        !           412:                                case '\\':
        !           413:                                        if ((c = *cp) == 0)
        !           414:                                                goto outqs;
        !           415:                                        cp++;
        !           416:                                        break;
        !           417:                                case '"':
        !           418:                                        goto outqs;
        !           419:                                }
        !           420:                                *cp2++ = c;
        !           421:                        }
        !           422:                outqs:
        !           423:                        lastsp = 0;
        !           424:                        break;
        !           425: 
        !           426:                case ' ':
        !           427:                        if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ')
        !           428:                                cp += 3, *cp2++ = '@';
        !           429:                        else
        !           430:                        if (cp[0] == '@' && cp[1] == ' ')
        !           431:                                cp += 2, *cp2++ = '@';
        !           432:                        else
        !           433:                                lastsp = 1;
        !           434:                        break;
        !           435: 
        !           436:                case '<':
        !           437:                        if (!seenfullname) {
        !           438:                                *cp2 = '\0';
        !           439:                                strcpy(fullname, name);
        !           440:                                seenfullname = TRUE;
        !           441:                        }
        !           442:                        cp2 = bufend;
        !           443:                        gotlt++;
        !           444:                        lastsp = 0;
        !           445:                        break;
        !           446: 
        !           447:                case '>':
        !           448:                        if (gotlt) {
        !           449:                                gotlt = 0;
        !           450:                                /*
        !           451:                                 * this doesn't seem reasonable, what about (,)
        !           452:                                 * or "," ??
        !           453:                                 */
        !           454:                                while (*cp != ',' && *cp != 0)
        !           455:                                        cp++;
        !           456:                                if (*cp == 0 )
        !           457:                                        goto done;
        !           458:                                *cp2++ = ',';
        !           459:                                *cp2++ = ' ';
        !           460:                                bufend = cp2;
        !           461:                                break;
        !           462:                        }
        !           463: 
        !           464:                        /* Fall into . . . */
        !           465: 
        !           466:                default:
        !           467:                        if (lastsp) {
        !           468:                                lastsp = 0;
        !           469:                                *cp2++ = ' ';
        !           470:                        }
        !           471:                        *cp2++ = c;
        !           472:                        break;
        !           473:                }
        !           474:        }
        !           475: done:
        !           476:        *cp2 = 0;
        !           477: }
        !           478: 
        !           479: 
        !           480: #ifdef OLD
        !           481: char *
        !           482: oident(ident)
        !           483: char *ident;
        !           484: {
        !           485:        char lbuf[BUFLEN];
        !           486:        static char oidbuf[BUFLEN];
        !           487:        register char *p, *q;
        !           488: 
        !           489:        (void) strcpy(lbuf, ident);
        !           490:        p = index(lbuf, '@');
        !           491:        if (p == NULL)
        !           492:                return ident;
        !           493:        *p++ = '\0';
        !           494:        q = index(p, '.');
        !           495:        if (q == NULL)
        !           496:                q = index(p, '>');
        !           497:        if (q)
        !           498:                *q++ = '\0';
        !           499:        p[SNLN] = '\0';
        !           500:        (void) sprintf(oidbuf, "%s.%s", p, lbuf+1);
        !           501:        return oidbuf;
        !           502: }
        !           503: #endif /* OLD */
        !           504: 
        !           505: /*
        !           506:  * Get the given field of a header (char * parm) from bfr, but only
        !           507:  * if there's something actually there (after the colon).  Don't
        !           508:  * bother if we already have an entry for this field.
        !           509:  */
        !           510: getfield(hpfield, size)
        !           511: char   *hpfield;
        !           512: int    size;
        !           513: {
        !           514:        register char   *ptr;
        !           515: 
        !           516:        if (hpfield[0])
        !           517:                return;
        !           518:        for (ptr = index(bfr, ':'); isspace(*++ptr); )
        !           519:                ;
        !           520:        if (*ptr != '\0') {
        !           521:                (void) strncpy(hpfield, ptr, size - 1);
        !           522:                (void) nstrip(hpfield);
        !           523:        }
        !           524: }
        !           525: 
        !           526: 
        !           527: #define its(type) (prefix(ptr, type))
        !           528: type(ptr)
        !           529: register char  *ptr;
        !           530: {
        !           531:        register char   *colon, *space;
        !           532: 
        !           533:        if (ptr == NULL)
        !           534:                return FALSE;
        !           535:        if (!isalpha(*ptr))
        !           536:                return FALSE;
        !           537:        colon = index(ptr, ':');
        !           538:        space = index(ptr, ' ');
        !           539:        if (!colon || space && space < colon)
        !           540:                return FALSE;
        !           541:        if (its("From: "))
        !           542:                if (index(ptr, '@') || !index(ptr, '!'))
        !           543:                        return FROM;
        !           544:                else
        !           545:                        return PATH;
        !           546:        if (its("Path: "))
        !           547:                return PATH;
        !           548:        if (its("Newsgroups: "))
        !           549:                return NEWSGROUP;
        !           550:        if (its("Subject: "))
        !           551:                return TITLE;
        !           552:        if (its("Date: "))
        !           553:                return SUBMIT;
        !           554:        if (its("Date-Received: "))
        !           555:                return RECEIVE;
        !           556: #ifdef OLD
        !           557:        if (its("Title: "))
        !           558:                return TITLE;
        !           559:        if (its("Posted: "))
        !           560:                return SUBMIT;
        !           561:        if (its("Received: "))
        !           562:                return RECEIVE;
        !           563: #endif /* OLD */
        !           564:        if (its("Expires: "))
        !           565:                return EXPIRE;
        !           566:        if (its("Article-I.D.: "))
        !           567:                return ARTICLEID;
        !           568:        if (its("Message-ID: "))
        !           569:                return MESSAGEID;
        !           570:        if (its("Reply-To: "))
        !           571:                return REPLYTO;
        !           572:        if (its("References: "))
        !           573:                return FOLLOWID;
        !           574:        if (its("Control: "))
        !           575:                return CONTROL;
        !           576:        if (its("Sender: "))
        !           577:                return SENDER;
        !           578:        if (its("Followup-To: "))
        !           579:                return FOLLOWTO;
        !           580:        if (its("Posting-Version: "))
        !           581:                return POSTVERSION;
        !           582:        if (its("Relay-Version: "))
        !           583:                return RELAYVERSION;
        !           584:        if (its("Distribution: "))
        !           585:                return DISTRIBUTION;
        !           586:        if (its("Organization: "))
        !           587:                return ORGANIZATION;
        !           588:        if (its("Lines: "))
        !           589:                return NUMLINES;
        !           590:        if (its("Summary: "))
        !           591:                return SUMMARY;
        !           592:        if (its("Keywords: "))
        !           593:                return KEYWORDS;
        !           594:        if (its("Approved: "))
        !           595:                return APPROVED;
        !           596:        if (its("Nf-ID: "))
        !           597:                return NFID;
        !           598:        if (its("Nf-From: "))
        !           599:                return NFFROM;
        !           600:        if (its("Xref: "))
        !           601:                return XREF;
        !           602:        if (its("Xpath: "))
        !           603:                return XPATH;
        !           604:        return OTHER;
        !           605: }
        !           606: 
        !           607: /*
        !           608:  * Generate the current version of the news software.
        !           609:  */
        !           610: 
        !           611: static char *my_version = NULL;
        !           612: 
        !           613: char *
        !           614: genversion()
        !           615: {
        !           616:        char rb[BUFLEN];
        !           617:        register char *t;
        !           618: 
        !           619:        if (my_version == NULL) {
        !           620: #ifdef HIDDENNET
        !           621:                if (strcmp(LOCALSYSNAME, FULLSYSNAME))
        !           622:                        (void) sprintf(rb, "version %s; site %s.%s%s",
        !           623:                                news_version, LOCALSYSNAME, FULLSYSNAME, MYDOMAIN);
        !           624:                else
        !           625: #endif /* !HIDDENNET */
        !           626:                        (void) sprintf(rb, "version %s; site %s%s",
        !           627:                                news_version, FULLSYSNAME, MYDOMAIN);
        !           628:                while (t = index(rb, '\t'))
        !           629:                        *t = ' ';
        !           630:                my_version = malloc((unsigned)strlen(rb) + 1);
        !           631:                if (my_version == NULL)
        !           632:                        xerror("malloc failed for my_version");
        !           633:                (void) strcpy(my_version, rb);
        !           634:        }
        !           635:        return my_version;
        !           636: }
        !           637: 
        !           638: /*
        !           639:  * Write header at 'hp' on stream 'fp' in B+ format.  Include received date
        !           640:  * if wr is 1.  Leave off sysname if wr is 2.
        !           641:  */
        !           642: ihwrite(hp, fp, wr)
        !           643: register struct hbuf *hp;
        !           644: register FILE *fp;
        !           645: int    wr;
        !           646: {
        !           647:        int iu;
        !           648:        time_t t;
        !           649:        time_t cgtdate();
        !           650: 
        !           651:        /*
        !           652:         * We're being tricky with Path/From because of upward compatibility
        !           653:         * issues.  The new version considers From and Path to be separate.
        !           654:         * The old one thinks they both mean "Path" but only believes the
        !           655:         * first one it sees, so will ignore the second.
        !           656:         */
        !           657:        if (prefix(hp->path, FULLSYSNAME) &&
        !           658:                index(NETCHRS, hp->path[strlen(FULLSYSNAME)]))
        !           659:                fprintf(fp, "Path: %s\n", hp->path);
        !           660:        else
        !           661:                fprintf(fp, "Path: %s!%s\n", FULLSYSNAME, hp->path);
        !           662:        if (hp->from[0])
        !           663:                fprintf(fp, "From: %s\n", hp->from);
        !           664: 
        !           665:        fprintf(fp, "Newsgroups: %s\n", hp->nbuf);
        !           666:        fprintf(fp, "Subject: %s\n", hp->title);
        !           667:        fprintf(fp, "Message-ID: %s\n", hp->ident);
        !           668:        t = cgtdate(hp->subdate);
        !           669:        fprintf(fp, "Date: %s\n", arpadate(&t));
        !           670: #ifdef OLD
        !           671:        fprintf(fp, "Article-I.D.: %s\n", oident(hp->ident));
        !           672:        fprintf(fp, "Posted: %s", ctime(&t));
        !           673: #endif /* OLD */
        !           674:        if (*hp->expdate)
        !           675:                fprintf(fp, "Expires: %s\n", hp->expdate);
        !           676:        if (*hp->followid) {
        !           677:                register char *dp, *cp;
        !           678: 
        !           679:                dp = cp = hp->followid;
        !           680:                while (*cp != '\0')
        !           681:                        if (*cp == '<' && *(cp + 1) == '>')
        !           682:                                cp += 2;
        !           683:                        else
        !           684:                                *dp++ = *cp++;
        !           685:                *dp = '\0';
        !           686:                if (*hp->followid)
        !           687:                        fprintf(fp, "References: %s\n", hp->followid);
        !           688:        }
        !           689:        if (*hp->ctlmsg)
        !           690:                fprintf(fp, "Control: %s\n", hp->ctlmsg);
        !           691:        if (*hp->sender)
        !           692:                fprintf(fp, "Sender: %s\n", hp->sender);
        !           693:        if (*hp->replyto)
        !           694:                fprintf(fp, "Reply-To: %s\n", hp->replyto);
        !           695:        if (*hp->followto)
        !           696:                fprintf(fp, "Followup-To: %s\n", hp->followto);
        !           697:        if (*hp->distribution)
        !           698:                fprintf(fp, "Distribution: %s\n", hp->distribution);
        !           699:        if (*hp->organization)
        !           700:                fprintf(fp, "Organization: %s\n", hp->organization);
        !           701:        if (*hp->numlines)
        !           702:                fprintf(fp, "Lines: %s\n", hp->numlines);
        !           703:        if (*hp->keywords)
        !           704:                fprintf(fp, "Keywords: %s\n", hp->keywords);
        !           705:        if (*hp->summary)
        !           706:                fprintf(fp, "Summary: %s\n", hp->summary);
        !           707:        if (*hp->approved)
        !           708:                fprintf(fp, "Approved: %s\n", hp->approved);
        !           709:        if (*hp->nf_id)
        !           710:                fprintf(fp, "Nf-ID: %s\n", hp->nf_id);
        !           711:        if (*hp->nf_from)
        !           712:                fprintf(fp, "Nf-From: %s\n", hp->nf_from);
        !           713: #ifdef DOXREFS
        !           714:        if ( wr ==1 && *hp->xref)
        !           715:                fprintf(fp, "Xref: %s\n", hp->xref);
        !           716: #endif /* DOXREFS */
        !           717:        for (iu = 0; iu < NUNREC; iu++) {
        !           718:                if (hp->unrec[iu])
        !           719:                        fprintf(fp, "%s\n", &hp->unrec[iu][0]);
        !           720:        }
        !           721:        putc('\n', fp);
        !           722: }
        !           723: 
        !           724: 
        !           725: #ifndef BSD4_2
        !           726: /*
        !           727:  * Set nc bytes, starting at cp, to zero.
        !           728:  */
        !           729: bzero(cp, nc)
        !           730: register char  *cp;
        !           731: register int   nc;
        !           732: {
        !           733:        if (nc > 0)
        !           734:                do {
        !           735:                        *cp++ = 0;
        !           736:                } while (--nc);
        !           737: }
        !           738: #endif /* !BSD4_2 */
        !           739: 
        !           740: /*
        !           741:  * hfgets is like fgets, but deals with continuation lines.
        !           742:  * It also ensures that even if a line that is too long is
        !           743:  * received, the remainder of the line is thrown away
        !           744:  * instead of treated like a second line.
        !           745:  */
        !           746: char *
        !           747: hfgets(buf, len, fp)
        !           748: char *buf;
        !           749: int len;
        !           750: FILE *fp;
        !           751: {
        !           752:        register int c;
        !           753:        register int n = 0;
        !           754:        register char *cp;
        !           755: 
        !           756:        cp = buf;
        !           757:        while (n < len && (c = getc(fp)) != EOF) {
        !           758:                if (c == '\n')
        !           759:                        break;
        !           760:                if (isprint(c) || c == '\b' || c == ' ' || c == '\t') {
        !           761:                        *cp++ = c;
        !           762:                        n++;
        !           763:                }
        !           764:        }
        !           765:        if (c == EOF && cp == buf)
        !           766:                return NULL;
        !           767:        *cp = '\0';
        !           768: 
        !           769:        if (c != '\n') {
        !           770:                /* Line too long - part read didn't fit into a newline */
        !           771:                while ((c = getc(fp)) != '\n' && c != EOF)
        !           772:                        ;
        !           773:        } else if (cp == buf) {
        !           774:                /* Don't look for continuation of blank lines */
        !           775:                *cp++ = '\n';
        !           776:                *cp = '\0';
        !           777:                return buf;
        !           778:        }
        !           779: 
        !           780:        while ((c = getc(fp)) == ' ' || c == '\t') {    /* for each cont line */
        !           781:                /* Continuation line. */
        !           782:                if ((n += 2) < len) {
        !           783:                        *cp++ = '\n';
        !           784:                        *cp++ = c;
        !           785:                }
        !           786:                while ((c = getc(fp)) != '\n' && c != EOF)
        !           787:                        if ((isprint(c) || c == '\b' || c == ' ' || c == '\t')
        !           788:                                && n++ < len)
        !           789:                                *cp++ = c;
        !           790:        }
        !           791:        if (n >= len - 1)
        !           792:                cp = buf + len - 2;
        !           793:        *cp++ = '\n';
        !           794:        *cp = '\0';
        !           795:        if (c != EOF)
        !           796:                (void) ungetc(c, fp); /* push back first char of next header */
        !           797:        return buf;
        !           798: }

unix.superglobalmegacorp.com

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