Commit | Line | Data |
---|---|---|
992de934 GM |
1 | /* |
2 | * Copyright (c) 1984-1987 by the Regents of the | |
3 | * University of California and by Gregory Glenn Minshall. | |
4 | * | |
5 | * Permission to use, copy, modify, and distribute these | |
6 | * programs and their documentation for any purpose and | |
7 | * without fee is hereby granted, provided that this | |
8 | * copyright and permission appear on all copies and | |
9 | * supporting documentation, the name of the Regents of | |
10 | * the University of California not be used in advertising | |
11 | * or publicity pertaining to distribution of the programs | |
12 | * without specific prior permission, and notice be given in | |
13 | * supporting documentation that copying and distribution is | |
14 | * by permission of the Regents of the University of California | |
15 | * and by Gregory Glenn Minshall. Neither the Regents of the | |
16 | * University of California nor Gregory Glenn Minshall make | |
17 | * representations about the suitability of this software | |
18 | * for any purpose. It is provided "as is" without | |
19 | * express or implied warranty. | |
20 | */ | |
21 | ||
22 | #ifndef lint | |
23 | static char sccsid[] = "@(#)api_bsd.c 1.9 (Berkeley) %G%"; | |
24 | #endif /* not lint */ | |
25 | ||
5bfaa2bb GM |
26 | #if defined(unix) |
27 | ||
bbc35556 GM |
28 | #include <sys/types.h> |
29 | #include <sys/socket.h> | |
30 | #include <netinet/in.h> | |
31 | #include <netdb.h> | |
32 | #include <stdio.h> | |
33 | ||
9c711786 | 34 | #include "../ctlr/api.h" |
62946391 | 35 | #include "api_exch.h" |
bbc35556 GM |
36 | |
37 | ||
d024bcc4 GM |
38 | int |
39 | api_close_api() | |
40 | { | |
41 | if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) { | |
42 | return -1; | |
43 | } else if (api_exch_flush() == -1) { | |
44 | return -1; | |
45 | } else { | |
46 | return 0; | |
47 | } | |
48 | } | |
49 | ||
50 | ||
51 | int | |
bbc35556 GM |
52 | api_open_api(string) |
53 | char *string; /* if non-zero, where to connect to */ | |
54 | { | |
55 | struct sockaddr_in server; | |
56 | struct hostent *hp; | |
fbda6d30 | 57 | struct storage_descriptor sd; |
bbc35556 GM |
58 | char *getenv(); |
59 | char thehostname[100]; | |
fbda6d30 GM |
60 | char keyname[100]; |
61 | char inkey[100]; | |
62 | FILE *keyfile; | |
62946391 | 63 | int sock; |
bbc35556 | 64 | int port; |
62946391 | 65 | int i; |
bbc35556 GM |
66 | |
67 | if (string == 0) { | |
68 | string = getenv("API3270"); /* Get API */ | |
69 | if (string == 0) { | |
70 | fprintf(stderr, | |
71 | "API3270 environmental variable not set - no API.\n"); | |
72 | return -1; /* Nothing */ | |
73 | } | |
74 | } | |
75 | ||
fbda6d30 | 76 | if (sscanf(string, "%[^:]:%d:%s", thehostname, &port, keyname) != 3) { |
bbc35556 GM |
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, &server.sin_addr, hp->h_length); | |
93 | server.sin_port = htons(port); | |
94 | ||
95 | if (connect(sock, &server, sizeof server) < 0) { | |
96 | perror("connecting to API server"); | |
97 | return -1; | |
98 | } | |
62946391 | 99 | /* Now, try application level connection */ |
d024bcc4 | 100 | if (api_exch_init(sock, "client") == -1) { |
62946391 GM |
101 | return -1; |
102 | } | |
d024bcc4 | 103 | if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { |
62946391 GM |
104 | return -1; |
105 | } | |
fbda6d30 GM |
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 | } | |
d024bcc4 | 122 | while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) { |
62946391 GM |
123 | int passwd_length; |
124 | char *passwd, *getpass(); | |
125 | char buffer[200]; | |
126 | ||
127 | switch (i) { | |
d024bcc4 | 128 | case EXCH_CMD_REJECTED: |
62946391 GM |
129 | if (api_exch_intype(EXCH_TYPE_STORE_DESC, |
130 | sizeof sd, (char *)&sd) == -1) { | |
131 | return -1; | |
132 | } | |
62946391 GM |
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); | |
d024bcc4 | 138 | if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) { |
62946391 GM |
139 | return -1; |
140 | } | |
141 | break; | |
d024bcc4 | 142 | case EXCH_CMD_SEND_AUTH: |
62946391 GM |
143 | if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { |
144 | return -1; | |
145 | } | |
62946391 GM |
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 | } | |
62946391 GM |
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 | } | |
fbda6d30 | 171 | sd.length = passwd_length; |
d024bcc4 | 172 | if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) { |
62946391 GM |
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 | } | |
bbc35556 GM |
190 | /* YEAH */ |
191 | return 0; /* Happiness! */ | |
192 | } | |
193 | ||
194 | ||
cee740d6 | 195 | api_exch_api(regs, sregs, parms, length) |
bbc35556 GM |
196 | union REGS *regs; |
197 | struct SREGS *sregs; | |
cee740d6 GM |
198 | char *parms; |
199 | int length; | |
bbc35556 | 200 | { |
0d854484 GM |
201 | struct storage_descriptor sd; |
202 | int i; | |
203 | ||
d024bcc4 | 204 | if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) { |
0d854484 GM |
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 | } | |
fbda6d30 GM |
213 | sd.length = length; |
214 | sd.location = (long) parms; | |
0d854484 GM |
215 | if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { |
216 | return -1; | |
217 | } | |
cee740d6 GM |
218 | if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) { |
219 | return -1; | |
220 | } | |
d024bcc4 | 221 | while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) { |
0d854484 | 222 | switch (i) { |
d024bcc4 | 223 | case EXCH_CMD_GIMME: |
0d854484 GM |
224 | if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) |
225 | == -1) { | |
226 | return -1; | |
227 | } | |
228 | /*XXX validity check GIMME? */ | |
d024bcc4 | 229 | if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { |
0d854484 GM |
230 | return -1; |
231 | } | |
232 | if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) | |
233 | == -1) { | |
234 | return -1; | |
235 | } | |
fbda6d30 GM |
236 | if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, |
237 | sd.location) == -1) { | |
0d854484 GM |
238 | return -1; |
239 | } | |
240 | break; | |
d024bcc4 | 241 | case EXCH_CMD_HEREIS: |
0d854484 GM |
242 | if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) |
243 | == -1) { | |
244 | return -1; | |
245 | } | |
246 | /* XXX Validty check HEREIS? */ | |
fbda6d30 GM |
247 | if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, |
248 | sd.location) == -1) { | |
0d854484 GM |
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! */ | |
bbc35556 | 266 | } |
5bfaa2bb GM |
267 | |
268 | #endif /* unix */ |