home *** CD-ROM | disk | FTP | other *** search
- /*
- stat.c -- an attempt to provide somewhat compatible stat functions for MPW
-
- stat & fstat return:
-
- -1 on failure and sets errno.
- 0 on success.
-
- There is no lstat or symbolic link information. Tough luck.
-
- Copyright (c) 1993 Anthony C. Ard.
-
- This program is free software; you can redistribute it and/or
- modifiy 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.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <string.h>
- #include <strings.h>
- #include <files.h>
- #include <errors.h>
- #include <errno.h>
- #include <ioctl.h>
- #include "sys_types.h"
- #include "stat.h"
-
- static int bit( unsigned long op, unsigned long bitnum );
- #define bit(op,bitnum) (int)(op >> bitnum & 0x01UL)
-
- static int GetBlockSize( StringPtr fname, long *bsize )
- {
- int err;
- HParamBlockRec myVInfo;
-
- myVInfo.volumeParam.ioNamePtr = fname;
- myVInfo.volumeParam.ioVRefNum = 0;
- myVInfo.volumeParam.ioVolIndex = -1;
-
- err = PBHGetVInfo( &myVInfo, false );
-
- *bsize = myVInfo.volumeParam.ioVAlBlkSiz;
-
- return err;
- }
-
- int stat( const char *fileName, struct stat *statPtr )
- {
- int err, file_open = 0;
- char fname[256];
- CInfoPBRec myInfo;
-
- strcpy( fname, fileName );
-
- #ifdef DEBUG
- printf( "# stat: fname = %s\n", fname );
- #endif DEBUG
-
- c2pstr( fname );
-
- myInfo.hFileInfo.ioVRefNum = 0;
- myInfo.hFileInfo.ioFDirIndex = 0;
- myInfo.hFileInfo.ioDirID = 0;
- myInfo.hFileInfo.ioNamePtr = fname;
-
- err = PBGetCatInfoSync( &myInfo );
-
- if( err == noErr ) {
-
- statPtr->st_dev = myInfo.hFileInfo.ioVRefNum;
-
- /* Set read, exec permissions */
- statPtr->st_mode = S_IREAD + S_IEXEC + S_IRUSR + S_IXUSR + S_IRGRP
- + S_IXGRP + S_IROTH + S_IXOTH;
-
- /* Check if file locked */
- if( !bit( myInfo.hFileInfo.ioFlAttrib, 0 ) )
- statPtr->st_mode += S_IWRITE + S_IWUSR + S_IWGRP + S_IWOTH;
-
- /* Check if directory*/
- if( bit( myInfo.hFileInfo.ioFlAttrib, 4 ) ) {
-
- /* Directory */
-
- statPtr->st_ino = myInfo.dirInfo.ioDrDirID;
-
- statPtr->st_mode += S_IFDIR;
-
- statPtr->st_nlink = statPtr->st_uid = statPtr->st_gid = 0;
- statPtr->st_rdev = 0;
-
- statPtr->st_size = myInfo.dirInfo.ioDrNmFls;
-
- statPtr->st_atime =
- statPtr->st_mtime =
- statPtr->st_ctime = myInfo.dirInfo.ioDrMdDat;
- statPtr->st_crtime = myInfo.dirInfo.ioDrCrDat;
- statPtr->st_bktime = myInfo.dirInfo.ioDrBkDat;
-
- err = GetBlockSize( fname, &statPtr->st_blksize );
-
- statPtr->st_blocks = 0;
-
- } else {
-
- /* Regular file */
-
- statPtr->st_ino = myInfo.hFileInfo.ioDirID;
-
- statPtr->st_mode += S_IFREG;
-
- statPtr->st_nlink = statPtr->st_uid = statPtr->st_gid = 0;
- statPtr->st_rdev = 0;
-
- statPtr->st_size = myInfo.hFileInfo.ioFlLgLen
- + myInfo.hFileInfo.ioFlRLgLen;
-
- statPtr->st_atime =
- statPtr->st_mtime =
- statPtr->st_ctime = myInfo.hFileInfo.ioFlMdDat;
- statPtr->st_crtime = myInfo.hFileInfo.ioFlCrDat;
- statPtr->st_bktime = myInfo.hFileInfo.ioFlBkDat;
-
- err = GetBlockSize( fname, &statPtr->st_blksize );
-
- if( statPtr->st_size <= statPtr->st_blksize ) statPtr->st_blocks = 2;
- else {
- statPtr->st_blocks = statPtr->st_size / statPtr->st_blksize + 1;
- if( statPtr->st_blocks * statPtr->st_blksize != statPtr->st_size )
- statPtr->st_blocks++;
- }
-
- }
- }
-
- /* Check for errors and set errno correctly */
-
- if( err == noErr ) {
- err = 0;
- errno = 0;
- } else {
- switch( err ) {
- case bdNamErr:
- errno = EINVAL;
- break;
- case dirNFErr:
- errno = ENOENT;
- break;
- case fnfErr:
- errno = ENOENT;
- break;
- case ioErr:
- errno = EIO;
- break;
- case nsvErr:
- errno = ENXIO;
- break;
- case paramErr:
- errno = EINVAL;
- break;
- }
- err = -1;
- }
-
- return err;
- }
-
-
- int fstat( int fd, struct stat *statPtr )
- {
- int err;
- char fname[256];
-
- err = ioctl( fd, FIOFNAME, (long *)fname );
- if( err == 0 ) return stat( fname, statPtr );
- else err = -1;
-
- return err;
- }
-
- #ifdef TEST
-
- #include <StdIO.h>
-
- int main( int argc, char *argv[] )
- {
- struct stat mystat;
-
- if( stat( argv[1], &mystat ) ) {
- printf( "struct stat = {\n" );
-
- printf( "\t st_ino = %d;\n", mystat.st_ino );
- printf( "\t st_mode = %d;\n", mystat.st_mode );
- printf( "\t st_nlink = %d;\n", mystat.st_nlink );
- printf( "\t st_uid = %d;\n", mystat.st_uid );
- printf( "\t st_gid = %d;\n", mystat.st_gid );
- printf( "\t st_rdev = %d;\n", mystat.st_rdev );
- printf( "\t st_size = %d;\n", mystat.st_size );
- printf( "\t st_atime = %d;\n", mystat.st_atime );
- printf( "\t st_mtime = %d;\n", mystat.st_mtime );
- printf( "\t st_ctime = %d;\n", mystat.st_ctime );
- printf( "\t st_blksize = %d;\n", mystat.st_blksize );
- printf( "\t st_blocks = %d;\n", mystat.st_blocks );
-
- printf( "};\n" );
- } else {
- printf( "### Error: stat returned : (%s)\n", strerror( errno ) );
- }
-
- return 0;
- }
-
- #endif TEST