#include "command-line-arguments.h"
typedef enum {
- OPT_FAILED, /* false */
- OPT_OK, /* good */
- OPT_GIVEBACK, /* pop one of the arguments you thought you were getting off the stack */
+ OPT_FAILED, /* false */
+ OPT_OK, /* good */
+ OPT_GIVEBACK, /* pop one of the arguments you thought you were getting off the stack */
} opt_handled;
/*
- Search the array of keywords for a given argument, assigning the
- output variable to the corresponding value. Return false if nothing
- matches.
-*/
+ * Search the array of keywords for a given argument, assigning the
+ * output variable to the corresponding value. Return false if nothing
+ * matches.
+ */
static opt_handled
_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next,
return OPT_FAILED;
}
- *arg_desc->opt_bool = negate ? !value : value;
+ *arg_desc->opt_bool = negate ? (! value) : value;
return OPT_OK;
}
static opt_handled
-_process_int_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
+_process_int_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str)
+{
char *endptr;
+
if (next == '\0' || arg_str[0] == '\0') {
fprintf (stderr, "Option \"%s\" needs an integer argument.\n", arg_desc->name);
return OPT_FAILED;
}
static opt_handled
-_process_string_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
+_process_string_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str)
+{
if (next == '\0') {
fprintf (stderr, "Option \"%s\" needs a string argument.\n", arg_desc->name);
}
/* Return number of non-NULL opt_* fields in opt_desc. */
-static int _opt_set_count (const notmuch_opt_desc_t *opt_desc)
+static int
+_opt_set_count (const notmuch_opt_desc_t *opt_desc)
{
return
- !!opt_desc->opt_inherit +
- !!opt_desc->opt_bool +
- !!opt_desc->opt_int +
- !!opt_desc->opt_keyword +
- !!opt_desc->opt_flags +
- !!opt_desc->opt_string +
- !!opt_desc->opt_position;
+ (bool) opt_desc->opt_inherit +
+ (bool) opt_desc->opt_bool +
+ (bool) opt_desc->opt_int +
+ (bool) opt_desc->opt_keyword +
+ (bool) opt_desc->opt_flags +
+ (bool) opt_desc->opt_string +
+ (bool) opt_desc->opt_position;
}
/* Return true if opt_desc is valid. */
-static bool _opt_valid (const notmuch_opt_desc_t *opt_desc)
+static bool
+_opt_valid (const notmuch_opt_desc_t *opt_desc)
{
int n = _opt_set_count (opt_desc);
}
/*
- Search for the {pos_arg_index}th position argument, return false if
- that does not exist.
-*/
+ * Search for the {pos_arg_index}th position argument, return false if
+ * that does not exist.
+ */
bool
parse_position_arg (const char *arg_str, int pos_arg_index,
- const notmuch_opt_desc_t *arg_desc) {
+ const notmuch_opt_desc_t *arg_desc)
+{
int pos_arg_counter = 0;
+
while (_opt_valid (arg_desc)) {
if (arg_desc->opt_position) {
if (pos_arg_counter == pos_arg_index) {
int
parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_index)
{
- assert(argv);
+ assert (argv);
const char *_arg = argv[opt_index];
- assert(_arg);
- assert(options);
+ assert (_arg);
+ assert (options);
const char *arg = _arg + 2; /* _arg starts with -- */
const char *negative_arg = NULL;
if (lookahead) {
next = ' ';
value = next_arg;
- opt_index ++;
+ opt_index++;
}
opt_handled opt_status = OPT_FAILED;
return -1;
if (lookahead && opt_status == OPT_GIVEBACK)
- opt_index --;
+ opt_index--;
if (try->present)
*try->present = true;
- return opt_index+1;
+ return opt_index + 1;
}
return -1;
}
/* See command-line-arguments.h for description */
int
parse_arguments (int argc, char **argv,
- const notmuch_opt_desc_t *options, int opt_index) {
+ const notmuch_opt_desc_t *options, int opt_index)
+{
int pos_arg_index = 0;
bool more_args = true;
while (more_args && opt_index < argc) {
- if (strncmp (argv[opt_index],"--",2) != 0) {
+ if (strncmp (argv[opt_index], "--", 2) != 0) {
more_args = parse_position_arg (argv[opt_index], pos_arg_index, options);
int prev_opt_index = opt_index;
if (strlen (argv[opt_index]) == 2)
- return opt_index+1;
+ return opt_index + 1;
opt_index = parse_option (argc, argv, options, opt_index);
if (opt_index < 0) {
/*
- This is the main entry point for command line argument parsing.
-
- Parse command line arguments according to structure options,
- starting at position opt_index.
-
- All output of parsed values is via pointers in options.
-
- Parsing stops at -- (consumed) or at the (k+1)st argument
- not starting with -- (a "positional argument") if options contains
- k positional argument descriptors.
-
- Returns the index of first non-parsed argument, or -1 in case of error.
-
-*/
+ * This is the main entry point for command line argument parsing.
+ *
+ * Parse command line arguments according to structure options,
+ * starting at position opt_index.
+ *
+ * All output of parsed values is via pointers in options.
+ *
+ * Parsing stops at -- (consumed) or at the (k+1)st argument
+ * not starting with -- (a "positional argument") if options contains
+ * k positional argument descriptors.
+ *
+ * Returns the index of first non-parsed argument, or -1 in case of error.
+ *
+ */
int
parse_arguments (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_index);
*/
int
-parse_option (int argc, char **argv, const notmuch_opt_desc_t* options, int opt_index);
+parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_index);
bool
parse_position_arg (const char *arg,
int position_arg_index,
- const notmuch_opt_desc_t* options);
+ const notmuch_opt_desc_t *options);
#endif
#include <stdlib.h>
char *
-canonicalize_file_name (const char * path)
+canonicalize_file_name (const char *path)
{
#ifdef PATH_MAX
- char *resolved_path = malloc (PATH_MAX+1);
+ char *resolved_path = malloc (PATH_MAX + 1);
if (resolved_path == NULL)
return NULL;
#include <time.h>
#include <stdio.h>
-int main()
+int
+main ()
{
struct tm tm;
#include <stdio.h>
#include <pwd.h>
-int main()
+int
+main ()
{
struct passwd passwd, *ignored;
extern "C" {
#endif
-#if !STD_GETPWUID
+#if ! STD_GETPWUID
#define _POSIX_PTHREAD_SEMANTICS 1
#endif
-#if !STD_ASCTIME
+#if ! STD_ASCTIME
#define _POSIX_PTHREAD_SEMANTICS 1
#endif
-#if !HAVE_CANONICALIZE_FILE_NAME
+#if ! HAVE_CANONICALIZE_FILE_NAME
/* we only call this function from C, and this makes testing easier */
#ifndef __cplusplus
char *
#endif
#endif
-#if !HAVE_GETLINE
+#if ! HAVE_GETLINE
#include <stdio.h>
#include <unistd.h>
ssize_t
getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp);
-#endif /* !HAVE_GETLINE */
+#endif /* !HAVE_GETLINE */
-#if !HAVE_STRCASESTR
-char* strcasestr(const char *haystack, const char *needle);
-#endif /* !HAVE_STRCASESTR */
+#if ! HAVE_STRCASESTR
+char *strcasestr (const char *haystack, const char *needle);
+#endif /* !HAVE_STRCASESTR */
-#if !HAVE_STRSEP
-char *strsep(char **stringp, const char *delim);
-#endif /* !HAVE_STRSEP */
+#if ! HAVE_STRSEP
+char *strsep (char **stringp, const char *delim);
+#endif /* !HAVE_STRSEP */
-#if !HAVE_TIMEGM
+#if ! HAVE_TIMEGM
#include <time.h>
time_t timegm (struct tm *tm);
-#endif /* !HAVE_TIMEGM */
+#endif /* !HAVE_TIMEGM */
/* Silence gcc warnings about unused results. These warnings exist
* for a reason; any use of this needs to be justified. */
#ifdef __GNUC__
-#define IGNORE_RESULT(x) ({ __typeof__(x) __z = (x); (void)(__z = __z); })
+#define IGNORE_RESULT(x) ({ __typeof__(x) __z = (x); (void) (__z = __z); })
#else /* !__GNUC__ */
#define IGNORE_RESULT(x) x
-#endif /* __GNUC__ */
+#endif /* __GNUC__ */
#ifdef __cplusplus
}
#endif
-#endif /* NOTMUCH_COMPAT_H */
+#endif /* NOTMUCH_COMPAT_H */
* provides support for testing for function attributes.
*/
#ifndef NORETURN_ATTRIBUTE
-#if (__GNUC__ >= 3 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || \
- __has_attribute (noreturn))
+#if (__GNUC__ >= 3 || \
+ (__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || \
+ __has_attribute (noreturn))
#define NORETURN_ATTRIBUTE __attribute__ ((noreturn))
#else
#define NORETURN_ATTRIBUTE
#include <zlib.h>
static const char *template =
- "prefix=/usr\n"
- "exec_prefix=${prefix}\n"
- "libdir=${exec_prefix}/lib\n"
- "\n"
- "Name: zlib\n"
- "Description: zlib compression library\n"
- "Version: %s\n"
- "Libs: -lz\n";
+ "prefix=/usr\n"
+ "exec_prefix=${prefix}\n"
+ "libdir=${exec_prefix}/lib\n"
+ "\n"
+ "Name: zlib\n"
+ "Description: zlib compression library\n"
+ "Version: %s\n"
+ "Libs: -lz\n";
-int main(void)
+int
+main (void)
{
- printf(template, ZLIB_VERSION);
- return 0;
+ printf (template, ZLIB_VERSION);
+ return 0;
}
/* getdelim.c --- Implementation of replacement getdelim function.
- Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007,
- 2008, 2009 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 3, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007,
+ * 2008, 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA. */
/* Ported from glibc by Simon Josefsson. */
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
-# define getc_maybe_unlocked(fp) getc(fp)
-#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED
+# define getc_maybe_unlocked(fp) getc (fp)
+#elif ! HAVE_FLOCKFILE || ! HAVE_FUNLOCKFILE || ! HAVE_DECL_GETC_UNLOCKED
# undef flockfile
# undef funlockfile
# define flockfile(x) ((void) 0)
# define funlockfile(x) ((void) 0)
-# define getc_maybe_unlocked(fp) getc(fp)
+# define getc_maybe_unlocked(fp) getc (fp)
#else
-# define getc_maybe_unlocked(fp) getc_unlocked(fp)
+# define getc_maybe_unlocked(fp) getc_unlocked (fp)
#endif
/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
- NUL-terminate it). *LINEPTR is a pointer returned from malloc (or
- NULL), pointing to *N characters of space. It is realloc'ed as
- necessary. Returns the number of characters read (not including
- the null terminator), or -1 on error or EOF. */
+ * NUL-terminate it). *LINEPTR is a pointer returned from malloc (or
+ * NULL), pointing to *N characters of space. It is realloc'ed as
+ * necessary. Returns the number of characters read (not including
+ * the null terminator), or -1 on error or EOF. */
ssize_t
getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
{
- ssize_t result = -1;
- size_t cur_len = 0;
+ ssize_t result = -1;
+ size_t cur_len = 0;
- if (lineptr == NULL || n == NULL || fp == NULL)
- {
- errno = EINVAL;
- return -1;
+ if (lineptr == NULL || n == NULL || fp == NULL) {
+ errno = EINVAL;
+ return -1;
}
- flockfile (fp);
-
- if (*lineptr == NULL || *n == 0)
- {
- char *new_lineptr;
- *n = 120;
- new_lineptr = (char *) realloc (*lineptr, *n);
- if (new_lineptr == NULL)
- {
- result = -1;
- goto unlock_return;
+ flockfile (fp);
+
+ if (*lineptr == NULL || *n == 0) {
+ char *new_lineptr;
+ *n = 120;
+ new_lineptr = (char *) realloc (*lineptr, *n);
+ if (new_lineptr == NULL) {
+ result = -1;
+ goto unlock_return;
}
- *lineptr = new_lineptr;
+ *lineptr = new_lineptr;
}
- for (;;)
- {
- int i;
+ for (;;) {
+ int i;
- i = getc_maybe_unlocked (fp);
- if (i == EOF)
- {
- result = -1;
- break;
+ i = getc_maybe_unlocked (fp);
+ if (i == EOF) {
+ result = -1;
+ break;
}
- /* Make enough space for len+1 (for final NUL) bytes. */
- if (cur_len + 1 >= *n)
- {
- size_t needed_max =
- SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
- size_t needed = 2 * *n + 1; /* Be generous. */
- char *new_lineptr;
-
- if (needed_max < needed)
- needed = needed_max;
- if (cur_len + 1 >= needed)
- {
- result = -1;
- errno = EOVERFLOW;
- goto unlock_return;
+ /* Make enough space for len+1 (for final NUL) bytes. */
+ if (cur_len + 1 >= *n) {
+ size_t needed_max =
+ SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
+ size_t needed = 2 * *n + 1; /* Be generous. */
+ char *new_lineptr;
+
+ if (needed_max < needed)
+ needed = needed_max;
+ if (cur_len + 1 >= needed) {
+ result = -1;
+ errno = EOVERFLOW;
+ goto unlock_return;
}
- new_lineptr = (char *) realloc (*lineptr, needed);
- if (new_lineptr == NULL)
- {
- result = -1;
- goto unlock_return;
+ new_lineptr = (char *) realloc (*lineptr, needed);
+ if (new_lineptr == NULL) {
+ result = -1;
+ goto unlock_return;
}
- *lineptr = new_lineptr;
- *n = needed;
+ *lineptr = new_lineptr;
+ *n = needed;
}
- (*lineptr)[cur_len] = i;
- cur_len++;
+ (*lineptr)[cur_len] = i;
+ cur_len++;
- if (i == delimiter)
- break;
+ if (i == delimiter)
+ break;
}
- (*lineptr)[cur_len] = '\0';
- result = cur_len ? (ssize_t) cur_len : result;
+ (*lineptr)[cur_len] = '\0';
+ result = cur_len ? (ssize_t) cur_len : result;
- unlock_return:
- funlockfile (fp); /* doesn't set errno */
+ unlock_return:
+ funlockfile (fp); /* doesn't set errno */
- return result;
+ return result;
}
/* getline.c --- Implementation of replacement getline function.
- Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 3, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ * Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA. */
/* Written by Simon Josefsson. */
ssize_t
getline (char **lineptr, size_t *n, FILE *stream)
{
- return getdelim (lineptr, n, '\n', stream);
+ return getdelim (lineptr, n, '\n', stream);
}
#define _GNU_SOURCE
#include <stdlib.h>
-int main()
+int
+main ()
{
char *found;
char *string;
#include <dirent.h>
-int main()
+int
+main ()
{
struct dirent ent;
#include <stdio.h>
#include <sys/types.h>
-int main()
+int
+main ()
{
ssize_t count = 0;
size_t n = 0;
char **lineptr = NULL;
FILE *stream = NULL;
- count = getline(lineptr, &n, stream);
+ count = getline (lineptr, &n, stream);
}
#define _GNU_SOURCE
#include <strings.h>
-int main()
+int
+main ()
{
char *found;
const char *haystack, *needle;
- found = strcasestr(haystack, needle);
+ found = strcasestr (haystack, needle);
}
#define _GNU_SOURCE
#include <string.h>
-int main()
+int
+main ()
{
char *found;
char **stringp;
const char *delim;
- found = strsep(stringp, delim);
+ found = strsep (stringp, delim);
}
#include <time.h>
-int main()
+int
+main ()
{
- return (int) timegm((struct tm *)0);
+ return (int) timegm ((struct tm *) 0);
}
* don't include it in their library
*
* based on a GPL implementation in OpenTTD found under GPL v2
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation, version 2.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA. */
/* Imported into notmuch by Dirk Hohndel - original author unknown. */
#include "compat.h"
-char *strcasestr(const char *haystack, const char *needle)
+char *
+strcasestr (const char *haystack, const char *needle)
{
- size_t hay_len = strlen(haystack);
- size_t needle_len = strlen(needle);
- while (hay_len >= needle_len) {
- if (strncasecmp(haystack, needle, needle_len) == 0)
- return (char *) haystack;
+ size_t hay_len = strlen (haystack);
+ size_t needle_len = strlen (needle);
+
+ while (hay_len >= needle_len) {
+ if (strncasecmp (haystack, needle, needle_len) == 0)
+ return (char *) haystack;
- haystack++;
- hay_len--;
- }
+ haystack++;
+ hay_len--;
+ }
- return NULL;
+ return NULL;
}
/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ * This file is part of the GNU C Library.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * The GNU C Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the GNU C Library; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA. */
#include <string.h>
/* Taken from glibc 2.6.1 */
-char *strsep (char **stringp, const char *delim)
+char *
+strsep (char **stringp, const char *delim)
{
- char *begin, *end;
+ char *begin, *end;
- begin = *stringp;
- if (begin == NULL)
- return NULL;
+ begin = *stringp;
+ if (begin == NULL)
+ return NULL;
- /* A frequent case is when the delimiter string contains only one
- character. Here we don't need to call the expensive `strpbrk'
- function and instead work using `strchr'. */
- if (delim[0] == '\0' || delim[1] == '\0')
- {
- char ch = delim[0];
+ /* A frequent case is when the delimiter string contains only one
+ * character. Here we don't need to call the expensive `strpbrk'
+ * function and instead work using `strchr'. */
+ if (delim[0] == '\0' || delim[1] == '\0') {
+ char ch = delim[0];
- if (ch == '\0')
- end = NULL;
- else
- {
- if (*begin == ch)
- end = begin;
- else if (*begin == '\0')
+ if (ch == '\0')
end = NULL;
- else
- end = strchr (begin + 1, ch);
+ else {
+ if (*begin == ch)
+ end = begin;
+ else if (*begin == '\0')
+ end = NULL;
+ else
+ end = strchr (begin + 1, ch);
}
- }
- else
- /* Find the end of the token. */
- end = strpbrk (begin, delim);
-
- if (end)
- {
- /* Terminate the token and set *STRINGP past NUL character. */
- *end++ = '\0';
- *stringp = end;
- }
- else
- /* No more delimiters; this is the last token. */
- *stringp = NULL;
-
- return begin;
+ } else
+ /* Find the end of the token. */
+ end = strpbrk (begin, delim);
+
+ if (end) {
+ /* Terminate the token and set *STRINGP past NUL character. */
+ *end++ = '\0';
+ *stringp = end;
+ } else
+ /* No more delimiters; this is the last token. */
+ *stringp = NULL;
+
+ return begin;
}
/* timegm.c --- Implementation of replacement timegm function.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 3, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA. */
/* Copyright 2013 Blake Jones. */
time_t
timegm (struct tm *tm)
{
- int monthlen[2][12] = {
+ int monthlen[2][12] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
};
- int year, month, days;
+ int year, month, days;
days = 365 * (tm->tm_year - 70);
for (year = 70; year < tm->tm_year; year++) {
- if (leapyear(1900 + year)) {
+ if (leapyear (1900 + year)) {
days++;
}
}
for (month = 0; month < tm->tm_mon; month++) {
- days += monthlen[leapyear(1900 + year)][month];
+ days += monthlen[leapyear (1900 + year)][month];
}
days += tm->tm_mday - 1;
srcdir=$(dirname "$0")
NOTMUCH_SRCDIR=$(cd "$srcdir" && pwd)
+case $NOTMUCH_SRCDIR in ( *\'* | *['\"`$']* )
+ echo "Definitely unsafe characters in source path '$NOTMUCH_SRCDIR'".
+ exit 1
+esac
+
+case $PWD in ( *\'* | *['\"`$']* )
+ echo "Definitely unsafe characters in current directory '$PWD'".
+ exit 1
+esac
+
+# In case of whitespace, builds may work, tests definitely will not.
+case $NOTMUCH_SRCDIR in ( *["$IFS"]* )
+ echo "Whitespace in source path '$NOTMUCH_SRCDIR' not supported".
+ exit 1
+esac
+
+case $PWD in ( *["$IFS"]* )
+ echo "Whitespace in current directory '$PWD' not supported".
+ exit 1
+esac
+
subdirs="util compat lib parse-time-string completion doc emacs"
subdirs="${subdirs} performance-test test test/test-databases"
subdirs="${subdirs} bindings"
g_mime_init ();
parser = g_mime_parser_new ();
- g_mime_parser_init_with_stream (parser, g_mime_stream_file_open("test/corpora/crypto/basic-encrypted.eml", "r", &error));
+ g_mime_parser_init_with_stream (parser, g_mime_stream_file_open("$srcdir/test/corpora/crypto/basic-encrypted.eml", "r", &error));
if (error) return !! fprintf (stderr, "failed to instantiate parser with test/corpora/crypto/basic-encrypted.eml\n");
body = GMIME_MULTIPART_ENCRYPTED(g_mime_message_get_mime_part (g_mime_parser_construct_message (parser, NULL)));
printf 'No.\nCould not make tempdir for testing session-key support.\n'
errors=$((errors + 1))
elif ${CC} ${CFLAGS} ${gmime_cflags} _check_session_keys.c ${gmime_ldflags} -o _check_session_keys \
- && GNUPGHOME=${TEMP_GPG} gpg --batch --quiet --import < test/gnupg-secret-key.asc \
+ && GNUPGHOME=${TEMP_GPG} gpg --batch --quiet --import < "$srcdir"/test/gnupg-secret-key.asc \
&& SESSION_KEY=$(GNUPGHOME=${TEMP_GPG} ./_check_session_keys) \
&& [ $SESSION_KEY = 9:0BACD64099D1468AB07C796F0C0AC4851948A658A15B34E803865E9FC635F2F5 ]
then
EMACSETCDIR="\$(prefix)/share/emacs/site-lisp"
fi
-printf "Checking if emacs (>= 24) is available... "
-if emacs --quick --batch --eval '(if (< emacs-major-version 24) (kill-emacs 1))' > /dev/null 2>&1; then
- printf "Yes.\n"
- have_emacs=1
-else
- printf "No (so will not byte-compile emacs code)\n"
- have_emacs=0
+if [ $WITH_EMACS = "1" ]; then
+ printf "Checking if emacs (>= 24) is available... "
+ if emacs --quick --batch --eval '(if (< emacs-major-version 24) (kill-emacs 1))' > /dev/null 2>&1; then
+ printf "Yes.\n"
+ else
+ printf "No (disabling emacs related parts of build)\n"
+ WITH_EMACS=0
+ fi
fi
have_doxygen=0
HAVE_PERL = ${have_perl}
PERL_ABSOLUTE = ${perl_absolute}
-# Whether there's an emacs binary available for byte-compiling
-HAVE_EMACS = ${have_emacs}
-
# Whether there's a sphinx-build binary available for building documentation
HAVE_SPHINX=${have_sphinx}
gnupg <!nocheck>,
bash-completion (>=1.9.0~),
texinfo
-Standards-Version: 4.1.3
+Standards-Version: 4.3.0
Homepage: https://notmuchmail.org/
Vcs-Git: https://git.notmuchmail.org/git/notmuch -b release
Vcs-Browser: https://git.notmuchmail.org/git/notmuch
Architecture: all
Section: python
Depends: ${misc:Depends}, ${python:Depends}, libnotmuch5 (>= ${source:Version})
+Provides: ${python:Provides}
+XB-Python-Version: ${python:Versions}
Description: Python interface to the notmuch mail search and index library
Notmuch is a system for indexing, searching, reading, and tagging
large collections of email messages in maildir or mh format. It uses
notmuch (>= 0.4),
libmail-box-perl, libmailtools-perl,
libstring-shellquote-perl, libterm-readline-gnu-perl,
- ${misc:Depends}
+ ${misc:Depends},
+ ${perl:Depends},
Recommends: mutt
Enhances: notmuch, mutt
Description: thread-based email index, search and tagging (Mutt interface)
python3_all = py3versions -s | xargs -n1 | xargs -t -I {} env {}
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
%:
dh $@ --with python2,python3,elpa
sprintf (buf, "/proc/%d/exe", getppid ());
if (readlink (buf, buf2, sizeof (buf2)) != -1 &&
- strncmp (basename (buf2), "gdb", 3) == 0)
- {
+ strncmp (basename (buf2), "gdb", 3) == 0) {
return true;
}
if/for/while test) and are preceded by a space. The opening brace of
functions is the exception, and starts on a new line.
-* Comments are always C-style /* */ block comments. They should start
- with a capital letter and generally be written in complete
- sentences. Public library functions are documented immediately
- before their prototype in lib/notmuch.h. Internal functions are
- typically documented immediately before their definition.
+* Opening parens also cuddle, even if the first argument does not fit
+ on the same line.
+
+* Ternary operators that span a line should be parenthesized like as
+ "a ? (\n b ) : c". This is mainly to keep the indentation tools
+ happy.
+
+* Comments are always C-style /* */ block comments, with a leading *
+ each line. They should start with a capital letter and generally be
+ written in complete sentences. Public library functions are
+ documented immediately before their prototype in lib/notmuch.h.
+ Internal functions are typically documented immediately before their
+ definition.
* Code lines should be less than 80 columns and comments should be
wrapped at 70 columns.
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
-# License: GPLv3+
-
-# This script reads a MIME message from stdin and produces a treelike
-# representation on it stdout.
-
-# Example:
-#
-# 0 dkg@alice:~$ printmimestructure < 'Maildir/cur/1269025522.M338697P12023.monkey,S=6459,W=6963:2,Sa'
-# └┬╴multipart/signed 6546 bytes
-# ├─╴text/plain inline 895 bytes
-# └─╴application/pgp-signature inline [signature.asc] 836 bytes
-# 0 dkg@alice:~$
-
-
-# If you want to number the parts, i suggest piping the output through
-# something like "cat -n"
-
-from __future__ import print_function
-
-import email
-import sys
-
-def print_part(z, prefix):
- fname = '' if z.get_filename() is None else ' [' + z.get_filename() + ']'
- cset = '' if z.get_charset() is None else ' (' + z.get_charset() + ')'
- disp = z.get_params(None, header='Content-Disposition')
- if (disp is None):
- disposition = ''
- else:
- disposition = ''
- for d in disp:
- if d[0] in [ 'attachment', 'inline' ]:
- disposition = ' ' + d[0]
- if z.is_multipart():
- nbytes = len(z.as_string())
- else:
- nbytes = len(z.get_payload())
-
- print('{}{}{}{}{} {:d} bytes'.format(
- prefix,
- z.get_content_type(),
- cset,
- disposition,
- fname,
- nbytes,
- ))
-
-def test(z, prefix=''):
- if (z.is_multipart()):
- print_part(z, prefix+'┬╴')
- if prefix.endswith('└'):
- prefix = prefix.rpartition('└')[0] + ' '
- if prefix.endswith('├'):
- prefix = prefix.rpartition('├')[0] + '│'
- parts = z.get_payload()
- i = 0
- while (i < parts.__len__()-1):
- test(parts[i], prefix + '├')
- i += 1
- test(parts[i], prefix + '└')
- # FIXME: show epilogue?
- else:
- print_part(z, prefix+'─╴')
-
-test(email.message_from_file(sys.stdin), '└')
cmt_star_cont = true
# indent_brace = 0
+
+indent_class = true
# You can set these variables from the command line.
SPHINXOPTS := -q
-SPHINXBUILD = HAVE_EMACS=${HAVE_EMACS} WITH_EMACS=${WITH_EMACS} sphinx-build
+SPHINXBUILD = WITH_EMACS=${WITH_EMACS} sphinx-build
DOCBUILDDIR := $(dir)/_build
# Internal variables.
MAN5_TEXI := $(patsubst $(srcdir)/doc/man5/%.rst,$(DOCBUILDDIR)/texinfo/%.texi,$(MAN5_RST))
MAN7_TEXI := $(patsubst $(srcdir)/doc/man7/%.rst,$(DOCBUILDDIR)/texinfo/%.texi,$(MAN7_RST))
INFO_TEXI_FILES := $(MAN1_TEXI) $(MAN5_TEXI) $(MAN7_TEXI)
-ifeq ($(HAVE_EMACS)$(WITH_EMACS),11)
- INFO_TEXI_FILES := $(INFO_TEXI_FILES) $(DOCBUILDDIR)/texinfo/notmuch-emacs.texi
+ifeq ($(WITH_EMACS),1)
+ INFO_TEXI_FILES += $(DOCBUILDDIR)/texinfo/notmuch-emacs.texi
endif
INFO_INFO_FILES := $(INFO_TEXI_FILES:.texi=.info)
# If we don't have emacs (or the user configured --without-emacs),
# don't build the notmuch-emacs docs, as they need emacs to generate
# the docstring include files
-if os.environ.get('HAVE_EMACS') != '1' or os.environ.get('WITH_EMACS') != '1':
+if os.environ.get('WITH_EMACS') != '1':
exclude_patterns.append('notmuch-emacs.rst')
# The name of the Pygments (syntax highlighting) style to use.
example, an AES-128 key might be stashed in a notmuch property as:
``session-key=7:14B16AF65536C28AF209828DFE34C9E0``.
+**index.repaired**
+
+ Some messages arrive in forms that are confusing to view; they can
+ be mangled by mail transport agents, or the sending mail user
+ agent may structure them in a way that is confusing. If notmuch
+ knows how to both detect and repair such a problematic message, it
+ will do so during indexing.
+
+ If it applies a message repair during indexing, it will use the
+ ``index.repaired`` property to note the type of repair(s) it
+ performed.
+
+ ``index.repaired=skip-protected-headers-legacy-display`` indicates
+ that when indexing the cleartext of an encrypted message, notmuch
+ skipped over a "legacy-display" text/rfc822-headers part that it
+ found in that message, since it was able to index the built-in
+ protected headers directly.
+
+ ``index.repaired=mixedup`` indicates the repair of a "Mixed Up"
+ encrypted PGP/MIME message, a mangling typically produced by
+ Microsoft's Exchange MTA. See
+ https://tools.ietf.org/html/draft-dkg-openpgp-pgpmime-message-mangling
+ for more information.
+
SEE ALSO
========
emacs_bytecode = $(emacs_sources:.el=.elc)
emacs_docstrings = $(emacs_sources:.el=.rsti)
-ifneq ($(HAVE_SPHINX)$(HAVE_EMACS),11)
+ifneq ($(HAVE_SPHINX)$(WITH_EMACS),11)
docstring.stamp:
@echo "Missing prerequisites, not collecting docstrings"
else
# the byte compiler may load an old .elc file when processing a
# "require" or we may fail to rebuild a .elc that depended on a macro
# from an updated file.
-ifeq ($(HAVE_EMACS),1)
+ifeq ($(WITH_EMACS),1)
$(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
-f batch-make-deps $(emacs_sources) > $@.tmp && \
endif
CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp $(dir)/.eldeps.x
-ifeq ($(HAVE_EMACS),1)
+ifeq ($(WITH_EMACS),1)
%.elc: %.el $(global_deps)
$(call quiet,EMACS) --directory emacs -batch -f batch-byte-compile $<
%.rsti: %.el
rm -r .elpa-build
ifeq ($(WITH_EMACS),1)
-ifeq ($(HAVE_EMACS),1)
all: $(emacs_bytecode) $(emacs_docstrings)
install-emacs: $(emacs_bytecode)
-endif
install: install-emacs
endif
install-emacs: $(emacs_sources) $(emacs_images)
mkdir -p "$(DESTDIR)$(emacslispdir)"
install -m0644 $(emacs_sources) "$(DESTDIR)$(emacslispdir)"
-ifeq ($(HAVE_EMACS),1)
+ifeq ($(WITH_EMACS),1)
install -m0644 $(emacs_bytecode) "$(DESTDIR)$(emacslispdir)"
endif
mkdir -p "$(DESTDIR)$(emacsetcdir)"
Terminal=false
Type=Application
Categories=Network;Email;
+Keywords=Mail;E-mail;Email;
GType
g_mime_filter_reply_get_type (void)
{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- .class_size = sizeof (GMimeFilterReplyClass),
- .base_init = NULL,
- .base_finalize = NULL,
- .class_init = (GClassInitFunc) g_mime_filter_reply_class_init,
- .class_finalize = NULL,
- .class_data = NULL,
- .instance_size = sizeof (GMimeFilterReply),
- .n_preallocs = 0,
- .instance_init = (GInstanceInitFunc) g_mime_filter_reply_init,
- .value_table = NULL,
- };
-
- type = g_type_register_static (GMIME_TYPE_FILTER, "GMimeFilterReply", &info, (GTypeFlags) 0);
- }
-
- return type;
+ static GType type = 0;
+
+ if (! type) {
+ static const GTypeInfo info = {
+ .class_size = sizeof (GMimeFilterReplyClass),
+ .base_init = NULL,
+ .base_finalize = NULL,
+ .class_init = (GClassInitFunc) g_mime_filter_reply_class_init,
+ .class_finalize = NULL,
+ .class_data = NULL,
+ .instance_size = sizeof (GMimeFilterReply),
+ .n_preallocs = 0,
+ .instance_init = (GInstanceInitFunc) g_mime_filter_reply_init,
+ .value_table = NULL,
+ };
+
+ type = g_type_register_static (GMIME_TYPE_FILTER, "GMimeFilterReply", &info, (GTypeFlags) 0);
+ }
+
+ return type;
}
static void
g_mime_filter_reply_class_init (GMimeFilterReplyClass *klass, unused (void *class_data))
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
- parent_class = (GMimeFilterClass *) g_type_class_ref (GMIME_TYPE_FILTER);
+ parent_class = (GMimeFilterClass *) g_type_class_ref (GMIME_TYPE_FILTER);
- object_class->finalize = g_mime_filter_reply_finalize;
+ object_class->finalize = g_mime_filter_reply_finalize;
- filter_class->copy = filter_copy;
- filter_class->filter = filter_filter;
- filter_class->complete = filter_complete;
- filter_class->reset = filter_reset;
+ filter_class->copy = filter_copy;
+ filter_class->filter = filter_filter;
+ filter_class->complete = filter_complete;
+ filter_class->reset = filter_reset;
}
static void
g_mime_filter_reply_init (GMimeFilterReply *filter, GMimeFilterReplyClass *klass)
{
- (void) klass;
- filter->saw_nl = true;
- filter->saw_angle = false;
+ (void) klass;
+ filter->saw_nl = true;
+ filter->saw_angle = false;
}
static void
g_mime_filter_reply_finalize (GObject *object)
{
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GMimeFilter *
filter_copy (GMimeFilter *filter)
{
- GMimeFilterReply *reply = (GMimeFilterReply *) filter;
+ GMimeFilterReply *reply = (GMimeFilterReply *) filter;
- return g_mime_filter_reply_new (reply->encode);
+ return g_mime_filter_reply_new (reply->encode);
}
static void
filter_filter (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
char **outbuf, size_t *outlen, size_t *outprespace)
{
- GMimeFilterReply *reply = (GMimeFilterReply *) filter;
- const char *inptr = inbuf;
- const char *inend = inbuf + inlen;
- char *outptr;
-
- (void) prespace;
- if (reply->encode) {
- g_mime_filter_set_size (filter, 3 * inlen, false);
-
- outptr = filter->outbuf;
- while (inptr < inend) {
- if (reply->saw_nl) {
- *outptr++ = '>';
- *outptr++ = ' ';
- reply->saw_nl = false;
- }
- if (*inptr == '\n')
- reply->saw_nl = true;
- else
- reply->saw_nl = false;
- if (*inptr != '\r')
- *outptr++ = *inptr;
- inptr++;
- }
- } else {
- g_mime_filter_set_size (filter, inlen + 1, false);
-
- outptr = filter->outbuf;
- while (inptr < inend) {
- if (reply->saw_nl) {
- if (*inptr == '>')
- reply->saw_angle = true;
- else
- *outptr++ = *inptr;
- reply->saw_nl = false;
- } else if (reply->saw_angle) {
- if (*inptr == ' ')
- ;
- else
- *outptr++ = *inptr;
- reply->saw_angle = false;
- } else if (*inptr != '\r') {
- if (*inptr == '\n')
- reply->saw_nl = true;
- *outptr++ = *inptr;
- }
-
- inptr++;
- }
+ GMimeFilterReply *reply = (GMimeFilterReply *) filter;
+ const char *inptr = inbuf;
+ const char *inend = inbuf + inlen;
+ char *outptr;
+
+ (void) prespace;
+ if (reply->encode) {
+ g_mime_filter_set_size (filter, 3 * inlen, false);
+
+ outptr = filter->outbuf;
+ while (inptr < inend) {
+ if (reply->saw_nl) {
+ *outptr++ = '>';
+ *outptr++ = ' ';
+ reply->saw_nl = false;
+ }
+ if (*inptr == '\n')
+ reply->saw_nl = true;
+ else
+ reply->saw_nl = false;
+ if (*inptr != '\r')
+ *outptr++ = *inptr;
+ inptr++;
+ }
+ } else {
+ g_mime_filter_set_size (filter, inlen + 1, false);
+
+ outptr = filter->outbuf;
+ while (inptr < inend) {
+ if (reply->saw_nl) {
+ if (*inptr == '>')
+ reply->saw_angle = true;
+ else
+ *outptr++ = *inptr;
+ reply->saw_nl = false;
+ } else if (reply->saw_angle) {
+ if (*inptr == ' ')
+ ;
+ else
+ *outptr++ = *inptr;
+ reply->saw_angle = false;
+ } else if (*inptr != '\r') {
+ if (*inptr == '\n')
+ reply->saw_nl = true;
+ *outptr++ = *inptr;
+ }
+
+ inptr++;
}
+ }
- *outlen = outptr - filter->outbuf;
- *outprespace = filter->outpre;
- *outbuf = filter->outbuf;
+ *outlen = outptr - filter->outbuf;
+ *outprespace = filter->outpre;
+ *outbuf = filter->outbuf;
}
static void
filter_complete (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
char **outbuf, size_t *outlen, size_t *outprespace)
{
- if (inbuf && inlen)
- filter_filter (filter, inbuf, inlen, prespace, outbuf, outlen, outprespace);
+ if (inbuf && inlen)
+ filter_filter (filter, inbuf, inlen, prespace, outbuf, outlen, outprespace);
}
static void
filter_reset (GMimeFilter *filter)
{
- GMimeFilterReply *reply = (GMimeFilterReply *) filter;
+ GMimeFilterReply *reply = (GMimeFilterReply *) filter;
- reply->saw_nl = true;
- reply->saw_angle = false;
+ reply->saw_nl = true;
+ reply->saw_angle = false;
}
GMimeFilter *
g_mime_filter_reply_new (gboolean encode)
{
- GMimeFilterReply *new_reply;
+ GMimeFilterReply *new_reply;
- new_reply = (GMimeFilterReply *) g_object_new (GMIME_TYPE_FILTER_REPLY, NULL);
- new_reply->encode = encode;
+ new_reply = (GMimeFilterReply *) g_object_new (GMIME_TYPE_FILTER_REPLY, NULL);
+ new_reply->encode = encode;
- return (GMimeFilter *) new_reply;
+ return (GMimeFilter *) new_reply;
}
* A filter to insert/remove reply markers (lines beginning with >)
**/
struct _GMimeFilterReply {
- GMimeFilter parent_object;
+ GMimeFilter parent_object;
- gboolean encode;
- gboolean saw_nl;
- gboolean saw_angle;
+ gboolean encode;
+ gboolean saw_nl;
+ gboolean saw_angle;
};
struct _GMimeFilterReplyClass {
- GMimeFilterClass parent_class;
+ GMimeFilterClass parent_class;
};
/* Flush any buffered output before forking. */
fflush (stdout);
- pid = fork();
+ pid = fork ();
if (pid == -1) {
fprintf (stderr, "Error: %s hook fork failed: %s\n", hook,
strerror (errno));
goto DONE;
}
- if (!WIFEXITED (status) || WEXITSTATUS (status)) {
+ if (! WIFEXITED (status) || WEXITSTATUS (status)) {
if (WIFEXITED (status)) {
fprintf (stderr, "Error: %s hook failed with status %d\n",
hook, WEXITSTATUS (status));
* reference to the database. We should avoid making a message
* its own parent, thus the above check.
*/
- return talloc_strdup(ctx, last_ref);
+ return talloc_strdup (ctx, last_ref);
}
static const char *
metadata_key = _get_metadata_thread_id_key (ctx, message_id);
thread_id_string = notmuch->xapian_db->get_metadata (metadata_key);
- if (thread_id_string.empty()) {
+ if (thread_id_string.empty ()) {
*thread_id_ret = talloc_strdup (ctx,
_notmuch_database_generate_thread_id (notmuch));
db->set_metadata (metadata_key, *thread_id_ret);
} else {
- *thread_id_ret = talloc_strdup (ctx, thread_id_string.c_str());
+ *thread_id_ret = talloc_strdup (ctx, thread_id_string.c_str ());
}
talloc_free (metadata_key);
_notmuch_database_find_doc_ids (notmuch, "thread", loser_thread_id, &loser, &loser_end);
- for ( ; loser != loser_end; loser++) {
+ for (; loser != loser_end; loser++) {
message = _notmuch_message_create (notmuch, notmuch,
*loser, &private_status);
if (message == NULL) {
last_ref_message_id);
} else if (in_reply_to_message_id) {
_notmuch_message_add_term (message, "replyto",
- in_reply_to_message_id);
+ in_reply_to_message_id);
}
keys = g_hash_table_get_keys (parents);
_notmuch_database_find_doc_ids (notmuch, "reference", message_id, &child, &children_end);
- for ( ; child != children_end; child++) {
+ for (; child != children_end; child++) {
child_message = _notmuch_message_create (message, notmuch,
*child, &private_status);
_notmuch_message_add_term (message, "thread", thread_id);
}
- DONE:
+ DONE:
talloc_free (local);
return status;
}
ret = _notmuch_database_link_message (notmuch, message,
- message_file, is_ghost);
+ message_file, is_ghost);
if (ret)
goto DONE;
if (is_new || is_ghost)
_notmuch_message_set_header_values (message, date, from, subject);
- if (!indexopts) {
+ if (! indexopts) {
def_indexopts = notmuch_database_get_default_indexopts (notmuch);
indexopts = def_indexopts;
}
if (ret)
goto DONE;
- if (! is_new && !is_ghost)
+ if (! is_new && ! is_ghost)
ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
_notmuch_message_sync (message);
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch, "A Xapian exception occurred adding message: %s.\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
goto DONE;
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
notmuch->exception_reported = true;
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred setting metadata: %s\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
}
return NOTMUCH_STATUS_SUCCESS;
}
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
notmuch->exception_reported = true;
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred getting metadata: %s\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
}
return status;
}
try {
new(&(list->iterator)) Xapian::TermIterator (notmuch->xapian_db->metadata_keys_begin
- (CONFIG_PREFIX + (prefix ? prefix : "")));
+ (CONFIG_PREFIX + (prefix ? prefix : "")));
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch, "A Xapian exception occurred getting metadata iterator: %s.\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
* unset, file names are stored in document data.
*
* Introduced: version 1. */
- NOTMUCH_FEATURE_FILE_TERMS = 1 << 0,
+ NOTMUCH_FEATURE_FILE_TERMS = 1 << 0,
/* If set, directory timestamps are stored in documents with
* XDIRECTORY terms and relative paths. If unset, directory
* absolute paths.
*
* Introduced: version 1. */
- NOTMUCH_FEATURE_DIRECTORY_DOCS = 1 << 1,
+ NOTMUCH_FEATURE_DIRECTORY_DOCS = 1 << 1,
/* If set, the from, subject, and message-id headers are stored in
* message document values. If unset, message documents *may*
*
* Introduced: optional in version 1, required as of version 3.
*/
- NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES = 1 << 2,
+ NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES = 1 << 2,
/* If set, folder terms are boolean and path terms exist. If
* unset, folder terms are probabilistic and stemmed and path
* terms do not exist.
*
* Introduced: version 2. */
- NOTMUCH_FEATURE_BOOL_FOLDER = 1 << 3,
+ NOTMUCH_FEATURE_BOOL_FOLDER = 1 << 3,
/* If set, missing messages are stored in ghost mail documents.
* If unset, thread IDs of ghost messages are stored as database
* metadata instead of in ghost documents.
*
* Introduced: version 3. */
- NOTMUCH_FEATURE_GHOSTS = 1 << 4,
+ NOTMUCH_FEATURE_GHOSTS = 1 << 4,
/* If set, then the database was created after the introduction of
* mixture of messages with indexed and non-indexed mime types.
*
* Introduced: version 3. */
- NOTMUCH_FEATURE_INDEXED_MIMETYPES = 1 << 5,
+ NOTMUCH_FEATURE_INDEXED_MIMETYPES = 1 << 5,
/* If set, messages store the revision number of the last
* modification in NOTMUCH_VALUE_LAST_MOD.
*
* Introduced: version 3. */
- NOTMUCH_FEATURE_LAST_MOD = 1 << 6,
+ NOTMUCH_FEATURE_LAST_MOD = 1 << 6,
/* If set, unprefixed terms are stored only for the message body,
* not for headers.
*
* Introduced: version 3. */
- NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY = 1 << 7,
+ NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY = 1 << 7,
};
/* In C++, a named enum is its own type, so define bitwise operators
* on _notmuch_features. */
inline _notmuch_features
-operator|(_notmuch_features a, _notmuch_features b)
+operator| (_notmuch_features a, _notmuch_features b)
{
return static_cast<_notmuch_features>(
static_cast<unsigned>(a) | static_cast<unsigned>(b));
}
inline _notmuch_features
-operator&(_notmuch_features a, _notmuch_features b)
+operator& (_notmuch_features a, _notmuch_features b)
{
return static_cast<_notmuch_features>(
static_cast<unsigned>(a) & static_cast<unsigned>(b));
}
inline _notmuch_features
-operator~(_notmuch_features a)
+operator~ (_notmuch_features a)
{
return static_cast<_notmuch_features>(~static_cast<unsigned>(a));
}
inline _notmuch_features&
-operator|=(_notmuch_features &a, _notmuch_features b)
+operator|= (_notmuch_features &a, _notmuch_features b)
{
a = a | b;
return a;
}
inline _notmuch_features&
-operator&=(_notmuch_features &a, _notmuch_features b)
+operator&= (_notmuch_features &a, _notmuch_features b)
{
a = a & b;
return a;
/*
* Configuration options for xapian database fields */
typedef enum notmuch_field_flags {
- NOTMUCH_FIELD_NO_FLAGS = 0,
- NOTMUCH_FIELD_EXTERNAL = 1 << 0,
+ NOTMUCH_FIELD_NO_FLAGS = 0,
+ NOTMUCH_FIELD_EXTERNAL = 1 << 0,
NOTMUCH_FIELD_PROBABILISTIC = 1 << 1,
- NOTMUCH_FIELD_PROCESSOR = 1 << 2,
+ NOTMUCH_FIELD_PROCESSOR = 1 << 2,
} notmuch_field_flag_t;
/*
* define bitwise operators to hide casts */
inline notmuch_field_flag_t
-operator|(notmuch_field_flag_t a, notmuch_field_flag_t b)
+operator| (notmuch_field_flag_t a, notmuch_field_flag_t b)
{
return static_cast<notmuch_field_flag_t>(
static_cast<unsigned>(a) | static_cast<unsigned>(b));
}
inline notmuch_field_flag_t
-operator&(notmuch_field_flag_t a, notmuch_field_flag_t b)
+operator& (notmuch_field_flag_t a, notmuch_field_flag_t b)
{
return static_cast<notmuch_field_flag_t>(
static_cast<unsigned>(a) & static_cast<unsigned>(b));
/* Prior to database version 3, features were implied by the database
* version number, so hard-code them for earlier versions. */
-#define NOTMUCH_FEATURES_V0 ((enum _notmuch_features)0)
+#define NOTMUCH_FEATURES_V0 ((enum _notmuch_features) 0)
#define NOTMUCH_FEATURES_V1 (NOTMUCH_FEATURES_V0 | NOTMUCH_FEATURE_FILE_TERMS | \
NOTMUCH_FEATURE_DIRECTORY_DOCS)
#define NOTMUCH_FEATURES_V2 (NOTMUCH_FEATURES_V1 | NOTMUCH_FEATURE_BOOL_FOLDER)
#include <signal.h>
#include <ftw.h>
-#include <glib.h> /* g_free, GPtrArray, GHashTable */
-#include <glib-object.h> /* g_type_init */
+#include <glib.h> /* g_free, GPtrArray, GHashTable */
+#include <glib-object.h> /* g_type_init */
-#include <gmime/gmime.h> /* g_mime_init */
+#include <gmime/gmime.h> /* g_mime_init */
using namespace std;
#define NOTMUCH_DATABASE_VERSION 3
-#define STRINGIFY(s) _SUB_STRINGIFY(s)
+#define STRINGIFY(s) _SUB_STRINGIFY (s)
#define _SUB_STRINGIFY(s) #s
#if HAVE_XAPIAN_DB_RETRY_LOCK
static const
prefix_t prefix_table[] = {
/* name term prefix flags */
- { "type", "T", NOTMUCH_FIELD_NO_FLAGS },
- { "reference", "XREFERENCE", NOTMUCH_FIELD_NO_FLAGS },
- { "replyto", "XREPLYTO", NOTMUCH_FIELD_NO_FLAGS },
- { "directory", "XDIRECTORY", NOTMUCH_FIELD_NO_FLAGS },
- { "file-direntry", "XFDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
- { "directory-direntry", "XDDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
- { "body", "", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROBABILISTIC},
- { "thread", "G", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROCESSOR },
- { "tag", "K", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROCESSOR },
- { "is", "K", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROCESSOR },
- { "id", "Q", NOTMUCH_FIELD_EXTERNAL },
- { "mid", "Q", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROCESSOR },
- { "path", "P", NOTMUCH_FIELD_EXTERNAL|
- NOTMUCH_FIELD_PROCESSOR },
- { "property", "XPROPERTY", NOTMUCH_FIELD_EXTERNAL },
+ { "type", "T", NOTMUCH_FIELD_NO_FLAGS },
+ { "reference", "XREFERENCE", NOTMUCH_FIELD_NO_FLAGS },
+ { "replyto", "XREPLYTO", NOTMUCH_FIELD_NO_FLAGS },
+ { "directory", "XDIRECTORY", NOTMUCH_FIELD_NO_FLAGS },
+ { "file-direntry", "XFDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
+ { "directory-direntry", "XDDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
+ { "body", "", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROBABILISTIC },
+ { "thread", "G", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROCESSOR },
+ { "tag", "K", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROCESSOR },
+ { "is", "K", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROCESSOR },
+ { "id", "Q", NOTMUCH_FIELD_EXTERNAL },
+ { "mid", "Q", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROCESSOR },
+ { "path", "P", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROCESSOR },
+ { "property", "XPROPERTY", NOTMUCH_FIELD_EXTERNAL },
/*
* Unconditionally add ':' to reduce potential ambiguity with
* overlapping prefixes and/or terms that start with capital
* letters. See Xapian document termprefixes.html for related
* discussion.
*/
- { "folder", "XFOLDER:", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROCESSOR },
+ { "folder", "XFOLDER:", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROCESSOR },
#if HAVE_XAPIAN_FIELD_PROCESSOR
- { "date", NULL, NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROCESSOR },
- { "query", NULL, NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROCESSOR },
+ { "date", NULL, NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROCESSOR },
+ { "query", NULL, NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROCESSOR },
#endif
- { "from", "XFROM", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROBABILISTIC |
- NOTMUCH_FIELD_PROCESSOR },
- { "to", "XTO", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROBABILISTIC },
- { "attachment", "XATTACHMENT", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROBABILISTIC },
- { "mimetype", "XMIMETYPE", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROBABILISTIC },
- { "subject", "XSUBJECT", NOTMUCH_FIELD_EXTERNAL |
- NOTMUCH_FIELD_PROBABILISTIC |
- NOTMUCH_FIELD_PROCESSOR},
+ { "from", "XFROM", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROBABILISTIC |
+ NOTMUCH_FIELD_PROCESSOR },
+ { "to", "XTO", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROBABILISTIC },
+ { "attachment", "XATTACHMENT", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROBABILISTIC },
+ { "mimetype", "XMIMETYPE", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROBABILISTIC },
+ { "subject", "XSUBJECT", NOTMUCH_FIELD_EXTERNAL |
+ NOTMUCH_FIELD_PROBABILISTIC |
+ NOTMUCH_FIELD_PROCESSOR },
};
static void
_setup_query_field_default (const prefix_t *prefix, notmuch_database_t *notmuch)
{
if (prefix->prefix)
- notmuch->query_parser->add_prefix ("",prefix->prefix);
+ notmuch->query_parser->add_prefix ("", prefix->prefix);
if (prefix->flags & NOTMUCH_FIELD_PROBABILISTIC)
notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
else
}
const char *
-_user_prefix (void *ctx, const char* name)
+_user_prefix (void *ctx, const char *name)
{
- return talloc_asprintf(ctx, "XU%s:", name);
+ return talloc_asprintf (ctx, "XU%s:", name);
}
static notmuch_status_t
prefix_t query_field;
const char *key = notmuch_config_list_key (list)
- + sizeof (CONFIG_HEADER_PREFIX) - 1;
+ + sizeof (CONFIG_HEADER_PREFIX) - 1;
_notmuch_string_map_append (notmuch->user_prefix,
key,
query_field.name = talloc_strdup (notmuch, key);
query_field.prefix = _user_prefix (notmuch, key);
query_field.flags = NOTMUCH_FIELD_PROBABILISTIC
- | NOTMUCH_FIELD_EXTERNAL;
+ | NOTMUCH_FIELD_EXTERNAL;
_setup_query_field_default (&query_field, notmuch);
}
Xapian::FieldProcessor *fp;
if (STRNCMP_LITERAL (prefix->name, "date") == 0)
- fp = (new DateFieldProcessor())->release ();
- else if (STRNCMP_LITERAL(prefix->name, "query") == 0)
+ fp = (new DateFieldProcessor ())->release ();
+ else if (STRNCMP_LITERAL (prefix->name, "query") == 0)
fp = (new QueryFieldProcessor (*notmuch->query_parser, notmuch))->release ();
- else if (STRNCMP_LITERAL(prefix->name, "thread") == 0)
+ else if (STRNCMP_LITERAL (prefix->name, "thread") == 0)
fp = (new ThreadFieldProcessor (*notmuch->query_parser, notmuch))->release ();
else
fp = (new RegexpFieldProcessor (prefix->name, prefix->flags,
/* we treat all field-processor fields as boolean in order to get the raw input */
if (prefix->prefix)
- notmuch->query_parser->add_prefix ("",prefix->prefix);
+ notmuch->query_parser->add_prefix ("", prefix->prefix);
notmuch->query_parser->add_boolean_prefix (prefix->name, fp);
} else {
_setup_query_field_default (prefix, notmuch);
{ NOTMUCH_FEATURE_BOOL_FOLDER,
"exact folder:/path: search", "rw" },
{ NOTMUCH_FEATURE_GHOSTS,
- "mail documents for missing messages", "w"},
+ "mail documents for missing messages", "w" },
/* Knowledge of the index mime-types are not required for reading
* a database because a reader will just be unable to query
* them. */
{ NOTMUCH_FEATURE_INDEXED_MIMETYPES,
- "indexed MIME types", "w"},
+ "indexed MIME types", "w" },
{ NOTMUCH_FEATURE_LAST_MOD,
- "modification tracking", "w"},
+ "modification tracking", "w" },
/* Existing databases will work fine for all queries not involving
* 'body:' */
{ NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY,
- "index body and headers separately", "w"},
+ "index body and headers separately", "w" },
};
const char *
void
_notmuch_database_log (notmuch_database_t *notmuch,
- const char *format,
- ...)
+ const char *format,
+ ...)
{
va_list va_args;
void
_notmuch_database_log_append (notmuch_database_t *notmuch,
- const char *format,
- ...)
+ const char *format,
+ ...)
{
va_list va_args;
return NOTMUCH_STATUS_SUCCESS;
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch, "A Xapian exception occurred finding message: %s.\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
*message_ret = NULL;
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
err = stat (path, &st);
if (err) {
IGNORE_RESULT (asprintf (&message, "Error: Cannot create database at %s: %s.\n",
- path, strerror (errno)));
+ path, strerror (errno)));
status = NOTMUCH_STATUS_FILE_ERROR;
goto DONE;
}
status = notmuch_database_upgrade (notmuch, NULL, NULL);
if (status) {
- notmuch_database_close(notmuch);
+ notmuch_database_close (notmuch);
notmuch = NULL;
}
notmuch_status_t status;
status = notmuch_database_open_verbose (path, mode, database,
- &status_string);
+ &status_string);
if (status_string) {
fputs (status_string, stderr);
}
/* Initialize the GLib type system and threads */
-#if !GLIB_CHECK_VERSION(2, 35, 1)
+#if ! GLIB_CHECK_VERSION (2, 35, 1)
g_type_init ();
#endif
notmuch->status_string = NULL;
notmuch->path = talloc_strdup (notmuch, path);
- strip_trailing(notmuch->path, '/');
+ strip_trailing (notmuch->path, '/');
notmuch->mode = mode;
notmuch->atomic_nesting = 0;
version = notmuch_database_get_version (notmuch);
if (version > NOTMUCH_DATABASE_VERSION) {
IGNORE_RESULT (asprintf (&message,
- "Error: Notmuch database at %s\n"
- " has a newer database format version (%u) than supported by this\n"
- " version of notmuch (%u).\n",
+ "Error: Notmuch database at %s\n"
+ " has a newer database format version (%u) than supported by this\n"
+ " version of notmuch (%u).\n",
notmuch_path, version, NOTMUCH_DATABASE_VERSION));
notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
notmuch_database_destroy (notmuch);
&incompat_features);
if (incompat_features) {
IGNORE_RESULT (asprintf (&message,
- "Error: Notmuch database at %s\n"
- " requires features (%s)\n"
- " not supported by this version of notmuch.\n",
+ "Error: Notmuch database at %s\n"
+ " requires features (%s)\n"
+ " not supported by this version of notmuch.\n",
notmuch_path, incompat_features));
notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
notmuch_database_destroy (notmuch);
status = _setup_user_query_fields (notmuch);
} catch (const Xapian::Error &error) {
IGNORE_RESULT (asprintf (&message, "A Xapian exception occurred opening database: %s\n",
- error.get_msg().c_str()));
+ error.get_msg ().c_str ()));
notmuch_database_destroy (notmuch);
notmuch = NULL;
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&
notmuch->atomic_nesting)
(static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))
- ->cancel_transaction ();
+ ->cancel_transaction ();
/* Close the database. This implicitly flushes
* outstanding changes. */
- notmuch->xapian_db->close();
+ notmuch->xapian_db->close ();
} catch (const Xapian::Error &error) {
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
if (! notmuch->exception_reported) {
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred closing database: %s\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
}
}
}
public:
NotmuchCompactor(notmuch_compact_status_cb_t cb, void *closure) :
- status_cb (cb), status_closure (closure) { }
+ status_cb (cb), status_closure (closure)
+ {
+ }
virtual void
set_status (const std::string &table, const std::string &status)
return;
if (status.length () == 0)
- msg = talloc_asprintf (NULL, "compacting table %s", table.c_str());
+ msg = talloc_asprintf (NULL, "compacting table %s", table.c_str ());
else
- msg = talloc_asprintf (NULL, " %s", status.c_str());
+ msg = talloc_asprintf (NULL, " %s", status.c_str ());
if (msg == NULL) {
return;
goto DONE;
}
keep_backup = false;
- }
- else {
+ } else {
keep_backup = true;
}
}
if (errno != ENOENT) {
_notmuch_database_log (notmuch, "Unknown error while stat()ing path: %s\n",
- strerror (errno));
+ strerror (errno));
ret = NOTMUCH_STATUS_FILE_ERROR;
goto DONE;
}
compactor.set_destdir (compact_xapian_path);
compactor.compact ();
} catch (const Xapian::Error &error) {
- _notmuch_database_log (notmuch, "Error while compacting: %s\n", error.get_msg().c_str());
+ _notmuch_database_log (notmuch, "Error while compacting: %s\n", error.get_msg ().c_str ());
ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
goto DONE;
}
if (rename (xapian_path, backup_path)) {
_notmuch_database_log (notmuch, "Error moving %s to %s: %s\n",
- xapian_path, backup_path, strerror (errno));
+ xapian_path, backup_path, strerror (errno));
ret = NOTMUCH_STATUS_FILE_ERROR;
goto DONE;
}
if (rename (compact_xapian_path, xapian_path)) {
_notmuch_database_log (notmuch, "Error moving %s to %s: %s\n",
- compact_xapian_path, xapian_path, strerror (errno));
+ compact_xapian_path, xapian_path, strerror (errno));
ret = NOTMUCH_STATUS_FILE_ERROR;
goto DONE;
}
if (! keep_backup) {
if (rmtree (backup_path)) {
_notmuch_database_log (notmuch, "Error removing old database %s: %s\n",
- backup_path, strerror (errno));
+ backup_path, strerror (errno));
ret = NOTMUCH_STATUS_FILE_ERROR;
goto DONE;
}
notmuch_database_needs_upgrade (notmuch_database_t *notmuch)
{
return notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&
- ((NOTMUCH_FEATURES_CURRENT & ~notmuch->features) ||
- (notmuch_database_get_version (notmuch) < NOTMUCH_DATABASE_VERSION));
+ ((NOTMUCH_FEATURES_CURRENT & ~notmuch->features) ||
+ (notmuch_database_get_version (notmuch) < NOTMUCH_DATABASE_VERSION));
}
static volatile sig_atomic_t do_progress_notify = 0;
*/
notmuch_status_t
notmuch_database_upgrade (notmuch_database_t *notmuch,
- void (*progress_notify) (void *closure,
- double progress),
+ void (*progress_notify)(void *closure,
+ double progress),
void *closure)
{
void *local = talloc_new (NULL);
goto DONE;
for (;
notmuch_messages_valid (messages);
- notmuch_messages_move_to_next (messages))
- {
+ notmuch_messages_move_to_next (messages)) {
if (do_progress_notify) {
progress_notify (closure, (double) count / total);
do_progress_notify = 0;
for (t = notmuch->xapian_db->allterms_begin ("XTIMESTAMP");
t != t_end;
- t++)
- {
+ t++) {
Xapian::PostingIterator p, p_end;
std::string term = *t;
for (p = notmuch->xapian_db->postlist_begin (term);
p != p_end;
- p++)
- {
+ p++) {
Xapian::Document document;
time_t mtime;
notmuch_directory_t *directory;
mtime = Xapian::sortable_unserialise (
document.get_value (NOTMUCH_VALUE_TIMESTAMP));
- directory = _notmuch_directory_create (notmuch, term.c_str() + 10,
+ directory = _notmuch_directory_create (notmuch, term.c_str () + 10,
NOTMUCH_FIND_CREATE, &status);
notmuch_directory_set_mtime (directory, mtime);
notmuch_directory_destroy (directory);
if (private_status) {
_notmuch_database_log (notmuch,
- "Upgrade failed while creating ghost messages.\n");
+ "Upgrade failed while creating ghost messages.\n");
status = COERCE_STATUS (private_status, "Unexpected status from _notmuch_message_initialize_ghost");
goto DONE;
}
db->set_metadata ("features", _print_features (local, notmuch->features));
db->set_metadata ("version", STRINGIFY (NOTMUCH_DATABASE_VERSION));
- DONE:
+ DONE:
if (status == NOTMUCH_STATUS_SUCCESS)
db->commit_transaction ();
else
(static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))->begin_transaction (false);
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch, "A Xapian exception occurred beginning transaction: %s.\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
-DONE:
+ DONE:
notmuch->atomic_nesting++;
return NOTMUCH_STATUS_SUCCESS;
}
db->commit ();
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch, "A Xapian exception occurred committing transaction: %s.\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
notmuch->atomic_dirty = false;
}
-DONE:
+ DONE:
notmuch->atomic_nesting--;
return NOTMUCH_STATUS_SUCCESS;
}
unsigned long
notmuch_database_get_revision (notmuch_database_t *notmuch,
- const char **uuid)
+ const char **uuid)
{
if (uuid)
*uuid = notmuch->uuid;
}
directory = _notmuch_directory_create (notmuch, path, flags, &status);
- if (status || !directory) {
+ if (status || ! directory) {
*directory_id = -1;
return status;
}
status = _notmuch_database_find_directory_id (notmuch, directory, flags,
&directory_id);
- if (status || directory_id == (unsigned int)-1) {
+ if (status || directory_id == (unsigned int) -1) {
*direntry = NULL;
return status;
}
relative = path;
if (*relative == '/') {
- while (*relative == '/' && *(relative+1) == '/')
+ while (*relative == '/' && *(relative + 1) == '/')
relative++;
- if (strncmp (relative, db_path, db_path_len) == 0)
- {
+ if (strncmp (relative, db_path, db_path_len) == 0) {
relative += db_path_len;
while (*relative == '/')
relative++;
NOTMUCH_FIND_LOOKUP, &status);
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch, "A Xapian exception occurred getting directory: %s.\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
&message);
if (status == NOTMUCH_STATUS_SUCCESS && message) {
- status = _notmuch_message_remove_filename (message, filename);
- if (status == NOTMUCH_STATUS_SUCCESS)
- _notmuch_message_delete (message);
- else if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
- _notmuch_message_sync (message);
+ status = _notmuch_message_remove_filename (message, filename);
+ if (status == NOTMUCH_STATUS_SUCCESS)
+ _notmuch_message_delete (message);
+ else if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
+ _notmuch_message_sync (message);
- notmuch_message_destroy (message);
+ notmuch_message_destroy (message);
}
return status;
try {
status = _notmuch_database_filename_to_direntry (
local, notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry);
- if (status || !direntry)
+ if (status || ! direntry)
goto DONE;
term = talloc_asprintf (local, "%s%s", prefix, direntry);
}
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred finding message by filename: %s\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
notmuch_string_list_t *tags;
try {
- i = db->xapian_db->allterms_begin();
- end = db->xapian_db->allterms_end();
+ i = db->xapian_db->allterms_begin ();
+ end = db->xapian_db->allterms_end ();
tags = _notmuch_database_get_terms_with_prefix (db, i, end,
_find_prefix ("tag"));
_notmuch_string_list_sort (tags);
return _notmuch_tags_create (db, tags);
} catch (const Xapian::Error &error) {
_notmuch_database_log (db, "A Xapian exception occurred getting tags: %s.\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
db->exception_reported = true;
return NULL;
}
notmuch_string_list_t *filename_list;
Xapian::TermIterator i, end;
- i = notmuch->xapian_db->allterms_begin();
- end = notmuch->xapian_db->allterms_end();
+ i = notmuch->xapian_db->allterms_begin ();
+ end = notmuch->xapian_db->allterms_end ();
filename_list = _notmuch_database_get_terms_with_prefix (ctx, i, end,
prefix);
if (unlikely (filename_list == NULL))
directory->document_id = directory->doc.get_docid ();
if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
- if (!create) {
+ if (! create) {
notmuch_directory_destroy (directory);
directory = NULL;
*status_ret = NOTMUCH_STATUS_SUCCESS;
directory->doc.get_value (NOTMUCH_VALUE_TIMESTAMP));
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch,
- "A Xapian exception occurred creating a directory: %s.\n",
- error.get_msg().c_str());
+ "A Xapian exception occurred creating a directory: %s.\n",
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
notmuch_directory_destroy (directory);
directory = NULL;
try {
directory->doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
- Xapian::sortable_serialise (mtime));
+ Xapian::sortable_serialise (mtime));
db->replace_document (directory->document_id, directory->doc);
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch,
- "A Xapian exception occurred setting directory mtime: %s.\n",
- error.get_msg().c_str());
+ "A Xapian exception occurred setting directory mtime: %s.\n",
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
directory->document_id);
child_directories = _create_filenames_for_terms_with_prefix (directory,
- directory->notmuch, term);
+ directory->notmuch, term);
talloc_free (term);
} catch (const Xapian::Error &error) {
_notmuch_database_log (directory->notmuch,
"A Xapian exception occurred deleting directory entry: %s.\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
directory->notmuch->exception_reported = true;
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
* which we discard data. */
static const int first_uuencode_skipping_state = 11;
static const scanner_state_t uuencode_states[] = {
- {0, 'b', 'b', 1, 0},
- {1, 'e', 'e', 2, 0},
- {2, 'g', 'g', 3, 0},
- {3, 'i', 'i', 4, 0},
- {4, 'n', 'n', 5, 0},
- {5, ' ', ' ', 6, 0},
- {6, '0', '7', 7, 0},
- {7, '0', '7', 8, 0},
- {8, '0', '7', 9, 0},
- {9, ' ', ' ', 10, 0},
- {10, '\n', '\n', 11, 10},
- {11, 'M', 'M', 12, 0},
- {12, ' ', '`', 12, 11}
+ { 0, 'b', 'b', 1, 0 },
+ { 1, 'e', 'e', 2, 0 },
+ { 2, 'g', 'g', 3, 0 },
+ { 3, 'i', 'i', 4, 0 },
+ { 4, 'n', 'n', 5, 0 },
+ { 5, ' ', ' ', 6, 0 },
+ { 6, '0', '7', 7, 0 },
+ { 7, '0', '7', 8, 0 },
+ { 8, '0', '7', 9, 0 },
+ { 9, ' ', ' ', 10, 0 },
+ { 10, '\n', '\n', 11, 10 },
+ { 11, 'M', 'M', 12, 0 },
+ { 12, ' ', '`', 12, 11 }
};
/* The following table is intended to implement this DFA (in 'dot'
- format). Note that 2 and 3 are "hidden" states used to step through
- the possible out edges of state 1.
-
-digraph html_filter {
- 0 -> 1 [label="<"];
- 0 -> 0;
- 1 -> 4 [label="'"];
- 1 -> 5 [label="\""];
- 1 -> 0 [label=">"];
- 1 -> 1;
- 4 -> 1 [label="'"];
- 4 -> 4;
- 5 -> 1 [label="\""];
- 5 -> 5;
-}
-*/
+ * format). Note that 2 and 3 are "hidden" states used to step through
+ * the possible out edges of state 1.
+ *
+ * digraph html_filter {
+ * 0 -> 1 [label="<"];
+ * 0 -> 0;
+ * 1 -> 4 [label="'"];
+ * 1 -> 5 [label="\""];
+ * 1 -> 0 [label=">"];
+ * 1 -> 1;
+ * 4 -> 1 [label="'"];
+ * 4 -> 4;
+ * 5 -> 1 [label="\""];
+ * 5 -> 5;
+ * }
+ */
static const int first_html_skipping_state = 1;
static const scanner_state_t html_states[] = {
- {0, '<', '<', 1, 0},
- {1, '\'', '\'', 4, 2}, /* scanning for quote or > */
- {1, '"', '"', 5, 3},
- {1, '>', '>', 0, 1},
- {4, '\'', '\'', 1, 4}, /* inside single quotes */
- {5, '"', '"', 1, 5}, /* inside double quotes */
+ { 0, '<', '<', 1, 0 },
+ { 1, '\'', '\'', 4, 2 }, /* scanning for quote or > */
+ { 1, '"', '"', 5, 3 },
+ { 1, '>', '>', 0, 1 },
+ { 4, '\'', '\'', 1, 4 }, /* inside single quotes */
+ { 5, '"', '"', 1, 5 }, /* inside double quotes */
};
/* Oh, how I wish that gobject didn't require so much noisy boilerplate!
filter_copy (GMimeFilter *gmime_filter)
{
NotmuchFilterDiscardNonTerm *filter = (NotmuchFilterDiscardNonTerm *) gmime_filter;
+
return notmuch_filter_discard_non_term_new (filter->content_type);
}
next = filter->state;
while (inptr < inend) {
- /* Each state is defined by a contiguous set of rows of the
+ /* Each state is defined by a contiguous set of rows of the
* state table marked by a common value for '.state'. The
* state numbers must be equal to the index of the first row
* in a given state; thus the loop condition here looks for a
* in the underlying DFA.
*/
do {
- if (*inptr >= states[next].a && *inptr <= states[next].b) {
+ if (*inptr >= states[next].a && *inptr <= states[next].b) {
next = states[next].next_if_match;
- } else {
+ } else {
next = states[next].next_if_not_match;
}
static GType type = 0;
NotmuchFilterDiscardNonTerm *filter;
- if (!type) {
+ if (! type) {
static const GTypeInfo info = {
.class_size = sizeof (NotmuchFilterDiscardNonTermClass),
.base_init = NULL,
filter->content_type = content_type;
filter->state = 0;
if (g_mime_content_type_is_type (content_type, "text", "html")) {
- filter->states = html_states;
- filter->first_skipping_state = first_html_skipping_state;
+ filter->states = html_states;
+ filter->first_skipping_state = first_html_skipping_state;
} else {
- filter->states = uuencode_states;
- filter->first_skipping_state = first_uuencode_skipping_state;
+ filter->states = uuencode_states;
+ filter->first_skipping_state = first_uuencode_skipping_state;
}
return (GMimeFilter *) filter;
_index_content_type (notmuch_message_t *message, GMimeObject *part)
{
GMimeContentType *content_type = g_mime_object_get_content_type (part);
+
if (content_type) {
char *mime_string = g_mime_content_type_get_mime_type (content_type);
if (mime_string) {
GMimeContentType *content_type;
char *body;
const char *charset;
+ GMimeObject *repaired_part = NULL;
if (! part) {
_notmuch_database_log (notmuch_message_get_database (message),
- "Warning: Not indexing empty mime part.\n");
- return;
+ "Warning: Not indexing empty mime part.\n");
+ goto DONE;
+ }
+
+ repaired_part = _notmuch_repair_mixed_up_mangled (part);
+ if (repaired_part) {
+ /* This was likely "Mixed Up" in transit! We will instead use
+ * the more likely-to-be-correct variant. */
+ notmuch_message_add_property (message, "index.repaired", "mixedup");
+ part = repaired_part;
}
_index_content_type (message, part);
int i;
if (GMIME_IS_MULTIPART_SIGNED (multipart))
- _notmuch_message_add_term (message, "tag", "signed");
+ _notmuch_message_add_term (message, "tag", "signed");
if (GMIME_IS_MULTIPART_ENCRYPTED (multipart))
- _notmuch_message_add_term (message, "tag", "encrypted");
+ _notmuch_message_add_term (message, "tag", "encrypted");
for (i = 0; i < g_mime_multipart_get_count (multipart); i++) {
- notmuch_status_t status;
GMimeObject *child;
if (GMIME_IS_MULTIPART_SIGNED (multipart)) {
/* Don't index the signature, but index its content type. */
_index_content_type (message,
g_mime_multipart_get_part (multipart, i));
if (i == GMIME_MULTIPART_ENCRYPTED_CONTENT) {
- _index_encrypted_mime_part(message, indexopts,
- GMIME_MULTIPART_ENCRYPTED (part),
- msg_crypto);
+ _index_encrypted_mime_part (message, indexopts,
+ GMIME_MULTIPART_ENCRYPTED (part),
+ msg_crypto);
} else {
if (i != GMIME_MULTIPART_ENCRYPTED_VERSION) {
_notmuch_database_log (notmuch_message_get_database (message),
continue;
}
child = g_mime_multipart_get_part (multipart, i);
- status = _notmuch_message_crypto_potential_payload (msg_crypto, child, part, i);
- if (status)
- _notmuch_database_log (notmuch_message_get_database (message),
- "Warning: failed to mark the potential cryptographic payload (%s).\n",
- notmuch_status_to_string (status));
- _index_mime_part (message, indexopts, child, msg_crypto);
+ GMimeObject *toindex = child;
+ if (_notmuch_message_crypto_potential_payload (msg_crypto, child, part, i) &&
+ msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL) {
+ toindex = _notmuch_repair_crypto_payload_skip_legacy_display (child);
+ if (toindex != child)
+ notmuch_message_add_property (message, "index.repaired", "skip-protected-headers-legacy-display");
+ }
+ _index_mime_part (message, indexopts, toindex, msg_crypto);
}
- return;
+ goto DONE;
}
if (GMIME_IS_MESSAGE_PART (part)) {
_index_mime_part (message, indexopts, g_mime_message_get_mime_part (mime_message), msg_crypto);
- return;
+ goto DONE;
}
if (! (GMIME_IS_PART (part))) {
_notmuch_database_log (notmuch_message_get_database (message),
- "Warning: Not indexing unknown mime part: %s.\n",
- g_type_name (G_OBJECT_TYPE (part)));
- return;
+ "Warning: Not indexing unknown mime part: %s.\n",
+ g_type_name (G_OBJECT_TYPE (part)));
+ goto DONE;
}
disposition = g_mime_object_get_content_disposition (part);
if (disposition &&
strcasecmp (g_mime_content_disposition_get_disposition (disposition),
- GMIME_DISPOSITION_ATTACHMENT) == 0)
- {
+ GMIME_DISPOSITION_ATTACHMENT) == 0) {
const char *filename = g_mime_part_get_filename (GMIME_PART (part));
_notmuch_message_add_term (message, "tag", "attachment");
/* XXX: Would be nice to call out to something here to parse
* the attachment into text and then index that. */
- return;
+ goto DONE;
}
byte_array = g_byte_array_new ();
free (body);
}
+ DONE:
+ if (repaired_part)
+ g_object_unref (repaired_part);
}
/* descend (if desired) into the cleartext part of an encrypted MIME
{
notmuch_status_t status;
GError *err = NULL;
- notmuch_database_t * notmuch = NULL;
+ notmuch_database_t *notmuch = NULL;
GMimeObject *clear = NULL;
- if (!indexopts || (notmuch_indexopts_get_decrypt_policy (indexopts) == NOTMUCH_DECRYPT_FALSE))
+ if (! indexopts || (notmuch_indexopts_get_decrypt_policy (indexopts) == NOTMUCH_DECRYPT_FALSE))
return;
notmuch = notmuch_message_get_database (message);
bool get_sk = (notmuch_indexopts_get_decrypt_policy (indexopts) == NOTMUCH_DECRYPT_TRUE);
clear = _notmuch_crypto_decrypt (&attempted, notmuch_indexopts_get_decrypt_policy (indexopts),
message, encrypted_data, get_sk ? &decrypt_result : NULL, &err);
- if (!attempted)
+ if (! attempted)
return;
- if (err || !clear) {
+ if (err || ! clear) {
if (decrypt_result)
g_object_unref (decrypt_result);
if (err) {
_notmuch_database_log (notmuch, "Failed to decrypt during indexing. (%d:%d) [%s]\n",
err->domain, err->code, err->message);
- g_error_free(err);
+ g_error_free (err);
} else {
_notmuch_database_log (notmuch, "Failed to decrypt during indexing. (unknown error)\n");
}
}
g_object_unref (decrypt_result);
}
- status = _notmuch_message_crypto_potential_payload (msg_crypto, clear, GMIME_OBJECT (encrypted_data), GMIME_MULTIPART_ENCRYPTED_CONTENT);
- _index_mime_part (message, indexopts, clear, msg_crypto);
+ GMimeObject *toindex = clear;
+ if (_notmuch_message_crypto_potential_payload (msg_crypto, clear, GMIME_OBJECT (encrypted_data), GMIME_MULTIPART_ENCRYPTED_CONTENT) &&
+ msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL) {
+ toindex = _notmuch_repair_crypto_payload_skip_legacy_display (clear);
+ if (toindex != clear)
+ notmuch_message_add_property (message, "index.repaired", "skip-protected-headers-legacy-display");
+ }
+ _index_mime_part (message, indexopts, toindex, msg_crypto);
g_object_unref (clear);
status = notmuch_message_add_property (message, "index.decryption", "success");
notmuch_database_get_default_indexopts (notmuch_database_t *db)
{
notmuch_indexopts_t *ret = talloc_zero (db, notmuch_indexopts_t);
- if (!ret)
+
+ if (! ret)
return ret;
ret->crypto.decrypt = NOTMUCH_DECRYPT_AUTO;
- char * decrypt_policy;
+ char *decrypt_policy;
notmuch_status_t err = notmuch_database_get_config (db, "index.decrypt", &decrypt_policy);
if (err)
return ret;
if (decrypt_policy) {
- if ((!(strcasecmp(decrypt_policy, "true"))) ||
- (!(strcasecmp(decrypt_policy, "yes"))) ||
- (!(strcasecmp(decrypt_policy, "1"))))
+ if ((! (strcasecmp (decrypt_policy, "true"))) ||
+ (! (strcasecmp (decrypt_policy, "yes"))) ||
+ (! (strcasecmp (decrypt_policy, "1"))))
notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_TRUE);
- else if ((!(strcasecmp(decrypt_policy, "false"))) ||
- (!(strcasecmp(decrypt_policy, "no"))) ||
- (!(strcasecmp(decrypt_policy, "0"))))
+ else if ((! (strcasecmp (decrypt_policy, "false"))) ||
+ (! (strcasecmp (decrypt_policy, "no"))) ||
+ (! (strcasecmp (decrypt_policy, "0"))))
notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_FALSE);
- else if (!strcasecmp(decrypt_policy, "nostash"))
+ else if (! strcasecmp (decrypt_policy, "nostash"))
notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_NOSTASH);
}
notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts,
notmuch_decryption_policy_t decrypt_policy)
{
- if (!indexopts)
+ if (! indexopts)
return NOTMUCH_STATUS_NULL_POINTER;
indexopts->crypto.decrypt = decrypt_policy;
return NOTMUCH_STATUS_SUCCESS;
notmuch_decryption_policy_t
notmuch_indexopts_get_decrypt_policy (const notmuch_indexopts_t *indexopts)
{
- if (!indexopts)
+ if (! indexopts)
return false;
return indexopts->crypto.decrypt;
}
FAIL:
_notmuch_database_log (notmuch, "Error opening %s: %s\n",
- filename, strerror (errno));
+ filename, strerror (errno));
_notmuch_message_file_close (message);
return NULL;
bool ret = false;
/* Is this mbox? */
- if (g_mime_stream_read (stream, from_buf, sizeof (from_buf)) == sizeof(from_buf) &&
+ if (g_mime_stream_read (stream, from_buf, sizeof (from_buf)) == sizeof (from_buf) &&
strncmp (from_buf, "From ", 5) == 0)
ret = true;
*/
static char *
-_extend_header (char *combined, const char *value) {
+_extend_header (char *combined, const char *value)
+{
char *decoded;
decoded = g_mime_utils_header_decode_text (NULL, value);
} else {
combined = decoded;
}
- DONE:
+ DONE:
return combined;
}
return NULL;
- for (int i=0; i < g_mime_header_list_get_count (headers); i++) {
+ for (int i = 0; i < g_mime_header_list_get_count (headers); i++) {
const char *value;
GMimeHeader *g_header = g_mime_header_list_get_header_at (headers, i);
const char *
_notmuch_message_file_get_header (notmuch_message_file_t *message,
- const char *header)
+ const char *header)
{
const char *value;
char *decoded;
message_id = talloc_asprintf (message_file, "notmuch-sha1-%s", sha1);
free (sha1);
}
- DONE:
+ DONE:
if (ret == NOTMUCH_STATUS_SUCCESS) {
if (from_out)
*from_out = from;
} else if (*s == ')') {
nesting--;
} else if (*s == '\\') {
- if (*(s+1))
+ if (*(s + 1))
s++;
}
s++;
for (r = result, len = strlen (r); *r; r++, len--)
if (*r == ' ' || *r == '\t')
- memmove (r, r+1, len);
+ memmove (r, r + 1, len);
}
return result;
_notmuch_message_remove_all_properties (notmuch_message_t *message, const char *key, bool prefix)
{
notmuch_status_t status;
- const char * term_prefix;
+ const char *term_prefix;
status = _notmuch_database_ensure_writable (notmuch_message_get_database (message));
if (status)
notmuch_message_get_properties (notmuch_message_t *message, const char *key, notmuch_bool_t exact)
{
notmuch_string_map_t *map;
+
map = _notmuch_message_property_map (message);
return _notmuch_string_map_iterator_create (map, key, exact);
}
/* ASCII ordered table of Maildir flags and associated tags */
static struct maildir_flag_tag flag2tag[] = {
- { 'D', "draft", false},
- { 'F', "flagged", false},
- { 'P', "passed", false},
- { 'R', "replied", false},
+ { 'D', "draft", false },
+ { 'F', "flagged", false },
+ { 'P', "passed", false },
+ { 'R', "replied", false },
{ 'S', "unread", true }
};
doc_id = _notmuch_database_generate_doc_id (notmuch);
} catch (const Xapian::Error &error) {
- _notmuch_database_log(notmuch_message_get_database (message), "A Xapian exception occurred creating message: %s\n",
- error.get_msg().c_str());
+ _notmuch_database_log (notmuch_message_get_database (message), "A Xapian exception occurred creating message: %s\n",
+ error.get_msg ().c_str ());
notmuch->exception_reported = true;
*status_ret = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
return NULL;
return NULL;
const std::string &term = *i;
- if (strncmp (term.c_str(), prefix, prefix_len))
+ if (strncmp (term.c_str (), prefix, prefix_len))
return NULL;
- value = talloc_strdup (message, term.c_str() + prefix_len);
+ value = talloc_strdup (message, term.c_str () + prefix_len);
#if DEBUG_DATABASE_SANITY
i++;
return;
const char *thread_prefix = _find_prefix ("thread"),
- *tag_prefix = _find_prefix ("tag"),
- *id_prefix = _find_prefix ("id"),
- *type_prefix = _find_prefix ("type"),
- *filename_prefix = _find_prefix ("file-direntry"),
- *property_prefix = _find_prefix ("property"),
- *reference_prefix = _find_prefix ("reference"),
- *replyto_prefix = _find_prefix ("replyto");
+ *tag_prefix = _find_prefix ("tag"),
+ *id_prefix = _find_prefix ("id"),
+ *type_prefix = _find_prefix ("type"),
+ *filename_prefix = _find_prefix ("file-direntry"),
+ *property_prefix = _find_prefix ("property"),
+ *reference_prefix = _find_prefix ("reference"),
+ *replyto_prefix = _find_prefix ("replyto");
/* We do this all in a single pass because Xapian decompresses the
* term list every time you iterate over it. Thus, while this is
* slightly more costly than looking up individual fields if only
* one field of the message object is actually used, it's a huge
* win as more fields are used. */
- for (int count=0; count < 3; count++) {
+ for (int count = 0; count < 3; count++) {
try {
i = message->doc.termlist_begin ();
end = message->doc.termlist_end ();
/* Get thread */
- if (!message->thread_id)
+ if (! message->thread_id)
message->thread_id =
_notmuch_message_get_term (message, i, end, thread_prefix);
/* Get tags */
assert (strcmp (thread_prefix, tag_prefix) < 0);
- if (!message->tag_list) {
+ if (! message->tag_list) {
message->tag_list =
_notmuch_database_get_terms_with_prefix (message, i, end,
tag_prefix);
/* Get id */
assert (strcmp (tag_prefix, id_prefix) < 0);
- if (!message->message_id)
+ if (! message->message_id)
message->message_id =
_notmuch_message_get_term (message, i, end, id_prefix);
* expand them to full file names when needed in
* _notmuch_message_ensure_filename_list. */
assert (strcmp (type_prefix, filename_prefix) < 0);
- if (!message->filename_term_list && !message->filename_list)
+ if (! message->filename_term_list && ! message->filename_list)
message->filename_term_list =
_notmuch_database_get_terms_with_prefix (message, i, end,
filename_prefix);
/* Get property terms. Mimic the setup with filenames above */
assert (strcmp (filename_prefix, property_prefix) < 0);
- if (!message->property_map && !message->property_term_list)
+ if (! message->property_map && ! message->property_term_list)
message->property_term_list =
_notmuch_database_get_terms_with_prefix (message, i, end,
- property_prefix);
+ property_prefix);
/* get references */
assert (strcmp (property_prefix, reference_prefix) < 0);
- if (!message->reference_list) {
+ if (! message->reference_list) {
message->reference_list =
_notmuch_database_get_terms_with_prefix (message, i, end,
reference_prefix);
/* Get reply to */
assert (strcmp (property_prefix, replyto_prefix) < 0);
- if (!message->in_reply_to)
+ if (! message->in_reply_to)
message->in_reply_to =
_notmuch_message_get_term (message, i, end, replyto_prefix);
/* It's perfectly valid for a message to have no In-Reply-To
* header. For these cases, we return an empty string. */
- if (!message->in_reply_to)
+ if (! message->in_reply_to)
message->in_reply_to = talloc_strdup (message, "");
/* all the way without an exception */
notmuch_status_to_string (status));
} catch (const Xapian::Error &error) {
INTERNAL_ERROR ("A Xapian exception occurred fetching message metadata: %s\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
}
}
message->last_view = message->notmuch->view;
notmuch_message_get_message_id (notmuch_message_t *message)
{
_notmuch_message_ensure_metadata (message, message->message_id);
- if (!message->message_id)
+ if (! message->message_id)
INTERNAL_ERROR ("Message with document ID of %u has no message ID.\n",
message->doc_id);
return message->message_id;
* it could just mean we didn't record the header. */
if ((message->notmuch->features &
NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES) ||
- ! value.empty())
+ ! value.empty ())
return talloc_strdup (message, value.c_str ());
} catch (Xapian::Error &error) {
- _notmuch_database_log(notmuch_message_get_database (message), "A Xapian exception occurred when reading header: %s\n",
- error.get_msg().c_str());
+ _notmuch_database_log (notmuch_message_get_database (message), "A Xapian exception occurred when reading header: %s\n",
+ error.get_msg ().c_str ());
message->notmuch->exception_reported = true;
return NULL;
}
notmuch_message_get_thread_id (notmuch_message_t *message)
{
_notmuch_message_ensure_metadata (message, message->thread_id);
- if (!message->thread_id)
+ if (! message->thread_id)
INTERNAL_ERROR ("Message with document ID of %u has no thread ID.\n",
message->doc_id);
return message->thread_id;
}
size_t
-_notmuch_message_get_thread_depth (notmuch_message_t *message) {
+_notmuch_message_get_thread_depth (notmuch_message_t *message)
+{
return message->thread_depth;
}
notmuch_messages_valid (messages);
notmuch_messages_move_to_next (messages)) {
notmuch_message_t *child = notmuch_messages_get (messages);
- _notmuch_message_label_depths (child, depth+1);
+ _notmuch_message_label_depths (child, depth + 1);
}
}
type_prefix = _find_prefix ("type");
/* Make sure we have the data to restore to Xapian*/
- _notmuch_message_ensure_metadata (message,NULL);
+ _notmuch_message_ensure_metadata (message, NULL);
/* Empirically, it turns out to be faster to remove all the terms,
* and add back the ones we want. */
STRNCMP_LITERAL (tag, "signed") != 0 &&
STRNCMP_LITERAL (tag, "attachment") != 0) {
std::string term = tag_prefix + tag;
- message->doc.add_term(term);
+ message->doc.add_term (term);
}
}
for (list = notmuch_message_get_properties (message, "", false);
notmuch_message_properties_valid (list); notmuch_message_properties_move_to_next (list)) {
std::string term = property_prefix +
- notmuch_message_properties_key(list) + "=" +
- notmuch_message_properties_value(list);
+ notmuch_message_properties_key (list) + "=" +
+ notmuch_message_properties_value (list);
- message->doc.add_term(term);
+ message->doc.add_term (term);
}
notmuch_message_properties_destroy (list);
/* Return true if p points at "new" or "cur". */
-static bool is_maildir (const char *p)
+static bool
+is_maildir (const char *p)
{
return strcmp (p, "cur") == 0 || strcmp (p, "new") == 0;
}
status = _notmuch_database_filename_to_direntry (
local, message->notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry);
- if (status || !direntry)
+ if (status || ! direntry)
return status;
/* Unlink this file from its parent directory. */
message->filename_list = _notmuch_string_list_create (message);
node = message->filename_term_list->head;
- if (!node) {
+ if (! node) {
/* A message document created by an old version of notmuch
* (prior to rename support) will have the filename in the
* data of the document rather than as a file-direntry term.
return NULL;
if (message->filename_list->head == NULL ||
- message->filename_list->head->string == NULL)
- {
+ message->filename_list->head->string == NULL) {
INTERNAL_ERROR ("message with no filename");
}
try {
value = message->doc.get_value (NOTMUCH_VALUE_TIMESTAMP);
} catch (Xapian::Error &error) {
- _notmuch_database_log(notmuch_message_get_database (message), "A Xapian exception occurred when reading date: %s\n",
- error.get_msg().c_str());
+ _notmuch_database_log (notmuch_message_get_database (message), "A Xapian exception occurred when reading date: %s\n",
+ error.get_msg ().c_str ());
message->notmuch->exception_reported = true;
return 0;
}
* possible to modify the message tags (which talloc_unlink's the
* current list from the message) while still iterating because
* the iterator will keep the current list alive. */
- if (!talloc_reference (message, message->tag_list))
+ if (! talloc_reference (message, message->tag_list))
return NULL;
return tags;
void
_notmuch_message_set_author (notmuch_message_t *message,
- const char *author)
+ const char *author)
{
if (message->author)
- talloc_free(message->author);
- message->author = talloc_strdup(message, author);
+ talloc_free (message->author);
+ message->author = talloc_strdup (message, author);
return;
}
_notmuch_message_sync (ghost);
} else if (private_status == NOTMUCH_PRIVATE_STATUS_SUCCESS) {
/* this is deeply weird, and we should not have gotten
- into this state. is there a better error message to
- return here? */
+ * into this state. is there a better error message to
+ * return here? */
status = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
}
message = notmuch_messages_get (messages);
status = _notmuch_message_delete (message);
if (status) /* we'll report the last failure we see;
- * if there is more than one failure, we
- * forget about previous ones */
+ * if there is more than one failure, we
+ * forget about previous ones */
last_error = status;
notmuch_message_destroy (message);
notmuch_messages_move_to_next (messages);
Xapian::TermIterator i = message->doc.termlist_begin ();
i.skip_to (term);
if (i != message->doc.termlist_end () &&
- !strcmp ((*i).c_str (), term))
+ ! strcmp ((*i).c_str (), term))
out = true;
} catch (Xapian::Error &error) {
status = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
dir = slash + 1;
if (STRNCMP_LITERAL (dir, "cur/") == 0 ||
- STRNCMP_LITERAL (dir, "new/") == 0)
- {
+ STRNCMP_LITERAL (dir, "new/") == 0) {
return dir;
}
for (filenames = notmuch_message_get_filenames (message);
notmuch_filenames_valid (filenames);
- notmuch_filenames_move_to_next (filenames))
- {
+ notmuch_filenames_move_to_next (filenames)) {
filename = notmuch_filenames_get (filenames);
dir = _filename_is_in_maildir (filename);
if (status)
return status;
- for (i = 0; i < ARRAY_SIZE(flag2tag); i++) {
+ for (i = 0; i < ARRAY_SIZE (flag2tag); i++) {
if ((strchr (message->maildir_flags, flag2tag[i].flag) != NULL)
^
- flag2tag[i].inverse)
- {
+ flag2tag[i].inverse) {
status = notmuch_message_add_tag (message, flag2tag[i].tag);
} else {
status = notmuch_message_remove_tag (message, flag2tag[i].tag);
/* First, find flags for all set tags. */
for (tags = notmuch_message_get_tags (message);
notmuch_tags_valid (tags);
- notmuch_tags_move_to_next (tags))
- {
+ notmuch_tags_move_to_next (tags)) {
tag = notmuch_tags_get (tags);
for (i = 0; i < ARRAY_SIZE (flag2tag); i++) {
* non-ASCII ordering of flags), this function will return NULL
* (meaning that renaming would not be safe and should not occur).
*/
-static char*
+static char *
_new_maildir_filename (void *ctx,
const char *filename,
const char *flags_to_set,
info = strstr (filename, ":2,");
if (info == NULL) {
- info = filename + strlen(filename);
+ info = filename + strlen (filename);
} else {
/* Loop through existing flags in filename. */
for (flags = info + 3, last_flag = 0;
*flags;
- last_flag = flag, flags++)
- {
+ last_flag = flag, flags++) {
flag = *flags;
/* Original flags not in ASCII order. Abort. */
return NULL;
/* Non-ASCII flag. Abort. */
- if (flag > sizeof(flag_map) - 1)
+ if (flag > sizeof (flag_map) - 1)
return NULL;
/* Repeated flag value. Abort. */
/* Messages in new/ without maildir info can be kept in new/ if no
* flags have changed. */
dir = (char *) _filename_is_in_maildir (filename);
- if (dir && STRNCMP_LITERAL (dir, "new/") == 0 && !*info && !flags_changed)
+ if (dir && STRNCMP_LITERAL (dir, "new/") == 0 && ! *info && ! flags_changed)
return talloc_strdup (ctx, filename);
filename_new = (char *) talloc_size (ctx,
strcat (filename_new, ":2,");
s = filename_new + strlen (filename_new);
- for (i = 0; i < sizeof (flag_map); i++)
- {
+ for (i = 0; i < sizeof (flag_map); i++) {
if (flag_map[i]) {
*s = i;
s++;
for (filenames = notmuch_message_get_filenames (message);
notmuch_filenames_valid (filenames);
- notmuch_filenames_move_to_next (filenames))
- {
+ notmuch_filenames_move_to_next (filenames)) {
filename = notmuch_filenames_get (filenames);
if (! _filename_is_in_maildir (filename))
for (tags = notmuch_message_get_tags (message);
notmuch_tags_valid (tags);
- notmuch_tags_move_to_next (tags))
- {
+ notmuch_tags_move_to_next (tags)) {
tag = notmuch_tags_get (tags);
private_status = _notmuch_message_remove_term (message, "tag", tag);
const char *key;
char *value;
- value = strchr(node->string, '=');
- if (!value)
+ value = strchr (node->string, '=');
+ if (! value)
INTERNAL_ERROR ("malformed property term");
*value = '\0';
/* Save in case we need to delete message */
orig_thread_id = notmuch_message_get_thread_id (message);
- if (!orig_thread_id) {
+ if (! orig_thread_id) {
/* XXX TODO: make up new error return? */
INTERNAL_ERROR ("message without thread-id");
}
private_status = _notmuch_message_remove_indexed_terms (message);
if (private_status) {
- ret = COERCE_STATUS(private_status, "error removing terms");
+ ret = COERCE_STATUS (private_status, "error removing terms");
goto DONE;
}
_notmuch_message_sync (message);
}
- DONE:
+ DONE:
if (message_file)
_notmuch_message_file_close (message_file);
return false;
if (! messages->is_of_list_type)
- INTERNAL_ERROR("_notmuch_messages_has_next not implimented for msets");
+ INTERNAL_ERROR ("_notmuch_messages_has_next not implemented for msets");
return (messages->iterator->next != NULL);
}
keys = g_hash_table_get_keys (htable);
for (l = keys; l; l = l->next) {
- _notmuch_string_list_append (tags, (char *)l->data);
+ _notmuch_string_list_append (tags, (char *) l->data);
}
g_list_free (keys);
#include "error_util.h"
#include "string-util.h"
#include "crypto.h"
+#include "repair.h"
#ifdef DEBUG
# define DEBUG_DATABASE_SANITY 1
# define DEBUG_QUERY 1
#endif
-#define COMPILE_TIME_ASSERT(pred) ((void)sizeof(char[1 - 2*!(pred)]))
+#define COMPILE_TIME_ASSERT(pred) ((void) sizeof (char[1 - 2 * ! (pred)]))
#define STRNCMP_LITERAL(var, literal) \
strncmp ((var), (literal), sizeof (literal) - 1)
#define _NOTMUCH_VALID_BIT(bit) \
((bit) >= 0 && ((unsigned long) bit) < CHAR_BIT * sizeof (unsigned long long))
#define NOTMUCH_TEST_BIT(val, bit) \
- (_NOTMUCH_VALID_BIT(bit) ? !!((val) & (1ull << (bit))) : 0)
+ (_NOTMUCH_VALID_BIT (bit) ? ! ! ((val) & (1ull << (bit))) : 0)
#define NOTMUCH_SET_BIT(valp, bit) \
- (_NOTMUCH_VALID_BIT(bit) ? (*(valp) |= (1ull << (bit))) : *(valp))
+ (_NOTMUCH_VALID_BIT (bit) ? (*(valp) |= (1ull << (bit))) : *(valp))
#define NOTMUCH_CLEAR_BIT(valp, bit) \
- (_NOTMUCH_VALID_BIT(bit) ? (*(valp) &= ~(1ull << (bit))) : *(valp))
+ (_NOTMUCH_VALID_BIT (bit) ? (*(valp) &= ~(1ull << (bit))) : *(valp))
#define unused(x) x __attribute__ ((unused))
/* these macros gain us a few percent of speed on gcc */
#if (__GNUC__ >= 3)
/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
- as its first argument */
+ * as its first argument */
#ifndef likely
-#define likely(x) __builtin_expect(!!(x), 1)
+#define likely(x) __builtin_expect (! ! (x), 1)
#endif
#ifndef unlikely
-#define unlikely(x) __builtin_expect(!!(x), 0)
+#define unlikely(x) __builtin_expect (! ! (x), 0)
#endif
#else
#ifndef likely
typedef enum _notmuch_private_status {
/* First, copy all the public status values. */
- NOTMUCH_PRIVATE_STATUS_SUCCESS = NOTMUCH_STATUS_SUCCESS,
- NOTMUCH_PRIVATE_STATUS_OUT_OF_MEMORY = NOTMUCH_STATUS_OUT_OF_MEMORY,
- NOTMUCH_PRIVATE_STATUS_READ_ONLY_DATABASE = NOTMUCH_STATUS_READ_ONLY_DATABASE,
- NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION = NOTMUCH_STATUS_XAPIAN_EXCEPTION,
- NOTMUCH_PRIVATE_STATUS_FILE_NOT_EMAIL = NOTMUCH_STATUS_FILE_NOT_EMAIL,
- NOTMUCH_PRIVATE_STATUS_NULL_POINTER = NOTMUCH_STATUS_NULL_POINTER,
- NOTMUCH_PRIVATE_STATUS_TAG_TOO_LONG = NOTMUCH_STATUS_TAG_TOO_LONG,
- NOTMUCH_PRIVATE_STATUS_UNBALANCED_FREEZE_THAW = NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW,
+ NOTMUCH_PRIVATE_STATUS_SUCCESS = NOTMUCH_STATUS_SUCCESS,
+ NOTMUCH_PRIVATE_STATUS_OUT_OF_MEMORY = NOTMUCH_STATUS_OUT_OF_MEMORY,
+ NOTMUCH_PRIVATE_STATUS_READ_ONLY_DATABASE = NOTMUCH_STATUS_READ_ONLY_DATABASE,
+ NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION = NOTMUCH_STATUS_XAPIAN_EXCEPTION,
+ NOTMUCH_PRIVATE_STATUS_FILE_NOT_EMAIL = NOTMUCH_STATUS_FILE_NOT_EMAIL,
+ NOTMUCH_PRIVATE_STATUS_NULL_POINTER = NOTMUCH_STATUS_NULL_POINTER,
+ NOTMUCH_PRIVATE_STATUS_TAG_TOO_LONG = NOTMUCH_STATUS_TAG_TOO_LONG,
+ NOTMUCH_PRIVATE_STATUS_UNBALANCED_FREEZE_THAW = NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW,
/* Then add our own private values. */
- NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG = NOTMUCH_STATUS_LAST_STATUS,
+ NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG = NOTMUCH_STATUS_LAST_STATUS,
NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND,
NOTMUCH_PRIVATE_STATUS_BAD_PREFIX,
* Note that the function _internal_error does not return. Evaluating
* to NOTMUCH_STATUS_SUCCESS is done purely to appease the compiler.
*/
-#define COERCE_STATUS(private_status, format, ...) \
- ((private_status >= (notmuch_private_status_t) NOTMUCH_STATUS_LAST_STATUS)\
- ? \
- _internal_error (format " (%s).\n", \
- ##__VA_ARGS__, \
- __location__), \
- (notmuch_status_t) NOTMUCH_PRIVATE_STATUS_SUCCESS \
- : \
+#define COERCE_STATUS(private_status, format, ...) \
+ ((private_status >= (notmuch_private_status_t) NOTMUCH_STATUS_LAST_STATUS) \
+ ? \
+ _internal_error (format " (%s).\n", \
+ ##__VA_ARGS__, \
+ __location__), \
+ (notmuch_status_t) NOTMUCH_PRIVATE_STATUS_SUCCESS \
+ : \
(notmuch_status_t) private_status)
/* Flags shared by various lookup functions. */
NOTMUCH_FIND_LOOKUP = 0,
/* If set, create the necessary document (or documents) if they
* are missing. Requires a read/write database. */
- NOTMUCH_FIND_CREATE = 1<<0,
+ NOTMUCH_FIND_CREATE = 1 << 0,
} notmuch_find_flags_t;
typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
/* Lookup a prefix value by name, including possibly user defined prefixes
*/
const char *
-_notmuch_database_prefix (notmuch_database_t *notmuch, const char *name);
+_notmuch_database_prefix (notmuch_database_t *notmuch, const char *name);
char *
_notmuch_message_id_compressed (void *ctx, const char *message_id);
*/
const char *
_notmuch_message_file_get_header (notmuch_message_file_t *message,
- const char *header);
+ const char *header);
notmuch_status_t
_notmuch_message_file_get_headers (notmuch_message_file_t *message_file,
_notmuch_message_remove_unprefixed_terms (notmuch_message_t *message);
const char *
-_notmuch_message_get_thread_id_only(notmuch_message_t *message);
+_notmuch_message_get_thread_id_only (notmuch_message_t *message);
size_t _notmuch_message_get_thread_depth (notmuch_message_t *message);
_notmuch_string_list_sort (notmuch_string_list_t *list);
const notmuch_string_list_t *
-_notmuch_message_get_references(notmuch_message_t *message);
+_notmuch_message_get_references (notmuch_message_t *message);
/* string-map.c */
-typedef struct _notmuch_string_map notmuch_string_map_t;
+typedef struct _notmuch_string_map notmuch_string_map_t;
typedef struct _notmuch_string_map_iterator notmuch_string_map_iterator_t;
notmuch_string_map_t *
_notmuch_string_map_create (const void *ctx);
* template function for this to maintain type safety, and redefine
* talloc_steal to use it.
*/
-#if !(__GNUC__ >= 3)
+#if ! (__GNUC__ >= 3)
template <class T> T *
_notmuch_talloc_steal (const void *new_ctx, const T *ptr)
{
* The library version number. This must agree with the soname
* version in Makefile.local.
*/
-#define LIBNOTMUCH_MAJOR_VERSION 5
-#define LIBNOTMUCH_MINOR_VERSION 2
-#define LIBNOTMUCH_MICRO_VERSION 0
+#define LIBNOTMUCH_MAJOR_VERSION 5
+#define LIBNOTMUCH_MINOR_VERSION 2
+#define LIBNOTMUCH_MICRO_VERSION 0
#if defined (__clang_major__) && __clang_major__ >= 3 \
|| defined (__GNUC__) && __GNUC__ >= 5 \
|| defined (__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 5
-#define NOTMUCH_DEPRECATED(major,minor) \
+#define NOTMUCH_DEPRECATED(major, minor) \
__attribute__ ((deprecated ("function deprecated as of libnotmuch " #major "." #minor)))
#else
-#define NOTMUCH_DEPRECATED(major,minor) __attribute__ ((deprecated))
+#define NOTMUCH_DEPRECATED(major, minor) __attribute__ ((deprecated))
#endif
* #endif
* @endcode
*/
-#define LIBNOTMUCH_CHECK_VERSION(major, minor, micro) \
- (LIBNOTMUCH_MAJOR_VERSION > (major) || \
+#define LIBNOTMUCH_CHECK_VERSION(major, minor, micro) \
+ (LIBNOTMUCH_MAJOR_VERSION > (major) || \
(LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION > (minor)) || \
(LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION == (minor) && \
LIBNOTMUCH_MICRO_VERSION >= (micro)))
* 'closure' is passed verbatim to any callback invoked.
*/
notmuch_status_t
-notmuch_database_compact (const char* path,
- const char* backup_path,
+notmuch_database_compact (const char *path,
+ const char *backup_path,
notmuch_compact_status_cb_t status_cb,
void *closure);
*/
notmuch_status_t
notmuch_database_upgrade (notmuch_database_t *database,
- void (*progress_notify) (void *closure,
- double progress),
+ void (*progress_notify)(void *closure,
+ double progress),
void *closure);
/**
*/
unsigned long
notmuch_database_get_revision (notmuch_database_t *notmuch,
- const char **uuid);
+ const char **uuid);
/**
* Retrieve a directory object from the database for 'path'.
* directory not retrieved.
*
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
- * database to use this function.
+ * database to use this function.
*/
notmuch_status_t
notmuch_database_get_directory (notmuch_database_t *database,
* mode so no message can be added.
*
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
- * database to use this function.
+ * database to use this function.
*
* @since libnotmuch 5.1 (notmuch 0.26)
*/
* use notmuch_database_index_file instead.
*
*/
-NOTMUCH_DEPRECATED(5,1)
+NOTMUCH_DEPRECATED (5, 1)
notmuch_status_t
notmuch_database_add_message (notmuch_database_t *database,
const char *filename,
* mode so no message can be removed.
*
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
- * database to use this function.
+ * database to use this function.
*/
notmuch_status_t
notmuch_database_remove_message (notmuch_database_t *database,
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
*
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
- * database to use this function.
+ * database to use this function.
*/
notmuch_status_t
notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
* use notmuch_query_search_threads instead.
*
*/
-NOTMUCH_DEPRECATED(5,0)
+NOTMUCH_DEPRECATED (5, 0)
notmuch_status_t
notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out);
*
*/
-NOTMUCH_DEPRECATED(5,0)
+NOTMUCH_DEPRECATED (5, 0)
notmuch_status_t
notmuch_query_search_messages_st (notmuch_query_t *query,
notmuch_messages_t **out);
* @deprecated Deprecated since libnotmuch 5.0 (notmuch 0.25). Please
* use notmuch_query_count_messages instead.
*/
-NOTMUCH_DEPRECATED(5,0)
+NOTMUCH_DEPRECATED (5, 0)
notmuch_status_t
notmuch_query_count_messages_st (notmuch_query_t *query, unsigned int *count);
*
* NOTMUCH_STATUS_OUT_OF_MEMORY: Memory allocation failed. The value
* of *count is not defined
-
+ *
* NOTMUCH_STATUS_SUCCESS: query completed successfully.
*
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occurred. The
* @deprecated Deprecated as of libnotmuch 5.0 (notmuch 0.25). Please
* use notmuch_query_count_threads_st instead.
*/
-NOTMUCH_DEPRECATED(5,0)
+NOTMUCH_DEPRECATED (5, 0)
notmuch_status_t
notmuch_query_count_threads_st (notmuch_query_t *query, unsigned *count);
* "date".
*/
time_t
-notmuch_message_get_date (notmuch_message_t *message);
+notmuch_message_get_date (notmuch_message_t *message);
/**
* Get the value of the specified header from 'message' as a UTF-8 string.
if (time (&now) == (time_t) -1)
return Xapian::BAD_VALUENO;
- if (!begin.empty ()) {
+ if (! begin.empty ()) {
if (parse_time_string (begin.c_str (), &t, &now, PARSE_TIME_ROUND_DOWN))
return Xapian::BAD_VALUENO;
begin.assign (Xapian::sortable_serialise ((double) t));
}
- if (!end.empty ()) {
+ if (! end.empty ()) {
if (end == "!" && ! b.empty ())
end = b;
#if HAVE_XAPIAN_FIELD_PROCESSOR
/* XXX TODO: is throwing an exception the right thing to do here? */
-Xapian::Query DateFieldProcessor::operator()(const std::string & str) {
+Xapian::Query
+DateFieldProcessor::operator() (const std::string & str)
+{
time_t from, to, now;
/* Use the same 'now' for begin and end. */
if (time (&now) == (time_t) -1)
- throw Xapian::QueryParserError("Unable to get current time");
+ throw Xapian::QueryParserError ("Unable to get current time");
if (parse_time_string (str.c_str (), &from, &now, PARSE_TIME_ROUND_DOWN))
throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'");
if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE))
throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'");
- return Xapian::Query(Xapian::Query::OP_AND,
- Xapian::Query(Xapian::Query::OP_VALUE_GE, 0, Xapian::sortable_serialise ((double) from)),
- Xapian::Query(Xapian::Query::OP_VALUE_LE, 0, Xapian::sortable_serialise ((double) to)));
+ return Xapian::Query (Xapian::Query::OP_AND,
+ Xapian::Query (Xapian::Query::OP_VALUE_GE, 0, Xapian::sortable_serialise ((double) from)),
+ Xapian::Query (Xapian::Query::OP_VALUE_LE, 0, Xapian::sortable_serialise ((double) to)));
}
#endif
public:
ParseTimeValueRangeProcessor (Xapian::valueno slot_)
- : valno(slot_) { }
+ : valno (slot_)
+ {
+ }
Xapian::valueno operator() (std::string &begin, std::string &end);
};
#if HAVE_XAPIAN_FIELD_PROCESSOR
class DateFieldProcessor : public Xapian::FieldProcessor {
- Xapian::Query operator()(const std::string & str);
+ Xapian::Query operator() (const std::string & str);
};
#endif
#endif /* NOTMUCH_PARSE_TIME_VRP_H */
#if HAVE_XAPIAN_FIELD_PROCESSOR
class QueryFieldProcessor : public Xapian::FieldProcessor {
- protected:
+protected:
Xapian::QueryParser &parser;
notmuch_database_t *notmuch;
- public:
+public:
QueryFieldProcessor (Xapian::QueryParser &parser_, notmuch_database_t *notmuch_)
- : parser(parser_), notmuch(notmuch_) { };
+ : parser (parser_), notmuch (notmuch_)
+ {
+ };
- Xapian::Query operator()(const std::string & str);
+ Xapian::Query operator() (const std::string & str);
};
#endif
#endif /* NOTMUCH_QUERY_FP_H */
_debug_query (void)
{
char *env = getenv ("NOTMUCH_DEBUG_QUERY");
+
return (env && strcmp (env, "") != 0);
}
/* Explicit destructor call for placement new */
static int
-_notmuch_query_destructor (notmuch_query_t *query) {
+_notmuch_query_destructor (notmuch_query_t *query)
+{
query->xapian_query.~Query();
query->terms.~set<std::string>();
return 0;
try {
query->xapian_query =
query->notmuch->query_parser->
- parse_query (query->query_string, NOTMUCH_QUERY_PARSER_FLAGS);
+ parse_query (query->query_string, NOTMUCH_QUERY_PARSER_FLAGS);
- /* Xapian doesn't support skip_to on terms from a query since
- * they are unordered, so cache a copy of all terms in
- * something searchable.
- */
+ /* Xapian doesn't support skip_to on terms from a query since
+ * they are unordered, so cache a copy of all terms in
+ * something searchable.
+ */
for (Xapian::TermIterator t = query->xapian_query.get_terms_begin ();
t != query->xapian_query.get_terms_end (); ++t)
query->parsed = true;
} catch (const Xapian::Error &error) {
- if (!query->notmuch->exception_reported) {
+ if (! query->notmuch->exception_reported) {
_notmuch_database_log (query->notmuch,
"A Xapian exception occurred parsing query: %s\n",
error.get_msg ().c_str ());
return status;
term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag);
- if (query->terms.count(term) != 0)
+ if (query->terms.count (term) != 0)
return NOTMUCH_STATUS_IGNORED;
_notmuch_string_list_append (query->exclude_terms, term);
notmuch_status_t
notmuch_query_search_messages (notmuch_query_t *query,
- notmuch_messages_t **out)
+ notmuch_messages_t **out)
{
return _notmuch_query_search_documents (query, "mail", out);
}
Xapian::MSetIterator iterator;
if (strcmp (query_string, "") == 0 ||
- strcmp (query_string, "*") == 0)
- {
+ strcmp (query_string, "*") == 0) {
final_query = mail_query;
} else {
final_query = Xapian::Query (Xapian::Query::OP_AND,
exclude_query = _notmuch_exclude_tags (query);
if (query->omit_excluded == NOTMUCH_EXCLUDE_TRUE ||
- query->omit_excluded == NOTMUCH_EXCLUDE_ALL)
- {
+ query->omit_excluded == NOTMUCH_EXCLUDE_ALL) {
final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
final_query, exclude_query);
} else { /* NOTMUCH_EXCLUDE_FLAG */
exclude_query = Xapian::Query (Xapian::Query::OP_AND,
- exclude_query, final_query);
+ exclude_query, final_query);
- enquire.set_weighting_scheme (Xapian::BoolWeight());
+ enquire.set_weighting_scheme (Xapian::BoolWeight ());
enquire.set_query (exclude_query);
mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ());
}
- enquire.set_weighting_scheme (Xapian::BoolWeight());
+ enquire.set_weighting_scheme (Xapian::BoolWeight ());
switch (query->sort) {
case NOTMUCH_SORT_OLDEST_FIRST:
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch,
"A Xapian exception occurred performing query: %s\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
_notmuch_database_log_append (notmuch,
- "Query string was: %s\n",
- query->query_string);
+ "Query string was: %s\n",
+ query->query_string);
notmuch->exception_reported = true;
talloc_free (messages);
&status);
if (message == NULL &&
- status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND)
- {
+ status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n");
}
unsigned char *bitmap;
for (unsigned int i = 0; i < arr->len; i++)
- max = MAX(max, g_array_index (arr, unsigned int, i));
- bitmap = talloc_zero_array (ctx, unsigned char, DOCIDSET_WORD(max) + 1);
+ max = MAX (max, g_array_index (arr, unsigned int, i));
+ bitmap = talloc_zero_array (ctx, unsigned char, DOCIDSET_WORD (max) + 1);
if (bitmap == NULL)
return false;
for (unsigned int i = 0; i < arr->len; i++) {
unsigned int doc_id = g_array_index (arr, unsigned int, i);
- bitmap[DOCIDSET_WORD(doc_id)] |= 1 << DOCIDSET_BIT(doc_id);
+ bitmap[DOCIDSET_WORD (doc_id)] |= 1 << DOCIDSET_BIT (doc_id);
}
return true;
{
if (doc_id >= doc_ids->bound)
return false;
- return doc_ids->bitmap[DOCIDSET_WORD(doc_id)] & (1 << DOCIDSET_BIT(doc_id));
+ return doc_ids->bitmap[DOCIDSET_WORD (doc_id)] & (1 << DOCIDSET_BIT (doc_id));
}
void
unsigned int doc_id)
{
if (doc_id < doc_ids->bound)
- doc_ids->bitmap[DOCIDSET_WORD(doc_id)] &= ~(1 << DOCIDSET_BIT(doc_id));
+ doc_ids->bitmap[DOCIDSET_WORD (doc_id)] &= ~(1 << DOCIDSET_BIT (doc_id));
}
/* Glib objects force use to use a talloc destructor as well, (but not
notmuch_status_t
notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out)
{
- return notmuch_query_search_threads(query, out);
+ return notmuch_query_search_threads (query, out);
}
notmuch_status_t
Xapian::MSet mset;
if (strcmp (query_string, "") == 0 ||
- strcmp (query_string, "*") == 0)
- {
+ strcmp (query_string, "*") == 0) {
final_query = mail_query;
} else {
final_query = Xapian::Query (Xapian::Query::OP_AND,
exclude_query = _notmuch_exclude_tags (query);
final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
- final_query, exclude_query);
+ final_query, exclude_query);
- enquire.set_weighting_scheme(Xapian::BoolWeight());
- enquire.set_docid_order(Xapian::Enquire::ASCENDING);
+ enquire.set_weighting_scheme (Xapian::BoolWeight ());
+ enquire.set_docid_order (Xapian::Enquire::ASCENDING);
if (_debug_query ()) {
fprintf (stderr, "Exclude query is:\n%s\n",
mset = enquire.get_mset (0, 1,
notmuch->xapian_db->get_doccount ());
- count = mset.get_matches_estimated();
+ count = mset.get_matches_estimated ();
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch,
"A Xapian exception occurred performing query: %s\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
_notmuch_database_log_append (notmuch,
"Query string was: %s\n",
query->query_string);
RegexpPostingSource::check (Xapian::docid did, unused (double min_wt))
{
started_ = true;
- if (!it_.check (did) || at_end ())
+ if (! it_.check (did) || at_end ())
return false;
return (regexec (®exp_, (*it_).c_str (), 0, NULL, 0) == 0);
}
-static inline Xapian::valueno _find_slot (std::string prefix)
+static inline Xapian::valueno
+_find_slot (std::string prefix)
{
if (prefix == "from")
return NOTMUCH_VALUE_FROM;
notmuch_field_flag_t options_,
Xapian::QueryParser &parser_,
notmuch_database_t *notmuch_)
- : slot (_find_slot (prefix)),
- term_prefix (_find_prefix (prefix.c_str ())),
- options (options_),
- parser (parser_),
- notmuch (notmuch_)
+ : slot (_find_slot (prefix)),
+ term_prefix (_find_prefix (prefix.c_str ())),
+ options (options_),
+ parser (parser_),
+ notmuch (notmuch_)
{
};
{
if (str.empty ()) {
if (options & NOTMUCH_FIELD_PROBABILISTIC) {
- return Xapian::Query(Xapian::Query::OP_AND_NOT,
- Xapian::Query::MatchAll,
- Xapian::Query (Xapian::Query::OP_WILDCARD, term_prefix));
+ return Xapian::Query (Xapian::Query::OP_AND_NOT,
+ Xapian::Query::MatchAll,
+ Xapian::Query (Xapian::Query::OP_WILDCARD, term_prefix));
} else {
return Xapian::Query (term_prefix);
}
}
if (str.at (0) == '/') {
- if (str.length() > 1 && str.at (str.size () - 1) == '/'){
- std::string regexp_str = str.substr(1,str.size () - 2);
+ if (str.length () > 1 && str.at (str.size () - 1) == '/') {
+ std::string regexp_str = str.substr (1, str.size () - 2);
if (slot != Xapian::BAD_VALUENO) {
RegexpPostingSource *postings = new RegexpPostingSource (slot, regexp_str);
return Xapian::Query (postings->release ());
std::vector<std::string> terms;
regex_t regexp;
- compile_regex(regexp, regexp_str.c_str ());
+ compile_regex (regexp, regexp_str.c_str ());
for (Xapian::TermIterator it = notmuch->xapian_db->allterms_begin (term_prefix);
it != notmuch->xapian_db->allterms_end (); ++it) {
- if (regexec (®exp, (*it).c_str () + term_prefix.size(),
+ if (regexec (®exp, (*it).c_str () + term_prefix.size (),
0, NULL, 0) == 0)
- terms.push_back(*it);
+ terms.push_back (*it);
}
- return Xapian::Query (Xapian::Query::OP_OR, terms.begin(), terms.end());
+ return Xapian::Query (Xapian::Query::OP_OR, terms.begin (), terms.end ());
}
} else {
throw Xapian::QueryParserError ("unmatched regex delimiter in '" + str + "'");
*/
class RegexpPostingSource : public Xapian::PostingSource
{
- protected:
+protected:
const Xapian::valueno slot_;
regex_t regexp_;
Xapian::Database db_;
RegexpPostingSource (const RegexpPostingSource &);
RegexpPostingSource &operator= (const RegexpPostingSource &);
- public:
+public:
RegexpPostingSource (Xapian::valueno slot, const std::string ®exp);
~RegexpPostingSource ();
void init (const Xapian::Database &db);
class RegexpFieldProcessor : public Xapian::FieldProcessor {
- protected:
+protected:
Xapian::valueno slot;
std::string term_prefix;
notmuch_field_flag_t options;
Xapian::QueryParser &parser;
notmuch_database_t *notmuch;
- public:
+public:
RegexpFieldProcessor (std::string prefix, notmuch_field_flag_t options,
Xapian::QueryParser &parser_, notmuch_database_t *notmuch_);
- ~RegexpFieldProcessor () { };
+ ~RegexpFieldProcessor ()
+ {
+ };
- Xapian::Query operator()(const std::string & str);
+ Xapian::Query operator() (const std::string & str);
};
#endif
#endif /* NOTMUCH_REGEXP_FIELDS_H */
_notmuch_sha1_of_file (const char *filename)
{
FILE *file;
+
#define BLOCK_SIZE 4096
unsigned char block[BLOCK_SIZE];
size_t bytes_read;
static int
cmpnode (const void *pa, const void *pb)
{
- notmuch_string_node_t *a = *(notmuch_string_node_t * const *)pa;
- notmuch_string_node_t *b = *(notmuch_string_node_t * const *)pb;
+ notmuch_string_node_t *a = *(notmuch_string_node_t *const *) pa;
+ notmuch_string_node_t *b = *(notmuch_string_node_t *const *) pb;
return strcmp (a->string, b->string);
}
qsort (nodes, list->length, sizeof (*nodes), cmpnode);
for (i = 0; i < list->length - 1; ++i)
- nodes[i]->next = nodes[i+1];
+ nodes[i]->next = nodes[i + 1];
nodes[i]->next = NULL;
list->head = nodes[0];
list->tail = &nodes[i]->next;
#if HAVE_XAPIAN_FIELD_PROCESSOR
class ThreadFieldProcessor : public Xapian::FieldProcessor {
- protected:
+protected:
Xapian::QueryParser &parser;
notmuch_database_t *notmuch;
- public:
+public:
ThreadFieldProcessor (Xapian::QueryParser &parser_, notmuch_database_t *notmuch_)
- : parser(parser_), notmuch(notmuch_) { };
+ : parser (parser_), notmuch (notmuch_)
+ {
+ };
- Xapian::Query operator()(const std::string & str);
+ Xapian::Query operator() (const std::string & str);
};
#endif
#endif /* NOTMUCH_THREAD_FP_H */
#include "database-private.h"
#include <gmime/gmime.h>
-#include <glib.h> /* GHashTable */
+#include <glib.h> /* GHashTable */
#ifdef DEBUG_THREADING
-#define THREAD_DEBUG(format, ...) fprintf(stderr, format " (%s).\n", ##__VA_ARGS__, __location__)
+#define THREAD_DEBUG(format, ...) fprintf (stderr, format " (%s).\n", ##__VA_ARGS__, __location__)
#else
-#define THREAD_DEBUG(format, ...) do {} while (0) /* ignored */
+#define THREAD_DEBUG(format, ...) do {} while (0) /* ignored */
#endif
struct _notmuch_thread {
g_ptr_array_free (thread->matched_authors_array, true);
thread->matched_authors_array = NULL;
- if (!thread->authors)
- thread->authors = talloc_strdup(thread, "");
+ if (! thread->authors)
+ thread->authors = talloc_strdup (thread, "");
}
/* clean up the ugly "Lastname, Firstname" format that some mail systems
_thread_cleanup_author (notmuch_thread_t *thread,
const char *author, const char *from)
{
- char *clean_author,*test_author;
+ char *clean_author, *test_author;
const char *comma;
char *blank;
- int fname,lname;
+ int fname, lname;
if (author == NULL)
return NULL;
- clean_author = talloc_strdup(thread, author);
+ clean_author = talloc_strdup (thread, author);
if (clean_author == NULL)
return NULL;
/* check if there's a comma in the name and that there's a
* one character long ",\0").
* Otherwise just return the copy of the original author name that
* we just made*/
- comma = strchr(author,',');
- if (comma && strlen(comma) > 1) {
+ comma = strchr (author, ',');
+ if (comma && strlen (comma) > 1) {
/* let's assemble what we think is the correct name */
lname = comma - author;
/* Skip all the spaces after the comma */
- fname = strlen(author) - lname - 1;
+ fname = strlen (author) - lname - 1;
comma += 1;
while (*comma == ' ') {
fname -= 1;
comma += 1;
}
- strncpy(clean_author, comma, fname);
+ strncpy (clean_author, comma, fname);
- *(clean_author+fname) = ' ';
- strncpy(clean_author + fname + 1, author, lname);
- *(clean_author+fname+1+lname) = '\0';
+ *(clean_author + fname) = ' ';
+ strncpy (clean_author + fname + 1, author, lname);
+ *(clean_author + fname + 1 + lname) = '\0';
/* make a temporary copy and see if it matches the email */
- test_author = talloc_strdup(thread,clean_author);
+ test_author = talloc_strdup (thread, clean_author);
- blank=strchr(test_author,' ');
+ blank = strchr (test_author, ' ');
while (blank != NULL) {
*blank = '.';
- blank=strchr(test_author,' ');
+ blank = strchr (test_author, ' ');
}
- if (strcasestr(from, test_author) == NULL)
+ if (strcasestr (from, test_author) == NULL)
/* we didn't identify this as part of the email address
- * so let's punt and return the original author */
+ * so let's punt and return the original author */
strcpy (clean_author, author);
}
return clean_author;
if (omit_exclude != NOTMUCH_EXCLUDE_FALSE) {
for (tags = notmuch_message_get_tags (message);
notmuch_tags_valid (tags);
- notmuch_tags_move_to_next (tags))
- {
+ notmuch_tags_move_to_next (tags)) {
tag = notmuch_tags_get (tags);
/* Is message excluded? */
for (notmuch_string_node_t *term = exclude_terms->head;
term != NULL;
- term = term->next)
- {
+ term = term->next) {
/* Check for an empty string, and then ignore initial 'K'. */
- if (*(term->string) && strcmp(tag, (term->string + 1)) == 0) {
+ if (*(term->string) && strcmp (tag, (term->string + 1)) == 0) {
message_excluded = true;
break;
}
for (tags = notmuch_message_get_tags (message);
notmuch_tags_valid (tags);
- notmuch_tags_move_to_next (tags))
- {
+ notmuch_tags_move_to_next (tags)) {
tag = notmuch_tags_get (tags);
g_hash_table_insert (thread->tags, xstrdup (tag), NULL);
}
cleaned_subject = talloc_strndup (thread,
subject + 4,
- strlen(subject) - 4);
+ strlen (subject) - 4);
} else {
cleaned_subject = talloc_strdup (thread, subject);
}
- if (! EMPTY_STRING(cleaned_subject)) {
+ if (! EMPTY_STRING (cleaned_subject)) {
if (thread->subject)
talloc_free (thread->subject);
if (date > thread->newest || ! thread->matched_messages) {
thread->newest = date;
- const char *cur_subject = notmuch_thread_get_subject(thread);
- if (sort != NOTMUCH_SORT_OLDEST_FIRST || EMPTY_STRING(cur_subject))
+ const char *cur_subject = notmuch_thread_get_subject (thread);
+ if (sort != NOTMUCH_SORT_OLDEST_FIRST || EMPTY_STRING (cur_subject))
_thread_set_subject_from_message (thread, message);
}
- if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
+ if (! notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
thread->matched_messages++;
if (g_hash_table_lookup_extended (thread->message_hash,
- notmuch_message_get_message_id (message), NULL,
- (void **) &hashed_message)) {
+ notmuch_message_get_message_id (message), NULL,
+ (void **) &hashed_message)) {
notmuch_message_set_flag (hashed_message,
NOTMUCH_MESSAGE_FLAG_MATCH, 1);
}
}
static bool
-_parent_via_in_reply_to (notmuch_thread_t *thread, notmuch_message_t *message) {
+_parent_via_in_reply_to (notmuch_thread_t *thread, notmuch_message_t *message)
+{
notmuch_message_t *parent;
const char *in_reply_to;
in_reply_to = _notmuch_message_get_in_reply_to (message);
- THREAD_DEBUG("checking message = %s in_reply_to=%s\n",
- notmuch_message_get_message_id (message), in_reply_to);
+ THREAD_DEBUG ("checking message = %s in_reply_to=%s\n",
+ notmuch_message_get_message_id (message), in_reply_to);
- if (in_reply_to && (! EMPTY_STRING(in_reply_to)) &&
+ if (in_reply_to && (! EMPTY_STRING (in_reply_to)) &&
g_hash_table_lookup_extended (thread->message_hash,
in_reply_to, NULL,
(void **) &parent)) {
const notmuch_string_list_t *references =
_notmuch_message_get_references (message);
- THREAD_DEBUG("trying to reparent via references: %s\n",
- notmuch_message_get_message_id (message));
+ THREAD_DEBUG ("trying to reparent via references: %s\n",
+ notmuch_message_get_message_id (message));
for (notmuch_string_node_t *ref_node = references->head;
ref_node; ref_node = ref_node->next) {
- THREAD_DEBUG("checking reference=%s\n", ref_node->string);
+ THREAD_DEBUG ("checking reference=%s\n", ref_node->string);
if ((g_hash_table_lookup_extended (thread->message_hash,
ref_node->string, NULL,
(void **) &new_parent))) {
size_t new_depth = _notmuch_message_get_thread_depth (new_parent);
- THREAD_DEBUG("got depth %lu\n", new_depth);
- if (new_depth > max_depth || !parent) {
- THREAD_DEBUG("adding at depth %lu parent=%s\n", new_depth, ref_node->string);
+ THREAD_DEBUG ("got depth %lu\n", new_depth);
+ if (new_depth > max_depth || ! parent) {
+ THREAD_DEBUG ("adding at depth %lu parent=%s\n", new_depth, ref_node->string);
max_depth = new_depth;
parent = new_parent;
}
}
}
if (parent) {
- THREAD_DEBUG("adding reply %s to parent=%s\n",
- notmuch_message_get_message_id (message),
- notmuch_message_get_message_id (parent));
+ THREAD_DEBUG ("adding reply %s to parent=%s\n",
+ notmuch_message_get_message_id (message),
+ notmuch_message_get_message_id (parent));
_notmuch_message_add_reply (parent, message);
} else {
- THREAD_DEBUG("adding as toplevel %s\n",
- notmuch_message_get_message_id (message));
+ THREAD_DEBUG ("adding as toplevel %s\n",
+ notmuch_message_get_message_id (message));
_notmuch_message_list_add_message (thread->toplevel_list, message);
}
}
*/
if (first_node) {
message = first_node->message;
- THREAD_DEBUG("checking first message %s\n",
- notmuch_message_get_message_id (message));
+ THREAD_DEBUG ("checking first message %s\n",
+ notmuch_message_get_message_id (message));
- if (_notmuch_message_list_empty (maybe_toplevel_list) ||
+ if (_notmuch_message_list_empty (maybe_toplevel_list) ||
! _parent_via_in_reply_to (thread, message)) {
- THREAD_DEBUG("adding first message as toplevel = %s\n",
- notmuch_message_get_message_id (message));
+ THREAD_DEBUG ("adding first message as toplevel = %s\n",
+ notmuch_message_get_message_id (message));
_notmuch_message_list_add_message (maybe_toplevel_list, message);
}
}
for (notmuch_messages_t *messages = _notmuch_messages_create (maybe_toplevel_list);
notmuch_messages_valid (messages);
- notmuch_messages_move_to_next (messages))
- {
+ notmuch_messages_move_to_next (messages)) {
notmuch_message_t *message = notmuch_messages_get (messages);
_notmuch_message_label_depths (message, 0);
}
for (;
notmuch_messages_valid (messages);
- notmuch_messages_move_to_next (messages))
- {
+ notmuch_messages_move_to_next (messages)) {
unsigned int doc_id;
message = notmuch_messages_get (messages);
GMimeMessage *mime_message;
_notmuch_message_crypto_t *msg_crypto;
+ /* repaired/unmangled parts that will need to be cleaned up */
+ GSList *repaired_parts;
+
/* Context provided by the caller. */
_notmuch_crypto_t *crypto;
} mime_node_context_t;
if (res->stream)
g_object_unref (res->stream);
+ if (res->repaired_parts)
+ g_slist_free_full (res->repaired_parts, g_object_unref);
+
return 0;
}
-const _notmuch_message_crypto_t*
+/* keep track of objects that need to be destroyed when the mime node
+ * context goes away. */
+static void
+_mime_node_context_track_repaired_part (mime_node_context_t *ctx, GMimeObject *part)
+{
+ if (part)
+ ctx->repaired_parts = g_slist_prepend (ctx->repaired_parts, part);
+}
+
+const _notmuch_message_crypto_t *
mime_node_get_message_crypto_status (mime_node_t *node)
{
return node->ctx->msg_crypto;
notmuch_filenames_t *filenames;
for (filenames = notmuch_message_get_filenames (message);
notmuch_filenames_valid (filenames);
- notmuch_filenames_move_to_next (filenames))
- {
+ notmuch_filenames_move_to_next (filenames)) {
filename = notmuch_filenames_get (filenames);
fd = open (filename, O_RDONLY);
if (fd != -1)
if (fd == -1) {
/* Give up */
fprintf (stderr, "Error opening %s: %s\n", filename, strerror (errno));
- status = NOTMUCH_STATUS_FILE_ERROR;
- goto DONE;
- }
+ status = NOTMUCH_STATUS_FILE_ERROR;
+ goto DONE;
}
+ }
mctx->stream = g_mime_stream_gzfile_new (fd);
- if (!mctx->stream) {
+ if (! mctx->stream) {
fprintf (stderr, "Out of memory.\n");
status = NOTMUCH_STATUS_OUT_OF_MEMORY;
goto DONE;
}
mctx->parser = g_mime_parser_new_with_stream (mctx->stream);
- if (!mctx->parser) {
+ if (! mctx->parser) {
fprintf (stderr, "Out of memory.\n");
status = NOTMUCH_STATUS_OUT_OF_MEMORY;
goto DONE;
}
mctx->mime_message = g_mime_parser_construct_message (mctx->parser, NULL);
- if (!mctx->mime_message) {
+ if (! mctx->mime_message) {
fprintf (stderr, "Failed to parse %s\n", filename);
status = NOTMUCH_STATUS_FILE_ERROR;
goto DONE;
*root_out = root;
return NOTMUCH_STATUS_SUCCESS;
-DONE:
+ DONE:
talloc_free (root);
return status;
}
set_signature_list_destructor (mime_node_t *node)
{
GMimeSignatureList **proxy = talloc (node, GMimeSignatureList *);
+
if (proxy) {
*proxy = node->sig_list;
talloc_set_destructor (proxy, _signature_list_free);
notmuch_status_t status;
node->verify_attempted = true;
- node->sig_list = g_mime_multipart_signed_verify
- (GMIME_MULTIPART_SIGNED (part), GMIME_ENCRYPT_NONE, &err);
+ node->sig_list = g_mime_multipart_signed_verify (
+ GMIME_MULTIPART_SIGNED (part), GMIME_ENCRYPT_NONE, &err);
if (node->sig_list)
set_signature_list_destructor (node);
g_object_unref (decrypt_result);
}
- DONE:
+ DONE:
if (err)
g_error_free (err);
}
+static bool
+_mime_node_set_up_part (mime_node_t *node, GMimeObject *part, int numchild);
+
static mime_node_t *
_mime_node_create (mime_node_t *parent, GMimeObject *part, int numchild)
{
mime_node_t *node = talloc_zero (parent, mime_node_t);
- notmuch_status_t status;
/* Set basic node properties */
- node->part = part;
node->ctx = parent->ctx;
- if (!talloc_reference (node, node->ctx)) {
+ if (! talloc_reference (node, node->ctx)) {
fprintf (stderr, "Out of memory.\n");
talloc_free (node);
return NULL;
node->part_num = node->next_part_num = -1;
node->next_child = 0;
+ if (_mime_node_set_up_part (node, part, numchild))
+ return node;
+ talloc_free (node);
+ return NULL;
+}
+
+/* associate a MIME part with a node. */
+static bool
+_mime_node_set_up_part (mime_node_t *node, GMimeObject *part, int numchild)
+{
/* Deal with the different types of parts */
if (GMIME_IS_PART (part)) {
+ node->part = part;
node->nchildren = 0;
} else if (GMIME_IS_MULTIPART (part)) {
+ GMimeObject *repaired_part = _notmuch_repair_mixed_up_mangled (part);
+ if (repaired_part) {
+ /* This was likely "Mixed Up" in transit! We replace it
+ * with the more likely-to-be-correct variant. */
+ _mime_node_context_track_repaired_part (node->ctx, repaired_part);
+ part = repaired_part;
+ }
+ node->part = part;
node->nchildren = g_mime_multipart_get_count (GMIME_MULTIPART (part));
} else if (GMIME_IS_MESSAGE_PART (part)) {
/* Promote part to an envelope and open it */
} else {
fprintf (stderr, "Warning: Unknown mime part type: %s.\n",
g_type_name (G_OBJECT_TYPE (part)));
- talloc_free (node);
- return NULL;
+ return false;
}
- /* Handle PGP/MIME parts */
+ /* Handle PGP/MIME parts (by definition not cryptographic payload parts) */
if (GMIME_IS_MULTIPART_ENCRYPTED (part) && (node->ctx->crypto->decrypt != NOTMUCH_DECRYPT_FALSE)) {
if (node->nchildren != 2) {
/* this violates RFC 3156 section 4, so we won't bother with it. */
node_verify (node, part);
}
} else {
- status = _notmuch_message_crypto_potential_payload (node->ctx->msg_crypto, part, parent ? parent->part : NULL, numchild);
- if (status)
- fprintf (stderr, "Warning: failed to record potential crypto payload (%s).\n", notmuch_status_to_string (status));
+ if (_notmuch_message_crypto_potential_payload (node->ctx->msg_crypto, part, node->parent ? node->parent->part : NULL, numchild) &&
+ node->ctx->msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL) {
+ GMimeObject *clean_payload = _notmuch_repair_crypto_payload_skip_legacy_display (part);
+ if (clean_payload != part) {
+ /* only one layer of recursion is possible here
+ * because there can be only a single cryptographic
+ * payload: */
+ return _mime_node_set_up_part (node, clean_payload, numchild);
+ }
+ }
}
- return node;
+ return true;
}
mime_node_t *
GMimeObject *sub;
mime_node_t *node;
- if (!parent || !parent->part || child < 0 || child >= parent->nchildren)
+ if (! parent || ! parent->part || child < 0 || child >= parent->nchildren)
return NULL;
if (GMIME_IS_MULTIPART (parent->part)) {
if (child == GMIME_MULTIPART_ENCRYPTED_CONTENT && parent->decrypted_child)
sub = parent->decrypted_child;
else
- sub = g_mime_multipart_get_part
- (GMIME_MULTIPART (parent->part), child);
+ sub = g_mime_multipart_get_part (
+ GMIME_MULTIPART (parent->part), child);
} else if (GMIME_IS_MESSAGE (parent->part)) {
sub = g_mime_message_get_mime_part (GMIME_MESSAGE (parent->part));
} else {
- /* This should have been caught by message_part_create */
+ /* This should have been caught by _mime_node_set_up_part */
INTERNAL_ERROR ("Unexpected GMimeObject type: %s",
g_type_name (G_OBJECT_TYPE (parent->part)));
}
#include "talloc-extra.h"
#include "crypto.h"
+#include "repair.h"
-#define unused(x) x __attribute__ ((unused))
+#define unused(x) x ## _unused __attribute__ ((unused))
-#define STRINGIFY(s) STRINGIFY_(s)
+#define STRINGIFY(s) STRINGIFY_ (s)
#define STRINGIFY_(s) #s
typedef struct mime_node mime_node_t;
struct notmuch_show_params;
typedef struct notmuch_show_format {
- struct sprinter *(*new_sprinter) (const void *ctx, FILE *stream);
- notmuch_status_t (*part) (const void *ctx, struct sprinter *sprinter,
- struct mime_node *node, int indent,
- const struct notmuch_show_params *params);
+ struct sprinter *(*new_sprinter)(const void *ctx, FILE *stream);
+ notmuch_status_t (*part)(const void *ctx, struct sprinter *sprinter,
+ struct mime_node *node, int indent,
+ const struct notmuch_show_params *params);
} notmuch_show_format_t;
typedef struct notmuch_show_params {
*
* Note that __location__ comes from talloc.h.
*/
-#define INTERNAL_ERROR(format, ...) \
- do { \
- fprintf(stderr, \
- "Internal error: " format " (%s)\n", \
- ##__VA_ARGS__, __location__); \
- exit (1); \
+#define INTERNAL_ERROR(format, ...) \
+ do { \
+ fprintf (stderr, \
+ "Internal error: " format " (%s)\n", \
+ ##__VA_ARGS__, __location__); \
+ exit (1); \
} while (0)
#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
static inline void
chomp_newline (char *str)
{
- if (str && str[strlen(str)-1] == '\n')
- str[strlen(str)-1] = '\0';
+ if (str && str[strlen (str) - 1] == '\n')
+ str[strlen (str) - 1] = '\0';
}
/* Exit status code indicating temporary failure; user is invited to
/* notmuch-config.c */
typedef enum {
- NOTMUCH_CONFIG_OPEN = 1 << 0,
- NOTMUCH_CONFIG_CREATE = 1 << 1,
+ NOTMUCH_CONFIG_OPEN = 1 << 0,
+ NOTMUCH_CONFIG_CREATE = 1 << 1,
} notmuch_config_mode_t;
notmuch_config_t *
void
notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
- const char *list[],
- size_t length);
+ const char *list[],
+ size_t length);
int
notmuch_run_hook (const char *db_path, const char *hook);
/* The list of signatures for signed or encrypted containers. If
* there are no signatures, this will be NULL. */
- GMimeSignatureList* sig_list;
+ GMimeSignatureList *sig_list;
/* Internal: Context inherited from the root iterator. */
struct mime_node_context *ctx;
mime_node_child (mime_node_t *parent, int child);
/* Return the nth child of node in a depth-first traversal. If n is
- * 0, returns node itself. Returns NULL if there is no such part. */
+* 0, returns node itself. Returns NULL if there is no such part. */
mime_node_t *
mime_node_seek_dfs (mime_node_t *node, int n);
-const _notmuch_message_crypto_t*
+const _notmuch_message_crypto_t *
mime_node_get_message_crypto_status (mime_node_t *node);
typedef enum dump_formats {
} dump_format_t;
typedef enum dump_includes {
- DUMP_INCLUDE_TAGS = 1,
- DUMP_INCLUDE_CONFIG = 2,
- DUMP_INCLUDE_PROPERTIES = 4
+ DUMP_INCLUDE_TAGS = 1,
+ DUMP_INCLUDE_CONFIG = 2,
+ DUMP_INCLUDE_PROPERTIES = 4
} dump_include_t;
#define DUMP_INCLUDE_DEFAULT (DUMP_INCLUDE_TAGS | DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_PROPERTIES)
bool gzip_output);
/* If status is non-zero (i.e. error) print appropriate
- messages to stderr.
-*/
+ * messages to stderr.
+ */
notmuch_status_t
print_status_query (const char *loc,
#include "command-line-arguments.h"
extern const char *notmuch_requested_db_uuid;
-extern const notmuch_opt_desc_t notmuch_shared_options [];
+extern const notmuch_opt_desc_t notmuch_shared_options [];
void notmuch_exit_if_unmatched_db_uuid (notmuch_database_t *notmuch);
-void notmuch_process_shared_options (const char* subcommand_name);
-int notmuch_minimal_options (const char* subcommand_name,
+void notmuch_process_shared_options (const char *subcommand_name);
+int notmuch_minimal_options (const char *subcommand_name,
int argc, char **argv);
struct _notmuch_client_indexing_cli_choices {
int decrypt_policy;
bool decrypt_policy_set;
- notmuch_indexopts_t * opts;
+ notmuch_indexopts_t *opts;
};
extern struct _notmuch_client_indexing_cli_choices indexing_cli_choices;
-extern const notmuch_opt_desc_t notmuch_shared_indexing_options [];
+extern const notmuch_opt_desc_t notmuch_shared_indexing_options [];
notmuch_status_t
notmuch_process_shared_indexing_options (notmuch_database_t *notmuch);
char *name;
int e;
- pw_buf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+ pw_buf_size = sysconf (_SC_GETPW_R_SIZE_MAX);
if (pw_buf_size == -1) pw_buf_size = 64;
pw_buf = talloc_size (ctx, pw_buf_size);
while ((e = getpwuid_r (getuid (), &passwd, pw_buf,
- pw_buf_size, &ignored)) == ERANGE) {
- pw_buf_size = pw_buf_size * 2;
- pw_buf = talloc_zero_size(ctx, pw_buf_size);
+ pw_buf_size, &ignored)) == ERANGE) {
+ pw_buf_size = pw_buf_size * 2;
+ pw_buf = talloc_zero_size (ctx, pw_buf_size);
}
if (e == 0) {
char *name;
int e;
- pw_buf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+ pw_buf_size = sysconf (_SC_GETPW_R_SIZE_MAX);
if (pw_buf_size == -1) pw_buf_size = 64;
pw_buf = talloc_zero_size (ctx, pw_buf_size);
while ((e = getpwuid_r (getuid (), &passwd, pw_buf,
- pw_buf_size, &ignored)) == ERANGE) {
- pw_buf_size = pw_buf_size * 2;
- pw_buf = talloc_zero_size(ctx, pw_buf_size);
+ pw_buf_size, &ignored)) == ERANGE) {
+ pw_buf_size = pw_buf_size * 2;
+ pw_buf = talloc_zero_size (ctx, pw_buf_size);
}
if (e == 0)
GError *error = NULL;
bool ret = false;
- FILE *fp = fopen(config->filename, "r");
+ FILE *fp = fopen (config->filename, "r");
if (fp == NULL) {
if (errno == ENOENT) {
/* If create_new is true, then the caller is prepared for a
}
} else {
fprintf (stderr, "Error opening config file '%s': %s\n",
- config->filename, strerror(errno));
+ config->filename, strerror (errno));
}
goto out;
}
g_error_free (error);
-out:
+ out:
if (fp)
- fclose(fp);
+ fclose (fp);
if (config_str)
- talloc_free(config_str);
+ talloc_free (config_str);
return ret;
}
*
* If is_new_ret is NULL, then a "file not found" message will be
* printed to stderr and NULL will be returned.
-
+ *
* If is_new_ret is non-NULL then a default configuration will be
* returned and *is_new_ret will be set to 1 on return so that
* the caller can recognize this case.
*
- * These default configuration settings are determined as
- * follows:
+ * These default configuration settings are determined as
+ * follows:
*
* database_path: $MAILDIR, otherwise $HOME/mail
*
* user_name: $NAME variable if set, otherwise
* read from /etc/passwd
*
- * user_primary_mail: $EMAIL variable if set, otherwise
+ * user_primary_mail: $EMAIL variable if set, otherwise
* constructed from the username and
* hostname of the current machine.
*
int file_had_crypto_group;
notmuch_config_t *config = talloc_zero (ctx, notmuch_config_t);
+
if (config == NULL) {
fprintf (stderr, "Out of memory.\n");
return NULL;
}
-
+
talloc_set_destructor (config, notmuch_config_destructor);
/* non-zero defaults */
}
if (notmuch_config_get_new_tags (config, &tmp) == NULL) {
- const char *tags[] = { "unread", "inbox" };
+ const char *tags[] = { "unread", "inbox" };
notmuch_config_set_new_tags (config, tags, 2);
}
}
/* Close the given notmuch_config_t object, freeing all resources.
- *
+ *
* Note: Any changes made to the configuration are *not* saved by this
* function. To save changes, call notmuch_config_save before
* notmuch_config_close.
-*/
+ */
void
notmuch_config_close (notmuch_config_t *config)
{
const char *section, const char *key,
const char ***outlist, size_t *list_length, size_t *ret_length)
{
- assert(outlist);
+ assert (outlist);
/* read from config file and cache value, if not cached already */
if (*outlist == NULL) {
char **inlist = g_key_file_get_string_list (config->key_file,
- section, key, list_length, NULL);
+ section, key, list_length, NULL);
if (inlist) {
unsigned int i;
const char *
notmuch_config_get_database_path (notmuch_config_t *config)
{
- char *db_path = (char *)_config_get (config, &config->database_path, "database", "path");
+ char *db_path = (char *) _config_get (config, &config->database_path, "database", "path");
if (db_path && *db_path != '/') {
/* If the path in the configuration file begins with any
size_t length)
{
_config_set_list (config, "user", "other_email", list, length,
- &(config->user_other_email));
+ &(config->user_other_email));
}
void
notmuch_config_set_new_tags (notmuch_config_t *config,
- const char *list[],
- size_t length)
+ const char *list[],
+ size_t length)
{
_config_set_list (config, "new", "tags", list, length,
- &(config->new_tags));
+ &(config->new_tags));
}
void
size_t length)
{
_config_set_list (config, "new", "ignore", list, length,
- &(config->new_ignore));
+ &(config->new_ignore));
}
const char **
void
notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
- const char *list[],
- size_t length)
+ const char *list[],
+ size_t length)
{
_config_set_list (config, "search", "exclude_tags", list, length,
&(config->search_exclude_tags));
*group = item;
period = strchr (item, '.');
- if (period == NULL || *(period+1) == '\0') {
+ if (period == NULL || *(period + 1) == '\0') {
fprintf (stderr,
"Invalid configuration name: %s\n"
"(Should be of the form <section>.<item>)\n", item);
}
/* These are more properly called Xapian fields, but the user facing
- docs call them prefixes, so make the error message match */
+ * docs call them prefixes, so make the error message match */
static bool
validate_field_name (const char *str)
{
} config_key_info_t;
static struct config_key
-config_key_table[] = {
- {"index.decrypt", true, false, NULL},
- {"index.header.", true, true, validate_field_name},
- {"query.", true, true, NULL},
+ config_key_table[] = {
+ { "index.decrypt", true, false, NULL },
+ { "index.header.", true, true, validate_field_name },
+ { "query.", true, true, NULL },
};
static config_key_info_t *
for (size_t i = 0; i < ARRAY_SIZE (config_key_table); i++) {
if (config_key_table[i].prefix &&
strncmp (item, config_key_table[i].name,
- strlen(config_key_table[i].name)) == 0)
- return config_key_table+i;
+ strlen (config_key_table[i].name)) == 0)
+ return config_key_table + i;
if (strcmp (item, config_key_table[i].name) == 0)
- return config_key_table+i;
+ return config_key_table + i;
}
return NULL;
}
_stored_in_db (const char *item)
{
config_key_info_t *info;
+
info = _config_key_info (item);
return (info && info->in_db);
}
static int
-_print_db_config(notmuch_config_t *config, const char *name)
+_print_db_config (notmuch_config_t *config, const char *name)
{
notmuch_database_t *notmuch;
char *val;
notmuch_database_get_config (notmuch, name, &val)))
return EXIT_FAILURE;
- puts (val);
+ puts (val);
return EXIT_SUCCESS;
}
static int
notmuch_config_command_get (notmuch_config_t *config, char *item)
{
- if (strcmp(item, "database.path") == 0) {
+ if (strcmp (item, "database.path") == 0) {
printf ("%s\n", notmuch_config_get_database_path (config));
- } else if (strcmp(item, "user.name") == 0) {
+ } else if (strcmp (item, "user.name") == 0) {
printf ("%s\n", notmuch_config_get_user_name (config));
- } else if (strcmp(item, "user.primary_email") == 0) {
+ } else if (strcmp (item, "user.primary_email") == 0) {
printf ("%s\n", notmuch_config_get_user_primary_email (config));
- } else if (strcmp(item, "user.other_email") == 0) {
+ } else if (strcmp (item, "user.other_email") == 0) {
const char **other_email;
size_t i, length;
-
+
other_email = notmuch_config_get_user_other_email (config, &length);
for (i = 0; i < length; i++)
printf ("%s\n", other_email[i]);
- } else if (strcmp(item, "new.tags") == 0) {
+ } else if (strcmp (item, "new.tags") == 0) {
const char **tags;
size_t i, length;
}
static int
-_set_db_config(notmuch_config_t *config, const char *key, int argc, char **argv)
+_set_db_config (notmuch_config_t *config, const char *key, int argc, char **argv)
{
notmuch_database_t *notmuch;
const char *val = "";
void
_notmuch_config_list_built_with ()
{
- printf("%scompact=%s\n",
- BUILT_WITH_PREFIX,
- notmuch_built_with ("compact") ? "true" : "false");
- printf("%sfield_processor=%s\n",
- BUILT_WITH_PREFIX,
- notmuch_built_with ("field_processor") ? "true" : "false");
- printf("%sretry_lock=%s\n",
- BUILT_WITH_PREFIX,
- notmuch_built_with ("retry_lock") ? "true" : "false");
+ printf ("%scompact=%s\n",
+ BUILT_WITH_PREFIX,
+ notmuch_built_with ("compact") ? "true" : "false");
+ printf ("%sfield_processor=%s\n",
+ BUILT_WITH_PREFIX,
+ notmuch_built_with ("field_processor") ? "true" : "false");
+ printf ("%sretry_lock=%s\n",
+ BUILT_WITH_PREFIX,
+ notmuch_built_with ("retry_lock") ? "true" : "false");
}
static int
return EXIT_FAILURE;
for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
- printf("%s=%s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
+ printf ("%s=%s\n", notmuch_config_list_key (list), notmuch_config_list_value (list));
}
notmuch_config_list_destroy (list);
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}
static int
notmuch_requested_db_uuid);
/* skip at least subcommand argument */
- argc-= opt_index;
- argv+= opt_index;
+ argc -= opt_index;
+ argv += opt_index;
if (argc < 1) {
fprintf (stderr, "Error: notmuch config requires at least one argument.\n");
notmuch_opt_desc_t options[] = {
{ .opt_keyword = &output, .name = "output", .keywords =
- (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS },
- { "messages", OUTPUT_MESSAGES },
- { "files", OUTPUT_FILES },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS },
+ { "messages", OUTPUT_MESSAGES },
+ { "files", OUTPUT_FILES },
+ { 0, 0 } } },
{ .opt_bool = &exclude, .name = "exclude" },
{ .opt_bool = &print_lastmod, .name = "lastmod" },
{ .opt_bool = &batch, .name = "batch" },
if (exclude) {
search_exclude_tags = notmuch_config_get_search_exclude_tags
- (config, &search_exclude_tags_length);
+ (config, &search_exclude_tags_length);
}
if (batch)
ret = EXIT_SUCCESS;
- DONE:
+ DONE:
if (list)
notmuch_config_list_destroy (list);
if (include & DUMP_INCLUDE_CONFIG) {
if (print_status_database ("notmuch dump", notmuch,
- database_dump_config(notmuch,output)))
+ database_dump_config (notmuch, output)))
return EXIT_FAILURE;
}
name_for_error, strerror (errno));
if (close (outfd))
fprintf (stderr, "Error closing %s during shutdown: %s\n",
- name_for_error, strerror (errno));
+ name_for_error, strerror (errno));
goto DONE;
}
}
}
- if (gzclose_w (output) != Z_OK) {
+ ret = gzclose_w (output);
+ if (ret) {
fprintf (stderr, "Error closing %s: %s\n", name_for_error,
gzerror (output, NULL));
ret = EXIT_FAILURE;
output = NULL;
goto DONE;
- }
+ } else
+ output = NULL;
if (output_file_name) {
ret = rename (tempname, output_file_name);
}
}
- DONE:
+ DONE:
if (ret != EXIT_SUCCESS && output)
(void) gzclose_w (output);
notmuch_opt_desc_t options[] = {
{ .opt_keyword = &output_format, .name = "format", .keywords =
- (notmuch_keyword_t []){ { "sup", DUMP_FORMAT_SUP },
- { "batch-tag", DUMP_FORMAT_BATCH_TAG },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "sup", DUMP_FORMAT_SUP },
+ { "batch-tag", DUMP_FORMAT_BATCH_TAG },
+ { 0, 0 } } },
{ .opt_flags = &include, .name = "include", .keywords =
- (notmuch_keyword_t []){ { "config", DUMP_INCLUDE_CONFIG },
- { "properties", DUMP_INCLUDE_PROPERTIES },
- { "tags", DUMP_INCLUDE_TAGS} } },
+ (notmuch_keyword_t []){ { "config", DUMP_INCLUDE_CONFIG },
+ { "properties", DUMP_INCLUDE_PROPERTIES },
+ { "tags", DUMP_INCLUDE_TAGS } } },
{ .opt_string = &output_file_name, .name = "output" },
{ .opt_bool = &gzip_output, .name = "gzip" },
{ .opt_inherit = notmuch_shared_options },
if ((p[0] == '.') && (p[1] == '.') && (p[2] == '\0' || p[2] == '/'))
return false;
p = strchr (p, '/');
- if (!p)
+ if (! p)
return true;
p++;
}
/* First check the common case: directory already exists. */
r = stat (path, &st);
if (r == 0) {
- if (! S_ISDIR (st.st_mode)) {
+ if (! S_ISDIR (st.st_mode)) {
fprintf (stderr, "Error: '%s' is not a directory: %s\n",
path, strerror (EEXIST));
return false;
} while (remain > 0);
}
- return (!interrupted && !empty);
+ return (! interrupted && ! empty);
}
/*
return path;
-FAIL:
+ FAIL:
close (fdout);
unlink (path);
return newpath;
-FAIL:
+ FAIL:
unlink (cleanpath);
return NULL;
* result. It is not required for correctness, and if it does
* fail or produce a short write, we want to get out of the signal
* handler as quickly as possible, not retry it. */
- IGNORE_RESULT (write (2, msg, sizeof(msg)-1));
+ IGNORE_RESULT (write (2, msg, sizeof (msg) - 1));
interrupted = 1;
}
/* Mapping from d_type to stat mode_t. We omit DT_LNK so that
* we'll fall through to stat and get the real file type. */
static const mode_t modes[] = {
- [DT_BLK] = S_IFBLK,
- [DT_CHR] = S_IFCHR,
- [DT_DIR] = S_IFDIR,
+ [DT_BLK] = S_IFBLK,
+ [DT_CHR] = S_IFCHR,
+ [DT_DIR] = S_IFDIR,
[DT_FIFO] = S_IFIFO,
- [DT_REG] = S_IFREG,
+ [DT_REG] = S_IFREG,
[DT_SOCK] = S_IFSOCK
};
- if (entry->d_type < ARRAY_SIZE(modes) && modes[entry->d_type])
+ if (entry->d_type < ARRAY_SIZE (modes) && modes[entry->d_type])
return modes[entry->d_type];
#endif
abspath = talloc_asprintf (NULL, "%s/%s", path, entry->d_name);
- if (!abspath) {
+ if (! abspath) {
errno = ENOMEM;
return -1;
}
- err = stat(abspath, &statbuf);
+ err = stat (abspath, &statbuf);
saved_errno = errno;
talloc_free (abspath);
if (err < 0) {
if (dirent_type (path, entries[i]) != S_IFDIR)
continue;
- if (strcmp(entries[i]->d_name, "new") == 0 ||
- strcmp(entries[i]->d_name, "cur") == 0 ||
- strcmp(entries[i]->d_name, "tmp") == 0)
- {
+ if (strcmp (entries[i]->d_name, "new") == 0 ||
+ strcmp (entries[i]->d_name, "cur") == 0 ||
+ strcmp (entries[i]->d_name, "tmp") == 0) {
found++;
if (found == 3)
return 1;
notmuch_message_maildir_flags_to_tags (message);
for (tag = state->new_tags; *tag != NULL; tag++) {
- if (strcmp ("unread", *tag) !=0 ||
- !notmuch_message_has_maildir_flag (message, 'S')) {
+ if (strcmp ("unread", *tag) != 0 ||
+ ! notmuch_message_has_maildir_flag (message, 'S')) {
notmuch_message_add_tag (message, *tag);
}
}
case NOTMUCH_STATUS_READ_ONLY_DATABASE:
case NOTMUCH_STATUS_XAPIAN_EXCEPTION:
case NOTMUCH_STATUS_OUT_OF_MEMORY:
- (void) print_status_database("add_file", notmuch, status);
+ (void) print_status_database ("add_file", notmuch, status);
goto DONE;
default:
INTERNAL_ERROR ("add_message returned unexpected value: %d", status);
* file system link count. So, only bail early if the
* database agrees that there are no sub-directories. */
db_subdirs = notmuch_directory_get_child_directories (directory);
- if (!notmuch_filenames_valid (db_subdirs))
+ if (! notmuch_filenames_valid (db_subdirs))
goto DONE;
notmuch_filenames_destroy (db_subdirs);
db_subdirs = NULL;
/* Pass 2: Scan for new files, removed files, and removed directories. */
for (i = 0; i < num_fs_entries && ! interrupted; i++) {
- entry = fs_entries[i];
+ entry = fs_entries[i];
/* Ignore special directories early. */
if (_special_directory (entry->d_name))
/* Check if we've walked past any names in db_files or
* db_subdirs. If so, these have been deleted. */
while (notmuch_filenames_valid (db_files) &&
- strcmp (notmuch_filenames_get (db_files), entry->d_name) < 0)
- {
+ strcmp (notmuch_filenames_get (db_files), entry->d_name) < 0) {
char *absolute = talloc_asprintf (state->removed_files,
"%s/%s", path,
notmuch_filenames_get (db_files));
}
while (notmuch_filenames_valid (db_subdirs) &&
- strcmp (notmuch_filenames_get (db_subdirs), entry->d_name) <= 0)
- {
+ strcmp (notmuch_filenames_get (db_subdirs), entry->d_name) <= 0) {
const char *filename = notmuch_filenames_get (db_subdirs);
- if (strcmp (filename, entry->d_name) < 0)
- {
+ if (strcmp (filename, entry->d_name) < 0) {
char *absolute = talloc_asprintf (state->removed_directories,
"%s/%s", path, filename);
if (state->debug)
printf ("(D) add_files, pass 2: queuing passed directory %s for deletion from database\n",
- absolute);
+ absolute);
_filename_list_add (state->removed_directories, absolute);
}
/* Don't add a file that we've added before. */
if (notmuch_filenames_valid (db_files) &&
- strcmp (notmuch_filenames_get (db_files), entry->d_name) == 0)
- {
+ strcmp (notmuch_filenames_get (db_files), entry->d_name) == 0) {
notmuch_filenames_move_to_next (db_files);
continue;
}
if (state->verbosity >= VERBOSITY_VERBOSE) {
if (state->output_is_a_tty)
- printf("\r\033[K");
+ printf ("\r\033[K");
printf ("%i/%i: %s", state->processed_files, state->total_files,
next);
- putchar((state->output_is_a_tty) ? '\r' : '\n');
+ putchar ((state->output_is_a_tty) ? '\r' : '\n');
fflush (stdout);
}
/* Now that we've walked the whole filesystem list, anything left
* over in the database lists has been deleted. */
- while (notmuch_filenames_valid (db_files))
- {
+ while (notmuch_filenames_valid (db_files)) {
char *absolute = talloc_asprintf (state->removed_files,
"%s/%s", path,
notmuch_filenames_get (db_files));
notmuch_filenames_move_to_next (db_files);
}
- while (notmuch_filenames_valid (db_subdirs))
- {
+ while (notmuch_filenames_valid (db_subdirs)) {
char *absolute = talloc_asprintf (state->removed_directories,
"%s/%s", path,
notmuch_filenames_get (db_subdirs));
}
for (i = 0; i < num_fs_entries && ! interrupted; i++) {
- entry = fs_entries[i];
+ entry = fs_entries[i];
/* Ignore special directories to avoid infinite recursion.
* Also ignore the .notmuch directory.
for (i = 0; i < num_fs_entries; i++)
free (fs_entries[i]);
- free (fs_entries);
+ free (fs_entries);
}
}
{
notmuch_status_t status;
notmuch_message_t *message;
+
status = notmuch_database_begin_atomic (notmuch);
if (status)
return status;
char *absolute;
status = notmuch_database_get_directory (notmuch, path, &directory);
- if (status || !directory)
+ if (status || ! directory)
return status;
for (files = notmuch_directory_get_child_files (directory);
notmuch_filenames_valid (files);
- notmuch_filenames_move_to_next (files))
- {
+ notmuch_filenames_move_to_next (files)) {
absolute = talloc_asprintf (ctx, "%s/%s", path,
notmuch_filenames_get (files));
status = remove_filename (notmuch, absolute, add_files_state);
for (subdirs = notmuch_directory_get_child_directories (directory);
notmuch_filenames_valid (subdirs);
- notmuch_filenames_move_to_next (subdirs))
- {
+ notmuch_filenames_move_to_next (subdirs)) {
absolute = talloc_asprintf (ctx, "%s/%s", path,
notmuch_filenames_get (subdirs));
status = _remove_directory (ctx, notmuch, absolute, add_files_state);
goto DONE;
gettimeofday (&tv_start, NULL);
- for (f = add_files_state.removed_files->head; f && !interrupted; f = f->next) {
+ for (f = add_files_state.removed_files->head; f && ! interrupted; f = f->next) {
ret = remove_filename (notmuch, f->filename, &add_files_state);
if (ret)
goto DONE;
if (do_print_progress) {
do_print_progress = 0;
generic_print_progress ("Cleaned up", "messages",
- tv_start, add_files_state.removed_messages + add_files_state.renamed_messages,
- add_files_state.removed_files->count);
+ tv_start, add_files_state.removed_messages + add_files_state.renamed_messages,
+ add_files_state.removed_files->count);
}
}
gettimeofday (&tv_start, NULL);
- for (f = add_files_state.removed_directories->head, i = 0; f && !interrupted; f = f->next, i++) {
+ for (f = add_files_state.removed_directories->head, i = 0; f && ! interrupted; f = f->next, i++) {
ret = _remove_directory (config, notmuch, f->filename, &add_files_state);
if (ret)
goto DONE;
if (do_print_progress) {
do_print_progress = 0;
generic_print_progress ("Cleaned up", "directories",
- tv_start, i,
- add_files_state.removed_directories->count);
+ tv_start, i,
+ add_files_state.removed_directories->count);
}
}
- for (f = add_files_state.directory_mtimes->head; f && !interrupted; f = f->next) {
+ for (f = add_files_state.directory_mtimes->head; f && ! interrupted; f = f->next) {
notmuch_directory_t *directory;
status = notmuch_database_get_directory (notmuch, f->filename, &directory);
if (status == NOTMUCH_STATUS_SUCCESS && directory) {
notmuch_database_destroy (notmuch);
- if (hooks && !ret && !interrupted)
+ if (hooks && ! ret && ! interrupted)
ret = notmuch_run_hook (db_path, "post-new");
if (ret || interrupted)
notmuch_messages_move_to_next (messages)) {
message = notmuch_messages_get (messages);
- ret = notmuch_message_reindex(message, indexopts);
+ ret = notmuch_message_reindex (message, indexopts);
if (ret != NOTMUCH_STATUS_SUCCESS)
break;
notmuch_message_destroy (message);
}
- if (!ret)
+ if (! ret)
ret = notmuch_database_end_atomic (notmuch);
notmuch_query_destroy (query);
return EXIT_FAILURE;
}
- query_string = query_string_from_args (config, argc-opt_index, argv+opt_index);
+ query_string = query_string_from_args (config, argc - opt_index, argv + opt_index);
if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
return EXIT_FAILURE;
fprintf (stderr, "Error: notmuch reindex requires at least one search term.\n");
return EXIT_FAILURE;
}
-
+
ret = reindex_query (notmuch, query_string, indexing_cli_choices.opts);
notmuch_database_destroy (notmuch);
show_reply_headers (GMimeStream *stream, GMimeMessage *message)
{
/* Output RFC 2822 formatted (and RFC 2047 encoded) headers. */
- if (g_mime_object_write_to_stream (GMIME_OBJECT(message), NULL, stream) < 0) {
- INTERNAL_ERROR("failed to write headers to stdout\n");
+ if (g_mime_object_write_to_stream (GMIME_OBJECT (message), NULL, stream) < 0) {
+ INTERNAL_ERROR ("failed to write headers to stdout\n");
}
}
g_mime_content_type_is_type (content_type, "application", "pgp-signature")) {
/* Ignore PGP/MIME cruft parts */
} else if (g_mime_content_type_is_type (content_type, "text", "*") &&
- !g_mime_content_type_is_type (content_type, "text", "html")) {
+ ! g_mime_content_type_is_type (content_type, "text", "html")) {
show_text_part_content (node->part, stream, NOTMUCH_SHOW_TEXT_PART_REPLY);
} else if (disposition &&
strcasecmp (g_mime_content_disposition_get_disposition (disposition),
const char **other;
size_t i, other_len;
- if (!str || *str == '\0')
+ if (! str || *str == '\0')
return NULL;
primary = notmuch_config_get_user_primary_email (config);
return ret;
}
-static InternetAddressList *get_sender(GMimeMessage *message)
+static InternetAddressList *
+get_sender (GMimeMessage *message)
{
InternetAddressList *reply_to_list;
reply_to_list = g_mime_message_get_reply_to_list (message);
if (reply_to_list &&
internet_address_list_length (reply_to_list) > 0) {
- /*
+ /*
* Some mailing lists munge the Reply-To header despite it
* being A Bad Thing, see
* http://marc.merlins.org/netrants/reply-to-harmful.html
return g_mime_message_get_from (message);
}
-static InternetAddressList *get_to(GMimeMessage *message)
+static InternetAddressList *
+get_to (GMimeMessage *message)
{
return g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_TO);
}
-static InternetAddressList *get_cc(GMimeMessage *message)
+static InternetAddressList *
+get_cc (GMimeMessage *message)
{
return g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_CC);
}
-static InternetAddressList *get_bcc(GMimeMessage *message)
+static InternetAddressList *
+get_bcc (GMimeMessage *message)
{
return g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_BCC);
}
InternetAddressList * (*get_header)(GMimeMessage *message);
GMimeAddressType recipient_type;
} reply_to_map[] = {
- { get_sender, GMIME_ADDRESS_TYPE_TO },
- { get_to, GMIME_ADDRESS_TYPE_TO },
- { get_cc, GMIME_ADDRESS_TYPE_CC },
- { get_bcc, GMIME_ADDRESS_TYPE_BCC },
+ { get_sender, GMIME_ADDRESS_TYPE_TO },
+ { get_to, GMIME_ADDRESS_TYPE_TO },
+ { get_cc, GMIME_ADDRESS_TYPE_CC },
+ { get_bcc, GMIME_ADDRESS_TYPE_BCC },
};
const char *from_addr = NULL;
unsigned int i;
n += scan_address_list (recipients, config, reply,
reply_to_map[i].recipient_type, &from_addr);
- if (!reply_all && n) {
+ if (! reply_all && n) {
/* Stop adding new recipients in reply-to-sender mode if
* we have added some recipient(s) above.
*
if (*by == '\0')
break;
mta = xstrdup (by);
- token = strtok(mta," \t");
+ token = strtok (mta, " \t");
if (token == NULL) {
free (mta);
break;
}
static GMimeMessage *
-create_reply_message(void *ctx,
- notmuch_config_t *config,
- notmuch_message_t *message,
- GMimeMessage *mime_message,
- bool reply_all,
- bool limited)
+create_reply_message (void *ctx,
+ notmuch_config_t *config,
+ notmuch_message_t *message,
+ GMimeMessage *mime_message,
+ bool reply_all,
+ bool limited)
{
const char *subject, *from_addr = NULL;
const char *in_reply_to, *orig_references, *references;
* otherwise.
*/
GMimeMessage *reply = g_mime_message_new (limited ? 0 : 1);
+
if (reply == NULL) {
fprintf (stderr, "Out of memory\n");
return NULL;
FORMAT_HEADERS_ONLY,
};
-static int do_reply(notmuch_config_t *config,
- notmuch_query_t *query,
- notmuch_show_params_t *params,
- int format,
- bool reply_all)
+static int
+do_reply (notmuch_config_t *config,
+ notmuch_query_t *query,
+ notmuch_show_params_t *params,
+ int format,
+ bool reply_all)
{
GMimeMessage *reply;
mime_node_t *node;
for (;
notmuch_messages_valid (messages);
- notmuch_messages_move_to_next (messages))
- {
+ notmuch_messages_move_to_next (messages)) {
message = notmuch_messages_get (messages);
if (mime_node_open (config, message, ¶ms->crypto, &node))
reply = create_reply_message (config, config, message,
GMIME_MESSAGE (node->part), reply_all,
format == FORMAT_HEADERS_ONLY);
- if (!reply)
+ if (! reply)
return 1;
if (format == FORMAT_JSON || format == FORMAT_SEXP) {
format_part_reply (stream_stdout, node);
}
g_mime_stream_flush (stream_stdout);
- g_object_unref(stream_stdout);
+ g_object_unref (stream_stdout);
}
g_object_unref (G_OBJECT (reply));
notmuch_opt_desc_t options[] = {
{ .opt_keyword = &format, .name = "format", .keywords =
- (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
- { "json", FORMAT_JSON },
- { "sexp", FORMAT_SEXP },
- { "headers-only", FORMAT_HEADERS_ONLY },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
+ { "json", FORMAT_JSON },
+ { "sexp", FORMAT_SEXP },
+ { "headers-only", FORMAT_HEADERS_ONLY },
+ { 0, 0 } } },
{ .opt_int = ¬much_format_version, .name = "format-version" },
{ .opt_keyword = &reply_all, .name = "reply-to", .keywords =
- (notmuch_keyword_t []){ { "all", true },
- { "sender", false },
- { 0, 0 } } },
- { .opt_keyword = (int*)(¶ms.crypto.decrypt), .name = "decrypt",
+ (notmuch_keyword_t []){ { "all", true },
+ { "sender", false },
+ { 0, 0 } } },
+ { .opt_keyword = (int *) (¶ms.crypto.decrypt), .name = "decrypt",
.keyword_no_arg_value = "true", .keywords =
- (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
- { "auto", NOTMUCH_DECRYPT_AUTO },
- { "true", NOTMUCH_DECRYPT_NOSTASH },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
+ { "auto", NOTMUCH_DECRYPT_AUTO },
+ { "true", NOTMUCH_DECRYPT_NOSTASH },
+ { 0, 0 } } },
{ .opt_inherit = notmuch_shared_options },
{ }
};
notmuch_exit_if_unsupported_format ();
- query_string = query_string_from_args (config, argc-opt_index, argv+opt_index);
+ query_string = query_string_from_args (config, argc - opt_index, argv + opt_index);
if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
return EXIT_FAILURE;
#include "zlib-extra.h"
static int
-process_config_line (notmuch_database_t *notmuch, const char* line)
+process_config_line (notmuch_database_t *notmuch, const char *line)
{
const char *key_p, *val_p;
char *key, *val;
- size_t key_len,val_len;
+ size_t key_len, val_len;
const char *delim = " \t\n";
int ret = EXIT_FAILURE;
- void *local = talloc_new(NULL);
+ void *local = talloc_new (NULL);
key_p = strtok_len_c (line, delim, &key_len);
- val_p = strtok_len_c (key_p+key_len, delim, &val_len);
+ val_p = strtok_len_c (key_p + key_len, delim, &val_len);
key = talloc_strndup (local, key_p, key_len);
val = talloc_strndup (local, val_p, val_len);
ret = EXIT_SUCCESS;
- DONE:
+ DONE:
talloc_free (local);
return ret;
}
static int
-process_properties_line (notmuch_database_t *notmuch, const char* line)
-
+process_properties_line (notmuch_database_t *notmuch, const char *line)
{
const char *id_p, *tok;
size_t id_len = 0, tok_len = 0;
notmuch_opt_desc_t options[] = {
{ .opt_keyword = &input_format, .name = "format", .keywords =
- (notmuch_keyword_t []){ { "auto", DUMP_FORMAT_AUTO },
- { "batch-tag", DUMP_FORMAT_BATCH_TAG },
- { "sup", DUMP_FORMAT_SUP },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "auto", DUMP_FORMAT_AUTO },
+ { "batch-tag", DUMP_FORMAT_BATCH_TAG },
+ { "sup", DUMP_FORMAT_SUP },
+ { 0, 0 } } },
{ .opt_flags = &include, .name = "include", .keywords =
- (notmuch_keyword_t []){ { "config", DUMP_INCLUDE_CONFIG },
- { "properties", DUMP_INCLUDE_PROPERTIES },
- { "tags", DUMP_INCLUDE_TAGS} } },
+ (notmuch_keyword_t []){ { "config", DUMP_INCLUDE_CONFIG },
+ { "properties", DUMP_INCLUDE_PROPERTIES },
+ { "tags", DUMP_INCLUDE_TAGS } } },
{ .opt_string = &input_file_name, .name = "input" },
{ .opt_bool = &accumulate, .name = "accumulate" },
if (status) {
fprintf (stderr, "Error reading (gzipped) input: %s\n",
- gz_error_string(status, input));
+ gz_error_string (status, input));
ret = EXIT_FAILURE;
goto DONE;
}
if ((include & DUMP_INCLUDE_CONFIG) && line_len >= 2 && line[0] == '#' && line[1] == '@') {
- ret = process_config_line(notmuch, line+2);
+ ret = process_config_line (notmuch, line + 2);
if (ret)
goto DONE;
}
} while ((line_len == 0) ||
(line[0] == '#') ||
- /* the cast is safe because we checked about for line_len < 0 */
- (strspn (line, " \t\n") == (unsigned)line_len));
+ /* the cast is safe because we checked about for line_len < 0 */
+ (strspn (line, " \t\n") == (unsigned) line_len));
if (! ((include & DUMP_INCLUDE_TAGS) || (include & DUMP_INCLUDE_PROPERTIES))) {
ret = EXIT_SUCCESS;
ret = EXIT_FAILURE;
}
- /* currently this should not be after DONE: since we don't
+ /* currently this should not be after DONE: since we don't
* know if the xregcomp was reached
*/
if (input_format == DUMP_FORMAT_SUP)
regfree (®ex);
- DONE:
+ DONE:
if (line_ctx != NULL)
talloc_free (line_ctx);
for (messages = notmuch_thread_get_messages (thread);
notmuch_messages_valid (messages);
- notmuch_messages_move_to_next (messages))
- {
+ notmuch_messages_move_to_next (messages)) {
notmuch_message_t *message = notmuch_messages_get (messages);
const char *mid = notmuch_message_get_message_id (message);
/* Determine which query buffer to extend */
*buf = talloc_asprintf_append_buffer (*buf, " %s", escaped);
else
*buf = talloc_strdup (thread, escaped);
- if (!*buf)
+ if (! *buf)
return -1;
}
talloc_free (escaped);
}
status = notmuch_query_search_threads (ctx->query, &threads);
- if (print_status_query("notmuch search", ctx->query, status))
+ if (print_status_query ("notmuch search", ctx->query, status))
return 1;
format->begin_list (format);
for (i = 0;
notmuch_threads_valid (threads) && (ctx->limit < 0 || i < ctx->offset + ctx->limit);
- notmuch_threads_move_to_next (threads), i++)
- {
+ notmuch_threads_move_to_next (threads), i++) {
thread = notmuch_threads_get (threads);
if (i < ctx->offset) {
relative_date = notmuch_time_relative_date (ctx_quote, date);
if (format->is_text_printer) {
- /* Special case for the text formatter */
+ /* Special case for the text formatter */
printf ("thread:%s %12s ",
thread_id,
relative_date);
if (total == files)
printf ("[%d/%d] %s; %s (",
- matched,
- total,
- sanitize_string (ctx_quote, authors),
- sanitize_string (ctx_quote, subject));
+ matched,
+ total,
+ sanitize_string (ctx_quote, authors),
+ sanitize_string (ctx_quote, subject));
else
printf ("[%d/%d(%d)] %s; %s (",
- matched,
- total,
- files,
- sanitize_string (ctx_quote, authors),
- sanitize_string (ctx_quote, subject));
+ matched,
+ total,
+ files,
+ sanitize_string (ctx_quote, authors),
+ sanitize_string (ctx_quote, subject));
} else { /* Structured Output */
format->map_key (format, "thread");
for (tags = notmuch_thread_get_tags (thread);
notmuch_tags_valid (tags);
- notmuch_tags_move_to_next (tags))
- {
+ notmuch_tags_move_to_next (tags)) {
const char *tag = notmuch_tags_get (tags);
if (format->is_text_printer) {
- /* Special case for the text formatter */
+ /* Special case for the text formatter */
if (first_tag)
first_tag = false;
else
return 0;
}
-static mailbox_t *new_mailbox (void *ctx, const char *name, const char *addr)
+static mailbox_t *
+new_mailbox (void *ctx, const char *name, const char *addr)
{
mailbox_t *mailbox;
return mailbox;
}
-static int mailbox_compare (const void *v1, const void *v2)
+static int
+mailbox_compare (const void *v1, const void *v2)
{
const mailbox_t *m1 = v1, *m2 = v2;
int ret;
}
if (! mailbox)
- INTERNAL_ERROR("Empty list in address hash table\n");
+ INTERNAL_ERROR ("Empty list in address hash table\n");
/* The original count is no longer needed, so overwrite. */
mailbox->count = total;
filenames = notmuch_message_get_filenames (message);
while (notmuch_filenames_valid (filenames)) {
- notmuch_filenames_move_to_next (filenames);
- i++;
+ notmuch_filenames_move_to_next (filenames);
+ i++;
}
notmuch_filenames_destroy (filenames);
for (i = 0;
notmuch_messages_valid (messages) && (ctx->limit < 0 || i < ctx->offset + ctx->limit);
- notmuch_messages_move_to_next (messages), i++)
- {
+ notmuch_messages_move_to_next (messages), i++) {
if (i < ctx->offset)
continue;
for (j = 1;
notmuch_filenames_valid (filenames);
- notmuch_filenames_move_to_next (filenames), j++)
- {
+ notmuch_filenames_move_to_next (filenames), j++) {
if (ctx->dupe < 0 || ctx->dupe == j) {
format->string (format, notmuch_filenames_get (filenames));
format->separator (format);
}
}
-
- notmuch_filenames_destroy( filenames );
+
+ notmuch_filenames_destroy ( filenames );
} else if (ctx->output == OUTPUT_MESSAGES) {
- /* special case 1 for speed */
- if (ctx->dupe <= 1 || ctx->dupe <= _count_filenames (message)) {
- format->set_prefix (format, "id");
- format->string (format,
- notmuch_message_get_message_id (message));
- format->separator (format);
- }
+ /* special case 1 for speed */
+ if (ctx->dupe <= 1 || ctx->dupe <= _count_filenames (message)) {
+ format->set_prefix (format, "id");
+ format->string (format,
+ notmuch_message_get_message_id (message));
+ format->separator (format);
+ }
} else {
if (ctx->output & OUTPUT_SENDER) {
const char *addrs;
for (;
notmuch_tags_valid (tags);
- notmuch_tags_move_to_next (tags))
- {
+ notmuch_tags_move_to_next (tags)) {
tag = notmuch_tags_get (tags);
format->string (format, tag);
break;
default:
/* this should never happen */
- INTERNAL_ERROR("no output format selected");
+ INTERNAL_ERROR ("no output format selected");
}
notmuch_exit_if_unsupported_format ();
size_t search_exclude_tags_length;
notmuch_status_t status;
- search_exclude_tags = notmuch_config_get_search_exclude_tags
- (config, &search_exclude_tags_length);
+ search_exclude_tags = notmuch_config_get_search_exclude_tags (
+ config, &search_exclude_tags_length);
for (i = 0; i < search_exclude_tags_length; i++) {
status = notmuch_query_add_tag_exclude (ctx->query, search_exclude_tags[i]);
static const notmuch_opt_desc_t common_options[] = {
{ .opt_keyword = &search_context.sort, .name = "sort", .keywords =
- (notmuch_keyword_t []){ { "oldest-first", NOTMUCH_SORT_OLDEST_FIRST },
- { "newest-first", NOTMUCH_SORT_NEWEST_FIRST },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "oldest-first", NOTMUCH_SORT_OLDEST_FIRST },
+ { "newest-first", NOTMUCH_SORT_NEWEST_FIRST },
+ { 0, 0 } } },
{ .opt_keyword = &search_context.format_sel, .name = "format", .keywords =
- (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON },
- { "sexp", NOTMUCH_FORMAT_SEXP },
- { "text", NOTMUCH_FORMAT_TEXT },
- { "text0", NOTMUCH_FORMAT_TEXT0 },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON },
+ { "sexp", NOTMUCH_FORMAT_SEXP },
+ { "text", NOTMUCH_FORMAT_TEXT },
+ { "text0", NOTMUCH_FORMAT_TEXT0 },
+ { 0, 0 } } },
{ .opt_int = ¬much_format_version, .name = "format-version" },
{ }
};
notmuch_opt_desc_t options[] = {
{ .opt_keyword = &ctx->output, .name = "output", .keywords =
- (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },
- { "threads", OUTPUT_THREADS },
- { "messages", OUTPUT_MESSAGES },
- { "files", OUTPUT_FILES },
- { "tags", OUTPUT_TAGS },
- { 0, 0 } } },
- { .opt_keyword = &ctx->exclude, .name = "exclude", .keywords =
- (notmuch_keyword_t []){ { "true", NOTMUCH_EXCLUDE_TRUE },
- { "false", NOTMUCH_EXCLUDE_FALSE },
- { "flag", NOTMUCH_EXCLUDE_FLAG },
- { "all", NOTMUCH_EXCLUDE_ALL },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },
+ { "threads", OUTPUT_THREADS },
+ { "messages", OUTPUT_MESSAGES },
+ { "files", OUTPUT_FILES },
+ { "tags", OUTPUT_TAGS },
+ { 0, 0 } } },
+ { .opt_keyword = &ctx->exclude, .name = "exclude", .keywords =
+ (notmuch_keyword_t []){ { "true", NOTMUCH_EXCLUDE_TRUE },
+ { "false", NOTMUCH_EXCLUDE_FALSE },
+ { "flag", NOTMUCH_EXCLUDE_FLAG },
+ { "all", NOTMUCH_EXCLUDE_ALL },
+ { 0, 0 } } },
{ .opt_int = &ctx->offset, .name = "offset" },
{ .opt_int = &ctx->limit, .name = "limit" },
{ .opt_int = &ctx->dupe, .name = "duplicate" },
if (ctx->output != OUTPUT_FILES && ctx->output != OUTPUT_MESSAGES &&
ctx->dupe != -1) {
- fprintf (stderr, "Error: --duplicate=N is only supported with --output=files and --output=messages.\n");
- return EXIT_FAILURE;
+ fprintf (stderr, "Error: --duplicate=N is only supported with --output=files and --output=messages.\n");
+ return EXIT_FAILURE;
}
if (_notmuch_search_prepare (ctx, config,
notmuch_opt_desc_t options[] = {
{ .opt_flags = &ctx->output, .name = "output", .keywords =
- (notmuch_keyword_t []){ { "sender", OUTPUT_SENDER },
- { "recipients", OUTPUT_RECIPIENTS },
- { "count", OUTPUT_COUNT },
- { "address", OUTPUT_ADDRESS },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "sender", OUTPUT_SENDER },
+ { "recipients", OUTPUT_RECIPIENTS },
+ { "count", OUTPUT_COUNT },
+ { "address", OUTPUT_ADDRESS },
+ { 0, 0 } } },
{ .opt_keyword = &ctx->exclude, .name = "exclude", .keywords =
- (notmuch_keyword_t []){ { "true", NOTMUCH_EXCLUDE_TRUE },
- { "false", NOTMUCH_EXCLUDE_FALSE },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "true", NOTMUCH_EXCLUDE_TRUE },
+ { "false", NOTMUCH_EXCLUDE_FALSE },
+ { 0, 0 } } },
{ .opt_keyword = &ctx->dedup, .name = "deduplicate", .keywords =
- (notmuch_keyword_t []){ { "no", DEDUP_NONE },
- { "mailbox", DEDUP_MAILBOX },
- { "address", DEDUP_ADDRESS },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "no", DEDUP_NONE },
+ { "mailbox", DEDUP_MAILBOX },
+ { "address", DEDUP_ADDRESS },
+ { 0, 0 } } },
{ .opt_inherit = common_options },
{ .opt_inherit = notmuch_shared_options },
{ }
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");
+ "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");
}
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\". To choose an alternate configuration\n"
-"location, set ${NOTMUCH_CONFIG}.\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");
+ "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\". To choose an alternate configuration\n"
+ "location, set ${NOTMUCH_CONFIG}.\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");
}
static void
print_tag_list (const char **tags, size_t tags_len)
{
unsigned int i;
+
for (i = 0; i < tags_len; i++) {
if (i != 0)
printf (" ");
int
notmuch_setup_command (notmuch_config_t *config,
- unused (int argc), unused (char *argv[]))
+ int argc, char *argv[])
{
char *response = NULL;
size_t response_size = 0;
const char **search_exclude_tags;
size_t search_exclude_tags_len;
-#define prompt(format, ...) \
- do { \
- printf (format, ##__VA_ARGS__); \
- fflush (stdout); \
- if (getline (&response, &response_size, stdin) < 0) { \
- printf ("Exiting.\n"); \
- exit (EXIT_FAILURE); \
- } \
- chomp_newline (response); \
+#define prompt(format, ...) \
+ do { \
+ printf (format, ##__VA_ARGS__); \
+ fflush (stdout); \
+ if (getline (&response, &response_size, stdin) < 0) { \
+ printf ("Exiting.\n"); \
+ exit (EXIT_FAILURE); \
+ } \
+ chomp_newline (response); \
} while (0)
if (notmuch_minimal_options ("setup", argc, argv) < 0)
other_emails = g_ptr_array_new ();
old_other_emails = notmuch_config_get_user_other_email (config,
- &old_other_emails_len);
+ &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 (config, response));
else
g_ptr_array_add (other_emails, talloc_strdup (config,
- old_other_emails[i]));
+ old_other_emails[i]));
}
do {
for (tags = notmuch_message_get_tags (message);
notmuch_tags_valid (tags);
- notmuch_tags_move_to_next (tags))
- {
+ notmuch_tags_move_to_next (tags)) {
tag = notmuch_tags_get (tags);
result = talloc_asprintf_append (result, "%s%s",
from, relative_date, tags);
}
-static const char *_get_disposition(GMimeObject *meta)
+static const char *
+_get_disposition (GMimeObject *meta)
{
GMimeContentDisposition *disposition;
disposition = g_mime_object_get_content_disposition (meta);
- if (!disposition)
+ if (! disposition)
return NULL;
return g_mime_content_disposition_get_disposition (disposition);
g_object_unref (addresses);
return email;
- }
+}
/* Return 1 if 'line' is an mbox From_ line---that is, a line
* beginning with zero or more '>' characters followed by the
charset = g_mime_object_get_content_type_parameter (part, "charset");
charset = charset ? g_mime_charset_canon_name (charset) : NULL;
wrapper = g_mime_part_get_content (GMIME_PART (part));
- if (wrapper && charset && !g_ascii_strncasecmp (charset, "iso-8859-", 9)) {
+ if (wrapper && charset && ! g_ascii_strncasecmp (charset, "iso-8859-", 9)) {
GMimeStream *null_stream = NULL;
GMimeStream *null_stream_filter = NULL;
null_stream = g_mime_stream_null_new ();
null_stream_filter = g_mime_stream_filter_new (null_stream);
windows_filter = g_mime_filter_windows_new (charset);
- g_mime_stream_filter_add(GMIME_STREAM_FILTER (null_stream_filter),
- windows_filter);
+ g_mime_stream_filter_add (GMIME_STREAM_FILTER (null_stream_filter),
+ windows_filter);
g_mime_data_wrapper_write_to_stream (wrapper, null_stream_filter);
- charset = g_mime_filter_windows_real_charset(
+ charset = g_mime_filter_windows_real_charset (
(GMimeFilterWindows *) windows_filter);
if (null_stream_filter)
stream_filter = g_mime_stream_filter_new (stream_out);
crlf_filter = g_mime_filter_dos2unix_new (false);
- g_mime_stream_filter_add(GMIME_STREAM_FILTER (stream_filter),
- crlf_filter);
+ g_mime_stream_filter_add (GMIME_STREAM_FILTER (stream_filter),
+ crlf_filter);
g_object_unref (crlf_filter);
if (charset) {
if (wrapper && stream_filter)
g_mime_data_wrapper_write_to_stream (wrapper, stream_filter);
if (stream_filter)
- g_object_unref(stream_filter);
+ g_object_unref (stream_filter);
if (windows_filter)
g_object_unref (windows_filter);
}
-static const char*
+static const char *
signature_status_to_string (GMimeSignatureStatus status)
{
if (g_mime_signature_status_bad (status))
/* Print signature flags */
struct key_map_struct {
GMimeSignatureStatus bit;
- const char * string;
+ const char *string;
};
static void
do_format_signature_errors (sprinter_t *sp, struct key_map_struct *key_map,
- unsigned int array_map_len, GMimeSignatureStatus errors) {
+ unsigned int array_map_len, GMimeSignatureStatus errors)
+{
sp->map_key (sp, "errors");
sp->begin_map (sp);
{
GMimeSignatureStatus errors = g_mime_signature_get_status (signature);
- if (!(errors & GMIME_SIGNATURE_STATUS_ERROR_MASK))
+ if (! (errors & GMIME_SIGNATURE_STATUS_ERROR_MASK))
return;
struct key_map_struct key_map[] = {
- { GMIME_SIGNATURE_STATUS_KEY_REVOKED, "key-revoked"},
- { GMIME_SIGNATURE_STATUS_KEY_EXPIRED, "key-expired"},
+ { GMIME_SIGNATURE_STATUS_KEY_REVOKED, "key-revoked" },
+ { GMIME_SIGNATURE_STATUS_KEY_EXPIRED, "key-expired" },
{ GMIME_SIGNATURE_STATUS_SIG_EXPIRED, "sig-expired" },
- { GMIME_SIGNATURE_STATUS_KEY_MISSING, "key-missing"},
- { GMIME_SIGNATURE_STATUS_CRL_MISSING, "crl-missing"},
- { GMIME_SIGNATURE_STATUS_CRL_TOO_OLD, "crl-too-old"},
- { GMIME_SIGNATURE_STATUS_BAD_POLICY, "bad-policy"},
- { GMIME_SIGNATURE_STATUS_SYS_ERROR, "sys-error"},
- { GMIME_SIGNATURE_STATUS_TOFU_CONFLICT, "tofu-conflict"},
+ { GMIME_SIGNATURE_STATUS_KEY_MISSING, "key-missing" },
+ { GMIME_SIGNATURE_STATUS_CRL_MISSING, "crl-missing" },
+ { GMIME_SIGNATURE_STATUS_CRL_TOO_OLD, "crl-too-old" },
+ { GMIME_SIGNATURE_STATUS_BAD_POLICY, "bad-policy" },
+ { GMIME_SIGNATURE_STATUS_SYS_ERROR, "sys-error" },
+ { GMIME_SIGNATURE_STATUS_TOFU_CONFLICT, "tofu-conflict" },
};
- do_format_signature_errors (sp, key_map, ARRAY_SIZE(key_map), errors);
+ do_format_signature_errors (sp, key_map, ARRAY_SIZE (key_map), errors);
}
/* Signature status sprinter */
sp->begin_list (sp);
- if (!siglist) {
+ if (! siglist) {
sp->end (sp);
return;
}
}
sp->end (sp);
- }
+ }
sp->end (sp);
}
{
/* The disposition and content-type metadata are associated with
* the envelope for message parts */
- GMimeObject *meta = node->envelope_part ?
- GMIME_OBJECT (node->envelope_part) : node->part;
+ GMimeObject *meta = node->envelope_part ? (
+ GMIME_OBJECT (node->envelope_part) ) : node->part;
GMimeContentType *content_type = g_mime_object_get_content_type (meta);
const bool leaf = GMIME_IS_PART (node->part);
GMimeStream *stream = params->out_stream;
char *content_string;
const char *disposition = _get_disposition (meta);
const char *cid = g_mime_object_get_content_id (meta);
- const char *filename = leaf ?
- g_mime_part_get_filename (GMIME_PART (node->part)) : NULL;
+ const char *filename = leaf ? (
+ g_mime_part_get_filename (GMIME_PART (node->part)) ) : NULL;
if (disposition &&
strcasecmp (disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)
g_mime_stream_printf (stream, "Date: %s\n", date_string);
g_mime_stream_printf (stream, "\fheader}\n");
- if (!params->output_body)
- {
+ if (! params->output_body) {
g_mime_stream_printf (stream, "\f%s}\n", part_type);
return NOTMUCH_STATUS_SUCCESS;
}
if (leaf) {
if (g_mime_content_type_is_type (content_type, "text", "*") &&
(params->include_html ||
- ! g_mime_content_type_is_type (content_type, "text", "html")))
- {
+ ! g_mime_content_type_is_type (content_type, "text", "html"))) {
show_text_part_content (node->part, stream, 0);
} else {
char *content_string = g_mime_content_type_get_mime_type (content_type);
/* The disposition and content-type metadata are associated with
* the envelope for message parts */
- GMimeObject *meta = node->envelope_part ?
- GMIME_OBJECT (node->envelope_part) : node->part;
+ GMimeObject *meta = node->envelope_part ? (
+ GMIME_OBJECT (node->envelope_part) ) : node->part;
GMimeContentType *content_type = g_mime_object_get_content_type (meta);
char *content_string;
const char *disposition = _get_disposition (meta);
const char *cid = g_mime_object_get_content_id (meta);
- const char *filename = GMIME_IS_PART (node->part) ?
- g_mime_part_get_filename (GMIME_PART (node->part)) : NULL;
+ const char *filename = GMIME_IS_PART (node->part) ? (
+ g_mime_part_get_filename (GMIME_PART (node->part) ) ) : NULL;
int nclose = 0;
int i;
*/
if (g_mime_content_type_is_type (content_type, "text", "*") &&
(include_html ||
- ! g_mime_content_type_is_type (content_type, "text", "html")))
- {
+ ! g_mime_content_type_is_type (content_type, "text", "html"))) {
GMimeStream *stream_memory = g_mime_stream_mem_new ();
GByteArray *part_content;
show_text_part_content (node->part, stream_memory, 0);
ssize_t line_size;
ssize_t line_len;
- if (!message)
+ if (! message)
INTERNAL_ERROR ("format_part_mbox requires a root part");
filename = notmuch_message_get_filename (message);
}
while (! g_mime_stream_eos (stream)) {
- ssize = g_mime_stream_read (stream, buf, sizeof(buf));
+ ssize = g_mime_stream_read (stream, buf, sizeof (buf));
if (ssize < 0) {
fprintf (stderr, "Error: Read failed from %s\n", filename);
goto DONE;
ret = NOTMUCH_STATUS_SUCCESS;
/* XXX This DONE is just for the special case of a node in a single file */
- DONE:
+ DONE:
if (stream)
g_object_unref (stream);
for (;
notmuch_messages_valid (messages);
- notmuch_messages_move_to_next (messages))
- {
+ notmuch_messages_move_to_next (messages)) {
sp->begin_list (sp);
message = notmuch_messages_get (messages);
next_indent = indent;
- if ((match && (!excluded || !params->omit_excluded)) || params->entire_thread) {
+ if ((match && (! excluded || ! params->omit_excluded)) || params->entire_thread) {
status = show_message (ctx, format, sp, message, indent, params);
- if (status && !res)
+ if (status && ! res)
res = status;
next_indent = indent + 1;
} else {
notmuch_message_get_replies (message),
next_indent,
params);
- if (status && !res)
+ if (status && ! res)
res = status;
notmuch_message_destroy (message);
notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH, 1);
return show_message (ctx, format, sp, message, 0, params)
- != NOTMUCH_STATUS_SUCCESS;
+ != NOTMUCH_STATUS_SUCCESS;
}
/* Formatted output of threads */
notmuch_messages_t *messages;
notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS;
- status= notmuch_query_search_threads (query, &threads);
+ status = notmuch_query_search_threads (query, &threads);
if (print_status_query ("notmuch show", query, status))
return 1;
sp->begin_list (sp);
- for ( ;
+ for (;
notmuch_threads_valid (threads);
- notmuch_threads_move_to_next (threads))
- {
+ notmuch_threads_move_to_next (threads)) {
thread = notmuch_threads_get (threads);
messages = notmuch_thread_get_toplevel_messages (thread);
notmuch_thread_get_thread_id (thread));
status = show_messages (ctx, format, sp, messages, 0, params);
- if (status && !res)
+ if (status && ! res)
res = status;
notmuch_thread_destroy (thread);
notmuch_opt_desc_t options[] = {
{ .opt_keyword = &format, .name = "format", .keywords =
- (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON },
- { "text", NOTMUCH_FORMAT_TEXT },
- { "sexp", NOTMUCH_FORMAT_SEXP },
- { "mbox", NOTMUCH_FORMAT_MBOX },
- { "raw", NOTMUCH_FORMAT_RAW },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON },
+ { "text", NOTMUCH_FORMAT_TEXT },
+ { "sexp", NOTMUCH_FORMAT_SEXP },
+ { "mbox", NOTMUCH_FORMAT_MBOX },
+ { "raw", NOTMUCH_FORMAT_RAW },
+ { 0, 0 } } },
{ .opt_int = ¬much_format_version, .name = "format-version" },
{ .opt_bool = &exclude, .name = "exclude" },
{ .opt_bool = ¶ms.entire_thread, .name = "entire-thread",
.present = &entire_thread_set },
{ .opt_int = ¶ms.part, .name = "part" },
- { .opt_keyword = (int*)(¶ms.crypto.decrypt), .name = "decrypt",
+ { .opt_keyword = (int *) (¶ms.crypto.decrypt), .name = "decrypt",
.keyword_no_arg_value = "true", .keywords =
- (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
- { "auto", NOTMUCH_DECRYPT_AUTO },
- { "true", NOTMUCH_DECRYPT_NOSTASH },
- { "stash", NOTMUCH_DECRYPT_TRUE },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
+ { "auto", NOTMUCH_DECRYPT_AUTO },
+ { "true", NOTMUCH_DECRYPT_NOSTASH },
+ { "stash", NOTMUCH_DECRYPT_TRUE },
+ { 0, 0 } } },
{ .opt_bool = ¶ms.crypto.verify, .name = "verify" },
{ .opt_bool = ¶ms.output_body, .name = "body" },
{ .opt_bool = ¶ms.include_html, .name = "include-html" },
(format == NOTMUCH_FORMAT_JSON || format == NOTMUCH_FORMAT_SEXP))
params.entire_thread = true;
- if (!params.output_body) {
+ if (! params.output_body) {
if (params.part > 0) {
fprintf (stderr, "Warning: --body=false is incompatible with --part > 0. Disabling.\n");
params.output_body = true;
}
if (params.include_html &&
- (format != NOTMUCH_FORMAT_TEXT &&
+ (format != NOTMUCH_FORMAT_TEXT &&
format != NOTMUCH_FORMAT_JSON &&
format != NOTMUCH_FORMAT_SEXP)) {
fprintf (stderr, "Warning: --include-html only implemented for format=text, format=json and format=sexp\n");
}
- query_string = query_string_from_args (config, argc-opt_index, argv+opt_index);
+ query_string = query_string_from_args (config, argc - opt_index, argv + opt_index);
if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
return EXIT_FAILURE;
/* Create structure printer. */
formatter = formatters[format];
- sprinter = formatter->new_sprinter(config, stdout);
+ sprinter = formatter->new_sprinter (config, stdout);
params.out_stream = g_mime_stream_stdout_new ();
notmuch_status_t status;
search_exclude_tags = notmuch_config_get_search_exclude_tags
- (config, &search_exclude_tags_length);
+ (config, &search_exclude_tags_length);
for (i = 0; i < search_exclude_tags_length; i++) {
status = notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
ret = do_show (config, query, formatter, sprinter, ¶ms);
}
- DONE:
+ DONE:
g_mime_stream_flush (params.out_stream);
g_object_unref (params.out_stream);
*
*/
#define MINUTE (60)
-#define HOUR (60 * MINUTE)
-#define DAY (24 * HOUR)
+#define HOUR (60 *MINUTE)
+#define DAY (24 *HOUR)
#define RELATIVE_DATE_MAX 20
const char *
notmuch_time_relative_date (const void *ctx, time_t then)
{
struct tm tm_now, tm_then;
- time_t now = time(NULL);
+ time_t now = time (NULL);
time_t delta;
char *result;
if (delta <= 7 * DAY) {
if (tm_then.tm_wday == tm_now.tm_wday &&
- delta < DAY)
- {
+ delta < DAY) {
strftime (result, RELATIVE_DATE_MAX,
- "Today %R", &tm_then); /* Today 12:30 */
+ "Today %R", &tm_then); /* Today 12:30 */
return result;
} else if ((tm_now.tm_wday + 7 - tm_then.tm_wday) % 7 == 1) {
strftime (result, RELATIVE_DATE_MAX,
- "Yest. %R", &tm_then); /* Yest. 12:30 */
+ "Yest. %R", &tm_then); /* Yest. 12:30 */
return result;
} else {
if (tm_then.tm_wday != tm_now.tm_wday) {
strftime (result, RELATIVE_DATE_MAX,
- "%a. %R", &tm_then); /* Mon. 12:30 */
+ "%a. %R", &tm_then); /* Mon. 12:30 */
return result;
}
}
}
strftime (result, RELATIVE_DATE_MAX,
- "%B %d", &tm_then); /* October 12 */
+ "%B %d", &tm_then); /* October 12 */
return result;
}
#undef MINUTE
* notmuch_process_shared_options (subcommand_name);
*/
void
-notmuch_process_shared_options (const char *subcommand_name) {
+notmuch_process_shared_options (const char *subcommand_name)
+{
if (print_version) {
- printf ("notmuch " STRINGIFY(NOTMUCH_VERSION) "\n");
+ printf ("notmuch " STRINGIFY (NOTMUCH_VERSION) "\n");
exit (EXIT_SUCCESS);
}
/* This is suitable for subcommands that do not actually open the
* database.
*/
-int notmuch_minimal_options (const char *subcommand_name,
- int argc, char **argv)
+int
+notmuch_minimal_options (const char *subcommand_name,
+ int argc, char **argv)
{
int opt_index;
struct _notmuch_client_indexing_cli_choices indexing_cli_choices = { };
-const notmuch_opt_desc_t notmuch_shared_indexing_options [] = {
+const notmuch_opt_desc_t notmuch_shared_indexing_options [] = {
{ .opt_keyword = &indexing_cli_choices.decrypt_policy,
.present = &indexing_cli_choices.decrypt_policy_set, .keywords =
- (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
- { "true", NOTMUCH_DECRYPT_TRUE },
- { "auto", NOTMUCH_DECRYPT_AUTO },
- { "nostash", NOTMUCH_DECRYPT_NOSTASH },
- { 0, 0 } },
+ (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
+ { "true", NOTMUCH_DECRYPT_TRUE },
+ { "auto", NOTMUCH_DECRYPT_AUTO },
+ { "nostash", NOTMUCH_DECRYPT_NOSTASH },
+ { 0, 0 } },
.name = "decrypt" },
{ }
};
size_t i;
for (i = 0; i < ARRAY_SIZE (commands); i++)
- if ((!name && !commands[i].name) ||
+ if ((! name && ! commands[i].name) ||
(name && commands[i].name && strcmp (name, commands[i].name) == 0))
return &commands[i];
{
const char *uuid = NULL;
- if (!notmuch_requested_db_uuid)
+ if (! notmuch_requested_db_uuid)
return;
IGNORE_RESULT (notmuch_database_get_revision (notmuch, &uuid));
- if (strcmp (notmuch_requested_db_uuid, uuid) != 0){
+ if (strcmp (notmuch_requested_db_uuid, uuid) != 0) {
fprintf (stderr, "Error: requested database revision %s does not match %s\n",
notmuch_requested_db_uuid, uuid);
exit (1);
help_topic_t *topic;
unsigned int i;
- if (!topic_name) {
+ if (! topic_name) {
printf ("The notmuch mail system.\n\n");
usage (stdout);
return EXIT_SUCCESS;
}
static int
-notmuch_help_command (unused (notmuch_config_t * config), int argc, char *argv[])
+notmuch_help_command (unused (notmuch_config_t *config), int argc, char *argv[])
{
int opt_index;
return EXIT_FAILURE;
/* skip at least subcommand argument */
- argc-= opt_index;
- argv+= opt_index;
+ argc -= opt_index;
+ argv += opt_index;
if (argc == 0) {
return _help_for (NULL);
*/
static int
notmuch_command (notmuch_config_t *config,
- unused(int argc), unused(char *argv[]))
+ unused(int argc), unused(char **argv))
{
char *db_path;
struct stat st;
* executed. Return true if external command is not found. Return
* false on errors.
*/
-static bool try_external_command(char *argv[])
+static bool
+try_external_command (char *argv[])
{
char *old_argv0 = argv[0];
bool ret = true;
execvp (argv[0], argv);
if (errno != ENOENT) {
fprintf (stderr, "Error: Running external command '%s' failed: %s\n",
- argv[0], strerror(errno));
+ argv[0], strerror (errno));
ret = false;
}
local = talloc_new (NULL);
g_mime_init ();
-#if !GLIB_CHECK_VERSION(2, 35, 1)
+#if ! GLIB_CHECK_VERSION (2, 35, 1)
g_type_init ();
#endif
command = find_command (command_name);
/* if command->function is NULL, try external command */
- if (!command || !command->function) {
+ if (! command || ! command->function) {
/* This won't return if the external command is found. */
- if (try_external_command(argv + opt_index))
+ if (try_external_command (argv + opt_index))
fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch help\")\n",
command_name);
ret = EXIT_FAILURE;
}
config = notmuch_config_open (local, config_file_name, command->config_mode);
- if (!config) {
+ if (! config) {
ret = EXIT_FAILURE;
goto DONE;
}
/* XXX: Redefine these to add i18n support. The keyword table uses
* N_() to mark strings to be translated; they are accessed
* dynamically using _(). */
-#define _(s) (s) /* i18n: define as gettext (s) */
-#define N_(s) (s) /* i18n: define as gettext_noop (s) */
+#define _(s) (s) /* i18n: define as gettext (s) */
+#define N_(s) (s) /* i18n: define as gettext_noop (s) */
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
*/
enum field {
/* Keep SEC...YEAR in this order. */
- TM_ABS_SEC, /* seconds */
- TM_ABS_MIN, /* minutes */
- TM_ABS_HOUR, /* hours */
- TM_ABS_MDAY, /* day of the month */
- TM_ABS_MON, /* month */
- TM_ABS_YEAR, /* year */
+ TM_ABS_SEC, /* seconds */
+ TM_ABS_MIN, /* minutes */
+ TM_ABS_HOUR, /* hours */
+ TM_ABS_MDAY, /* day of the month */
+ TM_ABS_MON, /* month */
+ TM_ABS_YEAR, /* year */
- TM_WDAY, /* day of the week. special: may be relative */
- TM_ABS_ISDST, /* daylight saving time */
+ TM_WDAY, /* day of the week. special: may be relative */
+ TM_ABS_ISDST, /* daylight saving time */
- TM_AMPM, /* am vs. pm */
- TM_TZ, /* timezone in minutes */
+ TM_AMPM, /* am vs. pm */
+ TM_TZ, /* timezone in minutes */
/* Keep SEC...YEAR in this order. */
- TM_REL_SEC, /* seconds relative to absolute or reference time */
- TM_REL_MIN, /* minutes ... */
- TM_REL_HOUR, /* hours ... */
- TM_REL_DAY, /* days ... */
- TM_REL_MON, /* months ... */
- TM_REL_YEAR, /* years ... */
- TM_REL_WEEK, /* weeks ... */
-
- TM_NONE, /* not a field */
-
- TM_SIZE = TM_NONE,
- TM_FIRST_ABS = TM_ABS_SEC,
- TM_FIRST_REL = TM_REL_SEC,
+ TM_REL_SEC, /* seconds relative to absolute or reference time */
+ TM_REL_MIN, /* minutes ... */
+ TM_REL_HOUR, /* hours ... */
+ TM_REL_DAY, /* days ... */
+ TM_REL_MON, /* months ... */
+ TM_REL_YEAR, /* years ... */
+ TM_REL_WEEK, /* weeks ... */
+
+ TM_NONE, /* not a field */
+
+ TM_SIZE = TM_NONE,
+ TM_FIRST_ABS = TM_ABS_SEC,
+ TM_FIRST_REL = TM_REL_SEC,
};
/* Values for the set array of struct state. */
enum field_set {
- FIELD_UNSET, /* The field has not been touched by parser. */
- FIELD_SET, /* The field has been set by parser. */
- FIELD_NOW, /* The field will be set to reference time. */
+ FIELD_UNSET, /* The field has not been touched by parser. */
+ FIELD_SET, /* The field has been set by parser. */
+ FIELD_NOW, /* The field will be set to reference time. */
};
static enum field
/* The parsing state. */
struct state {
- int tm[TM_SIZE]; /* parsed date and time */
- enum field_set set[TM_SIZE]; /* set status of tm */
+ int tm[TM_SIZE]; /* parsed date and time */
+ enum field_set set[TM_SIZE]; /* set status of tm */
- enum field last_field; /* Previously set field. */
+ enum field last_field; /* Previously set field. */
char delim;
- int postponed_length; /* Number of digits in postponed value. */
+ int postponed_length; /* Number of digits in postponed value. */
int postponed_value;
- char postponed_delim; /* The delimiter preceding postponed number. */
+ char postponed_delim; /* The delimiter preceding postponed number. */
};
/*
static bool
consume_postponed_number (struct state *state, int *v, int *n, char *d)
{
- if (!state->postponed_length)
+ if (! state->postponed_length)
return false;
if (n)
/*
* Validity checkers.
*/
-static bool is_valid_12hour (int h)
+static bool
+is_valid_12hour (int h)
{
return h >= 1 && h <= 12;
}
-static bool is_valid_time (int h, int m, int s)
+static bool
+is_valid_time (int h, int m, int s)
{
/* Allow 24:00:00 to denote end of day. */
if (h == 24 && m == 0 && s == 0)
return h >= 0 && h <= 23 && m >= 0 && m <= 59 && s >= 0 && s <= 59;
}
-static bool is_valid_mday (int mday)
+static bool
+is_valid_mday (int mday)
{
return mday >= 1 && mday <= 31;
}
-static bool is_valid_mon (int mon)
+static bool
+is_valid_mon (int mon)
{
return mon >= 1 && mon <= 12;
}
-static bool is_valid_year (int year)
+static bool
+is_valid_year (int year)
{
return year >= 1970;
}
-static bool is_valid_date (int year, int mon, int mday)
+static bool
+is_valid_date (int year, int mon, int mday)
{
return is_valid_year (year) && is_valid_mon (mon) && is_valid_mday (mday);
}
typedef int (*setter_t)(struct state *state, struct keyword *kw);
struct keyword {
- const char *name; /* keyword */
- enum field field; /* field to set, or FIELD_NONE if N/A */
- int value; /* value to set, or 0 if N/A */
- setter_t set; /* function to use for setting, if non-NULL */
+ const char *name; /* keyword */
+ enum field field; /* field to set, or FIELD_NONE if N/A */
+ int value; /* value to set, or 0 if N/A */
+ setter_t set; /* function to use for setting, if non-NULL */
};
/*
consume_postponed_number (state, &v, NULL, NULL);
- if (!is_valid_mday (v))
+ if (! is_valid_mday (v))
return -PARSE_TIME_ERR_INVALIDDATE;
r = set_field (state, TM_ABS_MDAY, v);
consume_postponed_number (state, &v, NULL, NULL);
- if (!is_valid_12hour (v))
+ if (! is_valid_12hour (v))
return -PARSE_TIME_ERR_INVALIDTIME;
r = set_abs_time (state, v, 0, 0);
int n, v;
/* Require a postponed number. */
- if (!consume_postponed_number (state, &v, &n, NULL))
+ if (! consume_postponed_number (state, &v, &n, NULL))
return -PARSE_TIME_ERR_DATEFORMAT;
/* Ordinals are mday. */
return -PARSE_TIME_ERR_INVALIDDATE;
else if (strcasecmp (kw->name, "rd") == 0 && v != 3 && v != 23)
return -PARSE_TIME_ERR_INVALIDDATE;
- else if (strcasecmp (kw->name, "th") == 0 && !is_valid_mday (v))
+ else if (strcasecmp (kw->name, "th") == 0 && ! is_valid_mday (v))
return -PARSE_TIME_ERR_INVALIDDATE;
return set_field (state, TM_ABS_MDAY, v);
*/
static struct keyword keywords[] = {
/* Weekdays. */
- { N_("sun|day"), TM_WDAY, 0, NULL },
- { N_("mon|day"), TM_WDAY, 1, NULL },
- { N_("tue|sday"), TM_WDAY, 2, NULL },
- { N_("wed|nesday"), TM_WDAY, 3, NULL },
- { N_("thu|rsday"), TM_WDAY, 4, NULL },
- { N_("fri|day"), TM_WDAY, 5, NULL },
- { N_("sat|urday"), TM_WDAY, 6, NULL },
+ { N_ ("sun|day"), TM_WDAY, 0, NULL },
+ { N_ ("mon|day"), TM_WDAY, 1, NULL },
+ { N_ ("tue|sday"), TM_WDAY, 2, NULL },
+ { N_ ("wed|nesday"), TM_WDAY, 3, NULL },
+ { N_ ("thu|rsday"), TM_WDAY, 4, NULL },
+ { N_ ("fri|day"), TM_WDAY, 5, NULL },
+ { N_ ("sat|urday"), TM_WDAY, 6, NULL },
/* Months. */
- { N_("jan|uary"), TM_ABS_MON, 1, kw_set_month },
- { N_("feb|ruary"), TM_ABS_MON, 2, kw_set_month },
- { N_("mar|ch"), TM_ABS_MON, 3, kw_set_month },
- { N_("apr|il"), TM_ABS_MON, 4, kw_set_month },
- { N_("may"), TM_ABS_MON, 5, kw_set_month },
- { N_("jun|e"), TM_ABS_MON, 6, kw_set_month },
- { N_("jul|y"), TM_ABS_MON, 7, kw_set_month },
- { N_("aug|ust"), TM_ABS_MON, 8, kw_set_month },
- { N_("sep|tember"), TM_ABS_MON, 9, kw_set_month },
- { N_("oct|ober"), TM_ABS_MON, 10, kw_set_month },
- { N_("nov|ember"), TM_ABS_MON, 11, kw_set_month },
- { N_("dec|ember"), TM_ABS_MON, 12, kw_set_month },
+ { N_ ("jan|uary"), TM_ABS_MON, 1, kw_set_month },
+ { N_ ("feb|ruary"), TM_ABS_MON, 2, kw_set_month },
+ { N_ ("mar|ch"), TM_ABS_MON, 3, kw_set_month },
+ { N_ ("apr|il"), TM_ABS_MON, 4, kw_set_month },
+ { N_ ("may"), TM_ABS_MON, 5, kw_set_month },
+ { N_ ("jun|e"), TM_ABS_MON, 6, kw_set_month },
+ { N_ ("jul|y"), TM_ABS_MON, 7, kw_set_month },
+ { N_ ("aug|ust"), TM_ABS_MON, 8, kw_set_month },
+ { N_ ("sep|tember"), TM_ABS_MON, 9, kw_set_month },
+ { N_ ("oct|ober"), TM_ABS_MON, 10, kw_set_month },
+ { N_ ("nov|ember"), TM_ABS_MON, 11, kw_set_month },
+ { N_ ("dec|ember"), TM_ABS_MON, 12, kw_set_month },
/* Durations. */
- { N_("y|ears"), TM_REL_YEAR, 1, kw_set_rel },
- { N_("mo|nths"), TM_REL_MON, 1, kw_set_rel },
- { N_("*M"), TM_REL_MON, 1, kw_set_rel },
- { N_("w|eeks"), TM_REL_WEEK, 1, kw_set_rel },
- { N_("d|ays"), TM_REL_DAY, 1, kw_set_rel },
- { N_("h|ours"), TM_REL_HOUR, 1, kw_set_rel },
- { N_("hr|s"), TM_REL_HOUR, 1, kw_set_rel },
- { N_("mi|nutes"), TM_REL_MIN, 1, kw_set_rel },
- { N_("mins"), TM_REL_MIN, 1, kw_set_rel },
- { N_("*m"), TM_REL_MIN, 1, kw_set_rel },
- { N_("s|econds"), TM_REL_SEC, 1, kw_set_rel },
- { N_("secs"), TM_REL_SEC, 1, kw_set_rel },
+ { N_ ("y|ears"), TM_REL_YEAR, 1, kw_set_rel },
+ { N_ ("mo|nths"), TM_REL_MON, 1, kw_set_rel },
+ { N_ ("*M"), TM_REL_MON, 1, kw_set_rel },
+ { N_ ("w|eeks"), TM_REL_WEEK, 1, kw_set_rel },
+ { N_ ("d|ays"), TM_REL_DAY, 1, kw_set_rel },
+ { N_ ("h|ours"), TM_REL_HOUR, 1, kw_set_rel },
+ { N_ ("hr|s"), TM_REL_HOUR, 1, kw_set_rel },
+ { N_ ("mi|nutes"), TM_REL_MIN, 1, kw_set_rel },
+ { N_ ("mins"), TM_REL_MIN, 1, kw_set_rel },
+ { N_ ("*m"), TM_REL_MIN, 1, kw_set_rel },
+ { N_ ("s|econds"), TM_REL_SEC, 1, kw_set_rel },
+ { N_ ("secs"), TM_REL_SEC, 1, kw_set_rel },
/* Numbers. */
- { N_("one"), TM_NONE, 1, kw_set_number },
- { N_("two"), TM_NONE, 2, kw_set_number },
- { N_("three"), TM_NONE, 3, kw_set_number },
- { N_("four"), TM_NONE, 4, kw_set_number },
- { N_("five"), TM_NONE, 5, kw_set_number },
- { N_("six"), TM_NONE, 6, kw_set_number },
- { N_("seven"), TM_NONE, 7, kw_set_number },
- { N_("eight"), TM_NONE, 8, kw_set_number },
- { N_("nine"), TM_NONE, 9, kw_set_number },
- { N_("ten"), TM_NONE, 10, kw_set_number },
- { N_("dozen"), TM_NONE, 12, kw_set_number },
- { N_("hundred"), TM_NONE, 100, kw_set_number },
+ { N_ ("one"), TM_NONE, 1, kw_set_number },
+ { N_ ("two"), TM_NONE, 2, kw_set_number },
+ { N_ ("three"), TM_NONE, 3, kw_set_number },
+ { N_ ("four"), TM_NONE, 4, kw_set_number },
+ { N_ ("five"), TM_NONE, 5, kw_set_number },
+ { N_ ("six"), TM_NONE, 6, kw_set_number },
+ { N_ ("seven"), TM_NONE, 7, kw_set_number },
+ { N_ ("eight"), TM_NONE, 8, kw_set_number },
+ { N_ ("nine"), TM_NONE, 9, kw_set_number },
+ { N_ ("ten"), TM_NONE, 10, kw_set_number },
+ { N_ ("dozen"), TM_NONE, 12, kw_set_number },
+ { N_ ("hundred"), TM_NONE, 100, kw_set_number },
/* Special number forms. */
- { N_("this"), TM_NONE, 0, kw_set_number },
- { N_("last"), TM_NONE, 1, kw_set_number },
+ { N_ ("this"), TM_NONE, 0, kw_set_number },
+ { N_ ("last"), TM_NONE, 1, kw_set_number },
/* Other special keywords. */
- { N_("yesterday"), TM_REL_DAY, 1, kw_set_rel },
- { N_("today"), TM_NONE, 0, kw_set_today },
- { N_("now"), TM_NONE, 0, kw_set_now },
- { N_("noon"), TM_NONE, 12, kw_set_timeofday },
- { N_("midnight"), TM_NONE, 0, kw_set_timeofday },
- { N_("am"), TM_AMPM, 0, kw_set_ampm },
- { N_("a.m."), TM_AMPM, 0, kw_set_ampm },
- { N_("pm"), TM_AMPM, 1, kw_set_ampm },
- { N_("p.m."), TM_AMPM, 1, kw_set_ampm },
- { N_("st"), TM_NONE, 0, kw_set_ordinal },
- { N_("nd"), TM_NONE, 0, kw_set_ordinal },
- { N_("rd"), TM_NONE, 0, kw_set_ordinal },
- { N_("th"), TM_NONE, 0, kw_set_ordinal },
- { N_("ago"), TM_NONE, 0, kw_ignore },
+ { N_ ("yesterday"), TM_REL_DAY, 1, kw_set_rel },
+ { N_ ("today"), TM_NONE, 0, kw_set_today },
+ { N_ ("now"), TM_NONE, 0, kw_set_now },
+ { N_ ("noon"), TM_NONE, 12, kw_set_timeofday },
+ { N_ ("midnight"), TM_NONE, 0, kw_set_timeofday },
+ { N_ ("am"), TM_AMPM, 0, kw_set_ampm },
+ { N_ ("a.m."), TM_AMPM, 0, kw_set_ampm },
+ { N_ ("pm"), TM_AMPM, 1, kw_set_ampm },
+ { N_ ("p.m."), TM_AMPM, 1, kw_set_ampm },
+ { N_ ("st"), TM_NONE, 0, kw_set_ordinal },
+ { N_ ("nd"), TM_NONE, 0, kw_set_ordinal },
+ { N_ ("rd"), TM_NONE, 0, kw_set_ordinal },
+ { N_ ("th"), TM_NONE, 0, kw_set_ordinal },
+ { N_ ("ago"), TM_NONE, 0, kw_ignore },
/* Timezone codes: offset in minutes. XXX: Add more codes. */
- { N_("pst"), TM_TZ, -8*60, NULL },
- { N_("mst"), TM_TZ, -7*60, NULL },
- { N_("cst"), TM_TZ, -6*60, NULL },
- { N_("est"), TM_TZ, -5*60, NULL },
- { N_("ast"), TM_TZ, -4*60, NULL },
- { N_("nst"), TM_TZ, -(3*60+30), NULL },
-
- { N_("gmt"), TM_TZ, 0, NULL },
- { N_("utc"), TM_TZ, 0, NULL },
-
- { N_("wet"), TM_TZ, 0, NULL },
- { N_("cet"), TM_TZ, 1*60, NULL },
- { N_("eet"), TM_TZ, 2*60, NULL },
- { N_("fet"), TM_TZ, 3*60, NULL },
-
- { N_("wat"), TM_TZ, 1*60, NULL },
- { N_("cat"), TM_TZ, 2*60, NULL },
- { N_("eat"), TM_TZ, 3*60, NULL },
+ { N_ ("pst"), TM_TZ, -8 * 60, NULL },
+ { N_ ("mst"), TM_TZ, -7 * 60, NULL },
+ { N_ ("cst"), TM_TZ, -6 * 60, NULL },
+ { N_ ("est"), TM_TZ, -5 * 60, NULL },
+ { N_ ("ast"), TM_TZ, -4 * 60, NULL },
+ { N_ ("nst"), TM_TZ, -(3 * 60 + 30), NULL },
+
+ { N_ ("gmt"), TM_TZ, 0, NULL },
+ { N_ ("utc"), TM_TZ, 0, NULL },
+
+ { N_ ("wet"), TM_TZ, 0, NULL },
+ { N_ ("cet"), TM_TZ, 1 * 60, NULL },
+ { N_ ("eet"), TM_TZ, 2 * 60, NULL },
+ { N_ ("fet"), TM_TZ, 3 * 60, NULL },
+
+ { N_ ("wat"), TM_TZ, 1 * 60, NULL },
+ { N_ ("cat"), TM_TZ, 2 * 60, NULL },
+ { N_ ("eat"), TM_TZ, 3 * 60, NULL },
};
/*
keyword++;
}
- if (!*s || !isalpha ((unsigned char) *s) || !*keyword)
+ if (! *s || ! isalpha ((unsigned char) *s) || ! *keyword)
break;
if (match_case) {
return 0;
/* did not match enough of keyword */
- if (*keyword && !prefix_matched)
+ if (*keyword && ! prefix_matched)
return 0;
return s - str;
int r;
for (i = 0; i < ARRAY_SIZE (keywords); i++) {
- const char *keyword = _(keywords[i].name);
+ const char *keyword = _ (keywords[i].name);
bool mcase = false;
/* Match case if keyword begins with '*'. */
}
}
- if (!kw)
+ if (! kw)
return -PARSE_TIME_ERR_KEYWORD;
if (kw->set)
char d;
/* Bail out if there's no postponed number. */
- if (!consume_postponed_number (state, &v, &n, &d))
+ if (! consume_postponed_number (state, &v, &n, &d))
return 0;
if (n == 1 || n == 2) {
* handles "January 20". */
if (state->last_field == TM_ABS_MON) {
/* D[D] */
- if (!is_valid_mday (v))
+ if (! is_valid_mday (v))
return -PARSE_TIME_ERR_INVALIDDATE;
return set_field (state, TM_ABS_MDAY, v);
/* Notable exception: Value affects parsing. Time zones are
* always at most 1400 and we don't understand years before
* 1970. */
- if (!is_valid_year (v)) {
+ if (! is_valid_year (v)) {
if (d == '+' || d == '-') {
/* +/-HHMM */
return set_user_tz (state, d, v / 100, v % 100);
int min = (v / 100) % 100;
int sec = v % 100;
- if (!is_valid_time (hour, min, sec))
+ if (! is_valid_time (hour, min, sec))
return -PARSE_TIME_ERR_INVALIDTIME;
return set_abs_time (state, hour, min, sec);
int mon = (v / 100) % 100;
int mday = v % 100;
- if (!is_valid_date (year, mon, mday))
+ if (! is_valid_date (year, mon, mday))
return -PARSE_TIME_ERR_INVALIDDATE;
return set_abs_date (state, year, mon, mday);
break;
}
- if (year != UNSET && !is_valid_year (year))
+ if (year != UNSET && ! is_valid_year (year))
return -PARSE_TIME_ERR_INVALIDDATE;
- if (mon != UNSET && !is_valid_mon (mon))
+ if (mon != UNSET && ! is_valid_mon (mon))
return -PARSE_TIME_ERR_INVALIDDATE;
- if (mday != UNSET && !is_valid_mday (mday))
+ if (mday != UNSET && ! is_valid_mday (mday))
return -PARSE_TIME_ERR_INVALIDDATE;
return set_abs_date (state, year, mon, mday);
return set_user_tz (state, state->delim, v1, v2);
}
- if (!is_valid_time (v1, v2, n3 ? v3 : 0))
+ if (! is_valid_time (v1, v2, n3 ? v3 : 0))
return -PARSE_TIME_ERR_INVALIDTIME;
return set_abs_time (state, v1, v2, n3 ? (int) v3 : UNSET);
v1 = strtoul_len (p, &p, &n1);
- if (!is_sep (*p) || !isdigit ((unsigned char) *(p + 1))) {
+ if (! is_sep (*p) || ! isdigit ((unsigned char) *(p + 1))) {
/* A single number. */
r = parse_single_number (state, v1, n1);
if (r)
* Skip non-alpha and non-digit, and store the last for further
* processing.
*/
- while (*p && !isalnum ((unsigned char) *p)) {
+ while (*p && ! isalnum ((unsigned char) *p)) {
set_delim (state, *p);
p++;
}
if (t == (time_t) -1)
return -PARSE_TIME_ERR_LIB;
- if (!localtime_r (&t, tm))
+ if (! localtime_r (&t, tm))
return -PARSE_TIME_ERR_LIB;
return 0;
tm_get_field (const struct tm *tm, enum field field)
{
switch (field) {
- case TM_ABS_SEC: return tm->tm_sec;
- case TM_ABS_MIN: return tm->tm_min;
- case TM_ABS_HOUR: return tm->tm_hour;
- case TM_ABS_MDAY: return tm->tm_mday;
- case TM_ABS_MON: return tm->tm_mon + 1; /* 0- to 1-based */
- case TM_ABS_YEAR: return 1900 + tm->tm_year;
- case TM_WDAY: return tm->tm_wday;
- case TM_ABS_ISDST: return tm->tm_isdst;
+ case TM_ABS_SEC: return tm->tm_sec;
+ case TM_ABS_MIN: return tm->tm_min;
+ case TM_ABS_HOUR: return tm->tm_hour;
+ case TM_ABS_MDAY: return tm->tm_mday;
+ case TM_ABS_MON: return tm->tm_mon + 1; /* 0- to 1-based */
+ case TM_ABS_YEAR: return 1900 + tm->tm_year;
+ case TM_WDAY: return tm->tm_wday;
+ case TM_ABS_ISDST: return tm->tm_isdst;
default:
assert (false);
break;
{
int hour, hdiff = 0;
- if (!is_field_set (state, TM_AMPM))
+ if (! is_field_set (state, TM_AMPM))
return 0;
- if (!is_field_set (state, TM_ABS_HOUR))
+ if (! is_field_set (state, TM_ABS_HOUR))
return -PARSE_TIME_ERR_TIMEFORMAT;
hour = get_field (state, TM_ABS_HOUR);
- if (!is_valid_12hour (hour))
+ if (! is_valid_12hour (hour))
return -PARSE_TIME_ERR_INVALIDTIME;
if (get_field (state, TM_AMPM)) {
* date?
*/
if (is_field_set (state, TM_WDAY) &&
- !is_field_set (state, TM_ABS_MDAY)) {
+ ! is_field_set (state, TM_ABS_MDAY)) {
int wday = get_field (state, TM_WDAY);
int today = tm_get_field (&now, TM_WDAY);
int rel_days;
}
}
- if (!is_field_set (state, f))
+ if (! is_field_set (state, f))
set_field (state, f, tm_get_field (&now, f));
}
struct state state = { .last_field = TM_NONE };
int r;
- if (!s || !t)
+ if (! s || ! t)
return EXTERNAL_ERR (-PARSE_TIME_ERR);
r = parse_input (&state, s);
/* return values for parse_time_string() */
enum {
PARSE_TIME_OK = 0,
- PARSE_TIME_ERR, /* unspecified error */
- PARSE_TIME_ERR_LIB, /* library call failed */
- PARSE_TIME_ERR_ALREADYSET, /* attempt to set unit twice */
- PARSE_TIME_ERR_FORMAT, /* generic date/time format error */
- PARSE_TIME_ERR_DATEFORMAT, /* date format error */
- PARSE_TIME_ERR_TIMEFORMAT, /* time format error */
- PARSE_TIME_ERR_INVALIDDATE, /* date value error */
- PARSE_TIME_ERR_INVALIDTIME, /* time value error */
- PARSE_TIME_ERR_KEYWORD, /* unknown keyword */
+ PARSE_TIME_ERR, /* unspecified error */
+ PARSE_TIME_ERR_LIB, /* library call failed */
+ PARSE_TIME_ERR_ALREADYSET, /* attempt to set unit twice */
+ PARSE_TIME_ERR_FORMAT, /* generic date/time format error */
+ PARSE_TIME_ERR_DATEFORMAT, /* date format error */
+ PARSE_TIME_ERR_TIMEFORMAT, /* time format error */
+ PARSE_TIME_ERR_INVALIDDATE, /* date value error */
+ PARSE_TIME_ERR_INVALIDTIME, /* time value error */
+ PARSE_TIME_ERR_KEYWORD, /* unknown keyword */
};
/* round values for parse_time_string() */
enum {
- PARSE_TIME_ROUND_DOWN = -1,
- PARSE_TIME_NO_ROUND = 0,
- PARSE_TIME_ROUND_UP = 1,
- PARSE_TIME_ROUND_UP_INCLUSIVE = 2,
+ PARSE_TIME_ROUND_DOWN = -1,
+ PARSE_TIME_NO_ROUND = 0,
+ PARSE_TIME_ROUND_UP = 1,
+ PARSE_TIME_ROUND_UP_INCLUSIVE = 2,
};
/**
-#!/bin/bash
+#!/usr/bin/env bash
test_description='notmuch new'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='dump and restore'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='show'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='search'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='search'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='reindex'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='search'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='notmuch new'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='dump and restore'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='tagging'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='reindexing'
-#!/bin/bash
+#!/usr/bin/env bash
test_description='thread subqueries'
* a sequence of alternating calls to map_key and one of the
* value-printing functions until the map is ended by end.
*/
- void (*begin_map) (struct sprinter *);
+ void (*begin_map)(struct sprinter *);
/* Start a new list/array structure.
*/
- void (*begin_list) (struct sprinter *);
+ void (*begin_list)(struct sprinter *);
/* End the last opened list or map structure.
*/
- void (*end) (struct sprinter *);
+ void (*end)(struct sprinter *);
/* Print one string/integer/boolean/null element (possibly inside
* a list or map, followed or preceded by separators). For string
* string (but not string_len) the string pointer passed may be
* NULL.
*/
- void (*string) (struct sprinter *, const char *);
- void (*string_len) (struct sprinter *, const char *, size_t);
- void (*integer) (struct sprinter *, int);
- void (*boolean) (struct sprinter *, bool);
- void (*null) (struct sprinter *);
+ void (*string)(struct sprinter *, const char *);
+ void (*string_len)(struct sprinter *, const char *, size_t);
+ void (*integer)(struct sprinter *, int);
+ void (*boolean)(struct sprinter *, bool);
+ void (*null)(struct sprinter *);
/* Print the key of a map's key/value pair. The char * must be UTF-8
* encoded.
*/
- void (*map_key) (struct sprinter *, const char *);
+ void (*map_key)(struct sprinter *, const char *);
/* Insert a separator (usually extra whitespace). For the text
* printers, this is a syntactic separator. For the structured
* the abstract syntax of the structure being printed. For JSON,
* this could simply be a line break.
*/
- void (*separator) (struct sprinter *);
+ void (*separator)(struct sprinter *);
/* Set the current string prefix. This only affects the text
* printer, which will print this string, followed by a colon,
* before any string. For other printers, this does nothing.
*/
- void (*set_prefix) (struct sprinter *, const char *);
+ void (*set_prefix)(struct sprinter *, const char *);
/* True if this is the special-cased plain text printer.
*/
notmuch_status_t
print_status_database (const char *loc,
- const notmuch_database_t *notmuch,
- notmuch_status_t status)
+ const notmuch_database_t *notmuch,
+ notmuch_status_t status)
{
if (status) {
const char *msg;
/* Use powers of 2 */
typedef enum {
- TAG_FLAG_NONE = 0,
+ TAG_FLAG_NONE = 0,
/* Operations are synced to maildir, if possible.
*/
- TAG_FLAG_MAILDIR_SYNC = (1 << 0),
+ TAG_FLAG_MAILDIR_SYNC = (1 << 0),
/* Remove all tags from message before applying list.
*/
- TAG_FLAG_REMOVE_ALL = (1 << 1),
+ TAG_FLAG_REMOVE_ALL = (1 << 1),
/* Don't try to avoid database operations. Useful when we
* know that message passed needs these operations.
*/
- TAG_FLAG_PRE_OPTIMIZED = (1 << 2),
+ TAG_FLAG_PRE_OPTIMIZED = (1 << 2),
/* Accept strange tags that might be user error;
* intended for use by notmuch-restore.
*/
- TAG_FLAG_BE_GENEROUS = (1 << 3)
+ TAG_FLAG_BE_GENEROUS = (1 << 3)
} tag_op_flag_t;
* skipped lines are positive.
*/
typedef enum {
- TAG_PARSE_OUT_OF_MEMORY = -1,
+ TAG_PARSE_OUT_OF_MEMORY = -1,
/* Line parsed successfully. */
- TAG_PARSE_SUCCESS = 0,
+ TAG_PARSE_SUCCESS = 0,
/* Line has a syntax error */
- TAG_PARSE_INVALID = 1,
+ TAG_PARSE_INVALID = 1,
/* Line was blank or a comment */
- TAG_PARSE_SKIPPED = 2
+ TAG_PARSE_SKIPPED = 2
} tag_parse_status_t;
test_description='"notmuch insert"'
. $(dirname "$0")/test-lib.sh || exit 1
-test_require_external_prereq gdb
-
# subtests about file permissions assume that we're working with umask
# 022 by default.
umask 022
notmuch config set new.tags $OLDCONFIG
# DUPLICATE_MESSAGE_ID is not tested here, because it should actually pass.
-
-for code in OUT_OF_MEMORY XAPIAN_EXCEPTION FILE_NOT_EMAIL \
- READ_ONLY_DATABASE UPGRADE_REQUIRED PATH_ERROR; do
-cat <<EOF > index-file-$code.gdb
-set breakpoint pending on
-set logging file index-file-$code.log
-set logging on
-break notmuch_database_index_file
-commands
-return NOTMUCH_STATUS_$code
-continue
-end
-run
+# pregenerate all of the test shims
+for code in FILE_NOT_EMAIL READ_ONLY_DATABASE UPGRADE_REQUIRED PATH_ERROR OUT_OF_MEMORY XAPIAN_EXCEPTION; do
+ make_shim shim-$code <<EOF
+#include <notmuch.h>
+#include <stdio.h>
+notmuch_status_t
+notmuch_database_index_file (notmuch_database_t *notmuch,
+ const char *filename,
+ notmuch_indexopts_t *indexopts,
+ notmuch_message_t **message_ret)
+{
+ return NOTMUCH_STATUS_$code;
+}
EOF
done
for code in FILE_NOT_EMAIL READ_ONLY_DATABASE UPGRADE_REQUIRED PATH_ERROR; do
test_begin_subtest "EXIT_FAILURE when index_file returns $code"
- test_expect_code 1 \
- "${TEST_GDB} --batch-silent --return-child-result \
- -ex 'set args insert < $gen_msg_filename' \
- -x index-file-$code.gdb notmuch"
+ test_expect_code 1 "notmuch_with_shim shim-$code insert < \"$gen_msg_filename\""
test_begin_subtest "success exit with --keep when index_file returns $code"
- test_expect_code 0 \
- "${TEST_GDB} --batch-silent --return-child-result \
- -ex 'set args insert --keep < $gen_msg_filename' \
- -x index-file-$code.gdb notmuch"
+ test_expect_code 0 "notmuch_with_shim shim-$code insert --keep < \"$gen_msg_filename\""
done
for code in OUT_OF_MEMORY XAPIAN_EXCEPTION ; do
test_begin_subtest "EX_TEMPFAIL when index_file returns $code"
- test_expect_code 75 \
- "${TEST_GDB} --batch-silent --return-child-result \
- -ex 'set args insert < $gen_msg_filename' \
- -x index-file-$code.gdb notmuch"
+ test_expect_code 75 "notmuch_with_shim shim-$code insert < \"$gen_msg_filename\""
test_begin_subtest "success exit with --keep when index_file returns $code"
- test_expect_code 0 \
- "${TEST_GDB} --batch-silent --return-child-result \
- -ex 'set args insert --keep < $gen_msg_filename' \
- -x index-file-$code.gdb notmuch"
+ test_expect_code 0 "notmuch_with_shim shim-$code insert --keep < \"$gen_msg_filename\""
done
test_done
--- /dev/null
+#!/usr/bin/env bash
+
+test_description='PGP/MIME message mangling'
+. $(dirname "$0")/test-lib.sh || exit 1
+
+add_gnupg_home
+add_email_corpus mangling
+
+bodytext='["body"][0]["content"][1]["content"]="The password is \"abcd1234!\", please do not tell anyone.\n"'
+
+test_begin_subtest "show 'Mixed-Up' mangled PGP/MIME message correctly"
+output=$(notmuch show --format=json --decrypt=true id:mixed-up@mangling.notmuchmail.org)
+test_json_nodes <<<"$output" \
+ 'body:[0][0][0]'"$bodytext"
+
+test_begin_subtest "reply to 'Mixed-Up' mangled PGP/MIME message correctly"
+output=$(notmuch reply --format=json --decrypt=true id:mixed-up@mangling.notmuchmail.org)
+test_json_nodes <<<"$output" \
+ 'body:["original"]'"$bodytext"
+
+test_begin_subtest "repaired 'Mixed-up' messages can be found with index.repaired=mixedup"
+output=$(notmuch search --output=messages property:index.repaired=mixedup)
+test_expect_equal "$output" id:mixed-up@mangling.notmuchmail.org
+
+test_begin_subtest "index cleartext of 'Mixed-Up' mangled PGP/MIME message"
+test_expect_success 'notmuch reindex --decrypt=true id:mixed-up@mangling.notmuchmail.org'
+
+test_begin_subtest "search cleartext of 'Mixed-Up' mangled PGP/MIME message"
+output=$(notmuch search --output=messages body:password)
+test_expect_equal "$output" id:mixed-up@mangling.notmuchmail.org
+
+test_done
id:protected-header@crypto.notmuchmail.org
id:subjectless-protected-header@crypto.notmuchmail.org'
+test_begin_subtest "when rendering protected headers, avoid rendering legacy-display part"
+output=$(notmuch show --format=json id:protected-with-legacy-display@crypto.notmuchmail.org)
+test_json_nodes <<<"$output" \
+ 'subject:[0][0][0]["headers"]["Subject"]="Interrupting Cow"' \
+ 'no_legacy_display:[0][0][0]["body"][0]["content"][1]["content-type"]="text/plain"'
+
+test_begin_subtest "when replying, avoid rendering legacy-display part"
+output=$(notmuch reply --format=json id:protected-with-legacy-display@crypto.notmuchmail.org)
+test_json_nodes <<<"$output" \
+ 'no_legacy_display:["original"]["body"][0]["content"][1]["content-type"]="text/plain"'
+
+test_begin_subtest "do not treat legacy-display part as body when indexing"
+output=$(notmuch search --output=messages body:interrupting)
+test_expect_equal "$output" ''
+
+test_begin_subtest "identify message that had a legacy display part skipped during indexing"
+output=$(notmuch search --output=messages property:index.repaired=skip-protected-headers-legacy-display)
+test_expect_equal "$output" id:protected-with-legacy-display@crypto.notmuchmail.org
+
+# TODO: test that a part that looks like a legacy-display in
+# multipart/signed, but not encrypted, is indexed and not stripped.
+
+# TODO: test that a legacy-display in a decrypted subpart (not in the
+# cryptographic payload) is indexed and not stripped.
+
+# TODO: test that a legacy-display inside multiple MIME layers that
+# include an encryption layer (e.g. multipart/encrypted around
+# multipart/signed) is stripped and not indexed.
+
test_done
expected='#= simple-encrypted@crypto.notmuchmail.org index.decryption=failure
#notmuch-dump batch-tag:3 config,properties,tags
+encrypted +inbox +unread -- id:basic-encrypted@crypto.notmuchmail.org
++encrypted +inbox +unread -- id:encrypted-signed@crypto.notmuchmail.org
+encrypted +inbox +unread -- id:simple-encrypted@crypto.notmuchmail.org'
test_expect_equal \
"$output" \
"$output" \
"$expected"
+goodsig='good_sig:[0][0][0]["crypto"]["signed"]["status"][0]["status"]="good"'
+nosig='no_sig:[0][0][0]["crypto"]!"signed"'
+
+test_begin_subtest "verify signature without a session key stashed when --decrypt=true"
+output=$(notmuch show --format=json --decrypt=true id:encrypted-signed@crypto.notmuchmail.org)
+test_json_nodes <<<"$output" "$goodsig"
+
+test_begin_subtest "do not verify sig without a session key stashed if --decrypt=auto"
+output=$(notmuch show --format=json id:encrypted-signed@crypto.notmuchmail.org)
+test_json_nodes <<<"$output" "$nosig"
+
+test_begin_subtest "verify signature when --decrypt=stash"
+output=$(notmuch show --format=json --decrypt=stash id:encrypted-signed@crypto.notmuchmail.org)
+test_json_nodes <<<"$output" "$goodsig"
+
+test_begin_subtest "verify signature with stashed session key"
+output=$(notmuch show --format=json id:encrypted-signed@crypto.notmuchmail.org)
+test_json_nodes <<<"$output" "$goodsig"
# TODO: test removal of a message from the message store between
# indexing and reindexing.
failed=0
broken=0
total=0
+all_skipped=0
for file
do
while read type value
do
case $type in
- '')
- continue ;;
fixed)
- fixed=$(($fixed + $value)) ;;
+ fixed=$((fixed + value)) ;;
success)
- success=$(($success + $value)) ;;
+ success=$((success + value)) ;;
failed)
- failed=$(($failed + $value)) ;;
+ failed=$((failed + value)) ;;
broken)
- broken=$(($broken + $value)) ;;
+ broken=$((broken + value)) ;;
total)
- total=$(($total + $value)) ;;
+ total=$((total + value))
+ if [ "$value" -eq 0 ]; then
+ all_skipped=$((all_skipped + 1))
+ fi
esac
done <"$file"
done
-pluralize () {
- case $2 in
- 1)
- case $1 in
- test)
- echo test ;;
- failure)
- echo failure ;;
- esac
- ;;
- *)
- case $1 in
- test)
- echo tests ;;
- failure)
- echo failures ;;
- esac
- ;;
- esac
-}
+pluralize_s () { [ "$1" -eq 1 ] && s='' || s='s'; }
echo "Notmuch test suite complete."
-if [ "$fixed" = "0" ] && [ "$failed" = "0" ]; then
- tests=$(pluralize "test" $total)
- printf "All $total $tests "
- if [ "$broken" = "0" ]; then
- echo "passed."
- else
- failures=$(pluralize "failure" $broken)
- echo "behaved as expected ($broken expected $failures)."
- fi;
+
+if [ "$fixed" -eq 0 ] && [ "$failed" -eq 0 ]; then
+ pluralize_s "$total"
+ printf "All $total test$s "
+ if [ "$broken" -eq 0 ]; then
+ echo "passed."
+ else
+ pluralize_s "$broken"
+ echo "behaved as expected ($broken expected failure$s)."
+ fi
else
- echo "$success/$total tests passed."
- if [ "$broken" != "0" ]; then
- tests=$(pluralize "test" $broken)
- echo "$broken broken $tests failed as expected."
- fi
- if [ "$fixed" != "0" ]; then
- tests=$(pluralize "test" $fixed)
- echo "$fixed broken $tests now fixed."
- fi
- if [ "$failed" != "0" ]; then
- tests=$(pluralize "test" $failed)
- echo "$failed $tests failed."
- fi
+ echo "$success/$total tests passed."
+ if [ "$broken" -ne 0 ]; then
+ pluralize_s "$broken"
+ echo "$broken broken test$s failed as expected."
+ fi
+ if [ "$fixed" -ne 0 ]; then
+ pluralize_s "$fixed"
+ echo "$fixed broken test$s now fixed."
+ fi
+ if [ "$failed" -ne 0 ]; then
+ pluralize_s "$failed"
+ echo "$failed test$s failed."
+ fi
fi
-skipped=$(($total - $fixed - $success - $failed - $broken))
-if [ "$skipped" != "0" ]; then
- tests=$(pluralize "test" $skipped)
- echo "$skipped $tests skipped."
+skipped=$((total - fixed - success - failed - broken))
+if [ "$skipped" -ne 0 ]; then
+ pluralize_s "$skipped"
+ echo "$skipped test$s skipped."
+fi
+if [ "$all_skipped" -ne 0 ]; then
+ pluralize_s "$all_skipped"
+ echo "All tests in $all_skipped file$s skipped."
fi
# Note that we currently do not consider skipped tests as failing the
# build.
-if [ $success -gt 0 -a $fixed -eq 0 -a $failed -eq 0 ]
+if [ "$success" -gt 0 ] && [ "$fixed" -eq 0 ] && [ "$failed" -eq 0 ]
then
- exit 0
+ exit 0
else
- exit 1
+ exit 1
fi
#include "command-line-arguments.h"
-int main(int argc, char **argv){
-
- int opt_index=1;
-
- int kw_val=0;
- int kwb_val=0;
- int fl_val=0;
- int int_val=0;
- const char *pos_arg1=NULL;
- const char *pos_arg2=NULL;
- const char *string_val=NULL;
+int
+main (int argc, char **argv)
+{
+
+ int opt_index = 1;
+
+ int kw_val = 0;
+ int kwb_val = 0;
+ int fl_val = 0;
+ int int_val = 0;
+ const char *pos_arg1 = NULL;
+ const char *pos_arg2 = NULL;
+ const char *string_val = NULL;
bool bool_val = false;
bool fl_set = false, int_set = false, bool_set = false, kwb_set = false,
- kw_set = false, string_set = false, pos1_set = false, pos2_set = false;
+ kw_set = false, string_set = false, pos1_set = false, pos2_set = false;
notmuch_opt_desc_t parent_options[] = {
{ .opt_flags = &fl_val, .name = "flag", .present = &fl_set, .keywords =
- (notmuch_keyword_t []){ { "one", 1 << 0},
- { "two", 1 << 1 },
- { "three", 1 << 2 },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "one", 1 << 0 },
+ { "two", 1 << 1 },
+ { "three", 1 << 2 },
+ { 0, 0 } } },
{ .opt_int = &int_val, .name = "int", .present = &int_set },
{ }
};
notmuch_opt_desc_t options[] = {
{ .opt_bool = &bool_val, .name = "boolean", .present = &bool_set },
{ .opt_keyword = &kw_val, .name = "keyword", .present = &kw_set, .keywords =
- (notmuch_keyword_t []){ { "zero", 0 },
- { "one", 1 },
- { "two", 2 },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "zero", 0 },
+ { "one", 1 },
+ { "two", 2 },
+ { 0, 0 } } },
{ .opt_keyword = &kwb_val, .name = "boolkeyword", .present = &kwb_set,
.keyword_no_arg_value = "true", .keywords =
- (notmuch_keyword_t []){ { "false", 0 },
- { "true", 1 },
- { "auto", 2 },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "false", 0 },
+ { "true", 1 },
+ { "auto", 2 },
+ { 0, 0 } } },
{ .opt_inherit = parent_options },
{ .opt_string = &string_val, .name = "string", .present = &string_set },
{ .opt_position = &pos_arg1, .present = &pos1_set },
{ }
};
- opt_index = parse_arguments(argc, argv, options, 1);
+ opt_index = parse_arguments (argc, argv, options, 1);
if (opt_index < 0)
return 1;
if (bool_set)
- printf("boolean %d\n", bool_val);
+ printf ("boolean %d\n", bool_val);
if (kw_set)
- printf("keyword %d\n", kw_val);
+ printf ("keyword %d\n", kw_val);
if (kwb_set)
- printf("boolkeyword %d\n", kwb_val);
+ printf ("boolkeyword %d\n", kwb_val);
if (fl_set)
- printf("flags %d\n", fl_val);
+ printf ("flags %d\n", fl_val);
if (int_set)
- printf("int %d\n", int_val);
+ printf ("int %d\n", int_val);
if (string_set)
- printf("string %s\n", string_val);
+ printf ("string %s\n", string_val);
if (pos1_set)
- printf("positional arg 1 %s\n", pos_arg1);
+ printf ("positional arg 1 %s\n", pos_arg1);
if (pos2_set)
- printf("positional arg 2 %s\n", pos_arg2);
+ printf ("positional arg 2 %s\n", pos_arg2);
- for ( ; opt_index < argc ; opt_index ++) {
- printf("non parsed arg %d = %s\n", opt_index, argv[opt_index]);
+ for (; opt_index < argc; opt_index++) {
+ printf ("non parsed arg %d = %s\n", opt_index, argv[opt_index]);
}
return 0;
--- /dev/null
+From: test_suite@notmuchmail.org
+To: test_suite@notmuchmail.org
+Subject: Lyrics
+Date: Wed 29 May 2019 06:09:22 PM EDT
+Message-ID: <encrypted-signed@crypto.notmuchmail.org>
+MIME-Version: 1.0
+Content-Type: multipart/encrypted; boundary="=-=-=";
+ protocol="application/pgp-encrypted"
+
+--=-=-=
+Content-Type: application/pgp-encrypted
+
+Version: 1
+
+--=-=-=
+Content-Type: application/octet-stream
+
+-----BEGIN PGP MESSAGE-----
+
+hIwDxE023q1UqxYBBAC9z781zV7QAInGMKHX6TKU5Xw/OkoWXahpDL88F6Ocm5R9
+7M9z2ocvlyrbgRhqE+nvFeGH/K7rVkBBT6TAcdIe/C8Qzbd3stPPcx1PlunGROj7
+H/WAcmDksK3HkXpHwmInUtzNw1pkhOoLy/sFSbPvtyg8GCUzXbafHAIIo0rB2tLB
+DwGWD3l4WdcyQWuYD9QJKuDIqdWo8E3TTcKkiOAt/6liwPNZ0jGzDeCuSTnWFj6Z
+AiXGeNtD3I1tCN/8T3NjEKOCQ+bdT5Y06dDaL61FpQ23eIuSUgksVxjnkEAb6iPe
+07gjzcyNuGP3WPI/0qu0wtZwpAQxvaNygDsQj/OjR5kn9luBd/VqodM3TWWS8miV
+m0z1tYbqYAQWW6TS7fXlsyXoOxTLW5MCfe3D36VSErL/NJItETklVKzNfKjMmRKx
+CI2ZUzugxPWSLQzOp5yl7iICk8e+vS9TkQw2j0nXAQYLYgmqZMhf4av5GlFv3tQu
+heO4XLT6NBDTHMFTDbgW42kE0N4MDPc29AqVFGImcTHvflF4Vp0qIbSJdIcHwKkU
+5LKqvicAa0lsIoJbsW3lHrzowyjov2vLH/VGd/wIX+MS3KT7cySdyp8HVMcwwyZu
+Y9nrTN/7G1FwKWlcGa4uJNcFFkYlcEymZj1EX2cyrdezPtX7K5vhwBYddptFD+Bn
+IVkghRut3UDeXe83F8OutWiZfK5EVYABq/aP3//hIbQl2o4Dkd3z9m+8LobrIV5s
+NXjAjU5WQOjRLoHBebG2HkMpFsWhXD/Fb/Bb58VOpdI=
+=x12v
+-----END PGP MESSAGE-----
+--=-=-=--
--- /dev/null
+From: test_suite@notmuchmail.org
+To: test_suite@notmuchmail.org
+Subject: Here is the password
+Date: Sat, 01 Jan 2000 12:00:00 +0000
+Message-ID: <mixed-up@mangling.notmuchmail.org>
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="=-=-="
+
+--=-=-=
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: quoted-printable
+
+
+--=-=-=
+Content-Type: application/pgp-encrypted
+Content-Transfer-Encoding: base64
+
+VmVyc2lvbjogMQ0K
+
+--=-=-=
+Content-Type: application/octet-stream
+Content-Transfer-Encoding: base64
+
+LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCmhJd0R4RTAyM3ExVXF4WUJCQUNwNzBlN0tQ
+eTlPWWFoZUlya0x6bWhxMWxScW15NTFhTDFqQkwwSy9xTjdyZksNCkJaRUcxY1I4amVMalRGZFBL
+UExWS0pJODByN0ZnS0kweXd2V3ZsNlIxYUUxVHk1Qm5WWFQ5WHpDckVIN2ZxQ2wNClNLSzgyRXZv
+bFhUb2hBWkhVcmg2SzY2ZVFRVFRJQUMxbjdCMEE4aEVyemtnYU00K3NlTjNMbHZlelQ2VExOS00N
+CkFUcHFzRWJNMk1WckdndzBiM29Vc0dHQVBFdDJNbWpORVlzcmlLbnF3dDZkSkRaYy8vWHloamdN
+UWF5aUQ4ZGENCk4xZ1Qzb3FndS9nS0NwQlpEWXpIZjlPdFZpMlVubEZEV3k2cnJNWkxqV0RuSXY0
+dmU5UG4vcW9sd0hWanpkSjENClpmak5DNXQwejNYQURLR3JqTjl3dXRyNHFtN1NUVzFySEFYSFA2
+OFRRVHhJMHFnSktqUFhOS1dFdzZnPQ0KPXBKRzQNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0N
+Cg==
+--=-=-=--
--- /dev/null
+From: test_suite@notmuchmail.org
+To: test_suite@notmuchmail.org
+Subject: Subject Unavailable
+Date: Sat, 01 Jan 2000 12:00:00 +0000
+Message-Id: <protected-with-legacy-display@crypto.notmuchmail.org>
+MIME-Version: 1.0
+Content-Type: multipart/encrypted; boundary="=-=-=";
+ protocol="application/pgp-encrypted"
+
+--=-=-=
+Content-Type: application/pgp-encrypted
+
+Version: 1
+
+--=-=-=
+Content-Type: application/octet-stream
+
+-----BEGIN PGP MESSAGE-----
+
+hIwDxE023q1UqxYBBACkgwtKOAP+UlKYDzYkZY+gDuMNKnHjWIvv2Cdnovy40QzL
+5sbuib40y7orO+MqYMCWpoFtgBVsGiOUE3bZAg8n3Ji38/zVGwQveu6sh7SAy0Q9
+zFEvLhtajw17nPe+QH2UmIyfVikA57Mot13THq4i6C4ozVCyhyIltx+sNJkmw9Lp
+AdQd+cgCMRSMbi++eRwIi4zgxKrfAoGOmdMiVzBrh3yZqnbI0rCxJIKu7gEWuQLT
+7BuvN2bJUkPGLAUhUanFararVoD7WWOl67IlWFkyncES0PRskUf9coV68WZnYjsR
+Y3LdLnha1sdMwUNeBKQ44XBd2e7mXbDSp1cSjTDf9euwB4m7uQFTLwoQ8Of+LmQD
+KMHzjmucbkNAIpfAjcDusTA/oaaqUiEgGIgYYMDqG1CaaxdT55S7tMjW5yJryQmo
+pg65jrUMgEn5XHZ+KI2OsCmwGdoBYNau8p1a2hsiKhHJmLUeEAu34gFI3hylIOC0
+0KC40d0zTSb0s7SZuTrD6vYgiXG9aFktHvAWFH0ATCts7qyiRN7k5jt7yWfRntE2
+UCexTGE3TH7aju+IqDPC1XsaKF4T3CVhdr8WmKCa+0VOaw7xHRGYnzq9y91GcaCx
+8AcoZ3kYs+f2LIn+T667A0KKP4Z6OmLjCx3b1RvRUQYR9taruEMAQbIuAajiyTe9
+KfUrsUULZfInE50x+OneYvDhzoSgSJoHIK+18X/wo6YcyleJ9fZxCQ/vaXTDkAeF
+ve7TFcbIqmJ4MHygXILHUuDwp7P4t/tIL7SZwja70P3digjsgoNZY29VTnU8uyIb
+d6eOjgpeNVhRjDWxbUvhFD7i4rHCi/bbXFlW0cCXoiaVQBtYmiNysRoRZOv0h3TW
+q/+/UmqkaQFnF3zp5sr87y+ValItgPWmb9Ds0lyAoSvQx35zVh8DFfH04m7hmsb7
+gcvemlPTAnQWkIMC3c/bZWgt8tNcG7tQeUMWd9n4281y/hApbm90x2NLzEqvVcRq
+K0iIgVxbCHSKqGh4TtbIwpNhzSP+KHYkZ8h6+QUDRwGEV9QqZKg=
+=2O0V
+-----END PGP MESSAGE-----
+
+--=-=-=--
#include <cstdlib>
#include <xapian.h>
-int main(int argc, char **argv) {
+int
+main (int argc, char **argv)
+{
if (argc < 2) {
std::cerr << "usage: ghost-report xapian-dir" << std::endl;
- exit(1);
+ exit (1);
}
- Xapian::Database db(argv[1]);
- std::cout << db.get_termfreq("Tghost") << std::endl;
+ Xapian::Database db (argv[1]);
+ std::cout << db.get_termfreq ("Tghost") << std::endl;
}
if (dir == ENCODE)
status = hex_encode (ctx, in, buf_p, size_p);
else
- if (inplace) {
- status = hex_decode_inplace (in);
- *buf_p = in;
- *size_p = strlen(in);
- } else {
- status = hex_decode (ctx, in, buf_p, size_p);
- }
+ if (inplace) {
+ status = hex_decode_inplace (in);
+ *buf_p = in;
+ *size_p = strlen (in);
+ } else {
+ status = hex_decode (ctx, in, buf_p, size_p);
+ }
if (status == HEX_SUCCESS)
fputs (*buf_p, stdout);
notmuch_opt_desc_t options[] = {
{ .opt_keyword = &dir, .name = "direction", .keywords =
- (notmuch_keyword_t []){ { "encode", ENCODE },
- { "decode", DECODE },
- { 0, 0 } } },
+ (notmuch_keyword_t []){ { "encode", ENCODE },
+ { "decode", DECODE },
+ { 0, 0 } } },
{ .opt_bool = &omit_newline, .name = "omit-newline" },
{ .opt_bool = &inplace, .name = "in-place" },
{ }
#include <xapian.h>
-int main(int argc, char **argv)
+int
+main (int argc, char **argv)
{
if (argc != 4) {
fprintf (stderr, "Usage: %s mailpath version features\n", argv[0]);
#include <notmuch.h>
inline static void
-expect0(int line, notmuch_status_t ret)
+expect0 (int line, notmuch_status_t ret)
{
- if (ret) {
+ if (ret) {
fprintf (stderr, "line %d: %d\n", line, ret);
exit (1);
- }
+ }
}
-#define EXPECT0(v) expect0(__LINE__, v);
+#define EXPECT0(v) expect0 (__LINE__, v);
#endif
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
static const char *parse_time_error_strings[] = {
- [PARSE_TIME_OK] = "OK",
- [PARSE_TIME_ERR] = "ERR",
- [PARSE_TIME_ERR_LIB] = "LIB",
- [PARSE_TIME_ERR_ALREADYSET] = "ALREADYSET",
- [PARSE_TIME_ERR_FORMAT] = "FORMAT",
- [PARSE_TIME_ERR_DATEFORMAT] = "DATEFORMAT",
- [PARSE_TIME_ERR_TIMEFORMAT] = "TIMEFORMAT",
- [PARSE_TIME_ERR_INVALIDDATE] = "INVALIDDATE",
- [PARSE_TIME_ERR_INVALIDTIME] = "INVALIDTIME",
- [PARSE_TIME_ERR_KEYWORD] = "KEYWORD",
+ [PARSE_TIME_OK] = "OK",
+ [PARSE_TIME_ERR] = "ERR",
+ [PARSE_TIME_ERR_LIB] = "LIB",
+ [PARSE_TIME_ERR_ALREADYSET] = "ALREADYSET",
+ [PARSE_TIME_ERR_FORMAT] = "FORMAT",
+ [PARSE_TIME_ERR_DATEFORMAT] = "DATEFORMAT",
+ [PARSE_TIME_ERR_TIMEFORMAT] = "TIMEFORMAT",
+ [PARSE_TIME_ERR_INVALIDDATE] = "INVALIDDATE",
+ [PARSE_TIME_ERR_INVALIDTIME] = "INVALIDTIME",
+ [PARSE_TIME_ERR_KEYWORD] = "KEYWORD",
};
static const char *
len += strlen (argv[i]) + 1;
p = malloc (len);
- if (!p)
+ if (! p)
return NULL;
*p = 0;
const char *operator;
int round;
} operators[] = {
- { "==>", PARSE_TIME_NO_ROUND },
- { "==_>", PARSE_TIME_ROUND_DOWN },
- { "==^>", PARSE_TIME_ROUND_UP_INCLUSIVE },
- { "==^^>", PARSE_TIME_ROUND_UP },
+ { "==>", PARSE_TIME_NO_ROUND },
+ { "==_>", PARSE_TIME_ROUND_DOWN },
+ { "==^>", PARSE_TIME_ROUND_UP_INCLUSIVE },
+ { "==^^>", PARSE_TIME_ROUND_UP },
};
static const char *
const char *oper = NULL;
unsigned int i;
- for (i = 0; i < ARRAY_SIZE(operators); i++) {
+ for (i = 0; i < ARRAY_SIZE (operators); i++) {
if (round == operators[i].round) {
oper = operators[i].operator;
break;
/* trail is trailing whitespace and (optional) comment */
trail = strchr (input, '#');
- if (!trail)
+ if (! trail)
trail = input + len;
- while (trail > input && isspace ((unsigned char) *(trail-1)))
+ while (trail > input && isspace ((unsigned char) *(trail - 1)))
trail--;
if (trail == input) {
}
tmp = strdup (trail);
- if (!tmp) {
+ if (! tmp) {
fprintf (stderr, "strdup() failed\n");
continue;
}
}
r = parse_time_string (input, &t, ref, round);
- if (!r) {
- if (!localtime_r (&t, &tm)) {
+ if (! r) {
+ if (! localtime_r (&t, &tm)) {
fprintf (stderr, "localtime_r() failed\n");
free (trail);
continue;
char buf[1024];
const char *format = DEFAULT_FORMAT;
struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "^", no_argument, NULL, 'u' },
- { "^^", no_argument, NULL, 'U' },
- { "_", no_argument, NULL, 'd' },
- { "format", required_argument, NULL, 'f' },
- { "ref", required_argument, NULL, 'r' },
+ { "help", no_argument, NULL, 'h' },
+ { "^", no_argument, NULL, 'u' },
+ { "^^", no_argument, NULL, 'U' },
+ { "_", no_argument, NULL, 'd' },
+ { "format", required_argument, NULL, 'f' },
+ { "ref", required_argument, NULL, 'r' },
{ NULL, 0, NULL, 0 },
};
return parse_stdin (stdin, nowp, round, format);
argstr = concat_args (optind, argc, argv);
- if (!argstr)
+ if (! argstr)
return 1;
r = parse_time_string (argstr, &result, nowp, round);
return r;
}
- if (!localtime_r (&result, &tm))
+ if (! localtime_r (&result, &tm))
return 1;
strftime (buf, sizeof (buf), format, &tm);
/* stubs since we cannot link with notmuch.o */
const notmuch_opt_desc_t notmuch_shared_options[] = {
- { }
+ { }
};
const char *notmuch_requested_db_uuid = NULL;
do_smtp_to_file (peer_file, output);
- DONE:
+ DONE:
if (output)
fclose (output);
if (peer_file)
#include <xapian.h>
#include <notmuch.h>
-int main (int argc, char** argv)
+int
+main (int argc, char **argv)
{
notmuch_database_t *notmuch;
char *message = NULL;
try {
(void) new Xapian::WritableDatabase (argv[2], Xapian::DB_OPEN);
} catch (const Xapian::Error &error) {
- printf("caught %s\n", error.get_msg().c_str());
+ printf ("caught %s\n", error.get_msg ().c_str ());
return 0;
}
TEST_GDB=${TEST_GDB:-gdb}
TEST_CC=${TEST_CC:-cc}
TEST_CFLAGS=${TEST_CFLAGS:-"-g -O0"}
+TEST_SHIM_CFLAGS=${TEST_SHIM_CFLAGS:-"-fpic -shared"}
+TEST_SHIM_LDFLAGS=${TEST_SHIM_LDFLAGS:-"-ldl"}
# Protect ourselves from common misconfiguration to export
# CDPATH into the environment
notmuch_dir_sanitize OUTPUT.stdout OUTPUT.stderr > OUTPUT
}
+make_shim () {
+ base_name="$1"
+ test_file="${base_name}.c"
+ shim_file="${base_name}.so"
+ cat > ${test_file}
+ ${TEST_CC} ${TEST_CFLAGS} ${TEST_SHIM_CFLAGS} -I${NOTMUCH_SRCDIR}/test -I${NOTMUCH_SRCDIR}/lib -o ${shim_file} ${test_file} ${TEST_SHIM_LDFLAGS}
+}
+
+notmuch_with_shim () {
+ base_name="$1"
+ shift
+ shim_file="${base_name}.so"
+ LD_PRELOAD=./${shim_file}${LD_PRELOAD:+:$LD_PRELOAD} notmuch-shared "$@"
+}
# Creates a script that counts how much time it is executed and calls
# notmuch. $notmuch_counter_command is set to the path to the
libnotmuch_util_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \
$(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c \
$(dir)/util.c $(dir)/gmime-extra.c $(dir)/crypto.c \
+ $(dir)/repair.c \
$(dir)/unicode-util.c
libnotmuch_util_modules := $(libnotmuch_util_c_srcs:.c=.o)
#include "crypto.h"
#include <strings.h>
+#include "error_util.h"
#define unused(x) x __attribute__ ((unused))
#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
-void _notmuch_crypto_cleanup (unused(_notmuch_crypto_t *crypto))
+void
+_notmuch_crypto_cleanup (unused(_notmuch_crypto_t *crypto))
{
}
GError **err)
{
GMimeObject *ret = NULL;
+
if (decrypt == NOTMUCH_DECRYPT_FALSE)
return NULL;
GMimeDecryptFlags flags = GMIME_DECRYPT_NONE;
if (decrypt == NOTMUCH_DECRYPT_TRUE && decrypt_result)
flags |= GMIME_DECRYPT_EXPORT_SESSION_KEY;
- ret = g_mime_multipart_encrypted_decrypt(part, flags, NULL,
- decrypt_result, err);
+ ret = g_mime_multipart_encrypted_decrypt (part, flags, NULL,
+ decrypt_result, err);
return ret;
}
static int
_notmuch_message_crypto_destructor (_notmuch_message_crypto_t *msg_crypto)
{
- if (!msg_crypto)
+ if (! msg_crypto)
return 0;
if (msg_crypto->sig_list)
g_object_unref (msg_crypto->sig_list);
_notmuch_message_crypto_new (void *ctx)
{
_notmuch_message_crypto_t *ret = talloc_zero (ctx, _notmuch_message_crypto_t);
+
talloc_set_destructor (ret, _notmuch_message_crypto_destructor);
return ret;
}
notmuch_status_t
_notmuch_message_crypto_potential_sig_list (_notmuch_message_crypto_t *msg_crypto, GMimeSignatureList *sigs)
{
- if (!msg_crypto)
+ if (! msg_crypto)
return NOTMUCH_STATUS_NULL_POINTER;
/* Signatures that arrive after a payload part during DFS are not
}
-notmuch_status_t
-_notmuch_message_crypto_potential_payload (_notmuch_message_crypto_t *msg_crypto, GMimeObject *payload, GMimeObject *parent, int childnum)
+bool
+_notmuch_message_crypto_potential_payload (_notmuch_message_crypto_t *msg_crypto, GMimeObject *part, GMimeObject *parent, int childnum)
{
const char *protected_headers = NULL;
const char *forwarded = NULL;
const char *subject = NULL;
- if (!msg_crypto || !payload)
- return NOTMUCH_STATUS_NULL_POINTER;
+ if ((! msg_crypto) || (! part))
+ INTERNAL_ERROR ("_notmuch_message_crypto_potential_payload() got NULL for %s\n",
+ msg_crypto? "part" : "msg_crypto");
/* only fire on the first payload part encountered */
if (msg_crypto->payload_encountered)
- return NOTMUCH_STATUS_SUCCESS;
+ return false;
/* the first child of multipart/encrypted that matches the
* encryption protocol should be "control information" metadata,
* https://tools.ietf.org/html/rfc1847#page-8) */
if (parent && GMIME_IS_MULTIPART_ENCRYPTED (parent) && childnum == GMIME_MULTIPART_ENCRYPTED_VERSION) {
const char *enc_type = g_mime_object_get_content_type_parameter (parent, "protocol");
- GMimeContentType *ct = g_mime_object_get_content_type (payload);
+ GMimeContentType *ct = g_mime_object_get_content_type (part);
if (ct && enc_type) {
const char *part_type = g_mime_content_type_get_mime_type (ct);
if (part_type && strcmp (part_type, enc_type) == 0)
- return NOTMUCH_STATUS_SUCCESS;
+ return false;
}
}
* envelope: */
if ((msg_crypto->decryption_status != NOTMUCH_MESSAGE_DECRYPTED_FULL) &&
(msg_crypto->sig_list == NULL))
- return NOTMUCH_STATUS_SUCCESS;
+ return false;
/* Verify that this payload has headers that are intended to be
* exported to the larger message: */
/* Consider a payload that uses Alexei Melinkov's forwarded="no" for
* message/global or message/rfc822:
* https://tools.ietf.org/html/draft-melnikov-smime-header-signing-05#section-4 */
- forwarded = g_mime_object_get_content_type_parameter (payload, "forwarded");
- if (GMIME_IS_MESSAGE_PART (payload) && forwarded && strcmp (forwarded, "no") == 0) {
- GMimeMessage *message = g_mime_message_part_get_message (GMIME_MESSAGE_PART (payload));
+ forwarded = g_mime_object_get_content_type_parameter (part, "forwarded");
+ if (GMIME_IS_MESSAGE_PART (part) && forwarded && strcmp (forwarded, "no") == 0) {
+ GMimeMessage *message = g_mime_message_part_get_message (GMIME_MESSAGE_PART (part));
subject = g_mime_message_get_subject (message);
/* FIXME: handle more than just Subject: at some point */
} else {
/* Consider "memoryhole"-style protected headers as practiced by Enigmail and K-9 */
- protected_headers = g_mime_object_get_content_type_parameter (payload, "protected-headers");
- if (protected_headers && strcasecmp("v1", protected_headers) == 0)
- subject = g_mime_object_get_header (payload, "Subject");
+ protected_headers = g_mime_object_get_content_type_parameter (part, "protected-headers");
+ if (protected_headers && strcasecmp ("v1", protected_headers) == 0)
+ subject = g_mime_object_get_header (part, "Subject");
/* FIXME: handle more than just Subject: at some point */
}
msg_crypto->payload_subject = talloc_strdup (msg_crypto, subject);
}
- return NOTMUCH_STATUS_SUCCESS;
+ return true;
}
notmuch_status_t
_notmuch_message_crypto_successful_decryption (_notmuch_message_crypto_t *msg_crypto)
{
- if (!msg_crypto)
+ if (! msg_crypto)
return NOTMUCH_STATUS_NULL_POINTER;
/* see the rationale for different values of
* _notmuch_message_decryption_status_t in util/crypto.h */
- if (!msg_crypto->payload_encountered)
+ if (! msg_crypto->payload_encountered)
msg_crypto->decryption_status = NOTMUCH_MESSAGE_DECRYPTED_FULL;
else if (msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_NONE)
msg_crypto->decryption_status = NOTMUCH_MESSAGE_DECRYPTED_PARTIAL;
/* signature status of the whole message (either the whole message
* is signed, or it is not) -- this means that partially-signed
* messages will get no signature status. */
- GMimeSignatureList * sig_list;
+ GMimeSignatureList *sig_list;
/* if part of the message was signed, and the MUA is clever, it
* can determine on its own exactly which part and try to make
* more sense of it. */
/* the value of any "Subject:" header in the cryptographic payload
* (the top level part within the crypto envelope), converted to
* UTF-8 */
- char * payload_subject;
+ char *payload_subject;
/* if both signed and encrypted, was the signature encrypted? */
bool signature_encrypted;
/* call potential_payload during a depth-first-search on a message
* when encountering a message part that is not part of the envelope.
+ *
+ * Returns true if part is the root of the cryptographic payload of
+ * this message.
*/
-notmuch_status_t
-_notmuch_message_crypto_potential_payload (_notmuch_message_crypto_t *msg_crypto, GMimeObject *payload, GMimeObject *parent, int childnum);
+bool
+_notmuch_message_crypto_potential_payload (_notmuch_message_crypto_t *msg_crypto, GMimeObject *part, GMimeObject *parent, int childnum);
#ifdef __cplusplus
*
* Note that __location__ comes from talloc.h.
*/
-#define INTERNAL_ERROR(format, ...) \
- _internal_error (format " (%s).\n", \
+#define INTERNAL_ERROR(format, ...) \
+ _internal_error (format " (%s).\n", \
##__VA_ARGS__, __location__)
#ifdef __cplusplus
static
GMimeStream *
-_gzfile_maybe_filter (GMimeStream *file_stream) {
+_gzfile_maybe_filter (GMimeStream *file_stream)
+{
char buf[4];
int bytes_read;
return NULL;
/* check for gzipped input */
- if (bytes_read >= 2 && buf[0] == 0x1f && (unsigned char)buf[1] == 0x8b) {
+ if (bytes_read >= 2 && buf[0] == 0x1f && (unsigned char) buf[1] == 0x8b) {
GMimeStream *gzstream;
GMimeFilter *gzfilter;
}
GMimeStream *
-g_mime_stream_stdout_new()
+g_mime_stream_stdout_new ()
{
GMimeStream *stream_stdout = NULL;
GMimeStream *stream_buffered = NULL;
stream_stdout = g_mime_stream_pipe_new (STDOUT_FILENO);
- if (!stream_stdout)
+ if (! stream_stdout)
return NULL;
g_mime_stream_pipe_set_owner (GMIME_STREAM_PIPE (stream_stdout), FALSE);
/**
* copy a glib string into a talloc context, and free it.
*/
-static char*
+static char *
g_string_talloc_strdup (void *ctx, char *g_string)
{
char *new_str = talloc_strdup (ctx, g_string);
+
g_free (g_string);
return new_str;
}
{
/* output user id only if validity is FULL or ULTIMATE. */
const char *uid = g_mime_certificate_get_user_id (cert);
+
if (uid == NULL)
return uid;
GMimeValidity validity = g_mime_certificate_get_id_validity (cert);
return NULL;
}
-const char*
-g_mime_certificate_get_fpr16 (GMimeCertificate *cert) {
+const char *
+g_mime_certificate_get_fpr16 (GMimeCertificate *cert)
+{
const char *fpr = g_mime_certificate_get_fingerprint (cert);
- if (!fpr || strlen (fpr) < 16)
+
+ if (! fpr || strlen (fpr) < 16)
return fpr;
return fpr + (strlen (fpr) - 16);
g_mime_message_get_address_string (GMimeMessage *message, GMimeAddressType type)
{
InternetAddressList *list = g_mime_message_get_addresses (message, type);
+
return internet_address_list_to_string (list, NULL, 0);
}
char *
g_mime_message_get_date_string (void *ctx, GMimeMessage *message)
{
- GDateTime* parsed_date = g_mime_message_get_date (message);
+ GDateTime *parsed_date = g_mime_message_get_date (message);
+
if (parsed_date) {
char *date = g_mime_utils_header_format_date (parsed_date);
return g_string_talloc_strdup (ctx, date);
} else {
- return talloc_strdup(ctx, "Thu, 01 Jan 1970 00:00:00 +0000");
+ return talloc_strdup (ctx, "Thu, 01 Jan 1970 00:00:00 +0000");
}
}
InternetAddressList *
-g_mime_message_get_reply_to_list(GMimeMessage *message)
+g_mime_message_get_reply_to_list (GMimeMessage *message)
{
return g_mime_message_get_reply_to (message);
}
g_mime_message_get_reply_to_string (void *ctx, GMimeMessage *message)
{
InternetAddressList *list = g_mime_message_get_reply_to (message);
+
return g_string_talloc_strdup (ctx, internet_address_list_to_string (list, NULL, 0));
}
*/
gboolean
-g_mime_signature_status_good (GMimeSignatureStatus status) {
- return ((status & (GMIME_SIGNATURE_STATUS_RED | GMIME_SIGNATURE_STATUS_ERROR_MASK)) == 0);
+g_mime_signature_status_good (GMimeSignatureStatus status)
+{
+ return ((status & (GMIME_SIGNATURE_STATUS_RED | GMIME_SIGNATURE_STATUS_ERROR_MASK)) == 0);
}
gboolean
-g_mime_signature_status_bad (GMimeSignatureStatus status) {
+g_mime_signature_status_bad (GMimeSignatureStatus status)
+{
return (status & GMIME_SIGNATURE_STATUS_RED);
}
gboolean
-g_mime_signature_status_error (GMimeSignatureStatus status) {
+g_mime_signature_status_error (GMimeSignatureStatus status)
+{
return (status & GMIME_SIGNATURE_STATUS_ERROR_MASK);
}
gint64
-g_mime_utils_header_decode_date_unix (const char *date) {
- GDateTime* parsed_date = g_mime_utils_header_decode_date (date);
+g_mime_utils_header_decode_date_unix (const char *date)
+{
+ GDateTime *parsed_date = g_mime_utils_header_decode_date (date);
time_t ret;
if (parsed_date) {
extern "C" {
#endif
-GMimeStream *g_mime_stream_stdout_new(void);
+GMimeStream *g_mime_stream_stdout_new (void);
/* Return a GMime stream for this open file descriptor, un-gzipping if
* necessary */
*/
char *g_mime_message_get_address_string (GMimeMessage *message, GMimeAddressType type);
-InternetAddressList * g_mime_message_get_addresses (GMimeMessage *message, GMimeAddressType type);
+InternetAddressList *g_mime_message_get_addresses (GMimeMessage *message, GMimeAddressType type);
/**
* return talloc allocated date string
* glib allocated list of From: addresses
*/
-InternetAddressList * g_mime_message_get_from (GMimeMessage *message);
+InternetAddressList *g_mime_message_get_from (GMimeMessage *message);
/**
* return string for From: address
* (owned by gmime)
*/
-const char * g_mime_message_get_from_string (GMimeMessage *message);
+const char *g_mime_message_get_from_string (GMimeMessage *message);
-InternetAddressList * g_mime_message_get_reply_to_list (GMimeMessage *message);
+InternetAddressList *g_mime_message_get_reply_to_list (GMimeMessage *message);
/**
* return talloc allocated reply-to string
*/
-char * g_mime_message_get_reply_to_string (void *ctx, GMimeMessage *message);
+char *g_mime_message_get_reply_to_string (void *ctx, GMimeMessage *message);
void g_mime_parser_set_scan_from (GMimeParser *parser, gboolean flag);
/**
* Return string for valid User ID (or NULL if no valid User ID exists)
*/
-const char * g_mime_certificate_get_valid_userid (GMimeCertificate *cert);
+const char *g_mime_certificate_get_valid_userid (GMimeCertificate *cert);
#ifdef __cplusplus
}
if (*out == NULL)
*out_size = 0;
- if (!maybe_realloc (ctx, needed, out, out_size))
+ if (! maybe_realloc (ctx, needed, out, out_size))
return HEX_OUT_OF_MEMORY;
q = *out;
if (is_output (*p)) {
*q++ = *p++;
} else {
- sprintf (q, "%%%02x", (unsigned char)*p++);
+ sprintf (q, "%%%02x", (unsigned char) *p++);
q += 3;
}
}
char *endp;
/* This also handles unexpected end-of-string. */
- if (!isxdigit ((unsigned char) in[1]) ||
- !isxdigit ((unsigned char) in[2]))
+ if (! isxdigit ((unsigned char) in[1]) ||
+ ! isxdigit ((unsigned char) in[2]))
return HEX_SYNTAX_ERROR;
buf[0] = in[1];
}
hex_status_t
-hex_decode (void *ctx, const char *in, char **out, size_t * out_size)
+hex_decode (void *ctx, const char *in, char **out, size_t *out_size)
{
const char *p;
- size_t needed = 1; /* for the NUL */
+ size_t needed = 1; /* for the NUL */
assert (ctx); assert (in); assert (out); assert (out_size);
else
needed += 1;
- if (!maybe_realloc (ctx, needed, out, out_size))
+ if (! maybe_realloc (ctx, needed, out, out_size))
return HEX_OUT_OF_MEMORY;
return hex_decode_internal (in, (unsigned char *) *out);
hex_status_t
hex_encode (void *talloc_ctx, const char *in, char **out,
- size_t *out_size);
+ size_t *out_size);
hex_status_t
hex_decode (void *talloc_ctx, const char *in, char **out,
- size_t *out_size);
+ size_t *out_size);
/*
* Non-allocating hex decode to decode 's' in-place. The length of the
--- /dev/null
+/* notmuch - Not much of an email program, (just index and search)
+ *
+ * Copyright © 2019 Daniel Kahn Gillmor
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ *
+ * Authors: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+ */
+
+#include <stdbool.h>
+#include "repair.h"
+
+
+static bool
+_notmuch_crypto_payload_has_legacy_display (GMimeObject *payload)
+{
+ GMimeMultipart *mpayload;
+ const char *protected_header_parameter;
+ GMimeTextPart *legacy_display;
+ char *legacy_display_header_text = NULL;
+ GMimeStream *stream = NULL;
+ GMimeParser *parser = NULL;
+ GMimeObject *legacy_header_object = NULL, *first;
+ GMimeHeaderList *legacy_display_headers = NULL, *protected_headers = NULL;
+ bool ret = false;
+
+ if (! g_mime_content_type_is_type (g_mime_object_get_content_type (payload),
+ "multipart", "mixed"))
+ return false;
+ protected_header_parameter = g_mime_object_get_content_type_parameter (payload, "protected-headers");
+ if ((! protected_header_parameter) || strcmp (protected_header_parameter, "v1"))
+ return false;
+ if (! GMIME_IS_MULTIPART (payload))
+ return false;
+ mpayload = GMIME_MULTIPART (payload);
+ if (mpayload == NULL)
+ return false;
+ if (g_mime_multipart_get_count (mpayload) != 2)
+ return false;
+ first = g_mime_multipart_get_part (mpayload, 0);
+ if (! g_mime_content_type_is_type (g_mime_object_get_content_type (first),
+ "text", "rfc822-headers"))
+ return false;
+ protected_header_parameter = g_mime_object_get_content_type_parameter (first, "protected-headers");
+ if ((! protected_header_parameter) || strcmp (protected_header_parameter, "v1"))
+ return false;
+ if (! GMIME_IS_TEXT_PART (first))
+ return false;
+
+ /* ensure that the headers in the first part all match the values
+ * found in the payload's own protected headers! if they don't,
+ * we should not treat this as a valid "legacy-display" part.
+ *
+ * Crafting a GMimeHeaderList object from the content of the
+ * text/rfc822-headers part is pretty clumsy; we should probably
+ * push something into GMime that makes this a one-shot
+ * operation. */
+ if ((protected_headers = g_mime_object_get_header_list (payload), protected_headers) &&
+ (legacy_display = GMIME_TEXT_PART (first), legacy_display) &&
+ (legacy_display_header_text = g_mime_text_part_get_text (legacy_display), legacy_display_header_text) &&
+ (stream = g_mime_stream_mem_new_with_buffer (legacy_display_header_text, strlen (legacy_display_header_text)), stream) &&
+ (g_mime_stream_write (stream, "\r\n\r\n", 4) == 4) &&
+ (g_mime_stream_seek (stream, 0, GMIME_STREAM_SEEK_SET) == 0) &&
+ (parser = g_mime_parser_new_with_stream (stream), parser) &&
+ (legacy_header_object = g_mime_parser_construct_part (parser, NULL), legacy_header_object) &&
+ (legacy_display_headers = g_mime_object_get_header_list (legacy_header_object), legacy_display_headers)) {
+ /* walk through legacy_display_headers, comparing them against
+ * their values in the protected_headers: */
+ ret = true;
+ for (int i = 0; i < g_mime_header_list_get_count (legacy_display_headers); i++) {
+ GMimeHeader *dh = g_mime_header_list_get_header_at (legacy_display_headers, i);
+ if (dh == NULL) {
+ ret = false;
+ goto DONE;
+ }
+ GMimeHeader *ph = g_mime_header_list_get_header (protected_headers, g_mime_header_get_name (dh));
+ if (ph == NULL) {
+ ret = false;
+ goto DONE;
+ }
+ const char *dhv = g_mime_header_get_value (dh);
+ const char *phv = g_mime_header_get_value (ph);
+ if (dhv == NULL || phv == NULL || strcmp (dhv, phv)) {
+ ret = false;
+ goto DONE;
+ }
+ }
+ }
+
+ DONE:
+ if (legacy_display_header_text)
+ g_free (legacy_display_header_text);
+ if (stream)
+ g_object_unref (stream);
+ if (parser)
+ g_object_unref (parser);
+ if (legacy_header_object)
+ g_object_unref (legacy_header_object);
+
+ return ret;
+}
+
+GMimeObject *
+_notmuch_repair_crypto_payload_skip_legacy_display (GMimeObject *payload)
+{
+ if (_notmuch_crypto_payload_has_legacy_display (payload)) {
+ return g_mime_multipart_get_part (GMIME_MULTIPART (payload), 1);
+ } else {
+ return payload;
+ }
+}
+
+/* see
+ * https://tools.ietf.org/html/draft-dkg-openpgp-pgpmime-message-mangling-00#section-4.1.1 */
+static bool
+_notmuch_is_mixed_up_mangled (GMimeObject *part)
+{
+ GMimeMultipart *mpart = NULL;
+ GMimeObject *parts[3] = {NULL, NULL, NULL};
+ GMimeContentType *type = NULL;
+ char *prelude_string = NULL;
+ bool prelude_is_empty;
+
+ if (part == NULL)
+ return false;
+ type = g_mime_object_get_content_type (part);
+ if (type == NULL)
+ return false;
+ if (! g_mime_content_type_is_type (type, "multipart", "mixed"))
+ return false;
+ if (! GMIME_IS_MULTIPART (part)) /* probably impossible */
+ return false;
+ mpart = GMIME_MULTIPART (part);
+ if (mpart == NULL)
+ return false;
+ if (g_mime_multipart_get_count (mpart) != 3)
+ return false;
+ parts[0] = g_mime_multipart_get_part (mpart, 0);
+ if (! g_mime_content_type_is_type (g_mime_object_get_content_type (parts[0]),
+ "text", "plain"))
+ return false;
+ if (! GMIME_IS_TEXT_PART (parts[0]))
+ return false;
+ parts[1] = g_mime_multipart_get_part (mpart, 1);
+ if (! g_mime_content_type_is_type (g_mime_object_get_content_type (parts[1]),
+ "application", "pgp-encrypted"))
+ return false;
+ parts[2] = g_mime_multipart_get_part (mpart, 2);
+ if (! g_mime_content_type_is_type (g_mime_object_get_content_type (parts[2]),
+ "application", "octet-stream"))
+ return false;
+
+ /* Is parts[0] length 0? */
+ prelude_string = g_mime_text_part_get_text (GMIME_TEXT_PART (parts[0]));
+ prelude_is_empty = (prelude_string[0] == '\0');
+ g_free (prelude_string);
+ if (! prelude_is_empty)
+ return false;
+
+ /* FIXME: after decoding and stripping whitespace, is parts[1]
+ * subpart just "Version: 1" ? */
+
+ /* FIXME: can we determine that parts[2] subpart is *only* PGP
+ * encrypted data? I tried g_mime_part_get_openpgp_data () but
+ * found https://github.com/jstedfast/gmime/issues/60 */
+
+ return true;
+}
+
+
+/* see
+ * https://tools.ietf.org/html/draft-dkg-openpgp-pgpmime-message-mangling-00#section-4.1.2 */
+GMimeObject *
+_notmuch_repair_mixed_up_mangled (GMimeObject *part)
+{
+ GMimeMultipart *mpart = NULL, *mpart_ret = NULL;
+ GMimeObject *ret = NULL;
+
+ if (! _notmuch_is_mixed_up_mangled (part))
+ return NULL;
+ mpart = GMIME_MULTIPART (part);
+ ret = GMIME_OBJECT (g_mime_multipart_encrypted_new ());
+ if (ret == NULL)
+ return NULL;
+ mpart_ret = GMIME_MULTIPART (ret);
+ if (mpart_ret == NULL) {
+ g_object_unref (ret);
+ return NULL;
+ }
+ g_mime_object_set_content_type_parameter (ret, "protocol", "application/pgp-encrypted");
+
+ g_mime_multipart_insert (mpart_ret, 0, g_mime_multipart_get_part (mpart, 1));
+ g_mime_multipart_insert (mpart_ret, 1, g_mime_multipart_get_part (mpart, 2));
+ return ret;
+}
--- /dev/null
+#ifndef _REPAIR_H
+#define _REPAIR_H
+
+#include "gmime-extra.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is a collection of message structure and message format repair
+ * techniques that are designed to improve the user experience of
+ * notmuch */
+
+/* If payload is a cryptographic payload within an encrypted message, and
+ * it has a "legacy display" part, then we can skip over it and jump
+ * to the actual content, because notmuch already handles protected
+ * headers appropriately.
+ *
+ * This function either returns payload directly (if it does not have
+ * a "legacy display" part), or it returns a pointer to its
+ * content-bearing subpart, with the "legacy display" part and the
+ * surrounding multipart/mixed object bypassed.
+ *
+ * No new objects are created by calling this function, and the
+ * returned object will only be released when the original part is
+ * disposed of.
+ */
+
+GMimeObject *
+_notmuch_repair_crypto_payload_skip_legacy_display (GMimeObject *payload);
+
+/* Detecting and repairing "Mixed-Up MIME mangling". see
+ * https://tools.ietf.org/html/draft-dkg-openpgp-pgpmime-message-mangling-00#section-4.1
+ * If this returns NULL, the message was probably not "Mixed up". If
+ * it returns non-NULL, then there is a newly-allocated MIME part that
+ * represents the repaired version. The caller is responsible for
+ * ensuring that any returned object is freed with g_object_unref. */
+GMimeObject *
+_notmuch_repair_mixed_up_mangled (GMimeObject *part);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
{
/* strtok_len is already const-safe, but we can't express both
* versions in the C type system. */
- return strtok_len ((char*)s, delim, len);
+ return strtok_len ((char *) s, delim, len);
}
char *
for (loop = out; *loop; loop++) {
if (*loop == '\t' || *loop == '\n')
*loop = ' ';
- else if ((unsigned char)(*loop) < 32)
+ else if ((unsigned char) (*loop) < 32)
*loop = '?';
}
* beginning, and anything containing non-ASCII text. */
if (! term[0])
need_quoting = 1;
- for (in = term; *in && !need_quoting; in++)
+ for (in = term; *in && ! need_quoting; in++)
if (is_unquoted_terminator (*in) || *in == '"' || *in == '('
- || (unsigned char)*in > 127)
+ || (unsigned char) *in > 127)
need_quoting = 1;
if (need_quoting)
return 0;
}
-const char*
+const char *
skip_space (const char *str)
{
while (*str && isspace ((unsigned char) *str))
char **prefix_out, char **term_out)
{
int err = EINVAL;
+
*prefix_out = *term_out = NULL;
/* Parse prefix */
}
/* Did the term terminate without a closing quote or is there
* trailing text after the closing quote? */
- if (!closed || *pos)
+ if (! closed || *pos)
goto FAIL;
*out = '\0';
} else {
}
return 0;
- FAIL:
+ FAIL:
talloc_free (*prefix_out);
talloc_free (*term_out);
errno = err;
else if (! s1 && ! s2)
return 0;
else if (s1)
- return 1; /* s1 (non-NULL) is greater than s2 (NULL) */
+ return 1; /* s1 (non-NULL) is greater than s2 (NULL) */
else
- return -1; /* s1 (NULL) is less than s2 (non-NULL) */
+ return -1; /* s1 (NULL) is less than s2 (non-NULL) */
}
int
/* This is the djb2 hash. */
unsigned int hash = 5381;
+
while (s && *s) {
hash = ((hash << 5) + hash) + tolower (*s);
s++;
void strip_trailing (char *str, char ch);
-const char* skip_space (const char *str);
+const char *skip_space (const char *str);
#ifdef __cplusplus
}
#include "unicode-util.h"
/* Based on Xapian::Unicode::is_wordchar, to avoid forcing clients to
- link directly to libxapian.
-*/
+ * link directly to libxapian.
+ */
static bool
unicode_is_wordchar (notmuch_unichar ch)
/* we lack context to be more informative here */
return "zlib error";
default:
- INTERNAL_ERROR("unexpected error status %d", errnum);
+ INTERNAL_ERROR ("unexpected error status %d", errnum);
}
}
regerror (rerr, preg, error, error_size);
fprintf (stderr, "compiling regex %s: %s\n",
- regex, error);
+ regex, error);
free (error);
return 1;
}
if (buf == NULL)
return UTIL_OUT_OF_MEMORY;
}
- SUCCESS:
+ SUCCESS:
*bufptr = buf;
*bytes_read = offset;
return UTIL_SUCCESS;
}
-const char *gz_error_string (util_status_t status, gzFile file)
+const char *
+gz_error_string (util_status_t status, gzFile file)
{
if (status == UTIL_GZERROR)
return gzerror (file, NULL);