Annotation of uae/src/fsusage.c, revision 1.1.1.4

1.1       root        1: /* fsusage.c -- return space usage of mounted filesystems
                      2:    Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc.
                      3: 
                      4:    This program is free software; you can redistribute it and/or modify
                      5:    it under the terms of the GNU General Public License as published by
                      6:    the Free Software Foundation; either version 2, or (at your option)
                      7:    any later version.
                      8: 
                      9:    This program is distributed in the hope that it will be useful,
                     10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12:    GNU General Public License for more details.
                     13: 
                     14:    You should have received a copy of the GNU General Public License
                     15:    along with this program; if not, write to the Free Software Foundation,
                     16:    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
                     17: 
                     18: #include "sysconfig.h"
                     19: 
1.1.1.2   root       20: #include <stdlib.h>
1.1       root       21: #include <sys/types.h>
                     22: 
                     23: #ifdef HAVE_SYS_STAT_H
                     24: #include <sys/stat.h>
                     25: #endif
                     26: 
                     27: #include "fsusage.h"
                     28: 
                     29: /* Return the number of TOSIZE-byte blocks used by
                     30:    BLOCKS FROMSIZE-byte blocks, rounding away from zero.
                     31:    TOSIZE must be positive.  Return -1 if FROMSIZE is not positive.  */
                     32: 
                     33: static long
                     34: adjust_blocks (blocks, fromsize, tosize)
                     35:      long blocks;
                     36:      int fromsize, tosize;
                     37: {
                     38:   if (tosize <= 0)
                     39:     abort ();
                     40:   if (fromsize <= 0)
                     41:     return -1;
                     42: 
                     43:   if (fromsize == tosize)      /* e.g., from 512 to 512 */
                     44:     return blocks;
                     45:   else if (fromsize > tosize)  /* e.g., from 2048 to 512 */
                     46:     return blocks * (fromsize / tosize);
                     47:   else                         /* e.g., from 256 to 512 */
                     48:     return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize);
                     49: }
                     50: 
                     51: #ifdef _WIN32
1.1.1.2   root       52: #include "sysdeps.h"
1.1.1.3   root       53: #include <windows.h>
1.1       root       54: int
                     55: get_fs_usage (path, disk, fsp)
                     56:      const char *path;
                     57:      const char *disk;
                     58:      struct fs_usage *fsp;
                     59: {
                     60:     char buf1[1024];
                     61:     char buf2[1024];
                     62:     DWORD SectorsPerCluster;
                     63:     DWORD BytesPerSector;
                     64:     DWORD NumberOfFreeClusters;
                     65:     DWORD TotalNumberOfClusters;
                     66: 
                     67:     fname_atow (path, buf1, sizeof buf1);
                     68: 
                     69:     GetFullPathName (buf1, sizeof buf2, buf2, NULL);
                     70: 
                     71:     buf2[3] = 0;
                     72: 
                     73:     if (!GetDiskFreeSpace (buf2, &SectorsPerCluster, &BytesPerSector,
                     74:                           &NumberOfFreeClusters, &TotalNumberOfClusters))
                     75:     {
                     76:        /* lasterror = GetLastError ();*/
                     77:        return -1;
                     78:     }
1.1.1.2   root       79: 
                     80:     /* HACK ALERT! WinNT returns 0 in TotalNumberOfClusters for an audio-CD, which calls the GURU! */
1.1.1.4 ! root       81:     if( ( TotalNumberOfClusters == 0 ) &&
        !            82:        ( GetDriveType( buf2 ) == DRIVE_CDROM ) )
1.1.1.2   root       83:     {
1.1.1.4 ! root       84:        TotalNumberOfClusters = 327680;
1.1.1.2   root       85:     }
                     86: 
1.1       root       87:     BytesPerSector *= SectorsPerCluster;
                     88:     fsp->fsu_blocks = adjust_blocks (TotalNumberOfClusters, BytesPerSector, 512);
                     89:     fsp->fsu_bavail = adjust_blocks (NumberOfFreeClusters, BytesPerSector, 512);
                     90: 
                     91:     return 0;
                     92: }
                     93: 
                     94: #else /* ! _WIN32 */
                     95: 
                     96: int statfs ();
                     97: 
                     98: #if HAVE_UNISTD_H
                     99: # include <unistd.h>
                    100: #endif
                    101: 
                    102: #if HAVE_SYS_PARAM_H
                    103: # include <sys/param.h>
                    104: #endif
                    105: 
                    106: #if HAVE_SYS_MOUNT_H
                    107: # include <sys/mount.h>
                    108: #endif
                    109: 
                    110: #if HAVE_SYS_VFS_H
                    111: # include <sys/vfs.h>
                    112: #endif
                    113: 
                    114: #if HAVE_SYS_FS_S5PARAM_H      /* Fujitsu UXP/V */
                    115: # include <sys/fs/s5param.h>
                    116: #endif
                    117: 
                    118: #if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY)
                    119: # include <sys/filsys.h>       /* SVR2 */
                    120: #endif
                    121: 
                    122: #if HAVE_FCNTL_H
                    123: # include <fcntl.h>
                    124: #endif
                    125: 
                    126: #if HAVE_SYS_STATFS_H
                    127: # include <sys/statfs.h>
                    128: #endif
                    129: 
                    130: #if HAVE_DUSTAT_H              /* AIX PS/2 */
                    131: # include <sys/dustat.h>
                    132: #endif
                    133: 
                    134: #if HAVE_SYS_STATVFS_H         /* SVR4 */
                    135: # include <sys/statvfs.h>
                    136: int statvfs ();
                    137: #endif
                    138: 
                    139: /* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
                    140:    Return the actual number of bytes read, zero for EOF, or negative
                    141:    for an error.  */
                    142: 
                    143: int
                    144: safe_read (desc, ptr, len)
                    145:      int desc;
                    146:      char *ptr;
                    147:      int len;
                    148: {
                    149:   int n_chars;
                    150: 
                    151:   if (len <= 0)
                    152:     return len;
                    153: 
                    154: #ifdef EINTR
                    155:   do
                    156:     {
                    157:       n_chars = read (desc, ptr, len);
                    158:     }
                    159:   while (n_chars < 0 && errno == EINTR);
                    160: #else
                    161:   n_chars = read (desc, ptr, len);
                    162: #endif
                    163: 
                    164:   return n_chars;
                    165: }
                    166: 
                    167: /* Fill in the fields of FSP with information about space usage for
                    168:    the filesystem on which PATH resides.
                    169:    DISK is the device on which PATH is mounted, for space-getting
                    170:    methods that need to know it.
                    171:    Return 0 if successful, -1 if not.  When returning -1, ensure that
                    172:    ERRNO is either a system error value, or zero if DISK is NULL
                    173:    on a system that requires a non-NULL value.  */
                    174: int
                    175: get_fs_usage (path, disk, fsp)
                    176:      const char *path;
                    177:      const char *disk;
                    178:      struct fs_usage *fsp;
                    179: {
                    180: #ifdef STAT_STATFS3_OSF1
                    181: # define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_fsize, 512)
                    182: 
                    183:   struct statfs fsd;
                    184: 
                    185:   if (statfs (path, &fsd, sizeof (struct statfs)) != 0)
                    186:     return -1;
                    187: 
                    188: #endif /* STAT_STATFS3_OSF1 */
                    189: 
                    190: #ifdef STAT_STATFS2_FS_DATA    /* Ultrix */
                    191: # define CONVERT_BLOCKS(B) adjust_blocks ((B), 1024, 512)
                    192: 
                    193:   struct fs_data fsd;
                    194: 
                    195:   if (statfs (path, &fsd) != 1)
                    196:     return -1;
                    197:   fsp->fsu_blocks = CONVERT_BLOCKS (fsd.fd_req.btot);
                    198:   fsp->fsu_bfree = CONVERT_BLOCKS (fsd.fd_req.bfree);
                    199:   fsp->fsu_bavail = CONVERT_BLOCKS (fsd.fd_req.bfreen);
                    200:   fsp->fsu_files = fsd.fd_req.gtot;
                    201:   fsp->fsu_ffree = fsd.fd_req.gfree;
                    202: 
                    203: #endif /* STAT_STATFS2_FS_DATA */
                    204: 
                    205: #ifdef STAT_READ_FILSYS                /* SVR2 */
                    206: # ifndef SUPERBOFF
                    207: #  define SUPERBOFF (SUPERB * 512)
                    208: # endif
                    209: # define CONVERT_BLOCKS(B) \
                    210:     adjust_blocks ((B), (fsd.s_type == Fs2b ? 1024 : 512), 512)
                    211: 
                    212:   struct filsys fsd;
                    213:   int fd;
                    214: 
                    215:   if (! disk)
                    216:     {
                    217:       errno = 0;
                    218:       return -1;
                    219:     }
                    220: 
                    221:   fd = open (disk, O_RDONLY);
                    222:   if (fd < 0)
                    223:     return -1;
                    224:   lseek (fd, (long) SUPERBOFF, 0);
                    225:   if (safe_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd)
                    226:     {
                    227:       close (fd);
                    228:       return -1;
                    229:     }
                    230:   close (fd);
                    231:   fsp->fsu_blocks = CONVERT_BLOCKS (fsd.s_fsize);
                    232:   fsp->fsu_bfree = CONVERT_BLOCKS (fsd.s_tfree);
                    233:   fsp->fsu_bavail = CONVERT_BLOCKS (fsd.s_tfree);
                    234:   fsp->fsu_files = (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1);
                    235:   fsp->fsu_ffree = fsd.s_tinode;
                    236: 
                    237: #endif /* STAT_READ_FILSYS */
                    238: 
                    239: #ifdef STAT_STATFS2_BSIZE      /* 4.3BSD, SunOS 4, HP-UX, AIX */
                    240: # define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_bsize, 512)
                    241: 
                    242:   struct statfs fsd;
                    243: 
                    244:   if (statfs (path, &fsd) < 0)
                    245:     return -1;
                    246: 
                    247: # ifdef STATFS_TRUNCATES_BLOCK_COUNTS
                    248: 
                    249:   /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
                    250:      struct statfs are truncated to 2GB.  These conditions detect that
                    251:      truncation, presumably without botching the 4.1.1 case, in which
                    252:      the values are not truncated.  The correct counts are stored in
                    253:      undocumented spare fields.  */
                    254:   if (fsd.f_blocks == 0x1fffff && fsd.f_spare[0] > 0)
                    255:     {
                    256:       fsd.f_blocks = fsd.f_spare[0];
                    257:       fsd.f_bfree = fsd.f_spare[1];
                    258:       fsd.f_bavail = fsd.f_spare[2];
                    259:     }
                    260: # endif /* STATFS_TRUNCATES_BLOCK_COUNTS */
                    261: 
                    262: #endif /* STAT_STATFS2_BSIZE */
                    263: 
                    264: #ifdef STAT_STATFS2_FSIZE      /* 4.4BSD */
                    265: # define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_fsize, 512)
                    266: 
                    267:   struct statfs fsd;
                    268: 
                    269:   if (statfs (path, &fsd) < 0)
                    270:     return -1;
                    271: 
                    272: #endif /* STAT_STATFS2_FSIZE */
                    273: 
                    274: #ifdef STAT_STATFS4            /* SVR3, Dynix, Irix, AIX */
                    275: # if _AIX || defined(_CRAY)
                    276: #  define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_bsize, 512)
                    277: #  ifdef _CRAY
                    278: #   define f_bavail f_bfree
                    279: #  endif
                    280: # else
                    281: #  define CONVERT_BLOCKS(B) (B)
                    282: #  ifndef _SEQUENT_            /* _SEQUENT_ is DYNIX/ptx */
                    283: #   ifndef DOLPHIN             /* DOLPHIN 3.8.alfa/7.18 has f_bavail */
                    284: #    define f_bavail f_bfree
                    285: #   endif
                    286: #  endif
                    287: # endif
                    288: 
                    289:   struct statfs fsd;
                    290: 
                    291:   if (statfs (path, &fsd, sizeof fsd, 0) < 0)
                    292:     return -1;
                    293:   /* Empirically, the block counts on most SVR3 and SVR3-derived
                    294:      systems seem to always be in terms of 512-byte blocks,
                    295:      no matter what value f_bsize has.  */
                    296: 
                    297: #endif /* STAT_STATFS4 */
                    298: 
                    299: #ifdef STAT_STATVFS            /* SVR4 */
                    300: # define CONVERT_BLOCKS(B) \
                    301:     adjust_blocks ((B), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512)
                    302: 
                    303:   struct statvfs fsd;
                    304: 
                    305:   if (statvfs (path, &fsd) < 0)
                    306:     return -1;
                    307:   /* f_frsize isn't guaranteed to be supported.  */
                    308: 
                    309: #endif /* STAT_STATVFS */
                    310: 
                    311: #if !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ_FILSYS)
                    312:                                /* !Ultrix && !SVR2 */
                    313: 
                    314:   fsp->fsu_blocks = CONVERT_BLOCKS (fsd.f_blocks);
                    315:   fsp->fsu_bfree = CONVERT_BLOCKS (fsd.f_bfree);
                    316:   fsp->fsu_bavail = CONVERT_BLOCKS (fsd.f_bavail);
                    317:   fsp->fsu_files = fsd.f_files;
                    318:   fsp->fsu_ffree = fsd.f_ffree;
                    319: 
                    320: #endif /* not STAT_STATFS2_FS_DATA && not STAT_READ_FILSYS */
                    321: 
                    322:   return 0;
                    323: }
                    324: 
                    325: #if defined(_AIX) && defined(_I386)
                    326: /* AIX PS/2 does not supply statfs.  */
                    327: 
                    328: int
                    329: statfs (path, fsb)
                    330:      char *path;
                    331:      struct statfs *fsb;
                    332: {
                    333:   struct stat stats;
                    334:   struct dustat fsd;
                    335: 
                    336:   if (stat (path, &stats))
                    337:     return -1;
                    338:   if (dustat (stats.st_dev, 0, &fsd, sizeof (fsd)))
                    339:     return -1;
                    340:   fsb->f_type   = 0;
                    341:   fsb->f_bsize  = fsd.du_bsize;
                    342:   fsb->f_blocks = fsd.du_fsize - fsd.du_isize;
                    343:   fsb->f_bfree  = fsd.du_tfree;
                    344:   fsb->f_bavail = fsd.du_tfree;
                    345:   fsb->f_files  = (fsd.du_isize - 2) * fsd.du_inopb;
                    346:   fsb->f_ffree  = fsd.du_tinode;
                    347:   fsb->f_fsid.val[0] = fsd.du_site;
                    348:   fsb->f_fsid.val[1] = fsd.du_pckno;
                    349:   return 0;
                    350: }
                    351: 
                    352: #endif /* _AIX && _I386 */
                    353: 
                    354: #endif /* ! _WIN32 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.