libquota-perl-1.7.2+dfsg.orig/0000755000175000017500000000000012533137253015201 5ustar salvisalvilibquota-perl-1.7.2+dfsg.orig/META.yml0000644000175000017500000000050312530602627016447 0ustar salvisalvi--- #YAML:1.0 name: Quota abstract: Quota - Perl interface to file system quotas version: 1.7.2 author: - Tom Zoerner license: perl distribution_type: module keywords: - quotactl excludes_os: MSWin32 no_index: directory: - contrib resources: license: http://dev.perl.org/licenses/ libquota-perl-1.7.2+dfsg.orig/MANIFEST0000644000175000017500000000076412533137253016341 0ustar salvisalviCHANGES INSTALL MANIFEST META.yml Makefile.PL Quota.pm Quota.xs linuxapi.c afsquota.c stdio_wrap.c README test.pl hints/aix_4_1.h hints/bsd.h hints/dec_osf.h hints/hpux.h hints/irix_5.h hints/irix_6.h hints/linux.h hints/none.h hints/solaris_2.h hints/sunos_4_1.h include/rquota.h include/afsquota.h include/vxquotactl.h include/stdio_wrap.h include/quotaio_xfs.h contrib/README contrib/test-group.pl contrib/report-quota contrib/quotamgmt/Author contrib/quotamgmt/config contrib/quotamgmt/quotamgmt libquota-perl-1.7.2+dfsg.orig/contrib/0000755000175000017500000000000011366363166016650 5ustar salvisalvilibquota-perl-1.7.2+dfsg.orig/contrib/test-64bit.pl0000644000175000017500000000121211123432125021065 0ustar salvisalvi#!/usr/bin/perl use blib; use Quota; $new_bs = 0xA00000000; $new_bh = 0xC00000000; # Get uid from username $uid=31979; # Get device from filesystem path $dev = Quota::getqcarg("/mnt"); # Get quota for user ($bc, $bs, $bh,$bt,$ic, $is, $ih, $it)=Quota::query($dev, $uid); print "CUR $uid - $dev - $bc - $bs - $bh - $bt\n"; print "SET $uid - $dev - $new_bs - $new_bh\n"; ($bc, $bs, $bh,$bt,$ic, $is, $ih, $it)=Quota::query($dev, $uid); if (Quota::setqlim($dev, $uid, $new_bs, $new_bh, 10,12, 1) != 0) { warn Quota::strerr,"\n"; } ($bc, $bs, $bh,$bt,$ic, $is, $ih, $it)=Quota::query($dev, $uid); print "NEW $uid - $dev - $bc - $bs - $bh - $bt\n"; libquota-perl-1.7.2+dfsg.orig/contrib/test-group.pl0000755000175000017500000000310110713416457021311 0ustar salvisalvi#!/usr/bin/perl # # testing group quota support -tom Apr/02/1999 # # This script is in the public domain and can be used and redistributed # without restrictions. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. use blib; use Quota; ## ## insert your test case constants here: ## $path = "."; $ugid = 2001; $dogrp = 1; @setq = qw(123 124 51 52); $typnam = ($dogrp ? "group" : "user"); $dev = Quota::getqcarg($path); die "$path: mount point not found\n" unless $dev; print "Using device/argument \"$dev\"\n"; if(Quota::sync($dev) && ($! != 1)) { die "Quota::sync: ".Quota::strerr."\n"; } print "\nQuery this fs with $typnam id $ugid\n"; ($bc,$bs,$bh,$bt,$fc,$fs,$fh,$ft) = Quota::query($dev,$ugid,$dogrp); if(defined($bc)) { my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($bt); $bt = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $bt; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($ft); $ft = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $ft; print "$typnam usage and limits are $bc ($bs,$bh,$bt) $fc ($fs,$fh,$ft)\n\n"; } else { die "Quota::query($dev,$ugid,$dogrp): ",Quota::strerr,"\n"; } ## ## set quota block & file limits for user ## Quota::setqlim($dev, $ugid, @setq, 1, $dogrp) && die Quota::strerr,"\n"; print "$typnam quotas set for id $ugid\n"; Quota::sync($dev) && ($! != 1) && die "Quota::sync: ".Quota::strerr."\n"; libquota-perl-1.7.2+dfsg.orig/contrib/aix_jfs2_class/0000755000175000017500000000000010724266563021542 5ustar salvisalvilibquota-perl-1.7.2+dfsg.orig/contrib/aix_jfs2_class/test_jfs2.pl0000755000175000017500000000740710724266563024015 0ustar salvisalvi#!/usr/bin/perl # ------------------------------------------------------------------------ # # Interactive test and demo script for the AFS JFS Quota Class Interface # # Author: Tom Zoerner, 2007 # # This program (test_jfs.pl) is in the public domain and can be used and # redistributed without restrictions. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # ------------------------------------------------------------------------ # use blib; use Quota; if (! -t) { print STDERR "\nThis is an interactive test script - input must be a tty\nExiting now.\n"; exit; } { print "\nEnter path to get quota for (JFS2 only; default '.'):\n> "; chomp($path = ); $path = "." unless $path =~ /\S/; $dev = Quota::getqcarg($path); $dev || warn "$path: mount point not found\n"; if ($dev =~ m#JFS2#) { print "Using device/argument \"$dev\"\n"; } else { warn "$path: is not a JFS2 file system\n"; print "Continuing anyway...\n\n"; } } # # Enumerate # $class = -1; @class_list = (); while(1) { $class = Quota::jfs2_getnextq($dev, $class); last if !defined $class; push @class_list, $class; } print "Class enumeration returned ". ($#class_list+1) ." classes\n"; # # Query all existing classes # sub print_limit { my($dev,$class) = @_; ($bs,$bh,$bt,$fs,$fh,$ft) = Quota::jfs2_getlimit($dev, $class); if (defined($bs)) { my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($bt); $bt = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $bt; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($ft); $ft = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $ft; print "Limits for class $class: $bs,$bh,$bt blocks - $fs,$fh,$ft files\n\n"; } else { warn "Quota::jfs2_getlimit($dev,$class): ",Quota::strerr,"\n\n"; last; } } print "\n"; for $class (@class_list) { print_limit($dev, $class); } # # Create a new class and work with it # print "Specify block and file limits for a new class bs,bh,fs,fh (empty to skip):\n> "; chomp($in = ); if($in =~ /\S/) { ($bs,$bh,$fs,$fh) = (split(/\s*,\s*/, $in)); $class = Quota::jfs2_newlimit($dev, $bs,$bh,0,$fs,$fh,0); if (defined $class) { print "Successfully created class $class\n"; print "Reading back new limits:\n"; print_limit($dev, $class); } else { warn "Creation failed: ". Quota::strerr ."\n"; } if (defined $class) { print "\nModify block and file limits for class $class: bs,bh,fs,fh (empty to skip):\n> "; chomp($in = ); if($in =~ /\S/) { ($bs,$bh,$fs,$fh) = (split(/\s*,\s*/, $in)); if (Quota::jfs2_putlimit($dev, $class, $bs,$bh,0,$fs,$fh,0) == 0) { print "Successfully modified limits for class $class\n"; print "Reading back new limits:\n"; print_limit($dev, $class); } else { warn "Modification failed: ". Quota::strerr ."\n"; } } { print "\nEnter a user ID to assign this class to: (empty to skip)\n"; chomp($uid = ); unless($uid =~ /^(\d+)?$/) { print "You have to enter a numerical class id.\n"; redo; } } if ($uid =~ /^\d+$/) { if (Quota::jfs2_uselimit($dev, $class, $uid) == 0) { print "Successfully assigned class $class to user $uid\n"; } else { warn "Assignment failed: ". Quota::strerr ."\n"; } } print "\nDelete the new class? y/n > "; chomp($in = ); if ($in =~ /y/) { if (Quota::jfs2_rmvlimit($dev, $class) != 0) { warn "Removal failed: ". Quota::strerr ."\n"; } } else { print "not confirmed\n"; } } } libquota-perl-1.7.2+dfsg.orig/contrib/aix_jfs2_class/jfs2class.pm0000644000175000017500000000236310724266534023774 0ustar salvisalvi# # Documentation for JFS2 quota classes interfaces # # See also http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf2/quotactl.htm # (Or search google for "Q_J2GETQUOTA") # __END__ =head1 JFS2 Quota Class Interface The following commands are usable on AIX JFS2 file systems only: =over 4 =item I<($bs,$bh,$bt, $is,$ih,$it) = Quota::jfs2_getlimit($dev, $class)> Returns quota limits for the given class. =item I Sets quota limits for the given class. Time limits are 32-bit epoch values. =item I Creates a new limit class with the given quota limits. Returns the class ID, or undef upon error. =item I Deletes the given class. =item I Sets the given class as default class. =item I Sets quota for the given user or group to the one specified by the given class. =item I Used to iterate all class IDs. Returns the next class ID larger then the given class ID. Return undef upon error or at the end of the list =back libquota-perl-1.7.2+dfsg.orig/contrib/aix_jfs2_class/jfs2class.xs0000644000175000017500000001142010724266534024004 0ustar salvisalvi/* * Perl interface to quota classes on JFS2 (AIX 5.3) * * This code is untested by me and reportedly not functional yet. * It's just provided as possible basis for further development. * * Copyright (C) 2007 Tom Zoerner. * * This program is free software: you can redistribute it and/or modify * it either under the terms of the Perl Artistic License or the GNU * General Public License as published by the Free Software Foundation. * (Either version 2 of the GPL, or any later version.) * For a copy of these licenses see . * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Perl Artistic License or GNU General Public License for more details. */ MODULE = Quota PACKAGE = Quota::JFS2CLASS void jfs2_getlimit(dev,class) char * dev int class PPCODE: #if defined(HAVE_JFS2) if (strncmp(dev, "(JFS2)", 6) == 0) { j2qlimit_t j2q; int retval; memset(&j2q, 0, sizeof(j2q)); retval = quotactl (dev + 6, Q_J2GETLIMIT, class, (caddr_t)&j2q); if (retval == 0) { EXTEND(sp, 8); PUSHs(sv_2mortal(newSViv(j2q.ql_bsoft))); PUSHs(sv_2mortal(newSViv(j2q.ql_bhard))); PUSHs(sv_2mortal(newSViv(j2q.ql_btime))); PUSHs(sv_2mortal(newSViv(j2q.ql_isoft))); PUSHs(sv_2mortal(newSViv(j2q.ql_ihard))); PUSHs(sv_2mortal(newSViv(j2q.ql_itime))); } } else #endif /* HAVE_JFS2 */ { errno = ENOENT; } int jfs2_putlimit(dev,class,bs,bh,bt,fs,fh,ft) char * dev int class int bs int bh int bt int fs int fh int ft CODE: #if defined(HAVE_JFS2) if (strncmp(dev, "(JFS2)", 6) == 0) { j2qlimit_t j2q; memset(&j2q, 0, sizeof(j2q)); j2q.ql_bsoft = bs; j2q.ql_bhard = bh; j2q.ql_btime = bt; j2q.ql_isoft = fs; j2q.ql_ihard = fh; j2q.ql_itime = ft; RETVAL = quotactl (dev + 6, Q_J2PUTLIMIT, class, (caddr_t)&j2q); } else #endif /* HAVE_JFS2 */ { RETVAL = -1; errno = ENOENT; } OUTPUT: RETVAL void jfs2_newlimit(dev,bs,bh,bt,fs,fh,ft) char * dev int bs int bh int bt int fs int fh int ft PPCODE: #if defined(HAVE_JFS2) if (strncmp(dev, "(JFS2)", 6) == 0) { j2qlimit_t j2q; uid_t class; int retval; memset(&j2q, 0, sizeof(j2q)); j2q.ql_bsoft = bs; j2q.ql_bhard = bh; j2q.ql_btime = bt; j2q.ql_isoft = fs; j2q.ql_ihard = fh; j2q.ql_itime = ft; retval = quotactl (dev + 6, Q_J2NEWLIMIT, 0, (caddr_t)&j2q); if (retval == 0) { EXTEND(sp, 1); class = *( (uid_t*) &j2q ); PUSHs(sv_2mortal(newSViv(class))); } } else #endif /* HAVE_JFS2 */ { errno = ENOENT; } int jfs2_rmvlimit(dev,class) char * dev int class CODE: #if defined(HAVE_JFS2) if (strncmp(dev, "(JFS2)", 6) == 0) { RETVAL = quotactl (dev + 6, Q_J2RMVLIMIT, class, NULL); } else #endif /* HAVE_JFS2 */ { RETVAL = -1; errno = ENOENT; } OUTPUT: RETVAL int jfs2_deflimit(dev,class) char * dev int class CODE: #if defined(HAVE_JFS2) if (strncmp(dev, "(JFS2)", 6) == 0) { RETVAL = quotactl (dev + 6, Q_J2DEFLIMIT, class, NULL); } else #endif /* HAVE_JFS2 */ { RETVAL = -1; errno = ENOENT; } OUTPUT: RETVAL int jfs2_uselimit(dev,class,uid=getuid(),kind=0) char * dev int class int uid int kind CODE: #if defined(HAVE_JFS2) if (strncmp(dev, "(JFS2)", 6) == 0) { uid_t id_buf = uid; RETVAL = quotactl (dev + 6, QCMD(Q_J2USELIMIT, ((kind != 0) ? GRPQUOTA : USRQUOTA)), class, (caddr_t)&id_buf); } else #endif /* HAVE_JFS2 */ { RETVAL = -1; errno = ENOENT; } OUTPUT: RETVAL void jfs2_getnextq(dev,class) char * dev int class PPCODE: #if defined(HAVE_JFS2) if (strncmp(dev, "(JFS2)", 6) == 0) { uid_t id_buf = 0; int retval; //retval = quotactl (dev + 6, QCMD(Q_J2GETNEXTQ,USRQUOTA), class, (caddr_t) &id_buf); retval = quotactl (dev + 6, Q_J2GETNEXTQ, class, (caddr_t) &id_buf); printf("Q_J2GETNEXTQ(%s,%d)=%d ID=%d\n",dev+6,class,retval,id_buf); if (retval == 0) { EXTEND(sp, 1); PUSHs(sv_2mortal(newSViv(id_buf))); } } else #endif /* HAVE_JFS2 */ { errno = ENOENT; } libquota-perl-1.7.2+dfsg.orig/contrib/report-quota0000644000175000017500000000461506401430113021220 0ustar salvisalvi#!/usr/local/bin/perl # Report Quota # # Please keep my name associated with this program. If you add features to it, # please drop me a copy. # # This is a little util I wrote to report users who have NO quotas. # use at your own risk as I could only test on a BSDI 2.1 machine # It does not modify any quotas, just reads each users quota... # And email you the results. # # Written by Jim Hribnak (hribnak@nucleus.com) Aug 28 1997 # use Quota; $mailprog = '/usr/sbin/sendmail'; # change path to sendmail $email = 'hribnak@nucleus.com'; # put your email address here $from = 'root@nucleus.com'; # put root@yourdomain here $subject = "User Quota Report\n"; $dev1= "/"; #filesystem with quota $dev2="/usr"; #filesystem with quota $dev3="/bbsusers"; #filesystem with quota &Email; # # uncomment format if you wish to use this header # #format STDOUT_TOP = #Quota's for @<<<<<<<<<<<<<<<< UID[@>>>>>>] #$user, $uid # Blocks Quota Quota #Filesystem Used Limit #---------------------------------------------------------------------------- #. format STDOUT = @<<<<<<<<< @###### @>>>>>> @>>>>>> Username: @<<<<<<<<<<<<<<<< $dev, $bc, $bs, $bh, $user . open (PW, "/etc/passwd") || die "Error opening password file"; while () { ($user,$passwd,$uid)=split(/:/); # # Change $dev to match a filesystem with Quotas # $dev=$dev1; ($bc,$bs,$bh,$bt,$fc,$fs,$fh,$ft) = Quota::query($dev, $uid); if(defined($bc)) { &Sub1; write ; } else { warn Quota::strerr,"\n\n"; } # # Change $dev to match a filesystem with Quotas # $dev=$dev2; ($bc,$bs,$bh,$bt,$fc,$fs,$fh,$ft) = Quota::query($dev, $uid); if(defined($bc)) { &Sub1; write; } else { warn Quota::strerr,"\n\n"; } # # Change $dev to match a filesystem with Quotas # $dev=$dev3; ($bc,$bs,$bh,$bt,$fc,$fs,$fh,$ft) = Quota::query($dev, $uid); if(defined($bc)) { &Sub1; write; print "----------------------------------------------------------------------------"; print "\n"; } else { warn Quota::strerr,"\n\n"; } } close(MAIL); exit; sub Sub1 { if (($bh eq "0") && ($bs eq "0")) { $bh = "None"; $bs = "None"; print MAIL "$user does not have a quota on $dev\n" } } sub Email { open(MAIL,"|$mailprog -t"); # open accessto Sendmail print MAIL "To: $email\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject \n\n"; print MAIL "\n"; } libquota-perl-1.7.2+dfsg.orig/contrib/README0000644000175000017500000000106706402407012017514 0ustar salvisalviPerl Quota Module: Contributions -------------------------------- This directory is not an integral part of the module. You'll find here some scripts that demonstrate it's usage and purpose. Please don't contact me if you have questions - address the various authors directly. Feel free to send me more (short) scripts if you want them included here in a future release. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. libquota-perl-1.7.2+dfsg.orig/contrib/mount-list-qcarg.pl0000644000175000017500000000145310713416457022413 0ustar salvisalvi#!/usr/bin/perl # # Author: Tom Zoerner # # This program (mount-list-qcarg.pl) is in the public domain and can # be used and redistributed without restrictions. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. use blib; use Quota; my($fsname,$path,$fstyp); if(!Quota::setmntent()) { while(($fsname,$path,$fstyp,$opt) = Quota::getmntent()) { push(@Mtab, "#$fsname#$path#$fstyp#$opt#"); } } Quota::endmntent(); print "Quota arg type=". Quota::getqcargtype() ."\n\n"; foreach (@Mtab) { $path = (split(/#/))[2]; $qcarg = Quota::getqcarg($path); $qcarg = "*UNDEF*" unless defined $qcarg; $dev = (stat($path))[0]; print "${_}$qcarg#$dev\n"; } libquota-perl-1.7.2+dfsg.orig/contrib/mount-list.pl0000644000175000017500000000105010713416457021311 0ustar salvisalvi#!/usr/bin/perl # # Author: Tom Zoerner # # This program (mount-list-qcarg.pl) is in the public domain and can # be used and redistributed without restrictions. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. use blib; use Quota; my($fsname,$path,$fstyp); if(!Quota::setmntent()) { while(($fsname,$path,$fstyp) = Quota::getmntent()) { print "#$fsname#$path#$fstyp#\n"; } } Quota::endmntent(); libquota-perl-1.7.2+dfsg.orig/contrib/quotamgmt/0000755000175000017500000000000010713416705020657 5ustar salvisalvilibquota-perl-1.7.2+dfsg.orig/contrib/quotamgmt/Author0000644000175000017500000000032406312023414022032 0ustar salvisalvi ______ __ _ /_ __/_ / / (_) Oetiker, Timelord & SysMgr @ EE-Dept ETH-Zurich / // _ \/ _ \/ / TEL:+41(0)1-6325286 FAX:+41(0)1-6321194 /_/ \___/_.__/_/ oetiker@ee.ethz.ch http://www.ee.ethz.ch/~oetiker libquota-perl-1.7.2+dfsg.orig/contrib/quotamgmt/config0000644000175000017500000000317106312022573022045 0ustar salvisalvi# user . a username # . g:regexp matched to gcos # # filesystem . path to a filesystem # . f: (matched on mountpath) # . HOME filesystem holding the users homedirectory # # space . space on the fs in Bloks (1024) # # inodes . number of inodes # # tlo . 0 - NOT Started # . 1 - 7 Days # #user filesystem space (soft/hard) inodes (soft/hard) tlo g:. f:. 1 1 1 1 0 g:. HOME 20000 21000 2000 2100 0 g:,staff, HOME 30000 30000 3000 3000 0 g:,proj, HOME 50000 51000 5000 5100 0 g:,syst, f:. 0 0 0 0 0 g:,ueb, HOME 0 0 0 0 0 # individual settings ahartman HOME 30000 30000 2000 2000 0 bodermat HOME 50000 50000 2000 2000 0 cbachofn /usr/tardis/stud7 20000 20000 2000 2000 0 cmaeder HOME 30000 30000 2000 2000 0 csrandaz HOME 50000 50000 2000 2000 0 dgallegr HOME 30000 30000 2000 2000 0 dweseman HOME 40000 40000 10000 10000 0 fpvass HOME 30000 30000 2000 2000 0 jgfluri /usr/tardis/stud7 20000 20000 1000 1000 0 jhaeflig HOME 150000 150000 10000 10000 0 jpchauny HOME 50000 50000 10000 10000 0 mastreif HOME 50000 50000 2000 2000 0 mcgastpa HOME 40000 40000 4000 4000 0 mdbraend HOME 60000 60000 2000 2000 0 mtibolla HOME 40000 40000 1000 1000 0 pmzwimpf HOME 30000 30000 3000 3000 0 uefleisc HOME 30000 30000 3000 3000 0 dip94w1 HOME 230000 230000 23000 23000 0 gisrael HOME 150000 151000 15000 15000 0 sem94w8 HOME 100000 100000 10000 10000 0 sem94w5 HOME 60000 60000 6000 6000 0 # till 30.3.97 because of diplom arbeit ktschmid HOME 60000 60000 6000 6000 0 libquota-perl-1.7.2+dfsg.orig/contrib/quotamgmt/quotamgmt0000644000175000017500000000731306312022606022615 0ustar salvisalvi#!/usr/drwho/local/bin/perl -w use Quota; select(STDERR); $|=1; select(STDOUT);$|=1; setpwent; my($cfg) = &ReadCfg; my($user) = &ReadUsers; my($fses) = &AllQuotaFs; print "Here we go\n"; # go through all quota fses foreach $fs (@{$fses}) { print "FS: $fs\n"; for($i=0;defined($$user[$i]{user});$i++) { my($block_soft,$block_hard,$inode_soft,$inode_hard,$tlo); for($ii=0;defined($$cfg[$ii][0]);$ii++){ # try match for username my($reg) = ''; if ($$cfg[$ii][0] =~/^g:(.+)/) { $reg = $1; } next unless ($$user[$i]{user} eq $$cfg[$ii][0]) or ($reg and ($$user[$i]{gcos} =~ /$reg/)); # try match for Filesystem my($fsr) = ''; if ($$cfg[$ii][1] =~/^f:(.+)/) { $fsr = $1; } my($homp) = ''; if ($$cfg[$ii][1] eq 'HOME') { $homp = $$user[$i]{home}; } next unless ($fs eq $$cfg[$ii][1]) or ($fsr and ($fs =~ /$fsr/)) or ($homp and ($fs eq $homp)); # if we come till here we set the defaults $block_soft = $$cfg[$ii][2]; $block_hard = $$cfg[$ii][3]; $inode_soft = $$cfg[$ii][4]; $inode_hard = $$cfg[$ii][5]; $tlo = $$cfg[$ii][6]; } my($qbc,$qbs,$qbh,$qic, $qis,$qih)= (Quota::query($fs, $$user[$i]{uid}))[0,1,2,4,5,6]; if (not defined $qbc) { $qbc=0;$qbs=0;$qbh=0;$qic=0;$qis=0;$qih=0;} if (($qbs != $block_soft) || ($qbh != $block_hard) || ($qis != $inode_soft) || ($qih != $inode_hard)) { Quota::setqlim($fs, $$user[$i]{uid}, $block_soft, $block_hard, $inode_soft, $inode_hard, $tlo); printf "%-20s %-20s %6.0f %6.0f %6.0f %6.0f\n", $fs, "$$user[$i]{user}-".(split ',', "$$user[$i]{gcos}")[1], $block_soft, $block_hard, $inode_soft, $inode_hard; }; if (($qbc > $block_hard) || ($qic > $inode_hard)) { printf "Oops %-20s %-20s %6.0f %6.0f %6.0f %6.0f\n", $fs, "$$user[$i]{user}-".(split ',', "$$user[$i]{gcos}")[1], $qbc, $block_hard, $qic, $inode_hard; } } Quota::sync($fs); } exit; sub Physical{ my($dir)=$_[0]; while (1) { if (-l $dir) { $dir=readlink($dir);} else {last; } } if (! -e $dir) { return -1; } else { return $dir; } } sub AllQuotaFs { my(@Fs); my($dev, $path, $type, $opts) = (); Quota::setmntent; while (($dev, $path, $type, $opts) = Quota::getmntent()) { push @Fs , $path if $opts =~ /quota/; } return \@Fs; } sub ReadCfg{ my(@cfg,$i); $i=0; my($qfs) = &AllQuotaFs; my($cfgfile)="./quotacfg"; warn "Reading $cfgfile ...\n"; open (CFG, "./quotacfg") || die ("Can't open /usr/local/etc/quotacfg"); while () { next if /^\s*\#/ or /^\s*$/; s/^\s+//; push @{$cfg[$i++]}, split (/\s+/); my($entry)=$#cfg; die ("Error on Line $.: UserName '$cfg[$entry][0]' does not make sense") unless ($cfg[$entry][0] =~ /^g:/) or getpwnam($cfg[$entry][0]); die ("Error on Line $.: Filesystem '$cfg[$entry][1]' does not exist") unless ($cfg[$entry][1] eq 'HOME') or ($cfg[$entry][1] =~ /^f:/) or grep ($cfg[$entry][1], @{$qfs}); my($i); for ($i=2;$i<7;$i++) { die ("Error on Line $.: Element $1 should be a number\n") unless $cfg[$entry][$i] =~ /^\d+$/ ; } } close CFG; return \@cfg; } sub ReadUsers { my(@Users); warn "Reading Userdata ...\n"; while (($user,$uid,$gcos,$home)=(getpwent)[0,2,6,7]) { %{$Users[$#Users+1]} = ( 'user' => $user, 'uid' => $uid, 'gcos' => $gcos, 'home' => Quota::getqcarg(&Physical($home))); # last if $#Users>50; } return \@Users; } libquota-perl-1.7.2+dfsg.orig/contrib/quotadm/0000755000175000017500000000000010713416705020313 5ustar salvisalvilibquota-perl-1.7.2+dfsg.orig/contrib/quotadm/README0000644000175000017500000000235207664742407021211 0ustar salvisalviDate: Sun, 20 Oct 2002 17:35:11 +0800 From: Ziaur Rahman To: tomzo@ Subject: Contrib: Quota warning based on threshold. X-Sender: ziaur.rahman User-Agent: Internet Messaging Program (IMP) 4.0-cvs X-Webmail-Company: QALA Singapore Pte Ltd. Hi, First, let me thank you from the bottom of my heart for writing this fantastic module that saved my life. I wrote a script to send warning message if user's disk usage is close to or over their quota limit. As I couldn't find a perl script or any script which can handle threshold, I had to come up with this script. It uses your Quota module and also some code snippets from test.pl that is included with the module. Administrators can run this and get a full report of disk usage with a predefined threshold status of all users or a particular user. They can also use it in the crontab to send out warning messages to users whose disk usage reached their threshold. Hope you consider this as worthy enough to include in your contrib directory. I have attached the script (tar file), with a sample quotawarn.msg file which is a configurable template for sending mails to user. You can also download it from: http://mzrahman.com/codes/quotadm.tar Regards, Ziaur Rahman Systems Engineer Singapore. libquota-perl-1.7.2+dfsg.orig/contrib/quotadm/quotawarn.msg0000644000175000017500000000067207554472460023062 0ustar salvisalviFrom: "Quota Administrator" To: %user@domain.com Subject: Warning: Your disk usage is close to or over quota!!! You account is extremely close to your quota limit. Once the quota limit is reached, no more data can be stored. That includes you mail directories also. So, mail will not be saved also. Consider moving some data to another location or increasing the limit. Please see your quota details below: %print libquota-perl-1.7.2+dfsg.orig/contrib/quotadm/quotadm0000755000175000017500000001403607554473334021731 0ustar salvisalvi#!/usr/bin/perl # # History: # # 17-10-02 Z Written. # 20-10-02 Z Modified to give QMAIL support. # # Author: Ziaur Rahman # # Synopsis: # # File quotadm # # Program Name Quota Administration (QUOTA ADMinistration). # # Description This script will show user quotas in the system, and if --email is mentioned # it will email a warning msg to users when the threshold is reached or exceeded. # # Variables $msgfile - Default: /etc/quotawarn.msg, this file contains the email that will # be sent to the users whose quota has reached or exceeded $threshold. # Inside this file you can use %user to mention the Username, %print to print the # table of quota information, %quota to how much quota is assigned to the user. # # $mta - Default: /usr/lib/sendmial, this is where you set the location of # of your MTA. Currently, this script only supports SENDMAIL and QMAIL. If you # are using QMAIL, please enter the location of your qmail-inject. # # $echo - Default: /bin/echo, this is the location of the echo command which # is used to send mail for QMAIL. # # $threshold - Default: 90, this is the "high water mark" for the users. When # user's disk usage equals/exceeds [>=] user's quota threshold, i.e. more # than or equal to 90% of user's quota, then the script will send a warning # message (/etc/quotawarn.msg) to the user. use Quota; # # Configurable Global variables start here... # # Define the global variables here $msgfile = "/etc/quotawarn.msg"; $mta = "/usr/lib/sendmail"; # define your MTA location here. $echo = "/bin/echo"; $threshold = 90; # # Configurable Global variables end here... # while(1) { $path = "/"; while(1) { $dev = Quota::getqcarg($path); if(!$dev) { warn "$path: mount point not found\n"; } last; } redo if !$dev; ## Check if quotas are present on this filesystem if($dev =~ m#^[^/]+:#) { print "$dev is a remote file system\n"; last; } elsif(Quota::sync($dev) && ($! != 1)) { # ignore EPERM warn "Quota::sync: ".Quota::strerr."\n"; warn "Choose another file system - quotas not functional on this one\n"; } else { #Quotas are present on this filesystem (sync ok) last; } } sub sendemail { local ($user,$printit,$quotaa) = @_; $quotadec = sprintf("%0.2d",$quotaa); open (MSGFILE, "$msgfile") or die "can not open $msgfile\n"; while () { $line = $_; $line =~ s/%user/$user/; $line =~ s/%print/$printit/; $line =~ s/%quota/$quotadec/; $msg .= $line; } if ($mta =~ "sendmail") { open (SENDMAIL, "| $mta -t -n") or die "Cannot open sendmial from $sendmail\n";; print SENDMAIL <= $threshold) { $diffth = ($percentUsage - $threshold); $diffthresh = sprintf ("%.2f%s%s",$diffth,"%","+"); } elsif ($threshold >= $percentUsage) { $diffth = ($threshold - $percentUsage); $diffthresh = sprintf ("%.2f%s%s",$diffth,"%","-"); } if ($email eq "--email") { $printem .= sprintf ("%15s%15s%15s%15s%15s%15s\n\n","UserName","Usage(MB)","Quota(MB)","Usage(%)","ThreshHold(%)","Diff(+/-)"); $printem .= sprintf ("%15s%15.2f%15.2f%15s%15s%15s\n",$user,$usageinMB,$quotainMB,$perUsage,$thresholds,$diffthresh); &sendemail($user,$printem,$quotainMB) if $bs != 0; } else { printf ("%15s%15.2f%15.2f%15s%15s%15s\n",$user,$usageinMB,$quotainMB,$perUsage,$thresholds,$diffthresh); } } } } else { warn "Quota::query($dev,$uid): ",Quota::strerr,"\n\n"; } } sub doall { local($argvp,$mail) = @_; open(PASSWD,"/etc/passwd"); while() { chop; ($userid,$dpw,$uin) = split (':',$_); &doquota($userid,$mail,$argvp); } close PASSWD; } sub usage { print "\nUsage: quotadm [OPTION]...\n"; print "Show quota information of particular user or all users.\n\n"; print "-u Single user's quota information with threshold info.\n"; print "--all-quota Show those user's quota information whose quota is on.\n"; print "--all Show all user's quota information.\n"; print "--email Email the user if he/she has reached/exceeded threshold for quota.\n"; print "\n"; print "Examples of combining OPTIONS:\n\n"; print "Example 1: \n\"quotadm -u tom --email\" \n- will send an email to tom if his quota has reached or exceeded the threshold.\n\n"; print "Example 2: \n\"quotadm --all-quota --email\" \n- will send an email to each user whose quota has reached or exceeded the threshold.\n"; print "\n"; exit; } # # The main program starts here. # $argv1 = $ARGV[0]; $argv2 = $ARGV[1]; $argv3 = $ARGV[2]; chomp ($argv1); chomp ($argv2); chomp ($argv3); if ($argv1 eq "-u") { printf ("%15s%15s%15s%15s%15s%15s\n\n","UserName","Usage(MB)","Quota(MB)","Usage(%)","ThreshHold(%)","Diff(+/-)") if $argv3 ne "--email"; &doquota($argv2,$argv3); } elsif ($argv1 eq "--all-quota" || $argv1 eq "--all") { &usage if defined($argv3); printf ("%15s%15s%15s%15s%15s%15s\n\n","UserName","Usage(MB)","Quota(MB)","Usage(%)","ThreshHold(%)","Diff(+/-)") if $argv2 ne "--email"; &doall($argv1,$argv2); } else { &usage(); } libquota-perl-1.7.2+dfsg.orig/Quota.pm0000644000175000017500000003535112530602627016636 0ustar salvisalvi# ------------------------------------------------------------------------ # # Quota.pm - Copyright (C) 1995-2013 Tom Zoerner # ------------------------------------------------------------------------ # # This program is free software: you can redistribute it and/or modify # it either under the terms of the Perl Artistic License or the GNU # General Public License as published by the Free Software Foundation. # (Either version 2 of the GPL, or any later version.) # For a copy of these licenses see . # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # Perl Artistic License or GNU General Public License for more details. # ------------------------------------------------------------------------ # package Quota; require Exporter; use AutoLoader; require DynaLoader; @ISA = qw(Exporter DynaLoader); @EXPORT = (); $VERSION = '1.7.2'; bootstrap Quota; use Carp; use POSIX qw(:errno_h); use strict; ## ## Get block device for locally mounted file system ## !! Do not use this to get the argument for the quota-functions in this ## !! module, since not all operating systems use the device path for the ## !! quotactl system call and e.g. Solaris doesn't even use a system call ## !! Always use getqcarg() instead. ## sub getdev { ($#_ > 0) && croak("Usage: Quota::getdev(path)"); my($target) = (($#_ == -1) ? "." : $_[0]); my($dev) = (stat($target))[0]; my($ret) = undef; my($fsname,$path); if($dev && ($target ne "") && !Quota::setmntent()) { while(($fsname,$path) = Quota::getmntent()) { ($ret=$fsname, last) if ($dev == (stat($path))[0]); } $! = 0; } Quota::endmntent(); $ret; } ## ## Get "device" argument for this module's Quota-functions ## sub getqcarg { ($#_ > 0) && croak("Usage: Quota::getqcarg(path)"); my($target) = (($#_ == -1) ? "." : $_[0]); my($dev) = (stat($target))[0]; my($ret) = undef; my($argtyp,$fsupp) = (Quota::getqcargtype() =~ /([^,]*)(,.*)?/); my($fsname,$path,$fstyp,$fsopt); if(defined($dev) && ($target ne "") && !Quota::setmntent()) { while(($fsname,$path,$fstyp,$fsopt) = Quota::getmntent()) { next if $fstyp =~ /^(lofs|ignore|auto.*|proc|rootfs)$/; my($pdev) = (stat($path))[0]; if (defined($pdev) && ($dev == $pdev)) { if ($fsname =~ m|^[^/]+:/|) { $ret = $fsname; #NFS host:/path } elsif (($fstyp =~ /^nfs/i) && ($fsname =~ m#^(/.*)\@([^/]+)$#)) { $ret = "$2:$1"; #NFS /path@host } elsif ($argtyp eq "dev") { if ($fsopt =~ m#(^|,)loop=(/dev/[^,]+)#) { $ret = $2; # Linux mount -o loop } else { $ret = $fsname; } } elsif ($argtyp eq "qfile") { $ret = "$path/quotas"; } elsif ($argtyp eq "any") { $ret = $target; } else { #($argtyp eq "mntpt") $ret = $path; } # XFS, VxFS and AFS quotas require separate access methods # (optional for VxFS: later versions use 'normal' quota interface) if (($fstyp eq "xfs") && ($fsupp =~ /,XFS/)) { $ret = "(XFS)$ret" } elsif(($fstyp eq "vxfs") && defined($fsupp) && ($fsupp =~ /,VXFS/)) { $ret = "(VXFS)$ret" } elsif((($fstyp eq "afs") || ($fsname eq "AFS")) && ($fsupp =~ /,AFS/)) { $ret = "(AFS)$target"; } if (($fstyp eq "jfs2") && ($fsupp =~ /,JFS2/)) { $ret = "(JFS2)$ret" } last; } } $! = 0; } Quota::endmntent(); $ret; } ## ## Translate error codes of quotactl syscall and ioctl ## sub strerr { ($#_ != -1) && croak("Usage: Quota::strerr()"); my($str); eval { if(($! == &EINVAL) || ($! == &ENOTTY) || ($! == &ENOENT) || ($! == ENOSYS)) { $str = "No quotas on this system" } elsif($! == &ENODEV) { $str = "Not a standard file system" } elsif($! == &EPERM) { $str = "Not privileged" } elsif($! == &EACCES) { $str = "Access denied" } elsif($! == &ESRCH) { $str = "No quota for this user" } elsif($! == &EUSERS) { $str = "Quota table overflow" } else { die "unknown quota error\n" } }; if($@) { my($err) = $! + 0; $str = "error #$err"; }; $str; } package Quota; # return to package Quota so AutoSplit is happy 1; __END__ =head1 NAME Quota - Perl interface to file system quotas =head1 SYNOPSIS use Quota; ($block_curr, $block_soft, $block_hard, $block_timelimit, $inode_curr, $inode_soft, $inode_hard, $inode_timelimit) = Quota::query($dev [,$uid [,kind]]); ($block_curr, $block_soft, $block_hard, $block_timelimit, $inode_curr, $inode_soft, $inode_hard, $inode_timelimit) = Quota::rpcquery($host, $path [,$uid [,kind]]); Quota::rpcpeer([$port [,$use_tcp [,timeout]]]); Quota::rpcauth([$uid [,$gid [,$hostname]]]); Quota::setqlim($dev, $uid, $block_soft, $block_hard, $inode_soft, $inode_hard [,$tlo [,kind]]); Quota::sync([$dev]); $arg = Quota::getqcarg([$path]); Quota::setmntent(); ($dev, $path, $type, $opts) = Quota::getmntent(); Quota::endmntent(); =head1 DESCRIPTION The B module provides access to file system quotas. The quotactl system call or ioctl is used to query or set quotas on the local host, or queries are submitted via RPC to a remote host. Mount tables can be parsed with B and paths can be translated to device files (or whatever the actual B implementations needs as argument) of the according file system. =head2 Functions =over 4 =item I<($bc,$bs,$bh,$bt, $ic,$is,$ih,$it) = Quota::query($dev, $uid, $kind)> Get current usage and quota limits for a given file system and user. The user is specified by its numeric uid; defaults to the process' real uid. The type of I<$dev> varies from system to system. It's the argument which is used by the B implementation to address a specific file system. It may be the path of a device file (e.g. B) or the path of the mount point or the quotas file at the top of the file system (e.g. B). However you do not have to worry about that; use B to automatically translate any path inside a file system to the required I<$dev> argument. I<$dev> may also be in the form of B, which has the module transparently query the given host via a remote procedure call (RPC). In case you have B (or similar network mounts), this type of argument may also be produced by B. Note: RPC queries require I to be running on the target system. If the daemon or host are down, the timeout is 12 seconds. In I<$bc> and I<$ic> the current usage in blocks and inodes is returned. I<$bs> and I<$is> are the soft limits, I<$bh> and I<$ih> hard limits. If the soft limit is exceeded, writes by this user will fail for blocks or inodes after I<$bt> or I<$it> is reached. These times are expressed as usual, i.e. in elapsed seconds since 00:00 1/Jan/1970 GMT. Note: When the quota limits are not exceeded, the timestamps are meaningless and should be ignored. When hard and soft limits are zero, there is no limit for that user. On most systems Quota::query will return undef in that case and errno will be set to ESRCH. When I<$kind> is given and set to 1, I<$uid> is taken as gid and group quotas are queried. This is B supported across RPC and even locally only on a few architectures (e.g. Linux and other BSD based Unix variants, OSF/1 and AIX - check the quotactl(2) man page on your systems). When I<$kind> is set to 2, project quotas are queried; this is currently only supported for XFS. When unsupported, this flag is ignored. =item I Sets quota limits for the given user. Meanings of I<$dev>, I<$uid>, I<$bs>, I<$bh>, I<$is> and I<$ih> are the same as in B. For file systems exceeding 2 TB: To allow passing block or inode values larger or equal to 2^32 on 32-bit Perl versions, pass them either as strings or floating point. I<$tlo> decides how the time limits are initialized: I<0>: The time limits are set to B, i.e. the time limits are not initialized until the first write attempt by this user. This is the default. I<1>: The time limits are set to B<7.0 days>. More alternatives (i.e. setting a specific time) aren't available in most implementations. When I<$kind> is given and set to 1, I<$uid> is taken as gid and group quota limits are set. This is supported only on a few architectures (see above). When I<$kind> is set to 2, project quotas are modified; this is currently only supported for XFS. When unsupported, this flag is ignored. Note: if you want to set the quota of a particular user to zero, i.e. no write permission, you must not set all limits to zero, since that is equivalent to unlimited access. Instead set only the hard limit to 0 and the soft limit for example to 1. Note that you cannot set quotas via RPC. =item I Have the kernel update the quota file on disk or all quota files if no argument given (the latter doesn't work on all systems, in particular on B). The main purpose of this function is to check if quota is enabled in the kernel and for a particular file system. Read the B man page on how to enable quotas on a file system. Note: on some systems this function always returns a success indication, even on partitions which do not have quotas enabled (e.g. Linux 2.4). This is not a bug in this module; it's a limitation in certain kernels. =item I<($bc,$bs,$bh,$bt, $ic,$is,$ih,$it) => I This is equivalent to B, i.e. query quota for a given user on a given remote host via RPC. I<$path> is the path of any file or directory inside the file system on the remote host. Querying group quotas ($kind = 1) is only recently supported on some platforms (e.g. on linux via "extended" quota RPC, i.e. quota RPC version 2) so it may fail due to lack of support either on client or server side, or both. =item I Configure parameters for subsequent RPC queries; all parameters are optional. By default the portmapper on the remote host is used (i.e. default port is 0, protocol is UDP) The default timeout is 4 seconds. =item I Configure authorization parameters for subsequent RPC queries; all parameters are optional. By default uid and gid are taken from owner of the process and hostname is the host name of current machine. =item I<$arg = Quota::getqcarg($path)> Get the required I<$dev> argument for B and B for the file system you want to operate on. I<$path> is any path of an existing file or directory inside that file system. The path argument is optional and defaults to the current working directory. The type of I<$dev> varies between operating systems, i.e. different implementations of the quotactl functionality. Hence it's important for compatibility to always use this module function and not really pass a device file to B (as returned by B). See also above at I =item I<$dev = Quota::getdev($path)> Returns the device entry in the mount table for a particular file system, specified by any path of an existing file or directory inside it. I<$path> defaults to the working directory. This device entry need not really be a device. For example on network mounts (B) it's I<"host:mountpath">, with I it may be something completely different. I use this to produce a I<$dev> argument for other functions of this module, since it's not compatible. On some systems I does not work on devices but on the I file or some other kind of argument. Always use B. =item I Opens or resets the mount table. This is required before the first invocation of B. Note: on some systems there is no equivalent function in the C library. But you still have to call this module procedure for initialization of module-internal variables. =item I<($dev, $path, $type, $opts) = Quota::getmntent()> Returns the next entry in the system mount table. This table contains information about all currently mounted (local or remote) file systems. The format and location of this table (e.g. B) vary from system to system. This function is provided as a compatible way to parse it. (On some systems, like B, this table isn't accessible as a file at all, i.e. only via B). =item I Close the mount table. Should be called after the last use of B to free possibly allocated file handles and memory. Always returns undef. =item I Translates B<$!> to a quota-specific error text. You should always use this function to output error messages, since the normal messages don't always make sense for quota errors (e.g. I: B, here: B) Note that this function only returns a defined result if you called a Quota command directly before which returned an error indication. =back =head1 RETURN VALUES Functions that are supposed return lists or scalars, return I upon errors. As usual B<$!> contains the error code (see B). B always returns I. All other functions return 0 upon success, non-zero integer otherwise. =head1 EXAMPLES An example for each function can be found in the test script I. See also the contrib directory, which contains some longer scripts, kindly donated by users of the module. =head1 BUGS With remote quotas we have to rely on the remote system to state correctly which block size the quota values are referring to. Old versions of the Linux rpc.rquotad reported a block size of 4 kilobytes, which was wildly incorrect. For more info on this and other Linux bugs please see INSTALL. =head1 AUTHORS This module was created 1995 by Tom Zoerner (email: tomzo AT users.sourceforge.net) and since then continually improved and ported to many operating- and file-systems. Numerous people have contributed to this process; for a complete list of names please see the CHANGES document. The quota module was in the public domain 1995-2001. Since 2001 it is licensed under both the Perl Artistic License and version 2 or later of the GNU General Public License as published by the Free Software Foundation. For a copy of these licenses see . The respective authors of the source code are it's owner in regard to copyright. =head1 SEE ALSO perl(1), edquota(1m), quotactl(2) or quotactl(7I), mount(1m), mtab(4) or mnttab(4), quotaon(1m), setmntent(3), getmntent(3) or getmntinfo(3), endmntent(3), rpc(3), rquotad(1m). =cut libquota-perl-1.7.2+dfsg.orig/hints/0000755000175000017500000000000012530604304016317 5ustar salvisalvilibquota-perl-1.7.2+dfsg.orig/hints/solaris_2.h0000644000175000017500000000252412162505301020366 0ustar salvisalvi/* * Configuration for Solaris 2.4 & 2.5.x & 2.6 - NOT 2.7 * (this is for use with SYSV flavour, not /usr/bsd) * * For AFS support look at the end of this file */ /* See hints/none.h for a complete list of options with explanations */ #include #include #include #include #include #include #include #include #include #include #define USE_IOCTL #define Q_DIV(X) ((X) / 2) #define Q_MUL(X) ((X) * 2) #define DEV_QBSIZE DEV_BSIZE #define CADR (caddr_t) /* Haven't found definition of quotactl-struct in any include, just mentioned in man quotactl(7) */ struct quotactl { int op; uid_t uid; caddr_t addr; }; #define NO_OPEN_MNTTAB #define MOUNTED MNTTAB #define MNTENT mnttab /* * Solaris seems to lack xdr routines for rquota. Use my own. */ #define MY_XDR #define GQA_TYPE_USR USRQUOTA /* RQUOTA_USRQUOTA */ #define GQA_TYPE_GRP GRPQUOTA /* RQUOTA_GRPQUOTA */ #define GQR_STATUS status #define GQR_RQUOTA getquota_rslt_u.gqr_rquota #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #define QS_BCUR dqb_curblocks #define QS_FHARD dqb_fhardlimit #define QS_FSOFT dqb_fsoftlimit #define QS_FCUR dqb_curfiles #define QS_BTIME dqb_btimelimit #define QS_FTIME dqb_ftimelimit libquota-perl-1.7.2+dfsg.orig/hints/none.h0000644000175000017500000001216012162505301017425 0ustar salvisalvi/* * Configuration options */ #include /* Defines all kinds of standard types (e.g. ulong). You may have to add * types.h include files from other /usr/include/ subdirectories */ #include /* This is needed for the quotactl syscall. See man quotactl(2) */ #include /* This is needed for the mntent library routines. See man getmntent(3) another probable name is mnttab or mtab. Basically that's the name of the file where mount(1m) keeps track of the current mounts. See FILES section of man mount for the name of that file */ #include /* See includes list man callrpc(3) and man rquota(3) */ #include #include /* Select one of the following, preferring the first */ #include /**/ /* #include "include/rquota.h" /**/ /* See man socket(2) and man gethostbyname(3) */ #include #include /* Needed for definition of type FILE for set/getmntent(3) routines */ #include /* Needed (at least) for memcpy */ #include /* These factors depend on the blocksize of your filesystem. Scale it in a way that quota values are in kB */ #define Q_DIV(X) ((X) / 2) #define Q_MUL(X) ((X) * 2) /* Specify what parameters the quotactl call expects (see man quotactl) */ /* group quotas are supported only with BSD and Linux (see INSTALL) */ /* BSD style: quotactl(dev, QCMD(Q_GETQUOTA, USRQUOTA), uid, &dqblk); */ /* #define Q_CTL_V2 */ /* Linux special: quotactl(QCMD(Q_GETQUOTA, USRQUOTA), dev, uid, &dqblk); */ /* #define Q_CTL_V3 */ /* Solaris uses ioctl() instead of quotactl() */ /* #define USE_IOCTL */ /* if none of the above defined: * old style: quotactl(Q_GETQUOTA, dev, uid, CADR &dqblk); */ /* Normally quota should be reported in file system block sizes. * On Linux though all values are converted to 1k blocks. So we * must not use DEV_BSIZE (usually 512) but 1024 instead. On all * other systems use the file system block size. This value is * used only with RPC, else only Q_DIV and Q_MUL are relevant. */ #define DEV_QBSIZE DEV_BSIZE /* Turn off attempt to convert remote quota block reports to 1k sizes. * This assumes that the remote system always reports in 1k blocks. * Only needed when the remote system also reports a bogus block * size value in the rquota structure (like Linux does). */ /* #define LINUX_RQUOTAD_BUG /**/ /* Some systems need to cast the dqblk structure Do change only if your compiler complains */ #define CADR (caddr_t) /* define if you don't want the RPC query functionality, i.e. you want to operate on the local host only */ /* #define NO_RPC /**/ /* This is for systems that lack librpcsvc and don't have xdr_getquota_args et. al. in libc either. If you do have /usr/include/rpcsvc/rquota.x you can generate these routines with rpcgen, too */ /* #define MY_XDR /**/ /* define this to enable support for extended quota RPC (i.e. quota RPC * version 2), which is needed to allow querying group quotas via RPC. To * check if your OS supports it, search for EXT_RQUOTAVERS in the system * header files. If not, you can define MY_XDR to use module internal * support. */ /* #define USE_EXT_RQUOTA /**/ /* needed only if MOUNTED is not defined in (see above) */ /* define MOUNTED mnttab /**/ /* name of the structure used by getmntent(3) */ #define MNTENT mntent /* on some systems setmntent/endmntend do not exist */ /* #define NO_OPEN_MNTTAB /**/ /* if your system doesn't have /etc/mnttab, and hence no getmntent, use getmntinfo instead then (e.g. in OSF) */ /* #define NO_MNTENT /**/ /* With USE_EXT_RQUOTA these constants distinguish queries for user and * group quota respectively. Only BSD defines these constants properly. For * others use USRQUTA and GRPQUOTA, or simply the real constants (these must * be the same for all OS to allow inter-operability.) */ #define GQA_TYPE_USR 0 /* RQUOTA_USRQUOTA */ #define GQA_TYPE_GRP 1 /* RQUOTA_GRPQUOTA */ /* name of the status entry in struc getquota_rslt and name of the struct * or union that contains the quota values. See include * or "include/rquota.h" if you're using MY_XDR */ #define GQR_STATUS gqr_status #define GQR_RQUOTA gqr_rquota /* members of the dqblk structure, see the include named in man quotactl */ #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #define QS_BCUR dqb_curblocks #define QS_FHARD dqb_fhardlimit #define QS_FSOFT dqb_fsoftlimit #define QS_FCUR dqb_curfiles #define QS_BTIME dqb_btimelimit #define QS_FTIME dqb_ftimelimit /* SFIO_VERSION should get defined automatically if sfio routines * are used with Perl instead of stdio; but you might wanna define * it here if you are using PerlIO and experience problems with * Quota::getqcarg() or the Quota::getmntent() family. * If PerlIO is used, PERLIO_IS_STDIO is not defined */ /* #ifndef PERLIO_IS_STDIO /**/ /* #define SFIO_VERSION x.x /**/ /* #endif /**/ /* If you have AFS (e.g. arla-0.13) then modify the lines below * and insert your paths to the Kerberos libraries and header files. * Depending on your compiler you may have to change the compiler * and linker arguments. See man cc(1) */ libquota-perl-1.7.2+dfsg.orig/hints/aix_4_1.h0000644000175000017500000000214112162505301017710 0ustar salvisalvi/* * Configuration for AIX 4.1 * * For AFS support look at the end of this file */ /* See hints/none.h for a complete list of options with explanations */ #include #include #include #include #include #include #include #include #include #include "include/rquota.h" #include #include #include #include #define AIX #define Q_CTL_V2 #if defined(_AIXVERSION_530) #include "j2/j2_quota.h" #define HAVE_JFS2 #endif #define Q_DIV(X) (X) #define Q_MUL(X) (X) #define DEV_QBSIZE DEV_BSIZE #define CADR (caddr_t) #define GQA_TYPE_USR USRQUOTA /* RQUOTA_USRQUOTA */ #define GQA_TYPE_GRP GRPQUOTA /* RQUOTA_GRPQUOTA */ #define GQR_STATUS status #define GQR_RQUOTA getquota_rslt_u.gqr_rquota #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #define QS_BCUR dqb_curblocks #define QS_FHARD dqb_ihardlimit #define QS_FSOFT dqb_isoftlimit #define QS_FCUR dqb_curinodes #define QS_BTIME dqb_btime #define QS_FTIME dqb_itime libquota-perl-1.7.2+dfsg.orig/hints/dec_osf.h0000644000175000017500000000200412162505301020064 0ustar salvisalvi/* * Configuration for DEC OSF/1 V3.2 - 4.0 */ /* See hints/none.h for a complete list of options with explanations */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define Q_DIV(X) (X) #define Q_MUL(X) (X) #define DEV_QBSIZE DEV_BSIZE #define Q_CTL_V2 #define CADR #define NO_MNTENT #define OSF_QUOTA extern char *getvfsbynumber(); /* prototype missing!? */ #define GQA_TYPE_USR USRQUOTA /* RQUOTA_USRQUOTA */ #define GQA_TYPE_GRP GRPQUOTA /* RQUOTA_GRPQUOTA */ #define GQR_STATUS gqr_status #define GQR_RQUOTA gqr_rquota #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #define QS_BCUR dqb_curblocks #define QS_FHARD dqb_ihardlimit #define QS_FSOFT dqb_isoftlimit #define QS_FCUR dqb_curinodes #define QS_BTIME dqb_btime #define QS_FTIME dqb_itime libquota-perl-1.7.2+dfsg.orig/hints/irix_5.h0000644000175000017500000000160712162505301017671 0ustar salvisalvi/* * Configuration for IRIX 5.3 */ /* See hints/none.h for a complete list of options with explanations */ #include #include #include #include #include #include #include #include #include #include #include #define Q_DIV(X) (X) #define Q_MUL(X) (X) #define DEV_QBSIZE DEV_BSIZE #define CADR (caddr_t) #define MNTENT mntent #define GQA_TYPE_USR USRQUOTA /* RQUOTA_USRQUOTA */ #define GQA_TYPE_GRP GRPQUOTA /* RQUOTA_GRPQUOTA */ #define GQR_STATUS gqr_status #define GQR_RQUOTA gqr_rquota #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #define QS_BCUR dqb_curblocks #define QS_FHARD dqb_fhardlimit #define QS_FSOFT dqb_fsoftlimit #define QS_FCUR dqb_curfiles #define QS_BTIME dqb_btimelimit #define QS_FTIME dqb_ftimelimit libquota-perl-1.7.2+dfsg.orig/hints/hpux.h0000644000175000017500000000214312162505301017452 0ustar salvisalvi/* * Configuration for HP-UX 9.0.x & HP-UX 10.10 & HP-UX 10.20 & HP-UX 11.00 * * For AFS support look at the end of this file */ /* See hints/none.h for a complete list of options with explanations */ #include #include #include #include #include #include #include #include #include #include #include #define Q_DIV(X) (X) #define Q_MUL(X) (X) #define DEV_QBSIZE DEV_BSIZE #define CADR (caddr_t) #define MNTENT mntent /* HP-UX has no shared librpcsvc. So we need to include the * XDR routines supplied with this module. */ #define MY_XDR #define GQA_TYPE_USR USRQUOTA /* RQUOTA_USRQUOTA */ #define GQA_TYPE_GRP GRPQUOTA /* RQUOTA_GRPQUOTA */ #define GQR_STATUS gqr_status #define GQR_RQUOTA gqr_rquota #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #define QS_BCUR dqb_curblocks #define QS_FHARD dqb_fhardlimit #define QS_FSOFT dqb_fsoftlimit #define QS_FCUR dqb_curfiles #define QS_BTIME dqb_btimelimit #define QS_FTIME dqb_ftimelimit libquota-perl-1.7.2+dfsg.orig/hints/irix_6.h0000644000175000017500000000256412162505301017675 0ustar salvisalvi/* * Configuration for 6.2 - 6.4 * (the only difference to IRIX 5 is XFS and AFS support) * * If you use XFS with IRIX 6.2 you *must* install the latest xfs patch sets! * For AFS support look at the end of this file */ /* See hints/none.h for a complete list of options with explanations */ #include #include #include #include #include /* For IRIX 6.5.1 you need the following hack */ #define __SYS_SEMA_H__ /* prevent sys/sema.h from being loaded */ #include #include #include #include #include #include #include #include #define Q_DIV(X) (X) #define Q_MUL(X) (X) #define DEV_QBSIZE DEV_BSIZE #define CADR (caddr_t) #define MNTENT mntent #define GQA_TYPE_USR USRQUOTA /* RQUOTA_USRQUOTA */ #define GQA_TYPE_GRP GRPQUOTA /* RQUOTA_GRPQUOTA */ #define GQR_STATUS gqr_status #define GQR_RQUOTA gqr_rquota #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #define QS_BCUR dqb_curblocks #define QS_FHARD dqb_fhardlimit #define QS_FSOFT dqb_fsoftlimit #define QS_FCUR dqb_curfiles #define QS_BTIME dqb_btimelimit #define QS_FTIME dqb_ftimelimit /* optional: for support of SGI XFS file systems - comment out if not needed */ #define SGI_XFS #define QX_DIV(X) (X) #define QX_MUL(X) (X) libquota-perl-1.7.2+dfsg.orig/hints/bsd.h0000644000175000017500000000466712203057556017265 0ustar salvisalvi/* * Configuration example for BSD-based systems - * BSDi, FreeBSD, NetBSD, OpenBSD * * Ported to BSDI 2.0 by Jim Hribnak (hribnak@nucleus.com) Aug 28 1997 * with the help of the original author Tom Zoerner * OpenBSD 2.0 mods provided by James Shelburne (reilly@eramp.net) * FreeBSD mods provided by Kurt Jaeger * and Jon Schewe * NetBSD mods and merge of *BSD-related hints provided by * Jaromir Dolecek * NetBSD libquota mods by David Holland */ /* See hints/none.h for a complete list of options with explanations */ #include #include #include #if defined(__NetBSD__) && __NetBSD_Version__ >= 599004800 && __NetBSD_Version__ < 599005900 #error "NetBSD 5.99 proplib-based quotas not supported" #endif #if defined(__NetBSD__) && (__NetBSD_Version__ >= 599005900) /* NetBSD 5.99.59 */ #include /* defining this will force the XS to use the libquota API for all file systems * except RPC; defines below such as Q_CTL_V2 have no effect */ #define NETBSD_LIBQUOTA #else #include #endif #if defined(__NetBSD__) && (__NetBSD_Version__ >= 299000900) /* NetBSD 2.99.9 */ /* NetBSD 3.0 has no statfs anymore */ #include #include #define HAVE_STATVFS #endif #include #include #include #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #else /* BSDi */ #include "include/rquota.h" #endif #include #include #include #include #define Q_DIV(X) ((X) / 2) #define Q_MUL(X) ((X) * 2) #define DEV_QBSIZE DEV_BSIZE #define Q_CTL_V2 #define Q_SETQLIM Q_SETQUOTA #define CADR (caddr_t) #define QCARG_MNTPT #define MY_XDR #if defined (EXT_RQUOTAVERS) #define USE_EXT_RQUOTA /* RPC version 2 aka extended quota RPC */ #endif #define NO_MNTENT #define GQA_TYPE_USR RQUOTA_USRQUOTA #define GQA_TYPE_GRP RQUOTA_GRPQUOTA #define GQR_STATUS status #define GQR_RQUOTA getquota_rslt_u.gqr_rquota #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #if defined(__APPLE__) #define QS_BCUR dqb_curbytes #else #define QS_BCUR dqb_curblocks #endif #define QS_FHARD dqb_ihardlimit #define QS_FSOFT dqb_isoftlimit #define QS_FCUR dqb_curinodes #define QS_BTIME dqb_btime #define QS_FTIME dqb_itime libquota-perl-1.7.2+dfsg.orig/hints/sunos_4_1.h0000644000175000017500000000175612162505301020311 0ustar salvisalvi/* * Configuration for SunOS 4.1.3 * * For AFS support look at the end of this file * For arla AFS an ANSI C compiler is required (SC1.0 acc or gcc) */ /* See hints/none.h for a complete list of options with explanations */ #include #include #include #include #include #include #include #include #include #include #define Q_DIV(X) ((X) / 2) #define Q_MUL(X) ((X) * 2) #define DEV_QBSIZE DEV_BSIZE #define CADR #define MNTENT mntent #define GQA_TYPE_USR USRQUOTA /* RQUOTA_USRQUOTA */ #define GQA_TYPE_GRP GRPQUOTA /* RQUOTA_GRPQUOTA */ #define GQR_STATUS gqr_status #define GQR_RQUOTA gqr_rquota #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #define QS_BCUR dqb_curblocks #define QS_FHARD dqb_fhardlimit #define QS_FSOFT dqb_fsoftlimit #define QS_FCUR dqb_curfiles #define QS_BTIME dqb_btimelimit #define QS_FTIME dqb_ftimelimit libquota-perl-1.7.2+dfsg.orig/hints/linux.h0000644000175000017500000000632112162505301017627 0ustar salvisalvi/* * Configuration for Linux - kernel version 2.0.22 and later * * For AFS support look at the end of this file */ /* See hints/none.h for a complete list of options with explanations */ #include #include /* #include */ /* is required only on some distributions (Debian 2.0, RedHat) if your's doesn't have it you can simply remove the following line */ #include #include #include #include #include #include /* #include "include/rquota.h" */ #include #include #include #include /* definitions from sys/quota.h */ #define USRQUOTA 0 /* element used for user quotas */ #define GRPQUOTA 1 /* element used for group quotas */ /* * Command definitions for the 'quotactl' system call. * The commands are broken into a main command defined below * and a subcommand that is used to convey the type of * quota that is being manipulated (see above). */ #define SUBCMDMASK 0x00ff #define SUBCMDSHIFT 8 #define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK)) /* declare an internal version of the quota block struct */ typedef u_int64_t qsize_t; struct dqblk { qsize_t dqb_ihardlimit; /* absolute limit on allocated inodes */ qsize_t dqb_isoftlimit; /* preferred inode limit */ qsize_t dqb_curinodes; /* current # allocated inodes */ qsize_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ qsize_t dqb_bsoftlimit; /* preferred limit on disk blks */ qsize_t dqb_curblocks; /* current block count */ time_t dqb_btime; /* time limit for excessive disk use */ time_t dqb_itime; /* time limit for excessive inode use */ }; /* you can use this switch to hard-wire the quota API if it's not identified correctly */ /* #define LINUX_API_VERSION 1 */ /* API range [1..3] */ int linuxquota_query( const char * dev, int uid, int isgrp, struct dqblk * dqb ); int linuxquota_setqlim( const char * dev, int uid, int isgrp, struct dqblk * dqb ); int linuxquota_sync( const char * dev, int isgrp ); #define Q_DIV(X) (X) #define Q_MUL(X) (X) #define DEV_QBSIZE 1024 #define Q_CTL_V3 #define CADR (caddr_t) #define MY_XDR #define MNTENT mntent #define GQA_TYPE_USR USRQUOTA /* RQUOTA_USRQUOTA */ #define GQA_TYPE_GRP GRPQUOTA /* RQUOTA_GRPQUOTA */ #define GQR_STATUS status #define GQR_RQUOTA getquota_rslt_u.gqr_rquota #define QS_BHARD dqb_bhardlimit #define QS_BSOFT dqb_bsoftlimit #define QS_BCUR dqb_curblocks #define QS_FHARD dqb_ihardlimit #define QS_FSOFT dqb_isoftlimit #define QS_FCUR dqb_curinodes #define QS_BTIME dqb_btime #define QS_FTIME dqb_itime /* uncomment this is you're using NFS with a version of the quota tools < 3.0 */ /* #define LINUX_RQUOTAD_BUG */ /* enable support for extended quota RPC (i.e. quota RPC version 2) */ /* note: could also be enabled by defining MY_XDR (and including "include/rquota.h") */ #if defined (EXT_RQUOTAVERS) #define USE_EXT_RQUOTA #endif /* optional: for support of SGI XFS file systems - comment out if not needed */ #define SGI_XFS #define QX_DIV(X) ((X) / 2) #define QX_MUL(X) ((X) * 2) #include "include/quotaio_xfs.h" libquota-perl-1.7.2+dfsg.orig/README0000644000175000017500000003127712530602627016072 0ustar salvisalviQuota extension module for Perl ------------------------------- Author: Tom Zoerner (tomzo AT users.sourceforge.net) Version: 1.7.2 Date: May 2015 DLSIP-Code:Rcdfg - stable release - C compiler required for installation - support by developer - plain functions, no references used - licensed under the Perl Artistic License or (at your option) version 2 or later of the GNU General Public License Location: http://www.perl.com/CPAN/authors/Tom_Zoerner/ Supported: SunOS 4.1.3, Solaris 2.4 - 2.10, HP-UX 9.0x & 10.10 & 10.20 & 11.00, IRIX 5.2 & 5.3 & 6.2 - 6.5, OSF/1 & Digital Unix 4, BSDi 2, FreeBSD 3.x - 4.9, OpenBSD & NetBSD (no RPC), Linux - kernel 2.0.30 and later, incl. Quota API v2 and XFS, AIX 4.1, 4.2 and 5.3. AFS (Andrew File System) on many of the above (see INSTALL), VxFS (Veritas File System) on Solaris 2. Documentation is in pod format at the end of Quota.pm, installation hints are in a file named INSTALL inside this package. See also CHANGES for a history of updates to this module. ----------------------------------------------------------------------------- THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ----------------------------------------------------------------------------- NAME Quota - Perl interface to file system quotas SYNOPSIS use Quota; ($block_curr, $block_soft, $block_hard, $block_timelimit, $inode_curr, $inode_soft, $inode_hard, $inode_timelimit) = Quota::query($dev [,$uid [,kind]]); ($block_curr, $block_soft, $block_hard, $block_timelimit, $inode_curr, $inode_soft, $inode_hard, $inode_timelimit) = Quota::rpcquery($host, $path [,$uid]); Quota::rpcpeer([$port [,$use_tcp [,timeout]]]); Quota::setqlim($dev, $uid, $block_soft, $block_hard, $inode_soft, $inode_hard [,$tlo [,kind]]); Quota::sync([$dev]); $arg = Quota::getqcarg([$path]); Quota::setmntent(); ($dev, $path, $type, $opts) = Quota::getmntent(); Quota::endmntent(); DESCRIPTION The Quota module provides access to file system quotas. The quotactl system call or ioctl is used to query or set quotas on the local host, or queries are submitted via RPC to a remote host. Mount tables can be parsed with getmntent and paths can be translated to device files (or whatever the actual quotactl implementations needs as argument) of the according file system. Functions ($bc,$bs,$bh,$bt, $ic,$is,$ih,$it) = Quota::query($dev, $uid, $kind) Get current usage and quota limits for a given file system and user. The user is specified by its numeric uid; defaults to the process' real uid. The type of $dev varies from system to system. It's the argument which is used by the quotactl implementation to address a specific file system. It may be the path of a device file (e.g. /dev/sd0a) or the path of the mount point or the quotas file at the top of the file system (e.g. /home.stand/quotas). However you do not have to worry about that; use Quota::getqcarg to automatically translate any path inside a file system to the required $dev argument. $dev may also be in the form of hostname:path, which has the module transparently query the given host via a remote procedure call (RPC). In case you have NFS (or similar network mounts), this type of argument may also be produced by Quota::getqcarg. Note: RPC queries require rquotad(1m) to be running on the target system. If the daemon or host are down, the timeout is 12 seconds. In $bc and $ic the current usage in blocks and inodes is returned. $bs and $is are the soft limits, $bh and $ih hard limits. If the soft limit is exceeded, writes by this user will fail for blocks or inodes after $bt or $it is reached. These times are expressed as usual, i.e. in elapsed seconds since 00:00 1/Jan/1970 GMT. Note: When the quota limits are not exceeded, the timestamps are meaningless and should be ignored. When hard and soft limits are zero, there is no limit for that user. On most systems Quota::query will return undef in that case and errno will be set to ESRCH. When $kind is given and set to 1, $uid is taken as gid and group quotas are queried. This is not supported across RPC and even locally only on a few architectures (e.g. Linux and other BSD based Unix variants, OSF/1 and AIX - check the quotactl(2) man page on your systems). When $kind is set to 2, project quotas are queried; this is currently only supported for XFS. When unsupported, this flag is ignored. Quota::setqlim($dev, $uid, $bs,$bh, $is,$ih, $tlo, $kind) Sets quota limits for the given user. Meanings of $dev, $uid, $bs, $bh, $is and $ih are the same as in Quota::query. For file systems exceeding 2 TB: To allow passing block or inode values larger or equal to 2^32 on 32-bit Perl versions, pass them either as strings or floating point. $tlo decides how the time limits are initialized: 0: The time limits are set to NOT STARTED, i.e. the time limits are not initialized until the first write attempt by this user. This is the default. 1: The time limits are set to 7.0 days. More alternatives (i.e. setting a specific time) aren't available in most implementations. When $kind is given and set to 1, $uid is taken as gid and group quota limits are set. This is supported only on a few architectures (see above). When I<$kind> is set to 2, project quotas are modified; this is currently only supported for XFS. When unsupported, this flag is ignored. Note: if you want to set the quota of a particular user to zero, i.e. no write permission, you must not set all limits to zero, since that is equivalent to unlimited access. Instead set only the hard limit to 0 and the soft limit for example to 1. Note that you cannot set quotas via RPC. Quota::sync($dev) Have the kernel update the quota file on disk or all quota files if no argument given (the latter doesn't work on all systems, in particular on HP-UX 10.10). The main purpose of this function is to check if quota is enabled in the kernel and for a particular file system. Read the quotaon(1m) man page on how to enable quotas on a file system. Note: on some systems this function always returns a success indication, even on partitions which do not have quotas enabled (e.g. Linux). This is not a bug in this module; it's a limitation in certain kernels. ($bc,$bs,$bh,$bt, $ic,$is,$ih,$it) = Quota::rpcquery($host,$path,$uid) This is equivalent to Quota::query("$host:$path",$uid), i.e. query quota for a given user on a given remote host via RPC. $path is the path of any file or directory inside the wanted file system on the remote host. Quota::rpcpeer($port,$use_tcp,timeout) Configure parameters for subsequent RPC queries; all parameters are optional. By default the portmapper on the remote host is used (i.e. default port is 0, protocol is UDP) The default timeout is 4 seconds. Quota::rpcauth($uid,$gid,$hostname) Configure authorization parameters for subsequent RPC queries; all parameters are optional. By default uid and gid are taken from owner of the process and hostname is the host name of current machine. $arg = Quota::getqcarg($path) Get the required $dev argument for Quota::query and Quota::setqlim for the file system you want to operate on. $path is any path of an existing file or directory inside that file system. The path argument is optional and defaults to the current working directory. The type of $dev varies between operating systems, i.e. different implementations of the quotactl functionality. Hence it's important for compatibility to always use this module function and not really pass a device file to Quota::query (as returned by Quota::getdev). See also above at Quota::query $dev = Quota::getdev($path) Returns the device entry in the mount table for a particular file system, specified by any path of an existing file or directory inside it. $path defaults to the working directory. This device entry need not really be a device. For example on network mounts (NFS) it's "host:mountpath", with amd(1m) it may be something completely different. NEVER use this to produce a $dev argument for other functions of this module, since it's not compatible. On some systems quotactl does not work on devices but on the quotas file or some other kind of argument. Always use Quota::getqcarg. Quota::setmntent() Opens or resets the mount table. This is required before the first invocation of Quota::getmntent. Note: on some systems there is no equivalent function in the C library. But you still have to call this module procedure for initialization of module-internal variables. ($dev, $path, $type, $opts) = Quota::getmntent() Returns the next entry in the system mount table. This table contains information about all currently mounted (local or remote) file systems. The format and location of this table (e.g. /etc/mtab) vary from system to system. This function is provided as a compatible way to parse it. (On some systems, like OSF/1, this table isn't accessible as a file at all, i.e. only via Quota::getmntent). Quota::endmntent() Close the mount table. Should be called after the last use of Quota::getmntent to free possibly allocated file handles and memory. Always returns undef. Quota::strerr() Translates $! to a quota-specific error text. You should always use this function to output error messages, since the normal messages don't always make sense for quota errors (e.g. ESRCH: No such process, here: No quota for this user) Note that this function only returns a defined result if you called a Quota command directly before which returned an error indication. RETURN VALUES Functions that are supposed return lists or scalars, return undef upon errors. As usual $! contains the error code (see Quota::strerr). Quota::endmntent always returns undef. All other functions return 0 upon success, non-zero integer otherwise. EXAMPLES An example for each function can be found in the test script test.pl. See also the contrib directory, which contains some longer scripts, kindly donated by users of the module. BUGS With remote quotas we have to rely on the remote system to state correctly which block size the quota values are referring to. Old versions of the Linux rpc.rquotad reported a block size of 4 kilobytes, which was wildly incorrect. For more info on this and other Linux bugs please see INSTALL. AUTHORS This module was created 1995 by Tom Zoerner (email: tomzo AT users.sourceforge.net) and since then continually improved and ported to many operating- and file-systems. Numerous people have contributed to this process; for a complete list of names please see the CHANGES document. The quota module was in the public domain 1995-2001. Since 2001 it is licensed under both the Perl Artistic License and version 2 or later of the GNU General Public License as published by the Free Software Foundation. For a copy of these licenses see . The respective authors of the source code are it's owner in regard to copyright. SEE ALSO perl(1), edquota(1m), quotactl(2) or quotactl(7I), mount(1m), mtab(4) or mnttab(4), quotaon(1m), setmntent(3), getmntent(3) or getmntinfo(3), endmntent(3), rpc(3), rquotad(1m). libquota-perl-1.7.2+dfsg.orig/test.pl0000755000175000017500000001250112222321270016504 0ustar salvisalvi#!../../../perl # ------------------------------------------------------------------------ # # Interactive test and demo script for the Perl Quota extension module # # Author: Tom Zoerner 1995-2005 # # This program (test.pl) is in the public domain and can be used and # redistributed without restrictions. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # ------------------------------------------------------------------------ # use blib; use Quota; if (! -t STDIN || ! -t STDOUT) { print STDERR "\nThis is an interactive test script - input and output must be a tty\nExiting now.\n"; exit; } if ($ENV{AUTOMATED_TESTING}) { print STDERR "\nNo tests available for AUTOMATED_TESTING - Exiting now.\n"; exit; } while(1) { print "\nEnter path to get quota for (NFS possible; default '.'): "; chomp($path = ); $path = "." unless $path =~ /\S/; while(1) { $dev = Quota::getqcarg($path); if(!$dev) { warn "$path: mount point not found\n"; if(-d $path && $path !~ m#/.$#) { # # try to append "/." to get past automounter fs # $path .= "/."; warn "Trying $path instead...\n"; redo; } } last; } redo if !$dev; print "Using device/argument \"$dev\"\n"; ## ## Check if quotas are present on this filesystem ## if($dev =~ m#^[^/]+:#) { print "Is a remote file system\n"; last; } elsif(Quota::sync($dev) && ($! != 1)) { # ignore EPERM warn "Quota::sync: ".Quota::strerr."\n"; warn "Choose another file system - quotas not functional on this one\n"; } else { print "Quotas are present on this filesystem (sync ok)\n"; last; } } ## ## call with one argument (uid defaults to getuid() ## print "\nQuery this fs with default uid (which is real uid) $>\n"; ($bc,$bs,$bh,$bt,$fc,$fs,$fh,$ft) = Quota::query($dev); if(defined($bc)) { my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($bt); $bt = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $bt; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($ft); $ft = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $ft; print "Your usage and limits are $bc ($bs,$bh,$bt) $fc ($fs,$fh,$ft)\n\n"; } else { warn "Quota::query($dev): ",Quota::strerr,"\n\n"; } ## ## call with two arguments ## { print "Enter a uid to get quota for: "; chomp($uid = ); unless($uid =~ /^\d{1,5}$/) { print "You have to enter a numerical uid in range 0..65535 here.\n"; redo; } } ($bc,$bs,$bh,$bt,$fc,$fs,$fh,$ft) = Quota::query($dev, $uid); if(defined($bc)) { my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($bt); $bt = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $bt; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($ft); $ft = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $ft; print "Usage and limits for $uid are $bc ($bs,$bh,$bt) $fc ($fs,$fh,$ft)\n\n"; } else { warn "Quota::query($dev,$uid): ",Quota::strerr,"\n\n"; } ## ## get quotas via RPC ## if($dev =~ m#^/#) { print "Query localhost via RPC.\n"; ($bc,$bs,$bh,$bt,$fc,$fs,$fh,$ft) = Quota::rpcquery('localhost', $path); if(defined($bc)) { my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($bt); $bt = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $bt; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($ft); $ft = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $ft; print "Your Usage and limits are $bc ($bs,$bh,$bt) $fc ($fs,$fh,$ft)\n\n"; } else { warn Quota::strerr,"\n\n"; } print "Query localhost via RPC for $uid.\n"; ($bc,$bs,$bh,$bt,$fc,$fs,$fh,$ft) = Quota::rpcquery('localhost', $path, $uid); if(!defined($bc)) { warn Quota::strerr,"\n\n"; print "Retrying with fake authentication for UID $uid.\n"; Quota::rpcauth($uid); ($bc,$bs,$bh,$bt,$fc,$fs,$fh,$ft) = Quota::rpcquery('localhost', $path, $uid); Quota::rpcauth(); } if(defined($bc)) { my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($bt); $bt = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $bt; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($ft); $ft = sprintf("%04d-%02d-%02d/%02d:%02d", $year+1900,$mon+1,$mday,$hour,$min) if $ft; print "Usage and limits for $uid are $bc ($bs,$bh,$bt) $fc ($fs,$fh,$ft)\n\n"; } else { warn Quota::strerr,"\n\n"; } } else { print "Skipping RPC query test - already done above.\n\n"; } ## ## set quota block & file limits for user ## print "Enter path to set quota (empty to skip): "; chomp($path = ); if($path =~ /\S/) { print "New quota limits bs,bh,fs,fh for $uid (empty to abort): "; chomp($in = ); if($in =~ /\S/) { $dev = Quota::getqcarg($path) || die "$path: $!\n"; unless(Quota::setqlim($dev, $uid, split(/\s*,\s*/, $in), 1)) { print "Quota set for $uid\n"; } else { warn Quota::strerr,"\n"; } } } ## ## Force immediate update on disk ## if($dev !~ m#^[^/]+:#) { Quota::sync($dev) && ($! != 1) && die "Quota::sync: ".Quota::strerr."\n"; } libquota-perl-1.7.2+dfsg.orig/stdio_wrap.c0000644000175000017500000000043106572230021017507 0ustar salvisalvi/* * Access to the std I/O routines for people using sfio * stdio FILE operators are needed by getmntent(3) */ #include FILE *std_fopen(const char *filename, const char *mode) { return fopen(filename, mode); } int std_fclose(FILE *fd) { return fclose(fd); } libquota-perl-1.7.2+dfsg.orig/Quota.xs0000644000175000017500000007615412203057603016655 0ustar salvisalvi#ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif #include "myconfig.h" #ifdef SFIO_VERSION #include "stdio_wrap.h" #else #define std_fopen fopen #define std_fclose fclose #endif #ifdef AFSQUOTA #include "include/afsquota.h" #endif #ifdef SOLARIS_VXFS #include "include/vxquotactl.h" #endif #ifndef AIX #ifndef NO_MNTENT FILE *mtab = NULL; #else /* NO_MNTENT */ #ifdef HAVE_STATVFS struct statvfs *mntp, *mtab = NULL; #else struct statfs *mntp, *mtab = NULL; #endif int mtab_size = 0; #endif /* NO_MNTENT */ #else /* AIX */ static struct vmount *mtab = NULL; static aix_mtab_idx, aix_mtab_count; #endif #define RPC_DEFAULT_TIMEOUT 4000 #ifndef NO_RPC static struct { char use_tcp; unsigned short port; unsigned timeout; } quota_rpc_cfg = {FALSE, 0, 4000}; static struct { int uid; int gid; char hostname[MAX_MACHINE_NAME + 1]; } quota_rpc_auth = {-1, -1, {0} }; struct quota_xs_nfs_rslt { double bhard; double bsoft; double bcur; time_t btime; double fhard; double fsoft; double fcur; time_t ftime; }; /* * fetch quotas from remote host */ int callaurpc(host, prognum, versnum, procnum, inproc, in, outproc, out) char *host; xdrproc_t inproc, outproc; char *in, *out; { struct sockaddr_in remaddr; struct hostent *hp; enum clnt_stat clnt_stat; struct timeval rep_time, timeout; CLIENT *client; int socket = RPC_ANYSOCK; /* * Get IP address; by default the port is determined via remote * portmap daemon; different ports and protocols can be configured */ hp = gethostbyname(host); if (hp == NULL) return ((int) RPC_UNKNOWNHOST); rep_time.tv_sec = quota_rpc_cfg.timeout / 1000; rep_time.tv_usec = (quota_rpc_cfg.timeout % 1000) * 1000; memcpy((char *)&remaddr.sin_addr, (char *)hp->h_addr, hp->h_length); remaddr.sin_family = AF_INET; remaddr.sin_port = htons(quota_rpc_cfg.port); /* * Create client RPC handle */ client = NULL; if (!quota_rpc_cfg.use_tcp) { client = (CLIENT *)clntudp_create(&remaddr, prognum, versnum, rep_time, &socket); } else { client = (CLIENT *)clnttcp_create(&remaddr, prognum, versnum, &socket, 0, 0); } if (client == NULL) return ((int) rpc_createerr.cf_stat); /* * Create an authentication handle */ if ((quota_rpc_auth.uid != -1) && (quota_rpc_auth.gid != -1)) { client->cl_auth = authunix_create(quota_rpc_auth.hostname, quota_rpc_auth.uid, quota_rpc_auth.gid, 0, 0); } else { client->cl_auth = authunix_create_default(); } /* * Call remote server */ timeout.tv_sec = quota_rpc_cfg.timeout / 1000; timeout.tv_usec = (quota_rpc_cfg.timeout % 1000) * 1000; clnt_stat = clnt_call(client, procnum, inproc, in, outproc, out, timeout); if (client->cl_auth) { auth_destroy(client->cl_auth); client->cl_auth = NULL; } clnt_destroy(client); return ((int) clnt_stat); } int getnfsquota( char *hostp, char *fsnamep, int uid, int kind, struct quota_xs_nfs_rslt *rslt ) { struct getquota_args gq_args; struct getquota_rslt gq_rslt; #ifdef USE_EXT_RQUOTA ext_getquota_args ext_gq_args; /* * First try USE_EXT_RQUOTAPROG (Extended quota RPC) */ ext_gq_args.gqa_pathp = fsnamep; ext_gq_args.gqa_id = uid; ext_gq_args.gqa_type = ((kind != 0) ? GQA_TYPE_GRP : GQA_TYPE_USR); if (callaurpc(hostp, RQUOTAPROG, EXT_RQUOTAVERS, RQUOTAPROC_GETQUOTA, xdr_ext_getquota_args, &ext_gq_args, xdr_getquota_rslt, &gq_rslt) != 0) #endif { /* * Fall back to RQUOTAPROG if the server (or client via compile switch) * don't support extended quota RPC */ gq_args.gqa_pathp = fsnamep; gq_args.gqa_uid = uid; if (callaurpc(hostp, RQUOTAPROG, RQUOTAVERS, RQUOTAPROC_GETQUOTA, xdr_getquota_args, &gq_args, xdr_getquota_rslt, &gq_rslt) != 0) { return (-1); } } switch (gq_rslt.GQR_STATUS) { case Q_OK: { struct timeval tv; int qb_fac; gettimeofday(&tv, NULL); #ifdef LINUX_RQUOTAD_BUG /* Since Linux reports a bogus block size value (4k), we must not * use it. Thankfully Linux at least always uses 1k block sizes * for quota reports, so we just leave away all conversions. * If you have a mixed environment, you have a problem though. * Complain to the Linux authors or apply my patch (see INSTALL) */ rslt->bhard = gq_rslt.GQR_RQUOTA.rq_bhardlimit; rslt->bsoft = gq_rslt.GQR_RQUOTA.rq_bsoftlimit; rslt->bcur = gq_rslt.GQR_RQUOTA.rq_curblocks; #else /* not buggy */ if (gq_rslt.GQR_RQUOTA.rq_bsize >= DEV_QBSIZE) { /* assign first, multiply later: ** so that mult works with the possibly larger type in rslt */ rslt->bhard = gq_rslt.GQR_RQUOTA.rq_bhardlimit; rslt->bsoft = gq_rslt.GQR_RQUOTA.rq_bsoftlimit; rslt->bcur = gq_rslt.GQR_RQUOTA.rq_curblocks; /* we rely on the fact that block sizes are always powers of 2 */ /* so the conversion factor will never be a fraction */ qb_fac = gq_rslt.GQR_RQUOTA.rq_bsize / DEV_QBSIZE; rslt->bhard *= qb_fac; rslt->bsoft *= qb_fac; rslt->bcur *= qb_fac; } else { qb_fac = DEV_QBSIZE / gq_rslt.GQR_RQUOTA.rq_bsize; rslt->bhard = gq_rslt.GQR_RQUOTA.rq_bhardlimit / qb_fac; rslt->bsoft = gq_rslt.GQR_RQUOTA.rq_bsoftlimit / qb_fac; rslt->bcur = gq_rslt.GQR_RQUOTA.rq_curblocks / qb_fac; } #endif /* LINUX_RQUOTAD_BUG */ rslt->fhard = gq_rslt.GQR_RQUOTA.rq_fhardlimit; rslt->fsoft = gq_rslt.GQR_RQUOTA.rq_fsoftlimit; rslt->fcur = gq_rslt.GQR_RQUOTA.rq_curfiles; /* if time is given relative to actual time, add actual time */ /* Note: all systems except Linux return relative times */ if (gq_rslt.GQR_RQUOTA.rq_btimeleft == 0) rslt->btime = 0; else if (gq_rslt.GQR_RQUOTA.rq_btimeleft + 10*365*24*60*60 < tv.tv_sec) rslt->btime = tv.tv_sec + gq_rslt.GQR_RQUOTA.rq_btimeleft; else rslt->btime = gq_rslt.GQR_RQUOTA.rq_btimeleft; if (gq_rslt.GQR_RQUOTA.rq_ftimeleft == 0) rslt->ftime = 0; else if (gq_rslt.GQR_RQUOTA.rq_ftimeleft + 10*365*24*60*60 < tv.tv_sec) rslt->ftime = tv.tv_sec + gq_rslt.GQR_RQUOTA.rq_ftimeleft; else rslt->ftime = gq_rslt.GQR_RQUOTA.rq_ftimeleft; if((gq_rslt.GQR_RQUOTA.rq_bhardlimit == 0) && (gq_rslt.GQR_RQUOTA.rq_bsoftlimit == 0) && (gq_rslt.GQR_RQUOTA.rq_fhardlimit == 0) && (gq_rslt.GQR_RQUOTA.rq_fsoftlimit == 0)) { errno = ESRCH; return(-1); } return (0); } case Q_NOQUOTA: errno = ESRCH; break; case Q_EPERM: errno = EPERM; break; default: errno = EINVAL; break; } return (-1); } #ifdef MY_XDR struct xdr_discrim gq_des[2] = { { (int)Q_OK, (xdrproc_t)xdr_rquota }, { 0, NULL } }; bool_t xdr_getquota_args(xdrs, gqp) XDR *xdrs; struct getquota_args *gqp; { return (xdr_string(xdrs, &gqp->gqa_pathp, 1024) && xdr_int(xdrs, &gqp->gqa_uid)); } bool_t xdr_getquota_rslt(xdrs, gqp) XDR *xdrs; struct getquota_rslt *gqp; { return (xdr_union(xdrs, (int *) &gqp->GQR_STATUS, (char *) &gqp->GQR_RQUOTA, gq_des, (xdrproc_t) xdr_void)); } bool_t xdr_rquota(xdrs, rqp) XDR *xdrs; struct rquota *rqp; { return (xdr_int(xdrs, &rqp->rq_bsize) && xdr_bool(xdrs, &rqp->rq_active) && xdr_u_long(xdrs, (unsigned long *)&rqp->rq_bhardlimit) && xdr_u_long(xdrs, (unsigned long *)&rqp->rq_bsoftlimit) && xdr_u_long(xdrs, (unsigned long *)&rqp->rq_curblocks) && xdr_u_long(xdrs, (unsigned long *)&rqp->rq_fhardlimit) && xdr_u_long(xdrs, (unsigned long *)&rqp->rq_fsoftlimit) && xdr_u_long(xdrs, (unsigned long *)&rqp->rq_curfiles) && xdr_u_long(xdrs, (unsigned long *)&rqp->rq_btimeleft) && xdr_u_long(xdrs, (unsigned long *)&rqp->rq_ftimeleft) ); } #endif /* MY_XDR */ #ifdef USE_EXT_RQUOTA bool_t xdr_ext_getquota_args(xdrs, objp) XDR *xdrs; ext_getquota_args *objp; { return xdr_string(xdrs, &objp->gqa_pathp, RQ_PATHLEN) && xdr_int(xdrs, &objp->gqa_type) && xdr_int(xdrs, &objp->gqa_id); } #endif /* USE_EXT_RQUOTA */ #endif /* !NO_RPC */ /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * The Perl interface * */ MODULE = Quota PACKAGE = Quota PROTOTYPES: DISABLE void query(dev,uid=getuid(),kind=0) char * dev int uid int kind PPCODE: { char *p = NULL; int err; #ifdef SGI_XFS if(!strncmp(dev, "(XFS)", 5)) { fs_disk_quota_t xfs_dqblk; #ifndef linux err = quotactl(Q_XGETQUOTA, dev+5, uid, CADR &xfs_dqblk); #else err = quotactl(QCMD(Q_XGETQUOTA, ((kind == 2) ? XQM_PRJQUOTA : ((kind == 1) ? XQM_GRPQUOTA : XQM_USRQUOTA))), dev+5, uid, CADR &xfs_dqblk); #endif if(!err) { EXTEND(SP, 8); PUSHs(sv_2mortal(newSVnv(QX_DIV(xfs_dqblk.d_bcount)))); PUSHs(sv_2mortal(newSVnv(QX_DIV(xfs_dqblk.d_blk_softlimit)))); PUSHs(sv_2mortal(newSVnv(QX_DIV(xfs_dqblk.d_blk_hardlimit)))); PUSHs(sv_2mortal(newSViv(xfs_dqblk.d_btimer))); PUSHs(sv_2mortal(newSVnv(xfs_dqblk.d_icount))); PUSHs(sv_2mortal(newSVnv(xfs_dqblk.d_ino_softlimit))); PUSHs(sv_2mortal(newSVnv(xfs_dqblk.d_ino_hardlimit))); PUSHs(sv_2mortal(newSViv(xfs_dqblk.d_itimer))); } } else #endif #ifdef SOLARIS_VXFS if(!strncmp(dev, "(VXFS)", 6)) { struct vx_dqblk vxfs_dqb; err = vx_quotactl(VX_GETQUOTA, dev+6, uid, CADR &vxfs_dqb); if(!err) { EXTEND(SP,8); PUSHs(sv_2mortal(newSVnv(Q_DIV(vxfs_dqb.dqb_curblocks)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(vxfs_dqb.dqb_bsoftlimit)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(vxfs_dqb.dqb_bhardlimit)))); PUSHs(sv_2mortal(newSViv(vxfs_dqb.dqb_btimelimit))); PUSHs(sv_2mortal(newSVnv(vxfs_dqb.dqb_curfiles))); PUSHs(sv_2mortal(newSVnv(vxfs_dqb.dqb_fsoftlimit))); PUSHs(sv_2mortal(newSVnv(vxfs_dqb.dqb_fhardlimit))); PUSHs(sv_2mortal(newSViv(vxfs_dqb.dqb_ftimelimit))); } } else #endif #ifdef AFSQUOTA if(!strncmp(dev, "(AFS)", 5)) { if (!afs_check()) { /* check is *required* as setup! */ errno = EINVAL; } else { int maxQuota, blocksUsed; err = afs_getquota(dev + 5, &maxQuota, &blocksUsed); if(!err) { EXTEND(SP, 8); PUSHs(sv_2mortal(newSViv(blocksUsed))); PUSHs(sv_2mortal(newSViv(maxQuota))); PUSHs(sv_2mortal(newSViv(maxQuota))); PUSHs(sv_2mortal(newSViv(0))); PUSHs(sv_2mortal(newSViv(0))); PUSHs(sv_2mortal(newSViv(0))); PUSHs(sv_2mortal(newSViv(0))); PUSHs(sv_2mortal(newSViv(0))); } } } else #endif { if((*dev != '/') && (p = strchr(dev, ':'))) { #ifndef NO_RPC struct quota_xs_nfs_rslt rslt; *p = '\0'; err = getnfsquota(dev, p+1, uid, kind, &rslt); if (!err) { EXTEND(SP, 8); PUSHs(sv_2mortal(newSVnv(Q_DIV(rslt.bcur)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(rslt.bsoft)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(rslt.bhard)))); PUSHs(sv_2mortal(newSViv(rslt.btime))); PUSHs(sv_2mortal(newSVnv(rslt.fcur))); PUSHs(sv_2mortal(newSVnv(rslt.fsoft))); PUSHs(sv_2mortal(newSVnv(rslt.fhard))); PUSHs(sv_2mortal(newSViv(rslt.ftime))); } *p = ':'; #else /* NO_RPC */ errno = ENOSYS; err = -1; #endif /* NO_RPC */ } else { #ifdef NETBSD_LIBQUOTA struct quotahandle *qh = quota_open(dev); if (qh != NULL) { struct quotakey qk_blocks, qk_files; struct quotaval qv_blocks, qv_files; qk_blocks.qk_idtype = qk_files.qk_idtype = kind ? QUOTA_IDTYPE_GROUP : QUOTA_IDTYPE_USER; qk_blocks.qk_id = qk_files.qk_id = uid; qk_blocks.qk_objtype = QUOTA_OBJTYPE_BLOCKS; qk_files.qk_objtype = QUOTA_OBJTYPE_FILES; if ( (quota_get(qh, &qk_blocks, &qv_blocks) >= 0) && (quota_get(qh, &qk_files, &qv_files) >= 0) ) { EXTEND(SP, 8); PUSHs(sv_2mortal(newSVnv(Q_DIV(qv_blocks.qv_usage)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(qv_blocks.qv_softlimit)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(qv_blocks.qv_hardlimit)))); PUSHs(sv_2mortal(newSViv(qv_blocks.qv_expiretime))); PUSHs(sv_2mortal(newSVnv(qv_files.qv_usage))); PUSHs(sv_2mortal(newSVnv(qv_files.qv_softlimit))); PUSHs(sv_2mortal(newSVnv(qv_files.qv_hardlimit))); PUSHs(sv_2mortal(newSViv(qv_files.qv_expiretime))); } quota_close(qh); } #else /* not NETBSD_LIBQUOTA */ struct dqblk dqblk; #ifdef USE_IOCTL struct quotactl qp; int fd = -1; qp.op = Q_GETQUOTA; qp.uid = uid; qp.addr = (char *)&dqblk; if ((fd = open(dev, O_RDONLY)) != -1) { err = (ioctl(fd, Q_QUOTACTL, &qp) == -1); close(fd); } else { err = 1; } #else /* not USE_IOCTL */ #ifdef Q_CTL_V3 /* Linux */ err = linuxquota_query(dev, uid, (kind != 0), &dqblk); #else /* not Q_CTL_V3 */ #ifdef Q_CTL_V2 #ifdef AIX /* AIX quotactl doesn't fail if path does not exist!? */ struct stat st; #if defined(HAVE_JFS2) if (strncmp(dev, "(JFS2)", 6) == 0) { if (stat(dev + 6, &st) == 0) { quota64_t user_quota; err = quotactl(dev + 6, QCMD(Q_J2GETQUOTA, ((kind != 0) ? GRPQUOTA : USRQUOTA)), uid, CADR &user_quota); if (!err) { EXTEND(SP, 8); PUSHs(sv_2mortal(newSVnv(user_quota.bused))); PUSHs(sv_2mortal(newSVnv(user_quota.bsoft))); PUSHs(sv_2mortal(newSVnv(user_quota.bhard))); PUSHs(sv_2mortal(newSViv(user_quota.btime))); PUSHs(sv_2mortal(newSVnv(user_quota.ihard))); PUSHs(sv_2mortal(newSVnv(user_quota.isoft))); PUSHs(sv_2mortal(newSVnv(user_quota.iused))); PUSHs(sv_2mortal(newSViv(user_quota.itime))); } } err = 1; /* dummy to suppress duplicate push below */ } #endif /* HAVE_JFS2 */ else if (stat(dev, &st)) { err = 1; } else #endif /* AIX */ err = quotactl(dev, QCMD(Q_GETQUOTA, ((kind != 0) ? GRPQUOTA : USRQUOTA)), uid, CADR &dqblk); #else /* not Q_CTL_V2 */ err = quotactl(Q_GETQUOTA, dev, uid, CADR &dqblk); #endif /* not Q_CTL_V2 */ #endif /* Q_CTL_V3 */ #endif /* not USE_IOCTL */ if(!err) { EXTEND(SP, 8); PUSHs(sv_2mortal(newSVnv(Q_DIV(dqblk.QS_BCUR)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(dqblk.QS_BSOFT)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(dqblk.QS_BHARD)))); PUSHs(sv_2mortal(newSViv(dqblk.QS_BTIME))); PUSHs(sv_2mortal(newSVnv(dqblk.QS_FCUR))); PUSHs(sv_2mortal(newSVnv(dqblk.QS_FSOFT))); PUSHs(sv_2mortal(newSVnv(dqblk.QS_FHARD))); PUSHs(sv_2mortal(newSViv(dqblk.QS_FTIME))); } #endif /* not NETBSD_LIBQUOTA */ } } } int setqlim(dev,uid,bs,bh,fs,fh,timelimflag=0,kind=0) char * dev int uid double bs double bh double fs double fh int timelimflag int kind CODE: { #ifndef NETBSD_LIBQUOTA struct dqblk dqblk; #endif #ifdef USE_IOCTL struct quotactl qp; int fd; qp.op = Q_SETQLIM; qp.uid = uid; qp.addr = (char *)&dqblk; #endif if(timelimflag != 0) timelimflag = 1; #ifdef SGI_XFS if(!strncmp(dev, "(XFS)", 5)) { fs_disk_quota_t xfs_dqblk; xfs_dqblk.d_blk_softlimit = QX_MUL(bs); xfs_dqblk.d_blk_hardlimit = QX_MUL(bh); xfs_dqblk.d_btimer = timelimflag; xfs_dqblk.d_ino_softlimit = fs; xfs_dqblk.d_ino_hardlimit = fh; xfs_dqblk.d_itimer = timelimflag; xfs_dqblk.d_fieldmask = FS_DQ_LIMIT_MASK; xfs_dqblk.d_flags = XFS_USER_QUOTA; #ifndef linux RETVAL = quotactl(Q_XSETQLIM, dev+5, uid, CADR &xfs_dqblk); #else RETVAL = quotactl(QCMD(Q_XSETQLIM, ((kind == 2) ? XQM_PRJQUOTA : ((kind == 1) ? XQM_GRPQUOTA : XQM_USRQUOTA))), dev+5, uid, CADR &xfs_dqblk); #endif } else /* if not xfs, than it's a classic IRIX efs file system */ #endif #ifdef SOLARIS_VXFS if(!strncmp(dev, "(VXFS)", 6)) { struct vx_dqblk vxfs_dqb; vxfs_dqb.dqb_bsoftlimit = Q_MUL(bs); vxfs_dqb.dqb_bhardlimit = Q_MUL(bh); vxfs_dqb.dqb_btimelimit = timelimflag; vxfs_dqb.dqb_fsoftlimit = fs; vxfs_dqb.dqb_fhardlimit = fh; vxfs_dqb.dqb_ftimelimit = timelimflag; RETVAL = vx_quotactl(VX_SETQUOTA, dev+6, uid, CADR &vxfs_dqb); } else #endif #ifdef AFSQUOTA if(!strncmp(dev, "(AFS)", 5)) { if (!afs_check()) { /* check is *required* as setup! */ errno = EINVAL; RETVAL = -1; } else RETVAL = afs_setqlim(dev + 5, bh); } else #endif #if defined(HAVE_JFS2) if(strncmp(dev, "(JFS2)", 6) == 0) { quota64_t user_quota; RETVAL = quotactl(dev + 6, QCMD(Q_J2GETQUOTA, ((kind != 0) ? GRPQUOTA : USRQUOTA)), uid, CADR &user_quota); if (RETVAL == 0) { user_quota.bsoft = bs; user_quota.bhard = bh; user_quota.btime = timelimflag; user_quota.isoft = fs; user_quota.ihard = fh; user_quota.itime = timelimflag; RETVAL = quotactl(dev + 6, QCMD(Q_J2PUTQUOTA, ((kind != 0) ? GRPQUOTA : USRQUOTA)), uid, CADR &user_quota); } } else #endif /* HAVE_JFS2 */ { #ifdef NETBSD_LIBQUOTA struct quotahandle *qh; struct quotakey qk; struct quotaval qv; RETVAL = -1; qh = quota_open(dev); if (qh != NULL) { qk.qk_idtype = kind ? QUOTA_IDTYPE_GROUP : QUOTA_IDTYPE_USER; qk.qk_id = uid; qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS; /* set the grace period for blocks */ if (timelimflag) { /* seven days */ qv.qv_grace = 7*24*60*60; } else if (quota_get(qh, &qk, &qv) >= 0) { /* use user's current setting */ /* OK */ } else if (qk.qk_id = QUOTA_DEFAULTID, quota_get(qh, &qk, &qv) >= 0) { /* use default setting */ /* OK, reset qk_id */ qk.qk_id = uid; } else { qv.qv_grace = 0; /* XXX */ } qv.qv_usage = 0; qv.qv_hardlimit = Q_MUL(bh); qv.qv_softlimit = Q_MUL(bs); qv.qv_expiretime = 0; if (quota_put(qh, &qk, &qv) >= 0) { qk.qk_objtype = QUOTA_OBJTYPE_FILES; /* set the grace period for files, see comments above */ if (timelimflag) { qv.qv_grace = 7*24*60*60; } else if (quota_get(qh, &qk, &qv) >= 0) { /* OK */ } else if (qk.qk_id = QUOTA_DEFAULTID, quota_get(qh, &qk, &qv) >= 0) { /* OK, reset qk_id */ qk.qk_id = uid; } else { qv.qv_grace = 0; /* XXX */ } qv.qv_usage = 0; qv.qv_hardlimit = fh; qv.qv_softlimit = fs; qv.qv_expiretime = 0; if (quota_put(qh, &qk, &qv) >= 0) { RETVAL = 0; } } quota_close(qh); } #else /* not NETBSD_LIBQUOTA */ memset(&dqblk, 0, sizeof(dqblk)); dqblk.QS_BSOFT = Q_MUL(bs); dqblk.QS_BHARD = Q_MUL(bh); dqblk.QS_BTIME = timelimflag; dqblk.QS_FSOFT = fs; dqblk.QS_FHARD = fh; dqblk.QS_FTIME = timelimflag; #ifdef USE_IOCTL if((fd = open(dev, O_RDONLY)) != -1) { RETVAL = (ioctl(fd, Q_QUOTACTL, &qp) != 0); close(fd); } else RETVAL = -1; #else #ifdef Q_CTL_V3 /* Linux */ RETVAL = linuxquota_setqlim (dev, uid, (kind != 0), &dqblk); #else #ifdef Q_CTL_V2 RETVAL = quotactl (dev, QCMD(Q_SETQUOTA,((kind != 0) ? GRPQUOTA : USRQUOTA)), uid, CADR &dqblk); #else RETVAL = quotactl (Q_SETQLIM, dev, uid, CADR &dqblk); #endif #endif #endif #endif /* not NETBSD_LIBQUOTA */ } } OUTPUT: RETVAL int sync(dev=NULL) char * dev CODE: #ifdef SOLARIS_VXFS if ((dev != NULL) && !strncmp(dev, "(VXFS)", 6)) { RETVAL = vx_quotactl(VX_QSYNCALL, dev+6, 0, NULL); } else #endif #ifdef AFSQUOTA if ((dev != NULL) && !strncmp(dev, "(AFS)", 5)) { if (!afs_check()) { errno = EINVAL; RETVAL = -1; } else { int foo1, foo2; RETVAL = (afs_getquota(dev + 5, &foo1, &foo2) ? -1 : 0); } } else #endif #ifdef NETBSD_LIBQUOTA RETVAL = 0; #else /* not NETBSD_LIBQUOTA */ #ifdef USE_IOCTL { struct quotactl qp; int fd; if(dev == NULL) { qp.op = Q_ALLSYNC; dev = "/"; /* is probably ignored anyways */ } else qp.op = Q_SYNC; if((fd = open(dev, O_RDONLY)) != -1) { RETVAL = (ioctl(fd, Q_QUOTACTL, &qp) != 0); if(errno == ESRCH) errno = EINVAL; close(fd); } else RETVAL = -1; } #else { #ifdef Q_CTL_V3 /* Linux */ #ifdef SGI_XFS if ((dev != NULL) && (!strncmp(dev, "(XFS)", 5))) { struct fs_quota_stat fsq_stat; if (!quotactl(QCMD(Q_XGETQSTAT, USRQUOTA), dev+5, 0, CADR &fsq_stat)) { if (fsq_stat.qs_flags & (XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_GDQ_ACCT)) RETVAL = 0; else if ( (strcmp(dev+5, "/") == 0) && (((fsq_stat.qs_flags & 0xff00) >> 8) & (XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_GDQ_ACCT)) ) RETVAL = 0; else { errno = ENOENT; RETVAL = -1; } } else { errno = ENOENT; RETVAL = -1; } } else #endif RETVAL = linuxquota_sync (dev, FALSE); #else #ifdef Q_CTL_V2 #ifdef AIX struct stat st; #endif if(dev == NULL) dev = "/"; #ifdef AIX #if defined(HAVE_JFS2) if (strncmp(dev, "(JFS2)", 6) == 0) dev += 6; #endif if (stat(dev, &st)) RETVAL = -1; else #endif RETVAL = quotactl(dev, QCMD(Q_SYNC, USRQUOTA), 0, NULL); #else #ifdef SGI_XFS #define XFS_UQUOTA (XFS_QUOTA_UDQ_ACCT|XFS_QUOTA_UDQ_ENFD) /* Q_SYNC is not supported on XFS filesystems, so emulate it */ if ((dev != NULL) && (!strncmp(dev, "(XFS)", 5))) { fs_quota_stat_t fsq_stat; sync(); RETVAL = quotactl(Q_GETQSTAT, dev+5, 0, CADR &fsq_stat); if (!RETVAL && ((fsq_stat.qs_flags & XFS_UQUOTA) != XFS_UQUOTA)) { errno = ENOENT; RETVAL = -1; } } else #endif RETVAL = quotactl(Q_SYNC, dev, 0, NULL); #endif #endif } #endif #endif /* NETBSD_LIBQUOTA */ OUTPUT: RETVAL void rpcquery(host,path,uid=getuid(),kind=0) char * host char * path int uid int kind PPCODE: { #ifndef NO_RPC struct quota_xs_nfs_rslt rslt; if (getnfsquota(host, path, uid, kind, &rslt) == 0) { EXTEND(SP, 8); PUSHs(sv_2mortal(newSVnv(Q_DIV(rslt.bcur)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(rslt.bsoft)))); PUSHs(sv_2mortal(newSVnv(Q_DIV(rslt.bhard)))); PUSHs(sv_2mortal(newSViv(rslt.btime))); PUSHs(sv_2mortal(newSVnv(rslt.fcur))); PUSHs(sv_2mortal(newSVnv(rslt.fsoft))); PUSHs(sv_2mortal(newSVnv(rslt.fhard))); PUSHs(sv_2mortal(newSViv(rslt.ftime))); } #else errno = ENOSYS; #endif } void rpcpeer(port=0,use_tcp=FALSE,timeout=RPC_DEFAULT_TIMEOUT) unsigned port unsigned use_tcp unsigned timeout PPCODE: { #ifndef NO_RPC quota_rpc_cfg.port = port; quota_rpc_cfg.use_tcp = use_tcp; quota_rpc_cfg.timeout = timeout; #endif } int rpcauth(uid=-1,gid=-1,hostname=NULL) int uid int gid char * hostname CODE: { #ifndef NO_RPC if ((uid == -1) && (gid == -1) && (hostname==NULL)) { /* reset to default values */ quota_rpc_auth.uid = uid; quota_rpc_auth.gid = gid; quota_rpc_auth.hostname[0] = 0; RETVAL = 0; } else { if (uid == -1) quota_rpc_auth.uid = getuid(); else quota_rpc_auth.uid = uid; if (gid == -1) quota_rpc_auth.gid = getgid(); else quota_rpc_auth.gid = gid; if (hostname == NULL) { RETVAL = gethostname(quota_rpc_auth.hostname, MAX_MACHINE_NAME); } else if (strlen(hostname) < MAX_MACHINE_NAME) { strcpy(quota_rpc_auth.hostname, hostname); RETVAL = 0; } else { errno = EINVAL; RETVAL = -1; } } #endif } OUTPUT: RETVAL int setmntent() CODE: { #ifndef AIX #ifndef NO_MNTENT #ifndef NO_OPEN_MNTTAB if(mtab != NULL) endmntent(mtab); if((mtab = setmntent(MOUNTED, "r")) == NULL) #else if(mtab != NULL) fclose(mtab); if((mtab = std_fopen (MOUNTED,"r")) == NULL) #endif RETVAL = -1; else RETVAL = 0; #else /* NO_MNTENT */ /* if(mtab != NULL) free(mtab); */ if((mtab_size = getmntinfo(&mtab, MNT_NOWAIT)) <= 0) RETVAL = -1; else RETVAL = 0; mntp = mtab; #endif #else /* AIX */ int count, space; if(mtab != NULL) free(mtab); count = mntctl(MCTL_QUERY, sizeof(space), (char *) &space); if (count == 0) { mtab = (struct vmount *) malloc(space); if (mtab != NULL) { count = mntctl(MCTL_QUERY, space, (char *) mtab); if (count > 0) { aix_mtab_count = count; aix_mtab_idx = 0; RETVAL = 0; } else { /* error, or size changed between calls */ if (count == 0) errno = EINTR; RETVAL = -1; } } else RETVAL = -1; } else if (count < 0) RETVAL = -1; else { /* should never happen */ errno = ENOENT; RETVAL = -1; } #endif } OUTPUT: RETVAL void getmntent() PPCODE: { #ifndef AIX #ifndef NO_MNTENT #ifndef NO_OPEN_MNTTAB struct mntent *mntp; if(mtab != NULL) { mntp = getmntent(mtab); if(mntp != NULL) { EXTEND(SP, 4); PUSHs(sv_2mortal(newSVpv(mntp->mnt_fsname, strlen(mntp->mnt_fsname)))); PUSHs(sv_2mortal(newSVpv(mntp->mnt_dir, strlen(mntp->mnt_dir)))); PUSHs(sv_2mortal(newSVpv(mntp->mnt_type, strlen(mntp->mnt_type)))); PUSHs(sv_2mortal(newSVpv(mntp->mnt_opts, strlen(mntp->mnt_opts)))); } } else errno = EBADF; #else /* NO_OPEN_MNTTAB */ struct mnttab mntp; if(mtab != NULL) { if(getmntent(mtab, &mntp) == 0) { EXTEND(SP, 4); PUSHs(sv_2mortal(newSVpv(mntp.mnt_special, strlen(mntp.mnt_special)))); PUSHs(sv_2mortal(newSVpv(mntp.mnt_mountp, strlen(mntp.mnt_mountp)))); PUSHs(sv_2mortal(newSVpv(mntp.mnt_fstype, strlen(mntp.mnt_fstype)))); PUSHs(sv_2mortal(newSVpv(mntp.mnt_mntopts, strlen(mntp.mnt_mntopts)))); } } else errno = EBADF; #endif #else /* NO_MNTENT */ #ifdef OSF_QUOTA char *fstype = getvfsbynumber((int)mntp->f_type); #endif if((mtab != NULL) && mtab_size) { EXTEND(SP,4); PUSHs(sv_2mortal(newSVpv(mntp->f_mntfromname, strlen(mntp->f_mntfromname)))); PUSHs(sv_2mortal(newSVpv(mntp->f_mntonname, strlen(mntp->f_mntonname)))); #ifdef OSF_QUOTA if (fstype != (char *) -1) PUSHs(sv_2mortal(newSVpv(fstype, strlen(fstype)))); else #endif #ifdef __OpenBSD__ /* OpenBSD struct statfs lacks the f_type member (starting with release 2.7) */ PUSHs(sv_2mortal(newSVpv("", 0))); #else /* !__OpenBSD__ */ #ifdef HAVE_STATVFS PUSHs(sv_2mortal(newSVpv(mntp->f_fstypename, strlen(mntp->f_fstypename)))); #else PUSHs(sv_2mortal(newSViv((IV)mntp->f_type))); #endif /* HAVE_STATVFS */ #endif /* !__OpenBSD__ */ #ifdef HAVE_STATVFS PUSHs(sv_2mortal(newSViv((IV)mntp->f_flag))); #else PUSHs(sv_2mortal(newSViv((IV)mntp->f_flags))); #endif mtab_size--; mntp++; } #endif #else /* AIX */ struct vmount *vmp; char *cp; int i; if ((mtab != NULL) && (aix_mtab_idx < aix_mtab_count)) { cp = (char *) mtab; for (i=0; ivmt_length; } vmp = (struct vmount *) cp; aix_mtab_idx += 1; EXTEND(SP,4); if ((vmp->vmt_gfstype != MNT_NFS) && (vmp->vmt_gfstype != MNT_NFS3)) { cp = vmt2dataptr(vmp, VMT_OBJECT); PUSHs(sv_2mortal(newSVpv(cp, strlen(cp)))); } else { uchar *mp, *cp2; cp = vmt2dataptr(vmp, VMT_HOST); cp2 = vmt2dataptr(vmp, VMT_OBJECT); mp = malloc(strlen(cp) + strlen(cp2) + 2); if (mp != NULL) { strcpy(mp, cp); strcat(mp, ":"); strcat(mp, cp2); PUSHs(sv_2mortal(newSVpv(mp, strlen(mp)))); free(mp); } else { cp = "?"; PUSHs(sv_2mortal(newSVpv(cp, strlen(cp)))); } } cp = vmt2dataptr(vmp, VMT_STUB); PUSHs(sv_2mortal(newSVpv(cp, strlen(cp)))); switch(vmp->vmt_gfstype) { case MNT_NFS: cp = "nfs"; break; case MNT_NFS3: cp = "nfs"; break; case MNT_JFS: cp = "jfs"; break; #if defined(MNT_AIX) && defined(MNT_J2) && (MNT_AIX==MNT_J2) case MNT_J2: cp = "jfs2"; break; #else #if defined(MNT_J2) case MNT_J2: cp = "jfs2"; break; #endif case MNT_AIX: cp = "aix"; break; #endif case 4: cp = "afs"; break; case MNT_CDROM: cp = "cdrom,ignore"; break; default: cp = "unknown,ignore"; break; } PUSHs(sv_2mortal(newSVpv(cp, strlen(cp)))); cp = vmt2dataptr(vmp, VMT_ARGS); PUSHs(sv_2mortal(newSVpv(cp, strlen(cp)))); } #endif } void endmntent() PPCODE: { if(mtab != NULL) { #ifndef AIX #ifndef NO_MNTENT #ifndef NO_OPEN_MNTTAB endmntent(mtab); /* returns always 1 in SunOS */ #else std_fclose (mtab); #endif /* #else: if(mtab != NULL) free(mtab); */ #endif #else /* AIX */ free(mtab); #endif mtab = NULL; } } char * getqcargtype() CODE: static char ret[25]; #if defined(USE_IOCTL) || defined(QCARG_MNTPT) strcpy(ret, "mntpt"); #else #if defined(HAVE_JFS2) strcpy(ret, "any,JFS2"); #else #if defined(AIX) || defined(OSF_QUOTA) strcpy(ret, "any"); #else #ifdef Q_CTL_V2 strcpy(ret, "qfile"); #else /* this branch applies to Q_CTL_V3 (Linux) too */ #ifdef SGI_XFS strcpy(ret, "dev,XFS"); #else strcpy(ret, "dev"); #endif #endif #endif #endif #endif #ifdef AFSQUOTA strcat(ret, ",AFS"); #endif #ifdef SOLARIS_VXFS strcat(ret, ",VXFS"); #endif RETVAL = ret; OUTPUT: RETVAL libquota-perl-1.7.2+dfsg.orig/afsquota.c0000644000175000017500000000664510720374517017205 0ustar salvisalvi/* * Interface to OpenAFS * * Contributed 1998,2003 by Wolfgang Friebel */ #if defined( __hpux) #define IGNORE_STDS_H #endif #include #include #include #include #define MAXSIZE 2048 #define MAXDNAME 2048 #include #include #include #ifdef SunOS4 #define _VICEIOCTL(id) ((unsigned int ) _IOW(V, id, struct ViceIoctl)) #endif /* * Check if AFS is installed */ int afs_check(void) { struct ViceIoctl vi; int32_t code; char space[MAXSIZE]; vi.in_size = 0; vi.out_size = MAXSIZE; vi.out = (caddr_t) space; code = pioctl(NULL, VIOC_GET_WS_CELL, &vi, 0); return ! code; } /* * report quota */ int afs_getquota(char *path, int *maxQuota, int *blocksUsed) { struct ViceIoctl a_params; struct VolumeStatus *vs; a_params.in_size = 0; a_params.out_size = MAXSIZE; a_params.in = NULL; a_params.out = malloc(MAXSIZE); if (a_params.out == NULL) { errno = ENOMEM; return -1; } if (pioctl(path, VIOCGETVOLSTAT,&a_params,1) == -1) { free(a_params.out); return -1; } vs = (struct VolumeStatus *) a_params.out; *maxQuota = vs->MaxQuota; *blocksUsed = vs->BlocksInUse; free(a_params.out); return 0; } /* * Usage: fs sq */ int afs_setqlim(char *path, int maxQuota) { struct ViceIoctl a_params; struct VolumeStatus *vs; int insize; a_params.in_size = 0; a_params.out_size = MAXSIZE; a_params.in = NULL; a_params.out = malloc(MAXSIZE); if (a_params.out == NULL) { errno = ENOMEM; return -1; } /* Read the old volume status */ if(pioctl(path,VIOCGETVOLSTAT,&a_params,1) == -1) { free(a_params.out); return -1; } insize = sizeof(struct VolumeStatus) + strlen(path) + 2; a_params.in_size = ((MAXSIZE < insize) ? MAXSIZE : insize); a_params.out_size = 0; a_params.in = a_params.out; a_params.out = NULL; vs = (struct VolumeStatus *) a_params.in; vs->MaxQuota = maxQuota; if(pioctl(path,VIOCSETVOLSTAT,&a_params,1) == -1) { free(a_params.in); return -1; } free(a_params.in); return 0; } #ifdef __hpux int sigvec( int sig, struct sigvec *vec, struct sigvec *ovec ) { return sigvector(sig, vec, ovec); } #endif #ifdef STAND_ALONE int main(int argc, char **argv) { int usage, limit; if (afs_check()) { if (afs_getquota("/afs/ifh.de/user/z/zorner", &limit, &usage) == 0) { printf("limit=%d usage=%d\n", limit, usage); } else perror("Not an AFS filesystem"); } else { printf("No AFS available\n"); } } #endif /* * Compiler options for standalone compilation */ /* AIX: cc afsquota.c -L/products/security/athena/lib -lkafs -ldes -lkrb -lroken -lld IRIX: cc afsquota.c -L/products/security/athena/lib -lkafs -ldes -lkrb \ -Wl,-rpath -Wl,/products/security/athena/lib Linux: cc afsquota.c -L/products/security/athena/lib -lkafs -ldes -lkrb \ -Wl,-rpath -Wl,/products/security/athena/lib HP-UX: cc -Ae afsquota.c -L/products/security/athena/lib -lkafs -ldes -lkrb Solaris: (Workshop compiler) cc afsquota.c -L/products/security/athena/lib -lkafs -ldes -lkrb \ -Wl,-R -Wl,/products/security/athena/lib SunOS: acc afsquota.c -U__STDC__ -DSunOS4 \ -L/products/security/athena/lib -lkafs -ldes -lkrb */ libquota-perl-1.7.2+dfsg.orig/INSTALL0000644000175000017500000001046207714246232016240 0ustar salvisalviInstallation Instructions ------------------------- Usually all you have to do is: perl Makefile.PL make make test make install make clean If this fails, regard the following instructions step by step. Note that this module does not support installation by the CPAN(++) module. Options: -> Support for Solaris VxFS should be added automatically if the module is installed. If not, #define or #undef SOLARIS_VXFS in myconfig.h -> If you want support for AFS, you need the OpenAFS package (tested with OpenAFS on (SuSE) Linux, HP-UX10, Solaris 2.6, 2.8, AIX 4.3 and IRIX 6.5). The Makefile.PL tries to detect automatically if AFS is preset on a system. If that fails, edit the Makefile.PL to always define $hasafs (and drop me a mail). 1) On Linux systems make sure you have configured your kernel with quota support. You also need the quota utilities and headers. E.g., with the SuSE Linux 6.0 distribution you'll find them in package ap::quota. If your distribution doesn't include the package you can get it from . See also (6) below. 2) Link or create the hints file. a) Should be done by Makefile.PL for all supported systems. If not, and there is a file below hints/ for your operating system (maybe for a previous release), just create a link named "myconfig.h" to that file: ln -s hints/my-os.h myconfig.h b) Else, use hints/none.h to create a myconfig.h of your own. Check which #includes you need in the online manuals. Contact me before you invest a lot of time, it might already be done. Edit Makefile.PL to maybe add/delete some libraries. Usually you'll need only librpcsvc for the quota RPC mechanism. If you don't have this library or it lacks the quota routines, #define MY_XDR in myconfig.h to include the routines provided with this module. If you don't have /usr/include/rpcsvc/rquota.h, include "include/rquota.h" instead. If you don't need RPC at all, just define NO_RPC. 3) Generate the Makefile: perl Makefile.PL 4) Compile the module: make 5) Run "make test" to check if the module routines do work correctly. (Since release 1.0 you can test the module without installing) 6) Linux specials: a) If you're using an ancient version of the Linux quota tools on a NFS server, check Quota::query() results for block usage and limits. Old versions of the rpc.rquotad did report a wrong block size, hence all sizes were 4 times too large. If your system shows this error, you should uncomment #define LINUX_RQUOTAD_BUG in the hints file and recompile. The better solution is to update your quota tools though. b) If you're using RedHat 7.1 or later, or the Alan Cox (ac) branch of the Linux 2.4.x kernels, you're victim of a new and completely backwards incompatible Quota file format and quotactl API. If you've downloaded the kernel separately, make sure to install the latest version of the quota tools: see (1). If the Quota module does not find quotas for any users anymore, the reason may be you've not set up the new aquota.user/group files yet. Remember: after creating these files with quotackeck(8) or convertquota(8) you have to execute quotaon(8) another time. You'll not see this requirement with quota(1) because that program reads the quota files directly if the kernel query fails; the module however only goes through the kernel. If in doubt, do an strace(1) on the quota(1) call. Normally you should see no access to the aquota files in the trace. Alternatively, make the quota files readable for root only (recommended anyway) and try quota -v again under a non-root login. If this fails, the kernel has not enabled quota support. 7) To install the module in your perl tree: "make install" You may need to su root before this step. The contrib directory contains some usage examples, donated by users. No guarantee from me that they do anything useful or don't format your hard drive. 8) Before you start for another OS, type "make clean" Please mail me any changes in the hints files or Makefile.PL you had to apply to get the package to compile. Please remember to include in your mail the name of used OS and version numbers of OS (uname -rs) and module. Tom --- email: tomzo AT nefkom DOT net libquota-perl-1.7.2+dfsg.orig/linuxapi.c0000644000175000017500000002601711123432125017172 0ustar salvisalvi/* ** Linux quotactl wrapper ** Required to support 3 official and intermediate quotactl() versions */ #include #include #include #include #include #include #include "myconfig.h" /* API v1 command definitions */ #define Q_V1_GETQUOTA 0x0300 #define Q_V1_SYNC 0x0600 #define Q_V1_SETQLIM 0x0700 #define Q_V1_GETSTATS 0x0800 /* API v2 command definitions */ #define Q_V2_SYNC 0x0600 #define Q_V2_SETQLIM 0x0700 #define Q_V2_GETQUOTA 0x0D00 #define Q_V2_GETSTATS 0x1100 /* proc API command definitions */ #define Q_V3_SYNC 0x800001 #define Q_V3_GETQUOTA 0x800007 #define Q_V3_SETQUOTA 0x800008 /* Interface versions */ #define IFACE_UNSET 0 #define IFACE_VFSOLD 1 #define IFACE_VFSV0 2 #define IFACE_GENERIC 3 /* format supported by current kernel */ static int kernel_iface = IFACE_UNSET; /* * Quota structure used for communication with userspace via quotactl * Following flags are used to specify which fields are valid */ #define QIF_BLIMITS 1 #define QIF_SPACE 2 #define QIF_ILIMITS 4 #define QIF_INODES 8 #define QIF_BTIME 16 #define QIF_ITIME 32 #define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS) #define QIF_USAGE (QIF_SPACE | QIF_INODES) #define QIF_TIMES (QIF_BTIME | QIF_ITIME) #define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES) /* ** Copy of struct declarations in the v2 quota.h header file ** (with structure names changed to avoid conflicts with v2 headers). ** This is required to be able to compile with v1 kernel headers. */ /* ** Packed into wrapper for compatibility of 32-bit clients with 64-bit kernels: ** 64-bit compilers add 4 padding bytes at the end of the struct, so a memcpy ** corrupts the 4 bytes following the struct in the 32-bit clients userspace */ union dqblk_v3_wrap { struct dqblk_v3 { u_int64_t dqb_bhardlimit; u_int64_t dqb_bsoftlimit; u_int64_t dqb_curspace; u_int64_t dqb_ihardlimit; u_int64_t dqb_isoftlimit; u_int64_t dqb_curinodes; u_int64_t dqb_btime; u_int64_t dqb_itime; u_int32_t dqb_valid; } dqblk; u_int64_t foo[9]; }; struct dqstats_v2 { u_int32_t lookups; u_int32_t drops; u_int32_t reads; u_int32_t writes; u_int32_t cache_hits; u_int32_t allocated_dquots; u_int32_t free_dquots; u_int32_t syncs; u_int32_t version; }; struct dqblk_v2 { unsigned int dqb_ihardlimit; unsigned int dqb_isoftlimit; unsigned int dqb_curinodes; unsigned int dqb_bhardlimit; unsigned int dqb_bsoftlimit; qsize_t dqb_curspace; time_t dqb_btime; time_t dqb_itime; }; struct dqblk_v1 { u_int32_t dqb_bhardlimit; u_int32_t dqb_bsoftlimit; u_int32_t dqb_curblocks; u_int32_t dqb_ihardlimit; u_int32_t dqb_isoftlimit; u_int32_t dqb_curinodes; time_t dqb_btime; time_t dqb_itime; }; /* ** Check kernel quota version ** Taken from quota-tools 3.08 by Jan Kara */ static void linuxquota_get_api( void ) { #ifndef LINUX_API_VERSION struct stat st; if (stat("/proc/sys/fs/quota", &st) == 0) { kernel_iface = IFACE_GENERIC; } else { struct dqstats_v2 v2_stats; struct sigaction sig; struct sigaction oldsig; /* This signal handling is needed because old kernels send us SIGSEGV as they try to resolve the device */ sig.sa_handler = SIG_IGN; sig.sa_sigaction = NULL; sig.sa_flags = 0; sigemptyset(&sig.sa_mask); if (sigaction(SIGSEGV, &sig, &oldsig) < 0) { fprintf(stderr, "linuxapi.c warning: cannot set SEGV signal handler: %s\n", strerror(errno)); goto failure; } if (quotactl(QCMD(Q_V2_GETSTATS, 0), NULL, 0, (void *)&v2_stats) >= 0) { kernel_iface = IFACE_VFSV0; } else if (errno != ENOSYS && errno != ENOTSUP) { /* RedHat 7.1 (2.4.2-2) newquota check * Q_V2_GETSTATS in it's old place, Q_GETQUOTA in the new place * (they haven't moved Q_GETSTATS to its new value) */ int err_stat = 0; int err_quota = 0; char tmp[1024]; /* Just temporary buffer */ if (quotactl(QCMD(Q_V1_GETSTATS, 0), NULL, 0, tmp)) err_stat = errno; if (quotactl(QCMD(Q_V1_GETQUOTA, 0), "/dev/null", 0, tmp)) err_quota = errno; /* On a RedHat 2.4.2-2 we expect 0, EINVAL * On a 2.4.x we expect 0, ENOENT * On a 2.4.x-ac we wont get here */ if (err_stat == 0 && err_quota == EINVAL) { kernel_iface = IFACE_VFSV0; } else { kernel_iface = IFACE_VFSOLD; } } else { /* This branch is *not* in quota-tools 3.08 ** but without it quota version is not correctly ** identified for the original SuSE 8.0 kernel */ unsigned int vers_no; FILE * qf; if ((qf = fopen("/proc/fs/quota", "r"))) { if (fscanf(qf, "Version %u", &vers_no) == 1) { if ( (vers_no == (6*10000 + 5*100 + 0)) || (vers_no == (6*10000 + 5*100 + 1)) ) { kernel_iface = IFACE_VFSV0; } } fclose(qf); } } if (sigaction(SIGSEGV, &oldsig, NULL) < 0) { fprintf(stderr, "linuxapi.c warning: cannot reset signal handler: %s\n", strerror(errno)); goto failure; } } failure: if (kernel_iface == IFACE_UNSET) kernel_iface = IFACE_VFSOLD; #else /* defined LINUX_API_VERSION */ kernel_iface = LINUX_API_VERSION; #endif } /* ** Wrapper for the quotactl(GETQUOTA) call. ** For API v2 the results are copied back into a v1 structure. */ int linuxquota_query( const char * dev, int uid, int isgrp, struct dqblk * dqb ) { int ret; if (kernel_iface == IFACE_UNSET) linuxquota_get_api(); if (kernel_iface == IFACE_GENERIC) { union dqblk_v3_wrap dqb3; ret = quotactl(QCMD(Q_V3_GETQUOTA, (isgrp ? GRPQUOTA : USRQUOTA)), dev, uid, (caddr_t) &dqb3.dqblk); if (ret == 0) { dqb->dqb_bhardlimit = dqb3.dqblk.dqb_bhardlimit; dqb->dqb_bsoftlimit = dqb3.dqblk.dqb_bsoftlimit; dqb->dqb_curblocks = dqb3.dqblk.dqb_curspace / DEV_QBSIZE; dqb->dqb_ihardlimit = dqb3.dqblk.dqb_ihardlimit; dqb->dqb_isoftlimit = dqb3.dqblk.dqb_isoftlimit; dqb->dqb_curinodes = dqb3.dqblk.dqb_curinodes; dqb->dqb_btime = dqb3.dqblk.dqb_btime; dqb->dqb_itime = dqb3.dqblk.dqb_itime; } } else if (kernel_iface == IFACE_VFSV0) { struct dqblk_v2 dqb2; ret = quotactl(QCMD(Q_V2_GETQUOTA, (isgrp ? GRPQUOTA : USRQUOTA)), dev, uid, (caddr_t) &dqb2); if (ret == 0) { dqb->dqb_bhardlimit = dqb2.dqb_bhardlimit; dqb->dqb_bsoftlimit = dqb2.dqb_bsoftlimit; dqb->dqb_curblocks = dqb2.dqb_curspace / DEV_QBSIZE; dqb->dqb_ihardlimit = dqb2.dqb_ihardlimit; dqb->dqb_isoftlimit = dqb2.dqb_isoftlimit; dqb->dqb_curinodes = dqb2.dqb_curinodes; dqb->dqb_btime = dqb2.dqb_btime; dqb->dqb_itime = dqb2.dqb_itime; } } else /* if (kernel_iface == IFACE_VFSOLD) */ { struct dqblk_v1 dqb1; ret = quotactl(QCMD(Q_V1_GETQUOTA, (isgrp ? GRPQUOTA : USRQUOTA)), dev, uid, (caddr_t) &dqb1); if (ret == 0) { dqb->dqb_bhardlimit = dqb1.dqb_bhardlimit; dqb->dqb_bsoftlimit = dqb1.dqb_bsoftlimit; dqb->dqb_curblocks = dqb1.dqb_curblocks; dqb->dqb_ihardlimit = dqb1.dqb_ihardlimit; dqb->dqb_isoftlimit = dqb1.dqb_isoftlimit; dqb->dqb_curinodes = dqb1.dqb_curinodes; dqb->dqb_btime = dqb1.dqb_btime; dqb->dqb_itime = dqb1.dqb_itime; } } return ret; } /* ** Wrapper for the quotactl(GETQUOTA) call. ** For API v2 and v3 the parameters are copied into the internal structure. */ int linuxquota_setqlim( const char * dev, int uid, int isgrp, struct dqblk * dqb ) { int ret; if (kernel_iface == IFACE_UNSET) linuxquota_get_api(); if (kernel_iface == IFACE_GENERIC) { union dqblk_v3_wrap dqb3; dqb3.dqblk.dqb_bhardlimit = dqb->dqb_bhardlimit; dqb3.dqblk.dqb_bsoftlimit = dqb->dqb_bsoftlimit; dqb3.dqblk.dqb_curspace = 0; dqb3.dqblk.dqb_ihardlimit = dqb->dqb_ihardlimit; dqb3.dqblk.dqb_isoftlimit = dqb->dqb_isoftlimit; dqb3.dqblk.dqb_curinodes = 0; dqb3.dqblk.dqb_btime = dqb->dqb_btime; dqb3.dqblk.dqb_itime = dqb->dqb_itime; dqb3.dqblk.dqb_valid = (QIF_BLIMITS | QIF_ILIMITS); ret = quotactl (QCMD(Q_V3_SETQUOTA, (isgrp ? GRPQUOTA : USRQUOTA)), dev, uid, (caddr_t) &dqb3.dqblk); } else if (kernel_iface == IFACE_VFSV0) { struct dqblk_v2 dqb2; dqb2.dqb_bhardlimit = dqb->dqb_bhardlimit; dqb2.dqb_bsoftlimit = dqb->dqb_bsoftlimit; dqb2.dqb_curspace = 0; dqb2.dqb_ihardlimit = dqb->dqb_ihardlimit; dqb2.dqb_isoftlimit = dqb->dqb_isoftlimit; dqb2.dqb_curinodes = 0; dqb2.dqb_btime = dqb->dqb_btime; dqb2.dqb_itime = dqb->dqb_itime; ret = quotactl (QCMD(Q_V2_SETQLIM, (isgrp ? GRPQUOTA : USRQUOTA)), dev, uid, (caddr_t) &dqb2); } else /* if (kernel_iface == IFACE_VFSOLD) */ { struct dqblk_v1 dqb1; dqb1.dqb_bhardlimit = dqb->dqb_bhardlimit; dqb1.dqb_bsoftlimit = dqb->dqb_bsoftlimit; dqb1.dqb_curblocks = 0; dqb1.dqb_ihardlimit = dqb->dqb_ihardlimit; dqb1.dqb_isoftlimit = dqb->dqb_isoftlimit; dqb1.dqb_curinodes = 0; dqb1.dqb_btime = dqb->dqb_btime; dqb1.dqb_itime = dqb->dqb_itime; ret = quotactl (QCMD(Q_V1_SETQLIM, (isgrp ? GRPQUOTA : USRQUOTA)), dev, uid, (caddr_t) &dqb1); } return ret; } /* ** Wrapper for the quotactl(SYNC) call. */ int linuxquota_sync( const char * dev, int isgrp ) { int ret; if (kernel_iface == IFACE_UNSET) linuxquota_get_api(); if (kernel_iface == IFACE_GENERIC) { ret = quotactl (QCMD(Q_V3_SYNC, (isgrp ? GRPQUOTA : USRQUOTA)), dev, 0, NULL); } else if (kernel_iface == IFACE_VFSV0) { ret = quotactl (QCMD(Q_V2_SYNC, (isgrp ? GRPQUOTA : USRQUOTA)), dev, 0, NULL); } else /* if (kernel_iface == IFACE_VFSOLD) */ { ret = quotactl (QCMD(Q_V1_SYNC, (isgrp ? GRPQUOTA : USRQUOTA)), dev, 0, NULL); } return ret; } #if 0 #define DEVICE_PATH "/dev/hda6" main() { struct dqblk dqb; linuxquota_get_api(); printf("API=%d\n", kernel_iface); if (linuxquota_sync(DEVICE_PATH, FALSE) != 0) perror("Q_SYNC"); if (linuxquota_query(DEVICE_PATH, getuid(), 0, &dqb) == 0) { printf("blocks: usage %d soft %d hard %d expire %s", dqb.dqb_curblocks, dqb.dqb_bhardlimit, dqb.dqb_bsoftlimit, ((dqb.dqb_btime != 0) ? (char*)ctime(&dqb.dqb_btime) : "n/a\n")); printf("inodes: usage %d soft %d hard %d expire %s", dqb.dqb_curinodes, dqb.dqb_ihardlimit, dqb.dqb_isoftlimit, ((dqb.dqb_itime != 0) ? (char*)ctime(&dqb.dqb_itime) : "n/a\n")); } else perror("Q_GETQUOTA"); } #endif libquota-perl-1.7.2+dfsg.orig/CHANGES0000644000175000017500000003273212530602665016204 0ustar salvisalviChanges in 1.7.2 (May 2015) - Adapted platform detection for Linux 4.* Thanks to C. Affolter for reporting the issue (CPAN ticket 104652) Changes in 1.7.1 (September 2013) - "make test" now aborts if STDOUT is not a terminal, same as already for STDIN. Suggested by Alexandr Ciornii via CPAN ticket 82564. Changes in 1.7.0 (August 2013) - Added support for the new NetBSD 6.0 quota system (libquota) Thanks to David Holland and Edgar Fuss - To support limits and usage >= 2^32 on 32-bit clients, Quota::setqlim and Quota::query interfaces were changed to use double (NV) instead of integer (IV). This should be transparent to users of the module. Changes in 1.6.7 (November 2011) - Added support to detect 3.x Linux kernels Thanks to Salvatore Bonaccorso of the Debian Perl Group Changes in 1.6.6 (June 2011) - Ignore "rootfs" filesystem in Quota::getqcarg() on Linux, which always is a duplicate. Thanks to "abaturin" for providing this patch. - Made test.pl exit immediately when AUTOMATED_TESTING is set in the environment (same as when called not from a tty), as all tests require user interaction. Changed on request of TODDR of cpan.org Changes in 1.6.5 (January 2011) - Fixed syntax error and missing init for params to setqlim() Thanks to Heinrich Mislik for reporting the bugs Changes in 1.6.4 (January 2010) - Fixed RPC quota block count truncation to 32bit (CPAN ticket 52813 ) Thanks to Lloyd Brown for reporting the bug Changes in 1.6.3 (December 2008) - Fixed SEG fault for 32-bit Linux clients on top of 64-bit kernels Thanks to Jani Ollikainen (pronetko.fi) for reporting and debugging this. Thanks to Thomas Rzipa for reporting this issue, too. - Fixed setqlim to allow setting limits exceeding 2^32 blocks or files. The current solution will work only for perl executables which support 64-bit wide integers (e.g. x86-64) Changes in 1.6.2 (January 2008) - Fixed memory leak in RPC authentication Thanks again to Kostik (koc at rol.ru) Changes in 1.6.1 (November 2007) - Adapted hints/bsd.h to use statvfs instead of statfs in NetBSD 3.0 - Added support for extended quota RPC to allow querying group quotas. Thanks to Kostik (koc AT rol.ru) for the suggestion. Changes in 1.6.0 (October 2007) - Work-around for different getmntent() semantics for linux loop mounts Thanks Wouter de Jong (wouter@widexs.nl) for reporting this issue. - (late) version bump due to the interface change in 1.5.2 Changes in 1.5.2 (October 2007) - Added support for new quotactl() parameters in JFS2 on AIX 5.3. Thanks to Joshua Frigerio (joshua@uic.edu) for providing a development account. (Note: also prepared support for JFS2 quota classes; this is yet unfinished and untested. See sub-directory contrib/aix_jfs2_class) - Added support for XFS project quotas on request of Sten Spans (sten@blinkenlights.nl); received no feedback it if works. Changed the "isgrp" param to Quota::query() and setqlim() from boolean into an enum: 0:=user, 1:=group, 2:=project quotas. - Added a copyright notice to the main module and the manual page on request of the Debian maintainer. Changes in 1.5.1 (July 2005) - Added new API function rpcauth: use non-default authentication for RPC Patch submitted by Karol Lassak - Makefile fix for Linux: compile linuxapi.c with default CFLAGS because for 64-bit systems -fPIC is required. Patches submitted by David Lee and James Olin Oden; used a different solution though. Changes in 1.5.0 (Nov 2004) - Added new API function rpcpeer: set port and protocol for RPC queries. On request by Sten Spans (sten@blinkenlights.nl) Changes in 1.4.11 (Aug 2004) - Updated VxFS detection in Makefile.PL for recent Solaris/VxFS versions Thanks to Joshua Frigerio for the info and to Keith Clay for verification. - tiny syntax cleanup in linuxapi.c Changes in 1.4.10 (Jan 2004) - Applied patch by Antti Tapaninen (aet at cc.hut.fi) to add support for MacOS X (based on BSD config) and NFS3 support for AIX. - Applied patch by Chris Adams (cmadams at hiwaay.net) to avoid warning in Quota::getqcarg() on systems where getmntent(3) may return invalid mount points, e.g. Tru64 UNIX Changes in 1.4.9 (Aug 2003) - Applied patch by Wolfgang.Friebel@desy.de: Changed AFS quota support, now based on OpenAFS instead of arla and Kerberos4. Changes in 1.4.8 (May 2003) - fixed bug in linuxapi.c, thanks to Shane DeRidder Changes in 1.4.7 (May 2003) - adapted for the latest fashion of Linux quota APIs (version 6.5.1) Thanks to Jay R. Wren, Shane DeRidder, Roman "romke" and Geoffrey Pan for your infos and feedback. - added quota threshold monitoring script to the contrib directory. Thanks to Ziaur Rahman. Changes in 1.4.6 (August 2002) - changed the test script to exit if STDIN is not a terminal device. This is an interactive script which cannot be run by CPANPLUS. Changes in 1.4.5 (July 2002) - replaced use of macro BCOPY with libc function memcpy() because of build problems on Solaris 2.8 (bcopy is depreciated now anyways) Thanks to Jost Krieger and Paul Sand for reporting this problem. Changes in 1.4.4 (June 2002) - bugfix in Quota::getqcarg(): the function failed if the device id returned by stat(2) for the queried path was zero (e.g. for the root fs on NetBSD) Thanks to Jake Fan (jake@chaogic.com) for reporting this bug. Changes in 1.4.3 (May 2002) - updated for new version of Solaris VxFS (Veritas Filesystem) by David Lee (T.D.Lee@durham.ac.uk) Changes in 1.4.2 (Jan. - Mar. 2002) - fixed test.pl to allow uids with more than 5 digits. Thanks to Neil Prockter (perl@iamafreeman.com) for the fix. - updated Linux quota version detection with quota-tools 3.04; removed compile-time version detection because it caused problems; added switch LINUX_API_VERSION to hints/linux.h to allow to hard-wire the API in case the automatic version detection fails. Changes in 1.4.1 (Sep. 2001 - Jan. 2002) - added support for an older (intermediate?) version of the new Linux Quota API which contains a mixture of v1 and v2 command ids (uses the old GETSTAT id, however with the new and larger struct as argument). Required for RedHat-7.1. Thanks to Andy Choi (andy@ensim.com) for pointing this out. - enabled RPC in hints/bsd.h Confirmed to work on FreeBSD by Alex Batko (abatko@cs.mcgill.ca) - fixed several glitches in the manual page. Changes in 1.4 (August 2001) - added support for the Alan Cox (ac) branch of the Linux kernel which uses a new and completely backwards incompatible Quota API. The API version is determined dynamically by use of Q_GETSTATS/v2, i.e. the same module binary will work on kernels with either API. Since the Linux quota API now needs some very special handling, I moved it into a separate file called linuxapi.c. NOTE: internally the module still uses the old (v1) dqblk structure, so any advantages the new struct mem_dqblk might have are not present here. Let me know if this is a problem for you. - commented out #define LINUX_RQUOTAD_BUG in hints/linux.h as this should no longer be needed on most systems. Updated INSTALL and README accordingly. - removed the Linux syscall wrapper in quotactl.c as this is now in libc. - changed copyright from "none/public domain" to Artistic License (not to restrict usage, but simply to include the legal disclaimers) - fixed bug in Quota::query() and setqlim(): when argument isgrp was present but 0, the functions still did work on group quotas instead of user quotas. Thanks to Szymon Juraszczyk (szymon@ssk.pl) for pointing this out. Changes in 1.3.4 (May 2001) - added support for SGI XFS on Linux. Thanks to Brian Johnson (brian@dev.brianj.com) for providing a development account. Changes in 1.3.3 (May 2001) - bugfix Quota::query, branch NO_RPC: forgot to set error flag, arbitrary results were returned; Pointed out by Mahlon Smith - fixed declaration of GQR_* macros for RPC in hints/bsd.h RPC still untested for BSD though - fixed OpenBSD2.7 fix from last release: replaced macro OpenBSD2_7 with __OpenBSD__ because the former is not defined in 2.8 anymore. Reported by Lou Hevly (lou@visca.com) - fixed hints/linux.h for RedHat 7.1: use sys/quota.h instead of linux/quota.h because the former has an incompatible definition of struct dqblk. [NOTE: this change proved to be wrong and was undone in 1.4] Reported by Waldemar Krotkiewicz (wk@brenet.de), Andy Choi (andy@ensim.com) and Brian Johnson (brian@dev.brianj.com). Changes in 1.3.2 (February 2001) - please note my new email address: tomzo AT nefkom DOT net - fixed AFS detection in Makefile.PL for Perl 5.6 thanks to Wolfgang Friebel - adapted getmntent for incompatible change of struct statfs in OpenBSD 2.7 thanks to andrew@ugh.net.au - adapted getqcarg for for OpenBSD and BSDi: define QCARG_MNTPT for all BSD os as reported by andrew@ugh.net.au and Chee-Wai Yeung - fixed block to kB conversion in Quota::query() for VxFS as reported by Rui Monteiro - renamed config.h symlink to myconfig.h to avoid conflict with Perl config Changes in 1.3.1 (October 2000) - added support for NetBSD, merged hints for BSD-based systems by Jaromir Dolecek - fixed include file name for vxquotactl.h changed quota block factors Q_DIV/Q_MUL from 1 to 2 for Veritas fs Thanks to David Lee (T.D.Lee@durham.ac.uk) - added automatic recognition of HPUX B.11 in Makefile.PL by Albert Chin (china@thewrittenword.com) Changes in 1.3: (January 2000) - bugfix/enhanced support for OSF/1 and Digital Unix: getqcarg used wrong path to quotas file and NFS file systems were not recognized when in "/path@host" format in mtab provided by Victor Mora (Victor.Mora@ac.upc.es) and Alessandro Miotto (Alessandro.Miotto@cern.ch) - added support for FreeBSD. provided by Kurt Jaeger (pi@complx.LF.net) and Jon Schewe (schewe@tcfreenet.org) - added support for Veritas file system (VxFS) on Solaris provided by David Lee (T.D.Lee@durham.ac.uk), Michael Gerdts (gerdts@cae.wisc.edu) and Daniel Hagerty (hag@shore.net). Beta-tested by John Randell Smith (jrsmith@eng.utah.edu). - added workaround for yet another bug in Linux rpc.rquotad: rquotad reports grace times as absolute values instead of relative bug found by Seth Vidal (skvidal@phy.duke.edu) - fixed grace time output for Y2K in test.pl - fixed bug in group-quota patch as pointed out by asun@cobaltnet.com incorporated the patch into the distribution. - fixed possible integer overflow in RPC quota block size conversions for very large quota limits; pointed out by Peter.Pickford (ppickfor@jaguar.com) - added warning to Makefile.PL if config.h symlink already exists Changes in 1.2.3: (April 1999) - added patch-file "group-quota.patch" that provides optional support for group-quotas (on some OS versions and localhost only) - added auto-detection for AFS by Wolfgang Friebel - fixed include path for AFS in Quota.xs Changes in 1.2.2: (December 1998) - fixed 2 problems in getqcarg() thanks to py@ecst.csuchico.edu for pointing those out. Changes in 1.2: (November 1998) - added support for AIX 4.1 (thanks to Wolfgang Friebel (friebel@ifh.de) for providing a development account) - added support for AFS (Andrew File System) by arla-0.13 on the following platforms: AIX, SunOS, Solaris, HP-UX, IRIX 6, Linux with much help from Wolfgang Friebel. Changes in 1.1.2: (August 1998) - changed names of tar archive and module directory - fixed message for getqcarg failure in test.pl - compatibility with sfio (moved fopen and fclose to seperate file) suggested by Christoph Lupe (lupe@alanya.m.isar.de) - yet UNTESTED - fixed problems with Solaris automounter (ignore lofs mounts in getqcarg) Changes in 1.1: (August 1998) - added support for Linux (thanks to Steve Nolan (nolansj@bookmark.com) for providing a development account) - added OpenBSD 2.2 support, provided by James Shelburne (reilly@eramp.net) - added syntax fixes (2 additional #includes) for IRIX 6.4 provided by Subhendu Ghosh (sghosh@menger.eecs.stevens-tech.edu) - support for IRIX xfs filesystems (additional to the older efs fs) provided by David Lloyd (cclloyd@monotreme.cc.missouri.edu) Changes in 1.0: (That's the version that's been released with O'Reillys Perl Resource Books) - improved documentation, now provided in pod format inside Quota.pm - finally fixed errno.h problem in Quota.pm Thanks to Tobias Oetiker (oetiker@ee.ethz.ch) - added BSDI port by Jim Hribnak (hribnak@nucleus.com) unfortunately without RPC support. - small fixes for OSF/1 - more hints in hints/none.h - I've again received requests for Linux ports. However since I don't have access to an installation with quota support, I can't do this myself. I've included a config file that compiles without warnings on our system ("Red Hat for Sparc" or something), but I can't run it. If anyone gets it to work with or without RPC, please contact me. Changes in 0.3a: - started port for Linux 2.0; still needs some work. Compiles correctly, but RPC call fails. - workarounds for HP-UX/10 bug in test script (SYNC without arguments doesn't work) - some cleanup in Query.pm fixes 0.2a's problems with the autoloader under perl-5.003 Changes in 0.2a: - need generic getqcarg instead of getdev, because: - added support for Solaris, OSF/1 (which operate without access to the according block device) Required extensive code changes. - getqcarg recognizes if path points into a NFS file system - query() may take NFS path as argument (in form host:/path) Thanks to David Lee for alpha-testing on Solaris and suggesting the two latter improvements. libquota-perl-1.7.2+dfsg.orig/include/0000755000175000017500000000000012162505324016620 5ustar salvisalvilibquota-perl-1.7.2+dfsg.orig/include/vxquotactl.h0000644000175000017500000000063507044510673021215 0ustar salvisalvi#ifndef INC_VXQUOTACTL_H #define INC_VXQUOTACTL_H #include #include #include #include #include #include #include #include #include #include int vx_quotactl(int cmd, char *mntpt, uid_t uid, void *addr); #endif /* INC_VXQUOTACTL_H */ libquota-perl-1.7.2+dfsg.orig/include/rquota.h0000644000175000017500000000351510722021473020306 0ustar salvisalvi #ifndef _RQUOTA_H_RPCGEN #define _RQUOTA_H_RPCGEN #include #define RQ_PATHLEN 1024 struct getquota_args { char *gqa_pathp; int gqa_uid; }; typedef struct getquota_args getquota_args; #ifdef USE_EXT_RQUOTA struct ext_getquota_args { char *gqa_pathp; int gqa_id; int gqa_type; }; typedef struct ext_getquota_args ext_getquota_args; #endif struct rquota { int rq_bsize; bool_t rq_active; u_int rq_bhardlimit; u_int rq_bsoftlimit; u_int rq_curblocks; u_int rq_fhardlimit; u_int rq_fsoftlimit; u_int rq_curfiles; u_int rq_btimeleft; u_int rq_ftimeleft; }; typedef struct rquota rquota; enum gqr_status { Q_OK = 1, Q_NOQUOTA = 2, Q_EPERM = 3 }; typedef enum gqr_status gqr_status; struct getquota_rslt { gqr_status status; union { rquota gqr_rquota; } getquota_rslt_u; }; typedef struct getquota_rslt getquota_rslt; #define RQUOTAPROG ((unsigned long)(100011)) #define RQUOTAVERS ((unsigned long)(1)) #define RQUOTAPROC_GETQUOTA ((unsigned long)(1)) extern getquota_rslt * rquotaproc_getquota_1(getquota_args *, CLIENT *); extern getquota_rslt * rquotaproc_getquota_1_svc(getquota_args *, struct svc_req *); #define RQUOTAPROC_GETACTIVEQUOTA ((unsigned long)(2)) extern getquota_rslt * rquotaproc_getactivequota_1(getquota_args *, CLIENT *); extern getquota_rslt * rquotaproc_getactivequota_1_svc(getquota_args *, struct svc_req *); extern int rquotaprog_1_freeresult(SVCXPRT *, xdrproc_t, caddr_t); /* the xdr functions */ extern bool_t xdr_getquota_args(XDR *, getquota_args*); extern bool_t xdr_rquota(XDR *, rquota*); extern bool_t xdr_gqr_status(XDR *, gqr_status*); extern bool_t xdr_getquota_rslt(XDR *, getquota_rslt*); #ifdef USE_EXT_RQUOTA #define EXT_RQUOTAVERS ((unsigned long)(2)) extern bool_t xdr_ext_getquota_args(XDR *, ext_getquota_args*); #endif #endif /* !_RQUOTA_H_RPCGEN */ libquota-perl-1.7.2+dfsg.orig/include/quotaio_xfs.h0000644000175000017500000001626410630075260021342 0ustar salvisalvi/* * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU General Public License along * with this program; if not, write the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston MA 02111-1307, USA. * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ #ifndef _QUOTAIO_XFS_H #define _QUOTAIO_XFS_H #include #define XQM_CMD(cmd) ( ('X'<<8)+(cmd) ) #define IS_XQM_CMD(cmd) ( ((int)(cmd)>>8) == 'X' ) #define XQM_USRQUOTA 0 /* system call user quota type */ #define XQM_GRPQUOTA 1 /* system call group quota type */ #define XQM_PRJQUOTA 2 /* system call project quota type */ #define XQM_MAXQUOTAS 3 /* * Disk quota - quotactl(2) commands for XFS Quota Manager (XQM). */ #define Q_XQUOTAON XQM_CMD(0x1) /* enable quota accounting/enforcement */ #define Q_XQUOTAOFF XQM_CMD(0x2) /* disable quota accounting/enforcement */ #define Q_XGETQUOTA XQM_CMD(0x3) /* get disk limits & usage */ #define Q_XSETQLIM XQM_CMD(0x4) /* set disk limits only */ #define Q_XGETQSTAT XQM_CMD(0x5) /* returns fs_quota_stat_t struct */ #define Q_XQUOTARM XQM_CMD(0x6) /* free quota files' space */ /* * fs_disk_quota structure: * * This contains the current quota information regarding a user/proj/group. * It is 64-bit aligned, and all the blk units are in BBs (Basic Blocks) of * 512 bytes. */ #define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */ typedef struct fs_disk_quota { __s8 d_version; /* version of this structure */ __s8 d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */ __u16 d_fieldmask; /* field specifier */ __u32 d_id; /* user, project, or group ID */ __u64 d_blk_hardlimit; /* absolute limit on disk blks */ __u64 d_blk_softlimit; /* preferred limit on disk blks */ __u64 d_ino_hardlimit; /* maximum # allocated inodes */ __u64 d_ino_softlimit; /* preferred inode limit */ __u64 d_bcount; /* # disk blocks owned by the user */ __u64 d_icount; /* # inodes owned by the user */ __s32 d_itimer; /* zero if within inode limits */ /* if not, we refuse service */ __s32 d_btimer; /* similar to above; for disk blocks */ __u16 d_iwarns; /* # warnings issued wrt num inodes */ __u16 d_bwarns; /* # warnings issued wrt disk blocks */ __s32 d_padding2; /* padding2 - for future use */ __u64 d_rtb_hardlimit; /* absolute limit on realtime blks */ __u64 d_rtb_softlimit; /* preferred limit on RT disk blks */ __u64 d_rtbcount; /* # realtime blocks owned */ __s32 d_rtbtimer; /* similar to above; for RT disk blks */ __u16 d_rtbwarns; /* # warnings issued wrt RT disk blks */ __s16 d_padding3; /* padding3 - for future use */ char d_padding4[8]; /* yet more padding */ } fs_disk_quota_t; /* * These fields are sent to Q_XSETQLIM to specify fields that need to change. */ #define FS_DQ_ISOFT (1<<0) #define FS_DQ_IHARD (1<<1) #define FS_DQ_BSOFT (1<<2) #define FS_DQ_BHARD (1<<3) #define FS_DQ_RTBSOFT (1<<4) #define FS_DQ_RTBHARD (1<<5) #define FS_DQ_LIMIT_MASK (FS_DQ_ISOFT | FS_DQ_IHARD | FS_DQ_BSOFT | \ FS_DQ_BHARD | FS_DQ_RTBSOFT | FS_DQ_RTBHARD) /* * These timers can only be set in super user's dquot. For others, timers are * automatically started and stopped. Superusers timer values set the limits * for the rest. In case these values are zero, the DQ_{F,B}TIMELIMIT values * defined below are used. * These values also apply only to the d_fieldmask field for Q_XSETQLIM. */ #define FS_DQ_BTIMER (1<<6) #define FS_DQ_ITIMER (1<<7) #define FS_DQ_RTBTIMER (1<<8) #define FS_DQ_TIMER_MASK (FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER) /* * The following constants define the default amount of time given a user * before the soft limits are treated as hard limits (usually resulting * in an allocation failure). These may be modified by the quotactl(2) * system call with the Q_XSETQLIM command. */ #define DQ_FTIMELIMIT (7 * 24*60*60) /* 1 week */ #define DQ_BTIMELIMIT (7 * 24*60*60) /* 1 week */ /* * Various flags related to quotactl(2). Only relevant to XFS filesystems. */ #define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */ #define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */ #define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */ #define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */ #define XFS_USER_QUOTA (1<<0) /* user quota type */ #define XFS_PROJ_QUOTA (1<<1) /* (IRIX) project quota type */ #define XFS_GROUP_QUOTA (1<<2) /* group quota type */ /* * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system. * Provides a centralized way to get meta infomation about the quota subsystem. * eg. space taken up for user and group quotas, number of dquots currently * incore. */ #define FS_QSTAT_VERSION 1 /* fs_quota_stat.qs_version */ /* * Some basic infomation about 'quota files'. */ typedef struct fs_qfilestat { __u64 qfs_ino; /* inode number */ __u64 qfs_nblks; /* number of BBs 512-byte-blks */ __u32 qfs_nextents; /* number of extents */ } fs_qfilestat_t; typedef struct fs_quota_stat { __s8 qs_version; /* version number for future changes */ __u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */ __s8 qs_pad; /* unused */ fs_qfilestat_t qs_uquota; /* user quota storage information */ fs_qfilestat_t qs_gquota; /* group quota storage information */ __u32 qs_incoredqs; /* number of dquots incore */ __s32 qs_btimelimit; /* limit for blks timer */ __s32 qs_itimelimit; /* limit for inodes timer */ __s32 qs_rtbtimelimit; /* limit for rt blks timer */ __u16 qs_bwarnlimit; /* limit for num warnings */ __u16 qs_iwarnlimit; /* limit for num warnings */ } fs_quota_stat_t; #endif /* _QUOTAIO_XFS_H */ libquota-perl-1.7.2+dfsg.orig/include/afsquota.h0000644000175000017500000000027106625761151020625 0ustar salvisalvi/* * prototype declarations for AFS quota interface */ int afs_check(void); int afs_getquota(char *path, int *maxQuota, int *blocksUsed); int afs_setqlim(char *path, int maxQuota); libquota-perl-1.7.2+dfsg.orig/include/stdio_wrap.h0000644000175000017500000000031106572227624021153 0ustar salvisalvi/* * Access to the std I/O routines for people using sfio * stdio FILE operators are needed by getmntent(3) */ FILE *std_fopen(const char *filename, const char *mode); int std_fclose(FILE *fd); libquota-perl-1.7.2+dfsg.orig/Makefile.PL0000644000175000017500000000764712530603001017153 0ustar salvisalvi#!/usr/local/bin/perl # You shouldn't need to change anything here. # All configuration is done in the hints/ directory. #-----------------------------------------------------------------------------# # # Automagically choose the right configuration # chop($os = `uname -rs 2>/dev/null`); if ($os =~ /^SunOS 4\.1/){ $config='sunos_4_1.h'; } elsif($os =~ /^SunOS 5/) { $config='solaris_2.h'; } elsif($os =~ /^HP-UX (A\.09|B\.10|[BC]\.11)/) { $config='hpux.h'; } elsif($os =~ /^IRIX 5/) { $config='irix_5.h'; } elsif($os =~ /^IRIX\d* 6/) { $config='irix_6.h'; } elsif($os =~ /^OSF1/) { $config='dec_osf.h'; } elsif($os =~ /^Linux/) { $config='linux.h'; $picobj='linuxapi.o'; } elsif($os =~ /^AIX/) { $config='aix_4_1.h'; } elsif($os =~ /^BSD\/OS 2/ || $os =~ /^Darwin/ || $os =~ /^FreeBSD/ || $os =~ /^NetBSD/ || $os =~ /^OpenBSD/) { $config='bsd.h'; } if (defined($config)) { print "Using hints/$config for myconfig.h\n"; if (-e "myconfig.h" && (!(-l "myconfig.h") || (readlink("myconfig.h") ne "hints/$config"))) { die "\nFATAL: myconfig.h already exists.\n\n" . "You need to do a `make clean' before you configure for a new platform.\n". "If that doesn't help, remove myconfig.h manually.\n"; } } else { warn "WARNING: No appropriate hints found for this OS: '$os - see INSTALL'\n"; } my $extralibs = ""; # check whether the Andrew File System (AFS) is installed and running if ( -d "/afs" ) { my $afs = `df /afs 2>/dev/null`; if ($afs =~ /\nAFS|\(AFS/) { $hasafs = '-DAFSQUOTA'; $AFSHOME = -d "/usr/afsws" ? "/usr/afsws" : "/usr"; $extrainc = "-I$AFSHOME/include -I$AFSHOME/include/afs"; $extralibs .= " -L$AFSHOME/lib -L$AFSHOME/lib/afs -lsys -lrx -lrxkad -llwp"; $afsquota = "afsquota.o"; } } # check to see if we have a kernel module for the Veritas file system if ( $os =~ /^SunOS/ ) { if ( -f '/usr/include/sys/fs/vx_quota.h' ) { $hasvxfs = '-DSOLARIS_VXFS'; $extraobj = "$extraobj vxquotactl.o"; print "Configured with the VERITAS File System on Solaris\n"; } # no warning because newer versions of Solaris have internal VxFS support # else { # print "Configured without VxFS support\n"; # } } # check whether wee are using the NetBSD quota library if ( ($os =~ /^NetBSD 6/) || (($os =~ /^NetBSD 5\.99\.(\d\d)/) && ($1 >= 59)) ) { $extralibs .= " -lquota"; } #-----------------------------------------------------------------------------# use ExtUtils::MakeMaker; &WriteMakefile('NAME' => 'Quota', 'OBJECT' => '$(BASEEXT)$(OBJ_EXT) stdio_wrap.o '. "$afsquota $picobj $extraobj ". $hint{'OBJ'}, 'INC' => $extrainc .' '. $hint{'INC'}, 'DEFINE' => "$hasafs $hasvxfs", 'LIBS' => [ "-lrpcsvc $extralibs" ], 'H' => [ 'myconfig.h' ], 'VERSION_FROM' => 'Quota.pm', 'clean' => { FILES => 'myconfig.h' }, ); # # Add rules for hints (myconfig.h) # and extra objects that need special compiler arguments # sub MY::postamble { my $ret = ''; my $extrac; if(!defined $config) { $ret .= ' myconfig.h: @echo "You need to make a myconfig.h. See the file INSTALL."; @false ' } else { $ret .= " myconfig.h: rm -f myconfig.h ln -s hints/$config myconfig.h " } # objects that must not be compiled with the CCCDL arguments if (defined $extraobj) { ($extrac = $extraobj) =~ s/\.o(\s+|$)/.c/g; $ret .= "\n$extraobj :\n\t". '$(CC) -c $(INC) $(CCFLAGS) $(OPTIMIZE) '."$extrac\n\n"; } # extract objects from a library to link them in statically # for lame OSes that have problems with LD_PATH recording in DLOs if (defined $hint{'ARXLIBOBJ'}) { $hint{'ARXLIBOBJ'} =~ /\s+/; $ret .= "\n$' :\n\t\$(AR) x " . $hint{'ARXLIBOBJ'} ."\n\n"; } $ret; }