xref: /csrg-svn/usr.bin/tn3270/api/api_bsd.c (revision 31869)
1 #if	defined(unix)
2 
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 "../ctlr/api.h"
10 #include "api_exch.h"
11 
12 
13 int
14 api_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 
26 int
27 api_open_api(string)
28 char	*string;		/* if non-zero, where to connect to */
29 {
30     struct sockaddr_in server;
31     struct hostent *hp;
32     struct storage_descriptor sd;
33     char *getenv();
34     char thehostname[100];
35     char keyname[100];
36     char inkey[100];
37     FILE *keyfile;
38     int sock;
39     int port;
40     int i;
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 
51     if (sscanf(string, "%[^:]:%d:%s", thehostname, &port, keyname) != 3) {
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     }
74     /* Now, try application level connection */
75     if (api_exch_init(sock, "client") == -1) {
76 	return -1;
77     }
78     if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
79 	return -1;
80     }
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     }
97     while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
98 	int passwd_length;
99 	char *passwd, *getpass();
100 	char buffer[200];
101 
102 	switch (i) {
103 	case EXCH_CMD_REJECTED:
104 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC,
105 					sizeof sd, (char *)&sd) == -1) {
106 		return -1;
107 	    }
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);
113 	    if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
114 		return -1;
115 	    }
116 	    break;
117 	case EXCH_CMD_SEND_AUTH:
118 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
119 		return -1;
120 	    }
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 	    }
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 	    }
146 	    sd.length = passwd_length;
147 	    if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
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     }
165     /* YEAH */
166     return 0;		/* Happiness! */
167 }
168 
169 
170 api_exch_api(regs, sregs, parms, length)
171 union REGS *regs;
172 struct SREGS *sregs;
173 char *parms;
174 int length;
175 {
176     struct storage_descriptor sd;
177     int i;
178 
179     if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
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     }
188     sd.length = length;
189     sd.location = (long) parms;
190     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
191 	return -1;
192     }
193     if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
194 	return -1;
195     }
196     while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
197 	switch (i) {
198 	case EXCH_CMD_GIMME:
199 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
200 					== -1) {
201 		return -1;
202 	    }
203 	    /*XXX validity check GIMME? */
204 	    if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
205 		return -1;
206 	    }
207 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
208 				== -1) {
209 		return -1;
210 	    }
211 	    if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
212 			    sd.location) == -1) {
213 		return -1;
214 	    }
215 	    break;
216 	case EXCH_CMD_HEREIS:
217 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
218 					== -1) {
219 		return -1;
220 	    }
221 	    /* XXX Validty check HEREIS? */
222 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
223 			    sd.location) == -1) {
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! */
241 }
242 
243 #endif	/* unix */
244