home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnuc / library / rcs / stat.c,v < prev    next >
Encoding:
Text File  |  1992-07-04  |  6.1 KB  |  239 lines

  1. head    1.1;
  2. access;
  3. symbols
  4.     version39-41:1.1;
  5. locks;
  6. comment    @ *  @;
  7.  
  8.  
  9. 1.1
  10. date    92.05.14.19.55.40;    author mwild;    state Exp;
  11. branches;
  12. next    ;
  13.  
  14.  
  15. desc
  16. @obtain information for a given path
  17. @
  18.  
  19.  
  20. 1.1
  21. log
  22. @Initial revision
  23. @
  24. text
  25. @/*
  26.  *  This file is part of ixemul.library for the Amiga.
  27.  *  Copyright (C) 1991, 1992  Markus M. Wild
  28.  *
  29.  *  This library is free software; you can redistribute it and/or
  30.  *  modify it under the terms of the GNU Library General Public
  31.  *  License as published by the Free Software Foundation; either
  32.  *  version 2 of the License, or (at your option) any later version.
  33.  *
  34.  *  This library is distributed in the hope that it will be useful,
  35.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  36.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  37.  *  Library General Public License for more details.
  38.  *
  39.  *  You should have received a copy of the GNU Library General Public
  40.  *  License along with this library; if not, write to the Free
  41.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  42.  *
  43.  *  $Id$
  44.  *
  45.  *  $Log$
  46.  */
  47.  
  48. #define KERNEL
  49. #include "ixemul.h"
  50.  
  51. #undef DEBUG
  52.  
  53. #ifdef DEBUG
  54. #define DP(a) kprintf a
  55. #else
  56. #define DP(a)
  57. #endif
  58.  
  59. #if __GNUC__ != 2
  60. #define alloca __builtin_alloca
  61. #endif
  62.  
  63. #ifndef ST_ROOT
  64. #define ST_ROOT        1
  65. #define ST_USERDIR     2
  66. #define ST_SOFTLINK    3
  67. #define ST_LINKDIR    4
  68. #define ST_FILE        -3
  69. #define ST_LINKFILE    -4
  70. #endif
  71.  
  72. #ifndef ERROR_IS_SOFT_LINK
  73. #define ERROR_IS_SOFT_LINK  233
  74. #endif
  75.  
  76. /* currently, links are quite buggy.. hope this get cleaned up RSN ;-) */
  77.  
  78. extern BPTR __lock (), __llock ();
  79.  
  80. static int
  81. __stat(char *fname, struct stat *stb, BPTR (*lock_func)())
  82. {
  83.   BPTR lock;
  84.   long mode;
  85.   struct FileInfoBlock *fib;
  86.   struct InfoData *info;
  87.   int omask;
  88.   int error;
  89.  
  90.   bzero (stb, sizeof(*stb));
  91.  
  92.   omask = syscall (SYS_sigsetmask, ~0);
  93.  
  94.   if (!(lock = (*lock_func) (fname, ACCESS_READ)))
  95.     {
  96.       int err = IoErr ();
  97.  
  98.       /* take special care of NIL:, /dev/null and friends ;-) */
  99.       if (err == 4242)
  100.         {
  101.           stb->st_mode = S_IFCHR | 0777;
  102.           stb->st_nlink = 1;
  103.           stb->st_blksize = ix.ix_fs_buf_factor * 512;
  104.           stb->st_blocks = 0;
  105.           goto rest_sigmask;
  106.         }
  107.  
  108. DP(("__stat: lock %s failed, err = %ld.\n", fname, err));
  109.       if (err == ERROR_IS_SOFT_LINK)
  110.     {
  111.       /* provide some default stb.. we can't get anymore info than
  112.        * that. Symlinks should work with Lock(), but till now they
  113.        * don't ;-( */
  114.       stb->st_handler = (int) DeviceProc ((UBYTE *)fname);
  115.       stb->st_dev = (dev_t) stb->st_handler;
  116.       /* HELP! no way to reach the fib of this entry except when
  117.        * scanning the parent directory, but this is NOT acceptable ! */
  118.       stb->st_ino = 123;
  119.       /* this is the most important entry ;-) */
  120.       stb->st_mode = S_IFLNK | 0777;
  121.       stb->st_size = 1024; /* again, this should be availabe... */
  122.       stb->st_nlink = 1;
  123.       stb->st_uid = stb->st_gid = stb->st_rdev = 0;
  124.       /* again, these values ARE accessible, but only by ExNext */
  125.       stb->st_atime = stb->st_mtime = stb->st_ctime = 0;
  126.       stb->st_blksize = stb->st_blocks = 0;
  127.       goto rest_sigmask;
  128.         }
  129. error:
  130.       syscall (SYS_sigsetmask, omask);
  131.       errno = __ioerr_to_errno (err);
  132.       return -1;
  133.     }
  134. DP(("__stat: lock %s ok.\n",fname));
  135.  
  136.   /* alloca() returns stack memory, so it's garanteed to be word 
  137.    * aligned (anything else would be deadly for the sp...) Since DOS needs
  138.    * long aligned data, we'll allocate 1 word more and adjust as needed */
  139.   fib = alloca (sizeof(*fib) + 2);
  140.   /* DON'T use LONG_ALIGN(alloca(..)), the argument is evaluated more than once! */
  141.   fib = LONG_ALIGN (fib);
  142.  
  143.   info = alloca (sizeof(*info) + 2);
  144.   info = LONG_ALIGN (info);
  145.  
  146.   if (!(Examine (lock, fib)))
  147.     {
  148.       __unlock (lock);
  149.       goto error;
  150.     }
  151.  
  152.   stb->st_nlink = 1; /* always one link entry per file, unless... */
  153.  
  154.   mode = 0L;
  155.   stb->st_amode = fib->fib_Protection;
  156.   if (!(fib->fib_Protection & FIBF_EXECUTE))
  157.     mode |= S_IXUSR | S_IXGRP | S_IXOTH;
  158.   if (!(fib->fib_Protection & FIBF_WRITE))
  159.     mode |= S_IWUSR | S_IWGRP | S_IWOTH;
  160. #if 0
  161.   if (fib->fib_Protection & FIBF_DELETE)
  162.     mode |= S_ISVTX;
  163. #endif
  164.   if (!(fib->fib_Protection & FIBF_READ))
  165.     mode |= S_IRUSR | S_IRGRP | S_IROTH;
  166.  
  167.   switch (fib->fib_DirEntryType)
  168.     {
  169.     case ST_LINKDIR:
  170.       stb->st_nlink ++;  /* we never get more than a link count of two.. */
  171.     case ST_ROOT:
  172.     case ST_USERDIR:
  173.       mode |= S_IFDIR;
  174.       break;
  175.  
  176.     /* at the moment, we NEVER get this entry, since we can't get a lock
  177.      * on a symlink */
  178.     case ST_SOFTLINK:
  179.       mode |= S_IFLNK;
  180.       break;
  181.  
  182.     case ST_LINKFILE:
  183.       stb->st_nlink ++;
  184.     case ST_FILE:
  185.     default:
  186.       mode |= S_IFREG;
  187.     }
  188.  
  189.   stb->st_mode = mode;
  190.   /* some kind of a default-size for directories... */
  191.   stb->st_size = fib->fib_DirEntryType<0 ? fib->fib_Size : 1024; 
  192.   stb->st_handler = (long)((struct FileLock *)((long)lock << 2))->fl_Task;
  193.   stb->st_dev = (dev_t)stb->st_handler; /* trunc to 16 bit */
  194.   stb->st_ino = fib->fib_DiskKey; 
  195.   stb->st_atime =
  196.   stb->st_ctime =
  197.   stb->st_mtime = (8*365+2)*24*3600 + /* offset to unix-timesystem */
  198.           fib->fib_Date.ds_Days * 24 * 60 * 60 +
  199.           fib->fib_Date.ds_Minute * 60 +
  200.           fib->fib_Date.ds_Tick/TICKS_PER_SECOND;
  201.   /* in a try to count the blocks used for filemanagement, we add one for
  202.    * the fileheader. Note, that this is wrong for large files, where there
  203.    * are some extension-blocks as well */
  204.   stb->st_blocks = fib->fib_NumBlocks + 1;
  205.   
  206.   bzero (info, sizeof (*info));
  207.   stb->st_blksize = 0;
  208.   if (Info(lock, info))
  209.     /* optimal for fileio is as high as possible ;-) This is a
  210.      * compromise between "as high as possible" and not too restricitve
  211.      * for people low on memory */
  212.     stb->st_blksize = info->id_BytesPerBlock * ix.ix_fs_buf_factor;
  213.  
  214.   if (! stb->st_blksize) stb->st_blksize = 512;
  215.  
  216.   __unlock (lock);
  217.  
  218. rest_sigmask:
  219.   syscall (SYS_sigsetmask, omask);
  220.   errno = 0;
  221.   return 0;
  222. }
  223.  
  224. /***************************************************************************/
  225.  
  226. int
  227. stat (char *fname, struct stat *stb)
  228. {
  229.   return __stat (fname, stb, __lock);
  230. }
  231.  
  232. int
  233. lstat (char *fname, struct stat *stb)
  234. {
  235.   return __stat (fname, stb, __llock);
  236. }
  237.  
  238. @
  239.