Annotation of 43BSD/contrib/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.13    1/17/86";
        !            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:                        username = AllocCpy(p->pw_name);
        !            46:                userhome = AllocCpy(p->pw_dir);
        !            47:                flag = FALSE;
        !            48:        }
        !            49:        (void) strcpy(header.path, username);
        !            50: }
        !            51: 
        !            52: static FILE    *sysfile;
        !            53: 
        !            54: char *fldget();
        !            55: 
        !            56: static int sfline;
        !            57: 
        !            58: /*
        !            59:  * Open SUBFILE.
        !            60:  */
        !            61: s_openr()
        !            62: {
        !            63:        sysfile = xfopen(SUBFILE, "r");
        !            64:        sfline = 0;
        !            65: }
        !            66: 
        !            67: /*
        !            68:  * Read SUBFILE.
        !            69:  */
        !            70: s_read(sp)
        !            71: register struct srec *sp;
        !            72: {
        !            73:        register char *p;
        !            74:        register int  c;
        !            75:        char *e;
        !            76:        int chop_spaces = 0;
        !            77: again:
        !            78:        p = bfr;
        !            79:         /*
        !            80:          * Read  the  SUBFILE  (/usr/lib/news/sys)  from   the   current
        !            81:         * position  to  the  first  unescaped newline.  If a newline is
        !            82:         * escaped with a backslash (\) continue reading but throw  away
        !            83:         * the backslash and newline; read the next line skipping spaces
        !            84:         * and tabs until the first non-space/tab character, then  start
        !            85:         * looking   for   a   newline   again.   Skipping  the  leading
        !            86:         * spaces/tabs after a escaped newline  keeps  the  news  groups
        !            87:         * together.  If  a  line  begins  with a newline, just skip it.
        !            88:         */
        !            89:        for (e=p+LBUFLEN; p < e && (c=getc(sysfile)) != EOF; p++) {
        !            90:                *p = c;
        !            91:                if (c == '\n') {
        !            92:                        sfline++;
        !            93:                        if (p == bfr || p[-1] != '\\') {
        !            94:                                p[1] = '\0';
        !            95:                                break;
        !            96:                        } else {
        !            97:                                chop_spaces++;
        !            98:                                p -= 2;
        !            99:                        }
        !           100:                } else if (chop_spaces) {
        !           101:                        if (c == '\t' || c == ' ')
        !           102:                                p--;
        !           103:                        else
        !           104:                                chop_spaces = 0;
        !           105:                }
        !           106:        }
        !           107:        if (c == EOF) {
        !           108:                return FALSE;
        !           109:        }
        !           110:        p = bfr;
        !           111:        if (*p == '\n')
        !           112:                goto again;          /* skip newlines */
        !           113:        if (!nstrip(p))
        !           114:                xerror("SUBFILE (%s) line %d too long.", SUBFILE, sfline);
        !           115:        if (*p == '#')
        !           116:                goto again;
        !           117:        sp->s_xmit[0] = '\0';
        !           118:        sp->s_flags[0] = '\0';
        !           119:        sp->s_nosend = (char *)0;
        !           120: 
        !           121:        p = fldget(sp->s_name, p);
        !           122:        if (*p++ == '\0')
        !           123:                xerror("Bad SUBFILE (%s) line %d.", SUBFILE, sfline);
        !           124: /*
        !           125:  * A sys file line reading "ME" means the name of the local system.
        !           126:  */
        !           127:        if (strcmp(sp->s_name, "ME") == 0)
        !           128:                (void) strcpy(sp->s_name, FULLSYSNAME);
        !           129:        e = index(sp->s_name, '/');
        !           130:        if (e) {
        !           131:                *e++ = '\0';
        !           132:                sp->s_nosend = e;
        !           133:        }
        !           134:        p = fldget(sp->s_nbuf, p);
        !           135:        lcase(sp->s_nbuf);
        !           136:        if (*p++ == '\0')
        !           137:                return TRUE;
        !           138: 
        !           139:        p = fldget(sp->s_flags, p);
        !           140:        if (*p++ == '\0')
        !           141:                return TRUE;
        !           142: 
        !           143:        (void) fldget(sp->s_xmit, p);
        !           144:        return TRUE;
        !           145: }
        !           146: 
        !           147: char *
        !           148: fldget(q, p)
        !           149: register char *q, *p;
        !           150: {
        !           151:        while (*p && *p != ':') {
        !           152:                if (*p == '\\' && p[1]==':')
        !           153:                        p++;
        !           154:                *q++ = *p++;
        !           155:        }
        !           156:        *q = '\0';
        !           157:        return p;
        !           158: }
        !           159: 
        !           160: /*
        !           161:  * Find the SUBFILE record for a system.
        !           162:  */
        !           163: s_find(sp, system)
        !           164: register struct srec *sp;
        !           165: char *system;
        !           166: {
        !           167:        s_openr();
        !           168:        while (s_read(sp))
        !           169:                if (strncmp(system, sp->s_name, SNLN) == 0) {
        !           170:                        s_close();
        !           171:                        return TRUE;
        !           172:                }
        !           173:        s_close();
        !           174:        return FALSE;
        !           175: }
        !           176: 
        !           177: /*
        !           178:  * Close sysfile.
        !           179:  */
        !           180: s_close()
        !           181: {
        !           182:        (void) fclose(sysfile);
        !           183: }
        !           184: 
        !           185: time_t
        !           186: cgtdate(datestr)
        !           187: char *datestr;
        !           188: {
        !           189:        char    junk[40],month[40],day[30],tod[60],year[50];
        !           190:        static time_t lasttime;
        !           191:        static char lastdatestr[BUFLEN] = "";
        !           192: 
        !           193:        if ( lastdatestr[0] && strcmp(datestr, lastdatestr) == 0)
        !           194:                return lasttime;
        !           195:        lasttime = getdate(datestr, (struct timeb *)NULL);
        !           196:        if (lasttime < 0 &&
        !           197:          sscanf(datestr, "%s %s %s %s %s", junk, month, day, tod, year) == 5) {
        !           198:                (void) sprintf(bfr, "%s %s, %s %s", month, day, year, tod);
        !           199:                lasttime = getdate(bfr, (struct timeb *)NULL);
        !           200:        }
        !           201:        strncpy(lastdatestr, datestr, BUFLEN);
        !           202:        return lasttime;
        !           203: }
        !           204: 
        !           205: lcase(s)
        !           206: register char *s;
        !           207: {
        !           208:        register char *ptr;
        !           209: 
        !           210:        for (ptr = s; *ptr; ptr++)
        !           211:                if (isupper(*ptr))
        !           212:                        *ptr = tolower(*ptr);
        !           213: }
        !           214: 
        !           215: /*
        !           216:  * Return a compact representation of the person who posted the given
        !           217:  * message.  A sender or internet name will be used, otherwise
        !           218:  * the last part of the path is used preceded by an optional ".."
        !           219:  */
        !           220: char *
        !           221: tailpath(hp)
        !           222: struct hbuf *hp;
        !           223: {
        !           224:        char *p, *r;
        !           225:        static char resultbuf[BUFLEN];
        !           226:        char pathbuf[PATHLEN];
        !           227:        char *malloc();
        !           228: 
        !           229:        /*
        !           230:         * This only happens for articles posted by old news software
        !           231:         * in non-internet format.
        !           232:         */
        !           233:        resultbuf[0] = '\0';
        !           234:        (void) strncpy(pathbuf, hp->path, PATHLEN);
        !           235:        p = index(pathbuf, ' ');
        !           236:        if (p)
        !           237:                *p = '\0';      /* Chop off trailing " (name)" */
        !           238:        r = rindex(pathbuf, '!');
        !           239:        if (r == 0) {
        !           240:                r = pathbuf;
        !           241:        } else {
        !           242:                while (r > pathbuf && *--r != '!')
        !           243:                        ;
        !           244:                if (r > pathbuf) {
        !           245:                        r++;
        !           246:                        (void) strcpy(resultbuf, "..!");
        !           247:                }
        !           248:        }
        !           249:        (void) strcat(resultbuf, r);
        !           250:        return resultbuf;
        !           251: }
        !           252: 
        !           253: /*
        !           254:  * arpadate is like ctime(3) except that the time is returned in
        !           255:  * an acceptable ARPANET time format instead of ctime format.
        !           256:  */
        !           257: char *
        !           258: arpadate(longtime)
        !           259: time_t *longtime;
        !           260: {
        !           261:        register char *p, *q, *ud;
        !           262:        register int i;
        !           263:        static char b[40];
        !           264:        extern struct tm *gmtime();
        !           265:        extern char *asctime();
        !           266: 
        !           267:        /*  Get current time. This will be used resolve the timezone. */
        !           268:        ud = asctime(gmtime(longtime));
        !           269: 
        !           270:        /*  Crack the UNIX date line in a singularly unoriginal way. */
        !           271:        q = b;
        !           272: 
        !           273: #ifdef notdef
        !           274: /* until every site installs the fix to getdate.y, the day
        !           275:    of the week can cause time warps */
        !           276:        p = &ud[0];             /* Mon */
        !           277:        *q++ = *p++;
        !           278:        *q++ = *p++;
        !           279:        *q++ = *p++;
        !           280:        *q++ = ','; *q++ = ' ';
        !           281: #endif
        !           282: 
        !           283:        p = &ud[8];             /* 16 */
        !           284:        if (*p == ' ')
        !           285:                p++;
        !           286:        else
        !           287:                *q++ = *p++;
        !           288:        *q++ = *p++; *q++ = ' ';
        !           289: 
        !           290:        p = &ud[4];             /* Sep */
        !           291:        *q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = ' ';
        !           292: 
        !           293:        p = &ud[22];            /* 1979 */
        !           294:        *q++ = *p++; *q++ = *p++; *q++ = ' ';
        !           295: 
        !           296:        p = &ud[11];            /* 01:03:52 */
        !           297:        for (i = 8; i > 0; i--)
        !           298:                *q++ = *p++;
        !           299: 
        !           300:        *q++ = ' ';
        !           301:        *q++ = 'G';             /* GMT */
        !           302:        *q++ = 'M';
        !           303:        *q++ = 'T';
        !           304:        *q = '\0';
        !           305: 
        !           306:        return b;
        !           307: }
        !           308: 
        !           309: char *
        !           310: replyname(hptr)
        !           311: struct hbuf *hptr;
        !           312: {
        !           313:        register char *ptr;
        !           314:        static char tbuf[PATHLEN];
        !           315: 
        !           316:        ptr = hptr->path;
        !           317:        if (prefix(ptr, FULLSYSNAME) &&
        !           318:                index(NETCHRS, ptr[strlen(FULLSYSNAME)]))
        !           319:                ptr = index(ptr, '!') + 1;
        !           320: #ifdef INTERNET
        !           321:        if (hptr->from[0])
        !           322:                ptr = hptr->from;
        !           323:        if (hptr->replyto[0])
        !           324:                ptr = hptr->replyto;
        !           325: #endif
        !           326:        (void) strcpy(tbuf, ptr);
        !           327:        ptr = index(tbuf, '(');
        !           328:        if (ptr) {
        !           329:                while (ptr[-1] == ' ')
        !           330:                        ptr--;
        !           331:                *ptr = 0;
        !           332:        }
        !           333: #ifdef SunIII
        !           334:        if (ptr = rindex(tbuf, '.')) {
        !           335:                if (prefix(++ptr, "OZ")) {
        !           336:                        /* some people only allow it in lower case ... */
        !           337:                        strcpy(ptr, "oz");
        !           338:                        return tbuf;
        !           339:                }
        !           340:                if (prefix(ptr, "UUCP") || prefix(ptr, "ARPA") ||
        !           341:                    prefix(ptr, "DEC") || prefix(ptr, "CSNET")) {
        !           342:                        strcat(tbuf, "@munnari.oz");    /* via sun to munnari */
        !           343:                        return tbuf;
        !           344:                }
        !           345:        }
        !           346:        /*
        !           347:         * must(?) have come from a uucp site, lets look see if path passes
        !           348:         * through munnari, and if so delete the fake uucp path after that.
        !           349:         */
        !           350:        for (ptr = tbuf ;; ptr++) {
        !           351:                if (prefix(ptr, "munnari!")) {
        !           352:                        strcpy(tbuf, ptr+8);
        !           353:                        break;
        !           354:                }
        !           355:                ptr = index(ptr, '!');
        !           356:                if (ptr == (char *)0)
        !           357:                        break;
        !           358:        }
        !           359:        /*
        !           360:         * now, just send the address we have left to munnari, and
        !           361:         * hope that something sensible will be done with it there.
        !           362:         * (This works in more cases than you'd think ...)
        !           363:         */
        !           364:        strcat(tbuf, "@munnari.oz");
        !           365: #else /* !SunIII */
        !           366: #ifndef INTERNET
        !           367:        /*
        !           368:         * Play games stripping off multiple berknet
        !           369:         * addresses (a!b!c:d:e => a!b!d:e) here.
        !           370:         */
        !           371:        for (ptr=tbuf; *ptr; ptr++) {
        !           372:                register char *ptr2;
        !           373: 
        !           374:                if (index(NETCHRS, *ptr) && *ptr == ':' &&
        !           375:                    (ptr2=index(ptr+1, ':')))
        !           376:                        (void) strcpy(ptr, ptr2);
        !           377:        }
        !           378: #endif /* !INTERNET */
        !           379: #endif /* SunIII */
        !           380:        return tbuf;
        !           381: }
        !           382: 
        !           383: #ifdef DBM
        !           384: typedef struct {
        !           385:        char *dptr;
        !           386:        int dsize;
        !           387: } datum;
        !           388: #endif /* DBM */
        !           389: 
        !           390: /*
        !           391:  * Given an article ID, find the line in the history file that mentions it.
        !           392:  * Return the text of the line, or NULL if not found.  A pointer to a
        !           393:  * static area is returned.
        !           394:  */
        !           395: char *
        !           396: findhist(artid)
        !           397: char *artid;
        !           398: {
        !           399:        static char lbuf[256];
        !           400:        char oidbuf[BUFSIZ];
        !           401:        FILE *hfp;
        !           402:        register char *p;
        !           403: #ifdef DBM
        !           404:        datum lhs, rhs;
        !           405:        datum fetch();
        !           406:        long fpos; /* We have to use an explicit variable to insure alignment */
        !           407: #else /* !DBM */
        !           408:        char *histfile();
        !           409: #endif /* !DBM */
        !           410: 
        !           411:        /* Try to understand old artid's as well.  Assume .UUCP domain. */
        !           412:        if (artid[0] != '<') {
        !           413:                p = index(artid, '.');
        !           414:                if (p)
        !           415:                        *p++ = '\0';
        !           416:                (void) sprintf(oidbuf, "<%s@%s.UUCP>", p, artid);
        !           417:                if (p)
        !           418:                        *--p = '.';
        !           419:        } else
        !           420:                (void) strcpy(oidbuf, artid);
        !           421:        lcase(oidbuf);
        !           422: #ifdef DBM
        !           423:        initdbm(ARTFILE);
        !           424:        lhs.dptr = oidbuf;
        !           425:        lhs.dsize = strlen(lhs.dptr) + 1;
        !           426:        rhs = fetch(lhs);
        !           427:        if (rhs.dptr == NULL)
        !           428:                return NULL;
        !           429:        hfp = xfopen(ARTFILE, "r");
        !           430:        /* The bcopy is NECESSARY to insure alignment on some machines */
        !           431:        bcopy(rhs.dptr, (char *)&fpos, sizeof (long));
        !           432:        fseek(hfp, fpos, 0);
        !           433: #else /* !DBM */
        !           434:        hfp = xfopen(histfile(oidbuf), "r");
        !           435: #endif /* !DBM */
        !           436:        while (fgets(lbuf, BUFLEN, hfp) != NULL) {
        !           437:                p = index(lbuf, '\t');
        !           438:                if (p == NULL)
        !           439:                        p = index(lbuf, '\n');
        !           440:                *p = 0;
        !           441:                if (strcmp(lbuf, artid) == 0 || strcmp(lbuf, oidbuf) == 0) {
        !           442:                        (void) fclose(hfp);
        !           443:                        *p = '\t';
        !           444:                        *(lbuf + strlen(lbuf) - 1) = 0; /* zap the \n */
        !           445:                        return lbuf;
        !           446:                }
        !           447: #ifdef DBM
        !           448:                break;
        !           449: #endif /* DBM */
        !           450:        }
        !           451:        (void) fclose(hfp);
        !           452:        return NULL;
        !           453: }
        !           454: 
        !           455: /*
        !           456:  * Hunt up the article "artid", and return the newsgroup/artnum
        !           457:  * where it can be found.
        !           458:  */
        !           459: char *
        !           460: findfname(artid)
        !           461: char *artid;
        !           462: {
        !           463:        char *line, *p, *q;
        !           464:        char *findhist();
        !           465:        static char fname[BUFLEN];
        !           466: 
        !           467:        line = findhist(artid);
        !           468:        if (line) {
        !           469:                /* Look for it stored as an article, where it should be */
        !           470:                p = index(line, '\t');
        !           471:                p = index(p+1, '\t');
        !           472:                p++;
        !           473:                if (*p) {
        !           474:                        q = index(p, ' ');
        !           475:                        if (q)
        !           476:                                *q = 0;
        !           477:                        (void) strcpy(fname, p);
        !           478:                        return fname;
        !           479:                }
        !           480:        }
        !           481:        return NULL;
        !           482: }
        !           483: 
        !           484: /*
        !           485:  * Hunt up the article "artid", fopen it for read, and return a
        !           486:  * file descriptor to it.  We look everywhere we can think of.
        !           487:  */
        !           488: FILE *
        !           489: hfopen(artid)
        !           490: char *artid;
        !           491: {
        !           492:        char *p;
        !           493:        char *findhist();
        !           494:        FILE *rv = NULL;
        !           495:        char fname[BUFLEN];
        !           496: 
        !           497:        p = findfname(artid);
        !           498:        if (p) {
        !           499:                (void) strcpy(fname, dirname(p));
        !           500:                rv = fopen(fname, "r"); /* NOT xfopen! */
        !           501:                if (rv == NULL)
        !           502:                        xerror("Cannot hfopen article %s", artid);
        !           503:        }
        !           504:        return rv;
        !           505: }
        !           506: 
        !           507: #ifdef DBM
        !           508: /*
        !           509: ** Avoid problems of multiple dbminit calls.
        !           510: */
        !           511: initdbm(name)
        !           512: char *name;
        !           513: {
        !           514:        static int called = 0;
        !           515: 
        !           516:        if (called != 0)
        !           517:                return;
        !           518:        called = 1;
        !           519:        (void) dbminit(name);
        !           520: }
        !           521: #endif
        !           522: 
        !           523: #ifndef BSD4_2
        !           524: /*
        !           525:  * move n bytes from a to b
        !           526:  */
        !           527: bcopy(a, b, n)
        !           528: register char *a, *b;
        !           529: register n;
        !           530: {
        !           531:        while (--n >= 0)
        !           532:                *b++ = *a++;
        !           533: }
        !           534: #endif
        !           535: 
        !           536: #if !defined(BSD4_2) && !defined(BSD4_1C)
        !           537: rename(from,to)
        !           538: register char *from, *to;
        !           539: {
        !           540:        (void) unlink(to);
        !           541:        if (link(from, to) < 0)
        !           542:                return -1;
        !           543: 
        !           544:        (void) unlink(from);
        !           545:        return 0;
        !           546: }
        !           547: #endif /* !BSD4_2 && ! BSD4_1C */
        !           548: 
        !           549: #ifndef DBM
        !           550: /*
        !           551: ** Generate the appropriate history subfile name
        !           552: */
        !           553: char *
        !           554: histfile(hline)
        !           555: char *hline;
        !           556: {
        !           557:        char *p;
        !           558:        char chr;       /* least significant digit of article number */
        !           559:        static char subfile[BUFLEN];
        !           560: 
        !           561:        p = strchr(hline, '@');
        !           562:        if (p != NULL && p > hline)
        !           563:                chr = *(p - 1);
        !           564:        else
        !           565:                chr = '0';
        !           566:        if (!isdigit(chr))
        !           567:                chr = '0';
        !           568:        sprintf(subfile, "%s.d/%c", ARTFILE, chr);
        !           569:        if (access(subfile, 04) < 0)
        !           570:                return(ARTFILE);
        !           571:        return(subfile);
        !           572: }
        !           573: #endif /* !DBM */

unix.superglobalmegacorp.com

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