Phasor 3.1.1
Stack VM based Programming Language
Loading...
Searching...
No Matches
file_properties.c
Go to the documentation of this file.
1#include <stdint.h>
2#include <stdbool.h>
3#include "file_properties.h"
4
5#ifdef _WIN32
6#include <windows.h>
7#include <fileapi.h>
8#include <handleapi.h>
9#include <winnt.h>
10#include <Aclapi.h>
11#else
12#include <sys/stat.h>
13#include <unistd.h>
14#include <utime.h>
15#include <errno.h>
16#include <string.h>
17#endif
18
19bool PHASORstd_file_setProperties(char *path, char param, int64_t epoch)
20{
21#ifdef _WIN32
22 HANDLE hFile = CreateFileA(path, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
23 if (hFile == INVALID_HANDLE_VALUE)
24 return false;
25
26 FILETIME ft;
27 LONGLONG ll = Int32x32To64(epoch, 10000000) + 116444736000000000; // convert epoch to FILETIME
28 ft.dwLowDateTime = (DWORD)ll;
29 ft.dwHighDateTime = (DWORD)(ll >> 32);
30
31 bool result = false;
32 if (param == 'a')
33 {
34 result = SetFileTime(hFile, NULL, &ft, NULL) != 0;
35 }
36 else if (param == 'c')
37 {
38 result = SetFileTime(hFile, &ft, NULL, NULL) != 0;
39 }
40 else if (param == 'm')
41 {
42 result = SetFileTime(hFile, NULL, NULL, &ft) != 0;
43 }
44
45 CloseHandle(hFile);
46 return result;
47
48#else
49 struct stat st;
50 if (stat(path, &st) != 0)
51 return false;
52
53 struct utimbuf times;
54 times.actime = st.st_atime;
55 times.modtime = st.st_mtime;
56
57 if (param == 'a')
58 {
59 times.actime = epoch;
60 }
61 else if (param == 'm')
62 {
63 times.modtime = epoch;
64 }
65 else
66 {
67 return false; // POSIX doesn't support setting creation time
68 }
69
70 return utime(path, &times) == 0;
71#endif
72}
73
74int64_t PHASORstd_file_getProperties(char *path, char param)
75{
76#ifdef _WIN32
77 WIN32_FILE_ATTRIBUTE_DATA fileInfo;
78 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &fileInfo))
79 return -1;
80
81 FILETIME ft;
82 if (param == 'a')
83 ft = fileInfo.ftLastAccessTime;
84 else if (param == 'c')
85 ft = fileInfo.ftCreationTime;
86 else if (param == 'm')
87 ft = fileInfo.ftLastWriteTime;
88 else
89 return -1;
90
91 ULARGE_INTEGER ull;
92 ull.LowPart = ft.dwLowDateTime;
93 ull.HighPart = ft.dwHighDateTime;
94 return (int64_t)((ull.QuadPart - 116444736000000000) / 10000000);
95
96#else
97 struct stat st;
98 if (stat(path, &st) != 0)
99 return -1;
100
101 if (param == 'a')
102 return (int64_t)st.st_atime;
103 else if (param == 'm')
104 return (int64_t)st.st_mtime;
105#if defined(__APPLE__) || defined(__FreeBSD__)
106 else if (param == 'c')
107 return (int64_t)st.st_birthtime; // BSD creation time
108#endif
109 else
110 return -1; // creation time not supported on other POSIX systems
111#endif
112}
113
114nlink_t PHASORstd_file_getLinksCount(const char *path)
115#ifdef _WIN32
116{
117
118 HANDLE hFile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
119 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
120 if (hFile == INVALID_HANDLE_VALUE)
121 return 0;
122
123 BY_HANDLE_FILE_INFORMATION info;
124 if (!GetFileInformationByHandle(hFile, &info))
125 {
126 CloseHandle(hFile);
127 return 0;
128 }
129 CloseHandle(hFile);
130 return (nlink_t)info.nNumberOfLinks;
131}
132#else
133{
134 struct stat st;
135 if (stat(path, &st) != 0)
136 return 0;
137 return st.st_nlink;
138}
139#endif
140
141bool PHASORstd_file_getOwnerId(const char *path, uid_t *uid, gid_t *gid)
142#ifdef _WIN32
143{
144 // Windows does not have UID/GID like POSIX, but we can get the owner SID
145 *uid = 0;
146 *gid = 0;
147
148 PSID pSidOwner = NULL;
149 PSECURITY_DESCRIPTOR pSD = NULL;
150 if (GetNamedSecurityInfoA(path, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD) !=
151 ERROR_SUCCESS)
152 {
153 return false;
154 }
155
156 *uid = (uid_t)GetSidIdentifierAuthority(pSidOwner)->Value[5]; // crude
157 *gid = 0;
158
159 if (pSD)
160 LocalFree(pSD);
161 return true;
162}
163#else // POSIX
164{
165 struct stat st;
166 if (stat(path, &st) != 0)
167 return false;
168 if (uid)
169 *uid = st.st_uid;
170 if (gid)
171 *gid = st.st_gid;
172 return true;
173}
174#endif
nlink_t PHASORstd_file_getLinksCount(const char *path)
Retrieves the number of hard links to a file.
int64_t PHASORstd_file_getProperties(char *path, char param)
Get file metadata time property.
bool PHASORstd_file_getOwnerId(const char *path, uid_t *uid, gid_t *gid)
Retrieves the owner identifier of a file.
bool PHASORstd_file_setProperties(char *path, char param, int64_t epoch)
Set file metadata time property.