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