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