home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #3
/
amigamamagazinepolishissue1998.iso
/
ppc
/
lha_ppc
/
src
/
stat.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-12-16
|
4KB
|
207 lines
/****** unix/stat *********************************************
*
* NAME
* stat -- get file status
*
* SYNOPSIS
* #include <sys/types.h>
* #include "stat.h"
*
* return = stat (filename, buf)
*
* int stat (const char *, struct stat *);
*
* FUNCTION
* stat() obtains information about the named file.
*
* The stat structure pointer to by "buf" is filled in. The
* following fields are used:
*
* u_short st_mode;
* short st_uid;
* short st_gid;
* long st_size;
* long st_mtime;
* long st_atime; same as st_mtime
* short st_nlink; always 1
* long st_blksize;
* long st_blocks;
*
* INPUTS
* filename full or relative pathname of file
* buf pointer to a stat structure
*
* RESULT
* On success, 0 is returned.
* On failure, -1 is returned, and errno is set.
*
* EXAMPLE
* struct stat buf;
*
* if (stat ("devs:foo", &buf) == -1)
* {
* printf ("Error: file not found\n");
* exit (1);
* }
*
* NOTES
* On Amiga files, st_uid and st_gid will be set to that
* of the local user.
*
* BUGS
*
* SEE ALSO
*
*
******************************************************************************
*
*/
#include <sys/types.h>
#include <exec/types.h>
#include <exec/exec.h>
#include <dos/dosextens.h>
#include <exec/memory.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <dos.h>
#include <ios1.h>
#include <string.h>
#include "lharc.h"
static int GetMyFib(BPTR lock, struct FileInfoBlock *inf);
static int lock_stat(BPTR l, struct stat *buf);
static void fill_in_buf(struct FileInfoBlock *fp, struct stat *buf);
extern int __io2errno(int);
static long blockSize;
int stat(const char *name, struct stat *buf)
{
BPTR l;
int success;
Chk_Abort();
if ((l = Lock(name, ACCESS_READ)) == 0)
{
errno = __io2errno(IoErr());
return -1;
}
success = lock_stat(l, buf);
UnLock(l);
return success;
}
static void fill_in_buf(struct FileInfoBlock *fp, struct stat *buf)
{
long
mode = 0;
long
prot = fp->fib_Protection;
bzero(buf, sizeof(struct stat));
buf->st_mtime = fp->fib_Date.ds_Days * ((24 * 60) * 60) +
fp->fib_Date.ds_Minute * 60 +
fp->fib_Date.ds_Tick / TICKS_PER_SECOND;
buf->st_atime = buf->st_mtime;
buf->st_size = fp->fib_Size;
buf->st_blksize = blockSize;
buf->st_blocks = fp->fib_NumBlocks;
buf->st_uid = fp->fib_OwnerUID;
buf->st_gid = fp->fib_OwnerGID;
if (!(prot & FIBF_READ))
mode |= 0400;
if ((prot & FIBF_GRP_READ))
mode |= 0040;
if ((prot & FIBF_OTR_READ))
mode |= 0004;
if (!(prot & FIBF_WRITE))
mode |= 0200;
if ((prot & FIBF_GRP_WRITE))
mode |= 0020;
if ((prot & FIBF_OTR_WRITE))
mode |= 0002;
if (!(prot & FIBF_EXECUTE))
mode |= 0100;
if ((prot & FIBF_GRP_EXECUTE))
mode |= 0010;
if ((prot & FIBF_OTR_EXECUTE))
mode |= 0001;
if (fp->fib_DirEntryType > 0)
mode |= S_IFDIR;
else
mode |= S_IFREG;
buf->st_mode = mode;
buf->st_nlink = 1; /* Hard coded */
}
static int lock_stat(BPTR l, struct stat *buf)
{
struct FileInfoBlock *fp;
fp = (struct FileInfoBlock *) AllocVec(sizeof(struct FileInfoBlock), MEMF_CLEAR);
if (fp == NULL)
{
errno = ENOMEM;
return -1;
}
if (GetMyFib(l, fp) == 0)
{
FreeVec(fp);
return -1;
}
fill_in_buf(fp, buf);
FreeVec(fp);
return 0;
}
static int GetMyFib(BPTR lock, struct FileInfoBlock *inf)
{
struct MsgPort *dev;
LONG result;
struct InfoData id;
if (lock != 0)
{
dev = btod(lock, struct FileLock *)->fl_Task;
}
else
{
dev = (struct MsgPort *) (((struct Process *) FindTask(0))->pr_FileSystemTask);
}
result = DoPkt(dev, ACTION_EXAMINE_OBJECT, lock, dtob(inf), 0, 0, 0);
if (!result)
{
errno = __io2errno(IoErr());
return 0;
}
memset(&id, 0, sizeof(struct InfoData));
result = DoPkt(dev, ACTION_INFO, lock, dtob(&id), NULL, NULL, NULL);
if (result)
blockSize = id.id_BytesPerBlock;
else
blockSize = 512; /* assume */
return 1;
}