/* rcmdserv.c */ /* This program is an example of how a remote command server */ /* like rsh might work. */ #define begin { #define end } #include #include #include #include #include #include #include #include #include char buffer[200]; struct hostent *hp; struct hostent *gethostbyname(); struct sockaddr_in name; struct sockaddr_in client; extern int errno; int srvpid; main(argc, argv) int argc; char *argv[]; { int i; int session = 0; unsigned char c; int sock; int msgsock; int status; int ramt; int wamt; int namesize; int hostaddr; /* Create a stream (TCP) socket */ srvpid = getpid(); sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { printf("Socket create failed \n"); exit(1); } /* Get nameserver to convert host name to address */ hp = gethostbyname(argv[1]); if (hp == 0) { printf("Host %s not found", argv[1]); exit(2); } /* Fill in host and port address in name structure */ bcopy((char *)hp->h_addr, (char *)&name.sin_addr, hp->h_length); name.sin_family = AF_INET; name.sin_port = htons(atoi(argv[2])); /* Bind socket to network,port address */ status = bind(sock, (struct sockaddr *)&name, sizeof(name)); printf("Bind status = %d \n", status); if (status < 0) exit(3); /* Signify availabilty for network connections */ status = listen(sock, 4); if (status < 0) { printf("Listen failed with code %d. \n", errno); exit(4); } namesize = sizeof(name); while(1) { /* Accept a connection from the network */ /* Address of the connecting party will be in name after */ /* the connection is established. */ status = accept(sock, (struct sockaddr *)&name, &namesize); if (status < 0) { printf("Accept failed with code %d. \n", errno); exit(5); } /* Value returned by accept is a handle for reading or writing */ printf("Accept status = %d \n", status); msgsock = status; /* Invoke the remote command processor */ session += 1; if (fork() == 0) { rcmd(msgsock, session); exit(6); } } } /* This is the remote command server.. It reads commands */ /* from a connected client, redirects the standard out */ /* back across the net and executes the commands. */ rcmd(comfile, id) int comfile; int id; { int infile; int amtread; int killrc; int *loc = 0; char msgbuf[10]; int i; /* Redirect standard output back to network connection */ sprintf(msgbuf, "SVR%d>", id); close(1); dup(comfile); while(1) { write(comfile, msgbuf, 6); /* @ informs the other end its ok to send.. This is a SNA-like */ /* "Dataflow" protocol. */ write(comfile, "@", 1); amtread = read(comfile, buffer, sizeof(buffer)); *(buffer + amtread - 1) = 0; fprintf(stderr, "Cmd was: %s \n", buffer); /* Session level protocol ... x ==> terminate this session */ /* z ==> terminate server. */ if (buffer[0] == 'x') { close(comfile); close(1); return(1); } if (buffer[0] == 'z') { close(comfile); killrc = kill(getppid(), SIGKILL); fprintf(stderr, "Kill RC = %d \r\n", killrc); return(-1); } /* Execute the command that was transferred. */ system(buffer); } }