Annotation of researchv10no/cmd/netnews/src/ifuncs.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * ifuncs - functions used by inews.
        !             3:  */
        !             4: 
        !             5: static char *SccsId = "@(#)ifuncs.c    2.21    3/31/83";
        !             6: 
        !             7: #include "iparams.h"
        !             8: 
        !             9: /*
        !            10:  * Transmit this article to all interested systems.
        !            11:  */
        !            12: 
        !            13: #ifdef u370
        !            14: static struct srec srec;
        !            15: static struct hbuf h;
        !            16: #endif
        !            17: 
        !            18: broadcast()
        !            19: {
        !            20:        register char *nptr, *hptr;
        !            21:        register FILE *fp;
        !            22: #ifndef u370
        !            23:        struct srec srec;
        !            24:        struct hbuf h;
        !            25: #endif
        !            26: 
        !            27:        /* h is a local copy of the header we can scribble on */
        !            28:        fp = xfopen(ARTICLE, "r");
        !            29:        if (hread(&h, fp, TRUE) == NULL)
        !            30:                xerror("Cannot reread article");
        !            31:        fclose(fp);
        !            32:        if (h.distribution[0])
        !            33:                strcpy(h.nbuf, h.distribution);
        !            34:        ngcat(h.nbuf);
        !            35: 
        !            36:         /* break path into list of systems. */
        !            37:        hptr = nptr = h.path;
        !            38:        while (*hptr != '\0') {
        !            39:                if (index(NETCHRS, *hptr)) {
        !            40:                        *hptr++ = '\0';
        !            41:                        nptr = hptr;
        !            42:                } else
        !            43:                        hptr++;
        !            44:        }
        !            45:        *nptr = '\0';
        !            46: 
        !            47:        /* loop once per system. */
        !            48:        lock();
        !            49:        s_openr();
        !            50:        while (s_read(&srec)) {
        !            51:                if (strncmp(srec.s_name, FULLSYSNAME, SNLN) == 0)
        !            52:                        continue;
        !            53:                hptr = h.path;
        !            54:                while (*hptr != '\0') {
        !            55:                        if (strncmp(srec.s_name, hptr, SNLN) == 0)
        !            56:                                goto contin;
        !            57:                        while (*hptr++ != '\0')
        !            58:                                ;
        !            59:                }
        !            60:                if (ngmatch(h.nbuf, srec.s_nbuf)) {
        !            61:                        transmit(&srec, xfopen(ARTICLE, "r"), 1);
        !            62:                }
        !            63:        contin:;
        !            64:        }
        !            65:        s_close();
        !            66:        unlock();
        !            67: }
        !            68: 
        !            69: /*
        !            70:  * Transmit file to system.
        !            71:  */
        !            72: #define PROC 0004
        !            73: transmit(sp, ifp, maynotify)
        !            74: register struct srec *sp;
        !            75: register FILE *ifp;
        !            76: int maynotify;
        !            77: {
        !            78:        register FILE *ofp;
        !            79:        register int c;
        !            80:        register char *ptr;
        !            81:        struct hbuf hh;
        !            82:        char TRANS[BUFLEN];
        !            83:        char *argv[20];
        !            84:        register int pid, fd;
        !            85:        extern char firstbufname[];
        !            86: 
        !            87: /* A:  afmt: the other machine runs an A news, so we xmit in A format */
        !            88:        int afmt = (index(sp->s_flags, 'A') != NULL);
        !            89: /* B:  use B format (this is the default - don't use this letter elsewise). */
        !            90: /* F:  append name to file */
        !            91:        int appfile = (index(sp->s_flags, 'F') != NULL);
        !            92: /* L:  local: don't send the article unless it was generated locally */
        !            93:        int local = (index(sp->s_flags, 'L') != NULL);
        !            94: /* N:  notify: don't send the article, just tell him we have it */
        !            95:        int notify = maynotify && (index(sp->s_flags, 'N') != NULL);
        !            96: /* S:  noshell: don't fork a shell to execute the xmit command */
        !            97:        int noshell = (index(sp->s_flags, 'S') != NULL);
        !            98: /* U:  useexist: use the -c option to uux to use the existing copy */
        !            99:        int useexist = (index(sp->s_flags, 'U') != NULL);
        !           100: 
        !           101:        if (local && mode == PROC)
        !           102:                return;
        !           103: #ifdef DEBUG
        !           104:        printf("Transmitting to '%s'\n", sp->s_name);
        !           105: #endif
        !           106:        if (!appfile && !useexist) {
        !           107:                if (hread(&hh, ifp, TRUE) == NULL) {
        !           108:                        fprintf(stderr, "Bad header, not transmitting\n");
        !           109:                        log("Bad header, not transmitting %s re %s to %s",
        !           110:                                hh.ident, hh.title, sp->s_name);
        !           111:                        return;
        !           112:                }
        !           113:                /* Taken out for obscure reasons - see the standard.
        !           114:                ngsquash(hh.nbuf, sp->s_nbuf);
        !           115:                */
        !           116:                if (hh.nbuf[0] == '\0') {
        !           117:                        printf("Article not subscribed to by %s\n", sp->s_name);
        !           118:                        return;
        !           119:                }
        !           120:                sprintf(TRANS, "%s/trXXXXXX", SPOOL);
        !           121:        }
        !           122: 
        !           123:        if (notify) {
        !           124:                char oldid[50];
        !           125:                sprintf(hh.title, "ihave %s %s", hh.ident, FULLSYSNAME);
        !           126:                sprintf(hh.nbuf, "to.%s.ctl", sp->s_name);
        !           127:                strcpy(oldid, hh.ident);
        !           128:                getident(&hh);
        !           129:                log("tell %s about %s, notif. id %s",
        !           130:                        sp->s_name, oldid, hh.ident);
        !           131:        } else
        !           132:                log("xmit article %s to %s",
        !           133:                        hh.ident, sp->s_name);
        !           134: 
        !           135:        if (appfile) {
        !           136:                if (firstbufname[0] == '\0')
        !           137:                        xerror("No file name to xmit from");
        !           138:                ofp = fopen(sp->s_xmit, "a");
        !           139:                if (ofp == NULL)
        !           140:                        xerror("Cannot append to %s", sp->s_xmit);
        !           141:                fprintf(ofp, "%s\n", firstbufname);
        !           142:                fclose(ofp);
        !           143:                return;
        !           144:        }
        !           145:        else
        !           146: #ifdef UXMIT
        !           147:        if (useexist) {
        !           148:                if (firstbufname[0] == '\0')
        !           149:                        xerror("No file name to xmit from");
        !           150:                if (*sp->s_xmit == '\0')
        !           151:                        sprintf(bfr, UXMIT, sp->s_name, firstbufname);
        !           152:                else
        !           153:                        sprintf(bfr, sp->s_xmit, firstbufname);
        !           154:        } else
        !           155: #endif
        !           156:        {
        !           157:                ofp = xfopen(mktemp(TRANS), "w");
        !           158:                if (afmt)
        !           159:                        ohwrite(&hh, ofp);
        !           160:                else 
        !           161:                        hwrite(&hh, ofp);
        !           162:                if (!notify)
        !           163:                        while ((c = getc(ifp)) != EOF)
        !           164:                                putc(c, ofp);
        !           165:                fclose(ifp);
        !           166:                fclose(ofp);
        !           167:                if (*sp->s_xmit == '\0')
        !           168:                        sprintf(bfr, DFTXMIT, sp->s_name, TRANS);
        !           169:                else
        !           170:                        sprintf(bfr, "(%s) < %s", sp->s_xmit, TRANS);
        !           171:        }
        !           172: 
        !           173:        /* At this point, the command to be executed is in bfr. */
        !           174:        if (noshell) {
        !           175:                if (pid = fork())
        !           176:                        fwait(pid);
        !           177:                else {
        !           178:                        close(0);
        !           179:                        open(TRANS, 0);
        !           180:                        ptr = sp->s_xmit;
        !           181:                        for (pid = 0; pid < 19; pid++) {
        !           182:                                while (isspace(*ptr))
        !           183:                                        *ptr++ = 0;
        !           184:                                argv[pid] = ptr;
        !           185:                                while (!isspace(*++ptr) && *ptr)
        !           186:                                        ;
        !           187:                                if (!*ptr)
        !           188:                                        break;
        !           189:                        }
        !           190:                        argv[++pid] = 0;
        !           191:                        execv(sp->s_xmit, argv);
        !           192:                        xerror("Can't execv\n");
        !           193:                }
        !           194:        } else
        !           195:                system(bfr);
        !           196:        if (!appfile && !useexist)
        !           197:                unlink(TRANS);
        !           198: }
        !           199: 
        !           200: typedef struct {
        !           201:        char *dptr;
        !           202:        int dsize;
        !           203: } datum;
        !           204: 
        !           205: /*
        !           206:  * Return TRUE if we have seen this file before, else FALSE.
        !           207:  */
        !           208: history(hp)
        !           209: struct hbuf *hp;
        !           210: {
        !           211:        register FILE *hfp;
        !           212:        register char *p;
        !           213:        datum lhs, rhs;
        !           214:        datum fetch();
        !           215: 
        !           216: #ifdef DEBUG
        !           217:        fprintf(stderr,"history(%s)\n", hp->ident);
        !           218: #endif
        !           219:        idlock(hp->ident);
        !           220: #ifdef DBM
        !           221:        dbminit(ARTFILE);
        !           222:        lhs.dptr = hp->ident;
        !           223:        lhs.dsize = strlen(lhs.dptr) + 1;
        !           224:        rhs = fetch(lhs);
        !           225:        if (rhs.dptr)
        !           226:                return(TRUE);
        !           227: #else
        !           228:        hfp = xfopen(ARTFILE, "r");
        !           229:        while (fgets(bfr, BUFLEN, hfp) != NULL) {
        !           230:                p = index(bfr, '\t');
        !           231:                if (p == NULL)
        !           232:                        p = index(bfr, '\n');
        !           233:                if (p != NULL)  /* can happen if nulls in file */
        !           234:                        *p = 0;
        !           235:                if (strcmp(bfr, hp->ident)==0 ||
        !           236:                                hp->oident[0] && strcmp(bfr, hp->oident)==0) {
        !           237:                        fclose(hfp);
        !           238:                        idunlock();
        !           239: #ifdef DEBUG
        !           240:                        fprintf(stderr,"history returns true\n");
        !           241: #endif
        !           242:                        return(TRUE);
        !           243:                }
        !           244:        }
        !           245:        fclose(hfp);
        !           246: #endif
        !           247:        addhist(hp->ident);
        !           248:        addhist("\t");
        !           249: #ifdef DEBUG
        !           250:        fprintf(stderr,"history returns false\n");
        !           251: #endif
        !           252:        return(FALSE);
        !           253: }
        !           254: 
        !           255: static char histline[256];     /* Assumed initially zero */
        !           256: 
        !           257: addhist(msg)
        !           258: char *msg;
        !           259: {
        !           260:        strcat(histline, msg);
        !           261: }
        !           262: 
        !           263: savehist()
        !           264: {
        !           265:        register FILE *hfp;
        !           266:        datum lhs, rhs;
        !           267:        long fpos;
        !           268:        register char *p;
        !           269: 
        !           270:        hfp = xfopen(ARTFILE, "a");
        !           271:        fpos = ftell(hfp);
        !           272:        fprintf(hfp, "%s\n", histline);
        !           273:        fclose(hfp);
        !           274: #ifdef DBM
        !           275:        /* We assume that history has already been called, calling dbminit. */
        !           276:        p = index(histline, '\t');
        !           277:        if (p)
        !           278:                *p = 0;
        !           279:        lhs.dptr = histline;
        !           280:        lhs.dsize = strlen(lhs.dptr) + 1;
        !           281:        rhs.dptr = (char *) &fpos;
        !           282:        rhs.dsize = sizeof fpos;
        !           283:        store(lhs, rhs);
        !           284: #endif
        !           285:        histline[0] = 0;
        !           286:        idunlock();
        !           287: }
        !           288: 
        !           289: /*
        !           290:  * Save partial news.
        !           291:  */
        !           292: newssave(fd, dummy)
        !           293: FILE *fd, *dummy;
        !           294: {
        !           295:        register FILE *tofd, *fromfd;
        !           296:        char sfname[BUFLEN];
        !           297:        register int c;
        !           298:        struct hbuf h;
        !           299:        time_t tim;
        !           300: 
        !           301:        if (fd == NULL)
        !           302:                fromfd = xfopen(INFILE, "r");
        !           303:        else
        !           304:                fromfd = fd;
        !           305:        umask(savmask);
        !           306:        setgid(gid);
        !           307:        setuid(uid);
        !           308: 
        !           309:        sprintf(sfname, "%s/%s", userhome, PARTIAL);
        !           310:        if ((tofd = fopen(sfname, "a")) == NULL)
        !           311:                xerror("Cannot save partial news");
        !           312:        time(&tim);
        !           313:        fprintf(tofd, "----- News saved at %s\n", arpadate(&tim));
        !           314:        while ((c = getc(fromfd)) != EOF)
        !           315:                putc(c, tofd);
        !           316:        fclose(fromfd);
        !           317:        fclose(tofd);
        !           318:        printf("News saved in %s\n", sfname);
        !           319:        xxit(0);
        !           320: }
        !           321: 
        !           322: /*
        !           323:  * Handle dates in header.
        !           324:  */
        !           325: 
        !           326: dates(hp)
        !           327: struct hbuf *hp;
        !           328: {
        !           329:        long edt;
        !           330: 
        !           331:        time(&hp->rectime);
        !           332:        nstrip(strcpy(hp->recdate, arpadate(&hp->rectime)));
        !           333:        if (*hp->subdate) {
        !           334:                if (cgtdate(hp->subdate) < 0) {
        !           335:                        log("Bad sub date '%s'", hp->subdate);
        !           336:                        xerror("Cannot parse submittal date");
        !           337:                }
        !           338:        } else
        !           339:                strcpy(hp->subdate, hp->recdate);
        !           340:        if (*hp->expdate) {
        !           341:                if ((edt = cgtdate(hp->expdate)) < 0)
        !           342:                        xerror("Cannot parse expiration date");
        !           343:                nstrip(strcpy(hp->expdate, arpadate(&edt)));
        !           344:        } else {
        !           345:                defexp = TRUE;
        !           346:                /*
        !           347:                 * Default is now applied in expire.c
        !           348:                hp->exptime = hp->rectime + DFLTEXP;
        !           349:                nstrip(strcpy(hp->expdate, arpadate(&hp->exptime)));
        !           350:                */
        !           351:        }
        !           352: }
        !           353: 
        !           354: /*
        !           355:  *     Exit and cleanup.
        !           356:  */
        !           357: xxit(status)
        !           358: int status;
        !           359: {
        !           360:        unlink(INFILE);
        !           361:        unlink(ARTICLE);
        !           362:        while (lockcount > 0)
        !           363:                unlock();
        !           364:        idunlock();
        !           365:        exit(status);
        !           366: }
        !           367: 
        !           368: xerror(message, arg1, arg2)
        !           369: char *message;
        !           370: int arg1, arg2;
        !           371: {
        !           372:        char buffer[128];
        !           373: 
        !           374:        fflush(stdout);
        !           375:        sprintf(buffer, message, arg1, arg2);
        !           376:        fprintf(stderr, "inews: %s.\n", buffer);
        !           377:        log(buffer);
        !           378:        xxit(1);
        !           379: }
        !           380: 
        !           381: #ifdef VMS
        !           382: 
        !           383: #define        SUBLOCK "/tmp/netnews.lck.1"
        !           384: 
        !           385: /*
        !           386:  * Newsystem locking.
        !           387:  * These routines are different for VMS because we can not
        !           388:  * effectively simulate links, and VMS supports multiple
        !           389:  * version numbers of files
        !           390:  */
        !           391: lock()
        !           392: {
        !           393:        register int i;
        !           394:        register int fd;
        !           395: 
        !           396:        if (lockcount++ == 0) {
        !           397:                i = DEADTIME;
        !           398:                while ((fd = creat(SUBLOCK, 0444)) < 0) {
        !           399:                        if (--i < 0) {
        !           400:                                unlink(SUBLOCK);
        !           401:                                log("News system locked up");
        !           402:                        }
        !           403:                        if (i < -3)
        !           404:                                xerror("Unable to unlock news system");
        !           405:                        sleep((unsigned)1);
        !           406:                }
        !           407:                close(fd);
        !           408:        }
        !           409: }
        !           410: 
        !           411: unlock()
        !           412: {
        !           413:        if (--lockcount == 0)
        !           414:                unlink(SUBLOCK);
        !           415: }
        !           416: 
        !           417: #else  VMS
        !           418: 
        !           419: /*
        !           420:  * Newsystem locking.
        !           421:  */
        !           422: 
        !           423: lock()
        !           424: {
        !           425:        register int i;
        !           426: 
        !           427:        if (lockcount++ == 0) {
        !           428:                i = DEADTIME;
        !           429:                while (link(SUBFILE, LOCKFILE)) {
        !           430:                        if (--i < 0)
        !           431:                                xerror("News system locked up");
        !           432:                        sleep((unsigned)1);
        !           433:                }
        !           434:        }
        !           435: }
        !           436: 
        !           437: unlock()
        !           438: {
        !           439:        if (--lockcount == 0)
        !           440:                unlink(LOCKFILE);
        !           441: }
        !           442: #endif VMS
        !           443: 
        !           444: char lockname[80];
        !           445: idlock(str)
        !           446: char *str;
        !           447: {
        !           448:        register int i;
        !           449:        char tempname[80];
        !           450:        long now;
        !           451:        struct stat sbuf;
        !           452:        int fd;
        !           453: 
        !           454: #ifdef VMS
        !           455:        sprintf(lockname, "/tmp/%s.l.1", str);
        !           456:        if ((fd = creat(lockname, 0444)) < 0) {
        !           457: #else  VMS
        !           458:        sprintf(tempname, "/tmp/LTMP.%d", getpid());
        !           459:        sprintf(lockname, "/tmp/L%s", str);
        !           460: #ifdef FOURTEENMAX
        !           461:        lockname[5 /* /tmp/ */ + 14] = '\0';
        !           462: #endif
        !           463:        close(creat(tempname, 0666));
        !           464:        while (link(tempname, lockname)) {
        !           465: #endif VMS
        !           466:                time(&now);
        !           467:                i = stat(lockname, &sbuf);
        !           468:                if (i < 0) {
        !           469:                        xerror("Directory permission problem in /tmp");
        !           470:                }
        !           471:                if (sbuf.st_mtime + 10*60 < now) {
        !           472:                        unlink(lockname);
        !           473:                        log("Article %s locked up", str);
        !           474:                        continue;
        !           475:                }
        !           476:                log("waiting on lock for %s", lockname);
        !           477:                sleep((unsigned)60);
        !           478:        }
        !           479: #ifdef VMS
        !           480:        close(fd);
        !           481: #else
        !           482:        unlink(tempname);
        !           483: #endif
        !           484:        unlink(tempname);
        !           485: }
        !           486: 
        !           487: idunlock()
        !           488: {
        !           489:        unlink(lockname);
        !           490: }
        !           491: 
        !           492: /*
        !           493:  * Put a unique name into header.ident.
        !           494:  */
        !           495: getident(hp)
        !           496: struct hbuf *hp;
        !           497: {
        !           498:        long seqn;
        !           499:        register FILE *fp;
        !           500: 
        !           501:        lock();
        !           502:        fp = xfopen(SEQFILE, "r");
        !           503:        fgets(bfr, BUFLEN, fp);
        !           504:        fclose(fp);
        !           505:        seqn = atol(bfr) + 1;
        !           506: #ifdef VMS
        !           507:        unlink(SEQFILE);
        !           508: #endif VMS
        !           509:        fp = xfopen(SEQFILE, "w");
        !           510:        fprintf(fp, "%ld\n", seqn);
        !           511:        fclose(fp);
        !           512:        unlock();
        !           513:        sprintf(hp->ident, "<%ld@%s%s>", seqn, FULLSYSNAME, MYDOMAIN);
        !           514: }
        !           515: 
        !           516: /*
        !           517:  * Log the given message, with printf strings and parameters allowed,
        !           518:  * on the log file, if it can be written.  The date and an attempt at
        !           519:  * figuring out the remote system name are also logged.
        !           520:  */
        !           521: log(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
        !           522: char *fmt;
        !           523: {
        !           524:        FILE *logfile;
        !           525:        char msg[256];
        !           526:        char *logtime, *p, *q;
        !           527:        char rmtsys[256];
        !           528:        char c;
        !           529:        long t;
        !           530: 
        !           531:        if (header.relayversion[0]) {
        !           532:                for (p=header.relayversion; p; p=index(p+1, 's'))
        !           533:                        if (strncmp(p, "site ", 5) == 0)
        !           534:                                break;
        !           535:                if (p == NULL)
        !           536:                        goto crackpath;
        !           537:                p += 4;
        !           538:                while (*p == ' ' || *p == '\t')
        !           539:                        p++;
        !           540:                for (q=p; *q && *q!=' ' && *q != '\t'; q++)
        !           541:                        ;
        !           542:                c = *q;
        !           543:                strcpy(rmtsys, p);
        !           544:                *q = c;
        !           545:        } else {
        !           546: crackpath:
        !           547:                strcpy(rmtsys, header.path);
        !           548:                p = index(rmtsys, '!');
        !           549:                if (p == NULL)
        !           550:                        p = index(rmtsys, ':');
        !           551:                if (p)
        !           552:                        *p = 0;
        !           553:                else {
        !           554:                        p = rindex(rmtsys, '@');
        !           555:                        if (p)
        !           556:                                strcpy(rmtsys, p+1);
        !           557:                        else
        !           558:                                strcpy(rmtsys, "local");
        !           559:                }
        !           560:        }
        !           561: 
        !           562:        time(&t);
        !           563:        logtime = ctime(&t);
        !           564:        logtime[16] = 0;
        !           565:        logtime += 4;
        !           566: 
        !           567:        sprintf(msg, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
        !           568: 
        !           569:        lock();
        !           570:        if (access(logfname, 0)) {
        !           571:                unlock(0);
        !           572:                return;
        !           573:        }
        !           574:        logfile = fopen(logfname, "a");
        !           575:        if (logfile == NULL) {
        !           576:                unlock(0);
        !           577:                return;
        !           578:        }
        !           579:        fprintf(logfile, "%s %s\t%s\n", logtime, rmtsys, msg);
        !           580:        fclose(logfile);
        !           581:        unlock();
        !           582: }
        !           583: 
        !           584: /*
        !           585:  * Check if header.nbuf contains only valid newsgroup names;
        !           586:  * exit with error if not valid.
        !           587:  *
        !           588:  * a == TRUE means header.nbuf is subscription list
        !           589:  * a == FALSE means header.nbuf is newsgroup list
        !           590:  */
        !           591: 
        !           592: ngfcheck(a)
        !           593: int a;
        !           594: {
        !           595:        char ngcheck[NGFSIZ];   /* Hold NGFILE newsgroups */
        !           596:        char tbuf[BUFLEN];      /* hold single header.nbuf news group */
        !           597:        register char *s1, *s2;
        !           598:        register FILE *f;
        !           599: 
        !           600:        s1 = ngcheck;
        !           601:        f = xfopen(NGFILE, "r");
        !           602:        while (fgets(bfr, BUFLEN, f) != NULL) {
        !           603:                for (s2 = bfr; *s2 != '\0' &&
        !           604:                    *s2 != ' ' && *s2 != '\t' &&
        !           605:                    *s2 != ':' && *s2 != '\n';) {
        !           606:                        if (s1 >= &ngcheck[NGFSIZ-2])
        !           607:                                xerror("NGFILE too long");
        !           608:                        *s1++ = *s2++;
        !           609:                }
        !           610:                *s1++ = NGDELIM;
        !           611:        }
        !           612:        *s1 = '\0';
        !           613:        fclose(f);
        !           614:        for (s1 = header.nbuf; *s1 != '\0';) {
        !           615:                if (*s1 == NEGCHAR)
        !           616:                        s1++;
        !           617:                s2 = tbuf;
        !           618:                while ((*s2++ = *s1++) != NGDELIM)
        !           619:                        if (s1[-1] == ':')
        !           620:                                xerror("Newsgroup cannot contain ':'");
        !           621:                *s2 = '\0';
        !           622:                s2 = tbuf;
        !           623:                if (!ngmatch(s2, ngcheck) && (!a || !ngmatch(ngcheck, s2))) {
        !           624:                        ngdel(s2);
        !           625:                        sprintf(bfr, "Bad news group \"%s\"", s2);
        !           626:                        newssave(stdin, NULL);
        !           627:                        xerror(bfr);
        !           628:                }
        !           629:        }
        !           630: }
        !           631: 
        !           632: /*
        !           633:  * Figure out who posted the article (which is locally entered).
        !           634:  * The results are placed in the header structure hp.
        !           635:  */
        !           636: gensender(hp, logname)
        !           637: struct hbuf *hp;
        !           638: char *logname;
        !           639: {
        !           640:        char *fn;
        !           641:        static char buf[100];
        !           642:        char buf2[100];
        !           643:        char *fullname(), *getenv();
        !           644:        char *p;
        !           645:        int fd;
        !           646: 
        !           647:        fn = getenv("NAME");
        !           648: 
        !           649:        if (fn == NULL) {
        !           650:                sprintf(buf, "%s/%s", getenv("HOME"), ".name");
        !           651:                fd = open(buf, 0);
        !           652:                if (fd >= 0) {
        !           653:                        read(fd, buf2, sizeof buf2);
        !           654:                        close(fd);
        !           655:                        if (buf2[0] >= 'A')
        !           656:                                fn = buf2;
        !           657:                        for (p=fn; *p; p++)
        !           658:                                if (*p < ' ')
        !           659:                                        *p = 0;
        !           660:                }
        !           661:        }
        !           662: 
        !           663:        if (fn == NULL)
        !           664:                fn = fullname(logname);
        !           665: 
        !           666:        sprintf(hp->path, "%s", logname);
        !           667:        sprintf(hp->from, "%s@%s%s (%s)", logname, FULLSYSNAME, MYDOMAIN, fn);
        !           668: }
        !           669: 
        !           670: /*
        !           671:  * Trap interrupts.
        !           672:  */
        !           673: onsig(n)
        !           674: int n;
        !           675: {
        !           676:        static int numsigs = 0;
        !           677:        /*
        !           678:         * Most UNIX systems reset caught signals to SIG_DFL.
        !           679:         * This bad design requires that the trap be set again here.
        !           680:         * Unfortunately, if the signal recurs before the trap is set,
        !           681:         * the program will die, possibly leaving the lock in place.
        !           682:         */
        !           683:        if (++numsigs > 100) {
        !           684:                log("readnews ran away looping on signal %d", n);
        !           685:                xxit(1);
        !           686:        }
        !           687:        signal(n, onsig);
        !           688:        sigtrap = n;
        !           689: }
        !           690: 
        !           691: /*
        !           692:  * If the stdin begins with "#", we assume we have been fed a batched
        !           693:  * shell script which looks like this:
        !           694:  *     #! rnews 1234
        !           695:  *     article with 1234 chars
        !           696:  *     #! rnews 4321
        !           697:  *     article with 4321 chars
        !           698:  *
        !           699:  * In this case we just exec the unbatcher and let it unpack and call us back.
        !           700:  *
        !           701:  * Note that there is a potential security hole here.  If the batcher is
        !           702:  * /bin/sh, someone could ship you arbitrary stuff to run as shell commands.
        !           703:  * The main protection you have is that the effective uid will be news, not
        !           704:  * uucp and not the super user.  (That, plus the fact that BATCH is set to
        !           705:  * "unbatch" as the system is distributed.)  If you want to run a batched link
        !           706:  * and you are security concious, do not use /bin/sh as the unbatcher.
        !           707:  * the thing to do is to change BATCH in your localize.sh file from /bin/sh
        !           708:  * to some restricted shell which can only run rnews.
        !           709:  */
        !           710: checkbatch()
        !           711: {
        !           712:        int c;
        !           713: 
        !           714: #ifdef BATCH
        !           715:        c = getc(stdin);
        !           716:        ungetc(c, stdin);
        !           717:        clearerr(stdin);
        !           718:        if (c == '#') {
        !           719:                reset_stdin();
        !           720:                execl(BATCH, "news-unpack", 0);
        !           721:                xerror("Unable to exec shell to unpack news.\n");
        !           722:        }
        !           723: #endif
        !           724: }
        !           725: 
        !           726: /*
        !           727:  * We've already done a read on stdin, and we want to seek back to the
        !           728:  * beginning.  We want the real file descriptor (beyond buffers) to
        !           729:  * reflect the true beginning.  Do whatever is necessary.
        !           730:  */
        !           731: reset_stdin()
        !           732: {
        !           733:        register FILE *ofd;
        !           734:        register int c;
        !           735:        char *ofdname;
        !           736: 
        !           737:        /* First try to seek back - if so, it's a cheap way back. */
        !           738:        if (lseek(0, 0L, 0) == 0)
        !           739:                return;
        !           740: 
        !           741:        /* Can't seek, so have to copy input to a file and use that. */
        !           742:        ofdname = "/tmp/inewsXXXXX";
        !           743:        mktemp(ofdname);
        !           744:        ofd = fopen(ofdname, "w");
        !           745:        while ((c=getc(stdin)) != EOF)
        !           746:                putc(c, ofd);
        !           747:        fclose(stdin);
        !           748:        fclose(ofd);
        !           749: 
        !           750:        /* Now for a few lower level hacks to reopen stdin and make
        !           751:         * absolutely sure that the right fd's are done for the exec.
        !           752:         */
        !           753:        close(0);               /* to make sure stdin is really closed. */
        !           754:        open(ofdname, 0);       /* returns zero */
        !           755:        unlink(ofdname);        /* to avoid cleaning it up later. */
        !           756: }

unix.superglobalmegacorp.com

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