1 #if defined(unix) 2 3 #include <sys/types.h> 4 #include <sys/socket.h> 5 #include <netinet/in.h> 6 #include <netdb.h> 7 #include <stdio.h> 8 9 #include "../ctlr/api.h" 10 #include "api_exch.h" 11 12 13 int 14 api_close_api() 15 { 16 if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) { 17 return -1; 18 } else if (api_exch_flush() == -1) { 19 return -1; 20 } else { 21 return 0; 22 } 23 } 24 25 26 int 27 api_open_api(string) 28 char *string; /* if non-zero, where to connect to */ 29 { 30 struct sockaddr_in server; 31 struct hostent *hp; 32 struct storage_descriptor sd; 33 char *getenv(); 34 char thehostname[100]; 35 char keyname[100]; 36 char inkey[100]; 37 FILE *keyfile; 38 int sock; 39 int port; 40 int i; 41 42 if (string == 0) { 43 string = getenv("API3270"); /* Get API */ 44 if (string == 0) { 45 fprintf(stderr, 46 "API3270 environmental variable not set - no API.\n"); 47 return -1; /* Nothing */ 48 } 49 } 50 51 if (sscanf(string, "%[^:]:%d:%s", thehostname, &port, keyname) != 3) { 52 fprintf(stderr, "API3270 environmental variable has bad format.\n"); 53 return -1; 54 } 55 /* Now, try to connect */ 56 sock = socket(AF_INET, SOCK_STREAM, 0); 57 if (sock < 0) { 58 perror("opening API socket"); 59 return -1; 60 } 61 server.sin_family = AF_INET; 62 hp = gethostbyname(thehostname); 63 if (hp == 0) { 64 fprintf(stderr, "%s specifies bad host name.\n", string); 65 return -1; 66 } 67 bcopy(hp->h_addr, &server.sin_addr, hp->h_length); 68 server.sin_port = htons(port); 69 70 if (connect(sock, &server, sizeof server) < 0) { 71 perror("connecting to API server"); 72 return -1; 73 } 74 /* Now, try application level connection */ 75 if (api_exch_init(sock, "client") == -1) { 76 return -1; 77 } 78 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 79 return -1; 80 } 81 keyfile = fopen(keyname, "r"); 82 if (keyfile == 0) { 83 perror("fopen"); 84 return -1; 85 } 86 if (fscanf(keyfile, "%s\n", inkey) != 1) { 87 perror("fscanf"); 88 return -1; 89 } 90 sd.length = strlen(inkey)+1; 91 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 92 return -1; 93 } 94 if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) { 95 return -1; 96 } 97 while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) { 98 int passwd_length; 99 char *passwd, *getpass(); 100 char buffer[200]; 101 102 switch (i) { 103 case EXCH_CMD_REJECTED: 104 if (api_exch_intype(EXCH_TYPE_STORE_DESC, 105 sizeof sd, (char *)&sd) == -1) { 106 return -1; 107 } 108 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 109 return -1; 110 } 111 buffer[sd.length] = 0; 112 fprintf(stderr, "%s\n", buffer); 113 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 114 return -1; 115 } 116 break; 117 case EXCH_CMD_SEND_AUTH: 118 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 119 return -1; 120 } 121 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 122 return -1; 123 } 124 buffer[sd.length] = 0; 125 passwd = getpass(buffer); /* Go to terminal */ 126 passwd_length = strlen(passwd); 127 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 128 return -1; 129 } 130 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 131 return -1; 132 } 133 buffer[sd.length] = 0; 134 if (sd.length) { 135 char *ptr; 136 137 ptr = passwd; 138 i = 0; 139 while (*ptr) { 140 *ptr++ ^= buffer[i++]; 141 if (i >= sd.length) { 142 i = 0; 143 } 144 } 145 } 146 sd.length = passwd_length; 147 if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) { 148 return -1; 149 } 150 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 151 return -1; 152 } 153 if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) { 154 return -1; 155 } 156 break; 157 case -1: 158 return -1; 159 default: 160 fprintf(stderr, 161 "Waiting for connection indicator, received 0x%x.\n", i); 162 break; 163 } 164 } 165 /* YEAH */ 166 return 0; /* Happiness! */ 167 } 168 169 170 api_exch_api(regs, sregs, parms, length) 171 union REGS *regs; 172 struct SREGS *sregs; 173 char *parms; 174 int length; 175 { 176 struct storage_descriptor sd; 177 int i; 178 179 if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) { 180 return -1; 181 } 182 if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 183 return -1; 184 } 185 if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 186 return -1; 187 } 188 sd.length = length; 189 sd.location = (long) parms; 190 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 191 return -1; 192 } 193 if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) { 194 return -1; 195 } 196 while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) { 197 switch (i) { 198 case EXCH_CMD_GIMME: 199 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 200 == -1) { 201 return -1; 202 } 203 /*XXX validity check GIMME? */ 204 if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { 205 return -1; 206 } 207 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 208 == -1) { 209 return -1; 210 } 211 if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, 212 sd.location) == -1) { 213 return -1; 214 } 215 break; 216 case EXCH_CMD_HEREIS: 217 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 218 == -1) { 219 return -1; 220 } 221 /* XXX Validty check HEREIS? */ 222 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, 223 sd.location) == -1) { 224 return -1; 225 } 226 break; 227 default: 228 fprintf(stderr, "Waiting for reply command, we got command %d.\n", 229 i); 230 return -1; 231 } 232 } 233 if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 234 return -1; 235 } 236 if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 237 return -1; 238 } 239 /* YEAH */ 240 return 0; /* Happiness! */ 241 } 242 243 #endif /* unix */ 244