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