07800 #include "../h/param.h" 07801 #include "../h/systm.h" 07802 #include "../h/dir.h" 07803 #include "../h/user.h" 07804 #include "../h/filsys.h" 07805 #include "../h/file.h" 07806 #include "../h/conf.h" 07807 #include "../h/inode.h" 07808 #include "../h/reg.h" 07809 #include "../h/acct.h" 07810 07811 /* 07812 * Convert a user supplied 07813 * file descriptor into a pointer 07814 * to a file structure. 07815 * Only task is to check range 07816 * of the descriptor. 07817 */ 07818 struct file */ 07819 getf(f) 07820 register int f; 07821 { 07822 register struct file *fp; 07823 07824 if(0 <= f && f < NOFILE) { 07825 fp = u.u_ofile[f]; 07826 if(fp != NULL) 07827 return(fp); 07828 } 07829 u.u_error = EBADF; 07830 return(NULL); 07831 } 07832 07833 /* 07834 * Internal form of close. 07835 * Decrement reference count on 07836 * file structure. 07837 * Also make sure the pipe protocol 07838 * does not constipate. 07839 * 07840 * Decrement reference count on the inode following 07841 * removal to the referencing file structure. 07842 * Call device handler on last close. 07843 */ 07844 closef(fp) 07845 register struct file *fp; 07846 { 07847 register struct inode *ip; 07848 int flag, mode; 07849 dev_t dev; 07850 register int (*cfunc)(); 07851 struct chan *cp; 07852 07853 if(fp == NULL) 07854 return; 07855 if (fp->f_count > 1) { 07856 fp->f_count--; 07857 return; 07858 } 07859 ip = fp->f_inode; 07860 flag = fp->f_flag; 07861 cp = fp->f_un.f_chan; 07862 dev = (dev_t)ip->i_un.i_rdev; 07863 mode = ip->i_mode; 07864 07865 plock(ip); 07866 fp->f_count = 0; 07867 if(flag & FPIPE) { 07868 ip->i_mode &= ~(IREAD|IWRITE); 07869 wakeup((caddr_t)ip+1); 07870 wakeup((caddr_t)ip+2); 07871 } 07872 iput(ip); 07873 07874 switch(mode&IFMT) { 07875 07876 case IFCHR: 07877 case IFMPC: 07878 cfunc = cdevsw[major(dev)].d_close; 07879 break; 07880 07881 case IFBLK: 07882 case IFMPB: 07883 cfunc = bdevsw[major(dev)].d_close; 07884 break; 07885 default: 07886 return; 07887 } 07888 07889 if ((flag & FMP) == 0) 07890 for(fp=file; fp < &file[NFILE]; fp++) 07891 if (fp->f_count && fp->f_inode==ip) 07892 return; 07893 (*cfunc)(dev, flag, cp); 07894 } 07895 07896 /* 07897 * openi called to allow handler 07898 * of special files to initialize and 07899 * validate before actual IO. 07900 */ 07901 openi(ip, rw) 07902 register struct inode *ip; 07903 { 07904 dev_t dev; 07905 register unsigned int maj; 07906 07907 dev = (dev_t)ip->i_un.i_rdev; 07908 maj = major(dev); 07909 switch(ip->i_mode&IFMT) { 07910 07911 case IFCHR: 07912 case IFMPC: 07913 if(maj >= nchrdev) 07914 goto bad; 07915 (*cdevsw[maj].d_open)(dev, rw); 07916 break; 07917 07918 case IFBLK: 07919 case IFMPB: 07920 if(maj >= nblkdev) 07921 goto bad; 07922 (*bdevsw[maj].d_open)(dev, rw); 07923 } 07924 return; 07925 07926 bad: 07927 u.u_error = ENXIO; 07928 } 07929 07930 /* 07931 * Check mode permission on inode pointer. 07932 * Mode is READ, WRITE or EXEC. 07933 * In the case of WRITE, the 07934 * read-only status of the file 07935 * system is checked. 07936 * Also in WRITE, prototype text 07937 * segments cannot be written. 07938 * The mode is shifted to select 07939 * the owner/group/other fields. 07940 * The super user is granted all 07941 * permissions. 07942 */ 07943 access(ip, mode) 07944 register struct inode *ip; 07945 { 07946 register m; 07947 07948 m = mode; 07949 if(m == IWRITE) { 07950 if(getfs(ip->i_dev)->s_ronly != 0) { 07951 u.u_error = EROFS; 07952 return(1); 07953 } 07954 if (ip->i_flag&ITEXT) /* try to free text */ 07955 xrele(ip); 07956 if(ip->i_flag & ITEXT) { 07957 u.u_error = ETXTBSY; 07958 return(1); 07959 } 07960 } 07961 if(u.u_uid == 0) 07962 return(0); 07963 if(u.u_uid != ip->i_uid) { 07964 m >>= 3; 07965 if(u.u_gid != ip->i_gid) 07966 m >>= 3; 07967 } 07968 if((ip->i_mode&m) != 0) 07969 return(0); 07970 07971 u.u_error = EACCES; 07972 return(1); 07973 } 07974 07975 /* 07976 * Look up a pathname and test if 07977 * the resultant inode is owned by the 07978 * current user. 07979 * If not, try for super-user. 07980 * If permission is granted, 07981 * return inode pointer. 07982 */ 07983 struct inode */ 07984 owner() 07985 { 07986 register struct inode *ip; 07987 07988 ip = namei(uchar, 0); 07989 if(ip == NULL) 07990 return(NULL); 07991 if(u.u_uid == ip->i_uid) 07992 return(ip); 07993 if(suser()) 07994 return(ip); 07995 iput(ip); 07996 return(NULL); 07997 } 07998 07999 /* 08000 * Test if the current user is the 08001 * super user. 08002 */ 08003 suser() 08004 { 08005 08006 if(u.u_uid == 0) { 08007 u.u_acflag |= ASU; 08008 return(1); 08009 } 08010 u.u_error = EPERM; 08011 return(0); 08012 } 08013 08014 /* 08015 * Allocate a user file descriptor. 08016 */ 08017 ufalloc() 08018 { 08019 register i; 08020 08021 for(i=0; i08022 if(u.u_ofile[i] == NULL) { 08023 u.u_r.r_val1 = i; 08024 u.u_pofile[i] = 0; 08025 return(i); 08026 } 08027 u.u_error = EMFILE; 08028 return(-1); 08029 } 08030 08031 /* 08032 * Allocate a user file descriptor 08033 * and a file structure. 08034 * Initialize the descriptor 08035 * to point at the file structure. 08036 * 08037 * no file -- if there are no available 08038 * file structures. 08039 */ 08040 struct file */ 08041 falloc() 08042 { 08043 register struct file *fp; 08044 register i; 08045 08046 i = ufalloc(); 08047 if(i < 0) 08048 return(NULL); 08049 for(fp = &file[0]; fp < &file[NFILE]; fp++) 08050 if(fp->f_count == 0) { 08051 u.u_ofile[i] = fp; 08052 fp->f_count++; 08053 fp->f_un.f_offset = 0; 08054 return(fp); 08055 } 08056 printf("no file\n"); 08057 u.u_error = ENFILE; 08058 return(NULL); 08059 } 08060 08061 08062 08063 08064 08065 08066 08067 08068 08069 08070 08071 08072 08073 08074 08075 08076 08077 08078 08079 08080 08081 08082 08083 08084 08085 08086 08087 08088 08089 08090 08091 08092 08093 08094 08095 08096 08097 08098 08099