]> cygwin.com Git - cygwin-apps/setup.git/blame - mkdir.cc
* prereq.cc (PrereqChecker::getUnmetString): Improve dependency list
[cygwin-apps/setup.git] / mkdir.cc
CommitLineData
23c9e63c
DD
1/*
2 * Copyright (c) 2000, Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by DJ Delorie <dj@cygnus.com>
13 *
14 */
15
16/* see mkdir.h */
17
b24c88b3
RC
18#if 0
19static const char *cvsid =
20 "\n%%% $Id$\n";
21#endif
8507f105 22
aa1e3b4d 23#if defined(WIN32) && !defined (_CYGWIN_)
23c9e63c 24#include "win32.h"
6dcfeb7d 25#include "ntdll.h"
ac949c48
MB
26#else
27#include <unistd.h>
28#include <string.h>
29#include <errno.h>
aa1e3b4d 30#endif
89cc2408
CV
31
32#include <sys/stat.h>
23c9e63c
DD
33#include <stdio.h>
34
35#include "mkdir.h"
2f0315ad 36#include "filemanip.h"
23c9e63c 37
d2a5fdfb 38/* A mode of 0 means no POSIX perms. */
23c9e63c 39int
b41c2908 40mkdir_p (int isadir, const char *in_path, mode_t mode)
23c9e63c
DD
41{
42 char saved_char, *slash = 0;
43 char *c;
2f0315ad
CV
44 const size_t len = strlen (in_path) + 1;
45 char path[len];
aa1e3b4d
RC
46#if defined(WIN32) && !defined (_CYGWIN_)
47 DWORD d, gse;
2f0315ad
CV
48 WCHAR wpath[len + 6];
49
85b43844 50 strcpy (path, in_path);
2f0315ad
CV
51 if (IsWindowsNT ())
52 mklongpath (wpath, path, len + 6);
23c9e63c 53
2f0315ad
CV
54 d = IsWindowsNT () ? GetFileAttributesW (wpath) : GetFileAttributesA (path);
55 if (d != INVALID_FILE_ATTRIBUTES && d & FILE_ATTRIBUTE_DIRECTORY)
23c9e63c
DD
56 return 0;
57
58 if (isadir)
59 {
b41c2908
CV
60 if (IsWindowsNT ())
61 {
62 NTSTATUS status;
63 HANDLE dir;
64 UNICODE_STRING upath;
65 OBJECT_ATTRIBUTES attr;
66 IO_STATUS_BLOCK io;
26922cd2
CV
67 SECURITY_DESCRIPTOR sd;
68 acl_t acl;
b41c2908 69
b41c2908
CV
70 wpath[1] = '?';
71 upath.Length = wcslen (wpath) * sizeof (WCHAR);
72 upath.MaximumLength = upath.Length + sizeof (WCHAR);
73 upath.Buffer = wpath;
26922cd2 74 InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL,
d2a5fdfb
CV
75 mode == 0 ? NULL
76 : nt_sec.GetPosixPerms (path, NULL, NULL,
77 S_IFDIR | mode,
78 sd, acl));
26922cd2 79 status = NtCreateFile (&dir, SYNCHRONIZE | READ_CONTROL
21aa9a8b 80 | FILE_LIST_DIRECTORY,
6dcfeb7d
CV
81 &attr, &io, NULL, FILE_ATTRIBUTE_DIRECTORY,
82 FILE_SHARE_VALID_FLAGS, FILE_CREATE,
83 FILE_DIRECTORY_FILE
84 | FILE_SYNCHRONOUS_IO_NONALERT
85 | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0);
b41c2908
CV
86 if (NT_SUCCESS (status))
87 {
6dcfeb7d 88 NtClose (dir);
b41c2908
CV
89 return 0;
90 }
91 else
6dcfeb7d 92 SetLastError (RtlNtStatusToDosError (status));
b41c2908
CV
93 }
94 else if (CreateDirectoryA (path, 0))
23c9e63c
DD
95 return 0;
96 gse = GetLastError ();
89725f30 97 if (gse != ERROR_PATH_NOT_FOUND && gse != ERROR_FILE_NOT_FOUND)
23c9e63c
DD
98 {
99 if (gse == ERROR_ALREADY_EXISTS)
100 {
b24c88b3
RC
101 fprintf (stderr,
102 "warning: deleting \"%s\" so I can make a directory there\n",
1fd6d0a2 103 path);
2f0315ad 104 if (IsWindowsNT () ? DeleteFileW (wpath) : DeleteFileA (path))
d2a5fdfb 105 return mkdir_p (isadir, path, mode ? 0755 : 0);
23c9e63c
DD
106 }
107 return 1;
108 }
109 }
aa1e3b4d 110#else
ac949c48 111 struct stat st;
aa1e3b4d 112 strcpy (path, in_path);
23c9e63c 113
ac949c48
MB
114 if (stat(path,&st) == 0 && S_ISDIR(st.st_mode))
115 return 0;
116
117 if (isadir)
118 {
119 if (mkdir (path, 0777))
120 return 0;
121 if (errno != ENOENT)
122 {
123 if (errno == EEXIST)
124 {
125 fprintf (stderr,
126 "warning: deleting \"%s\" so I can make a directory there\n",
127 path);
128 if (unlink (path))
129 return mkdir_p (isadir, path);
130 }
131 return 1;
132 }
133 }
aa1e3b4d
RC
134#endif
135
85b43844 136 for (c = path; *c; c++)
23c9e63c
DD
137 {
138 if (*c == ':')
139 slash = 0;
140 if (*c == '/' || *c == '\\')
141 slash = c;
142 }
143
144 if (!slash)
145 return 0;
146
f2e49cf8
RC
147 // Trying to create a drive... It's time to give up.
148 if (((slash - path) == 2) && (path[1] == ':'))
149 return 1;
150
23c9e63c
DD
151 saved_char = *slash;
152 *slash = 0;
d2a5fdfb 153 if (mkdir_p (1, path, mode ? 0755 : 0))
23c9e63c
DD
154 {
155 *slash = saved_char;
156 return 1;
157 }
f2e49cf8 158
23c9e63c
DD
159 *slash = saved_char;
160
161 if (!isadir)
162 return 0;
163
b41c2908 164 return mkdir_p (isadir, path, mode);
23c9e63c 165}
This page took 0.078977 seconds and 5 git commands to generate.