/* * call-seq: DB.close => nil * * Close the notmuch database. */ VALUE notmuch_rb_database_close(VALUE self) { notmuch_database_t *db; Data_Get_Notmuch_Database(self, db); notmuch_database_close(db); DATA_PTR(self) = NULL; return Qnil; }
static int release_db(struct nm_ctxdata *data) { if (data && data->db) { dprint(1, (debugfile, "nm: db close\n")); #ifdef NOTMUCH_API_3 notmuch_database_destroy(data->db); #else notmuch_database_close(data->db); #endif data->db = NULL; data->longrun = 0; return 0; } return -1; }
static void free_ctxdata(struct nm_ctxdata *data) { if (!data) return; dprint(1, (debugfile, "nm: freeing context data %p\n", data)); if (data->db) #ifdef NOTMUCH_API_3 notmuch_database_destroy(data->db); #else notmuch_database_close(data->db); #endif data->db = NULL; FREE(&data->db_filename); FREE(&data->db_query); url_free_tags(data->query_items); FREE(&data); }
int notmuch_count_command (void *ctx, int argc, char *argv[]) { notmuch_config_t *config; notmuch_database_t *notmuch; notmuch_query_t *query; char *query_str; int i; notmuch_bool_t output_messages = TRUE; argc--; argv++; /* skip subcommand argument */ for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (strcmp (argv[i], "--") == 0) { i++; break; } if (STRNCMP_LITERAL (argv[i], "--output=") == 0) { const char *opt = argv[i] + sizeof ("--output=") - 1; if (strcmp (opt, "threads") == 0) { output_messages = FALSE; } else if (strcmp (opt, "messages") == 0) { output_messages = TRUE; } else { fprintf (stderr, "Invalid value for --output: %s\n", opt); return 1; } } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); return 1; } } argc -= i; argv += i; config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; notmuch = notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY); if (notmuch == NULL) return 1; query_str = query_string_from_args (ctx, argc, argv); if (query_str == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; } if (*query_str == '\0') { query_str = talloc_strdup (ctx, ""); } query = notmuch_query_create (notmuch, query_str); if (query == NULL) { fprintf (stderr, "Out of memory\n"); return 1; } if (output_messages) printf ("%u\n", notmuch_query_count_messages (query)); else printf ("%u\n", notmuch_query_count_threads (query)); notmuch_query_destroy (query); notmuch_database_close (notmuch); return 0; }
int notmuch_search_command (void *ctx, int argc, char *argv[]) { notmuch_config_t *config; notmuch_database_t *notmuch; notmuch_query_t *query; char *query_str; char *opt; notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST; const search_format_t *format = &format_text; int i, ret; output_t output = OUTPUT_SUMMARY; for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (strcmp (argv[i], "--") == 0) { i++; break; } if (STRNCMP_LITERAL (argv[i], "--sort=") == 0) { opt = argv[i] + sizeof ("--sort=") - 1; if (strcmp (opt, "oldest-first") == 0) { sort = NOTMUCH_SORT_OLDEST_FIRST; } else if (strcmp (opt, "newest-first") == 0) { sort = NOTMUCH_SORT_NEWEST_FIRST; } else { fprintf (stderr, "Invalid value for --sort: %s\n", opt); return 1; } } else if (STRNCMP_LITERAL (argv[i], "--format=") == 0) { opt = argv[i] + sizeof ("--format=") - 1; if (strcmp (opt, "text") == 0) { format = &format_text; } else if (strcmp (opt, "json") == 0) { format = &format_json; } else { fprintf (stderr, "Invalid value for --format: %s\n", opt); return 1; } } else if (STRNCMP_LITERAL (argv[i], "--output=") == 0) { opt = argv[i] + sizeof ("--output=") - 1; if (strcmp (opt, "summary") == 0) { output = OUTPUT_SUMMARY; } else if (strcmp (opt, "threads") == 0) { output = OUTPUT_THREADS; } else if (strcmp (opt, "messages") == 0) { output = OUTPUT_MESSAGES; } else if (strcmp (opt, "files") == 0) { output = OUTPUT_FILES; } else if (strcmp (opt, "tags") == 0) { output = OUTPUT_TAGS; } else { fprintf (stderr, "Invalid value for --output: %s\n", opt); return 1; } } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); return 1; } } argc -= i; argv += i; config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; notmuch = notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY); if (notmuch == NULL) return 1; query_str = query_string_from_args (notmuch, argc, argv); if (query_str == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; } if (*query_str == '\0') { fprintf (stderr, "Error: notmuch search requires at least one search term.\n"); return 1; } query = notmuch_query_create (notmuch, query_str); if (query == NULL) { fprintf (stderr, "Out of memory\n"); return 1; } notmuch_query_set_sort (query, sort); switch (output) { default: case OUTPUT_SUMMARY: case OUTPUT_THREADS: ret = do_search_threads (format, query, sort, output); break; case OUTPUT_MESSAGES: case OUTPUT_FILES: ret = do_search_messages (format, query, output); break; case OUTPUT_TAGS: ret = do_search_tags (notmuch, format, query); break; } notmuch_query_destroy (query); notmuch_database_close (notmuch); return ret; }
int notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[])) { int *add_tags, *remove_tags; int add_tags_count = 0; int remove_tags_count = 0; char *query_string; notmuch_config_t *config; notmuch_database_t *notmuch; notmuch_query_t *query; notmuch_messages_t *messages; notmuch_message_t *message; struct sigaction action; int i; /* Setup our handler for SIGINT */ memset (&action, 0, sizeof (struct sigaction)); action.sa_handler = handle_sigint; sigemptyset (&action.sa_mask); action.sa_flags = SA_RESTART; sigaction (SIGINT, &action, NULL); add_tags = talloc_size (ctx, argc * sizeof (int)); if (add_tags == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; } remove_tags = talloc_size (ctx, argc * sizeof (int)); if (remove_tags == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; } for (i = 0; i < argc; i++) { if (strcmp (argv[i], "--") == 0) { i++; break; } if (argv[i][0] == '+') { add_tags[add_tags_count++] = i; } else if (argv[i][0] == '-') { remove_tags[remove_tags_count++] = i; } else { break; } } if (add_tags_count == 0 && remove_tags_count == 0) { fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n"); return 1; } query_string = query_string_from_args (ctx, argc - i, &argv[i]); if (*query_string == '\0') { fprintf (stderr, "Error: notmuch tag requires at least one search term.\n"); return 1; } config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; notmuch = notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_WRITE); if (notmuch == NULL) return 1; query = notmuch_query_create (notmuch, query_string); if (query == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; } /* tagging is not interested in any special sort order */ notmuch_query_set_sort (query, NOTMUCH_SORT_UNSORTED); for (messages = notmuch_query_search_messages (query); notmuch_messages_valid (messages) && !interrupted; notmuch_messages_move_to_next (messages)) { message = notmuch_messages_get (messages); notmuch_message_freeze (message); for (i = 0; i < remove_tags_count; i++) notmuch_message_remove_tag (message, argv[remove_tags[i]] + 1); for (i = 0; i < add_tags_count; i++) notmuch_message_add_tag (message, argv[add_tags[i]] + 1); notmuch_message_thaw (message); notmuch_message_destroy (message); } notmuch_query_destroy (query); notmuch_database_close (notmuch); return interrupted; }
int notmuch_new_command (void *ctx, int argc, char *argv[]) { notmuch_config_t *config; notmuch_database_t *notmuch; add_files_state_t add_files_state; double elapsed; struct timeval tv_now, tv_start; int ret = 0; struct stat st; const char *db_path; char *dot_notmuch_path; struct sigaction action; _filename_node_t *f; int renamed_files, removed_files; notmuch_status_t status; int i; notmuch_bool_t timer_is_active = FALSE; add_files_state.verbose = 0; add_files_state.output_is_a_tty = isatty (fileno (stdout)); for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) { add_files_state.verbose = 1; } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); return 1; } } config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length); add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config); add_files_state.message_ids_to_sync = _filename_list_create (ctx); db_path = notmuch_config_get_database_path (config); dot_notmuch_path = talloc_asprintf (ctx, "%s/%s", db_path, ".notmuch"); if (stat (dot_notmuch_path, &st)) { int count; count = 0; count_files (db_path, &count); if (interrupted) return 1; printf ("Found %d total files (that's not much mail).\n", count); notmuch = notmuch_database_create (db_path); add_files_state.total_files = count; } else { notmuch = notmuch_database_open (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE); if (notmuch == NULL) return 1; if (notmuch_database_needs_upgrade (notmuch)) { printf ("Welcome to a new version of notmuch! Your database will now be upgraded.\n"); gettimeofday (&add_files_state.tv_start, NULL); notmuch_database_upgrade (notmuch, upgrade_print_progress, &add_files_state); printf ("Your notmuch database has now been upgraded to database format version %u.\n", notmuch_database_get_version (notmuch)); } add_files_state.total_files = 0; } if (notmuch == NULL) return 1; /* Setup our handler for SIGINT. We do this after having * potentially done a database upgrade we this interrupt handler * won't support. */ memset (&action, 0, sizeof (struct sigaction)); action.sa_handler = handle_sigint; sigemptyset (&action.sa_mask); action.sa_flags = SA_RESTART; sigaction (SIGINT, &action, NULL); talloc_free (dot_notmuch_path); dot_notmuch_path = NULL; add_files_state.processed_files = 0; add_files_state.added_messages = 0; gettimeofday (&add_files_state.tv_start, NULL); add_files_state.removed_files = _filename_list_create (ctx); add_files_state.removed_directories = _filename_list_create (ctx); if (! debugger_is_active () && add_files_state.output_is_a_tty && ! add_files_state.verbose) { setup_progress_printing_timer (); timer_is_active = TRUE; } ret = add_files (notmuch, db_path, &add_files_state); removed_files = 0; renamed_files = 0; gettimeofday (&tv_start, NULL); for (f = add_files_state.removed_files->head; f; f = f->next) { status = notmuch_database_remove_message (notmuch, f->filename); if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) renamed_files++; else removed_files++; if (do_print_progress) { do_print_progress = 0; generic_print_progress ("Cleaned up", "messages", tv_start, removed_files + renamed_files, add_files_state.removed_files->count); } } gettimeofday (&tv_start, NULL); for (f = add_files_state.removed_directories->head, i = 0; f; f = f->next, i++) { _remove_directory (ctx, notmuch, f->filename, &renamed_files, &removed_files); if (do_print_progress) { do_print_progress = 0; generic_print_progress ("Cleaned up", "directories", tv_start, i, add_files_state.removed_directories->count); } } talloc_free (add_files_state.removed_files); talloc_free (add_files_state.removed_directories); /* Now that removals are done (hence the database is aware of all * renames), we can synchronize maildir_flags to tags for all * messages that had new filenames appear on this run. */ gettimeofday (&tv_start, NULL); if (add_files_state.synchronize_flags) { _filename_node_t *node; notmuch_message_t *message; for (node = add_files_state.message_ids_to_sync->head, i = 0; node; node = node->next, i++) { message = notmuch_database_find_message (notmuch, node->filename); notmuch_message_maildir_flags_to_tags (message); notmuch_message_destroy (message); if (do_print_progress) { do_print_progress = 0; generic_print_progress ( "Synchronized tags for", "messages", tv_start, i, add_files_state.message_ids_to_sync->count); } } } talloc_free (add_files_state.message_ids_to_sync); add_files_state.message_ids_to_sync = NULL; if (timer_is_active) stop_progress_printing_timer (); gettimeofday (&tv_now, NULL); elapsed = notmuch_time_elapsed (add_files_state.tv_start, tv_now); if (add_files_state.processed_files) { 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.).\033[K\n", (int) (add_files_state.processed_files / elapsed)); } else { printf (".\033[K\n"); } } if (add_files_state.added_messages) { printf ("Added %d new %s to the database.", add_files_state.added_messages, add_files_state.added_messages == 1 ? "message" : "messages"); } else { printf ("No new mail."); } if (removed_files) { printf (" Removed %d %s.", removed_files, removed_files == 1 ? "message" : "messages"); } if (renamed_files) { printf (" Detected %d file %s.", renamed_files, renamed_files == 1 ? "rename" : "renames"); } printf ("\n"); if (ret) { printf ("\nNote: At least one error was encountered: %s\n", notmuch_status_to_string (ret)); } notmuch_database_close (notmuch); return ret || interrupted; }
int notmuch_count_command (void *ctx, int argc, char *argv[]) { notmuch_config_t *config; notmuch_database_t *notmuch; notmuch_query_t *query; char *query_str; int i; #if 0 char *opt, *end; int i, first = 0, max_threads = -1; notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST; #endif for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (strcmp (argv[i], "--") == 0) { i++; break; } #if 0 if (STRNCMP_LITERAL (argv[i], "--first=") == 0) { opt = argv[i] + sizeof ("--first=") - 1; first = strtoul (opt, &end, 10); if (*opt == '\0' || *end != '\0') { fprintf (stderr, "Invalid value for --first: %s\n", opt); return 1; } } else if (STRNCMP_LITERAL (argv[i], "--max-threads=") == 0) { opt = argv[i] + sizeof ("--max-threads=") - 1; max_threads = strtoul (opt, &end, 10); if (*opt == '\0' || *end != '\0') { fprintf (stderr, "Invalid value for --max-threads: %s\n", opt); return 1; } } else if (STRNCMP_LITERAL (argv[i], "--sort=") == 0) { opt = argv[i] + sizeof ("--sort=") - 1; if (strcmp (opt, "oldest-first") == 0) { sort = NOTMUCH_SORT_OLDEST_FIRST; } else if (strcmp (opt, "newest-first") == 0) { sort = NOTMUCH_SORT_NEWEST_FIRST; } else { fprintf (stderr, "Invalid value for --sort: %s\n", opt); return 1; } } else #endif { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); return 1; } } argc -= i; argv += i; config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; notmuch = notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY); if (notmuch == NULL) return 1; query_str = query_string_from_args (ctx, argc, argv); if (query_str == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; } if (*query_str == '\0') { fprintf (stderr, "Error: notmuch count requires at least one count term.\n"); return 1; } query = notmuch_query_create (notmuch, query_str); if (query == NULL) { fprintf (stderr, "Out of memory\n"); return 1; } printf ("%u\n", notmuch_query_count_messages(query)); notmuch_query_destroy (query); notmuch_database_close (notmuch); return 0; }
int notmuch_reply_command (void *ctx, int argc, char *argv[]) { notmuch_config_t *config; notmuch_database_t *notmuch; notmuch_query_t *query; char *opt, *query_string; int i, ret = 0; int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params); notmuch_show_params_t params; reply_format_func = notmuch_reply_format_default; params.part = -1; params.cryptoctx = NULL; argc--; argv++; /* skip subcommand argument */ for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (strcmp (argv[i], "--") == 0) { i++; break; } if (STRNCMP_LITERAL (argv[i], "--format=") == 0) { opt = argv[i] + sizeof ("--format=") - 1; if (strcmp (opt, "default") == 0) { reply_format_func = notmuch_reply_format_default; } else if (strcmp (opt, "headers-only") == 0) { reply_format_func = notmuch_reply_format_headers_only; } else { fprintf (stderr, "Invalid value for --format: %s\n", opt); return 1; } } else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) { if (params.cryptoctx == NULL) { GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL); if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) fprintf (stderr, "Failed to construct gpg context.\n"); else g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE); g_object_unref (session); session = NULL; } } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); return 1; } } argc -= i; argv += i; config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; query_string = query_string_from_args (ctx, argc, argv); if (query_string == NULL) { fprintf (stderr, "Out of memory\n"); return 1; } if (*query_string == '\0') { fprintf (stderr, "Error: notmuch reply requires at least one search term.\n"); return 1; } notmuch = notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY); if (notmuch == NULL) return 1; query = notmuch_query_create (notmuch, query_string); if (query == NULL) { fprintf (stderr, "Out of memory\n"); return 1; } if (reply_format_func (ctx, config, query, ¶ms) != 0) return 1; notmuch_query_destroy (query); notmuch_database_close (notmuch); if (params.cryptoctx) g_object_unref(params.cryptoctx); return ret; }
int notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) { notmuch_config_t *config; notmuch_database_t *notmuch; notmuch_query_t *query; char *query_string; char *opt; const notmuch_show_format_t *format = &format_text; notmuch_show_params_t params; int mbox = 0; int format_specified = 0; int i; params.entire_thread = 0; params.raw = 0; params.part = -1; params.cryptoctx = NULL; params.decrypt = 0; argc--; argv++; /* skip subcommand argument */ for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (strcmp (argv[i], "--") == 0) { i++; break; } if (STRNCMP_LITERAL (argv[i], "--format=") == 0) { opt = argv[i] + sizeof ("--format=") - 1; if (strcmp (opt, "text") == 0) { format = &format_text; } else if (strcmp (opt, "json") == 0) { format = &format_json; params.entire_thread = 1; } else if (strcmp (opt, "mbox") == 0) { format = &format_mbox; mbox = 1; } else if (strcmp (opt, "raw") == 0) { format = &format_raw; params.raw = 1; } else { fprintf (stderr, "Invalid value for --format: %s\n", opt); return 1; } format_specified = 1; } else if (STRNCMP_LITERAL (argv[i], "--part=") == 0) { params.part = atoi(argv[i] + sizeof ("--part=") - 1); } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) { params.entire_thread = 1; } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) || (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) { if (params.cryptoctx == NULL) { GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL); if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) fprintf (stderr, "Failed to construct gpg context.\n"); else g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE); g_object_unref (session); session = NULL; } if (STRNCMP_LITERAL (argv[i], "--decrypt") == 0) params.decrypt = 1; } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); return 1; } } argc -= i; argv += i; config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; query_string = query_string_from_args (ctx, argc, argv); if (query_string == NULL) { fprintf (stderr, "Out of memory\n"); return 1; } if (mbox && params.part > 0) { fprintf (stderr, "Error: specifying parts is incompatible with mbox output format.\n"); return 1; } if (*query_string == '\0') { fprintf (stderr, "Error: notmuch show requires at least one search term.\n"); return 1; } notmuch = notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY); if (notmuch == NULL) return 1; query = notmuch_query_create (notmuch, query_string); if (query == NULL) { fprintf (stderr, "Out of memory\n"); return 1; } /* if part was requested and format was not specified, use format=raw */ if (params.part >= 0 && !format_specified) format = &format_raw; /* If --format=raw specified without specifying part, we can only * output single message, so set part=0 */ if (params.raw && params.part < 0) params.part = 0; if (params.part >= 0) return do_show_single (ctx, query, format, ¶ms); else return do_show (ctx, query, format, ¶ms); notmuch_query_destroy (query); notmuch_database_close (notmuch); if (params.cryptoctx) g_object_unref(params.cryptoctx); return 0; }