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