6600: # 6601: /* 6602: */ 6603: 6604: #include "../param.h" 6605: #include "../user.h" 6606: #include "../filsys.h" 6607: #include "../file.h" 6608: #include "../conf.h" 6609: #include "../inode.h" 6610: #include "../reg.h" 6611: 6612: /* 6613: * Convert a user supplied 6614: * file descriptor into a pointer 6615: * to a file structure. 6616: * Only task is to check range 6617: * of the descriptor. 6618: */ 6619: getf(f) 6620: { 6621: register *fp, rf; 6622: 6623: rf = f; 6624: if(rf<0 || rf>=NOFILE) 6625: goto bad; 6626: fp = u.u_ofile[rf]; 6627: if(fp != NULL) 6628: return(fp); 6629: bad: 6630: u.u_error = EBADF; 6631: return(NULL); 6632: } 6633: /* --------------------------- */ 6634: 6635: /* 6636: * Internal form of close. 6637: * Decrement reference count on 6638: * file structure and call closei 6639: * on last closef. 6640: * Also make sure the pipe protocol 6641: * does not constipate. 6642: */ 6643: closef(fp) 6644: int *fp; 6645: { 6646: register *rfp, *ip; 6647: 6648: rfp = fp; 6649: if(rfp->f_flag&FPIPE) { 6650: ip = rfp->f_inode; 6651: ip->i_mode =& ~(IREAD|IWRITE); 6652: wakeup(ip+1); 6653: wakeup(ip+2); 6654: } 6655: if(rfp->f_count <= 1) 6656: closei(rfp->f_inode, rfp->f_flag&FWRITE); 6657: rfp->f_count--; 6658: } 6659: /* --------------------------- */ 6660: 6661: /* 6662: * Decrement reference count on an 6663: * inode due to the removal of a 6664: * referencing file structure. 6665: * On the last closei, switchout 6666: * to the close entry point of special 6667: * device handler. 6668: * Note that the handler gets called 6669: * on every open and only on the last 6670: * close. 6671: */ 6672: closei(ip, rw) 6673: int *ip; 6674: { 6675: register *rip; 6676: register dev, maj; 6677: 6678: rip = ip; 6679: dev = rip->i_addr[0]; 6680: maj = rip->i_addr[0].d_major; 6681: if(rip->i_count <= 1) 6682: switch(rip->i_mode&IFMT) { 6683: 6684: case IFCHR: 6685: (*cdevsw[maj].d_close)(dev, rw); 6686: break; 6687: 6688: case IFBLK: 6689: (*bdevsw[maj].d_close)(dev, rw); 6690: } 6691: iput(rip); 6692: } 6693: /* --------------------------- */ 6694: 6695: /* 6696: * openi called to allow handler 6697: * of special files to initialize and 6698: * validate before actual IO. 6699: * Called on all sorts of opens 6700: * and also on mount. 6701: */ 6702: openi(ip, rw) 6703: int *ip; 6704: { 6705: register *rip; 6706: register dev, maj; 6707: 6708: rip = ip; 6709: dev = rip->i_addr[0]; 6710: maj = rip->i_addr[0].d_major; 6711: switch(rip->i_mode&IFMT) { 6712: 6713: case IFCHR: 6714: if(maj >= nchrdev) 6715: goto bad; 6716: (*cdevsw[maj].d_open)(dev, rw); 6717: break; 6718: 6719: case IFBLK: 6720: if(maj >= nblkdev) 6721: goto bad; 6722: (*bdevsw[maj].d_open)(dev, rw); 6723: } 6724: return; 6725: 6726: bad: 6727: u.u_error = ENXIO; 6728: } 6729: /* --------------------------- */ 6730: 6731: /* 6732: * Check mode permission on inode pointer. 6733: * Mode is READ, WRITE or EXEC. 6734: * In the case of WRITE, the 6735: * read-only status of the file 6736: * system is checked. 6737: * Also in WRITE, prototype text 6738: * segments cannot be written. 6739: * The mode is shifted to select 6740: * the owner/group/other fields. 6741: * The super user is granted all 6742: * permissions except for EXEC where 6743: * at least one of the EXEC bits must 6744: * be on. 6745: */ 6746: access(aip, mode) 6747: int *aip; 6748: { 6749: register *ip, m; 6750: 6751: ip = aip; 6752: m = mode; 6753: if(m == IWRITE) { 6754: if(getfs(ip->i_dev)->s_ronly != 0) { 6755: u.u_error = EROFS; 6756: return(1); 6757: } 6758: if(ip->i_flag & ITEXT) { 6759: u.u_error = ETXTBSY; 6760: return(1); 6761: } 6762: } 6763: if(u.u_uid == 0) { 6764: if(m == IEXEC && (ip->i_mode & 6765: (IEXEC | (IEXEC>>3) | (IEXEC>>6))) == 0) 6766: goto bad; 6767: return(0); 6768: } 6769: if(u.u_uid != ip->i_uid) { 6770: m =>> 3; 6771: if(u.u_gid != ip->i_gid) 6772: m =>> 3; 6773: } 6774: if((ip->i_mode&m) != 0) 6775: return(0); 6776: 6777: bad: 6778: u.u_error = EACCES; 6779: return(1); 6780: } 6781: /* --------------------------- */ 6782: 6783: /* 6784: * Look up a pathname and test if 6785: * the resultant inode is owned by the 6786: * current user. 6787: * If not, try for super-user. 6788: * If permission is granted, 6789: * return inode pointer. 6790: */ 6791: owner() 6792: { 6793: register struct inode *ip; 6794: extern uchar(); 6795: 6796: if ((ip = namei(uchar, 0)) == NULL) 6797: return(NULL); 6798: if(u.u_uid == ip->i_uid) 6799: return(ip); 6800: if (suser()) 6801: return(ip); 6802: iput(ip); 6803: return(NULL); 6804: } 6805: /* --------------------------- */ 6806: 6807: /* 6808: * Test if the current user is the 6809: * super user. 6810: */ 6811: suser() 6812: { 6813: 6814: if(u.u_uid == 0) 6815: return(1); 6816: u.u_error = EPERM; 6817: return(0); 6818: } 6819: /* --------------------------- */ 6820: 6821: /* 6822: * Allocate a user file descriptor. 6823: */ 6824: ufalloc() 6825: { 6826: register i; 6827: 6828: for (i=0; i<NOFILE; i++) 6829: if (u.u_ofile[i] == NULL) { 6830: u.u_ar0[R0] = i; 6831: return(i); 6832: } 6833: u.u_error = EMFILE; 6834: return(-1); 6835: } 6836: /* --------------------------- */ 6837: 6838: /* 6839: * Allocate a user file descriptor 6840: * and a file structure. 6841: * Initialize the descriptor 6842: * to point at the file structure. 6843: * 6844: * no file -- if there are no available 6845: * file structures. 6846: */ 6847: falloc() 6848: { 6849: register struct file *fp; 6850: register i; 6851: 6852: if ((i = ufalloc()) < 0) 6853: return(NULL); 6854: for (fp = &file[0]; fp < &file[NFILE]; fp++) 6855: if (fp->f_count==0) { 6856: u.u_ofile[i] = fp; 6857: fp->f_count++; 6858: fp->f_offset[0] = 0; 6859: fp->f_offset[1] = 0; 6860: return(fp); 6861: } 6862: printf("no file\n"); 6863: u.u_error = ENFILE; 6864: return(NULL); 6865: } 6866: /* --------------------------- */