home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / MPW / gzip 1.2.2 / cextras-1.0 / stat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-11  |  5.2 KB  |  222 lines  |  [TEXT/MPS ]

  1. /*
  2.     stat.c -- an attempt to provide somewhat compatible stat functions for MPW
  3.     
  4.     stat & fstat return:
  5.         
  6.         -1 on failure and sets errno.
  7.         0 on success.
  8.  
  9.     There is no lstat or symbolic link information. Tough luck.
  10.     
  11.     Copyright (c) 1993 Anthony C. Ard.
  12.  
  13.     This program is free software; you can redistribute it and/or
  14.     modifiy it under the terms of the GNU General Public License
  15.     as published by the Free Software Foundation; either version 2
  16.     of the License, or (at your option) any later version.
  17.     
  18.     This program is distributed in the hope that it will be useful,
  19.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21.     GNU General Public License for more details.
  22.     
  23.     You should have received a copy of the GNU General Public License
  24.     along with this program; if not, write to the Free Software
  25.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26. */
  27.  
  28. #include <string.h>
  29. #include <strings.h>
  30. #include <files.h>
  31. #include <errors.h>
  32. #include <errno.h>
  33. #include <ioctl.h>
  34. #include "sys_types.h"
  35. #include "stat.h"
  36.  
  37. static int bit( unsigned long op, unsigned long bitnum );
  38. #define bit(op,bitnum) (int)(op >> bitnum & 0x01UL)
  39.  
  40. static int GetBlockSize( StringPtr fname, long *bsize )
  41. {
  42.     int err;
  43.     HParamBlockRec myVInfo;
  44.  
  45.     myVInfo.volumeParam.ioNamePtr = fname;
  46.     myVInfo.volumeParam.ioVRefNum = 0;
  47.     myVInfo.volumeParam.ioVolIndex = -1;
  48.     
  49.     err = PBHGetVInfo( &myVInfo, false );
  50.     
  51.     *bsize = myVInfo.volumeParam.ioVAlBlkSiz;
  52.     
  53.     return err;
  54. }
  55.  
  56. int stat( const char *fileName, struct stat *statPtr )
  57. {
  58.     int err, file_open = 0;
  59.     char fname[256];
  60.     CInfoPBRec myInfo;
  61.     
  62.     strcpy( fname, fileName );
  63.     
  64. #ifdef DEBUG
  65.     printf( "# stat: fname = %s\n", fname );
  66. #endif DEBUG
  67.  
  68.     c2pstr( fname );
  69.  
  70.     myInfo.hFileInfo.ioVRefNum = 0;
  71.     myInfo.hFileInfo.ioFDirIndex = 0;
  72.     myInfo.hFileInfo.ioDirID = 0;
  73.     myInfo.hFileInfo.ioNamePtr = fname;
  74.  
  75.     err = PBGetCatInfoSync( &myInfo );
  76.  
  77.     if( err == noErr ) {
  78.  
  79.         statPtr->st_dev = myInfo.hFileInfo.ioVRefNum;
  80.  
  81.         /* Set read, exec permissions */
  82.         statPtr->st_mode = S_IREAD + S_IEXEC + S_IRUSR + S_IXUSR + S_IRGRP
  83.                             + S_IXGRP + S_IROTH + S_IXOTH;
  84.     
  85.         /* Check if file locked */
  86.         if( !bit( myInfo.hFileInfo.ioFlAttrib, 0 ) )
  87.             statPtr->st_mode +=  S_IWRITE + S_IWUSR + S_IWGRP + S_IWOTH;
  88.         
  89.         /* Check if directory*/    
  90.         if( bit( myInfo.hFileInfo.ioFlAttrib, 4 ) ) {
  91.         
  92.             /* Directory */
  93.             
  94.             statPtr->st_ino = myInfo.dirInfo.ioDrDirID;
  95.  
  96.             statPtr->st_mode += S_IFDIR;
  97.  
  98.             statPtr->st_nlink = statPtr->st_uid = statPtr->st_gid = 0;
  99.             statPtr->st_rdev = 0;
  100.             
  101.             statPtr->st_size = myInfo.dirInfo.ioDrNmFls;
  102.  
  103.             statPtr->st_atime =
  104.                 statPtr->st_mtime = 
  105.                     statPtr->st_ctime = myInfo.dirInfo.ioDrMdDat;
  106.             statPtr->st_crtime = myInfo.dirInfo.ioDrCrDat;
  107.             statPtr->st_bktime = myInfo.dirInfo.ioDrBkDat;
  108.  
  109.             err = GetBlockSize( fname, &statPtr->st_blksize );
  110.  
  111.             statPtr->st_blocks = 0;
  112.             
  113.         } else {
  114.         
  115.             /* Regular file */
  116.             
  117.             statPtr->st_ino = myInfo.hFileInfo.ioDirID;
  118.  
  119.             statPtr->st_mode += S_IFREG;
  120.         
  121.             statPtr->st_nlink = statPtr->st_uid = statPtr->st_gid = 0;
  122.             statPtr->st_rdev = 0;
  123.             
  124.             statPtr->st_size = myInfo.hFileInfo.ioFlLgLen
  125.                                + myInfo.hFileInfo.ioFlRLgLen;
  126.             
  127.             statPtr->st_atime =
  128.                 statPtr->st_mtime = 
  129.                     statPtr->st_ctime = myInfo.hFileInfo.ioFlMdDat;
  130.             statPtr->st_crtime = myInfo.hFileInfo.ioFlCrDat;
  131.             statPtr->st_bktime = myInfo.hFileInfo.ioFlBkDat;
  132.  
  133.             err = GetBlockSize( fname, &statPtr->st_blksize );
  134.  
  135.             if( statPtr->st_size <= statPtr->st_blksize ) statPtr->st_blocks = 2;
  136.             else {
  137.                 statPtr->st_blocks = statPtr->st_size / statPtr->st_blksize + 1;
  138.                 if( statPtr->st_blocks * statPtr->st_blksize != statPtr->st_size )
  139.                     statPtr->st_blocks++;
  140.             }
  141.         
  142.         }
  143.     }
  144.  
  145.     /* Check for errors and set errno correctly */
  146.     
  147.     if( err == noErr ) {
  148.         err = 0;
  149.         errno = 0;
  150.     } else {
  151.         switch( err ) {
  152.             case bdNamErr:
  153.                 errno = EINVAL;
  154.                 break;
  155.             case dirNFErr:
  156.                 errno = ENOENT;
  157.                 break;
  158.             case fnfErr:
  159.                 errno = ENOENT;
  160.                 break;
  161.             case ioErr:
  162.                 errno = EIO;
  163.                 break;
  164.             case nsvErr:
  165.                 errno = ENXIO;
  166.                 break;
  167.             case paramErr:
  168.                 errno = EINVAL;
  169.                 break;
  170.         }
  171.         err = -1;
  172.     }
  173.     
  174.     return err;
  175. }
  176.  
  177.  
  178. int fstat( int fd, struct stat *statPtr )
  179. {
  180.     int err;
  181.     char fname[256];
  182.     
  183.     err = ioctl( fd, FIOFNAME, (long *)fname );
  184.     if( err == 0 ) return stat( fname, statPtr );
  185.     else err = -1;
  186.     
  187.     return err;
  188. }
  189.  
  190. #ifdef TEST
  191.  
  192. #include <StdIO.h>
  193.  
  194. int main( int argc, char *argv[] )
  195. {
  196.     struct stat mystat;
  197.     
  198.     if( stat( argv[1], &mystat ) ) {
  199.         printf( "struct stat = {\n" );
  200.     
  201.         printf( "\t st_ino = %d;\n", mystat.st_ino );
  202.         printf( "\t st_mode = %d;\n", mystat.st_mode );
  203.         printf( "\t st_nlink = %d;\n", mystat.st_nlink );
  204.         printf( "\t st_uid = %d;\n", mystat.st_uid );
  205.         printf( "\t st_gid = %d;\n", mystat.st_gid );
  206.         printf( "\t st_rdev = %d;\n", mystat.st_rdev );
  207.         printf( "\t st_size = %d;\n", mystat.st_size );
  208.         printf( "\t st_atime = %d;\n", mystat.st_atime );
  209.         printf( "\t st_mtime = %d;\n", mystat.st_mtime );
  210.         printf( "\t st_ctime = %d;\n", mystat.st_ctime );
  211.         printf( "\t st_blksize = %d;\n", mystat.st_blksize );
  212.         printf( "\t st_blocks = %d;\n", mystat.st_blocks );
  213.     
  214.         printf( "};\n" );
  215.     } else {
  216.         printf( "### Error: stat returned : (%s)\n", strerror( errno ) );
  217.     }
  218.     
  219.     return 0;
  220. }
  221.  
  222. #endif TEST