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