[comp.os.cpm] UZI, part 2 of 5

dbraun@cadavr.intel.com (Doug Braun ~) (11/29/88)

UZI, Part 2 of 5:

#!/bin/sh
#
#Run this file through sh to get:
#    scall1.c
echo -n 'Extracting scall1.c ... '
sed 's/^X//' > scall1.c << 'EOF_scall1.c'
X/**************************************************
XUZI (Unix Z80 Implementation) Kernel:  scall1.c
X***************************************************/
X
X
X/*LINTLIBRARY*/
X#include "unix.h"
X#include "extern.h"
X
X
X/*******************************************
Xopen(name, flag)
Xchar *name;
Xregister int16 flag;
X*********************************************/
X
X#define name (char *)udata.u_argn1
X#define flag (int16)udata.u_argn
X
X_open()
X{
X    int16 uindex;
X    register int16 oftindex;
X    register inoptr ino;
X    register int16 perm;
X    inoptr n_open();
X
X    if (flag < 0 || flag > 2)
X    {
X	udata.u_error = EINVAL;
X	return (-1);
X    }
X    if ((uindex = uf_alloc()) == -1)
X	return (-1);
X
X    if ((oftindex = oft_alloc()) == -1)
X	goto nooft;
X
X    ifnot (ino = n_open(name,NULLINOPTR))
X	goto cantopen;
X
X    of_tab[oftindex].o_inode = ino;
X
X    perm = getperm(ino);
X    if (((flag == O_RDONLY || flag == O_RDWR) && !(perm & OTH_RD)) ||
X	((flag == O_WRONLY || flag == O_RDWR) && !(perm & OTH_WR)))
X    {
X	udata.u_error = EPERM;
X	goto cantopen;
X    }
X
X    if (getmode(ino) == F_DIR &&
X	(flag == O_WRONLY || flag == O_RDWR))
X    {
X	udata.u_error = EISDIR;
X	goto cantopen;
X    }
X
X    if (isdevice(ino) && d_open((int)ino->c_node.i_addr[0]) != 0)
X    {
X	udata.u_error = ENXIO;
X	goto cantopen;
X    }
X
X    udata.u_files[uindex] = oftindex;
X
X    of_tab[oftindex].o_ptr.o_offset = 0;
X    of_tab[oftindex].o_ptr.o_blkno = 0;
X    of_tab[oftindex].o_access = flag;
X
X    return (uindex);
X
Xcantopen:
X    oft_deref(oftindex);  /* This will call i_deref() */
Xnooft:
X    udata.u_files[uindex] = -1;
X    return (-1);
X}
X
X#undef name
X#undef flag
X
X
X
X/*********************************************
Xclose(uindex)
Xint16 uindex;
X**********************************************/
X
X#define uindex (int16)udata.u_argn
X
X_close()
X{
X    return(doclose(uindex));
X}
X
X#undef uindex
X
X
Xdoclose(uindex)
Xint16 uindex;
X{
X    register int16 oftindex;
X    inoptr ino;
X    inoptr getinode();
X
X    ifnot(ino = getinode(uindex))
X	return(-1);
X    oftindex = udata.u_files[uindex];
X
X    if (isdevice(ino)
X	/* && ino->c_refs == 1 && of_tab[oftindex].o_refs == 1 */ )
X	d_close((int)(ino->c_node.i_addr[0]));
X
X    udata.u_files[uindex] = -1;
X    oft_deref(oftindex);
X
X    return(0);
X}
X
X
X
X/****************************************
Xcreat(name, mode)
Xchar *name;
Xint16 mode;
X*****************************************/
X
X#define name (char *)udata.u_argn1
X#define mode (int16)udata.u_argn
X
X_creat()
X{
X    register inoptr ino;
X    register int16 uindex;
X    register int16 oftindex;
X    inoptr parent;
X    register int16 j;
X    inoptr n_open();
X    inoptr newfile();
X
X    parent = NULLINODE;
X
X    if ((uindex = uf_alloc()) == -1)
X	return (-1);
X    if ((oftindex = oft_alloc()) == -1)
X	return (-1);
X
X    if (ino = n_open(name,&parent))  /* The file exists */
X    {
X	i_deref(parent);
X	if (getmode(ino) == F_DIR)
X	{
X	    i_deref(ino);
X	    udata.u_error = EISDIR;
X	    goto nogood;
X	}
X	ifnot (getperm(ino) & OTH_WR)
X	{
X	    i_deref(ino);
X	    udata.u_error = EACCES;
X	    goto nogood;
X	}
X	if (getmode(ino) == F_REG)
X	{
X	    /* Truncate the file to zero length */
X	    f_trunc(ino);
X	    /* Reset any oft pointers */
X	    for (j=0; j < OFTSIZE; ++j)
X	        if (of_tab[j].o_inode == ino)
X	            of_tab[j].o_ptr.o_blkno = of_tab[j].o_ptr.o_offset = 0;
X	}
X
X    }
X    else
X    {
X	if (parent && (ino = newfile(parent,name)))
X	         /* Parent was derefed in newfile */
X	{
X	    ino->c_node.i_mode = (F_REG | (mode & MODE_MASK & ~udata.u_mask));
X	    setftime(ino, A_TIME|M_TIME|C_TIME);
X	    /* The rest of the inode is initialized in newfile() */
X	    wr_inode(ino);
X	}
X	else
X	{
X	    /* Doesn't exist and can't make it */
X	    if (parent)
X	        i_deref(parent);
X	    goto nogood;
X	}
X    }
X
X    udata.u_files[uindex] = oftindex;
X
X    of_tab[oftindex].o_ptr.o_offset = 0;
X    of_tab[oftindex].o_ptr.o_blkno = 0;
X    of_tab[oftindex].o_inode = ino;
X    of_tab[oftindex].o_access = O_WRONLY;
X
X    return (uindex);
X
Xnogood:
X    oft_deref(oftindex);
X    return (-1);
X
X}
X
X#undef name
X#undef mode
X
X
X
X/********************************************
Xpipe(fildes)
Xint fildes[];
X*******************************************/
X
X#define fildes (int *)udata.u_argn
X
X_pipe()
X{
X    register int16 u1, u2, oft1, oft2;
X    register inoptr ino;
X    inoptr i_open();
X
X    if ((u1 = uf_alloc()) == -1)
X	goto nogood2;
X    if ((oft1 = oft_alloc()) == -1)
X	goto nogood2;
X    udata.u_files[u1] = oft1;
X
X    if ((u2 = uf_alloc()) == -1)
X	goto nogood;
X    if ((oft2 = oft_alloc()) == -1)
X    {
X	oft_deref(oft1);
X	goto nogood;
X    }
X
X    ifnot (ino = i_open(ROOTDEV, 0))
X    {
X	oft_deref(oft1);
X	oft_deref(oft2);
X	goto nogood;
X    }
X
X    udata.u_files[u2] = oft2;
X
X    of_tab[oft1].o_ptr.o_offset = 0;
X    of_tab[oft1].o_ptr.o_blkno = 0;
X    of_tab[oft1].o_inode = ino;
X    of_tab[oft1].o_access = O_RDONLY;
X
X    of_tab[oft2].o_ptr.o_offset = 0;
X    of_tab[oft2].o_ptr.o_blkno = 0;
X    of_tab[oft2].o_inode = ino;
X    of_tab[oft2].o_access = O_WRONLY;
X
X    ++ino->c_refs;
X    ino->c_node.i_mode = F_PIPE | 0777; /* No permissions necessary on pipes */
X    ino->c_node.i_nlink = 0;            /* a pipe is not in any directory */
X
X    *fildes = u1;
X    *(fildes+1) = u2;
X    return (0);
X
Xnogood:
X    udata.u_files[u1] = -1;
Xnogood2:
X    return(-1);
X
X}
X
X#undef fildes
X
X
X
X/********************************************
Xlink(name1, name2)
Xchar *name1;
Xchar *name2;
X*********************************************/
X
X#define name1 (char *)udata.u_argn1
X#define name2 (char *)udata.u_argn
X
X_link()
X{
X    register inoptr ino;
X    register inoptr ino2;
X    inoptr parent2;
X    char *filename();
X    inoptr n_open();
X
X    ifnot (ino = n_open(name1,NULLINOPTR))
X	return(-1);
X
X    if (getmode(ino) == F_DIR && !super())
X    {
X	udata.u_error = EPERM;
X	goto nogood;
X    }
X
X    /* Make sure file2 doesn't exist, and get its parent */
X    if (ino2 = n_open(name2,&parent2))
X    {
X	i_deref(ino2);
X	i_deref(parent2);
X	udata.u_error = EEXIST;
X	goto nogood;
X    }
X
X    ifnot (parent2)
X	goto nogood;
X
X    if (ino->c_dev != parent2->c_dev)
X    {
X	i_deref(parent2);
X	udata.u_error = EXDEV;
X	goto nogood;
X    }
X
X    if (ch_link(parent2,"",filename(name2),ino) == 0)
X	goto nogood;
X
X
X    /* Update the link count. */
X    ++ino->c_node.i_nlink;
X    wr_inode(ino);
X    setftime(ino, C_TIME);
X
X    i_deref(parent2);
X    i_deref(ino);
X    return(0);
X
Xnogood:
X    i_deref(ino);
X    return(-1);
X
X}
X
X#undef name1
X#undef name2
X
X
X
X/**********************************************************
Xunlink(path)
Xchar *path;
X**************************************************/
X
X#define path (char *)udata.u_argn
X
X_unlink()
X{
X    register inoptr ino;
X    inoptr pino;
X    char *filename();
X    inoptr i_open();
X    inoptr n_open();
X
X    ino = n_open(path,&pino);
X
X    ifnot (pino && ino)
X    {
X	udata.u_error = ENOENT;
X	return (-1);
X    }
X
X    if (getmode(ino) == F_DIR && !super())
X    {
X	udata.u_error = EPERM;
X	goto nogood;
X    }
X
X    /* Remove the directory entry */
X
X    if (ch_link(pino,filename(path),"",NULLINODE) == 0)
X	goto nogood;
X
X    /* Decrease the link count of the inode */
X
X    ifnot (ino->c_node.i_nlink--)
X    {
X	ino->c_node.i_nlink += 2;
X	warning("_unlink: bad nlink");
X    }
X    setftime(ino, C_TIME);
X    i_deref(pino);
X    i_deref(ino);
X    return(0);
X
Xnogood:
X    i_deref(pino);
X    i_deref(ino);
X    return(-1);
X}
X
X#undef path
X
X
X
X/*****************************************************
Xread(d, buf, nbytes)
Xint16 d;
Xchar *buf;
Xuint16 nbytes;
X**********************************************/
X
X#define d (int16)udata.u_argn2
X#define buf (char *)udata.u_argn1
X#define nbytes (uint16)udata.u_argn
X
X_read()
X{
X    register inoptr ino;
X    inoptr rwsetup();
X
X    /* Set up u_base, u_offset, ino; check permissions, file num. */
X    if ((ino = rwsetup(1)) == NULLINODE)
X	return (-1);   /* bomb out if error */
X
X    readi(ino);
X    updoff();
X
X    return (udata.u_count);
X}
X
X#undef d
X#undef buf
X#undef nbytes
X
X
X/***********************************
Xwrite(d, buf, nbytes)
Xint16 d;
Xchar *buf;
Xuint16 nbytes;
X***********************************/
X
X#define d (int16)udata.u_argn2
X#define buf (char *)udata.u_argn1
X#define nbytes (uint16)udata.u_argn
X
X_write()
X{
X    register inoptr ino;
X    off_t *offp;
X    inoptr rwsetup();
X
X    /* Set up u_base, u_offset, ino; check permissions, file num. */
X    if ((ino = rwsetup(0)) == NULLINODE)
X	return (-1);   /* bomb out if error */
X
X    writei(ino);
X    updoff();
X
X    return (udata.u_count);
X}
X
X#undef d
X#undef buf
X#undef nbytes
X
X
X
Xinoptr
Xrwsetup(rwflag)
Xint rwflag;
X{
X    register inoptr ino;
X    register struct oft *oftp;
X    inoptr getinode();
X
X    udata.u_base = (char *)udata.u_argn1;  /* buf */
X    udata.u_count = (uint16)udata.u_argn;  /* nbytes */
X
X    if ((ino = getinode(udata.u_argn2)) == NULLINODE)
X	return (NULLINODE);
X
X    oftp = of_tab + udata.u_files[udata.u_argn2];
X    if (oftp->o_access == (rwflag ? O_WRONLY : O_RDONLY))
X    {
X	udata.u_error = EBADF;
X	return (NULLINODE);
X    }
X
X    setftime(ino, rwflag ? A_TIME : (A_TIME | M_TIME | C_TIME));
X
X    /* Initialize u_offset from file pointer */
X    udata.u_offset.o_blkno = oftp->o_ptr.o_blkno;
X    udata.u_offset.o_offset = oftp->o_ptr.o_offset;
X
X    return (ino);
X}
X
X
X
Xreadi(ino)
Xregister inoptr ino;
X{
X    register uint16 amount;
X    register uint16 toread;
X    register blkno_t pblk;
X    register char *bp;
X    int dev;
X    int ispipe;
X    char *bread();
X    char *zerobuf();
X    blkno_t bmap();
X
X    dev = ino->c_dev;
X    ispipe = 0;
X    switch (getmode(ino))
X    {
X
X    case F_DIR:
X    case F_REG:
X
X	/* See of end of file will limit read */
X	toread = udata.u_count =
X	    ino->c_node.i_size.o_blkno-udata.u_offset.o_blkno >= 64 ?
X	        udata.u_count :
X	        min(udata.u_count,
X	         512*(ino->c_node.i_size.o_blkno-udata.u_offset.o_blkno) +
X	         (ino->c_node.i_size.o_offset-udata.u_offset.o_offset));
X	goto loop;
X
X    case F_PIPE:
X	ispipe = 1;
X	while (psize(ino) == 0)
X	{
X	    if (ino->c_refs == 1) /* No writers */
X	        break;
X	    /* Sleep if empty pipe */
X	    psleep(ino);
X	}
X	toread = udata.u_count = min(udata.u_count, psize(ino));
X	goto loop;
X
X    case F_BDEV:
X	toread = udata.u_count;
X	dev = *(ino->c_node.i_addr);
X
X    loop:
X	while (toread)
X	{
X	    if ((pblk = bmap(ino, udata.u_offset.o_blkno, 1)) != NULLBLK)
X	        bp = bread(dev, pblk, 0);
X	    else
X	        bp = zerobuf();
X
X	    bcopy(bp+udata.u_offset.o_offset, udata.u_base,
X	            (amount = min(toread, 512 - udata.u_offset.o_offset)));
X	    brelse(bp);
X
X	    udata.u_base += amount;
X	    addoff(&udata.u_offset, amount);
X	    if (ispipe && udata.u_offset.o_blkno >= 18)
X	        udata.u_offset.o_blkno = 0;
X	    toread -= amount;
X	    if (ispipe)
X	    {
X	        addoff(&(ino->c_node.i_size), -amount);
X	        wakeup(ino);
X	    }
X	}
X
X	break;
X
X    case F_CDEV:
X	udata.u_count = cdread(ino->c_node.i_addr[0]);
X
X	if (udata.u_count != -1)
X	    addoff(&udata.u_offset, udata.u_count);
X	break;
X
X    default:
X	udata.u_error = ENODEV;
X    }
X}
X
X
X
X/* Writei (and readi) need more i/o error handling */
X
Xwritei(ino)
Xregister inoptr ino;
X{
X    register uint16 amount;
X    register uint16 towrite;
X    register char *bp;
X    int ispipe;
X    blkno_t pblk;
X    int created;        /* Set by bmap if newly allocated block used */
X    int dev;
X    char *zerobuf();
X    char *bread();
X    blkno_t bmap();
X
X    dev = ino->c_dev;
X
X    switch (getmode(ino))
X    {
X
X    case F_BDEV:
X	dev = *(ino->c_node.i_addr);
X    case F_DIR:
X    case F_REG:
X	ispipe = 0;
X	towrite = udata.u_count;
X	goto loop;
X
X    case F_PIPE:
X	ispipe = 1;
X	while ((towrite = udata.u_count) > (16*512) - psize(ino))
X	{
X	    if (ino->c_refs == 1) /* No readers */
X	    {
X	        udata.u_count = -1;
X	        udata.u_error = EPIPE;
X	        ssig(udata.u_ptab, SIGPIPE);
X	        return;
X	    }
X	    /* Sleep if empty pipe */
X	    psleep(ino);
X	}
X
X	/* Sleep if empty pipe */
X	goto loop;
X
X    loop:
X
X	while (towrite)
X	{
X	    amount = min(towrite, 512 - udata.u_offset.o_offset);
X
X
X	    if ((pblk = bmap(ino, udata.u_offset.o_blkno, 0)) == NULLBLK)
X	        break;    /* No space to make more blocks */
X
X	    /* If we are writing an entire block, we don't care
X	    about its previous contents */
X	    bp = bread(dev, pblk, (amount == 512));
X
X	    bcopy(udata.u_base, bp+udata.u_offset.o_offset, amount);
X	    bawrite(bp);
X
X	    udata.u_base += amount;
X	    addoff(&udata.u_offset, amount);
X	    if(ispipe)
X	    {
X	        if (udata.u_offset.o_blkno >= 18)
X	            udata.u_offset.o_blkno = 0;
X	        addoff(&(ino->c_node.i_size), amount);
X	        /* Wake up any readers */
X	        wakeup(ino);
X	    }
X	    towrite -= amount;
X	}
X
X	/* Update size if file grew */
X	ifnot (ispipe)
X	{
X	    if ( udata.u_offset.o_blkno > ino->c_node.i_size.o_blkno ||
X	        (udata.u_offset.o_blkno == ino->c_node.i_size.o_blkno &&
X	            udata.u_offset.o_offset > ino->c_node.i_size.o_offset))
X	    {
X	        ino->c_node.i_size.o_blkno = udata.u_offset.o_blkno;
X	        ino->c_node.i_size.o_offset = udata.u_offset.o_offset;
X	        ino->c_dirty = 1;
X	    }
X	}
X
X	break;
X
X    case F_CDEV:
X	udata.u_count = cdwrite(ino->c_node.i_addr[0]);
X
X	if (udata.u_count != -1)
X	    addoff(&udata.u_offset, udata.u_count);
X	break;
X
X    default:
X	udata.u_error = ENODEV;
X    }
X
X}
X
X
Xmin(a, b)
Xint a, b;
X{
X    return ( a < b ? a : b);
X}
X
X
Xpsize(ino)
Xinoptr ino;
X{
X    return (512*ino->c_node.i_size.o_blkno+ino->c_node.i_size.o_offset);
X}
X
X
X
Xaddoff(ofptr, amount)
Xoff_t *ofptr;
Xint amount;
X{
X    if (amount >= 0)
X    {
X    ofptr->o_offset += amount % 512;
X    if (ofptr->o_offset >= 512)
X    {
X	ofptr->o_offset -= 512;
X	++ofptr->o_blkno;
X    }
X    ofptr->o_blkno += amount/512;
X    }
X    else
X    {
X	ofptr->o_offset -= (-amount) % 512;
X	if (ofptr->o_offset < 0)
X	{
X	    ofptr->o_offset += 512;
X	    --ofptr->o_blkno;
X	}
X	ofptr->o_blkno -= (-amount)/512;
X    }
X}
X
X
Xupdoff()
X{
X    register off_t *offp;
X
X    /* Update current file pointer */
X    offp = &of_tab[udata.u_files[udata.u_argn2]].o_ptr;
X    offp->o_blkno = udata.u_offset.o_blkno;
X    offp->o_offset = udata.u_offset.o_offset;
X}
X
X
X
X/****************************************
Xseek(file,offset,flag)
Xint16 file;
Xuint16 offset;
Xint16 flag;
X*****************************************/
X
X#define file (int16)udata.u_argn2
X#define offset (uint16)udata.u_argn1
X#define flag (int16)udata.u_argn
X
X_seek()
X{
X    register inoptr ino;
X    register int16 oftno;
X    register uint16 retval;
X    inoptr getinode();
X
X    if ((ino = getinode(file)) == NULLINODE)
X	return(-1);
X
X    if (getmode(ino) == F_PIPE)
X    {
X	udata.u_error = ESPIPE;
X	return(-1);
X    }
X
X    oftno = udata.u_files[file];
X
X
X    if (flag <= 2)
X	retval = of_tab[oftno].o_ptr.o_offset;
X    else
X	retval = of_tab[oftno].o_ptr.o_blkno;
X
X    switch(flag)
X    {
X    case 0:
X	of_tab[oftno].o_ptr.o_blkno = 0;
X	of_tab[oftno].o_ptr.o_offset = offset;
X	break;
X    case 1:
X	of_tab[oftno].o_ptr.o_offset += offset;
X	break;
X    case 2:
X	of_tab[oftno].o_ptr.o_blkno = ino->c_node.i_size.o_blkno;
X	of_tab[oftno].o_ptr.o_offset = ino->c_node.i_size.o_offset + offset;
X	break;
X    case 3:
X	of_tab[oftno].o_ptr.o_blkno = offset;
X	break;
X    case 4:
X	of_tab[oftno].o_ptr.o_blkno += offset;
X	break;
X    case 5:
X	of_tab[oftno].o_ptr.o_blkno = ino->c_node.i_size.o_blkno + offset;
X	break;
X    default:
X	udata.u_error = EINVAL;
X	return(-1);
X    }
X
X    while ((unsigned)of_tab[oftno].o_ptr.o_offset >= 512)
X    {
X	of_tab[oftno].o_ptr.o_offset -= 512;
X	++of_tab[oftno].o_ptr.o_blkno;
X    }
X
X    return((int16)retval);
X}
X
X#undef file
X#undef offset
X#undef flag
X
X
X
X/************************************
Xchdir(dir)
Xchar *dir;
X************************************/
X
X#define dir (char *)udata.u_argn
X
X_chdir()
X{
X    register inoptr newcwd;
X    inoptr n_open();
X
X    ifnot (newcwd = n_open(dir,NULLINOPTR))
X	return(-1);
X
X    if (getmode(newcwd) != F_DIR)
X    {
X	udata.u_error = ENOTDIR;
X	i_deref(newcwd);
X	return(-1);
X    }
X    i_deref(udata.u_cwd);
X    udata.u_cwd = newcwd;
X    return(0);
X}
X
X#undef dir
X
X
X
X/*************************************
Xmknod(name,mode,dev)
Xchar *name;
Xint16 mode;
Xint16 dev;
X***************************************/
X
X#define name (char *)udata.u_argn2
X#define mode (int16)udata.u_argn1
X#define dev (int16)udata.u_argn
X
X_mknod()
X{
X    register inoptr ino;
X    inoptr parent;
X    inoptr n_open();
X    inoptr newfile();
X
X    udata.u_error = 0;
X    ifnot (super())
X    {
X	udata.u_error = EPERM;
X	return(-1);
X    }
X
X    if (ino = n_open(name,&parent))
X    {
X	udata.u_error = EEXIST;
X	goto nogood;
X    }
X
X    ifnot (parent)
X    {
X	udata.u_error = ENOENT;
X	goto nogood3;
X    }
X
X    ifnot (ino = newfile(parent,name))
X	goto nogood2;
X
X    /* Initialize mode and dev */
X    ino->c_node.i_mode = mode & ~udata.u_mask;
X    ino->c_node.i_addr[0] = isdevice(ino) ? dev : 0;
X    setftime(ino, A_TIME|M_TIME|C_TIME);
X    wr_inode(ino);
X
X    i_deref(ino);
X    return (0);
X
Xnogood:
X    i_deref(ino);
Xnogood2:
X    i_deref(parent);
Xnogood3:
X    return (-1);
X}
X
X#undef name
X#undef mode
X#undef dev
X
X
X
X/****************************************
Xsync()
X***************************************/
X
X_sync()
X{
X    register j;
X    register inoptr ino;
X    register char *buf;
X    char *bread();
X
X    /* Write out modified inodes */
X
X    for (ino=i_tab; ino < i_tab+ITABSIZE; ++ino)
X	if ((ino->c_refs) > 0 && ino->c_dirty != 0)
X	{
X	    wr_inode(ino);
X	    ino->c_dirty = 0;
X	}
X
X    /* Write out modified super blocks */
X    /* This fills the rest of the super block with garbage. */
X
X    for (j=0; j < NDEVS; ++j)
X    {
X	if (fs_tab[j].s_mounted == SMOUNTED && fs_tab[j].s_fmod)
X	{
X	    fs_tab[j].s_fmod = 0;
X	    buf = bread(j, 1, 1);
X	    bcopy((char *)&fs_tab[j], buf, 512);
X	    bfree(buf, 2);
X	}
X    }
X
X    bufsync();   /* Clear buffer pool */
X}
X
X
X/****************************************
Xaccess(path,mode)
Xchar *path;
Xint16 mode;
X****************************************/
X
X#define path (char *)udata.u_argn1
X#define mode (int16)udata.u_argn
X
X_access()
X{
X    register inoptr ino;
X    register int16 euid;
X    register int16 egid;
X    register int16 retval;
X    inoptr n_open();
X
X    if ((mode & 07) && !*(path))
X    {
X	udata.u_error = ENOENT;
X	return (-1);
X    }
X
X    /* Temporarily make eff. id real id. */
X    euid = udata.u_euid;
X    egid = udata.u_egid;
X    udata.u_euid = udata.u_ptab->p_uid;
X    udata.u_egid = udata.u_gid;
X
X    ifnot (ino = n_open(path,NULLINOPTR))
X    {
X	retval = -1;
X	goto nogood;
X    }
X
X    retval = 0;
X    if (~getperm(ino) & (mode&07))
X    {
X	udata.u_error = EPERM;
X	retval = -1;
X    }
X
X    i_deref(ino);
Xnogood:
X    udata.u_euid = euid;
X    udata.u_egid = egid;
X
X    return(retval);
X}
X
X#undef path
X#undef mode
X
X
X
X/*******************************************
Xchmod(path,mode)
Xchar *path;
Xint16 mode;
X*******************************************/
X
X#define path (char *)udata.u_argn1
X#define mode (int16)udata.u_argn
X
X_chmod()
X{
X
X    inoptr ino;
X    inoptr n_open();
X
X    ifnot (ino = n_open(path,NULLINOPTR))
X	return (-1);
X
X    if (ino->c_node.i_uid != udata.u_euid && !super())
X    {
X	i_deref(ino);
X	udata.u_error = EPERM;
X	return(-1);
X    }
X
X    ino->c_node.i_mode = (mode & MODE_MASK) | (ino->c_node.i_mode & F_MASK);
X    setftime(ino, C_TIME);
X    i_deref(ino);
X    return(0);
X}
X
X#undef path
X#undef mode
X
X
X
X/***********************************************
Xchown(path, owner, group)
Xchar *path;
Xint owner;
Xint group;
X**********************************************/
X
X#define path (char *)udata.u_argn2
X#define owner (int16)udata.u_argn1
X#define group (int16)udata.u_argn
X
X_chown()
X{
X    register inoptr ino;
X    inoptr n_open();
X
X    ifnot (ino = n_open(path,NULLINOPTR))
X	return (-1);
X
X    if (ino->c_node.i_uid != udata.u_euid && !super())
X    {
X	i_deref(ino);
X	udata.u_error = EPERM;
X	return(-1);
X    }
X
X    ino->c_node.i_uid = owner;
X    ino->c_node.i_gid = group;
X    setftime(ino, C_TIME);
X    i_deref(ino);
X    return(0);
X}
X
X#undef path
X#undef owner
X#undef group
X
X
X
X/**************************************
Xstat(path,buf)
Xchar *path;
Xchar *buf;
X****************************************/
X
X#define path (char *)udata.u_argn1
X#define buf (char *)udata.u_argn
X
X_stat()
X{
X
X    register inoptr ino;
X    inoptr n_open();
X
X    ifnot (valadr(buf,sizeof(struct stat)) && (ino = n_open(path,NULLINOPTR)))
X    {
X	return (-1);
X    }
X
X    stcpy(ino,buf);
X    i_deref(ino);
X    return(0);
X}
X
X#undef path
X#undef buf
X
X
X
X/********************************************
Xfstat(fd, buf)
Xint16 fd;
Xchar *buf;
X********************************************/
X
X#define fd (int16)udata.u_argn1
X#define buf (char *)udata.u_argn
X
X_fstat()
X{
X    register inoptr ino;
X    inoptr getinode();
X
X    ifnot (valadr(buf,sizeof(struct stat)))
X	return(-1);
X
X    if ((ino = getinode(fd)) == NULLINODE)
X	return(-1);
X
X    stcpy(ino,buf);
X    return(0);
X}
X
X#undef fd
X#undef buf
X
X
X/* Utility for stat and fstat */
Xstcpy(ino, buf)
Xinoptr ino;
Xchar *buf;
X{
X    /* violently system-dependent */
X    bcopy((char *)&(ino->c_dev), buf, 12);
X    bcopy((char *)&(ino->c_node.i_addr[0]), buf+12, 2);
X    bcopy((char *)&(ino->c_node.i_size), buf+14, 16);
X}
X
X
X
X/************************************
Xdup(oldd)
Xint16 oldd;
X************************************/
X
X#define oldd (uint16)udata.u_argn
X
X_dup()
X{
X    register int newd;
X    inoptr getinode();
X
X    if (getinode(oldd) == NULLINODE)
X	return(-1);
X
X    if ((newd = uf_alloc()) == -1)
X	return (-1);
X
X    udata.u_files[newd] = udata.u_files[oldd];
X    ++of_tab[udata.u_files[oldd]].o_refs;
X
X    return(newd);
X}
X
X#undef oldd
X
X
X
X/****************************************
Xdup2(oldd, newd)
Xint16 oldd;
Xint16 newd;
X****************************************/
X
X#define oldd (int16)udata.u_argn1
X#define newd (int16)udata.u_argn
X
X_dup2()
X{
X    inoptr getinode();
X
X    if (getinode(oldd) == NULLINODE)
X	return(-1);
X
X    if (newd < 0 || newd >= UFTSIZE)
X    {
X	udata.u_error = EBADF;
X	return (-1);
X    }
X
X    ifnot (udata.u_files[newd] & 0x80)
X	doclose(newd);
X
X    udata.u_files[newd] = udata.u_files[oldd];
X    ++of_tab[udata.u_files[oldd]].o_refs;
X
X    return(0);
X}
X
X#undef oldd
X#undef newd
X
X
X
X/**************************************
Xumask(mask)
Xint mask;
X*************************************/
X
X#define mask (int16)udata.u_argn
X
X_umask()
X{
X    register int omask;
X
X    omask = udata.u_mask;
X    udata.u_mask = mask & 0777;
X    return(omask);
X}
X
X#undef mask
X
X
X
X/* Special system call returns super-block of given
Xfilesystem for users to determine free space, etc.
XShould be replaced with a sync() followed by a read
Xof block 1 of the device.  */
X
X/***********************************************
Xgetfsys(dev,buf)
Xint16 dev;
Xstruct filesys *buf;
X**************************************************/
X
X#define dev (int16)udata.u_argn1
X#define buf (struct filesys *)udata.u_argn
X
X_getfsys()
X{
X   if (dev < 0 || dev >= NDEVS || fs_tab[dev].s_mounted != SMOUNTED)
X   {
X       udata.u_error = ENXIO;
X       return(-1);
X    }
X
X    bcopy((char *)&fs_tab[dev],(char *)buf,sizeof(struct filesys));
X    return(0);
X}
X
X#undef dev
X#undef buf
X
X
X
X/****************************************
Xioctl(fd, request, data)
Xint fd;
Xint request;
Xchar *data;
X*******************************************/
X
X#define fd (int)udata.u_argn2
X#define request (int)udata.u_argn1
X#define data (char *)udata.u_argn
X
X_ioctl()
X{
X
X    register inoptr ino;
X    register int dev;
X    inoptr getinode();
X
X    if ((ino = getinode(fd)) == NULLINODE)
X	return(-1);
X
X    ifnot (isdevice(ino))
X    {
X	udata.u_error = ENOTTY;
X	return(-1);
X    }
X
X    ifnot (getperm(ino) & OTH_WR)
X    {
X	udata.u_error = EPERM;
X	return(-1);
X    }
X
X    dev = ino->c_node.i_addr[0];
X
X    if (d_ioctl(dev, request,data))
X	return(-1);
X    return(0);
X}
X
X#undef fd
X#undef request
X#undef data
X
X
X
X/* This implementation of mount ignores the rwflag */
X
X/*****************************************
Xmount(spec, dir, rwflag)
Xchar *spec;
Xchar *dir;
Xint rwflag;
X*******************************************/
X
X#define spec (char *)udata.u_argn2
X#define dir (char *)udata.u_argn1
X#define rwflag (int)udata.u_argn
X
X_mount()
X{
X    register inoptr sino, dino;
X    register int dev;
X    inoptr n_open();
X
X    ifnot(super())
X    {
X	udata.u_error = EPERM;
X	return (-1);
X    }
X
X    ifnot (sino = n_open(spec,NULLINOPTR))
X	return (-1);
X
X    ifnot (dino = n_open(dir,NULLINOPTR))
X    {
X	i_deref(sino);
X	return (-1);
X    }
X
X    if (getmode(sino) != F_BDEV)
X    {
X	udata.u_error = ENOTBLK;
X	goto nogood;
X    }
X
X    if (getmode(dino) != F_DIR)
X    {
X	udata.u_error = ENOTDIR;
X	goto nogood;
X    }
X
X    dev = (int)sino->c_node.i_addr[0];
X
X    if ( dev >= NDEVS || d_open(dev))
X    {
X	udata.u_error = ENXIO;
X	goto nogood;
X    }
X
X    if (fs_tab[dev].s_mounted || dino->c_refs != 1 || dino->c_num == ROOTINODE)
X    {
X       udata.u_error = EBUSY;
X       goto nogood;
X    }
X
X    _sync();
X
X    if (fmount(dev,dino))
X    {
X       udata.u_error = EBUSY;
X       goto nogood;
X    }
X
X    i_deref(dino);
X    i_deref(sino);
X    return(0);
X
Xnogood:
X    i_deref(dino);
X    i_deref(sino);
X    return (-1);
X}
X
X#undef spec
X#undef dir
X#undef rwflag
X
X
X
X/******************************************
Xumount(spec)
Xchar *spec;
X******************************************/
X
X#define spec (char *)udata.u_argn
X
X_umount()
X{
X    register inoptr sino;
X    register int dev;
X    register inoptr ptr;
X    inoptr n_open();
X
X    ifnot(super())
X    {
X	udata.u_error = EPERM;
X	return (-1);
X    }
X
X    ifnot (sino = n_open(spec,NULLINOPTR))
X	return (-1);
X
X    if (getmode(sino) != F_BDEV)
X    {
X	udata.u_error = ENOTBLK;
X	goto nogood;
X    }
X
X    dev = (int)sino->c_node.i_addr[0];
X    ifnot (validdev(dev))
X    {
X	udata.u_error = ENXIO;
X	goto nogood;
X    }
X
X    if (!fs_tab[dev].s_mounted)
X    {
X	udata.u_error = EINVAL;
X	goto nogood;
X    }
X
X    for (ptr = i_tab; ptr < i_tab+ITABSIZE; ++ptr)
X	if (ptr->c_refs > 0 && ptr->c_dev == dev)
X	{
X	    udata.u_error = EBUSY;
X	    goto nogood;
X	}
X
X    _sync();
X    fs_tab[dev].s_mounted = 0;
X    i_deref(fs_tab[dev].s_mntpt);
X
X    i_deref(sino);
X    return(0);
X
Xnogood:
X    i_deref(sino);
X    return (-1);
X}
X
X#undef spec
X
EOF_scall1.c
echo 'Done'

exit 0

Doug Braun				Intel Corp CAD
					408 765-4279

 / decwrl \
 | hplabs |
-| oliveb |- !intelca!mipos3!cadev4!dbraun
 | amd    |
 \ qantel /