Mercurial > pidgin
comparison src/proxy.c @ 4993:de84c1de2f66
[gaim-migrate @ 5328]
this is beyond ugly. then again, the better part of proxy.c is beyond ugly.
i'm ashamed to have written this, but desperate times call for desperate
meausres :-/
this fixes the crashes that occur when you cancel a signon in mid-connect
committer: Tailor Script <tailor@pidgin.im>
| author | Nathan Walp <nwalp@pidgin.im> |
|---|---|
| date | Fri, 04 Apr 2003 01:37:34 +0000 |
| parents | 5b372a95b9a8 |
| children | 0241d6b6702d |
comparison
equal
deleted
inserted
replaced
| 4992:e2047cd770d6 | 4993:de84c1de2f66 |
|---|---|
| 62 gpointer data; | 62 gpointer data; |
| 63 char *host; | 63 char *host; |
| 64 int port; | 64 int port; |
| 65 gint inpa; | 65 gint inpa; |
| 66 struct gaim_proxy_info *gpi; | 66 struct gaim_proxy_info *gpi; |
| 67 struct gaim_account *account; | |
| 67 }; | 68 }; |
| 68 | 69 |
| 69 typedef struct _GaimIOClosure { | 70 typedef struct _GaimIOClosure { |
| 70 GaimInputFunction function; | 71 GaimInputFunction function; |
| 71 guint result; | 72 guint result; |
| 86 gaim_cond |= GAIM_INPUT_READ; | 87 gaim_cond |= GAIM_INPUT_READ; |
| 87 if (condition & GAIM_WRITE_COND) | 88 if (condition & GAIM_WRITE_COND) |
| 88 gaim_cond |= GAIM_INPUT_WRITE; | 89 gaim_cond |= GAIM_INPUT_WRITE; |
| 89 | 90 |
| 90 /* | 91 /* |
| 91 debug_printf("CLOSURE: callback for %d, fd is %d\n", | 92 debug_printf("CLOSURE: callback for %d, fd is %d\n", closure->result, g_io_channel_unix_get_fd(source)); |
| 92 closure->result, g_io_channel_unix_get_fd(source)); | |
| 93 */ | 93 */ |
| 94 | 94 |
| 95 closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond); | 95 closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond); |
| 96 | 96 |
| 97 return TRUE; | 97 return TRUE; |
| 112 cond |= GAIM_WRITE_COND; | 112 cond |= GAIM_WRITE_COND; |
| 113 | 113 |
| 114 channel = g_io_channel_unix_new(source); | 114 channel = g_io_channel_unix_new(source); |
| 115 closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, | 115 closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, |
| 116 gaim_io_invoke, closure, gaim_io_destroy); | 116 gaim_io_invoke, closure, gaim_io_destroy); |
| 117 | |
| 118 /* debug_printf("CLOSURE: adding input watcher %d for fd %d\n", closure->result, source); */ | 117 /* debug_printf("CLOSURE: adding input watcher %d for fd %d\n", closure->result, source); */ |
| 119 | 118 |
| 120 g_io_channel_unref(channel); | 119 g_io_channel_unref(channel); |
| 121 return closure->result; | 120 return closure->result; |
| 122 } | 121 } |
| 597 | 596 |
| 598 ret = getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len); | 597 ret = getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len); |
| 599 if (ret < 0 || error != 0) { | 598 if (ret < 0 || error != 0) { |
| 600 close(source); | 599 close(source); |
| 601 gaim_input_remove(phb->inpa); | 600 gaim_input_remove(phb->inpa); |
| 602 phb->func(phb->data, -1, GAIM_INPUT_READ); | 601 if(!phb->account || phb->account->gc) |
| 602 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 603 g_free(phb->host); | 603 g_free(phb->host); |
| 604 g_free(phb); | 604 g_free(phb); |
| 605 debug_printf("getsockopt SO_ERROR check: %s\n", | 605 debug_printf("getsockopt SO_ERROR check: %s\n", |
| 606 strerror(((ret<0) ? errno : error))); | 606 strerror(((ret<0) ? errno : error))); |
| 607 return; | 607 return; |
| 608 } | 608 } |
| 609 fcntl(source, F_SETFL, 0); | 609 fcntl(source, F_SETFL, 0); |
| 610 gaim_input_remove(phb->inpa); | 610 gaim_input_remove(phb->inpa); |
| 611 phb->func(phb->data, source, GAIM_INPUT_READ); | 611 if(!phb->account || phb->account->gc) |
| 612 phb->func(phb->data, source, GAIM_INPUT_READ); | |
| 612 g_free(phb->host); | 613 g_free(phb->host); |
| 613 g_free(phb); | 614 g_free(phb); |
| 614 } | 615 } |
| 615 | 616 |
| 616 static gboolean clean_connect(gpointer data) | 617 static gboolean clean_connect(gpointer data) |
| 617 { | 618 { |
| 618 struct PHB *phb = data; | 619 struct PHB *phb = data; |
| 619 | 620 |
| 620 phb->func(phb->data, phb->port, GAIM_INPUT_READ); | 621 if(!phb->account || phb->account->gc) |
| 622 phb->func(phb->data, phb->port, GAIM_INPUT_READ); | |
| 621 g_free(phb->host); | 623 g_free(phb->host); |
| 622 g_free(phb); | 624 g_free(phb); |
| 623 | 625 |
| 624 return FALSE; | 626 return FALSE; |
| 625 } | 627 } |
| 712 debug_printf("Proxy reserver replied: (%s)\n", p); | 714 debug_printf("Proxy reserver replied: (%s)\n", p); |
| 713 close(source); | 715 close(source); |
| 714 source=-1; | 716 source=-1; |
| 715 } | 717 } |
| 716 | 718 |
| 717 phb->func(phb->data, source, GAIM_INPUT_READ); | 719 if(!phb->account || phb->account->gc) |
| 720 phb->func(phb->data, source, GAIM_INPUT_READ); | |
| 718 g_free(phb->host); | 721 g_free(phb->host); |
| 719 g_free(phb); | 722 g_free(phb); |
| 720 return; | 723 return; |
| 721 } | 724 } |
| 722 | 725 |
| 732 if (phb->inpa > 0) | 735 if (phb->inpa > 0) |
| 733 gaim_input_remove(phb->inpa); | 736 gaim_input_remove(phb->inpa); |
| 734 len = sizeof(error); | 737 len = sizeof(error); |
| 735 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 738 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 736 close(source); | 739 close(source); |
| 737 phb->func(phb->data, -1, GAIM_INPUT_READ); | 740 if(!phb->account || phb->account->gc) |
| 741 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 738 g_free(phb->host); | 742 g_free(phb->host); |
| 739 g_free(phb); | 743 g_free(phb); |
| 740 return; | 744 return; |
| 741 } | 745 } |
| 742 request_len = g_snprintf(request, sizeof(request), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, | 746 request_len = g_snprintf(request, sizeof(request), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, |
| 756 strcpy(request + request_len, "\r\n"); | 760 strcpy(request + request_len, "\r\n"); |
| 757 request_len += 2; | 761 request_len += 2; |
| 758 | 762 |
| 759 if (write(source, request, request_len) < 0) { | 763 if (write(source, request, request_len) < 0) { |
| 760 close(source); | 764 close(source); |
| 761 phb->func(phb->data, -1, GAIM_INPUT_READ); | 765 if(!phb->account || phb->account->gc) |
| 766 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 762 g_free(phb->host); | 767 g_free(phb->host); |
| 763 g_free(phb); | 768 g_free(phb); |
| 764 return; | 769 return; |
| 765 } | 770 } |
| 766 | 771 |
| 812 gaim_input_remove(phb->inpa); | 817 gaim_input_remove(phb->inpa); |
| 813 | 818 |
| 814 memset(packet, 0, sizeof(packet)); | 819 memset(packet, 0, sizeof(packet)); |
| 815 | 820 |
| 816 if (read(source, packet, 9) >= 4 && packet[1] == 90) { | 821 if (read(source, packet, 9) >= 4 && packet[1] == 90) { |
| 817 phb->func(phb->data, source, GAIM_INPUT_READ); | 822 if(!phb->account || phb->account->gc) |
| 823 phb->func(phb->data, source, GAIM_INPUT_READ); | |
| 818 g_free(phb->host); | 824 g_free(phb->host); |
| 819 g_free(phb); | 825 g_free(phb); |
| 820 return; | 826 return; |
| 821 } | 827 } |
| 822 | 828 |
| 823 close(source); | 829 close(source); |
| 824 phb->func(phb->data, -1, GAIM_INPUT_READ); | 830 if(!phb->account || phb->account->gc) |
| 831 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 825 g_free(phb->host); | 832 g_free(phb->host); |
| 826 g_free(phb); | 833 g_free(phb); |
| 827 } | 834 } |
| 828 | 835 |
| 829 static void s4_canwrite(gpointer data, gint source, GaimInputCondition cond) | 836 static void s4_canwrite(gpointer data, gint source, GaimInputCondition cond) |
| 838 if (phb->inpa > 0) | 845 if (phb->inpa > 0) |
| 839 gaim_input_remove(phb->inpa); | 846 gaim_input_remove(phb->inpa); |
| 840 len = sizeof(error); | 847 len = sizeof(error); |
| 841 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 848 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 842 close(source); | 849 close(source); |
| 843 phb->func(phb->data, -1, GAIM_INPUT_READ); | 850 if(!phb->account || phb->account->gc) |
| 851 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 844 g_free(phb->host); | 852 g_free(phb->host); |
| 845 g_free(phb); | 853 g_free(phb); |
| 846 return; | 854 return; |
| 847 } | 855 } |
| 848 fcntl(source, F_SETFL, 0); | 856 fcntl(source, F_SETFL, 0); |
| 849 | 857 |
| 850 /* XXX does socks4 not support host name lookups by the proxy? */ | 858 /* XXX does socks4 not support host name lookups by the proxy? */ |
| 851 if (!(hp = gethostbyname(phb->host))) { | 859 if (!(hp = gethostbyname(phb->host))) { |
| 852 close(source); | 860 close(source); |
| 853 phb->func(phb->data, -1, GAIM_INPUT_READ); | 861 if(!phb->account || phb->account->gc) |
| 862 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 854 g_free(phb->host); | 863 g_free(phb->host); |
| 855 g_free(phb); | 864 g_free(phb); |
| 856 return; | 865 return; |
| 857 } | 866 } |
| 858 | 867 |
| 866 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; | 875 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; |
| 867 packet[8] = 0; | 876 packet[8] = 0; |
| 868 | 877 |
| 869 if (write(source, packet, 9) != 9) { | 878 if (write(source, packet, 9) != 9) { |
| 870 close(source); | 879 close(source); |
| 871 phb->func(phb->data, -1, GAIM_INPUT_READ); | 880 if(!phb->account || phb->account->gc) |
| 881 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 872 g_free(phb->host); | 882 g_free(phb->host); |
| 873 g_free(phb); | 883 g_free(phb); |
| 874 return; | 884 return; |
| 875 } | 885 } |
| 876 | 886 |
| 922 debug_printf("able to read again\n"); | 932 debug_printf("able to read again\n"); |
| 923 | 933 |
| 924 if (read(source, buf, 10) < 10) { | 934 if (read(source, buf, 10) < 10) { |
| 925 debug_printf("or not...\n"); | 935 debug_printf("or not...\n"); |
| 926 close(source); | 936 close(source); |
| 927 phb->func(phb->data, -1, GAIM_INPUT_READ); | 937 if(!phb->account || phb->account->gc) |
| 938 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 928 g_free(phb->host); | 939 g_free(phb->host); |
| 929 g_free(phb); | 940 g_free(phb); |
| 930 return; | 941 return; |
| 931 } | 942 } |
| 932 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { | 943 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { |
| 933 debug_printf("bad data\n"); | 944 debug_printf("bad data\n"); |
| 934 close(source); | 945 close(source); |
| 935 phb->func(phb->data, -1, GAIM_INPUT_READ); | 946 if(!phb->account || phb->account->gc) |
| 936 g_free(phb->host); | 947 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 937 g_free(phb); | 948 g_free(phb->host); |
| 938 return; | 949 g_free(phb); |
| 939 } | 950 return; |
| 940 | 951 } |
| 941 phb->func(phb->data, source, GAIM_INPUT_READ); | 952 |
| 953 if(!phb->account || phb->account->gc) | |
| 954 phb->func(phb->data, source, GAIM_INPUT_READ); | |
| 942 g_free(phb->host); | 955 g_free(phb->host); |
| 943 g_free(phb); | 956 g_free(phb); |
| 944 return; | 957 return; |
| 945 } | 958 } |
| 946 | 959 |
| 959 buf[5 + strlen(phb->host)] = phb->port >> 8; | 972 buf[5 + strlen(phb->host)] = phb->port >> 8; |
| 960 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; | 973 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; |
| 961 | 974 |
| 962 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { | 975 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { |
| 963 close(source); | 976 close(source); |
| 964 phb->func(phb->data, -1, GAIM_INPUT_READ); | 977 if(!phb->account || phb->account->gc) |
| 978 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 965 g_free(phb->host); | 979 g_free(phb->host); |
| 966 g_free(phb); | 980 g_free(phb); |
| 967 return; | 981 return; |
| 968 } | 982 } |
| 969 | 983 |
| 978 gaim_input_remove(phb->inpa); | 992 gaim_input_remove(phb->inpa); |
| 979 debug_printf("got auth response\n"); | 993 debug_printf("got auth response\n"); |
| 980 | 994 |
| 981 if (read(source, buf, 2) < 2) { | 995 if (read(source, buf, 2) < 2) { |
| 982 close(source); | 996 close(source); |
| 983 phb->func(phb->data, -1, GAIM_INPUT_READ); | 997 if(!phb->account || phb->account->gc) |
| 998 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 984 g_free(phb->host); | 999 g_free(phb->host); |
| 985 g_free(phb); | 1000 g_free(phb); |
| 986 return; | 1001 return; |
| 987 } | 1002 } |
| 988 | 1003 |
| 989 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { | 1004 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { |
| 990 close(source); | 1005 close(source); |
| 991 phb->func(phb->data, -1, GAIM_INPUT_READ); | 1006 if(!phb->account || phb->account->gc) |
| 1007 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 992 g_free(phb->host); | 1008 g_free(phb->host); |
| 993 g_free(phb); | 1009 g_free(phb); |
| 994 return; | 1010 return; |
| 995 } | 1011 } |
| 996 | 1012 |
| 1005 gaim_input_remove(phb->inpa); | 1021 gaim_input_remove(phb->inpa); |
| 1006 debug_printf("able to read\n"); | 1022 debug_printf("able to read\n"); |
| 1007 | 1023 |
| 1008 if (read(source, buf, 2) < 2) { | 1024 if (read(source, buf, 2) < 2) { |
| 1009 close(source); | 1025 close(source); |
| 1010 phb->func(phb->data, -1, GAIM_INPUT_READ); | 1026 if(!phb->account || phb->account->gc) |
| 1027 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 1011 g_free(phb->host); | 1028 g_free(phb->host); |
| 1012 g_free(phb); | 1029 g_free(phb); |
| 1013 return; | 1030 return; |
| 1014 } | 1031 } |
| 1015 | 1032 |
| 1016 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { | 1033 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { |
| 1017 close(source); | 1034 close(source); |
| 1018 phb->func(phb->data, -1, GAIM_INPUT_READ); | 1035 if(!phb->account || phb->account->gc) |
| 1036 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 1019 g_free(phb->host); | 1037 g_free(phb->host); |
| 1020 g_free(phb); | 1038 g_free(phb); |
| 1021 return; | 1039 return; |
| 1022 } | 1040 } |
| 1023 | 1041 |
| 1029 buf[2 + i] = j; | 1047 buf[2 + i] = j; |
| 1030 memcpy(buf + 2 + i + 1, phb->gpi->proxypass, j); | 1048 memcpy(buf + 2 + i + 1, phb->gpi->proxypass, j); |
| 1031 | 1049 |
| 1032 if (write(source, buf, 3 + i + j) < 3 + i + j) { | 1050 if (write(source, buf, 3 + i + j) < 3 + i + j) { |
| 1033 close(source); | 1051 close(source); |
| 1034 phb->func(phb->data, -1, GAIM_INPUT_READ); | 1052 if(!phb->account || phb->account->gc) |
| 1053 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 1035 g_free(phb->host); | 1054 g_free(phb->host); |
| 1036 g_free(phb); | 1055 g_free(phb); |
| 1037 return; | 1056 return; |
| 1038 } | 1057 } |
| 1039 | 1058 |
| 1055 if (phb->inpa > 0) | 1074 if (phb->inpa > 0) |
| 1056 gaim_input_remove(phb->inpa); | 1075 gaim_input_remove(phb->inpa); |
| 1057 len = sizeof(error); | 1076 len = sizeof(error); |
| 1058 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 1077 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 1059 close(source); | 1078 close(source); |
| 1060 phb->func(phb->data, -1, GAIM_INPUT_READ); | 1079 if(!phb->account || phb->account->gc) |
| 1080 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 1061 g_free(phb->host); | 1081 g_free(phb->host); |
| 1062 g_free(phb); | 1082 g_free(phb); |
| 1063 return; | 1083 return; |
| 1064 } | 1084 } |
| 1065 fcntl(source, F_SETFL, 0); | 1085 fcntl(source, F_SETFL, 0); |
| 1078 } | 1098 } |
| 1079 | 1099 |
| 1080 if (write(source, buf, i) < i) { | 1100 if (write(source, buf, i) < i) { |
| 1081 debug_printf("unable to write\n"); | 1101 debug_printf("unable to write\n"); |
| 1082 close(source); | 1102 close(source); |
| 1083 phb->func(phb->data, -1, GAIM_INPUT_READ); | 1103 if(!phb->account || phb->account->gc) |
| 1104 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 1084 g_free(phb->host); | 1105 g_free(phb->host); |
| 1085 g_free(phb); | 1106 g_free(phb); |
| 1086 return; | 1107 return; |
| 1087 } | 1108 } |
| 1088 | 1109 |
| 1155 } | 1176 } |
| 1156 if (ret > 0) | 1177 if (ret > 0) |
| 1157 break; | 1178 break; |
| 1158 } | 1179 } |
| 1159 if(ret < 0) { | 1180 if(ret < 0) { |
| 1160 phb->func(phb->data, -1, GAIM_INPUT_READ); | 1181 if(!phb->account || phb->account->gc) |
| 1182 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 1161 g_free(phb->host); | 1183 g_free(phb->host); |
| 1162 g_free(phb); | 1184 g_free(phb); |
| 1163 } | 1185 } |
| 1164 } | 1186 } |
| 1165 | 1187 |
| 1175 phb->gpi = account->gpi; | 1197 phb->gpi = account->gpi; |
| 1176 phb->func = func; | 1198 phb->func = func; |
| 1177 phb->data = data; | 1199 phb->data = data; |
| 1178 phb->host = g_strdup(host); | 1200 phb->host = g_strdup(host); |
| 1179 phb->port = port; | 1201 phb->port = port; |
| 1202 phb->account = account; | |
| 1180 | 1203 |
| 1181 if (!host || !port || (port == -1) || !func) { | 1204 if (!host || !port || (port == -1) || !func) { |
| 1182 if(host) | 1205 if(host) |
| 1183 g_free(phb->host); | 1206 g_free(phb->host); |
| 1184 g_free(phb); | 1207 g_free(phb); |
