]> git.notmuchmail.org Git - notmuch/blobdiff - notmuch.c
Add -Wmising-declarations and fix warnings.
[notmuch] / notmuch.c
index 0a05e1afd864768b77a79c0535e48d48fcd70850..ef93ded9b3a848297e1d72c960801eb528a48500 100644 (file)
--- a/notmuch.c
+++ b/notmuch.c
 
 #include <glib.h> /* g_strdup_printf */
 
+#define unused(x) x __attribute__ ((unused))
+
+/* There's no point in continuing when we've detected that we've done
+ * something wrong internally (as opposed to the user passing in a
+ * bogus value).
+ *
+ * Note that __location__ comes from talloc.h.
+ */
+#define INTERNAL_ERROR(format, ...)                    \
+    do {                                               \
+       fprintf(stderr,                                 \
+               "Internal error: " format " (%s)\n",    \
+               ##__VA_ARGS__, __location__);           \
+       exit (1);                                       \
+    } while (0)
+
 #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
 
 typedef int (*command_function_t) (int argc, char *argv[]);
@@ -55,6 +71,7 @@ typedef struct command {
 
 typedef struct {
     int ignore_read_only_directories;
+    int saw_read_only_directory;
 
     int total_files;
     int processed_files;
@@ -70,14 +87,14 @@ chomp_newline (char *str)
 }
 
 /* Compute the number of seconds elapsed from start to end. */
-double
+static double
 tv_elapsed (struct timeval start, struct timeval end)
 {
     return ((end.tv_sec - start.tv_sec) +
            (end.tv_usec - start.tv_usec) / 1e6);
 }
 
-void
+static void
 print_formatted_seconds (double seconds)
 {
     int hours;
@@ -103,7 +120,7 @@ print_formatted_seconds (double seconds)
     printf ("%ds", (int) seconds);
 }
 
-void
+static void
 add_files_print_progress (add_files_state_t *state)
 {
     struct timeval tv_now;
@@ -148,7 +165,7 @@ add_files_print_progress (add_files_state_t *state)
  * The 'struct stat *st' must point to a structure that has already
  * been initialized for 'path' by calling stat().
  */
-notmuch_status_t
+static notmuch_status_t
 add_files_recursive (notmuch_database_t *notmuch,
                     const char *path,
                     struct stat *st,
@@ -169,6 +186,7 @@ add_files_recursive (notmuch_database_t *notmuch,
     if (state->ignore_read_only_directories &&
        (st->st_mode & S_IWUSR) == 0)
     {
+       state->saw_read_only_directory = TRUE;
        goto DONE;
     }
 
@@ -253,8 +271,7 @@ add_files_recursive (notmuch_database_t *notmuch,
                        ret = status;
                        goto DONE;
                    default:
-                       fprintf (stderr, "Internal error: add_message returned unexpected value: %d\n",  status);
-                       ret = status;
+                       INTERNAL_ERROR ("add_message returned unexpected value: %d",  status);
                        goto DONE;
                }
                if (state->processed_files % 1000 == 0)
@@ -270,7 +287,9 @@ add_files_recursive (notmuch_database_t *notmuch,
        next = NULL;
     }
 
-    notmuch_database_set_timestamp (notmuch, path, path_mtime);
+    status = notmuch_database_set_timestamp (notmuch, path, path_mtime);
+    if (status && ret == NOTMUCH_STATUS_SUCCESS)
+       ret = status;
 
   DONE:
     if (next)
@@ -313,7 +332,7 @@ add_files (notmuch_database_t *notmuch,
  * of path.  The result is added to *count (which should be
  * initialized to zero by the top-level caller before calling
  * count_files). */
-void
+static void
 count_files (const char *path, int *count)
 {
     DIR *dir;
@@ -381,8 +400,8 @@ count_files (const char *path, int *count)
     closedir (dir);
 }
 
-int
-setup_command (int argc, char *argv[])
+static int
+setup_command (unused (int argc), unused (char *argv[]))
 {
     notmuch_database_t *notmuch = NULL;
     char *default_path, *mail_directory = NULL;
@@ -461,6 +480,7 @@ setup_command (int argc, char *argv[])
     printf ("Next, we'll inspect the messages and create a database of threads:\n");
 
     add_files_state.ignore_read_only_directories = FALSE;
+    add_files_state.saw_read_only_directory = FALSE;
     add_files_state.total_files = count;
     add_files_state.processed_files = 0;
     add_files_state.added_messages = 0;
@@ -491,10 +511,6 @@ setup_command (int argc, char *argv[])
     printf ("When new mail is delivered to %s in the future,\n"
            "run \"notmuch new\" to add it to the database.\n\n",
            mail_directory);
-    printf ("And if you have any sub-directories that are archives (that is,\n"
-           "they will never receive new mail), marking these directores as\n"
-           "read-only (chmod u-w /path/to/dir) will make \"notmuch new\"\n"
-           "much more efficient (it won't even look in those directories).\n\n");
 
     if (ret) {
        printf ("Note: At least one error was encountered: %s\n",
@@ -510,8 +526,8 @@ setup_command (int argc, char *argv[])
     return ret;
 }
 
-int
-new_command (int argc, char *argv[])
+static int
+new_command (unused (int argc), unused (char *argv[]))
 {
     notmuch_database_t *notmuch;
     const char *mail_directory;
@@ -529,6 +545,7 @@ new_command (int argc, char *argv[])
     mail_directory = notmuch_database_get_path (notmuch);
 
     add_files_state.ignore_read_only_directories = TRUE;
+    add_files_state.saw_read_only_directory = FALSE;
     add_files_state.total_files = 0;
     add_files_state.processed_files = 0;
     add_files_state.added_messages = 0;
@@ -557,11 +574,18 @@ new_command (int argc, char *argv[])
                add_files_state.added_messages == 1 ?
                "message" : "messages");
     } else {
-       printf ("No new mail---and that's not much!\n");
+       printf ("No new mail---and that's not much.\n");
+    }
+
+    if (elapsed > 1 && ! add_files_state.saw_read_only_directory) {
+       printf ("\nTip: If you have any sub-directories that are archives (that is,\n"
+               "they will never receive new mail), marking these directores as\n"
+               "read-only (chmod u-w /path/to/dir) will make \"notmuch new\"\n"
+               "much more efficient (it won't even look in those directories).\n");
     }
 
     if (ret) {
-       printf ("Note: At least one error was encountered: %s\n",
+       printf ("\nNote: At least one error was encountered: %s\n",
                notmuch_status_to_string (ret));
     }
 
@@ -572,25 +596,90 @@ new_command (int argc, char *argv[])
     return ret;
 }
 
-int
+static int
 search_command (int argc, char *argv[])
 {
-    fprintf (stderr, "Error: search is not implemented yet.\n");
-    return 1;
+    void *local = talloc_new (NULL);
+    notmuch_database_t *notmuch = NULL;
+    notmuch_query_t *query;
+    notmuch_results_t *results;
+    notmuch_message_t *message;
+    notmuch_tags_t *tags;
+    char *query_str;
+    int i;
+    notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
+
+    notmuch = notmuch_database_open (NULL);
+    if (notmuch == NULL) {
+       ret = 1;
+       goto DONE;
+    }
+
+    /* XXX: Should add xtalloc wrappers here and use them. */
+    query_str = talloc_strdup (local, "");
+
+    for (i = 0; i < argc; i++) {
+       if (i != 0)
+           query_str = talloc_asprintf_append (query_str, " ");
+
+       query_str = talloc_asprintf_append (query_str, "%s", argv[i]);
+    }
+
+    query = notmuch_query_create (notmuch, query_str);
+    if (query == NULL) {
+       fprintf (stderr, "Out of memory\n");
+       ret = 1;
+       goto DONE;
+    }
+
+    for (results = notmuch_query_search (query);
+        notmuch_results_has_more (results);
+        notmuch_results_advance (results))
+    {
+       int first = 1;
+       message = notmuch_results_get (results);
+
+       printf ("%s (", notmuch_message_get_message_id (message));
+
+       for (tags = notmuch_message_get_tags (message);
+            notmuch_tags_has_more (tags);
+            notmuch_tags_advance (tags))
+       {
+           if (! first)
+               printf (" ");
+
+           printf ("%s", notmuch_tags_get (tags));
+
+           first = 0;
+       }
+
+       printf (")\n");
+
+       notmuch_message_destroy (message);
+    }
+
+    notmuch_query_destroy (query);
+
+  DONE:
+    if (notmuch)
+       notmuch_database_close (notmuch);
+    talloc_free (local);
+
+    return ret;
 }
 
-int
-show_command (int argc, char *argv[])
+static int
+show_command (unused (int argc), unused (char *argv[]))
 {
     fprintf (stderr, "Error: show is not implemented yet.\n");
     return 1;
 }
 
-int
+static int
 dump_command (int argc, char *argv[])
 {
     FILE *output;
-    notmuch_database_t *notmuch;
+    notmuch_database_t *notmuch = NULL;
     notmuch_query_t *query;
     notmuch_results_t *results;
     notmuch_message_t *message;
@@ -662,13 +751,14 @@ dump_command (int argc, char *argv[])
     return ret;
 }
 
-int
+static int
 restore_command (int argc, char *argv[])
 {
     FILE *input;
-    notmuch_database_t *notmuch;
+    notmuch_database_t *notmuch = NULL;
     char *line = NULL;
-    size_t line_size, line_len;
+    size_t line_size;
+    ssize_t line_len;
     regex_t regex;
     int rerr;
     int ret = 0;
@@ -744,7 +834,8 @@ restore_command (int argc, char *argv[])
                                 notmuch_status_to_string (status));
                    }
                } else {
-                   fprintf (stderr, "%s ", tag);
+                   fprintf (stderr, "%s%s",
+                            tag == tags ? "" : " ", tag);
                }
            }
 
@@ -801,11 +892,11 @@ command_t commands[] = {
       "\t\tRestore the tags from the given dump file (see 'dump')." }
 };
 
-void
+static void
 usage (void)
 {
     command_t *command;
-    int i;
+    unsigned int i;
 
     fprintf (stderr, "Usage: notmuch <command> [args...]\n");
     fprintf (stderr, "\n");
@@ -823,7 +914,7 @@ int
 main (int argc, char *argv[])
 {
     command_t *command;
-    int i;
+    unsigned int i;
 
     if (argc == 1)
        return setup_command (0, NULL);