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