Indentation with GNU indent
[dockapps/wmnotify.git] / src / imap.c
index da11e47..61f83b8 100644 (file)
@@ -34,7 +34,7 @@
 #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"
@@ -42,7 +42,7 @@
 #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;
 
@@ -69,241 +72,289 @@ 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;
 }