148754Sbostic /*- 2*62317Sbostic * Copyright (c) 1988, 1993 3*62317Sbostic * The Regents of the University of California. All rights reserved. 431890Sminshall * 548754Sbostic * %sccs.include.redist.c% 631890Sminshall */ 731890Sminshall 831890Sminshall #ifndef lint 9*62317Sbostic static char sccsid[] = "@(#)api_bsd.c 8.1 (Berkeley) 06/06/93"; 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 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 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(); 4535494Sminshall #if !defined(htons) 4635418Sminshall extern unsigned short htons(); 4735494Sminshall #endif /* !defined(htons) */ 4831459Sminshall char thehostname[100]; 4931797Sminshall char keyname[100]; 5031797Sminshall char inkey[100]; 5131797Sminshall FILE *keyfile; 5231467Sminshall int sock; 5335418Sminshall unsigned int port; 5431467Sminshall int i; 5531459Sminshall 5631459Sminshall if (string == 0) { 5731459Sminshall string = getenv("API3270"); /* Get API */ 5831459Sminshall if (string == 0) { 5931459Sminshall fprintf(stderr, 6031459Sminshall "API3270 environmental variable not set - no API.\n"); 6131459Sminshall return -1; /* Nothing */ 6231459Sminshall } 6331459Sminshall } 6431459Sminshall 6535418Sminshall if (sscanf(string, "%[^:]:%d:%s", thehostname, 6635418Sminshall (int *)&port, keyname) != 3) { 6731459Sminshall fprintf(stderr, "API3270 environmental variable has bad format.\n"); 6831459Sminshall return -1; 6931459Sminshall } 7031459Sminshall /* Now, try to connect */ 7131459Sminshall sock = socket(AF_INET, SOCK_STREAM, 0); 7231459Sminshall if (sock < 0) { 7331459Sminshall perror("opening API socket"); 7431459Sminshall return -1; 7531459Sminshall } 7631459Sminshall server.sin_family = AF_INET; 7731459Sminshall hp = gethostbyname(thehostname); 7831459Sminshall if (hp == 0) { 7931459Sminshall fprintf(stderr, "%s specifies bad host name.\n", string); 8031459Sminshall return -1; 8131459Sminshall } 8235418Sminshall bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length); 8331459Sminshall server.sin_port = htons(port); 8431459Sminshall 8535418Sminshall if (connect(sock, (struct sockaddr *)&server, sizeof server) < 0) { 8631459Sminshall perror("connecting to API server"); 8731459Sminshall return -1; 8831459Sminshall } 8931467Sminshall /* Now, try application level connection */ 9031493Sminshall if (api_exch_init(sock, "client") == -1) { 9131467Sminshall return -1; 9231467Sminshall } 9331493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 9431467Sminshall return -1; 9531467Sminshall } 9631797Sminshall keyfile = fopen(keyname, "r"); 9731797Sminshall if (keyfile == 0) { 9831797Sminshall perror("fopen"); 9931797Sminshall return -1; 10031797Sminshall } 10131797Sminshall if (fscanf(keyfile, "%s\n", inkey) != 1) { 10231797Sminshall perror("fscanf"); 10331797Sminshall return -1; 10431797Sminshall } 10531797Sminshall sd.length = strlen(inkey)+1; 10631797Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 10731797Sminshall return -1; 10831797Sminshall } 10931797Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) { 11031797Sminshall return -1; 11131797Sminshall } 11231493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) { 11331467Sminshall int passwd_length; 11431467Sminshall char *passwd, *getpass(); 11531467Sminshall char buffer[200]; 11631467Sminshall 11731467Sminshall switch (i) { 11831493Sminshall case EXCH_CMD_REJECTED: 11931467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, 12031467Sminshall sizeof sd, (char *)&sd) == -1) { 12131467Sminshall return -1; 12231467Sminshall } 12331467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 12431467Sminshall return -1; 12531467Sminshall } 12631467Sminshall buffer[sd.length] = 0; 12731467Sminshall fprintf(stderr, "%s\n", buffer); 12831493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 12931467Sminshall return -1; 13031467Sminshall } 13131467Sminshall break; 13231493Sminshall case EXCH_CMD_SEND_AUTH: 13331467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 13431467Sminshall return -1; 13531467Sminshall } 13631467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 13731467Sminshall return -1; 13831467Sminshall } 13931467Sminshall buffer[sd.length] = 0; 14031467Sminshall passwd = getpass(buffer); /* Go to terminal */ 14131467Sminshall passwd_length = strlen(passwd); 14231467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 14331467Sminshall return -1; 14431467Sminshall } 14531467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 14631467Sminshall return -1; 14731467Sminshall } 14831467Sminshall buffer[sd.length] = 0; 14931467Sminshall if (sd.length) { 15031467Sminshall char *ptr; 15131467Sminshall 15231467Sminshall ptr = passwd; 15331467Sminshall i = 0; 15431467Sminshall while (*ptr) { 15531467Sminshall *ptr++ ^= buffer[i++]; 15631467Sminshall if (i >= sd.length) { 15731467Sminshall i = 0; 15831467Sminshall } 15931467Sminshall } 16031467Sminshall } 16131797Sminshall sd.length = passwd_length; 16231493Sminshall if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) { 16331467Sminshall return -1; 16431467Sminshall } 16531467Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 16631467Sminshall return -1; 16731467Sminshall } 16831467Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) { 16931467Sminshall return -1; 17031467Sminshall } 17131467Sminshall break; 17231467Sminshall case -1: 17331467Sminshall return -1; 17431467Sminshall default: 17531467Sminshall fprintf(stderr, 17631467Sminshall "Waiting for connection indicator, received 0x%x.\n", i); 17731467Sminshall break; 17831467Sminshall } 17931467Sminshall } 18031459Sminshall /* YEAH */ 18131459Sminshall return 0; /* Happiness! */ 18231459Sminshall } 18331459Sminshall 18431459Sminshall 18531500Sminshall api_exch_api(regs, sregs, parms, length) 18631459Sminshall union REGS *regs; 18731459Sminshall struct SREGS *sregs; 18831500Sminshall char *parms; 18931500Sminshall int length; 19031459Sminshall { 19131472Sminshall struct storage_descriptor sd; 19231472Sminshall int i; 19331472Sminshall 19431493Sminshall if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) { 19531472Sminshall return -1; 19631472Sminshall } 19731472Sminshall if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 19831472Sminshall return -1; 19931472Sminshall } 20031472Sminshall if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 20131472Sminshall return -1; 20231472Sminshall } 20331797Sminshall sd.length = length; 20431797Sminshall sd.location = (long) parms; 20531472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 20631472Sminshall return -1; 20731472Sminshall } 20831500Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) { 20931500Sminshall return -1; 21031500Sminshall } 21131493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) { 21231472Sminshall switch (i) { 21331493Sminshall case EXCH_CMD_GIMME: 21431472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 21531472Sminshall == -1) { 21631472Sminshall return -1; 21731472Sminshall } 21831472Sminshall /*XXX validity check GIMME? */ 21931493Sminshall if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { 22031472Sminshall return -1; 22131472Sminshall } 22231472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 22331472Sminshall == -1) { 22431472Sminshall return -1; 22531472Sminshall } 22631797Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, 22735418Sminshall (char *)sd.location) == -1) { 22831472Sminshall return -1; 22931472Sminshall } 23031472Sminshall break; 23131493Sminshall case EXCH_CMD_HEREIS: 23231472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 23331472Sminshall == -1) { 23431472Sminshall return -1; 23531472Sminshall } 23631472Sminshall /* XXX Validty check HEREIS? */ 23731797Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, 23835418Sminshall (char *)sd.location) == -1) { 23931472Sminshall return -1; 24031472Sminshall } 24131472Sminshall break; 24231472Sminshall default: 24331472Sminshall fprintf(stderr, "Waiting for reply command, we got command %d.\n", 24431472Sminshall i); 24531472Sminshall return -1; 24631472Sminshall } 24731472Sminshall } 24831472Sminshall if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 24931472Sminshall return -1; 25031472Sminshall } 25131472Sminshall if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 25231472Sminshall return -1; 25331472Sminshall } 25431472Sminshall /* YEAH */ 25531472Sminshall return 0; /* Happiness! */ 25631459Sminshall } 25731796Sminshall 25831796Sminshall #endif /* unix */ 259