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