Annotation of 43BSDTahoe/new/dsh/src/dsh.c, revision 1.1

1.1     ! root        1: #include <sys/types.h>
        !             2: #include <stdio.h>
        !             3: #include <errno.h>
        !             4: #include <sys/wait.h>
        !             5: #include "dsh.h"
        !             6: 
        !             7: int    errno;          /* global error location */
        !             8: 
        !             9: /* options */
        !            10: bool   fflg = FALSE;           /* if TRUE fanout stdin */
        !            11: bool   hflg = FALSE;           /* if TRUE use specified host */
        !            12: bool   vflg = FALSE;           /* tell hosts */
        !            13: bool   nflg = FALSE;           /* same as for rsh */
        !            14: bool   aflg = FALSE;           /* true if all nodes to be used */
        !            15: bool   sflg = FALSE;           /* like -n for make */
        !            16: 
        !            17: /* files to be rcp'd for input or output */
        !            18: struct rcpfile {
        !            19:     char       *r_name;        /* name of the file */
        !            20:     struct rcpfile *r_next;
        !            21: };
        !            22: struct rcpfile *rcpin = 0;     /* list of files to copy to */
        !            23: struct rcpfile *rcpout = 0;    /* list of files to copy from */
        !            24: 
        !            25: char           *av[100];       /* the command */
        !            26: union wait     pstatus;        /* the return status of the job */
        !            27: struct hostdef *thehost;       /* the hosts */
        !            28: char           *spechost;      /* the specified host */
        !            29: 
        !            30: /* external routines */
        !            31: int            error();
        !            32: struct hostdef *highest();
        !            33: int            getbids();
        !            34: double         atof();
        !            35: bool           aresynonyms();
        !            36: 
        !            37: main(argc, argv)
        !            38: int    argc;
        !            39: char   *argv[];
        !            40: {
        !            41:     int        inda, indc, ind;
        !            42:     struct rcpfile *lin, *lout, *next;
        !            43:     struct hostdef *hp;
        !            44:     
        !            45:     /* now worry about the commands */
        !            46:     for (inda = 1; inda < argc; inda++) {
        !            47:        
        !            48:        /* process an opton */
        !            49:        if (argv[inda][0] == '-') {
        !            50:            ind = inda;
        !            51:            for (indc = 1; argv[ind][indc] != NULL; indc++) {
        !            52:                switch (argv[ind][indc]) {
        !            53: 
        !            54:                /* all nodes are specified */
        !            55:                case 'a':
        !            56:                    aflg = TRUE;
        !            57:                    break;
        !            58: 
        !            59:                case 's':
        !            60:                    sflg = TRUE;
        !            61:                    break;
        !            62:                
        !            63:                /* fanout input */
        !            64:                case 'f':
        !            65:                    fflg = TRUE;
        !            66:                    break;
        !            67: 
        !            68:                /* specify  hosts */
        !            69:                case 'h':
        !            70:                    inda++;
        !            71:                    if (inda < argc) {
        !            72:                        hflg = TRUE;
        !            73:                        spechost = argv[inda];
        !            74:                    } else {
        !            75:                        fprintf (stderr, "%s: no host after -h\n", argv[0]);
        !            76:                        exit (-1);
        !            77:                    }
        !            78:                    break;
        !            79: 
        !            80:                /* specify input files */
        !            81:                case 'i':
        !            82:                    inda++;
        !            83:                    if (inda < argc) {
        !            84:                        next = new (struct rcpfile);
        !            85:                        if (rcpin == 0) {
        !            86:                            rcpin = next;
        !            87:                        } else {
        !            88:                            lin->r_next = next;
        !            89:                        }
        !            90:                        lin = next;
        !            91:                        lin->r_next = 0;
        !            92:                        lin->r_name = argv[inda];
        !            93:                    } else {
        !            94:                        fprintf (stderr, "%s: no input file after -i\n", argv[0]);
        !            95:                        exit (-1);
        !            96:                    }
        !            97:                    break;
        !            98: 
        !            99:                /* specify output files */
        !           100:                case 'o':
        !           101:                    inda++;
        !           102:                    if (inda < argc) {
        !           103:                        next = new (struct rcpfile);
        !           104:                        if (rcpout == 0) {
        !           105:                            rcpout = next;
        !           106:                        } else {
        !           107:                            lout->r_next = next;
        !           108:                        }
        !           109:                        lout = next;
        !           110:                        lout->r_next = 0;
        !           111:                        lout->r_name = argv[inda];
        !           112:                    } else {
        !           113:                        fprintf (stderr, "%s: no output file after -o\n", argv[0]);
        !           114:                        exit (-1);
        !           115:                    }
        !           116:                    break;
        !           117: 
        !           118:                /* pipe from /dev/null */
        !           119:                case 'n':
        !           120:                    nflg = TRUE;
        !           121:                    break;
        !           122: 
        !           123:                /* tell which machine we're using */
        !           124:                case 'v':
        !           125:                    vflg = TRUE;
        !           126:                    break;
        !           127: 
        !           128:                default:
        !           129:                    fprintf (stderr, "usage: %s [-anv][-io file] <command>\n", argv[0]);
        !           130:                    exit (-1);
        !           131:                }
        !           132:            }
        !           133:        } else {
        !           134:            break;
        !           135:        }
        !           136:     }
        !           137: 
        !           138:     /* pick up the command */
        !           139:     for (ind = 0; inda < argc; inda++, ind++) {
        !           140:        av[ind] = argv[inda];
        !           141:     }
        !           142:     av[ind] = 0;
        !           143: 
        !           144:     /* process the defaults file */
        !           145:     getnodes();
        !           146: 
        !           147:     /* see if anyone wants to bid */
        !           148:     getbids(av, thehost);
        !           149: 
        !           150:     /* execute the command */
        !           151:     hp = highest ();
        !           152:     if (hp == 0) {
        !           153:        error ("no machine bid for the command");
        !           154:     }
        !           155:     if (aflg) {
        !           156:        do {
        !           157:            rexecute (hp);
        !           158:            hp = highest ();
        !           159:        } while (hp != 0);
        !           160:     } else {
        !           161:        rexecute (hp);
        !           162:     }
        !           163: 
        !           164:     if (pstatus.w_T.w_Termsig != 0) {
        !           165:        fprintf (stderr, "(signal %d)", pstatus.w_T.w_Termsig);
        !           166:        pstatus.w_T.w_Retcode = 0;
        !           167:     }
        !           168:     if (pstatus.w_T.w_Coredump == 1) {
        !           169:        fprintf (stderr, "(core dumped)\n");
        !           170:        pstatus.w_T.w_Retcode = 0;
        !           171:     } 
        !           172: 
        !           173:     exit (pstatus.w_T.w_Retcode);
        !           174: }
        !           175: 
        !           176: /*
        !           177:  *     find out which nodes to use 
        !           178:  */
        !           179: char *
        !           180: skipgrey(p)
        !           181: char   *p;
        !           182: {
        !           183:     while (*p == ' ' || *p == '\t' || *p == ',' || *p == ')' || *p == '*')
        !           184:        p++;
        !           185:     return (p);
        !           186: }
        !           187: 
        !           188: char *
        !           189: token (to, sp)
        !           190: char *to;
        !           191: char *sp;
        !           192: {
        !           193:     while (*sp != ' ' && *sp != '\t' && *sp != ',' && *sp !=')' && *sp != 0) {
        !           194:        *to++ = *sp++;
        !           195:     }
        !           196:     return (sp);
        !           197: }
        !           198: 
        !           199: getnodes()
        !           200: {
        !           201:     char *sp;
        !           202:     struct hostdef *last, *next;
        !           203:     bool account;
        !           204:     double weight;
        !           205:     char buf[132];
        !           206:     int rv;
        !           207: 
        !           208:     thehost = 0;
        !           209:     rv = getstringrc (".dshrc", "hosts", buf);
        !           210:     if (rv < 0) {
        !           211:        rv = getstringrc ("/usr/lib/dshrc", "hosts", buf);
        !           212:        if (rv < 0) {
        !           213:            error ("dsh: no hosts in rc files");
        !           214:        }
        !           215:     }
        !           216: 
        !           217:     /* convert to reasonable format */
        !           218:     sp = buf;
        !           219:     while (*sp != 0) {
        !           220:        sp = skipgrey (sp);
        !           221: 
        !           222:        /* get the multiplier */
        !           223:        weight = 1.0;
        !           224:        if ((*sp >= '0' && *sp <= '9') || *sp == '.') {
        !           225:            weight = atof (sp);
        !           226:            for (;*sp != '*' && *sp != 0; sp++);
        !           227:            sp = skipgrey (sp);
        !           228:        }
        !           229: 
        !           230:        if (*sp != 0) {
        !           231: 
        !           232:            /* allocate some space and chain it in */
        !           233:            next = new (struct hostdef);
        !           234:            if (thehost == 0) {
        !           235:                thehost = next;
        !           236:            } else {
        !           237:                last->h_next = next;
        !           238:            }
        !           239:            last = next;
        !           240:            last->h_next = 0;
        !           241:            last->h_weight = weight;
        !           242: 
        !           243:            /* pick up the entry */
        !           244:            if (*sp == '(') {
        !           245:                sp++;
        !           246:                sp = skipgrey (sp);
        !           247:                account = TRUE;
        !           248:            } else {
        !           249:                account = FALSE;
        !           250:            }
        !           251:            sp = token (last->h_name, sp);
        !           252:            if (account) {
        !           253:                sp = skipgrey (sp);
        !           254:                sp = token (last->h_user, sp);
        !           255:            } else {
        !           256:                *(last->h_user) = 0;
        !           257:            }
        !           258:        }
        !           259:     }
        !           260: }
        !           261: 
        !           262: /*
        !           263:  *     execute a command
        !           264:  */
        !           265: execute (argv, block, justtell, ignore)
        !           266: char   *argv[];        /* the command */
        !           267: bool   block;          /* if true, block till the command is done */
        !           268: bool   justtell;       /* true if we shouldn't execute when debuging */
        !           269: bool   ignore;         /* ignore output */
        !           270: {
        !           271:     int                argc;
        !           272:     int                pid, rv;
        !           273:     int                status, fd;
        !           274: 
        !           275:     if (sflg) {
        !           276: 
        !           277:        /* just say what we'll do */
        !           278:        for (argc = 0;argv[argc] != 0; argc++) {
        !           279:            printf ("%s ", argv[argc]);
        !           280:        }
        !           281:        printf ("\n");
        !           282:     }
        !           283:     if (!(justtell && sflg)) {
        !           284: 
        !           285:        /* really do it */
        !           286:        if (pid = fork()) {
        !           287:            if (block) {
        !           288:                do {
        !           289:                    rv = wait (&status);
        !           290:                } while (rv != -1 && rv != pid);
        !           291:            }
        !           292:        } else {
        !           293:            if (ignore) {
        !           294:                fd = open ("/dev/null", 2);
        !           295:                dup2 (fd, 1);
        !           296:                dup2 (fd, 2);
        !           297:            }
        !           298:            execvp (argv[0], argv);
        !           299:            _exit (0);
        !           300:        }
        !           301:     }
        !           302: }
        !           303: 
        !           304: /*
        !           305:  *     remotely execute the command
        !           306:  */
        !           307: rexecute (hp)
        !           308: struct hostdef *hp;            /* the host to execute on */
        !           309: {
        !           310:     struct rcpfile *fp;
        !           311:     int                rv;
        !           312:     int                argc, ac;
        !           313:     char       *argv[200];
        !           314:     char       mydir[PATHSIZE];
        !           315:     bool       local;
        !           316:        
        !           317:     if (vflg || aflg) {
        !           318:        fprintf (stderr, ">>%s<<\n", hp->h_name);
        !           319:     }
        !           320:     argc = 0;
        !           321:     local = aresynonyms (hp->h_name, myhostname());
        !           322:     if (!local) {
        !           323:        /* get our directory if we're going to copy files */
        !           324:        if (rcpin != 0 || rcpout != 0) {
        !           325:            getwd (mydir);
        !           326:        }
        !           327: 
        !           328:        /* make the directory we're going to use */
        !           329:        argv[argc++] = "(";
        !           330:        argv[argc++] = "mkdir";
        !           331:        argv[argc++] = hp->h_dir;
        !           332:        argv[argc++] = ";";
        !           333: 
        !           334:        /* and hop to it */
        !           335:        argv[argc++] = "cd";
        !           336:        argv[argc++] = hp->h_dir;
        !           337:        argv[argc++] = ";";
        !           338: 
        !           339:        /* copy over any files */
        !           340:        if (rcpin != 0) {
        !           341:            argv[argc++] = "rcp";
        !           342:            for (fp = rcpin; fp != 0; fp = fp->r_next) {
        !           343:                argv[argc] = (char *) malloc (HOSTNAMESIZE+2*PATHSIZE);
        !           344:                if (fp->r_name[0] == '/' || fp->r_name[0] == '~') {
        !           345:                    sprintf (argv[argc++], "%s:%s", myhostname(), fp->r_name);
        !           346:                } else {
        !           347:                    sprintf (argv[argc++], "%s:%s/%s", myhostname(),
        !           348:                        mydir, fp->r_name);
        !           349:                }
        !           350:            }
        !           351:            argv[argc++] = ".";
        !           352:            argv[argc++] = ";";
        !           353:        }
        !           354:     }
        !           355: 
        !           356:     /* execute the command */
        !           357:     for (ac = 0; av[ac] != 0; ac++) {
        !           358:        argv[argc++] = av[ac];
        !           359:     }
        !           360:     argv[argc++] = ";";
        !           361: 
        !           362:     if (!local) {
        !           363: 
        !           364:        /* copy back any files */
        !           365:        if (rcpout != 0) {
        !           366:            argv[argc++] = "rcp";
        !           367:            for (fp = rcpout; fp != 0; fp = fp->r_next) {
        !           368:                argv[argc++] = fp->r_name;
        !           369:            }
        !           370:            argv[argc] = (char *) malloc (HOSTNAMESIZE+2*PATHSIZE);
        !           371:            sprintf (argv[argc++], "%s:%s", myhostname(), mydir);
        !           372:            argv[argc++] = ";";
        !           373:        }
        !           374: 
        !           375:        /* clean up the directory */
        !           376:        argv[argc++] = "cd";
        !           377:        argv[argc++] = "..";
        !           378:        argv[argc++] = ";";
        !           379:        argv[argc++] = "/bin/rm";
        !           380:        argv[argc++] = "-fr";
        !           381:        argv[argc++] = hp->h_dir;
        !           382:        argv[argc++] = ")";
        !           383:     }
        !           384:     argv[argc] = 0;
        !           385:     
        !           386:     rshell (hp, argv, TRUE, nflg, TRUE, FALSE);
        !           387: }
        !           388: 
        !           389: rshell (hp, av, block, usenflg, justtell, ignore)
        !           390: struct hostdef *hp;            /* all about the host */
        !           391: char           *av[];          /* the command */
        !           392: bool           block;          /* true if we should block */
        !           393: bool           usenflg;        /* true if we should use the n flag */
        !           394: bool           justtell;       /* true if we shouldn't execute when debuging */
        !           395: bool           ignore;         /* ignore the output from the command */
        !           396: {
        !           397:     int                rv;
        !           398:     int                argc, ac;
        !           399:     char       *argv[100];
        !           400:     char       command[256];
        !           401:     char       *p, *p1;
        !           402:     bool       local;
        !           403:        
        !           404:     argc = 0;
        !           405:     local = aresynonyms (hp->h_name, myhostname());
        !           406:     if (local) {
        !           407:        argv[argc++] = "csh";
        !           408:        argv[argc++] = "-c";
        !           409:        argv[argc++] = command;
        !           410:        p = command;
        !           411:        for (ac = 0; av[ac] != 0; ac++) {
        !           412:            *p++ = ' ';
        !           413:            for (p1 = av[ac]; *p1 != 0;){
        !           414:                *p++ = *p1++;
        !           415:            }
        !           416:        }
        !           417:        *p = 0;
        !           418:     } else {
        !           419:        argv[argc++] = "rsh";
        !           420:        argv[argc++] = hp->h_name;
        !           421:        if (usenflg) {
        !           422:            argv[argc++] = "-n";
        !           423:        }
        !           424:        if (*(hp->h_user) != 0) {
        !           425:            argv[argc++] = "-l";
        !           426:            argv[argc++] = hp->h_user;
        !           427:        }
        !           428:        for (ac = 0; av[ac] != 0; ac++) {
        !           429:            argv[argc++] = av[ac];
        !           430:        }
        !           431:     }
        !           432:     argv[argc] = 0;
        !           433:     execute (argv, block, justtell, ignore);
        !           434: }

unix.superglobalmegacorp.com

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