|
|
1.1 ! root 1: #include "sys/param.h" ! 2: #include "sys/user.h" ! 3: #include "sys/filsys.h" ! 4: #include "sys/file.h" ! 5: #include "sys/conf.h" ! 6: #include "sys/inode.h" ! 7: #include "sys/stream.h" ! 8: #include "sys/buf.h" ! 9: #include "sys/acct.h" ! 10: ! 11: /* ! 12: * Convert a user supplied ! 13: * file descriptor into a pointer ! 14: * to a file structure. ! 15: * Only task is to check range ! 16: * of the descriptor. ! 17: */ ! 18: ! 19: #ifndef getf /* done inline */ ! 20: ! 21: struct file * ! 22: getf(f) ! 23: register int f; ! 24: { ! 25: register struct file *fp; ! 26: ! 27: if ((unsigned)f >= NOFILE || (fp = u.u_ofile[f]) == NULL) ! 28: return (NULL); ! 29: return (fp); ! 30: } ! 31: ! 32: #endif ! 33: ! 34: /* ! 35: * Internal form of close. ! 36: * Decrement reference count on ! 37: * file structure. ! 38: * Decrement reference count on the inode following ! 39: * removal to the referencing file structure. ! 40: */ ! 41: closef(fp) ! 42: register struct file *fp; ! 43: { ! 44: struct inode *ip; ! 45: ! 46: if(fp == NULL) ! 47: return; ! 48: if (fp->f_count > 1) { ! 49: fp->f_count--; ! 50: return; ! 51: } ! 52: ip = fp->f_inode; ! 53: plock(ip); ! 54: iput(ip); ! 55: fp->f_count = 0; ! 56: } ! 57: ! 58: /* ! 59: * close the file opened on ip ! 60: * called from iput when last reference is removed; ! 61: * ip is locked, and i_count == 1 ! 62: * ! 63: * free files with no links; ! 64: * call device driver for special files ! 65: */ ! 66: ! 67: extern int rootfstyp; ! 68: extern dev_t rootdev; ! 69: ! 70: closei(ip) ! 71: register struct inode *ip; ! 72: { ! 73: register dev_t dev; ! 74: register int (*cfunc)(); ! 75: ! 76: if (ip->i_sptr) ! 77: stclose(ip, 1); ! 78: if ((ip->i_flag & IOPEN) == 0) ! 79: return; ! 80: ip->i_flag &=~ IOPEN; ! 81: if(ip->i_fstyp) /* temporary hack */ ! 82: return; ! 83: dev = (dev_t)ip->i_un.i_rdev; ! 84: switch(ip->i_mode & IFMT) { ! 85: ! 86: case IFCHR: ! 87: cfunc = cdevsw[major(dev)]->d_close; ! 88: break; ! 89: ! 90: case IFBLK: ! 91: if (rootfstyp == 0 && rootdev == dev) /* awful hack: root is not open */ ! 92: return; ! 93: bflush(dev); ! 94: binval(dev); ! 95: cfunc = bdevsw[major(dev)]->d_close; ! 96: break; ! 97: ! 98: default: ! 99: return; ! 100: } ! 101: (*cfunc)(dev); ! 102: } ! 103: ! 104: /* ! 105: * the default open routine for the file system switch entry `t_open' ! 106: */ ! 107: struct inode * ! 108: nullopen(ip, rw) ! 109: struct inode *ip; ! 110: { ! 111: return(ip); ! 112: } ! 113: ! 114: /* ! 115: * openi called to allow handler ! 116: * of special files to initialize and ! 117: * validate before actual IO. ! 118: * returns the inode, ! 119: * NULL if error. ! 120: * may return an alternate inode, ! 121: * in which event the original has been put. ! 122: * ! 123: * responsibilities of open routines (fs and stream): ! 124: * if an inode is returned, it is unlocked, ! 125: * and any other inode has been put. ! 126: * if an error happens, NULL is returned and ip is put. ! 127: */ ! 128: struct inode * ! 129: openi(ip, rw) ! 130: register struct inode *ip; ! 131: { ! 132: register dev_t dev; ! 133: ! 134: dev = (dev_t)ip->i_un.i_rdev; ! 135: if (ip->i_sptr) /* stream is attached */ ! 136: ip = stopen(cdevsw[major(dev)]->qinfo, dev, rw, ip); ! 137: else ! 138: ip = (*fstypsw[ip->i_fstyp]->t_open)(ip, rw); ! 139: if (ip) ! 140: ip->i_flag |= IOPEN; ! 141: else if (u.u_error == 0) /* temporary firewall */ ! 142: panic("openi"); ! 143: return (ip); ! 144: } ! 145: ! 146: /* ! 147: * Check mode permission on inode pointer. ! 148: * Mode is READ, WRITE or EXEC. ! 149: * In the case of WRITE, the ! 150: * read-only status of the file ! 151: * system is checked. ! 152: * Also in WRITE, prototype text ! 153: * segments cannot be written. ! 154: * The mode is shifted to select ! 155: * the owner/group/other fields. ! 156: * The super user is granted all ! 157: * permissions. ! 158: */ ! 159: access(ip, mode) ! 160: register struct inode *ip; ! 161: { ! 162: register m; ! 163: register short *gp; ! 164: ! 165: m = mode; ! 166: if(m == IWRITE) { ! 167: if(ip->i_fstyp==0 && ip->i_un.i_bufp->b_un.b_filsys->s_ronly != 0) { ! 168: u.u_error = EROFS; ! 169: return(1); ! 170: } ! 171: if (ip->i_flag&ITEXT) /* try to free text */ ! 172: xrele(ip); ! 173: if(ip->i_flag & ITEXT) { ! 174: u.u_error = ETXTBSY; ! 175: return(1); ! 176: } ! 177: } ! 178: if(u.u_uid == 0) ! 179: return(0); ! 180: if(u.u_uid != ip->i_uid) { ! 181: m >>= 3; ! 182: if(u.u_gid == ip->i_gid) ! 183: goto found; ! 184: gp = u.u_groups; ! 185: for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) ! 186: if (ip->i_gid == *gp) ! 187: goto found; ! 188: m >>= 3; ! 189: } ! 190: found: ! 191: if((ip->i_mode&m) != 0) ! 192: return(0); ! 193: ! 194: u.u_error = EACCES; ! 195: return(1); ! 196: } ! 197: ! 198: /* ! 199: * check inode ownership. ! 200: * succeeds if the current user owns the file, ! 201: * or is the super-user. ! 202: */ ! 203: accowner(ip) ! 204: register struct inode *ip; ! 205: { ! 206: ! 207: if(u.u_uid == ip->i_uid) ! 208: return(1); ! 209: if(suser()) ! 210: return(1); ! 211: return(0); ! 212: } ! 213: ! 214: /* ! 215: * Return 0 if the file isn't open for writing, 1 if it is ! 216: */ ! 217: writers(ip) ! 218: register struct inode *ip; ! 219: { ! 220: register struct file *fp; ! 221: ! 222: for (fp = file; fp < fileNFILE; fp++) ! 223: if (fp->f_count!=0 && fp->f_inode==ip && (fp->f_flag&FWRITE)) ! 224: return(1); ! 225: return(0); ! 226: } ! 227: ! 228: /* ! 229: * Control concurrent access to a file. The possibile types are: ! 230: * - 1 writer and n readers (I1WNR) ! 231: * - 1 writer or n readers (ILCKD) ! 232: * The file pointers are searched. If an open with the given mode ! 233: * would result in a violation, errno is set to ECONC. ! 234: */ ! 235: concurrency(ip, mode) ! 236: register struct inode *ip; ! 237: int mode; ! 238: { ! 239: switch(ip->i_mode&ICCTYP) { ! 240: case ISYNC: ! 241: if ((mode&FWRITE) && writers(ip)) ! 242: u.u_error = ECONC; ! 243: break; ! 244: case IEXCL: ! 245: if ((mode&FWRITE) || writers(ip)) ! 246: u.u_error = ECONC; ! 247: break; ! 248: } ! 249: } ! 250: ! 251: /* ! 252: * Test if the current user is the ! 253: * super user. ! 254: */ ! 255: suser() ! 256: { ! 257: ! 258: if(u.u_uid == 0) { ! 259: u.u_acflag |= ASU; ! 260: return(1); ! 261: } ! 262: u.u_error = EPERM; ! 263: return(0); ! 264: } ! 265: ! 266: /* ! 267: * Allocate a user file descriptor. ! 268: */ ! 269: ufalloc() ! 270: { ! 271: register i; ! 272: ! 273: for(i=0; i<NOFILE; i++) ! 274: if(u.u_ofile[i] == NULL) { ! 275: u.u_r.r_val1 = i; ! 276: u.u_pofile[i] = 0; ! 277: return(i); ! 278: } ! 279: u.u_error = EMFILE; ! 280: return(-1); ! 281: } ! 282: ! 283: struct file *lastf; ! 284: /* ! 285: * Allocate a user file descriptor ! 286: * and a file structure. ! 287: * Initialize the descriptor ! 288: * to point at the file structure. ! 289: */ ! 290: struct file * ! 291: falloc() ! 292: { ! 293: register struct file *fp; ! 294: register i; ! 295: ! 296: i = ufalloc(); ! 297: if (i < 0) ! 298: return(NULL); ! 299: if ((fp = allocfile()) == NULL) { ! 300: u.u_error = ENFILE; ! 301: return(NULL); ! 302: } ! 303: u.u_ofile[i] = fp; ! 304: return (fp); ! 305: } ! 306: ! 307: /* ! 308: * allocate file structure ! 309: */ ! 310: struct file * ! 311: allocfile() ! 312: { ! 313: register struct file *fp; ! 314: ! 315: if (lastf == 0) ! 316: lastf = file; ! 317: for (fp = lastf; fp < fileNFILE; fp++) ! 318: if (fp->f_count == 0) ! 319: goto gotit; ! 320: for (fp = file; fp < lastf; fp++) ! 321: if (fp->f_count == 0) ! 322: goto gotit; ! 323: tablefull("file"); ! 324: return (NULL); ! 325: gotit: ! 326: lastf = fp + 1; ! 327: fp->f_count++; ! 328: fp->f_offset = ltoL(0); ! 329: return(fp); ! 330: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.