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