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