xref: /csrg-svn/usr.bin/tn3270/api/api_bsd.c (revision 33820)
131890Sminshall /*
2*33820Sbostic  * Copyright (c) 1988 Regents of the University of California.
3*33820Sbostic  * All rights reserved.
431890Sminshall  *
5*33820Sbostic  * Redistribution and use in source and binary forms are permitted
6*33820Sbostic  * provided that this notice is preserved and that due credit is given
7*33820Sbostic  * to the University of California at Berkeley. The name of the University
8*33820Sbostic  * may not be used to endorse or promote products derived from this
9*33820Sbostic  * software without specific prior written permission. This software
10*33820Sbostic  * is provided ``as is'' without express or implied warranty.
1131890Sminshall  */
1231890Sminshall 
1331890Sminshall #ifndef lint
14*33820Sbostic static char sccsid[] = "@(#)api_bsd.c	3.2 (Berkeley) 03/28/88";
15*33820Sbostic #endif /* not lint */
1631890Sminshall 
1731796Sminshall #if	defined(unix)
1831796Sminshall 
1931459Sminshall #include <sys/types.h>
2031459Sminshall #include <sys/socket.h>
2131459Sminshall #include <netinet/in.h>
2231459Sminshall #include <netdb.h>
2331459Sminshall #include <stdio.h>
2431459Sminshall 
2531869Sminshall #include "../ctlr/api.h"
2631467Sminshall #include "api_exch.h"
2731459Sminshall 
2831459Sminshall 
2931493Sminshall int
3031493Sminshall api_close_api()
3131493Sminshall {
3231493Sminshall     if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) {
3331493Sminshall 	return -1;
3431493Sminshall     } else if (api_exch_flush() == -1) {
3531493Sminshall 	return -1;
3631493Sminshall     } else {
3731493Sminshall 	return 0;
3831493Sminshall     }
3931493Sminshall }
4031493Sminshall 
4131493Sminshall 
4231493Sminshall int
4331459Sminshall api_open_api(string)
4431459Sminshall char	*string;		/* if non-zero, where to connect to */
4531459Sminshall {
4631459Sminshall     struct sockaddr_in server;
4731459Sminshall     struct hostent *hp;
4831797Sminshall     struct storage_descriptor sd;
4931459Sminshall     char *getenv();
5031459Sminshall     char thehostname[100];
5131797Sminshall     char keyname[100];
5231797Sminshall     char inkey[100];
5331797Sminshall     FILE *keyfile;
5431467Sminshall     int sock;
5531459Sminshall     int port;
5631467Sminshall     int i;
5731459Sminshall 
5831459Sminshall     if (string == 0) {
5931459Sminshall 	string = getenv("API3270");	/* Get API */
6031459Sminshall 	if (string == 0) {
6131459Sminshall 	    fprintf(stderr,
6231459Sminshall 			"API3270 environmental variable not set - no API.\n");
6331459Sminshall 	    return -1;			/* Nothing */
6431459Sminshall 	}
6531459Sminshall     }
6631459Sminshall 
6731797Sminshall     if (sscanf(string, "%[^:]:%d:%s", thehostname, &port, keyname) != 3) {
6831459Sminshall 	fprintf(stderr, "API3270 environmental variable has bad format.\n");
6931459Sminshall 	return -1;
7031459Sminshall     }
7131459Sminshall     /* Now, try to connect */
7231459Sminshall     sock = socket(AF_INET, SOCK_STREAM, 0);
7331459Sminshall     if (sock < 0) {
7431459Sminshall 	perror("opening API socket");
7531459Sminshall 	return -1;
7631459Sminshall     }
7731459Sminshall     server.sin_family = AF_INET;
7831459Sminshall     hp = gethostbyname(thehostname);
7931459Sminshall     if (hp == 0) {
8031459Sminshall 	fprintf(stderr, "%s specifies bad host name.\n", string);
8131459Sminshall 	return -1;
8231459Sminshall     }
8331459Sminshall     bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
8431459Sminshall     server.sin_port = htons(port);
8531459Sminshall 
8631459Sminshall     if (connect(sock, &server, sizeof server) < 0) {
8731459Sminshall 	perror("connecting to API server");
8831459Sminshall 	return -1;
8931459Sminshall     }
9031467Sminshall     /* Now, try application level connection */
9131493Sminshall     if (api_exch_init(sock, "client") == -1) {
9231467Sminshall 	return -1;
9331467Sminshall     }
9431493Sminshall     if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
9531467Sminshall 	return -1;
9631467Sminshall     }
9731797Sminshall     keyfile = fopen(keyname, "r");
9831797Sminshall     if (keyfile == 0) {
9931797Sminshall 	perror("fopen");
10031797Sminshall 	return -1;
10131797Sminshall     }
10231797Sminshall     if (fscanf(keyfile, "%s\n", inkey) != 1) {
10331797Sminshall 	perror("fscanf");
10431797Sminshall 	return -1;
10531797Sminshall     }
10631797Sminshall     sd.length = strlen(inkey)+1;
10731797Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
10831797Sminshall 	return -1;
10931797Sminshall     }
11031797Sminshall     if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) {
11131797Sminshall 	return -1;
11231797Sminshall     }
11331493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
11431467Sminshall 	int passwd_length;
11531467Sminshall 	char *passwd, *getpass();
11631467Sminshall 	char buffer[200];
11731467Sminshall 
11831467Sminshall 	switch (i) {
11931493Sminshall 	case EXCH_CMD_REJECTED:
12031467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC,
12131467Sminshall 					sizeof sd, (char *)&sd) == -1) {
12231467Sminshall 		return -1;
12331467Sminshall 	    }
12431467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
12531467Sminshall 		return -1;
12631467Sminshall 	    }
12731467Sminshall 	    buffer[sd.length] = 0;
12831467Sminshall 	    fprintf(stderr, "%s\n", buffer);
12931493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
13031467Sminshall 		return -1;
13131467Sminshall 	    }
13231467Sminshall 	    break;
13331493Sminshall 	case EXCH_CMD_SEND_AUTH:
13431467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
13531467Sminshall 		return -1;
13631467Sminshall 	    }
13731467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
13831467Sminshall 		return -1;
13931467Sminshall 	    }
14031467Sminshall 	    buffer[sd.length] = 0;
14131467Sminshall 	    passwd = getpass(buffer);		/* Go to terminal */
14231467Sminshall 	    passwd_length = strlen(passwd);
14331467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
14431467Sminshall 		return -1;
14531467Sminshall 	    }
14631467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
14731467Sminshall 		return -1;
14831467Sminshall 	    }
14931467Sminshall 	    buffer[sd.length] = 0;
15031467Sminshall 	    if (sd.length) {
15131467Sminshall 		char *ptr;
15231467Sminshall 
15331467Sminshall 		ptr = passwd;
15431467Sminshall 		i = 0;
15531467Sminshall 		while (*ptr) {
15631467Sminshall 		    *ptr++ ^= buffer[i++];
15731467Sminshall 		    if (i >= sd.length) {
15831467Sminshall 			i = 0;
15931467Sminshall 		    }
16031467Sminshall 		}
16131467Sminshall 	    }
16231797Sminshall 	    sd.length = passwd_length;
16331493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
16431467Sminshall 		return -1;
16531467Sminshall 	    }
16631467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
16731467Sminshall 		return -1;
16831467Sminshall 	    }
16931467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
17031467Sminshall 		return -1;
17131467Sminshall 	    }
17231467Sminshall 	    break;
17331467Sminshall 	case -1:
17431467Sminshall 	    return -1;
17531467Sminshall 	default:
17631467Sminshall 	    fprintf(stderr,
17731467Sminshall 		    "Waiting for connection indicator, received 0x%x.\n", i);
17831467Sminshall 	    break;
17931467Sminshall 	}
18031467Sminshall     }
18131459Sminshall     /* YEAH */
18231459Sminshall     return 0;		/* Happiness! */
18331459Sminshall }
18431459Sminshall 
18531459Sminshall 
18631500Sminshall api_exch_api(regs, sregs, parms, length)
18731459Sminshall union REGS *regs;
18831459Sminshall struct SREGS *sregs;
18931500Sminshall char *parms;
19031500Sminshall int length;
19131459Sminshall {
19231472Sminshall     struct storage_descriptor sd;
19331472Sminshall     int i;
19431472Sminshall 
19531493Sminshall     if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
19631472Sminshall 	return -1;
19731472Sminshall     }
19831472Sminshall     if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
19931472Sminshall 	return -1;
20031472Sminshall     }
20131472Sminshall     if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
20231472Sminshall 	return -1;
20331472Sminshall     }
20431797Sminshall     sd.length = length;
20531797Sminshall     sd.location = (long) parms;
20631472Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
20731472Sminshall 	return -1;
20831472Sminshall     }
20931500Sminshall     if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
21031500Sminshall 	return -1;
21131500Sminshall     }
21231493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
21331472Sminshall 	switch (i) {
21431493Sminshall 	case EXCH_CMD_GIMME:
21531472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
21631472Sminshall 					== -1) {
21731472Sminshall 		return -1;
21831472Sminshall 	    }
21931472Sminshall 	    /*XXX validity check GIMME? */
22031493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
22131472Sminshall 		return -1;
22231472Sminshall 	    }
22331472Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
22431472Sminshall 				== -1) {
22531472Sminshall 		return -1;
22631472Sminshall 	    }
22731797Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
22831797Sminshall 			    sd.location) == -1) {
22931472Sminshall 		return -1;
23031472Sminshall 	    }
23131472Sminshall 	    break;
23231493Sminshall 	case EXCH_CMD_HEREIS:
23331472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
23431472Sminshall 					== -1) {
23531472Sminshall 		return -1;
23631472Sminshall 	    }
23731472Sminshall 	    /* XXX Validty check HEREIS? */
23831797Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
23931797Sminshall 			    sd.location) == -1) {
24031472Sminshall 		return -1;
24131472Sminshall 	    }
24231472Sminshall 	    break;
24331472Sminshall 	default:
24431472Sminshall 	    fprintf(stderr, "Waiting for reply command, we got command %d.\n",
24531472Sminshall 			i);
24631472Sminshall 	    return -1;
24731472Sminshall 	}
24831472Sminshall     }
24931472Sminshall     if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
25031472Sminshall 	return -1;
25131472Sminshall     }
25231472Sminshall     if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
25331472Sminshall 	return -1;
25431472Sminshall     }
25531472Sminshall     /* YEAH */
25631472Sminshall     return 0;		/* Happiness! */
25731459Sminshall }
25831796Sminshall 
25931796Sminshall #endif	/* unix */
260