1152
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2 /*
|
|
3 $Id: util.c 1162 2000-11-28 02:22:42Z warmenhoven $
|
|
4 $Log$
|
|
5 Revision 1.1 2000/11/28 02:22:42 warmenhoven
|
|
6 icq. whoop de doo
|
|
7
|
|
8 Revision 1.32 2000/07/22 16:49:32 denis
|
|
9 Trinidad and Tobago country was added.
|
|
10
|
|
11 Revision 1.31 2000/07/21 16:51:20 denis
|
|
12 All languages, possible in original icq were added.
|
|
13 Occupation array fixed.
|
|
14
|
|
15 Revision 1.30 2000/07/20 09:58:59 denis
|
|
16 Occupation table corrected to comply with original ICQ.
|
|
17
|
|
18 Revision 1.29 2000/07/04 07:25:29 pcadach
|
|
19 icq_FmtLog() crashed when it receives NULL at link argument.
|
|
20
|
|
21 Revision 1.28 2000/06/30 13:59:43 denis
|
|
22 Slovak Republic country code fixed.
|
|
23
|
|
24 Revision 1.27 2000/06/25 17:00:32 denis
|
|
25 icq_MetaOccupation[], icq_MetaPastBackgrounds[],
|
|
26 icq_MetaAffiliations[] and icq_MetaLanguages[] arrays were added along
|
|
27 with icq_GetMetaOccupationName(), icq_GetMetaBackgroundName(),
|
|
28 icq_GetMetaAffiliationName() and icq_GetMetaLanguageName() functions
|
|
29 to access them.
|
|
30
|
|
31 Revision 1.26 2000/05/21 17:42:51 denis
|
|
32 Bulgaria country code was added. Thanks to
|
|
33 "Napalm Death" <napalmbox@hotmail.com>
|
|
34
|
|
35 Revision 1.25 2000/05/03 18:29:15 denis
|
|
36 Callbacks have been moved to the ICQLINK structure.
|
|
37
|
|
38 Revision 1.24 2000/04/10 16:36:04 denis
|
|
39 Some more Win32 compatibility from Guillaume Rosanis <grs@mail.com>
|
|
40
|
|
41 Revision 1.23 2000/04/05 14:37:02 denis
|
|
42 Applied patch from "Guillaume R." <grs@mail.com> for basic Win32
|
|
43 compatibility.
|
|
44
|
|
45 Revision 1.22 2000/03/31 12:49:15 nofate
|
|
46 remove static variable
|
|
47
|
|
48 Revision 1.21 1999/11/11 15:10:33 guruz
|
|
49 - Added Base for Webpager Messages. Please type "make fixme"
|
|
50 - Removed Segfault when kicq is started the first time
|
|
51
|
|
52 Revision 1.20 1999/10/07 18:01:40 denis
|
|
53 Cleanups.
|
|
54
|
|
55 Revision 1.19 1999/09/29 17:16:45 denis
|
|
56 Cleanups.
|
|
57
|
|
58 Revision 1.18 1999/07/18 20:24:27 bills
|
|
59 removed old byte order and contact list functions
|
|
60
|
|
61 Revision 1.17 1999/07/16 15:46:03 denis
|
|
62 Cleaned up.
|
|
63
|
|
64 Revision 1.16 1999/07/16 12:04:49 denis
|
|
65 Status support changed.
|
|
66
|
|
67 Revision 1.15 1999/07/12 15:13:46 cproch
|
|
68 - added definition of ICQLINK to hold session-specific global variabled
|
|
69 applications which have more than one connection are now possible
|
|
70 - changed nearly every function defintion to support ICQLINK parameter
|
|
71
|
|
72 Revision 1.14 1999/04/17 19:20:35 bills
|
|
73 removed *_link entries from icq_ContactItem, including cleanup/init code
|
|
74
|
|
75 Revision 1.13 1999/04/14 15:06:51 denis
|
|
76 Cleanups for "strict" compiling (-ansi -pedantic)
|
|
77
|
|
78 */
|
|
79
|
|
80 #include <stdlib.h>
|
|
81 #include <ctype.h>
|
|
82
|
|
83 #ifndef _WIN32
|
|
84 #include <unistd.h>
|
|
85 #endif
|
|
86
|
|
87 #include "icqtypes.h"
|
|
88 #include "icq.h"
|
|
89 #include "icqlib.h"
|
|
90 #include "stdpackets.h"
|
|
91 #include "util.h"
|
|
92 #include "stdarg.h"
|
|
93
|
|
94 /*
|
|
95 * This list of countries should be sorted according to country code.
|
|
96 * When adding new country, please preserve the order!
|
|
97 */
|
|
98 icq_ArrayType icq_Countries[] = {
|
|
99 {"USA",1},
|
|
100 {"Russia",7},
|
|
101 {"Egypt",20},
|
|
102 {"South Africa",27},
|
|
103 {"Greece",30},
|
|
104 {"Netherlands",31},
|
|
105 {"Belgium",32},
|
|
106 {"France",33},
|
|
107 {"Monaco",33},
|
|
108 {"Spain",34},
|
|
109 {"Hungary",36},
|
|
110 {"Yugoslavia",38},
|
|
111 {"Italy",39},
|
|
112 {"San Marino",39},
|
|
113 {"Vatican City",39},
|
|
114 {"Romania",40},
|
|
115 {"Liechtenstein",41},
|
|
116 {"Switzerland",41},
|
|
117 {"Czech Republic",42},
|
|
118 {"Austria",43},
|
|
119 {"UK",44},
|
|
120 {"Denmark",45},
|
|
121 {"Sweden",46},
|
|
122 {"Norway",47},
|
|
123 {"Poland",48},
|
|
124 {"Germany",49},
|
|
125 {"Peru",51},
|
|
126 {"Mexico",52},
|
|
127 {"Guantanomo Bay",53},
|
|
128 {"Argentina",54},
|
|
129 {"Brazil",55},
|
|
130 {"Chile",56},
|
|
131 {"Columbia",57},
|
|
132 {"Venezuela",58},
|
|
133 {"Malaysia",60},
|
|
134 {"Australia",61},
|
|
135 {"Indonesia",62},
|
|
136 {"Philippines",63},
|
|
137 {"New Zealand",64},
|
|
138 {"Singapore",65},
|
|
139 {"Thailand",66},
|
|
140 {"Japan",81},
|
|
141 {"South Korea",82},
|
|
142 {"Vietnam",84},
|
|
143 {"China",86},
|
|
144 {"Turkey",90},
|
|
145 {"India",91},
|
|
146 {"Pakistan",92},
|
|
147 {"Sri Lanka",94},
|
|
148 {"Iran",98},
|
|
149 {"Canada",107},
|
|
150 {"Morocco",212},
|
|
151 {"Algeria",213},
|
|
152 {"Tunisia",216},
|
|
153 {"Libya",218},
|
|
154 {"Senegal",221},
|
|
155 {"Mali",223},
|
|
156 {"Ivory Coast",225},
|
|
157 {"Liberia",231},
|
|
158 {"Ghana",233},
|
|
159 {"Nigeria",234},
|
|
160 {"Cameroon",237},
|
|
161 {"Gabon",241},
|
|
162 {"Zaire",243},
|
|
163 {"Ethiopia",251},
|
|
164 {"Kenya",254},
|
|
165 {"Tanzania",255},
|
|
166 {"Zimbabwe",263},
|
|
167 {"Namibia",264},
|
|
168 {"Malawi",265},
|
|
169 {"Aruba",297},
|
|
170 {"Portugal",351},
|
|
171 {"Luxembourg",352},
|
|
172 {"Ireland",353},
|
|
173 {"Iceland",354},
|
|
174 {"Malta",356},
|
|
175 {"Cyprus",357},
|
|
176 {"Finland",358},
|
|
177 {"Bulgaria",359},
|
|
178 {"Ukraine",380},
|
|
179 {"Belize",501},
|
|
180 {"Guatemala",502},
|
|
181 {"El Salvador",503},
|
|
182 {"Honduras",504},
|
|
183 {"Nicaragua",505},
|
|
184 {"Costa Rice",506},
|
|
185 {"Panama",507},
|
|
186 {"Haiti",509},
|
|
187 {"Guadeloupe",590},
|
|
188 {"Bolivia",591},
|
|
189 {"Guyana",592},
|
|
190 {"Ecuador",593},
|
|
191 {"Paraguay",595},
|
|
192 {"French Antilles",596},
|
|
193 {"Suriname",597},
|
|
194 {"Uruguay",598},
|
|
195 {"Netherlands Antilles",599},
|
|
196 {"Saipan",670},
|
|
197 {"Saipan",670},
|
|
198 {"Guam",671},
|
|
199 {"Papua New Guinea",675},
|
|
200 {"Fiji",679},
|
|
201 {"American Samoa",684},
|
|
202 {"New Caledonia",687},
|
|
203 {"French Polynesia",689},
|
|
204 {"Hong Kong",852},
|
|
205 {"Trinidad and Tobago",868},
|
|
206 {"Bangladesh",880},
|
|
207 {"Taiwan",886},
|
|
208 {"Jordan",962},
|
|
209 {"Iraq",964},
|
|
210 {"Kuwait",965},
|
|
211 {"Saudia Arabia",966},
|
|
212 {"Yemen",967},
|
|
213 {"Oman",968},
|
|
214 {"United Arab Emirates",971},
|
|
215 {"Israel",972},
|
|
216 {"Bahrain",973},
|
|
217 {"Qatar",974},
|
|
218 {"Nepal",977},
|
|
219 {"Slovak Republic",4201},
|
|
220 {"Not entered",0xffff},
|
|
221 };
|
|
222
|
|
223 icq_ArrayType icq_MetaOccupation[] = {
|
|
224 {"Academic", 1},
|
|
225 {"Administrative", 2},
|
|
226 {"Art/Entertainment", 3},
|
|
227 {"College Student", 4},
|
|
228 {"Computers", 5},
|
|
229 {"Community & Social", 6},
|
|
230 {"Education", 7},
|
|
231 {"Engineering", 8},
|
|
232 {"Financial Services", 9},
|
|
233 {"Government", 10},
|
|
234 {"High School Student", 11},
|
|
235 {"Home", 12},
|
|
236 {"ICQ - Providing Help", 13},
|
|
237 {"Law", 14},
|
|
238 {"Managerial", 15},
|
|
239 {"Manufacturing", 16},
|
|
240 {"Medical/Health", 17},
|
|
241 {"Military", 18},
|
|
242 {"Non-Government Organization", 19},
|
|
243 {"Professional", 20},
|
|
244 {"Retail", 21},
|
|
245 {"Retired", 22},
|
|
246 {"Science & Research", 23},
|
|
247 {"Sports", 24},
|
|
248 {"Technical", 25},
|
|
249 {"University Student", 26},
|
|
250 {"Web Building", 27},
|
|
251 {"Other Services", 99},
|
|
252 };
|
|
253
|
|
254 icq_ArrayType icq_MetaPastBackgrounds[] = {
|
|
255 {"Elementary School", 300},
|
|
256 {"High School", 301},
|
|
257 {"College", 302},
|
|
258 {"University", 303},
|
|
259 {"Military", 304},
|
|
260 {"Past Work Place", 305},
|
|
261 {"Past Organization", 306},
|
|
262 {"Other", 399},
|
|
263 };
|
|
264
|
|
265 icq_ArrayType icq_MetaAffiliations[] = {
|
|
266 {"Alumni Org.", 200},
|
|
267 {"Charity Org.", 201},
|
|
268 {"Club/Social Org.", 202},
|
|
269 {"Community Org.", 203},
|
|
270 {"Cultural Org.", 204},
|
|
271 {"Fan Clubs", 205},
|
|
272 {"Fraternity/Sorority", 206},
|
|
273 {"Hobbyists Org.", 207},
|
|
274 {"International Org.", 208},
|
|
275 {"Nature and Environment Org.", 209},
|
|
276 {"Professional Org.", 210},
|
|
277 {"Scientific/Technical Org.", 211},
|
|
278 {"Self Improvement Group", 212},
|
|
279 {"Spiritual/Religious Org.", 213},
|
|
280 {"Sports Org.", 214},
|
|
281 {"Support Org.", 215},
|
|
282 {"Trade and Business Org.", 216},
|
|
283 {"Union", 217},
|
|
284 {"Voluntary Org.", 218},
|
|
285 {"Other", 299},
|
|
286 };
|
|
287
|
|
288 icq_ArrayType icq_MetaLanguages[] = {
|
|
289 {"Not Entered", 0},
|
|
290 {"Arabic", 1},
|
|
291 {"Bhojpuri", 2},
|
|
292 {"Bulgarian", 3},
|
|
293 {"Burmese", 4},
|
|
294 {"Cantonese", 5},
|
|
295 {"Catalan", 6},
|
|
296 {"Chinese", 7},
|
|
297 {"Croatian", 8},
|
|
298 {"Czech", 9},
|
|
299 {"Danish", 10},
|
|
300 {"Dutch", 11},
|
|
301 {"English", 12},
|
|
302 {"Esperanto", 13},
|
|
303 {"Estonian", 14},
|
|
304 {"Farsi", 15},
|
|
305 {"Finnish", 16},
|
|
306 {"French", 17},
|
|
307 {"Gaelic", 18},
|
|
308 {"German", 19},
|
|
309 {"Greek", 20},
|
|
310 {"Hebrew", 21},
|
|
311 {"Hindi", 22},
|
|
312 {"Hungarian", 23},
|
|
313 {"Icelandic", 24},
|
|
314 {"Indonesian", 25},
|
|
315 {"Italian", 26},
|
|
316 {"Japanese", 27},
|
|
317 {"Khmer", 28},
|
|
318 {"Korean", 29},
|
|
319 {"Lao", 30},
|
|
320 {"Latvian", 31},
|
|
321 {"Lithuanian", 32},
|
|
322 {"Malay", 33},
|
|
323 {"Norwegian", 34},
|
|
324 {"Polish", 35},
|
|
325 {"Portuguese", 36},
|
|
326 {"Romanian", 37},
|
|
327 {"Russian", 38},
|
|
328 {"Serbian", 39},
|
|
329 {"Slovak", 40},
|
|
330 {"Slovenian", 41},
|
|
331 {"Somali", 42},
|
|
332 {"Spanish", 43},
|
|
333 {"Swahili", 44},
|
|
334 {"Swedish", 45},
|
|
335 {"Tagalog", 46},
|
|
336 {"Tatar", 47},
|
|
337 {"Thai", 48},
|
|
338 {"Turkish", 49},
|
|
339 {"Ukrainian", 50},
|
|
340 {"Urdu", 51},
|
|
341 {"Vietnamese", 52},
|
|
342 {"Yiddish", 53},
|
|
343 {"Yoruba", 54},
|
|
344 {"Afrikaans", 55},
|
|
345 {"Bosnian", 56},
|
|
346 {"Persian", 57},
|
|
347 {"Albanian", 58},
|
|
348 {"Armenian", 59},
|
|
349 {"Punjabi", 60},
|
|
350 {"Chamorro", 61},
|
|
351 {"Mongolian", 62},
|
|
352 {"Mandarin", 63},
|
|
353 {"Taiwaness", 64},
|
|
354 {"Macedonian", 65},
|
|
355 {"Sindhi", 66},
|
|
356 {"Welsh", 67},
|
|
357 };
|
|
358
|
|
359 void hex_dump(char *data, long size)
|
|
360 {
|
|
361 long i;
|
|
362 long x;
|
|
363 int r=1;
|
|
364 char d[32];
|
|
365 unsigned char bfr[64];
|
|
366 for(i=0, x=0;;i++)
|
|
367 {
|
|
368 if(i<size)
|
|
369 {
|
|
370 if(x==0)
|
|
371 printf("%04lx: ", i);
|
|
372 #ifdef _WIN32
|
|
373 sprintf(d, "%08x", data[i]);
|
|
374 #else
|
|
375 snprintf(d, 9, "%08x", data[i]);
|
|
376 #endif
|
|
377 printf("%c%c ", d[6], d[7]);
|
|
378 bfr[x]=data[i];
|
|
379 if(bfr[x]<0x20)
|
|
380 bfr[x]='.';
|
|
381 if(bfr[x]>0x7f)
|
|
382 bfr[x]='.';
|
|
383 }
|
|
384 else
|
|
385 {
|
|
386 if(x==0)
|
|
387 break;
|
|
388 else
|
|
389 {
|
|
390 printf(" ");
|
|
391 bfr[x]=' ';
|
|
392 r=0;
|
|
393 }
|
|
394 }
|
|
395 x++;
|
|
396 if(!(x<16))
|
|
397 {
|
|
398 bfr[x]=0;
|
|
399 printf("%s\n", bfr);
|
|
400 x=0;
|
|
401 if(!r)
|
|
402 break;
|
|
403 }
|
|
404 }
|
|
405 }
|
|
406
|
|
407 /* simple mapping for udp status->tcp status translation function */
|
|
408 struct icq_TCPStatusRec
|
|
409 {
|
|
410 unsigned long udp_status;
|
|
411 long tcp_status;
|
|
412 } icq_TCPStatusMap[] = {
|
|
413 { STATUS_OFFLINE , 0 },
|
|
414 { STATUS_ONLINE , ICQ_TCP_STATUS_ONLINE },
|
|
415 { STATUS_INVISIBLE , ICQ_TCP_STATUS_INVISIBLE },
|
|
416 { STATUS_NA , ICQ_TCP_STATUS_NA },
|
|
417 { STATUS_FREE_CHAT , ICQ_TCP_STATUS_FREE_CHAT },
|
|
418 { STATUS_OCCUPIED , ICQ_TCP_STATUS_OCCUPIED },
|
|
419 { STATUS_AWAY , ICQ_TCP_STATUS_AWAY },
|
|
420 { STATUS_DND , ICQ_TCP_STATUS_DND },
|
|
421 };
|
|
422
|
|
423 long icq_TCPXlateStatus(unsigned long udp_status)
|
|
424 {
|
|
425 unsigned int i;
|
|
426 for(i=0;i<sizeof(icq_TCPStatusMap)/sizeof(struct icq_TCPStatusRec);i++)
|
|
427 if(icq_TCPStatusMap[i].udp_status==udp_status)
|
|
428 return icq_TCPStatusMap[i].tcp_status;
|
|
429 /* warning: "couldn't find tcp status for %d, assuming 0", udp_status */
|
|
430 return 0;
|
|
431 }
|
|
432
|
|
433 void icq_FmtLog(ICQLINK *link, int level, const char *fmt, ...)
|
|
434 {
|
|
435 char buffer[2048];
|
|
436 va_list ap;
|
|
437 va_start(ap, fmt);
|
|
438
|
|
439 if(!link)
|
|
440 return;
|
|
441 #ifdef _MSVC_
|
|
442 _vsnprintf(buffer, 1024, fmt, ap);
|
|
443 #else
|
|
444 (void)vsnprintf(buffer, 1024, fmt, ap);
|
|
445 #endif
|
|
446 va_end(ap);
|
|
447
|
|
448 if(link->icq_Log && icq_LogLevel>=level)
|
|
449 (*link->icq_Log)(link, time(0L), level, buffer);
|
|
450 }
|
|
451
|
|
452 /**
|
|
453 * Following functions used by qsort and bsearch to
|
|
454 * compare 2 pointers to icq_ArrayType object.
|
|
455 */
|
|
456 int array_code_compare(const void *x, const void *y)
|
|
457 {
|
|
458 return ((icq_ArrayType*)x)->code - ((icq_ArrayType*)y)->code;
|
|
459 }
|
|
460
|
|
461 const char *icq_GetCountryName(unsigned short code)
|
|
462 {
|
|
463 icq_ArrayType *res,key;
|
|
464
|
|
465 key.code=code;
|
|
466 res=bsearch(&key, icq_Countries, sizeof(icq_Countries)/sizeof(icq_ArrayType),
|
|
467 sizeof(icq_ArrayType), array_code_compare);
|
|
468
|
|
469 return res?res->name:"Unknown";
|
|
470 }
|
|
471
|
|
472 const char *icq_GetMetaOccupationName(unsigned short code)
|
|
473 {
|
|
474 icq_ArrayType *res,key;
|
|
475
|
|
476 key.code=code;
|
|
477 res=bsearch(&key, icq_MetaOccupation, sizeof(icq_MetaOccupation)/sizeof(icq_ArrayType),
|
|
478 sizeof(icq_ArrayType), array_code_compare);
|
|
479
|
|
480 return res?res->name:"Unknown";
|
|
481 }
|
|
482
|
|
483 const char *icq_GetMetaBackgroundName(unsigned short code)
|
|
484 {
|
|
485 icq_ArrayType *res,key;
|
|
486
|
|
487 key.code=code;
|
|
488 res=bsearch(&key, icq_MetaPastBackgrounds, sizeof(icq_MetaPastBackgrounds)/sizeof(icq_ArrayType),
|
|
489 sizeof(icq_ArrayType), array_code_compare);
|
|
490
|
|
491 return res?res->name:"Unknown";
|
|
492 }
|
|
493
|
|
494 const char *icq_GetMetaAffiliationName(unsigned short code)
|
|
495 {
|
|
496 icq_ArrayType *res,key;
|
|
497
|
|
498 key.code=code;
|
|
499 res=bsearch(&key, icq_MetaAffiliations, sizeof(icq_MetaAffiliations)/sizeof(icq_ArrayType),
|
|
500 sizeof(icq_ArrayType), array_code_compare);
|
|
501
|
|
502 return res?res->name:"Unknown";
|
|
503 }
|
|
504
|
|
505 const char *icq_GetMetaLanguageName(unsigned short code)
|
|
506 {
|
|
507 icq_ArrayType *res,key;
|
|
508
|
|
509 key.code=code;
|
|
510 res=bsearch(&key, icq_MetaLanguages, sizeof(icq_MetaLanguages)/sizeof(icq_ArrayType),
|
|
511 sizeof(icq_ArrayType), array_code_compare);
|
|
512
|
|
513 return res?res->name:"Unknown";
|
|
514 }
|
|
515
|
|
516 /********************************************
|
|
517 returns a string describing the status or
|
|
518 a "Error" if no such string exists
|
|
519 *********************************************/
|
|
520 const char *icq_ConvertStatus2Str(unsigned long status)
|
|
521 {
|
|
522 if((unsigned long)STATUS_OFFLINE == status) /* this because -1 & 0x01FF is not -1 */
|
|
523 return "Offline";
|
|
524
|
|
525 if((status & STATUS_INVISIBLE) == STATUS_INVISIBLE)
|
|
526 return "Invisible";
|
|
527 else if((status & STATUS_FREE_CHAT) == STATUS_FREE_CHAT)
|
|
528 return "Free for chat";
|
|
529 else if((status & STATUS_DND) == STATUS_DND)
|
|
530 return "Do not disturb";
|
|
531 else if((status & STATUS_OCCUPIED) == STATUS_OCCUPIED)
|
|
532 return "Occupied";
|
|
533 else if((status & STATUS_NA) == STATUS_NA)
|
|
534 return "Not available";
|
|
535 else if((status & STATUS_AWAY) == STATUS_AWAY)
|
|
536 return "Away";
|
|
537 else if(!(status & 0x01FF))
|
|
538 return "Online";
|
|
539 else
|
|
540 return "Error";
|
|
541 }
|