Mercurial > pidgin.yaz
annotate src/network.c @ 8378:2b68c423357e
[gaim-migrate @ 9105]
" For people and systems which have libzephyr installed
(e.g Debian), this will allow the zephyr plugin to
optionally be linked against it, instead of building
and linking in the libzephyr that comes with gaim.
Why?
1) A gaim binary package can be compiled against a
locally installed libzephyr.a, and use either
unkerberized or kerberized zephyr depending on which
version of the zephyr shared libraries is installed.
2) It reduces the build speed and size of the zephyr
plugin (on Debian x86, from 6.5 MB to ~ 300 kb)
Also, I added a zephyr icon (a blue Z), that's similar
to the icons used by Windows and MacOS zephyr clients
at MIT." --Arun A Tharuvai
someone will have to tell me how to fix the win32 makefiles, and i'm not
sure he patched enough to get his icon to be actually used.
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Mon, 01 Mar 2004 18:08:42 +0000 |
parents | 86b8d8b4287e |
children | beb7be215db3 |
rev | line source |
---|---|
8231 | 1 /** |
2 * @file network.c Network Implementation | |
3 * @ingroup core | |
4 * | |
5 * gaim | |
6 * | |
7 * Gaim is the legal property of its developers, whose names are too numerous | |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
10 * | |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
25 | |
8245
91c6629b1ee8
[gaim-migrate @ 8968]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
8240
diff
changeset
|
26 #include "internal.h" |
8231 | 27 |
28 #include "debug.h" | |
29 #include "account.h" | |
30 #include "network.h" | |
31 #include "prefs.h" | |
32 | |
33 void | |
34 gaim_network_set_local_ip(const char *ip) | |
35 { | |
36 g_return_if_fail(ip != NULL); | |
37 | |
38 gaim_prefs_set_string("/core/network/public_ip", ip); | |
39 } | |
40 | |
41 const char * | |
42 gaim_network_get_local_ip(void) | |
43 { | |
44 const char *ip; | |
45 | |
46 if (gaim_prefs_get_bool("/core/network/auto_ip")) | |
47 return NULL; | |
48 | |
49 ip = gaim_prefs_get_string("/core/network/public_ip"); | |
50 | |
51 if (ip == NULL || *ip == '\0') | |
52 return NULL; | |
53 | |
54 return ip; | |
55 } | |
56 | |
57 static const char * | |
58 gaim_network_get_local_ip_from_fd(int fd) | |
59 { | |
60 struct sockaddr_in addr; | |
61 socklen_t len; | |
62 static char ip[16]; | |
63 const char *tmp; | |
64 | |
65 g_return_val_if_fail(fd > 0, NULL); | |
66 | |
67 len = sizeof(addr); | |
68 if (getsockname(fd, (struct sockaddr *) &addr, &len) == -1) { | |
69 gaim_debug_warning("network", "getsockname: %s\n", strerror(errno)); | |
70 return NULL; | |
71 } | |
72 | |
73 tmp = inet_ntoa(addr.sin_addr); | |
74 strncpy(ip, tmp, sizeof(ip)); | |
75 return ip; | |
76 } | |
77 | |
78 const char * | |
79 gaim_network_get_local_system_ip(int fd) | |
80 { | |
81 struct hostent *host; | |
82 char localhost[129]; | |
83 long unsigned add; | |
84 static char ip[46]; | |
85 const char *tmp = NULL; | |
86 | |
87 if (fd != -1) | |
88 tmp = gaim_network_get_local_ip_from_fd(fd); | |
89 | |
90 if (tmp) | |
91 return tmp; | |
92 | |
93 if (gethostname(localhost, 128) < 0) | |
94 return NULL; | |
95 | |
96 if ((host = gethostbyname(localhost)) == NULL) | |
97 return NULL; | |
98 | |
99 memcpy(&add, host->h_addr_list[0], 4); | |
100 add = htonl(add); | |
101 | |
102 g_snprintf(ip, 16, "%lu.%lu.%lu.%lu", | |
103 ((add >> 24) & 255), | |
104 ((add >> 16) & 255), | |
105 ((add >> 8) & 255), | |
106 add & 255); | |
107 | |
108 return ip; | |
109 } | |
110 | |
111 const char * | |
112 gaim_network_get_ip_for_account(const GaimAccount *account, int fd) | |
113 { | |
114 if (account && (gaim_account_get_public_ip(account) != NULL)) | |
115 return gaim_account_get_public_ip(account); | |
116 else if (gaim_network_get_local_ip() != NULL) | |
117 return gaim_network_get_local_ip(); | |
118 else | |
119 return gaim_network_get_local_system_ip(fd); | |
120 } | |
121 | |
8251 | 122 static int gaim_network_do_listen(unsigned short port) |
8231 | 123 { |
124 #if HAVE_GETADDRINFO | |
125 int listenfd; | |
126 const int on = 1; | |
127 struct addrinfo hints, *res, *ressave; | |
128 char serv[5]; | |
129 | |
8251 | 130 snprintf(serv, sizeof(serv), "%d", port); |
8231 | 131 memset(&hints, 0, sizeof(struct addrinfo)); |
132 hints.ai_flags = AI_PASSIVE; | |
133 hints.ai_family = AF_UNSPEC; | |
134 hints.ai_socktype = SOCK_STREAM; | |
135 if (getaddrinfo(NULL /* any IP */, serv, &hints, &res) != 0) { | |
136 gaim_debug_warning("network", "getaddrinfo: %s\n", strerror(errno)); | |
137 return -1; | |
138 } | |
139 ressave = res; | |
140 do { | |
141 listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | |
142 if (listenfd < 0) | |
143 continue; | |
144 setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); | |
145 if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0) | |
146 break; /* success */ | |
147 close(listenfd); | |
148 } while ( (res = res->ai_next) ); | |
149 | |
150 if (!res) | |
151 return -1; | |
152 | |
153 freeaddrinfo(ressave); | |
154 #else | |
155 int listenfd; | |
156 const int on = 1; | |
157 struct sockaddr_in sockin; | |
158 | |
159 if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | |
160 gaim_debug_warning("network", "socket: %s\n", strerror(errno)); | |
161 return -1; | |
162 } | |
163 | |
164 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0) { | |
165 gaim_debug_warning("network", "setsockopt: %s\n", strerror(errno)); | |
166 close(listenfd); | |
167 return -1; | |
168 } | |
169 | |
170 memset(&sockin, 0, sizeof(struct sockaddr_in)); | |
171 sockin.sin_family = AF_INET; | |
8251 | 172 sockin.sin_port = htons(port); |
8231 | 173 |
174 if (bind(listenfd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0) { | |
175 gaim_debug_warning("network", "bind: %s\n", strerror(errno)); | |
176 close(listenfd); | |
177 return -1; | |
178 } | |
179 #endif | |
180 | |
181 if (listen(listenfd, 4) != 0) { | |
182 gaim_debug_warning("network", "listen: %s\n", strerror(errno)); | |
183 close(listenfd); | |
184 return -1; | |
185 } | |
186 fcntl(listenfd, F_SETFL, O_NONBLOCK); | |
187 | |
188 gaim_debug_info("network", "Listening on port: %hu\n", gaim_network_get_port_from_fd(listenfd)); | |
189 return listenfd; | |
190 } | |
191 | |
8250 | 192 int gaim_network_listen(unsigned short port) |
8246 | 193 { |
8250 | 194 g_return_val_if_fail(port != 0, -1); |
195 | |
8246 | 196 return gaim_network_do_listen(port); |
197 } | |
198 | |
8250 | 199 int gaim_network_listen_range(unsigned short start, unsigned short end) |
8231 | 200 { |
8240 | 201 int ret = -1; |
8231 | 202 |
8250 | 203 if (gaim_prefs_get_bool("/core/network/ports_range_use")) { |
8239 | 204 start = gaim_prefs_get_int("/core/network/ports_range_start"); |
205 end = gaim_prefs_get_int("/core/network/ports_range_end"); | |
8250 | 206 } else { |
207 if (end < start) | |
208 end = start; | |
8239 | 209 } |
8231 | 210 |
211 for (; start <= end; start++) { | |
212 ret = gaim_network_do_listen(start); | |
213 if (ret >= 0) | |
214 break; | |
215 } | |
216 | |
217 return ret; | |
218 } | |
219 | |
220 short gaim_network_get_port_from_fd(int fd) | |
221 { | |
222 struct sockaddr_in addr; | |
223 socklen_t len; | |
224 | |
225 g_return_val_if_fail(fd > 0, 0); | |
226 | |
227 len = sizeof(addr); | |
228 if (getsockname(fd, (struct sockaddr *) &addr, &len) == -1) { | |
229 gaim_debug_warning("network", "getsockname: %s\n", strerror(errno)); | |
230 return 0; | |
231 } | |
232 | |
233 return ntohs(addr.sin_port); | |
234 } | |
235 | |
236 void | |
237 gaim_network_init(void) | |
238 { | |
239 gaim_prefs_add_none ("/core/network"); | |
240 gaim_prefs_add_bool ("/core/network/auto_ip", TRUE); | |
241 gaim_prefs_add_string("/core/network/public_ip", ""); | |
242 gaim_prefs_add_bool ("/core/network/ports_range_use", FALSE); | |
243 gaim_prefs_add_int ("/core/network/ports_range_start", 1024); | |
244 gaim_prefs_add_int ("/core/network/ports_range_end", 2048); | |
245 } |