mirror of https://github.com/djcb/mu.git
* add symlink support, code refactoring
This commit is contained in:
parent
f8ba8fbd3c
commit
366c1ea44f
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
** Copyright (C) 2009 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mu-maildir.h"
|
||||
|
||||
static gboolean
|
||||
_create_maildir (const char *path, int mode, GError **err)
|
||||
{
|
||||
int i;
|
||||
const gchar* subdirs[] = {"new", "cur", "tmp"};
|
||||
|
||||
/* make sure it does not exist yet */
|
||||
if (access (path, F_OK) == 0)
|
||||
errno = EEXIST;
|
||||
if (errno != ENOENT) {
|
||||
g_set_error (err, 0, 0, "%s", strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i != G_N_ELEMENTS(subdirs); ++i) {
|
||||
|
||||
gchar *fullpath;
|
||||
int rv;
|
||||
|
||||
fullpath = g_strdup_printf ("%s%c%s", path,
|
||||
G_DIR_SEPARATOR,
|
||||
subdirs[i]);
|
||||
rv = g_mkdir_with_parents (fullpath, mode);
|
||||
g_free (fullpath);
|
||||
|
||||
if (rv != 0) {
|
||||
g_set_error (err, 0, 0, "%s",
|
||||
strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_create_noindex (const char *path, GError **err)
|
||||
{
|
||||
/* create a noindex file if requested */
|
||||
int fd;
|
||||
gchar *noindexpath;
|
||||
noindexpath = g_strdup_printf ("%s%c%s", path,
|
||||
G_DIR_SEPARATOR,
|
||||
".noindex");
|
||||
fd = creat (noindexpath, 0644);
|
||||
g_free (noindexpath);
|
||||
if (fd < 0 || close (fd) != 0) {
|
||||
g_set_error (err, 0, 0, "%s", strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
mu_maildir_mkmdir (const char* path, int mode,
|
||||
gboolean noindex, GError **err)
|
||||
{
|
||||
|
||||
g_return_val_if_fail (path, FALSE);
|
||||
|
||||
if (!_create_maildir (path, mode, err))
|
||||
return FALSE;
|
||||
|
||||
if (noindex && !_create_noindex (path, err))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* determine whether the source message is in 'new' or in 'cur';
|
||||
* we ignore messages in 'tmp' for obvious reasons */
|
||||
static gboolean
|
||||
_check_subdir (const char *src, gboolean *in_cur, GError **err)
|
||||
{
|
||||
gchar *srcpath;
|
||||
|
||||
srcpath = g_path_get_dirname (src);
|
||||
|
||||
if (g_str_has_suffix (srcpath, "new"))
|
||||
*in_cur = FALSE;
|
||||
else if (g_str_has_suffix (srcpath, "cur"))
|
||||
*in_cur = TRUE;
|
||||
else {
|
||||
g_set_error (err, 0, 0, "%s",
|
||||
"Invalid source message");
|
||||
return FALSE;
|
||||
}
|
||||
g_free (srcpath);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
_get_target_fullpath (const char* src, const gchar *targetpath,
|
||||
GError **err)
|
||||
{
|
||||
gchar *targetfullpath;
|
||||
gchar *srcfile;
|
||||
gboolean in_cur;
|
||||
|
||||
if (!_check_subdir (src, &in_cur, err))
|
||||
return NULL;
|
||||
|
||||
srcfile = g_path_get_basename (src);
|
||||
|
||||
/* create & test targetpath */
|
||||
targetfullpath = g_strdup_printf ("%s%c%s%c%s",
|
||||
targetpath,
|
||||
G_DIR_SEPARATOR,
|
||||
in_cur ? "cur" : "new",
|
||||
G_DIR_SEPARATOR,
|
||||
srcfile);
|
||||
g_free (srcfile);
|
||||
|
||||
return targetfullpath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gboolean
|
||||
mu_maildir_link (const char* src, const char *targetpath,
|
||||
GError **err)
|
||||
{
|
||||
gchar *targetfullpath;
|
||||
int rv;
|
||||
|
||||
g_return_val_if_fail (src, FALSE);
|
||||
g_return_val_if_fail (targetpath, FALSE);
|
||||
|
||||
/* just a basic check */
|
||||
if (access (src, R_OK) != 0) {
|
||||
g_set_error (err, 0, 0, "Cannot read source message: %s",
|
||||
strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
targetfullpath = _get_target_fullpath (src, targetpath, err);
|
||||
if (!targetfullpath)
|
||||
return FALSE;
|
||||
|
||||
rv = symlink (src, targetfullpath);
|
||||
g_free (targetfullpath);
|
||||
if (rv != 0) {
|
||||
g_set_error (err, 0, 0, "Error creating link: %s",
|
||||
strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
** Copyright (C) 2009 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef __MU_MAILDIR_H__
|
||||
#define __MU_MAILDIR_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/**
|
||||
* create a new maildir. Note, if the function fails 'halfway', it
|
||||
* will *not* try to remove the parts the were created.
|
||||
*
|
||||
* @param path the path (missing components will be created, as in 'mkdir -p')
|
||||
* @param mode the file mode (e.g., 0755)
|
||||
* @param noindex add a .noindex file to the maildir, so it will be excluded
|
||||
* from indexing by 'mu index'
|
||||
* @param err a GError* to receive error info, or NULL
|
||||
*
|
||||
* @return TRUE if creation succeeded, FALSE otherwise
|
||||
*/
|
||||
gboolean mu_maildir_mkmdir (const char* path, int mode,
|
||||
gboolean noindex, GError **err);
|
||||
|
||||
|
||||
/**
|
||||
* create a symbolic link to a mail message; the function will
|
||||
* automatically
|
||||
*
|
||||
* @param src the full path to the source message
|
||||
* @param targetpath the path to the target maildir; ie., *not*
|
||||
* MyMaildir/cur, but just MyMaildir/. The function will figure out
|
||||
* the correct subdir then. *
|
||||
* @param err a GError* to receive error info, or NULL
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
gboolean mu_maildir_link (const char* src, const char *targetpath,
|
||||
GError **err);
|
||||
|
||||
#endif /*__MU_MAILDIR_H__*/
|
39
src/mu.c
39
src/mu.c
|
@ -38,6 +38,7 @@ enum _MuCmd {
|
|||
MU_CMD_INDEX,
|
||||
MU_CMD_QUERY,
|
||||
MU_CMD_MKDIR,
|
||||
MU_CMD_LINK,
|
||||
MU_CMD_HELP,
|
||||
MU_CMD_UNKNOWN
|
||||
};
|
||||
|
@ -62,6 +63,9 @@ parse_cmd (const char* cmd)
|
|||
if ((strcmp (cmd, "mkmdir") == 0) ||
|
||||
(strcmp (cmd, "mkdir") == 0))
|
||||
return MU_CMD_MKDIR;
|
||||
|
||||
if (strcmp (cmd, "link") == 0)
|
||||
return MU_CMD_LINK;
|
||||
|
||||
if ((strcmp (cmd, "help") == 0) ||
|
||||
(strcmp (cmd, "info") == 0))
|
||||
|
@ -112,7 +116,8 @@ make_maildir (MuConfigOptions *opts)
|
|||
i = 1;
|
||||
while (opts->params[i]) {
|
||||
GError *err = NULL;
|
||||
if (!mu_maildir_mkmdir (opts->params[i], 0755, &err)) {
|
||||
if (!mu_maildir_mkmdir (opts->params[i], 0755, FALSE,
|
||||
&err)) {
|
||||
g_printerr ("error creating %s: %s\n",
|
||||
opts->params[i], err->message);
|
||||
g_error_free (err);
|
||||
|
@ -123,7 +128,34 @@ make_maildir (MuConfigOptions *opts)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
make_symlink (MuConfigOptions *opts)
|
||||
{
|
||||
GError *err;
|
||||
|
||||
if (!opts->params[0])
|
||||
return 1; /* shouldn't happen */
|
||||
|
||||
if (!opts->params[1] || !opts->params[2]) {
|
||||
g_printerr ("usage: mu link <src> <targetdir>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = NULL;
|
||||
if (!mu_maildir_link (opts->params[1], opts->params[2], &err)) {
|
||||
if (err) {
|
||||
g_printerr ("error: %s\n", err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -165,7 +197,7 @@ show_help (MuConfigOptions *opts)
|
|||
{
|
||||
/* FIXME: get context-sensitive help */
|
||||
show_version ();
|
||||
show_usage (FALSE);
|
||||
return show_usage (FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -240,6 +272,9 @@ main (int argc, char *argv[])
|
|||
if (cmd == MU_CMD_MKDIR)
|
||||
return make_maildir (&config);
|
||||
|
||||
if (cmd == MU_CMD_LINK)
|
||||
return make_symlink (&config);
|
||||
|
||||
if (!init_log (&config))
|
||||
return 1;
|
||||
|
||||
|
|
Loading…
Reference in New Issue