Annotation of 43BSDTahoe/new/dsh/src/dsh.c, revision 1.1.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.