1: /*
   2:  *	SCCS id	@(#)sys3.c	2.1 (Berkeley)	9/4/83
   3:  */
   4: 
   5: #include "param.h"
   6: #include <sys/systm.h>
   7: #include <sys/ino.h>
   8: #include <sys/reg.h>
   9: #include <sys/buf.h>
  10: #include <sys/filsys.h>
  11: #include <sys/mount.h>
  12: #include <sys/dir.h>
  13: #include <sys/user.h>
  14: #include <sys/inode.h>
  15: #include <sys/file.h>
  16: #include <sys/conf.h>
  17: #include <sys/stat.h>
  18: #include <sys/inline.h>
  19: 
  20: 
  21: /*
  22:  * the fstat system call.
  23:  */
  24: fstat()
  25: {
  26:     register struct file *fp;
  27:     register struct a {
  28:         int fdes;
  29:         struct stat *sb;
  30:     } *uap;
  31: 
  32:     uap = (struct a *)u.u_ap;
  33:     fp = getf(uap->fdes);
  34:     if (fp == NULL)
  35:         return;
  36: #ifdef  UCB_NET
  37:     if (fp->f_flag & FSOCKET)
  38:         u.u_error = sostat(fp->f_socket, uap->sb);
  39:     else
  40: #endif
  41:         stat1(fp->f_inode, uap->sb, fp->f_flag & FPIPE?  fp->f_un.f_offset: (off_t) 0);
  42: }
  43: 
  44: /*
  45:  * the stat system call.
  46:  */
  47: stat()
  48: {
  49:     register struct inode *ip;
  50:     register struct a {
  51:         char    *fname;
  52:         struct stat *sb;
  53:     } *uap;
  54: 
  55:     uap = (struct a *)u.u_ap;
  56: #ifndef UCB_SYMLINKS
  57:     ip = namei(uchar, LOOKUP);
  58: #else
  59:     ip = namei(uchar, LOOKUP, 1);
  60: #endif
  61:     if (ip == NULL)
  62:         return;
  63:     stat1(ip, uap->sb, (off_t)0);
  64:     iput(ip);
  65: }
  66: 
  67: #ifdef  UCB_SYMLINKS
  68: /*
  69:  * Lstat system call; like stat but doesn't follow links.
  70:  */
  71: lstat()
  72: {
  73:     register struct inode *ip;
  74:     register struct a {
  75:         char    *fname;
  76:         struct stat *sb;
  77:     } *uap;
  78: 
  79:     uap = (struct a *)u.u_ap;
  80:     ip = namei(uchar, 0, 0);
  81:     if (ip == NULL)
  82:         return;
  83:     stat1(ip, uap->sb, (off_t)0);
  84:     iput(ip);
  85: }
  86: #endif
  87: 
  88: /*
  89:  * The basic routine for fstat and stat:
  90:  * get the inode and pass appropriate parts back.
  91:  */
  92: stat1(ip, ub, pipeadj)
  93: register struct inode *ip;
  94: struct stat *ub;
  95: off_t pipeadj;
  96: {
  97:     register struct dinode *dp;
  98:     register struct buf *bp;
  99:     struct stat ds;
 100: 
 101: #ifdef UCB_FSFIX
 102:     IUPDAT(ip, &time, &time, 0);
 103: #else
 104:     IUPDAT(ip, &time, &time);
 105: #endif
 106:     /*
 107: 	 * first copy from inode table
 108: 	 */
 109:     ds.st_dev = ip->i_dev;
 110:     ds.st_ino = ip->i_number;
 111:     ds.st_mode = ip->i_mode;
 112:     ds.st_nlink = ip->i_nlink;
 113:     ds.st_uid = ip->i_uid;
 114:     ds.st_gid = ip->i_gid;
 115:     ds.st_rdev = (dev_t)ip->i_un.i_rdev;
 116:     ds.st_size = ip->i_size - pipeadj;
 117:     /*
 118: 	 * next the dates in the disk
 119: 	 */
 120:     bp = bread(ip->i_dev, itod(ip->i_number));
 121:     dp = (struct dinode *) mapin(bp);
 122:     dp += itoo(ip->i_number);
 123:     ds.st_atime = dp->di_atime;
 124:     ds.st_mtime = dp->di_mtime;
 125:     ds.st_ctime = dp->di_ctime;
 126:     mapout(bp);
 127:     brelse(bp);
 128:     if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
 129:         u.u_error = EFAULT;
 130: }
 131: 
 132: /*
 133:  * the dup system call.
 134:  */
 135: dup()
 136: {
 137:     register struct file *fp;
 138:     register struct a {
 139:         int fdes;
 140:         int fdes2;
 141:     } *uap;
 142:     register i, m;
 143: 
 144:     uap = (struct a *)u.u_ap;
 145:     m = uap->fdes & ~077;
 146:     uap->fdes &= 077;
 147:     fp = getf(uap->fdes);
 148:     if (fp == NULL)
 149:         return;
 150:     if ((m&0100) == 0) {
 151:         if ((i = ufalloc()) < 0)
 152:             return;
 153:     } else {
 154:         i = uap->fdes2;
 155:         if (i<0 || i>=NOFILE) {
 156:             u.u_error = EBADF;
 157:             return;
 158:         }
 159:         u.u_r.r_val1 = i;
 160:     }
 161:     if (i!=uap->fdes) {
 162:         if (u.u_ofile[i]!=NULL)
 163: #ifndef UCB_NET
 164:             closef(u.u_ofile[i]);
 165: #else
 166:             closef(u.u_ofile[i],0);
 167: #endif
 168:         u.u_ofile[i] = fp;
 169:         fp->f_count++;
 170:     }
 171: }
 172: 
 173: /*
 174:  * the mount system call.
 175:  */
 176: smount()
 177: {
 178:     dev_t dev;
 179:     char *cp;
 180:     register struct inode *ip;
 181:     register struct mount *mp;
 182:     struct mount *smp;
 183:     register struct filsys *fp;
 184:     struct buf *bp;
 185:     register struct a {
 186:         char    *fspec;
 187:         char    *freg;
 188:         int ronly;
 189:     } *uap;
 190: 
 191:     uap = (struct a *)u.u_ap;
 192:     dev = getmdev();
 193:     if (u.u_error || !suser())
 194:         return;
 195:     u.u_dirp = (caddr_t)uap->freg;
 196: #ifndef UCB_SYMLINKS
 197:     ip = namei(uchar, LOOKUP);
 198: #else
 199:     ip = namei(uchar, LOOKUP, 1);
 200: #endif
 201:     if (ip == NULL)
 202:         return;
 203:     if (ip->i_count != 1 || (ip->i_mode & (IFBLK & IFCHR)) != 0)
 204:         goto out;
 205:     smp = NULL;
 206:     for(mp = mount; mp < mountNMOUNT; mp++) {
 207:         if (mp->m_inodp != NULL) {
 208:             if (dev == mp->m_dev)
 209:                 goto out;
 210:         } else
 211:             if (smp == NULL)
 212:                 smp = mp;
 213:     }
 214:     mp = smp;
 215:     if (mp == NULL)
 216:         goto out;
 217:     (*bdevsw[major(dev)].d_open)(dev, !uap->ronly);
 218:     if (u.u_error)
 219:         goto out;
 220:     bp = bread(dev, SUPERB);
 221:     if (u.u_error) {
 222:         brelse(bp);
 223:         goto out1;
 224:     }
 225:     mp->m_inodp = ip;
 226:     mp->m_dev = dev;
 227:     fp = &mp->m_filsys;
 228:     bcopy((caddr_t) mapin(bp), (caddr_t)fp, sizeof(struct filsys));
 229:     mapout(bp);
 230:     fp->s_ilock = 0;
 231:     fp->s_flock = 0;
 232:     fp->s_ronly = uap->ronly & 1;
 233: #ifdef  UCB_IHASH
 234:     fp->s_nbehind = 0;
 235:     fp->s_lasti = 1;
 236: #endif
 237:     u.u_dirp = uap->freg;
 238:     for (cp = fp->s_fsmnt; cp < &fp->s_fsmnt[sizeof(fp->s_fsmnt) - 1];)
 239:         if ((*cp++ = uchar()) == 0)
 240:             u.u_dirp--;     /* get 0 again */
 241:     *cp = 0;
 242:     brelse(bp);
 243:     ip->i_flag |= IMOUNT;
 244:     prele(ip);
 245:     return;
 246: 
 247: out:
 248:     u.u_error = EBUSY;
 249: out1:
 250:     iput(ip);
 251: }
 252: 
 253: /*
 254:  * the umount system call.
 255:  */
 256: sumount()
 257: {
 258:     dev_t dev;
 259:     register struct inode *ip;
 260:     register struct mount *mp;
 261:     register struct buf *bp;
 262:     struct buf *dp;
 263: 
 264:     dev = getmdev();
 265:     if (u.u_error || !suser())
 266:         return;
 267:     xumount(dev);   /* remove unused sticky files from text table */
 268:     update();
 269:     for (mp = mount; mp < mountNMOUNT; mp++)
 270:         if (mp->m_inodp != NULL && dev == mp->m_dev) {
 271:             for(ip = inode; ip < inodeNINODE; ip++)
 272:                 if (ip->i_number != 0 && dev == ip->i_dev) {
 273:                     u.u_error = EBUSY;
 274:                     return;
 275:                 }
 276:             (*bdevsw[major(dev)].d_close)(dev, 0);
 277:             dp = bdevsw[major(dev)].d_tab;
 278:             for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) {
 279:                 (void) _spl6();
 280:                 if (bp->b_dev == dev) {
 281: #ifdef UCB_BHASH
 282:                     bunhash(bp);
 283: #endif
 284:                     bp->b_dev = NODEV;
 285:                 }
 286:                 (void) _spl0();
 287:             }
 288:             ip = mp->m_inodp;
 289:             ip->i_flag &= ~IMOUNT;
 290:             plock(ip);
 291:             iput(ip);
 292:             mp->m_inodp = NULL;
 293:             return;
 294:         }
 295: 
 296:     u.u_error = EINVAL;
 297: }
 298: 
 299: /*
 300:  * Common code for mount and umount.
 301:  * Check that the user's argument is a reasonable
 302:  * thing on which to mount, and return the device number if so.
 303:  */
 304: dev_t
 305: getmdev()
 306: {
 307:     register dev_t dev;
 308:     register struct inode *ip;
 309: 
 310: #ifndef UCB_SYMLINKS
 311:     ip = namei(uchar, LOOKUP);
 312: #else
 313:     ip = namei(uchar, LOOKUP, 1);
 314: #endif
 315:     if (ip == NULL)
 316:         return(NODEV);
 317:     if ((ip->i_mode&IFMT) != IFBLK)
 318:         u.u_error = ENOTBLK;
 319:     dev = (dev_t)ip->i_un.i_rdev;
 320:     if (major(dev) >= nblkdev)
 321:         u.u_error = ENXIO;
 322:     iput(ip);
 323:     return(dev);
 324: }
 325: 
 326: #ifdef  UCB_SYMLINKS
 327: /*
 328:  * Return target name of a symbolic link
 329:  */
 330: readlink()
 331: {
 332:     register struct inode *ip;
 333:     register struct a {
 334:         char    *name;
 335:         char    *buf;
 336:         int count;
 337:     } *uap;
 338: 
 339:     ip = namei(uchar, 0, 0);
 340:     if (ip == NULL)
 341:         return;
 342:     if ((ip->i_mode&IFMT) != IFLNK) {
 343:         u.u_error = ENXIO;
 344:         goto out;
 345:     }
 346:     uap = (struct a *)u.u_ap;
 347:     u.u_offset = 0;
 348:     u.u_base = uap->buf;
 349:     u.u_count = uap->count;
 350:     u.u_segflg = 0;
 351:     readi(ip);
 352: out:
 353:     iput(ip);
 354:     u.u_r.r_val1 = uap->count - u.u_count;
 355: }
 356: 
 357: /*
 358:  * symlink -- make a symbolic link
 359:  */
 360: symlink()
 361: {
 362:     register struct a {
 363:         char    *target;
 364:         char    *linkname;
 365:     } *uap;
 366:     register struct inode *ip;
 367:     register char *tp;
 368:     register c, nc;
 369: 
 370:     uap = (struct a *)u.u_ap;
 371:     tp = uap->target;
 372:     nc = 0;
 373:     while (c = fubyte(tp)) {
 374:         if (c < 0) {
 375:             u.u_error = EFAULT;
 376:             return;
 377:         }
 378:         tp++;
 379:         nc++;
 380:     }
 381:     u.u_dirp = uap->linkname;
 382:     ip = namei(uchar, 1, 0);
 383:     if (ip) {
 384:         iput(ip);
 385:         u.u_error = EEXIST;
 386:         return;
 387:     }
 388:     if (u.u_error)
 389:         return;
 390:     ip = maknode(IFLNK | 0777);
 391:     if (ip == NULL)
 392:         return;
 393:     u.u_base = uap->target;
 394:     u.u_count = nc;
 395:     u.u_offset = 0;
 396:     u.u_segflg = 0;
 397:     writei(ip);
 398:     iput(ip);
 399: }
 400: #endif	UCB_SYMLINKS

Defined functions

dup defined in line 135; used 2 times
fstat defined in line 24; used 2 times
getmdev defined in line 304; used 2 times
lstat defined in line 71; never used
readlink defined in line 330; never used
smount defined in line 176; used 2 times
stat defined in line 47; used 2 times
stat1 defined in line 92; used 3 times
sumount defined in line 256; used 2 times
symlink defined in line 360; never used

Defined struct's

a defined in line 362; used 14 times
Last modified: 1983-09-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1148
Valid CSS Valid XHTML 1.0 Strict