#include <unistd.h>
#include <dirent.h>
#include <errno.h>
+#include <signal.h>
#include <talloc.h>
printf ("%ds", (int) seconds);
}
+static volatile sig_atomic_t do_add_files_print_progress = 0;
+
+static void
+handle_sigalrm (unused (int signal))
+{
+ do_add_files_print_progress = 1;
+}
+
static void
add_files_print_progress (add_files_state_t *state)
{
message = NULL;
}
- if (state->processed_files % 1000 == 0)
+ if (do_add_files_print_progress) {
+ do_add_files_print_progress = 0;
add_files_print_progress (state);
+ }
}
} else if (S_ISDIR (st->st_mode)) {
status = add_files_recursive (notmuch, next, st, state);
}
/* This is the top-level entry point for add_files. It does a couple
- * of error checks, and then calls into the recursive function,
- * (avoiding the repeating of these error checks at every
- * level---which would be useless becaues we already do a stat() at
- * the level above). */
+ * of error checks, sets up the progress-printing timer and then calls
+ * into the recursive function. */
static notmuch_status_t
add_files (notmuch_database_t *notmuch,
const char *path,
add_files_state_t *state)
{
struct stat st;
+ notmuch_status_t status;
+ struct sigaction action;
+ struct itimerval timerval;
if (stat (path, &st)) {
fprintf (stderr, "Error reading directory %s: %s\n",
return NOTMUCH_STATUS_FILE_ERROR;
}
- return add_files_recursive (notmuch, path, &st, state);
+ /* Setup our handler for SIGALRM */
+ memset (&action, 0, sizeof (struct sigaction));
+ action.sa_handler = handle_sigalrm;
+ sigemptyset (&action.sa_mask);
+ action.sa_flags = SA_RESTART;
+ sigaction (SIGALRM, &action, NULL);
+
+ /* Then start a timer to send SIGALRM once per second. */
+ timerval.it_interval.tv_sec = 1;
+ timerval.it_interval.tv_usec = 0;
+ timerval.it_value.tv_sec = 1;
+ timerval.it_value.tv_usec = 0;
+ setitimer (ITIMER_REAL, &timerval, NULL);
+
+ status = add_files_recursive (notmuch, path, &st, state);
+
+ /* Now stop the timer. */
+ timerval.it_interval.tv_sec = 0;
+ timerval.it_interval.tv_usec = 0;
+ timerval.it_value.tv_sec = 0;
+ timerval.it_value.tv_usec = 0;
+ setitimer (ITIMER_REAL, &timerval, NULL);
+
+ /* And disable the signal handler. */
+ action.sa_handler = SIG_IGN;
+ sigaction (SIGALRM, &action, NULL);
+
+ return status;
}
/* Recursively count all regular files in path and all sub-direcotries
free (default_path);
}
+ /* Coerce th directory into an absolute directory name. */
+ if (*mail_directory != '/') {
+ char *cwd, *absolute_mail_directory;
+
+ cwd = getcwd (NULL, 0);
+ if (cwd == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ if (asprintf (&absolute_mail_directory, "%s/%s",
+ cwd, mail_directory) < 0)
+ {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ free (cwd);
+ free (mail_directory);
+ mail_directory = absolute_mail_directory;
+
+ printf ("Abs: %s\n", mail_directory);
+ }
+
notmuch = notmuch_database_create (mail_directory);
if (notmuch == NULL) {
fprintf (stderr, "Failed to create new notmuch database at %s\n",
static int
show_command (unused (int argc), unused (char *argv[]))
{
- fprintf (stderr, "Error: show is not implemented yet.\n");
- return 1;
+ void *local = talloc_new (NULL);
+ char *query_string;
+ notmuch_database_t *notmuch = NULL;
+ notmuch_query_t *query = NULL;
+ notmuch_message_results_t *messages;
+ notmuch_message_t *message;
+ const char *filename;
+ FILE *file;
+ int ret = 0;
+ int c;
+
+ const char *headers[] = {
+ "Subject", "From", "To", "Cc", "Bcc", "Date"
+ };
+ const char *name, *value;
+ unsigned int i;
+
+ if (argc != 1) {
+ fprintf (stderr, "Error: \"notmuch show\" requires exactly one thread-ID argument.\n");
+ ret = 1;
+ goto DONE;
+ }
+
+ notmuch = notmuch_database_open (NULL);
+ if (notmuch == NULL) {
+ ret = 1;
+ goto DONE;
+ }
+
+ query_string = talloc_asprintf (local, "thread:%s", argv[0]);
+ if (query_string == NULL) {
+ fprintf (stderr, "Out of memory\n");
+ ret = 1;
+ goto DONE;
+ }
+
+ query = notmuch_query_create (notmuch, query_string);
+ if (query == NULL) {
+ fprintf (stderr, "Out of memory\n");
+ ret = 1;
+ goto DONE;
+ }
+
+ for (messages = notmuch_query_search_messages (query);
+ notmuch_message_results_has_more (messages);
+ notmuch_message_results_advance (messages))
+ {
+ message = notmuch_message_results_get (messages);
+
+ printf ("%%message{\n");
+
+ printf ("%%header{\n");
+
+ for (i = 0; i < ARRAY_SIZE (headers); i++) {
+ name = headers[i];
+ value = notmuch_message_get_header (message, name);
+ if (value)
+ printf ("%s: %s\n", name, value);
+ }
+
+ printf ("%%header}\n");
+
+ filename = notmuch_message_get_filename (message);
+
+ file = fopen (filename, "r");
+ if (file) {
+ size_t header_size = notmuch_message_get_header_size (message);
+ fseek (file, header_size + 1, SEEK_SET);
+ while (1) {
+ c = fgetc (file);
+ if (c == EOF)
+ break;
+ putchar (c);
+ }
+ }
+ fclose (file);
+
+ printf ("%%message}\n");
+
+ notmuch_message_destroy (message);
+ }
+
+ DONE:
+ if (local)
+ talloc_free (local);
+
+ if (query)
+ notmuch_query_destroy (query);
+
+ if (notmuch)
+ notmuch_database_close (notmuch);
+
+ return ret;
}
static int
"\t\tmarks around any parenthesized expression)." },
{ "show", show_command,
"<thread-id>\n\n"
- "\t\tNote: The \"notmuch show\" command is not implemented yet.\n\n"
"\t\tShow the thread with the given thread ID (see 'search').",
"\t\tThread ID values are given as the first column in the\n"
"\t\toutput of the \"notmuch search\" command. These are the\n"