1*7dd7cddfSDavid du Colombier #include <stdio.h> 2*7dd7cddfSDavid du Colombier #include <stdlib.h> 3*7dd7cddfSDavid du Colombier #include <string.h> 4*7dd7cddfSDavid du Colombier #include <sys/types.h> 5*7dd7cddfSDavid du Colombier #include <sys/socket.h> 6*7dd7cddfSDavid du Colombier #include <netinet/in.h> 7*7dd7cddfSDavid du Colombier #include <netdb.h> 8*7dd7cddfSDavid du Colombier #include <sys/time.h> 9*7dd7cddfSDavid du Colombier 10*7dd7cddfSDavid du Colombier #define DIALTIMEOUT 30 11*7dd7cddfSDavid du Colombier 12*7dd7cddfSDavid du Colombier /* This is a dummy routine for non Plan9 systems. 13*7dd7cddfSDavid du Colombier * No attempt has been made to be clever, it's just 14*7dd7cddfSDavid du Colombier * supposed to work in this program. 15*7dd7cddfSDavid du Colombier */ 16*7dd7cddfSDavid du Colombier int dial_debug = 0; 17*7dd7cddfSDavid du Colombier 18*7dd7cddfSDavid du Colombier int 19*7dd7cddfSDavid du Colombier dial(char *dest, char *local, char *dir, int *cfdp) { 20*7dd7cddfSDavid du Colombier int sockconn, lport; 21*7dd7cddfSDavid du Colombier struct hostent *hp; /* Pointer to host info */ 22*7dd7cddfSDavid du Colombier struct sockaddr_in sin; /* Socket address, Internet style */ 23*7dd7cddfSDavid du Colombier struct servent *sp = 0; 24*7dd7cddfSDavid du Colombier char *tdest, *netname, *hostname, *servname; 25*7dd7cddfSDavid du Colombier int sock_type; 26*7dd7cddfSDavid du Colombier #ifndef plan9 27*7dd7cddfSDavid du Colombier #define USED(x) if(x); else 28*7dd7cddfSDavid du Colombier int sockoption, sockoptsize; 29*7dd7cddfSDavid du Colombier #endif 30*7dd7cddfSDavid du Colombier 31*7dd7cddfSDavid du Colombier USED(dir); 32*7dd7cddfSDavid du Colombier USED(cfdp); 33*7dd7cddfSDavid du Colombier if ((tdest = malloc(strlen(dest)+1)) == NULL) { 34*7dd7cddfSDavid du Colombier if (dial_debug) fprintf(stderr, "dial: could not allocate memory\n"); 35*7dd7cddfSDavid du Colombier return(-1); 36*7dd7cddfSDavid du Colombier } 37*7dd7cddfSDavid du Colombier strcpy(tdest, dest); 38*7dd7cddfSDavid du Colombier 39*7dd7cddfSDavid du Colombier if ((netname = strtok(tdest, "!")) == NULL) { 40*7dd7cddfSDavid du Colombier fprintf(stderr, "dial: no network name\n"); 41*7dd7cddfSDavid du Colombier return(-1); 42*7dd7cddfSDavid du Colombier } 43*7dd7cddfSDavid du Colombier if (strcmp(netname, "tcp") == 0) { 44*7dd7cddfSDavid du Colombier sock_type = SOCK_STREAM; 45*7dd7cddfSDavid du Colombier } else if (strcmp(netname, "udp") == 0) { 46*7dd7cddfSDavid du Colombier sock_type = SOCK_DGRAM; 47*7dd7cddfSDavid du Colombier } else { 48*7dd7cddfSDavid du Colombier fprintf(stderr, "dial: network protocol name `%s' is invalid; must be `tcp' or `udp'\n", netname); 49*7dd7cddfSDavid du Colombier return(-1); 50*7dd7cddfSDavid du Colombier } 51*7dd7cddfSDavid du Colombier if ((hostname = strtok(0, "!")) == NULL) { 52*7dd7cddfSDavid du Colombier fprintf(stderr, "dial: no host name or number\n"); 53*7dd7cddfSDavid du Colombier return(-1); 54*7dd7cddfSDavid du Colombier } 55*7dd7cddfSDavid du Colombier if ((servname = strtok(0, "!")) == NULL) { 56*7dd7cddfSDavid du Colombier fprintf(stderr, "dial: no service name or number\n"); 57*7dd7cddfSDavid du Colombier return(-1); 58*7dd7cddfSDavid du Colombier } 59*7dd7cddfSDavid du Colombier hp = gethostbyname(hostname); 60*7dd7cddfSDavid du Colombier if (hp == (struct hostent *)NULL) { 61*7dd7cddfSDavid du Colombier if (dial_debug) fprintf(stderr, "host `%s' unknown by local host\n", hostname); 62*7dd7cddfSDavid du Colombier return(-1); 63*7dd7cddfSDavid du Colombier } 64*7dd7cddfSDavid du Colombier if (!isdigit(servname[0])) 65*7dd7cddfSDavid du Colombier sp = getservbyname(servname, netname); 66*7dd7cddfSDavid du Colombier sin.sin_addr.s_addr = *(unsigned long*)hp->h_addr; 67*7dd7cddfSDavid du Colombier sin.sin_port = htons((sp==0)?atoi(servname):sp->s_port); 68*7dd7cddfSDavid du Colombier sin.sin_family = AF_INET; 69*7dd7cddfSDavid du Colombier if (local == NULL) { 70*7dd7cddfSDavid du Colombier if ((sockconn = socket(AF_INET, sock_type, 0)) < 0) { 71*7dd7cddfSDavid du Colombier if (dial_debug) perror("dial:socket():"); 72*7dd7cddfSDavid du Colombier return(-1); 73*7dd7cddfSDavid du Colombier } 74*7dd7cddfSDavid du Colombier if (dial_debug) fprintf(stderr, "socket FD=%d\n", sockconn); 75*7dd7cddfSDavid du Colombier } else { 76*7dd7cddfSDavid du Colombier lport = atoi(local); 77*7dd7cddfSDavid du Colombier if ((lport < 512) || (lport >= 1024)) { 78*7dd7cddfSDavid du Colombier fprintf(stderr, "dial:invalid local port %d\n", lport); 79*7dd7cddfSDavid du Colombier return(-1); 80*7dd7cddfSDavid du Colombier } 81*7dd7cddfSDavid du Colombier if ((sockconn = rresvport(&lport)) < 0) { 82*7dd7cddfSDavid du Colombier if (dial_debug) perror("dial:rresvport():"); 83*7dd7cddfSDavid du Colombier return(-1); 84*7dd7cddfSDavid du Colombier } 85*7dd7cddfSDavid du Colombier } 86*7dd7cddfSDavid du Colombier if (dial_debug) { 87*7dd7cddfSDavid du Colombier fprintf(stderr, "sin size=%d\n", sizeof(sin)); 88*7dd7cddfSDavid du Colombier } 89*7dd7cddfSDavid du Colombier alarm(DIALTIMEOUT); 90*7dd7cddfSDavid du Colombier if ((connect(sockconn, (struct sockaddr *) &sin, sizeof(sin)) < 0)) { 91*7dd7cddfSDavid du Colombier if (dial_debug) perror("dial:connect():"); 92*7dd7cddfSDavid du Colombier return(-1); 93*7dd7cddfSDavid du Colombier } 94*7dd7cddfSDavid du Colombier alarm(0); 95*7dd7cddfSDavid du Colombier #ifndef plan9 96*7dd7cddfSDavid du Colombier sockoptsize = sizeof(sockoption); 97*7dd7cddfSDavid du Colombier if (getsockopt(sockconn, SOL_SOCKET, SO_KEEPALIVE, &sockoption, &sockoptsize) < 0) { 98*7dd7cddfSDavid du Colombier if (dial_debug) perror("dial:getsockopt():"); 99*7dd7cddfSDavid du Colombier return(-1); 100*7dd7cddfSDavid du Colombier } 101*7dd7cddfSDavid du Colombier if (sockoptsize == sizeof(sockoption) && !sockoption) { 102*7dd7cddfSDavid du Colombier if (setsockopt(sockconn, SOL_SOCKET, SO_KEEPALIVE, &sockoption, sockoptsize) < 0) { 103*7dd7cddfSDavid du Colombier if (dial_debug) perror("dial:getsockopt():"); 104*7dd7cddfSDavid du Colombier return(-1); 105*7dd7cddfSDavid du Colombier } 106*7dd7cddfSDavid du Colombier } 107*7dd7cddfSDavid du Colombier #endif 108*7dd7cddfSDavid du Colombier return(sockconn); 109*7dd7cddfSDavid du Colombier } 110