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