Imported gammu 0.90.7
[gammu.git] / common / misc / misc.c
blob2535d7fa118ac3f3ce6fab6ba221ef2153e9500b
2 #include <string.h>
3 #include <ctype.h>
4 #include <time.h>
5 #include <stdarg.h>
6 #include <stdio.h>
7 #include <locale.h>
8 #include <sys/timeb.h>
9 #ifdef WIN32
10 # include "windows.h"
11 #endif
13 #include "../gsmstate.h"
14 #include "misc.h"
16 /* Based on article in Polish PC-Kurier 8/1998 page 104
17 * Archive on http://www.pckurier.pl
19 char *DayOfWeek (int year, int month, int day)
21 int p,q,r,w;
22 static char DayOfWeekChar[10];
24 p=(14-month) / 12;
25 q=month+12*p-2;
26 r=year-p;
27 w=(day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7;
28 strcpy(DayOfWeekChar,"");
29 switch (w) {
30 case 0: strcpy(DayOfWeekChar,"Sun"); break;
31 case 1: strcpy(DayOfWeekChar,"Mon"); break;
32 case 2: strcpy(DayOfWeekChar,"Tue"); break;
33 case 3: strcpy(DayOfWeekChar,"Wed"); break;
34 case 4: strcpy(DayOfWeekChar,"Thu"); break;
35 case 5: strcpy(DayOfWeekChar,"Fri"); break;
36 case 6: strcpy(DayOfWeekChar,"Sat"); break;
38 return DayOfWeekChar;
41 void Fill_GSM_DateTime(GSM_DateTime *Date, time_t timet)
43 struct tm *now;
45 now = localtime(&timet);
46 Date->Year = now->tm_year;
47 Date->Month = now->tm_mon+1;
48 Date->Day = now->tm_mday;
49 Date->Hour = now->tm_hour;
50 Date->Minute = now->tm_min;
51 Date->Second = now->tm_sec;
54 void GSM_GetCurrentDateTime (GSM_DateTime *Date)
56 Fill_GSM_DateTime(Date, time(NULL));
57 if (Date->Year<1900)
59 if (Date->Year>90) Date->Year = Date->Year+1900;
60 else Date->Year = Date->Year+2000;
64 time_t Fill_Time_T(GSM_DateTime DT, int TZ)
66 struct tm tm_starttime;
67 unsigned char buffer[30];
69 dbgprintf(" StartTime : %02i-%02i-%04i %02i:%02i:%02i\n",
70 DT.Day,DT.Month,DT.Year,DT.Hour,DT.Minute,DT.Second);
72 if (TZ != 0) {
73 #if defined(WIN32) || defined(__SVR4)
74 sprintf(buffer,"TZ=PST+%i",TZ);
75 putenv(buffer);
76 #else
77 sprintf(buffer,"PST+%i",TZ);
78 setenv("TZ",buffer,1);
79 #endif
81 tzset();
83 memset(&tm_starttime, 0, sizeof(tm_starttime));
84 tm_starttime.tm_year = DT.Year - 1900;
85 tm_starttime.tm_mon = DT.Month - 1;
86 tm_starttime.tm_mday = DT.Day;
87 tm_starttime.tm_hour = DT.Hour;
88 tm_starttime.tm_min = DT.Minute;
89 tm_starttime.tm_sec = DT.Second;
90 tm_starttime.tm_isdst = 0;
92 return mktime(&tm_starttime);
95 void GetTimeDifference(unsigned long diff, GSM_DateTime *DT, bool Plus, int multi)
97 time_t t_time;
99 t_time = Fill_Time_T(*DT,8);
101 if (Plus) {
102 t_time += diff*multi;
103 } else {
104 t_time -= diff*multi;
107 Fill_GSM_DateTime(DT, t_time);
108 DT->Year = DT->Year + 1900;
109 dbgprintf(" EndTime : %02i-%02i-%04i %02i:%02i:%02i\n",
110 DT->Day,DT->Month,DT->Year,DT->Hour,DT->Minute,DT->Second);
113 char *OSDateTime (GSM_DateTime dt, bool TimeZone)
115 struct tm timeptr;
116 static char retval[200],retval2[200];
117 int p,q,r,w;
119 #ifdef WIN32
120 setlocale(LC_ALL, ".OCP");
121 #endif
123 /* Based on article in Polish PC-Kurier 8/1998 page 104
124 * Archive on http://www.pckurier.pl
126 p=(14-dt.Month) / 12;
127 q=dt.Month+12*p-2;
128 r=dt.Year-p;
129 w=(dt.Day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7;
131 timeptr.tm_yday = 0; /* FIXME */
132 timeptr.tm_isdst = -1; /* FIXME */
133 timeptr.tm_year = dt.Year - 1900;
134 timeptr.tm_mon = dt.Month - 1;
135 timeptr.tm_mday = dt.Day;
136 timeptr.tm_hour = dt.Hour;
137 timeptr.tm_min = dt.Minute;
138 timeptr.tm_sec = dt.Second;
139 timeptr.tm_wday = w;
140 #ifdef _BSD_SOURCE
141 timeptr.tm_zone = NULL;
142 #endif
144 #ifdef WIN32
145 strftime(retval2, 200, "%#c", &timeptr);
146 #else
147 strftime(retval2, 200, "%c", &timeptr);
148 #endif
149 if (TimeZone) {
150 if (dt.Timezone >= 0) {
151 sprintf(retval," +%02i00",dt.Timezone);
152 } else {
153 sprintf(retval," -%02i00",dt.Timezone);
155 strcat(retval2,retval);
157 /* If don't have weekday name, include it */
158 strftime(retval, 200, "%A", &timeptr);
159 if (strstr(retval2,retval)==NULL) {
160 /* Check for abbreviated weekday */
161 strftime(retval, 200, "%a", &timeptr);
162 if (strstr(retval2,retval)==NULL) {
163 strcat(retval2," (");
164 strcat(retval2,retval);
165 strcat(retval2,")");
169 #ifdef WIN32
170 setlocale(LC_ALL, ".ACP");
171 #endif
173 return retval2;
176 char *OSDate (GSM_DateTime dt)
178 struct tm timeptr;
179 static char retval[200],retval2[200];
180 int p,q,r,w;
182 #ifdef WIN32
183 setlocale(LC_ALL, ".OCP");
184 #endif
186 /* Based on article in Polish PC-Kurier 8/1998 page 104
187 * Archive on http://www.pckurier.pl
189 p=(14-dt.Month) / 12;
190 q=dt.Month+12*p-2;
191 r=dt.Year-p;
192 w=(dt.Day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7;
194 timeptr.tm_yday = 0; /* FIXME */
195 timeptr.tm_isdst = -1; /* FIXME */
196 timeptr.tm_year = dt.Year - 1900;
197 timeptr.tm_mon = dt.Month - 1;
198 timeptr.tm_mday = dt.Day;
199 timeptr.tm_hour = dt.Hour;
200 timeptr.tm_min = dt.Minute;
201 timeptr.tm_sec = dt.Second;
202 timeptr.tm_wday = w;
203 #ifdef _BSD_SOURCE
204 timeptr.tm_zone = NULL;
205 #endif
207 #ifdef WIN32
208 strftime(retval2, 200, "%#x", &timeptr);
209 #else
210 strftime(retval2, 200, "%x", &timeptr);
211 #endif
212 /* If don't have weekday name, include it */
213 strftime(retval, 200, "%A", &timeptr);
214 if (strstr(retval2,retval)==NULL) {
215 /* Check also for short name */
216 strftime(retval, 200, "%a", &timeptr);
217 if (strstr(retval2,retval)==NULL) {
218 strcat(retval2," (");
219 strcat(retval2,retval);
220 strcat(retval2,")");
224 #ifdef WIN32
225 setlocale(LC_ALL, ".ACP");
226 #endif
228 return retval2;
231 bool CheckDate(GSM_DateTime *date)
233 /* FIXME: This could also check if day is correct for selected month */
234 return date->Year != 0 &&
235 date->Month >= 1 && date->Month <= 12 &&
236 date->Day >= 1 && date->Day <= 31;
239 bool CheckTime(GSM_DateTime *date)
241 return date->Hour <= 23 && date->Hour >= 0 &&
242 date->Minute <= 59 && date->Minute >= 0 &&
243 date->Second <= 59 && date->Second >= 0;
246 int GetLine(FILE *File, char *Line, int count)
248 char *ptr;
250 if (fgets(Line, count, File)) {
251 ptr=Line+strlen(Line)-1;
253 while ( (*ptr == '\n' || *ptr == '\r') && ptr>=Line) *ptr--='\0';
255 return strlen(Line);
256 } else {
257 return -1;
261 void SplitLines(unsigned char *message, int messagesize, GSM_Lines *lines, unsigned char *whitespaces, int spaceslen, bool eot)
263 int i,number=0,j;
264 bool whitespace=true, nowwhite;
266 for (i=0;i<MAX_LINES*2;i++) lines->numbers[i]=0;
268 for (i=0;i<messagesize;i++) {
269 nowwhite = false;
270 for (j=0;j<spaceslen;j++) {
271 if (whitespaces[j] == message[i]) {
272 nowwhite = true;
273 break;
276 if (whitespace) {
277 if (!nowwhite) {
278 lines->numbers[number]=i;
279 number++;
280 whitespace=false;
282 } else {
283 if (nowwhite) {
284 lines->numbers[number]=i;
285 number++;
286 whitespace=true;
291 if (eot && !whitespace) lines->numbers[number]=messagesize;
294 char *GetLineString(unsigned char *message, GSM_Lines lines, int start)
296 static char retval[800];
298 memcpy(retval,message + lines.numbers[start*2-2],lines.numbers[start*2-2+1]-lines.numbers[start*2-2]);
299 retval[lines.numbers[start*2-2+1]-lines.numbers[start*2-2]]=0;
301 return retval;
304 void CopyLineString(unsigned char *dest, unsigned char *src, GSM_Lines lines, int start)
306 memcpy(dest,GetLineString(src, lines, start),strlen(GetLineString(src, lines, start)));
307 dest[strlen(GetLineString(src, lines, start))] = 0;
310 Debug_Info di = {0,NULL,false,""};
312 #ifdef DEBUG
313 int dbgprintf(const char *format, ...)
315 va_list argp;
316 int result;
317 static unsigned char nextline[2000]="";
318 unsigned char buffer[2000];
319 GSM_DateTime date_time;
321 if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) {
322 va_start(argp, format);
323 result = vsprintf(buffer, format, argp);
324 strcat(nextline, buffer);
325 if (strstr(buffer, "\n")) {
326 if (di.dl == DL_TEXTALLDATE) {
327 GSM_GetCurrentDateTime(&date_time);
328 fprintf(di.df,"%s %4d/%02d/%02d %02d:%02d:%02d: %s",
329 DayOfWeek(date_time.Year, date_time.Month, date_time.Day),
330 date_time.Year, date_time.Month, date_time.Day,
331 date_time.Hour, date_time.Minute, date_time.Second,nextline);
332 } else {
333 fprintf(di.df,"%s",nextline);
335 strcpy(nextline, "");
337 fflush(di.df);
338 va_end(argp);
339 return result;
341 return 0;
343 #endif
345 #define SMPRINTF_MAX_TIME 30
347 /* assumption: if \n is present it is always the last char,
348 * string never of the form "......\n..."
350 int smfprintf(FILE *f, const char *format, ...)
352 va_list argp;
353 int result=0;
354 static unsigned char prevline[2000] = "", nextline[2000]="";
355 static unsigned int linecount=0;
356 unsigned char buffer[2000];
357 GSM_DateTime date_time;
359 if (f == NULL) return 0;
360 va_start(argp, format);
361 result = vsprintf(buffer, format, argp);
362 strcat(nextline, buffer);
363 if (strstr(buffer, "\n")) {
364 if (ftell(f) < 5000000) {
365 GSM_GetCurrentDateTime(&date_time);
366 if (linecount > 0) {
367 if (di.dl == DL_TEXTALLDATE || di.dl == DL_TEXTERRORDATE || di.dl == DL_TEXTDATE) {
368 fprintf(f,"%s %4d/%02d/%02d %02d:%02d:%02d: <%i> %s",
369 DayOfWeek(date_time.Year, date_time.Month, date_time.Day),
370 date_time.Year, date_time.Month, date_time.Day,
371 date_time.Hour, date_time.Minute, date_time.Second,linecount,prevline);
372 } else {
373 fprintf(f,"%s",prevline);
376 linecount=0;
377 if (di.dl == DL_TEXTALLDATE || di.dl == DL_TEXTERRORDATE || di.dl == DL_TEXTDATE) {
378 fprintf(f,"%s %4d/%02d/%02d %02d:%02d:%02d: %s",
379 DayOfWeek(date_time.Year, date_time.Month, date_time.Day),
380 date_time.Year, date_time.Month, date_time.Day,
381 date_time.Hour, date_time.Minute, date_time.Second,nextline);
382 } else {
383 fprintf(f,"%s",nextline);
385 strcpy(prevline, nextline);
387 strcpy(nextline, "");
388 fflush(f);
390 va_end(argp);
391 return result;
394 bool GSM_SetDebugLevel(char *info, Debug_Info *di)
396 if (!strcmp(info,"nothing")) {di->dl = 0; return true;}
397 if (!strcmp(info,"text")) {di->dl = DL_TEXT; return true;}
398 if (!strcmp(info,"textall")) {di->dl = DL_TEXTALL; return true;}
399 if (!strcmp(info,"binary")) {di->dl = DL_BINARY; return true;}
400 if (!strcmp(info,"errors")) {di->dl = DL_TEXTERROR; return true;}
401 if (!strcmp(info,"textdate")) {di->dl = DL_TEXTDATE; return true;}
402 if (!strcmp(info,"textalldate")) {di->dl = DL_TEXTALLDATE; return true;}
403 if (!strcmp(info,"errorsdate")) {di->dl = DL_TEXTERRORDATE; return true;}
404 return false;
407 /* Dumps a message */
408 void DumpMessage(FILE *df, const unsigned char *message, int messagesize)
410 int i,j=0,len=16;
411 unsigned char buffer[200];
413 if (df==NULL || messagesize == 0) return;
415 smfprintf(df, "\n");
417 memset(buffer,0x20,sizeof(buffer));
418 buffer[len*5-1]=0;
420 for (i = 0; i < messagesize; i++) {
421 sprintf(buffer+j*4,"%02x",message[i]);
422 buffer[j*4+2] = 0x20;
423 if (isprint(message[i]) && message[i]!=0x09) {
424 if (j != len-1) buffer[j*4+2] = message[i];
425 buffer[(len-1)*4+j+3] = message[i];
426 } else {
427 buffer[(len-1)*4+j+3] = '.';
429 if (j != len-1 && i != messagesize-1) buffer[j*4+3] = '|';
430 if (j == len-1) {
431 smfprintf(df,"%s\n",buffer);
432 memset(buffer,0x20,sizeof(buffer));
433 buffer[len*5-1]=0;
434 j = 0;
435 } else {
436 j++;
439 if (j != 0) smfprintf(df,"%s",buffer);
440 smfprintf(df, "\n");
443 /* How should editor hadle tabs in this file? Add editor commands here.
444 * vim: noexpandtab sw=8 ts=8 sts=8: