diff --git a/README.local-glib b/README.local-glib new file mode 100644 index 0000000..13813fc --- /dev/null +++ b/README.local-glib @@ -0,0 +1,27 @@ +To install with static glib (e.g. when system glib is to old): +============================================================== +git clone https://github.com/GNOME/glib.git glib_src +git -C glib_src checkout 2.70.5 +mkdir glib_build +meson setup glib_build glib_src --buildtype release -Ddefault_library=static +cd glib_build +ninja build + +patch -p1 Makefile <<'EOF' +diff --git a/Makefile b/Makefile +index 921b373..7a0bd0c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + CFLAGS += -O3 + CFLAGS += -g -Wall -Wextra -Werror +-CFLAGS += $(shell pkg-config --cflags glib-2.0) +-LDLIBS += $(shell pkg-config --libs glib-2.0) ++CFLAGS += -Iglib_src -Iglib_src/glib -Iglib_build/glib ++LDLIBS += -Lglib_build/glib -lglib-2.0 -lpthread -lpcre + + cmirror: cmirror.c + +EOF +make + diff --git a/cmirror.c b/cmirror.c index 987d3e4..c625d05 100644 --- a/cmirror.c +++ b/cmirror.c @@ -26,7 +26,6 @@ #include #include -// https://www.manpagez.com/html/glib/glib-2.56.0/glib-Double-ended-Queues.php // http://owww.molgen.mpg.de/~buczek/glib-doc/ #include @@ -61,7 +60,7 @@ static G_NORETURN G_GNUC_PRINTF(1, 2) void die(const char *restrict fmt, ...) { static GRegex *compile_pattern(char *pattern) { GError *error = NULL; - GRegex *regex = g_regex_new(pattern, 0, 0, &error);; + GRegex *regex = g_regex_new(pattern, 0, 0, &error); if (!regex) die("%s\n", error->message); return regex; @@ -112,9 +111,8 @@ static gboolean fn_unescape_cb(const GMatchInfo *match_info, GString *result, g static char *fn_unescape(char *fn) { static GRegex *regex = NULL; - if (!regex) { + if (!regex) regex = compile_pattern("\\\\x([0-9a-f]{0,2})"); - } GError *error; char *ret = g_regex_replace_eval(regex, fn, -1, 0, 0, fn_unescape_cb, NULL, &error); if (!ret) @@ -285,7 +283,7 @@ static int reduce; static int force_status; static int bandwidth; static int allowremotefs; -static char *ssh_opt; +static char **ssh_opts; static int cksum; static int opt_nice; static int unix_socket; @@ -318,17 +316,6 @@ static void fileop_mknod(char *path, char type, dev_t rdev) { die("%s: %m\n", path); } -static void fileop_chown(uid_t uid, gid_t gid, char *path) { - if (slave_unprivileged) - return; - if (fileop_debug) - warn("fileop: chown %d:%d %s\n", uid, gid, path); - if (fileop_noop) - return; - if (lchown(path, uid, gid) == -1) - die("%s: %m\n", path); -} - static void fileop_chmod(mode_t perm, char *path) { if (fileop_debug) warn("fileop: chmod 0%03o %s\n", perm, path); @@ -465,10 +452,10 @@ static void fileop_ln_or_cp(char *from, char *to) { } static void check_perm(FileInfo *is, FileInfo *want) { - if (is->uid != want->uid || is->gid != want ->gid ){ - if (!quiet && !slave_unprivileged) + if (!slave_unprivileged && (is->uid != want->uid || is->gid != want->gid) ) { + if (!quiet) warn("chown %d:%d %s\n", want->uid, want->gid, is->name); - fileop_chown(want->uid, want->gid, is->name); + fileop_lchown(want->uid, want->gid, is->name); } if (want->perm != is->perm) { if (!quiet) @@ -481,7 +468,8 @@ static void make_dir(char *path, mode_t perm, uid_t uid, gid_t gid) { if (!quiet) warn("mkdir %s owner %d:%d mode 0%03o\n", path, uid, gid, perm); fileop_mkdir(path); - fileop_chown(uid, gid, path); + if (!slave_unprivileged) + fileop_lchown(uid, gid, path); fileop_chmod(perm, path); } @@ -505,11 +493,10 @@ static void add_clean_dir(char *dir) { const char *entry; while ( (entry = g_dir_read_name(d)) ) { char *path = g_strdup_printf("%s/%s", dir, entry); - if (is_excepted(path)) { + if (is_excepted(path)) free(path); - } else { + else g_hash_table_insert(CLEAN, path, path); - } } g_dir_close(d); } @@ -527,7 +514,7 @@ static void out_of_the_way(FileInfo *fi) { static int is_local_fs(char *fs) { static GRegex *local_fs_regex; if (!local_fs_regex) - local_fs_regex = compile_pattern("^(advfs|ufs|ext\\d+|reiserfs|xfs|fuseblk|vfat|efs|tmpfs|btrfs)$"); + local_fs_regex = compile_pattern("^(advfs|ufs|ext\\d+|reiserfs|xfs|fuseblk|vfat|efs|tmpfs|btrfs|ecryptfs)$"); return g_regex_match(local_fs_regex, fs, 0, 0); } @@ -778,9 +765,11 @@ static void slave(char *slave_path) { g_autofree char *hardlink = fn_unescape(word[7]); g_autoptr(FileInfo) fi_src = fileinfo_lstat(hardlink); if (!fi_src) { + // source removed, i/o error, --reduce or logic error. We could + // request the file here, but the above cases don't seem to + // ustify this. warn("%s: hardlink source %s: %m\n", filename, hardlink); - } - if (!fi_is || fi_is->dev != fi_src->dev || fi_is->ino != fi_src->ino) { + } else if (!fi_is || fi_is->dev != fi_src->dev || fi_is->ino != fi_src->ino) { if (fi_is) out_of_the_way(fi_is); if (!quiet) @@ -816,7 +805,7 @@ static void slave(char *slave_path) { close(fd); } if (!slave_unprivileged) { - fileop_chown(fi_want->uid, fi_want->gid, tmpfile); + fileop_lchown(fi_want->uid, fi_want->gid, tmpfile); fileop_chmod(fi_want->perm, tmpfile); } if (fi_is && fi_is->type == 'D') @@ -846,7 +835,8 @@ static void slave(char *slave_path) { if (!quiet) warn("ln -s %s %s\n", fi_want->target, filename); fileop_symlink(fi_want->target, filename); - fileop_lchown(fi_want->uid, fi_want->gid, filename); + if (!slave_unprivileged) + fileop_lchown(fi_want->uid, fi_want->gid, filename); fileop_lmtime(fi_want->mtime, filename); } else { if (!slave_unprivileged && (fi_is->uid != fi_want->uid || fi_is->gid != fi_want->gid)) { @@ -867,7 +857,8 @@ static void slave(char *slave_path) { if (!quiet) warn("mknod %s P\n", filename); fileop_mknod(filename, fi_want->type, 0); - fileop_chown(fi_want->uid, fi_want->gid, filename); + if (!slave_unprivileged) + fileop_lchown(fi_want->uid, fi_want->gid, filename); fileop_chmod(fi_want->perm, filename); } } else if (fi_want->type== 'S') { @@ -879,7 +870,8 @@ static void slave(char *slave_path) { if (!quiet) warn("mknod %s %c\n", filename, fi_want->type); fileop_mknod(filename, fi_want->type, fi_want->rdev); - fileop_chown(fi_want->uid, fi_want->gid, filename); + if (!slave_unprivileged) + fileop_lchown(fi_want->uid, fi_want->gid, filename); fileop_chmod(fi_want->perm, filename); } else { check_perm(fi_is, fi_want); @@ -1101,7 +1093,6 @@ static void master(char *master_path, char *target) { g_ptr_array_add (EXCEPTS, "./.tags"); g_ptr_array_add (EXCEPTS, "./.PMIRROR_ENABLED"); g_ptr_array_add (EXCEPTS, "./.PMIRROR_STATUS"); - g_ptr_array_add (EXCEPTS, "./.PMIRROR_HISTORY"); if (excepts) { for (char **p = excepts; *p; p++) { g_ptr_array_add (EXCEPTS, *p); @@ -1211,7 +1202,9 @@ static void master(char *master_path, char *target) { char *s = g_strdup_printf("%s:%s", unix_socket_name, unix_socket_name); g_ptr_array_add(args, s); } - if (ssh_opt) g_ptr_array_add(args, ssh_opt); + if (ssh_opts) + for (char **p = ssh_opts ; *p ; p++) + g_ptr_array_add(args, *p); g_ptr_array_add(args, slave); g_ptr_array_add(args, "/usr/bin/cmirror"); g_ptr_array_add(args, "--slave"); @@ -1450,7 +1443,6 @@ static void master(char *master_path, char *target) { } } - int main(int argc, char **argv) { char *argv0 = argv[0]; @@ -1464,6 +1456,7 @@ int main(int argc, char **argv) { } g_autoptr(GStrvBuilder) excepts_builder = g_strv_builder_new(); + g_autoptr(GStrvBuilder) ssh_opts_builder = g_strv_builder_new(); while (1) { int opt = getopt_long(argc, argv, "", options, NULL); if (opt == -1) @@ -1475,9 +1468,9 @@ int main(int argc, char **argv) { else if (opt == 101) identity_file = g_strdup(optarg); else if (opt == 102) - g_strv_builder_add(excepts_builder, g_strdup(optarg)); + g_strv_builder_add(excepts_builder, optarg); else if (opt == 103) - ssh_opt = g_strdup(optarg); + g_strv_builder_add(ssh_opts_builder, optarg); else if (opt == 104) unix_socket_name = g_strdup(optarg); else if (opt == '?') @@ -1486,6 +1479,7 @@ int main(int argc, char **argv) { die("internal error: getopt returned %d\n", opt); } excepts = g_strv_builder_end(excepts_builder); + ssh_opts = g_strv_builder_end(ssh_opts_builder); argv = &argv[optind]; argc -= optind; @@ -1496,7 +1490,7 @@ int main(int argc, char **argv) { if (opt_nice) { g_autofree char *cmd = g_strdup_printf("ionice -c idle -p %d", getpid()); - system(cmd); + int __attribute__((unused)) status = system(cmd); } if (slave_mode) {