Annotation of 43BSD/contrib/news/src/control.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:  * Control message handling code.  Deal with messages which are to be
        !            16:  * acted on by netnews itself rather than by people.
        !            17:  *
        !            18:  * See defs.h "news_version" for the real version of netnews.
        !            19:  */
        !            20: 
        !            21: #ifdef SCCSID
        !            22: static char    *SccsId = "@(#)control.c        2.43    3/19/86";
        !            23: #endif /* SCCSID */
        !            24: 
        !            25: #include "iparams.h"
        !            26: 
        !            27: #define eq(msg) (strcmp(msg, cargv[0]) == 0)
        !            28: 
        !            29: int cargc;
        !            30: char **cargv;
        !            31: 
        !            32: FILE *hfopen();
        !            33: FILE *popen(), *mhopen(), *mailhdr();
        !            34: 
        !            35: char *senderof();
        !            36: #ifdef u370
        !            37: static struct hbuf htmp;
        !            38: #endif /* u370 */
        !            39: 
        !            40: control(h)
        !            41: struct hbuf *h;
        !            42: {
        !            43:        register char *ctlmsgtext;
        !            44: 
        !            45:        if (strncmp(h->title, "cmsg ", 5) == 0) {
        !            46:                register char *cp1, *cp2;
        !            47:                cp1 = h->title;
        !            48:                cp2 = h->title + 5;
        !            49:                while (*cp1++ = *cp2++)
        !            50:                        ;
        !            51:        }
        !            52: 
        !            53:        if (*h->ctlmsg)
        !            54:                ctlmsgtext = h->ctlmsg;
        !            55:        else
        !            56:                ctlmsgtext = h->title;
        !            57:        log("Ctl Msg %s from %s: %s", h->nbuf, h->path, ctlmsgtext);
        !            58:        /*
        !            59:         * Control messages have the standard format
        !            60:         *      command [args]
        !            61:         * much like shell commands.  Each site has the option
        !            62:         * of customizing this code to deal with control messages
        !            63:         * as they see fit, but we would like to buy back the
        !            64:         * code, ifdeffed or otherwise parameterized, to simplify
        !            65:         * the maintenence issues.
        !            66:         */
        !            67:        argparse(ctlmsgtext);
        !            68:        
        !            69:        if (eq("cancel"))
        !            70:                return c_cancel(cargc, cargv);
        !            71:        else if (eq("newgroup"))
        !            72:                c_newgroup(cargc, cargv);
        !            73:        else if (eq("ihave"))
        !            74:                c_ihave(cargc, cargv);
        !            75:        else if (eq("sendme"))
        !            76:                c_sendme(cargc, cargv);
        !            77:        else if (eq("sendbad"))
        !            78:                c_sendme(cargc, cargv);
        !            79:        else if (eq("rmgroup"))
        !            80:                c_rmgroup(cargc, cargv);
        !            81:        else if (eq("sendsys"))
        !            82:                c_sendsys(cargc, cargv);
        !            83:        else if (eq("senduuname"))
        !            84:                c_senduuname(cargc, cargv);
        !            85:        else if (eq("version"))
        !            86:                c_version(cargc, cargv);
        !            87:        else if (eq("checkgroups"))
        !            88:                c_checkgroups(cargc, cargv);
        !            89:        else if (eq("delsub"))
        !            90:                c_unimp(cargc, cargv);
        !            91:        else
        !            92:                c_unknown(h, ctlmsgtext);
        !            93:        return 0;
        !            94: }
        !            95: 
        !            96: /*
        !            97:  * Parse the string str into separate words in cargc and cargv
        !            98:  * as per the usual UNIX convention.  Nothing fancy here, just
        !            99:  * blanks and tabs separating words.
        !           100:  */
        !           101: argparse(str)
        !           102: char *str;
        !           103: {
        !           104:        static char *cavpbuf[20];
        !           105:        static char cavbuf[256];
        !           106:        char *nextfree = cavbuf;
        !           107: 
        !           108:        if (str == '\0')
        !           109:                xerror("Control message %s has no title", header.ident);
        !           110:        cargc = (*str != '\0');
        !           111:        cargv = cavpbuf;
        !           112:        cargv[0] = cavbuf;
        !           113: 
        !           114:        while (*str) {
        !           115:                if (*str <= ' ') {
        !           116:                        *nextfree++ = 0;
        !           117:                        cargv[cargc] = nextfree;
        !           118:                        cargc++;
        !           119:                        /* skip over white space */
        !           120:                        while (*str != '\0' && *str <= ' ')
        !           121:                                str++;
        !           122:                        if (*str == '\0')       /* line ends in white space */
        !           123:                                return;
        !           124:                } else
        !           125:                        *nextfree++ = *str++;
        !           126:        }
        !           127: }
        !           128: 
        !           129: /*
        !           130:  * ihave <artid> <remotesys>
        !           131:  * The other system is telling you it has article <artid>, in case
        !           132:  * you decide you want it to transmit it to you.
        !           133:  */
        !           134: c_ihave(argc, argv)
        !           135: char **argv;
        !           136: {
        !           137:        char tl[256], ng[256];
        !           138: #ifndef u370
        !           139:        struct hbuf htmp;
        !           140: #endif /* !u370 */
        !           141: 
        !           142:        if (argc < 2)
        !           143:                xerror("ihave: Not enough arguments.");
        !           144:        /*
        !           145:         * Check that we haven't already seen it (history)
        !           146:         * and then send back a "sendme" message if we subscribe.
        !           147:         */
        !           148:        (void) strncpy(htmp.ident, argv[1], BUFLEN);
        !           149:        if (history(&htmp) == 0) {
        !           150:                /* Should probably check SUBFILE here. */
        !           151:                (void) sprintf(tl, "sendme %s %s", argv[1], FULLSYSNAME);
        !           152:                (void) sprintf(ng, "to.%s.ctl", argv[2]);
        !           153:                xmitmsg(argv[2], tl, ng);
        !           154:        }
        !           155: }
        !           156: 
        !           157: /*
        !           158:  * sendme <artid> ... <remotesys>
        !           159:  * The other system wants me to send him article <artid>.
        !           160:  */
        !           161: c_sendme(argc, argv)
        !           162: char **argv;
        !           163: {
        !           164:        int i;
        !           165:        FILE *fp;
        !           166:        struct srec srec;
        !           167: #ifndef u370
        !           168:        struct hbuf htmp;
        !           169: #endif /* !u370 */
        !           170: 
        !           171:        if (argc < 2)
        !           172:                xerror("sendme: Not enough arguments.");
        !           173:        /* Don't ask for it from myself */
        !           174:        if (strncmp(FULLSYSNAME, argv[argc], SNLN) == 0)
        !           175:                return;
        !           176:        /* Find the sys record */
        !           177:        s_openr();
        !           178:        while (s_read(&srec)) {
        !           179:                if (strncmp(srec.s_name, argv[argc], SNLN))
        !           180:                        continue;
        !           181:                /* It's the right one.  Send them. */
        !           182:                for (i=1; i<argc; i++) {
        !           183:                        fp = hfopen(argv[i]);
        !           184:                        htmp.unrec[0] = NULL;
        !           185:                        if (hread(&htmp, fp, TRUE) == NULL) {
        !           186:                                if (bfr[0] == '/') {
        !           187:                                        fp = xfopen(bfr, "r");
        !           188:                                        if (hread(&htmp, fp, TRUE) == NULL)
        !           189:                                                xerror("Article %s is garbled.", bfr);
        !           190:                                } else
        !           191:                                        xerror("Article %s is garbled.", argv[i]);
        !           192:                        }
        !           193:                        (void) fseek(fp, 0L, 0);
        !           194:                        if (strcmp(argv[0], "sendme") == 0) {
        !           195:                                /* check that other sys subscribes. */
        !           196:                                if (!ngmatch(htmp.nbuf, srec.s_nbuf) || 
        !           197:                                        !(htmp.distribution[0] == '\0' ||
        !           198:                                        ngmatch(htmp.distribution, srec.s_nbuf)))
        !           199:                                        continue;
        !           200:                        }
        !           201:                        transmit(&srec, fp, 0, (char **)0, 0);
        !           202:                        /* transmit does fclose(fp) */
        !           203:                }
        !           204:                return;
        !           205:        }
        !           206:        xerror("Cannot find system %s to send article %s to.", argv[argc],
        !           207:                argv[1]);
        !           208: }
        !           209: 
        !           210: /*
        !           211:  * newgroup <groupname>
        !           212:  * A new newsgroup has been created.
        !           213:  * The body of the article, if present, is a description of the
        !           214:  * purpose of the newsgroup.
        !           215:  *
        !           216:  */
        !           217: c_newgroup(argc, argv)
        !           218: char **argv;
        !           219: {
        !           220:        FILE *fd;
        !           221:        int didcreate = 0;
        !           222: 
        !           223:        if (argc < 1)
        !           224:                xerror("newgroup: Not enough arguments.");
        !           225:        if (validng(argv[1]))
        !           226:                return;
        !           227:        if (header.approved[0] == '\0')
        !           228:                xerror("newgroup: %s not approved", argv[1]);
        !           229: 
        !           230: #ifndef NONEWGROUPS
        !           231: #ifdef ORGDISTRIB
        !           232:        if (!strcmp(ORGDISTRIB, header.distribution)) {
        !           233:                didcreate++;
        !           234: #endif /* ORGDISTRIB */
        !           235:                actfp = xfopen(ACTIVE, "a");
        !           236:                fprintf(actfp, "%s 00000 00001 y\n", argv[1]);
        !           237:                (void) fclose(actfp);
        !           238: #ifdef ORGDISTRIB
        !           239:        }
        !           240: #endif /* ORGDISTRIB */
        !           241: #endif /* !NONEWGROUPS */
        !           242: 
        !           243: #ifdef NOTIFY
        !           244:        fd = mailhdr((struct hbuf *)NULL, "creation of new newsgroup");
        !           245:        if (fd != NULL) {
        !           246:                if (didcreate) 
        !           247:                        fprintf(fd, "A new newsgroup called '%s' has been created by %s.\n",
        !           248:                        argv[1], header.path);
        !           249:                else
        !           250:                        fprintf(fd, "%s requested that a new newsgroup called '%s' be created.\n",
        !           251:                        header.path, argv[1]);
        !           252:                fprintf(fd, "It was approved by %s\n\n", header.approved);
        !           253: #ifdef ORGDISTRIB
        !           254:                    fprintf(fd, "You can accomplish this by sending a newgroup control message with a\n");
        !           255:                    fprintf(fd, "distribution code of %s; in other words, by executing the command:\n", ORGDISTRIB);
        !           256:                    fprintf(fd, "%s/inews -n net.news -d %s -t \"cmsg newgroup %s\"\n", 
        !           257:                        LIB, ORGDISTRIB, argv[1]);
        !           258: #endif /* ORGDISTRIB */
        !           259:                (void) mclose(fd);
        !           260:        }
        !           261: }
        !           262: #endif /* NOTIFY */
        !           263: 
        !           264: 
        !           265: /*
        !           266:  * rmgroup <groupname>
        !           267:  * An old newsgroup is being cancelled on a network wide basis.
        !           268:  */
        !           269: c_rmgroup(argc, argv)
        !           270: char **argv;
        !           271: {
        !           272:        FILE *fd;
        !           273:        int shouldremove = 0;
        !           274: 
        !           275:        if (argc < 1)
        !           276:                xerror("rmgroup: Not enough arguments.");
        !           277:        if (!validng(argv[1]))
        !           278:                return;
        !           279:        if (header.approved[0] == '\0')
        !           280:                xerror("rmgroup: %s not approved", argv[1]);
        !           281: 
        !           282: #ifndef MANUALLY
        !           283: #ifdef ORGDISTRIB
        !           284:        if (!strcmp(ORGDISTRIB, header.distribution))
        !           285: #endif /* ORGDISTRIB */                
        !           286:        shouldremove++;
        !           287: #endif /* !MANUALLY */
        !           288: #ifdef NOTIFY
        !           289:        fd = mailhdr((struct hbuf *)NULL, "rmgroup control message");
        !           290:        if (fd != NULL) {
        !           291:                if (shouldremove) {
        !           292:                        fprintf(fd, "A newsgroup called '%s' has been removed by %s.\n\n",
        !           293:                                argv[1], header.path);
        !           294: #  ifdef USG
        !           295:                        fprintf(fd, "You may need to remove the directory %s by hand\n",
        !           296:                                dirname(argv[1]));
        !           297: #  endif
        !           298:                } else {
        !           299:                        fprintf(fd, "%s has requested that newsgroup %s be removed.\n",
        !           300:                                header.path, argv[1]);
        !           301:                        fprintf(fd, "You should remove it by hand\n");
        !           302:                        fprintf(fd, "To do this, execute the command\n");
        !           303:                        fprintf(fd, "\t%s/rmgroup %s\n", LIB, argv[1]);
        !           304:                }
        !           305:                (void) mclose(fd);
        !           306:        }
        !           307: #endif /* NOTIFY */
        !           308: 
        !           309:        if (shouldremove) {
        !           310:                int rc;
        !           311:                /* We let the shell do all the work.
        !           312:                 * See the rmgrp shell script. */
        !           313:                (void) setuid(geteuid()); /* otherwise it won't rmdir the dir */
        !           314:                (void) sprintf(bfr, "exec %s/rmgroup %s", LIB, argv[1]);
        !           315:                rc = system(bfr);
        !           316:                log("system(%s) status %d", bfr, rc);
        !           317:        }
        !           318: }
        !           319: 
        !           320: /*
        !           321:  * cancel <artid>
        !           322:  * Cancel the named article
        !           323:  */
        !           324: c_cancel(argc, argv)
        !           325: char **argv;
        !           326: {
        !           327:        char *line, *p, *q, *r, *poster;
        !           328:        char *findhist();
        !           329:        register FILE *fp;
        !           330:        char whatsisname[BUFLEN], nfilename[BUFLEN];
        !           331:        time_t t;
        !           332:        int su = 0;
        !           333: #ifndef u370
        !           334:        struct hbuf htmp;
        !           335: #endif /* !u370 */
        !           336: 
        !           337:        if (argc < 1)
        !           338:                xerror("cancel: Not enough arguments.");
        !           339:        (void) strcpy(whatsisname, senderof(&header));
        !           340:        line = findhist(argv[1]);
        !           341:        if (line == NULL) {
        !           342:                struct tm *tm;
        !           343:                log("Can't cancel %s:  non-existent", argv[1]);
        !           344:                (void) time(&t);
        !           345:                tm = localtime(&t);
        !           346: #ifdef USG
        !           347:                sprintf(bfr,"%s\t%2.2d/%2.2d/%d %2.2d:%2.2d\tcancelled",
        !           348: #else /* !USG */
        !           349:                sprintf(bfr,"%s\t%02d/%02d/%d %02d:%02d\tcancelled",
        !           350: #endif /* !USG */
        !           351:                   argv[1], tm->tm_mon+1, tm->tm_mday, tm->tm_year, tm->tm_hour,
        !           352:                   tm->tm_min);
        !           353:                savehist(bfr);
        !           354:                return 1;
        !           355:        }
        !           356: 
        !           357:        q = index(line, '\t');
        !           358:        p = index(q+1, '\t');
        !           359:        if (p == NULL || *++p == '\0' || *p == '\n') {
        !           360:                *q = '\0';
        !           361:                log("Expired article %s", line);
        !           362:                return 1;
        !           363:        }
        !           364:        if (strcmp(p, "cancelled") == 0) {
        !           365:                *q = '\0';
        !           366:                log("Already Cancelled %s", line);
        !           367:                return 1;
        !           368:        } else
        !           369:                log("Cancelling %s", line);
        !           370:        if ((uid == ROOTID||uid == 0) && strcmp(header.distribution, "local") == 0)
        !           371:                su = 1;
        !           372:        while (*p) {
        !           373:                q = index(p, ' ');
        !           374:                if (q)
        !           375:                        *q = '\0';
        !           376:                (void) strcpy(nfilename, dirname(p));
        !           377:                fp = fopen(nfilename, "r");
        !           378:                if (fp == NULL) {
        !           379:                        log("Already Cancelled %s", line);
        !           380:                        return 1;
        !           381:                }
        !           382:                htmp.unrec[0] = NULL;
        !           383:                if (hread(&htmp, fp, TRUE) == NULL) {
        !           384:                        if (bfr[0] == '/') {
        !           385:                                fp = fopen(bfr, "r");
        !           386:                                if (fp == NULL
        !           387:                                        || hread(&htmp, fp, TRUE) == NULL)
        !           388:                                        xerror("Article is garbled.");
        !           389:                        } else 
        !           390:                                xerror("Article is garbled.");
        !           391:                }
        !           392:                (void) fclose(fp);
        !           393:                poster = senderof(&htmp);
        !           394:                /* only compare up to '.' or ' ' */
        !           395:                r = index(poster,'.');
        !           396:                if (r == NULL)
        !           397:                        r = index(poster,' ');
        !           398:                if (r != NULL)
        !           399:                        *r = '\0';
        !           400:                if (!su && strncmp(whatsisname, poster,strlen(poster))) {
        !           401:                        xerror("Not contributor: posted by %s, and you are %s", poster, whatsisname);
        !           402:                }
        !           403: 
        !           404:                (void) unlink(nfilename);
        !           405:                p = q+1;
        !           406:        }
        !           407:        return 0;
        !           408: }
        !           409: 
        !           410: /*
        !           411:  * sendsys     (no arguments)
        !           412:  *
        !           413:  * Mail the sys file to the person submitting the article.
        !           414:  * POLICY: the contents of your sys file are public information
        !           415:  * and as such, you should not change this code.  You may feel
        !           416:  * free to arrange for it to manually notify you, in the event
        !           417:  * that you want to do something to clean it up before it goes out.
        !           418:  * Secret sites on the net are expressly frowned on.
        !           419:  * 
        !           420:  * The purpose of this command is for making a network map.  The
        !           421:  * details of your link and which newsgroups are forwarded are not
        !           422:  * important, in case you want to sanitize them.  Since the definition
        !           423:  * of USENET is those sites getting net.announce, you can disable this
        !           424:  * on sites not getting net articles, but if you take out the list of
        !           425:  * forwarded newsgroups, and you have sites that only get local newsgroups,
        !           426:  * you should make this clear, or remove those sites from what you send out.
        !           427:  */
        !           428: /* ARGSUSED */
        !           429: c_sendsys(argc, argv)
        !           430: char **argv;
        !           431: {
        !           432:        register FILE *f, *u;
        !           433:        int c;
        !           434: 
        !           435: #ifdef NOTIFY
        !           436:        f = mailhdr((struct hbuf *)NULL, "sendsys control message");
        !           437:        if (f != NULL) {
        !           438:                fprintf(f, "%s requested your %s/sys file.\n", header.path, LIB);
        !           439:                fprintf(f, "It has been sent.\n");
        !           440:                (void) mclose(f);
        !           441:        }
        !           442: #endif
        !           443:        f = mailhdr(&header, "response to your sendsys request");
        !           444:        u = fopen(SUBFILE, "r");
        !           445:        if (f != NULL && u != NULL) {
        !           446:                while ((c=getc(u)) != EOF)
        !           447:                        putc(c, f);
        !           448:                (void) fclose(u);
        !           449:                (void) mclose(f);
        !           450:        }
        !           451: }
        !           452: 
        !           453: /*
        !           454:  * senduuname  (no arguments)
        !           455:  *
        !           456:  * Run the "uuname" command and send it back to the person who submitted
        !           457:  * the article.  The purpose of this control message is for attempting to
        !           458:  * make a uucp net map.
        !           459:  *
        !           460:  * POLICY: If you view this information as not public (because you have
        !           461:  * a connection you consider secret, or know a site that considers itself
        !           462:  * secret) you can feel free to change this code in whatever way is
        !           463:  * appropriate, so long as it sends some response back to the sender.  If
        !           464:  * you don't run uucp, this code does not make sense, and so an error
        !           465:  * message (or garbage, such as "research") will be mailed back.
        !           466:  *
        !           467:  * If you wish to add or remove sites from the output of uuname, you
        !           468:  * may wish to use the euuname.sh shell script here.
        !           469:  */
        !           470: /* ARGSUSED */
        !           471: c_senduuname(argc, argv)
        !           472: char **argv;
        !           473: {
        !           474:        char buf[256];
        !           475:        FILE *fd, *u;
        !           476:        int c;
        !           477: 
        !           478: #ifdef NOTIFY
        !           479:        fd = mailhdr((struct hbuf *)NULL, "uuname control message");
        !           480:        fprintf(fd, "%s requested your uuname output\n", header.path);
        !           481:        (void) mclose(fd);
        !           482: #endif
        !           483:        fd = mailhdr(&header, "response to your senduuname request");
        !           484: #ifdef UUPROG
        !           485:        if (UUPROG[0] == '/')
        !           486:                (void) strcpy(buf, UUPROG);
        !           487:        else
        !           488:                (void) sprintf(buf, "%s/%s", LIB, UUPROG);
        !           489: #else
        !           490:        (void) strcpy(buf, "uuname");
        !           491: #endif
        !           492:        u = popen(buf, "r");
        !           493:        if (fd != NULL && u != NULL) {
        !           494:                while ((c=getc(u)) != EOF)
        !           495:                        putc(c, fd);
        !           496:                (void) pclose(u);
        !           497:                (void) mclose(fd);
        !           498:        }
        !           499: }
        !           500: 
        !           501: /*
        !           502:  * Send the version number to the right person.
        !           503:  */
        !           504: /* ARGSUSED */
        !           505: c_version(argc, argv)
        !           506: char **argv;
        !           507: {
        !           508:        register FILE *f;
        !           509: 
        !           510:        f = mailhdr(&header, "Our news version");
        !           511:        if (f == NULL)
        !           512:                xerror("Cannot send back error message");
        !           513:        fprintf(f, "Currently running news version %s.\n\n", news_version);
        !           514:        fprintf(f, "The header of your message follows:\n\n");
        !           515:        (void) hwrite(&header, f);
        !           516:        (void) mclose(f);
        !           517: }
        !           518: 
        !           519: /*
        !           520:  * Check the active file for old or missing newsgroups
        !           521:  * Body of article is list of valid groups
        !           522:  */
        !           523: /* ARGSUSED */
        !           524: c_checkgroups(argc, argv)
        !           525: char **argv;
        !           526: {
        !           527:        int rc;
        !           528: 
        !           529:        (void) setuid(geteuid());
        !           530:        /* dont change the cat %s| to < %s, it breaks some "unix" systems */
        !           531:        (void) sprintf(bfr, "cat %s | %s/checkgroups %s", INFILE, LIB,
        !           532: #ifdef NOTIFY
        !           533:                (TELLME && *TELLME) ? TELLME : NEWSUSR );
        !           534: #else /* !NOTIFY */
        !           535:                NEWSUSR);
        !           536: #endif /* !NOTIFY */
        !           537:        rc = system(bfr);
        !           538:        log("system(%s) status %d", bfr, rc);
        !           539: }
        !           540: 
        !           541: /*
        !           542:  * An unknown control message has been received.
        !           543:  */
        !           544: c_unknown(h, ctlmsgtext)
        !           545: struct hbuf *h;
        !           546: char *ctlmsgtext;
        !           547: {
        !           548:        register FILE *f;
        !           549: 
        !           550:        log("UNKNOWN Ctl Msg %s from %s", ctlmsgtext, h->path);
        !           551: #ifdef NOTIFY
        !           552:        f = mailhdr((struct hbuf *)NULL, "Unrecognized Control Message");
        !           553:        if (f != NULL) {
        !           554:                fprintf(f, "Currently running news version %s.\n\n", news_version);
        !           555:                fprintf(f, "The header of the message follows:\n\n");
        !           556:                (void) hwrite(h, f);
        !           557:                (void) mclose(f);
        !           558:        }
        !           559: #endif /* NOTIFY */
        !           560: }
        !           561: 
        !           562: /* ARGSUSED */
        !           563: c_unimp(argc, argv)
        !           564: char **argv;
        !           565: {
        !           566:        register FILE *f;
        !           567: 
        !           568: #ifdef NOTIFY
        !           569:        f = mailhdr((struct hbuf*)NULL, "Unimplemented Control Message");
        !           570:        if (f != NULL) {
        !           571:                fprintf(f, "Currently running news version B %s.\n\n", news_version);
        !           572:                fprintf(f, "The header of the message follows:\n\n");
        !           573:                (void) hwrite(&header, f);
        !           574:                (void) mclose(f);
        !           575:        }
        !           576: #endif /* NOTIFY */
        !           577: }
        !           578: 
        !           579: xmitmsg(tosys, title, ng)
        !           580: char *tosys, *title, *ng;
        !           581: {
        !           582: #ifndef u370
        !           583:        struct hbuf htmp;
        !           584: #endif /* !u370 */
        !           585:        struct srec srec;
        !           586:        FILE *tfp;
        !           587:        char *fname;
        !           588: 
        !           589:        /* Make an article called ARTICLE */
        !           590:        (void) sprintf(htmp.from, "%s@%s%s", "usenet", FULLSYSNAME, MYDOMAIN);
        !           591:        (void) strcpy(htmp.path, NEWSUSR);
        !           592:        (void) strcpy(htmp.nbuf, ng);
        !           593:        (void) strcpy(htmp.title, title);
        !           594:        (void) strcpy(htmp.ctlmsg, title);
        !           595:        (void) strcpy(htmp.subdate, "");
        !           596:        (void) strcpy(htmp.expdate, "");
        !           597:        getident(&htmp);
        !           598:        dates(&htmp);
        !           599:        tfp = xfopen(fname = mktemp("/tmp/xmsgXXXXXX"), "w");
        !           600:        hwrite(&htmp, tfp);
        !           601:        (void) fclose(tfp);
        !           602: 
        !           603:        /* Find the sys record */
        !           604:        s_openr();
        !           605:        while (s_read(&srec)) {
        !           606:                if (strncmp(srec.s_name, tosys, SNLN))
        !           607:                        continue;
        !           608:                tfp = xfopen(fname, "r");
        !           609:                (void) transmit(&srec, tfp, 0, (char **)0, 0);
        !           610:                (void) unlink(fname);
        !           611:                return;
        !           612:        }
        !           613:        log("Can't find sys record for %s", tosys);
        !           614:        xerror("Cannot find sys record");
        !           615: }
        !           616: 
        !           617: /*
        !           618:  * This is a modified version of popen, made more secure.  Rather than
        !           619:  * forking off a shell, you get a bare process.  You must have exactly
        !           620:  * one argument, and the command must be mail (or sendmail if you have it).
        !           621:  */
        !           622: #define        RDR     0
        !           623: #define        WTR     1
        !           624: static int     mopen_pid[20];
        !           625: char *replyname();
        !           626: 
        !           627: FILE *
        !           628: mhopen(hptr)
        !           629: struct hbuf *hptr;
        !           630: {
        !           631:        int p[2];
        !           632:        register myside, hisside, pid;
        !           633:        char *sendto = "usenet";
        !           634: 
        !           635:        if (hptr)
        !           636:                sendto = replyname(hptr);
        !           637:        else {
        !           638: #ifdef NOTIFY
        !           639:                if (TELLME && *TELLME)
        !           640:                        sendto = TELLME;
        !           641: #endif /* NOTIFY */
        !           642:                if (sendto == NULL)
        !           643:                        return NULL;
        !           644:        }
        !           645:        verifyname(sendto);
        !           646:        if(pipe(p) < 0)
        !           647:                return NULL;
        !           648:        myside = p[WTR];
        !           649:        hisside = p[RDR];
        !           650:        if((pid = fork()) == 0) {
        !           651:                /* myside and hisside reverse roles in child */
        !           652:                (void) close(myside);
        !           653:                (void) close(0);
        !           654:                (void) dup(hisside);
        !           655:                (void) close(hisside);
        !           656:                (void) setgid(gid);
        !           657:                (void) setuid(uid);
        !           658: #ifdef SENDMAIL
        !           659:                execl(SENDMAIL, "sendmail", "-oi", "-oeq", sendto, (char *)NULL);
        !           660: #endif /* SENDMAIL */
        !           661: #ifdef MMDF
        !           662:                execl(MMDF, "inews-mail", "-smuxto,cc*", (char *)NULL);
        !           663: #endif /* MMDF */
        !           664:                execl("/bin/mail", "mail", sendto, (char *)NULL);
        !           665:                execl("/usr/bin/mail", "mail", sendto, (char *)NULL);
        !           666:                execl("/usr/ucb/mail", "mail", sendto, (char *)NULL);
        !           667:                _exit(1);
        !           668:        }
        !           669:        if(pid == -1)
        !           670:                return NULL;
        !           671:        mopen_pid[myside] = pid;
        !           672:        (void) close(hisside);
        !           673:        return(fdopen(myside, "w"));
        !           674: }
        !           675: 
        !           676: mclose(ptr)
        !           677: FILE *ptr;
        !           678: {
        !           679:        register f, r, (*hstat)(), (*istat)(), (*qstat)();
        !           680:        int status;
        !           681: 
        !           682:        f = fileno(ptr);
        !           683:        (void) fclose(ptr);
        !           684:        istat = signal(SIGINT, SIG_IGN);
        !           685:        qstat = signal(SIGQUIT, SIG_IGN);
        !           686:        hstat = signal(SIGHUP, SIG_IGN);
        !           687:        while((r = wait(&status)) != mopen_pid[f] && r != -1)
        !           688:                ;
        !           689:        if(r == -1)
        !           690:                status = -1;
        !           691:        signal(SIGINT, istat);
        !           692:        signal(SIGQUIT, qstat);
        !           693:        signal(SIGHUP, hstat);
        !           694:        return status;
        !           695: }
        !           696: 
        !           697: /*
        !           698:  * mhopen a pipe to mail, write out a std header, and return the file ptr.
        !           699:  *
        !           700:  * We don't include a From: field because this is probably uucp, i.e.
        !           701:  * explicitly routed.  Leave it up to the recipient's mailer.
        !           702:  * Always include the To: field because if we ge back failed mail, we
        !           703:  * might be able to deliver it by hand if we know to wom it was addressed.
        !           704:  * By convention, hptr==NULL means to send the message to the local contact person.
        !           705:  */
        !           706: FILE *
        !           707: mailhdr(hptr, subject)
        !           708: struct hbuf *hptr;
        !           709: char  *subject;
        !           710: {
        !           711:        FILE *fp;
        !           712:        time_t now;
        !           713:        char *to = "usenet";
        !           714: 
        !           715: #ifdef NOTIFY
        !           716:        if (TELLME && *TELLME)
        !           717:                to = TELLME;
        !           718: #endif /* NOTIFY */
        !           719:        if (hptr)
        !           720:                to = replyname(hptr);
        !           721: 
        !           722:        if ((fp = mhopen(hptr)) != NULL) {
        !           723:                (void) time(&now);
        !           724:                fprintf(fp, "Date: %s\n", arpadate(&now));
        !           725: #ifdef MMDF
        !           726:                fprintf(fp, "From: The News System <usenet@%s%s>\n",
        !           727:                                FULLSYSNAME, MYDOMAIN);
        !           728: #endif /* MMDF */
        !           729:                fprintf(fp, "To: %s\n", to);
        !           730:                fprintf(fp, "Subject: %s\n", subject);
        !           731: #ifdef HIDDENNET
        !           732:                if (strcmp(LOCALSYSNAME, FULLSYSNAME))
        !           733:                        fprintf(fp, "Responding-System: %s.%s%s\n\n",
        !           734:                                LOCALSYSNAME, FULLSYSNAME, MYDOMAIN);
        !           735: #endif /* !HIDDENNET */
        !           736:                        fprintf(fp, "Responding-System: %s%s\n\n",
        !           737:                                FULLSYSNAME, MYDOMAIN);
        !           738:        }
        !           739:        return fp;
        !           740: }
        !           741: 
        !           742: /*
        !           743:  * verify that the name mail is being sent to does not contain any
        !           744:  * nasty hooks to invoke funny functions from the shell or the like.
        !           745:  */
        !           746: verifyname(sendto)
        !           747: char *sendto;
        !           748: {
        !           749:        /* Be sure we DO allow alphabetics, !, :, ., -, @. *. */
        !           750:        char *nasty = "\"'\\`^|;& <>/~";
        !           751:        register char *p;
        !           752: 
        !           753:        if (sendto[0] <= ' ') {
        !           754:                log("nasty mail name %s from %s", sendto, header.path);
        !           755:                xxit(1);
        !           756:        }
        !           757:        for (p=sendto; *p; p++) {
        !           758:                if (*p == ' ') {
        !           759:                        *p = 0;
        !           760:                        break;
        !           761:                }
        !           762:        }
        !           763:        if (strpbrk(sendto, nasty) != NULL)
        !           764:                xerror("nasty mail name %s from %s", sendto, header.path);
        !           765: 
        !           766:        for (nasty = sendto; (nasty = index(nasty, '.')) != NULL; ) {
        !           767:                if (*++nasty == '.')    /* check for .. */
        !           768:                        xerror("nasty mail name %s from %s", sendto, header.path);
        !           769:        }
        !           770: }
        !           771: 
        !           772: /*
        !           773:  * Checks to make sure the control message is OK to post.
        !           774:  */
        !           775: ctlcheck()
        !           776: {
        !           777:        char msg[BUFLEN];
        !           778:        char *p;
        !           779: 
        !           780:        if (!is_ctl)
        !           781:                return;
        !           782: 
        !           783:        if (header.ctlmsg[0])
        !           784:                (void) strcpy(msg, header.ctlmsg);
        !           785:        else
        !           786:                (void) strcpy(msg, header.title);
        !           787: 
        !           788:        p = index(msg, ' ');
        !           789:        if (p)
        !           790:                *p = 0;
        !           791:        
        !           792:        if (strcmp(msg, "ihave") == 0) {
        !           793:        } else if (strcmp(msg, "sendme") == 0) {
        !           794:                return; /* no restrictions */
        !           795:        } else if (strcmp(msg, "newgroup") == 0) {
        !           796:                suser();
        !           797:        } else if (strcmp(msg, "rmgroup") == 0) {
        !           798:                suser();
        !           799:        } else if (strcmp(msg, "sendsys") == 0) {
        !           800:                suser();
        !           801:        } else if (strcmp(msg, "senduuname") == 0) {
        !           802:                suser();
        !           803:        } else if (strcmp(msg, "checkgroups") == 0) {
        !           804:                suser();
        !           805:        } else if (strcmp(msg, "version") == 0) {
        !           806:                return; /* no restrictions */
        !           807:        } else if (strcmp(msg, "cancel") == 0) {
        !           808:                return; /* no restrictions at this level */
        !           809:        } else if (strcmp(msg, "delsub") == 0) {
        !           810:                if (!prefix(header.nbuf, "to.")) {
        !           811:                        printf("Must be in a 'to.system' newsgroup.");
        !           812:                        xxit(0);
        !           813:                }
        !           814:                return;
        !           815:        } else {
        !           816:                printf("Unrecognized control message - %s\n", msg);
        !           817:                xxit(0);
        !           818:        }
        !           819: }
        !           820: 
        !           821: /* Make sure this guy is special. */
        !           822: suser()
        !           823: {
        !           824:        if (uid == 0 || uid == ROOTID)
        !           825:                return;
        !           826:        /*
        !           827:         * We assume that since our real uid is the same as NEWSUSR
        !           828:         * (the euid) we were run by rootid and it did a setuid.
        !           829:         * Too bad we can't set just the effective uid like suid does.
        !           830:         */
        !           831:        if (uid == geteuid())
        !           832:                return;
        !           833: #ifdef IHCC
        !           834:        printf("Please use the command:\n\ttoolnews providers\n");
        !           835:        printf("then call one of the news people.\n");
        !           836: #else
        !           837:        printf("Get your local netnews contact to do it for you.\n");
        !           838: #endif
        !           839:        xxit(0);
        !           840: }

unix.superglobalmegacorp.com

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