xref: /csrg-svn/usr.bin/tn3270/api/api_bsd.c (revision 31472)
131459Sminshall #include <sys/types.h>
231459Sminshall #include <sys/socket.h>
331459Sminshall #include <netinet/in.h>
431459Sminshall #include <netdb.h>
531459Sminshall #include <stdio.h>
631459Sminshall 
731459Sminshall #include "../api/api.h"
831467Sminshall #include "api_exch.h"
931459Sminshall 
1031459Sminshall 
1131459Sminshall api_open_api(string)
1231459Sminshall char	*string;		/* if non-zero, where to connect to */
1331459Sminshall {
1431459Sminshall     struct sockaddr_in server;
1531459Sminshall     struct hostent *hp;
1631459Sminshall     char *getenv();
1731459Sminshall     char thehostname[100];
1831467Sminshall     int sock;
1931459Sminshall     int port;
2031467Sminshall     int i;
2131459Sminshall 
2231459Sminshall     if (string == 0) {
2331459Sminshall 	string = getenv("API3270");	/* Get API */
2431459Sminshall 	if (string == 0) {
2531459Sminshall 	    fprintf(stderr,
2631459Sminshall 			"API3270 environmental variable not set - no API.\n");
2731459Sminshall 	    return -1;			/* Nothing */
2831459Sminshall 	}
2931459Sminshall     }
3031459Sminshall 
3131459Sminshall     if (sscanf(string, "%[^:]:%d", thehostname, &port) != 2) {
3231459Sminshall 	fprintf(stderr, "API3270 environmental variable has bad format.\n");
3331459Sminshall 	return -1;
3431459Sminshall     }
3531459Sminshall     /* Now, try to connect */
3631459Sminshall     sock = socket(AF_INET, SOCK_STREAM, 0);
3731459Sminshall     if (sock < 0) {
3831459Sminshall 	perror("opening API socket");
3931459Sminshall 	return -1;
4031459Sminshall     }
4131459Sminshall     server.sin_family = AF_INET;
4231459Sminshall     hp = gethostbyname(thehostname);
4331459Sminshall     if (hp == 0) {
4431459Sminshall 	fprintf(stderr, "%s specifies bad host name.\n", string);
4531459Sminshall 	return -1;
4631459Sminshall     }
4731459Sminshall     bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
4831459Sminshall     server.sin_port = htons(port);
4931459Sminshall 
5031459Sminshall     if (connect(sock, &server, sizeof server) < 0) {
5131459Sminshall 	perror("connecting to API server");
5231459Sminshall 	return -1;
5331459Sminshall     }
5431467Sminshall     /* Now, try application level connection */
5531467Sminshall     if (api_exch_init(sock) == -1) {
5631467Sminshall 	return -1;
5731467Sminshall     }
5831467Sminshall     if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) {
5931467Sminshall 	return -1;
6031467Sminshall     }
6131467Sminshall     while ((i = api_exch_inbyte()) != EXCH_ASSOCIATED) {
6231467Sminshall 	struct storage_descriptor sd;
6331467Sminshall 	int passwd_length;
6431467Sminshall 	char *passwd, *getpass();
6531467Sminshall 	char buffer[200];
6631467Sminshall 
6731467Sminshall 	switch (i) {
6831467Sminshall 	case EXCH_REJECTED:
6931467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC,
7031467Sminshall 					sizeof sd, (char *)&sd) == -1) {
7131467Sminshall 		return -1;
7231467Sminshall 	    }
7331467Sminshall 	    sd.length = ntohs(sd.length);
7431467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
7531467Sminshall 		return -1;
7631467Sminshall 	    }
7731467Sminshall 	    buffer[sd.length] = 0;
7831467Sminshall 	    fprintf(stderr, "%s\n", buffer);
7931467Sminshall 	    if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) {
8031467Sminshall 		return -1;
8131467Sminshall 	    }
8231467Sminshall 	    break;
8331467Sminshall 	case EXCH_SEND_AUTH:
8431467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
8531467Sminshall 		return -1;
8631467Sminshall 	    }
8731467Sminshall 	    sd.length = ntohs(sd.length);
8831467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
8931467Sminshall 		return -1;
9031467Sminshall 	    }
9131467Sminshall 	    buffer[sd.length] = 0;
9231467Sminshall 	    passwd = getpass(buffer);		/* Go to terminal */
9331467Sminshall 	    passwd_length = strlen(passwd);
9431467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
9531467Sminshall 		return -1;
9631467Sminshall 	    }
9731467Sminshall 	    sd.length = ntohs(sd.length);
9831467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
9931467Sminshall 		return -1;
10031467Sminshall 	    }
10131467Sminshall 	    buffer[sd.length] = 0;
10231467Sminshall 	    if (sd.length) {
10331467Sminshall 		char *ptr;
10431467Sminshall 
10531467Sminshall 		ptr = passwd;
10631467Sminshall 		i = 0;
10731467Sminshall 		while (*ptr) {
10831467Sminshall 		    *ptr++ ^= buffer[i++];
10931467Sminshall 		    if (i >= sd.length) {
11031467Sminshall 			i = 0;
11131467Sminshall 		    }
11231467Sminshall 		}
11331467Sminshall 	    }
11431467Sminshall 	    sd.length = htons(passwd_length);
11531467Sminshall 	    if (api_exch_outcommand(EXCH_AUTH) == -1) {
11631467Sminshall 		return -1;
11731467Sminshall 	    }
11831467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
11931467Sminshall 		return -1;
12031467Sminshall 	    }
12131467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
12231467Sminshall 		return -1;
12331467Sminshall 	    }
12431467Sminshall 	    break;
12531467Sminshall 	case -1:
12631467Sminshall 	    return -1;
12731467Sminshall 	default:
12831467Sminshall 	    fprintf(stderr,
12931467Sminshall 		    "Waiting for connection indicator, received 0x%x.\n", i);
13031467Sminshall 	    break;
13131467Sminshall 	}
13231467Sminshall     }
13331459Sminshall     /* YEAH */
13431459Sminshall     return 0;		/* Happiness! */
13531459Sminshall }
13631459Sminshall 
13731459Sminshall 
13831459Sminshall api_exch_api(regs, sregs)
13931459Sminshall union REGS *regs;
14031459Sminshall struct SREGS *sregs;
14131459Sminshall {
142*31472Sminshall     struct storage_descriptor sd;
143*31472Sminshall     int i;
144*31472Sminshall 
145*31472Sminshall     if (api_exch_outcommand(EXCH_REQUEST) == -1) {
146*31472Sminshall 	return -1;
147*31472Sminshall     }
148*31472Sminshall     if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
149*31472Sminshall 	return -1;
150*31472Sminshall     }
151*31472Sminshall     if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
152*31472Sminshall 	return -1;
153*31472Sminshall     }
154*31472Sminshall     sd.length = 0;
155*31472Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
156*31472Sminshall 	return -1;
157*31472Sminshall     }
158*31472Sminshall     while ((i = api_exch_inbyte()) != EXCH_REPLY) {
159*31472Sminshall 	switch (i) {
160*31472Sminshall 	case EXCH_GIMME:
161*31472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
162*31472Sminshall 					== -1) {
163*31472Sminshall 		return -1;
164*31472Sminshall 	    }
165*31472Sminshall 	    /*XXX validity check GIMME? */
166*31472Sminshall 	    if (api_exch_outcommand(EXCH_HEREIS) == -1) {
167*31472Sminshall 		return -1;
168*31472Sminshall 	    }
169*31472Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
170*31472Sminshall 				== -1) {
171*31472Sminshall 		return -1;
172*31472Sminshall 	    }
173*31472Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, ntohs(sd.length),
174*31472Sminshall 			    ntohl(sd.location)) == -1) {
175*31472Sminshall 		return -1;
176*31472Sminshall 	    }
177*31472Sminshall 	    break;
178*31472Sminshall 	case EXCH_HEREIS:
179*31472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
180*31472Sminshall 					== -1) {
181*31472Sminshall 		return -1;
182*31472Sminshall 	    }
183*31472Sminshall 	    /* XXX Validty check HEREIS? */
184*31472Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, ntohs(sd.length),
185*31472Sminshall 			    ntohl(sd.location)) == -1) {
186*31472Sminshall 		return -1;
187*31472Sminshall 	    }
188*31472Sminshall 	    break;
189*31472Sminshall 	default:
190*31472Sminshall 	    fprintf(stderr, "Waiting for reply command, we got command %d.\n",
191*31472Sminshall 			i);
192*31472Sminshall 	    return -1;
193*31472Sminshall 	}
194*31472Sminshall     }
195*31472Sminshall     if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
196*31472Sminshall 	return -1;
197*31472Sminshall     }
198*31472Sminshall     if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
199*31472Sminshall 	return -1;
200*31472Sminshall     }
201*31472Sminshall     /* YEAH */
202*31472Sminshall     return 0;		/* Happiness! */
20331459Sminshall }
204