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, &quotastat)) {		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 + -
显示快捷键?