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