|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 7400 (0x1ce8) Types: TextFile Notes: UNIX file Names: »sys2.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦2d53db1df⟧ UNIX Filesystem └─⟦this⟧ »sys/coh/sys2.c«
/* (-lgl * The information contained herein is a trade secret of Mark Williams * Company, and is confidential information. It is provided under a * license agreement, and may be copied or disclosed only under the * terms of that agreement. Any reproduction or disclosure of this * material without the express written authorization of Mark Williams * Company or persuant to the license agreement is unlawful. * * COHERENT Version 0.7.3 * Copyright (c) 1982, 1983, 1984. * An unpublished work by Mark Williams Company, Chicago. * All rights reserved. -lgl) */ /* * Coherent. * System calls (filesystem related). */ #include <coherent.h> #include <errno.h> #include <fd.h> #include <ino.h> #include <inode.h> #include <mount.h> #include <stat.h> #include <uproc.h> /* * Determine accessibility of the given file. */ uaccess(np, mode) char *np; register int mode; { register INODE *ip; register int r; schizo(); r = ftoi(np, 'r'); schizo(); if (r != 0) return; ip = u.u_cdiri; if ((mode&imode(ip, u.u_ruid, u.u_rgid)) != mode) u.u_error = EACCES; idetach(ip); return (0); } /* * Schizo - swap real and effective id's. */ schizo() { register int t; t = u.u_uid; u.u_uid = u.u_ruid; u.u_ruid = t; t = u.u_gid; u.u_gid = u.u_rgid; u.u_rgid = t; } /* * Turn accounting on or off. */ uacct(np) register char *np; { register INODE *ip; if (super() == 0) return; if (np == NULL) { if (acctip == NULL) { u.u_error = EINVAL; return; } ldetach(acctip); acctip = NULL; } else { if (acctip != NULL) { u.u_error = EINVAL; return; } if (ftoi(np, 'r') != 0) return; ip = u.u_cdiri; if ((ip->i_mode&IFMT) != IFREG) { u.u_error = EINVAL; idetach(ip); return; } iunlock(ip); acctip = ip; } return (0); } /* * Set current directory. */ uchdir(np) char *np; { setcdir(np, &u.u_cdir); return (0); } /* * Given a directory name and a pointer to a working directory pointer, * Save the inode associated with the directory name in the working * directory pointer and release the old one. This is used to change * working and root directories. */ setcdir(np, ipp) char *np; register INODE **ipp; { register INODE *ip; if (ftoi(np, 'r') != 0) return; ip = u.u_cdiri; if ((ip->i_mode&IFMT) != IFDIR) { u.u_error = ENOTDIR; idetach(ip); return; } if (iaccess(ip, IPE) == 0) { u.u_error = EACCES; idetach(ip); return; } iunlock(ip); ldetach(*ipp); *ipp = ip; } /* * Change the mode of a file. */ uchmod(np, mode) char *np; { register INODE *ip; if (ftoi(np, 'r') != 0) return; ip = u.u_cdiri; if (owner(ip->i_uid)) { if (u.u_uid != 0) mode &= ~ISVTXT; ip->i_mode &= IFMT; ip->i_mode |= mode&~IFMT; icrt(ip); /* chmod - ctime */ } idetach(ip); return (0); } /* * Change owner and group of a file. */ uchown(np, uid, gid) char *np; { register INODE *ip; if (ftoi(np, 'r') != 0) return; ip = u.u_cdiri; if (super()) { ip->i_mode &= ~(ISUID | ISGID); /* clear any setuid/setgid */ ip->i_uid = uid; ip->i_gid = gid; icrt(ip); /* chown - ctime */ } idetach(ip); return (0); } /* * Set root directory. */ uchroot(np) register char *np; { if (super()) setcdir(np, &u.u_rdir); return (0); } /* * Close the given file descriptor. */ uclose(fd) { fdclose(fd); return (0); } /* * Create a file with the given mode. */ ucreat(np, mode) char *np; register int mode; { register INODE *ip; register int fd; register int cflag; cflag = 0; if (ftoi(np, 'c') != 0) return; if ((ip=u.u_cdiri) == NULL) { if ((ip=imake((mode&~IFMT)|IFREG, 0)) == NULL) return; } else { if (iaccess(ip, IPW)==0 || getment(ip->i_dev, 1)==NULL) { idetach(ip); return; } if ((ip->i_mode&IFMT) == IFDIR) { u.u_error = EISDIR; idetach(ip); return; } cflag = 1; } if ((fd=fdopen(ip, IPW)) < 0) { idetach(ip); return; } if (cflag) iclear(ip); iunlock(ip); return (fd); } /* * Duplicate a file descriptor. */ udup(ofd, nfd) { return (fddup(ofd, nfd)); } /* * Given a file descriptor, return a status structure. */ ufstat(fd, stp) struct stat *stp; { register INODE *ip; register FD *fdp; struct stat stat; if ((fdp=fdget(fd)) == NULL) return; ip = fdp->f_ip; istat(ip, &stat); kucopy(&stat, stp, sizeof(stat)); return (0); } /* * Device control information. */ uioctl(fd, r, argp) struct sgttyb *argp; { register FD *fdp; register INODE *ip; register int mode; if ((fdp=fdget(fd)) == NULL) return; ip = fdp->f_ip; mode = ip->i_mode&IFMT; if (mode!=IFCHR && mode!=IFBLK) { u.u_error = ENOTTY; return; } dioctl(ip->i_a.i_rdev, r, argp); return (0); } /* * Create a link, `np2' to the already existing file `np1'. */ ulink(np1, np2) char *np1; char *np2; { register INODE *ip1; if (ftoi(np1, 'r') != 0) return; ip1 = u.u_cdiri; if ((ip1->i_mode&IFMT)==IFDIR && super()==0) { idetach(ip1); return; } iunlock(ip1); if (ftoi(np2, 'c') != 0) { ldetach(ip1); return; } if (u.u_cdiri != NULL) { u.u_error = EEXIST; idetach(u.u_cdiri); ldetach(ip1); return; } if (ip1->i_dev != u.u_pdiri->i_dev) { u.u_error = EXDEV; idetach(u.u_pdiri); ldetach(ip1); return; } if (iaccess(u.u_pdiri, IPW) == 0) { idetach(u.u_pdiri); ldetach(ip1); return; } idirent(ip1->i_ino); idetach(u.u_pdiri); ilock(ip1); ip1->i_nlink++; icrt(ip1); /* link - ctime */ idetach(ip1); return (0); } /* * Seek on the given file descriptor. */ size_t ulseek(fd, off, w) register size_t off; { register FD *fdp; register INODE *ip; if ((fdp=fdget(fd)) == NULL) return; ip = fdp->f_ip; if ((ip->i_mode&IFMT) == IFPIPE) { u.u_error = ESPIPE; return; } switch (w) { case 0: break; case 1: off += fdp->f_seek; break; case 2: off += ip->i_size; break; default: u.u_error = EINVAL; return; } if (off < 0) { u.u_error = EINVAL; return; } fdp->f_seek = off; return (off); } /* * Create a special file. */ umknod(np, mode, rdev) char *np; dev_t rdev; { register INODE *ip; register int type; type = mode&IFMT; if (type!=IFPIPE && super()==0) return; if (type!=IFBLK && type!=IFCHR) rdev = 0; if (ftoi(np, 'c') != 0) return; if ((ip=u.u_cdiri) != NULL) { u.u_error = EEXIST; idetach(ip); return; } if ((ip=imake(mode, rdev)) != NULL) idetach(ip); return (0); } /* * Mount the device `sp' on the pathname `np'. The flag, `f', * indicates that the device is to be mounted read only. */ umount(sp, np, f) char *sp; char *np; { register INODE *ip; register MOUNT *mp; register dev_t rdev; register int mode; if (ftoi(sp, 'r') != 0) return; ip = u.u_cdiri; if (iaccess(ip, IPR|IPW) == 0) goto err; mode = ip->i_mode; rdev = ip->i_a.i_rdev; if ((mode&IFMT) != IFBLK) { u.u_error = ENOTBLK; goto err; } idetach(ip); if (ftoi(np, 'r') != 0) return; ip = u.u_cdiri; if (iaccess(ip, IPR) == 0) goto err; if ((ip->i_mode&IFMT) != IFDIR) { u.u_error = ENOTDIR; goto err; } /* Check for current directory, open, or mount directory */ if (ip->i_refc > 1 || ip->i_ino == ROOTIN) { u.u_error = EBUSY; goto err; } for (mp=mountp; mp!=NULL; mp=mp->m_next) { if (mp->m_dev == rdev) { u.u_error = EBUSY; goto err; } } if ((mp=fsmount(rdev, f)) == NULL) goto err; mp->m_ip = ip; ip->i_flag |= IFMNT; ip->i_refc++; err: idetach(ip); return (0); }