2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright (C) 1995 Matthias Ettrich
8 * Copyright (C) 1995-1998 The LyX Team.
10 *======================================================*/
14 #include <sys/types.h>
19 // $Id: FileInfo.C,v 1.1 1999/09/27 18:44:36 larsbj Exp $
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 $";
27 # define S_IRUSR S_IREAD
29 # define S_IRUSR 00400
35 # define S_IWUSR S_IWRITE
37 # define S_IWUSR 00200
43 # define S_IXUSR S_IEXEC
45 # define S_IXUSR 00100
49 #ifdef STAT_MACROS_BROKEN
62 #if !defined(S_ISBLK) && defined(S_IFBLK)
63 #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
65 #if !defined(S_ISCHR) && defined(S_IFCHR)
66 #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
68 #if !defined(S_ISDIR) && defined(S_IFDIR)
69 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
71 #if !defined(S_ISREG) && defined(S_IFREG)
72 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
74 #if !defined(S_ISFIFO) && defined(S_IFIFO)
75 #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
77 #if !defined(S_ISLNK) && defined(S_IFLNK)
78 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
80 #if !defined(S_ISSOCK) && defined(S_IFSOCK)
81 #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
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)
87 #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
88 #define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
91 // Since major is a function on SVR4, we can't use `ifndef major'.
92 // might want to put MAJOR_IN_MKDEV for SYSV
94 #include <sys/mkdev.h>
97 #ifdef MAJOR_IN_SYSMACROS
98 #include <sys/sysmacros.h>
106 #define major(dev) (((dev) >> 8) & 0xff)
107 #define minor(dev) ((dev) & 0xff)
108 #define makedev(maj, min) (((maj) << 8) | (min))
119 FileInfo::FileInfo(LString const &path, bool link)
127 FileInfo::FileInfo(int fildes)
130 status = fstat(fildes, buf);
131 if (status) err = errno;
135 FileInfo::~FileInfo()
141 void FileInfo::init()
145 buf = (struct stat*) new char[sizeof(struct stat)];
149 void FileInfo::dostat(bool link)
152 status = lstat(fname.c_str(), buf);
154 status = stat(fname.c_str(), buf);
156 if (status) err = errno;
160 FileInfo& FileInfo::newFile(LString const &path, bool link)
173 FileInfo& FileInfo::newFile(int fildes)
177 status = fstat(fildes, buf);
178 if (status) err = errno;
183 char const *FileInfo::typeIndicator() const
185 if (S_ISDIR(buf->st_mode)) return ("/");
187 if (S_ISLNK(buf->st_mode)) return ("@");
190 if (S_ISFIFO(buf->st_mode)) return ("|");
193 if (S_ISSOCK(buf->st_mode)) return ("=");
195 if (S_ISREG(buf->st_mode) && (buf->st_mode & (S_IEXEC | S_IXGRP | S_IXOTH)))
201 mode_t FileInfo::getMode() const
206 long FileInfo::getBlockSize() const
209 return buf->st_blksize; /* Preferred I/O block size */
211 #warning May be fixed in 0.13 (SMiyata)
212 return 512; /* Assume HPFS */
216 void FileInfo::modeString(char *szString) const
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]);
227 char FileInfo::typeLetter() const
230 if (S_ISBLK(buf->st_mode)) return 'b';
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 '-';
236 if (S_ISFIFO(buf->st_mode)) return 'p';
239 if (S_ISLNK(buf->st_mode)) return 'l';
242 if (S_ISSOCK(buf->st_mode)) return 's';
245 if (S_ISMPC(buf->st_mode)) return 'm';
248 if (S_ISNWK(buf->st_mode)) return 'n';
254 void FileInfo::flagRWX(unsigned short i, char *szString) const
256 szString[0] = (i & S_IRUSR) ? 'r' : '-';
257 szString[1] = (i & S_IWUSR) ? 'w' : '-';
258 szString[2] = (i & S_IXUSR) ? 'x' : '-';
262 void FileInfo::setSticky(char *szString) const
265 if (buf->st_mode & S_ISUID) {
266 if (szString[3] != 'x') szString[3] = 'S';
267 else szString[3] = 's';
271 if (buf->st_mode & S_ISGID) {
272 if (szString[6] != 'x') szString[6] = 'S';
273 else szString[6] = 's';
277 if (buf->st_mode & S_ISVTX) {
278 if (szString[9] != 'x') szString[9] = 'T';
279 else szString[9] = 't';
285 time_t FileInfo::getModificationTime() const
287 return buf->st_mtime;
291 time_t FileInfo::getAccessTime() const
293 return buf->st_atime;
297 time_t FileInfo::getStatusChangeTime() const
299 return buf->st_ctime;
303 nlink_t FileInfo::getNumberOfLinks() const
305 return buf->st_nlink;
309 uid_t FileInfo::getUid() const
315 gid_t FileInfo::getGid() const
321 off_t FileInfo::getSize() const
327 int FileInfo::getError() const
333 bool FileInfo::isOK() const
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)
342 bool FileInfo::isLink() const
344 return S_ISLNK(buf->st_mode);
348 bool FileInfo::isRegular() const
350 return S_ISREG(buf->st_mode);
354 bool FileInfo::isDir() const
356 return S_ISDIR(buf->st_mode);
360 bool FileInfo::isChar() const
362 return S_ISCHR(buf->st_mode);
366 bool FileInfo::isBlock() const
368 return S_ISBLK(buf->st_mode);
372 bool FileInfo::isFifo() const
374 return S_ISFIFO(buf->st_mode);
378 bool FileInfo::isSocket() const
381 return S_ISSOCK(buf->st_mode);
388 bool FileInfo::access(int p)
390 // if we don't have a filename we fail
391 if (fname.empty()) return false;
393 if (::access(fname.c_str(), p) == 0)
396 // If we were really kind, we would also tell why
397 // the file access failed.