standalone: big clean up of ucp
authorAlan Cox <alan@linux.intel.com>
Fri, 2 Oct 2015 13:01:15 +0000 (14:01 +0100)
committerAlan Cox <alan@linux.intel.com>
Fri, 2 Oct 2015 13:01:15 +0000 (14:01 +0100)
Standalone/Makefile
Standalone/devio.c [deleted file]
Standalone/fuzix_fs.h
Standalone/ucp.c
Standalone/util.c
Standalone/xfs1.c [deleted file]
Standalone/xfs1a.c [deleted file]
Standalone/xfs1b.c [deleted file]
Standalone/xfs2.c [deleted file]

index d8ea331..2d4dfad 100644 (file)
@@ -1,7 +1,6 @@
 CC=gcc
-CCOPTS=-O2 -g -Wall -Wno-char-subscripts -Wno-deprecated-declarations
+CCOPTS=-O2 -g -Wall -pedantic -Wno-char-subscripts -Wno-deprecated-declarations
 TARGETS=mkfs fsck ucp chmem size
-UTILS=util.o devio.o xfs1.o xfs1a.o xfs1b.o xfs2.o
 
 all:   $(TARGETS)
 
@@ -15,7 +14,7 @@ fsck: fsck.o util.o
        $(CC) $(CCOPTS) -o $@ $< util.o
 
 ucp:   ucp.o $(UTILS)
-       $(CC) $(CCOPTS) -o $@ $< $(UTILS)
+       $(CC) $(CCOPTS) -o $@ $< util.o
 
 chmem: chmem.o
        $(CC) $(CCOPTS) -o $@ $<
diff --git a/Standalone/devio.c b/Standalone/devio.c
deleted file mode 100644 (file)
index 0aab459..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-#define DEVIO
-
-#include <string.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <strings.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "fuzix_fs.h"
-
-/* Buffer pool management */
-/*********************************************************************
-The high-level interface is through bread() and bfree().
-Bread() is given a device and block number, and a rewrite flag.  If
-rewrite is 0, the block is actually read if it is not already in the
-buffer pool. If rewrite is set, it is assumed that the caller plans to
-rewrite the entire contents of the block, and it will not be read in,
-but only have a buffer named after it.
-
-Bfree() is given a buffer pointer and a dirty flag.  If the dirty flag
-is 0, the buffer is made available for further use.  If the flag is 1,
-the buffer is marked "dirty", and it will eventually be written out to
-disk.  If the flag is 2, it will be immediately written out.
-
-Zerobuf() returns a buffer of zeroes not belonging to any device.  It
-must be bfree'd after use, and must not be dirty. It is used when a
-read() wants to read an unallocated block of a file.
-
-Bufsync() write outs all dirty blocks.
-
-Note that a pointer to a buffer structure is the same as a pointer to
-the data.  This is very important.
-**********************************************************************/
-
-uint16_t bufclock = 0;         /* Time-stamp counter for LRU */
-struct blkbuf bufpool[NBUFS];
-
-char *bread(int dev, blkno_t blk, int rewrite)
-{
-       register bufptr bp;
-
-/*printf("Reading block %d\n", blk);*/
-
-       bp = bfind(dev, blk);
-       if (bp) {
-               if (bp->bf_busy)
-                       panic("want busy block");
-               goto done;
-       }
-       bp = freebuf();
-       bp->bf_dev = dev;
-       bp->bf_blk = blk;
-
-       /* If rewrite is set, we are about to write over the entire block,
-          so we don't need the previous contents */
-
-       ifnot(rewrite)
-           if (bdread(bp) == -1) {
-               udata.u_error = EIO;
-               return 0;
-       }
-
-done:
-       bp->bf_busy = 1;
-       bp->bf_time = ++bufclock;       /* Time stamp it */
-       return (bp->bf_data);
-}
-
-
-void brelse(bufptr bp)
-{
-/*printf("Releasing block %d (0)\n", bp->bf_blk);*/
-       bfree(bp, 0);
-}
-
-void bawrite(bufptr bp)
-{
-/*printf("Releasing block %d (1)\n", bp->bf_blk);*/
-       bfree(bp, 1);
-}
-
-int bfree(bufptr bp, int dirty)
-{
-/*printf("Releasing block %d (%d)\n", bp->bf_blk, dirty);*/
-       bp->bf_dirty |= dirty;
-       bp->bf_busy = 0;
-
-       if (dirty == 2) {       /* Extra dirty */
-               if (bdwrite(bp) == -1)
-                       udata.u_error = EIO;
-               bp->bf_dirty = 0;
-               return (-1);
-       }
-       return (0);
-}
-
-
-/* This returns a busy block not belonging to any device, with
- * garbage contents.  It is essentially a malloc for the kernel.
- * Free it with brelse()!
- */
-char *tmpbuf()
-{
-       bufptr bp;
-       bufptr freebuf();
-
-/*printf("Allocating temp block\n");*/
-       bp = freebuf();
-       bp->bf_dev = -1;
-       bp->bf_busy = 1;
-       bp->bf_time = ++bufclock;       /* Time stamp it */
-       return (bp->bf_data);
-}
-
-
-char *zerobuf(void)
-{
-       char *b;
-       char *tmpbuf();
-
-       b = tmpbuf();
-       bzero(b, 512);
-       return (b);
-}
-
-
-void bufsync(void)
-{
-       register bufptr bp;
-
-       for (bp = bufpool; bp < bufpool + NBUFS; ++bp) {
-               if (bp->bf_dev != -1 && bp->bf_dirty) {
-                       bdwrite(bp);
-                       if (!bp->bf_busy)
-                               bp->bf_dirty = 0;
-               }
-       }
-}
-
-#ifndef ASM_BUFIO
-
-bufptr bfind(int dev, blkno_t blk)
-{
-       register bufptr bp;
-
-       for (bp = bufpool; bp < bufpool + NBUFS; ++bp) {
-               if (bp->bf_dev == dev && bp->bf_blk == blk)
-                       return (bp);
-       }
-       return (NULL);
-}
-
-
-bufptr freebuf(void)
-{
-       register bufptr bp;
-       register bufptr oldest;
-       register int oldtime;
-
-       /* Try to find a non-busy buffer and write out the data if it is dirty */
-       oldest = NULL;
-       oldtime = 0;
-       for (bp = bufpool; bp < bufpool + NBUFS; ++bp) {
-               if (bufclock - bp->bf_time >= oldtime && !bp->bf_busy) {
-                       oldest = bp;
-                       oldtime = bufclock - bp->bf_time;
-               }
-       }
-       ifnot(oldest)
-           panic("no free buffers");
-
-       if (oldest->bf_dirty) {
-               if (bdwrite(oldest) == -1)
-                       udata.u_error = EIO;
-               oldest->bf_dirty = 0;
-       }
-       return (oldest);
-}
-
-#endif
-
-
-void bufinit(void)
-{
-       register bufptr bp;
-
-       for (bp = bufpool; bp < bufpool + NBUFS; ++bp) {
-               bp->bf_dev = -1;
-       }
-}
-
-
-void bufdump(void)
-{
-       register bufptr j;
-
-       printf("\ndev\tblock\tdirty\tbusy\ttime clock %d\n", bufclock);
-       for (j = bufpool; j < bufpool + NBUFS; ++j)
-               printf("%d\t%u\t%d\t%d\t%u\n",
-                      j->bf_dev, j->bf_blk, j->bf_dirty, j->bf_busy,
-                      j->bf_time);
-}
-
-
-/*********************************************************************
-Bdread() and bdwrite() are the block device interface routines.  they
-are given a buffer pointer, which contains the device, block number,
-and data location.  They basically validate the device and vector the
-call.
-
-Cdread() and cdwrite are the same for character (or "raw") devices,
-and are handed a device number.  Udata.u_base, count, and offset have
-the rest of the data.
-**********************************************************************/
-
-int bdread(bufptr bp)
-{
-//    printf("bdread(fd=%d, block %d)\n", dev_fd, bp->bf_blk);
-
-       udata.u_buf = bp;
-       if (lseek
-           (dev_fd, dev_offset + (((int) bp->bf_blk) * 512),
-            SEEK_SET) == -1)
-               perror("lseek");
-       if (read(dev_fd, bp->bf_data, 512) != 512)
-               panic("read() failed");
-
-       return 0;
-}
-
-
-int bdwrite(bufptr bp)
-{
-       udata.u_buf = bp;
-
-       lseek(dev_fd, dev_offset + (((int) bp->bf_blk) * 512), SEEK_SET);
-       if (write(dev_fd, bp->bf_data, 512) != 512)
-               panic("write() failed");
-       return 0;
-}
index 79f54ee..321faef 100644 (file)
 extern int dev_fd;
 extern int dev_offset;
 int fd_open(char *name);
-int d_close(void);
-void xfs_init();
 void panic(char *s);
-void bufsync (void);
-char *zerobuf (void);
-int super(void);
 
 extern uint16_t swizzle16(uint32_t v);
 extern uint32_t swizzle32(uint32_t v);
@@ -147,6 +142,41 @@ typedef struct filesys {
     inoptr      s_mntpt;
 } filesys, *fsptr;
 
+#define EPERM           1               /* Not owner */
+#define ENOENT          2               /* No such file or directory */
+#define ESRCH           3               /* No such process */
+#define EINTR           4               /* Interrupted System Call */
+#define EIO             5               /* I/O Error */
+#define ENXIO           6               /* No such device or address */
+#define E2BIG           7               /* Arg list too long */
+#define ENOEXEC         8               /* Exec format error */
+#define EBADF           9               /* Bad file number */
+#define ECHILD          10              /* No children */
+#define EAGAIN          11              /* No more processes */
+#define ENOMEM          12              /* Not enough core */
+#define EACCES          13              /* Permission denied */
+#define EFAULT          14              /* Bad address */
+#define ENOTBLK         15              /* Block device required */
+#define EBUSY           16              /* Mount device busy */
+#define EEXIST          17              /* File exists */
+#define EXDEV           18              /* Cross-device link */
+#define ENODEV          19              /* No such device */
+#define ENOTDIR         20              /* Not a directory */
+#define EISDIR          21              /* Is a directory */
+#define EINVAL          22              /* Invalid argument */
+#define ENFILE          23              /* File table overflow */
+#define EMFILE          24              /* Too many open files */
+#define ENOTTY          25              /* Not a typewriter */
+#define ETXTBSY         26              /* Text file busy */
+#define EFBIG           27              /* File too large */
+#define ENOSPC          28              /* No space left on device */
+#define ESPIPE          29              /* Illegal seek */
+#define EROFS           30              /* Read-only file system */
+#define EMLINK          31              /* Too many links */
+#define EPIPE           32              /* Broken pipe */
+
+
+#ifdef UCP
 typedef struct u_data {
     struct p_tab *u_ptab;       /* Process table pointer */
     char        u_insys;        /* True if in kernel */
@@ -188,140 +218,86 @@ typedef struct u_data {
     uint32_t      u_cstime;
 } u_data;
 
-
-extern inoptr root;
-extern struct cinode i_tab[ITABSIZE];
-extern struct filesys fs_tab[1];
-extern struct blkbuf bufpool[NBUFS];
-extern struct u_data udata; /* MUST BE FIRST */
-#define PTABSIZE 20
-// extern struct p_tab ptab[PTABSIZE];
-
-#define EPERM           1               /* Not owner */
-#define ENOENT          2               /* No such file or directory */
-#define ESRCH           3               /* No such process */
-#define EINTR           4               /* Interrupted System Call */
-#define EIO             5               /* I/O Error */
-#define ENXIO           6               /* No such device or address */
-#define E2BIG           7               /* Arg list too long */
-#define ENOEXEC         8               /* Exec format error */
-#define EBADF           9               /* Bad file number */
-#define ECHILD          10              /* No children */
-#define EAGAIN          11              /* No more processes */
-#define ENOMEM          12              /* Not enough core */
-#define EACCES          13              /* Permission denied */
-#define EFAULT          14              /* Bad address */
-#define ENOTBLK         15              /* Block device required */
-#define EBUSY           16              /* Mount device busy */
-#define EEXIST          17              /* File exists */
-#define EXDEV           18              /* Cross-device link */
-#define ENODEV          19              /* No such device */
-#define ENOTDIR         20              /* Not a directory */
-#define EISDIR          21              /* Is a directory */
-#define EINVAL          22              /* Invalid argument */
-#define ENFILE          23              /* File table overflow */
-#define EMFILE          24              /* Too many open files */
-#define ENOTTY          25              /* Not a typewriter */
-#define ETXTBSY         26              /* Text file busy */
-#define EFBIG           27              /* File too large */
-#define ENOSPC          28              /* No space left on device */
-#define ESPIPE          29              /* Illegal seek */
-#define EROFS           30              /* Read-only file system */
-#define EMLINK          31              /* Too many links */
-#define EPIPE           32              /* Broken pipe */
-
 typedef struct oft {
     uint32_t     o_ptr;      /* File position point16_ter */
     inoptr    o_inode;    /* Pointer into in-core inode table */
     char      o_access;   /* O_RDONLY, O_WRONLY, or O_RDWR */
     char      o_refs;     /* Reference count: depends on # of active children*/
 } oft;
-
-// extern struct cinode i_tab[ITABSIZE];    /* In-core inode table */
-extern struct oft of_tab[OFTSIZE]; /* Open File Table */
-
-void brelse(bufptr bp);
-void bawrite(bufptr bp);
-int bfree(bufptr bp, int dirty);
-int bdwrite(bufptr bp);
-int bdread(bufptr bp);
-void bufinit(void);
-void bufdump(void);
-bufptr bfind(int dev, blkno_t blk);
-bufptr freebuf(void);
-int insq (struct s_queue *q, char c);
-int remq (struct s_queue *q, char *cp);
-int uninsq (struct s_queue *q, char *cp);
-int fullq (struct s_queue *q);
-void clrq (struct s_queue *q);
-char *bread(int dev, blkno_t blk, int rewrite);
-int fmount(int dev, inoptr ino);
-void i_ref(inoptr ino);
-void xfs_end(void);
-int doclose(int16_t uindex);
-int _open(char *name, int16_t flag);
-int _creat(char *name, int16_t mode);
-int _close(int16_t uindex);
-int _link( char *name1, char *name2);
-int _unlink(char *path);
-int _read( int16_t d, char *buf, uint16_t nbytes);
-int _write( int16_t d, char *buf, uint16_t nbytes);
-int _mknod( char *name, int16_t mode, int16_t dev);
-blkno_t bmap(inoptr ip, blkno_t bn, int rwflg);
-inoptr rwsetup( int rwflag, int d, char *buf, int nbytes);
-int psize(inoptr ino);
-void oft_deref(int of);
-void i_deref(inoptr ino);
-void f_trunc(inoptr ino);
-void setftime(inoptr ino, int flag);
-void wr_inode(inoptr ino);
-int _seek( int16_t file, uint16_t offset, int16_t flag);
-void readi( inoptr ino );
-void writei( inoptr ino);
-void addoff( uint32_t *ofptr, int amount);
-void updoff(int d);
-inoptr getinode(int uindex);
-inoptr n_open( register char *name, register inoptr *parent );
-inoptr srch_dir(inoptr wd, register char *compname);
-inoptr srch_mt( inoptr ino);
-inoptr i_open( register int dev, register unsigned ino);
-int ch_link( inoptr wd, char *oldname, char *newname, inoptr nindex);
-char * filename( char *path);
-int namecomp( char *n1, char *n2);
-inoptr newfile( inoptr pino, char *name);
-fsptr getdev( int devno);
-unsigned i_alloc(int devno);
-void i_free( int devno, unsigned ino);
-blkno_t blk_alloc( int devno );
-void blk_free( int devno, blkno_t blk);
-int oft_alloc(void);
-void _sync(void);
-int _chdir(char *dir);
-int min(int a, int b);
-int _access( char *path, int16_t mode);
-int _chmod( char *path, int16_t mode);
-int _chown( char *path, int owner, int group);
-int _stat( char *path, struct uzi_stat *buf);
-int _fstat( int16_t fd, struct uzi_stat *buf);
-void stcpy( inoptr ino, struct uzi_stat *buf);
-int _dup( int16_t oldd);
-int _dup2( int16_t oldd, int16_t newd);
-int _umask( int mask);
-int _getfsys(int dev,char * buf);
-int _ioctl( int fd, int request, char *data);
-int getperm(inoptr ino);
-int _mount( char *spec, char *dir, int rwflag);
-int _time( int tvec[]);
-int fuzix_getmode(inoptr ino);
-void bawrite(bufptr bp);
-int isdevice(inoptr ino);
-int bfree(bufptr bp, int dirty);
-void magic(inoptr ino);
-int baddev(fsptr dev);
-void validblk(int dev, blkno_t num);
-int uf_alloc(void);
-void i_ref( inoptr ino);
-void freeblk(int dev, blkno_t blk, int level);
-int valadr(char *base, uint16_t size);
-int _umount(char *spec);
-
+// static struct cinode i_tab[ITABSIZE];    /* In-core inode table */
+static struct oft of_tab[OFTSIZE]; /* Open File Table */
+
+static void xfs_init(int);
+
+static inoptr root;
+static struct cinode i_tab[ITABSIZE];
+static struct filesys fs_tab[1];
+static struct blkbuf bufpool[NBUFS];
+static struct u_data udata;
+static void bufsync (void);
+static char *zerobuf (void);
+static void brelse(bufptr bp);
+static void bawrite(bufptr bp);
+static int bfree(bufptr bp, int dirty);
+static int bdwrite(bufptr bp);
+static int bdread(bufptr bp);
+static void bufinit(void);
+static bufptr bfind(int dev, blkno_t blk);
+static bufptr freebuf(void);
+static void magic(inoptr ino);
+static char *bread(int dev, blkno_t blk, int rewrite);
+static int fmount(int dev, inoptr ino);
+static void i_ref(inoptr ino);
+static void xfs_end(void);
+static int doclose(int16_t uindex);
+static int fuzix_open(char *name, int16_t flag);
+static int fuzix_creat(char *name, int16_t mode);
+static int fuzix_close(int16_t uindex);
+static int fuzix_link( char *name1, char *name2);
+static int fuzix_unlink(char *path);
+static int fuzix_read( int16_t d, char *buf, uint16_t nbytes);
+static int fuzix_write( int16_t d, char *buf, uint16_t nbytes);
+static int fuzix_mknod( char *name, int16_t mode, int16_t dev);
+static blkno_t bmap(inoptr ip, blkno_t bn, int rwflg);
+static inoptr rwsetup( int rwflag, int d, char *buf, int nbytes);
+static void oft_deref(int of);
+static int uf_alloc(void);
+static void i_deref(inoptr ino);
+static void f_trunc(inoptr ino);
+static void freeblk(int dev, blkno_t blk, int level);
+static void setftime(inoptr ino, int flag);
+static void wr_inode(inoptr ino);
+static int isdevice(inoptr ino);
+static void readi( inoptr ino );
+static void writei( inoptr ino);
+static void updoff(int d);
+static void validblk(int dev, blkno_t num);
+static inoptr getinode(int uindex);
+static inoptr n_open( register char *name, register inoptr *parent );
+static inoptr srch_dir(inoptr wd, register char *compname);
+static inoptr srch_mt( inoptr ino);
+static inoptr i_open( register int dev, register unsigned ino);
+static int ch_link( inoptr wd, char *oldname, char *newname, inoptr nindex);
+static char * filename( char *path);
+static int namecomp( char *n1, char *n2);
+static inoptr newfile( inoptr pino, char *name);
+static fsptr getdev( int devno);
+static unsigned i_alloc(int devno);
+static void i_free( int devno, unsigned ino);
+static blkno_t blk_alloc( int devno );
+static void blk_free( int devno, blkno_t blk);
+static int oft_alloc(void);
+static void fuzix_sync(void);
+static int fuzix_chdir(char *dir);
+static int min(int a, int b);
+static int fuzix_chmod( char *path, int16_t mode);
+static int fuzix_stat( char *path, struct uzi_stat *buf);
+static void stcpy( inoptr ino, struct uzi_stat *buf);
+static int fuzix_getfsys(int dev,char * buf);
+static int fuzix_mount( char *spec, char *dir, int rwflag);
+static int fuzix_getmode(inoptr ino);
+static void bawrite(bufptr bp);
+static int bfree(bufptr bp, int dirty);
+static int fuzix_umount( char *spec);
+
+#endif
index 11c8585..8f28cfa 100644 (file)
@@ -13,39 +13,51 @@ HP
 #include <string.h>
 #include <stdint.h>
 #include <time.h>
+#include <unistd.h>
 #include <libgen.h>
+#define UCP
 #include "fuzix_fs.h"
 
-#define UCP_VERSION  "1.1ac"
+#define UCP_VERSION  "1.2ac"
 
-int16_t *syserror = (int16_t*)&udata.u_error;
+static int16_t *syserror = (int16_t*)&udata.u_error;
 static char cwd[100];
 static char line[128];
-char *nextline = NULL;
-char *month[] =
+static char *nextline = NULL;
+static char *month[] =
 { "Jan", "Feb", "Mar", "Apr",
     "May", "Jun", "Jul", "Aug",
     "Sep", "Oct", "Nov", "Dec" };
 
+#define DEVIO
+
+static uint16_t bufclock = 0;          /* Time-stamp counter for LRU */
+static struct blkbuf bufpool[NBUFS];
+
+static struct cinode i_tab[ITABSIZE];
+static struct filesys fs_tab[1];
+
 int swizzling = 0;
 
-int match(char *cmd);
-void usage(void);
-void prmode(int mode);
-int ls(char *path);
-int chmod(char *modes, char *path);
-int mknod( char *path, char *modes, char *devs);
-int mkdir(char *path);
-int get( char *src, char *dest, int binflag);
-int put( char *arg, int binflag);
-int type( char *arg);
-int fdump(char *arg);
-int unlink( char *path);
-int rmdir(char *path);
-
-int main(argc, argval)
-    int argc;
-    char *argval[];
+static inoptr root;
+static struct oft of_tab[OFTSIZE];
+
+
+static int match(char *cmd);
+static void usage(void);
+static void prmode(int mode);
+static int ls(char *path);
+static int chmod(char *modes, char *path);
+static int mknod( char *path, char *modes, char *devs);
+static int mkdir(char *path);
+static int get( char *src, char *dest, int binflag);
+static int put( char *arg, int binflag);
+static int type( char *arg);
+static int fdump(char *arg);
+static int fuzix_rm( char *path);
+static int fuzix_rmdir(char *path);
+
+int main(int argc, char *argval[])
 {
     int  rdev;
     char cmd[30], arg1[1024], arg2[30], arg3[30];
@@ -54,14 +66,7 @@ int main(argc, argval)
     int  pending_line = 0;
     struct filesys fsys;
     int  j, retc = 0;
-    /*--    char *argv[5];--*/
 
-    /*
-       if (argc < 2)
-       rdev = 0;
-       else
-       rdev = atoi(argval[1]);
-       */
     if (argc == 2) {
         fd_open(argval[1]);
         interactive = 1;
@@ -119,7 +124,7 @@ int main(argc, argval)
                 continue;
         }
 
-        _sync();
+        fuzix_sync();
 
         if (strcmp(cmd, "\n") == 0)
             continue;
@@ -138,7 +143,7 @@ int main(argc, argval)
             case 2:         /* cd */
                 if (*arg1) {
                     strcpy(cwd, arg1);
-                    if ((retc = _chdir(arg1)) != 0) {
+                    if ((retc = fuzix_chdir(arg1)) != 0) {
                         printf("cd: error number %d\n", *syserror);
                     }
                 }
@@ -191,12 +196,12 @@ int main(argc, argval)
 
             case 12:        /* rm */
                 if (*arg1)
-                    retc = unlink(arg1);
+                    retc = fuzix_rm(arg1);
                 break;
 
             case 13:        /* df */
                 for (j = 0; j < 4; ++j) {
-                    retc = _getfsys(j, (char*)&fsys);
+                    retc = fuzix_getfsys(j, (char*)&fsys);
                     if (retc == 0 && fsys.s_mounted) {
                         printf("%d:  %u blks used, %u free;  ", j,
                                 (fsys.s_fsize - fsys.s_isize) - fsys.s_tfree,
@@ -210,19 +215,19 @@ int main(argc, argval)
 
             case 14:        /* rmdir */
                 if (*arg1)
-                    retc = rmdir(arg1);
+                    retc = fuzix_rmdir(arg1);
                 break;
 
             case 15:        /* mount */
                 if (*arg1 && *arg2)
-                    if ((retc = _mount(arg1, arg2, 0)) != 0) {
+                    if ((retc = fuzix_mount(arg1, arg2, 0)) != 0) {
                         printf("Mount error: %d\n", *syserror);
                     }
                 break;
 
             case 16:        /* umount */
                 if (*arg1)
-                    if ((retc = _umount(arg1)) != 0) {
+                    if ((retc = fuzix_umount(arg1)) != 0) {
                         printf("Umount error: %d\n", *syserror);
                     }
                 break;
@@ -239,13 +244,13 @@ int main(argc, argval)
         }           /* End Switch */
     } while (interactive || pending_line);
 
-    _sync();
+    fuzix_sync();
 
     return retc;
 }
 
 
-int match(char *cmd)
+static int match(char *cmd)
 {
     if (strcmp(cmd, "exit") == 0)
         return (0);
@@ -296,7 +301,7 @@ int match(char *cmd)
 }
 
 
-void usage(void)
+static void usage(void)
 {
     printf("UCP commands:\n");
     printf("?|help\n");
@@ -317,7 +322,7 @@ void usage(void)
     printf("umount path\n");
 }
 
-void prmode(int mode)
+static void prmode(int mode)
 {
     if (mode & 4)
         printf("r");
@@ -335,7 +340,7 @@ void prmode(int mode)
         printf("-");
 }
 
-int ls(char *path)
+static int ls(char *path)
 {
     struct direct buf;
     struct uzi_stat statbuf;
@@ -343,18 +348,18 @@ int ls(char *path)
     int d, st;
 
     /*
-       if (_stat(path, &statbuf) != 0 || (statbuf.st_mode & F_MASK) != F_DIR) {
+       if (fuzix_stat(path, &statbuf) != 0 || (statbuf.st_mode & F_MASK) != F_DIR) {
        printf("ls: can't stat %s\n", path);
        return -1;
        }
        */
 
-    d = _open(path, 0);
+    d = fuzix_open(path, 0);
     if (d < 0) {
         fprintf(stderr, "ls: can't open %s\n", path);
         return -1;
     }
-    while (_read(d, (char *) &buf, 16) == 16) {
+    while (fuzix_read(d, (char *) &buf, 16) == 16) {
         if (buf.d_name[0] == '\0')
             continue;
 
@@ -367,7 +372,7 @@ int ls(char *path)
 
         strcat(dname, buf.d_name);
 
-        if (_stat(dname, &statbuf) != 0) {
+        if (fuzix_stat(dname, &statbuf) != 0) {
             fprintf(stderr, "ls: can't stat %s\n", dname);
             break;
         }
@@ -418,31 +423,29 @@ int ls(char *path)
 
         printf("  %-15s\n", dname);
     }
-    _close(d);
+    fuzix_close(d);
     return 0;
 }
 
-int chmod(char *modes, char *path)
+static int chmod(char *modes, char *path)
 {
-    int mode;
+    unsigned int mode;
 
     printf("chmod %s to %s\n", path, modes);
-    mode = -1;
-    sscanf(modes, "%o", &mode);
-    if (mode == -1) {
+    if (sscanf(modes, "%o", &mode) != 1) {
         fprintf(stderr, "chmod: bad mode\n");
         return (-1);
     }
     /* Preserve the type if not specified */
     if (mode < 10000) {
         struct uzi_stat st;
-        if (_stat(path, &st) != 0) {
+        if (fuzix_stat(path, &st) != 0) {
             fprintf(stderr, "chmod: can't stat file '%s': %d\n", path, *syserror);
             return -1;
         }
         mode = (st.st_mode & ~0x7777) | mode;
     }
-    if (_chmod(path, mode)) {
+    if (fuzix_chmod(path, mode)) {
         fprintf(stderr, "chmod: error %d\n", *syserror);
         return (-1);
     }
@@ -450,14 +453,12 @@ int chmod(char *modes, char *path)
 }
 
 
-int mknod( char *path, char *modes, char *devs)
+static int mknod( char *path, char *modes, char *devs)
 {
-    int mode;
+    unsigned int mode;
     int dev;
 
-    mode = -1;
-    sscanf(modes, "%o", &mode);
-    if (mode == -1) {
+    if (sscanf(modes, "%o", &mode) != 1) {
         fprintf(stderr, "mknod: bad mode\n");
         return (-1);
     }
@@ -471,8 +472,8 @@ int mknod( char *path, char *modes, char *devs)
         fprintf(stderr, "mknod: bad device\n");
         return (-1);
     }
-    if (_mknod(path, mode, dev) != 0) {
-        fprintf(stderr, "_mknod: error %d\n", *syserror);
+    if (fuzix_mknod(path, mode, dev) != 0) {
+        fprintf(stderr, "fuzix_mknod: error %d\n", *syserror);
         return (-1);
     }
     return (0);
@@ -480,23 +481,23 @@ int mknod( char *path, char *modes, char *devs)
 
 
 
-int mkdir(char *path)
+static int mkdir(char *path)
 {
     char dot[100];
 
-    if (_mknod(path, 040000 | 0777, 0) != 0) {
+    if (fuzix_mknod(path, 040000 | 0777, 0) != 0) {
         fprintf(stderr, "mkdir: mknod error %d\n", *syserror);
         return (-1);
     }
     strcpy(dot, path);
     strcat(dot, "/.");
-    if (_link(path, dot) != 0) {
+    if (fuzix_link(path, dot) != 0) {
         fprintf(stderr, "mkdir: link \".\" error %d\n", *syserror);
         return (-1);
     }
     strcpy(dot, path);
     strcat(dot, "/..");
-    if (_link(".", dot) != 0) {
+    if (fuzix_link(".", dot) != 0) {
         fprintf(stderr, "mkdir: link \"..\" error %d\n", *syserror);
         return (-1);
     }
@@ -505,7 +506,7 @@ int mkdir(char *path)
 
 
 
-int get( char *src, char *dest, int binflag)
+static int get( char *src, char *dest, int binflag)
 {
     FILE *fp;
     int d;
@@ -517,7 +518,7 @@ int get( char *src, char *dest, int binflag)
         fprintf(stderr, "Source file '%s' not found\n", src);
         return (-1);
     }
-    d = _creat(basename(dest), 0666);
+    d = fuzix_creat(basename(dest), 0666);
     if (d < 0) {
         fprintf(stderr, "Can't open destination file '%s'; error %d\n", dest, *syserror);
         return (-1);
@@ -526,21 +527,21 @@ int get( char *src, char *dest, int binflag)
         nread = fread(cbuf, 1, 512, fp);
         if (nread == 0)
             break;
-        if (_write(d, cbuf, nread) != nread) {
-            fprintf(stderr, "_write error %d\n", *syserror);
+        if (fuzix_write(d, cbuf, nread) != nread) {
+            fprintf(stderr, "fuzix_write error %d\n", *syserror);
             fclose(fp);
-            _close(d);
+            fuzix_close(d);
             return (-1);
         }
     }
     fclose(fp);
-    _close(d);
-    _sync();
+    fuzix_close(d);
+    fuzix_sync();
     return (0);
 }
 
 
-int put( char *arg, int binflag)
+static int put( char *arg, int binflag)
 {
     FILE *fp;
     int d;
@@ -552,40 +553,40 @@ int put( char *arg, int binflag)
         fprintf(stderr, "Can't open destination file.\n");
         return (-1);
     }
-    d = _open(arg, 0);
+    d = fuzix_open(arg, 0);
     if (d < 0) {
         fprintf(stderr, "Can't open unix file error %d\n", *syserror);
         return (-1);
     }
     for (;;) {
-        if ((nread = _read(d, cbuf, 512)) == 0)
+        if ((nread = fuzix_read(d, cbuf, 512)) == 0)
             break;
         if (fwrite(cbuf, 1, nread, fp) != nread) {
             fprintf(stderr, "fwrite error");
             fclose(fp);
-            _close(d);
+            fuzix_close(d);
             return (-1);
         }
     }
     fclose(fp);
-    _close(d);
+    fuzix_close(d);
     return (0);
 }
 
 
-int type( char *arg)
+static int type( char *arg)
 {
     int d, i;
     char cbuf[512];
     int nread;
 
-    d = _open(arg, 0);
+    d = fuzix_open(arg, 0);
     if (d < 0) {
         fprintf(stderr, "Can't open unix file error %d\n", *syserror);
         return (-1);
     }
     for (;;) {
-        if ((nread = _read(d, cbuf, 512)) == 0)
+        if ((nread = fuzix_read(d, cbuf, 512)) == 0)
             break;
 
         for (i = 0; i < nread; i++) {
@@ -595,38 +596,38 @@ int type( char *arg)
         }
     }
     fputc('\n', stdout);
-    _close(d);
+    fuzix_close(d);
     return (0);
 }
 
 
-int fdump(char *arg)
+static int fdump(char *arg)
 {
     int d;
     char cbuf[512];
     int nread;
 
     printf("Dump starting.\n");
-    d = _open(arg, 0);
+    d = fuzix_open(arg, 0);
     if (d < 0) {
         fprintf(stderr, "Can't open unix file error %d\n", *syserror);
         return (-1);
     }
     for (;;) {
-        if ((nread = _read(d, cbuf, 512)) == 0)
+        if ((nread = fuzix_read(d, cbuf, 512)) == 0)
             break;
     }
-    _close(d);
+    fuzix_close(d);
     printf("Dump done.\n");
     return (0);
 }
 
 
-int unlink( char *path)
+static int fuzix_rm( char *path)
 {
     struct uzi_stat statbuf;
 
-    if (_stat(path, &statbuf) != 0) {
+    if (fuzix_stat(path, &statbuf) != 0) {
         fprintf(stderr, "unlink: can't stat %s\n", path);
         return (-1);
     }
@@ -634,22 +635,22 @@ int unlink( char *path)
         fprintf(stderr, "unlink: %s is a directory\n", path);
         return (-1);
     }
-    if (_unlink(path) != 0) {
-        fprintf(stderr, "unlink: _unlink errn=or %d\n", *syserror);
+    if (fuzix_unlink(path) != 0) {
+        fprintf(stderr, "unlink: fuzix_unlink errn=or %d\n", *syserror);
         return (-1);
     }
     return (0);
 }
 
 
-int rmdir(char *path)
+static int fuzix_rmdir(char *path)
 {
     struct uzi_stat statbuf;
     char newpath[100];
     struct direct dir;
     int fd;
 
-    if (_stat(path, &statbuf) != 0) {
+    if (fuzix_stat(path, &statbuf) != 0) {
         fprintf(stderr, "rmdir: can't stat %s\n", path);
         return (-1);
     }
@@ -658,35 +659,1837 @@ int rmdir(char *path)
         fprintf(stderr, "rmdir: %s is not a directory\n", path);
         return (-1);
     }
-    if ((fd = _open(path, 0)) < 0) {
+    if ((fd = fuzix_open(path, 0)) < 0) {
         fprintf(stderr, "rmdir: %s is unreadable\n", path);
         return (-1);
     }
-    while (_read(fd, (char *) &dir, sizeof(dir)) == sizeof(dir)) {
+    while (fuzix_read(fd, (char *) &dir, sizeof(dir)) == sizeof(dir)) {
         if (dir.d_ino == 0)
             continue;
         if (!strcmp(dir.d_name, ".") || !strcmp(dir.d_name, ".."))
             continue;
         fprintf(stderr, "rmdir: %s is not empty\n", path);
-        _close(fd);
+        fuzix_close(fd);
         return (-1);
     }
-    _close(fd);
+    fuzix_close(fd);
 
     strcpy(newpath, path);
     strcat(newpath, "/.");
-    if (_unlink(newpath) != 0) {
+    if (fuzix_unlink(newpath) != 0) {
         fprintf(stderr, "rmdir: can't unlink \".\"  error %d\n", *syserror);
         /*return (-1); */
     }
     strcat(newpath, ".");
-    if (_unlink(newpath) != 0) {
+    if (fuzix_unlink(newpath) != 0) {
         fprintf(stderr, "rmdir: can't unlink \"..\"  error %d\n", *syserror);
         /*return (-1); */
     }
-    if (_unlink(path) != 0) {
-        fprintf(stderr, "rmdir: _unlink error %d\n", *syserror);
+    if (fuzix_unlink(path) != 0) {
+        fprintf(stderr, "rmdir: fuzix_unlink error %d\n", *syserror);
         return (-1);
     }
     return (0);
 }
+
+static void fs_init(void)
+{
+       udata.u_euid = 0;
+       udata.u_insys = 1;
+}
+
+static void xfs_init(int bootdev)
+{
+       register char *j;
+
+       fs_init();
+       bufinit();
+
+       /* User's file table */
+       for (j = udata.u_files; j < (udata.u_files + UFTSIZE); ++j)
+               *j = -1;
+
+       /* Mount the root device */
+       if (fmount(ROOTDEV, NULLINODE))
+               panic("no filesys");
+
+       ifnot(root = i_open(ROOTDEV, ROOTINODE))
+           panic("no root");
+
+       i_ref(udata.u_cwd = root);
+}
+
+
+static void xfs_end(void)
+{
+       register int16_t j;
+
+       for (j = 0; j < UFTSIZE; ++j) {
+               ifnot(udata.u_files[j] & 0x80)  /* Portable equivalent of == -1 */
+                   doclose(j);
+       }
+}
+
+
+static int fuzix_open(char *name, int16_t flag)
+{
+       int16_t uindex;
+       register int16_t oftindex;
+       register inoptr ino;
+
+       udata.u_error = 0;
+
+       if (flag < 0 || flag > 2) {
+               udata.u_error = EINVAL;
+               return (-1);
+       }
+       if ((uindex = uf_alloc()) == -1)
+               return (-1);
+
+       if ((oftindex = oft_alloc()) == -1)
+               goto nooft;
+
+       ifnot(ino = n_open(name, NULLINOPTR))
+           goto cantopen;
+
+       of_tab[oftindex].o_inode = ino;
+
+       if (fuzix_getmode(ino) == F_DIR &&
+           (flag == FO_WRONLY || flag == FO_RDWR)) {
+               udata.u_error = EISDIR;
+               goto cantopen;
+       }
+
+       if (isdevice(ino))      // && d_open((int)ino->c_node.i_addr[0]) != 0)
+       {
+               udata.u_error = ENXIO;
+               goto cantopen;
+       }
+
+       udata.u_files[uindex] = oftindex;
+
+       of_tab[oftindex].o_ptr = 0;
+       of_tab[oftindex].o_access = flag;
+
+       return (uindex);
+
+      cantopen:
+       oft_deref(oftindex);    /* This will call i_deref() */
+      nooft:
+       udata.u_files[uindex] = -1;
+       return (-1);
+}
+
+static int doclose(int16_t uindex)
+{
+       register int16_t oftindex;
+       inoptr ino;
+
+       udata.u_error = 0;
+       ifnot(ino = getinode(uindex))
+           return (-1);
+       oftindex = udata.u_files[uindex];
+
+       //if (isdevice(ino)
+       //        /* && ino->c_refs == 1 && of_tab[oftindex].o_refs == 1 */ )
+       //    d_close((int)(ino->c_node.i_addr[0]));
+
+       udata.u_files[uindex] = -1;
+       oft_deref(oftindex);
+
+       return (0);
+}
+
+static int fuzix_close(int16_t uindex)
+{
+       udata.u_error = 0;
+       return (doclose(uindex));
+}
+
+static int fuzix_creat(char *name, int16_t mode)
+{
+       register inoptr ino;
+       register int16_t uindex;
+       register int16_t oftindex;
+       inoptr parent;
+       register int16_t j;
+
+       udata.u_error = 0;
+       parent = NULLINODE;
+
+       if ((uindex = uf_alloc()) == -1)
+               return (-1);
+       if ((oftindex = oft_alloc()) == -1)
+               return (-1);
+
+       ino = n_open(name, &parent);
+       if (ino) {
+               i_deref(parent);
+               if (fuzix_getmode(ino) == F_DIR) {
+                       i_deref(ino);
+                       udata.u_error = EISDIR;
+                       goto nogood;
+               }
+               if (fuzix_getmode(ino) == F_REG) {
+                       /* Truncate the file to zero length */
+                       f_trunc(ino);
+                       /* Reset any oft pointers */
+                       for (j = 0; j < OFTSIZE; ++j)
+                               if (of_tab[j].o_inode == ino)
+                                       of_tab[j].o_ptr = 0;
+               }
+       } else {
+               if (parent && (ino = newfile(parent, name)))
+                       /* Parent was derefed in newfile */
+               {
+                       ino->c_node.i_mode =
+                           swizzle16(F_REG |
+                                     (mode & MODE_MASK & ~udata.u_mask));
+                       setftime(ino, A_TIME | M_TIME | C_TIME);
+                       /* The rest of the inode is initialized in newfile() */
+                       wr_inode(ino);
+               } else {
+                       /* Doesn't exist and can't make it */
+                       if (parent)
+                               i_deref(parent);
+                       goto nogood;
+               }
+       }
+       udata.u_files[uindex] = oftindex;
+
+       of_tab[oftindex].o_ptr = 0;
+       of_tab[oftindex].o_inode = ino;
+       of_tab[oftindex].o_access = FO_WRONLY;
+
+       return (uindex);
+
+      nogood:
+       oft_deref(oftindex);
+       return (-1);
+}
+
+static int fuzix_link(char *name1, char *name2)
+{
+       register inoptr ino;
+       register inoptr ino2;
+       inoptr parent2;
+
+       udata.u_error = 0;
+       ifnot(ino = n_open(name1, NULLINOPTR))
+           return (-1);
+
+       /* Make sure file2 doesn't exist, and get its parent */
+       if ((ino2 = n_open(name2, &parent2))) {
+               i_deref(ino2);
+               i_deref(parent2);
+               udata.u_error = EEXIST;
+               goto nogood;
+       }
+
+       ifnot(parent2)
+           goto nogood;
+
+       if (ino->c_dev != parent2->c_dev) {
+               i_deref(parent2);
+               udata.u_error = EXDEV;
+               goto nogood;
+       }
+
+       if (ch_link(parent2, "", filename(name2), ino) == 0)
+               goto nogood;
+
+       /* Update the link count. */
+       ino->c_node.i_nlink =
+           swizzle16(swizzle16(ino->c_node.i_nlink) + 1);
+       wr_inode(ino);
+       setftime(ino, C_TIME);
+
+       i_deref(parent2);
+       i_deref(ino);
+       return (0);
+
+      nogood:
+       i_deref(ino);
+       return (-1);
+}
+
+static int fuzix_unlink(char *path)
+{
+       register inoptr ino;
+       inoptr pino;
+
+       udata.u_error = 0;
+       ino = n_open(path, &pino);
+
+       ifnot(pino && ino) {
+               udata.u_error = ENOENT;
+               return (-1);
+       }
+
+       /* Remove the directory entry */
+
+       if (ch_link(pino, filename(path), "", NULLINODE) == 0)
+               goto nogood;
+
+       /* Decrease the link count of the inode */
+
+       if (ino->c_node.i_nlink == 0) {
+               ino->c_node.i_nlink =
+                   swizzle16(swizzle16(ino->c_node.i_nlink) + 2);
+               printf("fuzix_unlink: bad nlink\n");
+       } else
+               ino->c_node.i_nlink =
+                   swizzle16(swizzle16(ino->c_node.i_nlink) - 1);
+       setftime(ino, C_TIME);
+       i_deref(pino);
+       i_deref(ino);
+       return (0);
+      nogood:
+       i_deref(pino);
+       i_deref(ino);
+       return (-1);
+}
+
+static int fuzix_read(int16_t d, char *buf, uint16_t nbytes)
+{
+       register inoptr ino;
+
+       udata.u_error = 0;
+       /* Set up u_base, u_offset, ino; check permissions, file num. */
+       if ((ino = rwsetup(1, d, buf, nbytes)) == NULLINODE)
+               return (-1);    /* bomb out if error */
+
+       readi(ino);
+       updoff(d);
+
+       return (udata.u_count);
+}
+
+static int fuzix_write(int16_t d, char *buf, uint16_t nbytes)
+{
+       register inoptr ino;
+
+       udata.u_error = 0;
+       /* Set up u_base, u_offset, ino; check permissions, file num. */
+       if ((ino = rwsetup(0, d, buf, nbytes)) == NULLINODE)
+               return (-1);    /* bomb out if error */
+
+       writei(ino);
+       updoff(d);
+
+       return (udata.u_count);
+}
+
+static inoptr rwsetup(int rwflag, int d, char *buf, int nbytes)
+{
+       register inoptr ino;
+       register struct oft *oftp;
+
+       udata.u_base = buf;
+       udata.u_count = nbytes;
+
+       if ((ino = getinode(d)) == NULLINODE)
+               return (NULLINODE);
+
+       oftp = of_tab + udata.u_files[d];
+       if (oftp->o_access == (rwflag ? FO_WRONLY : FO_RDONLY)) {
+               udata.u_error = EBADF;
+               return (NULLINODE);
+       }
+
+       setftime(ino, rwflag ? A_TIME : (A_TIME | M_TIME | C_TIME));
+
+       /* Initialize u_offset from file pointer */
+       udata.u_offset = oftp->o_ptr;
+
+       return (ino);
+}
+
+static void readi(inoptr ino)
+{
+       register uint16_t amount;
+       register uint16_t toread;
+       register blkno_t pblk;
+       register char *bp;
+       int dev;
+
+       dev = ino->c_dev;
+       switch (fuzix_getmode(ino)) {
+
+       case F_DIR:
+       case F_REG:
+
+               /* See of end of file will limit read */
+               toread = udata.u_count =
+                   min(udata.u_count,
+                       swizzle32(ino->c_node.i_size) - udata.u_offset);
+               goto loop;
+
+       case F_BDEV:
+               toread = udata.u_count;
+               dev = swizzle16(*(ino->c_node.i_addr));
+
+             loop:
+               while (toread) {
+                       if ((pblk =
+                            bmap(ino, udata.u_offset >> 9, 1)) != NULLBLK)
+                               bp = bread(dev, pblk, 0);
+                       else
+                               bp = zerobuf();
+
+                       bcopy(bp + (udata.u_offset & 511), udata.u_base,
+                             (amount =
+                              min(toread, 512 - (udata.u_offset & 511))));
+                       brelse((bufptr) bp);
+
+                       udata.u_base += amount;
+                       udata.u_offset += amount;
+                       toread -= amount;
+               }
+               break;
+
+       default:
+               udata.u_error = ENODEV;
+       }
+}
+
+
+
+/* Writei (and readi) need more i/o error handling */
+
+static void writei(inoptr ino)
+{
+       register uint16_t amount;
+       register uint16_t towrite;
+       register char *bp;
+       blkno_t pblk;
+       int dev;
+
+       dev = ino->c_dev;
+
+       switch (fuzix_getmode(ino)) {
+
+       case F_BDEV:
+               dev = swizzle16(*(ino->c_node.i_addr));
+       case F_DIR:
+       case F_REG:
+               towrite = udata.u_count;
+               goto loop;
+
+             loop:
+               while (towrite) {
+                       amount =
+                           min(towrite, 512 - (udata.u_offset & 511));
+
+                       if ((pblk =
+                            bmap(ino, udata.u_offset >> 9, 0)) == NULLBLK)
+                               break;  /* No space to make more blocks */
+
+                       /* If we are writing an entire block, we don't care
+                          about its previous contents */
+                       bp = bread(dev, pblk, (amount == 512));
+
+                       bcopy(udata.u_base, bp + (udata.u_offset & 511),
+                             amount);
+                       bawrite((bufptr) bp);
+
+                       udata.u_base += amount;
+                       udata.u_offset += amount;
+                       towrite -= amount;
+               }
+
+               /* Update size if file grew */
+               if (udata.u_offset > swizzle32(ino->c_node.i_size)) {
+                       ino->c_node.i_size = swizzle32(udata.u_offset);
+                       ino->c_dirty = 1;
+               }
+               break;
+
+       default:
+               udata.u_error = ENODEV;
+       }
+}
+
+
+
+static void updoff(int d)
+{
+       /* Update current file pointer */
+       of_tab[udata.u_files[d]].o_ptr = udata.u_offset;
+}
+
+static int valadr(char *base, uint16_t size)
+{
+       return (1);
+}
+
+
+static int fuzix_mknod(char *name, int16_t mode, int16_t dev)
+{
+       register inoptr ino;
+       inoptr parent;
+
+       udata.u_error = 0;
+
+       if ((ino = n_open(name, &parent))) {
+               udata.u_error = EEXIST;
+               goto nogood;
+       }
+
+       ifnot(parent) {
+               udata.u_error = ENOENT;
+               return (-1);
+       }
+
+       ifnot(ino = newfile(parent, name))
+           goto nogood2;
+
+       /* Initialize mode and dev */
+       ino->c_node.i_mode = swizzle16(mode & ~udata.u_mask);
+       ino->c_node.i_addr[0] = swizzle16(isdevice(ino) ? dev : 0);
+       setftime(ino, A_TIME | M_TIME | C_TIME);
+       wr_inode(ino);
+
+       i_deref(ino);
+       return (0);
+
+      nogood:
+       i_deref(ino);
+      nogood2:
+       i_deref(parent);
+       return (-1);
+}
+
+static void fuzix_sync(void)
+{
+       int j;
+       inoptr ino;
+       char *buf;
+
+       /* Write out modified inodes */
+
+       udata.u_error = 0;
+       for (ino = i_tab; ino < i_tab + ITABSIZE; ++ino)
+               if ((ino->c_refs) > 0 && ino->c_dirty != 0) {
+                       wr_inode(ino);
+                       ino->c_dirty = 0;
+               }
+
+       /* Write out modified super blocks */
+       /* This fills the rest of the super block with garbage. */
+
+       for (j = 0; j < NDEVS; ++j) {
+               if (swizzle16(fs_tab[j].s_mounted) == SMOUNTED
+                   && fs_tab[j].s_fmod) {
+                       fs_tab[j].s_fmod = 0;
+                       buf = bread(j, 1, 1);
+                       bcopy((char *) &fs_tab[j], buf, 512);
+                       bfree((bufptr) buf, 2);
+               }
+       }
+       bufsync();              /* Clear buffer pool */
+}
+
+static int fuzix_chdir(char *dir)
+{
+       register inoptr newcwd;
+
+       udata.u_error = 0;
+       ifnot(newcwd = n_open(dir, NULLINOPTR))
+           return (-1);
+
+       if (fuzix_getmode(newcwd) != F_DIR) {
+               udata.u_error = ENOTDIR;
+               i_deref(newcwd);
+               return (-1);
+       }
+       i_deref(udata.u_cwd);
+       udata.u_cwd = newcwd;
+       return (0);
+}
+
+static int min(int a, int b)
+{
+       return (a < b ? a : b);
+}
+
+static int fuzix_chmod(char *path, int16_t mode)
+{
+       inoptr ino;
+
+       udata.u_error = 0;
+       ifnot(ino = n_open(path, NULLINOPTR))
+           return (-1);
+
+       ino->c_node.i_mode =
+           swizzle16((mode & MODE_MASK) |
+                     (swizzle16(ino->c_node.i_mode) & F_MASK));
+       setftime(ino, C_TIME);
+       i_deref(ino);
+       return (0);
+}
+
+static int fuzix_stat(char *path, struct uzi_stat *buf)
+{
+       register inoptr ino;
+
+       udata.u_error = 0;
+       ifnot(valadr((char *) buf, sizeof(struct uzi_stat))
+             && (ino = n_open(path, NULLINOPTR))) {
+               return (-1);
+       }
+       stcpy(ino, buf);
+       i_deref(ino);
+       return (0);
+}
+
+/* Utility for stat and fstat */
+static void stcpy(inoptr ino, struct uzi_stat *buf)
+{
+       struct uzi_stat *b = (struct uzi_stat *) buf;
+
+       b->st_dev = swizzle16(ino->c_dev);
+       b->st_ino = swizzle16(ino->c_num);
+       b->st_mode = swizzle16(ino->c_node.i_mode);
+       b->st_nlink = swizzle16(ino->c_node.i_nlink);
+       b->st_uid = swizzle16(ino->c_node.i_uid);
+       b->st_gid = swizzle16(ino->c_node.i_gid);
+
+       b->st_rdev = swizzle16(ino->c_node.i_addr[0]);
+
+       b->st_size = swizzle32(ino->c_node.i_size);
+       b->fst_atime = swizzle32(ino->c_node.i_atime);
+       b->fst_mtime = swizzle32(ino->c_node.i_mtime);
+       b->fst_ctime = swizzle32(ino->c_node.i_ctime);
+}
+
+/* Special system call returns super-block of given filesystem for
+ * users to determine free space, etc.  Should be replaced with a
+ * sync() followed by a read of block 1 of the device.
+ */
+
+static int fuzix_getfsys(int dev, char *buf)
+{
+       udata.u_error = 0;
+       if (dev < 0 || dev >= NDEVS
+           || swizzle16(fs_tab[dev].s_mounted) != SMOUNTED) {
+               udata.u_error = ENXIO;
+               return (-1);
+       }
+
+       /* FIXME: endiam swapping here */
+       bcopy((char *) &fs_tab[dev], (char *) buf, sizeof(struct filesys));
+       return (0);
+}
+
+static int fuzix_mount(char *spec, char *dir, int rwflag)
+{
+       register inoptr sino, dino;
+       register int dev;
+
+       udata.u_error = 0;
+       ifnot(sino = n_open(spec, NULLINOPTR))
+           return (-1);
+
+       ifnot(dino = n_open(dir, NULLINOPTR)) {
+               i_deref(sino);
+               return (-1);
+       }
+       if (fuzix_getmode(sino) != F_BDEV) {
+               udata.u_error = ENOTBLK;
+               goto nogood;
+       }
+       if (fuzix_getmode(dino) != F_DIR) {
+               udata.u_error = ENOTDIR;
+               goto nogood;
+       }
+       dev = (int) swizzle16(sino->c_node.i_addr[0]);
+
+       if (dev >= NDEVS)       // || d_open(dev))
+       {
+               udata.u_error = ENXIO;
+               goto nogood;
+       }
+       if (fs_tab[dev].s_mounted || dino->c_refs != 1
+           || dino->c_num == ROOTINODE) {
+               udata.u_error = EBUSY;
+               goto nogood;
+       }
+       fuzix_sync();
+
+       if (fmount(dev, dino)) {
+               udata.u_error = EBUSY;
+               goto nogood;
+       }
+       i_deref(dino);
+       i_deref(sino);
+       return (0);
+      nogood:
+       i_deref(dino);
+       i_deref(sino);
+       return (-1);
+}
+
+static int fuzix_umount(char *spec)
+{
+       register inoptr sino;
+       register int dev;
+       register inoptr ptr;
+
+       udata.u_error = 0;
+
+       ifnot(sino = n_open(spec, NULLINOPTR))
+           return (-1);
+
+       if (fuzix_getmode(sino) != F_BDEV) {
+               udata.u_error = ENOTBLK;
+               goto nogood;
+       }
+
+       dev = (int) swizzle16(sino->c_node.i_addr[0]);
+
+       if (!fs_tab[dev].s_mounted) {
+               udata.u_error = EINVAL;
+               goto nogood;
+       }
+
+       for (ptr = i_tab; ptr < i_tab + ITABSIZE; ++ptr)
+               if (ptr->c_refs > 0 && ptr->c_dev == dev) {
+                       udata.u_error = EBUSY;
+                       goto nogood;
+               }
+       fuzix_sync();
+       fs_tab[dev].s_mounted = 0;
+       i_deref(fs_tab[dev].s_mntpt);
+
+       i_deref(sino);
+       return (0);
+
+      nogood:
+       i_deref(sino);
+       return (-1);
+}
+
+static inoptr n_open(register char *name, register inoptr * parent)
+{
+       register inoptr wd;     /* the directory we are currently searching. */
+       register inoptr ninode;
+       register inoptr temp;
+
+       if (*name == '/')
+               wd = root;
+       else
+               wd = udata.u_cwd;
+
+       i_ref(ninode = wd);
+       i_ref(ninode);
+
+       for (;;) {
+               if (ninode)
+                       magic(ninode);
+
+               /* See if we are at a mount point */
+               if (ninode)
+                       ninode = srch_mt(ninode);
+
+               while (*name == '/')    /* Skip (possibly repeated) slashes */
+                       ++name;
+               ifnot(*name)    /* No more components of path? */
+                   break;
+               ifnot(ninode) {
+                       udata.u_error = ENOENT;
+                       goto nodir;
+               }
+               i_deref(wd);
+               wd = ninode;
+               if (fuzix_getmode(wd) != F_DIR) {
+                       udata.u_error = ENOTDIR;
+                       goto nodir;
+               }
+
+               /* See if we are going up through a mount point */
+               if (wd->c_num == ROOTINODE && wd->c_dev != ROOTDEV
+                   && name[1] == '.') {
+                       temp = fs_tab[wd->c_dev].s_mntpt;
+                       ++temp->c_refs;
+                       i_deref(wd);
+                       wd = temp;
+               }
+
+               ninode = srch_dir(wd, name);
+
+               while (*name != '/' && *name)
+                       ++name;
+       }
+
+       if (parent)
+               *parent = wd;
+       else
+               i_deref(wd);
+       ifnot(parent || ninode)
+           udata.u_error = ENOENT;
+       return (ninode);
+
+nodir:
+       if (parent)
+               *parent = NULLINODE;
+       i_deref(wd);
+       return (NULLINODE);
+
+}
+
+
+
+/* Srch_dir is given a inode pointer of an open directory and a string
+ * containing a filename, and searches the directory for the file.  If
+ * it exists, it opens it and returns the inode pointer, otherwise NULL.
+ * This depends on the fact that ba_read will return unallocated blocks
+ * as zero-filled, and a partially allocated block will be padded with
+ * zeroes.
+ */
+
+static inoptr srch_dir(inoptr wd, register char *compname)
+{
+       register int curentry;
+       register blkno_t curblock;
+       register struct direct *buf;
+       register int nblocks;
+       unsigned inum;
+
+       nblocks = (swizzle32(wd->c_node.i_size) + 511) >> 9;
+
+       for (curblock = 0; curblock < nblocks; ++curblock) {
+               buf =
+                   (struct direct *) bread(wd->c_dev,
+                                           bmap(wd, curblock, 1), 0);
+               for (curentry = 0; curentry < 16; ++curentry) {
+                       if (namecomp(compname, buf[curentry].d_name)) {
+                               inum =
+                                   swizzle16(buf[curentry & 0x0f].d_ino);
+                               brelse((bufptr) buf);
+                               return (i_open(wd->c_dev, inum));
+                       }
+               }
+               brelse((bufptr) buf);
+       }
+       return (NULLINODE);
+}
+
+
+/* Srch_mt sees if the given inode is a mount point. If so it
+ * dereferences it, and references and returns a pointer to the
+ * root of the mounted filesystem.
+ */
+
+static inoptr srch_mt(inoptr ino)
+{
+       register int j;
+
+       for (j = 0; j < NDEVS; ++j)
+               if (swizzle16(fs_tab[j].s_mounted) == SMOUNTED
+                   && fs_tab[j].s_mntpt == ino) {
+                       i_deref(ino);
+                       return (i_open(j, ROOTINODE));
+               }
+
+       return (ino);
+}
+
+
+/* I_open is given an inode number and a device number,
+ * and makes an entry in the inode table for them, or
+ * increases it reference count if it is already there.
+ * An inode # of zero means a newly allocated inode.
+ */
+
+static inoptr i_open(register int dev, register unsigned ino)
+{
+
+       struct dinode *buf;
+       register inoptr nindex;
+       int i;
+       register inoptr j;
+       int new;
+       static inoptr nexti = i_tab;    /* added inoptr. 26.12.97  HFB */
+
+       if (dev < 0 || dev >= NDEVS)
+               panic("i_open: Bad dev");
+
+       new = 0;
+       ifnot(ino) {            /* Want a new one */
+               new = 1;
+               ifnot(ino = i_alloc(dev)) {
+                       udata.u_error = ENOSPC;
+                       return (NULLINODE);
+               }
+       }
+
+       if (ino < ROOTINODE || ino >= (swizzle16(fs_tab[dev].s_isize) - 2) * 8) {
+               printf("i_open: bad inode number\n");
+               return (NULLINODE);
+       }
+
+
+       nindex = NULLINODE;
+       j = (inoptr) nexti;
+       for (i = 0; i < ITABSIZE; ++i) {
+               nexti = (inoptr) j;
+               if (++j >= i_tab + ITABSIZE)
+                       j = i_tab;
+
+               ifnot(j->c_refs)
+                   nindex = j;
+
+               if (j->c_dev == dev && j->c_num == ino) {
+                       nindex = j;
+                       goto found;
+               }
+       }
+
+       /* Not already in table. */
+
+       ifnot(nindex) {         /* No unrefed slots in inode table */
+               udata.u_error = ENFILE;
+               return (NULLINODE);
+       }
+
+       buf = (struct dinode *) bread(dev, (ino >> 3) + 2, 0);
+       bcopy((char *) &(buf[ino & 0x07]), (char *) &(nindex->c_node), 64);
+       brelse((bufptr) buf);
+
+       nindex->c_dev = dev;
+       nindex->c_num = ino;
+       nindex->c_magic = CMAGIC;
+
+found:
+       if (new) {
+               if (nindex->c_node.i_nlink
+                   || swizzle16(nindex->c_node.i_mode) & F_MASK)
+                       goto badino;
+       } else {
+               ifnot(nindex->c_node.i_nlink
+                     && swizzle16(nindex->c_node.i_mode) & F_MASK)
+                   goto badino;
+       }
+
+       ++nindex->c_refs;
+       return (nindex);
+
+badino:
+       printf("i_open: bad disk inode\n");
+       return (NULLINODE);
+}
+
+
+
+/* Ch_link modifies or makes a new entry in the directory for the name
+ * and inode pointer given. The directory is searched for oldname.  When
+ * found, it is changed to newname, and it inode # is that of *nindex.
+ * A oldname of "" matches a unused slot, and a nindex of NULLINODE
+ * means an inode # of 0.  A return status of 0 means there was no
+ * space left in the filesystem, or a non-empty oldname was not found,
+ * or the user did not have write permission.
+ */
+
+static int ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex)
+{
+       struct direct curentry;
+
+       /* Search the directory for the desired slot. */
+
+       udata.u_offset = 0;
+
+       for (;;) {
+               udata.u_count = 32;
+               udata.u_base = (char *) &curentry;
+//        udata.u_sysio = 1;                                    /*280*/
+               readi(wd);
+
+               /* Read until EOF or name is found */
+               /* readi() advances udata.u_offset */
+               if (udata.u_count == 0
+                   || namecomp(oldname, curentry.d_name))
+                       break;
+       }
+
+       if (udata.u_count == 0 && *oldname)
+               return (0);     /* Entry not found */
+
+       bcopy(newname, curentry.d_name, 30);
+
+       {
+               int i;
+
+               for (i = 0; i < 30; ++i)
+                       if (curentry.d_name[i] == '\0')
+                               break;
+               for (; i < 30; ++i)
+                       curentry.d_name[i] = '\0';
+       }
+
+       if (nindex)
+               curentry.d_ino = swizzle16(nindex->c_num);
+       else
+               curentry.d_ino = 0;
+
+       /* If an existing slot is being used, we must back up the file offset */
+       if (udata.u_count)
+               udata.u_offset -= 32;
+
+       udata.u_count = 32;
+       udata.u_base = (char *) &curentry;
+       udata.u_sysio = 1;      /*280 */
+       writei(wd);
+
+       if (udata.u_error)
+               return (0);
+
+       setftime(wd, A_TIME | M_TIME | C_TIME); /* Sets c_dirty */
+
+       /* Update file length to next block */
+       if (swizzle32(wd->c_node.i_size) & 511)
+               wd->c_node.i_size = swizzle32(
+                   swizzle32(wd->c_node.i_size) + 512 -
+                   (swizzle32(wd->c_node.i_size) & 511));
+
+       return (1);
+}
+
+
+
+/* Filename is given a path name, and returns a pointer to the
+ * final component of it.
+ */
+
+static char *filename(char *path)
+{
+       register char *ptr;
+
+       ptr = path;
+       while (*ptr)
+               ++ptr;
+       while (*ptr != '/' && ptr-- > path);
+       return (ptr + 1);
+}
+
+
+/* Namecomp compares two strings to see if they are the same file name.
+ * It stops at 30 chars or a null or a slash. It returns 0 for difference.
+ */
+
+static int namecomp(char *n1, char *n2)
+{
+       register int n;
+
+       n = 30;
+       while (*n1 && *n1 != '/') {
+               if (*n1++ != *n2++)
+                       return (0);
+               ifnot(--n)
+                   return (-1);
+       }
+       return (*n2 == '\0' || *n2 == '/');
+}
+
+
+/* Newfile is given a pointer to a directory and a name, and creates
+ * an entry in the directory for the name, dereferences the parent,
+ * and returns a pointer to the new inode.  It allocates an inode
+ * number, and creates a new entry in the inode table for the new
+ * file, and initializes the inode table entry for the new file.
+ * The new file will have one reference, and 0 links to it.  Better
+ * Better make sure there isn't already an entry with the same name.
+ */
+
+static inoptr newfile(inoptr pino, char *name)
+{
+       register inoptr nindex;
+       register int j;
+
+       ifnot(nindex = i_open(pino->c_dev, 0))
+           goto nogood;
+
+       /* BIG FIX:  user/group setting was missing  SN *//*280 */
+       nindex->c_node.i_uid = swizzle16(udata.u_euid); /*280 */
+       nindex->c_node.i_gid = swizzle16(udata.u_egid); /*280 */
+
+       nindex->c_node.i_mode = swizzle16(F_REG);       /* For the time being */
+       nindex->c_node.i_nlink = swizzle16(1);
+       nindex->c_node.i_size = 0;
+       for (j = 0; j < 20; j++)
+               nindex->c_node.i_addr[j] = 0;
+       wr_inode(nindex);
+
+       ifnot(ch_link(pino, "", filename(name), nindex)) {
+               i_deref(nindex);
+               goto nogood;
+       }
+
+       i_deref(pino);
+       return (nindex);
+
+nogood:
+       i_deref(pino);
+       return (NULLINODE);
+}
+
+
+/* Check the given device number, and return its address in the mount
+ * table.  Also time-stamp the superblock of dev, and mark it modified.
+ * Used when freeing and allocating blocks and inodes.
+ */
+
+static fsptr getdev(int devno)
+{
+       register fsptr dev;
+
+       dev = fs_tab + devno;
+       if (devno < 0 || devno >= NDEVS || !dev->s_mounted)
+               panic("getdev: bad dev");
+       dev->s_fmod = 1;
+       return (dev);
+}
+
+
+/* Returns true if the magic number of a superblock is corrupt.
+ */
+
+static int baddev(fsptr dev)
+{
+       return (swizzle16(dev->s_mounted) != SMOUNTED);
+}
+
+
+/* I_alloc finds an unused inode number, and returns it, or 0
+ * if there are no more inodes available.
+ */
+
+static unsigned i_alloc(int devno)
+{
+       fsptr dev;
+       blkno_t blk;
+       struct dinode *buf;
+       register int j;
+       register int k;
+       unsigned ino;
+
+       if (baddev(dev = getdev(devno)))
+               goto corrupt;
+
+      tryagain:
+       if (dev->s_ninode) {
+               int i;
+
+               ifnot(dev->s_tinode)
+                   goto corrupt;
+               i = swizzle16(dev->s_ninode);
+               ino = swizzle16(dev->s_inode[--i]);
+               dev->s_ninode = swizzle16(i);
+               if (ino < 2 || ino >= (swizzle16(dev->s_isize) - 2) * 8)
+                       goto corrupt;
+               dev->s_tinode = swizzle16(swizzle16(dev->s_tinode) - 1);
+               return (ino);
+       }
+
+       /* We must scan the inodes, and fill up the table */
+
+       fuzix_sync();           /* Make on-disk inodes consistent */
+       k = 0;
+       for (blk = 2; blk < swizzle16(dev->s_isize); blk++) {
+               buf = (struct dinode *) bread(devno, blk, 0);
+               for (j = 0; j < 8; j++) {
+                       ifnot(buf[j].i_mode || buf[j].i_nlink)
+                           dev->s_inode[k++] =
+                           swizzle16(8 * (blk - 2) + j);
+                       if (k == 50) {
+                               brelse((bufptr) buf);
+                               goto done;
+                       }
+               }
+               brelse((bufptr) buf);
+       }
+
+      done:
+       ifnot(k) {
+               if (dev->s_tinode)
+                       goto corrupt;
+               udata.u_error = ENOSPC;
+               return (0);
+       }
+
+       dev->s_ninode = swizzle16(k);
+       goto tryagain;
+
+      corrupt:
+       printf("i_alloc: corrupt superblock\n");
+       dev->s_mounted = swizzle16(1);
+       udata.u_error = ENOSPC;
+       return (0);
+}
+
+
+/* I_free is given a device and inode number, and frees the inode.
+ * It is assumed that there are no references to the inode in the
+ * inode table or in the filesystem.
+ */
+
+static void i_free(int devno, unsigned ino)
+{
+       register fsptr dev;
+
+       if (baddev(dev = getdev(devno)))
+               return;
+
+       if (ino < 2 || ino >= (swizzle16(dev->s_isize) - 2) * 8)
+               panic("i_free: bad ino");
+
+       dev->s_tinode = swizzle16(swizzle16(dev->s_tinode) + 1);
+       if (swizzle16(dev->s_ninode) < 50) {
+               int i = swizzle16(dev->s_ninode);
+               dev->s_inode[i++] = swizzle16(ino);
+               dev->s_ninode = swizzle16(i);
+       }
+}
+
+
+/* Blk_alloc is given a device number, and allocates an unused block
+ * from it. A returned block number of zero means no more blocks.
+ */
+
+static blkno_t blk_alloc(int devno)
+{
+       register fsptr dev;
+       register blkno_t newno;
+       blkno_t *buf;           /*, *bread(); -- HP */
+       register int j;
+       int i;
+
+       if (baddev(dev = getdev(devno)))
+               goto corrupt2;
+
+       if (swizzle16(dev->s_nfree) <= 0 || swizzle16(dev->s_nfree) > 50)
+               goto corrupt;
+
+       i = swizzle16(dev->s_nfree);
+       newno = swizzle16(dev->s_free[--i]);
+       dev->s_nfree = swizzle16(i);
+       ifnot(newno) {
+               if (dev->s_tfree != 0)
+                       goto corrupt;
+               udata.u_error = ENOSPC;
+               dev->s_nfree = swizzle16(swizzle16(dev->s_nfree) + 1);
+               return (0);
+       }
+
+       /* See if we must refill the s_free array */
+
+       ifnot(dev->s_nfree) {
+               buf = (blkno_t *) bread(devno, newno, 0);
+               dev->s_nfree = buf[0];
+               for (j = 0; j < 50; j++) {
+                       dev->s_free[j] = buf[j + 1];
+               }
+               brelse((bufptr) buf);
+       }
+
+       validblk(devno, newno);
+
+       ifnot(dev->s_tfree)
+           goto corrupt;
+       dev->s_tfree = swizzle16(swizzle16(dev->s_tfree) - 1);
+
+       /* Zero out the new block */
+       buf = (blkno_t *) bread(devno, newno, 2);
+       bzero(buf, 512);
+       bawrite((bufptr) buf);
+       return (newno);
+
+      corrupt:
+       printf("blk_alloc: corrupt\n");
+       dev->s_mounted = swizzle16(1);
+      corrupt2:
+       udata.u_error = ENOSPC;
+       return (0);
+}
+
+
+/* Blk_free is given a device number and a block number,
+and frees the block. */
+
+static void blk_free(int devno, blkno_t blk)
+{
+       register fsptr dev;
+       register char *buf;
+       int b;
+
+       ifnot(blk)
+           return;
+
+       if (baddev(dev = getdev(devno)))
+               return;
+
+       validblk(devno, blk);
+
+       if (dev->s_nfree == 50) {
+               buf = bread(devno, blk, 1);
+               bcopy((char *) &(dev->s_nfree), buf, 512);
+               bawrite((bufptr) buf);
+               dev->s_nfree = 0;
+       }
+
+       dev->s_tfree = swizzle16(swizzle16(dev->s_tfree) + 1);
+       b = swizzle16(dev->s_nfree);
+       dev->s_free[b++] = swizzle16(blk);
+       dev->s_nfree = swizzle16(b);
+}
+
+
+/* Oft_alloc and oft_deref allocate and dereference (and possibly free)
+ * entries in the open file table.
+ */
+
+static int oft_alloc(void)
+{
+       register int j;
+
+       for (j = 0; j < OFTSIZE; ++j) {
+               ifnot(of_tab[j].o_refs) {
+                       of_tab[j].o_refs = 1;
+                       of_tab[j].o_inode = NULLINODE;
+                       return (j);
+               }
+       }
+       udata.u_error = ENFILE;
+       return (-1);
+}
+
+
+static void oft_deref(int of)
+{
+       register struct oft *ofptr;
+
+       ofptr = of_tab + of;
+       if (!(--ofptr->o_refs) && ofptr->o_inode) {
+               i_deref(ofptr->o_inode);
+               ofptr->o_inode = NULLINODE;
+       }
+}
+
+
+/* Uf_alloc finds an unused slot in the user file table.
+ */
+
+static int uf_alloc(void)
+{
+       register int j;
+
+       for (j = 0; j < UFTSIZE; ++j) {
+               if (udata.u_files[j] & 0x80) {  /* Portable, unlike  == -1 */
+                       return (j);
+               }
+       }
+       udata.u_error = ENFILE;
+       return (-1);
+}
+
+
+/* I_ref increases the reference count of the given inode table entry.
+ */
+
+static void i_ref(inoptr ino)
+{
+       if (++(ino->c_refs) == 2 * ITABSIZE) {  /* Arbitrary limit. *//*280 */
+               printf("inode %u,", ino->c_num);        /*280 */
+               panic("too many i-refs");
+       }                       /*280 */
+}
+
+
+/* I_deref decreases the reference count of an inode, and frees it from
+ * the table if there are no more references to it.  If it also has no
+ * links, the inode itself and its blocks (if not a device) is freed.
+ */
+
+static void i_deref(inoptr ino)
+{
+       unsigned int m;
+
+       magic(ino);
+
+       ifnot(ino->c_refs)
+           panic("inode freed.");
+
+       /* If the inode has no links and no refs, it must have
+          its blocks freed. */
+
+       ifnot(--ino->c_refs || ino->c_node.i_nlink) {
+/*
+ SN  (mcy)
+*/
+
+               m = swizzle16(ino->c_node.i_mode);
+               if (((m & F_MASK) == F_REG) ||
+                   ((m & F_MASK) == F_DIR) || ((m & F_MASK) == F_PIPE))
+                       f_trunc(ino);
+       }
+       /* If the inode was modified, we must write it to disk. */
+       if (!(ino->c_refs) && ino->c_dirty) {
+               ifnot(ino->c_node.i_nlink) {
+                       ino->c_node.i_mode = 0;
+                       i_free(ino->c_dev, ino->c_num);
+               }
+               wr_inode(ino);
+       }
+}
+
+
+/* Wr_inode writes out the given inode in the inode table out to disk,
+ * and resets its dirty bit.
+ */
+
+static void wr_inode(inoptr ino)
+{
+       struct dinode *buf;
+       register blkno_t blkno;
+
+       magic(ino);
+
+       blkno = (ino->c_num >> 3) + 2;
+       buf = (struct dinode *) bread(ino->c_dev, blkno, 0);
+       bcopy((char *) (&ino->c_node),
+             (char *) ((char **) &buf[ino->c_num & 0x07]), 64);
+       bfree((bufptr) buf, 2);
+       ino->c_dirty = 0;
+}
+
+
+/* isdevice(ino) returns true if ino points to a device */
+static int isdevice(inoptr ino)
+{
+       return (swizzle16(ino->c_node.i_mode) & 020000);
+}
+
+
+/* F_trunc frees all the blocks associated with the file, if it
+ * is a disk file.
+ */
+
+static void f_trunc(inoptr ino)
+{
+       int dev;
+       int j;
+
+       dev = ino->c_dev;
+
+       /* First deallocate the double indirect blocks */
+       freeblk(dev, swizzle16(ino->c_node.i_addr[19]), 2);
+
+       /* Also deallocate the indirect blocks */
+       freeblk(dev, swizzle16(ino->c_node.i_addr[18]), 1);
+
+       /* Finally, free the direct blocks */
+       for (j = 17; j >= 0; --j)
+               freeblk(dev, swizzle16(ino->c_node.i_addr[j]), 0);
+
+       bzero((char *) ino->c_node.i_addr, sizeof(ino->c_node.i_addr));
+
+       ino->c_dirty = 1;
+       ino->c_node.i_size = 0;
+}
+
+
+/* Companion function to f_trunc(). */
+static void freeblk(int dev, blkno_t blk, int level)
+{
+       blkno_t *buf;
+       int j;
+
+       ifnot(blk)
+           return;
+
+       if (level) {
+               buf = (blkno_t *) bread(dev, blk, 0);
+               for (j = 255; j >= 0; --j)
+                       freeblk(dev, swizzle16(buf[j]), level - 1);
+               brelse((bufptr) buf);
+       }
+
+       blk_free(dev, blk);
+}
+
+
+
+/* Changes: blk_alloc zeroes block it allocates */
+/*
+ * Bmap defines the structure of file system storage by returning
+ * the physical block number on a device given the inode and the
+ * logical block number in a file.  The block is zeroed if created.
+ */
+static blkno_t bmap(inoptr ip, blkno_t bn, int rwflg)
+{
+       register int i;
+       register bufptr bp;
+       register int j;
+       register blkno_t nb;
+       int sh;
+       int dev;
+
+       if (fuzix_getmode(ip) == F_BDEV)
+               return (bn);
+
+       dev = ip->c_dev;
+
+       /*
+        * blocks 0..17 are direct blocks
+        */
+       if (bn < 18) {
+               nb = swizzle16(ip->c_node.i_addr[bn]);
+               if (nb == 0) {
+                       if (rwflg || (nb = blk_alloc(dev)) == 0)
+                               return (NULLBLK);
+                       ip->c_node.i_addr[bn] = swizzle16(nb);
+                       ip->c_dirty = 1;
+               }
+               return (nb);
+       }
+
+       /*
+        * addresses 18 and 19 have single and double indirect blocks.
+        * the first step is to determine how many levels of indirection.
+        */
+       bn -= 18;
+       sh = 0;
+       j = 2;
+       if (bn & 0xff00) {      /* bn > 255  so double indirect */
+               sh = 8;
+               bn -= 256;
+               j = 1;
+       }
+
+       /*
+        * fetch the address from the inode
+        * Create the first indirect block if needed.
+        */
+       ifnot(nb = swizzle16(ip->c_node.i_addr[20 - j])) {
+               if (rwflg || !(nb = blk_alloc(dev)))
+                       return (NULLBLK);
+               ip->c_node.i_addr[20 - j] = swizzle16(nb);
+               ip->c_dirty = 1;
+       }
+
+       /*
+        * fetch through the indirect blocks
+        */
+       for (; j <= 2; j++) {
+               bp = (bufptr) bread(dev, nb, 0);
+               /******
+                if(bp->bf_error) {
+                        brelse(bp);
+                        return((blkno_t)0);
+                }
+                ******/
+               i = (bn >> sh) & 0xff;
+               if ((swizzle16(nb) == ((blkno_t *) bp)[i]))
+                       brelse(bp);
+               else {
+                       if (rwflg || !(nb = blk_alloc(dev))) {
+                               brelse(bp);
+                               return (NULLBLK);
+                       }
+                       ((blkno_t *) bp)[i] = swizzle16(nb);
+                       bawrite(bp);
+               }
+               sh -= 8;
+       }
+       return (nb);
+}
+
+
+
+/* Validblk panics if the given block number is not a valid
+ *  data block for the given device.
+ */
+static void validblk(int dev, blkno_t num)
+{
+       register fsptr devptr;
+
+       devptr = fs_tab + dev;
+
+       if (devptr->s_mounted == 0)
+               panic("validblk: not mounted");
+
+       if (num < swizzle16(devptr->s_isize)
+           || num >= swizzle16(devptr->s_fsize))
+               panic("validblk: invalid blk");
+}
+
+
+/* This returns the inode pointer associated with a user's file
+ * descriptor, checking for valid data structures.
+ */
+static inoptr getinode(int uindex)
+{
+       register int oftindex;
+       register inoptr inoindex;
+
+       if (uindex < 0 || uindex >= UFTSIZE
+           || udata.u_files[uindex] & 0x80) {
+               udata.u_error = EBADF;
+               return (NULLINODE);
+       }
+
+       if ((oftindex = udata.u_files[uindex]) < 0 || oftindex >= OFTSIZE)
+               panic("Getinode: bad desc table");
+
+       if ((inoindex = of_tab[oftindex].o_inode) < i_tab ||
+           inoindex >= i_tab + ITABSIZE)
+               panic("Getinode: bad OFT");
+
+       magic(inoindex);
+
+       return (inoindex);
+}
+
+/* This sets the times of the given inode, according to the flags.
+ */
+static void setftime(inoptr ino, int flag)
+{
+       time_t now;
+       ino->c_dirty = 1;
+
+       now = time(NULL);
+
+       if (flag & A_TIME)
+               ino->c_node.i_atime = swizzle32(now);
+       if (flag & M_TIME)
+               ino->c_node.i_mtime = swizzle32(now);
+       if (flag & C_TIME)
+               ino->c_node.i_ctime = swizzle32(now);
+}
+
+
+static int fuzix_getmode(inoptr ino)
+{
+       return (swizzle16(ino->c_node.i_mode) & F_MASK);
+}
+
+
+/* Fmount places the given device in the mount table with mount point ino.
+ */
+static int fmount(int dev, inoptr ino)
+{
+       char *buf;
+       register struct filesys *fp;
+
+       /* Dev 0 blk 1 */
+       fp = fs_tab + dev;
+       buf = bread(dev, 1, 0);
+       bcopy(buf, (char *) fp, sizeof(struct filesys));
+       brelse((bufptr) buf);
+
+       /* See if there really is a filesystem on the device */
+       if (fp->s_mounted == SMOUNTED_WRONGENDIAN)
+               swizzling = 1;
+       if (swizzle16(fp->s_mounted) != SMOUNTED ||
+           swizzle16(fp->s_isize) >= swizzle16(fp->s_fsize))
+               return (-1);
+
+       fp->s_mntpt = ino;
+       if (ino)
+               ++ino->c_refs;
+
+       return (0);
+}
+
+static void magic(inoptr ino)
+{
+       if (ino->c_magic != CMAGIC)
+               panic("Corrupt inode");
+}
+
+static char *bread(int dev, blkno_t blk, int rewrite)
+{
+       register bufptr bp;
+
+/*printf("Reading block %d\n", blk);*/
+
+       bp = bfind(dev, blk);
+       if (bp) {
+               if (bp->bf_busy)
+                       panic("want busy block");
+               goto done;
+       }
+       bp = freebuf();
+       bp->bf_dev = dev;
+       bp->bf_blk = blk;
+
+       /* If rewrite is set, we are about to write over the entire block,
+          so we don't need the previous contents */
+
+       ifnot(rewrite)
+           if (bdread(bp) == -1) {
+               udata.u_error = EIO;
+               return 0;
+       }
+
+done:
+       bp->bf_busy = 1;
+       bp->bf_time = ++bufclock;       /* Time stamp it */
+       return (bp->bf_data);
+}
+
+
+static void brelse(bufptr bp)
+{
+/*printf("Releasing block %d (0)\n", bp->bf_blk);*/
+       bfree(bp, 0);
+}
+
+static void bawrite(bufptr bp)
+{
+/*printf("Releasing block %d (1)\n", bp->bf_blk);*/
+       bfree(bp, 1);
+}
+
+static int bfree(bufptr bp, int dirty)
+{
+/*printf("Releasing block %d (%d)\n", bp->bf_blk, dirty);*/
+       bp->bf_dirty |= dirty;
+       bp->bf_busy = 0;
+
+       if (dirty == 2) {       /* Extra dirty */
+               if (bdwrite(bp) == -1)
+                       udata.u_error = EIO;
+               bp->bf_dirty = 0;
+               return (-1);
+       }
+       return (0);
+}
+
+
+/* This returns a busy block not belonging to any device, with
+ * garbage contents.  It is essentially a malloc for the kernel.
+ * Free it with brelse()!
+ */
+static char *tmpbuf(void)
+{
+       bufptr bp;
+       bufptr freebuf();
+
+/*printf("Allocating temp block\n");*/
+       bp = freebuf();
+       bp->bf_dev = -1;
+       bp->bf_busy = 1;
+       bp->bf_time = ++bufclock;       /* Time stamp it */
+       return (bp->bf_data);
+}
+
+
+static char *zerobuf(void)
+{
+       char *b;
+       char *tmpbuf();
+
+       b = tmpbuf();
+       bzero(b, 512);
+       return (b);
+}
+
+
+static void bufsync(void)
+{
+       register bufptr bp;
+
+       for (bp = bufpool; bp < bufpool + NBUFS; ++bp) {
+               if (bp->bf_dev != -1 && bp->bf_dirty) {
+                       bdwrite(bp);
+                       if (!bp->bf_busy)
+                               bp->bf_dirty = 0;
+               }
+       }
+}
+
+static bufptr bfind(int dev, blkno_t blk)
+{
+       register bufptr bp;
+
+       for (bp = bufpool; bp < bufpool + NBUFS; ++bp) {
+               if (bp->bf_dev == dev && bp->bf_blk == blk)
+                       return (bp);
+       }
+       return (NULL);
+}
+
+
+static bufptr freebuf(void)
+{
+       register bufptr bp;
+       register bufptr oldest;
+       register int oldtime;
+
+       /* Try to find a non-busy buffer and write out the data if it is dirty */
+       oldest = NULL;
+       oldtime = 0;
+       for (bp = bufpool; bp < bufpool + NBUFS; ++bp) {
+               if (bufclock - bp->bf_time >= oldtime && !bp->bf_busy) {
+                       oldest = bp;
+                       oldtime = bufclock - bp->bf_time;
+               }
+       }
+       ifnot(oldest)
+           panic("no free buffers");
+
+       if (oldest->bf_dirty) {
+               if (bdwrite(oldest) == -1)
+                       udata.u_error = EIO;
+               oldest->bf_dirty = 0;
+       }
+       return (oldest);
+}
+
+static void bufinit(void)
+{
+       register bufptr bp;
+
+       for (bp = bufpool; bp < bufpool + NBUFS; ++bp) {
+               bp->bf_dev = -1;
+       }
+}
+
+
+/*********************************************************************
+Bdread() and bdwrite() are the block device interface routines.  they
+are given a buffer pointer, which contains the device, block number,
+and data location.  They basically validate the device and vector the
+call.
+
+Cdread() and cdwrite are the same for character (or "raw") devices,
+and are handed a device number.  Udata.u_base, count, and offset have
+the rest of the data.
+**********************************************************************/
+
+static int bdread(bufptr bp)
+{
+//    printf("bdread(fd=%d, block %d)\n", dev_fd, bp->bf_blk);
+
+       udata.u_buf = bp;
+       if (lseek
+           (dev_fd, dev_offset + (((int) bp->bf_blk) * 512),
+            SEEK_SET) == -1)
+               perror("lseek");
+       if (read(dev_fd, bp->bf_data, 512) != 512)
+               panic("read() failed");
+
+       return 0;
+}
+
+
+static int bdwrite(bufptr bp)
+{
+       udata.u_buf = bp;
+
+       lseek(dev_fd, dev_offset + (((int) bp->bf_blk) * 512), SEEK_SET);
+       if (write(dev_fd, bp->bf_data, 512) != 512)
+               panic("write() failed");
+       return 0;
+}
index 657a993..a4ce42e 100644 (file)
@@ -11,7 +11,6 @@
 
 int dev_fd;
 int dev_offset;
-struct u_data udata;
 
 extern int swizzling;
 
diff --git a/Standalone/xfs1.c b/Standalone/xfs1.c
deleted file mode 100644 (file)
index ca1dff6..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-/**************************************************
-UZI (Unix Z80 Implementation) Utilities:  xfs1.c
-***************************************************/
-
- /*LINTLIBRARY*/
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include "fuzix_fs.h"
-void fs_init(void)
-{
-       udata.u_euid = 0;
-       udata.u_insys = 1;
-}
-
-void xfs_init(int bootdev)
-{
-       register char *j;
-       inoptr i_open();
-
-       fs_init();
-       bufinit();
-
-       /* User's file table */
-       for (j = udata.u_files; j < (udata.u_files + UFTSIZE); ++j)
-               *j = -1;
-
-       /* Mount the root device */
-       if (fmount(ROOTDEV, NULLINODE))
-               panic("no filesys");
-
-       ifnot(root = i_open(ROOTDEV, ROOTINODE))
-           panic("no root");
-
-       i_ref(udata.u_cwd = root);
-}
-
-
-void xfs_end(void)
-{
-       register int16_t j;
-
-       for (j = 0; j < UFTSIZE; ++j) {
-               ifnot(udata.u_files[j] & 0x80)  /* Portable equivalent of == -1 */
-                   doclose(j);
-       }
-}
-
-
-int _open(char *name, int16_t flag)
-{
-       int16_t uindex;
-       register int16_t oftindex;
-       register inoptr ino;
-       register int16_t perm;
-       inoptr n_open();
-       int getperm(), fuzix_getmode(), isdevice(), d_open();
-       int uf_alloc(), oft_alloc();
-
-       udata.u_error = 0;
-
-       if (flag < 0 || flag > 2) {
-               udata.u_error = EINVAL;
-               return (-1);
-       }
-       if ((uindex = uf_alloc()) == -1)
-               return (-1);
-
-       if ((oftindex = oft_alloc()) == -1)
-               goto nooft;
-
-       ifnot(ino = n_open(name, NULLINOPTR))
-           goto cantopen;
-
-       of_tab[oftindex].o_inode = ino;
-
-       perm = getperm(ino);
-       if (((flag == FO_RDONLY || flag == FO_RDWR) && !(perm & OTH_RD)) ||
-           ((flag == FO_WRONLY || flag == FO_RDWR) && !(perm & OTH_WR))) {
-               udata.u_error = EPERM;
-               goto cantopen;
-       }
-
-       if (fuzix_getmode(ino) == F_DIR &&
-           (flag == FO_WRONLY || flag == FO_RDWR)) {
-               udata.u_error = EISDIR;
-               goto cantopen;
-       }
-
-       if (isdevice(ino))      // && d_open((int)ino->c_node.i_addr[0]) != 0)
-       {
-               udata.u_error = ENXIO;
-               goto cantopen;
-       }
-
-       udata.u_files[uindex] = oftindex;
-
-       of_tab[oftindex].o_ptr = 0;
-       of_tab[oftindex].o_access = flag;
-
-       return (uindex);
-
-      cantopen:
-       oft_deref(oftindex);    /* This will call i_deref() */
-      nooft:
-       udata.u_files[uindex] = -1;
-       return (-1);
-}
-
-int doclose(int16_t uindex)
-{
-       register int16_t oftindex;
-       inoptr ino;
-       inoptr getinode();
-       int isdevice();
-
-       udata.u_error = 0;
-       ifnot(ino = getinode(uindex))
-           return (-1);
-       oftindex = udata.u_files[uindex];
-
-       //if (isdevice(ino)
-       //        /* && ino->c_refs == 1 && of_tab[oftindex].o_refs == 1 */ )
-       //    d_close((int)(ino->c_node.i_addr[0]));
-
-       udata.u_files[uindex] = -1;
-       oft_deref(oftindex);
-
-       return (0);
-}
-
-int _close(int16_t uindex)
-{
-       udata.u_error = 0;
-       return (doclose(uindex));
-}
-
-int _creat(char *name, int16_t mode)
-{
-       register inoptr ino;
-       register int16_t uindex;
-       register int16_t oftindex;
-       inoptr parent;
-       register int16_t j;
-       inoptr n_open();
-       inoptr newfile();
-       int getperm(), fuzix_getmode(), uf_alloc(), oft_alloc();
-
-       udata.u_error = 0;
-       parent = NULLINODE;
-
-       if ((uindex = uf_alloc()) == -1)
-               return (-1);
-       if ((oftindex = oft_alloc()) == -1)
-               return (-1);
-
-       ino = n_open(name, &parent);
-       if (ino) {
-               i_deref(parent);
-               if (fuzix_getmode(ino) == F_DIR) {
-                       i_deref(ino);
-                       udata.u_error = EISDIR;
-                       goto nogood;
-               }
-               ifnot(getperm(ino) & OTH_WR) {
-                       i_deref(ino);
-                       udata.u_error = EACCES;
-                       goto nogood;
-               }
-               if (fuzix_getmode(ino) == F_REG) {
-                       /* Truncate the file to zero length */
-                       f_trunc(ino);
-                       /* Reset any oft pointers */
-                       for (j = 0; j < OFTSIZE; ++j)
-                               if (of_tab[j].o_inode == ino)
-                                       of_tab[j].o_ptr = 0;
-               }
-       } else {
-               if (parent && (ino = newfile(parent, name)))
-                       /* Parent was derefed in newfile */
-               {
-                       ino->c_node.i_mode =
-                           swizzle16(F_REG |
-                                     (mode & MODE_MASK & ~udata.u_mask));
-                       setftime(ino, A_TIME | M_TIME | C_TIME);
-                       /* The rest of the inode is initialized in newfile() */
-                       wr_inode(ino);
-               } else {
-                       /* Doesn't exist and can't make it */
-                       if (parent)
-                               i_deref(parent);
-                       goto nogood;
-               }
-       }
-       udata.u_files[uindex] = oftindex;
-
-       of_tab[oftindex].o_ptr = 0;
-       of_tab[oftindex].o_inode = ino;
-       of_tab[oftindex].o_access = FO_WRONLY;
-
-       return (uindex);
-
-      nogood:
-       oft_deref(oftindex);
-       return (-1);
-}
-
-int _link(char *name1, char *name2)
-{
-       register inoptr ino;
-       register inoptr ino2;
-       inoptr parent2;
-       char *filename();
-       inoptr n_open();
-       int ch_link(), fuzix_getmode(), super();
-
-       udata.u_error = 0;
-       ifnot(ino = n_open(name1, NULLINOPTR))
-           return (-1);
-
-       if (fuzix_getmode(ino) == F_DIR && !super()) {
-               udata.u_error = EPERM;
-               goto nogood;
-       }
-
-       /* Make sure file2 doesn't exist, and get its parent */
-       if ((ino2 = n_open(name2, &parent2))) {
-               i_deref(ino2);
-               i_deref(parent2);
-               udata.u_error = EEXIST;
-               goto nogood;
-       }
-
-       ifnot(parent2)
-           goto nogood;
-
-       if (ino->c_dev != parent2->c_dev) {
-               i_deref(parent2);
-               udata.u_error = EXDEV;
-               goto nogood;
-       }
-
-       if (ch_link(parent2, "", filename(name2), ino) == 0)
-               goto nogood;
-
-       /* Update the link count. */
-       ino->c_node.i_nlink =
-           swizzle16(swizzle16(ino->c_node.i_nlink) + 1);
-       wr_inode(ino);
-       setftime(ino, C_TIME);
-
-       i_deref(parent2);
-       i_deref(ino);
-       return (0);
-
-      nogood:
-       i_deref(ino);
-       return (-1);
-}
-
-int _unlink(char *path)
-{
-       register inoptr ino;
-       inoptr pino;
-       char *filename();
-    /*--    inoptr i_open();--*/
-       inoptr n_open();
-       int fuzix_getmode(), ch_link(), super();
-
-       udata.u_error = 0;
-       ino = n_open(path, &pino);
-
-       ifnot(pino && ino) {
-               udata.u_error = ENOENT;
-               return (-1);
-       }
-
-       if (fuzix_getmode(ino) == F_DIR && !super()) {
-               udata.u_error = EPERM;
-               goto nogood;
-       }
-
-       /* Remove the directory entry */
-
-       if (ch_link(pino, filename(path), "", NULLINODE) == 0)
-               goto nogood;
-
-       /* Decrease the link count of the inode */
-
-       if (ino->c_node.i_nlink == 0) {
-               ino->c_node.i_nlink =
-                   swizzle16(swizzle16(ino->c_node.i_nlink) + 2);
-               printf("_unlink: bad nlink\n");
-       } else
-               ino->c_node.i_nlink =
-                   swizzle16(swizzle16(ino->c_node.i_nlink) - 1);
-       setftime(ino, C_TIME);
-       i_deref(pino);
-       i_deref(ino);
-       return (0);
-      nogood:
-       i_deref(pino);
-       i_deref(ino);
-       return (-1);
-}
-
-int _read(int16_t d, char *buf, uint16_t nbytes)
-{
-       register inoptr ino;
-       inoptr rwsetup();
-
-       udata.u_error = 0;
-       /* Set up u_base, u_offset, ino; check permissions, file num. */
-       if ((ino = rwsetup(1, d, buf, nbytes)) == NULLINODE)
-               return (-1);    /* bomb out if error */
-
-       readi(ino);
-       updoff(d);
-
-       return (udata.u_count);
-}
-
-int _write(int16_t d, char *buf, uint16_t nbytes)
-{
-       register inoptr ino;
-    /*--    off_t *offp;--*/
-       inoptr rwsetup();
-
-       udata.u_error = 0;
-       /* Set up u_base, u_offset, ino; check permissions, file num. */
-       if ((ino = rwsetup(0, d, buf, nbytes)) == NULLINODE)
-               return (-1);    /* bomb out if error */
-
-       writei(ino);
-       updoff(d);
-
-       return (udata.u_count);
-}
-
-inoptr rwsetup(int rwflag, int d, char *buf, int nbytes)
-{
-       register inoptr ino;
-       register struct oft *oftp;
-       inoptr getinode();
-
-       udata.u_base = buf;
-       udata.u_count = nbytes;
-
-       if ((ino = getinode(d)) == NULLINODE)
-               return (NULLINODE);
-
-       oftp = of_tab + udata.u_files[d];
-       if (oftp->o_access == (rwflag ? FO_WRONLY : FO_RDONLY)) {
-               udata.u_error = EBADF;
-               return (NULLINODE);
-       }
-
-       setftime(ino, rwflag ? A_TIME : (A_TIME | M_TIME | C_TIME));
-
-       /* Initialize u_offset from file pointer */
-       udata.u_offset = oftp->o_ptr;
-
-       return (ino);
-}
-
-int psize(inoptr ino)
-{
-       return swizzle32(ino->c_node.i_size);
-}
diff --git a/Standalone/xfs1a.c b/Standalone/xfs1a.c
deleted file mode 100644 (file)
index 96c212e..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/**************************************************
-  UZI (Unix Z80 Implementation) Utilities:  xfs1a.c
- ***************************************************/
-/* Revisions:
- *  1.4.98 - Split xfs.c into parts for compilation with Hi-Tech C.   HFB
- */
-
- /*LINTLIBRARY*/
-#include <stddef.h>
-#include <stdint.h>
-#include <strings.h>
-#include "fuzix_fs.h"
-
-int32_t _lseek(int16_t file, int32_t offset, int16_t flag)
-{
-       register inoptr ino;
-       register int32_t retval;
-       register int oftno;
-
-       udata.u_error = 0;
-       if ((ino = getinode(file)) == NULLINODE)
-               return (-1);
-
-       oftno = udata.u_files[file];
-
-       retval = of_tab[oftno].o_ptr;
-
-       switch (flag) {
-       case 0:
-               of_tab[oftno].o_ptr = offset;
-               break;
-       case 1:
-               of_tab[oftno].o_ptr += offset;
-               break;
-       case 2:
-               of_tab[oftno].o_ptr =
-                   swizzle32(ino->c_node.i_size) + offset;
-               break;
-       default:
-               udata.u_error = EINVAL;
-               return (-1);
-       }
-       retval = of_tab[oftno].o_ptr;
-       return retval;
-}
-
-
-
-void readi(inoptr ino)
-{
-       register uint16_t amount;
-       register uint16_t toread;
-       register blkno_t pblk;
-       register char *bp;
-       int dev;
-
-       dev = ino->c_dev;
-       switch (fuzix_getmode(ino)) {
-
-       case F_DIR:
-       case F_REG:
-
-               /* See of end of file will limit read */
-               toread = udata.u_count =
-                   min(udata.u_count,
-                       swizzle32(ino->c_node.i_size) - udata.u_offset);
-               goto loop;
-
-       case F_BDEV:
-               toread = udata.u_count;
-               dev = swizzle16(*(ino->c_node.i_addr));
-
-             loop:
-               while (toread) {
-                       if ((pblk =
-                            bmap(ino, udata.u_offset >> 9, 1)) != NULLBLK)
-                               bp = bread(dev, pblk, 0);
-                       else
-                               bp = zerobuf();
-
-                       bcopy(bp + (udata.u_offset & 511), udata.u_base,
-                             (amount =
-                              min(toread, 512 - (udata.u_offset & 511))));
-                       brelse((bufptr) bp);
-
-                       udata.u_base += amount;
-                       udata.u_offset += amount;
-                       toread -= amount;
-               }
-               break;
-
-       default:
-               udata.u_error = ENODEV;
-       }
-}
-
-
-
-/* Writei (and readi) need more i/o error handling */
-
-void writei(inoptr ino)
-{
-       register uint16_t amount;
-       register uint16_t towrite;
-       register char *bp;
-       blkno_t pblk;
-       int dev;
-
-       dev = ino->c_dev;
-
-       switch (fuzix_getmode(ino)) {
-
-       case F_BDEV:
-               dev = swizzle16(*(ino->c_node.i_addr));
-       case F_DIR:
-       case F_REG:
-               towrite = udata.u_count;
-               goto loop;
-
-             loop:
-               while (towrite) {
-                       amount =
-                           min(towrite, 512 - (udata.u_offset & 511));
-
-                       if ((pblk =
-                            bmap(ino, udata.u_offset >> 9, 0)) == NULLBLK)
-                               break;  /* No space to make more blocks */
-
-                       /* If we are writing an entire block, we don't care
-                          about its previous contents */
-                       bp = bread(dev, pblk, (amount == 512));
-
-                       bcopy(udata.u_base, bp + (udata.u_offset & 511),
-                             amount);
-                       bawrite((bufptr) bp);
-
-                       udata.u_base += amount;
-                       udata.u_offset += amount;
-                       towrite -= amount;
-               }
-
-               /* Update size if file grew */
-               if (udata.u_offset > swizzle32(ino->c_node.i_size)) {
-                       ino->c_node.i_size = swizzle32(udata.u_offset);
-                       ino->c_dirty = 1;
-               }
-               break;
-
-       default:
-               udata.u_error = ENODEV;
-       }
-}
-
-
-
-void updoff(int d)
-{
-       /* Update current file pointer */
-       of_tab[udata.u_files[d]].o_ptr = udata.u_offset;
-}
diff --git a/Standalone/xfs1b.c b/Standalone/xfs1b.c
deleted file mode 100644 (file)
index 24d0c19..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-/**************************************************
-  UZI (Unix Z80 Implementation) Utilities:  xfs1a1.c
- ***************************************************/
-
- /*LINTLIBRARY*/
-#include <stddef.h>
-#include <stdint.h>
-#include <strings.h>
-#include "fuzix_fs.h"
-
-
-struct cinode i_tab[ITABSIZE];
-struct filesys fs_tab[1];
-
-int valadr(char *base, uint16_t size)
-{
-       return (1);
-}
-
-
-int _mknod(char *name, int16_t mode, int16_t dev)
-{
-       register inoptr ino;
-       inoptr parent;
-
-       udata.u_error = 0;
-       ifnot(super()) {
-               udata.u_error = EPERM;
-               return (-1);
-       }
-
-       if ((ino = n_open(name, &parent))) {
-               udata.u_error = EEXIST;
-               goto nogood;
-       }
-
-       ifnot(parent) {
-               udata.u_error = ENOENT;
-               return (-1);
-       }
-
-       ifnot(ino = newfile(parent, name))
-           goto nogood2;
-
-       /* Initialize mode and dev */
-       ino->c_node.i_mode = swizzle16(mode & ~udata.u_mask);
-       ino->c_node.i_addr[0] = swizzle16(isdevice(ino) ? dev : 0);
-       setftime(ino, A_TIME | M_TIME | C_TIME);
-       wr_inode(ino);
-
-       i_deref(ino);
-       return (0);
-
-      nogood:
-       i_deref(ino);
-      nogood2:
-       i_deref(parent);
-       return (-1);
-}
-
-void _sync(void)
-{
-       int j;
-       inoptr ino;
-       char *buf;
-
-       /* Write out modified inodes */
-
-       udata.u_error = 0;
-       for (ino = i_tab; ino < i_tab + ITABSIZE; ++ino)
-               if ((ino->c_refs) > 0 && ino->c_dirty != 0) {
-                       wr_inode(ino);
-                       ino->c_dirty = 0;
-               }
-
-       /* Write out modified super blocks */
-       /* This fills the rest of the super block with garbage. */
-
-       for (j = 0; j < NDEVS; ++j) {
-               if (swizzle16(fs_tab[j].s_mounted) == SMOUNTED
-                   && fs_tab[j].s_fmod) {
-                       fs_tab[j].s_fmod = 0;
-                       buf = bread(j, 1, 1);
-                       bcopy((char *) &fs_tab[j], buf, 512);
-                       bfree((bufptr) buf, 2);
-               }
-       }
-       bufsync();              /* Clear buffer pool */
-}
-
-int _chdir(char *dir)
-{
-       register inoptr newcwd;
-       inoptr n_open();
-       int fuzix_getmode();
-
-       udata.u_error = 0;
-       ifnot(newcwd = n_open(dir, NULLINOPTR))
-           return (-1);
-
-       if (fuzix_getmode(newcwd) != F_DIR) {
-               udata.u_error = ENOTDIR;
-               i_deref(newcwd);
-               return (-1);
-       }
-       i_deref(udata.u_cwd);
-       udata.u_cwd = newcwd;
-       return (0);
-}
-
-int min(int a, int b)
-{
-       return (a < b ? a : b);
-}
-
-int _access(char *path, int16_t mode)
-{
-       register inoptr ino;
-       register int16_t euid;
-       register int16_t egid;
-       register int16_t retval;
-       inoptr n_open();
-       int getperm();
-
-       udata.u_error = 0;
-       if ((mode & 07) && !*(path)) {
-               udata.u_error = ENOENT;
-               return (-1);
-       }
-
-       /* Temporarily make eff. id real id. */
-       euid = udata.u_euid;
-       egid = udata.u_egid;
-       udata.u_euid = 0;       // udata.u_ptab->p_uid;
-       udata.u_egid = 0;       // udata.u_gid;
-
-       ifnot(ino = n_open(path, NULLINOPTR)) {
-               retval = -1;
-               goto nogood;
-       }
-
-       retval = 0;
-       if (~getperm(ino) & (mode & 07)) {
-               udata.u_error = EPERM;
-               retval = -1;
-       }
-
-       i_deref(ino);
-nogood:
-       udata.u_euid = euid;
-       udata.u_egid = egid;
-
-       return (retval);
-}
-
-int _chmod(char *path, int16_t mode)
-{
-       inoptr ino;
-       inoptr n_open();
-       int super();
-
-       udata.u_error = 0;
-       ifnot(ino = n_open(path, NULLINOPTR))
-           return (-1);
-
-       if (swizzle16(ino->c_node.i_uid) != udata.u_euid && !super()) {
-               i_deref(ino);
-               udata.u_error = EPERM;
-               return (-1);
-       }
-       ino->c_node.i_mode =
-           swizzle16((mode & MODE_MASK) |
-                     (swizzle16(ino->c_node.i_mode) & F_MASK));
-       setftime(ino, C_TIME);
-       i_deref(ino);
-       return (0);
-}
-
-int _chown(char *path, int owner, int group)
-{
-       register inoptr ino;
-       inoptr n_open();
-       int super();
-
-       udata.u_error = 0;
-       ifnot(ino = n_open(path, NULLINOPTR))
-           return (-1);
-
-       if (swizzle16(ino->c_node.i_uid) != udata.u_euid && !super()) {
-               i_deref(ino);
-               udata.u_error = EPERM;
-               return (-1);
-       }
-
-       ino->c_node.i_uid = swizzle16(owner);
-       ino->c_node.i_gid = swizzle16(group);
-       setftime(ino, C_TIME);
-       i_deref(ino);
-       return (0);
-}
-
-int _stat(char *path, struct uzi_stat *buf)
-{
-       register inoptr ino;
-
-       udata.u_error = 0;
-       ifnot(valadr((char *) buf, sizeof(struct uzi_stat))
-             && (ino = n_open(path, NULLINOPTR))) {
-               return (-1);
-       }
-       stcpy(ino, buf);
-       i_deref(ino);
-       return (0);
-}
-
-int _fstat(int16_t fd, struct uzi_stat *buf)
-{
-       register inoptr ino;
-
-       udata.u_error = 0;
-       ifnot(valadr((char *) buf, sizeof(struct uzi_stat)))
-           return (-1);
-
-       if ((ino = getinode(fd)) == NULLINODE)
-               return (-1);
-
-       stcpy(ino, buf);
-       return (0);
-}
-
-/* Utility for stat and fstat */
-void stcpy(inoptr ino, struct uzi_stat *buf)
-{
-       struct uzi_stat *b = (struct uzi_stat *) buf;
-
-       b->st_dev = swizzle16(ino->c_dev);
-       b->st_ino = swizzle16(ino->c_num);
-       b->st_mode = swizzle16(ino->c_node.i_mode);
-       b->st_nlink = swizzle16(ino->c_node.i_nlink);
-       b->st_uid = swizzle16(ino->c_node.i_uid);
-       b->st_gid = swizzle16(ino->c_node.i_gid);
-
-       b->st_rdev = swizzle16(ino->c_node.i_addr[0]);
-
-       b->st_size = swizzle32(ino->c_node.i_size);
-       b->fst_atime = swizzle32(ino->c_node.i_atime);
-       b->fst_mtime = swizzle32(ino->c_node.i_mtime);
-       b->fst_ctime = swizzle32(ino->c_node.i_ctime);
-}
-
-int _dup(int16_t oldd)
-{
-       register int newd;
-       inoptr getinode();
-       int uf_alloc();
-
-       udata.u_error = 0;
-       if (getinode(oldd) == NULLINODE)
-               return (-1);
-
-       if ((newd = uf_alloc()) == -1)
-               return (-1);
-
-       udata.u_files[newd] = udata.u_files[oldd];
-       ++of_tab[udata.u_files[oldd]].o_refs;
-
-       return (newd);
-}
-
-int _dup2(int16_t oldd, int16_t newd)
-{
-       inoptr getinode();
-
-       udata.u_error = 0;
-       if (getinode(oldd) == NULLINODE)
-               return (-1);
-
-       if (newd < 0 || newd >= UFTSIZE) {
-               udata.u_error = EBADF;
-               return (-1);
-       }
-
-       ifnot(udata.u_files[newd] & 0x80)
-           doclose(newd);
-
-       udata.u_files[newd] = udata.u_files[oldd];
-       ++of_tab[udata.u_files[oldd]].o_refs;
-
-       return (0);
-}
-
-int _umask(int mask)
-{
-       register int omask;
-
-       udata.u_error = 0;
-       omask = udata.u_mask;
-       udata.u_mask = mask & 0777;
-       return (omask);
-}
-
-/* Special system call returns super-block of given filesystem for
- * users to determine free space, etc.  Should be replaced with a
- * sync() followed by a read of block 1 of the device.
- */
-
-int _getfsys(int dev, char *buf)
-{
-       udata.u_error = 0;
-       if (dev < 0 || dev >= NDEVS
-           || swizzle16(fs_tab[dev].s_mounted) != SMOUNTED) {
-               udata.u_error = ENXIO;
-               return (-1);
-       }
-
-       /* FIXME: endiam swapping here */
-       bcopy((char *) &fs_tab[dev], (char *) buf, sizeof(struct filesys));
-       return (0);
-}
-
-int _ioctl(int fd, int request, char *data)
-{
-       register inoptr ino;
-       // register int dev;
-
-       udata.u_error = 0;
-       if ((ino = getinode(fd)) == NULLINODE)
-               return (-1);
-
-       ifnot(isdevice(ino)) {
-               udata.u_error = ENOTTY;
-               return (-1);
-       }
-
-       ifnot(getperm(ino) & OTH_WR) {
-               udata.u_error = EPERM;
-               return (-1);
-       }
-
-       // dev = ino->c_node.i_addr[0];
-
-       // if (d_ioctl(dev, request,data))
-       //     return(-1);
-
-       return (0);
-}
-
-int _mount(char *spec, char *dir, int rwflag)
-{
-       register inoptr sino, dino;
-       register int dev;
-
-       udata.u_error = 0;
-       ifnot(super()) {
-               udata.u_error = EPERM;
-               return (-1);
-       }
-       ifnot(sino = n_open(spec, NULLINOPTR))
-           return (-1);
-
-       ifnot(dino = n_open(dir, NULLINOPTR)) {
-               i_deref(sino);
-               return (-1);
-       }
-       if (fuzix_getmode(sino) != F_BDEV) {
-               udata.u_error = ENOTBLK;
-               goto nogood;
-       }
-       if (fuzix_getmode(dino) != F_DIR) {
-               udata.u_error = ENOTDIR;
-               goto nogood;
-       }
-       dev = (int) swizzle16(sino->c_node.i_addr[0]);
-
-       if (dev >= NDEVS)       // || d_open(dev))
-       {
-               udata.u_error = ENXIO;
-               goto nogood;
-       }
-       if (fs_tab[dev].s_mounted || dino->c_refs != 1
-           || dino->c_num == ROOTINODE) {
-               udata.u_error = EBUSY;
-               goto nogood;
-       }
-       _sync();
-
-       if (fmount(dev, dino)) {
-               udata.u_error = EBUSY;
-               goto nogood;
-       }
-       i_deref(dino);
-       i_deref(sino);
-       return (0);
-      nogood:
-       i_deref(dino);
-       i_deref(sino);
-       return (-1);
-}
-
-int _umount(char *spec)
-{
-       register inoptr sino;
-       register int dev;
-       register inoptr ptr;
-
-       udata.u_error = 0;
-       ifnot(super()) {
-               udata.u_error = EPERM;
-               return (-1);
-       }
-
-       ifnot(sino = n_open(spec, NULLINOPTR))
-           return (-1);
-
-       if (fuzix_getmode(sino) != F_BDEV) {
-               udata.u_error = ENOTBLK;
-               goto nogood;
-       }
-
-       dev = (int) swizzle16(sino->c_node.i_addr[0]);
-       //ifnot (validdev(dev))
-       //{
-       //    udata.u_error = ENXIO;
-       //    goto nogood;
-       //}
-
-       if (!fs_tab[dev].s_mounted) {
-               udata.u_error = EINVAL;
-               goto nogood;
-       }
-
-       for (ptr = i_tab; ptr < i_tab + ITABSIZE; ++ptr)
-               if (ptr->c_refs > 0 && ptr->c_dev == dev) {
-                       udata.u_error = EBUSY;
-                       goto nogood;
-               }
-       _sync();
-       fs_tab[dev].s_mounted = 0;
-       i_deref(fs_tab[dev].s_mntpt);
-
-       i_deref(sino);
-       return (0);
-
-      nogood:
-       i_deref(sino);
-       return (-1);
-}
diff --git a/Standalone/xfs2.c b/Standalone/xfs2.c
deleted file mode 100644 (file)
index 7a8f558..0000000
+++ /dev/null
@@ -1,1017 +0,0 @@
-/**************************************************
-UZI (Unix Z80 Implementation) Utilities:  xfs2.c
-***************************************************/
-
-/* Revisions:
- *  25.2.96      Bug fix in i_deref()     SN
- */
-
- /*LINTLIBRARY*/
-#include <time.h>
-#include <stdio.h>
-#include <strings.h>
-#include <stdint.h>
-#include "fuzix_fs.h"
-
-/* UZI180 NOTE: This file is basically the FILESYS.C module.   HFB */
-/* N_open is given a string containing a path name, and returns
- * an inode table pointer.  If it returns NULL, the file did not
- * exist.  If the parent existed, and parent is not null, parent
- * will be filled in with the parents inoptr. Otherwise, parent
- * will be set to NULL.
- */
-
-inoptr root;
-struct oft of_tab[OFTSIZE];
-
-inoptr n_open(register char *name, register inoptr * parent)
-{
-       register inoptr wd;     /* the directory we are currently searching. */
-       register inoptr ninode;
-       register inoptr temp;
-
-       if (*name == '/')
-               wd = root;
-       else
-               wd = udata.u_cwd;
-
-       i_ref(ninode = wd);
-       i_ref(ninode);
-
-       for (;;) {
-               if (ninode)
-                       magic(ninode);
-
-               /* See if we are at a mount point */
-               if (ninode)
-                       ninode = srch_mt(ninode);
-
-               while (*name == '/')    /* Skip (possibly repeated) slashes */
-                       ++name;
-               ifnot(*name)    /* No more components of path? */
-                   break;
-               ifnot(ninode) {
-                       udata.u_error = ENOENT;
-                       goto nodir;
-               }
-               i_deref(wd);
-               wd = ninode;
-               if (fuzix_getmode(wd) != F_DIR) {
-                       udata.u_error = ENOTDIR;
-                       goto nodir;
-               }
-               ifnot(getperm(wd) & OTH_EX) {
-                       udata.u_error = EPERM;
-                       goto nodir;
-               }
-
-               /* See if we are going up through a mount point */
-               if (wd->c_num == ROOTINODE && wd->c_dev != ROOTDEV
-                   && name[1] == '.') {
-                       temp = fs_tab[wd->c_dev].s_mntpt;
-                       ++temp->c_refs;
-                       i_deref(wd);
-                       wd = temp;
-               }
-
-               ninode = srch_dir(wd, name);
-
-               while (*name != '/' && *name)
-                       ++name;
-       }
-
-       if (parent)
-               *parent = wd;
-       else
-               i_deref(wd);
-       ifnot(parent || ninode)
-           udata.u_error = ENOENT;
-       return (ninode);
-
-nodir:
-       if (parent)
-               *parent = NULLINODE;
-       i_deref(wd);
-       return (NULLINODE);
-
-}
-
-
-
-/* Srch_dir is given a inode pointer of an open directory and a string
- * containing a filename, and searches the directory for the file.  If
- * it exists, it opens it and returns the inode pointer, otherwise NULL.
- * This depends on the fact that ba_read will return unallocated blocks
- * as zero-filled, and a partially allocated block will be padded with
- * zeroes.
- */
-
-inoptr srch_dir(inoptr wd, register char *compname)
-{
-       register int curentry;
-       register blkno_t curblock;
-       register struct direct *buf;
-       register int nblocks;
-       unsigned inum;
-
-       nblocks = (swizzle32(wd->c_node.i_size) + 511) >> 9;
-
-       for (curblock = 0; curblock < nblocks; ++curblock) {
-               buf =
-                   (struct direct *) bread(wd->c_dev,
-                                           bmap(wd, curblock, 1), 0);
-               for (curentry = 0; curentry < 16; ++curentry) {
-                       if (namecomp(compname, buf[curentry].d_name)) {
-                               inum =
-                                   swizzle16(buf[curentry & 0x0f].d_ino);
-                               brelse((bufptr) buf);
-                               return (i_open(wd->c_dev, inum));
-                       }
-               }
-               brelse((bufptr) buf);
-       }
-       return (NULLINODE);
-}
-
-
-/* Srch_mt sees if the given inode is a mount point. If so it
- * dereferences it, and references and returns a pointer to the
- * root of the mounted filesystem.
- */
-
-inoptr srch_mt(inoptr ino)
-{
-       register int j;
-       inoptr i_open();
-
-       for (j = 0; j < NDEVS; ++j)
-               if (swizzle16(fs_tab[j].s_mounted) == SMOUNTED
-                   && fs_tab[j].s_mntpt == ino) {
-                       i_deref(ino);
-                       return (i_open(j, ROOTINODE));
-               }
-
-       return (ino);
-}
-
-
-/* I_open is given an inode number and a device number,
- * and makes an entry in the inode table for them, or
- * increases it reference count if it is already there.
- * An inode # of zero means a newly allocated inode.
- */
-
-inoptr i_open(register int dev, register unsigned ino)
-{
-
-       struct dinode *buf;
-       register inoptr nindex;
-       int i;
-       register inoptr j;
-       int new;
-       static inoptr nexti = i_tab;    /* added inoptr. 26.12.97  HFB */
-       unsigned i_alloc();
-
-       if (dev < 0 || dev >= NDEVS)
-               panic("i_open: Bad dev");
-
-       new = 0;
-       ifnot(ino) {            /* Want a new one */
-               new = 1;
-               ifnot(ino = i_alloc(dev)) {
-                       udata.u_error = ENOSPC;
-                       return (NULLINODE);
-               }
-       }
-
-       if (ino < ROOTINODE || ino >= (swizzle16(fs_tab[dev].s_isize) - 2) * 8) {
-               printf("i_open: bad inode number\n");
-               return (NULLINODE);
-       }
-
-
-       nindex = NULLINODE;
-       j = (inoptr) nexti;
-       for (i = 0; i < ITABSIZE; ++i) {
-               nexti = (inoptr) j;
-               if (++j >= i_tab + ITABSIZE)
-                       j = i_tab;
-
-               ifnot(j->c_refs)
-                   nindex = j;
-
-               if (j->c_dev == dev && j->c_num == ino) {
-                       nindex = j;
-                       goto found;
-               }
-       }
-
-       /* Not already in table. */
-
-       ifnot(nindex) {         /* No unrefed slots in inode table */
-               udata.u_error = ENFILE;
-               return (NULLINODE);
-       }
-
-       buf = (struct dinode *) bread(dev, (ino >> 3) + 2, 0);
-       bcopy((char *) &(buf[ino & 0x07]), (char *) &(nindex->c_node), 64);
-       brelse((bufptr) buf);
-
-       nindex->c_dev = dev;
-       nindex->c_num = ino;
-       nindex->c_magic = CMAGIC;
-
-found:
-       if (new) {
-               if (nindex->c_node.i_nlink
-                   || swizzle16(nindex->c_node.i_mode) & F_MASK)
-                       goto badino;
-       } else {
-               ifnot(nindex->c_node.i_nlink
-                     && swizzle16(nindex->c_node.i_mode) & F_MASK)
-                   goto badino;
-       }
-
-       ++nindex->c_refs;
-       return (nindex);
-
-badino:
-       printf("i_open: bad disk inode\n");
-       return (NULLINODE);
-}
-
-
-
-/* Ch_link modifies or makes a new entry in the directory for the name
- * and inode pointer given. The directory is searched for oldname.  When
- * found, it is changed to newname, and it inode # is that of *nindex.
- * A oldname of "" matches a unused slot, and a nindex of NULLINODE
- * means an inode # of 0.  A return status of 0 means there was no
- * space left in the filesystem, or a non-empty oldname was not found,
- * or the user did not have write permission.
- */
-
-int ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex)
-{
-       struct direct curentry;
-
-       ifnot(getperm(wd) & OTH_WR) {
-               udata.u_error = EPERM;
-               return (0);
-       }
-
-       /* Search the directory for the desired slot. */
-
-       udata.u_offset = 0;
-
-       for (;;) {
-               udata.u_count = 32;
-               udata.u_base = (char *) &curentry;
-//        udata.u_sysio = 1;                                    /*280*/
-               readi(wd);
-
-               /* Read until EOF or name is found */
-               /* readi() advances udata.u_offset */
-               if (udata.u_count == 0
-                   || namecomp(oldname, curentry.d_name))
-                       break;
-       }
-
-       if (udata.u_count == 0 && *oldname)
-               return (0);     /* Entry not found */
-
-       bcopy(newname, curentry.d_name, 30);
-
-#if 1
-       {
-               int i;
-
-               for (i = 0; i < 30; ++i)
-                       if (curentry.d_name[i] == '\0')
-                               break;
-               for (; i < 30; ++i)
-                       curentry.d_name[i] = '\0';
-       }
-#endif
-
-       if (nindex)
-               curentry.d_ino = swizzle16(nindex->c_num);
-       else
-               curentry.d_ino = 0;
-
-       /* If an existing slot is being used, we must back up the file offset */
-       if (udata.u_count)
-               udata.u_offset -= 32;
-
-       udata.u_count = 32;
-       udata.u_base = (char *) &curentry;
-       udata.u_sysio = 1;      /*280 */
-       writei(wd);
-
-       if (udata.u_error)
-               return (0);
-
-       setftime(wd, A_TIME | M_TIME | C_TIME); /* Sets c_dirty */
-
-       /* Update file length to next block */
-       if (swizzle32(wd->c_node.i_size) & 511)
-               wd->c_node.i_size = swizzle32(
-                   swizzle32(wd->c_node.i_size) + 512 -
-                   (swizzle32(wd->c_node.i_size) & 511));
-
-       return (1);
-}
-
-
-
-/* Filename is given a path name, and returns a pointer to the
- * final component of it.
- */
-
-char *filename(char *path)
-{
-       register char *ptr;
-
-       ptr = path;
-       while (*ptr)
-               ++ptr;
-       while (*ptr != '/' && ptr-- > path);
-       return (ptr + 1);
-}
-
-
-/* Namecomp compares two strings to see if they are the same file name.
- * It stops at 30 chars or a null or a slash. It returns 0 for difference.
- */
-
-int namecomp(char *n1, char *n2)
-{
-       register int n;
-
-       n = 30;
-       while (*n1 && *n1 != '/') {
-               if (*n1++ != *n2++)
-                       return (0);
-               ifnot(--n)
-                   return (-1);
-       }
-       return (*n2 == '\0' || *n2 == '/');
-}
-
-
-/* Newfile is given a pointer to a directory and a name, and creates
- * an entry in the directory for the name, dereferences the parent,
- * and returns a pointer to the new inode.  It allocates an inode
- * number, and creates a new entry in the inode table for the new
- * file, and initializes the inode table entry for the new file.
- * The new file will have one reference, and 0 links to it.  Better
- * Better make sure there isn't already an entry with the same name.
- */
-
-inoptr newfile(inoptr pino, char *name)
-{
-       register inoptr nindex;
-       register int j;
-
-       /* First see if parent is writeable *//*280 */
-       ifnot(getperm(pino) & OTH_WR)   /*280 */
-           goto nogood;        /*280 */
-
-       ifnot(nindex = i_open(pino->c_dev, 0))
-           goto nogood;
-
-       /* BIG FIX:  user/group setting was missing  SN *//*280 */
-       nindex->c_node.i_uid = swizzle16(udata.u_euid); /*280 */
-       nindex->c_node.i_gid = swizzle16(udata.u_egid); /*280 */
-
-       nindex->c_node.i_mode = swizzle16(F_REG);       /* For the time being */
-       nindex->c_node.i_nlink = swizzle16(1);
-       nindex->c_node.i_size = 0;
-       for (j = 0; j < 20; j++)
-               nindex->c_node.i_addr[j] = 0;
-       wr_inode(nindex);
-
-       ifnot(ch_link(pino, "", filename(name), nindex)) {
-               i_deref(nindex);
-               goto nogood;
-       }
-
-       i_deref(pino);
-       return (nindex);
-
-nogood:
-       i_deref(pino);
-       return (NULLINODE);
-}
-
-
-/* Check the given device number, and return its address in the mount
- * table.  Also time-stamp the superblock of dev, and mark it modified.
- * Used when freeing and allocating blocks and inodes.
- */
-
-fsptr getdev(int devno)
-{
-       register fsptr dev;
-
-       dev = fs_tab + devno;
-       if (devno < 0 || devno >= NDEVS || !dev->s_mounted)
-               panic("getdev: bad dev");
-       dev->s_fmod = 1;
-       return (dev);
-}
-
-
-/* Returns true if the magic number of a superblock is corrupt.
- */
-
-int baddev(fsptr dev)
-{
-       return (swizzle16(dev->s_mounted) != SMOUNTED);
-}
-
-
-/* I_alloc finds an unused inode number, and returns it, or 0
- * if there are no more inodes available.
- */
-
-unsigned i_alloc(int devno)
-{
-       fsptr dev;
-       blkno_t blk;
-       struct dinode *buf;
-       register int j;
-       register int k;
-       unsigned ino;
-       int baddev();
-       /* struct  dinode *bread();  -- HP *//*?????  HFB  26.12.97 */
-
-       if (baddev(dev = getdev(devno)))
-               goto corrupt;
-
-      tryagain:
-       if (dev->s_ninode) {
-               int i;
-
-               ifnot(dev->s_tinode)
-                   goto corrupt;
-               i = swizzle16(dev->s_ninode);
-               ino = swizzle16(dev->s_inode[--i]);
-               dev->s_ninode = swizzle16(i);
-               if (ino < 2 || ino >= (swizzle16(dev->s_isize) - 2) * 8)
-                       goto corrupt;
-               dev->s_tinode = swizzle16(swizzle16(dev->s_tinode) - 1);
-               return (ino);
-       }
-
-       /* We must scan the inodes, and fill up the table */
-
-       _sync();                /* Make on-disk inodes consistent */
-       k = 0;
-       for (blk = 2; blk < swizzle16(dev->s_isize); blk++) {
-               buf = (struct dinode *) bread(devno, blk, 0);
-               for (j = 0; j < 8; j++) {
-                       ifnot(buf[j].i_mode || buf[j].i_nlink)
-                           dev->s_inode[k++] =
-                           swizzle16(8 * (blk - 2) + j);
-                       if (k == 50) {
-                               brelse((bufptr) buf);
-                               goto done;
-                       }
-               }
-               brelse((bufptr) buf);
-       }
-
-      done:
-       ifnot(k) {
-               if (dev->s_tinode)
-                       goto corrupt;
-               udata.u_error = ENOSPC;
-               return (0);
-       }
-
-       dev->s_ninode = swizzle16(k);
-       goto tryagain;
-
-      corrupt:
-       printf("i_alloc: corrupt superblock\n");
-       dev->s_mounted = swizzle16(1);
-       udata.u_error = ENOSPC;
-       return (0);
-}
-
-
-/* I_free is given a device and inode number, and frees the inode.
- * It is assumed that there are no references to the inode in the
- * inode table or in the filesystem.
- */
-
-void i_free(int devno, unsigned ino)
-{
-       register fsptr dev;
-
-       if (baddev(dev = getdev(devno)))
-               return;
-
-       if (ino < 2 || ino >= (swizzle16(dev->s_isize) - 2) * 8)
-               panic("i_free: bad ino");
-
-       dev->s_tinode = swizzle16(swizzle16(dev->s_tinode) + 1);
-       if (swizzle16(dev->s_ninode) < 50) {
-               int i = swizzle16(dev->s_ninode);
-               dev->s_inode[i++] = swizzle16(ino);
-               dev->s_ninode = swizzle16(i);
-       }
-}
-
-
-/* Blk_alloc is given a device number, and allocates an unused block
- * from it. A returned block number of zero means no more blocks.
- */
-
-blkno_t blk_alloc(int devno)
-{
-       register fsptr dev;
-       register blkno_t newno;
-       blkno_t *buf;           /*, *bread(); -- HP */
-       register int j;
-       int i;
-
-       if (baddev(dev = getdev(devno)))
-               goto corrupt2;
-
-       if (swizzle16(dev->s_nfree) <= 0 || swizzle16(dev->s_nfree) > 50)
-               goto corrupt;
-
-       i = swizzle16(dev->s_nfree);
-       newno = swizzle16(dev->s_free[--i]);
-       dev->s_nfree = swizzle16(i);
-       ifnot(newno) {
-               if (dev->s_tfree != 0)
-                       goto corrupt;
-               udata.u_error = ENOSPC;
-               dev->s_nfree = swizzle16(swizzle16(dev->s_nfree) + 1);
-               return (0);
-       }
-
-       /* See if we must refill the s_free array */
-
-       ifnot(dev->s_nfree) {
-               buf = (blkno_t *) bread(devno, newno, 0);
-               dev->s_nfree = buf[0];
-               for (j = 0; j < 50; j++) {
-                       dev->s_free[j] = buf[j + 1];
-               }
-               brelse((bufptr) buf);
-       }
-
-       validblk(devno, newno);
-
-       ifnot(dev->s_tfree)
-           goto corrupt;
-       dev->s_tfree = swizzle16(swizzle16(dev->s_tfree) - 1);
-
-       /* Zero out the new block */
-       buf = (blkno_t *) bread(devno, newno, 2);
-       bzero(buf, 512);
-       bawrite((bufptr) buf);
-       return (newno);
-
-      corrupt:
-       printf("blk_alloc: corrupt\n");
-       dev->s_mounted = swizzle16(1);
-      corrupt2:
-       udata.u_error = ENOSPC;
-       return (0);
-}
-
-
-/* Blk_free is given a device number and a block number,
-and frees the block. */
-
-void blk_free(int devno, blkno_t blk)
-{
-       register fsptr dev;
-       register char *buf;
-       int b;
-
-       ifnot(blk)
-           return;
-
-       if (baddev(dev = getdev(devno)))
-               return;
-
-       validblk(devno, blk);
-
-       if (dev->s_nfree == 50) {
-               buf = bread(devno, blk, 1);
-               bcopy((char *) &(dev->s_nfree), buf, 512);
-               bawrite((bufptr) buf);
-               dev->s_nfree = 0;
-       }
-
-       dev->s_tfree = swizzle16(swizzle16(dev->s_tfree) + 1);
-       b = swizzle16(dev->s_nfree);
-       dev->s_free[b++] = swizzle16(blk);
-       dev->s_nfree = swizzle16(b);
-}
-
-
-/* Oft_alloc and oft_deref allocate and dereference (and possibly free)
- * entries in the open file table.
- */
-
-int oft_alloc(void)
-{
-       register int j;
-
-       for (j = 0; j < OFTSIZE; ++j) {
-               ifnot(of_tab[j].o_refs) {
-                       of_tab[j].o_refs = 1;
-                       of_tab[j].o_inode = NULLINODE;
-                       return (j);
-               }
-       }
-       udata.u_error = ENFILE;
-       return (-1);
-}
-
-
-void oft_deref(int of)
-{
-       register struct oft *ofptr;
-
-       ofptr = of_tab + of;
-       if (!(--ofptr->o_refs) && ofptr->o_inode) {
-               i_deref(ofptr->o_inode);
-               ofptr->o_inode = NULLINODE;
-       }
-}
-
-
-/* Uf_alloc finds an unused slot in the user file table.
- */
-
-int uf_alloc(void)
-{
-       register int j;
-
-       for (j = 0; j < UFTSIZE; ++j) {
-               if (udata.u_files[j] & 0x80) {  /* Portable, unlike  == -1 */
-                       return (j);
-               }
-       }
-       udata.u_error = ENFILE;
-       return (-1);
-}
-
-
-/* I_ref increases the reference count of the given inode table entry.
- */
-
-void i_ref(inoptr ino)
-{
-       if (++(ino->c_refs) == 2 * ITABSIZE) {  /* Arbitrary limit. *//*280 */
-               printf("inode %u,", ino->c_num);        /*280 */
-               panic("too many i-refs");
-       }                       /*280 */
-}
-
-
-/* I_deref decreases the reference count of an inode, and frees it from
- * the table if there are no more references to it.  If it also has no
- * links, the inode itself and its blocks (if not a device) is freed.
- */
-
-void i_deref(inoptr ino)
-{
-       unsigned int m;
-
-       magic(ino);
-
-       ifnot(ino->c_refs)
-           panic("inode freed.");
-
-       /* If the inode has no links and no refs, it must have
-          its blocks freed. */
-
-       ifnot(--ino->c_refs || ino->c_node.i_nlink) {
-/*
- SN  (mcy)
-*/
-
-               m = swizzle16(ino->c_node.i_mode);
-               if (((m & F_MASK) == F_REG) ||
-                   ((m & F_MASK) == F_DIR) || ((m & F_MASK) == F_PIPE))
-                       f_trunc(ino);
-       }
-       /* If the inode was modified, we must write it to disk. */
-       if (!(ino->c_refs) && ino->c_dirty) {
-               ifnot(ino->c_node.i_nlink) {
-                       ino->c_node.i_mode = 0;
-                       i_free(ino->c_dev, ino->c_num);
-               }
-               wr_inode(ino);
-       }
-}
-
-
-/* Wr_inode writes out the given inode in the inode table out to disk,
- * and resets its dirty bit.
- */
-
-void wr_inode(inoptr ino)
-{
-       struct dinode *buf;
-       register blkno_t blkno;
-
-       magic(ino);
-
-       blkno = (ino->c_num >> 3) + 2;
-       buf = (struct dinode *) bread(ino->c_dev, blkno, 0);
-       bcopy((char *) (&ino->c_node),
-             (char *) ((char **) &buf[ino->c_num & 0x07]), 64);
-       bfree((bufptr) buf, 2);
-       ino->c_dirty = 0;
-}
-
-
-/* isdevice(ino) returns true if ino points to a device */
-int isdevice(inoptr ino)
-{
-       return (swizzle16(ino->c_node.i_mode) & 020000);
-}
-
-
-/* This returns the device number of an inode representing a device */
-int devnum(inoptr ino)
-{
-       return (swizzle16(*(ino->c_node.i_addr)));
-}
-
-
-/* F_trunc frees all the blocks associated with the file, if it
- * is a disk file.
- */
-
-void f_trunc(inoptr ino)
-{
-       int dev;
-       int j;
-
-       dev = ino->c_dev;
-
-       /* First deallocate the double indirect blocks */
-       freeblk(dev, swizzle16(ino->c_node.i_addr[19]), 2);
-
-       /* Also deallocate the indirect blocks */
-       freeblk(dev, swizzle16(ino->c_node.i_addr[18]), 1);
-
-       /* Finally, free the direct blocks */
-       for (j = 17; j >= 0; --j)
-               freeblk(dev, swizzle16(ino->c_node.i_addr[j]), 0);
-
-       bzero((char *) ino->c_node.i_addr, sizeof(ino->c_node.i_addr));
-
-       ino->c_dirty = 1;
-       ino->c_node.i_size = 0;
-}
-
-
-/* Companion function to f_trunc(). */
-void freeblk(int dev, blkno_t blk, int level)
-{
-       blkno_t *buf;
-       int j;
-
-       ifnot(blk)
-           return;
-
-       if (level) {
-               buf = (blkno_t *) bread(dev, blk, 0);
-               for (j = 255; j >= 0; --j)
-                       freeblk(dev, swizzle16(buf[j]), level - 1);
-               brelse((bufptr) buf);
-       }
-
-       blk_free(dev, blk);
-}
-
-
-
-/* Changes: blk_alloc zeroes block it allocates */
-/*
- * Bmap defines the structure of file system storage by returning
- * the physical block number on a device given the inode and the
- * logical block number in a file.  The block is zeroed if created.
- */
-blkno_t bmap(inoptr ip, blkno_t bn, int rwflg)
-{
-       register int i;
-       register bufptr bp;
-       register int j;
-       register blkno_t nb;
-       int sh;
-       int dev;
-
-       if (fuzix_getmode(ip) == F_BDEV)
-               return (bn);
-
-       dev = ip->c_dev;
-
-       /*
-        * blocks 0..17 are direct blocks
-        */
-       if (bn < 18) {
-               nb = swizzle16(ip->c_node.i_addr[bn]);
-               if (nb == 0) {
-                       if (rwflg || (nb = blk_alloc(dev)) == 0)
-                               return (NULLBLK);
-                       ip->c_node.i_addr[bn] = swizzle16(nb);
-                       ip->c_dirty = 1;
-               }
-               return (nb);
-       }
-
-       /*
-        * addresses 18 and 19 have single and double indirect blocks.
-        * the first step is to determine how many levels of indirection.
-        */
-       bn -= 18;
-       sh = 0;
-       j = 2;
-       if (bn & 0xff00) {      /* bn > 255  so double indirect */
-               sh = 8;
-               bn -= 256;
-               j = 1;
-       }
-
-       /*
-        * fetch the address from the inode
-        * Create the first indirect block if needed.
-        */
-       ifnot(nb = swizzle16(ip->c_node.i_addr[20 - j])) {
-               if (rwflg || !(nb = blk_alloc(dev)))
-                       return (NULLBLK);
-               ip->c_node.i_addr[20 - j] = swizzle16(nb);
-               ip->c_dirty = 1;
-       }
-
-       /*
-        * fetch through the indirect blocks
-        */
-       for (; j <= 2; j++) {
-               bp = (bufptr) bread(dev, nb, 0);
-               /******
-                if(bp->bf_error) {
-                        brelse(bp);
-                        return((blkno_t)0);
-                }
-                ******/
-               i = (bn >> sh) & 0xff;
-               if ((swizzle16(nb) == ((blkno_t *) bp)[i]))
-                       brelse(bp);
-               else {
-                       if (rwflg || !(nb = blk_alloc(dev))) {
-                               brelse(bp);
-                               return (NULLBLK);
-                       }
-                       ((blkno_t *) bp)[i] = swizzle16(nb);
-                       bawrite(bp);
-               }
-               sh -= 8;
-       }
-       return (nb);
-}
-
-
-
-/* Validblk panics if the given block number is not a valid
- *  data block for the given device.
- */
-void validblk(int dev, blkno_t num)
-{
-       register fsptr devptr;
-
-       devptr = fs_tab + dev;
-
-       if (devptr->s_mounted == 0)
-               panic("validblk: not mounted");
-
-       if (num < swizzle16(devptr->s_isize)
-           || num >= swizzle16(devptr->s_fsize))
-               panic("validblk: invalid blk");
-}
-
-
-/* This returns the inode pointer associated with a user's file
- * descriptor, checking for valid data structures.
- */
-inoptr getinode(int uindex)
-{
-       register int oftindex;
-       register inoptr inoindex;
-
-       if (uindex < 0 || uindex >= UFTSIZE
-           || udata.u_files[uindex] & 0x80) {
-               udata.u_error = EBADF;
-               return (NULLINODE);
-       }
-
-       if ((oftindex = udata.u_files[uindex]) < 0 || oftindex >= OFTSIZE)
-               panic("Getinode: bad desc table");
-
-       if ((inoindex = of_tab[oftindex].o_inode) < i_tab ||
-           inoindex >= i_tab + ITABSIZE)
-               panic("Getinode: bad OFT");
-
-       magic(inoindex);
-
-       return (inoindex);
-}
-
-
-/* Super returns true if we are the superuser */
-int super()
-{
-       return (udata.u_euid == 0);
-}
-
-
-/* Getperm looks at the given inode and the effective user/group ids,
- * and returns the effective permissions in the low-order 3 bits.
- */
-int getperm(inoptr ino)
-{
-       int mode;
-
-       if (super())
-               return (07);
-
-       mode = swizzle16(ino->c_node.i_mode);
-       if (swizzle16(ino->c_node.i_uid) == udata.u_euid)
-               mode >>= 6;
-       else if (swizzle16(ino->c_node.i_gid) == udata.u_egid)
-               mode >>= 3;
-
-       return (mode & 07);
-}
-
-
-/* This sets the times of the given inode, according to the flags.
- */
-void setftime(inoptr ino, int flag)
-{
-       time_t now;
-       ino->c_dirty = 1;
-
-       now = time(NULL);
-
-       if (flag & A_TIME)
-               ino->c_node.i_atime = swizzle32(now);
-       if (flag & M_TIME)
-               ino->c_node.i_mtime = swizzle32(now);
-       if (flag & C_TIME)
-               ino->c_node.i_ctime = swizzle32(now);
-}
-
-
-int fuzix_getmode(inoptr ino)
-{
-       return (swizzle16(ino->c_node.i_mode) & F_MASK);
-}
-
-
-/* Fmount places the given device in the mount table with mount point ino.
- */
-int fmount(int dev, inoptr ino)
-{
-       char *buf;
-       register struct filesys *fp;
-
-       /* Dev 0 blk 1 */
-       fp = fs_tab + dev;
-       buf = bread(dev, 1, 0);
-       bcopy(buf, (char *) fp, sizeof(struct filesys));
-       brelse((bufptr) buf);
-
-       /* See if there really is a filesystem on the device */
-       if (fp->s_mounted == SMOUNTED_WRONGENDIAN)
-               swizzling = 1;
-       if (swizzle16(fp->s_mounted) != SMOUNTED ||
-           swizzle16(fp->s_isize) >= swizzle16(fp->s_fsize))
-               return (-1);
-
-       fp->s_mntpt = ino;
-       if (ino)
-               ++ino->c_refs;
-
-       return (0);
-}
-
-
-void magic(inoptr ino)
-{
-       if (ino->c_magic != CMAGIC)
-               panic("Corrupt inode");
-}