CLBYTES should be NBPG
[unix-history] / usr / src / usr.bin / tn3270 / api / api_bsd.c
CommitLineData
5bfaa2bb
GM
1#if defined(unix)
2
bbc35556
GM
3#include <sys/types.h>
4#include <sys/socket.h>
5#include <netinet/in.h>
6#include <netdb.h>
7#include <stdio.h>
8
9#include "../api/api.h"
62946391 10#include "api_exch.h"
bbc35556
GM
11
12
d024bcc4
GM
13int
14api_close_api()
15{
16 if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) {
17 return -1;
18 } else if (api_exch_flush() == -1) {
19 return -1;
20 } else {
21 return 0;
22 }
23}
24
25
26int
bbc35556
GM
27api_open_api(string)
28char *string; /* if non-zero, where to connect to */
29{
30 struct sockaddr_in server;
31 struct hostent *hp;
fbda6d30 32 struct storage_descriptor sd;
bbc35556
GM
33 char *getenv();
34 char thehostname[100];
fbda6d30
GM
35 char keyname[100];
36 char inkey[100];
37 FILE *keyfile;
62946391 38 int sock;
bbc35556 39 int port;
62946391 40 int i;
bbc35556
GM
41
42 if (string == 0) {
43 string = getenv("API3270"); /* Get API */
44 if (string == 0) {
45 fprintf(stderr,
46 "API3270 environmental variable not set - no API.\n");
47 return -1; /* Nothing */
48 }
49 }
50
fbda6d30 51 if (sscanf(string, "%[^:]:%d:%s", thehostname, &port, keyname) != 3) {
bbc35556
GM
52 fprintf(stderr, "API3270 environmental variable has bad format.\n");
53 return -1;
54 }
55 /* Now, try to connect */
56 sock = socket(AF_INET, SOCK_STREAM, 0);
57 if (sock < 0) {
58 perror("opening API socket");
59 return -1;
60 }
61 server.sin_family = AF_INET;
62 hp = gethostbyname(thehostname);
63 if (hp == 0) {
64 fprintf(stderr, "%s specifies bad host name.\n", string);
65 return -1;
66 }
67 bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
68 server.sin_port = htons(port);
69
70 if (connect(sock, &server, sizeof server) < 0) {
71 perror("connecting to API server");
72 return -1;
73 }
62946391 74 /* Now, try application level connection */
d024bcc4 75 if (api_exch_init(sock, "client") == -1) {
62946391
GM
76 return -1;
77 }
d024bcc4 78 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
62946391
GM
79 return -1;
80 }
fbda6d30
GM
81 keyfile = fopen(keyname, "r");
82 if (keyfile == 0) {
83 perror("fopen");
84 return -1;
85 }
86 if (fscanf(keyfile, "%s\n", inkey) != 1) {
87 perror("fscanf");
88 return -1;
89 }
90 sd.length = strlen(inkey)+1;
91 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
92 return -1;
93 }
94 if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) {
95 return -1;
96 }
d024bcc4 97 while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
62946391
GM
98 int passwd_length;
99 char *passwd, *getpass();
100 char buffer[200];
101
102 switch (i) {
d024bcc4 103 case EXCH_CMD_REJECTED:
62946391
GM
104 if (api_exch_intype(EXCH_TYPE_STORE_DESC,
105 sizeof sd, (char *)&sd) == -1) {
106 return -1;
107 }
62946391
GM
108 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
109 return -1;
110 }
111 buffer[sd.length] = 0;
112 fprintf(stderr, "%s\n", buffer);
d024bcc4 113 if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
62946391
GM
114 return -1;
115 }
116 break;
d024bcc4 117 case EXCH_CMD_SEND_AUTH:
62946391
GM
118 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
119 return -1;
120 }
62946391
GM
121 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
122 return -1;
123 }
124 buffer[sd.length] = 0;
125 passwd = getpass(buffer); /* Go to terminal */
126 passwd_length = strlen(passwd);
127 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
128 return -1;
129 }
62946391
GM
130 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
131 return -1;
132 }
133 buffer[sd.length] = 0;
134 if (sd.length) {
135 char *ptr;
136
137 ptr = passwd;
138 i = 0;
139 while (*ptr) {
140 *ptr++ ^= buffer[i++];
141 if (i >= sd.length) {
142 i = 0;
143 }
144 }
145 }
fbda6d30 146 sd.length = passwd_length;
d024bcc4 147 if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
62946391
GM
148 return -1;
149 }
150 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
151 return -1;
152 }
153 if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
154 return -1;
155 }
156 break;
157 case -1:
158 return -1;
159 default:
160 fprintf(stderr,
161 "Waiting for connection indicator, received 0x%x.\n", i);
162 break;
163 }
164 }
bbc35556
GM
165 /* YEAH */
166 return 0; /* Happiness! */
167}
168
169
cee740d6 170api_exch_api(regs, sregs, parms, length)
bbc35556
GM
171union REGS *regs;
172struct SREGS *sregs;
cee740d6
GM
173char *parms;
174int length;
bbc35556 175{
0d854484
GM
176 struct storage_descriptor sd;
177 int i;
178
d024bcc4 179 if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
0d854484
GM
180 return -1;
181 }
182 if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
183 return -1;
184 }
185 if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
186 return -1;
187 }
fbda6d30
GM
188 sd.length = length;
189 sd.location = (long) parms;
0d854484
GM
190 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
191 return -1;
192 }
cee740d6
GM
193 if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
194 return -1;
195 }
d024bcc4 196 while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
0d854484 197 switch (i) {
d024bcc4 198 case EXCH_CMD_GIMME:
0d854484
GM
199 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
200 == -1) {
201 return -1;
202 }
203 /*XXX validity check GIMME? */
d024bcc4 204 if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
0d854484
GM
205 return -1;
206 }
207 if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
208 == -1) {
209 return -1;
210 }
fbda6d30
GM
211 if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
212 sd.location) == -1) {
0d854484
GM
213 return -1;
214 }
215 break;
d024bcc4 216 case EXCH_CMD_HEREIS:
0d854484
GM
217 if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
218 == -1) {
219 return -1;
220 }
221 /* XXX Validty check HEREIS? */
fbda6d30
GM
222 if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
223 sd.location) == -1) {
0d854484
GM
224 return -1;
225 }
226 break;
227 default:
228 fprintf(stderr, "Waiting for reply command, we got command %d.\n",
229 i);
230 return -1;
231 }
232 }
233 if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
234 return -1;
235 }
236 if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
237 return -1;
238 }
239 /* YEAH */
240 return 0; /* Happiness! */
bbc35556 241}
5bfaa2bb
GM
242
243#endif /* unix */