|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 18498 (0x4842)
Types: TextFile
Notes: UNIX file
Names: »cplist.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »local/cplist.c«
/*
* Fragment a directory tree into smaller pieces.
* Output is to stdout and is in a format which can be passed to the
* shell for execution.
* Preserve the ownerships, modes, dates, links, and order of links
* within a directory.
* Make each fragment root based so that a series of
* mount /dev/fd0 /f0; cpdir /f0 destination; umount /dev/fd0
* can be used to reinstall the original directory.
*
* Ideally this should be a variation of cpdir, but cpdir
* does not maintain the in core directory structure necessary
* for the partitioning.
*
* As is the program is not distributable because it assumes it
* runs as root and that access is unlimited. Errors are ignored
* or fatal.
*
* The algorithm for partitioning is empirical and may not work very
* well for directories other than the pc coherent distribution.
* Some degree of interaction is probably desirable for getting
* reasonable partitioning of arbitrary directory trees.
*
* Overview of cpfrag (upon which cplist is based...):
* After minimal checks for necessary conditions,
* Read the source directory tree into a memory
* resident pseudo file system in which MINODE inumbers
* identify unique files and replace dp->d_ino in the
* directories.
* While the original root directory is not flagged I_DONE,
* copy those parts of the tree that are not flagged I_DONE.
* While the copy is too big for the floppy partition
* prune the copy.
* For each pruned copy produced, fdformat, mkfs, mount, write the
* copy, and umount.
* /bin/mkdir and /bin/cp are exec'ed to do some of the
* work.
*
* -- rec 26.VI.84 --
* -- norm 4.I.85 --
*/
#include <stdio.h>
#include <dir.h>
#include <assert.h>
#include <sys/const.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/filsys.h>
#include <sys/ino.h>
typedef struct MINODE {
struct MINODE *i_link1; /* dev x ino hash linkage */
struct MINODE *i_link2; /* my inumbering hash linkage */
char *i_linkname; /* Name of first instance of file in copy */
int i_mino; /* My inumber */
int i_flag; /* Miscellaneous flags */
int i_blks; /* Cumulative block size, includes indirects */
int i_inos; /* Cumulative inodes used */
int i_size; /* Total data, indir, and inode blocks */
int i_isdir; /* Simplify many tests */
dev_t i_dev; /* Some fields from stat() */
ino_t i_ino;
int i_mode;
int i_nlink;
int i_uid;
int i_gid;
unsigned i_rdev;
time_t i_mtime;
int i_nent; /* Number of directory entries */
struct direct i_elem[]; /* Directory entries */
} MINODE;
#define I_DONE 1 /* Inode is done */
#define I_COUNT 2 /* Inode is counted */
#define I_PUT 8 /* Inode size reported */
#define I_DONE1 16 /* Inode has been done once, for directories */
#define I_PURGE 32 /* Inode should be purged */
#define I_KEEP 64 /* Keep entire subdirectory */
#define I_CANFIT 128 /* Subdirectory could fit on disk */
#define I_ISMADE 256 /* Inode is made, do link */
#define NDISK 32
MINODE *disks[NDISK];
int dsize;
int dused;
int vflag = 1;
int excess;
int ndisk;
int myuid;
int mygid;
int nofflag = 0; /* Suppress fdformat */
int roundu = 1;
MINODE *makeroot();
MINODE *cpyroot();
MINODE *cpydir();
MINODE *select();
int purge();
int entermi();
MINODE *fetchmi();
long blkuse();
char *myalloc();
char *string();
extern char edata[];
#define MAXFNAME 512
char fname[MAXFNAME]; /* Filename buffer */
char fname1[MAXFNAME]; /* Second file name buffer */
char cmdbuf[128];
struct stat sbuf; /* Stat buffer */
main(argc, argv)
char *argv[];
{
int i;
MINODE *rip, *tip, *sip;
/* static char dname[] = "disk #XX"; */
if (argc < 3)
usage();
if (*argv[1] == '-') {
while (*++argv[1] != '\0')
switch (*argv[1]) {
case 'n':
nofflag = 1;
break;
case 'r':
roundu = 0;
break;
default:
usage();
}
argv[1] = argv[2];
argv[2] = argv[3];
}
dsize = atoi(argv[2]);
/* printf("dsize = %d blocks\n", dsize); */
myuid = getuid();
mygid = getgid();
if (myuid != 0) {
fprintf(stderr, "cplist: must be root\n");
exit(1);
}
umask(0);
rip = makeroot(argv[1]);
/* printf("root size = %d\n", rip->i_size); */
while ((rip->i_flag & I_DONE) == 0) {
/* sprintf(dname, "disk #%d", ndisk+1); */
tip = cpyroot(rip);
dused = 4;
keepers(tip);
/* printf("copy #%d size = %d\n", ndisk+1, tip->i_size); */
excess = tip->i_size + 2 - dsize;
while (excess > 0) {
/* printf("\nexcess = %d\n", excess); */
while ((sip = select(tip)) == NULL) {
/* printf("bump excess\n"); */
excess += 1;
}
/* printf("select size = %d\n", sip->i_size); */
flagroot(sip, I_PURGE);
purge(tip);
sizeroot(tip);
/* printf("purge size = %d\n", tip->i_size); */
excess = tip->i_size + 2 - dsize;
}
donedir(tip);
markdir(rip);
/* printf("%s done\n", dname); */
disks[ndisk] = tip;
ndisk += 1;
}
/* printf("Fragmented to %d disk%s:\n", ndisk, (ndisk>1 ? "s" : "")); */
for (i = 0; i < ndisk; i += 1) {
makedisk(i, argv[1]);
/* printf("%s:\n", dname); */
/* printroot(dname, disks[i]); */
}
/* printf("Original tree:\n"); */
/* printroot(argv[1], rip); */
}
MINODE *
makeroot(cp)
char *cp;
{
MINODE *rip;
if (strlen(cp) >= MAXFNAME) {
fprintf(stderr, "cplist: initial path name too long\n");
exit(1);
}
strcpy(fname, cp);
if (stat(fname, &sbuf) < 0)
cantstat();
if ((sbuf.st_mode&S_IFMT) != S_IFDIR) {
fprintf(stderr, "cplist: initial path not directory\n");
exit(1);
}
rip = fetchmi(entermi());
makedir(rip);
sizeroot(rip);
return (rip);
}
makedir(ip)
MINODE *ip;
{
int fd;
int i;
struct direct *dp1, *dp2;
MINODE *tip;
char *cp;
cp = fname + strlen(fname);
if (cp + DIRSIZ + 2 >= fname + MAXFNAME) {
fprintf(stderr, "cplist: directory tree too deep\n");
exit(1);
}
if ((fd = open(fname, 0)) < 0) {
fprintf(stderr, "cplist: cannot open: %s\n", fname);
exit(1);
}
i = ip->i_nent * sizeof(struct direct);
if (read(fd, ip->i_elem, i) != i) {
fprintf(stderr, "cplist: read error: %s\n", fname);
exit(1);
}
close(fd);
dp1 = dp2 = ip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
if (dp2->d_name[0] == '.') {
if (dp2->d_name[1] == 0
|| (dp2->d_name[1] == '.' && dp2->d_name[2] == 0))
dp2->d_ino = 0;
}
if (dp2->d_ino != 0) {
if (dp1 != dp2)
*dp1 = *dp2;
dp1 += 1;
}
dp2 += 1;
}
ip->i_nent = dp1 - ip->i_elem;
i = sizeof(MINODE) + ip->i_nent * sizeof(struct direct);
if (realloc(ip, i) != ip) {
fprintf(stderr, "cplist: realloc moved block\n");
exit(1);
}
dp1 = ip->i_elem;
*cp = '/';
for (i = 0; i < ip->i_nent; i += 1) {
strncpy(cp+1, dp1->d_name, DIRSIZ);
if (stat(fname, &sbuf) < 0)
cantstat();
tip = fetchmi(dp1->d_ino = entermi());
if (tip->i_isdir)
makedir(tip);
dp1 += 1;
}
*cp = 0;
}
printroot(cp, rip)
char *cp;
MINODE *rip;
{
uflagroot(rip, I_PUT);
strcpy(fname, cp);
splat(rip);
if (cp[0] == '/' && cp[1] == 0)
fname[0] = 0;
printdir(rip);
}
printdir(ip)
MINODE *ip;
{
int i;
MINODE *tip;
struct direct *dp;
char *cp;
dp = ip->i_elem;
cp = fname + strlen(fname);
*cp = '/';
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
strncpy(cp+1, dp->d_name, DIRSIZ);
splat(tip);
if (tip->i_isdir)
printdir(tip);
dp += 1;
}
*cp = 0;
}
splat(ip)
MINODE *ip;
{
printf("(%2d,%2d,%4d) ",
major(ip->i_dev), minor(ip->i_dev), ip->i_ino);
if ((ip->i_flag & I_PUT) != 0)
printf("%6d %4d %6d ", 0, 0, 0);
else
printf("%6d %4d %6d ", ip->i_size, ip->i_inos, ip->i_blks);
printf("%s\n", fname);
ip->i_flag |= I_PUT;
}
makedisk(n, cp)
char *cp;
{
MINODE *ip;
ip = disks[n];
fprintf(stderr, "disk %d, %d inodes, %d data blocks\n",
n+1, ip->i_inos, ip->i_blks);
again:
printf("echo -n insert disk number %d, hit return\n", n+1);
printf("read x\n");
mkfs(ip->i_inos);
if (vflag)
printf("/etc/mount /dev/fd0 /f0\n");
if (cp[0] == '/' && cp[1] == 0)
fname[0] = 0;
else
strcpy(fname, cp);
strcpy(fname1, "/f0");
insdir(ip);
printf("/etc/umount /dev/fd0\n");
printf("sync\ncheck /dev/fd0\ndf -it /dev/fd0\n");
}
fdformat()
{
#if Z8001
return(1);
#endif
sprintf(cmdbuf, "/etc/fdformat -v /dev/rfd0\n");
if (vflag)
printf("%s", cmdbuf);
return (system("/etc/fdformat -v /dev/rfd0\n"));
}
mkfs(nino)
{
sprintf(cmdbuf, "/etc/mkfs -i %d /dev/rfd0 %d\n", nino, dsize);
if (vflag)
printf("%s", cmdbuf);
}
insdir(ip)
MINODE *ip;
{
int i;
MINODE *tip;
struct direct *dp;
char *cp, *cp1;
time_t date[2];
char dtype;
cp = fname + strlen(fname);
cp1 = fname1 + strlen(fname1);
*cp = '/';
*cp1 = '/';
dp = ip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
strncpy(cp+1, dp->d_name, DIRSIZ);
strncpy(cp1+1, dp->d_name, DIRSIZ);
if (tip->i_flag & I_ISMADE) {
if (vflag)
printf("ln %s %s\n", tip->i_linkname, fname1);
dp += 1;
continue;
}
dtype = 'b';
switch (tip->i_mode & S_IFMT) {
case S_IFDIR:
mkdir(fname1);
break;
case S_IFCHR:
dtype += 1;
case S_IFBLK:
if (vflag)
printf("mknod %s %c %d %d\n", fname1, dtype,
major(tip->i_rdev), minor(tip->i_rdev));
break;
case S_IFREG:
copy(fname, fname1);
break;
default:
fprintf(stderr, "cplist: bad file type %d of %s\n",
tip->i_mode&S_IFMT, fname);
exit(1);
}
if (tip->i_uid != myuid || tip->i_gid != mygid) {
if (vflag) {
printf("chown %d %s\n", tip->i_uid, fname1);
printf("chgrp %d %s\n", tip->i_gid, fname1);
}
}
if (vflag)
printf("chmod %o %s\n", tip->i_mode&~S_IFMT, fname1);
if (tip->i_isdir)
insdir(tip);
else if (tip->i_nlink > 1)
tip->i_linkname = string(fname1);
tip->i_flag |= I_ISMADE;
time(&date[0]);
date[1] = tip->i_mtime;
utime(fname1, date);
dp += 1;
}
*cp = 0;
*cp1 = 0;
}
mkdir(cp)
char *cp;
{
int n;
int s;
if (vflag)
printf("mkdir %s\n", cp);
}
copy(cp1, cp2)
char *cp1, *cp2;
{
int n;
int s;
if (vflag)
printf("cp %s %s\n", cp1, cp2);
}
uflagroot(rip, flag)
MINODE *rip;
{
uflagdir(rip, flag);
rip->i_flag &= ~flag;
}
uflagdir(ip, flag)
MINODE *ip;
{
int i;
MINODE *tip;
struct direct *dp;
dp = ip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
tip->i_flag &= ~flag;
if (tip->i_isdir)
uflagdir(tip, flag);
dp += 1;
}
}
flagroot(ip, flag)
MINODE *ip;
{
if (ip->i_isdir)
flagdir(ip, flag);
ip->i_flag |= flag;
}
flagdir(ip, flag)
MINODE *ip;
{
int i;
MINODE *tip;
struct direct *dp;
dp = ip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
if (tip->i_isdir)
flagdir(tip, flag);
tip->i_flag |= flag;
dp += 1;
}
}
sizeroot(rip)
MINODE *rip;
{
uflagroot(rip, I_COUNT);
sizedir(rip);
}
sizedir(ip)
MINODE *ip;
{
int i;
MINODE *tip;
struct direct *dp;
ip->i_blks = 0;
ip->i_inos = 0;
dp = ip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
if (tip->i_isdir)
sizedir(tip);
if ((tip->i_flag&I_COUNT) == 0) {
ip->i_inos += tip->i_inos;
ip->i_blks += tip->i_blks;
tip->i_flag |= I_COUNT;
}
dp += 1;
}
ip->i_inos += 1; /* For me */
if (roundu)
ip->i_inos += (ip->i_inos % 8 == 0 ? 0 : 8 - (ip->i_inos %8));
ip->i_blks += blkuse((long)(ip->i_nent+2)*sizeof(struct direct));
ip->i_size = ip->i_blks + (ip->i_inos+INOPB-1) / INOPB;
}
MINODE *
cpyroot(rip)
MINODE *rip;
{
uflagdir(rip, I_PURGE|I_KEEP);
rip = cpydir(rip);
sizeroot(rip);
return (rip);
}
MINODE *
cpydir(ip)
MINODE *ip;
{
int i;
MINODE *nip, *tip;
struct direct *dp1, *dp2;
nip = fetchmi(duplmi(ip));
nip->i_nent = 0;
dp1 = ip->i_elem;
dp2 = nip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp1->d_ino);
if ((tip->i_flag&I_DONE) != 0)
tip = NULL;
else if (tip->i_isdir)
tip = cpydir(tip);
if (tip != NULL) {
dp2->d_ino = tip->i_mino;
strncpy(dp2->d_name, dp1->d_name, DIRSIZ);
nip->i_nent += 1;
dp2 += 1;
}
dp1 += 1;
}
if (nip->i_nent < ip->i_nent) {
i = sizeof(MINODE) + nip->i_nent * sizeof(struct direct);
if (realloc(nip, i) != nip) {
fprintf(stderr, "cplist: realloc moved block\n");
exit(1);
}
}
return (nip);
}
keepers(ip)
MINODE *ip;
{
int i;
MINODE *tip;
struct direct *dp;
dp = ip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
if (tip->i_isdir == 0) {
dp += 1;
continue;
}
if (tip->i_size < dsize - 4)
tip->i_flag |= I_CANFIT;
if (dused + tip->i_size < dsize) {
tip->i_flag |= I_KEEP;
dused += tip->i_size;
}
dp += 1;
}
dp = ip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
if (tip->i_isdir != 0
&& (tip->i_flag & (I_CANFIT|I_KEEP)) == 0)
keepers(tip);
dp += 1;
}
}
MINODE *
select(ip)
MINODE *ip;
{
int i;
MINODE *uip, *lip, *tip;
struct direct *dp;
uip = lip = NULL;
dp = ip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
if (tip->i_flag & I_KEEP) {
dp += 1;
continue;
}
if (tip->i_flag & I_CANFIT)
return (tip);
if (tip->i_size == excess)
return (tip);
else if (tip->i_size > excess) {
if (uip == NULL || uip->i_size > tip->i_size)
uip = tip;
} else {
if (lip == NULL || lip->i_size < tip->i_size)
lip = tip;
}
dp += 1;
}
if (lip != NULL)
return (lip);
if (uip->i_isdir)
return (select(uip));
return (uip);
}
purge(rip)
MINODE *rip;
{
int i;
MINODE *tip;
struct direct *dp1, *dp2;
assert(rip->i_isdir);
dp1 = dp2 = rip->i_elem;
for (i = 0; i < rip->i_nent; i += 1) {
tip = fetchmi(dp1->d_ino);
if (tip->i_isdir) {
purge(tip);
if ((tip->i_flag & I_PURGE) && tip->i_nent == 0) {
dp1->d_ino = 0;
freemi(tip->i_mino);
}
} else if (tip->i_flag & I_PURGE)
dp1->d_ino = 0;
if (dp1->d_ino != 0) {
if (dp1 != dp2)
*dp2 = *dp1;
dp2 += 1;
}
dp1 += 1;
}
rip->i_nent = dp2 - rip->i_elem;
}
donedir(ip)
MINODE *ip;
{
int i;
MINODE *tip;
struct direct *dp;
ip->i_link1->i_flag |= I_DONE1;
dp = ip->i_elem;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
if (tip->i_isdir)
donedir(tip);
else
tip->i_flag |= I_DONE|I_DONE1;
dp += 1;
}
}
markdir(ip)
MINODE *ip;
{
int i;
MINODE *tip;
struct direct *dp;
int flag;
if (ip->i_flag & I_DONE)
return (ip->i_flag);
dp = ip->i_elem;
flag = I_DONE;
for (i = 0; i < ip->i_nent; i += 1) {
tip = fetchmi(dp->d_ino);
if (tip->i_isdir)
markdir(tip);
flag &= tip->i_flag;
dp += 1;
}
if ((flag & I_DONE) != 0 && (ip->i_flag & I_DONE1) != 0)
ip->i_flag |= I_DONE;
}
#define IHASH 128
MINODE *ihash1[IHASH]; /* dev x ino hash */
MINODE *ihash2[IHASH]; /* mino hash */
int minumber = 1;
entermi()
{
MINODE *ip, **ipp;
int nent;
ipp = &ihash1[sbuf.st_ino % IHASH];
while ((ip = *ipp) != NULL) {
if (ip->i_ino == sbuf.st_ino
&& ip->i_dev == sbuf.st_dev)
return (ip->i_mino);
ipp = &ip->i_link1;
}
nent = 0;
if ((sbuf.st_mode&S_IFMT) == S_IFDIR)
nent = sbuf.st_size / sizeof(struct direct);
*ipp = ip = myalloc(sizeof(MINODE) + nent * sizeof(struct direct));
ip->i_dev = sbuf.st_dev;
ip->i_ino = sbuf.st_ino;
ip->i_mode = sbuf.st_mode;
ip->i_nlink = sbuf.st_nlink;
ip->i_uid = sbuf.st_uid;
ip->i_gid = sbuf.st_gid;
ip->i_rdev = sbuf.st_rdev;
ip->i_mtime = sbuf.st_mtime;
ip->i_blks = blkuse(sbuf.st_size);
ip->i_inos = 1;
ip->i_size = ip->i_blks;
ip->i_nent = nent;
ip->i_mino = minumber++;
ip->i_isdir = (nent != 0);
ipp = &ihash2[ip->i_mino % IHASH];
ip->i_link2 = *ipp;
*ipp = ip;
return (ip->i_mino);
}
duplmi(ip)
MINODE *ip;
{
MINODE *nip, **ipp;
nip = myalloc(sizeof(MINODE) + ip->i_nent * sizeof(struct direct));
nip->i_dev = ip->i_dev;
nip->i_ino = ip->i_ino;
nip->i_mode = ip->i_mode;
nip->i_nlink = ip->i_nlink;
nip->i_uid = ip->i_uid;
nip->i_gid = ip->i_gid;
nip->i_rdev = ip->i_rdev;
nip->i_blks = ip->i_blks;
nip->i_inos = ip->i_inos;
nip->i_size = ip->i_size;
nip->i_nent = ip->i_nent;
nip->i_mino = minumber++;
nip->i_isdir = ip->i_isdir;
ipp = &ihash2[nip->i_mino % IHASH];
nip->i_link2 = *ipp;
*ipp = nip;
nip->i_link1 = ip;
return (nip->i_mino);
}
MINODE *
fetchmi(mino)
{
MINODE *ip, **ipp;
ipp = &ihash2[mino % IHASH];
while ((ip = *ipp) != NULL)
if (ip->i_mino == mino)
return (ip);
else
ipp = &ip->i_link2;
fprintf(stderr, "cplist: nonexistent internal inumber %d\n", mino);
exit(1);
}
freemi(mino)
{
MINODE *ip, **ipp;
ipp = &ihash2[mino % IHASH];
while ((ip = *ipp) != NULL)
if (ip->i_mino == mino) {
*ipp = ip->i_link2;
free(ip);
return;
} else
ipp = &ip->i_link2;
fprintf(stderr, "cplist: nonexistent internal inumber %d\n", mino);
exit(1);
}
/*
* A corrected disk usage computation
* for retrofit into /usr/src/cmd/du.c, /usr/src/cmd/ls.c/prsize(),
* and /usr/src/cmd/quot.c since they are all wrong.
*
* And this is not quite right either since it doesn't deal with sparse
* blocks.
*/
long
blkuse(nb)
long nb;
{
#undef NBN
#define NBN 128L
#define nindir(x) (((x)+NBN-1)/NBN)
#define nblock(x) (((x)+BSIZE-1)/BSIZE)
#define min(x, y) ((x)<(y) ? (x) : (y))
long bu, ndir, nidir, niidir;
nb = nblock(nb);
ndir = min(nb, ND);
nb -= ndir;
bu = ndir;
if (nb) {
nidir = min(nb, NBN);
nb -= nidir;
bu += nidir + 1;
if (nb) {
niidir = min(nb, NBN*NBN);
nb -= niidir;
bu += niidir + 1 + nindir(niidir);
if (nb)
bu += nb + 1 + nindir(nindir(nb)) + nindir(nb);
}
}
return (bu);
}
char *
string(cp)
char *cp;
{
char *sp;
sp = myalloc(strlen(cp)+1);
strcpy(sp, cp);
return (sp);
}
char *
myalloc(nb)
int nb;
{
char *p;
if ((p = malloc(nb)) == NULL) {
fprintf(stderr, "cplist: out of space\n");
exit(1);
}
while (--nb >= 0)
p[nb] = 0;
return (p);
}
usage()
{
fprintf(stderr, "Usage: cpfrag [-nf] directory size_of_floppy\n");
exit(1);
}
cantstat()
{
fprintf(stderr, "cplist: cannot stat: %s\n", fname);
exit(1);
}
/*
pmino(ip)
MINODE *ip;
{
printf("ip = %x\n", ip);
printf("i_link1 == %x\n", ip->i_link1);
printf("i_link2 == %x\n", ip->i_link2);
printf("i_linkname == %s\n", ip->i_linkname);
printf("i_mino == %d\n", ip->i_mino);
printf("i_flag == %d\n", ip->i_flag);
printf("i_blks == %d\n", ip->i_blks);
printf("i_inos == %d\n", ip->i_inos);
printf("i_size == %d\n", ip->i_size);
printf("i_isdir == %d\n", ip->i_isdir);
printf("i_dev == %x\n", ip->i_dev);
printf("i_ino == %d\n", ip->i_ino);
printf("i_mode == %d\n", ip->i_mode);
printf("i_nlink == %d\n", ip->i_nlink);
printf("i_uid == %d\n", ip->i_uid);
printf("i_gid == %d\n", ip->i_gid);
printf("i_rdev == %d\n", ip->i_rdev);
printf("i_mtime == %D\n", ip->i_mtime);
}
*/