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