Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4972 → Rev 4973

/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/Makefile
0,0 → 1,4
THIS_SRCS = chmod.c filelen.c fixpath.c fstat.c is_exec.c mkdir.c mkfifo.c \
stat.c st_loss.c umask.c xstat.c
 
include $(MENUET_LIBC_TOPDIR)/Make.rules
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/chmod.c
0,0 → 1,26
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <libc/stubs.h>
#include <sys/stat.h>
#include <io.h>
int
chmod(const char *filename, int pmode)
{
int dmode;
unsigned attr = _chmod(filename, 0, 0);
if (attr == -1)
return -1;
if(pmode & S_IWUSR) /* Only implemented toggle is write/nowrite */
dmode = 0; /* Normal file */
else
dmode = 1; /* Readonly file */
/* Must clear the directory and volume bits, otherwise 214301 fails.
Unused bits left alone (some network redirectors use them). */
if (_chmod(filename, 1, (attr & 0xffe6) | dmode) == -1)
return -1;
return 0;
}
 
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/filelen.c
0,0 → 1,19
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/* This is file FILELEN.C */
/*
* Copyright (c) 1994 Eli Zaretskii <eliz@is.elta.co.il>
*
* This software may be used freely so long as this copyright notice is
* left intact. There is no warranty on this software.
*
*/
 
#include <errno.h>
#include <libc/dosio.h>
 
long __filelength(int);
 
long __filelength(int fhandle)
{
return dosemu_iosize(fhandle);
}
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/fixpath.c
0,0 → 1,41
#include <libc/stubs.h>
#include <stdio.h> /* For FILENAME_MAX */
#include <errno.h> /* For errno */
#include <string.h> /* For strlen() */
#include <sys/stat.h>
#include <libc/dosio.h>
 
static inline int is_slash(char c)
{
return c=='/' || c=='\\';
}
 
void fix_slashes(char * in,char * out)
{
int slash_count;
for(slash_count=1;in && out && *in;in++)
{
if(is_slash(*in))
{
slash_count++;
continue;
} else {
if(slash_count)
{
slash_count=0;
*out++='/';
}
*out++=*in;
}
}
*out='\0';
}
 
char * __libc_combine_path(char * c);
 
void _fixpath(const char *in, char *out)
{
char * combined;
combined=__libc_combine_path((char *)in);
fix_slashes(combined,out);
}
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/fstat.c
0,0 → 1,26
#include <libc/stubs.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <libc/farptrgs.h>
#include <libc/bss.h>
#include <menuet/os.h>
 
#include "../../../dos/dos_emu/dosemuin.h"
 
#include "xstat.h"
 
int fstat(int handle, struct stat *statbuf)
{
if (handle < 0 || handle >= _MAX_HANDLES)
{
errno = EBADF;
return -1;
}
return stat(_io_handles[handle].filename, statbuf);
}
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/is_exec.c
0,0 → 1,125
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/* IS_EXEC.C
*
* Given a filename or a file handle, and the extension of the file,
* determine if the file is executable.
* First, the file extension is checked in case it uniquely identifies
* the file as either an executable or not. Failing this, the first
* two bytes of the file are tested for known signatures of executable
* files.
*
* Copyright (c) 1994 Eli Zaretskii <eliz@is.elta.co.il>
*
* This software may be used freely so long as this copyright notice is
* left intact. There is no warranty on this software.
*
*/
 
#include <libc/stubs.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <libc/farptrgs.h>
#include <libc/dosio.h>
 
extern unsigned short _djstat_flags;
unsigned short _get_magic(const char *, int);
int _is_executable(const char *, int, const char *);
 
/*
* Read a MAGIC NUMBER from a given file. These are the first
* two bytes of the file, if we look at them as an unsigned short. */
 
#define _STAT_EXEC_EXT 2 /* get execute bits from file extension? */
#define _STAT_EXEC_MAGIC 4 /* get execute bits from magic signature? */
 
unsigned short _get_magic(const char *s, int fh)
{
}
 
/* A list of extensions which designate executable files. These
are NOT tested for the magic number. */
static char executables[] = "|EXE|COM|BAT|BTM|DLL|VXD|";
 
/* A list of extensions which belong to files known to NEVER be
executables. These exist to minimize read()'ing files while
detecting executables by magic number. You are welcome to
add to this list, but remember: only extensions which could
NEVER be present in executables should go here. */
static char non_executables[] = "\
|A|A01|A02|A03|A04|A05|ADL|ARC|ARJ|ASC|ASM|AUX|AWK\
|BAS|BIB|BGI|BMP\
|C|CC|CFG|CGZ|CH3|CHR|CI|CLP|CMF|CPI|CPP|CXX\
|DAT|DBF|DIZ|DOC|DVI\
|E|EL|ELC\
|F77|FN3\
|GIF|GZ\
|H|HLP|HPP|HXX\
|ICO|IN|INC|INF|INI\
|JPG\
|L|LEX|LF|LIB|LOG|LST|LZH\
|M|MAK|MAP|MF|MID|MPG\
|O|OBJ\
|PAK|PAS|PBM|PCD|PCX|PDS|PIC|PIF|PN3|PRJ|PS\
|RAS|RGB|RLE\
|S|SND|SY3\
|TAR|TAZ|TEX|TGA|TGZ|TIF|TXH|TXI|TXT\
|VOC\
|WAV|WK1|WK3|WKB|WQ1|WQ3|WQ4|WQ5|WQ6|WQ!\
|XBM\
|Y\
|ZIP|ZOO|";
 
int _is_executable(const char *filename, int fhandle, const char *extension)
{
if (!extension && filename)
{
const char *cp, *ep=0;
for (cp=filename; *cp; cp++)
{
if (*cp == '.')
ep = cp;
if (*cp == '/' || *cp == '\\' || *cp == ':')
ep = 0;
}
extension = ep;
}
if ((_djstat_flags & _STAT_EXEC_EXT) == 0
&& extension
&& *extension
&& strlen(extension) <= ((extension[0]=='.') ? 4 : 3))
{
/* Search the list of extensions in executables[]. */
char tmp_buf[6];
 
tmp_buf[0] = '|';
strcpy(tmp_buf+1, *extension == '.' ? extension + 1 : extension);
strcat(tmp_buf, "|");
if (strstr(non_executables, tmp_buf))
return 0;
else if (strstr(executables, tmp_buf))
return 1;
}
 
/* No extension, or extension doesn't define execute
bits unambiguously. We are in for some dirty work.
Read the first two bytes of the file and see if they
are any of the known magic numbers which designate
executable files.
Unix-like shells, which have executable shell scripts
without extensions and DON'T have "#!" as their FIRST
TWO CHARACTERS, lose here. Sorry, folks. */
if ( (_djstat_flags & _STAT_EXEC_MAGIC) == 0 )
{
switch (_get_magic(filename, fhandle))
{
case 0x5a4d: /* "MZ" */
case 0x010b:
case 0x014c:
case 0x2123: /* "#!" */
return 1;
}
}
 
return 0;
}
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/mkdir.c
0,0 → 1,12
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <libc/stubs.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libc/dosio.h>
int mkdir(const char *dirname, mode_t mode)
{
return -1;
}
 
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/mkfifo.c
0,0 → 1,10
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <sys/stat.h>
#include <errno.h>
 
int
mkfifo(const char *path, mode_t mode)
{
errno = EACCES;
return -1;
}
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/st_loss.c
0,0 → 1,68
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/*
* This is file ST_LOSS.C
*
* Function to print a human-readable description of _DJSTAT_FAIL_BITS
* variable, for debugging purposes. A string which contains description
* of every fail bit set is printed to the stream given by FP, or to
* stderr if FP is NULL.
*
* Copyright (c) 1994 Eli Zaretskii <eliz@is.elta.co.il>
*
* This software may be used freely as long as the above copyright
* notice is left intact. There is no warranty on this software.
*
*/
 
#include <stdio.h>
#include "xstat.h"
 
/* List of messages describing possible failures. There is a message
for every bit in the _DJSTAT_FAIL_BITS variable, plus a success
message, which is printed if no bits are set.
*/
static const char *stfail_message[] = {
"Everything checks out OK",
"Get DOS SDA call (INT 21h/AX=5D06h/0Dh) failed",
"Unsupported DOS version: less than 3.10 (for stat), or 1.x (for fstat)",
"Cannot find SDA entry which corresponds to pathname (bad SDA pointer?)",
"Get TrueName call (INT 21h/AX=6000h) failed",
"Failed to get starting cluster number; inode defaults to hashing\n"
"(if no other messages were printed, then this is either an empty\n"
"file on a local disk drive, or a file on a networked drive, or\n"
"you run under some kind of DOS clone)",
"Root directory has no volume label required to get its time fields",
"Get SDA call returned preposterously large or negative number of SDAs",
"Write access bit required, but cannot be figured out",
"Failed to get drive letter for handle (Novell NetWare 3.x?)",
"SFT entry found, but is inconsistent with file size and time stamp",
"Negative index into SFT: might be bad handle table in PSP",
"File entry not found in SFT array (bad SFT index, or Novell 3.x)"
};
 
/* Number of used bits we know about in _djstat_fail_bits. */
static const int used_bits = sizeof(stfail_message)/sizeof(stfail_message[0]);
 
void
_djstat_describe_lossage(FILE *fp)
{
int i = 0;
unsigned long bits = _djstat_fail_bits; /* so we don't have side effects */
 
if (fp == 0)
fp = stderr; /* default: print to stderr */
 
while (bits && i < used_bits)
{
i++;
if (bits & 1) /* print message for this bit, if set */
fprintf(fp, "%s\n", stfail_message[i]);
 
bits >>= 1; /* get next bit */
}
 
/* Did we see any bit set? */
if (i == 0)
fprintf(fp, "%s\n", stfail_message[0]);
 
}
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/stat.c
0,0 → 1,80
#include <libc/stubs.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dos.h>
#include <dir.h>
#include <libc/farptrgs.h>
#include <libc/bss.h>
 
#include "xstat.h"
 
int stat(const char *path, struct stat *statbuf)
{
int nslash=0;
const char* p;
char* q;
struct systree_info2 finf;
struct bdfe_item attr;
 
memset(statbuf,0,sizeof(*statbuf));
// "/<base>/<number>" is special case
for (p=path;*p;p++) if (*p=='/') ++nslash;
while (p>path && p[-1]=='/') {--nslash;--p;}
if (nslash <= 2)
{
statbuf->st_mode = S_IFDIR;
return 0;
}
finf.command = 5;
finf.file_offset_low = 0;
finf.file_offset_high = 0;
finf.size = 0;
finf.data_pointer = (__u32)&attr;
_fixpath(path,finf.name);
for (q=finf.name+strlen(finf.name)-1;q>=finf.name && *q=='/';q--) ;
q[1]=0;
if (__kolibri__system_tree_access2(&finf))
{
errno = EFAULT;
return -1;
}
memset(statbuf,0,sizeof(*statbuf));
statbuf->st_size = attr.filesize_low;
if (attr.attr & 0x10)
statbuf->st_mode = S_IFDIR;
struct tm time;
time.tm_sec = attr.atime.seconds;
time.tm_min = attr.atime.minutes;
time.tm_hour = attr.atime.hours;
time.tm_mday = attr.adate.day;
time.tm_mon = attr.adate.month;
time.tm_year = attr.adate.year - 1900;
time.tm_isdst = -1;
statbuf->st_atime = mktime(&time);
time.tm_sec = attr.ctime.seconds;
time.tm_min = attr.ctime.minutes;
time.tm_hour = attr.ctime.hours;
time.tm_mday = attr.cdate.day;
time.tm_mon = attr.cdate.month;
time.tm_year = attr.cdate.year - 1900;
time.tm_isdst = -1;
statbuf->st_ctime = mktime(&time);
time.tm_sec = attr.mtime.seconds;
time.tm_min = attr.mtime.minutes;
time.tm_hour = attr.mtime.hours;
time.tm_mday = attr.mdate.day;
time.tm_mon = attr.mdate.month;
time.tm_year = attr.mdate.year - 1900;
time.tm_isdst = -1;
statbuf->st_mtime = mktime(&time);
return 0;
}
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/umask.c
0,0 → 1,11
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <sys/stat.h>
 
mode_t
umask(mode_t newmask)
{
static mode_t the_mask = 022;
mode_t old_mask = the_mask;
the_mask = newmask;
return old_mask;
}
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/xstat.c
0,0 → 1,262
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/*
* This is file XSTAT.C
*
* Internal assist functions which are common to stat() and fstat().
*
*
* Copyright (c) 1994-96 Eli Zaretskii <eliz@is.elta.co.il>
*
* This software may be used freely as long as the above copyright
* notice is left intact. There is no warranty on this software.
*
*/
 
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <limits.h>
#include <time.h>
#include <errno.h>
#include <dos.h>
#include <libc/farptrgs.h>
#include <libc/dosio.h>
#include <libc/bss.h>
 
#include "xstat.h"
 
static int xstat_count = -1;
 
/* Some fields of struct stat are expensive to compute under DOS,
because they require multiple disk accesses. Fortunately, many
DOS programs don't care about these. To leave both pedants (like
me) and performance-oriented guys happy, a variable is provided
which controls which expensive fields should be computed. To get
the fastest stat() for your program, clear the bits for only those
features you need and set the others.
 
This improvement was suggested by Charles Sandmann
<sandmann@clio.rice.edu> and DJ Delorie <dj@delorie.com>. */
 
#define _STAT_INODE 1 /* should we bother getting inode numbers? */
#define _STAT_EXEC_EXT 2 /* get execute bits from file extension? */
#define _STAT_EXEC_MAGIC 4 /* get execute bits from magic signature? */
#define _STAT_DIRSIZE 8 /* compute directory size? */
#define _STAT_ROOT_TIME 0x10 /* try to get root dir time stamp? */
#define _STAT_WRITEBIT 0x20 /* fstat() needs write bit? */
 
/* Should we bother about executables at all? */
#define _STAT_EXECBIT (_STAT_EXEC_EXT | _STAT_EXEC_MAGIC)
 
/* By default, all the bits are reset (including as yet unused ones), so
people who don't care will transparently have the full version. */
unsigned short _djstat_flags;
 
/* As we depend on undocumented DOS features, we could fail in some
incompatible environment or future DOS versions. If we do, the
following variable will have some of its bits set. Each bit
describes a single feature which we tried to use and failed.
The function _djstat_describe_lossage() may be called to print a
human-readable description of the bits which were set by the last
call to f?stat(). This should make debugging f?stat() failures
in an unanticipated environment a lot easier.
 
This improvement was suggested by Charles Sandmann
<sandmann@clio.rice.edu>. */
 
unsigned short _djstat_fail_bits;
 
/* ----------------------------------------------------------------------- */
 
/* Convert file date and time to time_t value suitable for
struct stat fields. */
 
time_t
_file_time_stamp(unsigned int dos_ftime)
{
struct tm file_tm;
 
memset(&file_tm, 0, sizeof(struct tm));
file_tm.tm_isdst = -1; /* let mktime() determine if DST is in effect */
 
file_tm.tm_sec = (dos_ftime & 0x1f) * 2;
file_tm.tm_min = (dos_ftime >> 5) & 0x3f;
file_tm.tm_hour = (dos_ftime >> 11) & 0x1f;
file_tm.tm_mday = (dos_ftime >> 16) & 0x1f;
file_tm.tm_mon = ((dos_ftime >> 21) & 0x0f) - 1; /* 0 = January */
file_tm.tm_year = (dos_ftime >> 25) + 80;
 
return mktime(&file_tm);
}
 
/* Get time stamp of a DOS file packed as a 32-bit int.
* This does what Borland's getftime() does, except it doesn't
* pollute the application namespace and returns an int instead
* of struct ftime with packed bit-fields.
*/
 
 
int
_getftime(int fhandle, unsigned int *dos_ftime)
{
return -1;
}
 
/* Invent an inode number for those files which don't have valid DOS
* cluster number. These could be: devices like /dev/nul; empty
* files which were not allocated disk space yet; or files on
* networked drives, for which the redirector doesn't bring the
* cluster number.
*
* To ensure proper operation of this function, you must call it
* with a filename in some canonical form. E.g., with a name
* returned by truename(), or that returned by _fixpath(). The
* point here is that the entire program MUST abide by these
* conventions through its operation, or else you risk getting
* different inode numbers for the same file.
*
* This function is due to Eric Backus and was taken with minor
* modifications from stat.c, as included in DJGPP 1.11m5.
* The function now returns 0 instead of -1 if it can't allocate
* memory for a new name, so that f?stat() won't fail if the inode
* is unavailable, but return zero inode instead.
*/
 
/*
(c) Copyright 1992 Eric Backus
 
This software may be used freely so long as this copyright notice is
left intact. There is no warranty on this software.
*/
 
struct name_list
{
struct name_list *next;
char *name;
unsigned mtime;
unsigned long size;
long inode;
};
 
ino_t
_invent_inode(const char *name, unsigned time_stamp, unsigned long fsize)
{
static struct name_list *name_list[256];
 
/* If the st_inode is wider than a short int, we will count up
* from USHRT_MAX+1 and thus ensure there will be no clashes with
* actual cluster numbers.
* Otherwise, we must count downward from USHRT_MAX, which could
* yield two files with identical inode numbers: one from actual
* DOS cluster number, and another from this function. In the
* latter case, we still have at least 80 inode numbers before
* we step into potentially used numbers, because some FAT entries
* are reserved to mean EOF, unused entry and other special codes,
* and the FAT itself uses up some clusters which aren't counted.
*/
static int dir = (sizeof(ino_t) > 2 ? 1 : -1);
 
/* INODE_COUNT is declared LONG and not ino_t, because some DOS-based
* compilers use short or unsigned short for ino_t.
*/
static long inode_count = (sizeof(ino_t) > 2
? (long)USHRT_MAX + 1L
: USHRT_MAX);
 
struct name_list *name_ptr, *prev_ptr;
const char *p;
int hash;
 
/* Force initialization in restarted programs (emacs). */
if (xstat_count != __bss_count)
{
xstat_count = __bss_count;
inode_count = (sizeof(ino_t) > 2 ? (long)USHRT_MAX + 1L : USHRT_MAX);
memset (name_list, 0, sizeof name_list);
}
 
if (!name)
return 0;
 
/* Skip over device and leading slash. This will allow for less
* inode numbers to be used, because there is nothing bad in generating
* identical inode for two files which belong to different drives.
*/
if (*name && name[1] == ':' && (name[2] == '\\' || name[2] == '/'))
{
/* If this is a root directory, return inode = 1. This is compatible
with the code on stat.c which deals with root directories. */
if (name[3] == 0)
return (ino_t)1;
 
name += 3;
}
 
/* If the passed name is empty, invent a new inode unconditionally.
* This is for those unfortunate circumstances where we couldn't
* get a name (e.g., fstat() under Novell). For these we want at
* least to ensure that no two calls will get the same inode number.
* The lossage here is that you get different inodes even if you call
* twice with the same file. Sigh...
*/
if (!*name)
{
ino_t retval = inode_count;
 
inode_count += dir;
return retval;
}
 
/* We could probably use a better hash than this */
p = name;
hash = 0;
while (*p != '\0')
hash += *p++;
hash &= 0xff;
 
/* Have we seen this string? */
name_ptr = name_list[hash];
prev_ptr = name_ptr;
while (name_ptr)
{
if (strcmp(name, name_ptr->name) == 0 &&
name_ptr->mtime == time_stamp &&
name_ptr->size == fsize)
break;
prev_ptr = name_ptr;
name_ptr = name_ptr->next;
}
 
if (name_ptr)
/* Same string, time stamp, and size, so same inode */
return name_ptr->inode;
else
{
ino_t retval;
/* New string with same hash code */
name_ptr = (struct name_list *)malloc(sizeof *name_ptr);
if (name_ptr == 0)
return 0;
name_ptr->next = (struct name_list *)0;
name_ptr->name = (char *)malloc(strlen(name)+1);
if (name_ptr->name == 0)
{
free(name_ptr);
return 0;
}
strcpy(name_ptr->name, name);
name_ptr->mtime = time_stamp;
name_ptr->size = fsize;
name_ptr->inode = inode_count;
if (prev_ptr)
prev_ptr->next = name_ptr;
else
name_list[hash] = name_ptr;
retval = inode_count;
inode_count += dir; /* increment or decrement as appropriate */
 
return retval;
}
}
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/xstat.h
0,0 → 1,72
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/*
* Header for internal stat()/fstat() assist functions.
*
*/
 
#ifndef __XSTAT_H
#define __XSTAT_H
 
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
 
/* Some errno.h headers do not define EFAULT. Here the value is
taken from POSIX IEEE 1003.1. */
#include <errno.h>
#ifndef EFAULT
#define EFAULT 14
#endif
 
/* Under MS-DOS, file access permissions are shared by all, except for
Write permission. */
#define READ_ACCESS (S_IRUSR | S_IRGRP | S_IROTH)
#define WRITE_ACCESS S_IWUSR
#define EXEC_ACCESS (S_IXUSR | S_IXGRP | S_IXOTH)
 
/* Macro to convert a segment and an offset to a "far offset" suitable
for _farxxx() functions of DJGPP. */
#ifndef MK_FOFF
#define MK_FOFF(s,o) ((int)((((unsigned long)(s)) << 4) + (unsigned short)(o)))
#endif
 
/* Ralph Brown's Interrupt List says this should be the length
of the buffer for INT 21H AX=6000H. */
#define MAX_TRUE_NAME 128
 
extern unsigned short _osmajor, _osminor;
extern const char * _os_flavor;
 
/* Bits to flag f?stat() failed to use individual undocumented features. */
#define _STFAIL_SDA 1 /* Get SDA call failed */
#define _STFAIL_OSVER 2 /* Unsupported DOS version */
#define _STFAIL_BADSDA 4 /* Bad pointer to SDA */
#define _STFAIL_TRUENAME 8 /* _truename() failed */
#define _STFAIL_HASH 0x10 /* inode defaults to hashing */
#define _STFAIL_LABEL 0x20 /* Root dir, but no volume label */
#define _STFAIL_DCOUNT 0x40 /* dirent_count ridiculously large */
#define _STFAIL_WRITEBIT 0x80 /* fstat() failed to get write access bit */
#define _STFAIL_DEVNO 0x100 /* fstat() failed to get device number */
#define _STFAIL_BADSFT 0x200 /* SFT entry found, but can't be trusted */
#define _STFAIL_SFTIDX 0x400 /* bad SFT index in JFT */
#define _STFAIL_SFTNF 0x800 /* file entry not found in SFT array */
 
extern unsigned short _djstat_fail_bits;
 
extern unsigned short _djstat_flags;
 
extern time_t _file_time_stamp(unsigned int);
extern ino_t _invent_inode(const char *, unsigned, unsigned long);
extern unsigned short _get_magic(const char *, int);
extern unsigned short _get_dos_version(int);
extern char * _truename(const char *, char *);
extern int _is_remote_drive(int);
extern int _is_executable(const char *, int, const char *);
extern short _get_dev_info(int);
extern long __filelength(int);
extern int _is_remote_handle(int);
extern void _djstat_describe_lossage(FILE *);
extern int _getftime(int, unsigned int *);
 
#endif /* __XSTAT_H */