xref: /csrg-svn/usr.bin/tn3270/api/api_bsd.c (revision 31869)
131796Sminshall #if	defined(unix)
231796Sminshall 
331459Sminshall #include <sys/types.h>
431459Sminshall #include <sys/socket.h>
531459Sminshall #include <netinet/in.h>
631459Sminshall #include <netdb.h>
731459Sminshall #include <stdio.h>
831459Sminshall 
9*31869Sminshall #include "../ctlr/api.h"
1031467Sminshall #include "api_exch.h"
1131459Sminshall 
1231459Sminshall 
1331493Sminshall int
1431493Sminshall api_close_api()
1531493Sminshall {
1631493Sminshall     if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) {
1731493Sminshall 	return -1;
1831493Sminshall     } else if (api_exch_flush() == -1) {
1931493Sminshall 	return -1;
2031493Sminshall     } else {
2131493Sminshall 	return 0;
2231493Sminshall     }
2331493Sminshall }
2431493Sminshall 
2531493Sminshall 
2631493Sminshall int
2731459Sminshall api_open_api(string)
2831459Sminshall char	*string;		/* if non-zero, where to connect to */
2931459Sminshall {
3031459Sminshall     struct sockaddr_in server;
3131459Sminshall     struct hostent *hp;
3231797Sminshall     struct storage_descriptor sd;
3331459Sminshall     char *getenv();
3431459Sminshall     char thehostname[100];
3531797Sminshall     char keyname[100];
3631797Sminshall     char inkey[100];
3731797Sminshall     FILE *keyfile;
3831467Sminshall     int sock;
3931459Sminshall     int port;
4031467Sminshall     int i;
4131459Sminshall 
4231459Sminshall     if (string == 0) {
4331459Sminshall 	string = getenv("API3270");	/* Get API */
4431459Sminshall 	if (string == 0) {
4531459Sminshall 	    fprintf(stderr,
4631459Sminshall 			"API3270 environmental variable not set - no API.\n");
4731459Sminshall 	    return -1;			/* Nothing */
4831459Sminshall 	}
4931459Sminshall     }
5031459Sminshall 
5131797Sminshall     if (sscanf(string, "%[^:]:%d:%s", thehostname, &port, keyname) != 3) {
5231459Sminshall 	fprintf(stderr, "API3270 environmental variable has bad format.\n");
5331459Sminshall 	return -1;
5431459Sminshall     }
5531459Sminshall     /* Now, try to connect */
5631459Sminshall     sock = socket(AF_INET, SOCK_STREAM, 0);
5731459Sminshall     if (sock < 0) {
5831459Sminshall 	perror("opening API socket");
5931459Sminshall 	return -1;
6031459Sminshall     }
6131459Sminshall     server.sin_family = AF_INET;
6231459Sminshall     hp = gethostbyname(thehostname);
6331459Sminshall     if (hp == 0) {
6431459Sminshall 	fprintf(stderr, "%s specifies bad host name.\n", string);
6531459Sminshall 	return -1;
6631459Sminshall     }
6731459Sminshall     bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
6831459Sminshall     server.sin_port = htons(port);
6931459Sminshall 
7031459Sminshall     if (connect(sock, &server, sizeof server) < 0) {
7131459Sminshall 	perror("connecting to API server");
7231459Sminshall 	return -1;
7331459Sminshall     }
7431467Sminshall     /* Now, try application level connection */
7531493Sminshall     if (api_exch_init(sock, "client") == -1) {
7631467Sminshall 	return -1;
7731467Sminshall     }
7831493Sminshall     if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
7931467Sminshall 	return -1;
8031467Sminshall     }
8131797Sminshall     keyfile = fopen(keyname, "r");
8231797Sminshall     if (keyfile == 0) {
8331797Sminshall 	perror("fopen");
8431797Sminshall 	return -1;
8531797Sminshall     }
8631797Sminshall     if (fscanf(keyfile, "%s\n", inkey) != 1) {
8731797Sminshall 	perror("fscanf");
8831797Sminshall 	return -1;
8931797Sminshall     }
9031797Sminshall     sd.length = strlen(inkey)+1;
9131797Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
9231797Sminshall 	return -1;
9331797Sminshall     }
9431797Sminshall     if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) {
9531797Sminshall 	return -1;
9631797Sminshall     }
9731493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
9831467Sminshall 	int passwd_length;
9931467Sminshall 	char *passwd, *getpass();
10031467Sminshall 	char buffer[200];
10131467Sminshall 
10231467Sminshall 	switch (i) {
10331493Sminshall 	case EXCH_CMD_REJECTED:
10431467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC,
10531467Sminshall 					sizeof sd, (char *)&sd) == -1) {
10631467Sminshall 		return -1;
10731467Sminshall 	    }
10831467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
10931467Sminshall 		return -1;
11031467Sminshall 	    }
11131467Sminshall 	    buffer[sd.length] = 0;
11231467Sminshall 	    fprintf(stderr, "%s\n", buffer);
11331493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
11431467Sminshall 		return -1;
11531467Sminshall 	    }
11631467Sminshall 	    break;
11731493Sminshall 	case EXCH_CMD_SEND_AUTH:
11831467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
11931467Sminshall 		return -1;
12031467Sminshall 	    }
12131467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
12231467Sminshall 		return -1;
12331467Sminshall 	    }
12431467Sminshall 	    buffer[sd.length] = 0;
12531467Sminshall 	    passwd = getpass(buffer);		/* Go to terminal */
12631467Sminshall 	    passwd_length = strlen(passwd);
12731467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
12831467Sminshall 		return -1;
12931467Sminshall 	    }
13031467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
13131467Sminshall 		return -1;
13231467Sminshall 	    }
13331467Sminshall 	    buffer[sd.length] = 0;
13431467Sminshall 	    if (sd.length) {
13531467Sminshall 		char *ptr;
13631467Sminshall 
13731467Sminshall 		ptr = passwd;
13831467Sminshall 		i = 0;
13931467Sminshall 		while (*ptr) {
14031467Sminshall 		    *ptr++ ^= buffer[i++];
14131467Sminshall 		    if (i >= sd.length) {
14231467Sminshall 			i = 0;
14331467Sminshall 		    }
14431467Sminshall 		}
14531467Sminshall 	    }
14631797Sminshall 	    sd.length = passwd_length;
14731493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
14831467Sminshall 		return -1;
14931467Sminshall 	    }
15031467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
15131467Sminshall 		return -1;
15231467Sminshall 	    }
15331467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
15431467Sminshall 		return -1;
15531467Sminshall 	    }
15631467Sminshall 	    break;
15731467Sminshall 	case -1:
15831467Sminshall 	    return -1;
15931467Sminshall 	default:
16031467Sminshall 	    fprintf(stderr,
16131467Sminshall 		    "Waiting for connection indicator, received 0x%x.\n", i);
16231467Sminshall 	    break;
16331467Sminshall 	}
16431467Sminshall     }
16531459Sminshall     /* YEAH */
16631459Sminshall     return 0;		/* Happiness! */
16731459Sminshall }
16831459Sminshall 
16931459Sminshall 
17031500Sminshall api_exch_api(regs, sregs, parms, length)
17131459Sminshall union REGS *regs;
17231459Sminshall struct SREGS *sregs;
17331500Sminshall char *parms;
17431500Sminshall int length;
17531459Sminshall {
17631472Sminshall     struct storage_descriptor sd;
17731472Sminshall     int i;
17831472Sminshall 
17931493Sminshall     if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
18031472Sminshall 	return -1;
18131472Sminshall     }
18231472Sminshall     if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
18331472Sminshall 	return -1;
18431472Sminshall     }
18531472Sminshall     if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
18631472Sminshall 	return -1;
18731472Sminshall     }
18831797Sminshall     sd.length = length;
18931797Sminshall     sd.location = (long) parms;
19031472Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
19131472Sminshall 	return -1;
19231472Sminshall     }
19331500Sminshall     if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
19431500Sminshall 	return -1;
19531500Sminshall     }
19631493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
19731472Sminshall 	switch (i) {
19831493Sminshall 	case EXCH_CMD_GIMME:
19931472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
20031472Sminshall 					== -1) {
20131472Sminshall 		return -1;
20231472Sminshall 	    }
20331472Sminshall 	    /*XXX validity check GIMME? */
20431493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
20531472Sminshall 		return -1;
20631472Sminshall 	    }
20731472Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
20831472Sminshall 				== -1) {
20931472Sminshall 		return -1;
21031472Sminshall 	    }
21131797Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
21231797Sminshall 			    sd.location) == -1) {
21331472Sminshall 		return -1;
21431472Sminshall 	    }
21531472Sminshall 	    break;
21631493Sminshall 	case EXCH_CMD_HEREIS:
21731472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
21831472Sminshall 					== -1) {
21931472Sminshall 		return -1;
22031472Sminshall 	    }
22131472Sminshall 	    /* XXX Validty check HEREIS? */
22231797Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
22331797Sminshall 			    sd.location) == -1) {
22431472Sminshall 		return -1;
22531472Sminshall 	    }
22631472Sminshall 	    break;
22731472Sminshall 	default:
22831472Sminshall 	    fprintf(stderr, "Waiting for reply command, we got command %d.\n",
22931472Sminshall 			i);
23031472Sminshall 	    return -1;
23131472Sminshall 	}
23231472Sminshall     }
23331472Sminshall     if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
23431472Sminshall 	return -1;
23531472Sminshall     }
23631472Sminshall     if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
23731472Sminshall 	return -1;
23831472Sminshall     }
23931472Sminshall     /* YEAH */
24031472Sminshall     return 0;		/* Happiness! */
24131459Sminshall }
24231796Sminshall 
24331796Sminshall #endif	/* unix */
244