notmuch_database_create/open: Fix to handle NULL as documented.

When documenting these functions I described support for a
NOTMUCH_BASE environment variable to be consulted in the case
of a NULL path. Only, I had forgotten to actually write the
code.

This code exists now, with a new, exported function:

     notmuch_database_default_path
This commit is contained in:
Carl Worth 2009-10-20 09:56:25 -07:00
parent ed6ee7330d
commit 55c8ee9a86
3 changed files with 64 additions and 26 deletions

View file

@ -379,24 +379,38 @@ parse_references (GPtrArray *array,
} }
} }
char *
notmuch_database_default_path (void)
{
if (getenv ("NOTMUCH_BASE"))
return strdup (getenv ("NOTMUCH_BASE"));
return g_strdup_printf ("%s/mail", getenv ("HOME"));
}
notmuch_database_t * notmuch_database_t *
notmuch_database_create (const char *path) notmuch_database_create (const char *path)
{ {
char *notmuch_path; notmuch_database_t *notmuch = NULL;
char *notmuch_path = NULL;
struct stat st; struct stat st;
int err; int err;
char *local_path = NULL;
if (path == NULL)
path = local_path = notmuch_database_default_path ();
err = stat (path, &st); err = stat (path, &st);
if (err) { if (err) {
fprintf (stderr, "Error: Cannot create database at %s: %s.\n", fprintf (stderr, "Error: Cannot create database at %s: %s.\n",
path, strerror (errno)); path, strerror (errno));
return NULL; goto DONE;
} }
if (! S_ISDIR (st.st_mode)) { if (! S_ISDIR (st.st_mode)) {
fprintf (stderr, "Error: Cannot create database at %s: Not a directory.\n", fprintf (stderr, "Error: Cannot create database at %s: Not a directory.\n",
path); path);
return NULL; goto DONE;
} }
notmuch_path = g_strdup_printf ("%s/%s", path, ".notmuch"); notmuch_path = g_strdup_printf ("%s/%s", path, ".notmuch");
@ -406,22 +420,31 @@ notmuch_database_create (const char *path)
if (err) { if (err) {
fprintf (stderr, "Error: Cannot create directory %s: %s.\n", fprintf (stderr, "Error: Cannot create directory %s: %s.\n",
notmuch_path, strerror (errno)); notmuch_path, strerror (errno));
free (notmuch_path); goto DONE;
return NULL;
} }
free (notmuch_path); notmuch = notmuch_database_open (path);
return notmuch_database_open (path); DONE:
if (notmuch_path)
free (notmuch_path);
if (local_path)
free (local_path);
return notmuch;
} }
notmuch_database_t * notmuch_database_t *
notmuch_database_open (const char *path) notmuch_database_open (const char *path)
{ {
notmuch_database_t *notmuch; notmuch_database_t *notmuch = NULL;
char *notmuch_path, *xapian_path; char *notmuch_path = NULL, *xapian_path = NULL;
struct stat st; struct stat st;
int err; int err;
char *local_path = NULL;
if (path == NULL)
path = local_path = notmuch_database_default_path ();
notmuch_path = g_strdup_printf ("%s/%s", path, ".notmuch"); notmuch_path = g_strdup_printf ("%s/%s", path, ".notmuch");
@ -429,12 +452,10 @@ notmuch_database_open (const char *path)
if (err) { if (err) {
fprintf (stderr, "Error: Cannot stat %s: %s\n", fprintf (stderr, "Error: Cannot stat %s: %s\n",
notmuch_path, strerror (err)); notmuch_path, strerror (err));
free (notmuch_path); goto DONE;
return NULL;
} }
xapian_path = g_strdup_printf ("%s/%s", notmuch_path, "xapian"); xapian_path = g_strdup_printf ("%s/%s", notmuch_path, "xapian");
free (notmuch_path);
/* C++ is so nasty in requiring these casts. I'm almost tempted to /* C++ is so nasty in requiring these casts. I'm almost tempted to
* write a C wrapper for Xapian... */ * write a C wrapper for Xapian... */
@ -449,7 +470,13 @@ notmuch_database_open (const char *path)
error.get_msg().c_str()); error.get_msg().c_str());
} }
free (xapian_path); DONE:
if (local_path)
free (local_path);
if (notmuch_path)
free (notmuch_path);
if (xapian_path)
free (xapian_path);
return notmuch; return notmuch;
} }

View file

@ -310,25 +310,19 @@ setup_command (int argc, char *argv[])
"such as mb2md. In that case, press Control-C now and run notmuch again\n" "such as mb2md. In that case, press Control-C now and run notmuch again\n"
"once the conversion is complete.\n\n"); "once the conversion is complete.\n\n");
printf ("Top-level mail directory [~/mail]: "); {
fflush (stdout); char *default_path = notmuch_database_default_path ();
printf ("Top-level mail directory [%s]: ", default_path);
free (default_path);
fflush (stdout);
}
mail_directory = read_line (); mail_directory = read_line ();
if (mail_directory == NULL || strlen (mail_directory) == 0) { if (mail_directory == NULL || strlen (mail_directory) == 0) {
char *home;
if (mail_directory) if (mail_directory)
free (mail_directory); free (mail_directory);
mail_directory = notmuch_database_default_path ();
home = getenv ("HOME");
if (!home) {
fprintf (stderr, "Error: No mail directory provided HOME environment variable is not set.\n");
fprintf (stderr, "Cowardly refusing to just guess where your mail might be.\n");
exit (1);
}
mail_directory = g_strdup_printf ("%s/mail", home);
} }
notmuch = notmuch_database_create (mail_directory); notmuch = notmuch_database_create (mail_directory);

View file

@ -110,6 +110,23 @@ notmuch_database_open (const char *path);
void void
notmuch_database_close (notmuch_database_t *database); notmuch_database_close (notmuch_database_t *database);
/* Lookup the default database path.
*
* This is the path that will be used by notmuch_database_create and
* notmuch_database_open if given a NULL path. Specifically it will be
* the value of the NOTMUCH_BASE environment variable if set,
* otherwise ${HOME}/mail
*
* Returns a newly allocated string which the caller should free()
* when finished with it.
*/
char *
notmuch_database_default_path (void);
/* Return the database path of the given database.
*
* The return value is a string owned by notmuch so should not be
* modified nor freed by the caller. */
const char * const char *
notmuch_database_get_path (notmuch_database_t *database); notmuch_database_get_path (notmuch_database_t *database);