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