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