1 #include <sys/types.h> 2 #include <sys/socket.h> 3 #include <netinet/in.h> 4 #include <netdb.h> 5 #include <stdio.h> 6 7 #include "../api/api.h" 8 #include "api_exch.h" 9 10 11 api_open_api(string) 12 char *string; /* if non-zero, where to connect to */ 13 { 14 struct sockaddr_in server; 15 struct hostent *hp; 16 char *getenv(); 17 char thehostname[100]; 18 int sock; 19 int port; 20 int i; 21 22 if (string == 0) { 23 string = getenv("API3270"); /* Get API */ 24 if (string == 0) { 25 fprintf(stderr, 26 "API3270 environmental variable not set - no API.\n"); 27 return -1; /* Nothing */ 28 } 29 } 30 31 if (sscanf(string, "%[^:]:%d", thehostname, &port) != 2) { 32 fprintf(stderr, "API3270 environmental variable has bad format.\n"); 33 return -1; 34 } 35 /* Now, try to connect */ 36 sock = socket(AF_INET, SOCK_STREAM, 0); 37 if (sock < 0) { 38 perror("opening API socket"); 39 return -1; 40 } 41 server.sin_family = AF_INET; 42 hp = gethostbyname(thehostname); 43 if (hp == 0) { 44 fprintf(stderr, "%s specifies bad host name.\n", string); 45 return -1; 46 } 47 bcopy(hp->h_addr, &server.sin_addr, hp->h_length); 48 server.sin_port = htons(port); 49 50 if (connect(sock, &server, sizeof server) < 0) { 51 perror("connecting to API server"); 52 return -1; 53 } 54 /* Now, try application level connection */ 55 if (api_exch_init(sock) == -1) { 56 return -1; 57 } 58 if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) { 59 return -1; 60 } 61 while ((i = api_exch_inbyte()) != EXCH_ASSOCIATED) { 62 struct storage_descriptor sd; 63 int passwd_length; 64 char *passwd, *getpass(); 65 char buffer[200]; 66 67 switch (i) { 68 case EXCH_REJECTED: 69 if (api_exch_intype(EXCH_TYPE_STORE_DESC, 70 sizeof sd, (char *)&sd) == -1) { 71 return -1; 72 } 73 sd.length = ntohs(sd.length); 74 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 75 return -1; 76 } 77 buffer[sd.length] = 0; 78 fprintf(stderr, "%s\n", buffer); 79 if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) { 80 return -1; 81 } 82 break; 83 case EXCH_SEND_AUTH: 84 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 85 return -1; 86 } 87 sd.length = ntohs(sd.length); 88 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 89 return -1; 90 } 91 buffer[sd.length] = 0; 92 passwd = getpass(buffer); /* Go to terminal */ 93 passwd_length = strlen(passwd); 94 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 95 return -1; 96 } 97 sd.length = ntohs(sd.length); 98 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 99 return -1; 100 } 101 buffer[sd.length] = 0; 102 if (sd.length) { 103 char *ptr; 104 105 ptr = passwd; 106 i = 0; 107 while (*ptr) { 108 *ptr++ ^= buffer[i++]; 109 if (i >= sd.length) { 110 i = 0; 111 } 112 } 113 } 114 sd.length = htons(passwd_length); 115 if (api_exch_outcommand(EXCH_AUTH) == -1) { 116 return -1; 117 } 118 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 119 return -1; 120 } 121 if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) { 122 return -1; 123 } 124 break; 125 case -1: 126 return -1; 127 default: 128 fprintf(stderr, 129 "Waiting for connection indicator, received 0x%x.\n", i); 130 break; 131 } 132 } 133 /* YEAH */ 134 return 0; /* Happiness! */ 135 } 136 137 138 api_exch_api(regs, sregs) 139 union REGS *regs; 140 struct SREGS *sregs; 141 { 142 } 143