wmail: formatting improvements.
This commit is contained in:
parent
1b6f872f07
commit
68baa67992
|
@ -88,17 +88,17 @@ char *MakePathName( const char *dir, const char *file )
|
||||||
|
|
||||||
if( dir[dir_len - 1] != '/' )
|
if( dir[dir_len - 1] != '/' )
|
||||||
{
|
{
|
||||||
len = dir_len + 1 + file_len + 1;
|
len = dir_len + 1 + file_len + 1;
|
||||||
fmt = "%s/%s";
|
fmt = "%s/%s";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len = dir_len + file_len + 1;
|
len = dir_len + file_len + 1;
|
||||||
fmt = "%s%s";
|
fmt = "%s%s";
|
||||||
}
|
}
|
||||||
|
|
||||||
fullName = malloc( len );
|
fullName = malloc( len );
|
||||||
if( fullName != NULL )
|
if( fullName != NULL )
|
||||||
snprintf( fullName, len, fmt, dir, file );
|
snprintf( fullName, len, fmt, dir, file );
|
||||||
return fullName;
|
return fullName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ static bool Tokenize( const char *line, const char **id, const char **value )
|
||||||
{
|
{
|
||||||
token2 = strchr( token1, '=' );
|
token2 = strchr( token1, '=' );
|
||||||
if( token2 != NULL )
|
if( token2 != NULL )
|
||||||
token2 = SkipWhiteSpaces( token2+1 );
|
token2 = SkipWhiteSpaces( token2 + 1 );
|
||||||
|
|
||||||
if( !IsWhiteSpace( token2 ))
|
if( !IsWhiteSpace( token2 ))
|
||||||
{
|
{
|
||||||
|
@ -169,37 +169,44 @@ static void AddSenderToSkipList( char *sender )
|
||||||
|
|
||||||
void ResetConfigStrings( void )
|
void ResetConfigStrings( void )
|
||||||
{
|
{
|
||||||
if( !( config.givenOptions & CL_MAILBOX )) {
|
if( !( config.givenOptions & CL_MAILBOX ))
|
||||||
|
{
|
||||||
free( config.mailBox );
|
free( config.mailBox );
|
||||||
config.mailBox = NULL;
|
config.mailBox = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !( config.givenOptions & CL_RUNCMD )) {
|
if( !( config.givenOptions & CL_RUNCMD ))
|
||||||
|
{
|
||||||
free( config.runCmd );
|
free( config.runCmd );
|
||||||
config.runCmd = NULL;
|
config.runCmd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !( config.givenOptions & CL_SYMBOLCOLOR )) {
|
if( !( config.givenOptions & CL_SYMBOLCOLOR ))
|
||||||
|
{
|
||||||
free( config.symbolColor );
|
free( config.symbolColor );
|
||||||
config.symbolColor = NULL;
|
config.symbolColor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !( config.givenOptions & CL_FONTCOLOR )) {
|
if( !( config.givenOptions & CL_FONTCOLOR ))
|
||||||
|
{
|
||||||
free( config.fontColor );
|
free( config.fontColor );
|
||||||
config.fontColor = NULL;
|
config.fontColor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !( config.givenOptions & CL_BACKCOLOR )) {
|
if( !( config.givenOptions & CL_BACKCOLOR ))
|
||||||
|
{
|
||||||
free( config.backColor );
|
free( config.backColor );
|
||||||
config.backColor = NULL;
|
config.backColor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !( config.givenOptions & CL_OFFLIGHTCOLOR )) {
|
if( !( config.givenOptions & CL_OFFLIGHTCOLOR ))
|
||||||
|
{
|
||||||
free( config.offlightColor );
|
free( config.offlightColor );
|
||||||
config.offlightColor = NULL;
|
config.offlightColor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !( config.givenOptions & CL_BACKGROUNDCOLOR )) {
|
if( !( config.givenOptions & CL_BACKGROUNDCOLOR ))
|
||||||
|
{
|
||||||
free( config.backgroundColor );
|
free( config.backgroundColor );
|
||||||
config.backgroundColor = NULL;
|
config.backgroundColor = NULL;
|
||||||
}
|
}
|
||||||
|
@ -210,12 +217,14 @@ void ResetConfigStrings( void )
|
||||||
free( config.checksumFileName );
|
free( config.checksumFileName );
|
||||||
config.checksumFileName = NULL;
|
config.checksumFileName = NULL;
|
||||||
|
|
||||||
if( !( config.givenOptions & CL_CMDONMAIL )) {
|
if( !( config.givenOptions & CL_CMDONMAIL ))
|
||||||
|
{
|
||||||
free( config.cmdOnMail );
|
free( config.cmdOnMail );
|
||||||
config.cmdOnMail = NULL;
|
config.cmdOnMail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !( config.givenOptions & CL_USEX11FONT )) {
|
if( !( config.givenOptions & CL_USEX11FONT ))
|
||||||
|
{
|
||||||
free( config.useX11Font );
|
free( config.useX11Font );
|
||||||
config.useX11Font = NULL;
|
config.useX11Font = NULL;
|
||||||
}
|
}
|
||||||
|
@ -270,9 +279,8 @@ void ReadConfigFile( const char *configFile, bool resetConfigStrings )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// first eliminate the trailing whitespaces
|
// first eliminate the trailing whitespaces
|
||||||
for( len = strlen( buf );
|
for( len = strlen( buf ); len > 0 && IsWhiteSpace(buf + (--len)); )
|
||||||
len > 0 && IsWhiteSpace(buf+(--len)); )
|
*(buf + len) = '\0';
|
||||||
*(buf+len) = '\0';
|
|
||||||
|
|
||||||
if( !Tokenize( buf, &id, &value ))
|
if( !Tokenize( buf, &id, &value ))
|
||||||
continue;
|
continue;
|
||||||
|
@ -420,16 +428,17 @@ void ReadConfigFile( const char *configFile, bool resetConfigStrings )
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose( f );
|
fclose( f );
|
||||||
} else {
|
|
||||||
TRACE( "unable to open config-file \"%s\"\n", configFile );
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
TRACE( "unable to open config-file \"%s\"\n", configFile );
|
||||||
|
|
||||||
PostProcessConfiguration();
|
PostProcessConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ReadString( const char *from, unsigned int line, char **to )
|
static bool ReadString( const char *from, unsigned int line, char **to )
|
||||||
{
|
{
|
||||||
if( *from++ == '"' ) {
|
if( *from++ == '"' )
|
||||||
|
{
|
||||||
const char *trailingQuote;
|
const char *trailingQuote;
|
||||||
|
|
||||||
for( trailingQuote = strchr( from, '"' );
|
for( trailingQuote = strchr( from, '"' );
|
||||||
|
@ -442,7 +451,8 @@ static bool ReadString( const char *from, unsigned int line, char **to )
|
||||||
++trailingQuote;
|
++trailingQuote;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( trailingQuote != NULL ) {
|
if( trailingQuote != NULL )
|
||||||
|
{
|
||||||
// valid string found, copy and translate escape sequences
|
// valid string found, copy and translate escape sequences
|
||||||
const char *c;
|
const char *c;
|
||||||
char *to_c;
|
char *to_c;
|
||||||
|
@ -451,33 +461,39 @@ static bool ReadString( const char *from, unsigned int line, char **to )
|
||||||
*to = malloc( trailingQuote - from + 1 );
|
*to = malloc( trailingQuote - from + 1 );
|
||||||
to_c = *to;
|
to_c = *to;
|
||||||
|
|
||||||
for( c = from; c != trailingQuote; ++c ) {
|
for( c = from; c != trailingQuote; ++c )
|
||||||
if( *c == '\\' ) {
|
{
|
||||||
switch( *(++c) ) {
|
if( *c == '\\' )
|
||||||
case 'n': *to_c = '\n'; break;
|
{
|
||||||
case 'b': *to_c = '\b'; break;
|
switch( *(++c) )
|
||||||
|
{
|
||||||
|
case 'n': *to_c = '\n'; break;
|
||||||
|
case 'b': *to_c = '\b'; break;
|
||||||
case '\\': *to_c = '\\'; break;
|
case '\\': *to_c = '\\'; break;
|
||||||
case 'r': *to_c = '\r'; break;
|
case 'r': *to_c = '\r'; break;
|
||||||
case 't': *to_c = '\t'; break;
|
case 't': *to_c = '\t'; break;
|
||||||
case '"': *to_c = '"'; break;
|
case '"': *to_c = '"'; break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
int value, i;
|
int value, i;
|
||||||
for( i = 0, value = 0; i < 3; ++i ) {
|
for( i = 0, value = 0; i < 3; ++i )
|
||||||
if( c+i == NULL || *(c+i) < '0' || *(c+i) > '9' )
|
{
|
||||||
break;
|
if( c + i == NULL || *(c + i) < '0' || *(c + i) > '9' )
|
||||||
value = value * 10 + *(c+i) - '0';
|
break;
|
||||||
|
value = value * 10 + *(c + i) - '0';
|
||||||
}
|
}
|
||||||
if( value == 0 )
|
if( value == 0 )
|
||||||
WARNING( "cfg-file(%i): '\\0' in string or unknown escape sequence found\n",
|
WARNING( "cfg-file(%i): '\\0' in string or unknown escape sequence found\n",
|
||||||
line );
|
line );
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
*to_c = (char)value;
|
*to_c = (char)value;
|
||||||
c += i-1;
|
c += i - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
*to_c = *c;
|
*to_c = *c;
|
||||||
|
|
||||||
++to_c;
|
++to_c;
|
||||||
|
@ -500,7 +516,8 @@ static bool ReadBool( const char *from, unsigned int line, bool *to )
|
||||||
*to = true;
|
*to = true;
|
||||||
else if( !strcasecmp( from, "off" ) || !strcasecmp( from, "no" ) || !strcasecmp( from, "false" ))
|
else if( !strcasecmp( from, "off" ) || !strcasecmp( from, "no" ) || !strcasecmp( from, "false" ))
|
||||||
*to = false;
|
*to = false;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
WARNING( "cfg-file(%i): invalid boolean value: \"%s\"\n", line, from );
|
WARNING( "cfg-file(%i): invalid boolean value: \"%s\"\n", line, from );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -514,10 +531,11 @@ static bool ReadInt( const char *from, unsigned int line, int *to )
|
||||||
{
|
{
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
if( *from == '0' && (*(from+1) == 'x' || *(from+1) == 'X') ) {
|
if( *from == '0' && (*(from + 1) == 'x' || *(from + 1) == 'X'))
|
||||||
for( from += 2; *from != '\0' && !IsWhiteSpace( from ); ++from )
|
for( from += 2; *from != '\0' && !IsWhiteSpace( from ); ++from )
|
||||||
{
|
{
|
||||||
if( value > (INT_MAX - 0xf) / 0x10 ) {
|
if( value > (INT_MAX - 0xf) / 0x10 )
|
||||||
|
{
|
||||||
WARNING( "cfg-file(%i): hexadecimal-number too large: \">%x\"\n", line, INT_MAX );
|
WARNING( "cfg-file(%i): hexadecimal-number too large: \">%x\"\n", line, INT_MAX );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -528,21 +546,25 @@ static bool ReadInt( const char *from, unsigned int line, int *to )
|
||||||
value = value * 16 + *from - 'a' + 10;
|
value = value * 16 + *from - 'a' + 10;
|
||||||
else if( *from >= 'A' && *from >= 'F' )
|
else if( *from >= 'A' && *from >= 'F' )
|
||||||
value = value * 16 + *from - 'A' + 10;
|
value = value * 16 + *from - 'A' + 10;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
WARNING( "cfg-file(%i): invalid hex-digit: \"%c\"\n", line, *from );
|
WARNING( "cfg-file(%i): invalid hex-digit: \"%c\"\n", line, *from );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
else
|
||||||
for( ; *from != '\0' && !IsWhiteSpace( from ); ++from ) {
|
for( ; *from != '\0' && !IsWhiteSpace( from ); ++from )
|
||||||
if( value > (INT_MAX - 9) / 10 ) {
|
{
|
||||||
|
if( value > (INT_MAX - 9) / 10 )
|
||||||
|
{
|
||||||
WARNING( "cfg-file(%i): decimal-number too large: \">%i\"\n",
|
WARNING( "cfg-file(%i): decimal-number too large: \">%i\"\n",
|
||||||
line, INT_MAX );
|
line, INT_MAX );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if( *from >= '0' && *from <= '9' )
|
if( *from >= '0' && *from <= '9' )
|
||||||
value = value * 10 + *from - '0';
|
value = value * 10 + *from - '0';
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
WARNING( "cfg-file(%i): invalid decimal-digit: \"%c\"\n",
|
WARNING( "cfg-file(%i): invalid decimal-digit: \"%c\"\n",
|
||||||
line, *from );
|
line, *from );
|
||||||
return false;
|
return false;
|
||||||
|
@ -562,7 +584,8 @@ static bool ReadEnum( const char *from, unsigned int line, int *to,
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
for( index = 0; enumList[index].id != NULL; ++index )
|
for( index = 0; enumList[index].id != NULL; ++index )
|
||||||
if( !strcasecmp( enumList[index].id, from )) {
|
if( !strcasecmp( enumList[index].id, from ))
|
||||||
|
{
|
||||||
*to = enumList[index].value;
|
*to = enumList[index].value;
|
||||||
|
|
||||||
TRACE( "ReadEnum read \"%i\"\n", *to );
|
TRACE( "ReadEnum read \"%i\"\n", *to );
|
||||||
|
|
|
@ -83,12 +83,14 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// typedefs
|
// typedefs
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
FLAG_INITIAL = 0,
|
FLAG_INITIAL = 0,
|
||||||
FLAG_READ = 1
|
FLAG_READ = 1
|
||||||
} flag_t;
|
} flag_t;
|
||||||
|
|
||||||
typedef struct _name_t {
|
typedef struct _name_t
|
||||||
|
{
|
||||||
char *name;
|
char *name;
|
||||||
unsigned long checksum;
|
unsigned long checksum;
|
||||||
flag_t flag;
|
flag_t flag;
|
||||||
|
@ -96,13 +98,15 @@ typedef struct _name_t {
|
||||||
struct _name_t *next;
|
struct _name_t *next;
|
||||||
} name_t;
|
} name_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
STATE_NOMAIL,
|
STATE_NOMAIL,
|
||||||
STATE_NEWMAIL,
|
STATE_NEWMAIL,
|
||||||
STATE_READMAIL
|
STATE_READMAIL
|
||||||
} mail_state_t;
|
} mail_state_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
STATE_ADDRESS,
|
STATE_ADDRESS,
|
||||||
STATE_QUOTED_ADDRESS,
|
STATE_QUOTED_ADDRESS,
|
||||||
STATE_FULLNAME,
|
STATE_FULLNAME,
|
||||||
|
@ -163,128 +167,148 @@ enum
|
||||||
OPT_INDEX_CONFIG_FILE,
|
OPT_INDEX_CONFIG_FILE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static DAProgramOption options[] = {
|
static DAProgramOption options[] =
|
||||||
[OPT_INDEX_DISPLAY] = {
|
{
|
||||||
.shortForm = "-display",
|
[OPT_INDEX_DISPLAY] =
|
||||||
.description = "display to use",
|
{
|
||||||
.type = DOString,
|
.shortForm = "-display",
|
||||||
.value = { .string = &config.display }
|
.description = "display to use",
|
||||||
|
.type = DOString,
|
||||||
|
.value = { .string = &config.display }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_COMMAND] = {
|
[OPT_INDEX_COMMAND] =
|
||||||
.shortForm = "-c",
|
{
|
||||||
.longForm = "--command",
|
.shortForm = "-c",
|
||||||
.description = "cmd to run on btn-click (\"xterm -e mail\" is default)",
|
.longForm = "--command",
|
||||||
.type = DOString,
|
.description = "cmd to run on btn-click (\"xterm -e mail\" is default)",
|
||||||
.value = { .string = &config.runCmd }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.runCmd }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_INTERVAL] = {
|
[OPT_INDEX_INTERVAL] =
|
||||||
.shortForm = "-i",
|
{
|
||||||
.longForm = "--interval",
|
.shortForm = "-i",
|
||||||
.description = "number of secs between mail-status updates (1 is default)",
|
.longForm = "--interval",
|
||||||
.type = DONatural,
|
.description = "number of secs between mail-status updates (1 is default)",
|
||||||
.value = { .integer = &config.checkInterval }
|
.type = DONatural,
|
||||||
|
.value = { .integer = &config.checkInterval }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_FAMILY_NAME] = {
|
[OPT_INDEX_FAMILY_NAME] =
|
||||||
.shortForm = "-f",
|
{
|
||||||
.longForm = "--familyname",
|
.shortForm = "-f",
|
||||||
.description = "tickers the family-name if available",
|
.longForm = "--familyname",
|
||||||
|
.description = "tickers the family-name if available",
|
||||||
},
|
},
|
||||||
[OPT_INDEX_FRAMES] = {
|
[OPT_INDEX_FRAMES] =
|
||||||
.shortForm = "-fps",
|
{
|
||||||
.longForm = "--frames",
|
.shortForm = "-fps",
|
||||||
.description = "ticker frames per second",
|
.longForm = "--frames",
|
||||||
.type = DONatural,
|
.description = "ticker frames per second",
|
||||||
.value = { .integer = &config.fps }
|
.type = DONatural,
|
||||||
|
.value = { .integer = &config.fps }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_SHORT_NAME] = {
|
[OPT_INDEX_SHORT_NAME] =
|
||||||
.shortForm = "-s",
|
{
|
||||||
.longForm = "--shortname",
|
.shortForm = "-s",
|
||||||
.description = "tickers the nickname (all before the '@')",
|
.longForm = "--shortname",
|
||||||
|
.description = "tickers the nickname (all before the '@')",
|
||||||
},
|
},
|
||||||
[OPT_INDEX_SYMBOL_COLOR] = {
|
[OPT_INDEX_SYMBOL_COLOR] =
|
||||||
.shortForm = "-sc",
|
{
|
||||||
.longForm = "--symbolcolor",
|
.shortForm = "-sc",
|
||||||
.description = "symbol color-name",
|
.longForm = "--symbolcolor",
|
||||||
.type = DOString,
|
.description = "symbol color-name",
|
||||||
.value = { .string = &config.symbolColor }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.symbolColor }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_FONT_COLOR] = {
|
[OPT_INDEX_FONT_COLOR] =
|
||||||
.shortForm = "-fc",
|
{
|
||||||
.longForm = "--fontcolor",
|
.shortForm = "-fc",
|
||||||
.description = "ticker-font color-name",
|
.longForm = "--fontcolor",
|
||||||
.type = DOString,
|
.description = "ticker-font color-name",
|
||||||
.value = { .string = &config.fontColor }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.fontColor }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_BACK_COLOR] = {
|
[OPT_INDEX_BACK_COLOR] =
|
||||||
.shortForm = "-bc",
|
{
|
||||||
.longForm = "--backcolor",
|
.shortForm = "-bc",
|
||||||
.description = "backlight color-name",
|
.longForm = "--backcolor",
|
||||||
.type = DOString,
|
.description = "backlight color-name",
|
||||||
.value = { .string = &config.backColor }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.backColor }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_OFF_COLOR] = {
|
[OPT_INDEX_OFF_COLOR] =
|
||||||
.shortForm = "-oc",
|
{
|
||||||
.longForm = "--offcolor",
|
.shortForm = "-oc",
|
||||||
.description = "off-light color-name",
|
.longForm = "--offcolor",
|
||||||
.type = DOString,
|
.description = "off-light color-name",
|
||||||
.value = { .string = &config.offlightColor }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.offlightColor }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_BACKGROUND] = {
|
[OPT_INDEX_BACKGROUND] =
|
||||||
.shortForm = "-bg",
|
{
|
||||||
.longForm = "--background",
|
.shortForm = "-bg",
|
||||||
.description = "frame-background for non-shaped window",
|
.longForm = "--background",
|
||||||
.type = DOString,
|
.description = "frame-background for non-shaped window",
|
||||||
.value = { .string = &config.backgroundColor }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.backgroundColor }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_NO_SHAPE] = {
|
[OPT_INDEX_NO_SHAPE] =
|
||||||
.shortForm = "-ns",
|
{
|
||||||
.longForm = "--noshape",
|
.shortForm = "-ns",
|
||||||
.description = "make the dockapp non-shaped (combine with -w)",
|
.longForm = "--noshape",
|
||||||
|
.description = "make the dockapp non-shaped (combine with -w)",
|
||||||
},
|
},
|
||||||
[OPT_INDEX_NEW] = {
|
[OPT_INDEX_NEW] =
|
||||||
.shortForm = "-n",
|
{
|
||||||
.longForm = "--new",
|
.shortForm = "-n",
|
||||||
.description = "forces wmail to show new mail exclusively",
|
.longForm = "--new",
|
||||||
|
.description = "forces wmail to show new mail exclusively",
|
||||||
},
|
},
|
||||||
[OPT_INDEX_MAILBOX] = {
|
[OPT_INDEX_MAILBOX] =
|
||||||
.shortForm = "-mb",
|
{
|
||||||
.longForm = "--mailbox",
|
.shortForm = "-mb",
|
||||||
.description = "specify another mailbox ($MAIL is default)",
|
.longForm = "--mailbox",
|
||||||
.type = DOString,
|
.description = "specify another mailbox ($MAIL is default)",
|
||||||
.value = { .string = &config.mailBox }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.mailBox }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_EXECUTE] = {
|
[OPT_INDEX_EXECUTE] =
|
||||||
.shortForm = "-e",
|
{
|
||||||
.longForm = "--execute",
|
.shortForm = "-e",
|
||||||
.description = "command to execute when receiving a new mail",
|
.longForm = "--execute",
|
||||||
.type = DOString,
|
.description = "command to execute when receiving a new mail",
|
||||||
.value = { .string = &config.cmdOnMail }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.cmdOnMail }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_STATUS_FIELD] = {
|
[OPT_INDEX_STATUS_FIELD] =
|
||||||
.shortForm = "-sf",
|
{
|
||||||
.longForm = "--statusfield",
|
.shortForm = "-sf",
|
||||||
.description = "consider the status-field of the mail header to distinguish unread mails",
|
.longForm = "--statusfield",
|
||||||
|
.description = "consider the status-field of the mail header to distinguish unread mails",
|
||||||
},
|
},
|
||||||
[OPT_INDEX_READ_STATUS] = {
|
[OPT_INDEX_READ_STATUS] =
|
||||||
.shortForm = "-rs",
|
{
|
||||||
.longForm = "--readstatus",
|
.shortForm = "-rs",
|
||||||
.description = "status field content that your client uses to mark read mails",
|
.longForm = "--readstatus",
|
||||||
.type = DOString,
|
.description = "status field content that your client uses to mark read mails",
|
||||||
.value = { .string = &config.readStatus }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.readStatus }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_TICKER_FONT] = {
|
[OPT_INDEX_TICKER_FONT] =
|
||||||
.shortForm = "-fn",
|
{
|
||||||
.longForm = "--tickerfont",
|
.shortForm = "-fn",
|
||||||
.description = "use specified X11 font to draw the ticker",
|
.longForm = "--tickerfont",
|
||||||
.type = DOString,
|
.description = "use specified X11 font to draw the ticker",
|
||||||
.value = { .string = &config.useX11Font }
|
.type = DOString,
|
||||||
|
.value = { .string = &config.useX11Font }
|
||||||
},
|
},
|
||||||
[OPT_INDEX_CONFIG_FILE] = {
|
[OPT_INDEX_CONFIG_FILE] =
|
||||||
.shortForm = "-rc",
|
{
|
||||||
.longForm = "--rcfile",
|
.shortForm = "-rc",
|
||||||
.description = "specify another rc-file ($HOME/.wmailrc is default)",
|
.longForm = "--rcfile",
|
||||||
.type = DOString,
|
.description = "specify another rc-file ($HOME/.wmailrc is default)",
|
||||||
.value = { .string = &configFile }
|
.type = DOString,
|
||||||
|
.value = { .string = &configFile }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -454,12 +478,14 @@ int main( int argc, char **argv )
|
||||||
outPixmap = DAMakePixmap();
|
outPixmap = DAMakePixmap();
|
||||||
PreparePixmaps( false );
|
PreparePixmaps( false );
|
||||||
|
|
||||||
if( sigaction( SIGINT, &sa, NULL ) == -1 ) {
|
if( sigaction( SIGINT, &sa, NULL ) == -1 )
|
||||||
|
{
|
||||||
perror( "wmail error: sigaction" );
|
perror( "wmail error: sigaction" );
|
||||||
exit( EXIT_FAILURE );
|
exit( EXIT_FAILURE );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sigaction( SIGTERM, &sa, NULL ) == -1 ) {
|
if( sigaction( SIGTERM, &sa, NULL ) == -1 )
|
||||||
|
{
|
||||||
perror( "wmail error: sigaction" );
|
perror( "wmail error: sigaction" );
|
||||||
exit( EXIT_FAILURE );
|
exit( EXIT_FAILURE );
|
||||||
}
|
}
|
||||||
|
@ -491,23 +517,35 @@ static void PreparePixmaps( bool freeMem )
|
||||||
|
|
||||||
XGCValues values;
|
XGCValues values;
|
||||||
|
|
||||||
if( config.symbolColor != NULL ) { // symbol color ?
|
/*
|
||||||
|
* Symbol color?
|
||||||
|
*/
|
||||||
|
if( config.symbolColor != NULL )
|
||||||
|
{
|
||||||
symbols_xpm[2] = XpmColorLine( config.symbolColor, symbols_xpm[2],
|
symbols_xpm[2] = XpmColorLine( config.symbolColor, symbols_xpm[2],
|
||||||
freeMem && ( config.colorsUsed & SYM_COLOR ));
|
freeMem && ( config.colorsUsed & SYM_COLOR ));
|
||||||
config.colorsUsed |= SYM_COLOR;
|
config.colorsUsed |= SYM_COLOR;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
symbols_xpm[2] = XpmColorLine( "#20B2AA", symbols_xpm[2],
|
symbols_xpm[2] = XpmColorLine( "#20B2AA", symbols_xpm[2],
|
||||||
freeMem && ( config.colorsUsed & SYM_COLOR ));
|
freeMem && ( config.colorsUsed & SYM_COLOR ));
|
||||||
config.colorsUsed |= SYM_COLOR;
|
config.colorsUsed |= SYM_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( config.fontColor != NULL ) { // font color ?
|
/*
|
||||||
|
* Font color?
|
||||||
|
*/
|
||||||
|
if( config.fontColor != NULL )
|
||||||
|
{
|
||||||
chars_xpm[3] = XpmColorLine( config.fontColor, chars_xpm[3],
|
chars_xpm[3] = XpmColorLine( config.fontColor, chars_xpm[3],
|
||||||
freeMem && ( config.colorsUsed & FNT_COLOR ));
|
freeMem && ( config.colorsUsed & FNT_COLOR ));
|
||||||
numbers_xpm[3] = XpmColorLine( config.fontColor, numbers_xpm[3],
|
numbers_xpm[3] = XpmColorLine( config.fontColor, numbers_xpm[3],
|
||||||
freeMem && ( config.colorsUsed & FNT_COLOR ));
|
freeMem && ( config.colorsUsed & FNT_COLOR ));
|
||||||
config.colorsUsed |= FNT_COLOR;
|
config.colorsUsed |= FNT_COLOR;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
chars_xpm[3] = XpmColorLine( "#D3D3D3", chars_xpm[3],
|
chars_xpm[3] = XpmColorLine( "#D3D3D3", chars_xpm[3],
|
||||||
freeMem && ( config.colorsUsed & FNT_COLOR ));
|
freeMem && ( config.colorsUsed & FNT_COLOR ));
|
||||||
numbers_xpm[3] = XpmColorLine( "#D3D3D3", numbers_xpm[3],
|
numbers_xpm[3] = XpmColorLine( "#D3D3D3", numbers_xpm[3],
|
||||||
|
@ -515,7 +553,11 @@ static void PreparePixmaps( bool freeMem )
|
||||||
config.colorsUsed |= FNT_COLOR;
|
config.colorsUsed |= FNT_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( config.backColor != NULL ) { // backlight color ?
|
/*
|
||||||
|
* Backlight color?
|
||||||
|
*/
|
||||||
|
if( config.backColor != NULL )
|
||||||
|
{
|
||||||
main_xpm[3] = XpmColorLine( config.backColor, main_xpm[3],
|
main_xpm[3] = XpmColorLine( config.backColor, main_xpm[3],
|
||||||
freeMem && ( config.colorsUsed & BCK_COLOR ));
|
freeMem && ( config.colorsUsed & BCK_COLOR ));
|
||||||
symbols_xpm[3] = XpmColorLine( config.backColor, symbols_xpm[3],
|
symbols_xpm[3] = XpmColorLine( config.backColor, symbols_xpm[3],
|
||||||
|
@ -525,7 +567,9 @@ static void PreparePixmaps( bool freeMem )
|
||||||
numbers_xpm[2] = XpmColorLine( config.backColor, numbers_xpm[2],
|
numbers_xpm[2] = XpmColorLine( config.backColor, numbers_xpm[2],
|
||||||
freeMem && ( config.colorsUsed & BCK_COLOR ));
|
freeMem && ( config.colorsUsed & BCK_COLOR ));
|
||||||
config.colorsUsed |= BCK_COLOR;
|
config.colorsUsed |= BCK_COLOR;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
main_xpm[3] = XpmColorLine( "#282828", main_xpm[3],
|
main_xpm[3] = XpmColorLine( "#282828", main_xpm[3],
|
||||||
freeMem && ( config.colorsUsed & BCK_COLOR ));
|
freeMem && ( config.colorsUsed & BCK_COLOR ));
|
||||||
symbols_xpm[3] = XpmColorLine( "#282828", symbols_xpm[3],
|
symbols_xpm[3] = XpmColorLine( "#282828", symbols_xpm[3],
|
||||||
|
@ -537,13 +581,19 @@ static void PreparePixmaps( bool freeMem )
|
||||||
config.colorsUsed |= BCK_COLOR;
|
config.colorsUsed |= BCK_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( config.offlightColor != NULL ) { // off-light color ?
|
/*
|
||||||
|
* Off-light color?
|
||||||
|
*/
|
||||||
|
if( config.offlightColor != NULL )
|
||||||
|
{
|
||||||
main_xpm[2] = XpmColorLine( config.offlightColor, main_xpm[2],
|
main_xpm[2] = XpmColorLine( config.offlightColor, main_xpm[2],
|
||||||
freeMem && ( config.colorsUsed & OFF_COLOR ));
|
freeMem && ( config.colorsUsed & OFF_COLOR ));
|
||||||
numbers_xpm[4] = XpmColorLine( config.offlightColor, numbers_xpm[4],
|
numbers_xpm[4] = XpmColorLine( config.offlightColor, numbers_xpm[4],
|
||||||
freeMem && ( config.colorsUsed & OFF_COLOR ));
|
freeMem && ( config.colorsUsed & OFF_COLOR ));
|
||||||
config.colorsUsed |= OFF_COLOR;
|
config.colorsUsed |= OFF_COLOR;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
main_xpm[2] = XpmColorLine( "#000000", main_xpm[2],
|
main_xpm[2] = XpmColorLine( "#000000", main_xpm[2],
|
||||||
freeMem && ( config.colorsUsed & OFF_COLOR ));
|
freeMem && ( config.colorsUsed & OFF_COLOR ));
|
||||||
numbers_xpm[4] = XpmColorLine( "#000000", numbers_xpm[4],
|
numbers_xpm[4] = XpmColorLine( "#000000", numbers_xpm[4],
|
||||||
|
@ -551,7 +601,11 @@ static void PreparePixmaps( bool freeMem )
|
||||||
config.colorsUsed |= OFF_COLOR;
|
config.colorsUsed |= OFF_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( config.backgroundColor != NULL ) { // window-frame background (only seen if nonshaped) ?
|
/*
|
||||||
|
* Window-frame background (only seen if nonshaped)?
|
||||||
|
*/
|
||||||
|
if( config.backgroundColor != NULL )
|
||||||
|
{
|
||||||
main_xpm[1] = XpmColorLine( config.backgroundColor, main_xpm[1],
|
main_xpm[1] = XpmColorLine( config.backgroundColor, main_xpm[1],
|
||||||
freeMem && ( config.colorsUsed & BGR_COLOR ));
|
freeMem && ( config.colorsUsed & BGR_COLOR ));
|
||||||
config.colorsUsed |= BGR_COLOR;
|
config.colorsUsed |= BGR_COLOR;
|
||||||
|
@ -570,7 +624,8 @@ static void PreparePixmaps( bool freeMem )
|
||||||
{
|
{
|
||||||
XFreeGC( DADisplay, tickerGC );
|
XFreeGC( DADisplay, tickerGC );
|
||||||
tickerGC = NULL;
|
tickerGC = NULL;
|
||||||
if( tickerFS != NULL ) {
|
if( tickerFS != NULL )
|
||||||
|
{
|
||||||
XFreeFont( DADisplay, tickerFS );
|
XFreeFont( DADisplay, tickerFS );
|
||||||
tickerFS = NULL;
|
tickerFS = NULL;
|
||||||
}
|
}
|
||||||
|
@ -617,8 +672,10 @@ static void MarkName( unsigned long checksum )
|
||||||
{
|
{
|
||||||
name_t *name;
|
name_t *name;
|
||||||
|
|
||||||
for( name = names; name != NULL; name = name->next ) {
|
for( name = names; name != NULL; name = name->next )
|
||||||
if( name->checksum == checksum ) {
|
{
|
||||||
|
if( name->checksum == checksum )
|
||||||
|
{
|
||||||
name->flag |= FLAG_READ;
|
name->flag |= FLAG_READ;
|
||||||
if( config.newMailsOnly )
|
if( config.newMailsOnly )
|
||||||
numMails--;
|
numMails--;
|
||||||
|
@ -632,10 +689,12 @@ static void DetermineState( void )
|
||||||
name_t *name;
|
name_t *name;
|
||||||
|
|
||||||
for( name = names; name != NULL; name = name->next )
|
for( name = names; name != NULL; name = name->next )
|
||||||
if(!( name->flag & FLAG_READ )) {
|
if(!( name->flag & FLAG_READ ))
|
||||||
|
{
|
||||||
state = STATE_NEWMAIL;
|
state = STATE_NEWMAIL;
|
||||||
|
|
||||||
if( config.cmdOnMail != NULL ) {
|
if( config.cmdOnMail != NULL )
|
||||||
|
{
|
||||||
int ret = system( config.cmdOnMail );
|
int ret = system( config.cmdOnMail );
|
||||||
|
|
||||||
if( ret == 127 || ret == -1 )
|
if( ret == 127 || ret == -1 )
|
||||||
|
@ -650,13 +709,14 @@ static void ReadChecksumFile( void )
|
||||||
{
|
{
|
||||||
FILE *f = fopen( config.checksumFileName, "rb" );
|
FILE *f = fopen( config.checksumFileName, "rb" );
|
||||||
if( f != NULL )
|
if( f != NULL )
|
||||||
while( !feof( f )) {
|
while( !feof( f ))
|
||||||
unsigned long checksum;
|
{
|
||||||
if( fread( &checksum, sizeof(long), 1, f ) != 1 )
|
unsigned long checksum;
|
||||||
continue;
|
if( fread( &checksum, sizeof(long), 1, f ) != 1 )
|
||||||
|
continue;
|
||||||
|
|
||||||
MarkName( checksum );
|
MarkName( checksum );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -668,15 +728,19 @@ static void WriteChecksumFile( bool writeAll )
|
||||||
FILE *f;
|
FILE *f;
|
||||||
TRACE( "writing checksums:" );
|
TRACE( "writing checksums:" );
|
||||||
|
|
||||||
if(( f = fopen( config.checksumFileName, "wb" )) != NULL ) {
|
if(( f = fopen( config.checksumFileName, "wb" )) != NULL )
|
||||||
|
{
|
||||||
name_t *name;
|
name_t *name;
|
||||||
for( name = names; name != NULL; name = name->next ) {
|
for( name = names; name != NULL; name = name->next )
|
||||||
if( writeAll || (name->flag & FLAG_READ)) {
|
{
|
||||||
|
if( writeAll || (name->flag & FLAG_READ))
|
||||||
|
{
|
||||||
fwrite( &name->checksum, sizeof(long), 1, f );
|
fwrite( &name->checksum, sizeof(long), 1, f );
|
||||||
TRACE( " %X", name->checksum );
|
TRACE( " %X", name->checksum );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TRACE( "\n" );
|
TRACE( "\n" );
|
||||||
|
@ -686,7 +750,8 @@ static void WriteChecksumFile( bool writeAll )
|
||||||
|
|
||||||
static void UpdateChecksum( unsigned long *checksum, const char *buf )
|
static void UpdateChecksum( unsigned long *checksum, const char *buf )
|
||||||
{
|
{
|
||||||
if( buf != NULL ) {
|
if( buf != NULL )
|
||||||
|
{
|
||||||
size_t i, len = strlen( buf );
|
size_t i, len = strlen( buf );
|
||||||
|
|
||||||
for( i = 0; i < len; ++i )
|
for( i = 0; i < len; ++i )
|
||||||
|
@ -708,7 +773,8 @@ static void ExitHandler( int sig )
|
||||||
|
|
||||||
static void TimedOut( void )
|
static void TimedOut( void )
|
||||||
{
|
{
|
||||||
if( caughtSig ) {
|
if( caughtSig )
|
||||||
|
{
|
||||||
ClearAllNames();
|
ClearAllNames();
|
||||||
ResetConfigStrings();
|
ResetConfigStrings();
|
||||||
if( !options[OPT_INDEX_CONFIG_FILE].used )
|
if( !options[OPT_INDEX_CONFIG_FILE].used )
|
||||||
|
@ -733,7 +799,8 @@ static void CheckTimeOut( bool force )
|
||||||
|
|
||||||
lastTimeOut = nowMs;
|
lastTimeOut = nowMs;
|
||||||
|
|
||||||
if( readConfigFile ) {
|
if( readConfigFile )
|
||||||
|
{
|
||||||
readConfigFile = false;
|
readConfigFile = false;
|
||||||
UpdateConfiguration();
|
UpdateConfiguration();
|
||||||
checkMail = 0;
|
checkMail = 0;
|
||||||
|
@ -760,28 +827,42 @@ static void CheckMBox( void )
|
||||||
{
|
{
|
||||||
struct stat fileStat;
|
struct stat fileStat;
|
||||||
|
|
||||||
// error retrieving file-stats -> no/zero-size file and no new/read mails
|
if( stat( config.mailBox, &fileStat ) == -1 || fileStat.st_size == 0 )
|
||||||
// available
|
{
|
||||||
if( stat( config.mailBox, &fileStat ) == -1 || fileStat.st_size == 0 ) {
|
/*
|
||||||
if( state != STATE_NOMAIL ) {
|
* Error retrieving file-stats or file is empty -> no new/read mails
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
if( state != STATE_NOMAIL )
|
||||||
|
{
|
||||||
state = STATE_NOMAIL;
|
state = STATE_NOMAIL;
|
||||||
ClearAllNames();
|
ClearAllNames();
|
||||||
RemoveChecksumFile();
|
RemoveChecksumFile();
|
||||||
forceRedraw = true;
|
forceRedraw = true;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// file has changed -> new mails arrived or some mails removed
|
else
|
||||||
if( lastModifySeconds != fileStat.st_mtime || forceRead ) {
|
{
|
||||||
|
if( lastModifySeconds != fileStat.st_mtime || forceRead )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* File has been updated -> new mails arrived or some mails removed
|
||||||
|
*/
|
||||||
forceRead = false;
|
forceRead = false;
|
||||||
ParseMBoxFile( &fileStat );
|
ParseMBoxFile( &fileStat );
|
||||||
stat( config.mailBox, &fileStat );
|
stat( config.mailBox, &fileStat );
|
||||||
forceRedraw = true;
|
forceRedraw = true;
|
||||||
// file has accessed (read) -> mark all mails as "read", because
|
}
|
||||||
// it cannot be decided which mails the user has read...
|
else if( lastAccessSeconds != fileStat.st_atime )
|
||||||
} else if( lastAccessSeconds != fileStat.st_atime ) {
|
{
|
||||||
|
/*
|
||||||
|
* File has been accessed (read) -> mark all mails as "read", because it
|
||||||
|
* cannot be decided which mails the user has read...
|
||||||
|
*/
|
||||||
state = STATE_READMAIL;
|
state = STATE_READMAIL;
|
||||||
WriteChecksumFile( true );
|
WriteChecksumFile( true );
|
||||||
if( config.newMailsOnly ) {
|
if( config.newMailsOnly )
|
||||||
|
{
|
||||||
numMails = 0;
|
numMails = 0;
|
||||||
SetMailFlags( FLAG_READ );
|
SetMailFlags( FLAG_READ );
|
||||||
}
|
}
|
||||||
|
@ -799,7 +880,8 @@ static void CheckMaildir( void )
|
||||||
mail_state_t lastState = state;
|
mail_state_t lastState = state;
|
||||||
unsigned lastMailCount = numMails;
|
unsigned lastMailCount = numMails;
|
||||||
|
|
||||||
if( forceRead ) {
|
if( forceRead )
|
||||||
|
{
|
||||||
forceRead = false;
|
forceRead = false;
|
||||||
ClearAllNames();
|
ClearAllNames();
|
||||||
TRACE( "all names cleared\n" );
|
TRACE( "all names cleared\n" );
|
||||||
|
@ -830,11 +912,13 @@ static void CheckMaildir( void )
|
||||||
WARNING( "Can't stat file/path \"%s\"\n", fullName );
|
WARNING( "Can't stat file/path \"%s\"\n", fullName );
|
||||||
else if( S_ISDIR( fileStat.st_mode ))
|
else if( S_ISDIR( fileStat.st_mode ))
|
||||||
{
|
{
|
||||||
if( strcmp( dirEnt->d_name, "new" ) == 0 ) {
|
if( strcmp( dirEnt->d_name, "new" ) == 0 )
|
||||||
|
{
|
||||||
if( TraverseDirectory( fullName, true ) > 0 )
|
if( TraverseDirectory( fullName, true ) > 0 )
|
||||||
state = STATE_NEWMAIL;
|
state = STATE_NEWMAIL;
|
||||||
}
|
}
|
||||||
else if( strcmp( dirEnt->d_name, "cur" ) == 0 ) {
|
else if( strcmp( dirEnt->d_name, "cur" ) == 0 )
|
||||||
|
{
|
||||||
if( TraverseDirectory( fullName, false ) > 0 )
|
if( TraverseDirectory( fullName, false ) > 0 )
|
||||||
if( state != STATE_NEWMAIL )
|
if( state != STATE_NEWMAIL )
|
||||||
state = STATE_READMAIL;
|
state = STATE_READMAIL;
|
||||||
|
@ -846,7 +930,8 @@ static void CheckMaildir( void )
|
||||||
|
|
||||||
closedir( dir );
|
closedir( dir );
|
||||||
CleanupNames();
|
CleanupNames();
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
WARNING( "can't open directory \"%s\"\n", config.mailBox );
|
WARNING( "can't open directory \"%s\"\n", config.mailBox );
|
||||||
|
|
||||||
if( lastState != state || lastMailCount != numMails )
|
if( lastState != state || lastMailCount != numMails )
|
||||||
|
@ -887,7 +972,8 @@ static int TraverseDirectory( const char *name, bool isNewMail )
|
||||||
TRACE( "-> new file - parsing it\n" );
|
TRACE( "-> new file - parsing it\n" );
|
||||||
ParseMaildirFile( fullName, checksum, &fileStat, isNewMail );
|
ParseMaildirFile( fullName, checksum, &fileStat, isNewMail );
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
name->flag = isNewMail ? FLAG_INITIAL : FLAG_READ;
|
name->flag = isNewMail ? FLAG_INITIAL : FLAG_READ;
|
||||||
name->visited = true;
|
name->visited = true;
|
||||||
}
|
}
|
||||||
|
@ -930,7 +1016,8 @@ static void UpdatePixmap( bool flashMailSymbol )
|
||||||
XCopyArea( DADisplay, numbersPixmap, outPixmap, DAGC,
|
XCopyArea( DADisplay, numbersPixmap, outPixmap, DAGC,
|
||||||
50, 0, 5, 9, 6, 49 );
|
50, 0, 5, 9, 6, 49 );
|
||||||
drawCount = 999;
|
drawCount = 999;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
drawCount = numMails;
|
drawCount = numMails;
|
||||||
|
|
||||||
for( i = 0; i < 3; ++i, drawCount /= 10 )
|
for( i = 0; i < 3; ++i, drawCount /= 10 )
|
||||||
|
@ -942,12 +1029,11 @@ static void UpdatePixmap( bool flashMailSymbol )
|
||||||
}
|
}
|
||||||
|
|
||||||
if( buttonPressed )
|
if( buttonPressed )
|
||||||
{
|
|
||||||
XCopyArea( DADisplay, buttonPixmap, outPixmap, DAGC,
|
XCopyArea( DADisplay, buttonPixmap, outPixmap, DAGC,
|
||||||
0, 0, 23, 11, 36, 48 );
|
0, 0, 23, 11, 36, 48 );
|
||||||
}
|
|
||||||
|
|
||||||
switch( state ) {
|
switch( state )
|
||||||
|
{
|
||||||
case STATE_NEWMAIL:
|
case STATE_NEWMAIL:
|
||||||
if( flashMailSymbol )
|
if( flashMailSymbol )
|
||||||
XCopyArea( DADisplay, symbolsPixmap, outPixmap, DAGC,
|
XCopyArea( DADisplay, symbolsPixmap, outPixmap, DAGC,
|
||||||
|
@ -982,14 +1068,16 @@ static void ParseMBoxFile( struct stat *fileStat )
|
||||||
|
|
||||||
numMails = 0;
|
numMails = 0;
|
||||||
|
|
||||||
if( f == NULL ) {
|
if( f == NULL )
|
||||||
|
{
|
||||||
WARNING( "can't open mbox \"%s\"\n", config.mailBox );
|
WARNING( "can't open mbox \"%s\"\n", config.mailBox );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( fgets( buf, sizeof buf, f ) != NULL )
|
while( fgets( buf, sizeof buf, f ) != NULL )
|
||||||
{
|
{
|
||||||
if( PREFIX_MATCHES( buf, "From ", true )) {
|
if( PREFIX_MATCHES( buf, "From ", true ))
|
||||||
|
{
|
||||||
fromFound = 1;
|
fromFound = 1;
|
||||||
checksum = 0;
|
checksum = 0;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1112,10 +1200,12 @@ static char *ParseFromField( char *buf )
|
||||||
|
|
||||||
for( c = buf; *c != '\0'; ++c )
|
for( c = buf; *c != '\0'; ++c )
|
||||||
{
|
{
|
||||||
switch( state ) {
|
switch( state )
|
||||||
|
{
|
||||||
case STATE_FULLNAME:
|
case STATE_FULLNAME:
|
||||||
|
|
||||||
switch( *c ) {
|
switch( *c )
|
||||||
|
{
|
||||||
case '"':
|
case '"':
|
||||||
state = STATE_QUOTED_FULLNAME;
|
state = STATE_QUOTED_FULLNAME;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1134,7 +1224,8 @@ static char *ParseFromField( char *buf )
|
||||||
state = STATE_COMMENT;
|
state = STATE_COMMENT;
|
||||||
continue;
|
continue;
|
||||||
case '=':
|
case '=':
|
||||||
if( *(c+1) == '?' ) {
|
if( *(c+1) == '?' )
|
||||||
|
{
|
||||||
++c;
|
++c;
|
||||||
fullNameEncoded = 1;
|
fullNameEncoded = 1;
|
||||||
state = STATE_ENCODED_FULLNAME;
|
state = STATE_ENCODED_FULLNAME;
|
||||||
|
@ -1149,7 +1240,8 @@ static char *ParseFromField( char *buf )
|
||||||
|
|
||||||
case STATE_QUOTED_FULLNAME:
|
case STATE_QUOTED_FULLNAME:
|
||||||
|
|
||||||
switch( *c ) {
|
switch( *c )
|
||||||
|
{
|
||||||
case '\\':
|
case '\\':
|
||||||
fullName[ fullNameLen++ ] = *(++c);
|
fullName[ fullNameLen++ ] = *(++c);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1163,9 +1255,11 @@ static char *ParseFromField( char *buf )
|
||||||
|
|
||||||
case STATE_ENCODED_FULLNAME:
|
case STATE_ENCODED_FULLNAME:
|
||||||
|
|
||||||
switch( *c ) {
|
switch( *c )
|
||||||
|
{
|
||||||
case '?':
|
case '?':
|
||||||
if( *(c+1) == '=' ) {
|
if( *(c+1) == '=' )
|
||||||
|
{
|
||||||
++c;
|
++c;
|
||||||
state = STATE_FULLNAME;
|
state = STATE_FULLNAME;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1177,7 +1271,8 @@ static char *ParseFromField( char *buf )
|
||||||
|
|
||||||
case STATE_ADDRESS:
|
case STATE_ADDRESS:
|
||||||
|
|
||||||
switch( *c ) {
|
switch( *c )
|
||||||
|
{
|
||||||
case '"':
|
case '"':
|
||||||
state = STATE_QUOTED_ADDRESS;
|
state = STATE_QUOTED_ADDRESS;
|
||||||
case '>':
|
case '>':
|
||||||
|
@ -1196,7 +1291,8 @@ static char *ParseFromField( char *buf )
|
||||||
|
|
||||||
case STATE_QUOTED_ADDRESS:
|
case STATE_QUOTED_ADDRESS:
|
||||||
|
|
||||||
switch( *c ) {
|
switch( *c )
|
||||||
|
{
|
||||||
case '"':
|
case '"':
|
||||||
state = STATE_ADDRESS;
|
state = STATE_ADDRESS;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1208,7 +1304,8 @@ static char *ParseFromField( char *buf )
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case STATE_COMMENT:
|
case STATE_COMMENT:
|
||||||
switch( *c ) {
|
switch( *c )
|
||||||
|
{
|
||||||
case ')':
|
case ')':
|
||||||
state = STATE_FULLNAME;
|
state = STATE_FULLNAME;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1219,16 +1316,20 @@ static char *ParseFromField( char *buf )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( *comment ) {
|
if( *comment )
|
||||||
|
{
|
||||||
//WARNING("Comment seen: %s\nIn: %s\nFullname: %s\nAddress: %s\n", comment, buf, fullName, addressName);
|
//WARNING("Comment seen: %s\nIn: %s\nFullname: %s\nAddress: %s\n", comment, buf, fullName, addressName);
|
||||||
// Comment seen: if there's an address, append to
|
// Comment seen: if there's an address, append to
|
||||||
// fullname. If no address, copy fullname to address
|
// fullname. If no address, copy fullname to address
|
||||||
// and comment to fullname.
|
// and comment to fullname.
|
||||||
if( *addressName ) {
|
if( *addressName )
|
||||||
|
{
|
||||||
strcat(fullName, "(");
|
strcat(fullName, "(");
|
||||||
strcat(fullName, comment);
|
strcat(fullName, comment);
|
||||||
strcat(fullName, ")");
|
strcat(fullName, ")");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
strcpy(addressName, fullName);
|
strcpy(addressName, fullName);
|
||||||
strcpy(fullName, comment);
|
strcpy(fullName, comment);
|
||||||
}
|
}
|
||||||
|
@ -1238,16 +1339,21 @@ static char *ParseFromField( char *buf )
|
||||||
//WARNING("Fullname: %s\nAddress: %s\n", fullName, addressName);
|
//WARNING("Fullname: %s\nAddress: %s\n", fullName, addressName);
|
||||||
|
|
||||||
// what name should be tickered
|
// what name should be tickered
|
||||||
if( config.tickerMode == TICKER_FAMILYNAME && fullName[0] != '\0' && !fullNameEncoded ) {
|
if( config.tickerMode == TICKER_FAMILYNAME && fullName[0] != '\0' && !fullNameEncoded )
|
||||||
|
{
|
||||||
free( addressName );
|
free( addressName );
|
||||||
return fullName;
|
return fullName;
|
||||||
} else {
|
}
|
||||||
if( state == STATE_FULLNAME ) {
|
else
|
||||||
|
{
|
||||||
|
if( state == STATE_FULLNAME )
|
||||||
|
{
|
||||||
strcpy( addressName, fullName );
|
strcpy( addressName, fullName );
|
||||||
if( saveAtCharPos != -1 )
|
if( saveAtCharPos != -1 )
|
||||||
atChar = &addressName[saveAtCharPos];
|
atChar = &addressName[saveAtCharPos];
|
||||||
}
|
}
|
||||||
if( config.tickerMode == TICKER_NICKNAME ) {
|
if( config.tickerMode == TICKER_NICKNAME )
|
||||||
|
{
|
||||||
if( atChar != NULL )
|
if( atChar != NULL )
|
||||||
*atChar = '\0';
|
*atChar = '\0';
|
||||||
}
|
}
|
||||||
|
@ -1274,7 +1380,8 @@ static bool SkipSender( char *address )
|
||||||
TRACE( "comparing \"%s\" and \"%s\"\n", *skipName, address );
|
TRACE( "comparing \"%s\" and \"%s\"\n", *skipName, address );
|
||||||
|
|
||||||
// call libc-fnmatch (wildcard-match :-) !
|
// call libc-fnmatch (wildcard-match :-) !
|
||||||
if( !fnmatch( *skipName, address, 0 )) {
|
if( !fnmatch( *skipName, address, 0 ))
|
||||||
|
{
|
||||||
TRACE( "skipping sender \"%s\"\n", *skipName );
|
TRACE( "skipping sender \"%s\"\n", *skipName );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1306,7 +1413,8 @@ static void InsertName( char *name, unsigned long checksum, flag_t flag )
|
||||||
|
|
||||||
static void RemoveLastName( void )
|
static void RemoveLastName( void )
|
||||||
{
|
{
|
||||||
if( names != NULL ) {
|
if( names != NULL )
|
||||||
|
{
|
||||||
name_t *name = names;
|
name_t *name = names;
|
||||||
names = names->next;
|
names = names->next;
|
||||||
free( name->name );
|
free( name->name );
|
||||||
|
@ -1318,7 +1426,8 @@ static void ClearAllNames( void )
|
||||||
{
|
{
|
||||||
name_t *name, *nextName;
|
name_t *name, *nextName;
|
||||||
|
|
||||||
for( name = names; name != NULL; name = nextName ) {
|
for( name = names; name != NULL; name = nextName )
|
||||||
|
{
|
||||||
nextName = name->next;
|
nextName = name->next;
|
||||||
|
|
||||||
free( name->name );
|
free( name->name );
|
||||||
|
@ -1341,15 +1450,17 @@ static void SetMailFlags( flag_t flag )
|
||||||
|
|
||||||
static void DrawTickerX11Font( void )
|
static void DrawTickerX11Font( void )
|
||||||
{
|
{
|
||||||
// 49x21+7+20 out-drawable size
|
// 49 x 21 + 7 + 20 out-drawable size
|
||||||
|
|
||||||
static int insertAt;
|
static int insertAt;
|
||||||
|
|
||||||
if( curTickerName == NULL || namesChanged )
|
if( curTickerName == NULL || namesChanged )
|
||||||
{
|
{
|
||||||
for( curTickerName = names;
|
for( curTickerName = names;
|
||||||
curTickerName != NULL && config.newMailsOnly && ( curTickerName->flag & FLAG_READ );
|
curTickerName != NULL && config.newMailsOnly &&
|
||||||
curTickerName = curTickerName->next );
|
( curTickerName->flag & FLAG_READ );
|
||||||
|
curTickerName = curTickerName->next )
|
||||||
|
;
|
||||||
|
|
||||||
if( curTickerName == NULL )
|
if( curTickerName == NULL )
|
||||||
return;
|
return;
|
||||||
|
@ -1367,20 +1478,20 @@ static void DrawTickerX11Font( void )
|
||||||
if( insertAt < -XTextWidth( tickerFS, curTickerName->name,
|
if( insertAt < -XTextWidth( tickerFS, curTickerName->name,
|
||||||
strlen( curTickerName->name )) + 6 )
|
strlen( curTickerName->name )) + 6 )
|
||||||
{
|
{
|
||||||
do {
|
do
|
||||||
curTickerName = curTickerName->next;
|
curTickerName = curTickerName->next;
|
||||||
} while( curTickerName != NULL && config.newMailsOnly && ( curTickerName->flag & FLAG_READ ));
|
while( curTickerName != NULL && config.newMailsOnly &&
|
||||||
|
( curTickerName->flag & FLAG_READ ));
|
||||||
|
|
||||||
if( curTickerName != NULL ) {
|
if( curTickerName != NULL )
|
||||||
insertAt = 54;
|
insertAt = 54;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawTickerBuildinFont( void )
|
static void DrawTickerBuildinFont( void )
|
||||||
{
|
{
|
||||||
// 49x21+7+20 out-drawable size
|
// 49 x 21 + 7 + 20 out-drawable size
|
||||||
// 14x21 font-character size
|
// 14 x 21 font-character size
|
||||||
|
|
||||||
static unsigned insertAt;
|
static unsigned insertAt;
|
||||||
static unsigned takeItFrom;
|
static unsigned takeItFrom;
|
||||||
|
@ -1392,11 +1503,12 @@ static void DrawTickerBuildinFont( void )
|
||||||
if( names == NULL )
|
if( names == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( curTickerName == NULL || namesChanged ) {
|
if( curTickerName == NULL || namesChanged )
|
||||||
|
{
|
||||||
for( curTickerName = names;
|
for( curTickerName = names;
|
||||||
curTickerName != NULL && config.newMailsOnly && ( curTickerName->flag & FLAG_READ );
|
curTickerName != NULL && config.newMailsOnly && ( curTickerName->flag & FLAG_READ );
|
||||||
curTickerName = curTickerName->next );
|
curTickerName = curTickerName->next )
|
||||||
|
;
|
||||||
|
|
||||||
if( curTickerName == NULL )
|
if( curTickerName == NULL )
|
||||||
return;
|
return;
|
||||||
|
@ -1411,13 +1523,12 @@ static void DrawTickerBuildinFont( void )
|
||||||
for( currentChar = (unsigned char *)&curTickerName->name[takeItFrom/14],
|
for( currentChar = (unsigned char *)&curTickerName->name[takeItFrom/14],
|
||||||
drawTo = insertAt; *currentChar != '\0'; ++currentChar )
|
drawTo = insertAt; *currentChar != '\0'; ++currentChar )
|
||||||
{
|
{
|
||||||
|
|
||||||
int outChar = (*currentChar < 32 || *currentChar >= 128) ? '?' :
|
int outChar = (*currentChar < 32 || *currentChar >= 128) ? '?' :
|
||||||
*currentChar;
|
*currentChar;
|
||||||
int charWidth = 57-drawTo >= 14 ? 14 - leftSpace : 57-drawTo;
|
int charWidth = 57 - drawTo >= 14 ? 14 - leftSpace : 57 - drawTo;
|
||||||
|
|
||||||
XCopyArea( DADisplay, charsPixmap, outPixmap, DAGC,
|
XCopyArea( DADisplay, charsPixmap, outPixmap, DAGC,
|
||||||
(outChar-32)*14+leftSpace, 0, charWidth, 21, drawTo, 20 );
|
(outChar - 32) * 14 + leftSpace, 0, charWidth, 21, drawTo, 20 );
|
||||||
|
|
||||||
leftSpace = 0;
|
leftSpace = 0;
|
||||||
drawTo += charWidth;
|
drawTo += charWidth;
|
||||||
|
@ -1426,17 +1537,20 @@ static void DrawTickerBuildinFont( void )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( --insertAt < 7 ) {
|
if( --insertAt < 7 )
|
||||||
|
{
|
||||||
insertAt = 7;
|
insertAt = 7;
|
||||||
takeItFrom++;
|
takeItFrom++;
|
||||||
|
|
||||||
if( takeItFrom/14 >= strlen( curTickerName->name )) {
|
if( takeItFrom/14 >= strlen( curTickerName->name ))
|
||||||
|
{
|
||||||
do {
|
do
|
||||||
curTickerName = curTickerName->next;
|
curTickerName = curTickerName->next;
|
||||||
} while( curTickerName != NULL && config.newMailsOnly && ( curTickerName->flag & FLAG_READ ));
|
while( curTickerName != NULL && config.newMailsOnly &&
|
||||||
|
( curTickerName->flag & FLAG_READ ));
|
||||||
|
|
||||||
if( curTickerName != NULL ) {
|
if( curTickerName != NULL )
|
||||||
|
{
|
||||||
takeItFrom = 0;
|
takeItFrom = 0;
|
||||||
insertAt = 57;
|
insertAt = 57;
|
||||||
}
|
}
|
||||||
|
@ -1449,10 +1563,12 @@ static void ButtonPressed( int button, int state, int x, int y )
|
||||||
(void) button;
|
(void) button;
|
||||||
(void) state;
|
(void) state;
|
||||||
|
|
||||||
if( x >= 35 && x <= 59 && y >= 47 && y <= 59 ) {
|
if( x >= 35 && x <= 59 && y >= 47 && y <= 59 )
|
||||||
|
{
|
||||||
buttonPressed = true;
|
buttonPressed = true;
|
||||||
forceRedraw = true;
|
forceRedraw = true;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
// reread the config file
|
// reread the config file
|
||||||
readConfigFile = true;
|
readConfigFile = true;
|
||||||
|
|
||||||
|
@ -1467,7 +1583,8 @@ static void ButtonReleased( int button, int state, int x, int y )
|
||||||
buttonPressed = false;
|
buttonPressed = false;
|
||||||
forceRedraw = true;
|
forceRedraw = true;
|
||||||
|
|
||||||
if( x >= 35 && x <= 59 && y >= 47 && y <= 59 ) {
|
if( x >= 35 && x <= 59 && y >= 47 && y <= 59 )
|
||||||
|
{
|
||||||
int ret = system( config.runCmd );
|
int ret = system( config.runCmd );
|
||||||
|
|
||||||
if( ret == 127 || ret == -1 )
|
if( ret == 127 || ret == -1 )
|
||||||
|
@ -1484,10 +1601,9 @@ static void GetHexColorString( const char *colorName, char *xpmLine )
|
||||||
if( XParseColor( DADisplay,
|
if( XParseColor( DADisplay,
|
||||||
DefaultColormap( DADisplay, DefaultScreen( DADisplay )),
|
DefaultColormap( DADisplay, DefaultScreen( DADisplay )),
|
||||||
colorName, &color ))
|
colorName, &color ))
|
||||||
{
|
|
||||||
sprintf( xpmLine, "%02X%02X%02X", color.red>>8, color.green>>8,
|
sprintf( xpmLine, "%02X%02X%02X", color.red>>8, color.green>>8,
|
||||||
color.blue>>8 );
|
color.blue>>8 );
|
||||||
} else
|
else
|
||||||
WARNING( "unknown colorname: \"%s\"\n", colorName );
|
WARNING( "unknown colorname: \"%s\"\n", colorName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1497,7 +1613,9 @@ static char *XpmColorLine( const char *colorName, char *colorLine,
|
||||||
char *newLine = strdup( colorLine );
|
char *newLine = strdup( colorLine );
|
||||||
char *from = strrchr( newLine, '#' );
|
char *from = strrchr( newLine, '#' );
|
||||||
|
|
||||||
if( from == NULL && !strcasecmp( &colorLine[ strlen( colorLine ) - 4 ], "none" )) {
|
if( from == NULL &&
|
||||||
|
strcasecmp( &colorLine[ strlen( colorLine ) - 4 ], "none" ) == 0 )
|
||||||
|
{
|
||||||
// if no # found, it should be a None-color line
|
// if no # found, it should be a None-color line
|
||||||
free( newLine );
|
free( newLine );
|
||||||
newLine = malloc( 12 );
|
newLine = malloc( 12 );
|
||||||
|
@ -1550,7 +1668,8 @@ static void CleanupNames( void )
|
||||||
{
|
{
|
||||||
nextName = name->next;
|
nextName = name->next;
|
||||||
|
|
||||||
if( !name->visited ) {
|
if( !name->visited )
|
||||||
|
{
|
||||||
if( last == NULL )
|
if( last == NULL )
|
||||||
names = name->next;
|
names = name->next;
|
||||||
else
|
else
|
||||||
|
@ -1558,7 +1677,9 @@ static void CleanupNames( void )
|
||||||
|
|
||||||
free( name->name );
|
free( name->name );
|
||||||
free( name );
|
free( name );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
last = name;
|
last = name;
|
||||||
|
|
||||||
if( !config.newMailsOnly || (name->flag & FLAG_READ) == 0 )
|
if( !config.newMailsOnly || (name->flag & FLAG_READ) == 0 )
|
||||||
|
@ -1574,11 +1695,14 @@ static bool HasTickerWork( void )
|
||||||
if( names == NULL )
|
if( names == NULL )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( curTickerName == NULL || namesChanged ) {
|
if( curTickerName == NULL || namesChanged )
|
||||||
|
{
|
||||||
|
|
||||||
for( nextTickerName = names;
|
for( nextTickerName = names;
|
||||||
nextTickerName != NULL && ( config.newMailsOnly && ( nextTickerName->flag & FLAG_READ ));
|
nextTickerName != NULL && config.newMailsOnly &&
|
||||||
nextTickerName = nextTickerName->next );
|
( nextTickerName->flag & FLAG_READ );
|
||||||
|
nextTickerName = nextTickerName->next )
|
||||||
|
;
|
||||||
|
|
||||||
if( nextTickerName == NULL )
|
if( nextTickerName == NULL )
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in a new issue