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