1*31796Sminshall #if defined(unix) 2*31796Sminshall 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; 3231459Sminshall char *getenv(); 3331459Sminshall char thehostname[100]; 3431467Sminshall int sock; 3531459Sminshall int port; 3631467Sminshall int i; 3731459Sminshall 3831459Sminshall if (string == 0) { 3931459Sminshall string = getenv("API3270"); /* Get API */ 4031459Sminshall if (string == 0) { 4131459Sminshall fprintf(stderr, 4231459Sminshall "API3270 environmental variable not set - no API.\n"); 4331459Sminshall return -1; /* Nothing */ 4431459Sminshall } 4531459Sminshall } 4631459Sminshall 4731459Sminshall if (sscanf(string, "%[^:]:%d", thehostname, &port) != 2) { 4831459Sminshall fprintf(stderr, "API3270 environmental variable has bad format.\n"); 4931459Sminshall return -1; 5031459Sminshall } 5131459Sminshall /* Now, try to connect */ 5231459Sminshall sock = socket(AF_INET, SOCK_STREAM, 0); 5331459Sminshall if (sock < 0) { 5431459Sminshall perror("opening API socket"); 5531459Sminshall return -1; 5631459Sminshall } 5731459Sminshall server.sin_family = AF_INET; 5831459Sminshall hp = gethostbyname(thehostname); 5931459Sminshall if (hp == 0) { 6031459Sminshall fprintf(stderr, "%s specifies bad host name.\n", string); 6131459Sminshall return -1; 6231459Sminshall } 6331459Sminshall bcopy(hp->h_addr, &server.sin_addr, hp->h_length); 6431459Sminshall server.sin_port = htons(port); 6531459Sminshall 6631459Sminshall if (connect(sock, &server, sizeof server) < 0) { 6731459Sminshall perror("connecting to API server"); 6831459Sminshall return -1; 6931459Sminshall } 7031467Sminshall /* Now, try application level connection */ 7131493Sminshall if (api_exch_init(sock, "client") == -1) { 7231467Sminshall return -1; 7331467Sminshall } 7431493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 7531467Sminshall return -1; 7631467Sminshall } 7731493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) { 7831467Sminshall struct storage_descriptor sd; 7931467Sminshall int passwd_length; 8031467Sminshall char *passwd, *getpass(); 8131467Sminshall char buffer[200]; 8231467Sminshall 8331467Sminshall switch (i) { 8431493Sminshall case EXCH_CMD_REJECTED: 8531467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, 8631467Sminshall sizeof sd, (char *)&sd) == -1) { 8731467Sminshall return -1; 8831467Sminshall } 8931467Sminshall sd.length = ntohs(sd.length); 9031467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 9131467Sminshall return -1; 9231467Sminshall } 9331467Sminshall buffer[sd.length] = 0; 9431467Sminshall fprintf(stderr, "%s\n", buffer); 9531493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 9631467Sminshall return -1; 9731467Sminshall } 9831467Sminshall break; 9931493Sminshall case EXCH_CMD_SEND_AUTH: 10031467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 10131467Sminshall return -1; 10231467Sminshall } 10331467Sminshall sd.length = ntohs(sd.length); 10431467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 10531467Sminshall return -1; 10631467Sminshall } 10731467Sminshall buffer[sd.length] = 0; 10831467Sminshall passwd = getpass(buffer); /* Go to terminal */ 10931467Sminshall passwd_length = strlen(passwd); 11031467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 11131467Sminshall return -1; 11231467Sminshall } 11331467Sminshall sd.length = ntohs(sd.length); 11431467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 11531467Sminshall return -1; 11631467Sminshall } 11731467Sminshall buffer[sd.length] = 0; 11831467Sminshall if (sd.length) { 11931467Sminshall char *ptr; 12031467Sminshall 12131467Sminshall ptr = passwd; 12231467Sminshall i = 0; 12331467Sminshall while (*ptr) { 12431467Sminshall *ptr++ ^= buffer[i++]; 12531467Sminshall if (i >= sd.length) { 12631467Sminshall i = 0; 12731467Sminshall } 12831467Sminshall } 12931467Sminshall } 13031467Sminshall sd.length = htons(passwd_length); 13131493Sminshall if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) { 13231467Sminshall return -1; 13331467Sminshall } 13431467Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 13531467Sminshall return -1; 13631467Sminshall } 13731467Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) { 13831467Sminshall return -1; 13931467Sminshall } 14031467Sminshall break; 14131467Sminshall case -1: 14231467Sminshall return -1; 14331467Sminshall default: 14431467Sminshall fprintf(stderr, 14531467Sminshall "Waiting for connection indicator, received 0x%x.\n", i); 14631467Sminshall break; 14731467Sminshall } 14831467Sminshall } 14931459Sminshall /* YEAH */ 15031459Sminshall return 0; /* Happiness! */ 15131459Sminshall } 15231459Sminshall 15331459Sminshall 15431500Sminshall api_exch_api(regs, sregs, parms, length) 15531459Sminshall union REGS *regs; 15631459Sminshall struct SREGS *sregs; 15731500Sminshall char *parms; 15831500Sminshall int length; 15931459Sminshall { 16031472Sminshall struct storage_descriptor sd; 16131472Sminshall int i; 16231472Sminshall 16331493Sminshall if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) { 16431472Sminshall return -1; 16531472Sminshall } 16631472Sminshall if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 16731472Sminshall return -1; 16831472Sminshall } 16931472Sminshall if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 17031472Sminshall return -1; 17131472Sminshall } 17231500Sminshall sd.length = htons(length); 173*31796Sminshall sd.location = (long) htonl(parms); 17431472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 17531472Sminshall return -1; 17631472Sminshall } 17731500Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) { 17831500Sminshall return -1; 17931500Sminshall } 18031493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) { 18131472Sminshall switch (i) { 18231493Sminshall case EXCH_CMD_GIMME: 18331472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 18431472Sminshall == -1) { 18531472Sminshall return -1; 18631472Sminshall } 18731472Sminshall /*XXX validity check GIMME? */ 18831493Sminshall if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { 18931472Sminshall return -1; 19031472Sminshall } 19131472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 19231472Sminshall == -1) { 19331472Sminshall return -1; 19431472Sminshall } 19531472Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, ntohs(sd.length), 19631472Sminshall ntohl(sd.location)) == -1) { 19731472Sminshall return -1; 19831472Sminshall } 19931472Sminshall break; 20031493Sminshall case EXCH_CMD_HEREIS: 20131472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 20231472Sminshall == -1) { 20331472Sminshall return -1; 20431472Sminshall } 20531472Sminshall /* XXX Validty check HEREIS? */ 20631472Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, ntohs(sd.length), 20731472Sminshall ntohl(sd.location)) == -1) { 20831472Sminshall return -1; 20931472Sminshall } 21031472Sminshall break; 21131472Sminshall default: 21231472Sminshall fprintf(stderr, "Waiting for reply command, we got command %d.\n", 21331472Sminshall i); 21431472Sminshall return -1; 21531472Sminshall } 21631472Sminshall } 21731472Sminshall if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 21831472Sminshall return -1; 21931472Sminshall } 22031472Sminshall if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 22131472Sminshall return -1; 22231472Sminshall } 22331472Sminshall /* YEAH */ 22431472Sminshall return 0; /* Happiness! */ 22531459Sminshall } 226*31796Sminshall 227*31796Sminshall #endif /* unix */ 228