xref: /csrg-svn/usr.bin/tn3270/api/api_bsd.c (revision 31493)
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)
153 union REGS *regs;
154 struct SREGS *sregs;
155 {
156     struct storage_descriptor sd;
157     int i;
158 
159     if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
160 	return -1;
161     }
162     if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
163 	return -1;
164     }
165     if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
166 	return -1;
167     }
168     sd.length = 0;
169     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
170 	return -1;
171     }
172     while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
173 	switch (i) {
174 	case EXCH_CMD_GIMME:
175 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
176 					== -1) {
177 		return -1;
178 	    }
179 	    /*XXX validity check GIMME? */
180 	    if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
181 		return -1;
182 	    }
183 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
184 				== -1) {
185 		return -1;
186 	    }
187 	    if (api_exch_outtype(EXCH_TYPE_BYTES, ntohs(sd.length),
188 			    ntohl(sd.location)) == -1) {
189 		return -1;
190 	    }
191 	    break;
192 	case EXCH_CMD_HEREIS:
193 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
194 					== -1) {
195 		return -1;
196 	    }
197 	    /* XXX Validty check HEREIS? */
198 	    if (api_exch_intype(EXCH_TYPE_BYTES, ntohs(sd.length),
199 			    ntohl(sd.location)) == -1) {
200 		return -1;
201 	    }
202 	    break;
203 	default:
204 	    fprintf(stderr, "Waiting for reply command, we got command %d.\n",
205 			i);
206 	    return -1;
207 	}
208     }
209     if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
210 	return -1;
211     }
212     if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
213 	return -1;
214     }
215     /* YEAH */
216     return 0;		/* Happiness! */
217 }
218