summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/misc/misc.c
Unidiff
Diffstat (limited to 'gammu/emb/common/misc/misc.c') (more/less context) (show whitespace changes)
-rw-r--r--gammu/emb/common/misc/misc.c591
1 files changed, 591 insertions, 0 deletions
diff --git a/gammu/emb/common/misc/misc.c b/gammu/emb/common/misc/misc.c
new file mode 100644
index 0000000..c2f09e4
--- a/dev/null
+++ b/gammu/emb/common/misc/misc.c
@@ -0,0 +1,591 @@
1/* (c) 2002-2004 by Marcin Wiacek and Michal Cihar */
2/* Checking used compiler (c) 2002 by Michal Cihar */
3
4#include <string.h>
5#include <ctype.h>
6#include <time.h>
7#include <stdarg.h>
8#include <stdio.h>
9#include <locale.h>
10#include <sys/timeb.h>
11#ifdef WIN32
12# include "windows.h"
13#endif
14
15#include "../gsmstate.h"
16#include "misc.h"
17
18/* Based on article in Polish PC-Kurier 8/1998 page 104
19 * Archive on http://www.pckurier.pl
20 */
21char *DayOfWeek (int year, int month, int day)
22{
23 int p,q,r,w;
24 static char DayOfWeekChar[10];
25
26 p=(14-month) / 12;
27 q=month+12*p-2;
28 r=year-p;
29 w=(day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7;
30 strcpy(DayOfWeekChar,"");
31 switch (w) {
32 case 0: strcpy(DayOfWeekChar,"Sun"); break;
33 case 1: strcpy(DayOfWeekChar,"Mon"); break;
34 case 2: strcpy(DayOfWeekChar,"Tue"); break;
35 case 3: strcpy(DayOfWeekChar,"Wed"); break;
36 case 4: strcpy(DayOfWeekChar,"Thu"); break;
37 case 5: strcpy(DayOfWeekChar,"Fri"); break;
38 case 6: strcpy(DayOfWeekChar,"Sat"); break;
39 }
40 return DayOfWeekChar;
41}
42
43void Fill_GSM_DateTime(GSM_DateTime *Date, time_t timet)
44{
45 struct tm *now;
46
47 now = localtime(&timet);
48 Date->Year= now->tm_year;
49 Date->Month= now->tm_mon+1;
50 Date->Day= now->tm_mday;
51 Date->Hour= now->tm_hour;
52 Date->Minute= now->tm_min;
53 Date->Second = now->tm_sec;
54}
55
56void GSM_GetCurrentDateTime (GSM_DateTime *Date)
57{
58 Fill_GSM_DateTime(Date, time(NULL));
59 if (Date->Year<1900) {
60 if (Date->Year>90) Date->Year = Date->Year+1900;
61 else Date->Year = Date->Year+2000;
62 }
63}
64
65time_t Fill_Time_T(GSM_DateTime DT, int TZ)
66{
67 struct tm tm_starttime;
68 unsigned char buffer[30];
69
70 dbgprintf(" StartTime : %02i-%02i-%04i %02i:%02i:%02i\n",
71 DT.Day,DT.Month,DT.Year,DT.Hour,DT.Minute,DT.Second);
72
73 if (TZ != 0) {
74#if defined(WIN32) || defined(__SVR4)
75 sprintf(buffer,"TZ=PST+%i",TZ);
76 putenv(buffer);
77#else
78 sprintf(buffer,"PST+%i",TZ);
79 setenv("TZ",buffer,1);
80#endif
81 }
82 tzset();
83
84 memset(&tm_starttime, 0, sizeof(tm_starttime));
85 tm_starttime.tm_year = DT.Year - 1900;
86 tm_starttime.tm_mon = DT.Month - 1;
87 tm_starttime.tm_mday = DT.Day;
88 tm_starttime.tm_hour = DT.Hour;
89 tm_starttime.tm_min = DT.Minute;
90 tm_starttime.tm_sec = DT.Second;
91 tm_starttime.tm_isdst= 0;
92
93 return mktime(&tm_starttime);
94}
95
96void GetTimeDifference(unsigned long diff, GSM_DateTime *DT, bool Plus, int multi)
97{
98 time_t t_time;
99
100 t_time = Fill_Time_T(*DT,8);
101
102 if (Plus) {
103 t_time += diff*multi;
104 } else {
105 t_time -= diff*multi;
106 }
107
108 Fill_GSM_DateTime(DT, t_time);
109 DT->Year = DT->Year + 1900;
110 dbgprintf(" EndTime : %02i-%02i-%04i %02i:%02i:%02i\n",
111 DT->Day,DT->Month,DT->Year,DT->Hour,DT->Minute,DT->Second);
112}
113
114char *OSDateTime (GSM_DateTime dt, bool TimeZone)
115{
116 struct tm timeptr;
117 static char retval[200],retval2[200];
118 int p,q,r,w;
119
120#ifdef WIN32
121 setlocale(LC_ALL, ".OCP");
122#endif
123
124 /* Based on article in Polish PC-Kurier 8/1998 page 104
125 * Archive on http://www.pckurier.pl
126 */
127 p=(14-dt.Month) / 12;
128 q=dt.Month+12*p-2;
129 r=dt.Year-p;
130 w=(dt.Day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7;
131
132 timeptr.tm_yday = 0; /* FIXME */
133 timeptr.tm_isdst = -1; /* FIXME */
134 timeptr.tm_year = dt.Year - 1900;
135 timeptr.tm_mon = dt.Month - 1;
136 timeptr.tm_mday = dt.Day;
137 timeptr.tm_hour = dt.Hour;
138 timeptr.tm_min = dt.Minute;
139 timeptr.tm_sec = dt.Second;
140 timeptr.tm_wday = w;
141#ifdef _BSD_SOURCE
142 timeptr.tm_zone = NULL;
143#endif
144
145#ifdef WIN32
146 strftime(retval2, 200, "%#c", &timeptr);
147#else
148 strftime(retval2, 200, "%c", &timeptr);
149#endif
150 if (TimeZone) {
151 if (dt.Timezone >= 0) {
152 sprintf(retval," +%02i00",dt.Timezone);
153 } else {
154 sprintf(retval," -%02i00",dt.Timezone);
155 }
156 strcat(retval2,retval);
157 }
158 /* If don't have weekday name, include it */
159 strftime(retval, 200, "%A", &timeptr);
160 if (strstr(retval2,retval)==NULL) {
161 /* Check for abbreviated weekday */
162 strftime(retval, 200, "%a", &timeptr);
163 if (strstr(retval2,retval)==NULL) {
164 strcat(retval2," (");
165 strcat(retval2,retval);
166 strcat(retval2,")");
167 }
168 }
169
170#ifdef WIN32
171 setlocale(LC_ALL, ".ACP");
172#endif
173
174 return retval2;
175}
176
177char *OSDate (GSM_DateTime dt)
178{
179 struct tm timeptr;
180 static char retval[200],retval2[200];
181 int p,q,r,w;
182
183#ifdef WIN32
184 setlocale(LC_ALL, ".OCP");
185#endif
186
187 /* Based on article in Polish PC-Kurier 8/1998 page 104
188 * Archive on http://www.pckurier.pl
189 */
190 p=(14-dt.Month) / 12;
191 q=dt.Month+12*p-2;
192 r=dt.Year-p;
193 w=(dt.Day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7;
194
195 timeptr.tm_yday = 0; /* FIXME */
196 timeptr.tm_isdst = -1; /* FIXME */
197 timeptr.tm_year = dt.Year - 1900;
198 timeptr.tm_mon = dt.Month - 1;
199 timeptr.tm_mday = dt.Day;
200 timeptr.tm_hour = dt.Hour;
201 timeptr.tm_min = dt.Minute;
202 timeptr.tm_sec = dt.Second;
203 timeptr.tm_wday = w;
204#ifdef _BSD_SOURCE
205 timeptr.tm_zone = NULL;
206#endif
207
208#ifdef WIN32
209 strftime(retval2, 200, "%#x", &timeptr);
210#else
211 strftime(retval2, 200, "%x", &timeptr);
212#endif
213 /* If don't have weekday name, include it */
214 strftime(retval, 200, "%A", &timeptr);
215 if (strstr(retval2,retval)==NULL) {
216 /* Check also for short name */
217 strftime(retval, 200, "%a", &timeptr);
218 if (strstr(retval2,retval)==NULL) {
219 strcat(retval2," (");
220 strcat(retval2,retval);
221 strcat(retval2,")");
222 }
223 }
224
225#ifdef WIN32
226 setlocale(LC_ALL, ".ACP");
227#endif
228
229 return retval2;
230}
231
232bool CheckDate(GSM_DateTime *date)
233{
234 /* FIXME: This could also check if day is correct for selected month */
235 return date->Year != 0 &&
236 date->Month >= 1 && date->Month <= 12 &&
237 date->Day >= 1 && date->Day <= 31;
238}
239
240bool CheckTime(GSM_DateTime *date)
241{
242 return date->Hour <= 23 && date->Hour >= 0 &&
243 date->Minute <= 59 && date->Minute >= 0 &&
244 date->Second <= 59 && date->Second >= 0;
245}
246
247int GetLine(FILE *File, char *Line, int count)
248{
249 int num;
250
251 if (fgets(Line, count, File) != NULL) {
252 num = strlen(Line) - 1;
253 while(1) {
254 if (Line[num] != '\n' && Line[num] != '\r') break;
255 if (num == 0) break;
256 Line[num--] = 0;
257 }
258 return strlen(Line);
259 }
260 return -1;
261}
262
263void SplitLines(unsigned char *message, int messagesize, GSM_Lines *lines, unsigned char *whitespaces, int spaceslen, bool eot)
264{
265 int i,number=0,j;
266 bool whitespace=true, nowwhite;
267
268 for (i=0;i<MAX_LINES*2;i++) lines->numbers[i]=0;
269
270 for (i=0;i<messagesize;i++) {
271 nowwhite = false;
272 for (j=0;j<spaceslen;j++) {
273 if (whitespaces[j] == message[i]) {
274 nowwhite = true;
275 break;
276 }
277 }
278 if (whitespace) {
279 if (!nowwhite) {
280 lines->numbers[number]=i;
281 number++;
282 whitespace=false;
283 }
284 } else {
285 if (nowwhite) {
286 lines->numbers[number]=i;
287 number++;
288 whitespace=true;
289 }
290
291 }
292 }
293 if (eot && !whitespace) lines->numbers[number]=messagesize;
294}
295
296char *GetLineString(unsigned char *message, GSM_Lines lines, int start)
297{
298 static char retval[800];
299
300 memcpy(retval,message + lines.numbers[start*2-2],lines.numbers[start*2-2+1]-lines.numbers[start*2-2]);
301 retval[lines.numbers[start*2-2+1]-lines.numbers[start*2-2]]=0;
302
303 return retval;
304}
305
306void CopyLineString(unsigned char *dest, unsigned char *src, GSM_Lines lines, int start)
307{
308 memcpy(dest,GetLineString(src, lines, start),strlen(GetLineString(src, lines, start)));
309 dest[strlen(GetLineString(src, lines, start))] = 0;
310}
311
312Debug_Info di = {0,NULL,false,""};
313
314#ifdef DEBUG
315#ifdef __GNUC__
316__attribute__((format(printf, 1, 2)))
317#endif
318int dbgprintf(const char *format, ...)
319{
320 va_list argp;
321 int result;
322 static unsigned char nextline[2000]="";
323 unsigned char buffer[2000];
324 GSM_DateTime date_time;
325
326 if (di.df != NULL && (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE)) {
327 va_start(argp, format);
328 result = vsprintf(buffer, format, argp);
329 strcat(nextline, buffer);
330 if (strstr(buffer, "\n")) {
331 if (di.dl == DL_TEXTALLDATE) {
332 GSM_GetCurrentDateTime(&date_time);
333 fprintf(di.df,"%s %4d/%02d/%02d %02d:%02d:%02d: %s",
334 DayOfWeek(date_time.Year, date_time.Month, date_time.Day),
335 date_time.Year, date_time.Month, date_time.Day,
336 date_time.Hour, date_time.Minute, date_time.Second,nextline);
337 } else {
338 fprintf(di.df,"%s",nextline);
339 }
340 strcpy(nextline, "");
341 }
342 fflush(di.df);
343 va_end(argp);
344 return result;
345 }
346 return 0;
347}
348#endif
349
350/* assumption: if \n is present it is always the last char,
351 * string never of the form "......\n..."
352 */
353#ifdef __GNUC__
354__attribute__((format(printf, 3, 4)))
355#endif
356int smfprintf(FILE *f, Debug_Level dl, const char *format, ...)
357{
358 va_list argp;
359 int result=0;
360 static unsigned char prevline[2000] = "", nextline[2000]="";
361 static unsigned int linecount=0;
362 unsigned char buffer[2000];
363 GSM_DateTime date_time;
364
365 if (f == NULL) return 0;
366 va_start(argp, format);
367 result = vsprintf(buffer, format, argp);
368 strcat(nextline, buffer);
369 if (strstr(buffer, "\n")) {
370 if (ftell(f) < 5000000) {
371 GSM_GetCurrentDateTime(&date_time);
372 if (linecount > 0) {
373 if (dl == DL_TEXTALLDATE || dl == DL_TEXTERRORDATE || dl == DL_TEXTDATE) {
374 fprintf(f,"%s %4d/%02d/%02d %02d:%02d:%02d: <%i> %s",
375 DayOfWeek(date_time.Year, date_time.Month, date_time.Day),
376 date_time.Year, date_time.Month, date_time.Day,
377 date_time.Hour, date_time.Minute, date_time.Second,linecount,prevline);
378 } else {
379 fprintf(f,"%s",prevline);
380 }
381 }
382 linecount=0;
383 if (dl == DL_TEXTALLDATE || dl == DL_TEXTERRORDATE || dl == DL_TEXTDATE) {
384 fprintf(f,"%s %4d/%02d/%02d %02d:%02d:%02d: %s",
385 DayOfWeek(date_time.Year, date_time.Month, date_time.Day),
386 date_time.Year, date_time.Month, date_time.Day,
387 date_time.Hour, date_time.Minute, date_time.Second,nextline);
388 } else {
389 fprintf(f,"%s",nextline);
390 }
391 strcpy(prevline, nextline);
392 }
393 strcpy(nextline, "");
394 fflush(f);
395 }
396 va_end(argp);
397 return result;
398}
399
400bool GSM_SetDebugLevel(char *info, Debug_Info *di)
401{
402 if (!strcmp(info,"nothing")) {di->dl = 0; return true;}
403 if (!strcmp(info,"text")) {di->dl = DL_TEXT; return true;}
404 if (!strcmp(info,"textall")) {di->dl = DL_TEXTALL; return true;}
405 if (!strcmp(info,"binary")) {di->dl = DL_BINARY; return true;}
406 if (!strcmp(info,"errors")) {di->dl = DL_TEXTERROR; return true;}
407 if (!strcmp(info,"textdate")) {di->dl = DL_TEXTDATE; return true;}
408 if (!strcmp(info,"textalldate")) {di->dl = DL_TEXTALLDATE; return true;}
409 if (!strcmp(info,"errorsdate")) {di->dl = DL_TEXTERRORDATE; return true;}
410 return false;
411}
412
413/* Dumps a message */
414void DumpMessage(FILE *df, Debug_Level dl, const unsigned char *message, int messagesize)
415{
416 int i,j=0,len=16;
417 unsigned charbuffer[200];
418
419 if (df==NULL || messagesize == 0) return;
420
421 smfprintf(df, dl, "\n");
422
423 memset(buffer,0x20,sizeof(buffer));
424 buffer[len*5-1]=0;
425
426 for (i = 0; i < messagesize; i++) {
427 sprintf(buffer+j*4,"%02X",message[i]);
428 buffer[j*4+2] = 0x20;
429 if (isprint(message[i]) && message[i]!=0x09) {
430 if (j != len-1) buffer[j*4+2] = message[i];
431 buffer[(len-1)*4+j+3] = message[i];
432 } else {
433 buffer[(len-1)*4+j+3] = '.';
434 }
435 if (j != len-1 && i != messagesize-1) buffer[j*4+3] = '|';
436 if (j == len-1) {
437 smfprintf(df, dl, "%s\n", buffer);
438 memset(buffer,0x20,sizeof(buffer));
439 buffer[len*5-1]=0;
440 j = 0;
441 } else {
442 j++;
443 }
444 }
445 if (j != 0) smfprintf(df, dl, "%s\n", buffer);
446}
447
448char *GetOS(void)
449{
450#ifdef WIN32
451 OSVERSIONINFOEX Ver;
452 bool Extended = true;
453#endif
454 static char Buffer[100] = {0x00};
455
456#ifdef WIN32
457 memset(&Ver,sizeof(OSVERSIONINFOEX),0);
458 Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
459
460 if (!GetVersionEx((OSVERSIONINFO *)&Ver)) {
461 Extended = false;
462 Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
463 if (!GetVersionEx((OSVERSIONINFO *)&Ver)) {
464//#ifdef _MSC_VER
465 // Ver.dwMajorVersion = _winmajor;
466 // Ver.dwMinorVersion = _winminor;
467 // Ver.dwBuildNumber = _osver;
468//#else
469 sprintf(Buffer, "Windows");
470 return Buffer;
471//#endif
472 }
473 }
474
475 /* ----------------- 9x family ------------------ */
476
477 /* no info about Win95 SP1, Win95 OSR2.1, Win95 OSR2.5.... */
478 if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 950) {
479 sprintf(Buffer,"Win 95");
480 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 1111) {
481 sprintf(Buffer,"Win 95 OSR2.x");
482
483 /* no info about Win98 SP1.... */
484 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 10 && Ver.dwBuildNumber == 1998) {
485 sprintf(Buffer,"Win 98");
486 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 10 && Ver.dwBuildNumber == 2222) {
487 sprintf(Buffer,"Win 98 SE");
488
489 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 90 && Ver.dwBuildNumber == 3000) {
490 sprintf(Buffer,"Win ME");
491
492 /* ---------------- NT family ------------------- */
493
494 } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 1381) {
495 sprintf(Buffer,"Win NT 4.0");
496
497 } else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 2195) {
498 sprintf(Buffer,"Win 2000");
499
500 } else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 1 && Ver.dwBuildNumber == 2600) {
501 sprintf(Buffer,"Win XP");
502#if _MSC_VER > 1200 //6.0 has it undeclared
503 if (Extended) {
504 if (Ver.wSuiteMask & VER_SUITE_PERSONAL) {
505 sprintf(Buffer+strlen(Buffer)," Home");
506 } else {
507 sprintf(Buffer+strlen(Buffer)," Pro");
508 }
509 }
510#endif
511
512 } else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 2) {
513 sprintf(Buffer,"Win 2003");
514
515 } else {
516 sprintf(Buffer, "Windows %i.%i.%i",Ver.dwMajorVersion,Ver.dwMinorVersion,Ver.dwBuildNumber);
517 }
518
519 if (Extended && Ver.wServicePackMajor != 0) {
520 sprintf(Buffer+strlen(Buffer)," SP%i",Ver.wServicePackMajor);
521 }
522#elif defined(linux) || defined(__linux) || defined(__linux__)
523 sprintf(Buffer, "Linux");
524#elif defined(__FreeBSD__)
525 sprintf(Buffer, "FreeBSD");
526#elif defined(__NetBSD__)
527 sprintf(Buffer, "NetBSD");
528#elif defined(__OpenBSD__)
529 sprintf(Buffer, "OpenBSD");
530#elif defined(__GNU__)
531 sprintf(Buffer, "GNU/Hurd");
532#elif defined(sun) || defined(__sun) || defined(__sun__)
533# ifdef __SVR4
534 sprintf(Buffer, "Sun Solaris");
535# else
536 sprintf(Buffer, "SunOS");
537# endif
538#elif defined(hpux) || defined(__hpux) || defined(__hpux__)
539 sprintf(Buffer, "HP-UX");
540#elif defined(ultrix) || defined(__ultrix) || defined(__ultrix__)
541 sprintf(Buffer, "DEC Ultrix");
542#elif defined(sgi) || defined(__sgi)
543 sprintf(Buffer, "SGI Irix");
544#elif defined(__osf__)
545 sprintf(Buffer, "OSF Unix");
546#elif defined(bsdi) || defined(__bsdi__)
547 sprintf(Buffer, "BSDI Unix");
548#elif defined(_AIX)
549 sprintf(Buffer, "AIX Unix");
550#elif defined(_UNIXWARE)
551 sprintf(Buffer, "SCO Unixware");
552#elif defined(DGUX)
553 sprintf(Buffer, "DG Unix");
554#elif defined(__QNX__)
555 sprintf(Buffer, "QNX");
556#endif
557 return Buffer;
558}
559
560char *GetCompiler(void)
561{
562 static char Buffer[100] = {0x00};
563
564#ifdef WIN32
565# ifdef _MSC_VER
566 if (_MSC_VER == 1200) { //?
567 sprintf(Buffer, "MS VC 6.0");
568 } else if (_MSC_VER == 1300) {
569 sprintf(Buffer, "MS VC .NET 2002");
570 } else if (_MSC_VER == 1310) {
571 sprintf(Buffer, "MS VC .NET 2003");
572 } else {
573 sprintf(Buffer, "MS VC %i",_MSC_VER);
574 }
575# elif defined(__BORLANDC__)
576 sprintf(Buffer, "Borland C++ %i",__BORLANDC__);
577# endif
578#elif defined(DJGPP)
579 sprintf(Buffer, "djgpp");
580#elif defined(__GNUC__)
581 sprintf(Buffer, "gcc %i.%i", __GNUC__, __GNUC_MINOR__);
582#elif defined(__SUNPRO_CC)
583 sprintf(Buffer, "Sun C++ %x", __SUNPRO_CC);
584#endif
585
586 return Buffer;
587}
588
589/* How should editor hadle tabs in this file? Add editor commands here.
590 * vim: noexpandtab sw=8 ts=8 sts=8:
591 */