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