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