|
|
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: 6353 (0x18d1)
Types: TextFile
Notes: UNIX file
Names: »mount.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/mount.c«
/*
* Mount a filesystem
*/
char helpmessage[] = "\
\
mount -- mount file system\n\
Usage: /etc/mount [ special directory [-fru] ]\n\
Options:\n\
-r Mount is read only\n\
-u No mount, just update '/etc/mnttab' and/or '/etc/mtab'\n\
The file system residing on the block special file 'special' becomes\n\
accessible through the pathname 'directory'.\n\
With no arguments, lists the currently mount file systems.\n\
If /etc/mtab appears out of date, due to reboot, the fact is noted.\n\
If /etc/mnttab is present, then the dates of mounting will be reported.\n\
\
";
#include <stdio.h>
#include <mtab.h>
#include <mnttab.h>
#include <mount.h>
#include <errno.h>
#include <filsys.h>
#include <canon.h>
#include <stat.h>
#include <timeb.h>
int uflag; /* Update mount table only */
int rflag; /* Read-only mount */
int qmtab; /* Mtab is out of date */
char mtabf[] = "/etc/mtab";
char mnttabf[] = "/etc/mnttab"; /* System 5 style */
struct mtab mtab;
struct mnttab mnttab;
struct stat sbuf;
char mspec[MNAMSIZ];
extern FILE *getmtab();
extern FILE *getmnttab();
char *ctime();
main(argc, argv)
char *argv[];
{
if (argc == 1)
mlist();
else {
if (argc==4 && *argv[3]=='-') {
getflags(argv[3]+1);
argc -= 1;
}
if (argc==3) {
domount(argv[1], argv[2], rflag);
} else
usage();
}
return (0);
}
getflags(ap)
register char *ap;
{
register int c;
while ((c = *ap++) != '\0')
switch (c) {
case 'r':
rflag = MFRON;
continue;
case 'u':
uflag++;
continue;
default:
usage();
}
}
usage()
{
fprintf(stderr, helpmessage);
exit(1);
}
merror(f)
char *f;
{
register int err;
err = errno;
fprintf(stderr, "mount: %r", &f);
if (err == EBUSY)
fprintf(stderr, ": mount device or directory busy\n");
else if (err > 0 && err < sys_nerr)
fprintf(stderr, ": %s\n", sys_errlist[err]);
else
fprintf(stderr, ": unrecognized error\n");
exit(1);
}
domount(special, name, flag)
char *special;
char *name;
int flag;
{
register FILE *fp;
register int openerr;
extern time_t time();
chkname(name);
if (!uflag) {
chkspec(special);
if (mount(special, name, flag) != 0)
merror("%s on %s", special, name);
}
if ((fp = getmnttab()) == NULL) {
openerr |= 1;
} else {
mcopy(special, mspec);
while (fread(&mnttab, sizeof(mnttab), 1, fp) == 1) {
if (mnttab.mt_dev[0] == '\0'
|| strncmp(mnttab.mt_filsys, mspec, MNTNSIZ) == 0) {
fseek(fp, (long)(-sizeof(mnttab)), 1);
break;
}
}
strncpy(mnttab.mt_dev, name, MNTNSIZ);
strncpy(mnttab.mt_filsys, mspec, MNTNSIZ);
mnttab.mt_ro_flg = flag;
mnttab.mt_time = time(NULL);
if (fwrite(&mnttab, sizeof(mnttab), 1, fp) != 1)
merror("writing %s", mnttabf);
fclose(fp);
}
if ((fp = getmtab()) == NULL) {
openerr |= 2;
} else {
mcopy(special, mspec);
while (fread(&mtab, sizeof(mtab), 1, fp) == 1) {
if (mtab.mt_name[0] == '\0'
|| strncmp(mtab.mt_special, mspec, MNAMSIZ) == 0) {
fseek(fp, (long)(-sizeof(mtab)), 1);
break;
}
}
strncpy(mtab.mt_name, name, MNAMSIZ);
strncpy(mtab.mt_special, mspec, MNAMSIZ);
mtab.mt_flags = flag;
if (fwrite(&mtab, sizeof(mtab), 1, fp) != 1)
merror("writing %s", mtabf);
fclose(fp);
}
if (openerr == 3 && uflag)
merror("could not open %s or %s", mnttabf, mtabf);
}
mlist()
{
register FILE *fp;
if ((fp = getmnttab()) != NULL) {
while (fread(&mnttab, sizeof(mnttab), 1, fp) == 1)
if (*mnttab.mt_dev != '\0') {
printf("/dev/%.*s on %.*s", MNTNSIZ,
mnttab.mt_filsys, MNTNSIZ, mnttab.mt_dev);
if (mnttab.mt_ro_flg & MFRON)
printf(" (read only)");
else
printf(" (writeable)");
printf(" since %s", ctime(&mnttab.mt_time));
}
return;
}
if ((fp = getmtab()) != NULL) {
if (qmtab)
fprintf(stderr,
"mount: /etc/mtab older than /etc/boottime\n");
while (fread(&mtab, sizeof(mtab), 1, fp) == 1)
if (*mtab.mt_name != '\0') {
printf("/dev/%.*s on %.*s", MNAMSIZ,
mtab.mt_special, MNAMSIZ, mtab.mt_name);
if (mtab.mt_flags & MFRON)
printf(" (read only)");
printf("\n");
}
}
}
FILE *
getmnttab()
{
return (fopen(mnttabf, "r+w"));
}
FILE *
getmtab()
{
time_t boottime;
if (stat("/etc/boottime", &sbuf) != 0)
boottime = (time_t)0;
else
boottime = sbuf.st_mtime;
if (stat(mtabf, &sbuf) != 0)
return (NULL);
if (sbuf.st_mtime < boottime)
qmtab = 1;
return (fopen(mtabf, "r+w"));
}
chkname(name)
char *name;
{
if (stat(name, &sbuf) < 0)
merror("%s", name);
if ((sbuf.st_mode&S_IFMT) != S_IFDIR) {
errno = ENOTDIR;
merror("%s", name);
}
}
chkspec(special)
char *special;
{
register FILE *fp;
struct filsys f;
if (stat(special, &sbuf) < 0)
merror("%s", special);
if ((sbuf.st_mode&S_IFMT) != S_IFBLK) {
errno = ENOTBLK;
merror("%s", special);
}
if ((fp = fopen(special, "r")) == NULL)
merror("opening %s", special);
fseek(fp, (long)SUPERI*BSIZE, 0);
if (fread(&f, sizeof(f), 1, fp) != 1)
merror("%s", special);
canf(&f);
if ( ! tstf(&f)) {
fprintf(stderr,
"mount: %s: badly formed file system\n", special);
exit(1);
}
}
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);
}
/*
* Copy special pathname (stripped of
* leading directories) into a fixed
* size buffer.
*/
mcopy(ms, buf)
char *ms, *buf;
{
register char *p1, *p2;
for (p1=p2=ms; *p1 != '\0'; )
if (*p1++ == '/')
p2 = p1;
p1 = buf;
while (*p1++ = *p2++)
;
}