paths.c 6.1 KB

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