]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/util/unix.c
Merge master
[netatalk.git] / libatalk / util / unix.c
index 1c131ad507c9712a4de3a18f8648795b89c950ef..d202b99a31f9d1dc165c7836b8b43d3d0fcd6f4c 100644 (file)
@@ -30,6 +30,8 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <dirent.h>
+#include <sys/time.h>
+#include <time.h>
 
 #include <atalk/adouble.h>
 #include <atalk/ea.h>
 #include <atalk/vfs.h>
 #include <atalk/util.h>
 #include <atalk/unix.h>
+#include <atalk/compat.h>
+
+/* close all FDs >= a specified value */
+static void closeall(int fd)
+{
+    int fdlimit = sysconf(_SC_OPEN_MAX);
+
+    while (fd < fdlimit)
+        close(fd++);
+}
+
+/*!
+ * Daemonize
+ *
+ * Fork, exit parent, setsid(), optionally chdir("/"), optionally close all fds
+ *
+ * returns -1 on failure, but you can't do much except exit in that case
+ * since we may already have forked
+ */
+int daemonize(int nochdir, int noclose)
+{
+    switch (fork()) {
+    case 0:
+        break;
+    case -1:
+        return -1;
+    default:
+        _exit(0);
+    }
+
+    if (setsid() < 0)
+        return -1;
+
+    switch (fork()) {
+    case 0: 
+        break;
+    case -1:
+        return -1;
+    default:
+        _exit(0);
+    }
+
+    if (!nochdir)
+        chdir("/");
+
+    if (!noclose) {
+        closeall(0);
+        open("/dev/null",O_RDWR);
+        dup(0);
+        dup(0);
+    }
+
+    return 0;
+}
 
 /*!
  * @brief get cwd in static buffer
@@ -55,6 +111,31 @@ const char *getcwdpath(void)
         return strerror(errno);
 }
 
+/*!
+ * Make argument path absoulte
+ *
+ * @returns pointer to path or pointer to error messages on error
+ */
+const char *abspath(const char *name)
+{
+    static char buf[MAXPATHLEN + 1];
+    char *p;
+    int n;
+
+    if (name[0] == '/')
+        return name;
+
+    if ((p = getcwd(buf, MAXPATHLEN)) == NULL)
+        return strerror(errno);
+
+    n = strlen(buf);
+    if (buf[n-1] != '/')
+        buf[n++] = '/';
+        
+    strlcpy(buf + n, name, MAXPATHLEN - n);
+    return buf;
+}
+
 /*!
  * Takes a buffer with a path, strips slashs, returns basename
  *
@@ -148,3 +229,33 @@ int lchdir(const char *dir)
 
     return 0;
 }
+
+/*!
+ * Store n random bytes an buf
+ */
+void randombytes(void *buf, int n)
+{
+    char *p = (char *)buf;
+    int fd, i;
+    struct timeval tv;
+
+    if ((fd = open("/dev/urandom", O_RDONLY)) != -1) {
+        /* generate from /dev/urandom */
+        if (read(fd, buf, n) != n) {
+            close(fd);
+            fd = -1;
+        } else {
+            close(fd);
+            /* fd now != -1, so srandom wont be called below */
+        }
+    }
+
+    if (fd == -1) {
+        gettimeofday(&tv, NULL);
+        srandom((unsigned int)tv.tv_usec);
+        for (i=0 ; i < n ; i++)
+            p[i] = random() & 0xFF;
+    }
+
+    return;
+}