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