2 Unix SMB/CIFS implementation.
3 System QUOTA function wrappers
4 Copyright (C) Stefan (metze) Metzmacher 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #ifdef HAVE_SYS_QUOTAS
26 #if defined(HAVE_QUOTACTL_4A)
27 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
28 /* this is used by: linux,HPUX,IRIX */
30 /****************************************************************************
31 Abstract out the old and new Linux quota get calls.
32 ****************************************************************************/
33 static int sys_get_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
38 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)QUOTABLOCK_SIZE
;
40 if (!path
||!bdev
||!dp
)
41 smb_panic("sys_get_vfs_quota: called with NULL pointer");
48 case SMB_USER_QUOTA_TYPE
:
49 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
))) {
53 if ((D
.dqb_curblocks
==0)&&
54 (D
.dqb_bsoftlimit
==0)&&
55 (D
.dqb_bhardlimit
==0)) {
56 /* the upper layer functions don't want empty quota records...*/
61 #ifdef HAVE_GROUP_QUOTA
62 case SMB_GROUP_QUOTA_TYPE
:
63 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
))) {
67 if ((D
.dqb_curblocks
==0)&&
68 (D
.dqb_bsoftlimit
==0)&&
69 (D
.dqb_bhardlimit
==0)) {
70 /* the upper layer functions don't want empty quota records...*/
75 #endif /* HAVE_GROUP_QUOTA */
76 case SMB_USER_FS_QUOTA_TYPE
:
79 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
))==0) {
80 qflags
|= QUOTAS_DENY_DISK
;
85 #ifdef HAVE_GROUP_QUOTA
86 case SMB_GROUP_FS_QUOTA_TYPE
:
89 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
))==0) {
90 qflags
|= QUOTAS_DENY_DISK
;
95 #endif /* HAVE_GROUP_QUOTA */
102 dp
->softlimit
= (SMB_BIG_UINT
)D
.dqb_bsoftlimit
;
103 dp
->hardlimit
= (SMB_BIG_UINT
)D
.dqb_bhardlimit
;
104 dp
->ihardlimit
= (SMB_BIG_UINT
)D
.dqb_ihardlimit
;
105 dp
->isoftlimit
= (SMB_BIG_UINT
)D
.dqb_isoftlimit
;
106 dp
->curinodes
= (SMB_BIG_UINT
)D
.dqb_curinodes
;
107 dp
->curblocks
= (SMB_BIG_UINT
)D
.dqb_curblocks
;
115 /****************************************************************************
116 Abstract out the old and new Linux quota set calls.
117 ****************************************************************************/
119 static int sys_set_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
123 uint32 oldqflags
= 0;
125 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)QUOTABLOCK_SIZE
;
127 if (!path
||!bdev
||!dp
)
128 smb_panic("sys_set_vfs_quota: called with NULL pointer");
132 if (bsize
== dp
->bsize
) {
133 D
.dqb_bsoftlimit
= dp
->softlimit
;
134 D
.dqb_bhardlimit
= dp
->hardlimit
;
135 D
.dqb_ihardlimit
= dp
->ihardlimit
;
136 D
.dqb_isoftlimit
= dp
->isoftlimit
;
138 D
.dqb_bsoftlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
139 D
.dqb_bhardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
140 D
.dqb_ihardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
141 D
.dqb_isoftlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
147 case SMB_USER_QUOTA_TYPE
:
148 ret
= quotactl(QCMD(Q_SETQLIM
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
);
150 #ifdef HAVE_GROUP_QUOTA
151 case SMB_GROUP_QUOTA_TYPE
:
152 ret
= quotactl(QCMD(Q_SETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
);
154 #endif /* HAVE_GROUP_QUOTA */
155 case SMB_USER_FS_QUOTA_TYPE
:
156 /* this stuff didn't work as it should:
157 * switching on/off quota via quotactl()
159 * So we just return 0
162 * On HPUX we didn't have the mount path,
163 * we need to fix sys_path_to_bdev()
169 ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
);
171 if ((qflags
"AS_DENY_DISK
)||(qflags
"AS_ENABLED
)) {
173 char *quota_file
= NULL
;
175 asprintf("a_file
,"/%s/%s%s",path
, QUOTAFILENAME
,USERQUOTAFILE_EXTENSION
);
176 if (quota_file
== NULL
) {
177 DEBUG(0,("asprintf() failed!\n"));
182 ret
= quotactl(QCMD(Q_QUOTAON
,USRQUOTA
), bdev
, -1,(CADDR_T
)quota_file
);
189 ret
= quotactl(QCMD(Q_QUOTAOFF
,USRQUOTA
), bdev
, -1, (CADDR_T
)0);
195 DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
196 ret
,errno
,strerror(errno
),id
.uid
,bdev
));
200 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
))==0) {
201 oldqflags
|= QUOTAS_DENY_DISK
;
204 if (oldqflags
== qflags
) {
211 #ifdef HAVE_GROUP_QUOTA
212 case SMB_GROUP_FS_QUOTA_TYPE
:
213 /* this stuff didn't work as it should:
214 * switching on/off quota via quotactl()
216 * So we just return 0
219 * On HPUX we didn't have the mount path,
220 * we need to fix sys_path_to_bdev()
226 ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
, (CADDR_T
)&D
);
228 if ((qflags
"AS_DENY_DISK
)||(qflags
"AS_ENABLED
)) {
230 char *quota_file
= NULL
;
232 asprintf("a_file
,"/%s/%s%s",path
, QUOTAFILENAME
,GROUPQUOTAFILE_EXTENSION
);
233 if (quota_file
== NULL
) {
234 DEBUG(0,("asprintf() failed!\n"));
239 ret
= quotactl(QCMD(Q_QUOTAON
,GRPQUOTA
), bdev
, -1,(CADDR_T
)quota_file
);
246 ret
= quotactl(QCMD(Q_QUOTAOFF
,GRPQUOTA
), bdev
, -1, (CADDR_T
)0);
252 DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
253 ret
,errno
,strerror(errno
),id
.gid
,bdev
));
257 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
))==0) {
258 oldqflags
|= QUOTAS_DENY_DISK
;
261 if (oldqflags
== qflags
) {
268 #endif /* HAVE_GROUP_QUOTA */
277 /*#endif HAVE_QUOTACTL_4A */
278 #elif defined(HAVE_QUOTACTL_4B)
280 #error HAVE_QUOTACTL_4B not implemeted
282 /*#endif HAVE_QUOTACTL_4B */
283 #elif defined(HAVE_QUOTACTL_3)
285 #error HAVE_QUOTACTL_3 not implemented
287 /* #endif HAVE_QUOTACTL_3 */
288 #else /* NO_QUOTACTL_USED */
290 static int sys_get_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
294 if (!path
||!bdev
||!dp
)
295 smb_panic("sys_get_vfs_quota: called with NULL pointer");
302 static int sys_set_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
306 if (!path
||!bdev
||!dp
)
307 smb_panic("sys_set_vfs_quota: called with NULL pointer");
314 #endif /* NO_QUOTACTL_USED */
317 static int sys_path_to_bdev(const char *path
, char **mntpath
, char **bdev
, char **fs
)
325 /* find the block device file */
327 if (!path
||!mntpath
||!bdev
||!fs
)
328 smb_panic("sys_path_to_bdev: called with NULL pointer");
334 if ( sys_stat(path
, &S
) == -1 )
339 fp
= setmntent(MOUNTED
,"r");
341 while ((mnt
= getmntent(fp
))) {
342 if ( sys_stat(mnt
->mnt_dir
,&S
) == -1 )
345 if (S
.st_dev
== devno
) {
346 (*mntpath
) = strdup(mnt
->mnt_dir
);
347 (*bdev
) = strdup(mnt
->mnt_fsname
);
348 (*fs
) = strdup(mnt
->mnt_type
);
349 if ((*mntpath
)&&(*bdev
)&&(*fs
)) {
366 /* #endif HAVE_MNTENT */
367 #elif defined(HAVE_DEVNM)
369 /* we have this on HPUX, ... */
370 static int sys_path_to_bdev(const char *path
, char **mntpath
, char **bdev
, char **fs
)
376 if (!path
||!mntpath
||!bdev
||!fs
)
377 smb_panic("sys_path_to_bdev: called with NULL pointer");
383 /* find the block device file */
385 if ((ret
=sys_stat(path
, &S
))!=0) {
389 if ((ret
=devnm(S_IFBLK
, S
.st_dev
, dev_disk
, 256, 1))!=0) {
393 /* we should get the mntpath right...
394 * but I don't know how
397 (*mntpath
) = strdup(path
);
398 (*bdev
) = strdup(dev_disk
);
399 if ((*mntpath
)&&(*bdev
)) {
411 /* #endif HAVE_DEVNM */
413 /* we should fake this up...*/
414 static int sys_path_to_bdev(const char *path
, char **mntpath
, char **bdev
, char **fs
)
418 if (!path
||!mntpath
||!bdev
||!fs
)
419 smb_panic("sys_path_to_bdev: called with NULL pointer");
425 (*mntpath
) = strdup(path
);
438 /*********************************************************
439 if we have XFS QUOTAS we should use them
440 *********************************************************/
441 #ifdef HAVE_XFS_QUOTA
442 /****************************************************************************
443 Abstract out the XFS Quota Manager quota get call.
444 ****************************************************************************/
445 static int sys_get_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
449 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
450 struct fs_disk_quota D
;
451 struct fs_quota_stat F
;
456 smb_panic("sys_get_xfs_quota: called with NULL pointer");
462 case SMB_USER_QUOTA_TYPE
:
463 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
)))
466 #ifdef HAVE_GROUP_QUOTA
467 case SMB_GROUP_QUOTA_TYPE
:
468 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
)))
471 #endif /* HAVE_GROUP_QUOTA */
472 case SMB_USER_FS_QUOTA_TYPE
:
473 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (CADDR_T
)&F
);
475 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
) {
476 qflags
|= QUOTAS_DENY_DISK
;
478 else if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
) {
479 qflags
|= QUOTAS_ENABLED
;
485 #ifdef HAVE_GROUP_QUOTA
486 case SMB_GROUP_FS_QUOTA_TYPE
:
487 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (CADDR_T
)&F
);
489 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
) {
490 qflags
|= QUOTAS_DENY_DISK
;
492 else if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
) {
493 qflags
|= QUOTAS_ENABLED
;
499 #endif /* HAVE_GROUP_QUOTA */
506 dp
->softlimit
= (SMB_BIG_UINT
)D
.d_blk_softlimit
;
507 dp
->hardlimit
= (SMB_BIG_UINT
)D
.d_blk_hardlimit
;
508 dp
->ihardlimit
= (SMB_BIG_UINT
)D
.d_ino_hardlimit
;
509 dp
->isoftlimit
= (SMB_BIG_UINT
)D
.d_ino_softlimit
;
510 dp
->curinodes
= (SMB_BIG_UINT
)D
.d_icount
;
511 dp
->curblocks
= (SMB_BIG_UINT
)D
.d_bcount
;
517 /****************************************************************************
518 Abstract out the XFS Quota Manager quota set call.
519 ****************************************************************************/
520 static int sys_set_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
524 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
525 struct fs_disk_quota D
;
526 struct fs_quota_stat F
;
533 smb_panic("sys_set_xfs_quota: called with NULL pointer");
535 if (bsize
== dp
->bsize
) {
536 D
.d_blk_softlimit
= dp
->softlimit
;
537 D
.d_blk_hardlimit
= dp
->hardlimit
;
538 D
.d_ino_hardlimit
= dp
->ihardlimit
;
539 D
.d_ino_softlimit
= dp
->isoftlimit
;
541 D
.d_blk_softlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
542 D
.d_blk_hardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
543 D
.d_ino_hardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
544 D
.d_ino_softlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
550 case SMB_USER_QUOTA_TYPE
:
551 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
552 ret
= quotactl(QCMD(Q_XSETQLIM
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
);
554 #ifdef HAVE_GROUP_QUOTA
555 case SMB_GROUP_QUOTA_TYPE
:
556 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
557 ret
= quotactl(QCMD(Q_XSETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
);
559 #endif /* HAVE_GROUP_QUOTA */
560 case SMB_USER_FS_QUOTA_TYPE
:
561 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (CADDR_T
)&F
);
563 if (qflags
& QUOTAS_DENY_DISK
) {
564 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
))
565 q_on
|= XFS_QUOTA_UDQ_ENFD
;
566 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
567 q_on
|= XFS_QUOTA_UDQ_ACCT
;
570 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
575 } else if (qflags
& QUOTAS_ENABLED
) {
576 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
577 q_off
|= XFS_QUOTA_UDQ_ENFD
;
580 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
585 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
586 q_on
|= XFS_QUOTA_UDQ_ACCT
;
589 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
595 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
596 * only swittching off XFS_QUOTA_UDQ_ACCT work
598 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
599 q_off
|= XFS_QUOTA_UDQ_ENFD
;
600 if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
)
601 q_off
|= XFS_QUOTA_UDQ_ACCT
;
604 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
614 #ifdef HAVE_GROUP_QUOTA
615 case SMB_GROUP_FS_QUOTA_TYPE
:
616 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (CADDR_T
)&F
);
618 if (qflags
& QUOTAS_DENY_DISK
) {
619 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
))
620 q_on
|= XFS_QUOTA_UDQ_ENFD
;
621 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
622 q_on
|= XFS_QUOTA_UDQ_ACCT
;
625 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
630 } else if (qflags
& QUOTAS_ENABLED
) {
631 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
632 q_off
|= XFS_QUOTA_UDQ_ENFD
;
635 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
640 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
641 q_on
|= XFS_QUOTA_UDQ_ACCT
;
644 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
650 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
651 * only swittching off XFS_QUOTA_UDQ_ACCT work
653 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
654 q_off
|= XFS_QUOTA_UDQ_ENFD
;
655 if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
)
656 q_off
|= XFS_QUOTA_UDQ_ACCT
;
659 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
669 #endif /* HAVE_GROUP_QUOTA */
677 #endif /* HAVE_XFS_QUOTA */
693 /*********************************************************************
694 Now the list of all filesystem specific quota systems we have found
695 **********************************************************************/
698 int (*get_quota
)(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
);
699 int (*set_quota
)(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
);
700 } sys_quota_backends
[] = {
701 #ifdef HAVE_XFS_QUOTA
702 {"xfs", sys_get_xfs_quota
, sys_set_xfs_quota
},
703 #endif /* HAVE_XFS_QUOTA */
707 static int command_get_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
709 const char *get_quota_command
;
711 get_quota_command
= lp_get_quota_command();
712 if (get_quota_command
&& *get_quota_command
) {
720 case SMB_USER_QUOTA_TYPE
:
721 case SMB_USER_FS_QUOTA_TYPE
:
724 case SMB_GROUP_QUOTA_TYPE
:
725 case SMB_GROUP_FS_QUOTA_TYPE
:
729 DEBUG(0,("invalid quota type.\n"));
733 slprintf(syscmd
, sizeof(syscmd
)-1,
735 get_quota_command
, path
, qtype
, _id
);
737 DEBUG (3, ("get_quota: Running command %s\n", syscmd
));
739 lines
= file_lines_pload(syscmd
, NULL
);
741 char *line
= lines
[0];
743 DEBUG (3, ("Read output from get_quota, \"%s\"\n", line
));
745 /* we need to deal with long long unsigned here, if supported */
747 dp
->qflags
= (enum SMB_QUOTA_TYPE
)strtoul(line
, &p2
, 10);
749 while (p
&& *p
&& isspace(*p
))
752 dp
->curblocks
= STR_TO_SMB_BIG_UINT(p
, &p
);
755 while (p
&& *p
&& isspace(*p
))
758 dp
->softlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
761 while (p
&& *p
&& isspace(*p
))
764 dp
->hardlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
767 while (p
&& *p
&& isspace(*p
))
770 dp
->curinodes
= STR_TO_SMB_BIG_UINT(p
, &p
);
773 while (p
&& *p
&& isspace(*p
))
776 dp
->isoftlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
779 while (p
&& *p
&& isspace(*p
))
782 dp
->ihardlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
785 while (p
&& *p
&& isspace(*p
))
788 dp
->bsize
= STR_TO_SMB_BIG_UINT(p
, NULL
);
791 file_lines_free(lines
);
792 DEBUG (3, ("Parsed output of get_quota, ...\n"));
794 #ifdef LARGE_SMB_OFF_T
796 "qflags:%u curblocks:%llu softlimit:%llu hardlimit:%llu\n"
797 "curinodes:%llu isoftlimit:%llu ihardlimit:%llu bsize:%llu\n",
798 dp
->qflags
,(long long unsigned)dp
->curblocks
,
799 (long long unsigned)dp
->softlimit
,(long long unsigned)dp
->hardlimit
,
800 (long long unsigned)dp
->curinodes
,
801 (long long unsigned)dp
->isoftlimit
,(long long unsigned)dp
->ihardlimit
,
802 (long long unsigned)dp
->bsize
));
803 #else /* LARGE_SMB_OFF_T */
805 "qflags:%u curblocks:%lu softlimit:%lu hardlimit:%lu\n"
806 "curinodes:%lu isoftlimit:%lu ihardlimit:%lu bsize:%lu\n",
807 dp
->qflags
,(long unsigned)dp
->curblocks
,
808 (long unsigned)dp
->softlimit
,(long unsigned)dp
->hardlimit
,
809 (long unsigned)dp
->curinodes
,
810 (long unsigned)dp
->isoftlimit
,(long unsigned)dp
->ihardlimit
,
811 (long unsigned)dp
->bsize
));
812 #endif /* LARGE_SMB_OFF_T */
816 DEBUG (0, ("get_quota_command failed!\n"));
824 DEBUG(0,("The output of get_quota_command is invalid!\n"));
828 static int command_set_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
830 const char *set_quota_command
;
832 set_quota_command
= lp_set_quota_command();
833 if (set_quota_command
&& *set_quota_command
) {
839 case SMB_USER_QUOTA_TYPE
:
840 case SMB_USER_FS_QUOTA_TYPE
:
843 case SMB_GROUP_QUOTA_TYPE
:
844 case SMB_GROUP_FS_QUOTA_TYPE
:
851 #ifdef LARGE_SMB_OFF_T
852 slprintf(syscmd
, sizeof(syscmd
)-1,
856 set_quota_command
, path
, qtype
, _id
, dp
->qflags
,
857 (long long unsigned)dp
->softlimit
,(long long unsigned)dp
->hardlimit
,
858 (long long unsigned)dp
->isoftlimit
,(long long unsigned)dp
->ihardlimit
,
859 (long long unsigned)dp
->bsize
);
860 #else /* LARGE_SMB_OFF_T */
861 slprintf(syscmd
, sizeof(syscmd
)-1,
865 set_quota_command
, path
, qtype
, _id
, dp
->qflags
,
866 (long unsigned)dp
->softlimit
,(long unsigned)dp
->hardlimit
,
867 (long unsigned)dp
->isoftlimit
,(long unsigned)dp
->ihardlimit
,
868 (long unsigned)dp
->bsize
);
869 #endif /* LARGE_SMB_OFF_T */
873 DEBUG (3, ("get_quota: Running command %s\n", syscmd
));
875 lines
= file_lines_pload(syscmd
, NULL
);
877 char *line
= lines
[0];
879 DEBUG (3, ("Read output from set_quota, \"%s\"\n", line
));
881 file_lines_free(lines
);
885 DEBUG (0, ("set_quota_command failed!\n"));
893 int sys_get_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
898 char *mntpath
= NULL
;
903 smb_panic("sys_get_quota: called with NULL pointer");
905 if (command_get_quota(path
, qtype
, id
, dp
)==0) {
907 } else if (errno
!= ENOSYS
) {
911 if ((ret
=sys_path_to_bdev(path
,&mntpath
,&bdev
,&fs
))!=0) {
912 DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path
));
916 for (i
=0;(fs
&& sys_quota_backends
[i
].name
&& sys_quota_backends
[i
].get_quota
);i
++) {
917 if (strcmp(fs
,sys_quota_backends
[i
].name
)==0) {
918 ret
= sys_quota_backends
[i
].get_quota(mntpath
, bdev
, qtype
, id
, dp
);
920 DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
921 fs
,mntpath
,bdev
,qtype
,(qtype
==SMB_GROUP_QUOTA_TYPE
?id
.gid
:id
.uid
),ret
));
929 /* use the default vfs quota functions */
930 ret
=sys_get_vfs_quota(mntpath
, bdev
, qtype
, id
, dp
);
932 DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
933 "vfs",mntpath
,bdev
,qtype
,(qtype
==SMB_GROUP_QUOTA_TYPE
?id
.gid
:id
.uid
),ret
));
941 if ((ret
!=0)&& (errno
== EDQUOT
)) {
948 int sys_set_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
953 char *mntpath
= NULL
;
957 /* find the block device file */
960 smb_panic("get_smb_quota: called with NULL pointer");
962 if (command_set_quota(path
, qtype
, id
, dp
)==0) {
964 } else if (errno
!= ENOSYS
) {
968 if ((ret
=sys_path_to_bdev(path
,&mntpath
,&bdev
,&fs
))!=0) {
969 DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path
));
973 for (i
=0;(fs
&& sys_quota_backends
[i
].name
&& sys_quota_backends
[i
].set_quota
);i
++) {
974 if (strcmp(fs
,sys_quota_backends
[i
].name
)==0) {
975 ret
= sys_quota_backends
[i
].set_quota(mntpath
, bdev
, qtype
, id
, dp
);
977 DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
978 fs
,mntpath
,bdev
,qtype
,(qtype
==SMB_GROUP_QUOTA_TYPE
?id
.gid
:id
.uid
),ret
));
986 /* use the default vfs quota functions */
987 ret
=sys_set_vfs_quota(mntpath
, bdev
, qtype
, id
, dp
);
989 DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
990 "vfs",mntpath
,bdev
,qtype
,(qtype
==SMB_GROUP_QUOTA_TYPE
?id
.gid
:id
.uid
),ret
));
998 if ((ret
!=0)&& (errno
== EDQUOT
)) {
1005 #else /* HAVE_SYS_QUOTAS */
1006 void dummy_sysquotas_c(void)
1010 #endif /* HAVE_SYS_QUOTAS */