From 5024dbfd2221a86ef0ac27599c7f66a1600198d0 Mon Sep 17 00:00:00 2001 From: Jordan Lee Date: Thu, 27 Dec 2012 19:39:44 +0000 Subject: [PATCH] =?UTF-8?q?(trunk,=20libT)=20#3833=20'freespace'=20argumen?= =?UTF-8?q?t=20for=20'session-get'=20RPC=20method=20--=20apply=20taem's=20?= =?UTF-8?q?=200001-Check-for-available-quota-when-getting-free-disk-spa.pa?= =?UTF-8?q?tch=E2=80=8B=20to=20check=20for=20available=20quota=20when=20ge?= =?UTF-8?q?tting=20free=20disk=20space?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- configure.ac | 1 + libtransmission/platform.c | 156 ++++++++++++++++++++++++++++++++++--- libtransmission/platform.h | 3 +- 3 files changed, 148 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 6ccc65b1c..1c514f5c4 100644 --- a/configure.ac +++ b/configure.ac @@ -125,6 +125,7 @@ AC_PATH_ZLIB AC_SYS_LARGEFILE AC_CHECK_FUNCS([lseek64]) +AC_FUNC_GETMNTENT dnl ---------------------------------------------------------------------------- dnl diff --git a/libtransmission/platform.c b/libtransmission/platform.c index 00ad0d375..3548792c9 100644 --- a/libtransmission/platform.c +++ b/libtransmission/platform.c @@ -10,6 +10,18 @@ * $Id$ */ +#ifndef WIN32 + #include /* quotactl */ + #ifdef HAVE_GETMNTENT + #include + #include /* _PATH_MOUNTED */ + #else /* BSD derived systems */ + #include + #include + #include + #endif +#endif + #ifdef WIN32 #include #define WINVER WindowsXP @@ -700,23 +712,145 @@ tr_getWebClientDir (const tr_session * session UNUSED) **** ***/ -int64_t -tr_getFreeSpace (const char * path) +#ifndef WIN32 +static char * +getdev( const char * path ) +{ +#ifdef HAVE_GETMNTENT + FILE *fp; + struct mntent *mnt; + + if ((fp = setmntent(_PATH_MOUNTED, "r")) == NULL) + { + return NULL; + } + while ((mnt = getmntent(fp)) != NULL) + { + if (strcmp(path, mnt->mnt_dir) == 0) + { + break; + } + } + endmntent(fp); + return mnt ? mnt->mnt_fsname : NULL; +#else /* BSD derived systems */ + int n, i; + struct statfs *mnt; + + if ((n = getmntinfo(&mnt, MNT_WAIT)) == 0) + { + return NULL; + } + for (i=0; i 0) + { + /* Use soft limit first */ + limit = dq.dqb_bsoftlimit; + } + else if (dq.dqb_bhardlimit > 0) + { + limit = dq.dqb_bhardlimit; + } + else + { + /* No quota enabled for this user */ + return -1; + } + freespace = limit - btodb(dq.dqb_curspace); + return (freespace < 0) ? 0 : freespace * 1024; + } + + /* Something went wrong */ + return -1; +} +#endif + +static int64_t +tr_getQuotaFreeSpace( const char * path ) +{ + int64_t ret=-1; +#ifndef WIN32 + char *device; + + if ((device = getblkdev(path)) != NULL) + { + ret = getquota(device); + } +#endif + return ret; +} + +static int64_t +tr_getDiskFreeSpace( const char * path ) { #ifdef WIN32 - uint64_t freeBytesAvailable = 0; - return GetDiskFreeSpaceEx (path, &freeBytesAvailable, NULL, NULL) - ? (int64_t)freeBytesAvailable - : -1; -#elif defined (HAVE_STATVFS) - struct statvfs buf; - return statvfs (path, &buf) ? -1 : (int64_t)buf.f_bavail * (int64_t)buf.f_frsize; + uint64_t freeBytesAvailable = 0; + return GetDiskFreeSpaceEx( path, &freeBytesAvailable, NULL, NULL) + ? (int64_t)freeBytesAvailable + : -1; +#elif defined(HAVE_STATVFS) + struct statvfs buf; + return statvfs( path, &buf ) ? -1 : (int64_t)buf.f_bavail * (int64_t)buf.f_frsize; #else - #warning FIXME: not implemented - return -1; + #warning FIXME: not implemented + return -1; #endif } +int64_t +tr_getFreeSpace( const char * path ) +{ + int64_t i = tr_getQuotaFreeSpace( path ); + if( i < 0 ) + i = tr_getDiskFreeSpace( path ); + return i; +} + /*** **** ***/ diff --git a/libtransmission/platform.h b/libtransmission/platform.h index 9e0e26834..7a55dd23d 100644 --- a/libtransmission/platform.h +++ b/libtransmission/platform.h @@ -42,7 +42,8 @@ const char * tr_getTorrentDir (const tr_session *); /** @brief return the directory where the Web Client's web ui files are kept */ const char * tr_getWebClientDir (const tr_session *); -/** @brief return the number of bytes available for use in the specified path, or -1 on error */ +/** If the disk quota is enabled and readable, this returns how much is available in the quota. + Otherwise, it returns how much is available on the disk, or -1 on error. */ int64_t tr_getFreeSpace (const char * path);