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