]> git.lyx.org Git - lyx.git/blob - src/support/FileInfo.C
clean up
[lyx.git] / src / support / FileInfo.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *
6  *           Copyright 1995 Matthias Ettrich
7  *           Copyright 1995-2001 The LyX Team.
8  *
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 } // namespace anon
119
120
121 FileInfo::FileInfo()
122 {
123         init();
124 }
125
126
127 FileInfo::FileInfo(string const & path, bool link)
128         : fname_(path)
129 {
130         init();
131         dostat(link);
132 }
133
134
135 FileInfo::FileInfo(int fildes)
136 {
137         init();
138         status_ = fstat(fildes, &buf_);
139         if (status_)
140                 err_ = errno;
141 }
142
143
144 void FileInfo::init()
145 {
146         status_ = 0;
147         err_ = NoErr;
148 }
149
150
151 void FileInfo::dostat(bool link)
152 {
153         if (link)
154                 status_ = ::lstat(fname_.c_str(), &buf_);
155         else
156                 status_ = ::stat(fname_.c_str(), &buf_);
157         if (status_)
158                 err_ = errno;
159 }
160
161
162 FileInfo & FileInfo::newFile(string const & path, bool link)
163 {
164         fname_  = path;
165         status_ = 0;
166         err_    = NoErr;
167         dostat(link);
168         return *this;
169 }
170
171
172 FileInfo & FileInfo::newFile(int fildes)
173 {
174         status_ = 0;
175         err_    = NoErr;
176         status_ = fstat(fildes, &buf_);
177         if (status_)
178                 err_ = errno;
179         return *this;
180 }
181
182
183 // should not be in FileInfo
184 char const * FileInfo::typeIndicator() const
185 {
186         lyx::Assert(isOK());
187         if (S_ISDIR(buf_.st_mode))
188                 return "/";
189 #ifdef S_ISLNK
190         if (S_ISLNK(buf_.st_mode))
191                 return "@";
192 #endif
193 #ifdef S_ISFIFO
194         if (S_ISFIFO(buf_.st_mode))
195                 return "|";
196 #endif
197 #ifdef S_ISSOCK
198         if (S_ISSOCK(buf_.st_mode))
199                 return "=";
200 #endif
201         if (S_ISREG(buf_.st_mode) && (buf_.st_mode & (S_IEXEC | S_IXGRP | S_IXOTH)))
202                 return "*";
203         return "";
204 }
205
206
207 mode_t FileInfo::getMode() const
208 {
209         lyx::Assert(isOK());
210         return buf_.st_mode;
211 }
212
213
214 // should not be in FileInfo
215 void FileInfo::modeString(char * str) const
216 {
217         str[0] = typeLetter();
218         flagRWX((buf_.st_mode & 0700) << 0, &str[1]);
219         flagRWX((buf_.st_mode & 0070) << 3, &str[4]);
220         flagRWX((buf_.st_mode & 0007) << 6, &str[7]);
221         lyx::Assert(isOK());
222         setSticky(buf_.st_mode, str);
223         str[10] = 0;
224 }
225
226
227 // should not be in FileInfo
228 char FileInfo::typeLetter() const
229 {
230         lyx::Assert(isOK());
231
232 #ifdef S_ISBLK
233         if (S_ISBLK(buf_.st_mode)) return 'b';
234 #endif
235         if (S_ISCHR(buf_.st_mode)) return 'c';
236         if (S_ISDIR(buf_.st_mode)) return 'd';
237         if (S_ISREG(buf_.st_mode)) return '-';
238 #ifdef S_ISFIFO
239         if (S_ISFIFO(buf_.st_mode)) return 'p';
240 #endif
241 #ifdef S_ISLNK
242         if (S_ISLNK(buf_.st_mode)) return 'l';
243 #endif
244 #ifdef S_ISSOCK
245         if (S_ISSOCK(buf_.st_mode)) return 's';
246 #endif
247 #ifdef S_ISMPC
248         if (S_ISMPC(buf_.st_mode)) return 'm';
249 #endif
250 #ifdef S_ISNWK
251         if (S_ISNWK(buf_.st_mode)) return 'n';
252 #endif
253         return '?';
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 }