Mercurial > pidgin.yaz
comparison src/protocols/qq/ip_location.c @ 14021:ef8490f9e823
[gaim-migrate @ 16618]
Replaced all C++-style comments with C-style ones.
Cleaned up some comments and implemented a more consistent formatting scheme.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Huetsch <markhuetsch> |
---|---|
date | Wed, 02 Aug 2006 15:35:36 +0000 |
parents | 983fd420e86b |
children |
comparison
equal
deleted
inserted
replaced
14020:13e7ba964993 | 14021:ef8490f9e823 |
---|---|
22 * This code is based on | 22 * This code is based on |
23 * * qqwry.c, by lvxiang <srm2003@163.com> | 23 * * qqwry.c, by lvxiang <srm2003@163.com> |
24 * * IpChecker.m, by Jeff_Ye | 24 * * IpChecker.m, by Jeff_Ye |
25 */ | 25 */ |
26 | 26 |
27 // START OF FILE | |
28 /*****************************************************************************/ | |
29 #include "internal.h" | 27 #include "internal.h" |
30 #include <string.h> // memset | 28 #include <string.h> |
31 #include "debug.h" | 29 #include "debug.h" |
32 #include "prefs.h" // gaim_prefs_get_string | 30 #include "prefs.h" |
33 | 31 |
34 #include "utils.h" | 32 #include "utils.h" |
35 #include "ip_location.h" | 33 #include "ip_location.h" |
36 | 34 |
37 #define DEFAULT_IP_LOCATION_FILE "gaim/QQWry.dat" | 35 #define DEFAULT_IP_LOCATION_FILE "gaim/QQWry.dat" |
38 | 36 |
39 typedef struct _ip_finder ip_finder; | 37 typedef struct _ip_finder ip_finder; |
40 | 38 |
41 // all offset is based the begining of the file | 39 /* all offset is based the begining of the file */ |
42 struct _ip_finder { | 40 struct _ip_finder { |
43 guint32 offset_first_start_ip; // first abs offset of start ip | 41 guint32 offset_first_start_ip; /* first abs offset of start ip */ |
44 guint32 offset_last_start_ip; // last abs offset of start ip | 42 guint32 offset_last_start_ip; /* last abs offset of start ip */ |
45 guint32 cur_start_ip; // start ip of current search range | 43 guint32 cur_start_ip; /* start ip of current search range */ |
46 guint32 cur_end_ip; // end ip of current search range | 44 guint32 cur_end_ip; /* end ip of current search range */ |
47 guint32 offset_cur_end_ip; // where is the current end ip saved | 45 guint32 offset_cur_end_ip; /* where is the current end ip saved */ |
48 GIOChannel *io; // IO Channel to read file | 46 GIOChannel *io; /* IO Channel to read file */ |
49 }; // struct _ip_finder | 47 }; /* struct _ip_finder */ |
50 | 48 |
51 /*****************************************************************************/ | 49 /* convert 1-4 bytes array to integer. |
52 // convert 1-4 bytes array to integer. | 50 * Small endian (higher bytes in lower place) */ |
53 // Small endian (higher bytes in lower place) | 51 static guint32 _byte_array_to_int(guint8 *ip, gint count) |
54 static guint32 _byte_array_to_int(guint8 * ip, gint count) | |
55 { | 52 { |
56 guint32 ret, i; | 53 guint32 ret, i; |
57 g_return_val_if_fail(count >= 1 && count <= 4, 0); | 54 g_return_val_if_fail(count >= 1 && count <= 4, 0); |
58 ret = ip[0]; | 55 ret = ip[0]; |
59 for (i = 0; i < count; i++) | 56 for (i = 0; i < count; i++) |
60 ret |= ((guint32) ip[i]) << (8 * i); | 57 ret |= ((guint32) ip[i]) << (8 * i); |
61 return ret; | 58 return ret; |
62 } // _byte_array_to_int | 59 } |
63 | 60 |
64 /*****************************************************************************/ | 61 /* read len of bytes to buf, from io at offset */ |
65 // read len of bytes to buf, from io at offset | 62 static void _read_from(GIOChannel *io, guint32 offset, guint8 *buf, gint len) |
66 static void _read_from(GIOChannel * io, guint32 offset, guint8 * buf, gint len) | |
67 { | 63 { |
68 GError *err; | 64 GError *err; |
69 GIOStatus status; | 65 GIOStatus status; |
70 | 66 |
71 err = NULL; | 67 err = NULL; |
73 if (err != NULL) { | 69 if (err != NULL) { |
74 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Fail seek file @offset[%d]: %s", offset, err->message); | 70 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Fail seek file @offset[%d]: %s", offset, err->message); |
75 g_error_free(err); | 71 g_error_free(err); |
76 memset(buf, 0, len); | 72 memset(buf, 0, len); |
77 return; | 73 return; |
78 } // if err | 74 } |
79 | 75 |
80 status = g_io_channel_read_chars(io, buf, len, NULL, &err); | 76 status = g_io_channel_read_chars(io, buf, len, NULL, &err); |
81 if (err != NULL) { | 77 if (err != NULL) { |
82 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Fail read %d bytes from file: %s", len, err->message); | 78 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Fail read %d bytes from file: %s", len, err->message); |
83 g_error_free(err); | 79 g_error_free(err); |
84 memset(buf, 0, len); | 80 memset(buf, 0, len); |
85 return; | 81 return; |
86 } // if err | 82 } |
87 } // _read_from | 83 } |
88 | 84 |
89 /*****************************************************************************/ | 85 /* read len of bytes to buf, from io at offset */ |
90 // read len of bytes to buf, from io at offset | 86 static gsize _read_line_from(GIOChannel *io, guint32 offset, gchar **ret_str) |
91 static gsize _read_line_from(GIOChannel * io, guint32 offset, gchar ** ret_str) | |
92 { | 87 { |
93 gsize bytes_read; | 88 gsize bytes_read; |
94 GError *err; | 89 GError *err; |
95 GIOStatus status; | 90 GIOStatus status; |
96 | 91 |
99 if (err != NULL) { | 94 if (err != NULL) { |
100 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Fail seek file @offset[%d]: %s", offset, err->message); | 95 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Fail seek file @offset[%d]: %s", offset, err->message); |
101 g_error_free(err); | 96 g_error_free(err); |
102 ret_str = NULL; | 97 ret_str = NULL; |
103 return -1; | 98 return -1; |
104 } // if err | 99 } |
105 | 100 |
106 status = g_io_channel_read_line(io, ret_str, &bytes_read, NULL, &err); | 101 status = g_io_channel_read_line(io, ret_str, &bytes_read, NULL, &err); |
107 if (err != NULL) { | 102 if (err != NULL) { |
108 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Fail read from file: %s", err->message); | 103 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Fail read from file: %s", err->message); |
109 g_error_free(err); | 104 g_error_free(err); |
110 ret_str = NULL; | 105 ret_str = NULL; |
111 return -1; | 106 return -1; |
112 } // if err | 107 } |
113 | 108 |
114 return bytes_read; | 109 return bytes_read; |
115 } // _read_from | 110 } |
116 | 111 |
117 /*****************************************************************************/ | 112 /* read the string from io, at offset, it may jump several times |
118 // read the string from io, at offset, it may jump several times | 113 * returns the offset of next readable string for area */ |
119 // returns the offset of next readable string for area | 114 static guint32 _get_string(GIOChannel *io, guint32 offset, gchar **ret) |
120 static guint32 _get_string(GIOChannel * io, guint32 offset, gchar ** ret) | |
121 { | 115 { |
122 guint8 *buf; | 116 guint8 *buf; |
123 g_return_val_if_fail(io != NULL, 0); | 117 g_return_val_if_fail(io != NULL, 0); |
124 | 118 |
125 buf = g_new0(guint8, 3); | 119 buf = g_new0(guint8, 3); |
134 _get_string(io, _byte_array_to_int(buf, 3), ret); | 128 _get_string(io, _byte_array_to_int(buf, 3), ret); |
135 return offset + 4; | 129 return offset + 4; |
136 default: | 130 default: |
137 _read_line_from(io, offset, ret); | 131 _read_line_from(io, offset, ret); |
138 return offset + strlen(*ret) + 1; | 132 return offset + strlen(*ret) + 1; |
139 } /* switch */ | 133 } |
140 } // _get_string | 134 } |
141 | 135 |
142 /*****************************************************************************/ | 136 /* extract country and area starting from offset */ |
143 // extract country and area starting from offset | 137 static void _get_country_city(GIOChannel *io, guint32 offset, gchar **country, gchar **area) |
144 static void _get_country_city(GIOChannel * io, guint32 offset, gchar ** country, gchar ** area) | |
145 { | 138 { |
146 guint32 next_offset; | 139 guint32 next_offset; |
147 g_return_if_fail(io != NULL); | 140 g_return_if_fail(io != NULL); |
148 | 141 |
149 next_offset = _get_string(io, offset, country); | 142 next_offset = _get_string(io, offset, country); |
150 if (next_offset == 0) | 143 if (next_offset == 0) |
151 *area = g_strdup(""); | 144 *area = g_strdup(""); |
152 else | 145 else |
153 _get_string(io, next_offset, area); | 146 _get_string(io, next_offset, area); |
154 } // _get_country_city | 147 } |
155 | 148 |
156 /*****************************************************************************/ | 149 /* set start_ip and end_ip of current range */ |
157 // set start_ip and end_ip of current range | 150 static void _set_ip_range(gint rec_no, ip_finder *f) |
158 static void _set_ip_range(gint rec_no, ip_finder * f) | |
159 { | 151 { |
160 guint8 *buf; | 152 guint8 *buf; |
161 guint32 offset; | 153 guint32 offset; |
162 | 154 |
163 g_return_if_fail(f != NULL); | 155 g_return_if_fail(f != NULL); |
169 f->cur_start_ip = _byte_array_to_int(buf, 4); | 161 f->cur_start_ip = _byte_array_to_int(buf, 4); |
170 f->offset_cur_end_ip = _byte_array_to_int(buf + 4, 3); | 162 f->offset_cur_end_ip = _byte_array_to_int(buf + 4, 3); |
171 | 163 |
172 _read_from(f->io, f->offset_cur_end_ip, buf, 4); | 164 _read_from(f->io, f->offset_cur_end_ip, buf, 4); |
173 f->cur_end_ip = _byte_array_to_int(buf, 4); | 165 f->cur_end_ip = _byte_array_to_int(buf, 4); |
174 | 166 } |
175 } // _set_ip_range | 167 |
176 | 168 /* set the country and area for given IP. |
177 /*****************************************************************************/ | 169 * country and area needs to be freed later */ |
178 // set the country and area for given IP. | 170 gboolean qq_ip_get_location(guint32 ip, gchar **country, gchar **area) |
179 // country and area needs to be freed later | |
180 gboolean qq_ip_get_location(guint32 ip, gchar ** country, gchar ** area) | |
181 { | 171 { |
182 gint rec, record_count, B, E; | 172 gint rec, record_count, B, E; |
183 guint8 *buf; | 173 guint8 *buf; |
184 gchar *addr_file; | 174 gchar *addr_file; |
185 ip_finder *f; | 175 ip_finder *f; |
202 g_free(addr_file); | 192 g_free(addr_file); |
203 if (err != NULL) { | 193 if (err != NULL) { |
204 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Unable to open (%s): %s\n", addr_file, err->message); | 194 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Unable to open (%s): %s\n", addr_file, err->message); |
205 g_error_free(err); | 195 g_error_free(err); |
206 return FALSE; | 196 return FALSE; |
207 } else | 197 } else { |
208 g_io_channel_set_encoding(f->io, NULL, NULL); // set binary | 198 g_io_channel_set_encoding(f->io, NULL, NULL); /* set binary */ |
199 } | |
209 | 200 |
210 buf = g_newa(guint8, 4); | 201 buf = g_newa(guint8, 4); |
211 | 202 |
212 _read_from(f->io, 0, buf, 4); | 203 _read_from(f->io, 0, buf, 4); |
213 f->offset_first_start_ip = _byte_array_to_int(buf, 4); | 204 f->offset_first_start_ip = _byte_array_to_int(buf, 4); |
218 if (record_count <= 1) { | 209 if (record_count <= 1) { |
219 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "File data error, no records found\n"); | 210 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "File data error, no records found\n"); |
220 g_io_channel_shutdown(f->io, FALSE, NULL); | 211 g_io_channel_shutdown(f->io, FALSE, NULL); |
221 return FALSE;; | 212 return FALSE;; |
222 } | 213 } |
223 // search for right range | 214 /* search for right range */ |
224 B = 0; | 215 B = 0; |
225 E = record_count; | 216 E = record_count; |
226 while (B < E - 1) { | 217 while (B < E - 1) { |
227 rec = (B + E) / 2; | 218 rec = (B + E) / 2; |
228 _set_ip_range(rec, f); | 219 _set_ip_range(rec, f); |
232 } | 223 } |
233 if (ip > f->cur_start_ip) | 224 if (ip > f->cur_start_ip) |
234 B = rec; | 225 B = rec; |
235 else | 226 else |
236 E = rec; | 227 E = rec; |
237 } // while | 228 } |
238 _set_ip_range(B, f); | 229 _set_ip_range(B, f); |
239 | 230 |
240 if (f->cur_start_ip <= ip && ip <= f->cur_end_ip) { | 231 if (f->cur_start_ip <= ip && ip <= f->cur_end_ip) { |
241 _get_country_city(f->io, f->offset_cur_end_ip + 4, country, area); | 232 _get_country_city(f->io, f->offset_cur_end_ip + 4, country, area); |
242 } else { // not in this range... miss | 233 } else { /* not in this range... miss */ |
243 *country = g_strdup("unkown"); | 234 *country = g_strdup("unkown"); |
244 *area = g_strdup(" "); | 235 *area = g_strdup(" "); |
245 } // if ip_start<=ip<=ip_end | 236 } /* if ip_start<=ip<=ip_end */ |
246 | 237 |
247 g_io_channel_shutdown(f->io, FALSE, NULL); | 238 g_io_channel_shutdown(f->io, FALSE, NULL); |
248 return TRUE; | 239 return TRUE; |
249 | 240 } |
250 } // qq_ip_get_location | |
251 | |
252 /*****************************************************************************/ | |
253 // END OF FILE |