quotas.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,493 行 · 第 1/3 页
C
1,493 行
clnt_stat=clnt_call(clnt, RQUOTAPROC_GETQUOTA, my_xdr_getquota_args, (caddr_t)&args, my_xdr_getquota_rslt, (caddr_t)&gqr, timeout); if (clnt_stat != RPC_SUCCESS) { DEBUG(9,("nfs_quotas: clnt_call fail\n")); ret = False; goto out; } /* * quotastat returns 0 if the rpc call fails, 1 if quotas exist, 2 if there is * no quota set, and 3 if no permission to get the quota. If 0 or 3 return * something sensible. */ switch ( quotastat ) { case 0: DEBUG(9,("nfs_quotas: Remote Quotas Failed! Error \"%i\" \n", quotastat )); ret = False; goto out; case 1: DEBUG(9,("nfs_quotas: Good quota data\n")); D.dqb_bsoftlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit; D.dqb_bhardlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit; D.dqb_curblocks = gqr.getquota_rslt_u.gqr_rquota.rq_curblocks; break; case 2: case 3: D.dqb_bsoftlimit = 1; D.dqb_curblocks = 1; DEBUG(9,("nfs_quotas: Remote Quotas returned \"%i\" \n", quotastat )); break; default: DEBUG(9,("nfs_quotas: Remote Quotas Questionable! Error \"%i\" \n", quotastat )); break; } DEBUG(10,("nfs_quotas: Let`s look at D a bit closer... status \"%i\" bsize \"%i\" active? \"%i\" bhard \"%i\" bsoft \"%i\" curb \"%i\" \n", quotastat, gqr.getquota_rslt_u.gqr_rquota.rq_bsize, gqr.getquota_rslt_u.gqr_rquota.rq_active, gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit, gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit, gqr.getquota_rslt_u.gqr_rquota.rq_curblocks)); *bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize; *dsize = D.dqb_bsoftlimit; if (D.dqb_curblocks == D.dqb_curblocks == 1) *bsize = 512; if (D.dqb_curblocks > D.dqb_bsoftlimit) { *dfree = 0; *dsize = D.dqb_curblocks; } else *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; out: if (clnt) { if (clnt->cl_auth) auth_destroy(clnt->cl_auth); clnt_destroy(clnt); } DEBUG(5,("nfs_quotas: For path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",args.gqa_pathp,(double)*bsize,(double)*dfree,(double)*dsize)); SAFE_FREE(cutstr); DEBUG(10,("nfs_quotas: End of nfs_quotas\n" )); return ret;}#endif/****************************************************************************try to get the disk space from disk quotas (SunOS & Solaris2 version)Quota code by Peter Urbanec (amiga@cse.unsw.edu.au).****************************************************************************/BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize){ uid_t euser_id; int ret; struct dqblk D;#if defined(SUNOS5) struct quotctl command; int file; static struct mnttab mnt; static pstring name; pstring devopt;#else /* SunOS4 */ struct mntent *mnt; static pstring name;#endif FILE *fd; SMB_STRUCT_STAT sbuf; SMB_DEV_T devno ; static SMB_DEV_T devno_cached = 0 ; static int found ; euser_id = geteuid(); if ( sys_stat(path,&sbuf) == -1 ) return(False) ; devno = sbuf.st_dev ; DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path,(unsigned int)devno)); if ( devno != devno_cached ) { devno_cached = devno ;#if defined(SUNOS5) if ((fd = sys_fopen(MNTTAB, "r")) == NULL) return(False) ; found = False ; slprintf(devopt, sizeof(devopt) - 1, "dev=%x", (unsigned int)devno); while (getmntent(fd, &mnt) == 0) { if( !hasmntopt(&mnt, devopt) ) continue; DEBUG(5,("disk_quotas: testing \"%s\" %s\n", mnt.mnt_mountp,devopt)); /* quotas are only on vxfs, UFS or NFS */ if ( strcmp( mnt.mnt_fstype, MNTTYPE_UFS ) == 0 || strcmp( mnt.mnt_fstype, "nfs" ) == 0 || strcmp( mnt.mnt_fstype, "vxfs" ) == 0 ) { found = True ; break; } } pstrcpy(name,mnt.mnt_mountp) ; pstrcat(name,"/quotas") ; fclose(fd) ;#else /* SunOS4 */ if ((fd = setmntent(MOUNTED, "r")) == NULL) return(False) ; found = False ; while ((mnt = getmntent(fd)) != NULL) { if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 ) continue ; DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n", mnt->mnt_dir,(unsigned int)sbuf.st_dev)); if (sbuf.st_dev == devno) { found = True ; break; } } pstrcpy(name,mnt->mnt_fsname) ; endmntent(fd) ;#endif } if ( ! found ) return(False) ; save_re_uid(); set_effective_uid(0);#if defined(SUNOS5) if ( strcmp( mnt.mnt_fstype, "nfs" ) == 0) { BOOL retval; DEBUG(5,("disk_quotas: looking for mountpath (NFS) \"%s\"\n", mnt.mnt_special)); retval = nfs_quotas(mnt.mnt_special, euser_id, bsize, dfree, dsize); restore_re_uid(); return retval; } DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name)); if((file=sys_open(name, O_RDONLY,0))<0) { restore_re_uid(); return(False); } command.op = Q_GETQUOTA; command.uid = euser_id; command.addr = (caddr_t) &D; ret = ioctl(file, Q_QUOTACTL, &command); close(file);#else DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name)); ret = quotactl(Q_GETQUOTA, name, euser_id, &D);#endif restore_re_uid(); if (ret < 0) { DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) ));#if defined(SUNOS5) && defined(VXFS_QUOTA) /* If normal quotactl() fails, try vxfs private calls */ set_effective_uid(euser_id); DEBUG(5,("disk_quotas: mount type \"%s\"\n", mnt.mnt_fstype)); if ( 0 == strcmp ( mnt.mnt_fstype, "vxfs" )) { BOOL retval; retval = disk_quotas_vxfs(name, path, bsize, dfree, dsize); return(retval); }#else return(False);#endif } /* If softlimit is zero, set it equal to hardlimit. */ if (D.dqb_bsoftlimit==0) D.dqb_bsoftlimit = D.dqb_bhardlimit; /* Use softlimit to determine disk space. A user exceeding the quota is told * that there's no space left. Writes might actually work for a bit if the * hardlimit is set higher than softlimit. Effectively the disk becomes * made of rubber latex and begins to expand to accommodate the user :-) */ if (D.dqb_bsoftlimit==0) return(False); *bsize = DEV_BSIZE; *dsize = D.dqb_bsoftlimit; if (D.dqb_curblocks > D.dqb_bsoftlimit) { *dfree = 0; *dsize = D.dqb_curblocks; } else *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n", path,(double)*bsize,(double)*dfree,(double)*dsize)); return(True);}#elif defined(OSF1)#include <ufs/quota.h>/****************************************************************************try to get the disk space from disk quotas - OSF1 version****************************************************************************/BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize){ int r, save_errno; struct dqblk D; SMB_STRUCT_STAT S; uid_t euser_id; /* * This code presumes that OSF1 will only * give out quota info when the real uid * matches the effective uid. JRA. */ euser_id = geteuid(); save_re_uid(); if (set_re_uid() != 0) return False; r= quotactl(path,QCMD(Q_GETQUOTA, USRQUOTA),euser_id,(char *) &D); if (r) { save_errno = errno; } restore_re_uid(); *bsize = DEV_BSIZE; if (r) { if (save_errno == EDQUOT) /* disk quota exceeded */ { *dfree = 0; *dsize = D.dqb_curblocks; return (True); } else return (False); } /* If softlimit is zero, set it equal to hardlimit. */ if (D.dqb_bsoftlimit==0) D.dqb_bsoftlimit = D.dqb_bhardlimit; /* Use softlimit to determine disk space, except when it has been exceeded */ if (D.dqb_bsoftlimit==0) return(False); if ((D.dqb_curblocks>D.dqb_bsoftlimit)) { *dfree = 0; *dsize = D.dqb_curblocks; } else { *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; *dsize = D.dqb_bsoftlimit; } return (True);}#elif defined (IRIX6)/****************************************************************************try to get the disk space from disk quotas (IRIX 6.2 version)****************************************************************************/#include <sys/quota.h>#include <mntent.h>BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize){ uid_t euser_id; int r; struct dqblk D; struct fs_disk_quota F; SMB_STRUCT_STAT S; FILE *fp; struct mntent *mnt; SMB_DEV_T devno; int found; /* find the block device file */ if ( sys_stat(path, &S) == -1 ) { return(False) ; } devno = S.st_dev ; fp = setmntent(MOUNTED,"r"); found = False ; while ((mnt = getmntent(fp))) { if ( sys_stat(mnt->mnt_dir,&S) == -1 ) continue ; if (S.st_dev == devno) { found = True ; break ; } } endmntent(fp) ; if (!found) { return(False); } euser_id=geteuid(); save_re_uid(); set_effective_uid(0); /* Use softlimit to determine disk space, except when it has been exceeded */ *bsize = 512; if ( 0 == strcmp ( mnt->mnt_type, "efs" )) { r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D); restore_re_uid(); if (r==-1) return(False); /* Use softlimit to determine disk space, except when it has been exceeded */ if ( (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) || (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) || (D.dqb_fsoftlimit && D.dqb_curfiles>=D.dqb_fsoftlimit) || (D.dqb_fhardlimit && D.dqb_curfiles>=D.dqb_fhardlimit) ) { *dfree = 0; *dsize = D.dqb_curblocks; } else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0) { return(False); } else { *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; *dsize = D.dqb_bsoftlimit; } } else if ( 0 == strcmp ( mnt->mnt_type, "xfs" )) { r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F); restore_re_uid(); if (r==-1) { DEBUG(5, ("quotactl for uid=%u: %s", euser_id, strerror(errno))); return(False); } /* No quota for this user. */ if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0) { return(False); } /* Use softlimit to determine disk space, except when it has been exceeded */ if ( (F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) || (F.d_blk_hardlimit && F.d_bcount>=F.d_blk_hardlimit) || (F.d_ino_softlimit && F.d_icount>=F.d_ino_softlimit) || (F.d_ino_hardlimit && F.d_icount>=F.d_ino_hardlimit) ) { *dfree = 0; *dsize = F.d_bcount; } else { *dfree = (F.d_blk_softlimit - F.d_bcount); *dsize = F.d_blk_softlimit ? F.d_blk_softlimit : F.d_blk_hardlimit; } } else { restore_re_uid(); return(False); } return (True);}#else#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)#include <ufs/ufs/quota.h>#include <machine/param.h>#elif AIX/* AIX quota patch from Ole Holm Nielsen <ohnielse@fysik.dtu.dk> */#include <jfs/quota.h>/* AIX 4.X: Rename members of the dqblk structure (ohnielse@fysik.dtu.dk) */#define dqb_curfiles dqb_curinodes#define dqb_fhardlimit dqb_ihardlimit#define dqb_fsoftlimit dqb_isoftlimit#else /* !__FreeBSD__ && !AIX && !__OpenBSD__ && !__DragonFly__ */#include <sys/quota.h>#include <devnm.h>#endif#if defined(__FreeBSD__) || defined(__DragonFly__)#include <rpc/rpc.h>#include <rpc/types.h>#include <rpcsvc/rquota.h>#ifdef HAVE_RPC_NETTYPE_H#include <rpc/nettype.h>#endif#include <rpc/xdr.h>static int quotastat;static int my_xdr_getquota_args(XDR *xdrsp, struct getquota_args *args){ if (!xdr_string(xdrsp, &args->gqa_pathp, RQ_PATHLEN )) return(0); if (!xdr_int(xdrsp, &args->gqa_uid)) return(0); return (1);}static int my_xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr){ if (!xdr_int(xdrsp, "astat)) { DEBUG(6,("nfs_quotas: Status bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsize)) { DEBUG(6,("nfs_quotas: Block size bad or zero\n")); return 0; } if (!xdr_bool(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_active)) { DEBUG(6,("nfs_quotas: Active bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bhardlimit)) { DEBUG(6,("nfs_quotas: Hardlimit bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsoftlimit)) { DEBUG(6,("nfs_quotas: Softlimit bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_curblocks)) { DEBUG(6,("nfs_quotas: Currentblocks bad or zero\n")); return 0; } return (1);}/* Works on FreeBSD, too. :-) */static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?