Annotation of 43BSD/contrib/news/src/postnews.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * This software is Copyright (c) 1986 by Rick Adams.
        !             3:  *
        !             4:  * Permission is hereby granted to copy, reproduce, redistribute or
        !             5:  * otherwise use this software as long as: there is no monetary
        !             6:  * profit gained specifically from the use or reproduction or this
        !             7:  * software, it is not sold, rented, traded or otherwise marketed, and
        !             8:  * this copyright notice is included prominently in any copy
        !             9:  * made.
        !            10:  *
        !            11:  * The author make no claims as to the fitness or correctness of
        !            12:  * this software for any use whatsoever, and it is provided as is. 
        !            13:  * Any use of this software is at the user's own risk.
        !            14:  *
        !            15:  * Postnews: post a news message to Usenet.  This C version replaces a shell
        !            16:  * script, and does more intelligent prompting and filtering than possible
        !            17:  * in a shell script.
        !            18:  */
        !            19: 
        !            20: #ifdef SCCSID
        !            21: static char    *SccsId = "@(#)postnews.c       1.25    3/19/86";
        !            22: #endif /* SCCSID */
        !            23: 
        !            24: #include "params.h"
        !            25: 
        !            26: #define APPEND 1
        !            27: #define REPLACE 2
        !            28: 
        !            29: extern char *MAILPARSER;
        !            30: 
        !            31: char tempfname[50];            /* file name used for making article */
        !            32: char original[BUFLEN];         /* file name of original, used in followup */
        !            33: char homedir[BUFLEN];          /* HOME environment setting */
        !            34: char user[SBUFLEN];            /* user name */
        !            35: char ccname[BUFLEN];           /* file name for article copy */
        !            36: 
        !            37: /* article header information */
        !            38: char subject[BUFLEN];
        !            39: char distribution[BUFLEN];
        !            40: char references[BUFLEN];
        !            41: char newsgroups[BUFLEN];
        !            42: char moderator[BUFLEN];
        !            43: char isfrom[BUFLEN];
        !            44: char msgid[BUFLEN];
        !            45: char keywords[BUFLEN];
        !            46: char summary[BUFLEN];
        !            47: int uid;
        !            48: 
        !            49: char ngsep[] = { NGDELIM, '\0' };      /* == "," */
        !            50: 
        !            51: char *Progname = "postnews";           /* for xerror */
        !            52: 
        !            53: time_t fmodtime;
        !            54: int ismod = 0;
        !            55: char buf[BUFLEN];
        !            56: 
        !            57: struct distr {
        !            58:        char abbr[24];
        !            59:        char descr[128];
        !            60: } distr[16];
        !            61: 
        !            62: FILE *xfopen();
        !            63: 
        !            64: main(argc, argv)
        !            65: char *argv[];
        !            66: {
        !            67:        register int c;
        !            68: 
        !            69:        init();
        !            70: 
        !            71:        if (argc == 2) {
        !            72:                if (!prefix(argv[1], SPOOL))
        !            73:                        xerror("Can only followup to articles in %s", SPOOL);
        !            74:                followup(argv[1]);
        !            75:                (void) strcpy(original, argv[1]);
        !            76:        } else
        !            77:        if (askyes("Is this message in response to some other message? ","no")) {
        !            78:                char ng[BUFLEN], num[BUFLEN];
        !            79:                long i, j, lastnum;
        !            80:                register char *p;
        !            81:                int fd, dir;
        !            82:                char canpost;
        !            83: 
        !            84:                getpr("In what newsgroup was the article posted? ",ng);
        !            85:                if (!valid_ng(ng, &i, &j, &canpost))
        !            86:                        if (canpost != 'n' )
        !            87:                                byebye("There is no such newsgroup.");
        !            88:                        else
        !            89:                                byebye("You are not allowed to post to that group.");
        !            90: 
        !            91:                printf("Valid article numbers are from %ld to %ld\n", j, i);
        !            92:                lastnum = i + 1;
        !            93:                dir = -1;
        !            94: 
        !            95:                for(;;) {
        !            96:                        getpr("\nWhat was the article number? ", num);
        !            97:                        switch(num[0]) {
        !            98:                        case '+':
        !            99:                                dir = 1;
        !           100:                                sprintf(num, "%ld", lastnum + 1);
        !           101:                                break;
        !           102:                        case '-':
        !           103:                                dir = -1;
        !           104:                                /* no break */
        !           105:                        case '\0':
        !           106:                                sprintf(num, "%ld", lastnum + dir);
        !           107:                                break;
        !           108:                        }
        !           109:                        (void) sprintf(original, "%s/%s", SPOOL, ng);
        !           110:                        for (p=original+strlen(SPOOL)+1; *p ;++p)
        !           111:                                if (*p == '.')
        !           112:                                        *p = '/';
        !           113:                        (void) strcat(original, "/");
        !           114:                        (void) strcat(original, num);
        !           115: 
        !           116:                        if ((fd=open(original,0)) >= 0) {
        !           117:                                (void) close(fd);
        !           118:                                printf("\narticle %s\n", original);
        !           119:                                if (article_line(original, "From: ", buf))
        !           120:                                        printf("%s\n", buf);
        !           121:                                if (article_line(original, "Subject: ", buf))
        !           122:                                        printf("%s\n", buf);
        !           123:                                if (askyes("Is this the one you want? ", "n"))
        !           124:                                        break;
        !           125:                        } else
        !           126:                                printf("I can't find that article.\n");
        !           127:                        lastnum = atol(num);
        !           128:                }
        !           129: 
        !           130:                followup(original);
        !           131:        } else {
        !           132:                do {
        !           133:                        getpr("Subject: ", subject);
        !           134:                        if (*subject == '?') {
        !           135: printf("People read the subject line to learn what your article is about.\n");
        !           136: printf("You want it to do the same job as a newspaper headline.\n");
        !           137: printf("So type in something both brief and descriptive.\n");
        !           138:                                *subject = '\0';
        !           139:                        }
        !           140:                } while (*subject == '\0');
        !           141:                getpr("Keywords: ", keywords);
        !           142: 
        !           143:                while (!get_newsgroup())
        !           144:                        ;
        !           145:                check_mod();
        !           146:                get_distribution((char *)0);
        !           147:        }
        !           148: 
        !           149:        if (pre_checks())
        !           150:                exit(1);
        !           151: 
        !           152:        prep_article();
        !           153:        c = 'e';
        !           154:        for (;;) {
        !           155:                if (c == 'e') {
        !           156:                        edit_article();
        !           157:                        post_checks();
        !           158:                }
        !           159:                do {
        !           160:                        do {
        !           161:                                getpr("\nWhat now?  [send, edit, list, quit, write] ", buf);
        !           162:                                c = buf[0];
        !           163:                        } while (c == '\0');
        !           164:                        if (isupper(c))
        !           165:                                c = tolower(c);
        !           166:                        if (c == 'q') {
        !           167:                                (void) UNLINK(tempfname);
        !           168:                                exit(1);
        !           169:                        }
        !           170:                        if (c == 'l') {
        !           171:                                char *pager = getenv("PAGER");
        !           172:                                char lbuf[BUFLEN];
        !           173:                                if (pager == NULL || *pager == '\0') {
        !           174: #ifdef PAGE
        !           175: # ifdef IHCC
        !           176:                                        (void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
        !           177: # else /* !IHCC */
        !           178:                                        (void) strcpy(lbuf, PAGE);
        !           179: # endif /* !IHCC */
        !           180:                                        pager = lbuf;
        !           181: #else /* !PAGE */
        !           182:                                        pager = "cat";
        !           183: #endif /* !PAGE */
        !           184:                                }
        !           185:                                sprintf(buf, "exec %s %s", pager, tempfname);
        !           186:                                (void)  system(buf);
        !           187:                        }
        !           188:                        if (c == 'w') {
        !           189:                                register int ifd, ofd, nbytes;
        !           190:                                char iobuf[BUFSIZ];
        !           191:                                char fname[BUFLEN];
        !           192:                                getpr("Filename? ", fname);
        !           193:                                if (fname[0] == '\0')
        !           194:                                        continue;
        !           195:                                ofd = creat(fname, 0666);
        !           196:                                if (ofd < 0)
        !           197:                                        perror(fname);
        !           198:                                else {
        !           199:                                        ifd = open(tempfname, 0);
        !           200:                                        if (ifd < 0)
        !           201:                                                xerror("Can't reopen %s\n", tempfname);
        !           202:                                        while ((nbytes = read(ifd, iobuf, BUFSIZ)) > 0 )
        !           203:                                                write(ofd, iobuf, nbytes);
        !           204:                                        close(ofd);
        !           205:                                        close(ifd);
        !           206:                                }
        !           207:                        }
        !           208:                } while (!index("eps", c));
        !           209:                if (c != 'e')
        !           210:                        post_article(); /* will exit if posted successfully */
        !           211:        };
        !           212: }
        !           213: 
        !           214: /*
        !           215:  * Find out the topic of interest.
        !           216:  */
        !           217: get_newsgroup()
        !           218: {
        !           219:        int n;
        !           220:        long i;
        !           221:        char canpost;
        !           222:        static int first = 1;
        !           223: 
        !           224:        printf("Newsgroups (enter one at a time, end with a blank line):\n");
        !           225:        if (first) {
        !           226:                printf("\nThe most relevant newsgroup should be the first, you should\n");
        !           227:                printf("add others only if your article really MUST be read by people\n");
        !           228:                printf("who choose not to read the appropriate group for your article.\n");
        !           229:                printf("But DO use multiple newsgroups rather than posting many times.\n\n");
        !           230:                first = 0;
        !           231:        }
        !           232:        printf("For a list of newsgroups, type ?\n");
        !           233:        n = 0;
        !           234:        newsgroups[0] = '\0';
        !           235: 
        !           236:        for(;;) {
        !           237:                getpr("> ", buf);
        !           238:                if (buf[0] == '\0')
        !           239:                        if (n == 0)
        !           240:                                return FALSE;
        !           241:                        else
        !           242:                                return TRUE;
        !           243:                if (buf[0] == '?'){
        !           244:                        char *pager = getenv("PAGER");
        !           245:                        char lbuf[BUFLEN];
        !           246:                        if (pager == NULL) {
        !           247: #ifdef PAGE
        !           248: # ifdef IHCC
        !           249:                                (void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
        !           250: # else /* !IHCC */
        !           251:                                (void) strcpy(lbuf, PAGE);
        !           252: # endif /* !IHCC */
        !           253:                                pager = lbuf;
        !           254: #else /* !PAGE */
        !           255:                                pager = "cat";
        !           256: #endif /* !PAGE */
        !           257:                        }
        !           258:                        printf("These are the currently active groups:\n");
        !           259:                        sprintf(buf, "exec %s %s/newsgroups", pager, LIB);
        !           260:                        (void) system(buf);
        !           261:                        continue;
        !           262:                }
        !           263:                if (valid_ng(buf, &i, &i, &canpost)) {
        !           264:                        if (n++ != 0)
        !           265:                                (void) strcat(newsgroups, ngsep);
        !           266:                        (void) strcat(newsgroups, buf);
        !           267:                } else {
        !           268:                        if (canpost == 'n')
        !           269:                                printf("You are not allowed to post to %s\n",
        !           270:                                        buf);
        !           271:                        else
        !           272:                                printf("%s is not a valid newsgroup.\n", buf);
        !           273:                }
        !           274:        }
        !           275: }
        !           276: 
        !           277: /*
        !           278:  * Find out how widely the author wants the message distributed.
        !           279:  */
        !           280: get_distribution(deflt)
        !           281:        char *deflt;
        !           282: {
        !           283:        register int i;
        !           284:        register char *r;
        !           285:        char def[BUFLEN];
        !           286:        char *lastgroup;
        !           287: 
        !           288:        lastgroup = newsgroups;
        !           289:        (void) strcpy(def, newsgroups);
        !           290:        r = index(def, NGDELIM);
        !           291:        if (r)
        !           292:                *r = '\0';
        !           293:        r = index(def, '.');
        !           294:        if (r) {
        !           295:                *r = '\0';
        !           296:                if (strcmp(def, "net") == 0)
        !           297:                        (void) strcpy(def, "world");
        !           298:        } else {
        !           299:                distribution[0] = '\0';
        !           300:                return;
        !           301:        }
        !           302: 
        !           303:        if (strcmp(def, "to") == 0) {
        !           304:                /*
        !           305:                 * This only works if "to.xx" is the first (or only)
        !           306:                 * newsgroup, but it usually is ..
        !           307:                 * Perhaps we should make the distribution be "to.xxx" ??
        !           308:                 */
        !           309:                distribution[0] = '\0';
        !           310:                return;         /* He's probably testing something */
        !           311:        }
        !           312:        if (deflt != (char *)0)
        !           313:                (void) strcpy(def, deflt);
        !           314:        if (ngmatch("net.test", newsgroups))
        !           315:                (void) strcpy(def, "local");
        !           316:        for(;;) {
        !           317:                do {
        !           318:                        (void) sprintf(buf, "Distribution (default='%s', '?' for help) : ", def);
        !           319:                        getpr(buf, distribution);
        !           320:                        if (distribution[0] == '\0') {
        !           321:                                if (strcmp(def, "*None*") == 0)
        !           322:                                        printf("You must enter a distribution, '?' for help.\n");
        !           323:                                (void) strcpy(distribution, def);
        !           324:                        }
        !           325:                } while (strcmp(distribution, "*None*") == 0);
        !           326: 
        !           327:                /* Did the user ask for help? */
        !           328:                if (distribution[0] == '?') {
        !           329:                        printf("How widely should your article be distributed?\n\n");
        !           330:                        for (i=0; distr[i].abbr[0]; i++)
        !           331:                                printf("%s\t%s\n", distr[i].abbr, distr[i].descr);
        !           332:                        printf("\nEnter the word that specifies the distribution that you require.\n");
        !           333:                        continue;
        !           334:                }
        !           335: 
        !           336:                /* Check that it's a proper distribution */
        !           337:                for (i=0; distr[i].abbr[0]; i++) {
        !           338:                        if (strncmp(distr[i].abbr, distribution, sizeof(distr[0].abbr)) == 0) {
        !           339:                                register int n;
        !           340:                                /* Found a match. Do any special rewriting. */
        !           341:                                if (strcmp(distribution, "world") == 0)
        !           342:                                        strcpy(distribution, "net");
        !           343:                                r = newsgroups;
        !           344:                                n = strlen(distribution);
        !           345:                                /*
        !           346:                                 * A distribution of foo is useless
        !           347:                                 * if all the newsgroups are in foo.all
        !           348:                                 */
        !           349:                                for (;;) {
        !           350:                                        if (strncmp(r, distribution, n))
        !           351:                                                return;
        !           352:                                        if ((r = index(r, NGDELIM)) == NULL)
        !           353:                                                break;
        !           354:                                        ++r;
        !           355:                                }
        !           356:                                distribution[0] = '\0';
        !           357:                                return;
        !           358:                        }
        !           359:                }
        !           360:                if (strcmp(distribution, def) != 0)
        !           361:                        printf("Type ? for help.\n");
        !           362:                else {
        !           363:                        int once = TRUE;
        !           364: 
        !           365:                        do {
        !           366:                                r = lastgroup;
        !           367:                                while (r = index(r, NGDELIM))
        !           368:                                        if (!prefix(++r, def))
        !           369:                                                break;
        !           370:                                if (r == NULL) {
        !           371:                                        /*
        !           372:                                         * no newsgroups are distribution
        !           373:                                         * names, and user simply will
        !           374:                                         * not type a valid distribution,
        !           375:                                         * assume that the default is OK.
        !           376:                                         */
        !           377:                                        distribution[0] = '\0';
        !           378:                                        return;
        !           379:                                }
        !           380:                                lastgroup = r;
        !           381:                                if (once)
        !           382:                                        printf("Sorry, '%s' is an unknown distribution.  Type ? for help.\n", def);
        !           383:                                once = FALSE;
        !           384:                                strcpy(def, r);
        !           385:                                r = index(def, NGDELIM);
        !           386:                                if (r)
        !           387:                                        *r = '\0';
        !           388:                                r = index(def, '.');
        !           389:                        } while (r == NULL);
        !           390:                        *r = '\0';
        !           391:                        if (strcmp(def, "net") == 0)
        !           392:                                strcpy(def, "world");
        !           393:                }
        !           394:        }
        !           395: }
        !           396: 
        !           397: /*
        !           398:  * Do sanity checks before the author types in the message.
        !           399:  */
        !           400: pre_checks()
        !           401: {
        !           402:        if (recording(newsgroups))
        !           403:                return 1;
        !           404:        return 0;
        !           405: }
        !           406: 
        !           407: /*
        !           408:  * Check to see if the newsgroup is moderated.
        !           409:  */
        !           410: check_mod()
        !           411: {
        !           412:        register FILE *fd;
        !           413:        char ng[BUFLEN], mod[BUFLEN];
        !           414: 
        !           415:        ismod = 0;
        !           416:        (void) sprintf(buf, "%s/%s", LIB, "moderators");
        !           417:        fd = xfopen(buf, "r");
        !           418: 
        !           419:        while (fgets(buf, sizeof buf, fd) != NULL) {
        !           420:                twosplit(buf, ng, mod);
        !           421:                if (ngmatch(newsgroups, ng)) {
        !           422:                        (void) strcpy(moderator, mod);
        !           423:                        ismod = 1;
        !           424:                }
        !           425:        }
        !           426:        (void) fclose(fd);
        !           427: }
        !           428: 
        !           429: /*
        !           430:  * Set up the temp file with headers.
        !           431:  */
        !           432: prep_article()
        !           433: {
        !           434:        FILE *tf, *of;
        !           435:        struct stat stbuf;
        !           436: 
        !           437:        (void) strcpy(tempfname, "/tmp/postXXXXXX");
        !           438:        (void) mktemp(tempfname);
        !           439: 
        !           440:        /* insert a header */
        !           441:        tf = xfopen(tempfname, "w");
        !           442:        fprintf(tf, "Subject: %s\n", subject);
        !           443:        fprintf(tf, "Newsgroups: %s\n", newsgroups);
        !           444:        if (distribution[0] != '\0')
        !           445:                fprintf(tf, "Distribution: %s\n", distribution);
        !           446:        if (ismod)
        !           447:                fprintf(tf, "To: %s\n", moderator);
        !           448: 
        !           449:        if (keywords[0] != '\0')
        !           450:                fprintf(tf, "Keywords: %s\n", keywords);
        !           451:        if (summary[0] != '\0')
        !           452:                fprintf(tf, "Summary: %s\n", summary);
        !           453: 
        !           454:        if (references[0] != '\0') {
        !           455:                fprintf(tf, "References: %s\n\n", references);
        !           456: 
        !           457:                if (askyes("Do you want to include a copy of the article? ", "no")){
        !           458:                        of = xfopen(original, "r");
        !           459:                        while (fgets(buf, BUFSIZ, of) != NULL)
        !           460:                                if (buf[0] == '\n')     /* skip headers */
        !           461:                                        break;
        !           462:                        fprintf(tf, "In article %s, %s writes:\n", msgid, isfrom);
        !           463:                        while (fgets(buf, BUFSIZ, of) != NULL)
        !           464:                                fprintf(tf, "> %s", buf);
        !           465:                        (void) fclose(of);
        !           466:                        printf("OK, but please edit it to suppress unnecessary verbiage, signatures, etc.\n");
        !           467:                }
        !           468:        }
        !           469: 
        !           470:        fprintf(tf, "\n\n");
        !           471:        (void) fflush(tf);
        !           472:        (void) fstat(fileno(tf), &stbuf);
        !           473:        fmodtime = stbuf.st_mtime;
        !           474:        (void) fclose(tf);
        !           475: }
        !           476: 
        !           477: edit_article()
        !           478: {
        !           479:        register char *p;
        !           480:        char *editor;
        !           481:        char *endflag = "";
        !           482:        char *getenv();
        !           483: 
        !           484:        /* edit the file */
        !           485:        editor = getenv("EDITOR");
        !           486:        if (editor == NULL)
        !           487:                editor = DFTEDITOR;
        !           488: 
        !           489:        p = editor + strlen(editor) - 2;
        !           490:        if (strcmp(p, "vi") == 0)
        !           491:                endflag = "+";
        !           492: 
        !           493:        (void) sprintf(buf, "A=%s;export A;exec %s %s %s",
        !           494:                original, editor, endflag, tempfname);
        !           495: 
        !           496:        (void) system(buf);
        !           497: }
        !           498: 
        !           499: /*
        !           500:  * Do sanity checks after the author has typed in the message.
        !           501:  */
        !           502: post_checks()
        !           503: {
        !           504:        char group[BUFLEN];
        !           505:        register char *c, *p;
        !           506:        struct stat stbuf;
        !           507: 
        !           508:        if (stat(tempfname, &stbuf) < 0) {
        !           509:                printf("File deleted - no message posted.\n");
        !           510:                (void) UNLINK(tempfname);
        !           511:                exit(1);
        !           512:        }
        !           513: 
        !           514:        if (stbuf.st_mtime == fmodtime || stbuf.st_size < 5) {
        !           515:                printf("File not modified - no message posted.\n");
        !           516:                (void) UNLINK(tempfname);
        !           517:                exit(1);
        !           518:        }
        !           519: 
        !           520:        /*
        !           521:         * Is this the right number?  Most of the headers are yet to be added
        !           522:         */
        !           523:        if (stbuf.st_size > 65000) {
        !           524:                printf("\nYour message will probably be truncated when it\n");
        !           525:                printf("passes through a notesfile site, since it is\n");
        !           526:                printf("greater than 65000 characters.\n\n");
        !           527:                if (!askyes("Do you still want to post it? ","")) {
        !           528:                        sprintf(ccname, "%s/dead.article", homedir);
        !           529:                        save_article();
        !           530:                        (void) UNLINK(tempfname);
        !           531:                        exit(1);
        !           532:                }
        !           533:        }
        !           534: 
        !           535:        /*
        !           536:         * get the newsgroups from the edited article, in
        !           537:         * case they were altered in the editor
        !           538:         */
        !           539:        if (!article_line(tempfname, "Newsgroups: ", group)) {
        !           540:   nogroups:
        !           541:                printf("Not sending to any newsgroups - no message posted\n");
        !           542:                (void) UNLINK(tempfname);
        !           543:                exit(1);
        !           544:        }
        !           545:        c = &group[11];
        !           546:        while (*c == ' ' || *c == '\t')
        !           547:                c++;
        !           548:        if (*c == '\0')
        !           549:                goto nogroups;
        !           550:        for (p = newsgroups; *c; c++)   /* copy to newsgroups, w/o blanks */
        !           551:                if (*c != ' ' && *c != '\t')
        !           552:                        *p++ = *c;
        !           553:        *p = '\0';
        !           554: 
        !           555:        /* Sanity checks for certain newsgroups */
        !           556:        if (ngmatch(newsgroups, "all.wanted") && ngmatch(distribution,"net,na,usa,att,btl,eunet,aus")) {
        !           557:                printf("Is your message something that might go in your local\n");
        !           558:                printf("newspaper, for example a used car ad, or an apartment\n");
        !           559:                printf("for rent? ");
        !           560:                if (askyes("","")) {
        !           561:                        printf("It's pointless to distribute your article widely, since\n");
        !           562:                        printf("people more than a hundred miles away won't be interested.\n");
        !           563:                        printf("Please use a more restricted distribution.\n");
        !           564:                        get_distribution("*None*");
        !           565:                        modify_article(tempfname, "Distribution: ", distribution,REPLACE);
        !           566:                }
        !           567:        }
        !           568: 
        !           569:        if (ngmatch(newsgroups, "all.jokes")) {
        !           570:                if (askyes("Could this be offensive to anyone? ","")) {
        !           571:                        getpr("Whom might it offend? ", group);
        !           572:                        (void) sprintf(buf," - offensive to %s (rot 13)",group);
        !           573:                        modify_article(tempfname, "Subject: ", buf, APPEND);
        !           574:                        encode(tempfname);
        !           575:                }
        !           576:        }
        !           577: 
        !           578:        if (ngmatch(newsgroups, "net.general")) {
        !           579:                if (index(newsgroups, NGDELIM)) {
        !           580:                        printf("Everybody in the world reads net.general, so it doesn't make\n");
        !           581:                        printf("sense to post to newsgroups in addition to net.general.  If your\n");
        !           582:                        printf("article belongs in one of these other newsgroups, then you\n");
        !           583:                        printf("should not post to net.general. If it is important enough\n");
        !           584:                        printf("for net.general, then you shouldn't post it in other places\n");
        !           585:                        printf("as well.        Please reenter the newsgroups.\n");
        !           586:                        while (!get_newsgroup())
        !           587:                                ;
        !           588:                        modify_article(tempfname, "Newsgroups: ", newsgroups,REPLACE);
        !           589:                }
        !           590:                if (ngmatch(newsgroups, "net.general")) {
        !           591:                        printf("net.general is for important announcements.\n");
        !           592:                        printf("It is not for items for which you couldn't think\n");
        !           593:                        printf("of a better place - those belong in net.misc.\n");
        !           594:                        if (!askyes("Are you sure your message belongs in net.general? ","")) {
        !           595:                                while (!get_newsgroup())
        !           596:                                        ;
        !           597:                                modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
        !           598:                        }
        !           599:                }
        !           600:        }
        !           601: 
        !           602:        if (ngmatch(newsgroups, "net.sources,!net.sources.all")) {
        !           603:                if (!article_line(tempfname, "Subject: ", group)) {
        !           604:   nosubj:
        !           605:                        printf("There seems to be no subject for this article.\n");
        !           606:                        getpr("Subject: ", subject);
        !           607:                        modify_article(tempfname, "Subject: ", subject, REPLACE);
        !           608:                } else {
        !           609:                        c = &group[8];
        !           610:                        while (*c == ' ' || *c == '\t')
        !           611:                                c++;
        !           612:                        if (*c == '\0')
        !           613:                                goto nosubj;
        !           614:                        strcpy(subject, c);
        !           615:                }
        !           616:                if (ngmatch(newsgroups, "all.wanted") || iswanted(subject)) {
        !           617:                        printf("Requests for sources should not be posted to any of\n");
        !           618:                        printf("the net.sources newsgroups, please post such requests\n");
        !           619:                        printf("to net.wanted.sources only.     Please reenter the newsgroups.\n\n");
        !           620:                        while (!get_newsgroup())
        !           621:                                ;
        !           622:                        modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
        !           623:                }
        !           624:                if (ngmatch(newsgroups, "net.sources")) {
        !           625:                        if (!ngmatch(newsgroups, "net.sources.all") &&
        !           626:                            stbuf.st_size < (4*1024)) {
        !           627:                                printf("Your article seems rather small to be a source distribution.\n");
        !           628:                                if (!askyes("Are you certain that this is really source? ", "")) {
        !           629: 
        !           630:                                        while (!get_newsgroup())
        !           631:                                                ;
        !           632:                                        modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
        !           633:                                }
        !           634:                        }
        !           635:                        if (index(newsgroups, NGDELIM)) {
        !           636:                                printf("Sources should be posted to one newsgroup only.\n");
        !           637:                                printf("Please pick the most appropriate group for your article.\n\n");
        !           638:                                while (!get_newsgroup())
        !           639:                                        ;
        !           640:                                modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
        !           641:                        }
        !           642:                }
        !           643:        }
        !           644:        check_mod();
        !           645: }
        !           646: 
        !           647: iswanted(str)
        !           648: register char *str;
        !           649: {
        !           650:        while (*str == ' ')
        !           651:                str++;
        !           652: 
        !           653:        if (prefix(str, "Re:"))
        !           654:                return (FALSE);
        !           655: 
        !           656:        if (isin(str, " wanted ") || isin(str, " can any") ||
        !           657:            isin(str, " need ") || isin(str, " please ") || isin(str, " help ")
        !           658:            || isin(str, " looking ") || index(str, '?'))
        !           659:                return (TRUE);
        !           660: 
        !           661:        return (FALSE);
        !           662: }
        !           663: 
        !           664: isin(str, words)
        !           665: register char *str, *words;
        !           666: {
        !           667:        register char *p;
        !           668:        register sc, wc;
        !           669: 
        !           670:        p = words;
        !           671:        while (sc = *str++) {
        !           672:                if ((wc = *p++) == '\0')
        !           673:                        return (TRUE);
        !           674:                if (wc == ' ') {
        !           675:                        if (index(".,!?-; \t\n", sc))
        !           676:                                continue;
        !           677:                } else {
        !           678:                        if (isupper(wc))
        !           679:                                wc = tolower(wc);
        !           680:                        if (isupper(sc))
        !           681:                                sc = tolower(sc);
        !           682:                        if (wc == sc)
        !           683:                                continue;
        !           684:                }
        !           685:                str -= p - words - 1;
        !           686:                p = words;
        !           687:        }
        !           688:        if (*p == '\0')
        !           689:                return (TRUE);
        !           690:        return (FALSE);
        !           691: }
        !           692: 
        !           693: /*
        !           694:  * Save a copy of the article in the users NEWSARCHIVE directory.
        !           695:  */
        !           696: save_article()
        !           697: {
        !           698:        FILE *in, *out;
        !           699:        int c;
        !           700:        time_t timenow, time();
        !           701:        char *today, *ctime();
        !           702:        struct stat stbuf;
        !           703:        char filename[BUFLEN];
        !           704: 
        !           705:        if (stat(ccname, &stbuf) == 0 && (stbuf.st_mode&S_IFMT) == S_IFDIR) {
        !           706:                /*
        !           707:                 * It would be much nicer here to write articles
        !           708:                 * in MH format (numbered files, in rfc822 format)
        !           709:                 *
        !           710:                 * one day ..
        !           711:                 */
        !           712:                (void) sprintf(filename, "%s/author_copy", ccname);
        !           713:                (void) strcpy(ccname, filename);
        !           714:        }
        !           715:        in = xfopen(tempfname, "r");
        !           716:        out = xfopen(ccname, "a");
        !           717:        timenow = time((time_t)0);
        !           718:        today = ctime(&timenow);
        !           719:        fprintf(out,"From postnews %s",today);
        !           720:        while ((c=getc(in)) != EOF)
        !           721:                putc(c, out);
        !           722:        putc('\n', out);
        !           723:        (void) fclose(in);
        !           724:        (void) fclose(out);
        !           725: }
        !           726: 
        !           727: /*
        !           728:  * Post the article to the net.
        !           729:  */
        !           730: post_article()
        !           731: {
        !           732:        int status;
        !           733: 
        !           734:        printf("%s article...\n", ismod ? "Mailing" : "Posting" );
        !           735:        fflush(stdout);
        !           736:        if (ismod)
        !           737:                (void) sprintf(buf, "exec %s -t < %s", MAILPARSER, tempfname);
        !           738:        else
        !           739:                (void) sprintf(buf, "exec %s/%s -h < %s", LIB, "inews", tempfname);
        !           740:        status = system(buf);
        !           741: 
        !           742:        if (status) {
        !           743:                printf("Article not %s - exit status %d\n", ismod ? "mailed" : "posted", status);
        !           744:                return;
        !           745:        } else
        !           746:                printf("Article %s successfully.\n", ismod ? "mailed" : "posted" );
        !           747: 
        !           748:        if (ccname[0]) {
        !           749:                printf("A copy has been saved in %s\n", ccname);
        !           750:                save_article();
        !           751:        }
        !           752: 
        !           753:        (void) UNLINK(tempfname);
        !           754:        exit(0);
        !           755: }
        !           756: 
        !           757: /*
        !           758:  * Initialization.
        !           759:  */
        !           760: init()
        !           761: {
        !           762:        FILE *fd;
        !           763:        register char *p;
        !           764:        int i;
        !           765:        char *getenv();
        !           766:        struct passwd *pw;
        !           767: 
        !           768:        references[0] = '\0';
        !           769:        distribution[0] = '\0';
        !           770: 
        !           771:        uid = getuid();
        !           772:        pw = getpwuid(uid);
        !           773:        if (pw == NULL) {
        !           774:                fprintf(stderr,"You're not in /etc/passwd\n");
        !           775:                exit(1);
        !           776:        }
        !           777:        p = getenv("HOME");
        !           778:        if (p == NULL) {
        !           779:                p = getenv("LOGDIR");
        !           780:                if (p == NULL) 
        !           781:                        p = pw->pw_dir;
        !           782:        }
        !           783:        (void) strncpy(user, pw->pw_name, SBUFLEN);
        !           784:        (void) strcpy(homedir, p);
        !           785: 
        !           786:        p = getenv("NEWSARCHIVE");
        !           787:        if (p != NULL) {
        !           788:                if (*p == '\0')
        !           789:                        sprintf(ccname, "%s/author_copy", homedir);
        !           790:                else
        !           791:                        strcpy(ccname, p);
        !           792:        }
        !           793: 
        !           794:        pathinit();
        !           795:        (void) sprintf(buf, "%s/%s", LIB, "distributions");
        !           796:        fd = xfopen(buf, "r");
        !           797:        for (i=0; !feof(fd); i++) {
        !           798:                if (fgets(buf, sizeof buf, fd) == NULL)
        !           799:                        break;
        !           800:                twosplit(buf, distr[i].abbr,distr[i].descr);
        !           801:        }
        !           802:        (void) fclose(fd);
        !           803: }
        !           804: 
        !           805: /*
        !           806:  * Split a line of the form
        !           807:  *             text whitespace text
        !           808:  * into two strings.   Also trim off any trailing newline.
        !           809:  * This is destructive on src.
        !           810:  */
        !           811: twosplit(src, dest1, dest2)
        !           812: char *src, *dest1, *dest2;
        !           813: {
        !           814:        register char *p;
        !           815: 
        !           816:        (void) nstrip(src);
        !           817:        for (p=src; isalnum(*p) || ispunct(*p); p++)
        !           818:                ;
        !           819:        *p++ = 0;
        !           820:        for ( ; isspace(*p); p++)
        !           821:                ;
        !           822:        (void) strcpy(dest1, src);
        !           823:        (void) strcpy(dest2, p);
        !           824: }
        !           825: 
        !           826: /*
        !           827:  * Get a yes or no answer to a question.       A default may be used.
        !           828:  */
        !           829: askyes(msg, def)
        !           830: char *msg, *def;
        !           831: {
        !           832:        for(;;) {
        !           833:                printf("%s", msg);
        !           834:                buf[0] = 0;
        !           835:                (void) gets(buf);
        !           836:                switch(buf[0]) {
        !           837:                case 'y':
        !           838:                case 'Y':
        !           839:                        return TRUE;
        !           840:                case 'n':
        !           841:                case 'N':
        !           842:                        return FALSE;
        !           843:                case '\0':
        !           844:                        switch(*def) {
        !           845:                        case 'y':
        !           846:                        case 'Y':
        !           847:                                return TRUE;
        !           848:                        case 'n':
        !           849:                        case 'N':
        !           850:                                return FALSE;
        !           851:                        }
        !           852:                default:
        !           853:                        printf("Please answer yes or no.\n");
        !           854:                }
        !           855:        }
        !           856: }
        !           857: 
        !           858: /*
        !           859:  * Get a character string into buf, using prompt msg.
        !           860:  */
        !           861: getpr(msg, bptr)
        !           862: char *msg, *bptr;
        !           863: {
        !           864:        static int numeof = 0;
        !           865:        printf("%s", msg);
        !           866:        (void) gets(bptr);
        !           867:        (void) nstrip(bptr);
        !           868:        if (feof(stdin)) {
        !           869:                if (numeof++ > 3) {
        !           870:                        fprintf(stderr,"Too many EOFs\n");
        !           871:                        exit(1);
        !           872:                }
        !           873:                clearerr(stdin);
        !           874:        }
        !           875: }
        !           876: 
        !           877: byebye(mesg)
        !           878: char *mesg;
        !           879: {
        !           880:        printf("%s\n", mesg);
        !           881:        exit(1);
        !           882: }
        !           883: 
        !           884: /*
        !           885:  * make a modification to the header of an article
        !           886:  *
        !           887:  *      fname -- name of article
        !           888:  *      field -- header field to modify
        !           889:  *      line   -- modification line
        !           890:  *      how     -- APPEND or REPLACE
        !           891:  *
        !           892:  * example:
        !           893:  *      modify_article("/tmp/article" , "Subject:" , "new subject" , REPLACE);
        !           894:  *
        !           895:  *
        !           896:  */
        !           897: modify_article(fname, field, line, how)
        !           898: char *fname, *field, *line;
        !           899: {
        !           900:        FILE *fpart, *fptmp;
        !           901:        char *temp2fname = "/tmp/postXXXXXX";
        !           902:        char lbfr[BUFLEN];
        !           903:        register found = FALSE;
        !           904: 
        !           905:        mktemp(temp2fname);
        !           906: 
        !           907:        fptmp = xfopen(temp2fname, "w");
        !           908:        fpart = xfopen(fname, "r");
        !           909: 
        !           910:        while (fgets(lbfr, BUFLEN, fpart) != NULL) {
        !           911:                if (prefix(lbfr, field)) {
        !           912:                        found = TRUE;
        !           913:                        (void) nstrip(lbfr);
        !           914:                        if (how == APPEND) {
        !           915:                                /* append to current field */
        !           916:                                (void) strcat(lbfr, line);
        !           917:                                (void) strcat(lbfr, "\n");
        !           918:                        } else
        !           919:                                /* replace current field */
        !           920:                                (void) sprintf(lbfr, "%s%s\n", field, line);
        !           921:                }
        !           922:                (void) fputs(lbfr, fptmp);
        !           923:        }
        !           924: 
        !           925:        fclose(fpart);
        !           926:        fclose(fptmp);
        !           927: 
        !           928:        fptmp = xfopen(temp2fname, "r");
        !           929:        fpart = xfopen(fname, "w");
        !           930: 
        !           931:        if (!found)
        !           932:                fprintf(fpart, "%s%s\n", field, line);
        !           933:        while (fgets(buf,BUFLEN,fptmp) != NULL)
        !           934:                (void) fputs(buf, fpart);
        !           935: 
        !           936:        (void) fclose(fpart);
        !           937:        (void) fclose(fptmp);
        !           938:        (void) UNLINK(temp2fname);
        !           939: }
        !           940: 
        !           941: 
        !           942: /* verify that newsgroup exists, and get number of entries */
        !           943: valid_ng(ng, maxart, minart, canpost)
        !           944: char *ng;
        !           945: long *maxart, *minart;
        !           946: char *canpost;
        !           947: {
        !           948:        char ng_check[BUFLEN], ng_read[BUFLEN];
        !           949:        FILE *fp;
        !           950: 
        !           951:        fp = xfopen(ACTIVE, "r");
        !           952:        while (fgets(ng_read, BUFLEN, fp) != NULL) {
        !           953:                switch (sscanf(ng_read, "%s %ld %ld %c", ng_check, maxart, minart, canpost)) {
        !           954:                case 2:
        !           955:                        *minart = 1;
        !           956:                        /* fall through */
        !           957:                case 3:
        !           958:                        *canpost = 'y';
        !           959:                        /* fall through */
        !           960:                case 4:
        !           961:                        break;
        !           962: 
        !           963:                default:
        !           964:                        printf("Active file (%s) corrupted. ", ACTIVE);
        !           965:                        byebye("Seek help!");
        !           966:                }
        !           967:                        
        !           968:                if (strcmp(ng_check, ng) == 0) {
        !           969:                        (void) fclose(fp);
        !           970:                        if (*canpost == 'y') {
        !           971: #ifdef FASCIST
        !           972:                                if (uid && uid != ROOTID && fascist(user, ng)) {
        !           973:                                        *canpost = 'n';
        !           974:                                        return FALSE;
        !           975:                                }
        !           976: #endif FASCIST
        !           977:                                return TRUE;
        !           978:                        } else
        !           979:                                return FALSE;
        !           980:                }
        !           981:        }
        !           982:        *canpost = 'i';
        !           983:        *maxart = 0;
        !           984:        *minart = 0;
        !           985:        (void) fclose(fp);
        !           986:        return FALSE;
        !           987: }
        !           988: 
        !           989: /* get the line specified by field from an article */
        !           990: article_line(article, field, line)
        !           991: char *article, *field, *line;
        !           992: {
        !           993:        FILE *fp;
        !           994:        char *c;
        !           995: 
        !           996:        fp = xfopen(article,"r");
        !           997:        while ((c=fgets(line,BUFLEN,fp)) != NULL && !prefix(line, field))
        !           998:                if (line[0] == '\n') {
        !           999:                        c = NULL;
        !          1000:                        break;
        !          1001:                }
        !          1002:        (void) fclose(fp);
        !          1003:        if (c != NULL) {
        !          1004:                (void) nstrip(line);
        !          1005:                return TRUE;
        !          1006:        } else {
        !          1007:                line[0] = '\0';
        !          1008:                return FALSE;
        !          1009:        }
        !          1010: }
        !          1011: 
        !          1012: /* get the header information for a followup article */
        !          1013: followup(baseart)
        !          1014: register char *baseart;
        !          1015: {
        !          1016:        register char *p;
        !          1017: 
        !          1018:        /* subject */
        !          1019:        if (article_line(baseart, "Subject: ", buf)) {
        !          1020:                p = buf+9;
        !          1021:                for ( ; ; ) {
        !          1022:                        while (*p == ' ' || *p == '\t')
        !          1023:                                ++p;
        !          1024:                        if ((*p != 'r' && *p != 'R') ||
        !          1025:                                (p[1] != 'e' && p[1] != 'E') ||
        !          1026:                                (p[2] != ':' && p[2] != ' '))
        !          1027:                                        break;
        !          1028:                        p += 3;
        !          1029:                }
        !          1030:                (void) sprintf(subject, "Re: %s", p);
        !          1031:        } else {
        !          1032:                if (article_line(baseart, "From: ", buf))
        !          1033:                        (void) sprintf(subject, "Re: orphan response from %s", buf);
        !          1034:                else
        !          1035:                        (void) strcpy(subject, "Re: orphan response");
        !          1036:        }
        !          1037: 
        !          1038:        /* newsgroup */
        !          1039:        if (article_line(baseart, "Newsgroups: ", buf))
        !          1040:                (void) strcpy(newsgroups, buf+12);
        !          1041:        if (ngmatch(newsgroups, "net.general"))
        !          1042:                (void) strcpy(newsgroups,"net.followup");
        !          1043:        if (ngmatch(newsgroups, "net.sources,!net.sources.all"))
        !          1044:                (void) strcpy(newsgroups,"net.sources.d");
        !          1045:        if (ngmatch(newsgroups, "net.jobs")) {
        !          1046:                printf("net.jobs is for the direct posting of job announcements and requests.\n");
        !          1047:                printf("it is not for discussion. You followup has been directed to net.misc\n");
        !          1048:                (void) strcpy(newsgroups,"net.misc");
        !          1049:        }
        !          1050: 
        !          1051:        /* moderator */
        !          1052:        check_mod();
        !          1053: 
        !          1054:        /* distribution */
        !          1055:        if (article_line(baseart, "Distribution: ", buf))
        !          1056:                (void) strcpy(distribution, buf+14);
        !          1057: 
        !          1058:        /* references */
        !          1059:        if (article_line(baseart, "References: ", buf)) {
        !          1060:                register char *rcp;
        !          1061:                (void) strcpy(references, buf+12);
        !          1062:                (void) strcat(references, " ");
        !          1063:                /* keep the number of references to a reasonable number */
        !          1064:                rcp = rindex(references, ' '); /* Can not fail */
        !          1065:                while ((int)(rcp - references) > 70) {
        !          1066:                        while (*--rcp != ' ')
        !          1067:                                ;
        !          1068:                        rcp[1] = '\0';
        !          1069:                }
        !          1070:        }
        !          1071:        if (article_line(baseart, "Message-ID: ", buf)) {
        !          1072:                (void) strcat(references, buf+12);
        !          1073:                (void) strcpy(msgid, buf+12);
        !          1074:        }
        !          1075: 
        !          1076:        if (article_line(baseart, "From: ", buf))
        !          1077:                (void) strcpy(isfrom, buf+6);
        !          1078: 
        !          1079:        if (article_line(baseart, "Keywords: ", buf))
        !          1080:                (void) strcpy(keywords, buf+10);
        !          1081: 
        !          1082:        if (article_line(baseart, "Followup-To: ", buf)) {
        !          1083:                (void) strcpy(newsgroups, buf+13);
        !          1084:                if (strcmp(newsgroups, "poster") == 0)
        !          1085:                        byebye("Mail followups directly to poster.");
        !          1086:        }
        !          1087: 
        !          1088:        get_summary();
        !          1089: }
        !          1090: 
        !          1091: get_summary()
        !          1092: {
        !          1093:        register char *p;
        !          1094:        register i;
        !          1095: 
        !          1096:        printf("Please enter a short summary of your contribution to the discussion\n");
        !          1097:        printf("Just one or two lines ...   (end with a blank line)\n");
        !          1098:        p = summary;
        !          1099:        for (i = 0; i < 3; i++) {       /* 3 * 80 < 256, should be safe .. */
        !          1100:                getpr(">\t", p);
        !          1101:                if (*p == '\0')
        !          1102:                        break;
        !          1103:                p = index(p, '\0');
        !          1104:                (void) strcpy(p, "\n\t ");
        !          1105:                p += 3;
        !          1106:        }
        !          1107:        if (p > summary)
        !          1108:                p[-3] = '\0';
        !          1109: }
        !          1110: 
        !          1111: encode(article)
        !          1112: char *article;
        !          1113: {
        !          1114:        FILE *fpart, *fphead, *fpcoded;
        !          1115:        char *headerfile = "/tmp/pheadXXXXXX";
        !          1116:        char *codedfile = "/tmp/pcodeXXXXXX";
        !          1117: 
        !          1118:        (void) mktemp(headerfile);
        !          1119:        (void) mktemp(codedfile);
        !          1120: 
        !          1121:        fpart = xfopen(article, "r");
        !          1122: 
        !          1123:        /* place article header in "headerfile" file */
        !          1124:        fphead = xfopen(headerfile, "w");
        !          1125:        while (fgets(buf, BUFLEN, fpart) != NULL) {
        !          1126:                (void) fputs(buf, fphead);
        !          1127:                if (buf[0] == '\n')
        !          1128:                        break;
        !          1129:        }
        !          1130:        (void) fclose(fphead);
        !          1131: 
        !          1132:        /* place article body in "codedfile" file */
        !          1133:        fpcoded = xfopen(codedfile, "w");
        !          1134:        while (fgets(buf, BUFLEN, fpart) != NULL)
        !          1135:                (void) fputs(buf, fpcoded);
        !          1136:        (void) fclose(fpcoded);
        !          1137:        (void) fclose(fpart);
        !          1138: 
        !          1139:        /* encode body and put back together with header */
        !          1140:        (void) rename(headerfile, article);
        !          1141: 
        !          1142:        (void) sprintf(buf,"exec %s/%s 13 < %s >> %s\n", LIB, "caesar", codedfile, article);
        !          1143:        printf("Encoding article -- please stand by\n");
        !          1144:        if (system(buf)) {
        !          1145:                printf("encoding failed");
        !          1146:                exit(2);
        !          1147:        }
        !          1148:        (void) UNLINK(codedfile);
        !          1149: }
        !          1150: 
        !          1151: 
        !          1152: /*
        !          1153:  * Print a recorded message warning the poor luser what he is doing
        !          1154:  * and demand that he understands it before proceeding.  Only do
        !          1155:  * this for newsgroups listed in LIBDIR/recording.
        !          1156:  */
        !          1157: recording(ngrps)
        !          1158: char *ngrps;
        !          1159: {
        !          1160:        char recbuf[BUFLEN];
        !          1161:        FILE *fd;
        !          1162:        char nglist[BUFLEN], fname[BUFLEN];
        !          1163:        int  c, n, yes, retval = 0;
        !          1164: 
        !          1165:        (void) sprintf(recbuf, "%s/%s", LIB, "recording");
        !          1166:        fd = fopen(recbuf, "r");
        !          1167:        if (fd == NULL)
        !          1168:                return 0;
        !          1169:        while ((fgets(recbuf, sizeof recbuf, fd)) != NULL) {
        !          1170:                (void) sscanf(recbuf, "%s %s", nglist, fname);
        !          1171:                if (ngmatch(ngrps, nglist)) {
        !          1172:                        (void) fclose(fd);
        !          1173:                        if (fname[0] == '/')
        !          1174:                                (void) strcpy(recbuf, fname);
        !          1175:                        else
        !          1176:                                (void) sprintf(recbuf, "%s/%s", LIB, fname);
        !          1177:                        fd = fopen(recbuf, "r");
        !          1178:                        if (fd == NULL)
        !          1179:                                return 0;
        !          1180:                        while ((c = getc(fd)) != EOF)
        !          1181:                                putc(c, stderr);
        !          1182:                        fprintf(stderr, "Do you understand this?  Hit <return> to proceed, <BREAK> to abort: ");
        !          1183:                        n = read(2, recbuf, 100);
        !          1184:                        c = recbuf[0];
        !          1185:                        yes = (c=='y' || c=='Y' || c=='\n' || c=='\n' || c==0);
        !          1186:                        if (n <= 0 || !yes)
        !          1187:                                retval = -1;
        !          1188:                }
        !          1189:        }
        !          1190:        return retval;
        !          1191: }
        !          1192: 
        !          1193: xxit(i)
        !          1194: {
        !          1195:        exit(i);
        !          1196: }
        !          1197: 
        !          1198: #if !defined(BSD4_2) && !defined(BSD4_1C)
        !          1199: rename(from,to)
        !          1200: register char *from, *to;
        !          1201: {
        !          1202:        (void) unlink(to);
        !          1203:        if (link(from, to) < 0)
        !          1204:                return -1;
        !          1205: 
        !          1206:        (void) unlink(from);
        !          1207:        return 0;
        !          1208: }
        !          1209: #endif /* !BSD4_2 && ! BSD4_1C */

unix.superglobalmegacorp.com

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