author | Olivier Brunel
<jjk@jjacky.com> 2015-03-16 17:53:09 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2015-04-04 12:47:36 UTC |
parent | a6ffa900d6e8d26976943445e970aa601f300709 |
doc/aa-enable.pod | +14 | -1 |
src/include/anopa/copy_file.h | +9 | -1 |
src/include/anopa/enable_service.h | +4 | -3 |
src/libanopa/copy_file.c | +8 | -2 |
src/libanopa/enable_service.c | +22 | -4 |
src/utils/aa-mvlog.c | +1 | -1 |
diff --git a/doc/aa-enable.pod b/doc/aa-enable.pod index 46ca81f..4a271e9 100644 --- a/doc/aa-enable.pod +++ b/doc/aa-enable.pod @@ -110,7 +110,8 @@ this is a long-run or one-shot service. - If the service name came from a directory in I<LISTDIR>, its content is then merged/copied over into the servicedir. This allows to specify service-specific -configuration, or could possibly be used to overwrite an actual script. +configuration, or could possibly be used to overwrite an actual script. See +below for how to remove/append to files. - If the service is a long-run, an empty regular file I<down> is created (unless it already existed, or the service was specified to B<--skip-down>) to ensure @@ -160,3 +161,15 @@ source directory); Or use a directory to simply specify/add configuration files. Note that you can also still provide files from the configuration directory in listdir, since it is copied last (and that this always includes providing a new I<run> file). + +=head2 Removing/appending to files + +When copying files from the "configuration directory" (directory in I<LISTDIR>) +regular files starting with either a dash ( - ) or plus sign ( + ) are processed +in a special manner: + +- A file I<-foobar> will have B<aa-enable>(1) remove file I<foobar> from the +destination servicedir, if it exists. + +- A file I<+foobar> will have its content be appended to I<foobar> in the +destination servicedir. diff --git a/src/include/anopa/copy_file.h b/src/include/anopa/copy_file.h index 9210255..90fb671 100644 --- a/src/include/anopa/copy_file.h +++ b/src/include/anopa/copy_file.h @@ -2,6 +2,14 @@ #ifndef AA_COPY_FILE_H #define AA_COPY_FILE_H -int aa_copy_file (const char *src, const char *dst, mode_t mode, int overwrite); +typedef enum +{ + AA_CP_CREATE = 0, + AA_CP_OVERWRITE, + AA_CP_APPEND, + _AA_CP_NB +} aa_cp; + +int aa_copy_file (const char *src, const char *dst, mode_t mode, aa_cp cp); #endif /* AA_COPY_FILE_H */ diff --git a/src/include/anopa/enable_service.h b/src/include/anopa/enable_service.h index 11031ec..9e38388 100644 --- a/src/include/anopa/enable_service.h +++ b/src/include/anopa/enable_service.h @@ -12,9 +12,10 @@ typedef enum AA_FLAG_SKIP_DOWN = (1 << 2), /* private */ _AA_FLAG_IS_SERVICEDIR = (1 << 3), - _AA_FLAG_IS_NEEDS = (1 << 4), - _AA_FLAG_IS_WANTS = (1 << 5), - _AA_FLAG_IS_BEF_AFT = (1 << 6), + _AA_FLAG_IS_CONFIGDIR = (1 << 4), + _AA_FLAG_IS_NEEDS = (1 << 5), + _AA_FLAG_IS_WANTS = (1 << 6), + _AA_FLAG_IS_BEF_AFT = (1 << 7), _AA_FLAG_IS_1OF4 = _AA_FLAG_IS_NEEDS | _AA_FLAG_IS_WANTS | _AA_FLAG_IS_BEF_AFT } aa_enable_flags; diff --git a/src/libanopa/copy_file.c b/src/libanopa/copy_file.c index 17275a7..dc6771a 100644 --- a/src/libanopa/copy_file.c +++ b/src/libanopa/copy_file.c @@ -2,18 +2,24 @@ #include <errno.h> #include <fcntl.h> #include <skalibs/djbunix.h> +#include <anopa/copy_file.h> int -aa_copy_file (const char *src, const char *dst, mode_t mode, int overwrite) +aa_copy_file (const char *src, const char *dst, mode_t mode, aa_cp cp) { int fd_src; int fd_dst; + int flag[_AA_CP_NB]; fd_src = open_readb (src); if (fd_src < 0) return -1; - fd_dst = open3 (dst, O_WRONLY | O_CREAT | ((overwrite) ? O_TRUNC : O_EXCL), mode); + flag[AA_CP_CREATE] = O_EXCL; + flag[AA_CP_OVERWRITE] = O_TRUNC; + flag[AA_CP_APPEND] = O_APPEND; + + fd_dst = open3 (dst, O_WRONLY | O_CREAT | flag[cp], mode); if (fd_dst < 0) { int e = errno; diff --git a/src/libanopa/enable_service.c b/src/libanopa/enable_service.c index 9336831..e0d3922 100644 --- a/src/libanopa/enable_service.c +++ b/src/libanopa/enable_service.c @@ -201,6 +201,23 @@ copy_dir (const char *src, r = copy_log (dst, NULL, 0, warn_fn); st.st_mode = 0755; } + else if ((flags & _AA_FLAG_IS_CONFIGDIR) && len > 1 + && (satmp.s[i] == '-' || satmp.s[i] == '+')) + { + byte_copy (buf_dst + l_dst + 1, len, satmp.s + i + 1); + + if (satmp.s[i] == '-') + { + r = unlink (buf_dst); + if (r < 0 && errno == ENOENT) + /* not an error */ + r = 0; + /* skip lchown/chmod calls */ + goto next; + } + else /* '+' */ + r = aa_copy_file (buf_src, buf_dst, st.st_mode, AA_CP_APPEND); + } else { /* for any file in one of the 4 special places that ends @@ -208,7 +225,7 @@ copy_dir (const char *src, if (depth == 1 && instance && (flags & _AA_FLAG_IS_1OF4) && satmp.s[i + len - 1] == '@') byte_copy (buf_dst + l_dst + 1 + len, l_inst + 1, instance); - r = aa_copy_file (buf_src, buf_dst, st.st_mode, 1); + r = aa_copy_file (buf_src, buf_dst, st.st_mode, AA_CP_OVERWRITE); if (depth == 1 && r == 0 && ae_cb) { if ((flags & (AA_FLAG_AUTO_ENABLE_NEEDS | _AA_FLAG_IS_NEEDS)) @@ -270,6 +287,7 @@ copy_dir (const char *src, if (r >= 0 && !S_ISLNK (st.st_mode) && !S_ISDIR (st.st_mode)) r = chmod (buf_dst, st.st_mode); +next: if (r < 0) { warn_fn (buf_src, errno); @@ -457,7 +475,7 @@ aa_enable_service (const char *_name, return r; if (name != _name) - return copy_dir (_name, name, _mode, 0, warn_fn, flags, ae_cb, instance); - else - return 0; + r = copy_dir (_name, name, _mode, 0, warn_fn, flags | _AA_FLAG_IS_CONFIGDIR, ae_cb, instance); + + return r; } diff --git a/src/utils/aa-mvlog.c b/src/utils/aa-mvlog.c index cc55d53..6aec2fe 100644 --- a/src/utils/aa-mvlog.c +++ b/src/utils/aa-mvlog.c @@ -54,7 +54,7 @@ main (int argc, char * const argv[]) strerr_dief2x (2, "invalid new name read from ", argv[1]); newname[l + 26] = '\0'; - if (aa_copy_file (argv[1], newname, st.st_mode, 0) < 0) + if (aa_copy_file (argv[1], newname, st.st_mode, AA_CP_CREATE) < 0) strerr_diefu4sys (2, "copy ", argv[1], " as ", newname); byte_copy (target, 26, newname + l + 1);