/* -------------------- SAS/C Sample Program -------------------- * * MODULE: rexeccmd.c - Main routine for sample rexec command * SYNTAX: rexec host username password cmd-words * * NOTE: This command does not support sending input to the remote * program. Non-UNIX implementations often restrict * select() to sockets. Thus, there is no portable * way to wait for sockets and "stdin" simultaneously. */ #include #include #include #include #include #include #ifdef __SASC__ static void to_ebcdic(char *buf, size_t n); #endif #define EXEC_PORT 512 /* Well-know port for exec server. */ main(int argc, char *argv[]) { int primary; /* Socket for stdin/stdout. */ int secondary; /* Socket for stderr. */ fd_set read_set; /* Set of sockets we will wait on. */ char buf[256]; /* Set of buffer for incoming data. */ char *host; /* Pointer to hostname. */ int port; /* Port for exec server */ char cmd[512]; /* Command string. */ struct servent *serv; /* exec server information. */ int i, n, rc; /* * Handle command line arguments. * argv[1] = hostname * argv[2] = username * argv[3] = password * argv[4] = first command word * ... * argv[argc-1] = last command word */ if (argc <5 || *argv[1]=='?' || strcmp(argv[1],"-?")==0) { printf("Usage: %s hostname username password cmd-words\n", argv[0]); exit(EXIT_FAILURE); } host = argv[1]; /* Pointer can be modified by rexec() call. */ /* Build up command string from remaining arguments. */ strcpy(cmd,argv[4]); for (i=5; is_port; primary = rexec(&host, port, argv[2], argv[3], cmd, &secondary); if (primary<0) return EXIT_FAILURE; FD_ZERO(&read_set); while (primary>=0 || secondary>=0) { /* * Wait for incoming data on both sockets. * select() clears bits from the mask, so we must reset * the bits each time through the loop. */ if (primary>=0) FD_SET(primary, &read_set); if (secondary>=0) FD_SET(secondary, &read_set); rc = select(FD_SETSIZE, &read_set, NULL, NULL, NULL); if (rc<0) { perror("select failed"); exit(EXIT_FAILURE); } /* * If incoming data available on primary... */ if (primary >= 0 /* Not end of file yet. */ && FD_ISSET(primary, &read_set)) { /* read it (or at least some of it). */ n = read(primary, buf, sizeof(buf)); if (n==0) primary = -1; /* Flag end-of-file on primary. */ else if (n<0) { perror("read failed on remote program's standard output"); exit(EXIT_FAILURE); } else { #ifdef __SASC__ to_ebcdic(buf, n); #endif fwrite(buf, n, 1, stdout); /* Write to local stdout */ } } /* * If incoming data available on secondary... */ if (secondary >= 0 /* Not end of file yet. */ && FD_ISSET(secondary, &read_set)) { n = read(secondary, buf, sizeof(buf)-1); if (n==0) secondary = -1; /* Flag end-of-file on secondary. */ else if (n<0) { perror("read failed on remote program's standard error"); exit(EXIT_FAILURE); } else { #ifdef __SASC__ to_ebcdic(buf, n); #endif fwrite(buf, n, 1, stderr); /* Write to local stderr */ } } } /* End of while loop. */ return EXIT_SUCCESS; } #ifdef __SASC__ /* Need conversion to EBCDIC */ #include /* prototype for htoncs(). */ static void to_ebcdic(char *buf, size_t n) { int i; /* * htoncs() is a SAS/C specific function which converts * a character from ASCII to EBCDIC. */ for (i=0; i