/*
This file implements macros for machine independent short and
int manipulation
+
+Here is a description of this file that I emailed to the samba list once:
+
+> I am confused about the way that byteorder.h works in Samba. I have
+> looked at it, and I would have thought that you might make a distinction
+> between LE and BE machines, but you only seem to distinguish between 386
+> and all other architectures.
+>
+> Can you give me a clue?
+
+sure.
+
+The distinction between 386 and other architectures is only there as
+an optimisation. You can take it out completely and it will make no
+difference. The routines (macros) in byteorder.h are totally byteorder
+independent. The 386 optimsation just takes advantage of the fact that
+the x86 processors don't care about alignment, so we don't have to
+align ints on int boundaries etc. If there are other processors out
+there that aren't alignment sensitive then you could also define
+CAREFUL_ALIGNMENT=0 on those processors as well.
+
+Ok, now to the macros themselves. I'll take a simple example, say we
+want to extract a 2 byte integer from a SMB packet and put it into a
+type called uint16 that is in the local machines byte order, and you
+want to do it with only the assumption that uint16 is _at_least_ 16
+bits long (this last condition is very important for architectures
+that don't have any int types that are 2 bytes long)
+
+You do this:
+
+#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
+#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
+#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
+
+then to extract a uint16 value at offset 25 in a buffer you do this:
+
+char *buffer = foo_bar();
+uint16 xx = SVAL(buffer,25);
+
+We are using the byteoder independence of the ANSI C bitshifts to do
+the work. A good optimising compiler should turn this into efficient
+code, especially if it happens to have the right byteorder :-)
+
+I know these macros can be made a bit tidier by removing some of the
+casts, but you need to look at byteorder.h as a whole to see the
+reasoning behind them. byteorder.h defines the following macros:
+
+SVAL(buf,pos) - extract a 2 byte SMB value
+IVAL(buf,pos) - extract a 4 byte SMB value
+SVALS(buf,pos) signed version of SVAL()
+IVALS(buf,pos) signed version of IVAL()
+
+SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer
+SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer
+SSVALS(buf,pos,val) - signed version of SSVAL()
+SIVALS(buf,pos,val) - signed version of SIVAL()
+
+RSVAL(buf,pos) - like SVAL() but for NMB byte ordering
+RIVAL(buf,pos) - like IVAL() but for NMB byte ordering
+RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering
+RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering
+
+it also defines lots of intermediate macros, just ignore those :-)
+
*/
#undef CAREFUL_ALIGNMENT
#include "includes.h"
+extern int DEBUGLEVEL;
#ifdef LINUX
*/
#include "quota/quotactl.c"
#include "quota/hasquota.c"
-static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
+BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
{
uid_t euser_id;
struct dqblk D;
/****************************************************************************
try to get the disk space from disk quotas (CRAY VERSION)
****************************************************************************/
-static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
+BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
{
struct mntent *mnt;
FILE *fd;
}
-#elif defined(SUNOS5)
+#elif defined(SUNOS5) || defined(SUNOS4)
-#include <devnm.h>
#include <fcntl.h>
+#if defined(SUNOS5)
#include <sys/fs/ufs_quota.h>
+#include <sys/mnttab.h>
+#else /* defined(SUNOS4) */
+#include <ufs/quota.h>
+#include <mntent.h>
+#endif
/****************************************************************************
try to get the disk space from disk quotas (solaris 2 version)
****************************************************************************/
/* Quota code by Peter Urbanec (amiga@cse.unsw.edu.au) */
-static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
+BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
{
uid_t user_id, euser_id;
- int r;
+ int ret;
struct dqblk D;
+#if defined(SUNOS5)
struct quotctl command;
int file;
- int ret;
-
- if((file=open(path, O_RDONLY))<0) return(False);
+ struct mnttab mnt;
+ static char name[MNT_LINE_MAX] ;
+#else
+ struct mntent *mnt;
+ static char name[MNTMAXSTR] ;
+#endif
+ FILE *fd;
+ struct stat sbuf;
+ dev_t devno ;
+ static dev_t devno_cached = 0 ;
+ int found ;
+
+ if ( stat(path,&sbuf) == -1 )
+ return(False) ;
+
+ devno = sbuf.st_dev ;
+DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%o\n", path,devno));
+ if ( devno != devno_cached ) {
+ devno_cached = devno ;
+#if defined(SUNOS5)
+ if ((fd = fopen(MNTTAB, "r")) == NULL)
+ return(False) ;
+
+ found = False ;
+ while (getmntent(fd, &mnt) == 0) {
+ if ( stat(mnt.mnt_mountp,&sbuf) == -1 )
+ continue ;
+DEBUG(5,("disk_quotas: testing \"%s\" devno=%o\n", mnt.mnt_mountp,sbuf.st_dev));
+ if (sbuf.st_dev == devno) {
+ found = True ;
+ break ;
+ }
+ }
+
+ strcpy(name,mnt.mnt_mountp) ;
+ strcat(name,"/quotas") ;
+ fclose(fd) ;
+#else
+ if ((fd = setmntent(MOUNTED, "r")) == NULL)
+ return(False) ;
+
+ found = False ;
+ while ((mnt = getmntent(fd)) != NULL) {
+ if ( stat(mnt->mnt_dir,&sbuf) == -1 )
+ continue ;
+DEBUG(5,("disk_quotas: testing \"%s\" devno=%o\n", mnt->mnt_dir,sbuf.st_dev));
+ if (sbuf.st_dev == devno) {
+ found = True ;
+ break ;
+ }
+ }
+
+ strcpy(name,mnt->mnt_fsname) ;
+ endmntent(fd) ;
+#endif
+
+ if ( ! found )
+ return(False) ;
+ }
euser_id = geteuid();
user_id = getuid();
- command.op = Q_GETQUOTA;
- command.uid = euser_id;
- command.addr = (caddr_t) &D;
-
setuid(0); /* Solaris seems to want to give info only to super-user */
seteuid(0);
+#if defined(SUNOS5)
+DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name));
+ if((file=open(name, O_RDONLY))<0) {
+ setuid(user_id); /* Restore the original UID status */
+ seteuid(euser_id);
+ 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
setuid(user_id); /* Restore the original UID status */
seteuid(euser_id);
if (ret < 0) {
- close(file);
DEBUG(2,("disk_quotas ioctl (Solaris) failed\n"));
return(False);
}
- close(file);
/* Use softlimit to determine disk space. A user exceeding the quota is told
* made of rubber latex and begins to expand to accommodate the user :-)
*/
+ if (D.dqb_bsoftlimit==0)
+ return(False);
*bsize = 512;
*dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
*dsize = D.dqb_bsoftlimit;
/****************************************************************************
try to get the disk space from disk quotas - default version
****************************************************************************/
-static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
+BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
{
uid_t user_id, euser_id;
int r;
}
else return(False);
}
+ if (D.dqb_bsoftlimit==0)
+ return(False);
/* Use softlimit to determine disk space, except when it has been exceeded */
if ((D.dqb_curblocks>D.dqb_bsoftlimit)||(D.dqb_curfiles>D.dqb_fsoftlimit))
{