pdp11v/usr/src/lib/libPW/curdir.c
static char Sccsid[]="@(#)curdir.c 3.4";
# define IROOT 2
# include "sys/types.h"
# include "macros.h"
#include <stdio.h>
#include "sys/param.h"
#include "mnttab.h"
#include "sys/dir.h"
#include "sys/filsys.h"
/*
current directory.
Places the full pathname of the current directory in `str'.
Handles file systems not mounted on a root directory
via /etc/mtab (see mtab(V)).
NOTE: PWB systems don't use mtab(V), but they don't mount
file systems anywhere but on a root directory (so far, at least).
returns 0 on success
< 0 on failure.
Current directory on return:
success: same as on entry
failure: UNKNOWN!
*/
static char *curdirp;
struct mtab {
char m_devstr[6];
char m_spcl[32];
char m_dir[32];
};
static char *flg[] = {
"read/write",
"read only"
};
static struct mnttab mtab[NMOUNT], *mp;
static struct filsys super;
curdir(str)
char *str;
{
register int n;
curdirp = str;
n = findir(0);
return(n+chdir(str));
}
# define ADDSLASH if (flag) *curdirp++ = '/';
# define QUIT { close(fd); return(-1); }
findir(flag)
{
register int fd,inum;
register char *tp;
char *slashp,tmp[100];
int dev, r;
struct direct entry;
struct stat s;
if (stat(".",&s)<0) return(-1);
if ((inum = s.st_ino) == IROOT) {
dev = s.st_dev;
if ((fd = open("/",0))<0) return(-1);
if (fstat(fd,&s)<0)
QUIT;
if (dev == s.st_dev) {
*curdirp++ = '/';
*curdirp = 0;
close(fd);
return(0);
}
slashp = entry.d_name;
slashp--;
while (read(fd,&entry,sizeof(entry)) == sizeof(entry)) {
if (entry.d_ino == 0) continue;
*slashp = '/';
if (stat(slashp,&s)<0) continue;
if (s.st_dev != dev) continue;
if ((s.st_mode&S_IFMT) != S_IFDIR) continue;
for (tp = slashp; *curdirp = (*tp++); curdirp++);
ADDSLASH;
*curdirp = 0;
close(fd);
return(0);
}
close(fd);
fd = open("/etc/mnttab",0);
if(fd < 0) {
fprintf(stderr, "curdir: cannot open /etc/mnttab!\n");
return(-1);
}
read(fd, mtab, sizeof mtab);
for(mp = mtab; mp < &mtab[NMOUNT]; mp++) {
if(mp->mt_dev[0]) {
sprintf(tmp,"/dev/%s",mp->mt_dev);
if ( stat(tmp,&s) < 0 )
QUIT;
if ( s.st_rdev != dev ) continue;
for ( tp = mp->mt_filsys; *curdirp = (*tp++); curdirp++ );
ADDSLASH;
close(fd);
/* test print
printf("%.10s on /dev/%s %s on %s",
mp->mt_filsys, mp->mt_dev,
flg[mp->mt_ro_flg], ctime(&mp->mt_time));
end test print */
return(0);
}
}
QUIT;
}
if ((fd = open("..",0))<0) return(-1);
for (entry.d_ino = 0; entry.d_ino != inum; )
if (read(fd,&entry,sizeof(entry)) != sizeof(entry))
QUIT;
close(fd);
if (chdir("..")<0) return(-1);
if (findir(-1)<0) r = -1;
else r = 0;
for (tp = entry.d_name; *curdirp = (*tp++); curdirp++);
ADDSLASH;
*curdirp = 0;
return(r);
}