1 //
2 // aegis - project change supervisor
3 // Copyright (C) 1991-2006, 2008, 2012 Peter Miller
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or (at
8 // your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, see <http://www.gnu.org/licenses/>.
17 //
18
19 #include <common/ac/errno.h>
20 #include <common/ac/stddef.h>
21 #include <common/ac/sys/types.h>
22 #include <common/ac/sys/stat.h>
23 #include <common/ac/unistd.h>
24
25 #include <libaegis/glue.h>
26 #include <libaegis/os.h>
27 #include <libaegis/sub.h>
28 #include <common/trace.h>
29
30
31 void
os_mkdir(const nstring & path,int mode,bool eexist_ok)32 os_mkdir(const nstring &path, int mode, bool eexist_ok)
33 {
34 trace(("os_mkdir(path = \"%s\", mode = 0%o)\n{\n", path.c_str(), mode));
35 os_become_must_be_active();
36 if (glue_mkdir(path.c_str(), mode))
37 {
38 int errno_old = errno;
39 if (errno_old == EEXIST && eexist_ok)
40 return;
41 sub_context_ty *scp = sub_context_new();
42 sub_errno_setx(scp, errno_old);
43 sub_var_set_string(scp, "File_Name", path);
44 sub_var_set_format(scp, "Argument", "%5.5o", mode);
45 fatal_intl(scp, i18n("mkdir(\"$filename\", $arg): $errno"));
46 // NOTREACHED
47 }
48
49 //
50 // There could be Berkeley semantics about the group
51 // of the newly created directory, so make sure it is
52 // the one intended (egid).
53 //
54 int uid;
55 int gid;
56 int um;
57 os_become_query(&uid, &gid, &um);
58 if (glue_chown(path.c_str(), uid, gid))
59 {
60 int errno_old = errno;
61 sub_context_ty *scp = sub_context_new();
62 sub_errno_setx(scp, errno_old);
63 sub_var_set_string(scp, "File_Name", path);
64 sub_var_set_long(scp, "Argument", gid);
65 fatal_intl(scp, i18n("chgrp(\"$filename\", $arg): $errno"));
66 // NOTREACHED
67 }
68
69 //
70 // The set-group-id bit is ignored by a Berkeley semantics mkdir
71 // (and it would be nuked the the chgrp, anyway)
72 // so set it explicitly.
73 //
74 mode &= ~um;
75 if (glue_chmod(path.c_str(), mode))
76 {
77 int errno_old = errno;
78 sub_context_ty *scp = sub_context_new();
79 sub_errno_setx(scp, errno_old);
80 sub_var_set_string(scp, "File_Name", path);
81 sub_var_set_format(scp, "Argument", "%5.5o", mode);
82 fatal_intl(scp, i18n("chmod(\"$filename\", $arg): $errno"));
83 // NOTREACHED
84 }
85 trace(("}\n"));
86 }
87
88
89 void
os_mkdir(string_ty * path,int mode,bool eexist_ok)90 os_mkdir(string_ty *path, int mode, bool eexist_ok)
91 {
92 os_mkdir(nstring(path), mode, eexist_ok);
93 }
94
95
96 // vim: set ts=8 sw=4 et :
97