static void _notmuch_search_cleanup (search_context_t *ctx) { notmuch_query_destroy (ctx->query); notmuch_database_destroy (ctx->notmuch); talloc_free (ctx->format); }
/* * call-seq: DB.close => nil * * Close the notmuch database. */ VALUE notmuch_rb_database_close (VALUE self) { notmuch_status_t ret; notmuch_database_t *db; Data_Get_Notmuch_Database (self, db); ret = notmuch_database_destroy (db); DATA_PTR (self) = NULL; notmuch_rb_status_raise (ret); 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_insert_command (notmuch_config_t *config, int argc, char *argv[]) { notmuch_status_t status, close_status; notmuch_database_t *notmuch; struct sigaction action; const char *db_path; const char **new_tags; size_t new_tags_length; tag_op_list_t *tag_ops; char *query_string = NULL; const char *folder = NULL; notmuch_bool_t create_folder = FALSE; notmuch_bool_t keep = FALSE; notmuch_bool_t no_hooks = FALSE; notmuch_bool_t synchronize_flags; const char *maildir; char *newpath; int opt_index; unsigned int i; notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_STRING, &folder, "folder", 0, 0 }, { NOTMUCH_OPT_BOOLEAN, &create_folder, "create-folder", 0, 0 }, { NOTMUCH_OPT_BOOLEAN, &keep, "keep", 0, 0 }, { NOTMUCH_OPT_BOOLEAN, &no_hooks, "no-hooks", 'n', 0 }, { NOTMUCH_OPT_INHERIT, (void *) ¬much_shared_options, NULL, 0, 0 }, { NOTMUCH_OPT_END, 0, 0, 0, 0 } }; opt_index = parse_arguments (argc, argv, options, 1); if (opt_index < 0) return EXIT_FAILURE; notmuch_process_shared_options (argv[0]); db_path = notmuch_config_get_database_path (config); new_tags = notmuch_config_get_new_tags (config, &new_tags_length); synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config); tag_ops = tag_op_list_create (config); if (tag_ops == NULL) { fprintf (stderr, "Out of memory.\n"); return EXIT_FAILURE; } for (i = 0; i < new_tags_length; i++) { const char *error_msg; error_msg = illegal_tag (new_tags[i], FALSE); if (error_msg) { fprintf (stderr, "Error: tag '%s' in new.tags: %s\n", new_tags[i], error_msg); return EXIT_FAILURE; } if (tag_op_list_append (tag_ops, new_tags[i], FALSE)) return EXIT_FAILURE; } if (parse_tag_command_line (config, argc - opt_index, argv + opt_index, &query_string, tag_ops)) return EXIT_FAILURE; if (*query_string != '\0') { fprintf (stderr, "Error: unexpected query string: %s\n", query_string); return EXIT_FAILURE; } if (folder == NULL) { maildir = db_path; } else { if (! is_valid_folder_name (folder)) { fprintf (stderr, "Error: invalid folder name: '%s'\n", folder); return EXIT_FAILURE; } maildir = talloc_asprintf (config, "%s/%s", db_path, folder); if (! maildir) { fprintf (stderr, "Out of memory\n"); return EXIT_FAILURE; } if (create_folder && ! maildir_create_folder (config, maildir)) return EXIT_FAILURE; } /* Set up our handler for SIGINT. We do not set SA_RESTART so that copying * from standard input may be interrupted. */ memset (&action, 0, sizeof (struct sigaction)); action.sa_handler = handle_sigint; sigemptyset (&action.sa_mask); action.sa_flags = 0; sigaction (SIGINT, &action, NULL); /* Write the message to the Maildir new directory. */ newpath = maildir_write_new (config, STDIN_FILENO, maildir); if (! newpath) { return EXIT_FAILURE; } status = notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much); if (status) return keep ? NOTMUCH_STATUS_SUCCESS : status_to_exit (status); notmuch_exit_if_unmatched_db_uuid (notmuch); /* Index the message. */ status = add_file (notmuch, newpath, tag_ops, synchronize_flags, keep); /* Commit changes. */ close_status = notmuch_database_destroy (notmuch); if (close_status) { /* Hold on to the first error, if any. */ if (! status) status = close_status; fprintf (stderr, "%s: failed to commit database changes: %s\n", keep ? "Warning" : "Error", notmuch_status_to_string (close_status)); } if (status) { if (keep) { status = NOTMUCH_STATUS_SUCCESS; } else { /* If maildir flag sync failed, this might fail. */ if (unlink (newpath)) { fprintf (stderr, "Warning: failed to remove '%s' from maildir " "after errors: %s. Please run 'notmuch new' to fix.\n", newpath, strerror (errno)); } } } if (! no_hooks && status == NOTMUCH_STATUS_SUCCESS) { /* Ignore hook failures. */ notmuch_run_hook (db_path, "post-insert"); } return status_to_exit (status); }
int main (int argc, char **argv) { void *ctx = talloc_new (NULL); char *config_path = NULL; notmuch_config_t *config; notmuch_database_t *notmuch; int num_messages = 500; int max_tags = 10; // leave room for UTF-8 encoding. int tag_len = NOTMUCH_TAG_MAX / 6; // NOTMUCH_MESSAGE_ID_MAX is not exported, so we make a // conservative guess. int message_id_len = (NOTMUCH_TAG_MAX - 20) / 6; int seed = 734569; notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_STRING, &config_path, "config-path", 'c', 0 }, { NOTMUCH_OPT_INT, &num_messages, "num-messages", 'n', 0 }, { NOTMUCH_OPT_INT, &max_tags, "max-tags", 'm', 0 }, { NOTMUCH_OPT_INT, &message_id_len, "message-id-len", 'M', 0 }, { NOTMUCH_OPT_INT, &tag_len, "tag-len", 't', 0 }, { NOTMUCH_OPT_INT, &seed, "seed", 's', 0 }, { 0, 0, 0, 0, 0 } }; int opt_index = parse_arguments (argc, argv, options, 1); if (opt_index < 0) exit (1); if (message_id_len < 1) { fprintf (stderr, "message id's must be least length 1\n"); exit (1); } if (config_path == NULL) { fprintf (stderr, "configuration path must be specified"); exit (1); } config = notmuch_config_open (ctx, config_path, FALSE); if (config == NULL) return 1; if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) return 1; srandom (seed); int count; for (count = 0; count < num_messages; count++) { int j; /* explicitly allow zero tags */ int num_tags = random () % (max_tags + 1); /* message ids should be non-empty */ int this_mid_len = (random () % message_id_len) + 1; const char **tag_list; char *mid; notmuch_status_t status; do { mid = random_utf8_string (ctx, this_mid_len); tag_list = talloc_realloc (ctx, NULL, const char *, num_tags + 1); for (j = 0; j < num_tags; j++) { int this_tag_len = random () % tag_len + 1; tag_list[j] = random_utf8_string (ctx, this_tag_len); } tag_list[j] = NULL; status = notmuch_database_add_stub_message (notmuch, mid, tag_list); } while (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID); if (status != NOTMUCH_STATUS_SUCCESS) { fprintf (stderr, "error %d adding message", status); exit (status); } } notmuch_database_destroy (notmuch); talloc_free (ctx); return 0; }
int notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[]) { tag_op_list_t *tag_ops = NULL; char *query_string = NULL; notmuch_database_t *notmuch; struct sigaction action; tag_op_flag_t tag_flags = TAG_FLAG_NONE; notmuch_bool_t batch = FALSE; notmuch_bool_t remove_all = FALSE; FILE *input = stdin; char *input_file_name = NULL; int opt_index; int ret = 0; /* 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); notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_BOOLEAN, &batch, "batch", 0, 0 }, { NOTMUCH_OPT_STRING, &input_file_name, "input", 'i', 0 }, { NOTMUCH_OPT_BOOLEAN, &remove_all, "remove-all", 0, 0 }, { 0, 0, 0, 0, 0 } }; opt_index = parse_arguments (argc, argv, options, 1); if (opt_index < 0) return 1; if (input_file_name) { batch = TRUE; input = fopen (input_file_name, "r"); if (input == NULL) { fprintf (stderr, "Error opening %s for reading: %s\n", input_file_name, strerror (errno)); return 1; } } if (batch) { if (opt_index != argc) { fprintf (stderr, "Can't specify both cmdline and stdin!\n"); return 1; } if (remove_all) { fprintf (stderr, "Can't specify both --remove-all and --batch\n"); return 1; } } else { tag_ops = tag_op_list_create (config); if (tag_ops == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; } if (parse_tag_command_line (config, argc - opt_index, argv + opt_index, &query_string, tag_ops)) return 1; if (tag_op_list_size (tag_ops) == 0 && ! remove_all) { fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n"); return 1; } } if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) return 1; if (notmuch_config_get_maildir_synchronize_flags (config)) tag_flags |= TAG_FLAG_MAILDIR_SYNC; if (remove_all) tag_flags |= TAG_FLAG_REMOVE_ALL; if (batch) ret = tag_file (config, notmuch, tag_flags, input); else ret = tag_query (config, notmuch, query_string, tag_ops, tag_flags); notmuch_database_destroy (notmuch); if (input != stdin) fclose (input); return ret || interrupted; }
int notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[]) { notmuch_database_t *notmuch; struct sigaction action; const char *db_path; const char **new_tags; size_t new_tags_length; tag_op_list_t *tag_ops; char *query_string = NULL; const char *folder = NULL; notmuch_bool_t create_folder = FALSE; const char *maildir; int opt_index; unsigned int i; notmuch_bool_t ret; notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_STRING, &folder, "folder", 0, 0 }, { NOTMUCH_OPT_BOOLEAN, &create_folder, "create-folder", 0, 0 }, { NOTMUCH_OPT_END, 0, 0, 0, 0 } }; opt_index = parse_arguments (argc, argv, options, 1); if (opt_index < 0) { /* diagnostics already printed */ return 1; } db_path = notmuch_config_get_database_path (config); new_tags = notmuch_config_get_new_tags (config, &new_tags_length); tag_ops = tag_op_list_create (config); if (tag_ops == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; } for (i = 0; i < new_tags_length; i++) { if (tag_op_list_append (tag_ops, new_tags[i], FALSE)) return 1; } if (parse_tag_command_line (config, argc - opt_index, argv + opt_index, &query_string, tag_ops)) return 1; if (*query_string != '\0') { fprintf (stderr, "Error: unexpected query string: %s\n", query_string); return 1; } if (folder == NULL) { maildir = db_path; } else { if (! check_folder_name (folder)) { fprintf (stderr, "Error: bad folder name: %s\n", folder); return 1; } maildir = talloc_asprintf (config, "%s/%s", db_path, folder); if (! maildir) { fprintf (stderr, "Out of memory\n"); return 1; } if (create_folder && ! maildir_create_folder (config, maildir)) { fprintf (stderr, "Error: creating maildir %s: %s\n", maildir, strerror (errno)); return 1; } } /* Setup our handler for SIGINT. We do not set SA_RESTART so that copying * from standard input may be interrupted. */ memset (&action, 0, sizeof (struct sigaction)); action.sa_handler = handle_sigint; sigemptyset (&action.sa_mask); action.sa_flags = 0; sigaction (SIGINT, &action, NULL); if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) return 1; ret = insert_message (config, notmuch, STDIN_FILENO, maildir, tag_ops); notmuch_database_destroy (notmuch); return (ret) ? 0 : 1; }
int notmuch_restore_command (unused (void *ctx), int argc, char *argv[]) { notmuch_config_t *config; notmuch_database_t *notmuch; notmuch_bool_t synchronize_flags; notmuch_bool_t accumulate = FALSE; char *input_file_name = NULL; FILE *input = stdin; char *line = NULL; size_t line_size; ssize_t line_len; regex_t regex; int rerr; int opt_index; config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) return 1; synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config); notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_POSITION, &input_file_name, 0, 0, 0 }, { NOTMUCH_OPT_BOOLEAN, &accumulate, "accumulate", 'a', 0 }, { 0, 0, 0, 0, 0 } }; opt_index = parse_arguments (argc, argv, options, 1); if (opt_index < 0) { /* diagnostics already printed */ return 1; } if (input_file_name) { input = fopen (input_file_name, "r"); if (input == NULL) { fprintf (stderr, "Error opening %s for reading: %s\n", input_file_name, strerror (errno)); return 1; } optind++; } if (opt_index < argc) { fprintf (stderr, "Cannot read dump from more than one file: %s\n", argv[optind]); return 1; } /* Dump output is one line per message. We match a sequence of * non-space characters for the message-id, then one or more * spaces, then a list of space-separated tags as a sequence of * characters within literal '(' and ')'. */ if ( xregcomp (®ex, "^([^ ]+) \\(([^)]*)\\)$", REG_EXTENDED) ) INTERNAL_ERROR("compile time constant regex failed."); while ((line_len = getline (&line, &line_size, input)) != -1) { regmatch_t match[3]; char *message_id, *file_tags; chomp_newline (line); rerr = xregexec (®ex, line, 3, match, 0); if (rerr == REG_NOMATCH) { fprintf (stderr, "Warning: Ignoring invalid input line: %s\n", line); continue; } message_id = xstrndup (line + match[1].rm_so, match[1].rm_eo - match[1].rm_so); file_tags = xstrndup (line + match[2].rm_so, match[2].rm_eo - match[2].rm_so); tag_message (notmuch, message_id, file_tags, !accumulate, synchronize_flags); free (message_id); free (file_tags); } regfree (®ex); if (line) free (line); notmuch_database_destroy (notmuch); if (input != stdin) fclose (input); return 0; }
int main (int argc, char** argv) { GFile *db_dir, *db_file; notmuch_status_t status; notmuch_database_t *db = NULL; notmuch_query_t *query = NULL; notmuch_messages_t *messages = NULL; notmuch_message_t *message = NULL; GMainLoop *loop = NULL; const char *query_string = "date:2014-02-01.."; if (argc != 2) { g_warning ("Usage: %s EVOLUTION_MAILDIR", argv[0]); return 1; } db_dir = g_file_new_for_path (argv[1]); db_file = g_file_get_child (db_dir, ".notmuch"); if (!g_file_query_exists (db_dir, NULL)) { g_object_unref (db_dir); g_object_unref (db_file); g_error ("directory %s does not exists"); return 2; } if (!g_file_query_exists (db_file, NULL)) status = notmuch_database_create (argv[1], &db); else status = notmuch_database_open (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db); if (status) { g_error ("Could not open database: %d", status); g_object_unref (db_dir); g_object_unref (db_file); notmuch_database_destroy (db); return 3; } scan_directory (db, db_dir); //loop = g_main_loop_new (NULL, FALSE); //g_main_loop_run (loop); query = notmuch_query_create (db, query_string); if (!query) { g_error ("Could not create query from string = \"%s\"", query_string); notmuch_database_destroy (db); g_object_unref (db_file); g_object_unref (db_dir); return 4; } g_message ("Query results -\n\n"); for (messages = notmuch_query_search_messages (query); notmuch_messages_valid (messages); notmuch_messages_move_to_next (messages)) { message = notmuch_messages_get (messages); g_message ("Message file: %s", notmuch_message_get_filename (message)); g_message ("Message ID: %s", notmuch_message_get_message_id (message)); g_message ("Message Sender: %s", notmuch_message_get_header (message, "from")); g_message ("Message Recipients: %s", notmuch_message_get_header (message, "to")); g_message ("Message Subject: %s", notmuch_message_get_header (message, "subject")); g_message ("Message date: %s\n", notmuch_message_get_header (message, "date")); notmuch_message_destroy (message); } notmuch_query_destroy (query); notmuch_database_destroy (db); g_object_unref (db_file); g_object_unref (db_dir); return 0; }