2 * Copyright (c) 2000, Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by DJ Delorie <dj@cygnus.com>
24 #include "filemanip.h"
25 #include "LogSingleton.h"
27 /* Return 0 on success.
28 A mode of 0 means no POSIX perms. */
30 mkdir_p (int isadir
, const char *in_path
, mode_t mode
)
32 char saved_char
, *slash
= 0;
34 const size_t len
= strlen (in_path
) + 1;
39 strcpy (path
, in_path
);
40 mklongpath (wpath
, path
, len
+ 6);
42 d
= GetFileAttributesW (wpath
);
43 if (d
!= INVALID_FILE_ATTRIBUTES
&& d
& FILE_ATTRIBUTE_DIRECTORY
)
51 OBJECT_ATTRIBUTES attr
;
53 SECURITY_DESCRIPTOR sd
;
57 upath
.Length
= wcslen (wpath
) * sizeof (WCHAR
);
58 upath
.MaximumLength
= upath
.Length
+ sizeof (WCHAR
);
60 InitializeObjectAttributes (&attr
, &upath
, OBJ_CASE_INSENSITIVE
, NULL
,
62 : nt_sec
.GetPosixPerms (path
, NULL
, NULL
,
65 status
= NtCreateFile (&dir
, SYNCHRONIZE
| READ_CONTROL
66 | FILE_LIST_DIRECTORY
,
67 &attr
, &io
, NULL
, FILE_ATTRIBUTE_DIRECTORY
,
68 FILE_SHARE_VALID_FLAGS
, FILE_CREATE
,
70 | FILE_SYNCHRONOUS_IO_NONALERT
71 | FILE_OPEN_FOR_BACKUP_INTENT
, NULL
, 0);
72 if (NT_SUCCESS (status
))
78 SetLastError (RtlNtStatusToDosError (status
));
79 gse
= GetLastError ();
80 if (gse
!= ERROR_PATH_NOT_FOUND
&& gse
!= ERROR_FILE_NOT_FOUND
)
82 if (gse
== ERROR_ALREADY_EXISTS
)
84 Log (LOG_TIMESTAMP
) << "warning: deleting \"" << path
85 << "\" so I can make a directory there" << endLog
;
86 if (DeleteFileW (wpath
))
87 return mkdir_p (isadir
, path
, mode
? 0755 : 0);
93 for (c
= path
; *c
; c
++)
95 if (*c
== '/' || *c
== '\\')
102 // Trying to create a drive... It's time to give up.
103 if (((slash
- path
) == 2) && (path
[1] == ':'))
108 if (mkdir_p (1, path
, mode
? 0755 : 0))
119 return mkdir_p (isadir
, path
, mode
);