xref: /csrg-svn/usr.bin/tn3270/api/api_bsd.c (revision 31890)
1*31890Sminshall /*
2*31890Sminshall  *	Copyright (c) 1984-1987 by the Regents of the
3*31890Sminshall  *	University of California and by Gregory Glenn Minshall.
4*31890Sminshall  *
5*31890Sminshall  *	Permission to use, copy, modify, and distribute these
6*31890Sminshall  *	programs and their documentation for any purpose and
7*31890Sminshall  *	without fee is hereby granted, provided that this
8*31890Sminshall  *	copyright and permission appear on all copies and
9*31890Sminshall  *	supporting documentation, the name of the Regents of
10*31890Sminshall  *	the University of California not be used in advertising
11*31890Sminshall  *	or publicity pertaining to distribution of the programs
12*31890Sminshall  *	without specific prior permission, and notice be given in
13*31890Sminshall  *	supporting documentation that copying and distribution is
14*31890Sminshall  *	by permission of the Regents of the University of California
15*31890Sminshall  *	and by Gregory Glenn Minshall.  Neither the Regents of the
16*31890Sminshall  *	University of California nor Gregory Glenn Minshall make
17*31890Sminshall  *	representations about the suitability of this software
18*31890Sminshall  *	for any purpose.  It is provided "as is" without
19*31890Sminshall  *	express or implied warranty.
20*31890Sminshall  */
21*31890Sminshall 
22*31890Sminshall #ifndef lint
23*31890Sminshall static char sccsid[] = "@(#)api_bsd.c	1.9 (Berkeley) 07/17/87";
24*31890Sminshall #endif	/* not lint */
25*31890Sminshall 
2631796Sminshall #if	defined(unix)
2731796Sminshall 
2831459Sminshall #include <sys/types.h>
2931459Sminshall #include <sys/socket.h>
3031459Sminshall #include <netinet/in.h>
3131459Sminshall #include <netdb.h>
3231459Sminshall #include <stdio.h>
3331459Sminshall 
3431869Sminshall #include "../ctlr/api.h"
3531467Sminshall #include "api_exch.h"
3631459Sminshall 
3731459Sminshall 
3831493Sminshall int
3931493Sminshall api_close_api()
4031493Sminshall {
4131493Sminshall     if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) {
4231493Sminshall 	return -1;
4331493Sminshall     } else if (api_exch_flush() == -1) {
4431493Sminshall 	return -1;
4531493Sminshall     } else {
4631493Sminshall 	return 0;
4731493Sminshall     }
4831493Sminshall }
4931493Sminshall 
5031493Sminshall 
5131493Sminshall int
5231459Sminshall api_open_api(string)
5331459Sminshall char	*string;		/* if non-zero, where to connect to */
5431459Sminshall {
5531459Sminshall     struct sockaddr_in server;
5631459Sminshall     struct hostent *hp;
5731797Sminshall     struct storage_descriptor sd;
5831459Sminshall     char *getenv();
5931459Sminshall     char thehostname[100];
6031797Sminshall     char keyname[100];
6131797Sminshall     char inkey[100];
6231797Sminshall     FILE *keyfile;
6331467Sminshall     int sock;
6431459Sminshall     int port;
6531467Sminshall     int i;
6631459Sminshall 
6731459Sminshall     if (string == 0) {
6831459Sminshall 	string = getenv("API3270");	/* Get API */
6931459Sminshall 	if (string == 0) {
7031459Sminshall 	    fprintf(stderr,
7131459Sminshall 			"API3270 environmental variable not set - no API.\n");
7231459Sminshall 	    return -1;			/* Nothing */
7331459Sminshall 	}
7431459Sminshall     }
7531459Sminshall 
7631797Sminshall     if (sscanf(string, "%[^:]:%d:%s", thehostname, &port, keyname) != 3) {
7731459Sminshall 	fprintf(stderr, "API3270 environmental variable has bad format.\n");
7831459Sminshall 	return -1;
7931459Sminshall     }
8031459Sminshall     /* Now, try to connect */
8131459Sminshall     sock = socket(AF_INET, SOCK_STREAM, 0);
8231459Sminshall     if (sock < 0) {
8331459Sminshall 	perror("opening API socket");
8431459Sminshall 	return -1;
8531459Sminshall     }
8631459Sminshall     server.sin_family = AF_INET;
8731459Sminshall     hp = gethostbyname(thehostname);
8831459Sminshall     if (hp == 0) {
8931459Sminshall 	fprintf(stderr, "%s specifies bad host name.\n", string);
9031459Sminshall 	return -1;
9131459Sminshall     }
9231459Sminshall     bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
9331459Sminshall     server.sin_port = htons(port);
9431459Sminshall 
9531459Sminshall     if (connect(sock, &server, sizeof server) < 0) {
9631459Sminshall 	perror("connecting to API server");
9731459Sminshall 	return -1;
9831459Sminshall     }
9931467Sminshall     /* Now, try application level connection */
10031493Sminshall     if (api_exch_init(sock, "client") == -1) {
10131467Sminshall 	return -1;
10231467Sminshall     }
10331493Sminshall     if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
10431467Sminshall 	return -1;
10531467Sminshall     }
10631797Sminshall     keyfile = fopen(keyname, "r");
10731797Sminshall     if (keyfile == 0) {
10831797Sminshall 	perror("fopen");
10931797Sminshall 	return -1;
11031797Sminshall     }
11131797Sminshall     if (fscanf(keyfile, "%s\n", inkey) != 1) {
11231797Sminshall 	perror("fscanf");
11331797Sminshall 	return -1;
11431797Sminshall     }
11531797Sminshall     sd.length = strlen(inkey)+1;
11631797Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
11731797Sminshall 	return -1;
11831797Sminshall     }
11931797Sminshall     if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) {
12031797Sminshall 	return -1;
12131797Sminshall     }
12231493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
12331467Sminshall 	int passwd_length;
12431467Sminshall 	char *passwd, *getpass();
12531467Sminshall 	char buffer[200];
12631467Sminshall 
12731467Sminshall 	switch (i) {
12831493Sminshall 	case EXCH_CMD_REJECTED:
12931467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC,
13031467Sminshall 					sizeof sd, (char *)&sd) == -1) {
13131467Sminshall 		return -1;
13231467Sminshall 	    }
13331467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
13431467Sminshall 		return -1;
13531467Sminshall 	    }
13631467Sminshall 	    buffer[sd.length] = 0;
13731467Sminshall 	    fprintf(stderr, "%s\n", buffer);
13831493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
13931467Sminshall 		return -1;
14031467Sminshall 	    }
14131467Sminshall 	    break;
14231493Sminshall 	case EXCH_CMD_SEND_AUTH:
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 	    passwd = getpass(buffer);		/* Go to terminal */
15131467Sminshall 	    passwd_length = strlen(passwd);
15231467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
15331467Sminshall 		return -1;
15431467Sminshall 	    }
15531467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
15631467Sminshall 		return -1;
15731467Sminshall 	    }
15831467Sminshall 	    buffer[sd.length] = 0;
15931467Sminshall 	    if (sd.length) {
16031467Sminshall 		char *ptr;
16131467Sminshall 
16231467Sminshall 		ptr = passwd;
16331467Sminshall 		i = 0;
16431467Sminshall 		while (*ptr) {
16531467Sminshall 		    *ptr++ ^= buffer[i++];
16631467Sminshall 		    if (i >= sd.length) {
16731467Sminshall 			i = 0;
16831467Sminshall 		    }
16931467Sminshall 		}
17031467Sminshall 	    }
17131797Sminshall 	    sd.length = passwd_length;
17231493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
17331467Sminshall 		return -1;
17431467Sminshall 	    }
17531467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
17631467Sminshall 		return -1;
17731467Sminshall 	    }
17831467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
17931467Sminshall 		return -1;
18031467Sminshall 	    }
18131467Sminshall 	    break;
18231467Sminshall 	case -1:
18331467Sminshall 	    return -1;
18431467Sminshall 	default:
18531467Sminshall 	    fprintf(stderr,
18631467Sminshall 		    "Waiting for connection indicator, received 0x%x.\n", i);
18731467Sminshall 	    break;
18831467Sminshall 	}
18931467Sminshall     }
19031459Sminshall     /* YEAH */
19131459Sminshall     return 0;		/* Happiness! */
19231459Sminshall }
19331459Sminshall 
19431459Sminshall 
19531500Sminshall api_exch_api(regs, sregs, parms, length)
19631459Sminshall union REGS *regs;
19731459Sminshall struct SREGS *sregs;
19831500Sminshall char *parms;
19931500Sminshall int length;
20031459Sminshall {
20131472Sminshall     struct storage_descriptor sd;
20231472Sminshall     int i;
20331472Sminshall 
20431493Sminshall     if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
20531472Sminshall 	return -1;
20631472Sminshall     }
20731472Sminshall     if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
20831472Sminshall 	return -1;
20931472Sminshall     }
21031472Sminshall     if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
21131472Sminshall 	return -1;
21231472Sminshall     }
21331797Sminshall     sd.length = length;
21431797Sminshall     sd.location = (long) parms;
21531472Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
21631472Sminshall 	return -1;
21731472Sminshall     }
21831500Sminshall     if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
21931500Sminshall 	return -1;
22031500Sminshall     }
22131493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
22231472Sminshall 	switch (i) {
22331493Sminshall 	case EXCH_CMD_GIMME:
22431472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
22531472Sminshall 					== -1) {
22631472Sminshall 		return -1;
22731472Sminshall 	    }
22831472Sminshall 	    /*XXX validity check GIMME? */
22931493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
23031472Sminshall 		return -1;
23131472Sminshall 	    }
23231472Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
23331472Sminshall 				== -1) {
23431472Sminshall 		return -1;
23531472Sminshall 	    }
23631797Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
23731797Sminshall 			    sd.location) == -1) {
23831472Sminshall 		return -1;
23931472Sminshall 	    }
24031472Sminshall 	    break;
24131493Sminshall 	case EXCH_CMD_HEREIS:
24231472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
24331472Sminshall 					== -1) {
24431472Sminshall 		return -1;
24531472Sminshall 	    }
24631472Sminshall 	    /* XXX Validty check HEREIS? */
24731797Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
24831797Sminshall 			    sd.location) == -1) {
24931472Sminshall 		return -1;
25031472Sminshall 	    }
25131472Sminshall 	    break;
25231472Sminshall 	default:
25331472Sminshall 	    fprintf(stderr, "Waiting for reply command, we got command %d.\n",
25431472Sminshall 			i);
25531472Sminshall 	    return -1;
25631472Sminshall 	}
25731472Sminshall     }
25831472Sminshall     if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
25931472Sminshall 	return -1;
26031472Sminshall     }
26131472Sminshall     if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
26231472Sminshall 	return -1;
26331472Sminshall     }
26431472Sminshall     /* YEAH */
26531472Sminshall     return 0;		/* Happiness! */
26631459Sminshall }
26731796Sminshall 
26831796Sminshall #endif	/* unix */
269