xref: /csrg-svn/usr.bin/tn3270/api/api_bsd.c (revision 31467)
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 api_open_api(string)
12 char	*string;		/* if non-zero, where to connect to */
13 {
14     struct sockaddr_in server;
15     struct hostent *hp;
16     char *getenv();
17     char thehostname[100];
18     int sock;
19     int port;
20     int i;
21 
22     if (string == 0) {
23 	string = getenv("API3270");	/* Get API */
24 	if (string == 0) {
25 	    fprintf(stderr,
26 			"API3270 environmental variable not set - no API.\n");
27 	    return -1;			/* Nothing */
28 	}
29     }
30 
31     if (sscanf(string, "%[^:]:%d", thehostname, &port) != 2) {
32 	fprintf(stderr, "API3270 environmental variable has bad format.\n");
33 	return -1;
34     }
35     /* Now, try to connect */
36     sock = socket(AF_INET, SOCK_STREAM, 0);
37     if (sock < 0) {
38 	perror("opening API socket");
39 	return -1;
40     }
41     server.sin_family = AF_INET;
42     hp = gethostbyname(thehostname);
43     if (hp == 0) {
44 	fprintf(stderr, "%s specifies bad host name.\n", string);
45 	return -1;
46     }
47     bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
48     server.sin_port = htons(port);
49 
50     if (connect(sock, &server, sizeof server) < 0) {
51 	perror("connecting to API server");
52 	return -1;
53     }
54     /* Now, try application level connection */
55     if (api_exch_init(sock) == -1) {
56 	return -1;
57     }
58     if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) {
59 	return -1;
60     }
61     while ((i = api_exch_inbyte()) != EXCH_ASSOCIATED) {
62 	struct storage_descriptor sd;
63 	int passwd_length;
64 	char *passwd, *getpass();
65 	char buffer[200];
66 
67 	switch (i) {
68 	case EXCH_REJECTED:
69 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC,
70 					sizeof sd, (char *)&sd) == -1) {
71 		return -1;
72 	    }
73 	    sd.length = ntohs(sd.length);
74 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
75 		return -1;
76 	    }
77 	    buffer[sd.length] = 0;
78 	    fprintf(stderr, "%s\n", buffer);
79 	    if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) {
80 		return -1;
81 	    }
82 	    break;
83 	case EXCH_SEND_AUTH:
84 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, 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 	    passwd = getpass(buffer);		/* Go to terminal */
93 	    passwd_length = strlen(passwd);
94 	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
95 		return -1;
96 	    }
97 	    sd.length = ntohs(sd.length);
98 	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
99 		return -1;
100 	    }
101 	    buffer[sd.length] = 0;
102 	    if (sd.length) {
103 		char *ptr;
104 
105 		ptr = passwd;
106 		i = 0;
107 		while (*ptr) {
108 		    *ptr++ ^= buffer[i++];
109 		    if (i >= sd.length) {
110 			i = 0;
111 		    }
112 		}
113 	    }
114 	    sd.length = htons(passwd_length);
115 	    if (api_exch_outcommand(EXCH_AUTH) == -1) {
116 		return -1;
117 	    }
118 	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
119 		return -1;
120 	    }
121 	    if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
122 		return -1;
123 	    }
124 	    break;
125 	case -1:
126 	    return -1;
127 	default:
128 	    fprintf(stderr,
129 		    "Waiting for connection indicator, received 0x%x.\n", i);
130 	    break;
131 	}
132     }
133     /* YEAH */
134     return 0;		/* Happiness! */
135 }
136 
137 
138 api_exch_api(regs, sregs)
139 union REGS *regs;
140 struct SREGS *sregs;
141 {
142 }
143