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" 8*31467Sminshall #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]; 18*31467Sminshall int sock; 1931459Sminshall int port; 20*31467Sminshall 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 } 54*31467Sminshall /* Now, try application level connection */ 55*31467Sminshall if (api_exch_init(sock) == -1) { 56*31467Sminshall return -1; 57*31467Sminshall } 58*31467Sminshall if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) { 59*31467Sminshall return -1; 60*31467Sminshall } 61*31467Sminshall while ((i = api_exch_inbyte()) != EXCH_ASSOCIATED) { 62*31467Sminshall struct storage_descriptor sd; 63*31467Sminshall int passwd_length; 64*31467Sminshall char *passwd, *getpass(); 65*31467Sminshall char buffer[200]; 66*31467Sminshall 67*31467Sminshall switch (i) { 68*31467Sminshall case EXCH_REJECTED: 69*31467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, 70*31467Sminshall sizeof sd, (char *)&sd) == -1) { 71*31467Sminshall return -1; 72*31467Sminshall } 73*31467Sminshall sd.length = ntohs(sd.length); 74*31467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 75*31467Sminshall return -1; 76*31467Sminshall } 77*31467Sminshall buffer[sd.length] = 0; 78*31467Sminshall fprintf(stderr, "%s\n", buffer); 79*31467Sminshall if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) { 80*31467Sminshall return -1; 81*31467Sminshall } 82*31467Sminshall break; 83*31467Sminshall case EXCH_SEND_AUTH: 84*31467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 85*31467Sminshall return -1; 86*31467Sminshall } 87*31467Sminshall sd.length = ntohs(sd.length); 88*31467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 89*31467Sminshall return -1; 90*31467Sminshall } 91*31467Sminshall buffer[sd.length] = 0; 92*31467Sminshall passwd = getpass(buffer); /* Go to terminal */ 93*31467Sminshall passwd_length = strlen(passwd); 94*31467Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 95*31467Sminshall return -1; 96*31467Sminshall } 97*31467Sminshall sd.length = ntohs(sd.length); 98*31467Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 99*31467Sminshall return -1; 100*31467Sminshall } 101*31467Sminshall buffer[sd.length] = 0; 102*31467Sminshall if (sd.length) { 103*31467Sminshall char *ptr; 104*31467Sminshall 105*31467Sminshall ptr = passwd; 106*31467Sminshall i = 0; 107*31467Sminshall while (*ptr) { 108*31467Sminshall *ptr++ ^= buffer[i++]; 109*31467Sminshall if (i >= sd.length) { 110*31467Sminshall i = 0; 111*31467Sminshall } 112*31467Sminshall } 113*31467Sminshall } 114*31467Sminshall sd.length = htons(passwd_length); 115*31467Sminshall if (api_exch_outcommand(EXCH_AUTH) == -1) { 116*31467Sminshall return -1; 117*31467Sminshall } 118*31467Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 119*31467Sminshall return -1; 120*31467Sminshall } 121*31467Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) { 122*31467Sminshall return -1; 123*31467Sminshall } 124*31467Sminshall break; 125*31467Sminshall case -1: 126*31467Sminshall return -1; 127*31467Sminshall default: 128*31467Sminshall fprintf(stderr, 129*31467Sminshall "Waiting for connection indicator, received 0x%x.\n", i); 130*31467Sminshall break; 131*31467Sminshall } 132*31467Sminshall } 13331459Sminshall /* YEAH */ 13431459Sminshall return 0; /* Happiness! */ 13531459Sminshall } 13631459Sminshall 13731459Sminshall 13831459Sminshall api_exch_api(regs, sregs) 13931459Sminshall union REGS *regs; 14031459Sminshall struct SREGS *sregs; 14131459Sminshall { 14231459Sminshall } 143