]> git.lyx.org Git - lyx.git/blob - src/support/FileInfo.C
FILMagain changes (will need some work)
[lyx.git] / src / support / FileInfo.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ======================================================
4  * 
5  *           LyX, The Document Processor
6  *        
7  *           Copyright 1995 Matthias Ettrich
8  *           Copyright 1995-2000 The LyX Team.
9  *
10  * ====================================================== */
11
12 #include <config.h>
13
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <cerrno>
17 #include "FileInfo.h"
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 // Since major is a function on SVR4, we can't use `ifndef major'. 
86 // might want to put MAJOR_IN_MKDEV for SYSV
87 #ifdef MAJOR_IN_MKDEV
88 #include <sys/mkdev.h>
89 #define HAVE_MAJOR
90 #endif
91 #ifdef MAJOR_IN_SYSMACROS
92 #include <sys/sysmacros.h>
93 #define HAVE_MAJOR
94 #endif
95 #ifdef major            
96 #define HAVE_MAJOR
97 #endif
98
99 #ifndef HAVE_MAJOR
100 #define major(dev)  (((dev) >> 8) & 0xff)
101 #define minor(dev)  ((dev) & 0xff)
102 #define makedev(maj, min)  (((maj) << 8) | (min))
103 #endif
104 #undef HAVE_MAJOR
105
106
107 FileInfo::FileInfo()
108 {
109         init();
110 }
111
112
113 FileInfo::FileInfo(string const & path, bool link)
114         : fname(path)
115 {
116         init();
117         dostat(link);
118 }
119
120
121 FileInfo::FileInfo(int fildes)
122 {
123         init();
124         status = fstat(fildes, &buf);
125         if (status) err = errno;
126 }
127
128
129 void FileInfo::init()
130 {
131         status = 0;
132         err = NoErr;
133 }
134
135
136 void FileInfo::dostat(bool link)
137 {
138         if (link) {
139                 status = lstat(fname.c_str(), &buf);
140         } else {
141                 status = stat(fname.c_str(), &buf);
142         }
143         if (status) err = errno;
144 }
145
146
147 FileInfo & FileInfo::newFile(string const & path, bool link)
148 {
149         fname = path;
150         
151         status = 0;
152         err = NoErr;
153
154         dostat(link);
155
156         return *this;
157 }
158
159
160 FileInfo & FileInfo::newFile(int fildes)
161 {
162         status = 0;
163         err = NoErr;
164         status = fstat(fildes, &buf);
165         if (status) err = errno;
166         return *this;
167 }
168
169
170 // should not be in FileInfo
171 char const * FileInfo::typeIndicator() const
172 {
173         if (S_ISDIR(buf.st_mode)) return ("/");
174 #ifdef S_ISLNK
175         if (S_ISLNK(buf.st_mode)) return ("@");
176 #endif
177 #ifdef S_ISFIFO
178         if (S_ISFIFO(buf.st_mode)) return ("|");
179 #endif
180 #ifdef S_ISSOCK
181         if (S_ISSOCK(buf.st_mode)) return ("=");
182 #endif
183         if (S_ISREG(buf.st_mode) && (buf.st_mode & (S_IEXEC | S_IXGRP | S_IXOTH)))
184                 return ("*");
185         return "";
186 }
187
188
189 mode_t FileInfo::getMode() const
190 {
191         return buf.st_mode;
192 }
193
194
195 long FileInfo::getBlockSize() const
196 {
197 #ifndef __EMX__
198         return buf.st_blksize; /* Preferred I/O block size */
199 #else
200 #warning May be fixed in 0.13 (SMiyata)
201         return 512; /* Assume HPFS */
202 #endif
203 }
204
205
206 // should not be in FileInfo
207 void FileInfo::modeString(char * szString) const
208 {
209         szString[0] = typeLetter();
210         flagRWX((buf.st_mode & 0700) << 0, &szString[1]);
211         flagRWX((buf.st_mode & 0070) << 3, &szString[4]);
212         flagRWX((buf.st_mode & 0007) << 6, &szString[7]);
213         setSticky(szString);
214         szString[10] = 0;
215 }
216
217
218 // should not be in FileInfo
219 char FileInfo::typeLetter() const
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(unsigned short 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 #ifdef S_ISUID
259         if (buf.st_mode & S_ISUID) {
260                 if (szString[3] != 'x') szString[3] = 'S';
261                 else szString[3] = 's';
262         }
263 #endif
264 #ifdef S_ISGID
265         if (buf.st_mode & S_ISGID) {
266                 if (szString[6] != 'x') szString[6] = 'S';
267                 else szString[6] = 's';
268         }
269 #endif
270 #ifdef S_ISVTX
271         if (buf.st_mode & S_ISVTX) {
272                 if (szString[9] != 'x') szString[9] = 'T';
273                 else szString[9] = 't';
274         }
275 #endif
276 }
277
278
279 time_t FileInfo::getModificationTime() const
280 {
281         return buf.st_mtime;
282 }
283
284
285 time_t FileInfo::getAccessTime() const
286 {
287         return buf.st_atime;
288 }
289
290
291 time_t FileInfo::getStatusChangeTime() const
292 {
293         return buf.st_ctime;
294 }
295
296
297 nlink_t FileInfo::getNumberOfLinks() const
298 {
299         return buf.st_nlink;
300 }
301
302
303 uid_t FileInfo::getUid() const
304 {
305         return buf.st_uid;
306 }
307
308
309 gid_t FileInfo::getGid() const
310 {
311         return buf.st_gid;
312 }
313
314
315 off_t FileInfo::getSize() const
316 {
317         return buf.st_size;
318 }
319
320
321 int FileInfo::getError() const
322 {
323         return err;
324 }
325
326
327 bool FileInfo::isOK() const
328 {
329         // DEC cxx 6.0 chokes on this bizarre construct (compiler bug)
330         // return (status) ? false : true;
331         // So I replaced it with a simpler one (JMarc)
332         return status == 0;
333 }
334
335
336 bool FileInfo::isLink() const
337 {
338         return S_ISLNK(buf.st_mode);
339 }
340
341
342 bool FileInfo::isRegular() const
343 {
344         return S_ISREG(buf.st_mode);
345 }
346
347
348 bool FileInfo::isDir() const
349 {
350         return S_ISDIR(buf.st_mode);
351 }
352
353
354 bool FileInfo::isChar() const
355 {
356         return S_ISCHR(buf.st_mode);
357 }
358
359
360 bool FileInfo::isBlock() const
361 {
362         return S_ISBLK(buf.st_mode);
363 }
364
365
366 bool FileInfo::isFifo() const
367 {
368         return S_ISFIFO(buf.st_mode);
369 }
370
371
372 bool FileInfo::isSocket() const
373 {
374 #ifdef S_ISSOCK
375         return S_ISSOCK(buf.st_mode);
376 #else
377         return false;
378 #endif
379 }
380
381
382 // should not be in FileInfo
383 bool FileInfo::access(int p)
384 {
385         // if we don't have a filename we fail
386         if (fname.empty()) return false;
387         
388         if (::access(fname.c_str(), p) == 0)
389                 return true;
390         else {
391                 // If we were really kind, we would also tell why
392                 // the file access failed.
393                 return false;
394         }
395 }