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.
26 #ifdef HAVE_SYS_QUOTAS
28 #if defined(HAVE_QUOTACTL_4A)
29 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
30 /* this is used by: linux,HPUX,IRIX */
32 /****************************************************************************
33 Abstract out the old and new Linux quota get calls.
34 ****************************************************************************/
35 static int sys_get_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
40 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)QUOTABLOCK_SIZE
;
42 if (!path
||!bdev
||!dp
)
43 smb_panic("sys_get_vfs_quota: called with NULL pointer");
50 case SMB_USER_QUOTA_TYPE
:
51 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
))) {
55 if ((D
.dqb_curblocks
==0)&&
56 (D
.dqb_bsoftlimit
==0)&&
57 (D
.dqb_bhardlimit
==0)) {
58 /* the upper layer functions don't want empty quota records...*/
63 #ifdef HAVE_GROUP_QUOTA
64 case SMB_GROUP_QUOTA_TYPE
:
65 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
))) {
69 if ((D
.dqb_curblocks
==0)&&
70 (D
.dqb_bsoftlimit
==0)&&
71 (D
.dqb_bhardlimit
==0)) {
72 /* the upper layer functions don't want empty quota records...*/
77 #endif /* HAVE_GROUP_QUOTA */
78 case SMB_USER_FS_QUOTA_TYPE
:
81 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
))==0) {
82 qflags
|= QUOTAS_DENY_DISK
;
87 #ifdef HAVE_GROUP_QUOTA
88 case SMB_GROUP_FS_QUOTA_TYPE
:
91 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
))==0) {
92 qflags
|= QUOTAS_DENY_DISK
;
97 #endif /* HAVE_GROUP_QUOTA */
104 dp
->softlimit
= (SMB_BIG_UINT
)D
.dqb_bsoftlimit
;
105 dp
->hardlimit
= (SMB_BIG_UINT
)D
.dqb_bhardlimit
;
106 dp
->ihardlimit
= (SMB_BIG_UINT
)D
.dqb_ihardlimit
;
107 dp
->isoftlimit
= (SMB_BIG_UINT
)D
.dqb_isoftlimit
;
108 dp
->curinodes
= (SMB_BIG_UINT
)D
.dqb_curinodes
;
109 dp
->curblocks
= (SMB_BIG_UINT
)D
.dqb_curblocks
;
117 /****************************************************************************
118 Abstract out the old and new Linux quota set calls.
119 ****************************************************************************/
121 static int sys_set_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
125 uint32 oldqflags
= 0;
127 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)QUOTABLOCK_SIZE
;
129 if (!path
||!bdev
||!dp
)
130 smb_panic("sys_set_vfs_quota: called with NULL pointer");
134 if (bsize
== dp
->bsize
) {
135 D
.dqb_bsoftlimit
= dp
->softlimit
;
136 D
.dqb_bhardlimit
= dp
->hardlimit
;
137 D
.dqb_ihardlimit
= dp
->ihardlimit
;
138 D
.dqb_isoftlimit
= dp
->isoftlimit
;
140 D
.dqb_bsoftlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
141 D
.dqb_bhardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
142 D
.dqb_ihardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
143 D
.dqb_isoftlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
149 case SMB_USER_QUOTA_TYPE
:
150 ret
= quotactl(QCMD(Q_SETQLIM
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
);
152 #ifdef HAVE_GROUP_QUOTA
153 case SMB_GROUP_QUOTA_TYPE
:
154 ret
= quotactl(QCMD(Q_SETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
);
156 #endif /* HAVE_GROUP_QUOTA */
157 case SMB_USER_FS_QUOTA_TYPE
:
158 /* this stuff didn't work as it should:
159 * switching on/off quota via quotactl()
161 * So we just return 0
164 * On HPUX we didn't have the mount path,
165 * we need to fix sys_path_to_bdev()
171 ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
);
173 if ((qflags
"AS_DENY_DISK
)||(qflags
"AS_ENABLED
)) {
175 char *quota_file
= NULL
;
177 asprintf("a_file
,"/%s/%s%s",path
, QUOTAFILENAME
,USERQUOTAFILE_EXTENSION
);
178 if (quota_file
== NULL
) {
179 DEBUG(0,("asprintf() failed!\n"));
184 ret
= quotactl(QCMD(Q_QUOTAON
,USRQUOTA
), bdev
, -1,(CADDR_T
)quota_file
);
191 ret
= quotactl(QCMD(Q_QUOTAOFF
,USRQUOTA
), bdev
, -1, (CADDR_T
)0);
197 DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
198 ret
,errno
,strerror(errno
),id
.uid
,bdev
));
202 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
))==0) {
203 oldqflags
|= QUOTAS_DENY_DISK
;
206 if (oldqflags
== qflags
) {
213 #ifdef HAVE_GROUP_QUOTA
214 case SMB_GROUP_FS_QUOTA_TYPE
:
215 /* this stuff didn't work as it should:
216 * switching on/off quota via quotactl()
218 * So we just return 0
221 * On HPUX we didn't have the mount path,
222 * we need to fix sys_path_to_bdev()
228 ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
, (CADDR_T
)&D
);
230 if ((qflags
"AS_DENY_DISK
)||(qflags
"AS_ENABLED
)) {
232 char *quota_file
= NULL
;
234 asprintf("a_file
,"/%s/%s%s",path
, QUOTAFILENAME
,GROUPQUOTAFILE_EXTENSION
);
235 if (quota_file
== NULL
) {
236 DEBUG(0,("asprintf() failed!\n"));
241 ret
= quotactl(QCMD(Q_QUOTAON
,GRPQUOTA
), bdev
, -1,(CADDR_T
)quota_file
);
248 ret
= quotactl(QCMD(Q_QUOTAOFF
,GRPQUOTA
), bdev
, -1, (CADDR_T
)0);
254 DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
255 ret
,errno
,strerror(errno
),id
.gid
,bdev
));
259 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
))==0) {
260 oldqflags
|= QUOTAS_DENY_DISK
;
263 if (oldqflags
== qflags
) {
270 #endif /* HAVE_GROUP_QUOTA */
279 /*#endif HAVE_QUOTACTL_4A */
280 #elif defined(HAVE_QUOTACTL_4B)
282 #error HAVE_QUOTACTL_4B not implemeted
284 /*#endif HAVE_QUOTACTL_4B */
285 #elif defined(HAVE_QUOTACTL_3)
287 #error HAVE_QUOTACTL_3 not implemented
289 /* #endif HAVE_QUOTACTL_3 */
290 #else /* NO_QUOTACTL_USED */
292 static int sys_get_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
296 if (!path
||!bdev
||!dp
)
297 smb_panic("sys_get_vfs_quota: called with NULL pointer");
304 static int sys_set_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
308 if (!path
||!bdev
||!dp
)
309 smb_panic("sys_set_vfs_quota: called with NULL pointer");
316 #endif /* NO_QUOTACTL_USED */
319 static int sys_path_to_bdev(const char *path
, char **mntpath
, char **bdev
, char **fs
)
327 /* find the block device file */
329 if (!path
||!mntpath
||!bdev
||!fs
)
330 smb_panic("sys_path_to_bdev: called with NULL pointer");
336 if ( sys_stat(path
, &S
) == -1 )
341 fp
= setmntent(MOUNTED
,"r");
343 while ((mnt
= getmntent(fp
))) {
344 if ( sys_stat(mnt
->mnt_dir
,&S
) == -1 )
347 if (S
.st_dev
== devno
) {
348 (*mntpath
) = strdup(mnt
->mnt_dir
);
349 (*bdev
) = strdup(mnt
->mnt_fsname
);
350 (*fs
) = strdup(mnt
->mnt_type
);
351 if ((*mntpath
)&&(*bdev
)&&(*fs
)) {
368 /* #endif HAVE_MNTENT */
369 #elif defined(HAVE_DEVNM)
371 /* we have this on HPUX, ... */
372 static int sys_path_to_bdev(const char *path
, char **mntpath
, char **bdev
, char **fs
)
378 if (!path
||!mntpath
||!bdev
||!fs
)
379 smb_panic("sys_path_to_bdev: called with NULL pointer");
385 /* find the block device file */
387 if ((ret
=sys_stat(path
, &S
))!=0) {
391 if ((ret
=devnm(S_IFBLK
, S
.st_dev
, dev_disk
, 256, 1))!=0) {
395 /* we should get the mntpath right...
396 * but I don't know how
399 (*mntpath
) = strdup(path
);
400 (*bdev
) = strdup(dev_disk
);
401 if ((*mntpath
)&&(*bdev
)) {
413 /* #endif HAVE_DEVNM */
415 /* we should fake this up...*/
416 static int sys_path_to_bdev(const char *path
, char **mntpath
, char **bdev
, char **fs
)
420 if (!path
||!mntpath
||!bdev
||!fs
)
421 smb_panic("sys_path_to_bdev: called with NULL pointer");
427 (*mntpath
) = strdup(path
);
440 /*********************************************************
441 if we have XFS QUOTAS we should use them
442 *********************************************************/
443 #ifdef HAVE_XFS_QUOTA
444 /****************************************************************************
445 Abstract out the XFS Quota Manager quota get call.
446 ****************************************************************************/
447 static int sys_get_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
451 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
452 struct fs_disk_quota D
;
453 struct fs_quota_stat F
;
458 smb_panic("sys_get_xfs_quota: called with NULL pointer");
464 case SMB_USER_QUOTA_TYPE
:
465 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
)))
468 #ifdef HAVE_GROUP_QUOTA
469 case SMB_GROUP_QUOTA_TYPE
:
470 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
)))
473 #endif /* HAVE_GROUP_QUOTA */
474 case SMB_USER_FS_QUOTA_TYPE
:
475 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (CADDR_T
)&F
);
477 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
) {
478 qflags
|= QUOTAS_DENY_DISK
;
480 else if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
) {
481 qflags
|= QUOTAS_ENABLED
;
487 #ifdef HAVE_GROUP_QUOTA
488 case SMB_GROUP_FS_QUOTA_TYPE
:
489 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (CADDR_T
)&F
);
491 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
) {
492 qflags
|= QUOTAS_DENY_DISK
;
494 else if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
) {
495 qflags
|= QUOTAS_ENABLED
;
501 #endif /* HAVE_GROUP_QUOTA */
508 dp
->softlimit
= (SMB_BIG_UINT
)D
.d_blk_softlimit
;
509 dp
->hardlimit
= (SMB_BIG_UINT
)D
.d_blk_hardlimit
;
510 dp
->ihardlimit
= (SMB_BIG_UINT
)D
.d_ino_hardlimit
;
511 dp
->isoftlimit
= (SMB_BIG_UINT
)D
.d_ino_softlimit
;
512 dp
->curinodes
= (SMB_BIG_UINT
)D
.d_icount
;
513 dp
->curblocks
= (SMB_BIG_UINT
)D
.d_bcount
;
519 /****************************************************************************
520 Abstract out the XFS Quota Manager quota set call.
521 ****************************************************************************/
522 static int sys_set_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
526 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
527 struct fs_disk_quota D
;
528 struct fs_quota_stat F
;
535 smb_panic("sys_set_xfs_quota: called with NULL pointer");
537 if (bsize
== dp
->bsize
) {
538 D
.d_blk_softlimit
= dp
->softlimit
;
539 D
.d_blk_hardlimit
= dp
->hardlimit
;
540 D
.d_ino_hardlimit
= dp
->ihardlimit
;
541 D
.d_ino_softlimit
= dp
->isoftlimit
;
543 D
.d_blk_softlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
544 D
.d_blk_hardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
545 D
.d_ino_hardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
546 D
.d_ino_softlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
552 case SMB_USER_QUOTA_TYPE
:
553 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
554 ret
= quotactl(QCMD(Q_XSETQLIM
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
);
556 #ifdef HAVE_GROUP_QUOTA
557 case SMB_GROUP_QUOTA_TYPE
:
558 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
559 ret
= quotactl(QCMD(Q_XSETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
);
561 #endif /* HAVE_GROUP_QUOTA */
562 case SMB_USER_FS_QUOTA_TYPE
:
563 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (CADDR_T
)&F
);
565 if (qflags
& QUOTAS_DENY_DISK
) {
566 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
))
567 q_on
|= XFS_QUOTA_UDQ_ENFD
;
568 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
569 q_on
|= XFS_QUOTA_UDQ_ACCT
;
572 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
577 } else if (qflags
& QUOTAS_ENABLED
) {
578 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
579 q_off
|= XFS_QUOTA_UDQ_ENFD
;
582 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
587 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
588 q_on
|= XFS_QUOTA_UDQ_ACCT
;
591 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
597 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
598 * only swittching off XFS_QUOTA_UDQ_ACCT work
600 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
601 q_off
|= XFS_QUOTA_UDQ_ENFD
;
602 if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
)
603 q_off
|= XFS_QUOTA_UDQ_ACCT
;
606 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
616 #ifdef HAVE_GROUP_QUOTA
617 case SMB_GROUP_FS_QUOTA_TYPE
:
618 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (CADDR_T
)&F
);
620 if (qflags
& QUOTAS_DENY_DISK
) {
621 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
))
622 q_on
|= XFS_QUOTA_UDQ_ENFD
;
623 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
624 q_on
|= XFS_QUOTA_UDQ_ACCT
;
627 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
632 } else if (qflags
& QUOTAS_ENABLED
) {
633 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
634 q_off
|= XFS_QUOTA_UDQ_ENFD
;
637 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
642 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
643 q_on
|= XFS_QUOTA_UDQ_ACCT
;
646 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
652 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
653 * only swittching off XFS_QUOTA_UDQ_ACCT work
655 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
656 q_off
|= XFS_QUOTA_UDQ_ENFD
;
657 if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
)
658 q_off
|= XFS_QUOTA_UDQ_ACCT
;
661 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
671 #endif /* HAVE_GROUP_QUOTA */
679 #endif /* HAVE_XFS_QUOTA */
695 /*********************************************************************
696 Now the list of all filesystem specific quota systems we have found
697 **********************************************************************/
700 int (*get_quota
)(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
);
701 int (*set_quota
)(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
);
702 } sys_quota_backends
[] = {
703 #ifdef HAVE_XFS_QUOTA
704 {"xfs", sys_get_xfs_quota
, sys_set_xfs_quota
},
705 #endif /* HAVE_XFS_QUOTA */
709 static int command_get_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
711 const char *get_quota_command
;
713 get_quota_command
= lp_get_quota_command();
714 if (get_quota_command
&& *get_quota_command
) {
722 case SMB_USER_QUOTA_TYPE
:
723 case SMB_USER_FS_QUOTA_TYPE
:
726 case SMB_GROUP_QUOTA_TYPE
:
727 case SMB_GROUP_FS_QUOTA_TYPE
:
731 DEBUG(0,("invalid quota type.\n"));
735 slprintf(syscmd
, sizeof(syscmd
)-1,
737 get_quota_command
, path
, qtype
, _id
);
739 DEBUG (3, ("get_quota: Running command %s\n", syscmd
));
741 lines
= file_lines_pload(syscmd
, NULL
);
743 char *line
= lines
[0];
745 DEBUG (3, ("Read output from get_quota, \"r%s\"\n", line
));
747 /* we need to deal with long long unsigned here, if supported */
749 dp
->qflags
= (enum SMB_QUOTA_TYPE
)strtoul(line
, &p2
, 10);
751 while (p
&& *p
&& isspace(*p
))
754 dp
->curblocks
= STR_TO_SMB_BIG_UINT(p
, &p
);
757 while (p
&& *p
&& isspace(*p
))
760 dp
->softlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
763 while (p
&& *p
&& isspace(*p
))
766 dp
->hardlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
769 while (p
&& *p
&& isspace(*p
))
772 dp
->curinodes
= STR_TO_SMB_BIG_UINT(p
, &p
);
775 while (p
&& *p
&& isspace(*p
))
778 dp
->isoftlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
781 while (p
&& *p
&& isspace(*p
))
784 dp
->ihardlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
787 while (p
&& *p
&& isspace(*p
))
790 dp
->bsize
= STR_TO_SMB_BIG_UINT(p
, NULL
);
793 file_lines_free(lines
);
794 DEBUG (3, ("Parsed output of get_quota, ...\n"));
796 #ifdef LARGE_SMB_OFF_T
798 "qflags:%u curblocks:%llu softlimit:%llu hardlimit:%llu\n"
799 "curinodes:%llu isoftlimit:%llu ihardlimit:%llu bsize:%llu\n",
800 dp
->qflags
,(long long unsigned)dp
->curblocks
,
801 (long long unsigned)dp
->softlimit
,(long long unsigned)dp
->hardlimit
,
802 (long long unsigned)dp
->curinodes
,
803 (long long unsigned)dp
->isoftlimit
,(long long unsigned)dp
->ihardlimit
,
804 (long long unsigned)dp
->bsize
));
805 #else /* LARGE_SMB_OFF_T */
807 "qflags:%u curblocks:%lu softlimit:%lu hardlimit:%lu\n"
808 "curinodes:%lu isoftlimit:%lu ihardlimit:%lu bsize:%lu\n",
809 dp
->qflags
,(long unsigned)dp
->curblocks
,
810 (long unsigned)dp
->softlimit
,(long unsigned)dp
->hardlimit
,
811 (long unsigned)dp
->curinodes
,
812 (long unsigned)dp
->isoftlimit
,(long unsigned)dp
->ihardlimit
,
813 (long unsigned)dp
->bsize
));
814 #endif /* LARGE_SMB_OFF_T */
818 DEBUG (0, ("get_quota_command failed!\n"));
826 DEBUG(0,("The output of get_quota_command is invalid!\n"));
830 static int command_set_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
832 const char *set_quota_command
;
834 set_quota_command
= lp_set_quota_command();
835 if (set_quota_command
&& *set_quota_command
) {
841 case SMB_USER_QUOTA_TYPE
:
842 case SMB_USER_FS_QUOTA_TYPE
:
845 case SMB_GROUP_QUOTA_TYPE
:
846 case SMB_GROUP_FS_QUOTA_TYPE
:
853 #ifdef LARGE_SMB_OFF_T
854 slprintf(syscmd
, sizeof(syscmd
)-1,
858 set_quota_command
, path
, qtype
, _id
, dp
->qflags
,
859 (long long unsigned)dp
->softlimit
,(long long unsigned)dp
->hardlimit
,
860 (long long unsigned)dp
->isoftlimit
,(long long unsigned)dp
->ihardlimit
,
861 (long long unsigned)dp
->bsize
);
862 #else /* LARGE_SMB_OFF_T */
863 slprintf(syscmd
, sizeof(syscmd
)-1,
867 set_quota_command
, path
, qtype
, _id
, dp
->qflags
,
868 (long unsigned)dp
->softlimit
,(long unsigned)dp
->hardlimit
,
869 (long unsigned)dp
->isoftlimit
,(long unsigned)dp
->ihardlimit
,
870 (long unsigned)dp
->bsize
);
871 #endif /* LARGE_SMB_OFF_T */
875 DEBUG (3, ("get_quota: Running command %s\n", syscmd
));
877 lines
= file_lines_pload(syscmd
, NULL
);
879 char *line
= lines
[0];
881 DEBUG (3, ("Read output from set_quota, \"%s\"\n", line
));
883 file_lines_free(lines
);
887 DEBUG (0, ("set_quota_command failed!\n"));
895 int sys_get_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
900 char *mntpath
= NULL
;
905 smb_panic("sys_get_quota: called with NULL pointer");
907 if (command_get_quota(path
, qtype
, id
, dp
)==0) {
909 } else if (errno
!= ENOSYS
) {
913 if ((ret
=sys_path_to_bdev(path
,&mntpath
,&bdev
,&fs
))!=0) {
914 DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path
));
918 for (i
=0;(fs
&& sys_quota_backends
[i
].name
&& sys_quota_backends
[i
].get_quota
);i
++) {
919 if (strcmp(fs
,sys_quota_backends
[i
].name
)==0) {
920 ret
= sys_quota_backends
[i
].get_quota(mntpath
, bdev
, qtype
, id
, dp
);
922 DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
923 fs
,mntpath
,bdev
,qtype
,(qtype
==SMB_GROUP_QUOTA_TYPE
?id
.gid
:id
.uid
),ret
));
931 /* use the default vfs quota functions */
932 ret
=sys_get_vfs_quota(mntpath
, bdev
, qtype
, id
, dp
);
934 DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
935 "vfs",mntpath
,bdev
,qtype
,(qtype
==SMB_GROUP_QUOTA_TYPE
?id
.gid
:id
.uid
),ret
));
943 if ((ret
!=0)&& (errno
== EDQUOT
)) {
950 int sys_set_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
955 char *mntpath
= NULL
;
959 /* find the block device file */
962 smb_panic("get_smb_quota: called with NULL pointer");
964 if (command_set_quota(path
, qtype
, id
, dp
)==0) {
966 } else if (errno
!= ENOSYS
) {
970 if ((ret
=sys_path_to_bdev(path
,&mntpath
,&bdev
,&fs
))!=0) {
971 DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path
));
975 for (i
=0;(fs
&& sys_quota_backends
[i
].name
&& sys_quota_backends
[i
].set_quota
);i
++) {
976 if (strcmp(fs
,sys_quota_backends
[i
].name
)==0) {
977 ret
= sys_quota_backends
[i
].set_quota(mntpath
, bdev
, qtype
, id
, dp
);
979 DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
980 fs
,mntpath
,bdev
,qtype
,(qtype
==SMB_GROUP_QUOTA_TYPE
?id
.gid
:id
.uid
),ret
));
988 /* use the default vfs quota functions */
989 ret
=sys_set_vfs_quota(mntpath
, bdev
, qtype
, id
, dp
);
991 DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
992 "vfs",mntpath
,bdev
,qtype
,(qtype
==SMB_GROUP_QUOTA_TYPE
?id
.gid
:id
.uid
),ret
));
1000 if ((ret
!=0)&& (errno
== EDQUOT
)) {
1007 #else /* HAVE_SYS_QUOTAS */
1008 void dummy_sysquotas_c(void)
1012 #endif /* HAVE_SYS_QUOTAS */
1014 #else /* ! AUTOCONF_TEST */
1015 /* this is the autoconf driver to test witch quota system we should use */
1017 #if defined(HAVE_QUOTACTL_4A)
1018 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
1020 #ifdef HAVE_SYS_TYPES_H
1021 #include <sys/types.h>
1024 #ifdef HAVE_ASM_TYPES_H
1025 #include <asm/types.h>
1028 #if defined(HAVE_LINUX_QUOTA_H)
1029 # include <linux/quota.h>
1030 # if defined(HAVE_STRUCT_IF_DQBLK)
1031 # define SYS_DQBLK if_dqblk
1032 # elif defined(HAVE_STRUCT_MEM_DQBLK)
1033 # define SYS_DQBLK mem_dqblk
1035 #elif defined(HAVE_SYS_QUOTA_H)
1036 # include <sys/quota.h>
1040 #define SYS_DQBLK dqblk
1043 int autoconf_quota(void)
1048 ret
= quotactl(Q_GETQUOTA
,"/dev/hda1",0,(void *)&D
);
1053 #elif defined(HAVE_QUOTACTL_4B)
1054 /* int quotactl(const char *path, int cmd, int id, char *addr); */
1056 #ifdef HAVE_SYS_QUOTA_H
1057 #include <sys/quota.h>
1059 #include <sys/types.h>
1060 #include <ufs/ufs/quota.h>
1061 #include <machine/param.h>
1064 int autoconf_quota(void)
1069 ret
= quotactl("/",Q_GETQUOTA
,0,(char *) &D
);
1074 #elif defined(HAVE_QUOTACTL_3)
1075 /* int quotactl (char *spec, int request, char *arg); */
1077 #ifdef HAVE_SYS_TYPES_H
1078 #include <sys/types.h>
1080 #ifdef HAVE_SYS_QUOTA_H
1081 #include <sys/quota.h>
1084 int autoconf_quota(void)
1087 struct q_request request
;
1089 ret
= quotactl("/", Q_GETQUOTA
, &request
);
1094 #elif defined(HAVE_QUOTACTL_2)
1096 #error HAVE_QUOTACTL_2 not implemented
1100 #error Unknow QUOTACTL prototype
1109 #endif /* AUTOCONF_TEST */