X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=notmuch-setup.c;h=2c3404ff67b6c0d36c511b997185400713d8dd09;hb=6bd01e1b340f6a209dde64471bc9d7137511dada;hp=65e975991d81a38550d2250cb6f8da0335a0ab4b;hpb=50144f95cababfb73027ca95ad1fb303c235a893;p=notmuch diff --git a/notmuch-setup.c b/notmuch-setup.c index 65e97599..2c3404ff 100644 --- a/notmuch-setup.c +++ b/notmuch-setup.c @@ -20,6 +20,52 @@ #include "notmuch-client.h" +static notmuch_status_t +add_all_files (notmuch_database_t *notmuch, + const char *mail_directory, + int num_files) +{ + add_files_state_t add_files_state; + double elapsed; + struct timeval tv_now; + notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; + + add_files_state.ignore_read_only_directories = FALSE; + add_files_state.saw_read_only_directory = FALSE; + add_files_state.total_files = num_files; + add_files_state.processed_files = 0; + add_files_state.added_messages = 0; + add_files_state.callback = NULL; + gettimeofday (&add_files_state.tv_start, NULL); + + ret = add_files (notmuch, mail_directory, &add_files_state); + + gettimeofday (&tv_now, NULL); + elapsed = notmuch_time_elapsed (add_files_state.tv_start, + tv_now); + printf ("Processed %d %s in ", add_files_state.processed_files, + add_files_state.processed_files == 1 ? + "file" : "total files"); + notmuch_time_print_formatted_seconds (elapsed); + if (elapsed > 1) { + printf (" (%d files/sec.). \n", + (int) (add_files_state.processed_files / elapsed)); + } else { + printf (". \n"); + } + if (add_files_state.added_messages) { + printf ("Added %d %s to the database.\n\n", + add_files_state.added_messages, + add_files_state.added_messages == 1 ? + "message" : "unique messages"); + } + + return ret; +} + + +/* XXX: This should be merged with the existing add_files function in + * add-files.c. */ /* Recursively count all regular files in path and all sub-direcotries * of path. The result is added to *count (which should be * initialized to zero by the top-level caller before calling @@ -99,152 +145,145 @@ count_files (const char *path, int *count) closedir (dir); } -int -notmuch_setup_command (unused (void *ctx), - unused (int argc), unused (char *argv[])) +static const char * +make_path_absolute (void *ctx, const char *path) { - notmuch_database_t *notmuch = NULL; - char *default_path, *mail_directory = NULL; - size_t line_size; - int count; - add_files_state_t add_files_state; - double elapsed; - struct timeval tv_now; - notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; - - printf ("Welcome to notmuch!\n\n"); - - printf ("The goal of notmuch is to help you manage and search your collection of\n" - "email, and to efficiently keep up with the flow of email as it comes in.\n\n"); + char *cwd; - printf ("Notmuch needs to know the top-level directory of your email archive,\n" - "(where you already have mail stored and where messages will be delivered\n" - "in the future). This directory can contain any number of sub-directories\n" - "and primarily just files with indvidual email messages (eg. maildir or mh\n" - "archives are perfect). If there are other, non-email files (such as\n" - "indexes maintained by other email programs) then notmuch will do its\n" - "best to detect those and ignore them.\n\n"); + if (*path == '/') + return path; - printf ("Mail storage that uses mbox format, (where one mbox file contains many\n" - "messages), will not work with notmuch. If that's how your mail is currently\n" - "stored, we recommend you first convert it to maildir format with a utility\n" - "such as mb2md. In that case, press Control-C now and run notmuch again\n" - "once the conversion is complete.\n\n"); - - - default_path = notmuch_database_default_path (); - printf ("Top-level mail directory [%s]: ", default_path); - fflush (stdout); - - getline (&mail_directory, &line_size, stdin); - chomp_newline (mail_directory); - - printf ("\n"); - - if (mail_directory == NULL || strlen (mail_directory) == 0) { - if (mail_directory) - free (mail_directory); - mail_directory = default_path; - } else { - /* XXX: Instead of telling the user to use an environment - * variable here, we should really be writing out a configuration - * file and loading that on the next run. */ - if (strcmp (mail_directory, default_path)) { - printf ("Note: Since you are not using the default path, you will want to set\n" - "the NOTMUCH_BASE environment variable to %s so that\n" - "future calls to notmuch commands will know where to find your mail.\n", - mail_directory); - printf ("For example, if you are using bash for your shell, add:\n\n"); - printf ("\texport NOTMUCH_BASE=%s\n\n", mail_directory); - printf ("to your ~/.bashrc file.\n\n"); - } - free (default_path); - } - - /* Coerce the 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; + cwd = getcwd (NULL, 0); + if (cwd == NULL) { + fprintf (stderr, "Out of memory.\n"); + return NULL; } - notmuch = notmuch_database_create (mail_directory); - if (notmuch == NULL) { - fprintf (stderr, "Failed to create new notmuch database at %s\n", - mail_directory); - ret = NOTMUCH_STATUS_FILE_ERROR; - goto DONE; - } + path = talloc_asprintf (ctx, "%s/%s", cwd, path); + if (path == NULL) + fprintf (stderr, "Out of memory.\n"); - printf ("OK. Let's take a look at the mail we can find in the directory\n"); - printf ("%s ...\n", mail_directory); + free (cwd); - count = 0; - count_files (mail_directory, &count); - - printf ("Found %d total files. That's not much mail.\n\n", count); - - printf ("Next, we'll inspect the messages and create a database of threads:\n"); + return path; +} - 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; - add_files_state.callback = NULL; - gettimeofday (&add_files_state.tv_start, NULL); +static void +welcome_message_pre_setup (void) +{ + printf ( +"Welcome to notmuch!\n\n" + +"The goal of notmuch is to help you manage and search your collection of\n" +"email, and to efficiently keep up with the flow of email as it comes in.\n\n" + +"Notmuch needs to know a few things about you such as your name and email\n" +"address, as well as the directory that contains your email. This is where\n" +"you already have mail stored and where messages will be delivered in the\n" +"future. This directory can contain any number of sub-directories. Regular\n" +"files in these directories should be individual email messages. If there\n" +"are other, non-email files (such as indexes maintained by other email\n" +"programs) then notmuch will do its best to detect those and ignore them.\n\n" + +"If you already have your email being delivered to directories in either\n" +"maildir or mh format, then that's perfect. Mail storage that uses mbox\n" +"format, (where one mbox file contains many messages), will not work with\n" +"notmuch. If that's how your mail is currently stored, we recommend you\n" +"first convert it to maildir format with a utility such as mb2md. You can\n" +"continue configuring notmuch now, but be sure to complete the conversion\n" +"before you run \"notmuch new\" for the first time.\n\n"); +} - ret = add_files (notmuch, mail_directory, &add_files_state); +static void +welcome_message_post_setup (void) +{ + printf ("\n" +"Notmuch is now configured, and the configuration settings are saved in\n" +"a file in your home directory named .notmuch-config . If you'd like to\n" +"change the configuration in the future, you can either edit that file\n" +"directly or run \"notmuch setup\".\n\n" + +"The next step is to run \"notmuch new\" which will create a database\n" +"that indexes all of your mail. Depending on the amount of mail you have\n" +"the initial indexing process can take a long time, so expect that.\n" +"Also, the resulting database will require roughly the same amount of\n" +"storage space as your current collection of email. So please ensure you\n" +"have sufficient storage space available now.\n\n"); +} - gettimeofday (&tv_now, NULL); - elapsed = notmuch_time_elapsed (add_files_state.tv_start, - tv_now); - printf ("Processed %d %s in ", add_files_state.processed_files, - add_files_state.processed_files == 1 ? - "file" : "total files"); - notmuch_time_print_formatted_seconds (elapsed); - if (elapsed > 1) { - printf (" (%d files/sec.). \n", - (int) (add_files_state.processed_files / elapsed)); - } else { - printf (". \n"); - } - if (add_files_state.added_messages) { - printf ("Added %d %s to the database.\n\n", - add_files_state.added_messages, - add_files_state.added_messages == 1 ? - "message" : "unique messages"); +int +notmuch_setup_command (unused (void *ctx), + unused (int argc), unused (char *argv[])) +{ + char *response = NULL; + size_t response_size; + notmuch_config_t *config; + char **old_other_emails; + size_t old_other_emails_len; + GPtrArray *other_emails; + unsigned int i; + int is_new; + +#define prompt(format, ...) \ + do { \ + printf (format, ##__VA_ARGS__); \ + fflush (stdout); \ + getline (&response, &response_size, stdin); \ + chomp_newline (response); \ + } while (0) + + config = notmuch_config_open (ctx, NULL, &is_new); + + if (is_new) + welcome_message_pre_setup (); + + prompt ("Your full name [%s]: ", notmuch_config_get_user_name (config)); + if (strlen (response)) + notmuch_config_set_user_name (config, response); + + prompt ("Your primary email address [%s]: ", + notmuch_config_get_user_primary_email (config)); + if (strlen (response)) + notmuch_config_set_user_primary_email (config, response); + + other_emails = g_ptr_array_new (); + + old_other_emails = notmuch_config_get_user_other_email (config, + &old_other_emails_len); + for (i = 0; i < old_other_emails_len; i++) { + prompt ("Additional email address [%s]: ", old_other_emails[i]); + if (strlen (response)) + g_ptr_array_add (other_emails, talloc_strdup (ctx, response)); + else + g_ptr_array_add (other_emails, talloc_strdup (ctx, + old_other_emails[i])); } - 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); - - if (ret) { - printf ("Note: At least one error was encountered: %s\n", - notmuch_status_to_string (ret)); + do { + prompt ("Additional email address [Press 'Enter' if none]: "); + if (strlen (response)) + g_ptr_array_add (other_emails, talloc_strdup (ctx, response)); + } while (strlen (response)); + if (other_emails->len) + notmuch_config_set_user_other_email (config, + (const char **) + other_emails->pdata, + other_emails->len); + g_ptr_array_free (other_emails, TRUE); + + prompt ("Top-level directory of your email archive [%s]: ", + notmuch_config_get_database_path (config)); + if (strlen (response)) { + const char *absolute_path; + + absolute_path = make_path_absolute (ctx, response); + notmuch_config_set_database_path (config, absolute_path); } - DONE: - if (mail_directory) - free (mail_directory); - if (notmuch) - notmuch_database_close (notmuch); + notmuch_config_save (config); - return ret; + if (is_new) + welcome_message_post_setup (); + + return 0; }