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