Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
kcc-4/lib/usys/stat.c
There are 9 other files named stat.c in the archive. Click here to see a list.
/* [SRI-NIC]SS:<C.LIB.UIO>STAT.C.76, 24-Aug-86 12:23:30, Edit by IAN
xstat extended stat for T20
[SRI-NIC]SS:<C.LIB.UIO>STAT.C.42, 3-Jun-86 14:37:53, Edit by IAN
updated etc
<KCC.LIB>STAT.C.35, 29-Aug-85 11:23:49, Edit by WHP4
restructure slightly so fstat() uses fds, not jfns */
/*
** stat(name, buf)
** char *name;
** struct stat *buf;
**
** Greg Satz / Stanford University / 12-Sep-84
** TENEX additions by Ken Harrenstien, SRI 1-Jun-85
*/
#include "c-env.h"
#include "errno.h"
#include "sys/types.h"
#include "sys/file.h"
#include "sys/usysio.h"
#include "sys/usysig.h"
#include "sys/stat.h"
#if SYS_T20+SYS_10X
#include "jsys.h"
#include "sys/time.h" /* For tadl_to_utime() to convert file times */
extern void _rljfn();
extern int _gtjfn();
static int _stat(), _xstat();
static int t2u_pro(), _gdsts(), _gfust();
#endif
/*
* stat(name, buf)
*/
int stat(name, buf)
char *name;
struct stat *buf;
{
#if SYS_T20+SYS_10X
int jfn, i;
USYS_BEG();
if ((jfn = _gtjfn(name, O_RDONLY)) == 0)
USYS_RETERR(ENOENT);
i = _stat(jfn, buf);
_rljfn(jfn);
USYS_RET(i);
#else /* T20+10X */
#error stat() not supported for this system.
#endif /* Not T20+10X */
}
int xstat(name, buf)
char *name;
struct xstat *buf;
{
#if SYS_T20+SYS_10X
int jfn, i;
if ((jfn = _gtjfn(name, O_RDONLY)) == 0)
USYS_RETERR(ENOENT);
i = _xstat(jfn, buf);
_rljfn(jfn);
USYS_RET(i);
#else /* T20+10X */
#error xstat() not supported for this system.
#endif /* Not T20+10X */
}
int fstat(fd, buf)
int fd;
struct stat *buf;
{
int ufx;
USYS_BEG();
if (fd < 0 || fd >= OPEN_MAX || !(ufx = _uioufx[fd]))
USYS_RETERR(EBADF);
#if SYS_T20+SYS_10X
USYS_RETVOLATILE(_stat(_uioch[ufx], buf));
#else /* T20+10X */
#error fstat() not supported for this system.
#endif /* not T20+10X */
}
int xfstat(fd, buf)
int fd;
struct xstat *buf;
{
int ufx;
if (fd < 0 || fd >= OPEN_MAX || !(ufx = _uioufx[fd]))
USYS_RETERR(EBADF);
#if SYS_T20+SYS_10X
USYS_RETVOLATILE(_xstat(_uioch[ufx], buf));
#else
#error xfstat() not supported for this system.
#endif
}
/*
* _stat(jfn, buf) - worker routine for stat() and fstat()
* _xstat(jfn, xbuf) - do above plus device dependent stuff
*/
static int _stat(jfn, buf)
int jfn;
struct stat *buf;
{
#if SYS_T20+SYS_10X
int i, time, fdb[_FBLEN];
char name[FILEPART_SIZE];
unsigned protection;
if (jfn == _PRIIN) _get_pio(&jfn, 0); /* in case redirected */
else if (jfn == _PRIOU) _get_pio(0, &jfn);
_gt_all_fdb(jfn, fdb); /* get the whole FDB */
buf->st_dev = _dvtype(jfn);
buf->st_ino = fdb[_FBADR]; /* disk address */
buf->st_mode = 0;
protection = fdb[_FBCTL];
buf->st_mode |= ((protection & FB_DIR) ? S_IFDIR : S_IFREG);
protection = fdb[_FBPRT]; /* protection */
i = (protection & T20_OWNER_MASK) >> T20_OWNER_OFFSET;
buf->st_mode |= (t2u_pro(i) >> UNIX_OWNER_OFFSET);
i = (protection & T20_GROUP_MASK) >> T20_GROUP_OFFSET;
buf->st_mode |= (t2u_pro(i) >> UNIX_GROUP_OFFSET);
i = (protection & T20_WORLD_MASK) >> T20_WORLD_OFFSET;
buf->st_mode |= (t2u_pro(i) >> UNIX_WORLD_OFFSET);
buf->st_nlink = 1; /* can it be anything else? */
#if SYS_10X
i = fdb[_FBUSE];
buf->st_uid = ((unsigned) i >> 18); /* Get LH (directory #) */
#endif
#if SYS_T20
_gfust(jfn, _GFAUT, name);
buf->st_uid = _rcusr(name);
#endif
buf->st_gid = 0; /* for now */
buf->st_rdev = 0; /* no major/minor devices on tops */
buf->st_size = fdb[_FBSIZ];
buf->st_atime = tadl_to_utime(fdb[_FBREF]);
buf->st_mtime = fdb[_FBCRE];
time = fdb[_FBCRV];
if (buf->st_mtime < time)
buf->st_mtime = time;
time = fdb[_FBWRT];
if (buf->st_mtime < time)
buf->st_mtime = time;
buf->st_mtime = tadl_to_utime(buf->st_mtime);
buf->st_ctime = buf->st_mtime;
return 0; /* success */
#else /* T20+10X */
return -1; /* Not implemented elsewhere yet */
#endif /* Not T20+10X */
}
static int _xstat(jfn, buf)
int jfn;
struct xstat *buf;
{
#if SYS_T20+SYS_10X
int ablock[5];
if (jfn == _PRIIN) _get_pio(&jfn, 0); /* in case redirected */
else if (jfn == _PRIOU) _get_pio(0, &jfn);
if (_stat(jfn, &buf->st)) /* get primary stuff */
return -1; /* failed! */
switch (buf->st.st_dev) { /* device-dependant stuff */
case ST_DEV_DSK:
buf->xst_version = _gtfdb(jfn, _FBGEN) >> 18;
buf->xst_pagcnt = _gtfdb(jfn, _FBBYV) & RH; break;
case ST_DEV_TCP:
_gdsts(jfn, &buf->xst_state, &buf->xst_fhost, &buf->xst_fport);
}
return 0;
#else
return -1;
#endif
}
#if SYS_T20+SYS_10X
/*
* get primary JFNs for ourself
*/
int _get_pio(i, o)
int *i, *o;
{
int ac[5];
ac[1] = _FHSLF; /* "Self" process handle */
if (jsys(GPJFN, ac)) {
if (i) *i = ((unsigned) ac[2]) >> 18;
if (o) *o = ac[2] & RH;
return 1;
} else return 0;
}
/*
* Takes TOPS-20 protections right justified and returns Unix protections
* right justified.
*/
static int t2u_pro(prot)
unsigned prot;
{
int i = 0;
if (prot & FP_READ) i |= S_IREAD;
if (prot & FP_WRITE) i |= S_IWRITE;
if (prot & FP_EXECUTE) i |= S_IEXEC;
return i;
}
/*
* _GTFDB() - read (and return) a word from a file's fdb
* this routine is exported, don't make it static!
*/
int _gtfdb(jfn, word)
int jfn, word;
{
int temp, arg_block[5];
arg_block[1] = jfn;
arg_block[2] = (1 << 18) + word;
arg_block[3] = 3; /* put the value in AC3 */
return (jsys(GTFDB, arg_block)) ? arg_block[3] : 0;
}
static int _gt_all_fdb(jfn, block)
int jfn, *block;
{
int ablock[5];
ablock[1] = jfn;
ablock[2] = (_FBLEN << 18); /* all words, start at 0 (RH) */
ablock[3] = (int) block; /* put them here */
return jsys(GTFDB, ablock);
}
/*
* _gdsts(jfn, a, b, c) - get device status stuff.
* int jfn, *a, *b, *c;
*
* Stores the ACs returned by GDSTS%
*/
static int _gdsts(jfn, a, b, c)
int jfn, *a, *b, *c;
{
int ablock[5];
ablock[1] = jfn;
if (!jsys(GDSTS, ablock)) return 0;
if (a) *a = ablock[2];
if (b) *b = ablock[3];
if (c) *c = ablock[4];
return 1;
}
/*
* Get device characteristics
*/
int _dvtype(jfn)
int jfn;
{
unsigned ablock[5];
ablock[1] = jfn;
return (jsys(DVCHR, ablock)) ? ((ablock[2] >> DV_TYP_S) & DV_TYP_M) : -1;
}
/*
* Get file user
*/
static int _gfust(jfn, func, name)
int jfn, func;
char *name;
{
int ablock[5];
ablock[1] = (func << 18) | jfn;
ablock[2] = (-1 << 18) | (unsigned) name;
return jsys(GFUST, ablock);
}
/*
* Return username number for given user name
*/
int _rcusr(name)
char *name;
{
int ablock[5];
ablock[1] = RC_EMO;
ablock[2] = (int) (name - 1);
if (!jsys(RCUSR, ablock) || (ablock[1] & RC_NOM)) /* jsys error */
return -1;
return ablock[3];
}
#endif /* T20+10X */