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: }

Defined functions

execute defined in line 265; used 1 times
getnodes defined in line 199; used 1 times
main defined in line 37; never used
rexecute defined in line 307; used 2 times
rshell defined in line 389; used 2 times
skipgrey defined in line 179; used 4 times
token defined in line 188; used 2 times

Defined variables

av defined in line 25; used 11 times
errno defined in line 7; never used
pstatus defined in line 26; used 6 times
rcpin defined in line 22; used 5 times
rcpout defined in line 23; used 5 times
spechost defined in line 28; used 1 times
  • in line 73
thehost defined in line 27; used 4 times

Defined struct's

rcpfile defined in line 18; used 14 times
Last modified: 1983-07-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1602
Valid CSS Valid XHTML 1.0 Strict