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