BSD 4_3_Reno release
[unix-history] / usr / src / usr.bin / tn3270 / api / api_bsd.c
CommitLineData
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 19static 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
34int
35api_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
47int
bbc35556
GM
48api_open_api(string)
49char *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 195api_exch_api(regs, sregs, parms, length)
bbc35556
GM
196union REGS *regs;
197struct SREGS *sregs;
cee740d6
GM
198char *parms;
199int 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 */