MAINTAINERCLEANFILES = Makefile.in
# we want these in the dist tarball
-EXTRA_DIST =
+EXTRA_DIST =
#define STREQ_LEN(a, b, c) (strncmp((a), (b), (c)) == 0)
-inline void
-ErrorLocation( const char *file, int line );
+inline void ErrorLocation(const char *file, int line);
-/*@out@*/ /*@only@*/
-void *
-xmalloc( size_t size, const char *filename, int line_number );
+ /*@out@*//*@only@ */
+void *xmalloc(size_t size, const char *filename, int line_number);
-#endif /* COMMON_H */
+#endif /* COMMON_H */
#include "wmnotify.h"
#include "configfile.h"
-
#define LINE_BUFFER_LEN 256
/* Name of configuration file in user's home directory. */
-const static char default_config_filename[] = ".wmnotifyrc";
-const static char delimiter_single_arg[] = " \n";
-const static char delimiter_multiple_arg[] = "#\n";
-
+static const char default_config_filename[] = ".wmnotifyrc";
+static const char delimiter_single_arg[] = " \n";
+static const char delimiter_multiple_arg[] = "#\n";
-static void
-CreateDefaultConfigurationFile( char *file )
+static void CreateDefaultConfigurationFile(char *file)
{
- int status;
- FILE *fp;
-
- fp = fopen( file, "w" );
- if( fp == NULL ) {
- fprintf( stderr, "%s: Can't create file \"%s\"\n", PACKAGE, file );
- exit( EXIT_FAILURE );
- }
-
- /* Changing permissions so that only the user can read/modify the file. */
- status = chmod( file, S_IRUSR | S_IWUSR );
- if( status < 0 ) {
- fprintf( stderr, "%s: Can't set permission bits on file \"%s\"\n", PACKAGE, file );
- exit( EXIT_FAILURE );
- }
-
- fprintf( fp, "# ~/.wmnotifyrc -- Default configuration file for wmnotify\n\n" );
- fprintf( fp, "# Replace all 'xxxxxxxx' fields with your own settings.\n\n" );
- fprintf( fp, "# Parameters preceded by a '#' character are optional.\n" );
- fprintf( fp, "# You can set their values by removing the leading '#'.\n\n" );
- fprintf( fp, "# Mail Protocol: POP3 or IMAP4.\n" );
- fprintf( fp, "protocol POP3\n\n" );
- fprintf( fp, "# Use SSL encrytion: 0=disable, 1=enable (optional, default is "
- "disabled).\n" );
- fprintf( fp, "use_ssl 0\n\n" );
- fprintf( fp, "# Mail Server Name.\n" );
- fprintf( fp, "server xxxxxxxx\n\n" );
- fprintf( fp, "# Mail Server Port Number (optional, default is 110).\n" );
- fprintf( fp, "port 110\n\n" );
- fprintf( fp, "# Username.\n" );
- fprintf( fp, "username xxxxxxxx\n\n" );
- fprintf( fp, "# Password.\n" );
- fprintf( fp, "password xxxxxxxx\n\n" );
- fprintf( fp, "# IMAP folder name (optional, default is INBOX).\n" );
- fprintf( fp, "# folder INBOX.some_folder\n\n" );
- fprintf( fp, "# Mail Check Interval (in minutes, default is 5 minutes).\n" );
- fprintf( fp, "#mailcheckdelay 5\n\n" );
- fprintf( fp, "# Default mail client (optional).\n" );
- fprintf( fp, "#mailclient sylpheed\n\n" );
- fprintf( fp, "# Audio notification, 0=disable, 1=enable (optional, default is "
- "disabled).\n" );
- fprintf( fp, "enablebeep 0\n\n" );
- fprintf( fp, "# Location of sound file for audio notification. If no sound file is\n" );
- fprintf( fp, "# specified, the console beep will be used instead.\n" );
- fprintf( fp, "audiofile /usr/local/share/sounds/halmsgs.wav\n\n" );
- fprintf( fp, "# Volume (0 to 100%%).\n" );
- fprintf( fp, "volume 100\n" );
-
- fprintf( stderr, "%s: A default configuration file has been created in your "
- "home directory: \"%s\"\n", PACKAGE, file );
- fprintf( stderr, "You must edit it before running %s.\n", PACKAGE );
-
- status = fclose( fp );
- if( status != EXIT_SUCCESS ) {
- fprintf( stderr, "%s: Error closing file \"%s\"\n", PACKAGE, file );
- }
+ int status;
+ FILE *fp;
+
+ fp = fopen(file, "w");
+ if (fp == NULL) {
+ fprintf(stderr, "%s: Can't create file \"%s\"\n", PACKAGE,
+ file);
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * Changing permissions so that only the user can read/modify the file
+ */
+ status = chmod(file, S_IRUSR | S_IWUSR);
+ if (status < 0) {
+ fprintf(stderr,
+ "%s: Can't set permission bits on file \"%s\"\n",
+ PACKAGE, file);
+ exit(EXIT_FAILURE);
+ }
+
+ fprintf(fp,
+ "# ~/.wmnotifyrc -- Default configuration file for wmnotify\n\n");
+ fprintf(fp,
+ "# Replace all 'xxxxxxxx' fields with your own settings.\n\n");
+ fprintf(fp,
+ "# Parameters preceded by a '#' character are optional.\n");
+ fprintf(fp,
+ "# You can set their values by removing the leading '#'.\n\n");
+ fprintf(fp, "# Mail Protocol: POP3 or IMAP4.\n");
+ fprintf(fp, "protocol POP3\n\n");
+ fprintf(fp,
+ "# Use SSL encrytion: 0=disable, 1=enable (optional, default is "
+ "disabled).\n");
+ fprintf(fp, "use_ssl 0\n\n");
+ fprintf(fp, "# Mail Server Name.\n");
+ fprintf(fp, "server xxxxxxxx\n\n");
+ fprintf(fp,
+ "# Mail Server Port Number (optional, default is 110).\n");
+ fprintf(fp, "port 110\n\n");
+ fprintf(fp, "# Username.\n");
+ fprintf(fp, "username xxxxxxxx\n\n");
+ fprintf(fp, "# Password.\n");
+ fprintf(fp, "password xxxxxxxx\n\n");
+ fprintf(fp, "# IMAP folder name (optional, default is INBOX).\n");
+ fprintf(fp, "# folder INBOX.some_folder\n\n");
+ fprintf(fp,
+ "# Mail Check Interval (in minutes, default is 5 minutes).\n");
+ fprintf(fp, "#mailcheckdelay 5\n\n");
+ fprintf(fp, "# Default mail client (optional).\n");
+ fprintf(fp, "#mailclient sylpheed\n\n");
+ fprintf(fp,
+ "# Audio notification, 0=disable, 1=enable (optional, default is "
+ "disabled).\n");
+ fprintf(fp, "enablebeep 0\n\n");
+ fprintf(fp,
+ "# Location of sound file for audio notification. If no sound file is\n");
+ fprintf(fp,
+ "# specified, the console beep will be used instead.\n");
+ fprintf(fp, "audiofile /usr/local/share/sounds/halmsgs.wav\n\n");
+ fprintf(fp, "# Volume (0 to 100%%).\n");
+ fprintf(fp, "volume 100\n");
+
+ fprintf(stderr,
+ "%s: A default configuration file has been created in your "
+ "home directory: \"%s\"\n", PACKAGE, file);
+ fprintf(stderr, "You must edit it before running %s.\n", PACKAGE);
+
+ status = fclose(fp);
+ if (status != EXIT_SUCCESS) {
+ fprintf(stderr, "%s: Error closing file \"%s\"\n", PACKAGE,
+ file);
+ }
}
-static void
-ParseCommand( char *line, /*@out@*/ char *argv[] )
+static void ParseCommand(char *line, /*@out@ */ char *argv[])
{
- int argc = 0;
-
- while( *line != '\0' ) { /* if not the end of line ....... */
- while( *line == ' ' || *line == '\t' || *line == '\n' ) {
- *line++ = '\0'; /* replace white spaces with 0 */
- }
- *argv++ = line; /* save the argument position */
- while( *line != '\0' && *line != ' ' && *line != '\t' && *line != '\n' ) {
- line++; /* skip the argument until ... */
- }
-
- argc++;
-
- if( argc == ARGV_LIMIT ) {
- fprintf( stderr, "%s: Too much arguments for external command\n",
- PACKAGE );
- exit( EXIT_FAILURE );
- }
- }
-
- *argv = NULL; /* mark the end of argument list */
+ int argc = 0;
+
+ while (*line != '\0') { /* if not the end of line ....... */
+ while (*line == ' ' || *line == '\t' || *line == '\n')
+ *line++ = '\0'; /* replace white spaces with 0 */
+
+ *argv++ = line; /* save the argument position */
+ while (*line != '\0' && *line != ' ' && *line != '\t'
+ && *line != '\n') {
+ line++; /* skip the argument until ... */
+ }
+
+ argc++;
+
+ if (argc == ARGV_LIMIT) {
+ fprintf(stderr,
+ "%s: Too much arguments for external command\n",
+ PACKAGE);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ *argv = NULL; /* mark the end of argument list */
}
-static char *
-GetArguments( char *parameter, bool single_argument )
+static char *GetArguments(char *parameter, bool single_argument)
{
- char *token;
-
- if( single_argument ) {
- token = strtok( NULL, delimiter_single_arg );
- }
- else {
- /* We search for a string terminated by either a '#' character (the rest of
- the line is then a comment, which is simply ignored ), or the end of line
- character '\n'. */
- token = strtok( NULL, delimiter_multiple_arg );
- }
-
- if( token == NULL ) {
- fprintf( stderr, "%s: Missing argument for \"%s\" parameter in "
- "configuration file.\n", PACKAGE, parameter );
- exit( EXIT_FAILURE );
- }
-
- return token;
+ char *token;
+
+ if (single_argument) {
+ token = strtok(NULL, delimiter_single_arg);
+ } else {
+ /*
+ * We search for a string terminated by either a '#' character
+ * (the rest of the line is then a comment, which is simply
+ * ignored ), or the end of line character '\n'.
+ */
+ token = strtok(NULL, delimiter_multiple_arg);
+ }
+
+ if (token == NULL) {
+ fprintf(stderr,
+ "%s: Missing argument for \"%s\" parameter in "
+ "configuration file.\n", PACKAGE, parameter);
+ exit(EXIT_FAILURE);
+ }
+
+ return token;
}
-static int
-GetNumber( char *token, char *parameter )
+static int GetNumber(char *token, char *parameter)
{
- char temp[32]; /* Check size ??? */
-
- if( sscanf( token, "%[0123456789]", temp ) == 0 ) {
- fprintf( stderr, "%s: Invalid argument for \"%s\" parameter in "
- "configuration file.\n", PACKAGE, parameter );
- exit( EXIT_FAILURE );
- }
-
- return atoi( temp );
-}
+ char temp[32]; /* Check size ??? */
+ if (sscanf(token, "%[0123456789]", temp) == 0) {
+ fprintf(stderr,
+ "%s: Invalid argument for \"%s\" parameter in "
+ "configuration file.\n", PACKAGE, parameter);
+ exit(EXIT_FAILURE);
+ }
+
+ return atoi(temp);
+}
-static void
-ParseConfigurationFile( FILE *file )
+static void ParseConfigurationFile(FILE *file)
{
- char line[LINE_BUFFER_LEN];
- char *token;
- bool protocol_found = false;
- bool server_found = false;
- bool username_found = false;
- bool password_found = false;
- const char *err_string = NULL;
-
- /* Default values for optional parameters. */
- strcpy( wmnotify_infos.imap_folder, "INBOX"); /* Default IMAP folder. */
- wmnotify_infos.port = 110;
- wmnotify_infos.mail_check_interval = 60; /* 1 minute interval. */
- wmnotify_infos.audible_notification = false; /* Disabled. */
- wmnotify_infos.use_ssl = false; /* Disabled. */
- wmnotify_infos.mail_client_argv[0] = NULL; /* No default command. */
- wmnotify_infos.audiofile[0] = '\0'; /* No default audio file. */
- wmnotify_infos.volume = 100; /* 100% volume. */
-
- /* Reading one line of data from the configuration file. */
- /* char *fgets(char *s, int size, FILE *stream);
- Reading stops after an EOF or a newline. If a newline is read, it is
- stored into the buffer. A '\0' is stored after the last character in
- the buffer. */
- while( fgets( line, LINE_BUFFER_LEN, file ) != NULL ) {
- token = strtok( line, delimiter_single_arg );
-
- if( ( token == NULL ) || ( token[0] == '#' ) ) {
- continue; /* Next iteration of the while() loop (next line). */
- }
-
- if( STREQ( token, "protocol" ) ) {
- token = GetArguments( "protocol", true );
- if( STREQ( token, "POP3" ) == true ) {
- wmnotify_infos.protocol = POP3_PROTOCOL;
- }
- else if( STREQ( token, "IMAP4" ) == true ) {
- wmnotify_infos.protocol = IMAP4_PROTOCOL;
- }
- else {
- fprintf( stderr, "%s: protocol must be POP3 or IMAP4.\n", PACKAGE );
- exit( EXIT_FAILURE );
- }
-
- protocol_found = true;
- }
- else if( STREQ( token, "imap_folder" ) ) {
- token = GetArguments( "imap_folder", true );
- /* Should check size before using strcpy(), or use strncopy() instead. */
- strcpy( wmnotify_infos.imap_folder, token );
- }
- else if( STREQ( token, "use_ssl" ) ){
- int number;
-
- token = GetArguments( "use_ssl", true );
- number = GetNumber( token, "use_ssl" );
- if( number == 0 ) {
- wmnotify_infos.use_ssl = false;
- }
- else if( number == 1 ) {
+ char line[LINE_BUFFER_LEN];
+ char *token;
+ bool protocol_found = false;
+ bool server_found = false;
+ bool username_found = false;
+ bool password_found = false;
+ const char *err_string = NULL;
+
+ /* Default values for optional parameters. */
+ strcpy(wmnotify_infos.imap_folder, "INBOX"); /* Default IMAP folder. */
+ wmnotify_infos.port = 110;
+ wmnotify_infos.mail_check_interval = 60; /* 1 minute interval. */
+ wmnotify_infos.audible_notification = false; /* Disabled. */
+ wmnotify_infos.use_ssl = false; /* Disabled. */
+ wmnotify_infos.mail_client_argv[0] = NULL; /* No default command. */
+ wmnotify_infos.audiofile[0] = '\0'; /* No default audio file. */
+ wmnotify_infos.volume = 100; /* 100% volume. */
+
+ /*
+ * Reading one line of data from the configuration file.
+ * char *fgets(char *s, int size, FILE *stream);
+ * Reading stops after an EOF or a newline. If a newline is read, it is
+ * stored into the buffer. A '\0' is stored after the last character
+ * in the buffer.
+ */
+ while (fgets(line, LINE_BUFFER_LEN, file) != NULL) {
+ token = strtok(line, delimiter_single_arg);
+
+ if ((token == NULL) || (token[0] == '#')) {
+ continue; /*
+ * Next iteration of the while() loop (next
+ * line).
+ */
+ }
+
+ if (STREQ(token, "protocol")) {
+ token = GetArguments("protocol", true);
+ if (STREQ(token, "POP3") == true) {
+ wmnotify_infos.protocol = POP3_PROTOCOL;
+ } else if (STREQ(token, "IMAP4") == true) {
+ wmnotify_infos.protocol = IMAP4_PROTOCOL;
+ } else {
+ fprintf(stderr,
+ "%s: protocol must be POP3 or IMAP4.\n",
+ PACKAGE);
+ exit(EXIT_FAILURE);
+ }
+
+ protocol_found = true;
+ } else if (STREQ(token, "imap_folder")) {
+ token = GetArguments("imap_folder", true);
+ /*
+ * Should check size before using strcpy(), or use
+ * strncopy() instead.
+ */
+ strcpy(wmnotify_infos.imap_folder, token);
+ } else if (STREQ(token, "use_ssl")) {
+ int number;
+
+ token = GetArguments("use_ssl", true);
+ number = GetNumber(token, "use_ssl");
+ if (number == 0) {
+ wmnotify_infos.use_ssl = false;
+ } else if (number == 1) {
#if HAVE_SSL
- wmnotify_infos.use_ssl = true;
+ wmnotify_infos.use_ssl = true;
#else
- fprintf( stderr, "%s error: You must compile %s with SSL support to\n" \
- "set parameter 'use_ssl' to true in configuration file\n", PACKAGE, PACKAGE );
- exit( EXIT_FAILURE );
+ fprintf(stderr,
+ "%s error: You must compile %s with SSL support to\n"
+ "set parameter 'use_ssl' to true in configuration file\n",
+ PACKAGE, PACKAGE);
+ exit(EXIT_FAILURE);
#endif
- }
- else {
- fprintf( stderr, "%s: Invalid value for parameter 'use_ssl' in\n" \
- "configuration file (must be 0 or 1): %d\n", PACKAGE, number );
- exit( EXIT_FAILURE );
- }
- }
- else if( STREQ( token, "server" ) ) {
- token = GetArguments( "server", true );
- strncpy( wmnotify_infos.server_name, token, MAX_STR_LEN );
- server_found = true;
- }
- else if( STREQ( token, "port" ) ) {
- token = GetArguments( "port", true );
- wmnotify_infos.port = (u_int16_t) GetNumber( token, "port" );
- }
-
- else if( STREQ( token, "username" ) ) {
- token = GetArguments( "username", true );
- strncpy( wmnotify_infos.username, token, MAX_STR_LEN );
- username_found = true;
- }
- else if( STREQ( token, "password" ) ) {
- token = GetArguments( "password", true );
- strncpy( wmnotify_infos.password, token, MAX_STR_LEN );
- password_found = true;
- }
- else if( STREQ( token, "mailcheckdelay" ) ) {
- int delay; /* delay in minutes. */
-
- token = GetArguments( "mailcheckdelay", true );
- /* GetNumber() will exit if a negative number is entered. */
- delay = GetNumber( token, "mailcheckdelay" );
- if( delay == 0 ) {
- fprintf( stderr, "%s: Mail check interval must be greater than '0'\n",
- PACKAGE );
- exit( EXIT_FAILURE );
- }
- wmnotify_infos.mail_check_interval = (unsigned int) delay * 60;
- }
- else if( STREQ( token, "mailclient" ) ) {
- token = GetArguments( "mailclient", false ); /* Multiple arguments */
- strcpy( wmnotify_infos.mail_client_command, token );
- ParseCommand( wmnotify_infos.mail_client_command,
- wmnotify_infos.mail_client_argv );
- }
- else if( STREQ( token, "enablebeep" ) ){
- int number;
-
- token = GetArguments( "enablebeep", true );
- number = GetNumber( token, "enablebeep" );
- if( number == 0 ) {
- wmnotify_infos.audible_notification = false;
- }
- else if( number == 1 ) {
- wmnotify_infos.audible_notification = true;
- }
- else {
- fprintf( stderr, "%s: Invalid value for for parameter 'enablebeep' in\n" \
- "configuration file (must be 0 or 1): %d\n", PACKAGE, number );
- exit( EXIT_FAILURE );
- }
- }
- else if( STREQ( token, "audiofile" ) ) {
- token = GetArguments( "audiofile", true );
- /* Should check size before using strcpy(), or use strncopy() instead. */
- strcpy( wmnotify_infos.audiofile, token );
- }
- else if( STREQ( token, "volume" ) ) {
- token = GetArguments( "volume", true );
- wmnotify_infos.volume = GetNumber( token, "volume" );
- }
- else {
- fprintf( stderr, "%s: invalid parameter in configuration file: %s\n", PACKAGE,
- token );
- exit( EXIT_FAILURE );
- }
-
- token = strtok( NULL, delimiter_single_arg );
- if( ( token != NULL ) && ( token[0] != '#' ) ) {
- fprintf( stderr, "%s: Garbage at end of line in configuration file: %s\n", PACKAGE,
- token );
- exit( EXIT_FAILURE );
- }
- }
-
- if( protocol_found == false ) {
- err_string = "protocol";
- }
- else if( server_found == false ) {
- err_string = "server";
- }
- else if( username_found == false ) {
- err_string = "username";
- }
- else if( password_found == false ) {
- err_string = "password";
- }
- else {
- return; /* success */
- }
-
- /* Failure. */
- fprintf( stderr, "%s: Mandatory parameter \"%s\" missing from configuration "
- "file.\n", PACKAGE, err_string );
- exit( EXIT_FAILURE );
+ } else {
+ fprintf(stderr,
+ "%s: Invalid value for parameter 'use_ssl' in\n"
+ "configuration file (must be 0 or 1): %d\n",
+ PACKAGE, number);
+ exit(EXIT_FAILURE);
+ }
+ } else if (STREQ(token, "server")) {
+ token = GetArguments("server", true);
+ strncpy(wmnotify_infos.server_name, token,
+ MAX_STR_LEN);
+ server_found = true;
+ } else if (STREQ(token, "port")) {
+ token = GetArguments("port", true);
+ wmnotify_infos.port =
+ (u_int16_t) GetNumber(token, "port");
+ }
+
+ else if (STREQ(token, "username")) {
+ token = GetArguments("username", true);
+ strncpy(wmnotify_infos.username, token,
+ MAX_STR_LEN);
+ username_found = true;
+ } else if (STREQ(token, "password")) {
+ token = GetArguments("password", true);
+ strncpy(wmnotify_infos.password, token,
+ MAX_STR_LEN);
+ password_found = true;
+ } else if (STREQ(token, "mailcheckdelay")) {
+ int delay; /* delay in minutes. */
+
+ token = GetArguments("mailcheckdelay", true);
+ /*
+ * GetNumber() will exit if a negative number is
+ * entered.
+ */
+ delay = GetNumber(token, "mailcheckdelay");
+ if (delay == 0) {
+ fprintf(stderr,
+ "%s: Mail check interval must be greater than '0'\n",
+ PACKAGE);
+ exit(EXIT_FAILURE);
+ }
+ wmnotify_infos.mail_check_interval =
+ (unsigned int)delay * 60;
+ } else if (STREQ(token, "mailclient")) {
+ /* Multiple arguments */
+ token = GetArguments("mailclient", false);
+ strcpy(wmnotify_infos.mail_client_command, token);
+ ParseCommand(wmnotify_infos.mail_client_command,
+ wmnotify_infos.mail_client_argv);
+ } else if (STREQ(token, "enablebeep")) {
+ int number;
+
+ token = GetArguments("enablebeep", true);
+ number = GetNumber(token, "enablebeep");
+ if (number == 0) {
+ wmnotify_infos.audible_notification =
+ false;
+ } else if (number == 1) {
+ wmnotify_infos.audible_notification = true;
+ } else {
+ fprintf(stderr,
+ "%s: Invalid value for for parameter 'enablebeep' in\n"
+ "configuration file (must be 0 or 1): %d\n",
+ PACKAGE, number);
+ exit(EXIT_FAILURE);
+ }
+ } else if (STREQ(token, "audiofile")) {
+ token = GetArguments("audiofile", true);
+ /*
+ * Should check size before using strcpy(), or use
+ * strncopy() instead.
+ */
+ strcpy(wmnotify_infos.audiofile, token);
+ } else if (STREQ(token, "volume")) {
+ token = GetArguments("volume", true);
+ wmnotify_infos.volume = GetNumber(token, "volume");
+ } else {
+ fprintf(stderr,
+ "%s: invalid parameter in configuration file: %s\n",
+ PACKAGE, token);
+ exit(EXIT_FAILURE);
+ }
+
+ token = strtok(NULL, delimiter_single_arg);
+ if ((token != NULL) && (token[0] != '#')) {
+ fprintf(stderr,
+ "%s: Garbage at end of line in configuration file: %s\n",
+ PACKAGE, token);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (protocol_found == false)
+ err_string = "protocol";
+ else if (server_found == false)
+ err_string = "server";
+ else if (username_found == false)
+ err_string = "username";
+ else if (password_found == false)
+ err_string = "password";
+ else
+ return; /* success */
+
+ /* Failure. */
+ fprintf(stderr,
+ "%s: Mandatory parameter \"%s\" missing from configuration "
+ "file.\n", PACKAGE, err_string);
+ exit(EXIT_FAILURE);
}
/*******************************************************************************
* Read and parse the configuration file in the user's home directory
******************************************************************************/
-void
-ConfigurationFileInit( void )
+void ConfigurationFileInit(void)
{
- FILE *fp;
- int status;
- size_t len;
-
- /* Check if an optional configuration file was specified on the command
- line. */
- if( wmnotify_infos.optional_config_file != NULL ) {
- /* Trying to open the file. */
- fp = fopen( wmnotify_infos.optional_config_file, "r" );
- if( fp == NULL ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
- }
- else {
- /* Using the default configuration file. */
- char *home_dir;
- char *default_config_file;
-
- home_dir = getenv("HOME");
- if( home_dir == NULL ) {
- /* We're trying to expand ~/, but HOME isn't set. */
- struct passwd *pw = getpwuid( getuid() );
-
- if( pw != NULL ) {
- home_dir = pw->pw_dir;
- }
- else {
- fprintf( stderr, "%s: Couldn't determine user's home directory path\n",
- PACKAGE );
- exit( EXIT_FAILURE );
- }
- }
-
- /* We add 1 to the length for the terminating character '\0'. */
- len = strlen( home_dir ) + strlen( "/" ) + strlen( default_config_filename )
- + 1;
- default_config_file = xmalloc( len, __FILE__, __LINE__ );
-
- sprintf( default_config_file, "%s/%s", home_dir, default_config_filename );
-
- fp = fopen( default_config_file, "r" );
- if( fp == NULL ) {
- /* If we cannot open the default configuration file, it probably means
- it is missing, so we create it. */
- CreateDefaultConfigurationFile( default_config_file );
- free( default_config_file );
- exit( EXIT_FAILURE );
- }
-
- free( default_config_file );
- }
-
- ParseConfigurationFile( fp );
-
- status = fclose( fp );
- if( status != EXIT_SUCCESS ) {
- fprintf( stderr, "%s: Error closing configuration file.\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
+ FILE *fp;
+ int status;
+ size_t len;
+
+ /* Check if an optional configuration file was specified on the command
+ line. */
+ if (wmnotify_infos.optional_config_file != NULL) {
+ /* Trying to open the file. */
+ fp = fopen(wmnotify_infos.optional_config_file, "r");
+ if (fp == NULL) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ /* Using the default configuration file. */
+ char *home_dir;
+ char *default_config_file;
+
+ home_dir = getenv("HOME");
+ if (home_dir == NULL) {
+ /* We're trying to expand ~/, but HOME isn't set. */
+ struct passwd *pw = getpwuid(getuid());
+
+ if (pw != NULL) {
+ home_dir = pw->pw_dir;
+ } else {
+ fprintf(stderr,
+ "%s: Couldn't determine user's home directory path\n",
+ PACKAGE);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* We add 1 to the length for the terminating character '\0'. */
+ len =
+ strlen(home_dir) + strlen("/") +
+ strlen(default_config_filename)
+ + 1;
+ default_config_file = xmalloc(len, __FILE__, __LINE__);
+
+ sprintf(default_config_file, "%s/%s", home_dir,
+ default_config_filename);
+
+ fp = fopen(default_config_file, "r");
+ if (fp == NULL) {
+ /*
+ * If we cannot open the default configuration file, it
+ * probably means it is missing, so we create it.
+ */
+ CreateDefaultConfigurationFile
+ (default_config_file);
+ free(default_config_file);
+ exit(EXIT_FAILURE);
+ }
+
+ free(default_config_file);
+ }
+
+ ParseConfigurationFile(fp);
+
+ status = fclose(fp);
+ if (status != EXIT_SUCCESS) {
+ fprintf(stderr, "%s: Error closing configuration file.\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
}
#ifndef CONFIGFILE_H
#define CONFIGFILE_H 1
-void
-ConfigurationFileInit( void );
+void ConfigurationFileInit(void);
-#endif /* CONFIGFILE_H */
+#endif /* CONFIGFILE_H */
#define ICON_SIZE 64
-static void
-CreateIconFromXpmData( char *pixmap_data[] )
+static void CreateIconFromXpmData(char *pixmap_data[])
{
- int status;
-
- dockapp.xpm_icon.attributes.valuemask |=
- ( XpmReturnPixels | XpmReturnExtensions );
-
- /* Using the XPM library to read XPM data from the array in the included XPM
- file. The 'shapemask' Pixmap variable is set to an additional 1-bit deep
- pixmap that can then be used as a shape mask for the XShapeCombineMask()
- function. */
- status = XpmCreatePixmapFromData( dockapp.display, dockapp.root_win,
- pixmap_data, &dockapp.xpm_icon.image,
- &dockapp.xpm_icon.shapemask,
- &dockapp.xpm_icon.attributes );
- if( status != XpmSuccess ) {
- fprintf( stderr, "%s: XpmCreatePixmapFromData() failed\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
+ int status;
+
+ dockapp.xpm_icon.attributes.valuemask |=
+ (XpmReturnPixels | XpmReturnExtensions);
+
+ /*
+ * Using the XPM library to read XPM data from the array in the included
+ * XPM file. The 'shapemask' Pixmap variable is set to an additional
+ * 1-bit deep pixmap that can then be used as a shape mask for the
+ * XShapeCombineMask() function.
+ */
+ status = XpmCreatePixmapFromData(dockapp.display, dockapp.root_win,
+ pixmap_data,
+ &dockapp.xpm_icon.image,
+ &dockapp.xpm_icon.shapemask,
+ &dockapp.xpm_icon.attributes);
+ if (status != XpmSuccess) {
+ fprintf(stderr, "%s: XpmCreatePixmapFromData() failed\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
}
-static Pixel
-GetColor( char *name )
+static Pixel GetColor(char *name)
{
- int status;
- bool res;
- XColor color;
- XWindowAttributes attributes;
-
- status = XGetWindowAttributes( dockapp.display, dockapp.root_win,
- &attributes );
- if( status == XLIB_FAILURE ) {
- fprintf( stderr, "%s: XGetWindowAttributes() failed\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- color.pixel = 0;
- res = (bool) XParseColor( dockapp.display, attributes.colormap, name,
- &color );
- if( res == false ) {
- fprintf( stderr, "%s: Can't parse %s.\n", PACKAGE, name );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- res = (bool) XAllocColor( dockapp.display, attributes.colormap, &color );
- if( res == false ) {
- fprintf( stderr, "%s: Can't allocate %s.\n", PACKAGE, name );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- return color.pixel;
+ int status;
+ bool res;
+ XColor color;
+ XWindowAttributes attributes;
+
+ status = XGetWindowAttributes(dockapp.display, dockapp.root_win,
+ &attributes);
+ if (status == XLIB_FAILURE) {
+ fprintf(stderr, "%s: XGetWindowAttributes() failed\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ color.pixel = 0;
+ res =
+ (bool) XParseColor(dockapp.display, attributes.colormap, name,
+ &color);
+ if (res == false) {
+ fprintf(stderr, "%s: Can't parse %s.\n", PACKAGE, name);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ res =
+ (bool) XAllocColor(dockapp.display, attributes.colormap,
+ &color);
+ if (res == false) {
+ fprintf(stderr, "%s: Can't allocate %s.\n", PACKAGE, name);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ return color.pixel;
}
-static void
-flush_expose( Window win )
+static void flush_expose(Window win)
{
- XEvent dummy;
- bool res = true;
+ XEvent dummy;
+ bool res = true;
- while( res != false ) {
- res = (bool) XCheckTypedWindowEvent( dockapp.display, win, Expose, &dummy );
- }
+ while (res != false) {
+ res =
+ (bool) XCheckTypedWindowEvent(dockapp.display, win,
+ Expose, &dummy);
+ }
}
-void
-RedrawWindow( void )
+void RedrawWindow(void)
{
- flush_expose( dockapp.iconwin );
-
- (void) XCopyArea( dockapp.display, dockapp.xpm_icon.image, dockapp.iconwin,
- dockapp.NormalGC, 0, 0, dockapp.xpm_icon.attributes.width,
- dockapp.xpm_icon.attributes.height, 0, 0 );
-
- flush_expose( dockapp.win );
-
- (void) XCopyArea( dockapp.display, dockapp.xpm_icon.image, dockapp.win,
- dockapp.NormalGC, 0, 0, dockapp.xpm_icon.attributes.width,
- dockapp.xpm_icon.attributes.height, 0, 0 );
+ flush_expose(dockapp.iconwin);
+
+ (void) XCopyArea(dockapp.display, dockapp.xpm_icon.image,
+ dockapp.iconwin, dockapp.NormalGC, 0, 0,
+ dockapp.xpm_icon.attributes.width,
+ dockapp.xpm_icon.attributes.height, 0, 0);
+
+ flush_expose(dockapp.win);
+
+ (void) XCopyArea(dockapp.display, dockapp.xpm_icon.image,
+ dockapp.win, dockapp.NormalGC, 0, 0,
+ dockapp.xpm_icon.attributes.width,
+ dockapp.xpm_icon.attributes.height, 0, 0);
}
void
-copyXPMArea( int x, int y, unsigned int sx, unsigned int sy, int dx, int dy )
+copyXPMArea(int x, int y, unsigned int sx, unsigned int sy, int dx, int dy)
{
- (void) XCopyArea( dockapp.display, dockapp.xpm_icon.image,
- dockapp.xpm_icon.image, dockapp.NormalGC, x, y, sx, sy,
- dx, dy );
+ (void) XCopyArea(dockapp.display, dockapp.xpm_icon.image,
+ dockapp.xpm_icon.image, dockapp.NormalGC, x, y,
+ sx, sy, dx, dy);
}
* New window creation and initialization for a Dockable Application
******************************************************************************/
void
-InitDockAppWindow( int argc, char *argv[], char *pixmap_data[],
- char *display_arg, char *geometry_arg )
+InitDockAppWindow(int argc, char *argv[], char *pixmap_data[],
+ char *display_arg, char *geometry_arg)
{
- XGCValues gcv;
- XSizeHints size_hints;
- XWMHints wm_hints;
- int status;
- int gravity = 0; /* Used to store the gravity value returned by XWMGeometry,
- but not used. */
-
- /* Opening a connection to the X server. */
- dockapp.display = XOpenDisplay( display_arg );
- if( dockapp.display == NULL ) {
- fprintf( stderr, "%s: Can't open display: %s\n", PACKAGE,
- XDisplayName( display_arg ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- dockapp.screen = DefaultScreen( dockapp.display );
- dockapp.root_win = RootWindow( dockapp.display, dockapp.screen );
- dockapp.d_depth = DefaultDepth( dockapp.display, dockapp.screen );
-
- /* Create a window to hold the stuff */
- size_hints.flags = USSize | USPosition;
- size_hints.x = 0;
- size_hints.y = 0;
-
- /* Constructing window's geometry information. */
- /* XWMGeometry() returns an 'int', but Xlib documentation doesn't explain
- it's meaning. */
- XWMGeometry( dockapp.display, dockapp.screen, geometry_arg, NULL, BWIDTH,
- &size_hints, &size_hints.x, &size_hints.y, &size_hints.width,
- &size_hints.height, &gravity );
-
- size_hints.width = ICON_SIZE;
- size_hints.height = ICON_SIZE;
- dockapp.back_pix = GetColor("white");
- dockapp.fore_pix = GetColor("black");
-
- dockapp.win = XCreateSimpleWindow( dockapp.display, dockapp.root_win,
- size_hints.x, size_hints.y,
- (unsigned int) size_hints.width,
- (unsigned int) size_hints.height,
- BWIDTH, dockapp.fore_pix,
- dockapp.back_pix );
-
- dockapp.iconwin = XCreateSimpleWindow( dockapp.display, dockapp.win,
- size_hints.x, size_hints.y,
- (unsigned int) size_hints.width,
- (unsigned int) size_hints.height,
- BWIDTH, dockapp.fore_pix,
- dockapp.back_pix );
-
- /* Configuring Client to Window Manager Communications. */
-
- /* WM_NORMAL_HINTS property: size hints for a window in it's normal state. */
- /* Replaces the size hints for the WM_NORMAL_HINTS property on the specified
- window. */
- XSetWMNormalHints( dockapp.display, dockapp.win, &size_hints );
-
- /* Setting the WM_CLASS property. */
- {
- char *app_name = argv[0];
- XClassHint wm_class;
-
- /* The res_name member contains the application name.
- The res_class member contains the application class. */
- /* The name set in this property may differ from the name set as WM_NAME.
- That is, WM_NAME specifies what should be displayed in the title bar and,
- therefore, can contain temporal information (for example, the name of a
- file currently in an editor's buffer). On the other hand, the name
- specified as part of WM_CLASS is the formal name of the application that
- should be used when retrieving the application's resources from the
- resource database. */
- wm_class.res_name = app_name;
- wm_class.res_class = app_name;
- (void) XSetClassHint( dockapp.display, dockapp.win, &wm_class );
- }
-
- /* Setting the WM_NAME property.
- This specifies what should be displayed in the title bar (usually the
- application name). */
- {
- XTextProperty text_prop;
-
- char *app_name = argv[0];
- const int string_count = 1;
-
- status = XStringListToTextProperty( &app_name, string_count, &text_prop );
- if( status == 0 ) {
- fprintf( stderr, "%s: XStringListToTextProperty() failed\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- XSetWMName( dockapp.display, dockapp.win, &text_prop );
-
- /* Freing the storage for the value field. */
- (void) XFree( text_prop.value );
- }
-
- /* WM_HINTS --> Additional hints set by the client for use by the Window
- Manager. */
- /* XWMHints wm_hints; */
-
- /* WithdrawnState, NormalState or IconicState. Must be set to WithdrawnState
- for DockApp. */
- wm_hints.flags = StateHint | IconWindowHint | IconPositionHint |
- WindowGroupHint;
- wm_hints.initial_state = WithdrawnState; /* Withdrawn, Normal */
- wm_hints.icon_window = dockapp.iconwin;
- wm_hints.icon_x = size_hints.x;
- wm_hints.icon_y = size_hints.y;
- wm_hints.window_group = dockapp.win;
- (void) XSetWMHints( dockapp.display, dockapp.win, &wm_hints );
-
- /* Sets the WM_COMMAND property. This sets the command and arguments used to
- invoke the application. */
- (void) XSetCommand( dockapp.display, dockapp.win, argv, argc );
-
- /* ... */
- (void) XSelectInput( dockapp.display, dockapp.win,
- ButtonPressMask | ExposureMask | ButtonReleaseMask |
- PointerMotionMask | StructureNotifyMask );
-
- (void) XSelectInput( dockapp.display, dockapp.iconwin,
- ButtonPressMask | ExposureMask | ButtonReleaseMask |
- PointerMotionMask | StructureNotifyMask );
-
- /* Create GC for drawing */
- gcv.foreground = dockapp.fore_pix;
- gcv.background = dockapp.back_pix;
- gcv.graphics_exposures = 0;
- dockapp.NormalGC = XCreateGC( dockapp.display, dockapp.root_win,
- GCForeground | GCBackground |
- GCGraphicsExposures, &gcv );
-
- /* Convert XPM data to XImage */
- CreateIconFromXpmData( pixmap_data );
-
- XShapeCombineMask( dockapp.display, dockapp.win, ShapeBounding, 0, 0,
- dockapp.xpm_icon.shapemask, ShapeSet );
-
- XShapeCombineMask( dockapp.display, dockapp.iconwin, ShapeBounding, 0, 0,
- dockapp.xpm_icon.shapemask, ShapeSet );
-
- /* Making the new window visible. */
- (void) XMapWindow( dockapp.display, dockapp.win );
+ XGCValues gcv;
+ XSizeHints size_hints;
+ XWMHints wm_hints;
+ int status;
+ int gravity = 0; /*
+ * Used to store the gravity value returned by
+ * XWMGeometry, but not used.
+ */
+
+ /* Opening a connection to the X server. */
+ dockapp.display = XOpenDisplay(display_arg);
+ if (dockapp.display == NULL) {
+ fprintf(stderr, "%s: Can't open display: %s\n", PACKAGE,
+ XDisplayName(display_arg));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ dockapp.screen = DefaultScreen(dockapp.display);
+ dockapp.root_win = RootWindow(dockapp.display, dockapp.screen);
+ dockapp.d_depth = DefaultDepth(dockapp.display, dockapp.screen);
+
+ /* Create a window to hold the stuff */
+ size_hints.flags = USSize | USPosition;
+ size_hints.x = 0;
+ size_hints.y = 0;
+
+ /*
+ * Constructing window's geometry information.
+ * XWMGeometry() returns an 'int', but Xlib documentation doesn't
+ * explain it's meaning.
+ */
+ XWMGeometry(dockapp.display, dockapp.screen, geometry_arg, NULL,
+ BWIDTH, &size_hints, &size_hints.x, &size_hints.y,
+ &size_hints.width, &size_hints.height, &gravity);
+
+ size_hints.width = ICON_SIZE;
+ size_hints.height = ICON_SIZE;
+ dockapp.back_pix = GetColor("white");
+ dockapp.fore_pix = GetColor("black");
+
+ dockapp.win =
+ XCreateSimpleWindow(dockapp.display, dockapp.root_win,
+ size_hints.x, size_hints.y,
+ (unsigned int) size_hints.width,
+ (unsigned int) size_hints.height, BWIDTH,
+ dockapp.fore_pix, dockapp.back_pix);
+
+ dockapp.iconwin = XCreateSimpleWindow(dockapp.display, dockapp.win,
+ size_hints.x, size_hints.y,
+ (unsigned int) size_hints.
+ width,
+ (unsigned int) size_hints.
+ height, BWIDTH,
+ dockapp.fore_pix,
+ dockapp.back_pix);
+
+ /* Configuring Client to Window Manager Communications. */
+
+ /*
+ * WM_NORMAL_HINTS property: size hints for a window in it's normal
+ * state.
+ * Replaces the size hints for the WM_NORMAL_HINTS property on the
+ * specified window.
+ */
+ XSetWMNormalHints(dockapp.display, dockapp.win, &size_hints);
+
+ /* Setting the WM_CLASS property. */
+ {
+ char *app_name = argv[0];
+ XClassHint wm_class;
+
+ /*
+ * The res_name member contains the application name.
+ * The res_class member contains the application class.
+ */
+ /*
+ * The name set in this property may differ from the name set as
+ * WM_NAME. That is, WM_NAME specifies what should be displayed
+ * in the title bar and, therefore, can contain temporal
+ * information (for example, the name of a file currently in an
+ * editor's buffer). On the other hand, the name specified as
+ * part of WM_CLASS is the formal name of the application that
+ * should be used when retrieving the application's resources
+ * from the resource database.
+ */
+ wm_class.res_name = app_name;
+ wm_class.res_class = app_name;
+ (void) XSetClassHint(dockapp.display, dockapp.win,
+ &wm_class);
+ }
+
+ /* Setting the WM_NAME property.
+ This specifies what should be displayed in the title bar (usually the
+ application name). */
+ {
+ XTextProperty text_prop;
+
+ char *app_name = argv[0];
+ const int string_count = 1;
+
+ status =
+ XStringListToTextProperty(&app_name, string_count,
+ &text_prop);
+ if (status == 0) {
+ fprintf(stderr,
+ "%s: XStringListToTextProperty() failed\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ XSetWMName(dockapp.display, dockapp.win, &text_prop);
+
+ /* Freing the storage for the value field. */
+ (void) XFree(text_prop.value);
+ }
+
+ /* WM_HINTS --> Additional hints set by the client for use by the Window
+ Manager. */
+ /* XWMHints wm_hints; */
+
+ /*
+ * WithdrawnState, NormalState or IconicState. Must be set to
+ * WithdrawnState for DockApp.
+ */
+ wm_hints.flags = StateHint | IconWindowHint | IconPositionHint |
+ WindowGroupHint;
+ wm_hints.initial_state = WithdrawnState; /* Withdrawn, Normal */
+ wm_hints.icon_window = dockapp.iconwin;
+ wm_hints.icon_x = size_hints.x;
+ wm_hints.icon_y = size_hints.y;
+ wm_hints.window_group = dockapp.win;
+ (void) XSetWMHints(dockapp.display, dockapp.win, &wm_hints);
+
+ /*
+ * Sets the WM_COMMAND property. This sets the command and arguments
+ * used to invoke the application.
+ */
+ (void) XSetCommand(dockapp.display, dockapp.win, argv, argc);
+
+ /* ... */
+ (void) XSelectInput(dockapp.display, dockapp.win,
+ ButtonPressMask | ExposureMask |
+ ButtonReleaseMask | PointerMotionMask |
+ StructureNotifyMask);
+
+ (void) XSelectInput(dockapp.display, dockapp.iconwin,
+ ButtonPressMask | ExposureMask |
+ ButtonReleaseMask | PointerMotionMask |
+ StructureNotifyMask);
+
+ /* Create GC for drawing */
+ gcv.foreground = dockapp.fore_pix;
+ gcv.background = dockapp.back_pix;
+ gcv.graphics_exposures = 0;
+ dockapp.NormalGC = XCreateGC(dockapp.display, dockapp.root_win,
+ GCForeground | GCBackground |
+ GCGraphicsExposures, &gcv);
+
+ /* Convert XPM data to XImage */
+ CreateIconFromXpmData(pixmap_data);
+
+ XShapeCombineMask(dockapp.display, dockapp.win, ShapeBounding, 0,
+ 0, dockapp.xpm_icon.shapemask, ShapeSet);
+
+ XShapeCombineMask(dockapp.display, dockapp.iconwin, ShapeBounding,
+ 0, 0, dockapp.xpm_icon.shapemask, ShapeSet);
+
+ /* Making the new window visible. */
+ (void) XMapWindow(dockapp.display, dockapp.win);
}
#include <X11/xpm.h>
-struct XpmIcon
-{
- XpmAttributes attributes;
- Pixmap shapemask;
- Pixmap image;
+struct XpmIcon {
+ XpmAttributes attributes;
+ Pixmap shapemask;
+ Pixmap image;
};
-struct dockapp_t
-{
- Display *display;
- Window root_win;
- int screen;
- int d_depth;
- Pixel back_pix;
- Pixel fore_pix;
- Window iconwin;
- Window win;
- GC NormalGC;
- struct XpmIcon xpm_icon;
+struct dockapp_t {
+ Display *display;
+ Window root_win;
+ int screen;
+ int d_depth;
+ Pixel back_pix;
+ Pixel fore_pix;
+ Window iconwin;
+ Window win;
+ GC NormalGC;
+ struct XpmIcon xpm_icon;
};
void
-InitDockAppWindow( int argc, char *argv[], char *pixmap_data[],
- char *display_arg, char *geometry_arg );
+InitDockAppWindow(int argc, char *argv[], char *pixmap_data[],
+ char *display_arg, char *geometry_arg);
-void
-RedrawWindow( void );
+void RedrawWindow(void);
void
-copyXPMArea( int x, int y, unsigned int sx, unsigned int sy, int dx, int dy );
+copyXPMArea(int x, int y, unsigned int sx, unsigned int sy, int dx,
+ int dy);
/* Exported variables */
#undef _SCOPE_
_SCOPE_ struct dockapp_t dockapp;
-#endif /* DOCKAPP_H */
+#endif /* DOCKAPP_H */
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
-#include <ctype.h> /* for isdigit() */
+#include <ctype.h> /* for isdigit() */
#include "common.h"
#include "wmnotify.h"
#include "imap.h"
-#define IMAP4_ENDL "\r\n" /* CRLF */
+#define IMAP4_ENDL "\r\n" /* CRLF */
#define IMAP4_CMD_CAPABILITY "CAPABILITY"
#define IMAP4_CMD_LOGIN "LOGIN"
#define IMAP4_RSP_SUCCESS "OK"
#define IMAP4_RSP_FAILURE "NO"
#define IMAP4_RSP_PROTOCOL_ERR "BAD"
-#define IMAP4_RSP_SEARCH_UNSEEN "* SEARCH " /* This is the line that will be returned by
- * the IMAP4 server after receiving the
- * "SEARCH UNSEEN" command, followed by the
- * messages ID of the unseen messages. */
-
-
-static int tlabel = 0;
+#define IMAP4_RSP_SEARCH_UNSEEN "* SEARCH " /*
+ * This is the line that will be
+ * returned by the IMAP4 server
+ * after receiving the
+ * "SEARCH UNSEEN" command, followed
+ * by the messages ID of the unseen
+ * messages.
+ */
+
+static int tlabel;
static int tlabel_len;
static int unseen_string_found;
extern char tx_buffer[WMNOTIFY_BUFSIZE + 1];
extern char rx_buffer[WMNOTIFY_BUFSIZE + 1];
-
-static int
-IMAP4_ReceiveResponse( void )
+static int IMAP4_ReceiveResponse(void)
{
- int len;
- char *token;
- char *stringp;
-
- /* All interactions transmitted by client and server are in the form of
- lines, that is, strings that end with a CRLF. The protocol receiver
- of an IMAP4rev1 client or server is either reading a line, or is
- reading a sequence of octets with a known count followed by a line. */
-
- get_packet:
- len = WmnotifyGetResponse( rx_buffer, WMNOTIFY_BUFSIZE );
- if( len < 0 ) {
- /* An error occured. WmnotifyGetResponse() should have printed an error message. */
- goto error;
- }
- else if( len == 0 ) {
- /* The return value will be 0 when the peer has performed an orderly shutdown. */
- if( wmnotify_infos.debug ) {
- fprintf( stderr, "IMAP server has closed connection.\n" );
- }
- goto error;
- }
- else if( len == WMNOTIFY_BUFSIZE ) {
- if( wmnotify_infos.debug ) {
- ErrorLocation( __FILE__, __LINE__ );
- fprintf( stderr, "Response too big (%d bytes) to fit in receive buffer.\n", len );
- }
- goto error;
- }
-
- /* We suppose that, if a partial response packet was sent, it is not broken in the middle
- of a line (to confirm). Normally, each string is terminated by CRLF. */
- if( STREQ_LEN( &rx_buffer[ len - 2 ], IMAP4_ENDL, 2 ) == false ) {
- /* No CRLF found at the end of the buffer --> not handled by wmnotify. */
- ErrorLocation( __FILE__, __LINE__ );
- fprintf( stderr, "Response buffer doesn't contain CRLF at the end.\n" );
- goto error;
- }
-
- if( wmnotify_infos.debug ) {
- printf( "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n" );
- printf( "IMAP4 Server Response (size %d bytes):\n", len );
- printf( "%s", rx_buffer );
- printf( "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n" );
- }
-
- /* Converting the last CRLF into a LF followed by a NULL termination character. */
- rx_buffer[ len - 2 ] = '\n';
- rx_buffer[ len - 1 ] = '\0';
-
- /* Check the Server Completion Response returned by the IMAP4 server. There are currently
- * three Server Completion Responses codes: success ("OK"), failure ("NO") and protocol error
- * ("BAD"). */
- stringp = rx_buffer;
-
- while( ( token = strsep( &stringp, "\n" ) ) != NULL ) {
-
- /* In case no delimiter was found, the token is taken to
- be the entire string *stringp, and *stringp is made NULL. */
- if( stringp == NULL ) {
- if( token[0] == '\0' ) {
- /* This means we finished parsing the last line of the buffer, but we need to
- get more data to continue process the next part of the IMAP4 response. */
- goto get_packet;
- }
- else {
- /* This should never happen. */
- ErrorLocation( __FILE__, __LINE__ );
- fprintf( stderr, " Delimiter not found in strsep() call.\n" );
- goto error;
- }
- }
-
- if( token == NULL ) {
- /* This should never happen. */
- ErrorLocation( __FILE__, __LINE__ );
- fprintf( stderr, " NULL token returned by strsep().\n" );
- goto error;
- }
-
- if( token[0] == '*' ) {
- /* Untagged response. If there is a space after the SEARCH response, it means
- * at least 1 message is unseen. */
- if( STREQ_LEN( token, IMAP4_RSP_SEARCH_UNSEEN, strlen(IMAP4_RSP_SEARCH_UNSEEN) ) == true ) {
- unseen_string_found = true;
- }
- }
- else {
- /* Must be the status... */
-
- /* We check for the correct transaction label plus a space. */
- if( STREQ_LEN( token, tx_buffer, tlabel_len + 1 ) == true ) {
- token += tlabel_len + 1;
- if( STREQ_LEN( token, IMAP4_RSP_SUCCESS, strlen(IMAP4_RSP_SUCCESS) ) == true ) {
- goto end; /* OK, no errors. */
+ int len;
+ char *token;
+ char *stringp;
+
+ /*
+ * All interactions transmitted by client and server are in the form of
+ * lines, that is, strings that end with a CRLF. The protocol receiver
+ * of an IMAP4rev1 client or server is either reading a line, or is
+ * reading a sequence of octets with a known count followed by a line.
+ */
+
+get_packet:
+ len = WmnotifyGetResponse(rx_buffer, WMNOTIFY_BUFSIZE);
+ if (len < 0) {
+ /*
+ * An error occured. WmnotifyGetResponse() should have printed
+ * an error message.
+ */
+ goto error;
+ } else if (len == 0) {
+ /*
+ * The return value will be 0 when the peer has performed an
+ * orderly shutdown.
+ */
+ if (wmnotify_infos.debug) {
+ fprintf(stderr,
+ "IMAP server has closed connection.\n");
+ }
+ goto error;
+ } else if (len == WMNOTIFY_BUFSIZE) {
+ if (wmnotify_infos.debug) {
+ ErrorLocation(__FILE__, __LINE__);
+ fprintf(stderr,
+ "Response too big (%d bytes) to fit in receive buffer.\n",
+ len);
+ }
+ goto error;
}
- else if( STREQ_LEN( token, IMAP4_RSP_PROTOCOL_ERR, strlen(IMAP4_RSP_PROTOCOL_ERR) ) == true ) {
- fprintf( stderr, "%s: Protocol error (%s).\n", PACKAGE, token );
- goto error;
- }
- else if( STREQ_LEN( token, IMAP4_RSP_FAILURE, strlen(IMAP4_RSP_FAILURE) ) == true ) {
- fprintf( stderr, "%s: Failure (%s).\n", PACKAGE, token );
- goto error;
+
+ /*
+ * We suppose that, if a partial response packet was sent, it is not
+ * broken in the middle of a line (to confirm). Normally, each string is
+ * terminated by CRLF.
+ */
+ if (STREQ_LEN(&rx_buffer[len - 2], IMAP4_ENDL, 2) == false) {
+ /*
+ * No CRLF found at the end of the buffer --> not handled by
+ * wmnotify.
+ */
+ ErrorLocation(__FILE__, __LINE__);
+ fprintf(stderr,
+ "Response buffer doesn't contain CRLF at the end.\n");
+ goto error;
}
- else {
- fprintf( stderr, "%s: Unknown error code (%s).\n", PACKAGE, token );
- goto error;
+
+ if (wmnotify_infos.debug) {
+ printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+ printf("IMAP4 Server Response (size %d bytes):\n", len);
+ printf("%s", rx_buffer);
+ printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
}
- }
- else {
- fprintf( stderr, "%s: Error, transaction label mismatch.\n", PACKAGE );
- goto error;
- }
- }
- } /* while( token ) */
-
- /* Get next part of IMAP4 response. */
- goto get_packet;
-
- end:
- /* No error. */
- return len;
-
- error:
- return -1;
+
+ /*
+ * Converting the last CRLF into a LF followed by a NULL termination
+ * character.
+ */
+ rx_buffer[len - 2] = '\n';
+ rx_buffer[len - 1] = '\0';
+
+ /*
+ * Check the Server Completion Response returned by the IMAP4 server.
+ * There are currently three Server Completion Responses codes:
+ * success ("OK")
+ * failure ("NO")
+ * protocol error ("BAD")
+ */
+ stringp = rx_buffer;
+
+ while ((token = strsep(&stringp, "\n")) != NULL) {
+ /*
+ * In case no delimiter was found, the token is taken to
+ * be the entire string *stringp, and *stringp is made NULL.
+ */
+ if (stringp == NULL) {
+ if (token[0] == '\0') {
+ /*
+ * This means we finished parsing the last line
+ * of the buffer, but we need to get more data
+ * to continue process the next part of the
+ * IMAP4 response.
+ */
+ goto get_packet;
+ } else {
+ /* This should never happen. */
+ ErrorLocation(__FILE__, __LINE__);
+ fprintf(stderr,
+ " Delimiter not found in strsep() call.\n");
+ goto error;
+ }
+ }
+
+ if (token == NULL) {
+ /* This should never happen. */
+ ErrorLocation(__FILE__, __LINE__);
+ fprintf(stderr,
+ " NULL token returned by strsep().\n");
+ goto error;
+ }
+
+ if (token[0] == '*') {
+ /*
+ * Untagged response. If there is a space after the
+ * SEARCH response, it means at least 1 message is
+ * unseen.
+ */
+ if (STREQ_LEN
+ (token, IMAP4_RSP_SEARCH_UNSEEN,
+ strlen(IMAP4_RSP_SEARCH_UNSEEN)) == true) {
+ unseen_string_found = true;
+ }
+ } else {
+ /* Must be the status... */
+
+ /*
+ * We check for the correct transaction label plus a
+ * space.
+ */
+ if (STREQ_LEN(token, tx_buffer, tlabel_len + 1) ==
+ true) {
+ token += tlabel_len + 1;
+ if (STREQ_LEN
+ (token, IMAP4_RSP_SUCCESS,
+ strlen(IMAP4_RSP_SUCCESS)) == true) {
+ goto end; /* OK, no errors. */
+ } else
+ if (STREQ_LEN
+ (token, IMAP4_RSP_PROTOCOL_ERR,
+ strlen(IMAP4_RSP_PROTOCOL_ERR)) ==
+ true) {
+ fprintf(stderr,
+ "%s: Protocol error (%s).\n",
+ PACKAGE, token);
+ goto error;
+ } else
+ if (STREQ_LEN
+ (token, IMAP4_RSP_FAILURE,
+ strlen(IMAP4_RSP_FAILURE)) ==
+ true) {
+ fprintf(stderr,
+ "%s: Failure (%s).\n",
+ PACKAGE, token);
+ goto error;
+ } else {
+ fprintf(stderr,
+ "%s: Unknown error code (%s).\n",
+ PACKAGE, token);
+ goto error;
+ }
+ } else {
+ fprintf(stderr,
+ "%s: Error, transaction label mismatch.\n",
+ PACKAGE);
+ goto error;
+ }
+ }
+ } /* while( token ) */
+
+ /* Get next part of IMAP4 response. */
+ goto get_packet;
+
+end:
+ /* No error. */
+ return len;
+
+error:
+ return -1;
}
-static int
-IMAP4_SendCommand( int argc, char *argv[] )
+static int IMAP4_SendCommand(int argc, char *argv[])
{
- int len;
- int i;
-
- /* Adding Transaction Label. */
- tlabel++;
- tx_buffer[0] = 'A';
- len = 1;
- len += sprintf( tx_buffer + len, "%d", tlabel );
- tlabel_len = len;
-
- /* Adding command and it's arguments. */
- for( i = 0; i < argc; i++ ) {
- len += sprintf( tx_buffer + len, " %s", argv[i] );
- }
-
- if( wmnotify_infos.debug ) {
- tx_buffer[len] = '\0';
- printf( ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" );
- printf( "IMAP4 Client Command (size %d bytes):\n%s\n", len, tx_buffer );
- printf( ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" );
- }
-
- /* Adding termination characters. */
- len += sprintf( tx_buffer + len, IMAP4_ENDL );
-
- len = WmnotifySendData( tx_buffer, len );
- if( len < 0 ) {
- return EXIT_FAILURE;
- }
-
- len = IMAP4_ReceiveResponse();
- if( len < 0 ) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
+ int len;
+ int i;
+
+ /* Adding Transaction Label. */
+ tlabel++;
+ tx_buffer[0] = 'A';
+ len = 1;
+ len += sprintf(tx_buffer + len, "%d", tlabel);
+ tlabel_len = len;
+
+ /* Adding command and it's arguments. */
+ for (i = 0; i < argc; i++)
+ len += sprintf(tx_buffer + len, " %s", argv[i]);
+
+ if (wmnotify_infos.debug) {
+ tx_buffer[len] = '\0';
+ printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+ printf("IMAP4 Client Command (size %d bytes):\n%s\n", len,
+ tx_buffer);
+ printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+ }
+
+ /* Adding termination characters. */
+ len += sprintf(tx_buffer + len, IMAP4_ENDL);
+
+ len = WmnotifySendData(tx_buffer, len);
+ if (len < 0)
+ return EXIT_FAILURE;
+
+ len = IMAP4_ReceiveResponse();
+ if (len < 0)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
}
-int
-IMAP4_CheckForNewMail( void )
+int IMAP4_CheckForNewMail(void)
{
- char *argv[10];
- int new_messages = 0;
- int status;
-
- status = ConnectionEstablish( wmnotify_infos.server_name, wmnotify_infos.port );
- if( status != EXIT_SUCCESS ) {
- new_messages = -1;
- goto end;
- }
-
- argv[0] = IMAP4_CMD_LOGIN;
- argv[1] = wmnotify_infos.username;
- argv[2] = wmnotify_infos.password;
- status = IMAP4_SendCommand( 3, argv );
- if( status != EXIT_SUCCESS ) {
- new_messages = -1;
- goto imap4_logout;
- }
-
- /* Selecting the mailbox first. */
- argv[0] = IMAP4_CMD_EXAMINE;
- argv[1] = wmnotify_infos.imap_folder;
- status = IMAP4_SendCommand( 2, argv );
- if( status != EXIT_SUCCESS ) {
- new_messages = -1;
- goto imap4_logout;
- }
-
- /* Searching in selected mailbox for new messages. We must use the UNSEEN search criteria
- * instead of NEW (combination of RECENT and UNSEEN). If there is a new message, RECENT
- * and UNSEEN will have entries. But if we recheck again later, RECENT will report zero.
- * RECENT, when set, simply means that there are new messages since our last visit.
- But, on the other hand, when using EXAMINE, no messages should lose their RECENT flag. */
- unseen_string_found = false;
- argv[0] = IMAP4_CMD_SEARCH_UNSEEN;
- argv[1] = "";
- status = IMAP4_SendCommand( 1, argv );
- if( status != EXIT_SUCCESS ) {
- new_messages = -1;
- goto imap4_logout;
- }
-
- if( unseen_string_found == true ) {
- new_messages = 1;
- }
-
- imap4_logout:
- argv[0] = IMAP4_CMD_LOGOUT;
- status = IMAP4_SendCommand( 1, argv );
- if( status != EXIT_SUCCESS ) {
- new_messages = -1;
- }
-
- status = ConnectionTerminate();
- if( status != EXIT_SUCCESS ) {
- new_messages = -1;
- }
-
- end:
- return new_messages;
+ char *argv[10];
+ int new_messages = 0;
+ int status;
+
+ status =
+ ConnectionEstablish(wmnotify_infos.server_name,
+ wmnotify_infos.port);
+ if (status != EXIT_SUCCESS) {
+ new_messages = -1;
+ goto end;
+ }
+
+ argv[0] = IMAP4_CMD_LOGIN;
+ argv[1] = wmnotify_infos.username;
+ argv[2] = wmnotify_infos.password;
+ status = IMAP4_SendCommand(3, argv);
+ if (status != EXIT_SUCCESS) {
+ new_messages = -1;
+ goto imap4_logout;
+ }
+
+ /* Selecting the mailbox first. */
+ argv[0] = IMAP4_CMD_EXAMINE;
+ argv[1] = wmnotify_infos.imap_folder;
+ status = IMAP4_SendCommand(2, argv);
+ if (status != EXIT_SUCCESS) {
+ new_messages = -1;
+ goto imap4_logout;
+ }
+
+ /*
+ * Searching in selected mailbox for new messages. We must use the
+ * UNSEEN search criteria instead of NEW (combination of RECENT and
+ * UNSEEN). If there is a new message, RECENT and UNSEEN will have
+ * entries. But if we recheck again later, RECENT will report zero.
+ * RECENT, when set, simply means that there are new messages since our
+ * last visit. But, on the other hand, when using EXAMINE, no messages
+ * should lose their RECENT flag.
+ */
+ unseen_string_found = false;
+ argv[0] = IMAP4_CMD_SEARCH_UNSEEN;
+ argv[1] = "";
+ status = IMAP4_SendCommand(1, argv);
+ if (status != EXIT_SUCCESS) {
+ new_messages = -1;
+ goto imap4_logout;
+ }
+
+ if (unseen_string_found == true)
+ new_messages = 1;
+
+imap4_logout:
+ argv[0] = IMAP4_CMD_LOGOUT;
+ status = IMAP4_SendCommand(1, argv);
+ if (status != EXIT_SUCCESS)
+ new_messages = -1;
+
+ status = ConnectionTerminate();
+ if (status != EXIT_SUCCESS)
+ new_messages = -1;
+
+end:
+ return new_messages;
}
# define _SCOPE_ extern
#endif
-int
-IMAP4_CheckForNewMail( void );
+int IMAP4_CheckForNewMail(void);
-#endif /* IMAP_H */
+#endif /* IMAP_H */
char rx_buffer[WMNOTIFY_BUFSIZE + 1];
-int
-SocketOpen( char *server_name, int port )
+int SocketOpen(char *server_name, int port)
{
- int status;
- int sock_fd = -1;
- struct hostent *hostinfo;
- struct sockaddr_in serv_addr;
-
- hostinfo = gethostbyname(server_name);
- if( hostinfo == NULL ) {
- herror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto error;
- }
-
- /* Open socket for Stream (TCP) */
- sock_fd = socket( PF_INET, SOCK_STREAM, 0 );
- if( sock_fd < 0 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto error;
- }
-
+ int status;
+ int sock_fd = -1;
+ struct hostent *hostinfo;
+ struct sockaddr_in serv_addr;
+
+ hostinfo = gethostbyname(server_name);
+ if (hostinfo == NULL) {
+ herror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto error;
+ }
+
+ /* Open socket for Stream (TCP) */
+ sock_fd = socket(PF_INET, SOCK_STREAM, 0);
+ if (sock_fd < 0) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto error;
+ }
+
/*---Initialize server address/port struct---*/
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(port);
- serv_addr.sin_addr = *((struct in_addr *) hostinfo->h_addr );
- memset( &( serv_addr.sin_zero ), '\0', 8 ); /* Clear the rest of the structure. */
-
- if( wmnotify_infos.debug ) {
- printf( " Server IP = %s\n", inet_ntoa( serv_addr.sin_addr ) );
- printf( " Server port = %d\n", ntohs(serv_addr.sin_port) );
- }
-
- /* Establishing connection. */
- status = connect( sock_fd, (struct sockaddr *) &(serv_addr), sizeof(serv_addr) );
- if( status < 0 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto error;
- }
-
- end:
- return sock_fd;
-
- error:
- if( sock_fd >= 0 ) {
- status = close( sock_fd );
- if( status < 0 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- }
- }
-
- sock_fd = -1;
- goto end;
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_port = htons(port);
+ serv_addr.sin_addr = *((struct in_addr *)hostinfo->h_addr);
+ memset(&(serv_addr.sin_zero), '\0', 8); /* Clear rest of structure. */
+
+ if (wmnotify_infos.debug) {
+ printf(" Server IP = %s\n",
+ inet_ntoa(serv_addr.sin_addr));
+ printf(" Server port = %d\n", ntohs(serv_addr.sin_port));
+ }
+
+ /* Establishing connection. */
+ status = connect(sock_fd, (struct sockaddr *)&(serv_addr),
+ sizeof(serv_addr));
+ if (status < 0) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto error;
+ }
+
+end:
+ return sock_fd;
+
+error:
+ if (sock_fd >= 0) {
+ status = close(sock_fd);
+ if (status < 0) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ }
+ }
+
+ sock_fd = -1;
+ goto end;
}
-int
-ConnectionEstablish( char *server_name, int port )
+int ConnectionEstablish(char *server_name, int port)
{
- int len;
- char rx_buffer[1024]; /* Temporary... */
+ int len;
+ char rx_buffer[1024]; /* Temporary... */
- wmnotify_infos.sock_fd = SocketOpen( wmnotify_infos.server_name, wmnotify_infos.port );
- if( wmnotify_infos.sock_fd < 0 ) {
- goto error;
- }
+ wmnotify_infos.sock_fd =
+ SocketOpen(wmnotify_infos.server_name, wmnotify_infos.port);
+ if (wmnotify_infos.sock_fd < 0)
+ goto error;
#if HAVE_SSL
- if( wmnotify_infos.use_ssl == true ) {
- int status;
- status = InitSSL( wmnotify_infos.sock_fd );
- if( status != EXIT_SUCCESS ) {
- goto error;
- }
- }
-#endif
-
- /* Testing connection. */
- len = WmnotifyGetResponse( rx_buffer, 1024 );
- if( len < 0 ) {
- goto error;
- }
-
- if( wmnotify_infos.debug ) {
- rx_buffer[len] = 0;
- printf(" Connect response:\n%s\n", rx_buffer );
- }
-
- return EXIT_SUCCESS;
-
- error:
- return EXIT_FAILURE;
+ if (wmnotify_infos.use_ssl == true) {
+ int status;
+ status = InitSSL(wmnotify_infos.sock_fd);
+ if (status != EXIT_SUCCESS)
+ goto error;
+ }
+#endif
+
+ /* Testing connection. */
+ len = WmnotifyGetResponse(rx_buffer, 1024);
+ if (len < 0)
+ goto error;
+
+ if (wmnotify_infos.debug) {
+ rx_buffer[len] = 0;
+ printf(" Connect response:\n%s\n", rx_buffer);
+ }
+
+ return EXIT_SUCCESS;
+
+error:
+ return EXIT_FAILURE;
}
-int
-ConnectionTerminate( void )
+int ConnectionTerminate(void)
{
#if HAVE_SSL
- if( wmnotify_infos.use_ssl == true ) {
- SSL_free( ssl_infos.ssl ); /* release connection state */
- }
+ if (wmnotify_infos.use_ssl == true)
+ SSL_free(ssl_infos.ssl); /* release connection state */
#endif
- close( wmnotify_infos.sock_fd ); /* close socket */
+ close(wmnotify_infos.sock_fd); /* close socket */
#if HAVE_SSL
- if( wmnotify_infos.use_ssl == true ) {
- SSL_CTX_free( ssl_infos.ctx ); /* release context */
- }
+ if (wmnotify_infos.use_ssl == true)
+ SSL_CTX_free(ssl_infos.ctx); /* release context */
#endif
-
- return EXIT_SUCCESS;
+
+ return EXIT_SUCCESS;
}
-int
-WmnotifySendData( char *buffer, int size )
+int WmnotifySendData(char *buffer, int size)
{
- int len;
+ int len;
#if HAVE_SSL
- if( wmnotify_infos.use_ssl == true ) {
- len = SSL_write( ssl_infos.ssl, buffer, size ); /* Encrypt & send message */
- if( len <= 0 ) {
- SSL_get_error( ssl_infos.ssl, len );
- len = -1;
- }
-
- return len;
- }
-#endif /* HAVE_SSL */
-
- /* if errno = EINTR, it means the operation was interrupted by a signal before any data was
- * sent. We must retry the operation in this case. */
- do {
- len = send( wmnotify_infos.sock_fd, buffer, size, SEND_FLAGS );
- }
- while( ( len < 0 ) && ( errno == EINTR ) );
-
- if( len < 0 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- }
-
- return len;
+ if (wmnotify_infos.use_ssl == true) {
+ /* Encrypt & send message */
+ len = SSL_write(ssl_infos.ssl, buffer, size);
+ if (len <= 0) {
+ SSL_get_error(ssl_infos.ssl, len);
+ len = -1;
+ }
+
+ return len;
+ }
+#endif /* HAVE_SSL */
+
+ /*
+ * if errno = EINTR, it means the operation was interrupted by a signal
+ * before any data was sent. We must retry the operation in this case.
+ */
+ do {
+ len = send(wmnotify_infos.sock_fd, buffer, size, SEND_FLAGS);
+ } while ((len < 0) && (errno == EINTR));
+
+ if (len < 0) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ }
+
+ return len;
}
-int
-WmnotifyGetResponse( char *buffer, int max_size )
+int WmnotifyGetResponse(char *buffer, int max_size)
{
- int len;
+ int len;
#if HAVE_SSL
- if( wmnotify_infos.use_ssl == true ) {
- len = SSL_read( ssl_infos.ssl, buffer, max_size ); /* Get reply & decrypt. */
- switch( SSL_get_error( ssl_infos.ssl, len ) ) {
- case SSL_ERROR_NONE:
- /* Success. */
- break;
- case SSL_ERROR_ZERO_RETURN:
- fprintf( stderr, "%s: SSL_read() connection closed.\n", PACKAGE );
- break;
- case SSL_ERROR_SYSCALL:
- fprintf( stderr, "%s: SSL_read() I/O error.\n", PACKAGE );
- goto ssl_error;
- case SSL_ERROR_SSL:
- fprintf( stderr, "%s: SSL_read() protocol error.\n", PACKAGE );
- goto ssl_error;
- default:
- fprintf( stderr, "%s: SSL_read() error.\n", PACKAGE );
- goto ssl_error;
- }
-
- return len;
-
- ssl_error:
- return -1;
- }
+ if (wmnotify_infos.use_ssl == true) {
+ /* Get reply & decrypt. */
+ len = SSL_read(ssl_infos.ssl, buffer, max_size);
+ switch (SSL_get_error(ssl_infos.ssl, len)) {
+ case SSL_ERROR_NONE:
+ /* Success. */
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ fprintf(stderr,
+ "%s: SSL_read() connection closed.\n",
+ PACKAGE);
+ break;
+ case SSL_ERROR_SYSCALL:
+ fprintf(stderr, "%s: SSL_read() I/O error.\n",
+ PACKAGE);
+ goto ssl_error;
+ case SSL_ERROR_SSL:
+ fprintf(stderr, "%s: SSL_read() protocol error.\n",
+ PACKAGE);
+ goto ssl_error;
+ default:
+ fprintf(stderr, "%s: SSL_read() error.\n",
+ PACKAGE);
+ goto ssl_error;
+ }
+
+ return len;
+
+ssl_error:
+ return -1;
+ }
#endif /* HAVE_SSL */
- /* if errno = EINTR, it means the operation was interrupted by a signal before any data was
- * read. We must retry the operation in this case. */
- do {
- len = recv( wmnotify_infos.sock_fd, buffer, max_size, RECV_FLAGS );
- }
- while( ( len < 0 ) && ( errno == EINTR ) );
-
- if( len < 0 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- }
-
- return len;
+ /*
+ * if errno = EINTR, it means the operation was interrupted by a signal
+ * before any data was read. We must retry the operation in this case.
+ */
+ do {
+ len =
+ recv(wmnotify_infos.sock_fd, buffer, max_size,
+ RECV_FLAGS);
+ } while ((len < 0) && (errno == EINTR));
+
+ if (len < 0) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ }
+
+ return len;
}
CRLF. IMAP4 responses can be more than 1024 characters. */
#define WMNOTIFY_BUFSIZE 10240
-int
-SocketOpen( char *server_name, int port );
+int SocketOpen(char *server_name, int port);
-int
-ConnectionEstablish( char *server_name, int port );
+int ConnectionEstablish(char *server_name, int port);
-int
-ConnectionTerminate( void );
+int ConnectionTerminate(void);
-int
-WmnotifySendData( char *buffer, int size );
+int WmnotifySendData(char *buffer, int size);
-int
-WmnotifyGetResponse( char *buffer, int max_size );
+int WmnotifyGetResponse(char *buffer, int max_size);
-#endif /* NETWORK_H */
+#endif /* NETWORK_H */
/*******************************************************************************
* Display the help message and exit
******************************************************************************/
-static void
-DisplayUsage( void )
+static void DisplayUsage(void)
{
- printf( "Usage: %s [OPTIONS]...\n", PACKAGE );
- printf( "Email notification for single POP3 or IMAP4 account.\n\n" );
- printf( " -c <config-file> use alternate configuration file\n" );
- printf( " -d Display debugging messages.\n" );
- printf( " -display <host:display> X display name\n" );
- printf( " -geometry +XPOS+YPOS initial window position\n" );
- printf( " -h display this help and exit\n" );
- printf( " -version display version information and exit\n");
- printf( "\n" );
+ printf("Usage: %s [OPTIONS]...\n", PACKAGE);
+ printf("Email notification for single POP3 or IMAP4 account.\n\n");
+ printf(" -c <config-file> ");
+ printf("use alternate configuration file\n");
+ printf(" -d ");
+ printf("Display debugging messages.\n");
+ printf(" -display <host:display> ");
+ printf("X display name\n");
+ printf(" -geometry +XPOS+YPOS ");
+ printf("initial window position\n");
+ printf(" -h ");
+ printf("display this help and exit\n");
+ printf(" -version ");
+ printf("display version information and exit\n");
+ printf("\n");
}
/*******************************************************************************
* Display version information and exit
******************************************************************************/
-static void
-DisplayVersion( void )
+static void DisplayVersion(void)
{
- printf( "\n" );
- printf( " %s, version %s\n", PACKAGE, VERSION );
- printf( " Written by Hugo Villeneuve\n\n" );
+ printf("\n");
+ printf(" %s, version %s\n", PACKAGE, VERSION);
+ printf(" Written by Hugo Villeneuve\n\n");
}
static void
-InvalidOption( const char *message, /*@null@*/ const char *string )
+InvalidOption(const char *message, /*@null@ */ const char *string)
{
- if( string == NULL ) {
- fprintf(stderr, "%s: %s\n", PACKAGE, message );
- }
- else {
- fprintf(stderr, "%s: %s %s\n", PACKAGE, message, string );
- }
+ if (string == NULL)
+ fprintf(stderr, "%s: %s\n", PACKAGE, message);
+ else
+ fprintf(stderr, "%s: %s %s\n", PACKAGE, message, string);
- fprintf(stderr, "Try `%s -h' for more information.\n", PACKAGE );
+ fprintf(stderr, "Try `%s -h' for more information.\n", PACKAGE);
- exit( EXIT_FAILURE );
+ exit(EXIT_FAILURE);
}
/*******************************************************************************
* Initializes the different options passed as arguments on the command line.
******************************************************************************/
-void
-ParseCommandLineOptions( int argc, char *argv[] )
+void ParseCommandLineOptions(int argc, char *argv[])
{
- int i;
- char *token;
- bool config_file_on = false;
- bool display_on = false;
- bool geometry_on = false;
-
- /* Default values. */
- wmnotify_infos.debug = false;
-
- for( i = 1; i < argc; i++ ) {
- token = argv[i];
- switch( token[0] ) {
- case '-':
- /* Processing options names */
- switch( token[1] ) {
- case 'c':
- if( strlen( &token[1] ) == 1 ) {
- config_file_on = true;
- }
- else {
- InvalidOption( "invalid option", token );
- }
- break;
- case 'd':
- if( STREQ( "display", &token[1] ) ) {
- display_on = true;
- }
- else if( strlen( &token[1] ) == 1 ) {
- wmnotify_infos.debug = true;
- }
- break;
- case 'g':
- if( STREQ( "geometry", &token[1] ) ) {
- geometry_on = true;
- }
- else {
- InvalidOption( "invalid option", token );
- }
- break;
- case 'h':
- if( strlen( &token[1] ) == 1 ) {
- DisplayUsage();
- exit( EXIT_SUCCESS );
- }
- InvalidOption( "invalid option", token );
- break;
- case 'v' :
- if( STREQ( "version", &token[1] ) ) {
- DisplayVersion();
- exit( EXIT_SUCCESS );
- }
- else {
- InvalidOption( "invalid option", token );
+ int i;
+ char *token;
+ bool config_file_on = false;
+ bool display_on = false;
+ bool geometry_on = false;
+
+ /* Default values. */
+ wmnotify_infos.debug = false;
+
+ for (i = 1; i < argc; i++) {
+ token = argv[i];
+ switch (token[0]) {
+ case '-':
+ /* Processing options names */
+ switch (token[1]) {
+ case 'c':
+ if (strlen(&token[1]) == 1) {
+ config_file_on = true;
+ } else {
+ InvalidOption("invalid option",
+ token);
+ }
+ break;
+ case 'd':
+ if (STREQ("display", &token[1]))
+ display_on = true;
+ else if (strlen(&token[1]) == 1)
+ wmnotify_infos.debug = true;
+ break;
+ case 'g':
+ if (STREQ("geometry", &token[1]))
+ geometry_on = true;
+ else
+ InvalidOption("invalid option", token);
+ break;
+ case 'h':
+ if (strlen(&token[1]) == 1) {
+ DisplayUsage();
+ exit(EXIT_SUCCESS);
+ }
+ InvalidOption("invalid option", token);
+ break;
+ case 'v':
+ if (STREQ("version", &token[1])) {
+ DisplayVersion();
+ exit(EXIT_SUCCESS);
+ } else {
+ InvalidOption("invalid option", token);
+ }
+ break;
+ default:
+ InvalidOption("invalid option", token);
+ break;
+ } /* end switch( token[1] ) */
+ break;
+ default:
+ /* Processing options arguments */
+ if (config_file_on != false) {
+ wmnotify_infos.optional_config_file =
+ token;
+ /*strcpy( config_file_name, token ); */
+ config_file_on = false;
+ } else if (display_on != false) {
+ display_on = false;
+ wmnotify_infos.display_arg = token;
+ } else if (geometry_on != false) {
+ geometry_on = false;
+ wmnotify_infos.geometry_arg = token;
+ } else {
+ InvalidOption("invalid option", token);
+ }
+ break;
+ } /* end switch( token[0] ) */
+ } /* end for */
+
+ if (config_file_on != false) {
+ InvalidOption("missing configuration file parameter",
+ NULL);
+ } else if (display_on != false) {
+ InvalidOption("missing display parameter", NULL);
+ } else if (geometry_on != false) {
+ InvalidOption("missing geometry parameter", NULL);
}
- break;
- default:
- InvalidOption( "invalid option", token );
- break;
- } /* end switch( token[1] ) */
- break;
- default:
- /* Processing options arguments */
- if( config_file_on != false ) {
- wmnotify_infos.optional_config_file = token;
- /*strcpy( config_file_name, token );*/
- config_file_on = false;
- }
- else if( display_on != false ) {
- display_on = false;
- wmnotify_infos.display_arg = token;
- }
- else if( geometry_on != false ) {
- geometry_on = false;
- wmnotify_infos.geometry_arg = token;
- }
- else {
- InvalidOption( "invalid option", token );
- }
- break;
- } /* end switch( token[0] ) */
- } /* end for */
-
- if( config_file_on != false ) {
- InvalidOption( "missing configuration file parameter", NULL );
- }
- else if( display_on != false ) {
- InvalidOption( "missing display parameter", NULL );
- }
- else if( geometry_on != false ) {
- InvalidOption( "missing geometry parameter", NULL );
- }
}
#ifndef OPTIONS_H
#define OPTIONS_H 1
-void
-ParseCommandLineOptions( int argc, char *argv[] );
+void ParseCommandLineOptions(int argc, char *argv[]);
-#endif /* OPTIONS_H */
+#endif /* OPTIONS_H */
#include "network.h"
#include "pop3.h"
-
/* Defined in network.c */
extern char tx_buffer[WMNOTIFY_BUFSIZE + 1];
extern char rx_buffer[WMNOTIFY_BUFSIZE + 1];
-
-static int
-POP3_ReceiveResponse( void )
+static int POP3_ReceiveResponse(void)
{
- int len;
-
- len = WmnotifyGetResponse( rx_buffer, WMNOTIFY_BUFSIZE );
- if( len < 0 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- return len;
- }
-
- rx_buffer[ len - 2 ] = '\0';
-
- if( wmnotify_infos.debug ) {
- printf( "Response: \"%s\"\n", rx_buffer );
- }
-
- /* No error in recv at this point. Now we parse response from POP3 server. */
-
- /* Check the status indicator returned by the POP3 server.
- There are currently two status indicators: positive ("+OK") and negative
- ("-ERR"). Servers MUST send the status indicators in upper case. */
- if( STREQ_LEN( rx_buffer, POP3_RSP_SUCCESS, strlen(POP3_RSP_SUCCESS) ) == false ) {
- fprintf( stderr, "%s: Error, POP3 server responded:\n \"%s\"\n", PACKAGE, rx_buffer );
- len = -1;
- }
-
- return len;
+ int len;
+
+ len = WmnotifyGetResponse(rx_buffer, WMNOTIFY_BUFSIZE);
+ if (len < 0) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ return len;
+ }
+
+ rx_buffer[len - 2] = '\0';
+
+ if (wmnotify_infos.debug)
+ printf("Response: \"%s\"\n", rx_buffer);
+
+ /*
+ * No error in recv at this point. Now we parse response from POP3
+ * server.
+ */
+
+ /*
+ * Check the status indicator returned by the POP3 server.
+ * There are currently two status indicators: positive ("+OK") and
+ * negative ("-ERR"). Servers MUST send the status indicators in upper
+ * case.
+ */
+ if (STREQ_LEN
+ (rx_buffer, POP3_RSP_SUCCESS,
+ strlen(POP3_RSP_SUCCESS)) == false) {
+ fprintf(stderr,
+ "%s: Error, POP3 server responded:\n \"%s\"\n",
+ PACKAGE, rx_buffer);
+ len = -1;
+ }
+
+ return len;
}
-static int
-POP3_SendCommand( int argc, char *argv[] )
+static int POP3_SendCommand(int argc, char *argv[])
{
- int len;
- int i;
-
- /* Adding command and it's arguments. */
- for( i = 0, len = 0; i < argc; i++ ) {
- len += sprintf( tx_buffer + len, "%s", argv[i] );
- if( i != ( argc - 1 ) ) {
- len += sprintf( tx_buffer + len, " " );
- }
- }
-
- if( wmnotify_infos.debug ) {
- tx_buffer[len] = '\0';
- printf( "Command: \"%s\"\n", tx_buffer );
- }
-
- /* Adding termination characters. */
- len += sprintf( tx_buffer + len, POP3_ENDL );
-
- len = WmnotifySendData( tx_buffer, len );
- if( len < 0 ) {
- return EXIT_FAILURE;
- }
-
- len = POP3_ReceiveResponse();
- if( len < 0 ) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
+ int len;
+ int i;
+
+ /* Adding command and it's arguments. */
+ for (i = 0, len = 0; i < argc; i++) {
+ len += sprintf(tx_buffer + len, "%s", argv[i]);
+
+ if (i != (argc - 1))
+ len += sprintf(tx_buffer + len, " ");
+ }
+
+ if (wmnotify_infos.debug) {
+ tx_buffer[len] = '\0';
+ printf("Command: \"%s\"\n", tx_buffer);
+ }
+
+ /* Adding termination characters. */
+ len += sprintf(tx_buffer + len, POP3_ENDL);
+
+ len = WmnotifySendData(tx_buffer, len);
+ if (len < 0)
+ return EXIT_FAILURE;
+
+ len = POP3_ReceiveResponse();
+ if (len < 0)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
}
/* Return the number of new messages on success, -1 on error. */
-static int
-POP3_ParseStatCommand( void )
+static int POP3_ParseStatCommand(void)
{
- int new_messages;
- char *token;
-
- /* STAT command:
- * The positive response consists of "+OK" followed by a single space, the number of messages
- * in the maildrop, a single space, and the size of the maildrop in octets. */
- token = strtok( rx_buffer, " " );
- token = strtok( NULL, " " );
- if( token != NULL ) {
- /* Do more checks for digits... */
- new_messages = atoi( token );
- }
- else {
- fprintf( stderr, "%s: Error parsing \"STAT\" response", PACKAGE );
- new_messages = -1;
- }
-
- return new_messages;
+ int new_messages;
+ char *token;
+
+ /*
+ * STAT command:
+ * The positive response consists of "+OK" followed by a single space,
+ * the number of messages in the maildrop, a single space, and the size
+ * of the maildrop in octets.
+ */
+ token = strtok(rx_buffer, " ");
+ token = strtok(NULL, " ");
+ if (token != NULL) {
+ /* Do more checks for digits... */
+ new_messages = atoi(token);
+ } else {
+ fprintf(stderr, "%s: Error parsing \"STAT\" response",
+ PACKAGE);
+ new_messages = -1;
+ }
+
+ return new_messages;
}
-int
-POP3_CheckForNewMail( void )
+int POP3_CheckForNewMail(void)
{
- int status;
- int new_messages = -1;
- char *argv[10];
-
- status = ConnectionEstablish( wmnotify_infos.server_name, wmnotify_infos.port );
- if( status != EXIT_SUCCESS ) {
- return -1;
- }
-
- /* Sending username. */
- argv[0] = POP3_CMD_USERNAME;
- argv[1] = wmnotify_infos.username;
- status = POP3_SendCommand( 2, argv );
- if( status != EXIT_SUCCESS ) {
- goto pop3_close_connection;
- }
-
- /* Sending password. */
- argv[0] = POP3_CMD_PASSWORD;
- argv[1] = wmnotify_infos.password;
- status = POP3_SendCommand( 2, argv );
- if( status != EXIT_SUCCESS ) {
- goto pop3_close_connection;
- }
-
- /* Sending STAT command to inquiry about new messages. */
- argv[0] = POP3_CMD_STAT;
- status = POP3_SendCommand( 1, argv );
- if( status != EXIT_SUCCESS ) {
- goto pop3_close_connection;
- }
-
- /* Parsing STAT command. */
- new_messages = POP3_ParseStatCommand();
- if( new_messages < 0 ) {
- goto pop3_close_connection;
- }
-
- /* Sending QUIT command. */
- argv[0] = POP3_CMD_QUIT;
- status = POP3_SendCommand( 1, argv );
- if( status != EXIT_SUCCESS ) {
- new_messages = -1;
- goto pop3_close_connection;
- }
-
- pop3_close_connection:
- status = ConnectionTerminate();
- if( status != EXIT_SUCCESS ) {
- new_messages = -1;
- }
-
- return new_messages;
+ int status;
+ int new_messages = -1;
+ char *argv[10];
+
+ status =
+ ConnectionEstablish(wmnotify_infos.server_name,
+ wmnotify_infos.port);
+ if (status != EXIT_SUCCESS)
+ return -1;
+
+ /* Sending username. */
+ argv[0] = POP3_CMD_USERNAME;
+ argv[1] = wmnotify_infos.username;
+ status = POP3_SendCommand(2, argv);
+ if (status != EXIT_SUCCESS)
+ goto pop3_close_connection;
+
+ /* Sending password. */
+ argv[0] = POP3_CMD_PASSWORD;
+ argv[1] = wmnotify_infos.password;
+ status = POP3_SendCommand(2, argv);
+ if (status != EXIT_SUCCESS)
+ goto pop3_close_connection;
+
+ /* Sending STAT command to inquiry about new messages. */
+ argv[0] = POP3_CMD_STAT;
+ status = POP3_SendCommand(1, argv);
+ if (status != EXIT_SUCCESS)
+ goto pop3_close_connection;
+
+ /* Parsing STAT command. */
+ new_messages = POP3_ParseStatCommand();
+ if (new_messages < 0)
+ goto pop3_close_connection;
+
+ /* Sending QUIT command. */
+ argv[0] = POP3_CMD_QUIT;
+ status = POP3_SendCommand(1, argv);
+ if (status != EXIT_SUCCESS) {
+ new_messages = -1;
+ goto pop3_close_connection;
+ }
+
+pop3_close_connection:
+ status = ConnectionTerminate();
+ if (status != EXIT_SUCCESS)
+ new_messages = -1;
+
+ return new_messages;
}
#define POP3_RSP_SUCCESS "+OK"
#define POP3_RSP_FAILURE "-ERR"
-int
-POP3_CheckForNewMail( void );
+int POP3_CheckForNewMail(void);
#endif /* POP3_H */
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/soundcard.h>
-#elif( defined(sun) && defined(unix) )
+#elif(defined(sun) && defined(unix))
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/audioio.h>
#define BUFFER_LEN ((sf_count_t) 2048)
-static int
-OpenDspDevice( int channels, int srate )
+static int OpenDspDevice(int channels, int srate)
{
- int fd, status;
-#if defined (__linux__)
- int stereo, temp;
- const char audio_device[] = "/dev/dsp";
-#elif( defined(sun) && defined(unix) )
- audio_info_t audio_info;
- const char audio_device[] = "/dev/audio";
+ int fd, status;
+#if defined(__linux__)
+ int stereo, temp;
+ const char audio_device[] = "/dev/dsp";
+#elif(defined(sun) && defined(unix))
+ audio_info_t audio_info;
+ const char audio_device[] = "/dev/audio";
#endif
-
-#if defined (__linux__)
- fd = open( audio_device, O_WRONLY, 0 );
-#elif( defined(sun) && defined(unix) )
- /* Open the audio device - write only, non-blocking */
- fd = open( audio_device, O_WRONLY | O_NONBLOCK );
+
+#if defined(__linux__)
+ fd = open(audio_device, O_WRONLY, 0);
+#elif(defined(sun) && defined(unix))
+ /* Open the audio device - write only, non-blocking */
+ fd = open(audio_device, O_WRONLY | O_NONBLOCK);
#endif
-
- if( fd < 0 ) {
- fprintf( stderr, "%s: open() failed trying to open device '%s':\n", PACKAGE,
- audio_device );
- fprintf( stderr, " %s\n", strerror( errno ) );
- fprintf( stderr,
- " Check if device file exists and has correct write permissions.\n" );
- ErrorLocation( __FILE__, __LINE__ );
- return -1;
- }
-
-#if defined (__linux__)
- stereo = 0;
- status = ioctl( fd, SNDCTL_DSP_STEREO, &stereo );
- if( status == -1 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- status = ioctl( fd, SNDCTL_DSP_RESET, 0 );
- if( status > 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- temp = 16;
- status = ioctl( fd, SOUND_PCM_WRITE_BITS, &temp );
- if( status != 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- status = ioctl( fd, SOUND_PCM_WRITE_CHANNELS, &channels );
- if( status != 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- status = ioctl( fd, SOUND_PCM_WRITE_RATE, &srate );
- if( status != 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- status = ioctl( fd, SNDCTL_DSP_SYNC, 0 );
- if( status != 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
-#elif( defined(sun) && defined(unix) )
- /* Retrieve standard values. */
- AUDIO_INITINFO( &audio_info );
-
- audio_info.play.sample_rate = sfinfo.samplerate;
- audio_info.play.channels = sfinfo.channels;
- audio_info.play.precision = 16;
- audio_info.play.encoding = AUDIO_ENCODING_LINEAR;
- audio_info.play.gain = AUDIO_MAX_GAIN;
- audio_info.play.balance = AUDIO_MID_BALANCE;
-
- status = ioctl( audio_fd, AUDIO_SETINFO, &audio_info );
- if( status > 0 ) {
- fprintf( stderr, "%s: ioctl() failed: %s\n", PACKAGE, strerror( errno ) );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
+
+ if (fd < 0) {
+ fprintf(stderr,
+ "%s: open() failed trying to open device '%s':\n",
+ PACKAGE, audio_device);
+ fprintf(stderr, " %s\n", strerror(errno));
+ fprintf(stderr,
+ " Check if device file exists and has correct write permissions.\n");
+ ErrorLocation(__FILE__, __LINE__);
+ return -1;
+ }
+#if defined(__linux__)
+ stereo = 0;
+ status = ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
+ if (status == -1) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ status = ioctl(fd, SNDCTL_DSP_RESET, 0);
+ if (status > 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ temp = 16;
+ status = ioctl(fd, SOUND_PCM_WRITE_BITS, &temp);
+ if (status != 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &channels);
+ if (status != 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ status = ioctl(fd, SOUND_PCM_WRITE_RATE, &srate);
+ if (status != 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ status = ioctl(fd, SNDCTL_DSP_SYNC, 0);
+ if (status != 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+#elif(defined(sun) && defined(unix))
+ /* Retrieve standard values. */
+ AUDIO_INITINFO(&audio_info);
+
+ audio_info.play.sample_rate = sfinfo.samplerate;
+ audio_info.play.channels = sfinfo.channels;
+ audio_info.play.precision = 16;
+ audio_info.play.encoding = AUDIO_ENCODING_LINEAR;
+ audio_info.play.gain = AUDIO_MAX_GAIN;
+ audio_info.play.balance = AUDIO_MID_BALANCE;
+
+ status = ioctl(audio_fd, AUDIO_SETINFO, &audio_info);
+ if (status > 0) {
+ fprintf(stderr, "%s: ioctl() failed: %s\n", PACKAGE,
+ strerror(errno));
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
#endif
-
- return fd;
+
+ return fd;
}
-void
-PlayAudioFile( char *filename, int volume )
+void PlayAudioFile(char *filename, int volume)
{
- static short buffer[BUFFER_LEN];
- SNDFILE *sndfile;
- SF_INFO sfinfo;
- int audio_fd;
- int readcount;
- int status;
-#if defined (__linux__)
- int subformat;
- int m;
-#elif( defined(sun) && defined(unix) )
- unsigned long delay_time;
- long start_count, output_count, write_count;
- bool done;
+ static short buffer[BUFFER_LEN];
+ SNDFILE *sndfile;
+ SF_INFO sfinfo;
+ int audio_fd;
+ int readcount;
+ int status;
+#if defined(__linux__)
+ int subformat;
+ int m;
+#elif(defined(sun) && defined(unix))
+ unsigned long delay_time;
+ long start_count, output_count, write_count;
+ bool done;
#endif
- if( wmnotify_infos.debug ) {
- printf( "%s: PlayAudioFile() Entry\n", PACKAGE );
- }
-
- if( filename == NULL ) {
- fprintf( stderr, "%s: No audio file specified.\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- sndfile = sf_open( filename, SFM_READ, &sfinfo );
-
- if( sndfile == NULL ) {
- fprintf( stderr, "%s: sf_open() failed trying to open '%s':\n", PACKAGE, filename );
- fprintf( stderr, " %s\n", sf_strerror(NULL) );
- fprintf( stderr, " Check if file exists and has correct read permissions.\n" );
- ErrorLocation( __FILE__, __LINE__ );
- return;
- }
-
- if( sfinfo.channels < 1 || sfinfo.channels > 2 ) {
- fprintf( stderr, "%s: Audio file has %d channel(s), but ", PACKAGE, sfinfo.channels );
- fprintf( stderr, "we support only 1 or 2 channels.\n" );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- audio_fd = OpenDspDevice( sfinfo.channels, sfinfo.samplerate );
- if( audio_fd < 0 ) {
- goto play_audio_file_close_file;
- }
-
-#if( defined(sun) && defined(unix) )
- /* Delay time equal to 1/4 of a buffer in microseconds. */
- delay_time = (BUFFER_LEN * 1000000) / (sfinfo.samplerate * 4);
-#endif
+ if (wmnotify_infos.debug)
+ printf("%s: PlayAudioFile() Entry\n", PACKAGE);
- subformat = sfinfo.format & SF_FORMAT_SUBMASK;
-
- if( subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE ) {
- static float flt_buffer[BUFFER_LEN];
- double scale;
-
- status = sf_command( sndfile, SFC_CALC_SIGNAL_MAX, &scale, (int) sizeof(scale) );
- if( status == 0 ) {
- fprintf( stderr, "%s: Warning, sf_command() failed.\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto play_audio_file_close_audio;
- }
-
- if (scale < 1e-10) {
- scale = 1.0;
- }
- else {
- scale = 32700.0 / scale;
- }
-
- while( ( readcount = (int) sf_read_float( sndfile, flt_buffer, BUFFER_LEN ) ) != 0 ) {
- /* Linux/OSS -- FLOAT samples */
-#if defined (__linux__)
- for( m = 0 ; m < readcount ; m++ ) {
- /* Float to integer conversion. */
- buffer[m] = (short) ( scale * flt_buffer[m] );
- /* Changing volume */
- buffer[m] = buffer[m] * volume / 100;
- }
- status = (int) write( audio_fd, buffer, readcount * sizeof(short) );
- if( status == -1 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto play_audio_file_close_audio;
- }
-
- /* Solaris -- FLOAT samples */
-#elif( defined(sun) && defined(unix) )
- start_count = 0;
- output_count = read_count * sizeof(short);
-
- while( output_count > 0 ) {
- /* Write as much data as possible */
- for( m = 0 ; m < readcount ; m++ ) {
- /* Float to integer conversion. */
- buffer[m] = (short) ( scale * flt_buffer[m] );
- /* Changing volume */
- buffer[m] = buffer[m] * volume / 100;
+ if (filename == NULL) {
+ fprintf(stderr, "%s: No audio file specified.\n", PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
}
-
- write_count = write( audio_fd, &(buffer[start_count]), output_count );
- if( write_count > 0 ) {
- output_count -= write_count;
- start_count += write_count;
+
+ sndfile = sf_open(filename, SFM_READ, &sfinfo);
+
+ if (sndfile == NULL) {
+ fprintf(stderr,
+ "%s: sf_open() failed trying to open '%s':\n",
+ PACKAGE, filename);
+ fprintf(stderr, " %s\n", sf_strerror(NULL));
+ fprintf(stderr,
+ " Check if file exists and has correct read permissions.\n");
+ ErrorLocation(__FILE__, __LINE__);
+ return;
}
- else {
- /* Give the audio output time to catch up. */
- usleep( delay_time );
+
+ if (sfinfo.channels < 1 || sfinfo.channels > 2) {
+ fprintf(stderr, "%s: Audio file has %d channel(s), but ",
+ PACKAGE, sfinfo.channels);
+ fprintf(stderr, "we support only 1 or 2 channels.\n");
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
}
- } /* while( output_count > 0 ) */
+
+ audio_fd = OpenDspDevice(sfinfo.channels, sfinfo.samplerate);
+ if (audio_fd < 0)
+ goto play_audio_file_close_file;
+
+#if (defined(sun) && defined(unix))
+ /* Delay time equal to 1/4 of a buffer in microseconds. */
+ delay_time = (BUFFER_LEN * 1000000) / (sfinfo.samplerate * 4);
#endif
- } /* while( ( readcount... ) */
- }
- else {
- while( ( readcount = (int) sf_read_short( sndfile, buffer, BUFFER_LEN ) ) != 0 ) {
- /* Linux/OSS -- INTEGER samples */
-#if defined (__linux__)
- /* Changing volume... */
- for( m = 0 ; m < readcount ; m++ ) {
- buffer[m] = ( buffer[m] * volume ) / 100;
- }
-
- status = (int) write( audio_fd, buffer, readcount * sizeof(short) );
- if( status == -1 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto play_audio_file_close_audio;
- }
-
- /* Solaris -- INTEGER samples */
-#elif( defined(sun) && defined(unix) )
- start_count = 0;
- output_count = read_count * sizeof(short);
-
- while( output_count > 0 ) {
- /* Write as much data as possible */
-
- /* Changing volume. */
- for( m = 0 ; m < read_count ; m++ ) {
- buffer[m] = ( buffer[m] * volume ) / 100;
- }
-
- write_count = write( audio_fd, &(buffer[start_count]), output_count );
- if( write_count > 0 ) {
- output_count -= write_count;
- start_count += write_count;
+
+ subformat = sfinfo.format & SF_FORMAT_SUBMASK;
+
+ if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) {
+ static float flt_buffer[BUFFER_LEN];
+ double scale;
+
+ status =
+ sf_command(sndfile, SFC_CALC_SIGNAL_MAX, &scale,
+ (int) sizeof(scale));
+ if (status == 0) {
+ fprintf(stderr,
+ "%s: Warning, sf_command() failed.\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto play_audio_file_close_audio;
+ }
+
+ if (scale < 1e-10)
+ scale = 1.0;
+ else
+ scale = 32700.0 / scale;
+
+ while ((readcount =
+ (int) sf_read_float(sndfile, flt_buffer,
+ BUFFER_LEN)) != 0) {
+ /* Linux/OSS -- FLOAT samples */
+#if defined(__linux__)
+ for (m = 0; m < readcount; m++) {
+ /* Float to integer conversion. */
+ buffer[m] =
+ (short) (scale * flt_buffer[m]);
+ /* Changing volume */
+ buffer[m] = buffer[m] * volume / 100;
+ }
+ status =
+ (int) write(audio_fd, buffer,
+ readcount * sizeof(short));
+ if (status == -1) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto play_audio_file_close_audio;
+ }
+
+ /* Solaris -- FLOAT samples */
+#elif(defined(sun) && defined(unix))
+ start_count = 0;
+ output_count = read_count * sizeof(short);
+
+ while (output_count > 0) {
+ /* Write as much data as possible */
+ for (m = 0; m < readcount; m++) {
+ /* Float to integer conversion. */
+ buffer[m] =
+ (short) (scale *
+ flt_buffer[m]);
+ /* Changing volume */
+ buffer[m] =
+ buffer[m] * volume / 100;
+ }
+
+ write_count =
+ write(audio_fd, &(buffer[start_count]),
+ output_count);
+ if (write_count > 0) {
+ output_count -= write_count;
+ start_count += write_count;
+ } else {
+ /*
+ * Give the audio output time to catch
+ * up.
+ */
+ usleep(delay_time);
+ }
+ } /* while( output_count > 0 ) */
+#endif
+ } /* while( ( readcount... ) */
+ } else {
+ while ((readcount =
+ (int) sf_read_short(sndfile, buffer,
+ BUFFER_LEN)) != 0) {
+ /* Linux/OSS -- INTEGER samples */
+#if defined(__linux__)
+ /* Changing volume... */
+ for (m = 0; m < readcount; m++)
+ buffer[m] = (buffer[m] * volume) / 100;
+
+ status = (int) write(audio_fd, buffer,
+ readcount * sizeof(short));
+ if (status == -1) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto play_audio_file_close_audio;
+ }
+
+ /* Solaris -- INTEGER samples */
+#elif(defined(sun) && defined(unix))
+ start_count = 0;
+ output_count = read_count * sizeof(short);
+
+ while (output_count > 0) {
+ /* Write as much data as possible */
+
+ /* Changing volume. */
+ for (m = 0; m < read_count; m++) {
+ buffer[m] =
+ (buffer[m] * volume) / 100;
+ }
+
+ write_count =
+ write(audio_fd, &(buffer[start_count]),
+ output_count);
+ if (write_count > 0) {
+ output_count -= write_count;
+ start_count += write_count;
+ } else {
+ /*
+ * Give the audio output time to catch
+ * up.
+ */
+ usleep(delay_time);
+ }
+ } /* while( output_count > 0 ) */
+#endif
+ } /* while( ( readcount... ) */
+ } /* else */
+
+play_audio_file_close_audio:
+
+ status = close(audio_fd);
+ if (status != 0) {
+ fprintf(stderr, "%s: Error, close() failed.\n", PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
}
- else {
- /* Give the audio output time to catch up. */
- usleep( delay_time );
+
+play_audio_file_close_file:
+
+ status = sf_close(sndfile);
+ if (status != 0) {
+ fprintf(stderr, "%s: Error, sf_close() failed.\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
}
- } /* while( output_count > 0 ) */
-#endif
- } /* while( ( readcount... ) */
- } /* else */
-
- play_audio_file_close_audio:
-
- status = close( audio_fd );
- if( status != 0 ) {
- fprintf( stderr, "%s: Error, close() failed.\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- play_audio_file_close_file:
-
- status = sf_close( sndfile );
- if( status != 0 ) {
- fprintf( stderr, "%s: Error, sf_close() failed.\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- if( wmnotify_infos.debug ) {
- printf( "%s: PlayAudioFile() Exit\n", PACKAGE );
- }
-
- return;
+
+ if (wmnotify_infos.debug)
+ printf("%s: PlayAudioFile() Exit\n", PACKAGE);
+
+ return;
}
#endif /* HAVE_SNDFILE */
#ifndef SOUND_H
#define SOUND_H 1
-void
-PlayAudioFile(char *filename, int volume);
+void PlayAudioFile(char *filename, int volume);
-#endif /* SOUND_H */
+#endif /* SOUND_H */
-/*\r
- * ssl.c\r
- *\r
- * Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>\r
- * Based on ssl_client.c (Sean Walton and Macmillan Publishers).\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.\r
- */\r
-\r
-#if HAVE_CONFIG_H\r
-# include "config.h"\r
-#endif\r
-\r
-#if HAVE_SSL\r
-\r
-/* Define filename_M */\r
-#define SSL_M 1\r
-\r
-#include <stdio.h>\r
-#include <errno.h>\r
-#include <unistd.h>\r
-#include <malloc.h>\r
-#include <string.h>\r
-#include <sys/socket.h>\r
-#include <resolv.h>\r
-#include <netdb.h>\r
-#include <openssl/ssl.h>\r
-#include <openssl/err.h>\r
-\r
-#include "common.h"\r
-#include "wmnotify.h"\r
-#include "ssl.h"\r
-\r
-\r
-/* InitCTX - initialize the SSL engine. */\r
-SSL_CTX *\r
-InitCTX( void )\r
-{\r
- const SSL_METHOD *method;\r
- SSL_CTX *ctx;\r
- \r
- SSL_library_init(); /* Load cryptos, et.al. */\r
- SSL_load_error_strings(); /* Bring in and register error messages */\r
- method = SSLv23_client_method(); /* Indicate we support SSLv2, SSLv3 and TLSv1 methods. */\r
- ctx = SSL_CTX_new(method); /* Create new context */\r
- if( ctx == NULL ) {\r
- ERR_print_errors_fp(stderr);\r
- abort();\r
- }\r
- return ctx;\r
-}\r
-\r
-\r
-/* ShowCerts - print out the certificates. */\r
-void\r
-ShowCerts( SSL *ssl )\r
-{\r
- X509 *cert;\r
- char *line;\r
- \r
- cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */\r
- if ( cert != NULL ) {\r
- printf("Server certificates:\n");\r
- line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);\r
- printf("Subject: %s\n", line);\r
- free(line); /* free the malloc'ed string */\r
- line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);\r
- printf("Issuer: %s\n", line);\r
- free(line); /* free the malloc'ed string */\r
- X509_free(cert); /* free the malloc'ed certificate copy */\r
- }\r
- else {\r
- printf("No certificates.\n");\r
- }\r
-}\r
-\r
-\r
-int\r
-InitSSL( int sock_fd )\r
-{\r
- ssl_infos.ctx = InitCTX(); \r
- ssl_infos.ssl = SSL_new( ssl_infos.ctx ); /* create new SSL connection state */\r
- if( ssl_infos.ssl == NULL ) {\r
- printf( "%s: Error in SSL_new()\n", PACKAGE );\r
- return EXIT_FAILURE;\r
- }\r
-\r
- SSL_set_fd( ssl_infos.ssl, sock_fd ); /* attach the socket descriptor */\r
- if( SSL_connect( ssl_infos.ssl ) == FAIL ) { /* perform the connection */\r
- ERR_print_errors_fp(stderr);\r
- return EXIT_FAILURE;\r
- }\r
-\r
- if( wmnotify_infos.debug ) {\r
- printf("Connected with %s encryption\n", SSL_get_cipher( ssl_infos.ssl ));\r
- ShowCerts( ssl_infos.ssl ); /* get any certs */\r
- }\r
-\r
- return EXIT_SUCCESS;\r
-}\r
-\r
-\r
-#endif /* HAVE_SSL */\r
+/*
+ * ssl.c
+ *
+ * Copyright (C) 2003 Hugo Villeneuve <hugo@hugovil.com>
+ * Based on ssl_client.c (Sean Walton and Macmillan Publishers).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif /* */
+
+#if HAVE_SSL
+
+/* Define filename_M */
+#define SSL_M 1
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <resolv.h>
+#include <netdb.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#include "common.h"
+#include "wmnotify.h"
+#include "ssl.h"
+
+/* InitCTX - initialize the SSL engine. */
+SSL_CTX *InitCTX(void)
+{
+ const SSL_METHOD *method;
+ SSL_CTX *ctx;
+ SSL_library_init(); /* Load cryptos, et.al. */
+ SSL_load_error_strings(); /* Bring in and register error messages */
+ method = SSLv23_client_method(); /*
+ * Indicate we support SSLv2, SSLv3 and
+ * TLSv1 methods.
+ */
+ ctx = SSL_CTX_new(method); /* Create new context */
+ if (ctx == NULL) {
+ ERR_print_errors_fp(stderr);
+ abort();
+ }
+ return ctx;
+}
+
+
+/* ShowCerts - print out the certificates. */
+void ShowCerts(SSL *ssl)
+{
+ X509 *cert;
+ char *line;
+ cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
+ if (cert != NULL) {
+ printf("Server certificates:\n");
+ line =
+ X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
+ printf("Subject: %s\n", line);
+ free(line); /* free the malloc'ed string */
+ line =
+ X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
+ printf("Issuer: %s\n", line);
+ free(line); /* free the malloc'ed string */
+ X509_free(cert); /* free the malloc'ed certificate copy */
+ } else {
+ printf("No certificates.\n");
+ }
+}
+
+int InitSSL(int sock_fd)
+{
+ ssl_infos.ctx = InitCTX();
+ ssl_infos.ssl = SSL_new(ssl_infos.ctx); /*
+ * create new SSL connection
+ * state
+ */
+ if (ssl_infos.ssl == NULL) {
+ printf("%s: Error in SSL_new()\n", PACKAGE);
+ return EXIT_FAILURE;
+ }
+ SSL_set_fd(ssl_infos.ssl, sock_fd); /* attach the socket descriptor */
+ if (SSL_connect(ssl_infos.ssl) == FAIL) { /* perform the connection */
+ ERR_print_errors_fp(stderr);
+ return EXIT_FAILURE;
+ }
+ if (wmnotify_infos.debug) {
+ printf("Connected with %s encryption\n",
+ SSL_get_cipher(ssl_infos.ssl));
+ ShowCerts(ssl_infos.ssl); /* get any certs */
+ }
+ return EXIT_SUCCESS;
+}
+
+
+#endif /* HAVE_SSL */
#define FAIL -1
struct ssl_infos_t {
- SSL_CTX *ctx;
- SSL *ssl;
+ SSL_CTX *ctx;
+ SSL *ssl;
};
_SCOPE_ struct ssl_infos_t ssl_infos;
-SSL_CTX *
-InitCTX( void );
+SSL_CTX *InitCTX(void);
-void
-ShowCerts( SSL *ssl );
+void ShowCerts(SSL *ssl);
-int
-InitSSL( int sock_fd );
+int InitSSL(int sock_fd);
#endif /* HAVE_SSL */
#include "wmnotify.h"
-/* Set in DoubleClick() to stop the new mail animation when the mail client is
- opened. */
-static bool animation_stop = false;
+/*
+ * Set in DoubleClick() to stop the new mail animation when the mail client is
+ * opened.
+ */
+static bool animation_stop;
static int animation_image = MAILBOX_FULL;
-/* Set in response to signal sent by SingleClick() to force mail check. Also set to true at
- * startup to force initial check. */
+/*
+ * Set in response to signal sent by SingleClick() to force mail check. Also set
+ * to true at startup to force initial check.
+ */
static bool manual_check = true;
/* Used to signal TimerThread to quit. Inactive for now. */
-static bool quit = false;
+static bool quit;
-static int double_click_notif = false;
+static int double_click_notif;
/* TimerThread ID */
static pthread_t timer_thread;
-inline void
-ErrorLocation( const char *file, int line )
+inline void ErrorLocation(const char *file, int line)
{
- fprintf( stderr, " Error in file \"%s\" at line #%d\n", file, line );
+ fprintf(stderr, " Error in file \"%s\" at line #%d\n", file,
+ line);
}
-void *
-xmalloc( size_t size, const char *filename, int line_number )
+void *xmalloc(size_t size, const char *filename, int line_number)
{
- void *value;
+ void *value;
- value = malloc( size );
-
- if( value == NULL ) {
- perror( PACKAGE );
- ErrorLocation( filename, line_number );
- exit( EXIT_FAILURE );
- }
+ value = malloc(size);
- return value;
+ if (value == NULL) {
+ perror(PACKAGE);
+ ErrorLocation(filename, line_number);
+ exit(EXIT_FAILURE);
+ }
+
+ return value;
}
-static void
-DisplayOpenedEmptyMailbox( void )
+static void DisplayOpenedEmptyMailbox(void)
{
- /* Opened and empty mailbox image */
- copyXPMArea( MAILBOX_OPENED_EMPTY_SRC_X, MAILBOX_OPENED_EMPTY_SRC_Y,
- MAILBOX_SIZE_X, MAILBOX_SIZE_Y, MAILBOX_DEST_X, MAILBOX_DEST_Y );
- RedrawWindow();
+ /* Opened and empty mailbox image */
+ copyXPMArea(MAILBOX_OPENED_EMPTY_SRC_X, MAILBOX_OPENED_EMPTY_SRC_Y,
+ MAILBOX_SIZE_X, MAILBOX_SIZE_Y, MAILBOX_DEST_X,
+ MAILBOX_DEST_Y);
+ RedrawWindow();
}
-static void
-DisplayOpenedFullMailbox( void )
+static void DisplayOpenedFullMailbox(void)
{
- /* Full mailbox image */
- copyXPMArea( MAILBOX_OPENED_FULL_SRC_X, MAILBOX_OPENED_FULL_SRC_Y,
- MAILBOX_SIZE_X, MAILBOX_SIZE_Y,
- MAILBOX_DEST_X, MAILBOX_DEST_Y );
- RedrawWindow();
+ /* Full mailbox image */
+ copyXPMArea(MAILBOX_OPENED_FULL_SRC_X, MAILBOX_OPENED_FULL_SRC_Y,
+ MAILBOX_SIZE_X, MAILBOX_SIZE_Y,
+ MAILBOX_DEST_X, MAILBOX_DEST_Y);
+ RedrawWindow();
}
-static void
-DisplayClosedMailbox( void )
+static void DisplayClosedMailbox(void)
{
- /* Opened mailbox image */
- copyXPMArea( MAILBOX_CLOSED_SRC_X, MAILBOX_CLOSED_SRC_Y,
- MAILBOX_SIZE_X, MAILBOX_SIZE_Y,
- MAILBOX_DEST_X, MAILBOX_DEST_Y );
- RedrawWindow();
+ /* Opened mailbox image */
+ copyXPMArea(MAILBOX_CLOSED_SRC_X, MAILBOX_CLOSED_SRC_Y,
+ MAILBOX_SIZE_X, MAILBOX_SIZE_Y,
+ MAILBOX_DEST_X, MAILBOX_DEST_Y);
+ RedrawWindow();
}
-static void
-DisplayExecuteCommandNotification( void )
+static void DisplayExecuteCommandNotification(void)
{
- /* Visual notification that the double-click was catched. */
- copyXPMArea( EXEC_CMD_IMG_SRC_X, EXEC_CMD_IMG_SRC_Y,
- MAILBOX_SIZE_X, MAILBOX_SIZE_Y, MAILBOX_DEST_X, MAILBOX_DEST_Y );
- RedrawWindow();
+ /* Visual notification that the double-click was catched. */
+ copyXPMArea(EXEC_CMD_IMG_SRC_X, EXEC_CMD_IMG_SRC_Y,
+ MAILBOX_SIZE_X, MAILBOX_SIZE_Y, MAILBOX_DEST_X,
+ MAILBOX_DEST_Y);
+ RedrawWindow();
}
-static void
-ExecuteCommand( char *argv[] )
+static void ExecuteCommand(char *argv[])
{
- pid_t pid;
- char *msg;
-
- /* No command defined, this is not an error. */
- if( argv[0] == NULL ) {
- return;
- }
-
- pid = fork(); /* fork a child process. */
-
- if( pid < 0) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
- else if( pid == 0 ) { /* Child process */
- /* When execvp() is successful, it doesn't return; otherwise, it returns
- -1 and sets errno. */
- (void) execvp( argv[0], argv );
-
- msg = strerror( errno );
- fprintf( stderr, "%s: The external mail program couldn't be started.\n",
- PACKAGE);
- fprintf( stderr, "Check your path or your configuration file for errors.\n"
- );
- fprintf( stderr, "%s: \"%s\"\n", msg, argv[0] );
- exit( EXIT_FAILURE );
- }
+ pid_t pid;
+ char *msg;
+
+ /* No command defined, this is not an error. */
+ if (argv[0] == NULL)
+ return;
+
+ pid = fork(); /* fork a child process. */
+
+ if (pid < 0) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ } else if (pid == 0) { /* Child process */
+ /*
+ * When execvp() is successful, it doesn't return; otherwise, it
+ * returns -1 and sets errno.
+ */
+ (void) execvp(argv[0], argv);
+
+ msg = strerror(errno);
+ fprintf(stderr,
+ "%s: The external mail program couldn't be started.\n",
+ PACKAGE);
+ fprintf(stderr,
+ "Check your path or your configuration file for errors.\n");
+ fprintf(stderr, "%s: \"%s\"\n", msg, argv[0]);
+ exit(EXIT_FAILURE);
+ }
}
/* single-click --> Checking mail */
-static void
-SingleClick( void )
+static void SingleClick(void)
{
- int status;
-
- if( wmnotify_infos.debug ) {
- printf( "%s: SingleClick() Entry\n", PACKAGE );
- }
-
- /* Sending a signal to awake the TimerThread() thread. */
- status = pthread_kill( timer_thread, SIGUSR1 );
- if( status != EXIT_SUCCESS ) {
- fprintf( stderr, "%s: pthread_kill() error (%d)\n", PACKAGE, status );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- if( wmnotify_infos.debug ) {
- printf( "%s: SingleClick() Exit\n", PACKAGE );
- }
+ int status;
+
+ if (wmnotify_infos.debug)
+ printf("%s: SingleClick() Entry\n", PACKAGE);
+
+ /* Sending a signal to awake the TimerThread() thread. */
+ status = pthread_kill(timer_thread, SIGUSR1);
+ if (status != EXIT_SUCCESS) {
+ fprintf(stderr, "%s: pthread_kill() error (%d)\n", PACKAGE,
+ status);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ if (wmnotify_infos.debug)
+ printf("%s: SingleClick() Exit\n", PACKAGE);
}
/* Double-click --> Starting external mail client. */
-static void
-DoubleClick( void )
+static void DoubleClick(void)
{
- int status;
-
- if( wmnotify_infos.mail_client_argv[0] != NULL ) {
- /* Starting external mail client. */
- ExecuteCommand( wmnotify_infos.mail_client_argv );
-
- double_click_notif = true;
-
- /* Sending a signal to awake the TimerThread() thread. This was previously
- done with a mutex variable (animation_stop), but this caused a bug when the
- following sequence was encountered:
- -The user double-click to start the external mail client
- -A new E-mail is received shortly after that
- -The user exit the external mail client
- -The user manually check for new E-mail
- -The audio notification sound is played, but no animation image is
- displayed.
- This was because setting the mutex variable 'animation_stop' didn't
- awakened the TimerThread(), but single-clicking awakened it. Since the
- 'animation_stop' variable was still set to true, no animation occured. */
- status = pthread_kill( timer_thread, SIGUSR2 );
- if( status != EXIT_SUCCESS ) {
- fprintf( stderr, "%s: pthread_kill() error (%d)\n", PACKAGE, status );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- DisplayExecuteCommandNotification();
- sleep(1);
- DisplayClosedMailbox();
-
- double_click_notif = false;
- }
- else {
- fprintf( stderr, "%s: Warning: No email-client defined.\n", PACKAGE );
- }
+ int status;
+
+ if (wmnotify_infos.mail_client_argv[0] != NULL) {
+ /* Starting external mail client. */
+ ExecuteCommand(wmnotify_infos.mail_client_argv);
+
+ double_click_notif = true;
+
+ /*
+ * Sending a signal to awake the TimerThread() thread. This was
+ * previously done with a mutex variable (animation_stop), but
+ * this caused a bug when the following sequence was
+ * encountered:
+ * -The user double-click to start the external mail client
+ * -A new E-mail is received shortly after that
+ * -The user exit the external mail client
+ * -The user manually check for new E-mail
+ * -The audio notification sound is played, but no animation
+ * image is displayed.
+ * This was because setting the mutex variable 'animation_stop'
+ * didn't awakened the TimerThread(), but single-clicking
+ * awakened it. Since the 'animation_stop' variable was still
+ * set to true, no animation occured.
+ */
+ status = pthread_kill(timer_thread, SIGUSR2);
+ if (status != EXIT_SUCCESS) {
+ fprintf(stderr, "%s: pthread_kill() error (%d)\n",
+ PACKAGE, status);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ DisplayExecuteCommandNotification();
+ sleep(1);
+ DisplayClosedMailbox();
+
+ double_click_notif = false;
+ } else {
+ fprintf(stderr, "%s: Warning: No email-client defined.\n",
+ PACKAGE);
+ }
}
-static void
-CatchChildTerminationSignal( int signal )
+static void CatchChildTerminationSignal(int signal)
{
- switch( signal ) {
- case SIGCHLD:
- /* Wait for Mail Client child process termination. Child enters zombie
- state: process is dead and most resources are released, but process
- descriptor remains until parent reaps exit status via wait. */
-
- /* The WNOHANG option prevents the call to waitpid from suspending execution
- of the caller. */
- (void) waitpid( 0, NULL, WNOHANG );
- break;
- default:
- fprintf( stderr, "%s: Unregistered signal received, exiting.\n", PACKAGE );
- exit( EXIT_FAILURE );
- }
+ switch (signal) {
+ case SIGCHLD:
+ /*
+ * Wait for Mail Client child process termination. Child enters
+ * zombie state: process is dead and most resources are
+ * released, but process descriptor remains until parent reaps
+ * exit status via wait.
+ */
+
+ /*
+ * The WNOHANG option prevents the call to waitpid from
+ * suspending execution of the caller.
+ */
+ (void) waitpid(0, NULL, WNOHANG);
+ break;
+ default:
+ fprintf(stderr,
+ "%s: Unregistered signal received, exiting.\n",
+ PACKAGE);
+ exit(EXIT_FAILURE);
+ }
}
-static void
-CatchTimerSignal( int signal )
+static void CatchTimerSignal(int signal)
{
- switch( signal ) {
- case SIGUSR1:
- /* Catching the signal sent by the SingleClick() function. */
- manual_check = true;
- break;
- case SIGUSR2:
- /* Catching the signal sent by the DoubleClick() function. */
- animation_stop = true;
- break;
- default:
- fprintf( stderr, "%s: CatchTimerSignal(): unknown signal (%d)\n", PACKAGE,
- signal );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
+ switch (signal) {
+ case SIGUSR1:
+ /* Catching the signal sent by the SingleClick() function. */
+ manual_check = true;
+ break;
+ case SIGUSR2:
+ /* Catching the signal sent by the DoubleClick() function. */
+ animation_stop = true;
+ break;
+ default:
+ fprintf(stderr,
+ "%s: CatchTimerSignal(): unknown signal (%d)\n",
+ PACKAGE, signal);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
}
-static void
-NewMailAnimation( void )
+static void NewMailAnimation(void)
{
- if( animation_image == MAILBOX_FULL ) {
- DisplayOpenedFullMailbox();
- animation_image = MAILBOX_CLOSED;
- if( wmnotify_infos.debug ) {
- printf( "%s: NewMailAnimation() MAILBOX_FULL.\n", PACKAGE );
- }
- }
- else {
- DisplayClosedMailbox();
- animation_image = MAILBOX_FULL;
- if( wmnotify_infos.debug ) {
- printf( "%s: NewMailAnimation() MAILBOX_CLOSED.\n", PACKAGE );
- }
- }
+ if (animation_image == MAILBOX_FULL) {
+ DisplayOpenedFullMailbox();
+ animation_image = MAILBOX_CLOSED;
+ if (wmnotify_infos.debug) {
+ printf("%s: NewMailAnimation() MAILBOX_FULL.\n",
+ PACKAGE);
+ }
+ } else {
+ DisplayClosedMailbox();
+ animation_image = MAILBOX_FULL;
+ if (wmnotify_infos.debug) {
+ printf("%s: NewMailAnimation() MAILBOX_CLOSED.\n",
+ PACKAGE);
+ }
+ }
}
/* We display the opened mailbox image only when doing a manual check. */
-static int
-CheckForNewMail( bool manual_check )
+static int CheckForNewMail(bool manual_check)
{
- int new_messages;
-
- if( manual_check == true ) {
- DisplayOpenedEmptyMailbox();
- }
-
- if( wmnotify_infos.protocol == POP3_PROTOCOL ) {
- new_messages = POP3_CheckForNewMail();
- }
- else if( wmnotify_infos.protocol == IMAP4_PROTOCOL ) {
- new_messages = IMAP4_CheckForNewMail();
- }
- else {
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- if( ( manual_check == true ) && ( new_messages > 0 ) ) {
- animation_image = MAILBOX_FULL;
- }
-
- return new_messages;
-}
+ int new_messages;
+
+ if (manual_check == true)
+ DisplayOpenedEmptyMailbox();
+
+ if (wmnotify_infos.protocol == POP3_PROTOCOL) {
+ new_messages = POP3_CheckForNewMail();
+ } else if (wmnotify_infos.protocol == IMAP4_PROTOCOL) {
+ new_messages = IMAP4_CheckForNewMail();
+ } else {
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+ if ((manual_check == true) && (new_messages > 0))
+ animation_image = MAILBOX_FULL;
+
+ return new_messages;
+}
-static void *
-TimerThread( /*@unused@*/ void *arg )
+static void check_audio_notification(bool *animation_running)
{
- int new_messages = 0;
- int counter = -1;
- bool animation_running = false;
-
- /* For catching the signal SIGUSR1. This signal is sent by the main program thread when the
- * user is issuing a single-click to manually check for new mails. */
- (void) signal( SIGUSR1, CatchTimerSignal );
-
- /* For catching the signal SIGUSR2. This signal is sent by the main program thread when the
- * user is issuing a double-click to start ther external mail client. */
- (void) signal( SIGUSR2, CatchTimerSignal );
-
- while( quit == false ) {
- if( wmnotify_infos.debug ) {
- printf( "%s: Timer thread iteration.\n", PACKAGE );
- }
- if( ( manual_check == true ) || ( counter == 0 ) ) {
- new_messages = CheckForNewMail( manual_check );
- manual_check = false;
-
- if( wmnotify_infos.debug ) {
- printf( "%s: new messages = %d.\n", PACKAGE, new_messages );
- }
-
- if( new_messages > 0 ) {
- /* Checking if audio notification was already produced. */
- if( animation_running == false ) {
- /* Audible notification, if requested in configuration file. */
- if( wmnotify_infos.audible_notification != false ) {
- if( strlen( wmnotify_infos.audiofile ) != 0 ) {
+ /*
+ * Checking if audio notification was already
+ * produced.
+ */
+ if (*animation_running == false) {
+ /* Audible notification, if requested in configuration file. */
+ if (wmnotify_infos.audible_notification) {
+ if (strlen(wmnotify_infos.audiofile) != 0) {
#if defined(HAVE_SNDFILE)
- PlayAudioFile( wmnotify_infos.audiofile, wmnotify_infos.volume );
+ PlayAudioFile(wmnotify_infos.audiofile,
+ wmnotify_infos.volume);
#endif
- }
- else {
- AudibleBeep();
- }
- }
-
- animation_running = true;
- }
- /* Number of times to execute timer loop before checking again for new mails when the
- * animation is running (when the animation is running, we sleep for
- * NEW_MAIL_ANIMATION_DURATION instead of wmnotify_infos.mail_check_interval). We set
- * the check interval to 30 seconds because we want the new mail condition to be
- * removed as soon as possible when the new messages are checked. */
- counter = 30 * 1000000 / NEW_MAIL_ANIMATION_DURATION;
- }
- }
-
- if( ( animation_stop == true ) || ( new_messages <= 0 ) ) {
- if( wmnotify_infos.debug ) {
- if( animation_stop != false ) {
- printf( "%s: animation_stop is true\n", PACKAGE );
+ } else {
+ AudibleBeep();
+ }
+ }
+
+ *animation_running = true;
}
- }
- animation_running = false;
- animation_stop = false;
- if( double_click_notif == false ) {
- /* Before exiting, be sure to put NO MAIL image back in place... */
- DisplayClosedMailbox();
- }
- }
-
- /* If sleep() returns because the requested time has elapsed, the value returned will be
- * 0. If sleep() returns because of premature arousal due to delivery of a signal, the
- * return value will be the "unslept" amount (the requested time minus the time actually
- * slept) in seconds. */
-
- if( animation_running == false ) {
- (void) sleep( wmnotify_infos.mail_check_interval );
- counter = 0;
- }
- else {
- NewMailAnimation();
- (void) usleep( NEW_MAIL_ANIMATION_DURATION );
- counter--;
- }
-
- if( wmnotify_infos.debug ) {
- printf( "%s: counter = %d\n", PACKAGE, counter );
- }
- } /* end while */
-
- if( wmnotify_infos.debug ) {
- printf( "%s: Error, TimerThread() exited abnormally\n", PACKAGE );
- }
-
- /* This code is never reached for now, because quit is always false. */
- pthread_exit( NULL );
+}
+
+static void *TimerThread(void *arg)
+{
+ int new_messages = 0;
+ int counter = -1;
+ bool animation_running = false;
+
+ /*
+ * For catching the signal SIGUSR1. This signal is sent by the main
+ * program thread when the user is issuing a single-click to manually
+ * check for new mails.
+ */
+ (void) signal(SIGUSR1, CatchTimerSignal);
+
+ /*
+ * For catching the signal SIGUSR2. This signal is sent by the main
+ * program thread when the user is issuing a double-click to start their
+ * external mail client.
+ */
+ (void) signal(SIGUSR2, CatchTimerSignal);
+
+ while (quit == false) {
+ if (wmnotify_infos.debug)
+ printf("%s: Timer thread iteration.\n", PACKAGE);
+
+ if ((manual_check == true) || (counter == 0)) {
+ new_messages = CheckForNewMail(manual_check);
+ manual_check = false;
+
+ if (wmnotify_infos.debug) {
+ printf("%s: new messages = %d.\n", PACKAGE,
+ new_messages);
+ }
+
+ if (new_messages > 0) {
+ check_audio_notification(&animation_running);
+
+ /*
+ * Number of times to execute timer loop before
+ * checking again for new mails when the
+ * animation is running (when the animation is
+ * running, we sleep for
+ * NEW_MAIL_ANIMATION_DURATION instead of
+ * wmnotify_infos.mail_check_interval). We set
+ * the check interval to 30 seconds because we
+ * want the new mail condition to be removed as
+ * soon as possible when the new messages are
+ * checked.
+ */
+ counter = 30 * 1000000 /
+ NEW_MAIL_ANIMATION_DURATION;
+ }
+ }
+
+ if ((animation_stop == true) || (new_messages <= 0)) {
+ if (wmnotify_infos.debug) {
+ if (animation_stop != false) {
+ printf
+ ("%s: animation_stop is true\n",
+ PACKAGE);
+ }
+ }
+ animation_running = false;
+ animation_stop = false;
+ if (double_click_notif == false) {
+ /*
+ * Before exiting, be sure to put NO MAIL image
+ * back in place.
+ */
+ DisplayClosedMailbox();
+ }
+ }
+
+ /*
+ * If sleep() returns because the requested time has elapsed,
+ * the value returned will be 0. If sleep() returns because of
+ * premature arousal due to delivery of a signal, the return
+ * value will be the "unslept" amount (the requested time minus
+ * the time actually slept) in seconds.
+ */
+ if (animation_running == false) {
+ (void) sleep(wmnotify_infos.mail_check_interval);
+ counter = 0;
+ } else {
+ NewMailAnimation();
+ (void) usleep(NEW_MAIL_ANIMATION_DURATION);
+ counter--;
+ }
+
+ if (wmnotify_infos.debug)
+ printf("%s: counter = %d\n", PACKAGE, counter);
+ } /* end while */
+
+ if (wmnotify_infos.debug)
+ printf("%s: Error, TimerThread() exited abnormally\n", PACKAGE);
+
+ /* This code is never reached for now, because quit is always false. */
+ pthread_exit(NULL);
}
/*******************************************************************************
* Main function
******************************************************************************/
-int
-main( int argc, char *argv[] )
+int main(int argc, char *argv[])
{
- int status;
-
- /* Initialization */
- ParseCommandLineOptions( argc, argv );
-
- /* Reading configuration options from configuration file. */
- ConfigurationFileInit();
-
- /* For catching the termination signal SIGCHLD when the external mail client
- program is terminated, thus permitting removing zombi processes... */
- (void) signal( SIGCHLD, CatchChildTerminationSignal );
-
- /* Initialize callback function pointers. */
- ProcessXlibEventsInit( SingleClick, DoubleClick );
-
- /* Initializing and creating a DockApp window. */
- InitDockAppWindow( argc, argv, wmnotify_xpm, wmnotify_infos.display_arg,
- wmnotify_infos.geometry_arg );
-
- /* Starting thread for periodically checking for new mail. */
- status = pthread_create( &timer_thread, NULL, TimerThread, NULL );
- if( status != 0 ) {
- fprintf( stderr, "%s: Thread creation failed (%d)\n", PACKAGE, status );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- /* Main loop, processing X Events */
- ProcessXlibEvents();
-
- /* This code is never reached for now. */
- fprintf( stderr, "%s: Program exit\n", PACKAGE );
-
- exit( EXIT_SUCCESS );
+ int status;
+
+ /* Initialization */
+ ParseCommandLineOptions(argc, argv);
+
+ /* Reading configuration options from configuration file. */
+ ConfigurationFileInit();
+
+ /*
+ * For catching the termination signal SIGCHLD when the external mail
+ * client program is terminated, thus permitting removing zombi
+ * processes...
+ */
+ (void) signal(SIGCHLD, CatchChildTerminationSignal);
+
+ /* Initialize callback function pointers. */
+ ProcessXlibEventsInit(SingleClick, DoubleClick);
+
+ /* Initializing and creating a DockApp window. */
+ InitDockAppWindow(argc, argv, wmnotify_xpm,
+ wmnotify_infos.display_arg,
+ wmnotify_infos.geometry_arg);
+
+ /* Starting thread for periodically checking for new mail. */
+ status = pthread_create(&timer_thread, NULL, TimerThread, NULL);
+ if (status != 0) {
+ fprintf(stderr, "%s: Thread creation failed (%d)\n",
+ PACKAGE, status);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ /* Main loop, processing X Events */
+ ProcessXlibEvents();
+
+ /* This code is never reached for now. */
+ fprintf(stderr, "%s: Program exit\n", PACKAGE);
+
+ exit(EXIT_SUCCESS);
}
#define MAILBOX_CLOSED_SRC_X 64
#define MAILBOX_CLOSED_SRC_Y 4
-/* Source coordinates in global pixmap for the opened and empty mailbox image. */
+/*
+ * Source coordinates in global pixmap for the opened and empty mailbox
+ * image.
+ */
#define MAILBOX_OPENED_EMPTY_SRC_X 64
#define MAILBOX_OPENED_EMPTY_SRC_Y 64
-/* Source coordinates in global pixmap for the opened and full mailbox image. */
+/*
+ * Source coordinates in global pixmap for the opened and full mailbox
+ * image.
+ */
#define MAILBOX_OPENED_FULL_SRC_X 4
#define MAILBOX_OPENED_FULL_SRC_Y 64
-/* Source coordinates in global pixmap for the opened and full mailbox image. */
+/*
+ * Source coordinates in global pixmap for the opened and full mailbox
+ * image.
+ */
#define EXEC_CMD_IMG_SRC_X 124
#define EXEC_CMD_IMG_SRC_Y 4
#define MAX_STR_LEN 256
-struct wmnotify_t
-{
- bool debug;
- char *display_arg;
- char *geometry_arg;
- char *optional_config_file;
- char mail_client_command[512];
- char *mail_client_argv[ARGV_LIMIT];
- unsigned int mail_check_interval; /* In seconds. */
- bool audible_notification;
- char audiofile[512];
- int volume;
- int protocol;
- char imap_folder[MAX_STR_LEN];
- bool use_ssl;
- char server_name[MAX_STR_LEN];
- int port;
- char username[MAX_STR_LEN];
- char password[MAX_STR_LEN];
- int sock_fd;
+struct wmnotify_t {
+ bool debug;
+ char *display_arg;
+ char *geometry_arg;
+ char *optional_config_file;
+ char mail_client_command[512];
+ char *mail_client_argv[ARGV_LIMIT];
+ unsigned int mail_check_interval; /* In seconds. */
+ bool audible_notification;
+ char audiofile[512];
+ int volume;
+ int protocol;
+ char imap_folder[MAX_STR_LEN];
+ bool use_ssl;
+ char server_name[MAX_STR_LEN];
+ int port;
+ char username[MAX_STR_LEN];
+ char password[MAX_STR_LEN];
+ int sock_fd;
};
/* Exported variables */
/* Function pointers to handle single and double mouse click events. */
-static void (*SingleClickCallback)( void ) = NULL;
+static void (*SingleClickCallback) (void);
-static void (*DoubleClickCallback)( void ) = NULL;
+static void (*DoubleClickCallback) (void);
-void
-AudibleBeep( void )
+void AudibleBeep(void)
{
- /* The specified volume is relative to the base volume for the keyboard.
- To change the base volume of the keyboard, use XChangeKeyboardControl(). */
- (void) XBell( dockapp.display, 100 ); /* Volume = 100% */
+ /*
+ * The specified volume is relative to the base volume for the keyboard.
+ * To change the base volume of the keyboard, use
+ * XChangeKeyboardControl().
+ */
+ (void) XBell(dockapp.display, 100); /* Volume = 100% */
}
/* This function must be called at the beginning of your program to initialize
the function pointers to handle single and double click mouse events. */
void
-ProcessXlibEventsInit( void (*single_click_callback)( void ),
- void (*double_click_callback)( void ) )
+ProcessXlibEventsInit(void (*single_click_callback) (void),
+ void (*double_click_callback) (void))
{
- int status;
-
- /* This must be called before any other XLib functions. */
- status = XInitThreads();
- if( status == 0 ) {
- fprintf( stderr, "%s: XInitThreads() initialization failed\n", PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- exit( EXIT_FAILURE );
- }
-
- SingleClickCallback = single_click_callback;
- DoubleClickCallback = double_click_callback;
+ int status;
+
+ /* This must be called before any other XLib functions. */
+ status = XInitThreads();
+ if (status == 0) {
+ fprintf(stderr,
+ "%s: XInitThreads() initialization failed\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+ SingleClickCallback = single_click_callback;
+ DoubleClickCallback = double_click_callback;
}
+static void detect_double_click(bool *double_click)
+{
+ /*
+ * We act only when the button is
+ * released.
+ */
+ if (*double_click) {
+ /* Double-click */
+ if (DoubleClickCallback != NULL)
+ (*DoubleClickCallback)();
+
+ *double_click = false;
+ } else {
+ (void) usleep(
+ DOUBLE_CLICK_MAX_INTERVAL_MS
+ * 1000);
+ *double_click = true;
+ }
+}
/* Processing of X events */
-void
-ProcessXlibEvents( void )
+void ProcessXlibEvents(void)
{
- bool quit = false;
- bool button1_pressed = false;
- bool check_for_double_click = false;
- XEvent Event;
-
- while( quit == false ) {
- if( ( check_for_double_click != false ) &&
- ( XPending( dockapp.display ) == 0 ) ) {
- /* If no other button 1 events are received after the delay, then it is a
- single-click mouse event. */
- if( SingleClickCallback != NULL ) {
- (*SingleClickCallback)();
- }
-
- check_for_double_click = false;
- }
- /* XNextEvent is a blocking call: it will return only when an event is
- ready to be processed, thus freeing the CPU for other tasks when no
- events are available. */
- (void) XNextEvent( dockapp.display, &Event );
- switch( Event.type ) {
- case Expose:
- /* Window was uncovered... */
- RedrawWindow();
- break;
- case DestroyNotify:
- /* Window was killed... */
- /* Is this necessary ? */
- (void) XCloseDisplay( dockapp.display );
- quit = true;
- break;
- case ClientMessage:
- /* Doesn't seem to work... */
- printf( "Client message received...\n" );
- break;
- case ButtonPress:
- if( Event.xbutton.button == Button1 ) {
- /* Mouse LEFT button pressed. */
- button1_pressed = true;
- }
- break;
- case ButtonRelease:
- if( Event.xbutton.button == Button1 ) {
- /* Mouse LEFT button released. */
- if( button1_pressed != false ) {
- /* We act only when the button is released */
- if( check_for_double_click != false ) {
- /* Double-click */
- if( DoubleClickCallback != NULL ) {
- (*DoubleClickCallback)();
- }
- check_for_double_click = false;
- }
- else {
- (void) usleep( DOUBLE_CLICK_MAX_INTERVAL_MS * 1000 );
- check_for_double_click = true;
- }
- }
- }
- break;
- }
- } /* end while */
+ bool quit = false;
+ bool button1_pressed = false;
+ bool double_click = false;
+ XEvent Event;
+
+ while (quit == false) {
+ if ((double_click) &&
+ (XPending(dockapp.display) == 0)) {
+ /*
+ * If no other button 1 events are received after the
+ * delay, then it is a single-click mouse event.
+ */
+ if (SingleClickCallback != NULL)
+ (*SingleClickCallback)();
+
+ double_click = false;
+ }
+ /*
+ * XNextEvent is a blocking call: it will return only when an
+ * event is ready to be processed, thus freeing the CPU for
+ * other tasks when no events are available.
+ */
+ (void) XNextEvent(dockapp.display, &Event);
+ switch (Event.type) {
+ case Expose:
+ /* Window was uncovered... */
+ RedrawWindow();
+ break;
+ case DestroyNotify:
+ /* Window was killed... */
+ /* Is this necessary ? */
+ (void) XCloseDisplay(dockapp.display);
+ quit = true;
+ break;
+ case ClientMessage:
+ /* Doesn't seem to work... */
+ printf("Client message received...\n");
+ break;
+ case ButtonPress:
+ if (Event.xbutton.button == Button1) {
+ /* Mouse LEFT button pressed. */
+ button1_pressed = true;
+ }
+ break;
+ case ButtonRelease:
+ if (Event.xbutton.button == Button1) {
+ /* Mouse LEFT button released. */
+ if (button1_pressed)
+ detect_double_click(&double_click);
+ }
+ break;
+ }
+ } /* end while */
}
#ifndef XEVENTS_H
#define XEVENTS_H 1
-void
-AudibleBeep(void);
+void AudibleBeep(void);
void
-ProcessXlibEventsInit(void (*single_click_callback)(void),
- void (*double_click_callback)(void));
+ProcessXlibEventsInit(void (*single_click_callback) (void),
+ void (*double_click_callback) (void));
-void
-ProcessXlibEvents(void);
+void ProcessXlibEvents(void);
-#endif /* XEVENTS_H */
+#endif /* XEVENTS_H */