1 /* $NetBSD: api_bsd.c,v 1.12 2006/04/30 23:52:14 christos Exp $ */
4 * Copyright (c) 1988 The Regents of the University of California.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
32 #include <sys/cdefs.h>
33 #if defined(__RCSID) && !defined(lint)
35 static char sccsid
[] = "@(#)api_bsd.c 4.2 (Berkeley) 4/26/91";
37 __RCSID("$NetBSD: api_bsd.c,v 1.12 2006/04/30 23:52:14 christos Exp $");
43 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <netinet/in.h>
52 #include "../ctlr/api.h"
59 if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE
) == -1) {
61 } else if (api_exch_flush() == -1) {
71 char *string
; /* if non-zero, where to connect to */
73 struct sockaddr_in server
;
75 struct storage_descriptor sd
;
76 char thehostname
[100];
85 string
= getenv("API3270"); /* Get API */
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");
98 /* Now, try to connect */
99 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
101 perror("opening API socket");
104 server
.sin_family
= AF_INET
;
105 hp
= gethostbyname(thehostname
);
107 fprintf(stderr
, "%s specifies bad host name.\n", string
);
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");
119 /* Now, try application level connection */
120 if (api_exch_init(sock
, "client") == -1) {
123 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE
) == -1) {
126 keyfile
= fopen(keyname
, "r");
131 if (fscanf(keyfile
, "%99s\n", inkey
) != 1) {
135 sd
.length
= strlen(inkey
)+1;
136 if (api_exch_outtype(EXCH_TYPE_STORE_DESC
, sizeof sd
, (char *)&sd
) == -1) {
139 if (api_exch_outtype(EXCH_TYPE_BYTES
, sd
.length
, inkey
) == -1) {
142 while ((i
= api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED
) {
148 case EXCH_CMD_REJECTED
:
149 if (api_exch_intype(EXCH_TYPE_STORE_DESC
,
150 sizeof sd
, (char *)&sd
) == -1) {
153 if (api_exch_intype(EXCH_TYPE_BYTES
, sd
.length
, buffer
) == -1) {
156 buffer
[sd
.length
] = 0;
157 fprintf(stderr
, "%s\n", buffer
);
158 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE
) == -1) {
162 case EXCH_CMD_SEND_AUTH
:
163 if (api_exch_intype(EXCH_TYPE_STORE_DESC
, sizeof sd
, (char *)&sd
) == -1) {
166 if (api_exch_intype(EXCH_TYPE_BYTES
, sd
.length
, buffer
) == -1) {
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) {
175 if (api_exch_intype(EXCH_TYPE_BYTES
, sd
.length
, buffer
) == -1) {
178 buffer
[sd
.length
] = 0;
185 *ptr
++ ^= buffer
[i
++];
186 if (i
>= sd
.length
) {
191 sd
.length
= passwd_length
;
192 if (api_exch_outcommand(EXCH_CMD_AUTH
) == -1) {
195 if (api_exch_outtype(EXCH_TYPE_STORE_DESC
, sizeof sd
, (char *)&sd
) == -1) {
198 if (api_exch_outtype(EXCH_TYPE_BYTES
, passwd_length
, passwd
) == -1) {
206 "Waiting for connection indicator, received 0x%x.\n", i
);
212 return 0; /* Happiness! */
221 api_exch_api(regs
, sregs
, parms
, length
)
227 struct storage_descriptor sd
;
230 if (api_exch_outcommand(EXCH_CMD_REQUEST
) == -1) {
233 if (api_exch_outtype(EXCH_TYPE_REGS
, sizeof *regs
, (char *)regs
) == -1) {
236 if (api_exch_outtype(EXCH_TYPE_SREGS
, sizeof *sregs
, (char *)sregs
) == -1) {
240 sd
.location
= (long) parms
;
241 if (api_exch_outtype(EXCH_TYPE_STORE_DESC
, sizeof sd
, (char *)&sd
) == -1) {
244 if (api_exch_outtype(EXCH_TYPE_BYTES
, length
, parms
) == -1) {
247 while ((i
= api_exch_nextcommand()) != EXCH_CMD_REPLY
) {
250 if (api_exch_intype(EXCH_TYPE_STORE_DESC
, sizeof sd
, (char *)&sd
)
254 /*XXX validity check GIMME? */
255 if (api_exch_outcommand(EXCH_CMD_HEREIS
) == -1) {
258 if (api_exch_outtype(EXCH_TYPE_STORE_DESC
, sizeof sd
, (char *)&sd
)
262 if (api_exch_outtype(EXCH_TYPE_BYTES
, sd
.length
,
263 (char *)sd
.location
) == -1) {
267 case EXCH_CMD_HEREIS
:
268 if (api_exch_intype(EXCH_TYPE_STORE_DESC
, sizeof sd
, (char *)&sd
)
272 /* XXX Validty check HEREIS? */
273 if (api_exch_intype(EXCH_TYPE_BYTES
, sd
.length
,
274 (char *)sd
.location
) == -1) {
279 fprintf(stderr
, "Waiting for reply command, we got command %d.\n",
284 if (api_exch_intype(EXCH_TYPE_REGS
, sizeof *regs
, (char *)regs
) == -1) {
287 if (api_exch_intype(EXCH_TYPE_SREGS
, sizeof *sregs
, (char *)sregs
) == -1) {
291 return 0; /* Happiness! */