Annotation of 43BSDTahoe/new/news/src/funcs2.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * This software is Copyright (c) 1985 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:  *
        !            16:  * funcs2 - functions used by both inews and readnews.
        !            17:  */
        !            18: 
        !            19: #ifdef SCCSID
        !            20: static char    *SccsId = "@(#)funcs2.c 1.22    10/15/87";
        !            21: #endif /* SCCSID */
        !            22: 
        !            23: #include "params.h"
        !            24: 
        !            25: #ifdef SunIII
        !            26: #ifndef INTERNET
        !            27: #define        INTERNET
        !            28: #endif /* !INTERNET */
        !            29: #endif /* SunIII */
        !            30: 
        !            31: /*LINTLIBRARY*/
        !            32: 
        !            33: /*
        !            34:  * Get user name and home directory.
        !            35:  */
        !            36: getuser()
        !            37: {
        !            38:        static int flag = TRUE;
        !            39:        register struct passwd *p;
        !            40: 
        !            41:        if (flag) {
        !            42:                if ((p = getpwuid(uid)) == NULL)
        !            43:                        xerror("Cannot get user's name");
        !            44:                if ( username == NULL || username[0] == 0 ||
        !            45:                        STRCMP(username, "Unknown") == 0)
        !            46:                        username = AllocCpy(p->pw_name);
        !            47:                userhome = AllocCpy(p->pw_dir);
        !            48:                flag = FALSE;
        !            49:        }
        !            50:        (void) strcpy(header.path, username);
        !            51: }
        !            52: 
        !            53: /* no sys file on clients via nntp */
        !            54: #ifndef SERVER
        !            55: static FILE    *sysfile;
        !            56: 
        !            57: char *fldget();
        !            58: 
        !            59: static int sfline;
        !            60: 
        !            61: /*
        !            62:  * Open SUBFILE.
        !            63:  */
        !            64: s_openr()
        !            65: {
        !            66:        sysfile = xfopen(SUBFILE, "r");
        !            67:        sfline = 0;
        !            68: }
        !            69: 
        !            70: /*
        !            71:  * Read SUBFILE.
        !            72:  */
        !            73: s_read(sp)
        !            74: register struct srec *sp;
        !            75: {
        !            76:        register char *p;
        !            77:        register int  c;
        !            78:        char *e;
        !            79:        int chop_spaces = 0;
        !            80: again:
        !            81:        p = bfr;
        !            82:         /*
        !            83:          * Read  the  SUBFILE  (/usr/lib/news/sys)  from   the   current
        !            84:         * position  to  the  first  unescaped newline.  If a newline is
        !            85:         * escaped with a backslash (\) continue reading but throw  away
        !            86:         * the backslash and newline; read the next line skipping spaces
        !            87:         * and tabs until the first non-space/tab character, then  start
        !            88:         * looking   for   a   newline   again.   Skipping  the  leading
        !            89:         * spaces/tabs after a escaped newline  keeps  the  news  groups
        !            90:         * together.  If  a  line  begins  with a newline, just skip it.
        !            91:         */
        !            92:        for (e=p+LBUFLEN; p < e && (c=getc(sysfile)) != EOF; p++) {
        !            93:                *p = c;
        !            94:                if (c == '\n') {
        !            95:                        sfline++;
        !            96:                        if (p == bfr || p[-1] != '\\') {
        !            97:                                p[1] = '\0';
        !            98:                                break;
        !            99:                        } else {
        !           100:                                chop_spaces++;
        !           101:                                p -= 2;
        !           102:                        }
        !           103:                } else if (chop_spaces) {
        !           104:                        if (c == '\t' || c == ' ')
        !           105:                                p--;
        !           106:                        else
        !           107:                                chop_spaces = 0;
        !           108:                }
        !           109:        }
        !           110:        if (c == EOF) {
        !           111:                return FALSE;
        !           112:        }
        !           113:        p = bfr;
        !           114:        while (*p == ' ' || *p == '\t') /* skip leading white space */
        !           115:                p++;
        !           116:        if (*p == '\n')
        !           117:                goto again;          /* skip newlines */
        !           118:        if (!nstrip(p))
        !           119:                xerror("SUBFILE (%s) line %d too long.", SUBFILE, sfline);
        !           120:        if (*p == '#')
        !           121:                goto again;
        !           122:        sp->s_xmit[0] = '\0';
        !           123:        sp->s_flags[0] = '\0';
        !           124:        sp->s_nosend = (char *)0;
        !           125: 
        !           126:        p = fldget(sp->s_name, p);
        !           127:        if (*p++ == '\0')
        !           128:                xerror("Bad SUBFILE (%s) line %d.", SUBFILE, sfline);
        !           129:        /*
        !           130:         * A sys file line reading "ME" means the name of the local system.
        !           131:         */
        !           132:        if (STRCMP(sp->s_name, "ME") == 0)
        !           133:                (void) strcpy(sp->s_name, LOCALPATHSYSNAME);
        !           134:        e = index(sp->s_name, '/');
        !           135:        if (e) {
        !           136:                *e++ = '\0';
        !           137:                sp->s_nosend = e;
        !           138:        }
        !           139:        p = fldget(sp->s_nbuf, p);
        !           140:        lcase(sp->s_nbuf);
        !           141:        if (*p++ == '\0')
        !           142:                return TRUE;
        !           143: 
        !           144:        p = fldget(sp->s_flags, p);
        !           145:        if (*p++ == '\0')
        !           146:                return TRUE;
        !           147: 
        !           148:        (void) fldget(sp->s_xmit, p);
        !           149:        return TRUE;
        !           150: }
        !           151: 
        !           152: char *
        !           153: fldget(q, p)
        !           154: register char *q, *p;
        !           155: {
        !           156:        while (*p && *p != ':') {
        !           157:                if (*p == '\\' && p[1]==':')
        !           158:                        p++;
        !           159:                *q++ = *p++;
        !           160:        }
        !           161:        *q = '\0';
        !           162:        return p;
        !           163: }
        !           164: 
        !           165: /*
        !           166:  * Find the SUBFILE record for a system.
        !           167:  */
        !           168: s_find(sp, system)
        !           169: register struct srec *sp;
        !           170: char *system;
        !           171: {
        !           172:        s_openr();
        !           173:        while (s_read(sp))
        !           174:                if (STRNCMP(system, sp->s_name, SNLN) == 0) {
        !           175:                        s_close();
        !           176:                        return TRUE;
        !           177:                }
        !           178:        s_close();
        !           179:        return FALSE;
        !           180: }
        !           181: 
        !           182: /*
        !           183:  * Close sysfile.
        !           184:  */
        !           185: s_close()
        !           186: {
        !           187:        (void) fclose(sysfile);
        !           188: }
        !           189: #endif /* SERVER */
        !           190: 
        !           191: extern struct timeb Now;
        !           192: 
        !           193: time_t
        !           194: cgtdate(datestr)
        !           195: char *datestr;
        !           196: {
        !           197:        char    junk[40],month[40],day[30],tod[60],year[50];
        !           198:        static time_t lasttime;
        !           199:        static char lastdatestr[BUFLEN] = "";
        !           200: 
        !           201:        if ( lastdatestr[0] && STRCMP(datestr, lastdatestr) == 0)
        !           202:                return lasttime;
        !           203:        lasttime = getdate(datestr, &Now);
        !           204:        if (lasttime < 0 &&
        !           205:          sscanf(datestr, "%s %s %s %s %s", junk, month, day, tod, year) == 5) {
        !           206:                (void) sprintf(bfr, "%s %s, %s %s", month, day, year, tod);
        !           207:                lasttime = getdate(bfr, &Now);
        !           208:                if (lasttime < 0) {
        !           209:                        logerr("Unparsable date \"%s\"", datestr);
        !           210:                        datestr = "now";        /* better than nothing */
        !           211:                        lasttime = Now.time;
        !           212:                }
        !           213:        }
        !           214:        strncpy(lastdatestr, datestr, BUFLEN);
        !           215:        return lasttime;
        !           216: }
        !           217: 
        !           218: lcase(s)
        !           219: register char *s;
        !           220: {
        !           221:        register char *ptr;
        !           222: 
        !           223:        for (ptr = s; *ptr; ptr++)
        !           224:                if (isupper(*ptr))
        !           225:                        *ptr = tolower(*ptr);
        !           226: }
        !           227: 
        !           228: /*
        !           229:  * Return a compact representation of the person who posted the given
        !           230:  * message.  A sender or internet name will be used, otherwise
        !           231:  * the last part of the path is used preceded by an optional ".."
        !           232:  */
        !           233: char *
        !           234: tailpath(hp)
        !           235: struct hbuf *hp;
        !           236: {
        !           237:        char *p, *r;
        !           238:        static char resultbuf[BUFLEN];
        !           239:        char pathbuf[PATHLEN];
        !           240:        char *malloc();
        !           241: 
        !           242:        /*
        !           243:         * This only happens for articles posted by old news software
        !           244:         * in non-internet format.
        !           245:         */
        !           246:        resultbuf[0] = '\0';
        !           247:        (void) strncpy(pathbuf, hp->path, PATHLEN);
        !           248:        p = index(pathbuf, ' ');
        !           249:        if (p)
        !           250:                *p = '\0';      /* Chop off trailing " (name)" */
        !           251:        r = rindex(pathbuf, '!');
        !           252:        if (r == 0) {
        !           253:                r = pathbuf;
        !           254:        } else {
        !           255:                while (r > pathbuf && *--r != '!')
        !           256:                        ;
        !           257:                if (r > pathbuf) {
        !           258:                        r++;
        !           259:                        (void) strcpy(resultbuf, "..!");
        !           260:                }
        !           261:        }
        !           262:        (void) strcat(resultbuf, r);
        !           263:        return resultbuf;
        !           264: }
        !           265: 
        !           266: /*
        !           267:  * arpadate is like ctime(3) except that the time is returned in
        !           268:  * an acceptable ARPANET time format instead of ctime format.
        !           269:  */
        !           270: char *
        !           271: arpadate(longtime)
        !           272: time_t *longtime;
        !           273: {
        !           274:        register char *p, *q, *ud;
        !           275:        register int i;
        !           276:        static char b[40];
        !           277:        extern struct tm *gmtime();
        !           278:        extern char *asctime();
        !           279: 
        !           280:        /*  Get current time. This will be used resolve the timezone. */
        !           281:        ud = asctime(gmtime(longtime));
        !           282: 
        !           283:        /*  Crack the UNIX date line in a singularly unoriginal way. */
        !           284:        q = b;
        !           285: 
        !           286: #ifdef notdef
        !           287: /* until every site installs the fix to getdate.y, the day
        !           288:    of the week can cause time warps */
        !           289:        p = &ud[0];             /* Mon */
        !           290:        *q++ = *p++;
        !           291:        *q++ = *p++;
        !           292:        *q++ = *p++;
        !           293:        *q++ = ','; *q++ = ' ';
        !           294: #endif
        !           295: 
        !           296:        p = &ud[8];             /* 16 */
        !           297:        if (*p == ' ')
        !           298:                p++;
        !           299:        else
        !           300:                *q++ = *p++;
        !           301:        *q++ = *p++; *q++ = ' ';
        !           302: 
        !           303:        p = &ud[4];             /* Sep */
        !           304:        *q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = ' ';
        !           305: 
        !           306:        p = &ud[22];            /* 1979 */
        !           307:        *q++ = *p++; *q++ = *p++; *q++ = ' ';
        !           308: 
        !           309:        p = &ud[11];            /* 01:03:52 */
        !           310:        for (i = 8; i > 0; i--)
        !           311:                *q++ = *p++;
        !           312: 
        !           313:        *q++ = ' ';
        !           314:        *q++ = 'G';             /* GMT */
        !           315:        *q++ = 'M';
        !           316:        *q++ = 'T';
        !           317:        *q = '\0';
        !           318: 
        !           319:        return b;
        !           320: }
        !           321: 
        !           322: char *
        !           323: replyname(hptr)
        !           324: struct hbuf *hptr;
        !           325: {
        !           326:        register char *ptr;
        !           327:        static char tbuf[PATHLEN];
        !           328: 
        !           329:        ptr = hptr->path;
        !           330:        if (PREFIX(ptr, PATHSYSNAME) &&
        !           331:                index(NETCHRS, ptr[strlen(PATHSYSNAME)]))
        !           332:                ptr = index(ptr, '!') + 1;
        !           333: #ifdef INTERNET
        !           334:        if (hptr->from[0])
        !           335:                ptr = hptr->from;
        !           336:        if (hptr->replyto[0])
        !           337:                ptr = hptr->replyto;
        !           338: #else /* !INTERNET */
        !           339:        if (hptr->replyto[0] && !index(hptr->replyto, '@'))
        !           340:                ptr = hptr->replyto;
        !           341: #endif
        !           342:        (void) strcpy(tbuf, ptr);
        !           343:        ptr = index(tbuf, '(');
        !           344:        if (ptr) {
        !           345:                while (ptr[-1] == ' ')
        !           346:                        ptr--;
        !           347:                *ptr = 0;
        !           348:        }
        !           349: #ifdef SunIII
        !           350:        if (ptr = rindex(tbuf, '.')) {
        !           351:                if (PREFIX(++ptr, "OZ")) {
        !           352:                        /* some people only allow it in lower case ... */
        !           353:                        strcpy(ptr, "oz");
        !           354:                        return tbuf;
        !           355:                }
        !           356:                if (PREFIX(ptr, "UUCP") || PREFIX(ptr, "ARPA") ||
        !           357:                    PREFIX(ptr, "DEC") || PREFIX(ptr, "CSNET")) {
        !           358:                        strcat(tbuf, "@munnari.oz");    /* via sun to munnari */
        !           359:                        return tbuf;
        !           360:                }
        !           361:        }
        !           362:        /*
        !           363:         * must(?) have come from a uucp site, lets look see if path passes
        !           364:         * through munnari, and if so delete the fake uucp path after that.
        !           365:         */
        !           366:        for (ptr = tbuf ;; ptr++) {
        !           367:                if (PREFIX(ptr, "munnari!")) {
        !           368:                        strcpy(tbuf, ptr+8);
        !           369:                        break;
        !           370:                }
        !           371:                ptr = index(ptr, '!');
        !           372:                if (ptr == (char *)0)
        !           373:                        break;
        !           374:        }
        !           375:        /*
        !           376:         * now, just send the address we have left to munnari, and
        !           377:         * hope that something sensible will be done with it there.
        !           378:         * (This works in more cases than you'd think ...)
        !           379:         */
        !           380:        strcat(tbuf, "@munnari.oz");
        !           381: #else /* !SunIII */
        !           382: #ifndef INTERNET
        !           383:        /*
        !           384:         * Play games stripping off multiple berknet
        !           385:         * addresses (a!b!c:d:e => a!b!d:e) here.
        !           386:         */
        !           387:        for (ptr=tbuf; *ptr; ptr++) {
        !           388:                register char *ptr2;
        !           389: 
        !           390:                if (index(NETCHRS, *ptr) && *ptr == ':' &&
        !           391:                    (ptr2=index(ptr+1, ':')))
        !           392:                        (void) strcpy(ptr, ptr2);
        !           393:        }
        !           394: #else  /* INTERNET */
        !           395:        {
        !           396:        char mbuf[BUFLEN], modadd[BUFLEN];
        !           397:        FILE *mfd;
        !           398:        /* Let's find a path to the backbone */
        !           399:        sprintf(mbuf, "%s/mailpaths", LIB);
        !           400:        mfd = xfopen(mbuf, "r");
        !           401:        do {
        !           402:                if (fgets(mbuf, sizeof mbuf, mfd) == NULL)
        !           403:                        xerror("Can't find internet in %s/mailpaths",
        !           404:                                LIB);
        !           405:        } while (!PREFIX(mbuf, "internet"));
        !           406:        if (sscanf(mbuf, "%*s %s", modadd) != 1)
        !           407:                xerror("backbone address corrupted");
        !           408:        (void) fclose(mfd);
        !           409:        (void)strcpy(mbuf, tbuf);
        !           410:        /* If we are lucky, there is no ! or @ in the forward address */
        !           411:        if (strpbrk(modadd, "!@") == NULL) {
        !           412:                sprintf(tbuf, modadd, mbuf);
        !           413:        } else {
        !           414:                char *cp = index(mbuf, '@');
        !           415:                if (index(modadd, '@') == NULL && cp) {
        !           416:                        /* we have to rearrange the address so no @ are in it */
        !           417:                        char atbuf[BUFLEN];
        !           418:                        *cp++ = '\0';
        !           419:                        sprintf(atbuf, "%s!%s", cp, mbuf);
        !           420:                        sprintf(tbuf, modadd, atbuf);
        !           421:                } else if (cp) {
        !           422:                        /* some days you don't get lucky. presume the % hack */
        !           423:                        *cp = '%';
        !           424:                        sprintf(tbuf, modadd, mbuf);
        !           425:                }
        !           426:        }
        !           427:        }
        !           428: #endif /* INTERNET */
        !           429: #endif /* !SunIII */
        !           430:        return tbuf;
        !           431: }
        !           432: 
        !           433: 
        !           434: /*
        !           435:  * Given an article ID, find the line in the history file that mentions it.
        !           436:  * Return the text of the line, or NULL if not found.  A pointer to a
        !           437:  * static area is returned.
        !           438:  */
        !           439: char *
        !           440: findhist(artid)
        !           441: char *artid;
        !           442: {
        !           443:        static char lbuf[256];
        !           444:        char oidbuf[BUFSIZ];
        !           445:        FILE *hfp;
        !           446:        register char *p;
        !           447: #ifdef SERVER
        !           448:        char workspace[256];
        !           449:        struct tm *tm;
        !           450:        long clock;
        !           451: #else /* !SERVER */
        !           452: #ifdef DBM
        !           453:        datum lhs, rhs;
        !           454:        datum fetch();
        !           455:        long fpos; /* We have to use an explicit variable to insure alignment */
        !           456: #else /* !DBM */
        !           457:        char *histfile();
        !           458: #endif /* !DBM */
        !           459: #endif /* !SERVER */
        !           460:        /* Try to understand old artid's as well.  Assume .UUCP domain. */
        !           461:        if (artid[0] != '<') {
        !           462:                p = index(artid, '.');
        !           463:                if (p)
        !           464:                        *p++ = '\0';
        !           465:                (void) sprintf(oidbuf, "<%s@%s.UUCP>", p, artid);
        !           466:                if (p)
        !           467:                        *--p = '.';
        !           468:        } else
        !           469:                (void) strcpy(oidbuf, artid);
        !           470: #ifdef SERVER
        !           471:        (void) sprintf(lbuf,"STAT %s",oidbuf);
        !           472:        put_server(lbuf);
        !           473:        (void) get_server(workspace,sizeof(workspace));
        !           474:        if (*workspace != CHAR_OK)
        !           475:                return NULL;
        !           476:        (void) sprintf(lbuf,"XHDR xref %s",oidbuf);
        !           477:        put_server(lbuf);
        !           478:        (void) get_server(workspace,sizeof(workspace)); /* get response */
        !           479:        if (*workspace != CHAR_OK)
        !           480:                return NULL;            /* old style nntp */
        !           481:        (void) get_server(workspace,sizeof(workspace)); /* get header line */
        !           482:        sync_server();  /* get rid of the rest of it */
        !           483:        p = index(workspace,' ');
        !           484:        p++;
        !           485: 
        !           486:        if (*p == '(') {        /* there is no xref line */
        !           487:                long s,sm;
        !           488:                FILE * af;
        !           489:                char n[100], buf[100], *name;
        !           490:                (void) sprintf(lbuf,"XHDR newsgroups %s",oidbuf);
        !           491:                put_server(lbuf);
        !           492:                (void) get_server(workspace,sizeof(workspace));
        !           493:                if (*workspace != CHAR_OK)
        !           494:                        return NULL;
        !           495:                (void) get_server(workspace,sizeof(workspace));
        !           496:                sync_server();
        !           497:                if ((name = index(workspace,' ')) == NULL)
        !           498:                        return NULL;
        !           499:                name++;
        !           500:                /* now we fetch the line from the active file */
        !           501:                af = xfopen(ACTIVE, "r");
        !           502:                while (fgets(buf, sizeof(buf), af) != NULL) {
        !           503:                        if (sscanf(buf, "%s %ld %ld", n, &s, &sm) == 3 &&
        !           504:                             STRCMP(n, name) == 0) {
        !           505:                                break;
        !           506:                        }
        !           507:                }
        !           508:                (void) fclose(af);
        !           509:                /* now we ask for a message ids in that newsgroup */
        !           510:                if (set_group(name) == NULL)
        !           511:                        return NULL;
        !           512:                (void) sprintf(lbuf, "XHDR message-id %d-%d", sm, s);
        !           513:                put_server(lbuf);
        !           514:                (void) get_server(workspace,sizeof(workspace));
        !           515:                if (*workspace != CHAR_OK)
        !           516:                        return NULL;
        !           517:                while ( get_server(workspace,sizeof(workspace)) >= 0) {
        !           518:                        if (*workspace == '.'  && strlen(workspace) == 1) 
        !           519:                                return NULL;
        !           520:                        if (strindex(workspace,oidbuf) > -1)
        !           521:                                break;
        !           522:                }
        !           523:                sync_server();
        !           524:                *(index(workspace,' ')) = '\0';
        !           525:                (void) sprintf(lbuf, "%s/%s", n, workspace);
        !           526:                bzero(workspace,sizeof(workspace));
        !           527:                strcpy(workspace, lbuf);
        !           528:        } else {
        !           529:                bzero(lbuf, sizeof(lbuf));
        !           530:                strcpy(lbuf, p);
        !           531:                while (*p != '\0' && (p = index(lbuf,':')) != NULL) {
        !           532:                        *p = '/';
        !           533:                        p++;
        !           534:                }
        !           535:                strcpy(workspace, lbuf);
        !           536:        }
        !           537:        p = &workspace[0];
        !           538:        time(&clock);           
        !           539:        tm = localtime(&clock);
        !           540: #ifdef USG
        !           541:        sprintf(lbuf, "%s\t%2.2d/%2.2d/%d %2.2d:%2.2d\t%s",
        !           542: #else /* !USG */
        !           543:        sprintf(lbuf, "%s\t%02d/%02d/%d %02d:%02d\t%s",
        !           544: #endif /* !USG */
        !           545:        oidbuf,tm->tm_mon,tm->tm_mday,tm->tm_year,tm->tm_hour,tm->tm_min,p);
        !           546:        return lbuf;            /* not really the same, but close */
        !           547: #else  /* !SERVER */
        !           548:        lcase(oidbuf);
        !           549: #ifdef DBM
        !           550:        initdbm(ARTFILE);
        !           551:        lhs.dptr = oidbuf;
        !           552:        lhs.dsize = strlen(lhs.dptr) + 1;
        !           553:        rhs = fetch(lhs);
        !           554:        if (rhs.dptr == NULL)
        !           555:                return NULL;
        !           556:        hfp = xfopen(ARTFILE, "r");
        !           557:        /* The bcopy is NECESSARY to insure alignment on some machines */
        !           558:        bcopy(rhs.dptr, (char *)&fpos, sizeof (long));
        !           559:        fseek(hfp, fpos, 0);
        !           560: #else /* !DBM */
        !           561:        hfp = xfopen(histfile(oidbuf), "r");
        !           562: #endif /* !DBM */
        !           563:        while (fgets(lbuf, BUFLEN, hfp) != NULL) {
        !           564:                p = index(lbuf, '\t');
        !           565:                if (p == NULL)
        !           566:                        p = index(lbuf, '\n');
        !           567:                *p = 0;
        !           568:                if (STRCMP(lbuf, artid) == 0 || STRCMP(lbuf, oidbuf) == 0) {
        !           569:                        (void) fclose(hfp);
        !           570:                        *p = '\t';
        !           571:                        *(lbuf + strlen(lbuf) - 1) = 0; /* zap the \n */
        !           572:                        return lbuf;
        !           573:                }
        !           574: #ifdef DBM
        !           575:                break;
        !           576: #endif /* DBM */
        !           577:        }
        !           578:        (void) fclose(hfp);
        !           579:        return NULL;
        !           580: #endif /* !SERVER */
        !           581: }
        !           582: 
        !           583: /*
        !           584:  * Hunt up the article "artid", and return the newsgroup/artnum
        !           585:  * where it can be found.
        !           586:  */
        !           587: char *
        !           588: findfname(artid)
        !           589: char *artid;
        !           590: {
        !           591:        char *line, *p, *q;
        !           592:        char *findhist();
        !           593:        static char fname[BUFLEN];
        !           594: 
        !           595:        line = findhist(artid);
        !           596:        if (line) {
        !           597:                /* Look for it stored as an article, where it should be */
        !           598:                p = index(line, '\t');
        !           599:                p = index(p+1, '\t');
        !           600:                p++;
        !           601:                if (*p) {
        !           602:                        q = index(p, ' ');
        !           603:                        if (q)
        !           604:                                *q = 0;
        !           605:                        (void) strcpy(fname, p);
        !           606:                        return fname;
        !           607:                }
        !           608:        }
        !           609:        return NULL;
        !           610: }
        !           611: 
        !           612: /*
        !           613:  * Hunt up the article "artid", fopen it for read, and return a
        !           614:  * file descriptor to it.  We look everywhere we can think of.
        !           615:  */
        !           616: FILE *
        !           617: hfopen(artid)
        !           618: char *artid;
        !           619: {
        !           620:        char *p;
        !           621:        char *findhist();
        !           622:        FILE *rv = NULL;
        !           623:        char fname[BUFLEN];
        !           624: 
        !           625:        p = findfname(artid);
        !           626:        if (p) {
        !           627: #ifdef SERVER
        !           628:        if ((rv = getartbyid(p)) != NULL) {
        !           629:                strcpy(fname, article_name());
        !           630:                (void) fclose(rv);
        !           631:                rv = NULL;
        !           632:        }
        !           633:        else
        !           634:                xerror("Cannot hfopen article %s", artid);
        !           635: #else  /* !SERVER */
        !           636:                (void) strcpy(fname, dirname(p));
        !           637: #endif /* !SERVER */
        !           638:                rv = fopen(fname, "r"); /* NOT xfopen! */
        !           639:                if (rv == NULL)
        !           640:                        xerror("Cannot hfopen article %s", artid);
        !           641:        }
        !           642: #ifdef SERVER
        !           643:        (void) unlink(fname);
        !           644: #endif /* !SERVER */
        !           645:        return rv;
        !           646: }
        !           647: #ifndef SERVER
        !           648: # ifdef DBM
        !           649: /*
        !           650: ** Avoid problems of multiple dbminit calls.
        !           651: */
        !           652: initdbm(name)
        !           653: char *name;
        !           654: {
        !           655:        static int called = 0;
        !           656: 
        !           657:        if (called != 0)
        !           658:                return;
        !           659:        called = 1;
        !           660:        (void) dbminit(name);
        !           661: }
        !           662: # endif /* DBM */
        !           663: #endif /* !SERVER */
        !           664: 
        !           665: #ifndef BSD4_2
        !           666: /*
        !           667:  * move n bytes from a to b
        !           668:  */
        !           669: bcopy(a, b, n)
        !           670: register char *a, *b;
        !           671: register n;
        !           672: {
        !           673:        while (--n >= 0)
        !           674:                *b++ = *a++;
        !           675: }
        !           676: #endif
        !           677: 
        !           678: #if !defined(BSD4_2)
        !           679: rename(from,to)
        !           680: register char *from, *to;
        !           681: {
        !           682:        (void) unlink(to);
        !           683:        if (link(from, to) < 0)
        !           684:                return -1;
        !           685: 
        !           686:        (void) unlink(from);
        !           687:        return 0;
        !           688: }
        !           689: #endif /* !BSD4_2 */
        !           690: 
        !           691: #ifndef DBM
        !           692: /*
        !           693: ** Generate the appropriate history subfile name
        !           694: */
        !           695: char *
        !           696: histfile(hline)
        !           697: char *hline;
        !           698: {
        !           699:        char chr;       /* least significant digit of article number */
        !           700:        static char subfile[BUFLEN];
        !           701: 
        !           702:        chr = findhfdigit(hline);
        !           703:        sprintf(subfile, "%s.d/%c", ARTFILE, chr);
        !           704:        return subfile;
        !           705: }
        !           706: 
        !           707: findhfdigit(fn)
        !           708: char *fn;
        !           709: {
        !           710:        register char *p;
        !           711:        register int chr;
        !           712: 
        !           713:        p = index(fn, '@');
        !           714:        if (p != NULL && p > fn)
        !           715:                chr = *(p - 1);
        !           716:        else
        !           717:                chr = '0';
        !           718:        if (!isdigit(chr))
        !           719:                chr = '0';
        !           720:        return chr;
        !           721: }
        !           722: #endif /* !DBM */
        !           723: 
        !           724: #ifdef VMS
        !           725: /*
        !           726:  * These functions open an article with one level of indirection,
        !           727:  * to support symbolic links. xart_open exits if the open fails.
        !           728:  */
        !           729: FILE *
        !           730: xart_open (filename,mode)
        !           731: char *filename,*mode;
        !           732: {
        !           733:        FILE *fp = art_open (filename, mode);
        !           734:        extern int errno;
        !           735:        if (fp == NULL)
        !           736:                xerror("Cannot open article %s (%s): %s\n",
        !           737:                         filename, mode, errmsg(errno));
        !           738:        return fp;
        !           739: }
        !           740: 
        !           741: FILE *
        !           742: art_open (filename,mode)
        !           743: char *filename,*mode;
        !           744: {
        !           745:        char linkfile[BUFSIZ];
        !           746:        FILE *fp;
        !           747: 
        !           748:        if ((fp = fopen (filename, mode)) == NULL)
        !           749:                return NULL;
        !           750:        if (fgets (linkfile, BUFSIZ, fp) == NULL || linkfile[0] != '/') {
        !           751:                rewind (fp);
        !           752:                return fp;
        !           753:        }
        !           754: /* Chase the symbolic link. */
        !           755:        (void) fclose (fp);
        !           756:        if ((fp = fopen (linkfile, mode)) == NULL)
        !           757: /* Clean up dangling link, if we have the power. Ignore error if we don't. */
        !           758:                (void) unlink (filename);
        !           759:        return fp;
        !           760: }
        !           761: #endif /* VMS */
        !           762: 
        !           763: /*
        !           764:  * Generate the name of the person responsible for posting this article,
        !           765:  * in order to check that two articles were posted by the same person.
        !           766:  */
        !           767: char *
        !           768: senderof(hp)
        !           769: struct hbuf *hp;
        !           770: {
        !           771:        register char *q, *tp;
        !           772:        char *tailpath();
        !           773:        static char senderbuf[BUFLEN];
        !           774: 
        !           775:        if (hp->sender[0])
        !           776:                tp = hp->sender;
        !           777:        else if (hp->from[0])
        !           778:                tp = hp->from;
        !           779:        else
        !           780:                tp = tailpath(hp);
        !           781: 
        !           782:        (void) strncpy(senderbuf, tp, BUFLEN);
        !           783:        /* Remove full name */
        !           784:        q = index(senderbuf, ' ');
        !           785:        if (q)
        !           786:                *q = '\0';
        !           787: 
        !           788:        return senderbuf;
        !           789: }

unix.superglobalmegacorp.com

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