Annotation of 43BSD/contrib/news/src/funcs2.c, revision 1.1.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.