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