author | zautrix <zautrix> | 2004-10-05 11:13:51 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-10-05 11:13:51 (UTC) |
commit | 50ab40e1e02ad7c65c17a78d08116a808b1257aa (patch) (side-by-side diff) | |
tree | 0d1939e2297fa7bbd8e1f2030f154463854164c6 /gammu/emb/common/misc | |
parent | cf8616f64f20e5448d4ff644f7cc15750cf3f85f (diff) | |
download | kdepimpi-50ab40e1e02ad7c65c17a78d08116a808b1257aa.zip kdepimpi-50ab40e1e02ad7c65c17a78d08116a808b1257aa.tar.gz kdepimpi-50ab40e1e02ad7c65c17a78d08116a808b1257aa.tar.bz2 |
updated to latest gammu version
-rw-r--r-- | gammu/emb/common/misc/coding/coding.c | 177 | ||||
-rw-r--r-- | gammu/emb/common/misc/coding/coding.h | 27 | ||||
-rw-r--r-- | gammu/emb/common/misc/coding/md5.c | 2 | ||||
-rw-r--r-- | gammu/emb/common/misc/misc.c | 19 | ||||
-rw-r--r-- | gammu/emb/common/misc/misc.h | 8 |
5 files changed, 209 insertions, 24 deletions
diff --git a/gammu/emb/common/misc/coding/coding.c b/gammu/emb/common/misc/coding/coding.c index 62543ac..b30b645 100644 --- a/gammu/emb/common/misc/coding/coding.c +++ b/gammu/emb/common/misc/coding/coding.c @@ -1,210 +1,363 @@ /* (c) 2002-2004 by Marcin Wiacek, Michal Cihar and others */ -/* based on some work from MyGnokii and Gnokii */ +/* based on some work from MyGnokii (www.mwiacek.com) */ +/* based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <locale.h> #ifndef __OpenBSD__ # include <wctype.h> #endif #ifdef WIN32 # include "windows.h" #endif #include "../misc.h" #include "coding.h" +/* function changes #10 #13 chars to \n \r */ +char *EncodeUnicodeSpecialChars(unsigned char *buffer) +{ + int Pos=0, Pos2=0; + static unsigned char Buf[20000]; + + while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) { + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 10) { + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = '\\'; + Pos2++; + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = 'n'; + Pos2++; + } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 13) { + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = '\\'; + Pos2++; + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = 'r'; + Pos2++; + } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') { + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = '\\'; + Pos2++; + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = '\\'; + Pos2++; + } else { + Buf[Pos2*2] = buffer[Pos*2]; + Buf[Pos2*2+1] = buffer[Pos*2+1]; + Pos2++; + } + Pos++; + } + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = 0; + return Buf; +} + +/* function changes #10 #13 chars to \n \r */ +char *EncodeSpecialChars(unsigned char *buffer) +{ + int Pos=0, Pos2=0; + static unsigned char Buf[10000]; + + while (buffer[Pos]!=0x00) { + switch (buffer[Pos]) { + case 10: + Buf[Pos2++] = '\\'; + Buf[Pos2++] = 'n'; + break; + case 13: + Buf[Pos2++] = '\\'; + Buf[Pos2++] = 'r'; + break; + case '\\': + Buf[Pos2++] = '\\'; + Buf[Pos2++] = '\\'; + break; + default: + Buf[Pos2++] = buffer[Pos]; + } + Pos++; + } + Buf[Pos2] = 0; + return Buf; +} + +char *DecodeUnicodeSpecialChars(unsigned char *buffer) +{ + int Pos=0, Pos2=0, level=0; + static unsigned char Buf[10000]; + + while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) { + Buf[Pos2*2] = buffer[Pos*2]; + Buf[Pos2*2+1] = buffer[Pos*2+1]; + switch (level) { + case 0: + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') { + level = 1; + } else { + Pos2++; + } + break; + case 1: + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'n') { + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = 10; + } + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'r') { + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = 13; + } + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') { + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = '\\'; + } + Pos2++; + level = 0; + } + Pos++; + } + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = 0; + return Buf; +} + +char *DecodeSpecialChars(unsigned char *buffer) +{ + int Pos=0, Pos2=0, level=0; + static unsigned char Buf[10000]; + + while (buffer[Pos]!=0x00) { + Buf[Pos2] = buffer[Pos]; + switch (level) { + case 0: + if (buffer[Pos] == '\\') { + level = 1; + } else { + Pos2++; + } + break; + case 1: + if (buffer[Pos] == 'n') Buf[Pos2] = 10; + if (buffer[Pos] == 'r') Buf[Pos2] = 13; + if (buffer[Pos] == '\\') Buf[Pos2] = '\\'; + Pos2++; + level = 0; + } + Pos++; + } + Buf[Pos2] = 0; + return Buf; +} + +char *mystrcasestr(unsigned const char *a, unsigned const char *b) +{ + unsigned char A[2000], B[200]; + int i; + + memset(A,0,sizeof(A)); + memset(B,0,sizeof(B)); + for (i=0;i<(int)strlen(a);i++) A[i] = tolower(a[i]); + for (i=0;i<(int)strlen(b);i++) B[i] = tolower(b[i]); + + return strstr(A,B); +} + unsigned int UnicodeLength(const unsigned char *str) { unsigned int len = 0; if (str == NULL) return 0; while(str[len*2] != 0 || str[len*2+1] != 0) len++; return len; } /* Convert Unicode char saved in src to dest */ unsigned int EncodeWithUnicodeAlphabet(const unsigned char *src, wchar_t *dest) { char retval; switch (retval = mbtowc(dest, src, MB_CUR_MAX)) { case -1 : case 0 : return 1; default : return retval; } } /* Convert Unicode char saved in src to dest */ unsigned int DecodeWithUnicodeAlphabet(wchar_t src, unsigned char *dest) { int retval; switch (retval = wctomb(dest, src)) { case -1: *dest = '?'; return 1; default: return retval; } } void DecodeUnicode (const unsigned char *src, unsigned char *dest) { int i=0,o=0; wchar_t wc; while (src[(2*i)+1]!=0x00 || src[2*i]!=0x00) { wc = src[(2*i)+1] | (src[2*i] << 8); o += DecodeWithUnicodeAlphabet(wc, dest + o); i++; } dest[o]=0; } /* Decode Unicode string and return as function result */ unsigned char *DecodeUnicodeString (const unsigned char *src) { static char dest[500]; DecodeUnicode(src,dest); return dest; } /* Decode Unicode string to UTF8 or other console charset * and return as function result */ unsigned char *DecodeUnicodeConsole(const unsigned char *src) { static char dest[500]; if (di.coding[0] != 0) { if (!strcmp(di.coding,"utf8")) { EncodeUTF8(dest, src); } else { #ifdef WIN32 setlocale(LC_ALL, di.coding); #endif DecodeUnicode(src,dest); } } else { #ifdef WIN32 setlocale(LC_ALL, ".OCP"); #endif DecodeUnicode(src,dest); #ifdef WIN32 setlocale(LC_ALL, ".ACP"); #endif } return dest; } /* Encode string to Unicode. Len is number of input chars */ void EncodeUnicode (unsigned char *dest, const unsigned char *src, int len) { int i_len = 0, o_len; wchar_t wc; for (o_len = 0; i_len < len; o_len++) { i_len += EncodeWithUnicodeAlphabet(&src[i_len], &wc); dest[o_len*2] = (wc >> 8) & 0xff; dest[(o_len*2)+1] = wc & 0xff; } dest[o_len*2] = 0; dest[(o_len*2)+1] = 0; } unsigned char EncodeWithBCDAlphabet(int value) { div_t division; division=div(value,10); return ( ( (value-division.quot*10) & 0x0f) << 4) | (division.quot & 0xf); } int DecodeWithBCDAlphabet(unsigned char value) { return 10*(value & 0x0f)+(value >> 4); } void DecodeBCD (unsigned char *dest, const unsigned char *src, int len) { int i,current=0,digit; for (i = 0; i < len; i++) { digit=src[i] & 0x0f; if (digit<10) dest[current++]=digit + '0'; digit=src[i] >> 4; if (digit<10) dest[current++]=digit + '0'; } dest[current++]=0; } void EncodeBCD (unsigned char *dest, const unsigned char *src, int len, bool fill) { int i,current=0; for (i = 0; i < len; i++) { if (i & 0x01) { dest[current]=dest[current] | ((src[i]-'0') << 4); current++; } else { dest[current]=src[i]-'0'; } } /* When fill is set: if number consist of odd number of digits, we fill last bits in last byte with 0x0f */ if (fill && (len & 0x01)) dest[current]=dest[current] | 0xf0; } int DecodeWithHexBinAlphabet (unsigned char mychar) { if (mychar>='A' && mychar<='F') return mychar-'A'+10; if (mychar>='a' && mychar<='f') return mychar-'a'+10; if (mychar>='0' && mychar<='9') return mychar-'0'; return -1; } unsigned char EncodeWithHexBinAlphabet (int digit) { if (digit >= 0 && digit <= 9) return '0'+(digit); if (digit >=10 && digit <=15) return 'A'+(digit-10); return 0; } void DecodeHexUnicode (unsigned char *dest, const unsigned char *src, int len) { int i,current=0; bool first = false; if (len != 0 && src[0] == '0' && src[1] == '0') { first = true; } else if (len != 0 && src[2] == '0' && src[3] == '0') { first = false; } else { first = (10 * (src[0] - '0') + (src[1] - '0')) < (10 * (src[2] - '0')+ (src[3] - '0')); } for (i = 0; i < len/4 ; i++) { if (first) { dest[current++] = DecodeWithHexBinAlphabet(src[i*4+0])*16+ DecodeWithHexBinAlphabet(src[i*4+1]); dest[current++] = DecodeWithHexBinAlphabet(src[i*4+2])*16+ DecodeWithHexBinAlphabet(src[i*4+3]); } else { dest[current++] = DecodeWithHexBinAlphabet(src[i*4+2])*16+ DecodeWithHexBinAlphabet(src[i*4+3]); dest[current++] = DecodeWithHexBinAlphabet(src[i*4+0])*16+ DecodeWithHexBinAlphabet(src[i*4+1]); } } dest[current++] = 0; dest[current++] = 0; } void EncodeHexUnicode (unsigned char *dest, const unsigned char *src, int len) @@ -397,814 +550,814 @@ void EncodeDefault(unsigned char *dest, const unsigned char *src, int *len, bool if (src[i*2] == GSM_DefaultAlphabetUnicode[j][0] && src[i*2+1] == GSM_DefaultAlphabetUnicode[j][1]) { ret = j; FoundNormal = true; break; } j++; } if (ExtraAlphabet!=NULL && !FoundNormal) { j = 0; while (ExtraAlphabet[j] != 0x00 || ExtraAlphabet[j+1] != 0x00 || ExtraAlphabet[j+2] != 0x00) { if (ExtraAlphabet[j+1] == src[i*2] && ExtraAlphabet[j+2] == src[i*2 + 1]) { ret = ExtraAlphabet[j]; FoundSpecial = true; break; } j=j+3; } } if (!FoundNormal && !FoundSpecial) { j = 0; FoundNormal = false; while (ConvertTable[j*4] != 0x00 || ConvertTable[j*4+1] != 0x00) { if (src[i*2] == ConvertTable[j*4] && src[i*2+1] == ConvertTable[j*4+1]) { z = 0; while (GSM_DefaultAlphabetUnicode[z][1]!=0x00) { if (ConvertTable[j*4+2] == GSM_DefaultAlphabetUnicode[z][0] && ConvertTable[j*4+3] == GSM_DefaultAlphabetUnicode[z][1]) { ret = z; FoundNormal = true; break; } z++; } if (FoundNormal) break; } j++; } } dest[current++]=ret; } } dest[current]=0; #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, di.dl, dest, current); #endif *len = current; } /* You don't have to use ConvertTable here - 1 char is replaced there by 1 char */ void FindDefaultAlphabetLen(const unsigned char *src, int *srclen, int *smslen, int maxlen) { int current=0,j,i; bool FoundSpecial; i = 0; while (src[i*2] != 0x00 || src[i*2+1] != 0x00) { FoundSpecial = false; j = 0; while (GSM_DefaultAlphabetCharsExtension[j][0]!=0x00) { if (src[i*2] == GSM_DefaultAlphabetCharsExtension[j][2] && src[i*2+1] == GSM_DefaultAlphabetCharsExtension[j][3]) { FoundSpecial = true; if (current+2 > maxlen) { *srclen = i; *smslen = current; return; } current+=2; break; } j++; } if (!FoundSpecial) { if (current+1 > maxlen) { *srclen = i; *smslen = current; return; } current++; } i++; } *srclen = i; *smslen = current; } #ifndef ENABLE_LGPL # define ByteMask ((1 << Bits) - 1) #endif int GSM_UnpackEightBitsToSeven(int offset, int in_length, int out_length, unsigned char *input, unsigned char *output) { #ifndef ENABLE_LGPL /* (c) by Pavel Janik and Pawel Kot */ unsigned char *OUTPUT = output; /* Current pointer to the output buffer */ unsigned char *INPUT = input; /* Current pointer to the input buffer */ unsigned char Rest = 0x00; int Bits; Bits = offset ? offset : 7; while ((INPUT - input) < in_length) { *OUTPUT = ((*INPUT & ByteMask) << (7 - Bits)) | Rest; Rest = *INPUT >> Bits; /* If we don't start from 0th bit, we shouldn't go to the next char. Under *OUTPUT we have now 0 and under Rest - _first_ part of the char. */ if ((INPUT != input) || (Bits == 7)) OUTPUT++; INPUT++; if ((OUTPUT - output) >= out_length) break; /* After reading 7 octets we have read 7 full characters but we have 7 bits as well. This is the next character */ if (Bits == 1) { *OUTPUT = Rest; OUTPUT++; Bits = 7; Rest = 0x00; } else { Bits--; } } return OUTPUT - output; #else return 0; #endif } int GSM_PackSevenBitsToEight(int offset, unsigned char *input, unsigned char *output, int length) { #ifndef ENABLE_LGPL /* (c) by Pavel Janik and Pawel Kot */ unsigned char *OUTPUT = output; /* Current pointer to the output buffer */ unsigned char *INPUT = input; /* Current pointer to the input buffer */ int Bits; /* Number of bits directly copied to * the output buffer */ Bits = (7 + offset) % 8; /* If we don't begin with 0th bit, we will write only a part of the first octet */ if (offset) { *OUTPUT = 0x00; OUTPUT++; } while ((INPUT - input) < length) { unsigned char Byte = *INPUT; *OUTPUT = Byte >> (7 - Bits); /* If we don't write at 0th bit of the octet, we should write a second part of the previous octet */ if (Bits != 7) *(OUTPUT-1) |= (Byte & ((1 << (7-Bits)) - 1)) << (Bits+1); Bits--; if (Bits == -1) Bits = 7; else OUTPUT++; INPUT++; } return (OUTPUT - output); #else return 0; #endif } void GSM_UnpackSemiOctetNumber(unsigned char *retval, unsigned char *Number, bool semioctet) { unsigned char Buffer[50] = ""; int length = Number[0]; if (semioctet) { /* Convert number of semioctets to number of chars */ if (length % 2) length++; length=length / 2 + 1; } /*without leading byte with format of number*/ length--; - switch (Number[1]) { - case NUMBER_ALPHANUMERIC: + switch ((Number[1] & 112)) { + case (NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN & 112): if (length > 6) length++; dbgprintf("Alphanumeric number, length %i\n",length); GSM_UnpackEightBitsToSeven(0, length, length, Number+2, Buffer); Buffer[length]=0; break; - case NUMBER_INTERNATIONAL: + case (NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN & 112): dbgprintf("International number\n"); Buffer[0]='+'; DecodeBCD(Buffer+1,Number+2, length); break; default: dbgprintf("Default number %02x\n",Number[1]); DecodeBCD (Buffer, Number+2, length); break; } EncodeUnicode(retval,Buffer,strlen(Buffer)); } /** * Packing some phone numbers (SMSC, SMS destination and others) * * See GSM 03.40 9.1.1: * 1 byte - length of number given in semioctets or bytes (when given in * bytes, includes one byte for byte with number format). * Returned by function (set semioctet to true, if want result * in semioctets). * 1 byte - format of number (see GSM_NumberType in coding.h). Returned * in unsigned char *Output. * n bytes - 2n or 2n-1 semioctets with number. Returned in unsigned char * *Output. * * 1 semioctet = 4 bits = half of byte */ int GSM_PackSemiOctetNumber(unsigned char *Number, unsigned char *Output, bool semioctet) { unsigned char format, buffer[50]; int length, i; length=UnicodeLength(Number); memcpy(buffer,DecodeUnicodeString(Number),length+1); /* Checking for format number */ - format = NUMBER_UNKNOWN; + format = NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN; for (i=0;i<length;i++) { /* first byte is '+'. Number can be international */ if (i==0 && buffer[i]=='+') { - format=NUMBER_INTERNATIONAL; + format=NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN; } else { /*char is not number. It must be alphanumeric*/ - if (!isdigit(buffer[i])) format=NUMBER_ALPHANUMERIC; + if (!isdigit(buffer[i])) format=NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN; } } /** * First byte is used for saving type of number. See GSM 03.40 * section 9.1.2.5 */ Output[0]=format; /* After number type we will have number. GSM 03.40 section 9.1.2 */ switch (format) { - case NUMBER_ALPHANUMERIC: + case NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN: length=GSM_PackSevenBitsToEight(0, buffer, Output+1, strlen(buffer))*2; if (strlen(buffer)==7) length--; break; - case NUMBER_INTERNATIONAL: + case NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN: length--; EncodeBCD (Output+1, buffer+1, length, true); break; default: EncodeBCD (Output+1, buffer, length, true); break; } if (semioctet) return length; /* Convert number of semioctets to number of chars */ if (length % 2) length++; return length / 2 + 1; } void CopyUnicodeString(unsigned char *Dest, unsigned char *Source) { int j = 0; while (Source[j]!=0x00 || Source[j+1]!=0x00) { Dest[j] = Source[j]; Dest[j+1] = Source[j+1]; j=j+2; } Dest[j] = 0; Dest[j+1] = 0; } /* Changes minor/major order in Unicode string */ void ReverseUnicodeString(unsigned char *String) { int j = 0; unsigned char byte1, byte2; while (String[j]!=0x00 || String[j+1]!=0x00) { byte1 = String[j]; byte2 = String[j+1]; String[j+1] = byte1; String[j] = byte2; j=j+2; } String[j] = 0; String[j+1] = 0; } /* All input is in Unicode. First char can show Unicode minor/major order. Output is Unicode string in Gammu minor/major order */ void ReadUnicodeFile(unsigned char *Dest, unsigned char *Source) { int j = 0, current = 0; if (Source[0] == 0xFF && Source[1] == 0xFE) j = 2; if (Source[0] == 0xFE && Source[1] == 0xFF) j = 2; while (Source[j]!=0x00 || Source[j+1]!=0x00) { if (Source[0] == 0xFF) { Dest[current++] = Source[j+1]; Dest[current++] = Source[j]; } else { Dest[current++] = Source[j]; Dest[current++] = Source[j+1]; } j=j+2; } Dest[current++] = 0; Dest[current++] = 0; } int GetBit(unsigned char *Buffer, int BitNum) { return Buffer[BitNum/8] & 1<<(7-(BitNum%8)); } int SetBit(unsigned char *Buffer, int BitNum) { return Buffer[BitNum/8] |= 1<<(7-(BitNum%8)); } int ClearBit(unsigned char *Buffer, int BitNum) { return Buffer[BitNum/8] &= 255 - (1 << (7-(BitNum%8))); } void BufferAlign(unsigned char *Destination, int *CurrentBit) { int i=0; while(((*CurrentBit) + i) % 8 != 0) { ClearBit(Destination, (*CurrentBit)+i); i++; } (*CurrentBit) = (*CurrentBit) + i; } void BufferAlignNumber(int *CurrentBit) { int i=0; while(((*CurrentBit) + i) % 8 != 0) { i++; } (*CurrentBit) = (*CurrentBit) + i; } void AddBuffer(unsigned char *Destination, int *CurrentBit, unsigned char *Source, int BitsToProcess) { int i=0; while (i!=BitsToProcess) { if (GetBit(Source, i)) { SetBit(Destination, (*CurrentBit)+i); } else { ClearBit(Destination, (*CurrentBit)+i); } i++; } (*CurrentBit) = (*CurrentBit) + BitsToProcess; } void AddBufferByte(unsigned char *Destination, int *CurrentBit, unsigned char Source, int BitsToProcess) { unsigned char Byte; Byte = Source; AddBuffer(Destination, CurrentBit, &Byte, BitsToProcess); } void GetBuffer(unsigned char *Source, int *CurrentBit, unsigned char *Destination, int BitsToProcess) { int i=0; while (i!=BitsToProcess) { if (GetBit(Source, (*CurrentBit)+i)) { SetBit(Destination, i); } else { ClearBit(Destination, i); } i++; } (*CurrentBit) = (*CurrentBit) + BitsToProcess; } void GetBufferInt(unsigned char *Source, int *CurrentBit, int *integer, int BitsToProcess) { int l=0,z=128,i=0; while (i!=BitsToProcess) { if (GetBit(Source, (*CurrentBit)+i)) l=l+z; z=z/2; i++; } *integer=l; (*CurrentBit) = (*CurrentBit) + i; } void GetBufferI(unsigned char *Source, int *CurrentBit, int *result, int BitsToProcess) { int l=0,z,i=0; z = 1<<(BitsToProcess-1); while (i!=BitsToProcess) { if (GetBit(Source, (*CurrentBit)+i)) l=l+z; z=z>>1; i++; } *result=l; (*CurrentBit) = (*CurrentBit) + i; } /* Unicode char 0x00 0x01 makes blinking in some Nokia phones. * We replace single ~ chars into it. When user give double ~, it's replaced * to single ~ */ void EncodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *src, int len) { int i,current = 0; bool special=false; for (i = 0; i < len; i++) { if (special) { if (src[i*2] == 0x00 && src[i*2+1] == '~') { dest[current++] = 0x00; dest[current++] = '~'; } else { dest[current++] = 0x00; dest[current++] = 0x01; dest[current++] = src[i*2]; dest[current++] = src[i*2+1]; } special = false; } else { if (src[i*2] == 0x00 && src[i*2+1] == '~') { special = true; } else { dest[current++] = src[i*2]; dest[current++] = src[i*2+1]; } } } if (special) { dest[current++] = 0x00; dest[current++] = 0x01; } dest[current++] = 0x00; dest[current++] = 0x00; } void DecodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *src, int len) { int i=0,current=0; for (i=0;i<len;i++) { switch (src[2*i]) { case 0x00: switch (src[2*i+1]) { case 0x01: dest[current++] = 0x00; dest[current++] = '~'; break; case '~': dest[current++] = 0x00; dest[current++] = '~'; dest[current++] = 0x00; dest[current++] = '~'; break; default: dest[current++] = src[i*2]; dest[current++] = src[i*2+1]; } break; default: dest[current++] = src[i*2]; dest[current++] = src[i*2+1]; } } dest[current++] = 0x00; dest[current++] = 0x00; } bool mystrncasecmp(unsigned const char *a, unsigned const char *b, int num) { int i; if (a == NULL || b == NULL) return false; - num--; + if (num == 0) num = -1; for (i = 0; i != num; i++) { if (a[i] == 0x00 && b[i] == 0x00) return true; if (a[i] == 0x00 || b[i] == 0x00) return false; if (tolower(a[i]) != tolower(b[i])) return false; } return true; } /* Compares two Unicode strings without regarding to case. * Return true, when they're equal */ bool mywstrncasecmp(unsigned const char *a, unsigned const char *b, int num) { int i; wchar_t wc,wc2; if (a == NULL || b == NULL) return false; - num--; + if (num == 0) num = -1; for (i = 0; i != num; i++) { if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) && (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return true; if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) || (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return false; wc = a[i*2+1] | (a[i*2] << 8); wc2 = b[i*2+1] | (b[i*2] << 8); if (mytowlower(wc) != mytowlower(wc2)) return false; } return true; } /* wcscmp in Mandrake 9.0 is wrong */ bool mywstrncmp(unsigned const char *a, unsigned const char *b, int num) { int i=0; while (1) { if (a[i*2] != b[i*2] || a[i*2+1] != b[i*2+1]) return false; if (a[i*2] == 0x00 && a[i*2+1] == 0x00) return true; i++; if (num == i) return true; } } /* FreeBSD boxes 4.7-STABLE does't have it, although it's ANSI standard */ bool myiswspace(unsigned const char *src) { #ifndef HAVE_ISWSPACE int o; unsigned char dest[10]; #endif wchar_t wc; wc = src[1] | (src[0] << 8); #ifndef HAVE_ISWSPACE o = DecodeWithUnicodeAlphabet(wc, dest); if (o == 1) { if (isspace(((int)dest[0]))!=0) return true; return false; } return false; #else return iswspace(wc); #endif } /* FreeBSD boxes 4.7-STABLE does't have it, although it's ANSI standard */ int mytowlower(wchar_t c) { #ifndef HAVE_TOWLOWER unsigned char dest[10]; DecodeWithUnicodeAlphabet(c, dest); return tolower(dest[0]); #else return towlower(c); #endif } /* * Following code is based on wcsstr from the GNU C Library, original * comment follows: */ /* * The original strstr() file contains the following comment: * * My personal strstr() implementation that beats most other algorithms. * Until someone tells me otherwise, I assume that this is the * fastest implementation of strstr() in C. * I deliberately chose not to comment it. You should have at least * as much fun trying to understand it, as I had to write it :-). * * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */ -unsigned char *mystrstr (const unsigned char *haystack, const unsigned char *needle) +unsigned char *mywstrstr (const unsigned char *haystack, const unsigned char *needle) { /* One crazy define to convert unicode used in Gammu to standard wchar_t */ #define tolowerwchar(x) (mytowlower((wchar_t)( (((&(x))[0] & 0xff) << 8) | (((&(x))[1] & 0xff)) ))) register wchar_t b, c; if ((b = tolowerwchar(*needle)) != L'\0') { haystack -= 2; /* possible ANSI violation */ do { haystack += 2; if ((c = tolowerwchar(*haystack)) == L'\0') goto ret0; } while (c != b); needle += 2; if ((c = tolowerwchar(*needle)) == L'\0') goto foundneedle; needle += 2; goto jin; for (;;) { register wchar_t a; register const unsigned char *rhaystack, *rneedle; do { haystack += 2; if ((a = tolowerwchar(*haystack)) == L'\0') goto ret0; if (a == b) break; haystack += 2; if ((a = tolowerwchar(*haystack)) == L'\0') goto ret0; shloop: ; } while (a != b); jin: haystack += 2; if ((a = tolowerwchar(*haystack)) == L'\0') goto ret0; if (a != c) goto shloop; rhaystack = haystack + 2; haystack -= 2; rneedle = needle; if (tolowerwchar(*rhaystack) == (a = tolowerwchar(*rneedle))) do { if (a == L'\0') goto foundneedle; rhaystack += 2; needle += 2; if (tolowerwchar(*rhaystack) != (a = tolowerwchar(*needle))) break ; if (a == L'\0') goto foundneedle; rhaystack += 2; needle += 2; } while (tolowerwchar(*rhaystack) == (a = tolowerwchar(*needle))); needle = rneedle; /* took the register-poor approach */ if (a == L'\0') break; } } foundneedle: return (unsigned char *)haystack; ret0: return NULL; #undef tolowerwchar } void MyGetLine(unsigned char *Buffer, int *Pos, unsigned char *OutBuffer, int MaxLen) { OutBuffer[0] = 0; if (Buffer == NULL) return; while (1) { if ((*Pos) >= MaxLen) return; switch (Buffer[*Pos]) { case 0x00: return; case 0x0A: if (strlen(OutBuffer) != 0) return; break; case 0x0D: if (strlen(OutBuffer) != 0) return; break; default : OutBuffer[strlen(OutBuffer) + 1] = 0; OutBuffer[strlen(OutBuffer)] = Buffer[*Pos]; } (*Pos)++; } } void StringToDouble(char *text, double *d) { bool before=true; double multiply = 1; unsigned int i; *d = 0; for (i=0;i<strlen(text);i++) { if (isdigit(text[i])) { if (before) { (*d)=(*d)*10+(text[i]-'0'); } else { multiply=multiply*0.1; (*d)=(*d)+(text[i]-'0')*multiply; } } if (text[i]=='.' || text[i]==',') before=false; } } /* When char can be converted, convert it from Unicode to UTF8 */ bool EncodeWithUTF8Alphabet(unsigned char mychar1, unsigned char mychar2, unsigned char *ret1, unsigned char *ret2) { unsigned char mychar3,mychar4; int j=0; if (mychar1>0x00 || mychar2>128) { mychar3=0x00; mychar4=128; while (true) { if (mychar3==mychar1) { if (mychar4+64>=mychar2) { *ret1=j+0xc2; *ret2=0x80+(mychar2-mychar4); return true; } } if (mychar4==192) { mychar3++; mychar4=0; } else { mychar4=mychar4+64; } j++; } } return false; } /* Make UTF8 string from Unicode input string */ bool EncodeUTF8QuotedPrintable(unsigned char *dest, const unsigned char *src) { int i,j=0; unsigned char mychar1, mychar2; bool retval = false; for (i = 0; i < (int)(UnicodeLength(src)); i++) { if (EncodeWithUTF8Alphabet(src[i*2],src[i*2+1],&mychar1,&mychar2)) { sprintf(dest+j, "=%02X=%02X",mychar1,mychar2); j = j+6; retval = true; } else { j += DecodeWithUnicodeAlphabet(((wchar_t)(src[i*2]*256+src[i*2+1])), dest + j); } } dest[j++]=0; return retval; } bool EncodeUTF8(unsigned char *dest, const unsigned char *src) { int i,j=0; unsigned char mychar1, mychar2; bool retval = false; for (i = 0; i < (int)(UnicodeLength(src)); i++) { if (EncodeWithUTF8Alphabet(src[i*2],src[i*2+1],&mychar1,&mychar2)) { sprintf(dest+j, "%c%c",mychar1,mychar2); j = j+2; retval = true; } else { j += DecodeWithUnicodeAlphabet(((wchar_t)(src[i*2]*256+src[i*2+1])), dest + j); } } dest[j++]=0; return retval; } /* Decode UTF8 char to Unicode char */ wchar_t DecodeWithUTF8Alphabet(unsigned char mychar3, unsigned char mychar4) { unsigned char mychar1, mychar2; int j; mychar1=0x00; mychar2=128; for(j=0;j<mychar3-0xc2;j++) { diff --git a/gammu/emb/common/misc/coding/coding.h b/gammu/emb/common/misc/coding/coding.h index d0c334d..4cf0038 100644 --- a/gammu/emb/common/misc/coding/coding.h +++ b/gammu/emb/common/misc/coding/coding.h @@ -1,133 +1,148 @@ /* (c) 2002-2004 by Marcin Wiacek and others */ #ifndef __coding_h #define __coding_h +#if defined(_MSC_VER) && defined(__cplusplus) + extern "C" { +#endif + #include <stdlib.h> #include "../misc.h" #ifdef __OpenBSD__ typedef int wint_t; #endif /* ---------------------------- Unicode ------------------------------------ */ bool mywstrncasecmp (unsigned const char *a, unsigned const char *b, int num); -unsigned char *mystrstr (unsigned const char *haystack, unsigned const char *needle); +unsigned char *mywstrstr (unsigned const char *haystack, unsigned const char *needle); bool mywstrncmp (unsigned const char *a, unsigned const char *b, int num); bool myiswspace (unsigned const char *src); int mytowlower (wchar_t c); unsigned int EncodeWithUnicodeAlphabet (const unsigned char *value, wchar_t *dest); unsigned int DecodeWithUnicodeAlphabet (wchar_t value, unsigned char *dest); unsigned int UnicodeLength (const unsigned char *str); unsigned char *DecodeUnicodeString (const unsigned char *src); unsigned char *DecodeUnicodeConsole (const unsigned char *src); void DecodeUnicode (const unsigned char *src, unsigned char *dest); void EncodeUnicode (unsigned char *dest, const unsigned char *src, int len); void CopyUnicodeString (unsigned char *Dest, unsigned char *Source); void ReverseUnicodeString (unsigned char *String); void ReadUnicodeFile (unsigned char *Dest, unsigned char *Source); void DecodeUnicodeSpecialNOKIAChars (unsigned char *dest, const unsigned char *src, int len); void EncodeUnicodeSpecialNOKIAChars (unsigned char *dest, const unsigned char *src, int len); +char *EncodeUnicodeSpecialChars (unsigned char *buffer); +char *DecodeUnicodeSpecialChars (unsigned char *buffer); + /* ------------------------------- BCD ------------------------------------- */ unsigned char EncodeWithBCDAlphabet (int value); int DecodeWithBCDAlphabet (unsigned char value); void DecodeBCD (unsigned char *dest, const unsigned char *src, int len); void EncodeBCD (unsigned char *dest, const unsigned char *src, int len, bool fill); /* ------------------------------ UTF7 ------------------------------------- */ void DecodeUTF7 (unsigned char *dest, const unsigned char *src, int len); /* ------------------------------ UTF8 ------------------------------------- */ wchar_t DecodeWithUTF8Alphabet (unsigned char mychar3, unsigned char mychar4); bool EncodeWithUTF8Alphabet (unsigned char mychar1, unsigned char mychar2, unsigned char *ret1, unsigned char *ret2); bool EncodeUTF8QuotedPrintable (unsigned char *dest, const unsigned char *src); void DecodeUTF8QuotedPrintable (unsigned char *dest, const unsigned char *src, int len); bool EncodeUTF8 (unsigned char *dest, const unsigned char *src); void DecodeUTF8 (unsigned char *dest, const unsigned char *src, int len); /* ------------------------------- BASE64 ---------------------------------- */ void EncodeBASE64 (const unsigned char *Input, unsigned char *Output, int Length); int DecodeBASE64 (const unsigned char *Input, unsigned char *Output, int Length); /* ----------------------------- HexBin ------------------------------------ */ void DecodeHexBin (unsigned char *dest, const unsigned char *src, int len); void EncodeHexBin (unsigned char *dest, const unsigned char *src, int len); /* ----------------------------- HexUnicode -------------------------------- */ void DecodeHexUnicode (unsigned char *dest, const unsigned char *src, int len); void EncodeHexUnicode (unsigned char *dest, const unsigned char *src, int len); /* ---------------------- DefaultAlphabet for SMS -------------------------- */ void EncodeDefault (unsigned char *dest, const unsigned char *src, int *len, bool UseExtensions, unsigned char *ExtraAlphabet); void DecodeDefault (unsigned char *dest, const unsigned char *src, int len, bool UseExtensions, unsigned char *ExtraAlphabet); void FindDefaultAlphabetLen (const unsigned char *src, int *srclen, int *smslen, int maxlen); int GSM_PackSevenBitsToEight (int offset, unsigned char *input, unsigned char *output, int length); int GSM_UnpackEightBitsToSeven (int offset, int in_length, int out_length, unsigned char *input, unsigned char *output); /* ----------------- Phone numbers according to GSM specs ------------------ */ /** * Enum to handle types of phones numbers like * specified in GSM 03.40 section 9.1.2.5 */ typedef enum { /** * Unknown number type */ - NUMBER_UNKNOWN = 0x81, + NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN = 0x81, /** * International number (full number with code of country) */ - NUMBER_INTERNATIONAL = 0x91, + NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN = 0x91, /** * Alphanumeric number (with chars too) */ - NUMBER_ALPHANUMERIC = 0xD0 + NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN = 0xD0 /* specification give also other values */ } GSM_NumberType; void GSM_UnpackSemiOctetNumber (unsigned char *retval, unsigned char *Number, bool semioctet); int GSM_PackSemiOctetNumber (unsigned char *Number, unsigned char *Output, bool semioctet); /* ---------------------------- Bits --------------------------------------- */ void BufferAlign (unsigned char *Destination, int *CurrentBit); void BufferAlignNumber(int *CurrentBit); void AddBuffer (unsigned char *Destination, int *CurrentBit, unsigned char *Source, int BitsToProcess); void AddBufferByte(unsigned char *Destination, int *CurrentBit, unsigned char Source, int BitsToProcess); void GetBuffer (unsigned char *Source, int *CurrentBit, unsigned char *Destination, int BitsToProcess); void GetBufferInt (unsigned char *Source, int *CurrentBit, int *integer, int BitsToProcess); void GetBufferI (unsigned char *Source, int *CurrentBit, int *result, int BitsToProcess); int GetBit (unsigned char *Buffer, int BitNum); int SetBit (unsigned char *Buffer, int BitNum); int ClearBit (unsigned char *Buffer, int BitNum); /* ---------------------------- Other -------------------------------------- */ void StringToDouble (char *text, double *d); -bool mystrncasecmp (unsigned const char *a, unsigned const char *b, int num); +bool mystrncasecmp (unsigned const char *a, unsigned const char *b, int num); +char *mystrcasestr (unsigned const char *a, unsigned const char *b); -void MyGetLine(unsigned char *Buffer, int *Pos, unsigned char *OutBuffer, int MaxLen); +void MyGetLine (unsigned char *Buffer, int *Pos, unsigned char *OutBuffer, int MaxLen); + +char *EncodeSpecialChars(unsigned char *buffer); +char *DecodeSpecialChars(unsigned char *buffer); + +#if defined(_MSC_VER) && defined(__cplusplus) + } +#endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/misc/coding/md5.c b/gammu/emb/common/misc/coding/md5.c index 30fe33f..abb61be 100644 --- a/gammu/emb/common/misc/coding/md5.c +++ b/gammu/emb/common/misc/coding/md5.c @@ -1,193 +1,193 @@ -/* Taken from ReHash (see http://www.reichlsoft.de.vu/) and released +/* Taken from ReHash (www.reichlsoft.de.vu) and released * under GPL/LGPL with permission from ReHash author * Dominik Reichl <dominik.reichl@t-online.de>, Germany */ /* ********************************************************************** ** MD5.cpp ** ** ** ** - Style modified by Tony Ray, January 2001 ** ** Added support for randomizing initialization constants ** ** - Style modified by Dominik Reichl, April 2003 ** ** Optimized code ** ** ** ** MD5.c ** ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** ********************************************************************** */ /* ********************************************************************** ** MD5.h -- Header file for implementation of MD5 ** ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** ** Revised (for MD5): RLR 4/27/91 ** ** -- G modified to have y&~z instead of y&z ** ** -- FF, GG, HH modified to add in last register done ** ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** ** -- distinct additive constant for each step ** ** -- round 4 added, working mod 7 ** ********************************************************************** */ /* ********************************************************************** ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** ** ** ** License to copy and use this software is granted provided that ** ** it is identified as the "RSA Data Security, Inc. MD5 Message ** ** Digest Algorithm" in all material mentioning or referencing this ** ** software or this function. ** ** ** ** License is also granted to make and use derivative works ** ** provided that such works are identified as "derived from the RSA ** ** Data Security, Inc. MD5 Message Digest Algorithm" in all ** ** material mentioning or referencing the derived work. ** ** ** ** RSA Data Security, Inc. makes no representations concerning ** ** either the merchantability of this software or the suitability ** ** of this software for any particular purpose. It is provided "as ** ** is" without express or implied warranty of any kind. ** ** ** ** These notices must be retained in any copies of any part of this ** ** documentation and/or software. ** ********************************************************************** */ #include <stdio.h> #include <stdlib.h> #include "md5.h" /* Typedef a 32 bit type */ #ifndef UINT4 typedef unsigned long int UINT4; #endif /* Data structure for MD5 (Message Digest) computation */ typedef struct { UINT4 i[2]; /* Number of _bits_ handled mod 2^64 */ UINT4 buf[4]; /* Scratch buffer */ unsigned char in[64]; /* Input buffer */ unsigned char digest[16]; /* Actual digest after MD5Final call */ } MD5_CTX; /* Padding */ static unsigned char MD5_PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* MD5_F, MD5_G and MD5_H are basic MD5 functions: selection, majority, parity */ #define MD5_F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define MD5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define MD5_H(x, y, z) ((x) ^ (y) ^ (z)) #define MD5_I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits */ #ifndef ROTATE_LEFT #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) #endif /* MD5_FF, MD5_GG, MD5_HH, and MD5_II transformations for rounds 1, 2, 3, and 4 */ /* Rotation is separate from addition to prevent recomputation */ #define MD5_FF(a, b, c, d, x, s, ac) {(a) += MD5_F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } #define MD5_GG(a, b, c, d, x, s, ac) {(a) += MD5_G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } #define MD5_HH(a, b, c, d, x, s, ac) {(a) += MD5_H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } #define MD5_II(a, b, c, d, x, s, ac) {(a) += MD5_I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } /* Constants for transformation */ #define MD5_S11 7 /* Round 1 */ #define MD5_S12 12 #define MD5_S13 17 #define MD5_S14 22 #define MD5_S21 5 /* Round 2 */ #define MD5_S22 9 #define MD5_S23 14 #define MD5_S24 20 #define MD5_S31 4 /* Round 3 */ #define MD5_S32 11 #define MD5_S33 16 #define MD5_S34 23 #define MD5_S41 6 /* Round 4 */ #define MD5_S42 10 #define MD5_S43 15 #define MD5_S44 21 /* Basic MD5 step. MD5_Transform buf based on in */ static void MD5_Transform (UINT4 *buf, UINT4 *in) { UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; /* Round 1 */ MD5_FF ( a, b, c, d, in[ 0], MD5_S11, (UINT4) 3614090360u); /* 1 */ MD5_FF ( d, a, b, c, in[ 1], MD5_S12, (UINT4) 3905402710u); /* 2 */ MD5_FF ( c, d, a, b, in[ 2], MD5_S13, (UINT4) 606105819u); /* 3 */ MD5_FF ( b, c, d, a, in[ 3], MD5_S14, (UINT4) 3250441966u); /* 4 */ MD5_FF ( a, b, c, d, in[ 4], MD5_S11, (UINT4) 4118548399u); /* 5 */ MD5_FF ( d, a, b, c, in[ 5], MD5_S12, (UINT4) 1200080426u); /* 6 */ MD5_FF ( c, d, a, b, in[ 6], MD5_S13, (UINT4) 2821735955u); /* 7 */ MD5_FF ( b, c, d, a, in[ 7], MD5_S14, (UINT4) 4249261313u); /* 8 */ MD5_FF ( a, b, c, d, in[ 8], MD5_S11, (UINT4) 1770035416u); /* 9 */ MD5_FF ( d, a, b, c, in[ 9], MD5_S12, (UINT4) 2336552879u); /* 10 */ MD5_FF ( c, d, a, b, in[10], MD5_S13, (UINT4) 4294925233u); /* 11 */ MD5_FF ( b, c, d, a, in[11], MD5_S14, (UINT4) 2304563134u); /* 12 */ MD5_FF ( a, b, c, d, in[12], MD5_S11, (UINT4) 1804603682u); /* 13 */ MD5_FF ( d, a, b, c, in[13], MD5_S12, (UINT4) 4254626195u); /* 14 */ MD5_FF ( c, d, a, b, in[14], MD5_S13, (UINT4) 2792965006u); /* 15 */ MD5_FF ( b, c, d, a, in[15], MD5_S14, (UINT4) 1236535329u); /* 16 */ /* Round 2 */ MD5_GG ( a, b, c, d, in[ 1], MD5_S21, (UINT4) 4129170786u); /* 17 */ MD5_GG ( d, a, b, c, in[ 6], MD5_S22, (UINT4) 3225465664u); /* 18 */ MD5_GG ( c, d, a, b, in[11], MD5_S23, (UINT4) 643717713u); /* 19 */ MD5_GG ( b, c, d, a, in[ 0], MD5_S24, (UINT4) 3921069994u); /* 20 */ MD5_GG ( a, b, c, d, in[ 5], MD5_S21, (UINT4) 3593408605u); /* 21 */ MD5_GG ( d, a, b, c, in[10], MD5_S22, (UINT4) 38016083u); /* 22 */ MD5_GG ( c, d, a, b, in[15], MD5_S23, (UINT4) 3634488961u); /* 23 */ MD5_GG ( b, c, d, a, in[ 4], MD5_S24, (UINT4) 3889429448u); /* 24 */ MD5_GG ( a, b, c, d, in[ 9], MD5_S21, (UINT4) 568446438u); /* 25 */ MD5_GG ( d, a, b, c, in[14], MD5_S22, (UINT4) 3275163606u); /* 26 */ MD5_GG ( c, d, a, b, in[ 3], MD5_S23, (UINT4) 4107603335u); /* 27 */ MD5_GG ( b, c, d, a, in[ 8], MD5_S24, (UINT4) 1163531501u); /* 28 */ MD5_GG ( a, b, c, d, in[13], MD5_S21, (UINT4) 2850285829u); /* 29 */ MD5_GG ( d, a, b, c, in[ 2], MD5_S22, (UINT4) 4243563512u); /* 30 */ MD5_GG ( c, d, a, b, in[ 7], MD5_S23, (UINT4) 1735328473u); /* 31 */ MD5_GG ( b, c, d, a, in[12], MD5_S24, (UINT4) 2368359562u); /* 32 */ /* Round 3 */ MD5_HH ( a, b, c, d, in[ 5], MD5_S31, (UINT4) 4294588738u); /* 33 */ MD5_HH ( d, a, b, c, in[ 8], MD5_S32, (UINT4) 2272392833u); /* 34 */ MD5_HH ( c, d, a, b, in[11], MD5_S33, (UINT4) 1839030562u); /* 35 */ MD5_HH ( b, c, d, a, in[14], MD5_S34, (UINT4) 4259657740u); /* 36 */ MD5_HH ( a, b, c, d, in[ 1], MD5_S31, (UINT4) 2763975236u); /* 37 */ MD5_HH ( d, a, b, c, in[ 4], MD5_S32, (UINT4) 1272893353u); /* 38 */ MD5_HH ( c, d, a, b, in[ 7], MD5_S33, (UINT4) 4139469664u); /* 39 */ MD5_HH ( b, c, d, a, in[10], MD5_S34, (UINT4) 3200236656u); /* 40 */ MD5_HH ( a, b, c, d, in[13], MD5_S31, (UINT4) 681279174u); /* 41 */ MD5_HH ( d, a, b, c, in[ 0], MD5_S32, (UINT4) 3936430074u); /* 42 */ MD5_HH ( c, d, a, b, in[ 3], MD5_S33, (UINT4) 3572445317u); /* 43 */ MD5_HH ( b, c, d, a, in[ 6], MD5_S34, (UINT4) 76029189u); /* 44 */ MD5_HH ( a, b, c, d, in[ 9], MD5_S31, (UINT4) 3654602809u); /* 45 */ MD5_HH ( d, a, b, c, in[12], MD5_S32, (UINT4) 3873151461u); /* 46 */ MD5_HH ( c, d, a, b, in[15], MD5_S33, (UINT4) 530742520u); /* 47 */ MD5_HH ( b, c, d, a, in[ 2], MD5_S34, (UINT4) 3299628645u); /* 48 */ /* Round 4 */ MD5_II ( a, b, c, d, in[ 0], MD5_S41, (UINT4) 4096336452u); /* 49 */ MD5_II ( d, a, b, c, in[ 7], MD5_S42, (UINT4) 1126891415u); /* 50 */ MD5_II ( c, d, a, b, in[14], MD5_S43, (UINT4) 2878612391u); /* 51 */ MD5_II ( b, c, d, a, in[ 5], MD5_S44, (UINT4) 4237533241u); /* 52 */ MD5_II ( a, b, c, d, in[12], MD5_S41, (UINT4) 1700485571u); /* 53 */ MD5_II ( d, a, b, c, in[ 3], MD5_S42, (UINT4) 2399980690u); /* 54 */ MD5_II ( c, d, a, b, in[10], MD5_S43, (UINT4) 4293915773u); /* 55 */ diff --git a/gammu/emb/common/misc/misc.c b/gammu/emb/common/misc/misc.c index c2f09e4..7227e7b 100644 --- a/gammu/emb/common/misc/misc.c +++ b/gammu/emb/common/misc/misc.c @@ -1,591 +1,600 @@ /* (c) 2002-2004 by Marcin Wiacek and Michal Cihar */ /* Checking used compiler (c) 2002 by Michal Cihar */ #include <string.h> #include <ctype.h> #include <time.h> #include <stdarg.h> #include <stdio.h> #include <locale.h> #include <sys/timeb.h> #ifdef WIN32 # include "windows.h" #endif +#if defined(linux) || defined(__linux) || defined(__linux__) +# include <sys/utsname.h> +#endif #include "../gsmstate.h" #include "misc.h" /* Based on article in Polish PC-Kurier 8/1998 page 104 * Archive on http://www.pckurier.pl */ char *DayOfWeek (int year, int month, int day) { int p,q,r,w; static char DayOfWeekChar[10]; p=(14-month) / 12; q=month+12*p-2; r=year-p; w=(day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7; strcpy(DayOfWeekChar,""); switch (w) { case 0: strcpy(DayOfWeekChar,"Sun"); break; case 1: strcpy(DayOfWeekChar,"Mon"); break; case 2: strcpy(DayOfWeekChar,"Tue"); break; case 3: strcpy(DayOfWeekChar,"Wed"); break; case 4: strcpy(DayOfWeekChar,"Thu"); break; case 5: strcpy(DayOfWeekChar,"Fri"); break; case 6: strcpy(DayOfWeekChar,"Sat"); break; } return DayOfWeekChar; } void Fill_GSM_DateTime(GSM_DateTime *Date, time_t timet) { struct tm *now; now = localtime(&timet); Date->Year = now->tm_year; Date->Month = now->tm_mon+1; Date->Day = now->tm_mday; Date->Hour = now->tm_hour; Date->Minute = now->tm_min; Date->Second = now->tm_sec; } void GSM_GetCurrentDateTime (GSM_DateTime *Date) { Fill_GSM_DateTime(Date, time(NULL)); if (Date->Year<1900) { if (Date->Year>90) Date->Year = Date->Year+1900; else Date->Year = Date->Year+2000; } } time_t Fill_Time_T(GSM_DateTime DT, int TZ) { struct tm tm_starttime; unsigned char buffer[30]; dbgprintf(" StartTime : %02i-%02i-%04i %02i:%02i:%02i\n", DT.Day,DT.Month,DT.Year,DT.Hour,DT.Minute,DT.Second); if (TZ != 0) { #if defined(WIN32) || defined(__SVR4) sprintf(buffer,"TZ=PST+%i",TZ); putenv(buffer); #else sprintf(buffer,"PST+%i",TZ); setenv("TZ",buffer,1); #endif } tzset(); memset(&tm_starttime, 0, sizeof(tm_starttime)); tm_starttime.tm_year = DT.Year - 1900; tm_starttime.tm_mon = DT.Month - 1; tm_starttime.tm_mday = DT.Day; tm_starttime.tm_hour = DT.Hour; tm_starttime.tm_min = DT.Minute; tm_starttime.tm_sec = DT.Second; tm_starttime.tm_isdst = 0; return mktime(&tm_starttime); } void GetTimeDifference(unsigned long diff, GSM_DateTime *DT, bool Plus, int multi) { time_t t_time; t_time = Fill_Time_T(*DT,8); if (Plus) { t_time += diff*multi; } else { t_time -= diff*multi; } Fill_GSM_DateTime(DT, t_time); DT->Year = DT->Year + 1900; dbgprintf(" EndTime : %02i-%02i-%04i %02i:%02i:%02i\n", DT->Day,DT->Month,DT->Year,DT->Hour,DT->Minute,DT->Second); } char *OSDateTime (GSM_DateTime dt, bool TimeZone) { struct tm timeptr; static char retval[200],retval2[200]; int p,q,r,w; #ifdef WIN32 setlocale(LC_ALL, ".OCP"); #endif /* Based on article in Polish PC-Kurier 8/1998 page 104 * Archive on http://www.pckurier.pl */ p=(14-dt.Month) / 12; q=dt.Month+12*p-2; r=dt.Year-p; w=(dt.Day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7; timeptr.tm_yday = 0; /* FIXME */ timeptr.tm_isdst = -1; /* FIXME */ timeptr.tm_year = dt.Year - 1900; timeptr.tm_mon = dt.Month - 1; timeptr.tm_mday = dt.Day; timeptr.tm_hour = dt.Hour; timeptr.tm_min = dt.Minute; timeptr.tm_sec = dt.Second; timeptr.tm_wday = w; #ifdef _BSD_SOURCE timeptr.tm_zone = NULL; #endif #ifdef WIN32 strftime(retval2, 200, "%#c", &timeptr); #else strftime(retval2, 200, "%c", &timeptr); #endif if (TimeZone) { if (dt.Timezone >= 0) { sprintf(retval," +%02i00",dt.Timezone); } else { sprintf(retval," -%02i00",dt.Timezone); } strcat(retval2,retval); } /* If don't have weekday name, include it */ strftime(retval, 200, "%A", &timeptr); if (strstr(retval2,retval)==NULL) { /* Check for abbreviated weekday */ strftime(retval, 200, "%a", &timeptr); if (strstr(retval2,retval)==NULL) { strcat(retval2," ("); strcat(retval2,retval); strcat(retval2,")"); } } #ifdef WIN32 setlocale(LC_ALL, ".ACP"); #endif return retval2; } char *OSDate (GSM_DateTime dt) { struct tm timeptr; static char retval[200],retval2[200]; int p,q,r,w; #ifdef WIN32 setlocale(LC_ALL, ".OCP"); #endif /* Based on article in Polish PC-Kurier 8/1998 page 104 * Archive on http://www.pckurier.pl */ p=(14-dt.Month) / 12; q=dt.Month+12*p-2; r=dt.Year-p; w=(dt.Day+(31*q) / 12 + r + r / 4 - r / 100 + r / 400) % 7; timeptr.tm_yday = 0; /* FIXME */ timeptr.tm_isdst = -1; /* FIXME */ timeptr.tm_year = dt.Year - 1900; timeptr.tm_mon = dt.Month - 1; timeptr.tm_mday = dt.Day; timeptr.tm_hour = dt.Hour; timeptr.tm_min = dt.Minute; timeptr.tm_sec = dt.Second; timeptr.tm_wday = w; #ifdef _BSD_SOURCE timeptr.tm_zone = NULL; #endif #ifdef WIN32 strftime(retval2, 200, "%#x", &timeptr); #else strftime(retval2, 200, "%x", &timeptr); #endif /* If don't have weekday name, include it */ strftime(retval, 200, "%A", &timeptr); if (strstr(retval2,retval)==NULL) { /* Check also for short name */ strftime(retval, 200, "%a", &timeptr); if (strstr(retval2,retval)==NULL) { strcat(retval2," ("); strcat(retval2,retval); strcat(retval2,")"); } } #ifdef WIN32 setlocale(LC_ALL, ".ACP"); #endif return retval2; } bool CheckDate(GSM_DateTime *date) -{ - /* FIXME: This could also check if day is correct for selected month */ +{ + const unsigned int days[]={31,29,31,30,31,30,31,31,30,31,30,31}; + + /* FIXME: This could also check for leap years */ return date->Year != 0 && - date->Month >= 1 && date->Month <= 12 && - date->Day >= 1 && date->Day <= 31; + date->Month >= 1 && date->Month <= 12 && + date->Day >= 1 && date->Day <= days[date->Month]; } bool CheckTime(GSM_DateTime *date) { return date->Hour <= 23 && date->Hour >= 0 && date->Minute <= 59 && date->Minute >= 0 && date->Second <= 59 && date->Second >= 0; } int GetLine(FILE *File, char *Line, int count) { int num; if (fgets(Line, count, File) != NULL) { num = strlen(Line) - 1; while(1) { if (Line[num] != '\n' && Line[num] != '\r') break; if (num == 0) break; Line[num--] = 0; } return strlen(Line); } return -1; } void SplitLines(unsigned char *message, int messagesize, GSM_Lines *lines, unsigned char *whitespaces, int spaceslen, bool eot) { int i,number=0,j; bool whitespace=true, nowwhite; for (i=0;i<MAX_LINES*2;i++) lines->numbers[i]=0; for (i=0;i<messagesize;i++) { nowwhite = false; for (j=0;j<spaceslen;j++) { if (whitespaces[j] == message[i]) { nowwhite = true; break; } } if (whitespace) { if (!nowwhite) { lines->numbers[number]=i; number++; whitespace=false; } } else { if (nowwhite) { lines->numbers[number]=i; number++; whitespace=true; } } } if (eot && !whitespace) lines->numbers[number]=messagesize; } char *GetLineString(unsigned char *message, GSM_Lines lines, int start) { static char retval[800]; memcpy(retval,message + lines.numbers[start*2-2],lines.numbers[start*2-2+1]-lines.numbers[start*2-2]); retval[lines.numbers[start*2-2+1]-lines.numbers[start*2-2]]=0; return retval; } void CopyLineString(unsigned char *dest, unsigned char *src, GSM_Lines lines, int start) { memcpy(dest,GetLineString(src, lines, start),strlen(GetLineString(src, lines, start))); dest[strlen(GetLineString(src, lines, start))] = 0; } Debug_Info di = {0,NULL,false,""}; #ifdef DEBUG #ifdef __GNUC__ __attribute__((format(printf, 1, 2))) #endif int dbgprintf(const char *format, ...) { va_list argp; int result; static unsigned char nextline[2000]=""; unsigned char buffer[2000]; GSM_DateTime date_time; if (di.df != NULL && (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE)) { va_start(argp, format); result = vsprintf(buffer, format, argp); strcat(nextline, buffer); if (strstr(buffer, "\n")) { if (di.dl == DL_TEXTALLDATE) { GSM_GetCurrentDateTime(&date_time); fprintf(di.df,"%s %4d/%02d/%02d %02d:%02d:%02d: %s", DayOfWeek(date_time.Year, date_time.Month, date_time.Day), date_time.Year, date_time.Month, date_time.Day, date_time.Hour, date_time.Minute, date_time.Second,nextline); } else { fprintf(di.df,"%s",nextline); } strcpy(nextline, ""); } fflush(di.df); va_end(argp); return result; } return 0; } #endif /* assumption: if \n is present it is always the last char, * string never of the form "......\n..." */ #ifdef __GNUC__ __attribute__((format(printf, 3, 4))) #endif int smfprintf(FILE *f, Debug_Level dl, const char *format, ...) { va_list argp; int result=0; static unsigned char prevline[2000] = "", nextline[2000]=""; static unsigned int linecount=0; unsigned char buffer[2000]; GSM_DateTime date_time; if (f == NULL) return 0; va_start(argp, format); result = vsprintf(buffer, format, argp); strcat(nextline, buffer); if (strstr(buffer, "\n")) { if (ftell(f) < 5000000) { GSM_GetCurrentDateTime(&date_time); if (linecount > 0) { if (dl == DL_TEXTALLDATE || dl == DL_TEXTERRORDATE || dl == DL_TEXTDATE) { fprintf(f,"%s %4d/%02d/%02d %02d:%02d:%02d: <%i> %s", DayOfWeek(date_time.Year, date_time.Month, date_time.Day), date_time.Year, date_time.Month, date_time.Day, date_time.Hour, date_time.Minute, date_time.Second,linecount,prevline); } else { fprintf(f,"%s",prevline); } } linecount=0; if (dl == DL_TEXTALLDATE || dl == DL_TEXTERRORDATE || dl == DL_TEXTDATE) { fprintf(f,"%s %4d/%02d/%02d %02d:%02d:%02d: %s", DayOfWeek(date_time.Year, date_time.Month, date_time.Day), date_time.Year, date_time.Month, date_time.Day, date_time.Hour, date_time.Minute, date_time.Second,nextline); } else { fprintf(f,"%s",nextline); } strcpy(prevline, nextline); } strcpy(nextline, ""); fflush(f); } va_end(argp); return result; } bool GSM_SetDebugLevel(char *info, Debug_Info *di) { if (!strcmp(info,"nothing")) {di->dl = 0; return true;} if (!strcmp(info,"text")) {di->dl = DL_TEXT; return true;} if (!strcmp(info,"textall")) {di->dl = DL_TEXTALL; return true;} if (!strcmp(info,"binary")) {di->dl = DL_BINARY; return true;} if (!strcmp(info,"errors")) {di->dl = DL_TEXTERROR; return true;} if (!strcmp(info,"textdate")) {di->dl = DL_TEXTDATE; return true;} if (!strcmp(info,"textalldate")) {di->dl = DL_TEXTALLDATE; return true;} if (!strcmp(info,"errorsdate")) {di->dl = DL_TEXTERRORDATE; return true;} return false; } /* Dumps a message */ void DumpMessage(FILE *df, Debug_Level dl, const unsigned char *message, int messagesize) { int i,j=0,len=16; unsigned char buffer[200]; if (df==NULL || messagesize == 0) return; smfprintf(df, dl, "\n"); memset(buffer,0x20,sizeof(buffer)); buffer[len*5-1]=0; for (i = 0; i < messagesize; i++) { sprintf(buffer+j*4,"%02X",message[i]); buffer[j*4+2] = 0x20; if (isprint(message[i]) && message[i]!=0x09) { if (j != len-1) buffer[j*4+2] = message[i]; buffer[(len-1)*4+j+3] = message[i]; } else { buffer[(len-1)*4+j+3] = '.'; } if (j != len-1 && i != messagesize-1) buffer[j*4+3] = '|'; if (j == len-1) { smfprintf(df, dl, "%s\n", buffer); memset(buffer,0x20,sizeof(buffer)); buffer[len*5-1]=0; j = 0; } else { j++; } } if (j != 0) smfprintf(df, dl, "%s\n", buffer); } char *GetOS(void) { #ifdef WIN32 OSVERSIONINFOEX Ver; bool Extended = true; #endif +#if defined(linux) || defined(__linux) || defined(__linux__) + struct utsname Ver; +#endif static char Buffer[100] = {0x00}; #ifdef WIN32 memset(&Ver,sizeof(OSVERSIONINFOEX),0); Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if (!GetVersionEx((OSVERSIONINFO *)&Ver)) { Extended = false; Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx((OSVERSIONINFO *)&Ver)) { //#ifdef _MSC_VER
// Ver.dwMajorVersion = _winmajor; // Ver.dwMinorVersion = _winminor; // Ver.dwBuildNumber = _osver; //#else sprintf(Buffer, "Windows"); return Buffer; //#endif } } /* ----------------- 9x family ------------------ */ /* no info about Win95 SP1, Win95 OSR2.1, Win95 OSR2.5.... */ if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 950) { sprintf(Buffer,"Win 95"); } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 1111) { sprintf(Buffer,"Win 95 OSR2.x"); /* no info about Win98 SP1.... */ } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 10 && Ver.dwBuildNumber == 1998) { sprintf(Buffer,"Win 98"); } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 10 && Ver.dwBuildNumber == 2222) { sprintf(Buffer,"Win 98 SE"); } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 90 && Ver.dwBuildNumber == 3000) { sprintf(Buffer,"Win ME"); /* ---------------- NT family ------------------- */ } else if (Ver.dwMajorVersion == 4 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 1381) { sprintf(Buffer,"Win NT 4.0"); } else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 0 && Ver.dwBuildNumber == 2195) { sprintf(Buffer,"Win 2000"); } else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 1 && Ver.dwBuildNumber == 2600) { sprintf(Buffer,"Win XP"); #if _MSC_VER > 1200 //6.0 has it undeclared
if (Extended) { if (Ver.wSuiteMask & VER_SUITE_PERSONAL) { sprintf(Buffer+strlen(Buffer)," Home"); } else { sprintf(Buffer+strlen(Buffer)," Pro"); } }
#endif } else if (Ver.dwMajorVersion == 5 && Ver.dwMinorVersion == 2) { sprintf(Buffer,"Win 2003"); } else { sprintf(Buffer, "Windows %i.%i.%i",Ver.dwMajorVersion,Ver.dwMinorVersion,Ver.dwBuildNumber); } if (Extended && Ver.wServicePackMajor != 0) { sprintf(Buffer+strlen(Buffer)," SP%i",Ver.wServicePackMajor); } #elif defined(linux) || defined(__linux) || defined(__linux__) - sprintf(Buffer, "Linux"); + uname(&Ver); + sprintf(Buffer, "Linux, kernel %s",Ver.release); #elif defined(__FreeBSD__) sprintf(Buffer, "FreeBSD"); #elif defined(__NetBSD__) sprintf(Buffer, "NetBSD"); #elif defined(__OpenBSD__) sprintf(Buffer, "OpenBSD"); #elif defined(__GNU__) sprintf(Buffer, "GNU/Hurd"); #elif defined(sun) || defined(__sun) || defined(__sun__) # ifdef __SVR4 sprintf(Buffer, "Sun Solaris"); # else sprintf(Buffer, "SunOS"); # endif #elif defined(hpux) || defined(__hpux) || defined(__hpux__) sprintf(Buffer, "HP-UX"); #elif defined(ultrix) || defined(__ultrix) || defined(__ultrix__) sprintf(Buffer, "DEC Ultrix"); #elif defined(sgi) || defined(__sgi) sprintf(Buffer, "SGI Irix"); #elif defined(__osf__) sprintf(Buffer, "OSF Unix"); #elif defined(bsdi) || defined(__bsdi__) sprintf(Buffer, "BSDI Unix"); #elif defined(_AIX) sprintf(Buffer, "AIX Unix"); #elif defined(_UNIXWARE) sprintf(Buffer, "SCO Unixware"); #elif defined(DGUX) sprintf(Buffer, "DG Unix"); #elif defined(__QNX__) sprintf(Buffer, "QNX"); #endif return Buffer; } char *GetCompiler(void) { static char Buffer[100] = {0x00}; #ifdef WIN32 # ifdef _MSC_VER if (_MSC_VER == 1200) { //? sprintf(Buffer, "MS VC 6.0"); } else if (_MSC_VER == 1300) { sprintf(Buffer, "MS VC .NET 2002"); } else if (_MSC_VER == 1310) { sprintf(Buffer, "MS VC .NET 2003"); } else { sprintf(Buffer, "MS VC %i",_MSC_VER); } # elif defined(__BORLANDC__) sprintf(Buffer, "Borland C++ %i",__BORLANDC__); # endif #elif defined(DJGPP) sprintf(Buffer, "djgpp"); #elif defined(__GNUC__) sprintf(Buffer, "gcc %i.%i", __GNUC__, __GNUC_MINOR__); #elif defined(__SUNPRO_CC) sprintf(Buffer, "Sun C++ %x", __SUNPRO_CC); #endif return Buffer; } /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/misc/misc.h b/gammu/emb/common/misc/misc.h index 8b46170..c461001 100644 --- a/gammu/emb/common/misc/misc.h +++ b/gammu/emb/common/misc/misc.h @@ -1,137 +1,145 @@ /* (c) 2002-2004 by Marcin Wiacek */ #ifndef __misc_h #define __misc_h +#if defined(_MSC_VER) && defined(__cplusplus) + extern "C" { +#endif + #include <stdio.h> #include <time.h> #ifdef WIN32 # include <windows.h> #endif #include "../config.h" #ifndef __cplusplus #ifndef false # define false 0 #endif #ifndef true # define true !0 #endif #ifndef bool # define bool char #endif #endif /* __cplusplus */ #ifdef WIN32 # define my_sleep(x) ((x)<1000 ? Sleep(1) : Sleep((x)/1000)) #else # define my_sleep(x) usleep(x) #endif #undef MAX #define MAX(a,b) ((a)>(b) ? (a) : (b)) #undef MIN #define MIN(a,b) ((a)<(b) ? (a) : (b)) /* ------------------------------------------------------------------------- */ #define MAX_LINES 50 int GetLine(FILE *File, char *Line, int count); typedef struct { int numbers[MAX_LINES*2]; } GSM_Lines; void SplitLines(unsigned char *message, int messagesize, GSM_Lines *lines, unsigned char *whitespaces, int spaceslen, bool eot); char *GetLineString(unsigned char *message, GSM_Lines lines, int start); void CopyLineString(unsigned char *dest, unsigned char *src, GSM_Lines lines, int start); /* ------------------------------------------------------------------------- */ typedef enum { DL_BINARY = 1, /* Binary transmission dump */ DL_TEXT, /* Text transmission dump */ DL_TEXTALL, /* Everything */ DL_TEXTERROR, /* Only errors */ DL_TEXTDATE, /* Text transmission dump */ DL_TEXTALLDATE, /* Everything */ DL_TEXTERRORDATE /* Only errors */ } Debug_Level; typedef struct { Debug_Level dl; FILE *df; bool use_global; char *coding; } Debug_Info; extern Debug_Info di; #ifdef DEBUG #ifdef __GNUC__ __attribute__((format(printf, 1, 2))) #endif int dbgprintf(const char *format, ...); #else # ifndef WIN32 # define dbgprintf(a...) do { } while (0) # else # define dbgprintf # endif #endif #ifdef __GNUC__ __attribute__((format(printf, 3, 4))) #endif int smfprintf(FILE *f, Debug_Level dl, const char *format, ...); void DumpMessage(FILE *df, Debug_Level dl, const unsigned char *message, int messagesize); bool GSM_SetDebugLevel(char *info, Debug_Info *di); /* ------------------------------------------------------------------------- */ /** * Structure used for saving date and time */ typedef struct { /** * The difference between local time and GMT in hours */ int Timezone; unsigned int Second; unsigned int Minute; unsigned int Hour; unsigned int Day; /** * January = 1, February = 2, etc. */ unsigned int Month; /** * Complete year number. Not 03, but 2003 */ unsigned int Year; } GSM_DateTime; void GSM_GetCurrentDateTime (GSM_DateTime *Date); char *OSDateTime (GSM_DateTime dt, bool TimeZone); char *OSDate (GSM_DateTime dt); char *DayOfWeek (int year, int month, int day); time_t Fill_Time_T (GSM_DateTime DT, int TZ); void GetTimeDifference (unsigned long diff, GSM_DateTime *DT, bool Plus, int multi); void Fill_GSM_DateTime (GSM_DateTime *Date, time_t timet); bool CheckDate (GSM_DateTime *date); bool CheckTime (GSM_DateTime *date); char *GetCompiler(void); char *GetOS(void); +#if defined(_MSC_VER) && defined(__cplusplus) + } +#endif + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ |