# HG changeset patch # User Mark Doliner # Date 1076608281 0 # Node ID 609a62b8e7481ac1a622ca89695d2b2fe67f6742 # Parent 5220e0898252b0d4287653cb2b0153627abbacb8 [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 diff -r 5220e0898252 -r 609a62b8e748 src/network.c --- a/src/network.c Thu Feb 12 17:23:17 2004 +0000 +++ b/src/network.c Thu Feb 12 17:51:21 2004 +0000 @@ -199,7 +199,7 @@ int gaim_network_listen(short start, short end) { - int ret = 0; + int ret = -1; if (gaim_prefs_get_bool("/core/network/ports_range_use") || (start > end) || (start < 1024) || (end < 1024)) { diff -r 5220e0898252 -r 609a62b8e748 src/network.h --- a/src/network.h Thu Feb 12 17:23:17 2004 +0000 +++ b/src/network.h Thu Feb 12 17:51:21 2004 +0000 @@ -101,7 +101,8 @@ * but users are allowed to specify a range. * @param end The highest possible port in the range of ports to listen on, * or 0 to let the core decide. - * @return The file descriptor of the listening socket. + * @return The file descriptor of the listening socket, or -1 if + * no socket could be established. */ int gaim_network_listen(short start, short end); diff -r 5220e0898252 -r 609a62b8e748 src/protocols/oscar/aim.h --- a/src/protocols/oscar/aim.h Thu Feb 12 17:23:17 2004 +0000 +++ b/src/protocols/oscar/aim.h Thu Feb 12 17:51:21 2004 +0000 @@ -933,12 +933,12 @@ faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding, int isawaymsg); faim_export const char *aim_odc_getsn(aim_conn_t *conn); faim_export aim_conn_t *aim_odc_getconn(aim_session_t *sess, const char *sn); -faim_export aim_conn_t *aim_odc_initiate(aim_session_t *sess, const char *sn); +faim_export aim_conn_t *aim_odc_initiate(aim_session_t *sess, const char *sn, int listenfd, fu16_t port); faim_export aim_conn_t *aim_odc_connect(aim_session_t *sess, const char *sn, const char *addr, const fu8_t *cookie); faim_export struct aim_oft_info *aim_oft_createinfo(aim_session_t *sess, const fu8_t *cookie, const char *sn, const char *ip, fu16_t port, fu32_t size, fu32_t modtime, char *filename); faim_export int aim_oft_destroyinfo(struct aim_oft_info *oft_info); -faim_export int aim_sendfile_listen(aim_session_t *sess, struct aim_oft_info *oft_info); +faim_export int aim_sendfile_listen(aim_session_t *sess, struct aim_oft_info *oft_info, int listenfd); faim_export int aim_oft_sendheader(aim_session_t *sess, fu16_t type, struct aim_oft_info *oft_info); diff -r 5220e0898252 -r 609a62b8e748 src/protocols/oscar/ft.c --- a/src/protocols/oscar/ft.c Thu Feb 12 17:23:17 2004 +0000 +++ b/src/protocols/oscar/ft.c Thu Feb 12 17:51:21 2004 +0000 @@ -158,85 +158,6 @@ } /** - * Create a listening socket on a given port. - * - * XXX - Give the client author the responsibility of setting up a - * listener, then we no longer have a libfaim problem with broken - * solaris *innocent smile* -- jbm - * - * @param portnum The port number to bind to. - * @return The file descriptor of the listening socket. - */ -static int listenestablish(fu16_t portnum) -{ -#if HAVE_GETADDRINFO - int listenfd; - const int on = 1; - struct addrinfo hints, *res, *ressave; - char serv[5]; - - snprintf(serv, sizeof(serv), "%d", portnum); - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_flags = AI_PASSIVE; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo(NULL /* any IP */, serv, &hints, &res) != 0) { - perror("getaddrinfo"); - return -1; - } - ressave = res; - do { - listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (listenfd < 0) - continue; - setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0) - break; /* success */ - close(listenfd); - } while ( (res = res->ai_next) ); - - if (!res) - return -1; - - freeaddrinfo(ressave); -#else - int listenfd; - const int on = 1; - struct sockaddr_in sockin; - - if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("socket"); - return -1; - } - - if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0) { - perror("setsockopt"); - close(listenfd); - return -1; - } - - memset(&sockin, 0, sizeof(struct sockaddr_in)); - sockin.sin_family = AF_INET; - sockin.sin_port = htons(portnum); - - if (bind(listenfd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0) { - perror("bind"); - close(listenfd); - return -1; - } -#endif - - if (listen(listenfd, 4) != 0) { - perror("listen"); - close(listenfd); - return -1; - } - fcntl(listenfd, F_SETFL, O_NONBLOCK); - - return listenfd; -} - -/** * After establishing a listening socket, this is called to accept a connection. It * clones the conn used by the listener, and passes both of these to a signal handler. * The signal handler should close the listener conn and keep track of the new conn, @@ -527,22 +448,17 @@ * @param sn The screen name to connect to. * @return The new connection. */ -faim_export aim_conn_t *aim_odc_initiate(aim_session_t *sess, const char *sn) +faim_export aim_conn_t *aim_odc_initiate(aim_session_t *sess, const char *sn, int listenfd, fu16_t port) { aim_conn_t *newconn; aim_msgcookie_t *cookie; struct aim_odc_intdata *priv; - int listenfd; - fu16_t port = 4443; fu8_t localip[4]; fu8_t ck[8]; if (aim_util_getlocalip(localip) == -1) return NULL; - if ((listenfd = listenestablish(port)) == -1) - return NULL; - aim_im_sendch2_odcrequest(sess, ck, sn, localip, port); cookie = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t)); @@ -787,16 +703,11 @@ * connection. * @return Return 0 if no errors, otherwise return the error number. */ -faim_export int aim_sendfile_listen(aim_session_t *sess, struct aim_oft_info *oft_info) +faim_export int aim_sendfile_listen(aim_session_t *sess, struct aim_oft_info *oft_info, int listenfd) { - int listenfd; - if (!oft_info) return -EINVAL; - if ((listenfd = listenestablish(oft_info->port)) == -1) - return 1; - if (!(oft_info->conn = aim_newconn(sess, AIM_CONN_TYPE_LISTENER, NULL))) { close(listenfd); return -ENOMEM; diff -r 5220e0898252 -r 609a62b8e748 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Thu Feb 12 17:23:17 2004 +0000 +++ b/src/protocols/oscar/oscar.c Thu Feb 12 17:51:21 2004 +0000 @@ -862,7 +862,7 @@ OscarData *od = gc->proto_data; if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) { - int i; + int listenfd; xfer->filename = g_path_get_basename(xfer->local_filename); strncpy(oft_info->fh.name, xfer->filename, 64); @@ -870,15 +870,12 @@ oft_info->fh.size = gaim_xfer_get_size(xfer); oft_info->fh.checksum = aim_oft_checksum_file(xfer->local_filename); - /* - * First try the port specified earlier (5190). If that fails, - * increment by 1 and try again. - */ - aim_sendfile_listen(od->sess, oft_info); - for (i=0; (i<5 && !oft_info->conn); i++) { - xfer->local_port = oft_info->port = oft_info->port + 1; - aim_sendfile_listen(od->sess, oft_info); - } + /* Create a listening socket and an associated libfaim conn */ + if ((listenfd = gaim_network_listen(5190, 5199)) < 0) + return; + xfer->local_port = gaim_network_get_port_from_fd(listenfd); + oft_info->port = xfer->local_port; + aim_sendfile_listen(od->sess, oft_info, listenfd); gaim_debug(GAIM_DEBUG_MISC, "oscar", "port is %d, ip is %s\n", xfer->local_port, oft_info->clientip); @@ -1042,11 +1039,10 @@ /* Build the file transfer handle */ xfer = gaim_xfer_new(gaim_connection_get_account(gc), GAIM_XFER_SEND, destsn); - xfer->local_port = 5190; /* Create the oscar-specific data */ - ip = gaim_network_get_ip_for_account(account, od->conn?od->conn->fd:-1); - oft_info = aim_oft_createinfo(od->sess, NULL, destsn, ip, xfer->local_port, 0, 0, NULL); + ip = gaim_network_get_ip_for_account(account, od->conn ? od->conn->fd : -1); + oft_info = aim_oft_createinfo(od->sess, NULL, destsn, ip, 0, 0, 0, NULL); xfer->data = oft_info; /* Setup our I/O op functions */ @@ -2135,7 +2131,7 @@ GaimConnection *gc = d->gc; OscarData *od; struct direct_im *dim; - char *host; int port = 4443; + char *host; int port = 5190; int i, rc; if (!g_list_find(gaim_connections_get_all(), gc)) { @@ -6124,6 +6120,7 @@ GaimConnection *gc = data->gc; OscarData *od; struct direct_im *dim; + int listenfd; if (!g_list_find(gaim_connections_get_all(), gc)) { g_free(data->who); @@ -6152,7 +6149,8 @@ dim->gc = gc; g_snprintf(dim->name, sizeof dim->name, "%s", data->who); - dim->conn = aim_odc_initiate(od->sess, data->who); + listenfd = gaim_network_listen(5190, 5199); + dim->conn = aim_odc_initiate(od->sess, data->who, listenfd, gaim_network_get_port_from_fd(listenfd)); if (dim->conn != NULL) { od->direct_ims = g_slist_append(od->direct_ims, dim); dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ,