]> git.lyx.org Git - lyx.git/blob - src/support/FileInfo.C
ws cleanup
[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 // Since major is a function on SVR4, we can't use `ifndef major'.
91 // might want to put MAJOR_IN_MKDEV for SYSV
92 #ifdef MAJOR_IN_MKDEV
93 #include <sys/mkdev.h>
94 #define HAVE_MAJOR
95 #endif
96 #ifdef MAJOR_IN_SYSMACROS
97 #include <sys/sysmacros.h>
98 #define HAVE_MAJOR
99 #endif
100 #ifdef major
101 #define HAVE_MAJOR
102 #endif
103
104 #ifndef HAVE_MAJOR
105 #define major(dev)  (((dev) >> 8) & 0xff)
106 #define minor(dev)  ((dev) & 0xff)
107 #define makedev(maj, min)  (((maj) << 8) | (min))
108 #endif
109 #undef HAVE_MAJOR
110
111
112 FileInfo::FileInfo()
113 {
114         init();
115 }
116
117
118 FileInfo::FileInfo(string const & path, bool link)
119         : fname(path)
120 {
121         init();
122         dostat(link);
123 }
124
125
126 FileInfo::FileInfo(int fildes)
127 {
128         init();
129         status = fstat(fildes, &buf);
130         if (status) err = errno;
131 }
132
133
134 void FileInfo::init()
135 {
136         status = 0;
137         err = NoErr;
138 }
139
140
141 void FileInfo::dostat(bool link)
142 {
143         if (link) {
144                 status = ::lstat(fname.c_str(), &buf);
145         } else {
146                 status = ::stat(fname.c_str(), &buf);
147         }
148         if (status) err = errno;
149 }
150
151
152 FileInfo & FileInfo::newFile(string const & path, bool link)
153 {
154         fname = path;
155
156         status = 0;
157         err = NoErr;
158
159         dostat(link);
160
161         return *this;
162 }
163
164
165 FileInfo & FileInfo::newFile(int fildes)
166 {
167         status = 0;
168         err = NoErr;
169         status = fstat(fildes, &buf);
170         if (status) err = errno;
171         return *this;
172 }
173
174
175 // should not be in FileInfo
176 char const * FileInfo::typeIndicator() const
177 {
178         lyx::Assert(isOK());
179
180         if (S_ISDIR(buf.st_mode)) return ("/");
181 #ifdef S_ISLNK
182         if (S_ISLNK(buf.st_mode)) return ("@");
183 #endif
184 #ifdef S_ISFIFO
185         if (S_ISFIFO(buf.st_mode)) return ("|");
186 #endif
187 #ifdef S_ISSOCK
188         if (S_ISSOCK(buf.st_mode)) return ("=");
189 #endif
190         if (S_ISREG(buf.st_mode) && (buf.st_mode & (S_IEXEC | S_IXGRP | S_IXOTH)))
191                 return ("*");
192         return "";
193 }
194
195
196 mode_t FileInfo::getMode() const
197 {
198         lyx::Assert(isOK());
199
200         return buf.st_mode;
201 }
202
203
204 // should not be in FileInfo
205 void FileInfo::modeString(char * szString) const
206 {
207         szString[0] = typeLetter();
208         flagRWX((buf.st_mode & 0700) << 0, &szString[1]);
209         flagRWX((buf.st_mode & 0070) << 3, &szString[4]);
210         flagRWX((buf.st_mode & 0007) << 6, &szString[7]);
211         setSticky(szString);
212         szString[10] = 0;
213 }
214
215
216 // should not be in FileInfo
217 char FileInfo::typeLetter() const
218 {
219         lyx::Assert(isOK());
220
221 #ifdef S_ISBLK
222         if (S_ISBLK(buf.st_mode)) return 'b';
223 #endif
224         if (S_ISCHR(buf.st_mode)) return 'c';
225         if (S_ISDIR(buf.st_mode)) return 'd';
226         if (S_ISREG(buf.st_mode)) return '-';
227 #ifdef S_ISFIFO
228         if (S_ISFIFO(buf.st_mode)) return 'p';
229 #endif
230 #ifdef S_ISLNK
231         if (S_ISLNK(buf.st_mode)) return 'l';
232 #endif
233 #ifdef S_ISSOCK
234         if (S_ISSOCK(buf.st_mode)) return 's';
235 #endif
236 #ifdef S_ISMPC
237         if (S_ISMPC(buf.st_mode)) return 'm';
238 #endif
239 #ifdef S_ISNWK
240         if (S_ISNWK(buf.st_mode)) return 'n';
241 #endif
242         return '?';
243 }
244
245
246 // should not be in FileInfo
247 void FileInfo::flagRWX(mode_t i, char * szString) const
248 {
249         szString[0] = (i & S_IRUSR) ? 'r' : '-';
250         szString[1] = (i & S_IWUSR) ? 'w' : '-';
251         szString[2] = (i & S_IXUSR) ? 'x' : '-';
252 }
253
254
255 // should not be in FileInfo
256 void FileInfo::setSticky(char * szString) const
257 {
258         lyx::Assert(isOK());
259
260 #ifdef S_ISUID
261         if (buf.st_mode & S_ISUID) {
262                 if (szString[3] != 'x') szString[3] = 'S';
263                 else szString[3] = 's';
264         }
265 #endif
266 #ifdef S_ISGID
267         if (buf.st_mode & S_ISGID) {
268                 if (szString[6] != 'x') szString[6] = 'S';
269                 else szString[6] = 's';
270         }
271 #endif
272 #ifdef S_ISVTX
273         if (buf.st_mode & S_ISVTX) {
274                 if (szString[9] != 'x') szString[9] = 'T';
275                 else szString[9] = 't';
276         }
277 #endif
278 }
279
280
281 time_t FileInfo::getModificationTime() const
282 {
283         lyx::Assert(isOK());
284         return buf.st_mtime;
285 }
286
287
288 time_t FileInfo::getAccessTime() const
289 {
290         lyx::Assert(isOK());
291         return buf.st_atime;
292 }
293
294
295 time_t FileInfo::getStatusChangeTime() const
296 {
297         lyx::Assert(isOK());
298         return buf.st_ctime;
299 }
300
301
302 nlink_t FileInfo::getNumberOfLinks() const
303 {
304         lyx::Assert(isOK());
305         return buf.st_nlink;
306 }
307
308
309 uid_t FileInfo::getUid() const
310 {
311         lyx::Assert(isOK());
312         return buf.st_uid;
313 }
314
315
316 gid_t FileInfo::getGid() const
317 {
318         lyx::Assert(isOK());
319         return buf.st_gid;
320 }
321
322
323 off_t FileInfo::getSize() const
324 {
325         lyx::Assert(isOK());
326         return buf.st_size;
327 }
328
329
330 int FileInfo::getError() const
331 {
332         return err;
333 }
334
335
336 bool FileInfo::isOK() const
337 {
338         // DEC cxx 6.0 chokes on this bizarre construct (compiler bug)
339         // return (status) ? false : true;
340         // So I replaced it with a simpler one (JMarc)
341         return status == 0;
342 }
343
344
345 bool FileInfo::isLink() const
346 {
347         lyx::Assert(isOK());
348         return S_ISLNK(buf.st_mode);
349 }
350
351
352 bool FileInfo::isRegular() const
353 {
354         lyx::Assert(isOK());
355         return S_ISREG(buf.st_mode);
356 }
357
358
359 bool FileInfo::isDir() const
360 {
361         lyx::Assert(isOK());
362         return S_ISDIR(buf.st_mode);
363 }
364
365
366 bool FileInfo::isChar() const
367 {
368         lyx::Assert(isOK());
369         return S_ISCHR(buf.st_mode);
370 }
371
372
373 bool FileInfo::isBlock() const
374 {
375         lyx::Assert(isOK());
376         return S_ISBLK(buf.st_mode);
377 }
378
379
380 bool FileInfo::isFifo() const
381 {
382         lyx::Assert(isOK());
383         return S_ISFIFO(buf.st_mode);
384 }
385
386
387 bool FileInfo::isSocket() const
388 {
389         lyx::Assert(isOK());
390 #ifdef S_ISSOCK
391         return S_ISSOCK(buf.st_mode);
392 #else
393         return false;
394 #endif
395 }
396
397
398 // should not be in FileInfo
399 bool FileInfo::access(int p) const
400 {
401         // if we don't have a filename we fail
402         if (fname.empty()) return false;
403
404         if (::access(fname.c_str(), p) == 0)
405                 return true;
406         else {
407                 // If we were really kind, we would also tell why
408                 // the file access failed.
409                 return false;
410         }
411 }