|
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 - download
Length: 5579 (0x15cb) Types: TextFile Notes: UNIX file Names: »df.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/df.c«
/* * df: print out information regarding the * remaining space available on a file system. * This command also considers a directory * to represent the filesystem. */ #include <stdio.h> #include <filsys.h> #include <stat.h> #include <dir.h> #include <canon.h> #include <mnttab.h> #if 1 #include <mtab.h> #endif #define NMOUNT 64 /* Maximum mounted file systems */ int aflag; /* Print for each mounted fs */ int iflag; /* Print information on i-nodes */ int tflag; /* Print total device size */ char buf[BSIZE]; /* Basic file system reading buffer */ struct mnttab mtab[NMOUNT]; struct mnttab *emtabp; char *devname(); main(argc, argv) int argc; char *argv[]; { register char *ap; register int i; register int estat = 0; while (argc>1 && *argv[1]=='-') { for (ap = &argv[1][1]; *ap != '\0'; ap++) switch (*ap) { case 'a': aflag++; break; case 'i': iflag++; break; case 't': tflag++; break; default: usage(); } argc--; argv++; } minit(); sync(); if (argc < 2) { if (aflag) estat = dfmtab(); else estat = df("."); } else { for (i=1; i<argc; i++) estat |= df(argv[i]); if (aflag) estat |= dfmtab(); } exit(estat); } /* * Read the mount table, looking for file systems * to run df on. */ dfmtab() { register struct mnttab *mp; int estat; int name[MNAMSIZ+10]; estat = 0; for (mp = mtab; mp < emtabp; mp++) { if (mp->mt_dev[0]=='\0' || mp->mt_filsys[0]=='\0') continue; sprintf(name, "/dev/%s", mp->mt_filsys); estat |= df(name); } return (estat); } /* * Look at the file system * and find out free space. */ df(fs) register char *fs; { register struct filsys *sbp; struct stat sb; int fd; long total; long free; if (stat(fs, &sb) < 0) { cmsg("cannot stat '%s'", fs); return (1); } switch (sb.st_mode & S_IFMT) { case S_IFDIR: { char *nfs; if ((nfs = devname(sb.st_dev)) == NULL) { cmsg("no file system device found for directory '%s'", fs); return (1); } fs = nfs; break; } case S_IFBLK: case S_IFCHR: break; default: cmsg("unknown file type '%s'", fs); return (1); } if ((fd = open(fs, 0)) < 0) { cmsg("cannot open '%s'", fs); return (1); } lseek(fd, (long)BSIZE * SUPERI, 0); if (read(fd, buf, sizeof(struct filsys)) != sizeof(struct filsys)) { cmsg("read error on '%s'", fs); close(fd); return (1); } close(fd); sbp = &buf[0]; canf(sbp); if (tstf(sbp) == 0) { cmsg("badly formed super block on '%s'", fs); return (1); } printf("%-11s", fs); free = sbp->s_tfree; total = sbp->s_fsize - sbp->s_isize; report(free, total); if (iflag) { printf(", "); total = (sbp->s_isize-INODEI)*INOPB; free = sbp->s_tinode; report(free, total); } if (tflag) printf(", %U", sbp->s_fsize); printf("\n"); return (0); } report(free, total) long free; long total; { long percent; printf("%6U/%6U = ", free, total); percent = (free * 1000L) / total; printf("%2D.%1D%%", percent/10L, percent%10L); } /* * Initialise mount table * in memory. */ minit() { register int fd; register int n; emtabp = &mtab[0]; if ((fd = open("/etc/mnttab", 0)) >= 0) { if ((n = read(fd, (char *)&mtab[0], sizeof mtab)) > 0) emtabp = (char *)(&mtab[0]) + n; close(fd); return; } #if 1 if ((fd = open("/etc/mtab", 0)) >= 0) { register struct mtab *mp; while (read(fd, (char *)emtabp, sizeof(*mp)) == sizeof(*mp)) emtabp++; close(fd); } #endif } /* * Return the name of the block special file * (in directory '/dev') which corresponds to * the device given in argument. */ char * devname(dev) dev_t dev; { register struct direct *dp; register int n; int fd; static char name[25]; struct stat sb; if ((fd = open("/dev", 0)) < 0) return (NULL); while ((n = read(fd, buf, sizeof buf)) > 0) { for (dp = &buf[0]; dp < &buf[n]; dp++) { canino(dp->d_ino); if (dp->d_ino == 0) continue; strcpy(name, "/dev/"); strncat(name, dp->d_name, DIRSIZ); if (stat(name, &sb) < 0) continue; if ((sb.st_mode & S_IFMT) != S_IFBLK) continue; if (sb.st_rdev != dev) continue; close(fd); return (name); } } close(fd); return (NULL); } /* * Canonicalize and check superblock for consistency. */ canf(fp) register struct filsys *fp; { register daddr_t *dp; register ino_t *ip; canshort(fp->s_isize); candaddr(fp->s_fsize); canshort(fp->s_nfree); for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1) candaddr(*dp); canshort(fp->s_ninode); for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1) canino(*ip); candaddr(fp->s_tfree); canino(fp->s_tinode); } tstf(fp) register struct filsys *fp; { register daddr_t *dp; register ino_t *ip; register ino_t maxinode; maxinode = (fp->s_isize - INODEI) * INOPB + 1; if (fp->s_isize >= fp->s_fsize) return (0); if (fp->s_tfree < fp->s_nfree || fp->s_tfree >= fp->s_fsize - fp->s_isize + 1) return (0); if (fp->s_tinode < fp->s_ninode || fp->s_tinode >= maxinode-1) return (0); for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1) if (*dp < fp->s_isize || *dp >= fp->s_fsize) return (0); for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1) if (*ip < 1 || *ip > maxinode) return (0); return (1); } /* * Errors and warnings. */ /* VARARGS */ cerr(arg) char *arg; { fprintf(stderr, "df: %r\n", &arg); exit(1); } /* VARARGS */ cmsg(arg) char *arg; { fprintf(stderr, "df: %r\n", &arg); } usage() { fprintf(stderr, "Usage: df [-ait] [directory ...] [filesystem ...]\n"); exit(1); }