|
|
1.1 root 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 4.1 (Berkeley) 12/4/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: extern char *getenv();
55: #if !defined(htons)
56: extern unsigned short htons();
57: #endif /* !defined(htons) */
58: char thehostname[100];
59: char keyname[100];
60: char inkey[100];
61: FILE *keyfile;
62: int sock;
63: unsigned int port;
64: int i;
65:
66: if (string == 0) {
67: string = getenv("API3270"); /* Get API */
68: if (string == 0) {
69: fprintf(stderr,
70: "API3270 environmental variable not set - no API.\n");
71: return -1; /* Nothing */
72: }
73: }
74:
75: if (sscanf(string, "%[^:]:%d:%s", thehostname,
76: (int *)&port, keyname) != 3) {
77: fprintf(stderr, "API3270 environmental variable has bad format.\n");
78: return -1;
79: }
80: /* Now, try to connect */
81: sock = socket(AF_INET, SOCK_STREAM, 0);
82: if (sock < 0) {
83: perror("opening API socket");
84: return -1;
85: }
86: server.sin_family = AF_INET;
87: hp = gethostbyname(thehostname);
88: if (hp == 0) {
89: fprintf(stderr, "%s specifies bad host name.\n", string);
90: return -1;
91: }
92: bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
93: server.sin_port = htons(port);
94:
95: if (connect(sock, (struct sockaddr *)&server, sizeof server) < 0) {
96: perror("connecting to API server");
97: return -1;
98: }
99: /* Now, try application level connection */
100: if (api_exch_init(sock, "client") == -1) {
101: return -1;
102: }
103: if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
104: return -1;
105: }
106: keyfile = fopen(keyname, "r");
107: if (keyfile == 0) {
108: perror("fopen");
109: return -1;
110: }
111: if (fscanf(keyfile, "%s\n", inkey) != 1) {
112: perror("fscanf");
113: return -1;
114: }
115: sd.length = strlen(inkey)+1;
116: if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
117: return -1;
118: }
119: if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) {
120: return -1;
121: }
122: while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
123: int passwd_length;
124: char *passwd, *getpass();
125: char buffer[200];
126:
127: switch (i) {
128: case EXCH_CMD_REJECTED:
129: if (api_exch_intype(EXCH_TYPE_STORE_DESC,
130: sizeof sd, (char *)&sd) == -1) {
131: return -1;
132: }
133: if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
134: return -1;
135: }
136: buffer[sd.length] = 0;
137: fprintf(stderr, "%s\n", buffer);
138: if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
139: return -1;
140: }
141: break;
142: case EXCH_CMD_SEND_AUTH:
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: passwd = getpass(buffer); /* Go to terminal */
151: passwd_length = strlen(passwd);
152: if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
153: return -1;
154: }
155: if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
156: return -1;
157: }
158: buffer[sd.length] = 0;
159: if (sd.length) {
160: char *ptr;
161:
162: ptr = passwd;
163: i = 0;
164: while (*ptr) {
165: *ptr++ ^= buffer[i++];
166: if (i >= sd.length) {
167: i = 0;
168: }
169: }
170: }
171: sd.length = passwd_length;
172: if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
173: return -1;
174: }
175: if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
176: return -1;
177: }
178: if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
179: return -1;
180: }
181: break;
182: case -1:
183: return -1;
184: default:
185: fprintf(stderr,
186: "Waiting for connection indicator, received 0x%x.\n", i);
187: break;
188: }
189: }
190: /* YEAH */
191: return 0; /* Happiness! */
192: }
193:
194:
195: api_exch_api(regs, sregs, parms, length)
196: union REGS *regs;
197: struct SREGS *sregs;
198: char *parms;
199: int length;
200: {
201: struct storage_descriptor sd;
202: int i;
203:
204: if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
205: return -1;
206: }
207: if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
208: return -1;
209: }
210: if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
211: return -1;
212: }
213: sd.length = length;
214: sd.location = (long) parms;
215: if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
216: return -1;
217: }
218: if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
219: return -1;
220: }
221: while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
222: switch (i) {
223: case EXCH_CMD_GIMME:
224: if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
225: == -1) {
226: return -1;
227: }
228: /*XXX validity check GIMME? */
229: if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
230: return -1;
231: }
232: if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
233: == -1) {
234: return -1;
235: }
236: if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
237: (char *)sd.location) == -1) {
238: return -1;
239: }
240: break;
241: case EXCH_CMD_HEREIS:
242: if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
243: == -1) {
244: return -1;
245: }
246: /* XXX Validty check HEREIS? */
247: if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
248: (char *)sd.location) == -1) {
249: return -1;
250: }
251: break;
252: default:
253: fprintf(stderr, "Waiting for reply command, we got command %d.\n",
254: i);
255: return -1;
256: }
257: }
258: if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
259: return -1;
260: }
261: if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
262: return -1;
263: }
264: /* YEAH */
265: return 0; /* Happiness! */
266: }
267:
268: #endif /* unix */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.