/* * This was taken from BinkD and modified a bit for hpt -- ml, 2001 * * * $Id: getfree.c,v 1.22.2.1 2002/10/23 08:13:08 stas_degteff Exp $ */ /*--------------------------------------------------------------------*/ /* Copyright (c) 1997 by Fydodor Ustinov */ /* FIDONet 2:5020/79 */ /* */ /* This program is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of */ /* the License, or (at your option) any later version. See COPYING. */ /*--------------------------------------------------------------------*/ #if defined(__NT__) || defined (NT) || defined (WINNT) #ifdef __WATCOMC__ #include #ifndef MAXPATHLEN #define MAXPATHLEN NAME_MAX #endif #elif defined (_MSC_VER) #include #ifndef MAXPATHLEN #define MAXPATHLEN _MAX_PATH #endif #endif #ifndef MAXPATHLEN #define MAXPATHLEN 255 #endif #ifdef MSG #undef MSG #endif #ifdef EXPENTRY #undef EXPENTRY #endif #include #include #include #include /* See fidoconf/log.h */ # define LL_ERROR 'A' /* Trivial error: continue */ # define LL_ERR LL_ERROR # define LL_WARN 'B' /* Warning */ extern void w_log(char key, char *logString, ...); unsigned long getfree (char *path) { char RPN[MAXPATHLEN]; // root path char *pRPN; // Pointer to Root path DWORD SPC; // sectors per cluster DWORD BPS; // bytes per sector DWORD FC; // number of free clusters DWORD TNC; // total number of clusters BOOL rc; pRPN = RPN; if (isalpha(path[0]) && path[1] == ':' ) { // Drive letter RPN[0] = path[0]; RPN[1] = ':'; RPN[2] = '\\'; RPN[3] = '\0'; } else if (path[0] == '\\' && path[1] == '\\') { // UNC path int i; RPN[0] = '\\'; RPN[1] = '\\'; i = 2; // copy server name.... do { RPN[i] = path[i]; } while (path[i++] != '\\'); // .... and share name do { RPN[i] = path[i]; } while (path[i++] != '\\'); RPN[i] = '\0'; } else { // Current Drive pRPN = NULL; } rc = GetDiskFreeSpace(pRPN,&SPC,&BPS,&FC,&TNC); if (rc != TRUE) { w_log (LL_ERR, "GetDiskFreeSpace error: return code = %lu", GetLastError()); return ULONG_MAX; /* Assume enough disk space */ } else { //return (unsigned long) (BPS * SPC * FC); if (BPS * SPC >= 1024) return (unsigned long) ((BPS * SPC / 1024l) * FC); else return (unsigned long) (FC / (1024 / (BPS * SPC))); } } #elif defined(__OS2__) || defined(OS2) #ifdef __WATCOMC__ #define __IBMC__ 0 #define __IBMCPP__ 0 #endif #define INCL_DOS #include #include #include #include unsigned long getfree (char *path) { FSALLOCATE fsa; ULONG disknum = 0; APIRET rc; if (isalpha (path[0]) && path[1] == ':') disknum = toupper (path[0]) - 'A' + 1; rc = DosQueryFSInfo (disknum, /* Drive number */ FSIL_ALLOC, /* Level 1 allocation info */ (PVOID) & fsa, /* Buffer */ sizeof (fsa)); /* Size of buffer */ if (rc) { w_log (LL_ERR, "DosQueryFSInfo error: return code = %u", rc); return ULONG_MAX; /* Assume enough disk space */ } else { //return fsa.cSectorUnit * fsa.cUnitAvail * fsa.cbSector; if (fsa.cSectorUnit * fsa.cbSector >= 1024) return fsa.cUnitAvail * (fsa.cSectorUnit * fsa.cbSector / 1024); else return fsa.cUnitAvail / (1024 / (fsa.cSectorUnit * fsa.cbSector)); } } #elif defined(UNIX) || defined (__linux__) /* This was taken from ifmail, and modified a bit for binkd -- mff, 1997 Copyright (c) 1993-1995 Eugene G. Crosser ifcico is a FidoNet(r) compatible mailer for U*IX platforms. You may do virtually what you wish with this software, as long as the explicit reference to its original author is retained: Eugene G. Crosser , 2:5020/230@FidoNet THIS SOFTWARE IS PROVIDED AS IS AND COME WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. IN NO EVENT WILL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE. */ #include /* TE: test for FreeBSD, NetBSD, OpenBSD or any other BSD 4.4 - derived OS */ #if (defined(__unix__) || defined(unix)) && !defined(USG) #include #endif #if (defined(BSD) && (BSD >= 199103)) /* now we can be sure we are on BSD 4.4 */ #include /* fake the following code to think we had a sys/statfs.h so it uses the proper code segments */ #ifndef _SYS_STATFS_H #define _SYS_STATFS_H #endif #else /* we are not on any BSD-like OS */ /* list other UNIX os'es without getfree mechanism here */ #if defined( __svr4__ ) || defined( __SVR4 ) || defined (__linux__) && defined (__GLIBC__) #include #ifndef _SYS_STATVFS_H #define _SYS_STATVFS_H #elif !defined (__BEOS__) #include #endif /* BEOS */ #endif /* svr4 or linux */ #if defined (__linux__) && !defined(__GLIBC__) #include #ifndef _SYS_STATFS_H #define _SYS_STATFS_H #endif /* _SYS_STATFS_H */ #endif /* linux &! GLIBC */ #include #endif /* not BSD-like OS */ /* #if !(defined(_SYS_STATFS_H) || defined(_SYS_STATVFS_H)) #error no statfs() or statvfs() in your system! #endif */ #include #if defined(_SYS_STATFS_H) || defined(_SYS_STATVFS_H) unsigned long getfree (char *path) { #ifdef _SYS_STATVFS_H struct statvfs sfs; if (statvfs (path, &sfs) != 0) #else struct statfs sfs; if (statfs (path, &sfs) != 0) #endif { w_log (LL_ERR, "cannot statfs \"%s\", assume enough space", path); return ULONG_MAX; } else { /* return (sfs.f_bsize * sfs.f_bfree); */ //return (sfs.f_bsize * sfs.f_bavail); if (sfs.f_bsize >= 1024) return ((sfs.f_bsize / 1024l) * sfs.f_bavail); else return (sfs.f_bavail / (1024l / sfs.f_bsize)); } } #else unsigned long getfree (char *path) { w_log (LL_WARN, "warning: free space doesn't checked in %s",path); return ULONG_MAX; } #endif #elif defined(MSDOS) #include #include unsigned long getfree (char *path) { w_log (LL_WARN, "warning: free space doesn't checked in %s",path); return ULONG_MAX; } #else #error "unknown system!" #endif