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