]> git.lyx.org Git - lyx.git/blob - src/support/FileInfo.C
Clean up licence info and add Lars as the mysterious unknown author.
[lyx.git] / src / support / FileInfo.C
1 /**
2  * \file FileInfo.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  *
8  * Full author contact details are available in file CREDITS
9  */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 //#include <sys/types.h>
18 //#include <sys/stat.h>
19
20 #include <cerrno>
21 #include "FileInfo.h"
22 #include "LAssert.h"
23
24 #if !S_IRUSR
25 # if S_IREAD
26 #  define S_IRUSR S_IREAD
27 # else
28 #  define S_IRUSR 00400
29 # endif
30 #endif
31
32 #if !S_IWUSR
33 # if S_IWRITE
34 #  define S_IWUSR S_IWRITE
35 # else
36 #  define S_IWUSR 00200
37 # endif
38 #endif
39
40 #if !S_IXUSR
41 # if S_IEXEC
42 #  define S_IXUSR S_IEXEC
43 # else
44 #  define S_IXUSR 00100
45 # endif
46 #endif
47
48 #ifdef STAT_MACROS_BROKEN
49 #undef S_ISBLK
50 #undef S_ISCHR
51 #undef S_ISDIR
52 #undef S_ISFIFO
53 #undef S_ISLNK
54 #undef S_ISMPB
55 #undef S_ISMPC
56 #undef S_ISNWK
57 #undef S_ISREG
58 #undef S_ISSOCK
59 #endif
60
61 #if !defined(S_ISBLK) && defined(S_IFBLK)
62 #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
63 #endif
64 #if !defined(S_ISCHR) && defined(S_IFCHR)
65 #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
66 #endif
67 #if !defined(S_ISDIR) && defined(S_IFDIR)
68 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
69 #endif
70 #if !defined(S_ISREG) && defined(S_IFREG)
71 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
72 #endif
73 #if !defined(S_ISFIFO) && defined(S_IFIFO)
74 #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
75 #endif
76 #if !defined(S_ISLNK) && defined(S_IFLNK)
77 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
78 #endif
79 #if !defined(S_ISSOCK) && defined(S_IFSOCK)
80 #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
81 #endif
82 #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
83 #define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
84 #define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
85 #endif
86 #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
87 #define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
88 #endif
89
90
91 namespace {
92
93 // builds 'rwx' string describing file access rights
94 void flagRWX(mode_t i, char * str)
95 {
96         str[0] = (i & S_IRUSR) ? 'r' : '-';
97         str[1] = (i & S_IWUSR) ? 'w' : '-';
98         str[2] = (i & S_IXUSR) ? 'x' : '-';
99 }
100
101 // updates mode string to match suid/sgid/sticky bits
102 void setSticky(mode_t i, char * str)
103 {
104 #ifdef S_ISUID
105         if (i & S_ISUID)
106                 str[3] = (str[3] == 'x') ? 's' : 'S';
107 #endif
108 #ifdef S_ISGID
109         if (i & S_ISGID)
110                 str[6] = (str[6] == 'x') ? 's' : 'S';
111 #endif
112 #ifdef S_ISVTX
113         if (i & S_ISVTX)
114                 str[9] = (str[9] == 'x') ? 's' : 'S';
115 #endif
116 }
117
118 // returns a letter describing a file type (ls style)
119 char typeLetter(mode_t i)
120 {
121 #ifdef S_ISBLK
122         if (S_ISBLK(i)) return 'b';
123 #endif
124         if (S_ISCHR(i)) return 'c';
125         if (S_ISDIR(i)) return 'd';
126         if (S_ISREG(i)) return '-';
127 #ifdef S_ISFIFO
128         if (S_ISFIFO(i)) return 'p';
129 #endif
130 #ifdef S_ISLNK
131         if (S_ISLNK(i)) return 'l';
132 #endif
133 #ifdef S_ISSOCK
134         if (S_ISSOCK(i)) return 's';
135 #endif
136 #ifdef S_ISMPC
137         if (S_ISMPC(i)) return 'm';
138 #endif
139 #ifdef S_ISNWK
140         if (S_ISNWK(i)) return 'n';
141 #endif
142         return '?';
143 }
144
145
146 } // namespace anon
147
148
149 FileInfo::FileInfo()
150 {
151         init();
152 }
153
154
155 FileInfo::FileInfo(string const & path, bool link)
156         : fname_(path)
157 {
158         init();
159         dostat(link);
160 }
161
162
163 FileInfo::FileInfo(int fildes)
164 {
165         init();
166         status_ = fstat(fildes, &buf_);
167         if (status_)
168                 err_ = errno;
169 }
170
171
172 void FileInfo::init()
173 {
174         status_ = 0;
175         err_ = NoErr;
176 }
177
178
179 void FileInfo::dostat(bool link)
180 {
181         if (link)
182                 status_ = ::lstat(fname_.c_str(), &buf_);
183         else
184                 status_ = ::stat(fname_.c_str(), &buf_);
185         if (status_)
186                 err_ = errno;
187 }
188
189
190 FileInfo & FileInfo::newFile(string const & path, bool link)
191 {
192         fname_  = path;
193         status_ = 0;
194         err_    = NoErr;
195         dostat(link);
196         return *this;
197 }
198
199
200 FileInfo & FileInfo::newFile(int fildes)
201 {
202         status_ = 0;
203         err_    = NoErr;
204         status_ = fstat(fildes, &buf_);
205         if (status_)
206                 err_ = errno;
207         return *this;
208 }
209
210
211 // should not be in FileInfo
212 char FileInfo::typeIndicator() const
213 {
214         lyx::Assert(isOK());
215         if (S_ISDIR(buf_.st_mode))
216                 return '/';
217 #ifdef S_ISLNK
218         if (S_ISLNK(buf_.st_mode))
219                 return '@';
220 #endif
221 #ifdef S_ISFIFO
222         if (S_ISFIFO(buf_.st_mode))
223                 return '|';
224 #endif
225 #ifdef S_ISSOCK
226         if (S_ISSOCK(buf_.st_mode))
227                 return '=';
228 #endif
229         if (S_ISREG(buf_.st_mode) && (buf_.st_mode & (S_IEXEC | S_IXGRP | S_IXOTH)))
230                 return '*';
231         return ' ';
232 }
233
234
235 mode_t FileInfo::getMode() const
236 {
237         lyx::Assert(isOK());
238         return buf_.st_mode;
239 }
240
241
242 // should not be in FileInfo
243 string FileInfo::modeString() const
244 {
245         lyx::Assert(isOK());
246         char str[11];
247         str[0] = typeLetter(buf_.st_mode);
248         flagRWX((buf_.st_mode & 0700) << 0, &str[1]);
249         flagRWX((buf_.st_mode & 0070) << 3, &str[4]);
250         flagRWX((buf_.st_mode & 0007) << 6, &str[7]);
251         setSticky(buf_.st_mode, str);
252         str[10] = 0;
253         return str;
254 }
255
256
257
258 time_t FileInfo::getModificationTime() const
259 {
260         lyx::Assert(isOK());
261         return buf_.st_mtime;
262 }
263
264
265 time_t FileInfo::getAccessTime() const
266 {
267         lyx::Assert(isOK());
268         return buf_.st_atime;
269 }
270
271
272 time_t FileInfo::getStatusChangeTime() const
273 {
274         lyx::Assert(isOK());
275         return buf_.st_ctime;
276 }
277
278
279 nlink_t FileInfo::getNumberOfLinks() const
280 {
281         lyx::Assert(isOK());
282         return buf_.st_nlink;
283 }
284
285
286 uid_t FileInfo::getUid() const
287 {
288         lyx::Assert(isOK());
289         return buf_.st_uid;
290 }
291
292
293 gid_t FileInfo::getGid() const
294 {
295         lyx::Assert(isOK());
296         return buf_.st_gid;
297 }
298
299
300 off_t FileInfo::getSize() const
301 {
302         lyx::Assert(isOK());
303         return buf_.st_size;
304 }
305
306
307 int FileInfo::getError() const
308 {
309         return err_;
310 }
311
312
313 bool FileInfo::isOK() const
314 {
315         return status_ == 0;
316 }
317
318
319 bool FileInfo::isLink() const
320 {
321         lyx::Assert(isOK());
322         return S_ISLNK(buf_.st_mode);
323 }
324
325
326 bool FileInfo::isRegular() const
327 {
328         lyx::Assert(isOK());
329         return S_ISREG(buf_.st_mode);
330 }
331
332
333 bool FileInfo::isDir() const
334 {
335         lyx::Assert(isOK());
336         return S_ISDIR(buf_.st_mode);
337 }
338
339
340 bool FileInfo::isChar() const
341 {
342         lyx::Assert(isOK());
343         return S_ISCHR(buf_.st_mode);
344 }
345
346
347 bool FileInfo::isBlock() const
348 {
349         lyx::Assert(isOK());
350         return S_ISBLK(buf_.st_mode);
351 }
352
353
354 bool FileInfo::isFifo() const
355 {
356         lyx::Assert(isOK());
357         return S_ISFIFO(buf_.st_mode);
358 }
359
360
361 bool FileInfo::isSocket() const
362 {
363         lyx::Assert(isOK());
364 #ifdef S_ISSOCK
365         return S_ISSOCK(buf_.st_mode);
366 #else
367         return false;
368 #endif
369 }
370
371
372 // should not be in FileInfo
373 bool FileInfo::access(int p) const
374 {
375         // if we don't have a filename we fail
376         if (fname_.empty())
377                 return false;
378
379         // If we were really kind, we would also tell why
380         // the file access failed.
381         return ::access(fname_.c_str(), p) == 0;
382 }