xref: /csrg-svn/usr.bin/tn3270/api/api_bsd.c (revision 31500)
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 
1131493Sminshall int
1231493Sminshall api_close_api()
1331493Sminshall {
1431493Sminshall     if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) {
1531493Sminshall 	return -1;
1631493Sminshall     } else if (api_exch_flush() == -1) {
1731493Sminshall 	return -1;
1831493Sminshall     } else {
1931493Sminshall 	return 0;
2031493Sminshall     }
2131493Sminshall }
2231493Sminshall 
2331493Sminshall 
2431493Sminshall int
2531459Sminshall api_open_api(string)
2631459Sminshall char	*string;		/* if non-zero, where to connect to */
2731459Sminshall {
2831459Sminshall     struct sockaddr_in server;
2931459Sminshall     struct hostent *hp;
3031459Sminshall     char *getenv();
3131459Sminshall     char thehostname[100];
3231467Sminshall     int sock;
3331459Sminshall     int port;
3431467Sminshall     int i;
3531459Sminshall 
3631459Sminshall     if (string == 0) {
3731459Sminshall 	string = getenv("API3270");	/* Get API */
3831459Sminshall 	if (string == 0) {
3931459Sminshall 	    fprintf(stderr,
4031459Sminshall 			"API3270 environmental variable not set - no API.\n");
4131459Sminshall 	    return -1;			/* Nothing */
4231459Sminshall 	}
4331459Sminshall     }
4431459Sminshall 
4531459Sminshall     if (sscanf(string, "%[^:]:%d", thehostname, &port) != 2) {
4631459Sminshall 	fprintf(stderr, "API3270 environmental variable has bad format.\n");
4731459Sminshall 	return -1;
4831459Sminshall     }
4931459Sminshall     /* Now, try to connect */
5031459Sminshall     sock = socket(AF_INET, SOCK_STREAM, 0);
5131459Sminshall     if (sock < 0) {
5231459Sminshall 	perror("opening API socket");
5331459Sminshall 	return -1;
5431459Sminshall     }
5531459Sminshall     server.sin_family = AF_INET;
5631459Sminshall     hp = gethostbyname(thehostname);
5731459Sminshall     if (hp == 0) {
5831459Sminshall 	fprintf(stderr, "%s specifies bad host name.\n", string);
5931459Sminshall 	return -1;
6031459Sminshall     }
6131459Sminshall     bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
6231459Sminshall     server.sin_port = htons(port);
6331459Sminshall 
6431459Sminshall     if (connect(sock, &server, sizeof server) < 0) {
6531459Sminshall 	perror("connecting to API server");
6631459Sminshall 	return -1;
6731459Sminshall     }
6831467Sminshall     /* Now, try application level connection */
6931493Sminshall     if (api_exch_init(sock, "client") == -1) {
7031467Sminshall 	return -1;
7131467Sminshall     }
7231493Sminshall     if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
7331467Sminshall 	return -1;
7431467Sminshall     }
7531493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
7631467Sminshall 	struct storage_descriptor sd;
7731467Sminshall 	int passwd_length;
7831467Sminshall 	char *passwd, *getpass();
7931467Sminshall 	char buffer[200];
8031467Sminshall 
8131467Sminshall 	switch (i) {
8231493Sminshall 	case EXCH_CMD_REJECTED:
8331467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC,
8431467Sminshall 					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 	    fprintf(stderr, "%s\n", buffer);
9331493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
9431467Sminshall 		return -1;
9531467Sminshall 	    }
9631467Sminshall 	    break;
9731493Sminshall 	case EXCH_CMD_SEND_AUTH:
9831467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
9931467Sminshall 		return -1;
10031467Sminshall 	    }
10131467Sminshall 	    sd.length = ntohs(sd.length);
10231467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
10331467Sminshall 		return -1;
10431467Sminshall 	    }
10531467Sminshall 	    buffer[sd.length] = 0;
10631467Sminshall 	    passwd = getpass(buffer);		/* Go to terminal */
10731467Sminshall 	    passwd_length = strlen(passwd);
10831467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
10931467Sminshall 		return -1;
11031467Sminshall 	    }
11131467Sminshall 	    sd.length = ntohs(sd.length);
11231467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
11331467Sminshall 		return -1;
11431467Sminshall 	    }
11531467Sminshall 	    buffer[sd.length] = 0;
11631467Sminshall 	    if (sd.length) {
11731467Sminshall 		char *ptr;
11831467Sminshall 
11931467Sminshall 		ptr = passwd;
12031467Sminshall 		i = 0;
12131467Sminshall 		while (*ptr) {
12231467Sminshall 		    *ptr++ ^= buffer[i++];
12331467Sminshall 		    if (i >= sd.length) {
12431467Sminshall 			i = 0;
12531467Sminshall 		    }
12631467Sminshall 		}
12731467Sminshall 	    }
12831467Sminshall 	    sd.length = htons(passwd_length);
12931493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
13031467Sminshall 		return -1;
13131467Sminshall 	    }
13231467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
13331467Sminshall 		return -1;
13431467Sminshall 	    }
13531467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
13631467Sminshall 		return -1;
13731467Sminshall 	    }
13831467Sminshall 	    break;
13931467Sminshall 	case -1:
14031467Sminshall 	    return -1;
14131467Sminshall 	default:
14231467Sminshall 	    fprintf(stderr,
14331467Sminshall 		    "Waiting for connection indicator, received 0x%x.\n", i);
14431467Sminshall 	    break;
14531467Sminshall 	}
14631467Sminshall     }
14731459Sminshall     /* YEAH */
14831459Sminshall     return 0;		/* Happiness! */
14931459Sminshall }
15031459Sminshall 
15131459Sminshall 
152*31500Sminshall api_exch_api(regs, sregs, parms, length)
15331459Sminshall union REGS *regs;
15431459Sminshall struct SREGS *sregs;
155*31500Sminshall char *parms;
156*31500Sminshall int length;
15731459Sminshall {
15831472Sminshall     struct storage_descriptor sd;
15931472Sminshall     int i;
16031472Sminshall 
16131493Sminshall     if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
16231472Sminshall 	return -1;
16331472Sminshall     }
16431472Sminshall     if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
16531472Sminshall 	return -1;
16631472Sminshall     }
16731472Sminshall     if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
16831472Sminshall 	return -1;
16931472Sminshall     }
170*31500Sminshall     sd.length = htons(length);
171*31500Sminshall     sd.location = htonl(parms);
17231472Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
17331472Sminshall 	return -1;
17431472Sminshall     }
175*31500Sminshall     if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
176*31500Sminshall 	return -1;
177*31500Sminshall     }
17831493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
17931472Sminshall 	switch (i) {
18031493Sminshall 	case EXCH_CMD_GIMME:
18131472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
18231472Sminshall 					== -1) {
18331472Sminshall 		return -1;
18431472Sminshall 	    }
18531472Sminshall 	    /*XXX validity check GIMME? */
18631493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
18731472Sminshall 		return -1;
18831472Sminshall 	    }
18931472Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
19031472Sminshall 				== -1) {
19131472Sminshall 		return -1;
19231472Sminshall 	    }
19331472Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, ntohs(sd.length),
19431472Sminshall 			    ntohl(sd.location)) == -1) {
19531472Sminshall 		return -1;
19631472Sminshall 	    }
19731472Sminshall 	    break;
19831493Sminshall 	case EXCH_CMD_HEREIS:
19931472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
20031472Sminshall 					== -1) {
20131472Sminshall 		return -1;
20231472Sminshall 	    }
20331472Sminshall 	    /* XXX Validty check HEREIS? */
20431472Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, ntohs(sd.length),
20531472Sminshall 			    ntohl(sd.location)) == -1) {
20631472Sminshall 		return -1;
20731472Sminshall 	    }
20831472Sminshall 	    break;
20931472Sminshall 	default:
21031472Sminshall 	    fprintf(stderr, "Waiting for reply command, we got command %d.\n",
21131472Sminshall 			i);
21231472Sminshall 	    return -1;
21331472Sminshall 	}
21431472Sminshall     }
21531472Sminshall     if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
21631472Sminshall 	return -1;
21731472Sminshall     }
21831472Sminshall     if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
21931472Sminshall 	return -1;
22031472Sminshall     }
22131472Sminshall     /* YEAH */
22231472Sminshall     return 0;		/* Happiness! */
22331459Sminshall }
224