Mercurial > pidgin
comparison libfaim/aim_conn.c @ 2:68b230f8da5f
[gaim-migrate @ 11]
A few more commits :)
committer: Tailor Script <tailor@pidgin.im>
author | Rob Flynn <gaim@robflynn.com> |
---|---|
date | Thu, 23 Mar 2000 03:16:06 +0000 |
parents | |
children | 6ced2f1c8b24 |
comparison
equal
deleted
inserted
replaced
1:2846a03bda67 | 2:68b230f8da5f |
---|---|
1 | |
2 /* | |
3 * aim_conn.c | |
4 * | |
5 * Does all this gloriously nifty connection handling stuff... | |
6 * | |
7 */ | |
8 | |
9 #include "aim.h" | |
10 | |
11 void aim_connrst(void) | |
12 { | |
13 int i; | |
14 for (i = 0; i < AIM_CONN_MAX; i++) | |
15 { | |
16 aim_conns[i].fd = -1; | |
17 aim_conns[i].type = -1; | |
18 aim_conns[i].status = 0; | |
19 } | |
20 | |
21 } | |
22 | |
23 struct aim_conn_t *aim_conn_getnext(void) | |
24 { | |
25 int i; | |
26 for (i=0;i<AIM_CONN_MAX;i++) | |
27 if (aim_conns[i].fd == -1) | |
28 return &(aim_conns[i]); | |
29 return NULL; | |
30 } | |
31 | |
32 void aim_conn_close(struct aim_conn_t *deadconn) | |
33 { | |
34 if (deadconn->fd >= 3) | |
35 close(deadconn->fd); | |
36 deadconn->fd = -1; | |
37 deadconn->type = -1; | |
38 } | |
39 | |
40 struct aim_conn_t *aim_getconn_type(int type) | |
41 { | |
42 int i; | |
43 for (i=0; i<AIM_CONN_MAX; i++) | |
44 if (aim_conns[i].type == type) | |
45 return &(aim_conns[i]); | |
46 return NULL; | |
47 } | |
48 | |
49 /* | |
50 * aim_newconn(type, dest) | |
51 * | |
52 * Opens a new connection to the specified dest host of type type. | |
53 * | |
54 * TODO: fix for proxies | |
55 * FIXME: Return errors in a more sane way. | |
56 * | |
57 */ | |
58 struct aim_conn_t *aim_newconn(int type, char *dest) | |
59 { | |
60 struct aim_conn_t *connstruct; | |
61 int ret; | |
62 struct sockaddr_in sa; | |
63 struct hostent *hp; | |
64 int port = FAIM_LOGIN_PORT; | |
65 int i=0; | |
66 | |
67 if (!dest || ((connstruct=aim_conn_getnext())==NULL)) | |
68 return NULL; | |
69 | |
70 connstruct->type = type; | |
71 | |
72 /* | |
73 * As of 23 Jul 1999, AOL now sends the port number, preceded by a | |
74 * colon, in the BOS redirect. This fatally breaks all previous | |
75 * libfaims. Bad, bad AOL. | |
76 * | |
77 * We put this here to catch every case. | |
78 * | |
79 */ | |
80 for(i=0;(i<strlen(dest));i++) | |
81 if (dest[i] == ':') break; | |
82 if (i<strlen(dest)) | |
83 { | |
84 port = atoi(dest+i); | |
85 dest[i] = '\0'; | |
86 } | |
87 | |
88 hp = gethostbyname2(dest, AF_INET); | |
89 if (hp == NULL) | |
90 { | |
91 connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR); | |
92 return connstruct; | |
93 } | |
94 | |
95 memset(&sa.sin_zero, 0, 8); | |
96 sa.sin_port = htons(port); | |
97 memcpy(&sa.sin_addr, hp->h_addr, hp->h_length); | |
98 sa.sin_family = hp->h_addrtype; | |
99 | |
100 connstruct->fd = socket(hp->h_addrtype, SOCK_STREAM, 0); | |
101 ret = connect(connstruct->fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)); | |
102 if( ret < 0) | |
103 { | |
104 connstruct->fd = -1; | |
105 connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); | |
106 return connstruct; | |
107 } | |
108 | |
109 return connstruct; | |
110 } | |
111 | |
112 int aim_conngetmaxfd(void) | |
113 { | |
114 int i,j; | |
115 j=0; | |
116 for (i=0;i<AIM_CONN_MAX;i++) | |
117 if(aim_conns[i].fd > j) | |
118 j = aim_conns[i].fd; | |
119 return j; | |
120 } | |
121 | |
122 int aim_countconn(void) | |
123 { | |
124 int i,cnt; | |
125 cnt = 0; | |
126 for (i=0;i<AIM_CONN_MAX;i++) | |
127 if (aim_conns[i].fd > -1) | |
128 cnt++; | |
129 return cnt; | |
130 } | |
131 | |
132 /* | |
133 * aim_select(timeout) | |
134 * | |
135 * Waits for a socket with data or for timeout, whichever comes first. | |
136 * See select(2). | |
137 * | |
138 */ | |
139 struct aim_conn_t *aim_select(struct timeval *timeout) | |
140 { | |
141 fd_set fds; | |
142 fd_set errfds; | |
143 int i; | |
144 | |
145 if (aim_countconn() <= 0) | |
146 return 0; | |
147 | |
148 FD_ZERO(&fds); | |
149 FD_ZERO(&errfds); | |
150 | |
151 for(i=0;i<AIM_CONN_MAX;i++) | |
152 if (aim_conns[i].fd>-1) | |
153 { | |
154 FD_SET(aim_conns[i].fd, &fds); | |
155 FD_SET(aim_conns[i].fd, &errfds); | |
156 } | |
157 | |
158 i = select(aim_conngetmaxfd()+1, &fds, NULL, &errfds, timeout); | |
159 if (i>=1) | |
160 { | |
161 int j; | |
162 for (j=0;j<AIM_CONN_MAX;j++) | |
163 { | |
164 if ((FD_ISSET(aim_conns[j].fd, &errfds))) | |
165 { | |
166 /* got an exception; close whats left of it up */ | |
167 aim_conn_close(&(aim_conns[j])); | |
168 return (struct aim_conn_t *)-1; | |
169 } | |
170 else if ((FD_ISSET(aim_conns[j].fd, &fds))) | |
171 return &(aim_conns[j]); /* return the first waiting struct */ | |
172 } | |
173 /* should never get here */ | |
174 } | |
175 else | |
176 return (struct aim_conn_t *)i; /* no waiting or error, return -- FIXME: return type funnies */ | |
177 return NULL; /* NO REACH */ | |
178 } | |
179 | |
180 int aim_conn_isready(struct aim_conn_t *conn) | |
181 { | |
182 if (conn) | |
183 return (conn->status & 0x0001); | |
184 else | |
185 return -1; | |
186 } | |
187 | |
188 int aim_conn_setstatus(struct aim_conn_t *conn, int status) | |
189 { | |
190 if (conn) | |
191 return (conn->status ^= status); | |
192 else | |
193 return -1; | |
194 } | |
195 |