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 11*31493Sminshall int 12*31493Sminshall api_close_api() 13*31493Sminshall { 14*31493Sminshall if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) { 15*31493Sminshall return -1; 16*31493Sminshall } else if (api_exch_flush() == -1) { 17*31493Sminshall return -1; 18*31493Sminshall } else { 19*31493Sminshall return 0; 20*31493Sminshall } 21*31493Sminshall } 22*31493Sminshall 23*31493Sminshall 24*31493Sminshall int 2531459Sminshall api_open_api(string) 2631459Sminshall char *string; /* if non-zero, where to connect to */ 2731459Sminshall { 2831459Sminshall struct sockaddr_in server; 2931459Sminshall struct hostent *hp; 3031459Sminshall char *getenv(); 3131459Sminshall char thehostname[100]; 3231467Sminshall int sock; 3331459Sminshall int port; 3431467Sminshall int i; 3531459Sminshall 3631459Sminshall if (string == 0) { 3731459Sminshall string = getenv("API3270"); /* Get API */ 3831459Sminshall if (string == 0) { 3931459Sminshall fprintf(stderr, 4031459Sminshall "API3270 environmental variable not set - no API.\n"); 4131459Sminshall return -1; /* Nothing */ 4231459Sminshall } 4331459Sminshall } 4431459Sminshall 4531459Sminshall if (sscanf(string, "%[^:]:%d", thehostname, &port) != 2) { 4631459Sminshall fprintf(stderr, "API3270 environmental variable has bad format.\n"); 4731459Sminshall return -1; 4831459Sminshall } 4931459Sminshall /* Now, try to connect */ 5031459Sminshall sock = socket(AF_INET, SOCK_STREAM, 0); 5131459Sminshall if (sock < 0) { 5231459Sminshall perror("opening API socket"); 5331459Sminshall return -1; 5431459Sminshall } 5531459Sminshall server.sin_family = AF_INET; 5631459Sminshall hp = gethostbyname(thehostname); 5731459Sminshall if (hp == 0) { 5831459Sminshall fprintf(stderr, "%s specifies bad host name.\n", string); 5931459Sminshall return -1; 6031459Sminshall } 6131459Sminshall bcopy(hp->h_addr, &server.sin_addr, hp->h_length); 6231459Sminshall server.sin_port = htons(port); 6331459Sminshall 6431459Sminshall if (connect(sock, &server, sizeof server) < 0) { 6531459Sminshall perror("connecting to API server"); 6631459Sminshall return -1; 6731459Sminshall } 6831467Sminshall /* Now, try application level connection */ 69*31493Sminshall if (api_exch_init(sock, "client") == -1) { 7031467Sminshall return -1; 7131467Sminshall } 72*31493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 7331467Sminshall return -1; 7431467Sminshall } 75*31493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) { 7631467Sminshall struct storage_descriptor sd; 7731467Sminshall int passwd_length; 7831467Sminshall char *passwd, *getpass(); 7931467Sminshall char buffer[200]; 8031467Sminshall 8131467Sminshall switch (i) { 82*31493Sminshall case EXCH_CMD_REJECTED: 8331467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, 8431467Sminshall 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 fprintf(stderr, "%s\n", buffer); 93*31493Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 9431467Sminshall return -1; 9531467Sminshall } 9631467Sminshall break; 97*31493Sminshall case EXCH_CMD_SEND_AUTH: 9831467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 9931467Sminshall return -1; 10031467Sminshall } 10131467Sminshall sd.length = ntohs(sd.length); 10231467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 10331467Sminshall return -1; 10431467Sminshall } 10531467Sminshall buffer[sd.length] = 0; 10631467Sminshall passwd = getpass(buffer); /* Go to terminal */ 10731467Sminshall passwd_length = strlen(passwd); 10831467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 10931467Sminshall return -1; 11031467Sminshall } 11131467Sminshall sd.length = ntohs(sd.length); 11231467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 11331467Sminshall return -1; 11431467Sminshall } 11531467Sminshall buffer[sd.length] = 0; 11631467Sminshall if (sd.length) { 11731467Sminshall char *ptr; 11831467Sminshall 11931467Sminshall ptr = passwd; 12031467Sminshall i = 0; 12131467Sminshall while (*ptr) { 12231467Sminshall *ptr++ ^= buffer[i++]; 12331467Sminshall if (i >= sd.length) { 12431467Sminshall i = 0; 12531467Sminshall } 12631467Sminshall } 12731467Sminshall } 12831467Sminshall sd.length = htons(passwd_length); 129*31493Sminshall if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) { 13031467Sminshall return -1; 13131467Sminshall } 13231467Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 13331467Sminshall return -1; 13431467Sminshall } 13531467Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) { 13631467Sminshall return -1; 13731467Sminshall } 13831467Sminshall break; 13931467Sminshall case -1: 14031467Sminshall return -1; 14131467Sminshall default: 14231467Sminshall fprintf(stderr, 14331467Sminshall "Waiting for connection indicator, received 0x%x.\n", i); 14431467Sminshall break; 14531467Sminshall } 14631467Sminshall } 14731459Sminshall /* YEAH */ 14831459Sminshall return 0; /* Happiness! */ 14931459Sminshall } 15031459Sminshall 15131459Sminshall 15231459Sminshall api_exch_api(regs, sregs) 15331459Sminshall union REGS *regs; 15431459Sminshall struct SREGS *sregs; 15531459Sminshall { 15631472Sminshall struct storage_descriptor sd; 15731472Sminshall int i; 15831472Sminshall 159*31493Sminshall if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) { 16031472Sminshall return -1; 16131472Sminshall } 16231472Sminshall if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 16331472Sminshall return -1; 16431472Sminshall } 16531472Sminshall if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 16631472Sminshall return -1; 16731472Sminshall } 16831472Sminshall sd.length = 0; 16931472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 17031472Sminshall return -1; 17131472Sminshall } 172*31493Sminshall while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) { 17331472Sminshall switch (i) { 174*31493Sminshall case EXCH_CMD_GIMME: 17531472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 17631472Sminshall == -1) { 17731472Sminshall return -1; 17831472Sminshall } 17931472Sminshall /*XXX validity check GIMME? */ 180*31493Sminshall if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { 18131472Sminshall return -1; 18231472Sminshall } 18331472Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 18431472Sminshall == -1) { 18531472Sminshall return -1; 18631472Sminshall } 18731472Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, ntohs(sd.length), 18831472Sminshall ntohl(sd.location)) == -1) { 18931472Sminshall return -1; 19031472Sminshall } 19131472Sminshall break; 192*31493Sminshall case EXCH_CMD_HEREIS: 19331472Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 19431472Sminshall == -1) { 19531472Sminshall return -1; 19631472Sminshall } 19731472Sminshall /* XXX Validty check HEREIS? */ 19831472Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, ntohs(sd.length), 19931472Sminshall ntohl(sd.location)) == -1) { 20031472Sminshall return -1; 20131472Sminshall } 20231472Sminshall break; 20331472Sminshall default: 20431472Sminshall fprintf(stderr, "Waiting for reply command, we got command %d.\n", 20531472Sminshall i); 20631472Sminshall return -1; 20731472Sminshall } 20831472Sminshall } 20931472Sminshall if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 21031472Sminshall return -1; 21131472Sminshall } 21231472Sminshall if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 21331472Sminshall return -1; 21431472Sminshall } 21531472Sminshall /* YEAH */ 21631472Sminshall return 0; /* Happiness! */ 21731459Sminshall } 218