148754Sbostic /*-
262317Sbostic * Copyright (c) 1988, 1993
362317Sbostic * The Regents of the University of California. All rights reserved.
431890Sminshall *
548754Sbostic * %sccs.include.redist.c%
631890Sminshall */
731890Sminshall
831890Sminshall #ifndef lint
9*65559Sbostic static char sccsid[] = "@(#)api_bsd.c 8.2 (Berkeley) 01/07/94";
1033820Sbostic #endif /* not lint */
1131890Sminshall
1231796Sminshall #if defined(unix)
1331796Sminshall
1431459Sminshall #include <sys/types.h>
1531459Sminshall #include <sys/socket.h>
1631459Sminshall #include <netinet/in.h>
1731459Sminshall #include <netdb.h>
1831459Sminshall #include <stdio.h>
1931459Sminshall
2031869Sminshall #include "../ctlr/api.h"
2131467Sminshall #include "api_exch.h"
2231459Sminshall
2331459Sminshall
2431493Sminshall int
api_close_api()2531493Sminshall api_close_api()
2631493Sminshall {
2731493Sminshall if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) {
2831493Sminshall return -1;
2931493Sminshall } else if (api_exch_flush() == -1) {
3031493Sminshall return -1;
3131493Sminshall } else {
3231493Sminshall return 0;
3331493Sminshall }
3431493Sminshall }
3531493Sminshall
3631493Sminshall
3731493Sminshall int
api_open_api(string)3831459Sminshall api_open_api(string)
3931459Sminshall char *string; /* if non-zero, where to connect to */
4031459Sminshall {
4131459Sminshall struct sockaddr_in server;
4231459Sminshall struct hostent *hp;
4331797Sminshall struct storage_descriptor sd;
4435418Sminshall extern char *getenv();
4531459Sminshall char thehostname[100];
4631797Sminshall char keyname[100];
4731797Sminshall char inkey[100];
4831797Sminshall FILE *keyfile;
4931467Sminshall int sock;
5035418Sminshall unsigned int port;
5131467Sminshall int i;
5231459Sminshall
5331459Sminshall if (string == 0) {
5431459Sminshall string = getenv("API3270"); /* Get API */
5531459Sminshall if (string == 0) {
5631459Sminshall fprintf(stderr,
5731459Sminshall "API3270 environmental variable not set - no API.\n");
5831459Sminshall return -1; /* Nothing */
5931459Sminshall }
6031459Sminshall }
6131459Sminshall
6235418Sminshall if (sscanf(string, "%[^:]:%d:%s", thehostname,
6335418Sminshall (int *)&port, keyname) != 3) {
6431459Sminshall fprintf(stderr, "API3270 environmental variable has bad format.\n");
6531459Sminshall return -1;
6631459Sminshall }
6731459Sminshall /* Now, try to connect */
6831459Sminshall sock = socket(AF_INET, SOCK_STREAM, 0);
6931459Sminshall if (sock < 0) {
7031459Sminshall perror("opening API socket");
7131459Sminshall return -1;
7231459Sminshall }
7331459Sminshall server.sin_family = AF_INET;
7431459Sminshall hp = gethostbyname(thehostname);
7531459Sminshall if (hp == 0) {
7631459Sminshall fprintf(stderr, "%s specifies bad host name.\n", string);
7731459Sminshall return -1;
7831459Sminshall }
7935418Sminshall bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
8031459Sminshall server.sin_port = htons(port);
8131459Sminshall
8235418Sminshall if (connect(sock, (struct sockaddr *)&server, sizeof server) < 0) {
8331459Sminshall perror("connecting to API server");
8431459Sminshall return -1;
8531459Sminshall }
8631467Sminshall /* Now, try application level connection */
8731493Sminshall if (api_exch_init(sock, "client") == -1) {
8831467Sminshall return -1;
8931467Sminshall }
9031493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
9131467Sminshall return -1;
9231467Sminshall }
9331797Sminshall keyfile = fopen(keyname, "r");
9431797Sminshall if (keyfile == 0) {
9531797Sminshall perror("fopen");
9631797Sminshall return -1;
9731797Sminshall }
9831797Sminshall if (fscanf(keyfile, "%s\n", inkey) != 1) {
9931797Sminshall perror("fscanf");
10031797Sminshall return -1;
10131797Sminshall }
10231797Sminshall sd.length = strlen(inkey)+1;
10331797Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
10431797Sminshall return -1;
10531797Sminshall }
10631797Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) {
10731797Sminshall return -1;
10831797Sminshall }
10931493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
11031467Sminshall int passwd_length;
11131467Sminshall char *passwd, *getpass();
11231467Sminshall char buffer[200];
11331467Sminshall
11431467Sminshall switch (i) {
11531493Sminshall case EXCH_CMD_REJECTED:
11631467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC,
11731467Sminshall sizeof sd, (char *)&sd) == -1) {
11831467Sminshall return -1;
11931467Sminshall }
12031467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
12131467Sminshall return -1;
12231467Sminshall }
12331467Sminshall buffer[sd.length] = 0;
12431467Sminshall fprintf(stderr, "%s\n", buffer);
12531493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
12631467Sminshall return -1;
12731467Sminshall }
12831467Sminshall break;
12931493Sminshall case EXCH_CMD_SEND_AUTH:
13031467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, 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 passwd = getpass(buffer); /* Go to terminal */
13831467Sminshall passwd_length = strlen(passwd);
13931467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
14031467Sminshall return -1;
14131467Sminshall }
14231467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
14331467Sminshall return -1;
14431467Sminshall }
14531467Sminshall buffer[sd.length] = 0;
14631467Sminshall if (sd.length) {
14731467Sminshall char *ptr;
14831467Sminshall
14931467Sminshall ptr = passwd;
15031467Sminshall i = 0;
15131467Sminshall while (*ptr) {
15231467Sminshall *ptr++ ^= buffer[i++];
15331467Sminshall if (i >= sd.length) {
15431467Sminshall i = 0;
15531467Sminshall }
15631467Sminshall }
15731467Sminshall }
15831797Sminshall sd.length = passwd_length;
15931493Sminshall if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
16031467Sminshall return -1;
16131467Sminshall }
16231467Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
16331467Sminshall return -1;
16431467Sminshall }
16531467Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
16631467Sminshall return -1;
16731467Sminshall }
16831467Sminshall break;
16931467Sminshall case -1:
17031467Sminshall return -1;
17131467Sminshall default:
17231467Sminshall fprintf(stderr,
17331467Sminshall "Waiting for connection indicator, received 0x%x.\n", i);
17431467Sminshall break;
17531467Sminshall }
17631467Sminshall }
17731459Sminshall /* YEAH */
17831459Sminshall return 0; /* Happiness! */
17931459Sminshall }
18031459Sminshall
18131459Sminshall
18231500Sminshall api_exch_api(regs, sregs, parms, length)
18331459Sminshall union REGS *regs;
18431459Sminshall struct SREGS *sregs;
18531500Sminshall char *parms;
18631500Sminshall int length;
18731459Sminshall {
18831472Sminshall struct storage_descriptor sd;
18931472Sminshall int i;
19031472Sminshall
19131493Sminshall if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
19231472Sminshall return -1;
19331472Sminshall }
19431472Sminshall if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
19531472Sminshall return -1;
19631472Sminshall }
19731472Sminshall if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
19831472Sminshall return -1;
19931472Sminshall }
20031797Sminshall sd.length = length;
20131797Sminshall sd.location = (long) parms;
20231472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
20331472Sminshall return -1;
20431472Sminshall }
20531500Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
20631500Sminshall return -1;
20731500Sminshall }
20831493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
20931472Sminshall switch (i) {
21031493Sminshall case EXCH_CMD_GIMME:
21131472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
21231472Sminshall == -1) {
21331472Sminshall return -1;
21431472Sminshall }
21531472Sminshall /*XXX validity check GIMME? */
21631493Sminshall if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
21731472Sminshall return -1;
21831472Sminshall }
21931472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
22031472Sminshall == -1) {
22131472Sminshall return -1;
22231472Sminshall }
22331797Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
22435418Sminshall (char *)sd.location) == -1) {
22531472Sminshall return -1;
22631472Sminshall }
22731472Sminshall break;
22831493Sminshall case EXCH_CMD_HEREIS:
22931472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
23031472Sminshall == -1) {
23131472Sminshall return -1;
23231472Sminshall }
23331472Sminshall /* XXX Validty check HEREIS? */
23431797Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
23535418Sminshall (char *)sd.location) == -1) {
23631472Sminshall return -1;
23731472Sminshall }
23831472Sminshall break;
23931472Sminshall default:
24031472Sminshall fprintf(stderr, "Waiting for reply command, we got command %d.\n",
24131472Sminshall i);
24231472Sminshall return -1;
24331472Sminshall }
24431472Sminshall }
24531472Sminshall if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
24631472Sminshall return -1;
24731472Sminshall }
24831472Sminshall if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
24931472Sminshall return -1;
25031472Sminshall }
25131472Sminshall /* YEAH */
25231472Sminshall return 0; /* Happiness! */
25331459Sminshall }
25431796Sminshall
25531796Sminshall #endif /* unix */
256