xref: /plan9/sys/src/cmd/postscript/tcpostio/dial.c (revision 14f51593fd82e19ba95969a8c07ff71131015979)
1*14f51593SDavid du Colombier #define _BSD_EXTENSION
2*14f51593SDavid du Colombier #define _NET_EXTENSION
3*14f51593SDavid du Colombier #define _POSIX_SOURCE
4*14f51593SDavid du Colombier 
57dd7cddfSDavid du Colombier #include <stdio.h>
67dd7cddfSDavid du Colombier #include <stdlib.h>
7*14f51593SDavid du Colombier #include <unistd.h>
8*14f51593SDavid du Colombier #include <ctype.h>
97dd7cddfSDavid du Colombier #include <string.h>
107dd7cddfSDavid du Colombier #include <sys/types.h>
117dd7cddfSDavid du Colombier #include <sys/socket.h>
127dd7cddfSDavid du Colombier #include <netinet/in.h>
137dd7cddfSDavid du Colombier #include <netdb.h>
147dd7cddfSDavid du Colombier #include <sys/time.h>
157dd7cddfSDavid du Colombier 
167dd7cddfSDavid du Colombier #define	DIALTIMEOUT	30
177dd7cddfSDavid du Colombier 
187dd7cddfSDavid du Colombier /* This is a dummy routine for non Plan9 systems.
197dd7cddfSDavid du Colombier  * No attempt has been made to be clever, it's just
207dd7cddfSDavid du Colombier  * supposed to work in this program.
217dd7cddfSDavid du Colombier  */
227dd7cddfSDavid du Colombier int dial_debug = 0;
237dd7cddfSDavid du Colombier 
247dd7cddfSDavid du Colombier int
dial(char * dest,char * local,char * dir,int * cfdp)257dd7cddfSDavid du Colombier dial(char *dest, char *local, char *dir, int *cfdp) {
267dd7cddfSDavid du Colombier 	int sockconn, lport;
277dd7cddfSDavid du Colombier 	struct hostent *hp;		/* Pointer to host info */
287dd7cddfSDavid du Colombier 	struct sockaddr_in sin;		/* Socket address, Internet style */
297dd7cddfSDavid du Colombier 	struct servent *sp = 0;
307dd7cddfSDavid du Colombier 	char *tdest, *netname, *hostname, *servname;
317dd7cddfSDavid du Colombier 	int sock_type;
327dd7cddfSDavid du Colombier #ifndef plan9
337dd7cddfSDavid du Colombier #define	USED(x)	if(x); else
347dd7cddfSDavid du Colombier 	int sockoption, sockoptsize;
357dd7cddfSDavid du Colombier #endif
367dd7cddfSDavid du Colombier 
377dd7cddfSDavid du Colombier 	USED(dir);
387dd7cddfSDavid du Colombier 	USED(cfdp);
397dd7cddfSDavid du Colombier 	if ((tdest = malloc(strlen(dest)+1)) == NULL) {
407dd7cddfSDavid du Colombier 		if (dial_debug) fprintf(stderr, "dial: could not allocate memory\n");
417dd7cddfSDavid du Colombier 		return(-1);
427dd7cddfSDavid du Colombier 	}
437dd7cddfSDavid du Colombier 	strcpy(tdest, dest);
447dd7cddfSDavid du Colombier 
457dd7cddfSDavid du Colombier 	if ((netname = strtok(tdest, "!")) == NULL) {
467dd7cddfSDavid du Colombier 		fprintf(stderr, "dial: no network name\n");
477dd7cddfSDavid du Colombier 		return(-1);
487dd7cddfSDavid du Colombier 	}
497dd7cddfSDavid du Colombier 	if (strcmp(netname, "tcp") == 0) {
507dd7cddfSDavid du Colombier 		sock_type = SOCK_STREAM;
517dd7cddfSDavid du Colombier 	} else if (strcmp(netname, "udp") == 0) {
527dd7cddfSDavid du Colombier 		sock_type = SOCK_DGRAM;
537dd7cddfSDavid du Colombier 	} else {
547dd7cddfSDavid du Colombier 		fprintf(stderr, "dial: network protocol name `%s' is invalid; must be `tcp' or `udp'\n", netname);
557dd7cddfSDavid du Colombier 		return(-1);
567dd7cddfSDavid du Colombier 	}
577dd7cddfSDavid du Colombier 	if ((hostname = strtok(0, "!")) == NULL) {
587dd7cddfSDavid du Colombier 		fprintf(stderr, "dial: no host name or number\n");
597dd7cddfSDavid du Colombier 		return(-1);
607dd7cddfSDavid du Colombier 	}
617dd7cddfSDavid du Colombier 	if ((servname = strtok(0, "!")) == NULL) {
627dd7cddfSDavid du Colombier 		fprintf(stderr, "dial: no service name or number\n");
637dd7cddfSDavid du Colombier 		return(-1);
647dd7cddfSDavid du Colombier 	}
657dd7cddfSDavid du Colombier 	hp = gethostbyname(hostname);
667dd7cddfSDavid du Colombier 	if (hp == (struct hostent *)NULL) {
677dd7cddfSDavid du Colombier 		if (dial_debug) fprintf(stderr, "host `%s' unknown by local host\n", hostname);
687dd7cddfSDavid du Colombier 		return(-1);
697dd7cddfSDavid du Colombier 	}
707dd7cddfSDavid du Colombier 	if (!isdigit(servname[0]))
717dd7cddfSDavid du Colombier 		sp = getservbyname(servname, netname);
727dd7cddfSDavid du Colombier 	sin.sin_addr.s_addr = *(unsigned long*)hp->h_addr;
737dd7cddfSDavid du Colombier 	sin.sin_port	= htons((sp==0)?atoi(servname):sp->s_port);
747dd7cddfSDavid du Colombier 	sin.sin_family	= AF_INET;
757dd7cddfSDavid du Colombier 	if (local == NULL) {
767dd7cddfSDavid du Colombier 		if ((sockconn = socket(AF_INET, sock_type, 0)) < 0) {
777dd7cddfSDavid du Colombier 			if (dial_debug) perror("dial:socket():");
787dd7cddfSDavid du Colombier 			return(-1);
797dd7cddfSDavid du Colombier 		}
807dd7cddfSDavid du Colombier 		if (dial_debug) fprintf(stderr, "socket FD=%d\n", sockconn);
817dd7cddfSDavid du Colombier 	} else {
827dd7cddfSDavid du Colombier 		lport = atoi(local);
837dd7cddfSDavid du Colombier 		if ((lport < 512) || (lport >= 1024)) {
847dd7cddfSDavid du Colombier 			fprintf(stderr, "dial:invalid local port %d\n", lport);
857dd7cddfSDavid du Colombier 			return(-1);
867dd7cddfSDavid du Colombier 		}
877dd7cddfSDavid du Colombier 		if ((sockconn = rresvport(&lport)) < 0) {
887dd7cddfSDavid du Colombier 			if (dial_debug) perror("dial:rresvport():");
897dd7cddfSDavid du Colombier 			return(-1);
907dd7cddfSDavid du Colombier 		}
917dd7cddfSDavid du Colombier 	}
927dd7cddfSDavid du Colombier 	if (dial_debug) {
937dd7cddfSDavid du Colombier 		fprintf(stderr, "sin size=%d\n", sizeof(sin));
947dd7cddfSDavid du Colombier 	}
957dd7cddfSDavid du Colombier 	alarm(DIALTIMEOUT);
967dd7cddfSDavid du Colombier 	if ((connect(sockconn, (struct sockaddr *) &sin, sizeof(sin)) < 0)) {
977dd7cddfSDavid du Colombier 		if (dial_debug) perror("dial:connect():");
987dd7cddfSDavid du Colombier 		return(-1);
997dd7cddfSDavid du Colombier 	}
1007dd7cddfSDavid du Colombier 	alarm(0);
1017dd7cddfSDavid du Colombier #ifndef plan9
1027dd7cddfSDavid du Colombier 	sockoptsize = sizeof(sockoption);
1037dd7cddfSDavid du Colombier 	if (getsockopt(sockconn, SOL_SOCKET, SO_KEEPALIVE, &sockoption, &sockoptsize) < 0) {
1047dd7cddfSDavid du Colombier 		if (dial_debug) perror("dial:getsockopt():");
1057dd7cddfSDavid du Colombier 		return(-1);
1067dd7cddfSDavid du Colombier 	}
1077dd7cddfSDavid du Colombier 	if (sockoptsize == sizeof(sockoption) && !sockoption) {
1087dd7cddfSDavid du Colombier 		if (setsockopt(sockconn, SOL_SOCKET, SO_KEEPALIVE, &sockoption, sockoptsize) < 0) {
1097dd7cddfSDavid du Colombier 			if (dial_debug) perror("dial:getsockopt():");
1107dd7cddfSDavid du Colombier 			return(-1);
1117dd7cddfSDavid du Colombier 		}
1127dd7cddfSDavid du Colombier 	}
1137dd7cddfSDavid du Colombier #endif
1147dd7cddfSDavid du Colombier 	return(sockconn);
1157dd7cddfSDavid du Colombier }
116