📄 accmode.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * accmode.c (file) * * File management * File access mode/Attribute information related */#include "fsinfo.h"#include "accmode.h"#include "fileio.h"#include "diskio.h"LOCAL BOOL fmNameCmp( UserName usrnm, UserName fownnm );LOCAL UW fmpGetAccLevel( W level, UH acclv );LOCAL UW fmpGetAccMode( PINFO *pinfo, FileAccMode *amode, FsInfo *fsinfo );LOCAL ER checkAttrAccess( PINFO *pinfo, DfFileHeader *fh, UH chkatr,FsInfo *fsinfo );#define TSD_FSD_FOW_0X00000000 0x00000000U#define TSD_FSD_FGA_0X00000000 0x00000000U#define TSD_FCF_MSK_0X0FFF 0x0fffU#define TSD_FCF_VAL_4 4#define TSD_FCF_MSK_0X00F0 0x00f0#define TSD_FSD_FGR_0X00000000 0x00000000U#define TSD_FSD_FPU_0X00000000 0x00000000U#define TSD_FSD_VAL_4 4U#define TSD_FSD_FGR_0X0FFF 0x0fffU#define TSD_FSD_FGA_0X0FFF 0x0fffU#define TSD_FSD_FPU_0X0FFF 0x0fffU#define TSD_FGL_MSK_MC1 (acclv >> 8) & 0xf#define TSD_FGL_MSK_MC2 (acclv >> 4) & 0xf#define TSD_FGL_MSK_MC3 acclv & 0xf#define TSD_FCF_CAS_1 1#define TSD_FCF_CAS_2 2#define TSD_FCF_CAS_3 3#define TSD_FCF_CAS_4 4/* * Fetch the default access mode. */EXPORT void fmcGetDefaultAccMode( FmCmdPkt *pkt ){ FM_GET_DFM_PARA *cmdPara = (FM_GET_DFM_PARA*)pkt->cmd.para; ER err; err = CheckSpaceRW(cmdPara->mode, sizeof(DA_MODE)); if ( err != E_OK ) { goto err_ret; } /* Fetch the access mode. */ LOCK_PINFO_SECTION(*cmdPara->mode = pkt->wrk.pinfo->user->mode); pkt->cmd.ret = E_OK; return;err_ret: DEBUG_PRINT(("fmcGetDefaultAccMode err = %d\n", err)); pkt->cmd.ret = err; return;}/* * Set the default access mode. */EXPORT void fmcSetDefaultAccMode( FmCmdPkt *pkt ){ FM_SET_DFM_PARA *cmdPara = (FM_SET_DFM_PARA*)pkt->cmd.para; DA_MODE *mode = cmdPara->mode; ER err; W i; err = CheckSpaceR(mode, sizeof(DA_MODE)); if ( err != E_OK ) { goto err_ret; } /* Parameter check */ err = E_PAR; if ( (mode->f_ownacc & ~(UW)F_OWNACC) != TSD_FSD_FOW_0X00000000 ) { goto err_ret; } if ( (mode->f_grpacc & ~TSD_FSD_FGR_0X0FFF) != TSD_FSD_FGR_0X00000000 ) { goto err_ret; } if ( (mode->f_pubacc & ~TSD_FSD_FPU_0X0FFF) != TSD_FSD_FPU_0X00000000 ) { goto err_ret; } if ( (UW)mode->f_grpno > TSD_FSD_VAL_4 ) { goto err_ret; } for ( i = 0; i < N_GRP; ++i ) { if ( (mode->f_gacc[i] & ~TSD_FSD_FGA_0X0FFF) != TSD_FSD_FGA_0X00000000 ) { goto err_ret; } } /* Set the access mode. */ LOCK_PINFO_SECTION(pkt->wrk.pinfo->user->mode = *mode); pkt->cmd.ret = E_OK; return;err_ret: DEBUG_PRINT(("fmcSetDefaultAccMode err = %d\n", err)); pkt->cmd.ret = err; return;}/* ------------------------------------------------------------------------ *//* * Fetch the access mode from file header. */EXPORT ER fmpGetFileAccMode( FileAccMode *amode, DfFileHeader *fhd, FsInfo *fsinfo ){ BOOL big = fsinfo->bigEndian; amode->ftype = fmConvEndianH(fhd->ftype, big); (void)fmConvEndianTC(amode->ownnm, (TC*)fhd->own, UserNameLen, big); (void)fmConvEndianTC(amode->grpnm, (TC*)fhd->grp, UserNameLen, big); amode->grpacc = fmConvEndianH(fhd->gacclv, big); amode->pubacc = fmConvEndianH(fhd->pacclv, big); return fmpCheckDiskError(NULL, fsinfo);}/* * Return TRUE when the user name matches. */LOCAL BOOL fmNameCmp( UserName usrnm, UserName fownnm ){ TC *uhide = &usrnm[OpenNameLen]; TC *fhide = &fownnm[OpenNameLen]; /* When the file has no user name, it does not match at all times. */ if ( fownnm[0] == TNULL ) { return FALSE; } if ( tc_strncmp(usrnm, fownnm, OpenNameLen) != 0 ) { return FALSE; } /* If the file has no hidden name, check is unnecessary. */ if ( (fhide[0] == 0) && (fhide[1] == 0) ) { return TRUE; } if ( (uhide[0] == fhide[0]) && (uhide[1] == fhide[1]) ) { return TRUE; } return FALSE;}/* * Obtain the accessible mode from the access level. */LOCAL UW fmpGetAccLevel( W level, UH acclv ){ W flv; UW accmode = 0; flv = TSD_FGL_MSK_MC1; if ( level <= flv ) { accmode |= F_READ; } flv = TSD_FGL_MSK_MC2; if ( level <= flv ) { accmode |= F_WRITE; } flv = TSD_FGL_MSK_MC3; if ( level <= flv ) { accmode |= F_EXCUTE; } return accmode;}/* * Obtain the accessible mode of the file. * Return the accessible mode in a combination of F_READ, F_WRITE, and F_EXCUTE. */LOCAL UW fmpGetAccMode( PINFO *pinfo, FileAccMode *amode, FsInfo *fsinfo ){ P_USER *user; UW accmode = 0; LOCK_PINFO; user = &pinfo->user->user; if ( user->level == 0 ) { /* Level 0 user : Always OK */ accmode |= (F_READ|F_WRITE|F_EXCUTE); } if ( fmNameCmp(user->usr_name, amode->ownnm) || (fsinfo->acclv == 0) ) { /* Owner */ accmode |= amode->ftype & (F_READ|F_WRITE|F_EXCUTE); } if ( fmNameCmp(user->grp_name1, amode->grpnm) || fmNameCmp(user->grp_name2, amode->grpnm) || fmNameCmp(user->grp_name3, amode->grpnm) || fmNameCmp(user->grp_name4, amode->grpnm) ) { /* Group */ accmode |= fmpGetAccLevel(user->level, amode->grpacc); } /* General */ accmode |= fmpGetAccLevel(user->level, amode->pubacc); UNLOCK_PINFO; return accmode;}/* * Check the access right of the file. * Return E_OK when there is the access right of chkacc. * * chkacc: F_READ 0x0004 R access right * F_WRITE 0x0002 W access right * F_EXCUTE 0x0001 E access right */EXPORT ER fmpCheckFileAccMode( PINFO *pinfo, FileAccMode *amode, UW chkacc, FsInfo *fsinfo ){ UW accmode; ER err; chkacc &= (F_READ|F_WRITE|F_EXCUTE); /* Obtain the accessible mode of the file. */ accmode = fmpGetAccMode(pinfo, amode, fsinfo); /* Check the access right. */ err = ( (accmode & chkacc) == chkacc )? E_OK: E_FACV; if ( (chkacc & F_WRITE) != 0U ) { /* Check the write protection. */ if ( (((UW)amode->ftype & F_RONLY) != 0U) || isNoWriteFS(fsinfo) ) { err = E_RONLY; /* Write-protected */ } } return err;}/* * Password check * 0 when the password is not set. * 1 when the password matches. * Return E_PWD when the password does not match. * * * (*) Although the password should be encrypted, we just compare the character strings for * the present because the encryption scheme has not decided yet in the specification and * we do not have the method to set the password to a file (System call). * Practically, it comes that there is no password at all times. */EXPORT WER fmpCheckPassWord( DfFileHeader *fhd, TC *pwd, FsInfo *fsinfo ){ PassWord fpwd; W len; len = fmpConvEndianTC(fpwd, (TC*)fhd->pswd, PassWordLen, fsinfo); if ( len == 0 ) { return 0; /* No password */ } if ( pwd == NULL ) { return E_PWD; } len = CheckStrSpaceR(pwd, PassWordLen); if ( len < 0 ) { return (ER)len; } return ( tc_strncmp(pwd, fpwd, PassWordLen) == 0 )? 1: E_PWD;}/* * Check the File access right. * Return MD_WRITE when writing is performed to fh. * Otherwise, return MD_RDONLY. */EXPORT UW fmpCheckFileAccess( FmCmdPkt *pkt, DfFileHeader *fh, FsInfo *fsinfo ){ FM_CHK_FIL_PARA *cmdPara = (FM_CHK_FIL_PARA*)pkt->cmd.para; UW mode = (UW)cmdPara->mode; FileAccMode amode; W pwd; UW ftype; ER err; /* Parameter check */ if ( (mode & ~(UW)(F_READ|F_WRITE|F_EXCUTE)) != 0U ){ err = E_PAR; goto err_ret; } /* Fetch the file access mode. */ err = fmpGetFileAccMode(&amode, fh, fsinfo); if ( err < E_OK ) { goto err_ret; } if ( mode != F_EXIST ) { /* Check the access right. */ err = fmpCheckFileAccMode(pkt->wrk.pinfo, &amode, mode, fsinfo); if ( err < E_OK ) { goto err_ret; } } /* Password check */ pwd = fmpCheckPassWord(fh, cmdPara->pwd, fsinfo); if ( (mode & (F_READ|F_WRITE)) != 0U ) { if ( pwd < E_OK ) { err = (ER)pwd; goto err_ret; } } if ( mode == F_EXIST ) { ftype = amode.ftype & TSD_FCF_MSK_0X00F0; ftype |= fmpGetAccMode(pkt->wrk.pinfo, &amode, fsinfo); if ( pwd != 0 ) { ftype |= (UH)F_PASWD; } } else { ftype = E_OK; } pkt->cmd.ret = (W)ftype; return MD_RDONLY;err_ret: DEBUG_PRINT(("fmpCheckFileAccess err = %d\n", err)); pkt->cmd.ret = err; return MD_RDONLY;}/* ------------------------------------------------------------------------ *//* * Check the access right of the attribute being changed. * Check the file attribute depending on chkatr. * F_RONLY Check the write protect attribute. * F_PERM Check the delete protect attribute. */LOCAL ER checkAttrAccess( PINFO *pinfo, DfFileHeader *fh, UH chkatr, FsInfo *fsinfo ){ UserName name; UH ftype; /* Write protected? */ ftype = fmpConvEndianH(fh->ftype, fsinfo); if ( ((ftype & chkatr) != 0) || isNoWriteFS(fsinfo) ) { if ( ((UW)ftype & (UW)chkatr & F_PERM) != 0U ) { return E_PERM; } return E_RONLY; } /* Anyone can change when the file access management level is 0. */ if ( fsinfo->acclv == 0 ) { return E_OK; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -