aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-07-19 15:16:16 +0300
committerSergey Poznyakoff <gray@gnu.org>2019-07-19 15:16:16 +0300
commitdd9d9c1240774e21c7eb50052225ff1e4cc376ee (patch)
treea06490ee30ab5bee2e707ffd6f0ab07a4e4ebd60
parentaf538cc27228edf816edea1bf52c84b5bb4f8720 (diff)
downloadwydawca-dd9d9c1240774e21c7eb50052225ff1e4cc376ee.tar.gz
wydawca-dd9d9c1240774e21c7eb50052225ff1e4cc376ee.tar.bz2
Create destination directories if necessary
* src/config.c (spool_kw): New statements: destination-mode and destination-owner. See the description of the similar source-* statements in the previous commit. * src/diskio.c (create_hierarchy): First argument is const. * src/vtab.c (wy_url) <local>: New member. (wy_url_is_local): New function. * src/wydawca.h (spool) <dest_metadata>: New member. (create_hierarchy): Change signature.
-rw-r--r--src/config.c83
-rw-r--r--src/diskio.c2
-rw-r--r--src/vtab.c9
-rw-r--r--src/wydawca.h4
4 files changed, 65 insertions, 33 deletions
diff --git a/src/config.c b/src/config.c
index eb5f7f5..ca0d750 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1138,6 +1138,18 @@ static struct grecs_keyword spool_kw[] = {
grecs_type_string, GRECS_CONST,
NULL, offsetof(struct spool, dest_url),
cb_url },
+ { "destination-mode",
+ N_("mode: octal"),
+ N_("mode for the destination directory (if local)"),
+ grecs_type_string, GRECS_CONST,
+ NULL, offsetof(struct spool, dest_metadata),
+ cb_metadata_mode },
+ { "destination-owner",
+ N_("uid: name-or-uid> <gid: name-or-gid"),
+ N_("owner user and group for the destination directory (if local)"),
+ grecs_type_string, GRECS_CONST,
+ NULL, offsetof(struct spool, dest_metadata),
+ cb_metadata_owner },
{ "file-sweep-time", N_("interval"), N_("Define file sweep time"),
grecs_type_string, GRECS_CONST,
NULL, offsetof(struct spool, file_sweep_time),
@@ -1552,55 +1564,64 @@ config_init()
}
static int
-create_source(struct spool *spool, void *data)
+create_spool_dir(struct spool *spool, char const *dir,
+ struct directory_metadata *meta,
+ char const *descr)
{
struct stat st;
int rc;
- if ((rc = stat(spool->source_dir, &st)) != 0) {
+ if ((rc = stat(dir, &st)) != 0) {
if (errno != ENOENT) {
- grecs_error(NULL, errno, _("%s: cannot stat %s"),
- spool->tag, spool->source_dir);
- *(int*)data = 1;
- return 0;
+ grecs_error(NULL, errno, _("%s: cannot stat %s %s"),
+ spool->tag, descr, dir);
+ return 1;
} else {
- wy_debug(1, (_("creating spool source directory %s"),
- spool->source_dir));
- if (create_hierarchy(spool->source_dir, 0)) {
- *(int*)data = 1;
- return 0;
+ wy_debug(1, (_("%s: creating %s"), spool->tag, descr));
+ if (create_hierarchy(dir, 0)) {
+ return 1;
}
}
} else if (!S_ISDIR(st.st_mode)) {
grecs_error(NULL, errno, _("%s: %s is not a directory"),
- spool->tag, spool->source_dir);
- *(int*)data = 1;
- return 0;
+ spool->tag, dir);
+ return 1;
}
- if ((spool->source_metadata.flags & METADATA_OWNER)
+ if ((meta->flags & METADATA_OWNER)
&& (rc
- || st.st_uid != spool->source_metadata.uid
- || st.st_gid != spool->source_metadata.gid)
- && chown(spool->source_dir,
- spool->source_metadata.uid,
- spool->source_metadata.gid)) {
- grecs_error(NULL, errno, _("%s: can't chown %s"),
- spool->tag, spool->source_dir);
- *(int*)data = 1;
- return 0;
+ || st.st_uid != meta->uid
+ || st.st_gid != meta->gid)
+ && chown(dir, meta->uid, meta->gid)) {
+ grecs_error(NULL, errno, _("%s: can't chown %s %s"),
+ spool->tag, descr, dir);
+ return 1;
}
- if ((spool->source_metadata.flags & METADATA_MODE)
- && (rc || (st.st_mode & 07777) != spool->source_metadata.mode)
- && chmod(spool->source_dir, spool->source_metadata.mode)) {
- grecs_error(NULL, errno, _("%s: can't chmod %s"),
- spool->tag, spool->source_dir);
- *(int*)data = 1;
+ if ((meta->flags & METADATA_MODE)
+ && (rc || (st.st_mode & 07777) != meta->mode)
+ && chmod(dir, meta->mode)) {
+ grecs_error(NULL, errno, _("%s: can't chmod %s %s"),
+ spool->tag, descr, dir);
+ return 1;
}
return 0;
}
+static int
+create_spool_dirs(struct spool *spool, void *data)
+{
+ if (create_spool_dir(spool, spool->source_dir, &spool->source_metadata,
+ _("source directory")))
+ *(int*)data = 1;
+ if (!wy_url_is_local(spool->dest_url)
+ && create_spool_dir(spool, spool->dest_dir,
+ &spool->dest_metadata,
+ _("destination directory")))
+ *(int*)data = 1;
+ return 0;
+}
+
void
config_finish(struct grecs_node *tree)
{
@@ -1622,6 +1643,6 @@ config_finish(struct grecs_node *tree)
}
err = 0;
- if (for_each_spool(create_source, &err) || err)
+ if (for_each_spool(create_spool_dirs, &err) || err)
exit(EX_CONFIG);
}
diff --git a/src/diskio.c b/src/diskio.c
index 1d072d4..6bed916 100644
--- a/src/diskio.c
+++ b/src/diskio.c
@@ -59,7 +59,7 @@ concat_dir(const char *base, const char *name, size_t * pbaselen)
/* Create the directory DIR, eventually creating all intermediate directories
starting from DIR + BASELEN. */
int
-create_hierarchy(char *dir, size_t baselen)
+create_hierarchy(char const *dir, size_t baselen)
{
int rc;
struct stat st;
diff --git a/src/vtab.c b/src/vtab.c
index a93a489..6e7cc82 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -21,6 +21,7 @@ struct wy_url {
char *printable;
char *scheme;
char *path;
+ int local:1;
};
wy_url_t
@@ -33,6 +34,7 @@ wy_url_create(const char *str)
if (*str == '/') {
url->scheme = grecs_strdup("file");
url->path = grecs_strdup(str);
+ url->local = 1;
} else {
size_t len = strcspn(str, ":");
if (!str[len]) {
@@ -50,6 +52,7 @@ wy_url_create(const char *str)
url->path = grecs_strdup(str + len + 1);
else
url->path = NULL;
+ url->local = 0;
}
return url;
}
@@ -81,6 +84,12 @@ wy_url_printable(wy_url_t url)
return url->printable;
}
+int
+wy_url_is_local(wy_url_t url)
+{
+ return url && url->local;
+}
+
struct virt_tab_reg {
char *scheme;
diff --git a/src/wydawca.h b/src/wydawca.h
index 1001694..cfd3ae2 100644
--- a/src/wydawca.h
+++ b/src/wydawca.h
@@ -204,6 +204,7 @@ void wy_url_free(wy_url_t url);
const char *wy_url_path(wy_url_t url);
const char *wy_url_scheme(wy_url_t url);
const char *wy_url_printable(wy_url_t url);
+int wy_url_is_local(wy_url_t url);
struct virt_tab {
int (*test_url) (wy_url_t url, grecs_locus_t * loc);
@@ -236,6 +237,7 @@ struct spool {
struct directory_metadata source_metadata;
wy_url_t dest_url; /* Destination URL */
const char *dest_dir; /* Directory part of the above */
+ struct directory_metadata dest_metadata;
struct virt_tab vtab; /* Virtual method table */
int inotify_enable;
@@ -398,7 +400,7 @@ size_t trim(char *str);
int test_dir(const char *name, int *ec);
char *create_directory(const char *base, const char *name);
-int create_hierarchy(char *dir, size_t baselen);
+int create_hierarchy(char const *dir, size_t baselen);
void parse_config(void);
void log_output(int prio, const char *prog, FILE * fp);

Return to:

Send suggestions and report system problems to the System administrator.