Commit | Line | Data |
---|---|---|
992de934 | 1 | /* |
f6e43951 KB |
2 | * Copyright (c) 1988 Regents of the University of California. |
3 | * All rights reserved. | |
992de934 | 4 | * |
f6e43951 | 5 | * Redistribution and use in source and binary forms are permitted |
b36fc510 KB |
6 | * provided that the above copyright notice and this paragraph are |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
992de934 GM |
16 | */ |
17 | ||
18 | #ifndef lint | |
1c15e888 | 19 | static char sccsid[] = "@(#)api_bsd.c 4.1 (Berkeley) 12/4/88"; |
f6e43951 | 20 | #endif /* not lint */ |
992de934 | 21 | |
5bfaa2bb GM |
22 | #if defined(unix) |
23 | ||
bbc35556 GM |
24 | #include <sys/types.h> |
25 | #include <sys/socket.h> | |
26 | #include <netinet/in.h> | |
27 | #include <netdb.h> | |
28 | #include <stdio.h> | |
29 | ||
9c711786 | 30 | #include "../ctlr/api.h" |
62946391 | 31 | #include "api_exch.h" |
bbc35556 GM |
32 | |
33 | ||
d024bcc4 GM |
34 | int |
35 | api_close_api() | |
36 | { | |
37 | if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) { | |
38 | return -1; | |
39 | } else if (api_exch_flush() == -1) { | |
40 | return -1; | |
41 | } else { | |
42 | return 0; | |
43 | } | |
44 | } | |
45 | ||
46 | ||
47 | int | |
bbc35556 GM |
48 | api_open_api(string) |
49 | char *string; /* if non-zero, where to connect to */ | |
50 | { | |
51 | struct sockaddr_in server; | |
52 | struct hostent *hp; | |
fbda6d30 | 53 | struct storage_descriptor sd; |
db693c34 | 54 | extern char *getenv(); |
fae18fad | 55 | #if !defined(htons) |
db693c34 | 56 | extern unsigned short htons(); |
fae18fad | 57 | #endif /* !defined(htons) */ |
bbc35556 | 58 | char thehostname[100]; |
fbda6d30 GM |
59 | char keyname[100]; |
60 | char inkey[100]; | |
61 | FILE *keyfile; | |
62946391 | 62 | int sock; |
db693c34 | 63 | unsigned int port; |
62946391 | 64 | int i; |
bbc35556 GM |
65 | |
66 | if (string == 0) { | |
67 | string = getenv("API3270"); /* Get API */ | |
68 | if (string == 0) { | |
69 | fprintf(stderr, | |
70 | "API3270 environmental variable not set - no API.\n"); | |
71 | return -1; /* Nothing */ | |
72 | } | |
73 | } | |
74 | ||
db693c34 GM |
75 | if (sscanf(string, "%[^:]:%d:%s", thehostname, |
76 | (int *)&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 | } | |
db693c34 | 92 | bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length); |
bbc35556 GM |
93 | server.sin_port = htons(port); |
94 | ||
db693c34 | 95 | if (connect(sock, (struct sockaddr *)&server, sizeof server) < 0) { |
bbc35556 GM |
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 | 236 | if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, |
db693c34 | 237 | (char *)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 | 247 | if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, |
db693c34 | 248 | (char *)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 */ |