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