1 /* (c) 2002-2005 by Marcin Wiacek and Michal Cihar */
2 /* Checking used compiler (c) 2002 by Michal Cihar */
3
4 #include <gammu-config.h>
5 #include <gammu-misc.h>
6
7 #include "misc.h"
8
9 #include "coding/coding.h"
10 #include "../debug.h"
11
12 #include <string.h>
13 #include <time.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <ctype.h>
17 #ifdef WIN32
18 # define WIN32_LEAN_AND_MEAN
19 # include <windows.h>
20 # include <locale.h>
21 # define gmtime_r(x, y) gmtime_s(y, x)
22 # define localtime_r(x, y) localtime_s(y, x)
23 #endif
24 #ifdef HAVE_SYS_UTSNAME_H
25 # include <sys/utsname.h>
26 #endif
27 #ifdef __CYGWIN__
28 #include <cygwin/version.h>
29 #endif
30
31 #ifdef WIN32
setenv(const char * name,const char * value,int overwrite)32 int setenv(const char *name, const char *value, int overwrite)
33 {
34 char env_var[_MAX_ENV];
35 char* has_value = getenv(name);
36 if(!has_value || overwrite) {
37 snprintf(env_var, _MAX_ENV, "%s=%s", name, value);
38 return _putenv(env_var);
39 }
40 return -1;
41 }
42
unsetenv(const char * name)43 void unsetenv(const char *name)
44 {
45 _putenv(name);
46 }
47 #endif // WIN32
48
49 /**
50 * Recalculates struct tm content. We can not use mktime directly, as it
51 * works only for dates > 1970. Day of week calculation is nased on article
52 * in Polish PC-Kurier 8/1998 page 104.
53 *
54 * @see http://www.pckurier.pl
55 */
RecalcDateTime(struct tm * st,const int year,const int month,const int day,const int hour,const int minute,const int second)56 int RecalcDateTime(struct tm *st, const int year, const int month, const int day, const int hour, const int minute, const int second)
57 {
58 const int days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
59 int i, p, q, r;
60 GSM_DateTime Date;
61
62 Date.Year = year;
63 Date.Month = month;
64 Date.Day = day;
65 Date.Hour = hour;
66 Date.Minute = minute;
67 Date.Second = second;
68 Date.Timezone = 0;
69
70 if (!CheckDate(&Date) || !CheckTime(&Date)) return 0;
71
72 memset(st, 0, sizeof(*st));
73
74 /* Calculate day of year */
75 st->tm_yday = day;
76 for (i = 0; i < month - 1; i++)
77 st->tm_yday += days[i];
78
79 /* Calculate day of week */
80 p = (14 - month) / 12;
81 q = month + 12 * p - 2;
82 r = year - p;
83 st->tm_wday = (day + (31 * q) / 12 + r + r / 4 - r / 100 + r / 400) % 7;
84
85
86 st->tm_hour = hour;
87 st->tm_min = minute;
88 st->tm_sec = second;
89 st->tm_year = year - 1900;
90 st->tm_mon = month - 1;
91 st->tm_mday = day;
92
93 st->tm_isdst = -1; /* FIXME */
94
95 return 1;
96 }
97
98
99 /**
100 * Recalculates struct tm content.
101 */
RecalcDate(struct tm * st,const int year,const int month,const int day)102 int RecalcDate(struct tm *st, const int year, const int month, const int day)
103 {
104 return RecalcDateTime(st, year, month, day, 0, 0, 0);
105 }
106
107
108 /**
109 * Return day of year index.
110 */
GetDayOfYear(unsigned int year,unsigned int month,unsigned int day)111 int GetDayOfYear(unsigned int year, unsigned int month, unsigned int day)
112 {
113 struct tm st;
114
115 RecalcDate(&st, year, month, day);
116
117 return st.tm_yday;
118 }
119
120 /**
121 * Return day of week index.
122 */
GetWeekOfMonth(unsigned int year,unsigned int month,unsigned int day)123 int GetWeekOfMonth(unsigned int year, unsigned int month, unsigned int day)
124 {
125 struct tm st;
126
127 RecalcDate(&st, year, month, day);
128
129 return 1 + (day - st.tm_wday) / 7;
130 }
131
132 /**
133 * Return day of week index.
134 */
GetDayOfWeek(unsigned int year,unsigned int month,unsigned int day)135 int GetDayOfWeek(unsigned int year, unsigned int month, unsigned int day)
136 {
137 struct tm st;
138
139 RecalcDate(&st, year, month, day);
140
141 return st.tm_wday;
142 }
143
144 /**
145 * Return textual representation of day of week;
146 */
DayOfWeek(unsigned int year,unsigned int month,unsigned int day)147 char *DayOfWeek (unsigned int year, unsigned int month, unsigned int day)
148 {
149 static char DayOfWeekChar[10];
150
151 strcpy(DayOfWeekChar,"");
152 switch (GetDayOfWeek(year, month, day)) {
153 case 0: strcpy(DayOfWeekChar,"Sun"); break;
154 case 1: strcpy(DayOfWeekChar,"Mon"); break;
155 case 2: strcpy(DayOfWeekChar,"Tue"); break;
156 case 3: strcpy(DayOfWeekChar,"Wed"); break;
157 case 4: strcpy(DayOfWeekChar,"Thu"); break;
158 case 5: strcpy(DayOfWeekChar,"Fri"); break;
159 case 6: strcpy(DayOfWeekChar,"Sat"); break;
160 }
161 return DayOfWeekChar;
162 }
163
get_local_timezone_offset(time_t posix_time)164 int get_local_timezone_offset(time_t posix_time)
165 {
166 struct tm *tm = gmtime(&posix_time);
167 tm->tm_isdst = -1;
168 return posix_time - mktime(tm);
169 }
170
GSM_GetLocalTimezoneOffset()171 int GSM_GetLocalTimezoneOffset()
172 {
173 return get_local_timezone_offset(time(NULL));
174 }
175
GSM_DateTimeToTimestamp(GSM_DateTime * Date,char * str)176 void GSM_DateTimeToTimestamp(GSM_DateTime *Date, char *str)
177 {
178 time_t timet;
179 timet = Fill_Time_T(*Date);
180 sprintf(str, "%ld", (long)timet);
181 }
182
GSM_DateTimeFromTimestamp(GSM_DateTime * Date,const char * str)183 void GSM_DateTimeFromTimestamp(GSM_DateTime *Date, const char *str)
184 {
185 time_t timet;
186
187 timet = atof(str);
188 Fill_GSM_DateTime(Date, timet);
189 }
190
Fill_GSM_DateTime(GSM_DateTime * Date,time_t timet)191 void Fill_GSM_DateTime(GSM_DateTime *Date, time_t timet)
192 {
193 struct tm *now;
194
195 now = localtime(&timet);
196 Date->Year = now->tm_year + 1900;
197 Date->Month = now->tm_mon + 1;
198 Date->Day = now->tm_mday;
199 Date->Hour = now->tm_hour;
200 Date->Minute = now->tm_min;
201 Date->Second = now->tm_sec;
202 Date->Timezone = GSM_GetLocalTimezoneOffset();
203 }
204
GSM_GetCurrentDateTime(GSM_DateTime * Date)205 void GSM_GetCurrentDateTime (GSM_DateTime *Date)
206 {
207 Fill_GSM_DateTime(Date, time(NULL));
208 }
209
210 /*
211 * Convert GSM_DateTime to POSIX time.
212 *
213 * A GSM timestamp consists of a date and time given in UTC and
214 * an originating local time offset. If the time and date part
215 * of the GSM_DateTime argument is not in UTC the returned
216 * calculated POSIX calendar time will not be valid.
217 */
Fill_Time_T(GSM_DateTime DT)218 time_t Fill_Time_T(GSM_DateTime DT)
219 {
220 char *tz;
221 struct tm tm;
222 time_t posix_time;
223
224 dbgprintf(NULL, "StartTime: %s\n", OSDate(DT));
225
226 memset(&tm, 0, sizeof(tm));
227 tm.tm_year = DT.Year - 1900;
228 tm.tm_mon = DT.Month - 1;
229 tm.tm_mday = DT.Day;
230 tm.tm_hour = DT.Hour;
231 tm.tm_min = DT.Minute;
232 tm.tm_sec = DT.Second;
233 tm.tm_isdst = 0;
234
235 tz = getenv("TZ");
236 if(tz) {
237 tz = strdup(tz);
238 if(!tz)
239 return -1;
240 }
241
242 putenv((char*)"TZ=GMT+00");
243 tzset();
244
245 posix_time = mktime(&tm);
246 if(posix_time != -1)
247 posix_time += DT.Timezone > 0 ? -DT.Timezone : abs(DT.Timezone);
248
249 if(tz) {
250 setenv("TZ", tz, 1);
251 free(tz);
252 }
253 else {
254 unsetenv("TZ");
255 }
256 tzset();
257
258 return posix_time;
259 }
260
GSM_AddTime(GSM_DateTime DT,GSM_DeltaTime delta)261 GSM_DateTime GSM_AddTime (GSM_DateTime DT , GSM_DeltaTime delta)
262 {
263 struct tm tm_time;
264 time_t t_time;
265 GSM_DateTime Date;
266
267 memset(&tm_time, 0, sizeof(tm_time));
268 tm_time.tm_year = DT.Year - 1900;
269 tm_time.tm_mon = DT.Month - 1;
270 tm_time.tm_mday = DT.Day;
271 tm_time.tm_hour = DT.Hour;
272 tm_time.tm_min = DT.Minute;
273 tm_time.tm_sec = DT.Second;
274 tm_time.tm_isdst = -1;
275
276 /* TODO: This works only for dates after 1970. But birthday dates may be before, so a more general
277 method than mktime /localtime should be used. */
278 t_time = mktime (&tm_time);
279 t_time = t_time + delta.Second + 60* (delta.Minute + 60* (delta.Hour + 24*delta.Day));
280
281 Fill_GSM_DateTime ( &Date, t_time);
282 return Date;
283 }
284
GetTimeDifference(unsigned long diff,GSM_DateTime * DT,gboolean Plus,int multi)285 void GetTimeDifference(unsigned long diff, GSM_DateTime *DT, gboolean Plus, int multi)
286 {
287 time_t t_time;
288
289 t_time = Fill_Time_T(*DT);
290
291 if (Plus) {
292 t_time += diff*multi;
293 } else {
294 t_time -= diff*multi;
295 }
296
297 Fill_GSM_DateTime(DT, t_time);
298 dbgprintf(NULL, "EndTime: %02i-%02i-%04i %02i:%02i:%02i\n",
299 DT->Day,DT->Month,DT->Year,DT->Hour,DT->Minute,DT->Second);
300 }
301
OSDateTime(GSM_DateTime dt,gboolean TimeZone)302 char *OSDateTime (GSM_DateTime dt, gboolean TimeZone)
303 {
304 struct tm timeptr;
305 static char retval[200],retval2[200];
306
307 if (!RecalcDateTime(&timeptr, dt.Year, dt.Month, dt.Day,
308 dt.Hour, dt.Minute, dt.Second)) {
309 retval2[0] = '\0';
310 return retval2;
311 }
312
313 #ifdef WIN32
314 setlocale(LC_ALL, ".OCP");
315 #endif
316
317 /* This is not Y2K safe */
318 strftime(retval2, 200, "%c", &timeptr);
319 if (TimeZone) {
320 snprintf(retval, sizeof(retval) - 1, " %+03i%02i",
321 dt.Timezone / 3600, abs((dt.Timezone % 3600) / 60));
322 strcat(retval2,retval);
323 }
324 /* If don't have weekday name, include it */
325 strftime(retval, 200, "%A", &timeptr);
326 if (strstr(retval2,retval)==NULL) {
327 /* Check for abbreviated weekday */
328 strftime(retval, 200, "%a", &timeptr);
329 if (strstr(retval2,retval)==NULL) {
330 strcat(retval2," (");
331 strcat(retval2,retval);
332 strcat(retval2,")");
333 }
334 }
335
336 #ifdef WIN32
337 setlocale(LC_ALL, ".ACP");
338 #endif
339
340 return retval2;
341 }
342
OSDate(GSM_DateTime dt)343 char *OSDate (GSM_DateTime dt)
344 {
345 struct tm timeptr;
346 static char retval[200],retval2[200];
347
348 #ifdef WIN32
349 setlocale(LC_ALL, ".OCP");
350 #endif
351
352 timeptr.tm_yday = 0; /* FIXME */
353 timeptr.tm_isdst = -1; /* FIXME */
354 timeptr.tm_year = dt.Year - 1900;
355 timeptr.tm_mon = dt.Month - 1;
356 timeptr.tm_mday = dt.Day;
357 timeptr.tm_hour = dt.Hour;
358 timeptr.tm_min = dt.Minute;
359 timeptr.tm_sec = dt.Second;
360 timeptr.tm_wday = GetDayOfWeek(dt.Year, dt.Month, dt.Day);
361 #ifdef HAVE_STRUCT_TM_TM_ZONE
362 timeptr.tm_zone = NULL;
363 #endif
364
365 /* This is not Y2K safe */
366 strftime(retval2, 200, "%x", &timeptr);
367
368 /* If don't have weekday name, include it */
369 strftime(retval, 200, "%A", &timeptr);
370 if (strstr(retval2,retval)==NULL) {
371 /* Check also for short name */
372 strftime(retval, 200, "%a", &timeptr);
373 if (strstr(retval2,retval)==NULL) {
374 strcat(retval2," (");
375 strcat(retval2,retval);
376 strcat(retval2,")");
377 }
378 }
379
380 #ifdef WIN32
381 setlocale(LC_ALL, ".ACP");
382 #endif
383
384 return retval2;
385 }
386
CheckDate(GSM_DateTime * date)387 gboolean CheckDate(GSM_DateTime *date)
388 {
389 const int days[]={31,28,31,30,31,30,31,31,30,31,30,31};
390
391 if (date->Year != 0 &&
392 ((date->Year % 4 == 0 && date->Year % 100 != 0) || date->Year % 400 == 0) &&
393 date->Month == 2) {
394 return (date->Day <= 29);
395 }
396 return date->Year != 0 &&
397 date->Month >= 1 && date->Month <= 12 &&
398 date->Day >= 1 && date->Day <= days[date->Month-1];
399 }
400
CheckTime(GSM_DateTime * date)401 gboolean CheckTime(GSM_DateTime *date)
402 {
403 return date->Hour <= 23 &&
404 date->Minute <= 59 &&
405 date->Second <= 59;
406 }
407
GetLine(FILE * File,char * Line,int count)408 size_t GetLine(FILE *File, char *Line, int count)
409 {
410 int num;
411
412 if (fgets(Line, count, File) != NULL) {
413 num = strlen(Line) - 1;
414 while (num > 0) {
415 if (Line[num] != '\n' && Line[num] != '\r') break;
416 Line[num--] = '\0';
417 }
418 return strlen(Line);
419 }
420 return -1;
421 }
422
InitLines(GSM_CutLines * lines)423 void InitLines(GSM_CutLines *lines)
424 {
425 lines->numbers = NULL;
426 lines->allocated = 0;
427 lines->retval = NULL;
428 }
429
FreeLines(GSM_CutLines * lines)430 void FreeLines(GSM_CutLines *lines)
431 {
432 free(lines->numbers);
433 lines->numbers = NULL;
434 lines->allocated = 0;
435 free(lines->retval);
436 lines->retval = NULL;
437 }
438
SplitLines(const char * message,const size_t messagesize,GSM_CutLines * lines,const char * whitespaces,const size_t spaceslen,const char * quotes,const size_t quoteslen,const gboolean eot)439 void SplitLines(const char *message, const size_t messagesize, GSM_CutLines *lines,
440 const char *whitespaces, const size_t spaceslen,
441 const char *quotes, const size_t quoteslen,
442 const gboolean eot)
443 {
444 size_t i=0,number=0,j=0, lastquote = 0;
445 gboolean whitespace = TRUE, nowwhite = FALSE, insidequotes = FALSE;
446
447 /* Clean current lines */
448 for (i = 0; i < lines->allocated; i++) {
449 lines->numbers[i] = 0;
450 }
451
452 /* Go through message */
453 for (i = 0; i < messagesize; i++) {
454 /* Reallocate buffer if needed */
455 if (number + 2 >= lines->allocated) {
456 lines->allocated += 20;
457 lines->numbers = (size_t *)realloc(lines->numbers, lines->allocated * sizeof(size_t));
458 if (lines->numbers == NULL) {
459 return;
460 }
461 for (j = lines->allocated - 20; j < lines->allocated; j++) {
462 lines->numbers[j] = 0;
463 }
464 }
465
466 nowwhite = FALSE;
467
468 /* Check for quotes */
469 for (j = 0; j < quoteslen; j++) {
470 if (quotes[j] == message[i]) {
471 insidequotes = !(insidequotes);
472 lastquote = i;
473 break;
474 }
475 }
476
477 /* Find matching quote */
478 if (insidequotes) {
479 continue;
480 }
481
482 rollback_quote:
483 /* Check for whitespace */
484 for (j = 0; j < spaceslen; j++) {
485 if (whitespaces[j] == message[i]) {
486 nowwhite = TRUE;
487 break;
488 }
489 }
490
491 /* Split line if there is change from whitespace to non whitespace */
492 if (whitespace) {
493 if (!nowwhite) {
494 lines->numbers[number] = i;
495 number++;
496 whitespace = FALSE;
497 }
498 } else {
499 if (nowwhite) {
500 lines->numbers[number] = i;
501 number++;
502 whitespace = TRUE;
503 }
504
505 }
506 }
507
508 /* Check for unterminated quotes and roll back to ignore them */
509 if (number % 2 == 1 && insidequotes) {
510 insidequotes = FALSE;
511 i = lastquote;
512 goto rollback_quote;
513 }
514
515 /* Store possible end if there was not just whitespace */
516 if (eot && !whitespace) {
517 lines->numbers[number] = messagesize;
518 }
519 }
520
GetLineStringPos(const char * message,const GSM_CutLines * lines,int start)521 const char *GetLineStringPos(const char *message, const GSM_CutLines *lines, int start)
522 {
523 if (message == NULL) {
524 return NULL;
525 }
526
527 return message + lines->numbers[start * 2 - 2];
528 }
529
GetLineString(const char * message,GSM_CutLines * lines,int start)530 const char *GetLineString(const char *message, GSM_CutLines *lines, int start)
531 {
532 int len=0;
533 const char *pos;
534
535 pos = GetLineStringPos(message, lines, start);
536 if (pos == NULL) {
537 return NULL;
538 }
539
540 len = GetLineLength(message, lines, start);
541
542 lines->retval = (char *)realloc(lines->retval, len + 1);
543 if (lines->retval == NULL) {
544 dbgprintf(NULL, "Allocation failed!\n");
545 return NULL;
546 }
547
548 memcpy(lines->retval, pos, len);
549
550 lines->retval[len] = '\0';
551
552 return lines->retval;
553 }
554
GetLineLength(const char * message UNUSED,const GSM_CutLines * lines,int start)555 int GetLineLength(const char *message UNUSED, const GSM_CutLines *lines, int start)
556 {
557 return lines->numbers[start*2-2+1] - lines->numbers[start*2-2];
558 }
559
CopyLineString(char * dest,const char * src,const GSM_CutLines * lines,int start)560 void CopyLineString(char *dest, const char *src, const GSM_CutLines *lines, int start)
561 {
562 int len;
563 const char *pos;
564
565 len = GetLineLength(src, lines, start);
566 pos = GetLineStringPos(src, lines, start);
567 if (pos == NULL) {
568 dest[0] = '\0';
569 return;
570 }
571 memcpy(dest, pos, len);
572 dest[len] = '\0';
573 }
574
GetOS(void)575 const char *GetOS(void)
576 {
577 #ifdef WIN32
578 OSVERSIONINFOEX Ver;
579 gboolean Extended = TRUE;
580 #else
581 # ifdef HAVE_SYS_UTSNAME_H
582 struct utsname Ver;
583 # endif
584 #endif
585 static char Buffer[240] = {0x00};
586
587 /* Value was already calculated */
588 if (Buffer[0] != 0) return Buffer;
589
590 #ifdef WIN32
591 memset(&Ver,0,sizeof(OSVERSIONINFOEX));
592 Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
593
594 if (!GetVersionEx((OSVERSIONINFO *)&Ver)) {
595 Extended = FALSE;
596 Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
597 if (!GetVersionEx((OSVERSIONINFO *)&Ver)) {
598 snprintf(Buffer, sizeof(Buffer) - 1, "Windows");
599 return Buffer;
600 }
601 }
602
603 /* ----------------- 9x family ------------------ */
604
605 /* no info about Win95 SP1, Win95 OSR2.1, Win95 OSR2.5.... */
606 if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 950) {
607 snprintf(Buffer, sizeof(Buffer) - 1, "Windows 95");
608 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 1111) {
609 snprintf(Buffer, sizeof(Buffer) - 1, "Windows 95 OSR2.x");
610
611 /* no info about Win98 SP1.... */
612 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 10 && Ver.dwBuildNumber == 1998) {
613 snprintf(Buffer, sizeof(Buffer) - 1, "Windows 98");
614 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 10 && Ver.dwBuildNumber == 2222) {
615 snprintf(Buffer, sizeof(Buffer) - 1, "Windows 98 SE");
616
617 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 90 && Ver.dwBuildNumber == 3000) {
618 snprintf(Buffer, sizeof(Buffer) - 1, "Windows ME");
619
620 /* ---------------- NT family ------------------- */
621
622 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 1381) {
623 snprintf(Buffer, sizeof(Buffer) - 1, "Windows NT 4.0");
624
625 } else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 2195) {
626 snprintf(Buffer, sizeof(Buffer) - 1, "Windows 2000");
627
628 } else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 1 && Ver.dwBuildNumber == 2600) {
629 snprintf(Buffer, sizeof(Buffer) - 1, "Windows XP");
630 #if _MSC_VER > 1200 /* 6.0 has it undeclared */
631 if (Extended) {
632 if (Ver.wSuiteMask & VER_SUITE_PERSONAL) {
633 snprintf(Buffer+strlen(Buffer), sizeof(Buffer) - 1 - strlen(Buffer)," Home");
634 } else {
635 snprintf(Buffer+strlen(Buffer), sizeof(Buffer) - 1 - strlen(Buffer)," Pro");
636 }
637 }
638 #endif
639
640 } else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 2) {
641 snprintf(Buffer, sizeof(Buffer) - 1, "Windows 2003");
642
643 } else if (Ver.dwMajorVersion == 6 && Ver.dwMinorVersion == 0) {
644 snprintf(Buffer, sizeof(Buffer) - 1, "Windows Vista");
645
646 } else if (Ver.dwMajorVersion == 6 && Ver.dwMinorVersion > 0) {
647 snprintf(Buffer, sizeof(Buffer) - 1, "Windows Server 2007");
648
649 } else {
650 snprintf(Buffer, sizeof(Buffer) - 1, "Windows %i.%i.%i",(int)Ver.dwMajorVersion,(int)Ver.dwMinorVersion,(int)Ver.dwBuildNumber);
651 }
652
653 if (Extended && Ver.wServicePackMajor != 0) {
654 snprintf(Buffer+strlen(Buffer), sizeof(Buffer) - 1 - strlen(Buffer)," SP%i",Ver.wServicePackMajor);
655 }
656 #elif defined(HAVE_SYS_UTSNAME_H)
657 uname(&Ver);
658 snprintf(Buffer, sizeof(Buffer) - 1, "%s, kernel %s (%s)", Ver.sysname, Ver.release, Ver.version);
659 #elif defined(__FreeBSD__)
660 snprintf(Buffer, sizeof(Buffer) - 1, "FreeBSD");
661 #elif defined(__NetBSD__)
662 snprintf(Buffer, sizeof(Buffer) - 1, "NetBSD");
663 #elif defined(__OpenBSD__)
664 snprintf(Buffer, sizeof(Buffer) - 1, "OpenBSD");
665 #elif defined(__GNU__)
666 snprintf(Buffer, sizeof(Buffer) - 1, "GNU/Hurd");
667 #elif defined(sun) || defined(__sun) || defined(__sun__)
668 # ifdef __SVR4
669 snprintf(Buffer, sizeof(Buffer) - 1, "Sun Solaris");
670 # else
671 snprintf(Buffer, sizeof(Buffer) - 1, "SunOS");
672 # endif
673 #elif defined(hpux) || defined(__hpux) || defined(__hpux__)
674 snprintf(Buffer, sizeof(Buffer) - 1, "HP-UX");
675 #elif defined(ultrix) || defined(__ultrix) || defined(__ultrix__)
676 snprintf(Buffer, sizeof(Buffer) - 1, "DEC Ultrix");
677 #elif defined(sgi) || defined(__sgi)
678 snprintf(Buffer, sizeof(Buffer) - 1, "SGI Irix");
679 #elif defined(__osf__)
680 snprintf(Buffer, sizeof(Buffer) - 1, "OSF Unix");
681 #elif defined(bsdi) || defined(__bsdi__)
682 snprintf(Buffer, sizeof(Buffer) - 1, "BSDI Unix");
683 #elif defined(_AIX)
684 snprintf(Buffer, sizeof(Buffer) - 1, "AIX Unix");
685 #elif defined(_UNIXWARE)
686 snprintf(Buffer, sizeof(Buffer) - 1, "SCO Unixware");
687 #elif defined(DGUX)
688 snprintf(Buffer, sizeof(Buffer) - 1, "DG Unix");
689 #elif defined(__QNX__)
690 snprintf(Buffer, sizeof(Buffer) - 1, "QNX");
691 #else
692 snprintf(Buffer, sizeof(Buffer) - 1, "unknown OS");
693 #endif
694 return Buffer;
695 }
696
GetCompiler(void)697 const char *GetCompiler(void)
698 {
699 static char Buffer[100] = {0x00};
700
701 /* Value was already calculated */
702 if (Buffer[0] != 0) return Buffer;
703
704 #ifdef _MSC_VER
705 if (_MSC_VER == 1200) { /* ? */
706 snprintf(Buffer, sizeof(Buffer) - 1, "MS VC 6.0");
707 } else if (_MSC_VER == 1300) {
708 snprintf(Buffer, sizeof(Buffer) - 1, "MS VC .NET 2002");
709 } else if (_MSC_VER == 1310) {
710 snprintf(Buffer, sizeof(Buffer) - 1, "MS VC .NET 2003");
711 } else if (_MSC_VER == 1400) {
712 snprintf(Buffer, sizeof(Buffer) - 1, "MS VC .NET 2005");
713 } else {
714 snprintf(Buffer, sizeof(Buffer) - 1, "MS VC %i",_MSC_VER);
715 }
716 #elif defined(__BORLANDC__)
717 snprintf(Buffer, sizeof(Buffer) - 1, "Borland C++ %i",__BORLANDC__);
718 #elif defined(__MINGW32__)
719 snprintf(Buffer, sizeof(Buffer) - 1, "GCC %i.%i, MinGW %i.%i", __GNUC__, __GNUC_MINOR__, __MINGW32_MAJOR_VERSION, __MINGW32_MINOR_VERSION);
720 #elif defined(__CYGWIN__)
721 snprintf(Buffer, sizeof(Buffer) - 1, "GCC %i.%i, Cygwin %i.%i", __GNUC__, __GNUC_MINOR__, CYGWIN_VERSION_DLL_MAJOR, CYGWIN_VERSION_DLL_MINOR);
722 #elif defined(__GNUC__)
723 snprintf(Buffer, sizeof(Buffer) - 1, "GCC %i.%i", __GNUC__, __GNUC_MINOR__);
724 #elif defined(DJGPP)
725 snprintf(Buffer, sizeof(Buffer) - 1, "djgpp %d.%d", __DJGPP, __DJGPP_MINOR);
726 #elif defined(__SUNPRO_CC)
727 snprintf(Buffer, sizeof(Buffer) - 1, "Sun C++ %x", __SUNPRO_CC);
728 #elif defined(__INTEL_COMPILER)
729 snprintf(Buffer, sizeof(Buffer) - 1, "Intel Compiler %ld", __INTEL_COMPILER);
730 #else
731 snprintf(Buffer, sizeof(Buffer) - 1, "unknown compiler");
732 #endif
733
734 return Buffer;
735 }
736
GSM_IsNewerVersion(const char * latest_version,const char * current_version)737 gboolean GSM_IsNewerVersion(const char *latest_version, const char *current_version)
738 {
739 size_t i;
740 size_t len = strlen(latest_version);
741
742 for (i = 0; i < len ; i++) {
743 if (latest_version[i] > current_version[i]) {
744 return TRUE;
745 }
746 }
747
748 return FALSE;
749 }
750
StripSpaces(char * buff)751 void StripSpaces(char *buff)
752 {
753 ssize_t i = 0;
754
755 while(isspace(buff[i])) {
756 i++;
757 }
758 if (i > 0) {
759 memmove(buff, buff + i, strlen(buff + i));
760 }
761 i = strlen(buff) - 1;
762 while(isspace(buff[i]) && i >= 0) {
763 buff[i] = 0;
764 i--;
765 }
766
767 }
768
769 /* How should editor hadle tabs in this file? Add editor commands here.
770 * vim: noexpandtab sw=8 ts=8 sts=8:
771 */
772