xref: /csrg-svn/usr.bin/tn3270/api/api_bsd.c (revision 35418)
131890Sminshall /*
233820Sbostic  * Copyright (c) 1988 Regents of the University of California.
333820Sbostic  * All rights reserved.
431890Sminshall  *
533820Sbostic  * Redistribution and use in source and binary forms are permitted
634888Sbostic  * provided that the above copyright notice and this paragraph are
734888Sbostic  * duplicated in all such forms and that any documentation,
834888Sbostic  * advertising materials, and other materials related to such
934888Sbostic  * distribution and use acknowledge that the software was developed
1034888Sbostic  * by the University of California, Berkeley.  The name of the
1134888Sbostic  * University may not be used to endorse or promote products derived
1234888Sbostic  * from this software without specific prior written permission.
1334888Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434888Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534888Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1631890Sminshall  */
1731890Sminshall 
1831890Sminshall #ifndef lint
19*35418Sminshall static char sccsid[] = "@(#)api_bsd.c	3.4 (Berkeley) 08/28/88";
2033820Sbostic #endif /* not lint */
2131890Sminshall 
2231796Sminshall #if	defined(unix)
2331796Sminshall 
2431459Sminshall #include <sys/types.h>
2531459Sminshall #include <sys/socket.h>
2631459Sminshall #include <netinet/in.h>
2731459Sminshall #include <netdb.h>
2831459Sminshall #include <stdio.h>
2931459Sminshall 
3031869Sminshall #include "../ctlr/api.h"
3131467Sminshall #include "api_exch.h"
3231459Sminshall 
3331459Sminshall 
3431493Sminshall int
3531493Sminshall api_close_api()
3631493Sminshall {
3731493Sminshall     if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) {
3831493Sminshall 	return -1;
3931493Sminshall     } else if (api_exch_flush() == -1) {
4031493Sminshall 	return -1;
4131493Sminshall     } else {
4231493Sminshall 	return 0;
4331493Sminshall     }
4431493Sminshall }
4531493Sminshall 
4631493Sminshall 
4731493Sminshall int
4831459Sminshall api_open_api(string)
4931459Sminshall char	*string;		/* if non-zero, where to connect to */
5031459Sminshall {
5131459Sminshall     struct sockaddr_in server;
5231459Sminshall     struct hostent *hp;
5331797Sminshall     struct storage_descriptor sd;
54*35418Sminshall     extern char *getenv();
55*35418Sminshall     extern unsigned short htons();
5631459Sminshall     char thehostname[100];
5731797Sminshall     char keyname[100];
5831797Sminshall     char inkey[100];
5931797Sminshall     FILE *keyfile;
6031467Sminshall     int sock;
61*35418Sminshall     unsigned int port;
6231467Sminshall     int i;
6331459Sminshall 
6431459Sminshall     if (string == 0) {
6531459Sminshall 	string = getenv("API3270");	/* Get API */
6631459Sminshall 	if (string == 0) {
6731459Sminshall 	    fprintf(stderr,
6831459Sminshall 			"API3270 environmental variable not set - no API.\n");
6931459Sminshall 	    return -1;			/* Nothing */
7031459Sminshall 	}
7131459Sminshall     }
7231459Sminshall 
73*35418Sminshall     if (sscanf(string, "%[^:]:%d:%s", thehostname,
74*35418Sminshall 				(int *)&port, keyname) != 3) {
7531459Sminshall 	fprintf(stderr, "API3270 environmental variable has bad format.\n");
7631459Sminshall 	return -1;
7731459Sminshall     }
7831459Sminshall     /* Now, try to connect */
7931459Sminshall     sock = socket(AF_INET, SOCK_STREAM, 0);
8031459Sminshall     if (sock < 0) {
8131459Sminshall 	perror("opening API socket");
8231459Sminshall 	return -1;
8331459Sminshall     }
8431459Sminshall     server.sin_family = AF_INET;
8531459Sminshall     hp = gethostbyname(thehostname);
8631459Sminshall     if (hp == 0) {
8731459Sminshall 	fprintf(stderr, "%s specifies bad host name.\n", string);
8831459Sminshall 	return -1;
8931459Sminshall     }
90*35418Sminshall     bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
9131459Sminshall     server.sin_port = htons(port);
9231459Sminshall 
93*35418Sminshall     if (connect(sock, (struct sockaddr *)&server, sizeof server) < 0) {
9431459Sminshall 	perror("connecting to API server");
9531459Sminshall 	return -1;
9631459Sminshall     }
9731467Sminshall     /* Now, try application level connection */
9831493Sminshall     if (api_exch_init(sock, "client") == -1) {
9931467Sminshall 	return -1;
10031467Sminshall     }
10131493Sminshall     if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
10231467Sminshall 	return -1;
10331467Sminshall     }
10431797Sminshall     keyfile = fopen(keyname, "r");
10531797Sminshall     if (keyfile == 0) {
10631797Sminshall 	perror("fopen");
10731797Sminshall 	return -1;
10831797Sminshall     }
10931797Sminshall     if (fscanf(keyfile, "%s\n", inkey) != 1) {
11031797Sminshall 	perror("fscanf");
11131797Sminshall 	return -1;
11231797Sminshall     }
11331797Sminshall     sd.length = strlen(inkey)+1;
11431797Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
11531797Sminshall 	return -1;
11631797Sminshall     }
11731797Sminshall     if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) {
11831797Sminshall 	return -1;
11931797Sminshall     }
12031493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
12131467Sminshall 	int passwd_length;
12231467Sminshall 	char *passwd, *getpass();
12331467Sminshall 	char buffer[200];
12431467Sminshall 
12531467Sminshall 	switch (i) {
12631493Sminshall 	case EXCH_CMD_REJECTED:
12731467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC,
12831467Sminshall 					sizeof sd, (char *)&sd) == -1) {
12931467Sminshall 		return -1;
13031467Sminshall 	    }
13131467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
13231467Sminshall 		return -1;
13331467Sminshall 	    }
13431467Sminshall 	    buffer[sd.length] = 0;
13531467Sminshall 	    fprintf(stderr, "%s\n", buffer);
13631493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
13731467Sminshall 		return -1;
13831467Sminshall 	    }
13931467Sminshall 	    break;
14031493Sminshall 	case EXCH_CMD_SEND_AUTH:
14131467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
14231467Sminshall 		return -1;
14331467Sminshall 	    }
14431467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
14531467Sminshall 		return -1;
14631467Sminshall 	    }
14731467Sminshall 	    buffer[sd.length] = 0;
14831467Sminshall 	    passwd = getpass(buffer);		/* Go to terminal */
14931467Sminshall 	    passwd_length = strlen(passwd);
15031467Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
15131467Sminshall 		return -1;
15231467Sminshall 	    }
15331467Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
15431467Sminshall 		return -1;
15531467Sminshall 	    }
15631467Sminshall 	    buffer[sd.length] = 0;
15731467Sminshall 	    if (sd.length) {
15831467Sminshall 		char *ptr;
15931467Sminshall 
16031467Sminshall 		ptr = passwd;
16131467Sminshall 		i = 0;
16231467Sminshall 		while (*ptr) {
16331467Sminshall 		    *ptr++ ^= buffer[i++];
16431467Sminshall 		    if (i >= sd.length) {
16531467Sminshall 			i = 0;
16631467Sminshall 		    }
16731467Sminshall 		}
16831467Sminshall 	    }
16931797Sminshall 	    sd.length = passwd_length;
17031493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
17131467Sminshall 		return -1;
17231467Sminshall 	    }
17331467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
17431467Sminshall 		return -1;
17531467Sminshall 	    }
17631467Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
17731467Sminshall 		return -1;
17831467Sminshall 	    }
17931467Sminshall 	    break;
18031467Sminshall 	case -1:
18131467Sminshall 	    return -1;
18231467Sminshall 	default:
18331467Sminshall 	    fprintf(stderr,
18431467Sminshall 		    "Waiting for connection indicator, received 0x%x.\n", i);
18531467Sminshall 	    break;
18631467Sminshall 	}
18731467Sminshall     }
18831459Sminshall     /* YEAH */
18931459Sminshall     return 0;		/* Happiness! */
19031459Sminshall }
19131459Sminshall 
19231459Sminshall 
19331500Sminshall api_exch_api(regs, sregs, parms, length)
19431459Sminshall union REGS *regs;
19531459Sminshall struct SREGS *sregs;
19631500Sminshall char *parms;
19731500Sminshall int length;
19831459Sminshall {
19931472Sminshall     struct storage_descriptor sd;
20031472Sminshall     int i;
20131472Sminshall 
20231493Sminshall     if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
20331472Sminshall 	return -1;
20431472Sminshall     }
20531472Sminshall     if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
20631472Sminshall 	return -1;
20731472Sminshall     }
20831472Sminshall     if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
20931472Sminshall 	return -1;
21031472Sminshall     }
21131797Sminshall     sd.length = length;
21231797Sminshall     sd.location = (long) parms;
21331472Sminshall     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
21431472Sminshall 	return -1;
21531472Sminshall     }
21631500Sminshall     if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
21731500Sminshall 	return -1;
21831500Sminshall     }
21931493Sminshall     while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
22031472Sminshall 	switch (i) {
22131493Sminshall 	case EXCH_CMD_GIMME:
22231472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
22331472Sminshall 					== -1) {
22431472Sminshall 		return -1;
22531472Sminshall 	    }
22631472Sminshall 	    /*XXX validity check GIMME? */
22731493Sminshall 	    if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
22831472Sminshall 		return -1;
22931472Sminshall 	    }
23031472Sminshall 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
23131472Sminshall 				== -1) {
23231472Sminshall 		return -1;
23331472Sminshall 	    }
23431797Sminshall 	    if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
235*35418Sminshall 			    (char *)sd.location) == -1) {
23631472Sminshall 		return -1;
23731472Sminshall 	    }
23831472Sminshall 	    break;
23931493Sminshall 	case EXCH_CMD_HEREIS:
24031472Sminshall 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
24131472Sminshall 					== -1) {
24231472Sminshall 		return -1;
24331472Sminshall 	    }
24431472Sminshall 	    /* XXX Validty check HEREIS? */
24531797Sminshall 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
246*35418Sminshall 			    (char *)sd.location) == -1) {
24731472Sminshall 		return -1;
24831472Sminshall 	    }
24931472Sminshall 	    break;
25031472Sminshall 	default:
25131472Sminshall 	    fprintf(stderr, "Waiting for reply command, we got command %d.\n",
25231472Sminshall 			i);
25331472Sminshall 	    return -1;
25431472Sminshall 	}
25531472Sminshall     }
25631472Sminshall     if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
25731472Sminshall 	return -1;
25831472Sminshall     }
25931472Sminshall     if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
26031472Sminshall 	return -1;
26131472Sminshall     }
26231472Sminshall     /* YEAH */
26331472Sminshall     return 0;		/* Happiness! */
26431459Sminshall }
26531796Sminshall 
26631796Sminshall #endif	/* unix */
267