home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
LIB
/
stat.lzh
/
STAT
/
stat.c
< prev
next >
Wrap
Text File
|
1991-08-29
|
5KB
|
220 lines
/*
Unix-like stat and fstat functions for OS/9 (version 2.2)
by Richard W.M. Jones
free software
August 1991
*/
#include <stdio.h>
#include <modes.h>
#include <dir.h>
#include <direct.h>
#include <time.h>
#include <strings.h>
#include <module.h>
#include "stat.h"
/*----- stat function -----*/
int
stat(pathname,buf)
register char *pathname;
register struct stat *buf;
{
register int fd,r;
fd=open(pathname,S_IREAD);
if(fd<0)
{
fd=open(pathname,S_IFDIR|S_IREAD); /* open as a directory */
if(fd<0) /* not a directory */
return(-1);
}
r=fstat(fd,buf);
close(fd);
return(r);
}
/*----- fstat function -----*/
int
fstat(path,buf)
register int path;
register struct stat *buf;
{
struct fildes fildes_buf;
struct tm tp;
register int mode,isdev=0,gfd=0,modaccess,modowner;
register mod_dev *mod;
char devn[32], fmgrn[32];
/* clear the stat buffer to default values, so programs that don't detect
stat errors will not die */
buf->st_dev=buf->st_ino=buf->st_mode=buf->st_nlink=buf->st_uid=
buf->st_gid=buf->st_size=0;
buf->st_atime=buf->st_ctime=buf->st_mtime=-1;
/* first, get the associated device name */
if(_gs_devn(path,devn)<0)
return(-1); /* no device name??? */
/* look for recognisable device names */
if(!strcmp(devn,"pipe"))
{
mode=S_IFIFO; /* it's a pipe */
gfd=1;
} else
if(!strcmp(devn,"socket"))
{
mode=S_IFSOCK; /* it's a socket */
isdev=1;
}
/* now find out more from the module header of the device descriptor */
mod=(mod_dev *)modlink(devn,0);
if(mod==(mod_dev *)-1)
return(-1); /* link failed */
/* copy the file manager name and access permissions out and unlink */
strcpy(fmgrn,(char *)mod+(int)(mod->_mfmgr));
strlwr(fmgrn); /* to lower case */
modaccess=mod->_mh._maccess; /* get the module permissions */
modowner=mod->_mh._mowner; /* get the module owner */
munlink(mod); /* unlink from the module */
/* look for a recognisable file manager */
if(!isdev && !gfd) /* mode not determined already */
{
if(!strcmp(fmgrn,"scf") || !strcmp(fmgrn,"sbf") ||
!strcmp(fmgrn,"pkman"))
{
mode=S_IFCHR; /* character special */
isdev=1;
} else
if(!strcmp(fmgrn,"sockman"))
{
mode=S_IFSOCK; /* socket */
isdev=1;
} else
if(!strcmp(fmgrn,"rbf"))
{
isdev=1; gfd=1; /* could be block special,
regular file or directory */
} else
{
mode=0; /* unknown device */
isdev=1;
}
}
/* if it is a file with a file descriptor, then get the file descriptor */
if(gfd && !isdev) /* pipe */
if(_gs_gfd(path,&fildes_buf,sizeof(struct fildes))<0)
return(-1); /* stat failed */
if(gfd && isdev) /* regular file, block special or
directory */
{
if(_gs_gfd(path,&fildes_buf,sizeof(struct fildes))<0)
{
mode=S_IFBLK;
gfd=0; /* must be block special */
}
else
{
if(fildes_buf.fd_att & S_IFDIR)
mode=S_IFDIR; /* must be directory */
else
mode=S_IFREG; /* must be regular file */
isdev=0;
}
}
/* convert file descriptor to stat structure */
if(gfd)
{
/* create a suitable stat structure for a regular file */
buf->st_dev=0; /* no devices in OS/9 */
buf->st_ino=0; /* no inodes in OS/9 */
buf->st_uid=fildes_buf.fd_own[1]; /* get uid */
buf->st_gid=fildes_buf.fd_own[0]; /* get gid */
buf->st_size=*(long *)fildes_buf.fd_fsize; /* get filesize */
buf->st_nlink=fildes_buf.fd_link; /* link count */
buf->st_mode=mode | (fildes_buf.fd_att & 0x7F); /* OS/9 attributes */
buf->st_atime=time(NULL); /* last access time is now! */
/* convert dates from strange OS/9 format to reasonable unix format */
tp.tm_sec=0;
tp.tm_min=fildes_buf.fd_date[4];
tp.tm_hour=fildes_buf.fd_date[3];
tp.tm_mday=fildes_buf.fd_date[2];
tp.tm_mon=fildes_buf.fd_date[1]-1;
tp.tm_year=fildes_buf.fd_date[0];
tp.tm_wday=tp.tm_yday=tp.tm_isdst=-1;
buf->st_mtime=mktime(&tp); /* file modify time */
if(!(mode & S_IFIFO)) /* creation date meaningless on
OS/9 pipes (why? who knows) */
{
tp.tm_sec=tp.tm_min=tp.tm_hour=0;
tp.tm_mday=fildes_buf.fd_dcr[2];
tp.tm_mon=fildes_buf.fd_dcr[1]-1;
tp.tm_year=fildes_buf.fd_dcr[0];
tp.tm_wday=tp.tm_yday=tp.tm_isdst=-1;
buf->st_ctime=mktime(&tp); /* create (inode changed) time */
}
/* all done */
return(0);
}
/* if its a device, then fill in the stat buffer using data from the
module header */
if(isdev)
{
/* fields not applicable */
buf->st_dev=0; /* no device numbers */
buf->st_ino=0; /* no inodes */
buf->st_size=0; /* no size */
buf->st_mtime=buf->st_ctime=-1; /* these values aren't stored */
/* convert permissions/times in module header into a suitable format */
buf->st_mode=mode | conv_modperms(modaccess);
buf->st_atime=time(NULL); /* last access time is now */
buf->st_gid=modowner >> 8; /* gid */
buf->st_uid=modowner & 0xFF; /* uid */
/* successful stat */
return(0);
}
return(-1);
}
/*----- static functions -----*/
/* convert module permissions into stat permissions */
static int
conv_modperms(modperms)
register int modperms;
{
register int r;
r=modperms & MP_OWNER_MASK;
r |= ((modperms & MP_WORLD_MASK) >> 5);
return(r);
}
/* convert string to lower case */
static
strlwr(s)
char *s;
{
while(*s)
{
*s=tolower(*s);
++s;
}
}