aboutsummaryrefslogtreecommitdiff
path: root/gnu/libexec/uucp/libunix/mkdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/libexec/uucp/libunix/mkdir.c')
-rw-r--r--gnu/libexec/uucp/libunix/mkdir.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/gnu/libexec/uucp/libunix/mkdir.c b/gnu/libexec/uucp/libunix/mkdir.c
new file mode 100644
index 000000000000..f59ad5dfd6e6
--- /dev/null
+++ b/gnu/libexec/uucp/libunix/mkdir.c
@@ -0,0 +1,58 @@
+/* mkdir.c
+ Create a directory. We must go through a subsidiary program to
+ force our real uid to be the uucp owner before invoking the setuid
+ /bin/mkdir program. */
+
+#include "uucp.h"
+
+#include "sysdep.h"
+
+#include <errno.h>
+
+int
+mkdir (zdir, imode)
+ const char *zdir;
+ int imode;
+{
+ struct stat s;
+ const char *azargs[3];
+ int aidescs[3];
+ pid_t ipid;
+
+ /* Make sure the directory does not exist, since we will otherwise
+ get the wrong errno value. */
+ if (stat (zdir, &s) == 0)
+ {
+ errno = EEXIST;
+ return -1;
+ }
+
+ /* /bin/mkdir will create the directory with mode 777, so we set our
+ umask to get the mode we want. */
+ (void) umask ((~ imode) & (S_IRWXU | S_IRWXG | S_IRWXO));
+
+ azargs[0] = UUDIR_PROGRAM;
+ azargs[1] = zdir;
+ azargs[2] = NULL;
+ aidescs[0] = SPAWN_NULL;
+ aidescs[1] = SPAWN_NULL;
+ aidescs[2] = SPAWN_NULL;
+
+ ipid = ixsspawn (azargs, aidescs, FALSE, FALSE, (const char *) NULL,
+ TRUE, FALSE, (const char *) NULL,
+ (const char *) NULL, (const char *) NULL);
+
+ (void) umask (0);
+
+ if (ipid < 0)
+ return -1;
+
+ if (ixswait ((unsigned long) ipid, (const char *) NULL) != 0)
+ {
+ /* Make up an errno value. */
+ errno = EACCES;
+ return -1;
+ }
+
+ return 0;
+}