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