1 #include <grass/config.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <unistd.h>
5
6 #ifndef __MINGW32__
7 #include <pwd.h>
8 #else
9 #include <windows.h>
10 #include "aclapi.h"
11 #endif
12
13 #include <grass/gis.h>
14 #include <grass/glocale.h>
15
16 /**
17 * \brief Creates a new directory
18 *
19 * Creates a new directory with permissions 0777 (on Unix) or
20 * default permissions(?) on Windows.
21 *
22 * \param path String containing path of directory to be created
23 *
24 * \return Return value from system mkdir() function
25 **/
26
G_mkdir(const char * path)27 int G_mkdir(const char *path)
28 {
29 #ifdef __MINGW32__
30 return mkdir(path);
31 #else
32 return mkdir(path, 0777);
33 #endif
34 }
35
36 /**
37 * \brief Checks if a specified character is a valid directory
38 * separator character on the host system
39 *
40 * \param c Character to check
41 *
42 * \return 1 if c is a directory separator character, 0 if not
43 **/
44
G_is_dirsep(char c)45 int G_is_dirsep(char c)
46 {
47 if (c == GRASS_DIRSEP || c == HOST_DIRSEP)
48 return 1;
49 else
50 return 0;
51 }
52
53 /**
54 * \brief Checks if a specified path looks like an absolute
55 * path on the host system
56 *
57 * \param path String containing path to check
58 *
59 * \return 1 if path looks like an absolute path, 0 if not
60 **/
61
G_is_absolute_path(const char * path)62 int G_is_absolute_path(const char *path)
63 {
64 if (G_is_dirsep(path[0])
65 #ifdef __MINGW32__
66 || (isalpha(path[0]) && (path[1] == ':') && G_is_dirsep(path[2]))
67 #endif
68 )
69 return 1;
70 else
71 return 0;
72 }
73
74 /**
75 * \brief Converts directory separator characters in a string to the
76 * native host separator character (/ on Unix, \ on Windows)
77 *
78 * \param path String to be converted
79 *
80 * \return Pointer to the string
81 **/
82
G_convert_dirseps_to_host(char * path)83 char *G_convert_dirseps_to_host(char *path)
84 {
85 char *i;
86
87 for (i = path; *i; i++) {
88 if (*i == GRASS_DIRSEP)
89 *i = HOST_DIRSEP;
90 }
91
92 return path;
93 }
94
95 /**
96 * \brief Converts directory separator characters in a string from the
97 * native host character to the GRASS separator character (/)
98 *
99 *
100 * \param path String to be converted
101 *
102 * \return Pointer to the string
103 **/
104
G_convert_dirseps_from_host(char * path)105 char *G_convert_dirseps_from_host(char *path)
106 {
107 char *i;
108
109 for (i = path; *i; i++) {
110 if (*i == HOST_DIRSEP)
111 *i = GRASS_DIRSEP;
112 }
113
114 return path;
115 }
116
117 /**
118 * \brief Get file status
119 *
120 * Returns information about the specified file.
121 *
122 * \param file_name file name
123 * \param stat pointer to structure filled with file information
124 *
125 * \return Return value from system lstat function
126 **/
127
G_stat(const char * file_name,struct stat * buf)128 int G_stat(const char *file_name, struct stat *buf)
129 {
130 return stat(file_name, buf);
131 }
132
133 /**
134 * \brief Get file status
135 *
136 * Returns information about the specified file.
137 *
138 * \param file_name file name, in the case of a symbolic link, the
139 * link itself is stat-ed, not the file that it refers to
140 * \param stat pointer to structure filled with file information
141 *
142 * \return Return value from system lstat function
143 **/
144
G_lstat(const char * file_name,struct stat * buf)145 int G_lstat(const char *file_name, struct stat *buf)
146 {
147 #ifdef __MINGW32__
148 return stat(file_name, buf);
149 #else
150 return lstat(file_name, buf);
151 #endif
152 }
153
154 /**
155 * \brief Get owner id of path
156 *
157 * Returns information about the specified file.
158 *
159 * \param path path to check
160 *
161 * \return Return owner id
162 **/
163
G_owner(const char * path)164 int G_owner(const char *path)
165 {
166
167 #ifndef __MINGW32__
168 struct stat info;
169
170 G_stat(path, &info);
171
172 return (int)info.st_uid;
173 #else
174
175 /* this code is taken from the official example to
176 * find the owner of a file object from
177 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa446629%28v=vs.85%29.aspx */
178
179 DWORD dwRtnCode = 0;
180 PSID pSidOwner = NULL;
181 BOOL bRtnBool = TRUE;
182 LPTSTR AcctName = NULL;
183 LPTSTR DomainName = NULL;
184 DWORD dwAcctName = 1, dwDomainName = 1;
185 SID_NAME_USE eUse = SidTypeUnknown;
186 HANDLE hFile;
187 PSECURITY_DESCRIPTOR pSD = NULL;
188
189 /* Get the handle of the file object. */
190 hFile = CreateFile(
191 TEXT(path), /* lpFileName */
192 GENERIC_READ, /* dwDesiredAccess */
193 FILE_SHARE_READ, /* dwShareMode */
194 NULL, /* lpSecurityAttributes */
195 OPEN_EXISTING, /* dwCreationDisposition */
196 FILE_ATTRIBUTE_NORMAL, /* dwFlagsAndAttributes */
197 NULL /* hTemplateFile */
198 );
199
200 if (hFile == INVALID_HANDLE_VALUE) {
201 G_fatal_error(_("Unable to open file <%s> for reading"), path);
202 }
203
204 /* Get the owner SID of the file. */
205 dwRtnCode = GetSecurityInfo(
206 hFile, /* handle */
207 SE_FILE_OBJECT, /* ObjectType */
208 OWNER_SECURITY_INFORMATION, /* SecurityInfo */
209 &pSidOwner, /* ppsidOwner */
210 NULL, /* ppsidGroup */
211 NULL, /* ppDacl */
212 NULL, /* ppSacl */
213 &pSD /* ppSecurityDescriptor */
214 );
215
216 if (dwRtnCode != ERROR_SUCCESS) {
217 G_fatal_error(_("Unable to fetch security info for <%s>"), path);
218 }
219 CloseHandle(hFile);
220
221 return (int)pSidOwner;
222 #endif
223 }
224