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

1.1     ! root        1: /*
        !             2:  * inews - insert, receive, and transmit news articles.
        !             3:  */
        !             4: 
        !             5: static char *SccsId = "@(#)inews.c     2.30    6/24/83";
        !             6: 
        !             7: #include "iparams.h"
        !             8: 
        !             9: /* local defines for inews */
        !            10: 
        !            11: #define OPTION 0       /* pick up an option string */
        !            12: #define STRING 1       /* pick up a string of arguments */
        !            13: 
        !            14: #define UNKNOWN 0001   /* possible modes for news program */
        !            15: #define UNPROC 0002    /* Unprocessed input */
        !            16: #define PROC   0004    /* Processed input */
        !            17: #define        CANCEL  0010    /* Cancel an article */
        !            18: #define        CREATENG 0020   /* Create a new newsgroup */
        !            19: 
        !            20: #ifndef SYSBUF
        !            21: char   SYSBUF[BUFSIZ];         /* to buffer std out */
        !            22: #endif
        !            23: char   forgedname[100];        /* A user specified -f option. */
        !            24: 
        !            25: struct {                       /* options table. */
        !            26:        char    optlet;         /* option character. */
        !            27:        char    filchar;        /* if to pickup string, fill character. */
        !            28:        int     flag;           /* TRUE if have seen this opt. */
        !            29:        int     oldmode;        /* OR of legal input modes. */
        !            30:        int     newmode;        /* output mode. */
        !            31:        char    *buf;           /* string buffer */
        !            32: } *optpt, options[] = { /*
        !            33: optlet filchar         flag    oldmode newmode         buf     */
        !            34: 't',   ' ',            FALSE,  UNPROC, UNKNOWN,        header.title,
        !            35: 'n',   NGDELIM,        FALSE,  UNPROC, UNKNOWN,        header.nbuf,
        !            36: 'e',   ' ',            FALSE,  UNPROC, UNKNOWN,        header.expdate,
        !            37: 'p',   '\0',           FALSE,  UNKNOWN,PROC,           filename,
        !            38: 'f',   '\0',           FALSE,  UNPROC, UNKNOWN,        forgedname,
        !            39: 'F',   ' ',            FALSE,  UNPROC, UNKNOWN,        header.followid,
        !            40: 'c',   '\0',           FALSE,  UNKNOWN,CANCEL,         filename,
        !            41: 'C',   '\0',           FALSE,  UNKNOWN,CREATENG,       header.nbuf,
        !            42: #define Dflag  options[8].flag
        !            43: 'D',   '\0',           FALSE,  UNPROC, UNKNOWN,        filename,
        !            44: #define hflag  options[9].flag
        !            45: 'h',   '\0',           FALSE,  UNPROC, UNKNOWN,        filename,
        !            46: '\0',  '\0',           0,      0,      0,              (char *)NULL
        !            47: };
        !            48: 
        !            49: FILE *mailhdr();
        !            50: 
        !            51: /*
        !            52:  *     Authors:
        !            53:  *             Matt Glickman   [email protected]
        !            54:  *             Mark Horton     [email protected]
        !            55:  *             Stephen Daniels [email protected]
        !            56:  *             Tom Truscott    [email protected]
        !            57:  *     IHCC version adapted by:
        !            58:  *             Larry Marek     [email protected]
        !            59:  */
        !            60: main(argc, argv)
        !            61: int    argc;
        !            62: register char **argv;
        !            63: {
        !            64:        int     state;          /* which type of argument to pick up    */
        !            65:        int     tlen, len;      /* temps for string processing routine  */
        !            66:        register char *ptr;     /* pointer to rest of buffer            */
        !            67:        int     filchar;        /* fill character (state = STRING)      */
        !            68:        char    *user, *home;   /* environment temps                    */
        !            69:        struct passwd   *pw;    /* struct for pw lookup                 */
        !            70:        struct group    *gp;    /* struct for group lookup              */
        !            71:        struct srec     srec;   /* struct for sys file lookup           */
        !            72:        struct utsname  ubuf;
        !            73:        register int    i;
        !            74:        FILE    *mfd;           /* mail file file-descriptor            */
        !            75:        char    cbuf[BUFLEN];   /* command buffer                       */
        !            76: 
        !            77:        /* uuxqt doesn't close all it's files */
        !            78:        for (i = 3; !close(i); i++)
        !            79:                ;
        !            80:        /* set up defaults and initialize. */
        !            81:        mode = UNKNOWN;
        !            82:        pathinit();
        !            83:        ptr = rindex(*argv, '/');
        !            84:        if (!ptr) 
        !            85:                ptr = *argv - 1;
        !            86:        if (!strncmp(ptr+1, "rnews", 5))
        !            87:                mode = PROC;
        !            88:        else if (argc < 2)
        !            89:                goto usage;
        !            90: 
        !            91:        state = OPTION;
        !            92:        header.title[0] = header.nbuf[0] = filename[0] = '\0';
        !            93: 
        !            94:        /* check for existence of special files */
        !            95:        if (!rwaccess(ARTFILE)) {
        !            96:                mfd = mailhdr(NULL, exists(ARTFILE) ? "Unwritable files!" : "Missing files!");
        !            97:                if (mfd != NULL) {
        !            98:                        fprintf(mfd,"System: %s\n\nThere was a problem with %s!!\n", SYSNAME, ARTFILE);
        !            99:                        sprintf(cbuf, "touch %s;chmod 666 %s", ARTFILE, ARTFILE);
        !           100:                        system(cbuf);
        !           101:                        if (rwaccess(ARTFILE))
        !           102:                                fprintf(mfd, "The problem has been taken care of.\n");
        !           103:                        else
        !           104:                                fprintf(mfd, "Corrective action failed - check suid bits.\n");
        !           105:                        mclose(mfd);
        !           106:                }
        !           107:        }
        !           108:        if (!rwaccess(ACTIVE)) {
        !           109:                mfd = mailhdr(NULL, exists(ACTIVE) ? "Unwritable files!" : "Missing files!");
        !           110:                if (mfd != NULL) {
        !           111:                        fprintf(mfd, "System: %s\n\nThere was a problem with %s!!\n", SYSNAME, ACTIVE);
        !           112:                        sprintf(cbuf, "touch %s;chmod 666 %s", ACTIVE, ACTIVE);
        !           113:                        system(cbuf);
        !           114:                        if (rwaccess(ACTIVE))
        !           115:                                fprintf(mfd, "The problem has been taken care of.\n");
        !           116:                        else
        !           117:                                fprintf(mfd, "Corrective action failed - check suid bits.\n");
        !           118:                        mclose(mfd);
        !           119:                }
        !           120:        }
        !           121:        setbuf(stdout, SYSBUF);
        !           122:        sigtrap = FALSE;        /* true if a signal has been caught */
        !           123: /*
        !           124:        signal(SIGQUIT, SIG_IGN);
        !           125: */
        !           126:        if (mode != PROC) {
        !           127:                signal(SIGHUP, onsig);
        !           128:                signal(SIGINT, onsig);
        !           129:        }
        !           130:        savmask = umask(N_UMASK);       /* set up mask */
        !           131:        uid = (unsigned) getuid();
        !           132:        gid = (unsigned) getgid();
        !           133:        duid = geteuid();
        !           134:        dgid = getegid();
        !           135:        if (uid == 0 && geteuid() == 0) {
        !           136:                /*
        !           137:                 * Must go through with this kludge since
        !           138:                 * some systems do not honor the setuid bit
        !           139:                 * when root invokes a setuid program.
        !           140:                 */
        !           141:                if ((pw = getpwnam(NEWSU)) == NULL)
        !           142:                        xerror("Cannot get NEWSU pw entry");
        !           143: 
        !           144:                duid = pw->pw_uid;
        !           145:                if ((gp = getgrnam(NEWSG)) == NULL)
        !           146:                        xerror("Cannot get NEWSG gr entry");
        !           147:                dgid = gp->gr_gid;
        !           148:                setuid(duid);
        !           149:                setgid(dgid);
        !           150:        }
        !           151: 
        !           152: #ifndef IHCC
        !           153:        /*
        !           154:         * We force the use of 'getuser()' to prevent forgery of articles
        !           155:         * by just changing $LOGNAME
        !           156:         */
        !           157:        if ((user = getenv("USER")) == NULL)
        !           158:                user = getenv("LOGNAME");
        !           159:        if ((home = getenv("HOME")) == NULL)
        !           160:                home = getenv("LOGDIR");
        !           161: #endif
        !           162:        if (user == NULL || home == NULL)
        !           163:                getuser();
        !           164:        else {
        !           165:                if (username[0] == 0) {
        !           166:                        strcpy(username, user);
        !           167:                }
        !           168:                strcpy(userhome, home);
        !           169:        }
        !           170:        getuser();
        !           171:        strcpy(whatever, username);
        !           172: 
        !           173:        /* loop once per arg. */
        !           174: 
        !           175:        ++argv;         /* skip first arg, which is prog name. */
        !           176: 
        !           177:        while (--argc) {
        !           178:            if (state == OPTION) {
        !           179:                if (**argv != '-') {
        !           180:                        sprintf(bfr, "Bad option string \"%s\"", *argv);
        !           181:                        xerror(bfr);
        !           182:                }
        !           183:                while (*++*argv != '\0') {
        !           184:                        for (optpt = options; optpt->optlet != '\0'; ++optpt) {
        !           185:                                if (optpt->optlet == **argv)
        !           186:                                        goto found;
        !           187:                        }
        !           188:                        /* unknown option letter */
        !           189: usage:
        !           190:                        fprintf(stderr, "usage: inews -t title");
        !           191:                        fprintf(stderr, " [ -n newsgroups ]");
        !           192:                        fprintf(stderr, " [ -e expiration date ]\n");
        !           193:                        fprintf(stderr, "\t[ -f sender]\n\n");
        !           194:                        fprintf(stderr, "       inews -p [ filename ]\n");
        !           195:                        xxit(1);
        !           196: 
        !           197:                    found:;
        !           198:                        if (optpt->flag == TRUE || (mode != UNKNOWN &&
        !           199:                            (mode&optpt->oldmode) == 0)) {
        !           200:                                sprintf(bfr, "Bad %c option", **argv);
        !           201:                                xerror(bfr);
        !           202:                        }
        !           203:                        if (mode == UNKNOWN)
        !           204:                                mode = optpt->newmode;
        !           205:                        filchar = optpt->filchar;
        !           206:                        optpt->flag = TRUE;
        !           207:                        state = STRING;
        !           208:                        ptr = optpt->buf;
        !           209:                        len = BUFLEN;
        !           210:                }
        !           211: 
        !           212:                argv++;         /* done with this option arg. */
        !           213: 
        !           214:            } else {
        !           215: 
        !           216:                /*
        !           217:                 * Pick up a piece of a string and put it into
        !           218:                 * the appropriate buffer.
        !           219:                 */
        !           220:                if (**argv == '-') {
        !           221:                        state = OPTION;
        !           222:                        argc++; /* uncount this arg. */
        !           223:                        continue;
        !           224:                }
        !           225: 
        !           226:                if ((tlen = strlen(*argv)) >= len)
        !           227:                        xerror("Argument string too long");
        !           228:                strcpy(ptr, *argv++);
        !           229:                ptr += tlen;
        !           230:                if (*(ptr-1) != filchar)
        !           231:                        *ptr++ = filchar;
        !           232:                len -= tlen + 1;
        !           233:                *ptr = '\0';
        !           234:            }
        !           235:        }
        !           236: 
        !           237:        /*
        !           238:         * ALL of the command line has now been processed. (!)
        !           239:         */
        !           240: 
        !           241:        tty = isatty(fileno(stdin));
        !           242:        if (!Dflag && mode != PROC && mode != CREATENG) {
        !           243:                if (recording(header.nbuf)) {
        !           244:                        if (!tty)
        !           245:                                fwait(fsubr(newssave, stdin, NULL));
        !           246:                        xerror("aborted due to recording");
        !           247:                }
        !           248:        }
        !           249: 
        !           250:        /* This code is really intended to be replaced by the control message. */
        !           251:        if (mode == CANCEL) {
        !           252:                char *p; FILE *f;
        !           253:                f = xfopen(filename, "r");
        !           254:                hread(&header, f, TRUE);
        !           255:                p = index(header.path, ' ');
        !           256:                if (p != NULL)
        !           257:                        *p = 0;
        !           258:                p = header.path;
        !           259:                if (strncmp(whatever, p, strlen(whatever))
        !           260:                        && uid != ROOTID && uid != geteuid() && uid)
        !           261:                        xerror("Not contributor");
        !           262:                cancel();
        !           263:                xxit(0);
        !           264:        }
        !           265: 
        !           266:        if (*header.nbuf)
        !           267:                lcase(header.nbuf);
        !           268:        if (mode != PROC) {
        !           269:                getident(&header);
        !           270: #ifdef MYORG
        !           271:                strcpy(header.organization, MYORG);
        !           272:                if (strncmp(header.organization, "Frobozz", 7) == 0)
        !           273:                        header.organization[0] = '\0';
        !           274:                if (ptr = getenv("ORGANIZATION"))
        !           275:                        strcpy(header.organization, ptr);
        !           276:                /*
        !           277:                 * Note that the organization can also be turned off by
        !           278:                 * setting it to the null string, either in MYORG or
        !           279:                 * $ORGANIZATION in the environment.
        !           280:                 */
        !           281:                if (header.organization[0] == '/') {
        !           282:                        mfd = fopen(header.organization, "r");
        !           283:                        if (mfd) {
        !           284:                                fgets(header.organization, sizeof header.organization, mfd);
        !           285:                                fclose(mfd);
        !           286:                        }
        !           287:                        ptr = index(header.organization, '\n');
        !           288:                        if (ptr)
        !           289:                                *ptr = 0;
        !           290:                }
        !           291: #endif
        !           292:                if (hflag) {
        !           293:                        /* Fill in a few to make frmread return TRUE */
        !           294:                        strcpy(header.subdate, "today");
        !           295:                        strcpy(header.path, "me");
        !           296:                        strcpy(header.oident, "id");
        !           297:                        /* Allow the user to supply some headers. */
        !           298:                        hread(&header, stdin, FALSE);
        !           299:                        /* But there are certain fields we won't let him specify. */
        !           300:                        if (header.from)
        !           301:                                strcpy(forgedname, header.from);
        !           302:                        header.from[0] = '\0';
        !           303:                        header.path[0] = '\0';
        !           304:                        header.subdate[0] = '\0';
        !           305:                        header.sender[0] = '\0';
        !           306:                        if (strcmp(header.oident, "id") == 0)
        !           307:                                header.oident[0] = '\0';
        !           308:                        ngcat(header.nbuf);
        !           309:                }
        !           310:                if (forgedname[0]) {
        !           311:                        strcpy(header.from, forgedname);
        !           312:                        sprintf(header.sender, "%s@%s%s",
        !           313:                                username, SYSNAME, MYDOMAIN);
        !           314:                } else {
        !           315:                        gensender(&header, username);
        !           316:                }
        !           317:                strcpy(header.postversion, genversion());
        !           318:        }
        !           319: 
        !           320:        /* Authorize newsgroups. */
        !           321:        if (mode == PROC) {
        !           322:                checkbatch();
        !           323:                signal(SIGHUP, SIG_IGN);
        !           324:                signal(SIGINT, SIG_IGN);
        !           325:                signal(SIGQUIT, SIG_IGN);
        !           326:                if (hread(&header, stdin, TRUE) == NULL)
        !           327:                        xerror("Inbound news is garbled");
        !           328:                input();
        !           329:                if (history(&header)) {
        !           330:                        fprintf(stderr, "Duplicate article %s rejected\n", header.ident);
        !           331:                        log("Duplicate article %s rejected", header.ident);
        !           332:                        xxit(0);
        !           333:                }
        !           334:        }
        !           335:        ngcat(header.nbuf);
        !           336: 
        !           337:        /* Easy way to make control messages, since all.all.ctl is unblessed */
        !           338:        if (mode != PROC && prefix(header.title, "cmsg ") && header.ctlmsg[0] == 0)
        !           339:                strcpy(header.ctlmsg, &header.title[5]);
        !           340:        is_ctl = mode != CREATENG &&
        !           341:                (ngmatch(header.nbuf, "all.all.ctl,") || header.ctlmsg[0]);
        !           342: #ifdef DEBUG
        !           343:        fprintf(stderr,"is_ctl set to %d\n", is_ctl);
        !           344: #endif
        !           345: 
        !           346:                        /* Must end in comma (NGDELIM) */
        !           347: #define MODGROUPS      "mod.all,all.mod,all.announce,"
        !           348:        if (ngmatch(header.nbuf, MODGROUPS) && !header.approved[0]) {
        !           349:                mfd = mailhdr(&header, "Moderated newsgroup");
        !           350:                if (mfd) {
        !           351:                        fprintf(mfd, "This newsgroup is moderated, and cannot be posted to directly.\n");
        !           352:                        fprintf(mfd, "Please mail your article to the moderator for posting.\n");
        !           353:                        hwrite(&header, mfd);
        !           354:                        if (infp)
        !           355:                                while ((i = getc(infp)) != EOF)
        !           356:                                        putc(i, mfd);
        !           357:                        mclose(mfd);
        !           358:                }
        !           359:                xerror("Unapproved moderated newsgroup\n");
        !           360:        }
        !           361: 
        !           362:        if (mode == PROC) {
        !           363:                strcpy(nbuf, header.nbuf);
        !           364:                if (s_find(&srec, FULLSYSNAME) == FALSE)
        !           365:                        xerror("Cannot find my name '%s' in %s", FULLSYSNAME, SUBFILE);
        !           366:                ngsquash(nbuf, srec.s_nbuf);
        !           367: 
        !           368:        }
        !           369:        else if (mode != CREATENG) {
        !           370:                if (!*header.title)
        !           371:                        xerror("No title");
        !           372:                if (!*header.nbuf)
        !           373:                        strcpy(header.nbuf, DFLTNG);
        !           374:                else if (!is_ctl)
        !           375:                        ngfcheck(FALSE);
        !           376:                ngcat(header.nbuf);
        !           377:                strcpy(nbuf, header.nbuf);
        !           378:        }
        !           379:        else {                          /* mode == CREATENG */
        !           380:                ngcat(header.nbuf);
        !           381:                strcpy(nbuf, header.nbuf);
        !           382:        }
        !           383: 
        !           384:        for (ptr = nbuf; (ptr = index(ptr, NGDELIM)) != NULL; *ptr++ = '\0')
        !           385:                ;
        !           386:        if (!is_ctl && header.followid[0] == '\0')
        !           387:                for (ptr = nbuf; *ptr;) {
        !           388:                        if (!exists(dirname(ptr)))
        !           389:                                ngcheck(ptr);
        !           390:                        while (*ptr++)
        !           391:                                ;
        !           392:                }
        !           393:        else if (mode <= UNPROC)
        !           394:                ctlcheck();
        !           395:        for (ptr = nbuf; *ptr;) {
        !           396:                if (*ptr != '-')
        !           397:                        goto out;
        !           398:                while (*ptr++)
        !           399:                        ;
        !           400:        }
        !           401:        xerror("No valid newsgroups in '%s'", header.nbuf);
        !           402: out:
        !           403: 
        !           404:        /* Determine input. */
        !           405:        if (mode != PROC)
        !           406:                input();
        !           407: 
        !           408: #ifndef VMS
        !           409:        /* Go into the background so the user can get on with his business. */
        !           410:        if (mode != PROC) {
        !           411:                i = fork();
        !           412:                if (i != 0)
        !           413:                        exit(0);
        !           414:        }
        !           415: #endif VMS
        !           416: 
        !           417:        /* Do the actual insertion. */
        !           418:        insert();
        !           419: }
        !           420: 
        !           421: /*
        !           422:  *     Create directory named by bfr.
        !           423:  *     Don't if user doesn't want to.
        !           424:  */
        !           425: ngcheck(ngname)
        !           426: char   *ngname;
        !           427: {
        !           428:        char    class[120];
        !           429:        char    dir[256];
        !           430:        char    *cp;
        !           431: 
        !           432:        strcpy(dir, dirname(ngname));
        !           433:        if (mode == PROC) {
        !           434: #ifdef AUTONEWNG
        !           435:                mknewsg(dir, ngname);
        !           436: #endif
        !           437:                return 1;
        !           438:        }
        !           439: 
        !           440:        /*
        !           441:         * If a user is trying to input to a non-existent group complain.
        !           442:         * First check to see if the newsgroup ever existed.  To do this, try
        !           443:         * to find the name in the "active" file.
        !           444:         */
        !           445:        if (mode != CREATENG && !is_ctl) {
        !           446:                /* Ick! Figure out if the newsgroup is in the active file. */
        !           447:                sprintf(dir, "grep -s '^%s ' %s", ngname, ACTIVE);
        !           448:                if ((system(dir) != 0))
        !           449:                        xerror("There is no such newsgroup as %s.", ngname);
        !           450:                else {
        !           451:                        strcpy(dir, dirname(ngname));
        !           452:                        mknewsg(dir, ngname);
        !           453:                        return 0;
        !           454:                }
        !           455:        }
        !           456:        /*
        !           457:         * Only certain users are allowed to create newsgroups
        !           458:         */
        !           459:        if (uid != ROOTID && uid != geteuid() && uid)
        !           460:                xerror("Please contact one of the local netnews people\n\tto create this group for you");
        !           461: 
        !           462:        /* Broadcast the new newsgroup */
        !           463:        strcpy(class, ngname);
        !           464:        for (cp=class; *cp && *cp!='.'; cp++)
        !           465:                ;
        !           466:        if (*cp)
        !           467:                *cp = 0;
        !           468:        else {
        !           469:                mknewsg(dir, ngname);
        !           470:                exit(0);        /* Local newsgroup */
        !           471:        }
        !           472:        sprintf(bfr, "inews -D -n %s.ctl -t cmsg newgroup %s", ngname, ngname);
        !           473:        printf("Please type in a paragraph describing the new newsgroup.\n");
        !           474:        printf("End with control D as usual.\n");
        !           475:        printf("%s\n", bfr);
        !           476:        fflush(stdout);
        !           477:        system(bfr);
        !           478:        exit(0);
        !           479: }
        !           480: 
        !           481: #include <errno.h>
        !           482: char firstbufname[100];
        !           483: /*
        !           484:  *     Link ARTICLE into dir for ngname and update active file.
        !           485:  */
        !           486: localize(ngname)
        !           487: char   *ngname;
        !           488: {
        !           489:        FILE    *fp;
        !           490:        struct stat     status;
        !           491:        char afline[BUFLEN];
        !           492:        long ngsize;
        !           493:        long fpos;
        !           494:        int i, e;
        !           495:        extern int errno;
        !           496: 
        !           497:        lock();
        !           498:        actfp = fopen(ACTIVE, "r+");
        !           499:        for(;;) {
        !           500:                fpos = ftell(actfp);
        !           501:                if (fgets(afline, sizeof afline, actfp) == NULL) {
        !           502:                        unlock();
        !           503:                        return FALSE;           /* No such newsgroup locally */
        !           504:                }
        !           505:                if (prefix(afline, ngname)) {
        !           506:                        sscanf(afline, "%s %ld", bfr, &ngsize);
        !           507:                        if (strcmp(bfr, ngname) == 0) {
        !           508:                                break;
        !           509:                        }
        !           510:                        if (ngsize < 0 || ngsize > 99998) {
        !           511:                                log("found bad ngsize %d ng %s, setting to 1", ngsize, bfr);
        !           512:                                ngsize = 1;
        !           513:                        }
        !           514:                }
        !           515:        }
        !           516:        for (;;) {
        !           517:                sprintf(bfr, "%s/%ld", dirname(ngname), ngsize+1);
        !           518:                if (link(ARTICLE, bfr) == 0) break;
        !           519:                e = errno;      /* keep log from clobbering it */
        !           520:                fprintf(stderr, "Cannot install article as %s\n", bfr);
        !           521:                log("Cannot install article as %s", bfr);
        !           522:                if (e != EEXIST) {
        !           523:                        log("Link into %s failed, errno %d, check dir permissions.", bfr, e);
        !           524:                        unlock();
        !           525:                        return FALSE;
        !           526:                }
        !           527:                ngsize++;
        !           528:        }
        !           529: 
        !           530:        /* Next two lines program around a bug in 4.1BSD stdio. */
        !           531:        fclose(actfp);
        !           532:        actfp = fopen(ACTIVE, "r+");
        !           533: 
        !           534:        fseek(actfp, fpos, 0);
        !           535:        /* Has to be same size as old because of %05d.
        !           536:         * This will overflow with 99999 articles.
        !           537:         */
        !           538:        fprintf(actfp, "%s %05ld\n", ngname, ngsize+1);
        !           539:        fclose(actfp);
        !           540:        unlock();
        !           541:        if (firstbufname[0] == '\0')
        !           542:                strcpy(firstbufname, bfr);
        !           543:        sprintf(bfr, "%s/%ld ", ngname, ngsize+1);
        !           544:        addhist(bfr);
        !           545:        return TRUE;
        !           546: }
        !           547: 
        !           548: /*
        !           549:  *     Localize for each newsgroup and broadcast.
        !           550:  */
        !           551: insert()
        !           552: {
        !           553:        register char *ptr;
        !           554:        register FILE *tfp;
        !           555:        int badgroup = 0, goodgroup = 0;
        !           556: 
        !           557:        /* Fill up the rest of header. */
        !           558:        if (mode != PROC) {
        !           559:                history(&header);
        !           560:        }
        !           561:        dates(&header);
        !           562:        addhist(header.recdate);
        !           563:        addhist("\t");
        !           564:        log("%s %s ng %s subj '%s'", mode==PROC ? "received" : "posted", header.ident, header.nbuf, header.title);
        !           565:        if (mode==PROC)
        !           566:                log("from %s relay %s", header.from, header.relayversion);
        !           567: 
        !           568:        /* Write article to temp file. */
        !           569:        tfp = xfopen(mktemp(ARTICLE), "w");
        !           570:        lhwrite(&header, tfp);
        !           571:        while (fgets(bfr, BUFLEN, infp) != NULL) {
        !           572:                /*
        !           573:                if (!strncmp(bfr, "From ", 5))
        !           574:                        putc('>', tfp);
        !           575:                */
        !           576:                fputs(bfr, tfp);
        !           577:        }
        !           578:        fclose(tfp);
        !           579:        fclose(infp);
        !           580: 
        !           581:        if (is_ctl) {
        !           582:                control(&header);
        !           583:                goodgroup++;
        !           584:                if (!localize("control")) {
        !           585:                        sprintf(bfr, "%s/%s", SPOOL, "control");
        !           586:                        mknewsg(bfr, "control");
        !           587:                        if (!localize("control")) {
        !           588:                                tfp = mailhdr(NULL, "No control newsgroup");
        !           589:                                if (tfp) {
        !           590:                                        fprintf(tfp, "Can't create newsgroup 'control'.\n");
        !           591:                                        mclose(tfp);
        !           592:                                }
        !           593:                        }
        !           594:                }
        !           595:        } else {
        !           596:                for (ptr = nbuf; *ptr;) {
        !           597:                        if (*ptr == '-') {
        !           598:                                while (*ptr++)
        !           599:                                        ;
        !           600:                                continue;
        !           601:                        }
        !           602:                        strcpy(bfr, dirname(ptr));
        !           603:                        if (!exists(bfr)) {
        !           604: #ifdef AUTONEWNG
        !           605:                                mknewsg(bfr, ptr);
        !           606: #else
        !           607:                                getapproval(ptr);
        !           608:                                badgroup++;
        !           609: #endif
        !           610:                        }
        !           611:                        else
        !           612:                                goodgroup++;
        !           613:                        if (*nbuf)
        !           614:                                localize(ptr);
        !           615:                        while (*ptr++)
        !           616:                                ;
        !           617:                }
        !           618:        }
        !           619: 
        !           620: #ifdef NOFORWARD
        !           621:        if (*nbuf)
        !           622: #endif
        !           623:                if (goodgroup)
        !           624:                        broadcast();
        !           625:        savehist();
        !           626:        xxit(0);
        !           627: }
        !           628: 
        !           629: input()
        !           630: {
        !           631:        register int empty = TRUE;
        !           632:        register char *cp;
        !           633:        int c;
        !           634:        long chcount = 0;
        !           635:        FILE *tmpfp;
        !           636:        int consec_newlines = 0;
        !           637:        int linecount = 0;
        !           638: 
        !           639:        tmpfp = xfopen(mktemp(INFILE), "w");
        !           640:        if (*filename) {
        !           641:                tty = FALSE;
        !           642:                infp = xfopen(filename, "r");
        !           643:        } else {
        !           644:                infp = stdin;
        !           645:        }
        !           646:        while (!sigtrap && fgets(bfr, BUFLEN, stdin) != NULL) {
        !           647:                if (mode == PROC)       /* zap trailing empty lines */
        !           648:                {
        !           649:                        if (bfr[0] == '\n')     /* 1 empty line, to go */
        !           650:                        {
        !           651:                                consec_newlines++;      /* count it, in case */
        !           652:                                continue;               /* but don't write it*/
        !           653:                        }
        !           654:                        /* foo! a non-empty line. write out all saved lines. */
        !           655:                        while (consec_newlines > 0)
        !           656:                        {
        !           657:                                putc('\n', tmpfp);
        !           658:                                consec_newlines--;
        !           659:                                linecount++;
        !           660:                        }
        !           661:                }
        !           662:                if (mode != PROC && tty && strcmp(bfr, ".\n") == 0)
        !           663:                        break;
        !           664:                for (cp = bfr; c = *cp; cp++) {
        !           665:                        if (isprint(c) || isspace(c) || c=='\b')
        !           666:                                putc(c, tmpfp);
        !           667:                        if (isprint(c))
        !           668:                                chcount++;
        !           669:                        if (c == '\n')
        !           670:                                linecount++;
        !           671:                }
        !           672:                empty = FALSE;
        !           673:        }
        !           674:        if (*filename)
        !           675:                fclose(infp);
        !           676: 
        !           677:        sprintf(bfr, "%s/%s", getenv("HOME"), ".signature");
        !           678:        if (mode != PROC && (infp = fopen(bfr, "r"))) {
        !           679:                fprintf(tmpfp, "-- \n");        /* To separate */
        !           680:                linecount++;
        !           681:                while ((c = getc(infp)) != EOF) {
        !           682:                        putc(c, tmpfp);
        !           683:                        if (c == '\n')
        !           684:                                linecount++;
        !           685:                }
        !           686:                fclose(infp);
        !           687:        }
        !           688: 
        !           689:        fclose(tmpfp);
        !           690:        if (sigtrap) {
        !           691:                if (tty)
        !           692:                        printf("Interrupt\n");
        !           693:                if (tty && !empty)
        !           694:                        fwait(fsubr(newssave, (char *) NULL, (char *) NULL));
        !           695:                if (!tty)
        !           696:                        log("Blown away by an interrupt %d", sigtrap);
        !           697:                xxit(1);
        !           698:        }
        !           699:        if (tty)
        !           700:                printf("EOT\n");
        !           701:        fflush(stdout);
        !           702:        infp = fopen(INFILE, "r");
        !           703:        if (chcount < 5 && mode <= UNPROC && !is_ctl)
        !           704:                xerror("You didn't really want to post THAT!");
        !           705:        if (header.numlines[0]) {
        !           706:                /*
        !           707:                 * Check line count if there's already one attached to
        !           708:                 * the article.  Could make this a fatal error -
        !           709:                 * throwing it away if it got chopped, in hopes that
        !           710:                 * another copy will come in later with a correct
        !           711:                 * line count.  But that seems a bit much for now.
        !           712:                 */
        !           713:                if (linecount != header.intnumlines)
        !           714:                        log("linecount expected %d, got %d\n", header.intnumlines, linecount);
        !           715:        } else {
        !           716:                /* Attach a line count to the article. */
        !           717:                header.intnumlines = linecount;
        !           718:                sprintf(header.numlines, "%d", linecount);
        !           719:        }
        !           720: }
        !           721: 
        !           722: /*
        !           723:  * Make the directory for a new newsgroup.  ngname should be the
        !           724:  * full pathname of the directory.  Do the other stuff too.
        !           725:  * The various games with setuid and chown are to try to make sure
        !           726:  * the directory is owned by NEWSUSR and NEWSGRP, which is tough to
        !           727:  * do if you aren't root.  This will work on a UCB system (which allows
        !           728:  * setuid(geteuid()) or a USG system (which allows you to give away files
        !           729:  * you own with chown), otherwise you have to change your kernel to allow
        !           730:  * one of these things or run with your dirs 777 so that it doesn't matter
        !           731:  * who owns them.
        !           732:  */
        !           733: mknewsg(fulldir, ngname)
        !           734: char   *fulldir;
        !           735: char   *ngname;
        !           736: {
        !           737:        int     pid;
        !           738:        register char *p;
        !           739:        char sysbuf[200];
        !           740:        char parent[200];
        !           741:        struct stat sbuf;
        !           742: 
        !           743:        if (ngname == NULL || !isalpha(ngname[0]))
        !           744:                xerror("Tried to make illegal newsgroup %s", ngname);
        !           745: 
        !           746:        /*
        !           747:         * If the parent is 755 and we're on a USG system, the setuid(getuid)
        !           748:         * will fail, and since mkdir is suid, and our real uid is random,
        !           749:         * the mkdir will fail.  So we have to temporarily chmod it to 755.
        !           750:         */
        !           751:        strcpy(parent, fulldir);
        !           752:        p = rindex(parent, '/');
        !           753:        if (p)
        !           754:                *p = '\0';
        !           755:        if (stat(parent, &sbuf) < 0)
        !           756:                sbuf.st_mode = 0777;
        !           757:        chmod(parent, 0777);
        !           758: 
        !           759:        if ((pid = fork()) <= 0) {
        !           760:                if (setuid(geteuid()))  /* This fails on some systems, but
        !           761:                                         * works on 4BSD, and 2BSD. */
        !           762: #ifndef USG
        !           763:                        umask(0)
        !           764: #endif
        !           765:                                ;
        !           766:                setgid(getegid());
        !           767:                /* Create the directory */
        !           768:                mkparents(fulldir);
        !           769:                sprintf(sysbuf, "mkdir %s", fulldir);
        !           770:                exit(system(sysbuf));
        !           771:        } else if (fwait(pid)) {
        !           772:                sprintf(sysbuf, "Cannot mkdir %s", fulldir);
        !           773:                xerror(sysbuf);
        !           774:        }
        !           775: 
        !           776:        chmod(parent, sbuf.st_mode);    /* put is back */
        !           777: 
        !           778: #ifdef USG
        !           779: # ifndef CHEAP
        !           780:        /*
        !           781:         * Give away the files we just created, which were assigned to our
        !           782:         * REAL uid.  This only works on USG systems.  It is an alternative
        !           783:         * to the setuid call above.  The directories we just made are owned
        !           784:         * by our real uid, so we have to temporarily set our effective uid
        !           785:         * the same to allow the chown.  Fortunately, USG lets us setuid back.
        !           786:         */
        !           787:        setuid(getuid());
        !           788:        chown(fulldir, duid, dgid);
        !           789:        setuid(duid);
        !           790: # endif
        !           791: #endif
        !           792: 
        !           793:        /* Update the "active newsgroup" file. */
        !           794:        if (ngname && *ngname) {
        !           795:                actfp = xfopen(ACTIVE, "a");
        !           796:                fprintf(actfp, "%s 00000\n", ngname);
        !           797:                fclose(actfp);
        !           798:        }
        !           799: 
        !           800:        log("make newsgroup %s in dir %s", ngname, fulldir);
        !           801: }
        !           802: 
        !           803: /*
        !           804:  * If any parent directories of this dir don't exist, create them.
        !           805:  */
        !           806: mkparents(dirname)
        !           807: char *dirname;
        !           808: {
        !           809:        char buf[200], sysbuf[200];
        !           810:        register char *p;
        !           811: 
        !           812:        strcpy(buf, dirname);
        !           813:        p = rindex(buf, '/');
        !           814:        if (p)
        !           815:                *p = '\0';
        !           816:        if (exists(buf))
        !           817:                return;
        !           818:        mkparents(buf);
        !           819:        sprintf(sysbuf, "mkdir %s", buf);
        !           820:        system(sysbuf);
        !           821: }
        !           822: 
        !           823: cancel()
        !           824: {
        !           825:        register FILE *fp;
        !           826: 
        !           827:        log("cancel article %s", filename);
        !           828:        fp = xfopen(filename, "r");
        !           829:        if (hread(&header, fp, TRUE) == NULL)
        !           830:                xerror("Article is garbled.\n");
        !           831:        fclose(fp);
        !           832:        unlink(filename);
        !           833: }
        !           834: 
        !           835: /*
        !           836:  * An article has come in that isn't in a newsgroup we know about.
        !           837:  * Stash it in the junk directory and notify the local contact person.
        !           838:  * Note that such articles are NOT broadcast to our neighbors, on the
        !           839:  * assumption that they are a typographical error.  We only keep them
        !           840:  * here because we might be a new site.
        !           841:  */
        !           842: getapproval(ng)
        !           843: char   *ng;
        !           844: {
        !           845:        FILE    *fd;
        !           846: 
        !           847:        if (localize("junk"))
        !           848:                return;
        !           849: 
        !           850:        sprintf(bfr, "%s/%s", SPOOL, "junk");
        !           851:        mknewsg(bfr, "junk");
        !           852:        if (localize("junk"))
        !           853:                return;
        !           854: 
        !           855:        fd = mailhdr(NULL, "Strange Newsgroup Received");
        !           856:        if (fd != NULL) {
        !           857:                fprintf(fd, "\nNewsgroup '%s' has been posted to\nby %s.\n\n",
        !           858:                        ng, header.from[0] ? header.from : header.path);
        !           859:                fprintf(fd, "I was unable to save it in the newsgroup 'junk'\n");
        !           860:                fprintf(fd, "I was also unable to create the newsgroup 'junk'\n");
        !           861:                mclose(fd);
        !           862:        }
        !           863: }

unix.superglobalmegacorp.com

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