5 #define _FILE_OFFSET_BITS 64
11 #include <msp/core/systemerror.h>
12 #include <msp/strings/format.h>
13 #include <msp/time/rawtime_private.h>
22 string get_account_name(PSID sid)
25 DWORD nlen = sizeof(name);
27 DWORD dlen = sizeof(domain);
29 if(!LookupAccountSid(0, sid, name, &nlen, domain, &dlen, &use))
30 throw Msp::system_error("LookupAccountSid");
31 return Msp::format("%s/%s", name, domain);
44 static Stat from_struct_stat(const struct stat &);
47 Stat Stat::Private::from_struct_stat(const struct stat &st)
51 if(S_ISREG(st.st_mode))
52 result.type = REGULAR;
53 else if(S_ISDIR(st.st_mode))
54 result.type = DIRECTORY;
55 else if(S_ISLNK(st.st_mode))
56 result.type = SYMLINK;
58 result.type = UNKNOWN;
59 result.size = st.st_size;
60 result.alloc_size = st.st_blocks*512;
61 result.mtime = Time::TimeStamp::from_unixtime(st.st_mtime);
67 if(!getpwuid_r(st.st_uid, &pw, buf, sizeof(buf), &owner) && owner)
68 result.owner = owner->pw_name;
70 result.owner = format("%d", st.st_uid);
74 if(!getgrgid_r(st.st_gid, &gr, buf, sizeof(buf), &group) && group)
75 result.group = group->gr_name;
77 result.group = format("%d", st.st_gid);
90 Stat Stat::stat(const Path &path)
94 handle = CreateFile(path.str().c_str(), 0, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
95 if(handle==INVALID_HANDLE_VALUE)
96 throw system_error("CreateFile");
98 BY_HANDLE_FILE_INFORMATION info;
99 if(!GetFileInformationByHandle(handle, &info))
102 throw system_error("GetFileInformationByHandle");
106 if(info.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
107 result.type = DIRECTORY;
109 result.type = REGULAR;
111 result.size = FileSize(info.nFileSizeHigh)<<32 | info.nFileSizeLow;
112 result.alloc_size = (result.size+511)&~511;
113 result.mtime = Time::TimeStamp(Time::filetime_to_rawtime(info.ftLastWriteTime));
115 PSECURITY_DESCRIPTOR sec_desc;
118 if(!GetSecurityInfo(handle, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION, &owner, &group, 0, 0, &sec_desc))
121 throw system_error("GetSecurityInfo");
125 result.owner = get_account_name(owner);
127 result.group = get_account_name(group);
136 int ret = ::stat(path.str().c_str(), &st);
142 throw system_error("stat");
145 return Private::from_struct_stat(st);
149 Stat Stat::lstat(const Path &path)
155 int ret = ::lstat(path.str().c_str(), &st);
161 throw system_error("lstat");
164 return Private::from_struct_stat(st);
168 bool exists(const Path &path)
171 return GetFileAttributes(path.str().c_str())!=INVALID_FILE_ATTRIBUTES;
173 return access(path.str().c_str(), F_OK)==0;