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