EC_INIT;
int status;
struct stat st;
- bstring oldpath, newpath, cmd = NULL;
+ bstring oldpath, newpath;
+ char *cmd_argv[4];
+
+ LOG(log_note, logtype_cnid, "set_dbdir: volume: %s, db path: %s", vpath, dbdir);
EC_NULL_LOG( oldpath = bformat("%s/%s/", vpath, DBHOME) );
EC_NULL_LOG( newpath = bformat("%s/%s/", dbdir, DBHOME) );
if (lstat(dbdir, &st) < 0 && mkdir(dbdir, 0755) < 0) {
LOG(log_error, logtype_cnid, "set_dbdir: mkdir failed for %s", dbdir);
- return -1;
+ EC_FAIL;
}
if (lstat(bdata(oldpath), &st) == 0 && lstat(bdata(newpath), &st) != 0 && errno == ENOENT) {
/* There's an .AppleDB in the volume root, we move it */
- EC_NULL_LOG( cmd = bformat("mv '%s' '%s'", bdata(oldpath), dbdir) );
- LOG(log_debug, logtype_cnid, "set_dbdir: cmd: %s", bdata(cmd));
- if (WEXITSTATUS(system(bdata(cmd))) != 0) {
+ cmd_argv[0] = "mv";
+ cmd_argv[1] = bdata(oldpath);
+ cmd_argv[2] = (char *)dbdir;
+ cmd_argv[3] = NULL;
+ if (run_cmd("mv", cmd_argv) != 0) {
LOG(log_error, logtype_cnid, "set_dbdir: moving CNID db from \"%s\" to \"%s\" failed",
bdata(oldpath), dbdir);
EC_FAIL;
}
+
}
if (lstat(bdata(newpath), &st) < 0 && mkdir(bdata(newpath), 0755 ) < 0) {
LOG(log_error, logtype_cnid, "set_dbdir: mkdir failed for %s", bdata(newpath));
- return -1;
+ EC_FAIL;
}
EC_CLEANUP:
bdestroy(oldpath);
bdestroy(newpath);
- bdestroy(cmd);
EC_EXIT;
}
extern int lchdir(const char *dir);
extern void randombytes(void *buf, int n);
extern int daemonize(int nochdir, int noclose);
+extern int run_cmd(const char *cmd, char **cmd_argv);
/******************************************************************
* cnid.c
#include <dirent.h>
#include <sys/time.h>
#include <time.h>
+#include <sys/wait.h>
#include <atalk/adouble.h>
#include <atalk/ea.h>
#include <atalk/util.h>
#include <atalk/unix.h>
#include <atalk/compat.h>
+#include <atalk/errchk.h>
/* close all FDs >= a specified value */
static void closeall(int fd)
close(fd++);
}
+/*!
+ * Run command in a child and wait for it to finish
+ */
+int run_cmd(const char *cmd, char **cmd_argv)
+{
+ EC_INIT;
+ pid_t pid, wpid;
+ sigset_t sigs, oldsigs;
+ int status = 0;
+
+ sigfillset(&sigs);
+ pthread_sigmask(SIG_SETMASK, &sigs, &oldsigs);
+
+ if ((pid = fork()) < 0) {
+ LOG(log_error, logtype_default, "run_cmd: fork: %s", strerror(errno));
+ return -1;
+ }
+
+ if (pid == 0) {
+ /* child */
+ closeall(3);
+ execvp("mv", cmd_argv);
+ }
+
+ /* parent */
+ while ((wpid = waitpid(pid, &status, 0)) < 0) {
+ if (errno == EINTR)
+ continue;
+ break;
+ }
+ if (wpid != pid) {
+ LOG(log_error, logtype_default, "waitpid(%d): %s", (int)pid, strerror(errno));
+ EC_FAIL;
+ }
+
+ if (WIFEXITED(status))
+ status = WEXITSTATUS(status);
+ else if (WIFSIGNALED(status))
+ status = WTERMSIG(status);
+
+ LOG(log_note, logtype_default, "run_cmd(\"%s\"): status: %d", cmd, status);
+
+EC_CLEANUP:
+ if (status != 0)
+ ret = status;
+ pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
+ EC_EXIT;
+}
+
/*!
* Daemonize
*