]> cygwin.com Git - cygwin-apps/setup.git/blob - mkdir.cc
Restructure how we try keys in order for signature checking
[cygwin-apps/setup.git] / mkdir.cc
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
18 #include "win32.h"
19 #include "ntdll.h"
20
21 #include <sys/stat.h>
22
23 #include "mkdir.h"
24 #include "filemanip.h"
25 #include "LogSingleton.h"
26
27 /* Return 0 on success.
28 A mode of 0 means no POSIX perms. */
29 int
30 mkdir_p (int isadir, const char *in_path, mode_t mode)
31 {
32 char saved_char, *slash = 0;
33 char *c;
34 const size_t len = strlen (in_path) + 1;
35 char path[len];
36 DWORD d, gse;
37 WCHAR wpath[len + 6];
38
39 strcpy (path, in_path);
40 mklongpath (wpath, path, len + 6);
41
42 d = GetFileAttributesW (wpath);
43 if (d != INVALID_FILE_ATTRIBUTES && d & FILE_ATTRIBUTE_DIRECTORY)
44 return 0;
45
46 if (isadir)
47 {
48 NTSTATUS status;
49 HANDLE dir;
50 UNICODE_STRING upath;
51 OBJECT_ATTRIBUTES attr;
52 IO_STATUS_BLOCK io;
53 SECURITY_DESCRIPTOR sd;
54 acl_t acl;
55
56 wpath[1] = '?';
57 upath.Length = wcslen (wpath) * sizeof (WCHAR);
58 upath.MaximumLength = upath.Length + sizeof (WCHAR);
59 upath.Buffer = wpath;
60 InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL,
61 mode == 0 ? NULL
62 : nt_sec.GetPosixPerms (path, NULL, NULL,
63 S_IFDIR | mode,
64 sd, acl));
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,
69 FILE_DIRECTORY_FILE
70 | FILE_SYNCHRONOUS_IO_NONALERT
71 | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0);
72 if (NT_SUCCESS (status))
73 {
74 NtClose (dir);
75 return 0;
76 }
77 else
78 SetLastError (RtlNtStatusToDosError (status));
79 gse = GetLastError ();
80 if (gse != ERROR_PATH_NOT_FOUND && gse != ERROR_FILE_NOT_FOUND)
81 {
82 if (gse == ERROR_ALREADY_EXISTS)
83 {
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);
88 }
89 return 1;
90 }
91 }
92
93 for (c = path; *c; c++)
94 {
95 if (*c == '/' || *c == '\\')
96 slash = c;
97 }
98
99 if (!slash)
100 return 0;
101
102 // Trying to create a drive... It's time to give up.
103 if (((slash - path) == 2) && (path[1] == ':'))
104 return 1;
105
106 saved_char = *slash;
107 *slash = 0;
108 if (mkdir_p (1, path, mode ? 0755 : 0))
109 {
110 *slash = saved_char;
111 return 1;
112 }
113
114 *slash = saved_char;
115
116 if (!isadir)
117 return 0;
118
119 return mkdir_p (isadir, path, mode);
120 }
This page took 0.03766 seconds and 5 git commands to generate.