]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/util/unix.c
Merge 2-2
[netatalk.git] / libatalk / util / unix.c
index 0ac210ec2c8d4e3e1d99ab16a33f7067cfabd24f..56c3e168eaea05c05705464a0f21830aedf60c03 100644 (file)
@@ -32,6 +32,7 @@
 #include <dirent.h>
 #include <sys/time.h>
 #include <time.h>
+#include <sys/wait.h>
 
 #include <atalk/adouble.h>
 #include <atalk/ea.h>
@@ -41,6 +42,7 @@
 #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)
@@ -51,6 +53,55 @@ 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
  *
@@ -95,6 +146,29 @@ int daemonize(int nochdir, int noclose)
     return 0;
 }
 
+static uid_t saved_uid = -1;
+
+/*
+ * seteuid(0) and back, if either fails and panic != 0 we PANIC
+ */
+void become_root(void)
+{
+    if (getuid() == 0) {
+        saved_uid = geteuid();
+        if (seteuid(0) != 0)
+            AFP_PANIC("Can't seteuid(0)");
+    }
+}
+
+void unbecome_root(void)
+{
+    if (getuid() == 0) {
+        if (saved_uid == -1 || seteuid(saved_uid) < 0)
+            AFP_PANIC("Can't seteuid back");
+        saved_uid = -1;
+    }
+}
+
 /*!
  * @brief get cwd in static buffer
  *
@@ -256,3 +330,15 @@ void randombytes(void *buf, int n)
 
     return;
 }
+
+int gmem(gid_t gid, int ngroups, gid_t *groups)
+{
+    int                i;
+
+    for ( i = 0; i < ngroups; i++ ) {
+        if ( groups[ i ] == gid ) {
+            return( 1 );
+        }
+    }
+    return( 0 );
+}