Ignore:
Timestamp:
Dec 27, 2012, 7:39:44 PM (8 years ago)
Author:
jordan
Message:

(trunk, libT) #3833 'freespace' argument for 'session-get' RPC method -- apply taem's 0001-Check-for-available-quota-when-getting-free-disk-spa.patch​ to check for available quota when getting free disk space

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/platform.c

    r13690 r13696  
    1010 * $Id$
    1111 */
     12
     13#ifndef WIN32
     14 #include <sys/quota.h> /* quotactl */
     15 #ifdef HAVE_GETMNTENT
     16  #include <mntent.h>
     17  #include <paths.h> /* _PATH_MOUNTED */
     18 #else /* BSD derived systems */
     19  #include <sys/param.h>
     20  #include <sys/ucred.h>
     21  #include <sys/mount.h>
     22 #endif
     23#endif
    1224
    1325#ifdef WIN32
     
    701713***/
    702714
     715#ifndef WIN32
     716static char *
     717getdev( const char * path )
     718{
     719#ifdef HAVE_GETMNTENT
     720        FILE *fp;
     721        struct mntent *mnt;
     722
     723        if ((fp = setmntent(_PATH_MOUNTED, "r")) == NULL)
     724        {
     725                return NULL;
     726        }
     727        while ((mnt = getmntent(fp)) != NULL)
     728        {
     729                if (strcmp(path, mnt->mnt_dir) == 0)
     730                {
     731                        break;
     732                }
     733        }
     734        endmntent(fp);
     735        return mnt ? mnt->mnt_fsname : NULL;
     736#else /* BSD derived systems */
     737        int n, i;
     738        struct statfs *mnt;
     739
     740        if ((n = getmntinfo(&mnt, MNT_WAIT)) == 0)
     741        {
     742                return NULL;
     743        }
     744        for (i=0; i<n; i++)
     745        {
     746                if (strcmp(path, mnt[i].f_mntonname) == 0)
     747                {
     748                        break;
     749                }
     750        }
     751        return (i < n) ? mnt[i].f_mntfromname : NULL;
     752#endif
     753}
     754
     755static char *
     756getblkdev( const char * path )
     757{
     758        char *dir, *c;
     759        char *device;
     760
     761        dir = tr_strdup(path);
     762        while (1)
     763        {
     764                if ((device = getdev(dir)) != NULL)
     765                {
     766                        break;
     767                }
     768                if ((c = strrchr(dir, '/')) != NULL)
     769                {
     770                        *c = '\0';
     771                }
     772                else
     773                {
     774                        break;
     775                }
     776        }
     777        tr_free(dir);
     778        return device;
     779}
     780
     781static int64_t
     782getquota( char * device )
     783{
     784        struct dqblk dq;
     785        int64_t freespace, limit;
     786
     787        if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device, getuid(),
     788                        (caddr_t) & dq) == 0)
     789        {
     790                if (dq.dqb_bsoftlimit > 0)
     791                {
     792                        /* Use soft limit first */
     793                        limit = dq.dqb_bsoftlimit;
     794                }
     795                else if (dq.dqb_bhardlimit > 0)
     796                {
     797                        limit = dq.dqb_bhardlimit;
     798                }
     799                else
     800                {
     801                        /* No quota enabled for this user */
     802                        return -1;
     803                }
     804                freespace = limit - btodb(dq.dqb_curspace);
     805                return (freespace < 0) ? 0 : freespace * 1024;
     806        }
     807
     808        /* Something went wrong */
     809        return -1;
     810}
     811#endif
     812
     813static int64_t
     814tr_getQuotaFreeSpace( const char * path )
     815{
     816    int64_t ret=-1;
     817#ifndef WIN32
     818    char *device;
     819
     820    if ((device = getblkdev(path)) != NULL)
     821    {
     822        ret = getquota(device);
     823    }
     824#endif
     825    return ret;
     826}
     827
     828static int64_t
     829tr_getDiskFreeSpace( const char * path )
     830{
     831#ifdef WIN32
     832    uint64_t freeBytesAvailable = 0;
     833    return GetDiskFreeSpaceEx( path, &freeBytesAvailable, NULL, NULL)
     834        ? (int64_t)freeBytesAvailable
     835        : -1;
     836#elif defined(HAVE_STATVFS)
     837    struct statvfs buf;
     838    return statvfs( path, &buf ) ? -1 : (int64_t)buf.f_bavail * (int64_t)buf.f_frsize;
     839#else
     840    #warning FIXME: not implemented
     841    return -1;
     842#endif
     843}
     844
    703845int64_t
    704 tr_getFreeSpace (const char * path)
    705 {
    706 #ifdef WIN32
    707   uint64_t freeBytesAvailable = 0;
    708   return GetDiskFreeSpaceEx (path, &freeBytesAvailable, NULL, NULL)
    709     ? (int64_t)freeBytesAvailable
    710     : -1;
    711 #elif defined (HAVE_STATVFS)
    712   struct statvfs buf;
    713   return statvfs (path, &buf) ? -1 : (int64_t)buf.f_bavail * (int64_t)buf.f_frsize;
    714 #else
    715   #warning FIXME: not implemented
    716   return -1;
    717 #endif
     846tr_getFreeSpace( const char * path )
     847{
     848    int64_t i = tr_getQuotaFreeSpace( path );
     849    if( i < 0 )
     850        i = tr_getDiskFreeSpace( path );
     851    return i;
    718852}
    719853
Note: See TracChangeset for help on using the changeset viewer.