386BSD 0.0 development
[unix-history] / usr / src / usr.bin / tn3270 / api / api_bsd.c
CommitLineData
b4817db3
WJ
1/*-
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)api_bsd.c 4.2 (Berkeley) 4/26/91";
36#endif /* not lint */
37
38#if defined(unix)
39
40#include <sys/types.h>
41#include <sys/socket.h>
42#include <netinet/in.h>
43#include <netdb.h>
44#include <stdio.h>
45
46#include "../ctlr/api.h"
47#include "api_exch.h"
48
49
50int
51api_close_api()
52{
53 if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) {
54 return -1;
55 } else if (api_exch_flush() == -1) {
56 return -1;
57 } else {
58 return 0;
59 }
60}
61
62
63int
64api_open_api(string)
65char *string; /* if non-zero, where to connect to */
66{
67 struct sockaddr_in server;
68 struct hostent *hp;
69 struct storage_descriptor sd;
70 extern char *getenv();
71#if !defined(htons)
72 extern unsigned short htons();
73#endif /* !defined(htons) */
74 char thehostname[100];
75 char keyname[100];
76 char inkey[100];
77 FILE *keyfile;
78 int sock;
79 unsigned int port;
80 int i;
81
82 if (string == 0) {
83 string = getenv("API3270"); /* Get API */
84 if (string == 0) {
85 fprintf(stderr,
86 "API3270 environmental variable not set - no API.\n");
87 return -1; /* Nothing */
88 }
89 }
90
91 if (sscanf(string, "%[^:]:%d:%s", thehostname,
92 (int *)&port, keyname) != 3) {
93 fprintf(stderr, "API3270 environmental variable has bad format.\n");
94 return -1;
95 }
96 /* Now, try to connect */
97 sock = socket(AF_INET, SOCK_STREAM, 0);
98 if (sock < 0) {
99 perror("opening API socket");
100 return -1;
101 }
102 server.sin_family = AF_INET;
103 hp = gethostbyname(thehostname);
104 if (hp == 0) {
105 fprintf(stderr, "%s specifies bad host name.\n", string);
106 return -1;
107 }
108 bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
109 server.sin_port = htons(port);
110
111 if (connect(sock, (struct sockaddr *)&server, sizeof server) < 0) {
112 perror("connecting to API server");
113 return -1;
114 }
115 /* Now, try application level connection */
116 if (api_exch_init(sock, "client") == -1) {
117 return -1;
118 }
119 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
120 return -1;
121 }
122 keyfile = fopen(keyname, "r");
123 if (keyfile == 0) {
124 perror("fopen");
125 return -1;
126 }
127 if (fscanf(keyfile, "%s\n", inkey) != 1) {
128 perror("fscanf");
129 return -1;
130 }
131 sd.length = strlen(inkey)+1;
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, sd.length, inkey) == -1) {
136 return -1;
137 }
138 while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
139 int passwd_length;
140 char *passwd, *getpass();
141 char buffer[200];
142
143 switch (i) {
144 case EXCH_CMD_REJECTED:
145 if (api_exch_intype(EXCH_TYPE_STORE_DESC,
146 sizeof sd, (char *)&sd) == -1) {
147 return -1;
148 }
149 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
150 return -1;
151 }
152 buffer[sd.length] = 0;
153 fprintf(stderr, "%s\n", buffer);
154 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
155 return -1;
156 }
157 break;
158 case EXCH_CMD_SEND_AUTH:
159 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
160 return -1;
161 }
162 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
163 return -1;
164 }
165 buffer[sd.length] = 0;
166 passwd = getpass(buffer); /* Go to terminal */
167 passwd_length = strlen(passwd);
168 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
169 return -1;
170 }
171 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
172 return -1;
173 }
174 buffer[sd.length] = 0;
175 if (sd.length) {
176 char *ptr;
177
178 ptr = passwd;
179 i = 0;
180 while (*ptr) {
181 *ptr++ ^= buffer[i++];
182 if (i >= sd.length) {
183 i = 0;
184 }
185 }
186 }
187 sd.length = passwd_length;
188 if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
189 return -1;
190 }
191 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
192 return -1;
193 }
194 if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
195 return -1;
196 }
197 break;
198 case -1:
199 return -1;
200 default:
201 fprintf(stderr,
202 "Waiting for connection indicator, received 0x%x.\n", i);
203 break;
204 }
205 }
206 /* YEAH */
207 return 0; /* Happiness! */
208}
209
210
211api_exch_api(regs, sregs, parms, length)
212union REGS *regs;
213struct SREGS *sregs;
214char *parms;
215int length;
216{
217 struct storage_descriptor sd;
218 int i;
219
220 if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
221 return -1;
222 }
223 if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
224 return -1;
225 }
226 if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
227 return -1;
228 }
229 sd.length = length;
230 sd.location = (long) parms;
231 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
232 return -1;
233 }
234 if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
235 return -1;
236 }
237 while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
238 switch (i) {
239 case EXCH_CMD_GIMME:
240 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
241 == -1) {
242 return -1;
243 }
244 /*XXX validity check GIMME? */
245 if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
246 return -1;
247 }
248 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
249 == -1) {
250 return -1;
251 }
252 if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
253 (char *)sd.location) == -1) {
254 return -1;
255 }
256 break;
257 case EXCH_CMD_HEREIS:
258 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
259 == -1) {
260 return -1;
261 }
262 /* XXX Validty check HEREIS? */
263 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
264 (char *)sd.location) == -1) {
265 return -1;
266 }
267 break;
268 default:
269 fprintf(stderr, "Waiting for reply command, we got command %d.\n",
270 i);
271 return -1;
272 }
273 }
274 if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
275 return -1;
276 }
277 if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
278 return -1;
279 }
280 /* YEAH */
281 return 0; /* Happiness! */
282}
283
284#endif /* unix */