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.5 (Berkeley) 09/14/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 extern char *getenv(); 55 #if !defined(htons) 56 extern unsigned short htons(); 57 #endif /* !defined(htons) */ 58 char thehostname[100]; 59 char keyname[100]; 60 char inkey[100]; 61 FILE *keyfile; 62 int sock; 63 unsigned int port; 64 int i; 65 66 if (string == 0) { 67 string = getenv("API3270"); /* Get API */ 68 if (string == 0) { 69 fprintf(stderr, 70 "API3270 environmental variable not set - no API.\n"); 71 return -1; /* Nothing */ 72 } 73 } 74 75 if (sscanf(string, "%[^:]:%d:%s", thehostname, 76 (int *)&port, keyname) != 3) { 77 fprintf(stderr, "API3270 environmental variable has bad format.\n"); 78 return -1; 79 } 80 /* Now, try to connect */ 81 sock = socket(AF_INET, SOCK_STREAM, 0); 82 if (sock < 0) { 83 perror("opening API socket"); 84 return -1; 85 } 86 server.sin_family = AF_INET; 87 hp = gethostbyname(thehostname); 88 if (hp == 0) { 89 fprintf(stderr, "%s specifies bad host name.\n", string); 90 return -1; 91 } 92 bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length); 93 server.sin_port = htons(port); 94 95 if (connect(sock, (struct sockaddr *)&server, sizeof server) < 0) { 96 perror("connecting to API server"); 97 return -1; 98 } 99 /* Now, try application level connection */ 100 if (api_exch_init(sock, "client") == -1) { 101 return -1; 102 } 103 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 104 return -1; 105 } 106 keyfile = fopen(keyname, "r"); 107 if (keyfile == 0) { 108 perror("fopen"); 109 return -1; 110 } 111 if (fscanf(keyfile, "%s\n", inkey) != 1) { 112 perror("fscanf"); 113 return -1; 114 } 115 sd.length = strlen(inkey)+1; 116 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 117 return -1; 118 } 119 if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) { 120 return -1; 121 } 122 while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) { 123 int passwd_length; 124 char *passwd, *getpass(); 125 char buffer[200]; 126 127 switch (i) { 128 case EXCH_CMD_REJECTED: 129 if (api_exch_intype(EXCH_TYPE_STORE_DESC, 130 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 fprintf(stderr, "%s\n", buffer); 138 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { 139 return -1; 140 } 141 break; 142 case EXCH_CMD_SEND_AUTH: 143 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 144 return -1; 145 } 146 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 147 return -1; 148 } 149 buffer[sd.length] = 0; 150 passwd = getpass(buffer); /* Go to terminal */ 151 passwd_length = strlen(passwd); 152 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 153 return -1; 154 } 155 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 156 return -1; 157 } 158 buffer[sd.length] = 0; 159 if (sd.length) { 160 char *ptr; 161 162 ptr = passwd; 163 i = 0; 164 while (*ptr) { 165 *ptr++ ^= buffer[i++]; 166 if (i >= sd.length) { 167 i = 0; 168 } 169 } 170 } 171 sd.length = passwd_length; 172 if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) { 173 return -1; 174 } 175 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 176 return -1; 177 } 178 if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) { 179 return -1; 180 } 181 break; 182 case -1: 183 return -1; 184 default: 185 fprintf(stderr, 186 "Waiting for connection indicator, received 0x%x.\n", i); 187 break; 188 } 189 } 190 /* YEAH */ 191 return 0; /* Happiness! */ 192 } 193 194 195 api_exch_api(regs, sregs, parms, length) 196 union REGS *regs; 197 struct SREGS *sregs; 198 char *parms; 199 int length; 200 { 201 struct storage_descriptor sd; 202 int i; 203 204 if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) { 205 return -1; 206 } 207 if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 208 return -1; 209 } 210 if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 211 return -1; 212 } 213 sd.length = length; 214 sd.location = (long) parms; 215 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 216 return -1; 217 } 218 if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) { 219 return -1; 220 } 221 while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) { 222 switch (i) { 223 case EXCH_CMD_GIMME: 224 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 225 == -1) { 226 return -1; 227 } 228 /*XXX validity check GIMME? */ 229 if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { 230 return -1; 231 } 232 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 233 == -1) { 234 return -1; 235 } 236 if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, 237 (char *)sd.location) == -1) { 238 return -1; 239 } 240 break; 241 case EXCH_CMD_HEREIS: 242 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) 243 == -1) { 244 return -1; 245 } 246 /* XXX Validty check HEREIS? */ 247 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, 248 (char *)sd.location) == -1) { 249 return -1; 250 } 251 break; 252 default: 253 fprintf(stderr, "Waiting for reply command, we got command %d.\n", 254 i); 255 return -1; 256 } 257 } 258 if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) { 259 return -1; 260 } 261 if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) { 262 return -1; 263 } 264 /* YEAH */ 265 return 0; /* Happiness! */ 266 } 267 268 #endif /* unix */ 269