131796Sminshall #if defined(unix) 231796Sminshall 331459Sminshall #include <sys/types.h> 431459Sminshall #include <sys/socket.h> 531459Sminshall #include <netinet/in.h> 631459Sminshall #include <netdb.h> 731459Sminshall #include <stdio.h> 831459Sminshall 931459Sminshall #include "../api/api.h" 1031467Sminshall #include "api_exch.h" 1131459Sminshall 1231459Sminshall 1331493Sminshall int 1431493Sminshall api_close_api() 1531493Sminshall { 1631493Sminshall if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) { 1731493Sminshall return -1; 1831493Sminshall } else if (api_exch_flush() == -1) { 1931493Sminshall return -1; 2031493Sminshall } else { 2131493Sminshall return 0; 2231493Sminshall } 2331493Sminshall } 2431493Sminshall 2531493Sminshall 2631493Sminshall int 2731459Sminshall api_open_api(string) 2831459Sminshall char *string; /* if non-zero, where to connect to */ 2931459Sminshall { 3031459Sminshall struct sockaddr_in server; 3131459Sminshall struct hostent *hp; 32*31797Sminshall struct storage_descriptor sd; 3331459Sminshall char *getenv(); 3431459Sminshall char thehostname[100]; 35*31797Sminshall char keyname[100]; 36*31797Sminshall char inkey[100]; 37*31797Sminshall FILE *keyfile; 3831467Sminshall int sock; 3931459Sminshall int port; 4031467Sminshall int i; 4131459Sminshall 4231459Sminshall if (string == 0) { 4331459Sminshall string = getenv("API3270"); /* Get API */ 4431459Sminshall if (string == 0) { 4531459Sminshall fprintf(stderr, 4631459Sminshall "API3270 environmental variable not set - no API.\n"); 4731459Sminshall return -1; /* Nothing */ 4831459Sminshall } 4931459Sminshall } 5031459Sminshall 51*31797Sminshall if (sscanf(string, "%[^:]:%d:%s", thehostname, &port, keyname) != 3) { 5231459Sminshall fprintf(stderr, "API3270 environmental variable has bad format.\n"); 5331459Sminshall return -1; 5431459Sminshall } 5531459Sminshall /* Now, try to connect */ 5631459Sminshall sock = socket(AF_INET, SOCK_STREAM, 0); 5731459Sminshall if (sock < 0) { 5831459Sminshall perror("opening API socket"); 5931459Sminshall return -1; 6031459Sminshall } 6131459Sminshall server.sin_family = AF_INET; 6231459Sminshall hp = gethostbyname(thehostname); 6331459Sminshall if (hp == 0) { 6431459Sminshall fprintf(stderr, "%s specifies bad host name.\n", string); 6531459Sminshall return -1; 6631459Sminshall } 6731459Sminshall bcopy(hp->h_addr, &server.sin_addr, hp->h_length); 6831459Sminshall server.sin_port = htons(port); 6931459Sminshall 7031459Sminshall if (connect(sock, &server, sizeof server) < 0) { 7131459Sminshall perror("connecting to API server"); 7231459Sminshall return -1; 7331459Sminshall } 7431467Sminshall /* Now, try application level connection */ 7531493Sminshall if (api_exch_init(sock, "client") == -1) { 7631467Sminshall return -1; 7731467Sminshall } 7831493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 7931467Sminshall return -1; 8031467Sminshall } 81*31797Sminshall keyfile = fopen(keyname, "r"); 82*31797Sminshall if (keyfile == 0) { 83*31797Sminshall perror("fopen"); 84*31797Sminshall return -1; 85*31797Sminshall } 86*31797Sminshall if (fscanf(keyfile, "%s\n", inkey) != 1) { 87*31797Sminshall perror("fscanf"); 88*31797Sminshall return -1; 89*31797Sminshall } 90*31797Sminshall sd.length = strlen(inkey)+1; 91*31797Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 92*31797Sminshall return -1; 93*31797Sminshall } 94*31797Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) { 95*31797Sminshall return -1; 96*31797Sminshall } 9731493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) { 9831467Sminshall int passwd_length; 9931467Sminshall char *passwd, *getpass(); 10031467Sminshall char buffer[200]; 10131467Sminshall 10231467Sminshall switch (i) { 10331493Sminshall case EXCH_CMD_REJECTED: 10431467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, 10531467Sminshall sizeof sd, (char *)&sd) == -1) { 10631467Sminshall return -1; 10731467Sminshall } 10831467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 10931467Sminshall return -1; 11031467Sminshall } 11131467Sminshall buffer[sd.length] = 0; 11231467Sminshall fprintf(stderr, "%s\n", buffer); 11331493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 11431467Sminshall return -1; 11531467Sminshall } 11631467Sminshall break; 11731493Sminshall case EXCH_CMD_SEND_AUTH: 11831467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 11931467Sminshall return -1; 12031467Sminshall } 12131467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 12231467Sminshall return -1; 12331467Sminshall } 12431467Sminshall buffer[sd.length] = 0; 12531467Sminshall passwd = getpass(buffer); /* Go to terminal */ 12631467Sminshall passwd_length = strlen(passwd); 12731467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 12831467Sminshall return -1; 12931467Sminshall } 13031467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 13131467Sminshall return -1; 13231467Sminshall } 13331467Sminshall buffer[sd.length] = 0; 13431467Sminshall if (sd.length) { 13531467Sminshall char *ptr; 13631467Sminshall 13731467Sminshall ptr = passwd; 13831467Sminshall i = 0; 13931467Sminshall while (*ptr) { 14031467Sminshall *ptr++ ^= buffer[i++]; 14131467Sminshall if (i >= sd.length) { 14231467Sminshall i = 0; 14331467Sminshall } 14431467Sminshall } 14531467Sminshall } 146*31797Sminshall sd.length = passwd_length; 14731493Sminshall if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) { 14831467Sminshall return -1; 14931467Sminshall } 15031467Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 15131467Sminshall return -1; 15231467Sminshall } 15331467Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) { 15431467Sminshall return -1; 15531467Sminshall } 15631467Sminshall break; 15731467Sminshall case -1: 15831467Sminshall return -1; 15931467Sminshall default: 16031467Sminshall fprintf(stderr, 16131467Sminshall "Waiting for connection indicator, received 0x%x.\n", i); 16231467Sminshall break; 16331467Sminshall } 16431467Sminshall } 16531459Sminshall /* YEAH */ 16631459Sminshall return 0; /* Happiness! */ 16731459Sminshall } 16831459Sminshall 16931459Sminshall 17031500Sminshall api_exch_api(regs, sregs, parms, length) 17131459Sminshall union REGS *regs; 17231459Sminshall struct SREGS *sregs; 17331500Sminshall char *parms; 17431500Sminshall int length; 17531459Sminshall { 17631472Sminshall struct storage_descriptor sd; 17731472Sminshall int i; 17831472Sminshall 17931493Sminshall if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) { 18031472Sminshall return -1; 18131472Sminshall } 18231472Sminshall if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 18331472Sminshall return -1; 18431472Sminshall } 18531472Sminshall if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 18631472Sminshall return -1; 18731472Sminshall } 188*31797Sminshall sd.length = length; 189*31797Sminshall sd.location = (long) parms; 19031472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 19131472Sminshall return -1; 19231472Sminshall } 19331500Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) { 19431500Sminshall return -1; 19531500Sminshall } 19631493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) { 19731472Sminshall switch (i) { 19831493Sminshall case EXCH_CMD_GIMME: 19931472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 20031472Sminshall == -1) { 20131472Sminshall return -1; 20231472Sminshall } 20331472Sminshall /*XXX validity check GIMME? */ 20431493Sminshall if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { 20531472Sminshall return -1; 20631472Sminshall } 20731472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 20831472Sminshall == -1) { 20931472Sminshall return -1; 21031472Sminshall } 211*31797Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, 212*31797Sminshall sd.location) == -1) { 21331472Sminshall return -1; 21431472Sminshall } 21531472Sminshall break; 21631493Sminshall case EXCH_CMD_HEREIS: 21731472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 21831472Sminshall == -1) { 21931472Sminshall return -1; 22031472Sminshall } 22131472Sminshall /* XXX Validty check HEREIS? */ 222*31797Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, 223*31797Sminshall sd.location) == -1) { 22431472Sminshall return -1; 22531472Sminshall } 22631472Sminshall break; 22731472Sminshall default: 22831472Sminshall fprintf(stderr, "Waiting for reply command, we got command %d.\n", 22931472Sminshall i); 23031472Sminshall return -1; 23131472Sminshall } 23231472Sminshall } 23331472Sminshall if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 23431472Sminshall return -1; 23531472Sminshall } 23631472Sminshall if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 23731472Sminshall return -1; 23831472Sminshall } 23931472Sminshall /* YEAH */ 24031472Sminshall return 0; /* Happiness! */ 24131459Sminshall } 24231796Sminshall 24331796Sminshall #endif /* unix */ 244