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: /* --------------------------- */