summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/misc
authorzautrix <zautrix>2004-10-05 11:13:51 (UTC)
committer zautrix <zautrix>2004-10-05 11:13:51 (UTC)
commit50ab40e1e02ad7c65c17a78d08116a808b1257aa (patch) (side-by-side diff)
tree0d1939e2297fa7bbd8e1f2030f154463854164c6 /gammu/emb/common/misc
parentcf8616f64f20e5448d4ff644f7cc15750cf3f85f (diff)
downloadkdepimpi-50ab40e1e02ad7c65c17a78d08116a808b1257aa.zip
kdepimpi-50ab40e1e02ad7c65c17a78d08116a808b1257aa.tar.gz
kdepimpi-50ab40e1e02ad7c65c17a78d08116a808b1257aa.tar.bz2
updated to latest gammu version
Diffstat (limited to 'gammu/emb/common/misc') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/misc/coding/coding.c177
-rw-r--r--gammu/emb/common/misc/coding/coding.h27
-rw-r--r--gammu/emb/common/misc/coding/md5.c2
-rw-r--r--gammu/emb/common/misc/misc.c19
-rw-r--r--gammu/emb/common/misc/misc.h8
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:
*/