コード例 #1
0
ファイル: socket.c プロジェクト: ittner/sylpheed-contrib
static gint sock_connect_address_list_async(SockConnectData *conn_data)
{
	SockAddrData *addr_data;
	gint sock = -1;

	for (; conn_data->cur_addr != NULL;
	     conn_data->cur_addr = conn_data->cur_addr->next) {
		addr_data = (SockAddrData *)conn_data->cur_addr->data;

		if ((sock = socket(addr_data->family, addr_data->socktype,
				   addr_data->protocol)) < 0) {
			perror("socket");
			continue;
		}

		sock_set_buffer_size(sock);
		set_nonblocking_mode(sock, TRUE);

		if (connect(sock, addr_data->addr, addr_data->addr_len) < 0) {
			if (EINPROGRESS == errno) {
				break;
			} else {
				perror("connect");
				fd_close(sock);
			}
		} else
			break;
	}

	if (conn_data->cur_addr == NULL) {
		g_warning("sock_connect_address_list_async: "
			  "connection to %s:%d failed\n",
			  conn_data->hostname, conn_data->port);
		conn_data->func(NULL, conn_data->data);
		sock_connect_async_cancel(conn_data->id);
		return -1;
	}

	debug_print("sock_connect_address_list_async: waiting for connect\n");

	conn_data->cur_addr = conn_data->cur_addr->next;

	conn_data->channel = g_io_channel_unix_new(sock);
	conn_data->io_tag = g_io_add_watch
		(conn_data->channel, G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
		 sock_connect_async_cb, conn_data);

	return 0;
}
コード例 #2
0
ファイル: socket.c プロジェクト: SpOOnman/claws
static gint sock_connect_address_list_async(SockConnectData *conn_data)
{
	SockAddrData *addr_data;
	gint sock = -1;

	for (; conn_data->cur_addr != NULL;
	     conn_data->cur_addr = conn_data->cur_addr->next) {
		addr_data = (SockAddrData *)conn_data->cur_addr->data;

		if ((sock = socket(addr_data->family, addr_data->socktype,
				   addr_data->protocol)) < 0) {
			perror("socket");

			continue;
		}

		set_nonblocking_mode(sock, TRUE);

		if (connect(sock, addr_data->addr, addr_data->addr_len) < 0) {
			if (EINPROGRESS == errno) {
				break;
			} else {
				perror("connect");
				close(sock);
			}
		} else {
			break;
		}
	}

	if (conn_data->cur_addr == NULL) {
		conn_data->func(NULL, conn_data->data);
		sock_connect_async_cancel(conn_data->id);
		return -1;
	}

	conn_data->cur_addr = conn_data->cur_addr->next;

#ifndef G_OS_WIN32
	conn_data->channel = g_io_channel_unix_new(sock);
#else
	conn_data->channel = g_io_channel_win32_new_socket(sock);
#endif
	conn_data->io_tag = g_io_add_watch(conn_data->channel, G_IO_IN|G_IO_OUT,
					   sock_connect_async_cb, conn_data);

	return 0;
}
コード例 #3
0
ファイル: socket.c プロジェクト: ittner/sylpheed-contrib
gint sock_set_nonblocking_mode(SockInfo *sock, gboolean nonblock)
{
	gint ret;

	g_return_val_if_fail(sock != NULL, -1);

	ret = set_nonblocking_mode(sock->sock, nonblock);
	if (ret == 0) {
		if (nonblock) {
			SOCK_SET_FLAGS(sock->flags, SYL_SOCK_NONBLOCK);
		} else {
			SOCK_UNSET_FLAGS(sock->flags, SYL_SOCK_NONBLOCK);
		}
	}

	return ret;
}
コード例 #4
0
ファイル: wizd_proxy.cpp プロジェクト: pochi0701/wizdlive
int http_proxy_response(int accept_socket, HTTP_RECV_INFO *http_recv_info_p)
{
    const char *HTTP_RECV_CONTENT_TYPE = "Content-type: text/html";
    const char *HTTP_RECV_CONTENT_LENGTH = "Content-Length: ";
    const char *HTTP_RECV_LOCATION = "Location: ";
    char *p_target_host_name;
    char *p_uri_string;
    char send_http_header_buf[2048];
    char line_buf[MAX_LINE][LINE_BUF_SIZE + 5];
    char proxy_pre_string[2048];
    char base_url[2048];
    char *p_url;
    char *p;
    char *p_auth = NULL;
    int port = 80;
    int sock;
    off_t content_length = 0;
    int len = 0;
    int line = 0;
    int i;
    int content_is_html = 0;
    p_uri_string = http_recv_info_p->request_uri;
    if (!strncmp(p_uri_string, "/-.-playlist.pls?", 17)) {
        char buff[FILENAME_MAX];
        if (p_uri_string[17] == '/') {
            snprintf(buff, sizeof(buff), "http://%s%s"
            , http_recv_info_p->recv_host, p_uri_string+17);
        } else {
            strncpy(buff, p_uri_string+17, sizeof(buff));
        }
        replace_character((char*)buff, ".pls", "");
        return 0;//http_uri_to_scplaylist_create(accept_socket, (char*)buff);
    }
    if (strncmp(p_uri_string, "/-.-http://", 11)) {
        return -1;
    }
    if (!global_param.flag_allow_proxy) {
        return -1;
    }
    strncpy(base_url, p_uri_string, 2048);
    p = strrchr(base_url, '/');
    p[1] = '\0';
    p_target_host_name = p_uri_string + 11;
    p_url = strchr(p_target_host_name, '/');
    if (p_url == NULL) return -1;
    *p_url++ = '\0';
    strncpy(proxy_pre_string, p_uri_string, 2048);
    p = strchr(p_target_host_name, '@');
    if (p != NULL) {
        // there is a user name.
        p_auth = p_target_host_name;
        p_target_host_name = p + 1;
        *p = '\0';
    }
    p = strchr(p_target_host_name, ':');
    if (p != NULL) {
        port = atoi(p+1);
        *p = '\0';
    }
    debug_log_output("proxy:target_host_name: %s", p_target_host_name);
    debug_log_output("proxy:authenticate: %s", p_auth ? p_auth : "NULL");
    debug_log_output("proxy:url: %s", p_url);
    debug_log_output("proxy:prestring: %s", proxy_pre_string);
    debug_log_output("proxy:base_url: %s", base_url);
    debug_log_output("proxy:port: %d", port);
    p = send_http_header_buf;
    if( http_recv_info_p->isGet == 1 ){
        p += sprintf((char*)p, "GET /%s HTTP/1.0\r\n", p_url);
    }else if ( http_recv_info_p->isGet == 2 ){
        p += sprintf((char*)p, "HEAD /%s HTTP/1.0\r\n", p_url);
    }
    p += sprintf((char*)p, "Host: %s:%u\r\n", p_target_host_name, port);
    if (global_param.user_agent_proxy_override[0]) {
        p += sprintf((char*)p, "User-agent: %s\r\n", global_param.user_agent_proxy_override);
    } else {
        if (http_recv_info_p->user_agent[0]) {
            p += sprintf((char*)p, "User-agent: %s\r\n", http_recv_info_p->user_agent);
        } else {
            p += sprintf((char*)p, "User-agent: %s\r\n", SERVER_NAME);
        }
    }
    p += sprintf(p, "Accept: */*\r\n");
    p += sprintf(p, "Connection: close\r\n");
    if (http_recv_info_p->range_start_pos) {
        p += sprintf((char*)p, "Range: bytes=");
        p += sprintf((char*)p, "%zu-", http_recv_info_p->range_start_pos);
        if (http_recv_info_p->range_end_pos) {
            p += sprintf((char*)p, "%zu", http_recv_info_p->range_end_pos);
        }
        p += sprintf(p, "\r\n");
    }
    if (p_auth != NULL) {
        p += sprintf((char*)p, "Authorization: Basic %s\r\n", base64((unsigned char*)p_auth));
    }
    p += sprintf(p, "\r\n");
    sock = sock_connect((char*)p_target_host_name, port);
    if (sock < 0) {
        debug_log_output("error: %s", strerror(errno));
        debug_log_output("sock: %d", sock);
        return -1;
    }
    set_nonblocking_mode(sock, 0); /* blocking mode */
    set_nonblocking_mode(accept_socket, 0); /* blocking mode */
    write(sock, send_http_header_buf, strlen(send_http_header_buf));
    debug_log_output("================= send to proxy\n");
    debug_log_output("%s", send_http_header_buf);
    debug_log_output("=================\n");
    
    //TODO ここが404や400の可能性あり
    for (line = 0; line < MAX_LINE; line ++) {
        char work_buf[LINE_BUF_SIZE + 10];
        memset(line_buf[line], 0, LINE_BUF_SIZE + 5);
        len = line_receive(sock, line_buf[line], LINE_BUF_SIZE + 1);
        if (len < 0) break;
        debug_log_output("recv html: '%s' len = %d", ((len)?(char*)line_buf[line]:""), len);
        line_buf[line][len++] = '\r';
        line_buf[line][len++] = '\n';
        line_buf[line][len] = '\0';
        if (!strncasecmp(line_buf[line], HTTP_RECV_CONTENT_TYPE, strlen(HTTP_RECV_CONTENT_TYPE))) {
            int n;
            content_is_html = 1;
            n = strlen(HTTP_RECV_CONTENT_TYPE);
            line_buf[line][n++] = '\r';
            line_buf[line][n++] = '\n';
            line_buf[line][n] = '\0';
        }else if (!strncasecmp(line_buf[line], HTTP_RECV_CONTENT_LENGTH, strlen(HTTP_RECV_CONTENT_LENGTH))) {
            content_length = strtoull((char*)(line_buf[line] + strlen(HTTP_RECV_CONTENT_LENGTH)), NULL, 0);
        }else if (!strncasecmp(line_buf[line], HTTP_RECV_LOCATION, strlen(HTTP_RECV_LOCATION))) {
            strcpy(work_buf, line_buf[line]);
            sprintf((char*)line_buf[line], "Location: /-.-%s", work_buf + strlen(HTTP_RECV_LOCATION));
        }else if ( strstr( line_buf[line],"charset") ){
            if ( strstr( line_buf[line], "EUC-JP" )){
                replace_character( (char*)line_buf[line], "EUC-JP", "UTF-8");
            }else if ( strstr ( line_buf[line], "Shift_JIS" )) {
                replace_character( (char*)line_buf[line], "Shift_JIS", "UTF-8");
            }
        }
        if (len <= 2) {
            line++;
            break;
        }
    }
    if (len < 0 ) {
        debug_log_output("CLOSED-C");
        close(sock);
        return -1;
    }
    if (content_is_html) {
        char *p, *q;
        char *new_p, *r;
        char work_buf[LINE_BUF_SIZE + 10];
        char work_buf2[LINE_BUF_SIZE * 2];
        char *link_pattern = (char*)"<A HREF=";
        int flag_conv_html_code = 1;
        for (i=0; i<line; i++) {
            //長さは不定なので送らない
            if (!strncasecmp(line_buf[i], HTTP_RECV_CONTENT_LENGTH, strlen(HTTP_RECV_CONTENT_LENGTH))) continue;
            //*q = '\0';
            p = work_buf;
            q = work_buf2;
            if (flag_conv_html_code) {
                convert_language_code(line_buf[i], work_buf, LINE_BUF_SIZE, CODE_AUTO, global_param.client_language_code);
            }
            //strcpy( work_buf, line_buf[i]);
            //            write(accept_socket, line_buf[i], strlen(line_buf[i]));
            //            debug_log_output("sent html: '%s' len = %d", line_buf[i], strlen(line_buf[i]));
            write(accept_socket, work_buf, strlen(line_buf[i]));
            debug_log_output("sent html: '%s' len = %d", work_buf, strlen(work_buf));
        }
        debug_log_output("sent header");
        //write(accept_socket, "debug:--\n", strlen("debug:--\n"));
        while (1) {
            char rep_str[1024];
            memset(work_buf, 0, LINE_BUF_SIZE);
            len = line_receive(sock, work_buf, LINE_BUF_SIZE);
            if (len < 0) break;
            debug_log_output("recv html: '%s' len = %d", work_buf, len);
            work_buf[len++] = '\r';
            work_buf[len++] = '\n';
            work_buf[len] = '\0';
            if (my_strcasestr(work_buf, "Content-Type") != NULL) {
                // Content-Type があったら
                // 漢字コードの変換をやめる
                //    flag_conv_html_code = 0;
                if ( strstr( work_buf, "EUC-JP" )){
                    replace_character( (char*)work_buf, "EUC-JP", "UTF-8");
                }else if ( strstr ( work_buf, "Shift_JIS" )) {
                    replace_character( (char*)work_buf, "Shift_JIS", "UTF-8");
                }
            }
            p = work_buf;
            q = work_buf2;
            memset(q, 0, sizeof(work_buf2));
            /*
            * HTML中に <A HREF="..."> があったら、プロクシを経由するように
            * たとえば <A HREF="/-.-http://www.yahoo.co.jp/"> のように変換する
            * もし、ファイルがストリーム可能そうであれば、VOD="0" も追加する。
            *
            * 問題点:
            *   タグの途中に改行があると失敗するだろう.
            *   面倒なのでたいした置換はしていない
            *   惰性で書いたので汚い。だれか修正して。
            */
            link_pattern = (char*)"<A HREF=";
            while ((new_p = my_strcasestr(p, link_pattern)) != NULL) {
                int l = new_p - p + strlen(link_pattern);
                char *tmp;
                MIME_LIST_T *mlt = NULL;
                strncpy(q, p, l);
                q += l;
                p += l; /* i.e., p = new_p + strlen(link_pattern); */
                r = strchr(p, '>');
                if (r == NULL) continue;
                *r = '\0';
                if (*p == '"') *q++ = *p++;
                if ((tmp = strchr(p, '"')) != NULL || (tmp = strchr(p, ' ')) != NULL) {
                    mlt = mime_list;
                    while (mlt->mime_name != NULL) {
                        if (*(tmp - strlen(mlt->file_extension) - 1) == '.'
                        && !strncasecmp(tmp - strlen(mlt->file_extension), mlt->file_extension, strlen(mlt->file_extension))) {
                            break;
                        }
                        mlt++;
                    }
                }
                //if (flag_pc && mlt != NULL && mlt->stream_type == TYPE_STREAM) {
                //    q += sprintf((char*)q, "/-.-playlist.pls?http://%s", http_recv_info_p->recv_host);
                //}
                if (*p == '/') {
                    q += sprintf(q, "%s%s", proxy_pre_string, p);
                } else if (!strncmp(p, "http://", 7)) {
                    q += sprintf(q, "/-.-%s", p);
                } else {
                    q += sprintf((char*)q, "%s%s", base_url, p);
                    //q += sprintf((char*)q, "%s", p);
                }
                if (mlt != NULL && mlt->stream_type == TYPE_STREAM) {
                    q += sprintf(q, " vod=\"0\"");
                }
                *q++ = '>';
                p = r + 1;
            }
            while (*p) *q++ = *p++;
            *q = '\0';
            /*
            * HTML中に SRC="..." があったら、プロクシを経由するように変換する
            *
            * 問題点:
            *   タグの途中に改行があると失敗するだろう.
            *   変数使いまわしたので、融通が効かない。
            *   だれか修正して。
            */
            p = work_buf2;
            q = work_buf;
            memset(q, 0, sizeof(work_buf));
            link_pattern = (char*)"SRC=";
            while ((new_p = my_strcasestr(p, link_pattern)) != NULL) {
                int l = new_p - p + strlen(link_pattern);
                strncpy(q, p, l);
                q += l;
                p += l; /* i.e., p = new_p + strlen(link_pattern); */
                if (*p == '"') *q++ = *p++;
                if (*p == '/') {
                    q += sprintf(q, "%s", proxy_pre_string);
                } else if (!strncmp(p, "http://", 7)) {
                    q += sprintf(q, "/-.-");
                } else {
                    q += sprintf(q, "%s", base_url);
                    //q += sprintf(q, "%s", p);
                }
            }
            while (*p) *q++ = *p++;
            *q = '\0';
            p = work_buf;
            q = work_buf2;
            if (flag_conv_html_code) {
                convert_language_code(p, q, LINE_BUF_SIZE, CODE_AUTO, global_param.client_language_code);
                //strcpy( q,p);
                p = q;
            }
            snprintf(rep_str, sizeof(rep_str), "|http://%s/-.-http://"
            , http_recv_info_p->recv_host);
            replace_character((char*)p, "|http://", rep_str);
            write(accept_socket, p, strlen(p));
            debug_log_output("sent html: %s", p);
        }
    } else {
        for (i=0; i<line; i++) {
            write(accept_socket, line_buf[i], strlen(line_buf[i]));
        }
        if( http_recv_info_p->isGet == 1 ){
            return ( copy_descriptors(sock, accept_socket, (size_t)content_length) );
            //NULL ,
            //(char*)http_recv_info_p->recv_uri,
           // http_recv_info_p->range_start_pos));
        }
    }
    sClose(sock);
    return 0;
}
コード例 #5
0
ファイル: socket.c プロジェクト: ittner/sylpheed-contrib
static gint sock_connect_with_timeout(gint sock,
				      const struct sockaddr *serv_addr,
				      gint addrlen,
				      guint timeout_secs)
{
	gint ret;

#ifdef G_OS_UNIX
	set_nonblocking_mode(sock, TRUE);
#endif

	ret = connect(sock, serv_addr, addrlen);

#ifdef G_OS_UNIX
	if (ret < 0) {
		if (EINPROGRESS == errno) {
			fd_set fds;
			struct timeval tv;

			tv.tv_sec = timeout_secs;
			tv.tv_usec = 0;
			FD_ZERO(&fds);
			FD_SET(sock, &fds);
			do {
				ret = select(sock + 1, NULL, &fds, NULL, &tv);
			} while (ret < 0 && EINTR == errno);
			if (ret < 0) {
				perror("sock_connect_with_timeout: select");
				return -1;
			} else if (ret == 0) {
				debug_print("sock_connect_with_timeout: timeout\n");
				errno = ETIMEDOUT;
				return -1;
			} else {
				gint val;
				guint len;

				if (FD_ISSET(sock, &fds)) {
					ret = 0;
				} else {
					debug_print("sock_connect_with_timeout: fd not set\n");
					return -1;
				}

				len = sizeof(val);
				if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &val, &len) < 0) {
					perror("sock_connect_with_timeout: getsockopt");
					return -1;
				}
				if (val != 0) {
					debug_print("sock_connect_with_timeout: getsockopt(SOL_SOCKET, SO_ERROR) returned error: %s\n", g_strerror(val));
					return -1;
				}
			}
		} else {
			perror("sock_connect_with_timeout: connect");
			return -1;
		}
	}

	set_nonblocking_mode(sock, FALSE);
#endif

	return ret;
}
コード例 #6
0
ファイル: socket.c プロジェクト: SpOOnman/claws
gint sock_set_nonblocking_mode(SockInfo *sock, gboolean nonblock)
{
	cm_return_val_if_fail(sock != NULL, -1);

	return set_nonblocking_mode(sock->sock, nonblock);
}