1*219b2ee8SDavid du Colombier /* posix */ 2*219b2ee8SDavid du Colombier #include <sys/types.h> 3*219b2ee8SDavid du Colombier #include <unistd.h> 4*219b2ee8SDavid du Colombier #include <stdlib.h> 5*219b2ee8SDavid du Colombier #include <stdio.h> 6*219b2ee8SDavid du Colombier #include <string.h> 7*219b2ee8SDavid du Colombier #include <errno.h> 8*219b2ee8SDavid du Colombier #include <signal.h> 9*219b2ee8SDavid du Colombier 10*219b2ee8SDavid du Colombier /* socket extensions */ 11*219b2ee8SDavid du Colombier #include <sys/socket.h> 12*219b2ee8SDavid du Colombier #include <netinet/in.h> 13*219b2ee8SDavid du Colombier #include <sys/un.h> 14*219b2ee8SDavid du Colombier #include <netdb.h> 15*219b2ee8SDavid du Colombier 16*219b2ee8SDavid du Colombier #include "priv.h" 17*219b2ee8SDavid du Colombier 18*219b2ee8SDavid du Colombier static char *pbotch = "rcmd: protocol botch\n"; 19*219b2ee8SDavid du Colombier static char *lbotch = "rcmd: botch starting error stream\n"; 20*219b2ee8SDavid du Colombier 21*219b2ee8SDavid du Colombier static void 22*219b2ee8SDavid du Colombier ding(int x) 23*219b2ee8SDavid du Colombier { 24*219b2ee8SDavid du Colombier } 25*219b2ee8SDavid du Colombier 26*219b2ee8SDavid du Colombier int 27*219b2ee8SDavid du Colombier rcmd(char **dst, int port, char *luser, char *ruser, char *cmd, int *fd2p) 28*219b2ee8SDavid du Colombier { 29*219b2ee8SDavid du Colombier char c; 30*219b2ee8SDavid du Colombier int i, fd, lfd, fd2, port2; 31*219b2ee8SDavid du Colombier struct hostent *h; 32*219b2ee8SDavid du Colombier Rock *r; 33*219b2ee8SDavid du Colombier struct sockaddr_in in; 34*219b2ee8SDavid du Colombier char buf[128]; 35*219b2ee8SDavid du Colombier void (*x)(int); 36*219b2ee8SDavid du Colombier 37*219b2ee8SDavid du Colombier h = gethostbyname(*dst); 38*219b2ee8SDavid du Colombier if(h == 0) 39*219b2ee8SDavid du Colombier return -1; 40*219b2ee8SDavid du Colombier *dst = h->h_name; 41*219b2ee8SDavid du Colombier 42*219b2ee8SDavid du Colombier /* connect using a reserved tcp port */ 43*219b2ee8SDavid du Colombier fd = socket(PF_INET, SOCK_STREAM, 0); 44*219b2ee8SDavid du Colombier if(fd < 0) 45*219b2ee8SDavid du Colombier return -1; 46*219b2ee8SDavid du Colombier r = _sock_findrock(fd, 0); 47*219b2ee8SDavid du Colombier if(r == 0){ 48*219b2ee8SDavid du Colombier errno = ENOTSOCK; 49*219b2ee8SDavid du Colombier return -1; 50*219b2ee8SDavid du Colombier } 51*219b2ee8SDavid du Colombier r->reserved = 1; 52*219b2ee8SDavid du Colombier in.sin_family = AF_INET; 53*219b2ee8SDavid du Colombier in.sin_port = htons(port); 54*219b2ee8SDavid du Colombier memmove(&in.sin_addr, h->h_addr_list[0], sizeof(in.sin_addr)); 55*219b2ee8SDavid du Colombier if(connect(fd, &in, sizeof(in)) < 0){ 56*219b2ee8SDavid du Colombier close(fd); 57*219b2ee8SDavid du Colombier return -1; 58*219b2ee8SDavid du Colombier } 59*219b2ee8SDavid du Colombier 60*219b2ee8SDavid du Colombier /* error stream */ 61*219b2ee8SDavid du Colombier if(fd2p){ 62*219b2ee8SDavid du Colombier /* create an error stream and wait for a call in */ 63*219b2ee8SDavid du Colombier for(i = 0; i < 10; i++){ 64*219b2ee8SDavid du Colombier lfd = rresvport(&port2); 65*219b2ee8SDavid du Colombier if(lfd < 0) 66*219b2ee8SDavid du Colombier continue; 67*219b2ee8SDavid du Colombier if(listen(lfd, 1) == 0) 68*219b2ee8SDavid du Colombier break; 69*219b2ee8SDavid du Colombier close(lfd); 70*219b2ee8SDavid du Colombier } 71*219b2ee8SDavid du Colombier if(i >= 10){ 72*219b2ee8SDavid du Colombier fprintf(stderr, pbotch); 73*219b2ee8SDavid du Colombier return -1; 74*219b2ee8SDavid du Colombier } 75*219b2ee8SDavid du Colombier 76*219b2ee8SDavid du Colombier sprintf(buf, "%d", port2); 77*219b2ee8SDavid du Colombier if(write(fd, buf, strlen(buf)+1) < 0){ 78*219b2ee8SDavid du Colombier close(fd); 79*219b2ee8SDavid du Colombier close(lfd); 80*219b2ee8SDavid du Colombier fprintf(stderr, lbotch); 81*219b2ee8SDavid du Colombier return -1; 82*219b2ee8SDavid du Colombier } 83*219b2ee8SDavid du Colombier } else { 84*219b2ee8SDavid du Colombier if(write(fd, "", 1) < 0){ 85*219b2ee8SDavid du Colombier fprintf(stderr, pbotch); 86*219b2ee8SDavid du Colombier return -1; 87*219b2ee8SDavid du Colombier } 88*219b2ee8SDavid du Colombier } 89*219b2ee8SDavid du Colombier 90*219b2ee8SDavid du Colombier /* pass id's and command */ 91*219b2ee8SDavid du Colombier if(write(fd, luser, strlen(luser)+1) < 0 92*219b2ee8SDavid du Colombier || write(fd, ruser, strlen(ruser)+1) < 0 93*219b2ee8SDavid du Colombier || write(fd, cmd, strlen(cmd)+1) < 0){ 94*219b2ee8SDavid du Colombier if(fd2p) 95*219b2ee8SDavid du Colombier close(fd2); 96*219b2ee8SDavid du Colombier fprintf(stderr, pbotch); 97*219b2ee8SDavid du Colombier return -1; 98*219b2ee8SDavid du Colombier } 99*219b2ee8SDavid du Colombier 100*219b2ee8SDavid du Colombier if(fd2p){ 101*219b2ee8SDavid du Colombier x = signal(SIGALRM, ding); 102*219b2ee8SDavid du Colombier alarm(15); 103*219b2ee8SDavid du Colombier fd2 = accept(lfd, &in, &i); 104*219b2ee8SDavid du Colombier alarm(0); 105*219b2ee8SDavid du Colombier close(lfd); 106*219b2ee8SDavid du Colombier signal(SIGALRM, x); 107*219b2ee8SDavid du Colombier 108*219b2ee8SDavid du Colombier if(fd2 < 0){ 109*219b2ee8SDavid du Colombier close(fd); 110*219b2ee8SDavid du Colombier close(lfd); 111*219b2ee8SDavid du Colombier fprintf(stderr, lbotch); 112*219b2ee8SDavid du Colombier return -1; 113*219b2ee8SDavid du Colombier } 114*219b2ee8SDavid du Colombier *fd2p = fd2; 115*219b2ee8SDavid du Colombier } 116*219b2ee8SDavid du Colombier 117*219b2ee8SDavid du Colombier /* get reply */ 118*219b2ee8SDavid du Colombier if(read(fd, &c, 1) != 1){ 119*219b2ee8SDavid du Colombier if(fd2p) 120*219b2ee8SDavid du Colombier close(fd2); 121*219b2ee8SDavid du Colombier fprintf(stderr, pbotch); 122*219b2ee8SDavid du Colombier return -1; 123*219b2ee8SDavid du Colombier } 124*219b2ee8SDavid du Colombier if(c == 0) 125*219b2ee8SDavid du Colombier return fd; 126*219b2ee8SDavid du Colombier i = 0; 127*219b2ee8SDavid du Colombier while(c){ 128*219b2ee8SDavid du Colombier buf[i++] = c; 129*219b2ee8SDavid du Colombier if(read(fd, &c, 1) != 1) 130*219b2ee8SDavid du Colombier break; 131*219b2ee8SDavid du Colombier if(i >= sizeof(buf)-1) 132*219b2ee8SDavid du Colombier break; 133*219b2ee8SDavid du Colombier } 134*219b2ee8SDavid du Colombier buf[i] = 0; 135*219b2ee8SDavid du Colombier fprintf(stderr, "rcmd: %s\n", buf); 136*219b2ee8SDavid du Colombier close(fd); 137*219b2ee8SDavid du Colombier return -1; 138*219b2ee8SDavid du Colombier } 139