Annotation of 43BSDTahoe/new/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.55    10/7/87";
        !            23: #endif /* SCCSID */
        !            24: 
        !            25: #include "iparams.h"
        !            26: 
        !            27: #define eq(msg) (msg[0] == cargv[0][0] && strcmp(msg, cargv[0]) == 0)
        !            28: 
        !            29: int cargc;
        !            30: char **cargv;
        !            31: 
        !            32: FILE *hfopen();
        !            33: FILE *popen(), *mhopen(), *mailhdr();
        !            34: 
        !            35: #define NCARGS 30
        !            36: char *senderof();
        !            37: #ifdef u370
        !            38: static struct hbuf htmp;
        !            39: #endif /* u370 */
        !            40: 
        !            41: /*
        !            42:  * The global structure is initialized to NOTIFY as the default (if defined)
        !            43:  * uid to send mail to for every state.  The following conditions are
        !            44:  * dealt with (assumes NOTIFY defined):
        !            45:  *
        !            46:  * 1) LIB/notify exists and is empty (or contains no recognizable control
        !            47:  *    message types).
        !            48:  *     Action: force TELLME = "";
        !            49:  * 2) LIB/notify contains the control message name "all" and no associated
        !            50:  *    address.
        !            51:  *     Action: force TELLME = "";
        !            52:  * 3) LIB/notify contains the control message name "all" and has an address.
        !            53:  *     Action: set TELLME = AlloCpy(address);
        !            54:  * 4) LIB/notify contains only some of the known control message types.
        !            55:  *     Action: initialize all addresses to "" and set declared addresses
        !            56:  *             to listed address.
        !            57:  */
        !            58: 
        !            59: 
        !            60: control(h)
        !            61: struct hbuf *h;
        !            62: {
        !            63:        register char *ctlmsgtext;
        !            64:        register struct msgtype *mp;
        !            65: 
        !            66:        if (strncmp(h->title, "cmsg ", 5) == 0) {
        !            67:                register char *cp1, *cp2;
        !            68:                cp1 = h->title;
        !            69:                cp2 = h->title + 5;
        !            70:                while (*cp1++ = *cp2++)
        !            71:                        ;
        !            72:        }
        !            73: 
        !            74:        if (*h->ctlmsg)
        !            75:                ctlmsgtext = h->ctlmsg;
        !            76:        else
        !            77:                ctlmsgtext = h->title;
        !            78:        log("Ctl Msg %s from %s: %s", h->nbuf, h->path, ctlmsgtext);
        !            79:        /*
        !            80:         * Control messages have the standard format
        !            81:         *      command [args]
        !            82:         * much like shell commands.  Each site has the option
        !            83:         * of customizing this code to deal with control messages
        !            84:         * as they see fit, but we would like to buy back the
        !            85:         * code, ifdeffed or otherwise parameterized, to simplify
        !            86:         * the maintenence issues.
        !            87:         */
        !            88:        argparse(ctlmsgtext);
        !            89:        
        !            90:        /*
        !            91:         * We look for a match of the control message name and then
        !            92:         * set TELLME to the value parsed from the LIB/notify file
        !            93:         * (if any).
        !            94:         */
        !            95:        for(mp=msgtype; mp->m_name; mp++) {
        !            96:                if(eq(mp->m_name) ) {           /* hit */
        !            97: #ifdef NOTIFY
        !            98:                        TELLME = mp->m_who_to;  /* reset whom to tell */
        !            99: #endif /* NOTIFY */
        !           100:                        return (*mp->m_func)(cargc, cargv); /* do it */
        !           101:                }
        !           102:        }
        !           103:        if( !mp->m_name ) {
        !           104: #ifdef NOTIFY
        !           105:                TELLME = NOTIFY;
        !           106: #endif /* NOTIFY */
        !           107:                c_unknown(h, ctlmsgtext);
        !           108:        }
        !           109:        return 0;
        !           110: }
        !           111: 
        !           112: /*
        !           113:  * Parse the string str into separate words in cargc and cargv
        !           114:  * as per the usual UNIX convention.  Nothing fancy here, just
        !           115:  * blanks and tabs separating words.
        !           116:  */
        !           117: argparse(str)
        !           118: char *str;
        !           119: {
        !           120:        static char *cavpbuf[NCARGS];
        !           121:        static char cavbuf[256];
        !           122:        char *nextfree = cavbuf;
        !           123: 
        !           124:        if (str == '\0')
        !           125:                error("Control message %s has no title", header.ident);
        !           126:        cargc = (*str != '\0');
        !           127:        cargv = cavpbuf;
        !           128:        cargv[0] = cavbuf;
        !           129: 
        !           130:        while (*str) {
        !           131:                if (*str <= ' ') {
        !           132:                        /* skip over white space */
        !           133:                        while (*str != '\0' && *str <= ' ')
        !           134:                                str++;
        !           135:                        if (*str == '\0')       /* line ends in white space */
        !           136:                                return;
        !           137:                        *nextfree++ = 0;
        !           138:                        cargv[cargc] = nextfree;
        !           139:                        if (cargc++ >= NCARGS)
        !           140:                                xerror("Too many arguments to control message %s",
        !           141:                                                header.ident);
        !           142:                } else
        !           143:                        *nextfree++ = *str++;
        !           144:        }
        !           145: }
        !           146: 
        !           147: /*
        !           148:  * ihave <artid> ... <remotesys>
        !           149:  *     or
        !           150:  * ihave <remotesys>
        !           151:  *     with <artid>s in message body.
        !           152:  *
        !           153:  * The other system is telling you it has article <artid>, in case
        !           154:  * you decide you want it to transmit it to you.
        !           155:  * The assumption is that the other system only tells you about articles
        !           156:  * in newsgroups you subscribe to.
        !           157:  *
        !           158:  * We turn the incoming ihave into an outgoing sendme on the fly.
        !           159:  * It then gets saved in the SPOOL directory and transmitted to the
        !           160:  * remote system.  (This way the sendme messages can be batched.)
        !           161:  */
        !           162: c_ihave(argc, argv)
        !           163: register char **       argv;
        !           164: {
        !           165:        register int    i;
        !           166:        char            list[sizeof header.title];
        !           167:        extern char *   findhist();
        !           168:        extern char *   mydomain();
        !           169: 
        !           170:        if (argc < 2)
        !           171:                error("ihave: Too few arguments.");
        !           172:        if (strncmp(PATHSYSNAME, argv[argc - 1], SNLN) == 0)
        !           173:                return 0;
        !           174:        list[0] = '\0';
        !           175:        if (argc > 2) {
        !           176:                for (i = 1; i < (argc - 1); ++i)
        !           177:                        if (findhist(argv[i]) == NULL) {
        !           178:                                (void) strcat(list, " ");
        !           179:                                (void) strcat(list, argv[i]);
        !           180:                        }
        !           181:                if (list[0] == '\0')
        !           182:                        return 0;
        !           183:        } else {
        !           184:                register FILE * outfp;
        !           185:                register long   outpos, inpos;
        !           186:                char            myid[256];
        !           187: 
        !           188:                outfp = xfopen(INFILE, "a");
        !           189:                outpos = ftell(outfp);
        !           190:                inpos = ftell(infp);
        !           191:                while (ftell(infp) < outpos) {
        !           192:                        if (fgets(myid, sizeof myid, infp) != myid)
        !           193:                                error("iline: Can't reread article");
        !           194:                        myid[strlen(myid) - 1] = '\0';
        !           195:                        if (findhist(myid) == NULL)
        !           196:                                (void) fprintf(outfp, "%s\n", myid);
        !           197:                }
        !           198:                if (outpos == ftell(outfp)) {   /* if nothing is wanted */
        !           199:                        (void) fclose(outfp);
        !           200:                        (void) fseek(infp, inpos, 0);
        !           201:                        return 0;
        !           202:                }
        !           203:                (void) fclose(outfp);
        !           204:                /*
        !           205:                ** The close and open may just be paranoia.
        !           206:                */
        !           207:                (void) fclose(infp);
        !           208:                infp = xfopen(INFILE, "r");
        !           209:                (void) fseek(infp, outpos, 0);
        !           210:        }
        !           211:        /*
        !           212:        ** Turn the ihave into a sendme.
        !           213:        */
        !           214:        (void) sprintf(header.nbuf, "to.%s.ctl", argv[argc - 1]);
        !           215:        (void) sprintf(header.title, "sendme%s %s", list, PATHSYSNAME);
        !           216:        (void) strcpy(header.ctlmsg, header.title);
        !           217:        getident(&header);
        !           218:        (void) sprintf(header.from, "%s@%s", "usenet", FROMSYSNAME);
        !           219:        (void) strcpy(header.path, NEWSUSR);
        !           220:        header.subdate[0] = header.expdate[0] = '\0';
        !           221:        dates(&header);
        !           222:        /*
        !           223:        ** What else of this kind should be done?
        !           224:        */
        !           225:        header.organization[0] = header.distribution[0] = '\0';
        !           226:        header.numlines[0] = '\0';
        !           227:        for (i = 0; i < NUNREC && header.unrec[i] != NULL; ++i) {
        !           228:                free(header.unrec[i]);
        !           229:                header.unrec[i] = NULL;
        !           230:        }
        !           231:        /*
        !           232:        ** Note that we do *not* change the history line
        !           233:        ** so that if the "ihave" message comes in again it gets rejected.
        !           234:        */
        !           235:        return 0;
        !           236: }
        !           237: 
        !           238: /*
        !           239:  * sendme <artid> ... <remotesys>
        !           240:  *     or
        !           241:  * sendme <remotesys>
        !           242:  *     with <artid>s in message body.
        !           243:  * The other system wants me to send out article <artid>.
        !           244:  * Give it to them with no fuss.
        !           245:  */
        !           246: #ifdef MULTICAST
        !           247: static int     c_mc;
        !           248: static char ** c_sysnames;
        !           249: #endif /* MULTICAST */
        !           250: c_sendme(argc, argv)
        !           251: register char **argv;
        !           252: {
        !           253:        struct srec     srec;
        !           254: 
        !           255:        if (argc < 2)
        !           256:                error("sendme: Too few arguments.");
        !           257:        if (strncmp(PATHSYSNAME, argv[argc - 1], SNLN) == 0)
        !           258:                return 0;
        !           259:        if (s_find(&srec, argv[argc - 1]) != TRUE)
        !           260:                error("sendme: Can't find sys record for %s", argv[argc - 1]);
        !           261: #ifdef MULTICAST
        !           262:        c_mc = index(srec.s_flags, 'M') != 0;
        !           263:        if (c_mc) {
        !           264:                struct srec     trec;
        !           265: 
        !           266:                c_sysnames = &argv[argc - 1];
        !           267:                if (s_find(&trec, srec.s_xmit) != TRUE)
        !           268:                        error("sendme: Can't find sys record for %s for %s",
        !           269:                                srec.s_xmit, argv[argc - 1]);
        !           270:                srec = trec;
        !           271:        } else  c_sysnames = NULL;
        !           272: #endif /* MULTICAST */
        !           273:        /* Send the articles. */
        !           274:        if (argc == 2) {
        !           275:                register FILE * fp;
        !           276:                char            buf[256];
        !           277: 
        !           278:                fp = xfopen(INFILE, "r");
        !           279:                while (fgets(buf, sizeof buf, fp) == buf) {
        !           280:                        buf[strlen(buf) - 1] = '\0';    /* zap trailing '\n' */
        !           281:                        sendmefunc(buf, &srec);
        !           282:                }
        !           283:                (void) fclose(fp);
        !           284:        } else {        /* argc > 2 */
        !           285:                register int    i;
        !           286: 
        !           287:                for (i = 1; i < (argc - 1); ++i)
        !           288:                        sendmefunc(argv[i], &srec);
        !           289:        }
        !           290:        return 0;
        !           291: }
        !           292: 
        !           293: static
        !           294: sendmefunc(id, sp)
        !           295: register char *                id;
        !           296: register struct srec * sp;
        !           297: {
        !           298:        register FILE * fp;
        !           299:        register char * cp;
        !           300:        char            savedbufname[256];
        !           301:        extern char     firstbufname[];
        !           302:        extern char *   dirname();
        !           303:        extern char *   findfname();
        !           304: 
        !           305:        cp = findfname(id);
        !           306:        if (cp == NULL) {
        !           307:                log("System %s wants unavailable article %s.",
        !           308: #ifdef MULTICAST
        !           309:                        (c_mc ? c_sysnames[0] : sp->s_name), id);
        !           310: #else /* !MULTICAST */
        !           311:                        sp->s_name, id);
        !           312: #endif /* !MULTICAST */
        !           313:                return;
        !           314:        }
        !           315:        cp = dirname(cp);
        !           316:        fp = fopen(cp, "r");
        !           317:        if (fp == NULL) {
        !           318:                logerr("Article %s unopenable as %s.", id, cp);
        !           319:                return;
        !           320:        }
        !           321:        (void) strcpy(savedbufname, firstbufname);
        !           322:        (void) strcpy(firstbufname, cp);
        !           323: #ifdef MULTICAST
        !           324:        transmit(sp, fp, FALSE, c_sysnames, c_mc);
        !           325: #else /* !MULTICAST */
        !           326:        transmit(sp, fp, FALSE, (char **) NULL, 0);
        !           327: #endif /* !MULTICAST */
        !           328:        /* transmit closes fp */
        !           329:        (void) strcpy(firstbufname, savedbufname);
        !           330: }
        !           331: 
        !           332: /*
        !           333:  * newgroup <groupname>
        !           334:  * A new newsgroup has been created.
        !           335:  * The body of the article, if present, is a description of the
        !           336:  * purpose of the newsgroup.
        !           337:  *
        !           338:  */
        !           339: c_newgroup(argc, argv)
        !           340: char **argv;
        !           341: {
        !           342:        FILE *fd;
        !           343:        char abuf[BUFLEN], subjline[BUFLEN];
        !           344:        int didcreate = 0;
        !           345:        register char *p, *q;
        !           346: # ifdef NONEWGROUPS
        !           347: #  ifdef ORGDISTRIB
        !           348:        /* local or ORGDISTRIB */
        !           349:        int can_change = (strcmp(header.distribution, "local") == 0) ||
        !           350:                                (strcmp(header.distribution, ORGDISTRIB) == 0);
        !           351: #  else /* ! ORGDISTRIB */
        !           352:        /* local only */
        !           353:        int can_change = strcmp(header.distribution, "local") == 0;
        !           354: #  endif /* ORGDISTRIB */
        !           355: # else /* ! NONEWGROUPS */
        !           356:        int can_change = 1;     /* allow changes for all distributions */
        !           357: # endif /* NONEWGROUPS */
        !           358: 
        !           359:        if (argc < 2)
        !           360:                error("newgroup: Too few arguments.");
        !           361: 
        !           362:        if (header.approved[0] == '\0') {
        !           363:                logerr("newgroup: %s not approved", argv[1]);
        !           364:                return 1;
        !           365:        }
        !           366: 
        !           367:        lock();
        !           368:        /* see if it already exists */
        !           369:        (void) rewind(actfp); clearerr(actfp);
        !           370:        while(fgets(abuf, BUFLEN, actfp) != NULL) {
        !           371:                p = abuf;
        !           372:                q = argv[1];
        !           373:                while (*p++ == *q++)
        !           374:                        ;
        !           375:                if (*--q == '\0' && *--p == ' ') {
        !           376:                        /* Now check if it's correctly moderated/unmoderated */
        !           377:                        while (*p++)
        !           378:                                ;
        !           379:                        p -= 3;
        !           380:                        if (argc > 2 && strcmp(argv[2], "moderated") == 0) {
        !           381:                                if (*p == 'm') {
        !           382:                                        unlock();
        !           383:                                        return 0;
        !           384:                                }
        !           385:                                *p = 'm';
        !           386:                        } else {
        !           387:                                if (*p != 'm') {
        !           388:                                        unlock();
        !           389:                                        return 0;
        !           390:                                }
        !           391:                                *p = 'y';
        !           392:                        }
        !           393: # ifdef NOTIFY
        !           394:                        (void) sprintf(subjline,
        !           395:                        "Newsgroup %s changed from %smoderated to %smoderated",
        !           396:                                argv[1], *p=='y' ? "" : "un",
        !           397:                                *p=='y' ? "un" : "");
        !           398:                        fd = mailhdr((struct hbuf *)NULL, subjline);
        !           399:                        if (fd != NULL) {
        !           400:                                if(can_change)
        !           401:                                        fprintf(fd,
        !           402: "%s has been changed from %smoderated to %smoderated as requested by\n%s\n",
        !           403:                                                argv[1], *p=='y' ? "" : "un", 
        !           404:                                                *p=='y' ? "un":"", header.path);
        !           405:                                else {
        !           406:                                        fprintf(fd,
        !           407: "%s\nhas requested that %s be changed from %smoderated to %smoderated\n",
        !           408:                                                header.path, argv[1], 
        !           409:                                                *p=='y' ? "" : "un",
        !           410:                                                *p=='y' ? "un" : "");
        !           411: #ifdef ORGDISTRIB
        !           412:                                        fprintf(fd,
        !           413: "You can accomplish this by re-creating the newsgroup with a distribution\n");
        !           414:                                        fprintf(fd,
        !           415: "of '%s' by executing the command:\n", ORGDISTRIB);
        !           416:                                        fprintf(fd,
        !           417:                                "%s/inews -d %s -C %s%s\n",
        !           418:                                                LIB, ORGDISTRIB, argv[1],
        !           419:                                                *p=='y' ? "" : " moderated");
        !           420: #else /* !ORGDISTRIB */
        !           421:                                        fprintf(fd,
        !           422: "You can accomplish this by re-creating the newsgroup by executing the command:\n");
        !           423:                                        fprintf(fd, "%s/inews -C %s%s\n",
        !           424:                                                LIB, argv[1],
        !           425:                                                *p=='y' ? "" : " moderated");
        !           426: #endif /* !ORGDISTRIB */
        !           427:                                }
        !           428:                                (void) mclose(fd);
        !           429:                        }
        !           430: # endif /* NOTIFY */
        !           431: # ifdef NONEWGROUPS
        !           432:                        /*
        !           433:                         * No permission to change
        !           434:                         */
        !           435:                        if(!can_change) {
        !           436:                                unlock();
        !           437:                                return 0;
        !           438:                        }
        !           439: # endif /* NONEWGROUPS */
        !           440:                        /* The active file was wrong about the state of the
        !           441:                         * group. Rewrite the active file
        !           442:                         */
        !           443:                        (void) fseek(actfp, -2L, 1); /* back up 2 characters */
        !           444:                        putc(*p, actfp);
        !           445:                        fflush(actfp);
        !           446:                        if (*p != 'm')
        !           447:                                logerr("Newsgroup %s changed from moderated to unmoderated",
        !           448:                                argv[1]);
        !           449:                        else
        !           450:                                logerr("Newsgroup %s changed from unmoderated to moderated",
        !           451:                                argv[1]);
        !           452:                        unlock();
        !           453:                        return 0;
        !           454:                }
        !           455:        }
        !           456: 
        !           457:        /* It doesn't already exist, we must create it */
        !           458: 
        !           459:        if(can_change) {
        !           460:                didcreate++;
        !           461:                (void) fseek(actfp, 0L, 2); clearerr(actfp);
        !           462:                fprintf(actfp, "%s 00000 00001 %c\n", argv[1],
        !           463:                        (argc > 2 && strcmp(argv[2], "moderated") == 0) 
        !           464:                                ? 'm' : 'y');
        !           465: #if defined(USG) || defined(MG1)
        !           466:                /*
        !           467:                 * U G L Y   K L U D G E
        !           468:                 * This utter piece of tripe is the only way I know of
        !           469:                 * to get around the fact that ATT BROKE standard IO
        !           470:                 * in System 5.2. Basically, you can't open a file for
        !           471:                 * "r+" and then try and write to it. This hack works
        !           472:                 * on all "real" USG Unix systems, It will probably
        !           473:                 * break on some obscure look alike that doesnt use the
        !           474:                 * real ATT stdio.h
        !           475:                 * also broken in WCW MG-1 42nix 2.0
        !           476:                 * Don't blame me, blame ATT. stdio should have
        !           477:                 * already done the following line for us, but it didn't
        !           478:                 */
        !           479:                actfp->_flag |= _IOWRT;
        !           480: #endif /* USG */
        !           481:                fflush(actfp);
        !           482:        }
        !           483: 
        !           484: # ifdef NOTIFY
        !           485:        (void) sprintf(subjline, "Newsgroup %s created", argv[1]);
        !           486:        fd = mailhdr((struct hbuf *)NULL, subjline);
        !           487:        if (fd != NULL) {
        !           488:                if (didcreate) 
        !           489:                        fprintf(fd, 
        !           490:                "A new %snewsgroup called '%s' has been created by %s.\n",
        !           491:                                argc > 2 ? "moderated " : "", argv[1],
        !           492:                                header.path);
        !           493:                else {
        !           494:                        fprintf(fd, 
        !           495:                "%s requested that a new %snewsgroup called '%s' be created.\n",
        !           496:                        header.path, argc > 2 ? "moderated " : "", argv[1]);
        !           497:                        fprintf(fd,"It was approved by %s\n\n",header.approved);
        !           498:                        fprintf(fd, 
        !           499:                "You can accomplish this by creating the newgroup yourself\n");
        !           500: #  ifdef ORGDISTRIB
        !           501:                        fprintf(fd,"with a distribution of '%s'.\n",
        !           502:                                ORGDISTRIB);
        !           503:                        fprintf(fd,
        !           504:                                "In other words, by executing the command:\n");
        !           505:                        fprintf(fd, "%s/inews -d %s -C %s %s\n", LIB, 
        !           506:                                ORGDISTRIB, argv[1], argc > 2 ? argv[2] : "");
        !           507: #  else /* !ORGDISTRIB */
        !           508:                        fprintf(fd, "In other words, by executing the command:\n");
        !           509:                        fprintf(fd, "%s/inews -C %s %s\n", LIB, argv[1],
        !           510:                                argc > 2 ? argv[2] : "");
        !           511: #  endif /* !ORGDISTRIB */
        !           512:                }
        !           513:                (void) mclose(fd);
        !           514:        }
        !           515: # endif /* NOTIFY */
        !           516:        unlock();
        !           517:        return 0;
        !           518: }
        !           519: 
        !           520: /*
        !           521:  * rmgroup <groupname>
        !           522:  * An old newsgroup is being cancelled on a network wide basis.
        !           523:  */
        !           524: c_rmgroup(argc, argv)
        !           525: char **argv;
        !           526: {
        !           527:        FILE *fd;
        !           528:        int shouldremove = 0;
        !           529: #ifdef NOTIFY
        !           530:        char subjline[BUFLEN];
        !           531: #endif /* NOTIFY */
        !           532: 
        !           533:        if (argc < 2)
        !           534:                error("rmgroup: Too few arguments.");
        !           535:        if (!validng(argv[1]))
        !           536:                return 0;
        !           537:        if (header.approved[0] == '\0') {
        !           538:                logerr("rmgroup: %s not approved", argv[1]);
        !           539:                return 1;
        !           540:        }
        !           541: 
        !           542: #ifdef MANUALLY
        !           543: #ifdef ORGDISTRIB
        !           544:        /*
        !           545:         * Allow local as well as organizational removals
        !           546:         */
        !           547:        if (!strcmp(ORGDISTRIB, header.distribution)
        !           548:           || !strcmp("local", header.distribution))
        !           549: #else  /* !ORGDISTRIB */               
        !           550:        if (!strcmp("local", header.distribution))
        !           551: #endif /* !ORGDISTRIB */               
        !           552: #endif /* MANUALLY */
        !           553:                shouldremove++;
        !           554: #ifdef NOTIFY
        !           555:        sprintf(subjline, "Received rmgroup for %s", argv[1]);
        !           556:        fd = mailhdr((struct hbuf *)NULL, subjline);
        !           557:        if (fd != NULL) {
        !           558:                if (shouldremove) {
        !           559:                    fprintf(fd, "Newsgroup '%s' has been removed by %s.\n\n",
        !           560:                                argv[1], header.path);
        !           561: #  ifdef USG
        !           562:                    fprintf(fd, "You may need to remove the directory %s by hand\n",
        !           563:                                dirname(argv[1]));
        !           564: #  endif
        !           565:                } else {
        !           566:                    fprintf(fd, "%s requested that newsgroup %s be removed.\n",
        !           567:                                header.path, argv[1]);
        !           568:                    fprintf(fd, "You should remove it by hand\n");
        !           569:                    fprintf(fd, "To do this, execute the command\n");
        !           570:                    fprintf(fd, "\t%s/rmgroup %s\n", LIB, argv[1]);
        !           571:                }
        !           572:                (void) mclose(fd);
        !           573:        }
        !           574: #endif /* NOTIFY */
        !           575: 
        !           576:        if (shouldremove) {
        !           577:                int pid, status;
        !           578:                /* We let the shell do all the work.
        !           579:                 * See the rmgrp shell script.
        !           580:                 */
        !           581:                lock();
        !           582:                (void) sprintf(bfr, "%s/rmgroup", LIB);
        !           583: 
        !           584:                if (pid = fork()) {
        !           585:                        status = fwait(pid);
        !           586:                } else {
        !           587:                        register int i;
        !           588:                        for (i =3; i<20; i++)
        !           589:                                if (close(i) < 0)
        !           590:                                        break;
        !           591:                        (void) setuid(duid);
        !           592:                        execvp(bfr, argv);
        !           593:                }
        !           594:                unlock();
        !           595:                if (status)
        !           596:                        log("rmgroup status %d", status);
        !           597:        }
        !           598:        return 0;
        !           599: }
        !           600: 
        !           601: /*
        !           602:  * cancel <artid>
        !           603:  * Cancel the named article
        !           604:  */
        !           605: c_cancel(argc, argv)
        !           606: char **argv;
        !           607: {
        !           608:        char *line, *p, *q, *r, *poster;
        !           609:        char *findhist();
        !           610:        register FILE *fp;
        !           611:        char whatsisname[BUFLEN], nfilename[BUFLEN];
        !           612:        time_t t;
        !           613:        int su = 0;
        !           614: #ifndef u370
        !           615:        struct hbuf htmp;
        !           616: #endif /* !u370 */
        !           617: 
        !           618:        if (argc < 2)
        !           619:                error("cancel: Too few arguments.");
        !           620:        (void) strcpy(whatsisname, senderof(&header));
        !           621:        line = findhist(argv[1]);
        !           622:        if (line == NULL) {
        !           623:                struct tm *tm;
        !           624:                log("Can't cancel %s:  non-existent", argv[1]);
        !           625:                (void) time(&t);
        !           626:                tm = localtime(&t);
        !           627: #ifdef USG
        !           628:                sprintf(bfr,"%s\t%2.2d/%2.2d/%d %2.2d:%2.2d\tcancelled",
        !           629: #else /* !USG */
        !           630:                sprintf(bfr,"%s\t%02d/%02d/%d %02d:%02d\tcancelled",
        !           631: #endif /* !USG */
        !           632:                   argv[1], tm->tm_mon+1, tm->tm_mday, tm->tm_year, tm->tm_hour,
        !           633:                   tm->tm_min);
        !           634:                savehist(bfr);
        !           635:                return -1;
        !           636:        }
        !           637: 
        !           638:        q = index(line, '\t');
        !           639:        p = index(q+1, '\t');
        !           640:        if (p == NULL || *++p == '\0' || *p == '\n') {
        !           641:                *q = '\0';
        !           642:                log("Expired article %s", line);
        !           643:                return -1;
        !           644:        }
        !           645:        if (strcmp(p, "cancelled") == 0) {
        !           646:                *q = '\0';
        !           647:                log("Already Cancelled %s", line);
        !           648:                return -1;
        !           649:        } else
        !           650:                log("Cancelling %s", line);
        !           651:        if ((uid == ROOTID||uid == 0) && (
        !           652: #ifdef ORGDISTRIB
        !           653:                strcmp(header.distribution, ORGDISTRIB) == 0 ||
        !           654: #endif /* ORGDISTRIB */
        !           655:                strcmp(header.distribution, "local") == 0))
        !           656:                su = 1;
        !           657:        while (*p) {
        !           658:                q = index(p, ' ');
        !           659:                if (q)
        !           660:                        *q = '\0';
        !           661:                (void) strcpy(nfilename, dirname(p));
        !           662:                fp = fopen(nfilename, "r");
        !           663:                if (fp == NULL) {
        !           664:                        log("Can't cancel %s: %s", line, errmsg(errno));
        !           665:                        return -1;
        !           666:                }
        !           667:                htmp.unrec[0] = NULL;
        !           668:                if (hread(&htmp, fp, TRUE) == NULL) {
        !           669:                        if (bfr[0] == '/') {
        !           670:                                fp = fopen(bfr, "r");
        !           671:                                if (fp == NULL
        !           672:                                        || hread(&htmp, fp, TRUE) == NULL)
        !           673:                                        error("Article is garbled.");
        !           674:                        } else 
        !           675:                                error("Article is garbled.");
        !           676:                }
        !           677:                (void) fclose(fp);
        !           678:                poster = senderof(&htmp);
        !           679:                /* only compare up to '.' or ' ' */
        !           680:                r = index(poster,'.');
        !           681:                if (r == NULL)
        !           682:                        r = index(poster,' ');
        !           683:                if (r != NULL)
        !           684:                        *r = '\0';
        !           685:                if (!su && strncmp(whatsisname, poster,strlen(poster))) {
        !           686:                        error("Not contributor: posted by %s, and you are %s", poster, whatsisname);
        !           687:                }
        !           688: 
        !           689:                (void) unlink(nfilename);
        !           690:                p = q+1;
        !           691:        }
        !           692:        return 0;
        !           693: }
        !           694: 
        !           695: /*
        !           696:  * sendsys     (no arguments)
        !           697:  *
        !           698:  * Mail the sys file to the person submitting the article.
        !           699:  * POLICY: the contents of your sys file are public information
        !           700:  * and as such, you should not change this code.  You may feel
        !           701:  * free to arrange for it to manually notify you, in the event
        !           702:  * that you want to do something to clean it up before it goes out.
        !           703:  * Secret sites on the net are expressly frowned on.
        !           704:  * 
        !           705:  * The purpose of this command is for making a network map.  The
        !           706:  * details of your link and which newsgroups are forwarded are not
        !           707:  * important, in case you want to sanitize them.  Since the definition
        !           708:  * of USENET is those sites getting net.announce, you can disable this
        !           709:  * on sites not getting net articles, but if you take out the list of
        !           710:  * forwarded newsgroups, and you have sites that only get local newsgroups,
        !           711:  * you should make this clear, or remove those sites from what you send out.
        !           712:  */
        !           713: /* ARGSUSED */
        !           714: c_sendsys(argc, argv)
        !           715: char **argv;
        !           716: {
        !           717:        register FILE *f, *u;
        !           718:        int c;
        !           719: 
        !           720: #ifdef NOTIFY
        !           721:        f = mailhdr((struct hbuf *)NULL, "sendsys control message");
        !           722:        if (f != NULL) {
        !           723:                fprintf(f, "%s requested your %s/sys file.\n", header.path, LIB);
        !           724:                fprintf(f, "It has been sent.\n");
        !           725:                (void) mclose(f);
        !           726:        }
        !           727: #endif /* NOTIFY */
        !           728:        f = mailhdr(&header, "response to your sendsys request");
        !           729:        u = fopen(SUBFILE, "r");
        !           730:        if (f != NULL && u != NULL) {
        !           731:                while ((c=getc(u)) != EOF)
        !           732:                        putc(c, f);
        !           733:                (void) fclose(u);
        !           734:                (void) mclose(f);
        !           735:        }
        !           736:        return 0;
        !           737: }
        !           738: 
        !           739: /*
        !           740:  * Send the version number to the right person.
        !           741:  */
        !           742: /* ARGSUSED */
        !           743: c_version(argc, argv)
        !           744: char **argv;
        !           745: {
        !           746:        register FILE *f;
        !           747: 
        !           748:        f = mailhdr(&header, "Our news version");
        !           749:        if (f == NULL)
        !           750:                error("Cannot send back error message");
        !           751:        fprintf(f, "Currently running news version %s.\n\n", news_version);
        !           752:        fprintf(f, "The header of your message follows:\n\n");
        !           753:        (void) hwrite(&header, f);
        !           754:        (void) mclose(f);
        !           755:        return 0;
        !           756: }
        !           757: 
        !           758: /*
        !           759:  * Check the active file for old or missing newsgroups
        !           760:  * Body of article is list of valid groups
        !           761:  */
        !           762: /* ARGSUSED */
        !           763: c_checkgroups(argc, argv)
        !           764: char **argv;
        !           765: {
        !           766:        int rc;
        !           767: 
        !           768:        (void) setuid(geteuid());
        !           769:        /* dont change the cat %s| to < %s, it breaks some "unix" systems */
        !           770:        (void) sprintf(bfr, "cat %s | %s/checkgroups %s", INFILE, LIB,
        !           771: #ifdef NOTIFY
        !           772:                (TELLME && *TELLME) ? TELLME : NEWSUSR );
        !           773: #else /* !NOTIFY */
        !           774:                NEWSUSR);
        !           775: #endif /* !NOTIFY */
        !           776:        rc = system(bfr);
        !           777:        log("system(%s) status %d", bfr, rc);
        !           778:        return 0;
        !           779: }
        !           780: 
        !           781: /*
        !           782:  * An unknown control message has been received.
        !           783:  */
        !           784: c_unknown(h, ctlmsgtext)
        !           785: struct hbuf *h;
        !           786: char *ctlmsgtext;
        !           787: {
        !           788:        register FILE *f;
        !           789: 
        !           790:        log("UNKNOWN Ctl Msg %s from %s", ctlmsgtext, h->path);
        !           791: #ifdef NOTIFY
        !           792:        f = mailhdr((struct hbuf *)NULL, "Unrecognized Control Message");
        !           793:        if (f != NULL) {
        !           794:                fprintf(f, "Currently running news version %s.\n\n", news_version);
        !           795:                fprintf(f, "The header of the message follows:\n\n");
        !           796:                (void) hwrite(h, f);
        !           797:                (void) mclose(f);
        !           798:        }
        !           799: #endif /* NOTIFY */
        !           800:        return 0;
        !           801: }
        !           802: 
        !           803: /* ARGSUSED */
        !           804: c_unimp(argc, argv)
        !           805: char **argv;
        !           806: {
        !           807:        register FILE *f;
        !           808: 
        !           809: #ifdef NOTIFY
        !           810:        f = mailhdr((struct hbuf*)NULL, "Unimplemented Control Message");
        !           811:        if (f != NULL) {
        !           812:                fprintf(f, "Currently running news version B %s.\n\n", news_version);
        !           813:                fprintf(f, "The header of the message follows:\n\n");
        !           814:                (void) hwrite(&header, f);
        !           815:                (void) mclose(f);
        !           816:        }
        !           817: #endif /* NOTIFY */
        !           818:        return 0;
        !           819: }
        !           820: 
        !           821: /*
        !           822:  * This is a modified version of popen, made more secure.  Rather than
        !           823:  * forking off a shell, you get a bare process.  You must have exactly
        !           824:  * one argument, and the command must be mail (or sendmail if you have it).
        !           825:  */
        !           826: #define        RDR     0
        !           827: #define        WTR     1
        !           828: static int     mopen_pid[20];
        !           829: char *replyname();
        !           830: 
        !           831: FILE *
        !           832: mhopen(hptr)
        !           833: struct hbuf *hptr;
        !           834: {
        !           835:        int p[2];
        !           836:        register myside, hisside, pid;
        !           837:        char *sendto = "usenet";
        !           838: 
        !           839:        if (hptr)
        !           840:                sendto = replyname(hptr);
        !           841:        else {
        !           842: #ifdef NOTIFY
        !           843:                if (TELLME)
        !           844:                        sendto = TELLME;
        !           845: #endif /* NOTIFY */
        !           846:                if (sendto == NULL || *sendto == '\0')
        !           847:                        return NULL;
        !           848:        }
        !           849:        verifyname(sendto);
        !           850:        if(pipe(p) < 0)
        !           851:                return NULL;
        !           852:        myside = p[WTR];
        !           853:        hisside = p[RDR];
        !           854:        if((pid = vfork()) == 0) {
        !           855:                /* myside and hisside reverse roles in child */
        !           856:                (void) close(myside);
        !           857:                (void) close(0);
        !           858:                (void) dup(hisside);
        !           859:                (void) close(hisside);
        !           860:                (void) setgid(gid);
        !           861:                (void) setuid(uid);
        !           862: #ifdef SENDMAIL
        !           863:                execl(SENDMAIL, "sendmail", "-oi", "-oeq", sendto, (char *)NULL);
        !           864: #endif /* SENDMAIL */
        !           865: #ifdef MMDF
        !           866:                execl(MMDF, "inews-mail", "-smuxto,cc*", (char *)NULL);
        !           867: #endif /* MMDF */
        !           868:                execl("/usr/bin/mailx", "mail", sendto, (char *)NULL);
        !           869:                execl("/usr/bin/mail", "mail", sendto, (char *)NULL);
        !           870:                execl("/usr/ucb/mail", "mail", sendto, (char *)NULL);
        !           871:                execl("/bin/mail", "mail", sendto, (char *)NULL);
        !           872:                _exit(1);
        !           873:        }
        !           874:        if(pid == -1)
        !           875:                return NULL;
        !           876:        mopen_pid[myside] = pid;
        !           877:        (void) close(hisside);
        !           878:        return(fdopen(myside, "w"));
        !           879: }
        !           880: 
        !           881: mclose(ptr)
        !           882: FILE *ptr;
        !           883: {
        !           884:        register f, r, (*hstat)(), (*istat)(), (*qstat)();
        !           885:        int status;
        !           886: 
        !           887:        f = fileno(ptr);
        !           888:        (void) fclose(ptr);
        !           889:        istat = signal(SIGINT, SIG_IGN);
        !           890:        qstat = signal(SIGQUIT, SIG_IGN);
        !           891:        hstat = signal(SIGHUP, SIG_IGN);
        !           892:        while((r = wait(&status)) != mopen_pid[f] && r != -1)
        !           893:                ;
        !           894:        if(r == -1)
        !           895:                status = -1;
        !           896:        signal(SIGINT, istat);
        !           897:        signal(SIGQUIT, qstat);
        !           898:        signal(SIGHUP, hstat);
        !           899:        return status;
        !           900: }
        !           901: 
        !           902: /*
        !           903:  * mhopen a pipe to mail, write out a std header, and return the file ptr.
        !           904:  *
        !           905:  * We don't include a From: field because this is probably uucp, i.e.
        !           906:  * explicitly routed.  Leave it up to the recipient's mailer.
        !           907:  * Always include the To: field because if we ge back failed mail, we
        !           908:  * might be able to deliver it by hand if we know to wom it was addressed.
        !           909:  * By convention, hptr==NULL means to send the message to the local contact person.
        !           910:  */
        !           911: FILE *
        !           912: mailhdr(hptr, subject)
        !           913: struct hbuf *hptr;
        !           914: char  *subject;
        !           915: {
        !           916:        FILE *fp;
        !           917:        time_t now;
        !           918:        char *to = "usenet";
        !           919:        extern char *mydomain();
        !           920: 
        !           921: #ifdef NOTIFY
        !           922:        if (TELLME && *TELLME)
        !           923:                to = TELLME;
        !           924: #endif /* NOTIFY */
        !           925:        if (hptr)
        !           926:                to = replyname(hptr);
        !           927: 
        !           928:        if ((fp = mhopen(hptr)) != NULL) {
        !           929:                (void) time(&now);
        !           930:                fprintf(fp, "Date: %s\n", arpadate(&now));
        !           931: #ifdef MMDF
        !           932:                fprintf(fp, "From: The News System <usenet@%s>\n",
        !           933:                                FROMSYSNAME);
        !           934: #endif /* MMDF */
        !           935:                fprintf(fp, "To: %s\n", to);
        !           936:                fprintf(fp, "Subject: %s\n", subject);
        !           937:                fprintf(fp, "Responding-System: %s\n\n", LOCALSYSNAME);
        !           938:        }
        !           939:        return fp;
        !           940: }
        !           941: 
        !           942: /*
        !           943:  * verify that the name mail is being sent to does not contain any
        !           944:  * nasty hooks to invoke funny functions from the shell or the like.
        !           945:  */
        !           946: verifyname(sendto)
        !           947: char *sendto;
        !           948: {
        !           949:        /* Be sure we DO allow alphabetics, !, :, ., -, @. *. */
        !           950:        char *nasty = "\"'\\`^|;& <>/~";
        !           951:        register char *p;
        !           952: 
        !           953:        if (sendto[0] <= ' ') {
        !           954:                xerror("nasty mail name %s from %s", sendto, header.path);
        !           955:        }
        !           956:        for (p=sendto; *p; p++) {
        !           957:                if (*p == ' ') {
        !           958:                        *p = 0;
        !           959:                        break;
        !           960:                }
        !           961:        }
        !           962:        if (strpbrk(sendto, nasty) != NULL)
        !           963:                error("nasty mail name %s from %s", sendto, header.path);
        !           964: 
        !           965:        for (nasty = sendto; (nasty = index(nasty, '.')) != NULL; ) {
        !           966:                if (*++nasty == '.')    /* check for .. */
        !           967:                        error("nasty mail name %s from %s", sendto, header.path);
        !           968:        }
        !           969: }
        !           970: 
        !           971: /*
        !           972:  * Checks to make sure the control message is OK to post.
        !           973:  */
        !           974: ctlcheck()
        !           975: {
        !           976:        char msg[BUFLEN];
        !           977:        char *p;
        !           978: 
        !           979:        if (!is_ctl)
        !           980:                return;
        !           981: 
        !           982:        if (header.ctlmsg[0])
        !           983:                (void) strcpy(msg, header.ctlmsg);
        !           984:        else
        !           985:                (void) strcpy(msg, header.title);
        !           986: 
        !           987:        p = index(msg, ' ');
        !           988:        if (p)
        !           989:                *p = 0;
        !           990:        
        !           991:        if (strcmp(msg, "ihave") == 0 || strcmp(msg, "sendbad") == 0 ||
        !           992:                strcmp(msg, "sendme") == 0) {
        !           993:                return; /* no restrictions */
        !           994:        } else if (strcmp(msg, "newgroup") == 0) {
        !           995:                suser();
        !           996:        } else if (strcmp(msg, "rmgroup") == 0) {
        !           997:                suser();
        !           998:        } else if (strcmp(msg, "sendsys") == 0) {
        !           999:                suser();
        !          1000:        } else if (strcmp(msg, "checkgroups") == 0) {
        !          1001:                suser();
        !          1002:        } else if (strcmp(msg, "version") == 0) {
        !          1003:                return; /* no restrictions */
        !          1004:        } else if (strcmp(msg, "cancel") == 0) {
        !          1005:                return; /* no restrictions at this level */
        !          1006:        } else if (strcmp(msg, "delsub") == 0) {
        !          1007:                if (!PREFIX(header.nbuf, "to.")) {
        !          1008:                        log("Must be in a 'to.system' newsgroup.");
        !          1009:                        xxit(0);
        !          1010:                }
        !          1011:                return;
        !          1012:        } else {
        !          1013:                log("Unrecognized control message - %s\n", msg);
        !          1014:                xxit(0);
        !          1015:        }
        !          1016: }
        !          1017: 
        !          1018: /* Make sure this guy is special. */
        !          1019: suser()
        !          1020: {
        !          1021:        if (uid == 0 || uid == ROOTID)
        !          1022:                return;
        !          1023:        /*
        !          1024:         * We assume that since our real uid is the same as NEWSUSR
        !          1025:         * (the euid) we were run by rootid and it did a setuid.
        !          1026:         * Too bad we can't set just the effective uid like suid does.
        !          1027:         */
        !          1028:        if (uid == geteuid())
        !          1029:                return;
        !          1030: #ifdef IHCC
        !          1031:        printf("Please use the command:\n\ttoolnews providers\n");
        !          1032:        printf("then call one of the news people.\n");
        !          1033: #else
        !          1034:        printf("Get your local netnews contact to do it for you.\n");
        !          1035: #endif
        !          1036:        xxit(0);
        !          1037: }

unix.superglobalmegacorp.com

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