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