Exemplo n.º 1
0
static int
parse_sup_line (void *ctx, char *line,
		char **query_str, tag_op_list_t *tag_ops)
{

    regmatch_t match[3];
    char *file_tags;
    int rerr;

    tag_op_list_reset (tag_ops);

    chomp_newline (line);

    /* Silently ignore blank lines */
    if (line[0] == '\0') {
	return 1;
    }

    rerr = xregexec (&regex, line, 3, match, 0);
    if (rerr == REG_NOMATCH) {
	fprintf (stderr, "Warning: Ignoring invalid sup format line: %s\n",
		 line);
	return 1;
    }

    *query_str = talloc_strndup_debug (ctx, line + match[1].rm_so,
				       match[1].rm_eo - match[1].rm_so);

    file_tags = talloc_strndup_debug (ctx, line + match[2].rm_so,
				      match[2].rm_eo - match[2].rm_so);

    char *tok = file_tags;
    size_t tok_len = 0;

    tag_op_list_reset (tag_ops);

    while ((tok = strtok_len (tok + tok_len, " ", &tok_len)) != NULL) {

	if (*(tok + tok_len) != '\0') {
	    *(tok + tok_len) = '\0';
	    tok_len++;
	}

	if (tag_op_list_append (tag_ops, tok, FALSE))
	    return -1;
    }

    return 0;

}
Exemplo n.º 2
0
static int
count_file (notmuch_database_t *notmuch, FILE *input, const char **exclude_tags,
            size_t exclude_tags_length, int output, int print_lastmod)
{
    char *line = NULL;
    ssize_t line_len;
    size_t line_size;
    int ret = 0;

    while (! ret && (line_len = getline (&line, &line_size, input)) != -1) {
        chomp_newline (line);
        ret = print_count (notmuch, line, exclude_tags, exclude_tags_length,
                           output, print_lastmod);
    }

    if (line)
        free (line);

    return ret;
}
Exemplo n.º 3
0
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, &notmuch))
	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 (&regex,
		   "^([^ ]+) \\(([^)]*)\\)$",
		   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 (&regex, 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 (&regex);

    if (line)
	free (line);

    notmuch_database_destroy (notmuch);
    if (input != stdin)
	fclose (input);

    return 0;
}
Exemplo n.º 4
0
tag_parse_status_t
parse_tag_line (void *ctx, char *line,
		tag_op_flag_t flags,
		char **query_string,
		tag_op_list_t *tag_ops)
{
    char *tok = line;
    size_t tok_len = 0;
    char *line_for_error;
    tag_parse_status_t ret = TAG_PARSE_SUCCESS;

    chomp_newline (line);

    line_for_error = talloc_strdup (ctx, line);
    if (line_for_error == NULL) {
	fprintf (stderr, "Error: out of memory\n");
	return TAG_PARSE_OUT_OF_MEMORY;
    }

    /* remove leading space */
    while (*tok == ' ' || *tok == '\t')
	tok++;

    /* Skip empty and comment lines. */
    if (*tok == '\0' || *tok == '#') {
	ret = TAG_PARSE_SKIPPED;
	goto DONE;
    }

    tag_op_list_reset (tag_ops);

    /* Parse tags. */
    while ((tok = strtok_len (tok + tok_len, " ", &tok_len)) != NULL) {
	notmuch_bool_t remove;
	char *tag;

	/* Optional explicit end of tags marker. */
	if (tok_len == 2 && strncmp (tok, "--", tok_len) == 0) {
	    tok = strtok_len (tok + tok_len, " ", &tok_len);
	    if (tok == NULL) {
		ret = line_error (TAG_PARSE_INVALID, line_for_error,
				  "no query string after --");
		goto DONE;
	    }
	    break;
	}

	/* Implicit end of tags. */
	if (*tok != '-' && *tok != '+')
	    break;

	/* If tag is terminated by NUL, there's no query string. */
	if (*(tok + tok_len) == '\0') {
	    ret = line_error (TAG_PARSE_INVALID, line_for_error,
			      "no query string");
	    goto DONE;
	}

	/* Terminate, and start next token after terminator. */
	*(tok + tok_len++) = '\0';

	remove = (*tok == '-');
	tag = tok + 1;

	/* Maybe refuse illegal tags. */
	if (! (flags & TAG_FLAG_BE_GENEROUS)) {
	    const char *msg = illegal_tag (tag, remove);
	    if (msg) {
		ret = line_error (TAG_PARSE_INVALID, line_for_error, msg);
		goto DONE;
	    }
	}

	/* Decode tag. */
	if (hex_decode_inplace (tag) != HEX_SUCCESS) {
	    ret = line_error (TAG_PARSE_INVALID, line_for_error,
			      "hex decoding of tag %s failed", tag);
	    goto DONE;
	}

	if (tag_op_list_append (tag_ops, tag, remove)) {
	    ret = line_error (TAG_PARSE_OUT_OF_MEMORY, line_for_error,
			      "aborting");
	    goto DONE;
	}
    }

    if (tok == NULL) {
	/* use a different error message for testing */
	ret = line_error (TAG_PARSE_INVALID, line_for_error,
			  "missing query string");
	goto DONE;
    }

    /* tok now points to the query string */
    *query_string = tok;

  DONE:
    talloc_free (line_for_error);
    return ret;
}