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