Phasor 2.2.0
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
19
20bool file_set_properties(char* path, char param, int64_t epoch) {
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) return false;
24
25 FILETIME ft;
26 LONGLONG ll = Int32x32To64(epoch, 10000000) + 116444736000000000; // convert epoch to FILETIME
27 ft.dwLowDateTime = (DWORD)ll;
28 ft.dwHighDateTime = (DWORD)(ll >> 32);
29
30 bool result = false;
31 if (param == 'a') {
32 result = SetFileTime(hFile, NULL, &ft, NULL) != 0;
33 } else if (param == 'c') {
34 result = SetFileTime(hFile, &ft, NULL, NULL) != 0;
35 } else if (param == 'm') {
36 result = SetFileTime(hFile, NULL, NULL, &ft) != 0;
37 }
38
39 CloseHandle(hFile);
40 return result;
41
42#else
43 struct stat st;
44 if (stat(path, &st) != 0) return false;
45
46 struct utimbuf times;
47 times.actime = st.st_atime;
48 times.modtime = st.st_mtime;
49
50 if (param == 'a') {
51 times.actime = epoch;
52 } else if (param == 'm') {
53 times.modtime = epoch;
54 } else {
55 return false; // POSIX doesn't support setting creation time
56 }
57
58 return utime(path, &times) == 0;
59#endif
60}
61
62int64_t file_get_properties(char* path, char param) {
63#ifdef _WIN32
64 WIN32_FILE_ATTRIBUTE_DATA fileInfo;
65 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &fileInfo)) return -1;
66
67 FILETIME ft;
68 if (param == 'a') ft = fileInfo.ftLastAccessTime;
69 else if (param == 'c') ft = fileInfo.ftCreationTime;
70 else if (param == 'm') ft = fileInfo.ftLastWriteTime;
71 else return -1;
72
73 ULARGE_INTEGER ull;
74 ull.LowPart = ft.dwLowDateTime;
75 ull.HighPart = ft.dwHighDateTime;
76 return (int64_t)((ull.QuadPart - 116444736000000000) / 10000000);
77
78#else
79 struct stat st;
80 if (stat(path, &st) != 0) return -1;
81
82 if (param == 'a') return (int64_t)st.st_atime;
83 else if (param == 'm') return (int64_t)st.st_mtime;
84#if defined(__APPLE__) || defined(__FreeBSD__)
85 else if (param == 'c') return (int64_t)st.st_birthtime; // BSD creation time
86#endif
87 else return -1; // creation time not supported on other POSIX systems
88#endif
89}
90
91nlink_t file_get_links_count(const char* path)
92#ifdef _WIN32
93{
94
95 HANDLE hFile = CreateFileA(path, GENERIC_READ,
96 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
97 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
98 if (hFile == INVALID_HANDLE_VALUE) return 0;
99
100 BY_HANDLE_FILE_INFORMATION info;
101 if (!GetFileInformationByHandle(hFile, &info)) {
102 CloseHandle(hFile);
103 return 0;
104 }
105 CloseHandle(hFile);
106 return (nlink_t)info.nNumberOfLinks;
107}
108#else
109{
110 struct stat st;
111 if (stat(path, &st) != 0) return 0;
112 return st.st_nlink;
113}
114#endif
115
116
117bool file_get_owner_id(const char* path, uid_t* uid, gid_t* gid)
118#ifdef _WIN32
119{
120 // Windows does not have UID/GID like POSIX, but we can get the owner SID
121 *uid = 0;
122 *gid = 0;
123
124 PSID pSidOwner = NULL;
125 PSECURITY_DESCRIPTOR pSD = NULL;
126 if (GetNamedSecurityInfoA(path, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION,
127 &pSidOwner, NULL, NULL, NULL, &pSD) != ERROR_SUCCESS) {
128 return false;
129 }
130
131 // Optional: convert SID to some numeric representation
132 *uid = (uid_t)GetSidIdentifierAuthority(pSidOwner)->Value[5]; // crude
133 *gid = 0;
134
135 if (pSD) LocalFree(pSD);
136 return true;
137}
138#else // POSIX
139{
140 struct stat st;
141 if (stat(path, &st) != 0) return false;
142 if (uid) *uid = st.st_uid;
143 if (gid) *gid = st.st_gid;
144 return true;
145}
146#endif
nlink_t file_get_links_count(const char *path)
Retrieves the number of hard links to a file.
int64_t file_get_properties(char *path, char param)
Get file metadata time property.
bool file_get_owner_id(const char *path, uid_t *uid, gid_t *gid)
Retrieves the owner identifier of a file.
bool file_set_properties(char *path, char param, int64_t epoch)
Set file metadata time property.