131459Sminshall #include <sys/types.h> 231459Sminshall #include <sys/socket.h> 331459Sminshall #include <netinet/in.h> 431459Sminshall #include <netdb.h> 531459Sminshall #include <stdio.h> 631459Sminshall 731459Sminshall #include "../api/api.h" 831467Sminshall #include "api_exch.h" 931459Sminshall 1031459Sminshall 1131459Sminshall api_open_api(string) 1231459Sminshall char *string; /* if non-zero, where to connect to */ 1331459Sminshall { 1431459Sminshall struct sockaddr_in server; 1531459Sminshall struct hostent *hp; 1631459Sminshall char *getenv(); 1731459Sminshall char thehostname[100]; 1831467Sminshall int sock; 1931459Sminshall int port; 2031467Sminshall int i; 2131459Sminshall 2231459Sminshall if (string == 0) { 2331459Sminshall string = getenv("API3270"); /* Get API */ 2431459Sminshall if (string == 0) { 2531459Sminshall fprintf(stderr, 2631459Sminshall "API3270 environmental variable not set - no API.\n"); 2731459Sminshall return -1; /* Nothing */ 2831459Sminshall } 2931459Sminshall } 3031459Sminshall 3131459Sminshall if (sscanf(string, "%[^:]:%d", thehostname, &port) != 2) { 3231459Sminshall fprintf(stderr, "API3270 environmental variable has bad format.\n"); 3331459Sminshall return -1; 3431459Sminshall } 3531459Sminshall /* Now, try to connect */ 3631459Sminshall sock = socket(AF_INET, SOCK_STREAM, 0); 3731459Sminshall if (sock < 0) { 3831459Sminshall perror("opening API socket"); 3931459Sminshall return -1; 4031459Sminshall } 4131459Sminshall server.sin_family = AF_INET; 4231459Sminshall hp = gethostbyname(thehostname); 4331459Sminshall if (hp == 0) { 4431459Sminshall fprintf(stderr, "%s specifies bad host name.\n", string); 4531459Sminshall return -1; 4631459Sminshall } 4731459Sminshall bcopy(hp->h_addr, &server.sin_addr, hp->h_length); 4831459Sminshall server.sin_port = htons(port); 4931459Sminshall 5031459Sminshall if (connect(sock, &server, sizeof server) < 0) { 5131459Sminshall perror("connecting to API server"); 5231459Sminshall return -1; 5331459Sminshall } 5431467Sminshall /* Now, try application level connection */ 5531467Sminshall if (api_exch_init(sock) == -1) { 5631467Sminshall return -1; 5731467Sminshall } 5831467Sminshall if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) { 5931467Sminshall return -1; 6031467Sminshall } 6131467Sminshall while ((i = api_exch_inbyte()) != EXCH_ASSOCIATED) { 6231467Sminshall struct storage_descriptor sd; 6331467Sminshall int passwd_length; 6431467Sminshall char *passwd, *getpass(); 6531467Sminshall char buffer[200]; 6631467Sminshall 6731467Sminshall switch (i) { 6831467Sminshall case EXCH_REJECTED: 6931467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, 7031467Sminshall sizeof sd, (char *)&sd) == -1) { 7131467Sminshall return -1; 7231467Sminshall } 7331467Sminshall sd.length = ntohs(sd.length); 7431467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 7531467Sminshall return -1; 7631467Sminshall } 7731467Sminshall buffer[sd.length] = 0; 7831467Sminshall fprintf(stderr, "%s\n", buffer); 7931467Sminshall if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) { 8031467Sminshall return -1; 8131467Sminshall } 8231467Sminshall break; 8331467Sminshall case EXCH_SEND_AUTH: 8431467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 8531467Sminshall return -1; 8631467Sminshall } 8731467Sminshall sd.length = ntohs(sd.length); 8831467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 8931467Sminshall return -1; 9031467Sminshall } 9131467Sminshall buffer[sd.length] = 0; 9231467Sminshall passwd = getpass(buffer); /* Go to terminal */ 9331467Sminshall passwd_length = strlen(passwd); 9431467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 9531467Sminshall return -1; 9631467Sminshall } 9731467Sminshall sd.length = ntohs(sd.length); 9831467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 9931467Sminshall return -1; 10031467Sminshall } 10131467Sminshall buffer[sd.length] = 0; 10231467Sminshall if (sd.length) { 10331467Sminshall char *ptr; 10431467Sminshall 10531467Sminshall ptr = passwd; 10631467Sminshall i = 0; 10731467Sminshall while (*ptr) { 10831467Sminshall *ptr++ ^= buffer[i++]; 10931467Sminshall if (i >= sd.length) { 11031467Sminshall i = 0; 11131467Sminshall } 11231467Sminshall } 11331467Sminshall } 11431467Sminshall sd.length = htons(passwd_length); 11531467Sminshall if (api_exch_outcommand(EXCH_AUTH) == -1) { 11631467Sminshall return -1; 11731467Sminshall } 11831467Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 11931467Sminshall return -1; 12031467Sminshall } 12131467Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) { 12231467Sminshall return -1; 12331467Sminshall } 12431467Sminshall break; 12531467Sminshall case -1: 12631467Sminshall return -1; 12731467Sminshall default: 12831467Sminshall fprintf(stderr, 12931467Sminshall "Waiting for connection indicator, received 0x%x.\n", i); 13031467Sminshall break; 13131467Sminshall } 13231467Sminshall } 13331459Sminshall /* YEAH */ 13431459Sminshall return 0; /* Happiness! */ 13531459Sminshall } 13631459Sminshall 13731459Sminshall 13831459Sminshall api_exch_api(regs, sregs) 13931459Sminshall union REGS *regs; 14031459Sminshall struct SREGS *sregs; 14131459Sminshall { 142*31472Sminshall struct storage_descriptor sd; 143*31472Sminshall int i; 144*31472Sminshall 145*31472Sminshall if (api_exch_outcommand(EXCH_REQUEST) == -1) { 146*31472Sminshall return -1; 147*31472Sminshall } 148*31472Sminshall if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 149*31472Sminshall return -1; 150*31472Sminshall } 151*31472Sminshall if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 152*31472Sminshall return -1; 153*31472Sminshall } 154*31472Sminshall sd.length = 0; 155*31472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 156*31472Sminshall return -1; 157*31472Sminshall } 158*31472Sminshall while ((i = api_exch_inbyte()) != EXCH_REPLY) { 159*31472Sminshall switch (i) { 160*31472Sminshall case EXCH_GIMME: 161*31472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 162*31472Sminshall == -1) { 163*31472Sminshall return -1; 164*31472Sminshall } 165*31472Sminshall /*XXX validity check GIMME? */ 166*31472Sminshall if (api_exch_outcommand(EXCH_HEREIS) == -1) { 167*31472Sminshall return -1; 168*31472Sminshall } 169*31472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 170*31472Sminshall == -1) { 171*31472Sminshall return -1; 172*31472Sminshall } 173*31472Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, ntohs(sd.length), 174*31472Sminshall ntohl(sd.location)) == -1) { 175*31472Sminshall return -1; 176*31472Sminshall } 177*31472Sminshall break; 178*31472Sminshall case EXCH_HEREIS: 179*31472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 180*31472Sminshall == -1) { 181*31472Sminshall return -1; 182*31472Sminshall } 183*31472Sminshall /* XXX Validty check HEREIS? */ 184*31472Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, ntohs(sd.length), 185*31472Sminshall ntohl(sd.location)) == -1) { 186*31472Sminshall return -1; 187*31472Sminshall } 188*31472Sminshall break; 189*31472Sminshall default: 190*31472Sminshall fprintf(stderr, "Waiting for reply command, we got command %d.\n", 191*31472Sminshall i); 192*31472Sminshall return -1; 193*31472Sminshall } 194*31472Sminshall } 195*31472Sminshall if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 196*31472Sminshall return -1; 197*31472Sminshall } 198*31472Sminshall if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 199*31472Sminshall return -1; 200*31472Sminshall } 201*31472Sminshall /* YEAH */ 202*31472Sminshall return 0; /* Happiness! */ 20331459Sminshall } 204