comparison src/protocols/oscar/ft.c @ 8240:609a62b8e748

[gaim-migrate @ 8963] Make oscar use marv's core listening code. Hopefully my changes won't make anything any worse... file transfer and odc really need some lovin. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Thu, 12 Feb 2004 17:51:21 +0000
parents 4720864c365d
children aa755705bcf5
comparison
equal deleted inserted replaced
8239:5220e0898252 8240:609a62b8e748
156 156
157 return checksum; 157 return checksum;
158 } 158 }
159 159
160 /** 160 /**
161 * Create a listening socket on a given port.
162 *
163 * XXX - Give the client author the responsibility of setting up a
164 * listener, then we no longer have a libfaim problem with broken
165 * solaris *innocent smile* -- jbm
166 *
167 * @param portnum The port number to bind to.
168 * @return The file descriptor of the listening socket.
169 */
170 static int listenestablish(fu16_t portnum)
171 {
172 #if HAVE_GETADDRINFO
173 int listenfd;
174 const int on = 1;
175 struct addrinfo hints, *res, *ressave;
176 char serv[5];
177
178 snprintf(serv, sizeof(serv), "%d", portnum);
179 memset(&hints, 0, sizeof(struct addrinfo));
180 hints.ai_flags = AI_PASSIVE;
181 hints.ai_family = AF_UNSPEC;
182 hints.ai_socktype = SOCK_STREAM;
183 if (getaddrinfo(NULL /* any IP */, serv, &hints, &res) != 0) {
184 perror("getaddrinfo");
185 return -1;
186 }
187 ressave = res;
188 do {
189 listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
190 if (listenfd < 0)
191 continue;
192 setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
193 if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)
194 break; /* success */
195 close(listenfd);
196 } while ( (res = res->ai_next) );
197
198 if (!res)
199 return -1;
200
201 freeaddrinfo(ressave);
202 #else
203 int listenfd;
204 const int on = 1;
205 struct sockaddr_in sockin;
206
207 if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
208 perror("socket");
209 return -1;
210 }
211
212 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0) {
213 perror("setsockopt");
214 close(listenfd);
215 return -1;
216 }
217
218 memset(&sockin, 0, sizeof(struct sockaddr_in));
219 sockin.sin_family = AF_INET;
220 sockin.sin_port = htons(portnum);
221
222 if (bind(listenfd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0) {
223 perror("bind");
224 close(listenfd);
225 return -1;
226 }
227 #endif
228
229 if (listen(listenfd, 4) != 0) {
230 perror("listen");
231 close(listenfd);
232 return -1;
233 }
234 fcntl(listenfd, F_SETFL, O_NONBLOCK);
235
236 return listenfd;
237 }
238
239 /**
240 * After establishing a listening socket, this is called to accept a connection. It 161 * After establishing a listening socket, this is called to accept a connection. It
241 * clones the conn used by the listener, and passes both of these to a signal handler. 162 * clones the conn used by the listener, and passes both of these to a signal handler.
242 * The signal handler should close the listener conn and keep track of the new conn, 163 * The signal handler should close the listener conn and keep track of the new conn,
243 * since this is what is used for file transfers and what not. 164 * since this is what is used for file transfers and what not.
244 * 165 *
525 * 446 *
526 * @param sess The session 447 * @param sess The session
527 * @param sn The screen name to connect to. 448 * @param sn The screen name to connect to.
528 * @return The new connection. 449 * @return The new connection.
529 */ 450 */
530 faim_export aim_conn_t *aim_odc_initiate(aim_session_t *sess, const char *sn) 451 faim_export aim_conn_t *aim_odc_initiate(aim_session_t *sess, const char *sn, int listenfd, fu16_t port)
531 { 452 {
532 aim_conn_t *newconn; 453 aim_conn_t *newconn;
533 aim_msgcookie_t *cookie; 454 aim_msgcookie_t *cookie;
534 struct aim_odc_intdata *priv; 455 struct aim_odc_intdata *priv;
535 int listenfd;
536 fu16_t port = 4443;
537 fu8_t localip[4]; 456 fu8_t localip[4];
538 fu8_t ck[8]; 457 fu8_t ck[8];
539 458
540 if (aim_util_getlocalip(localip) == -1) 459 if (aim_util_getlocalip(localip) == -1)
541 return NULL;
542
543 if ((listenfd = listenestablish(port)) == -1)
544 return NULL; 460 return NULL;
545 461
546 aim_im_sendch2_odcrequest(sess, ck, sn, localip, port); 462 aim_im_sendch2_odcrequest(sess, ck, sn, localip, port);
547 463
548 cookie = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t)); 464 cookie = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t));
785 * @param sess The session. 701 * @param sess The session.
786 * @param oft_info File transfer information associated with this 702 * @param oft_info File transfer information associated with this
787 * connection. 703 * connection.
788 * @return Return 0 if no errors, otherwise return the error number. 704 * @return Return 0 if no errors, otherwise return the error number.
789 */ 705 */
790 faim_export int aim_sendfile_listen(aim_session_t *sess, struct aim_oft_info *oft_info) 706 faim_export int aim_sendfile_listen(aim_session_t *sess, struct aim_oft_info *oft_info, int listenfd)
791 { 707 {
792 int listenfd;
793
794 if (!oft_info) 708 if (!oft_info)
795 return -EINVAL; 709 return -EINVAL;
796
797 if ((listenfd = listenestablish(oft_info->port)) == -1)
798 return 1;
799 710
800 if (!(oft_info->conn = aim_newconn(sess, AIM_CONN_TYPE_LISTENER, NULL))) { 711 if (!(oft_info->conn = aim_newconn(sess, AIM_CONN_TYPE_LISTENER, NULL))) {
801 close(listenfd); 712 close(listenfd);
802 return -ENOMEM; 713 return -ENOMEM;
803 } 714 }