home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #3 / amigamamagazinepolishissue1998.iso / ppc / lha_ppc / src / stat.c < prev    next >
C/C++ Source or Header  |  1997-12-16  |  4KB  |  207 lines

  1. /****** unix/stat *********************************************
  2. *
  3. *   NAME
  4. *    stat -- get file status
  5. *
  6. *   SYNOPSIS
  7. *    #include <sys/types.h>
  8. *    #include "stat.h"
  9. *
  10. *    return = stat (filename, buf)
  11. *
  12. *    int stat (const char *, struct stat *);
  13. *
  14. *   FUNCTION
  15. *    stat() obtains information about the named file.
  16. *
  17. *    The stat structure pointer to by "buf" is filled in. The
  18. *    following fields are used:
  19. *
  20. *        u_short     st_mode;
  21. *        short        st_uid;
  22. *        short        st_gid;
  23. *        long        st_size;
  24. *        long        st_mtime;
  25. *        long        st_atime;     same as st_mtime
  26. *        short        st_nlink;     always 1
  27. *        long        st_blksize;
  28. *        long        st_blocks;
  29. *
  30. *   INPUTS
  31. *    filename    full or relative pathname of file
  32. *    buf        pointer to a stat structure
  33. *
  34. *   RESULT
  35. *    On success,  0 is returned.
  36. *    On failure, -1 is returned, and errno is set.
  37. *
  38. *   EXAMPLE
  39. *    struct stat buf;
  40. *
  41. *    if (stat ("devs:foo", &buf) == -1)
  42. *    {
  43. *        printf ("Error: file not found\n");
  44. *        exit (1);
  45. *    }
  46. *
  47. *   NOTES
  48. *    On Amiga files, st_uid and st_gid will be set to that
  49. *    of the local user.
  50. *
  51. *   BUGS
  52. *
  53. *   SEE ALSO
  54. *
  55. *
  56. ******************************************************************************
  57. *
  58. */
  59.  
  60. #include <sys/types.h>
  61. #include <exec/types.h>
  62. #include <exec/exec.h>
  63. #include <dos/dosextens.h>
  64. #include <exec/memory.h>
  65. #include <proto/dos.h>
  66. #include <proto/exec.h>
  67.  
  68. #include <dos.h>
  69. #include <ios1.h>
  70. #include <string.h>
  71. #include "lharc.h"
  72.  
  73. static int GetMyFib(BPTR lock, struct FileInfoBlock *inf);
  74. static int lock_stat(BPTR l, struct stat *buf);
  75. static void fill_in_buf(struct FileInfoBlock *fp, struct stat *buf);
  76.  
  77. extern int __io2errno(int);
  78.  
  79. static long blockSize;
  80.  
  81. int stat(const char *name, struct stat *buf)
  82. {
  83.   BPTR l;
  84.   int success;
  85.  
  86.   Chk_Abort();
  87.  
  88.   if ((l = Lock(name, ACCESS_READ)) == 0)
  89.   {
  90.     errno = __io2errno(IoErr());
  91.     return -1;
  92.   }
  93.  
  94.   success = lock_stat(l, buf);
  95.   UnLock(l);
  96.  
  97.   return success;
  98. }
  99.  
  100. static void fill_in_buf(struct FileInfoBlock *fp, struct stat *buf)
  101. {
  102.   long
  103.     mode = 0;
  104.   long
  105.     prot = fp->fib_Protection;
  106.  
  107.   bzero(buf, sizeof(struct stat));
  108.  
  109.   buf->st_mtime = fp->fib_Date.ds_Days * ((24 * 60) * 60) +
  110.     fp->fib_Date.ds_Minute * 60 +
  111.     fp->fib_Date.ds_Tick / TICKS_PER_SECOND;
  112.   buf->st_atime = buf->st_mtime;
  113.   buf->st_size = fp->fib_Size;
  114.   buf->st_blksize = blockSize;
  115.   buf->st_blocks = fp->fib_NumBlocks;
  116.   buf->st_uid = fp->fib_OwnerUID;
  117.   buf->st_gid = fp->fib_OwnerGID;
  118.  
  119.   if (!(prot & FIBF_READ))
  120.     mode |= 0400;
  121.   if ((prot & FIBF_GRP_READ))
  122.     mode |= 0040;
  123.   if ((prot & FIBF_OTR_READ))
  124.     mode |= 0004;
  125.  
  126.   if (!(prot & FIBF_WRITE))
  127.     mode |= 0200;
  128.   if ((prot & FIBF_GRP_WRITE))
  129.     mode |= 0020;
  130.   if ((prot & FIBF_OTR_WRITE))
  131.     mode |= 0002;
  132.  
  133.   if (!(prot & FIBF_EXECUTE))
  134.     mode |= 0100;
  135.   if ((prot & FIBF_GRP_EXECUTE))
  136.     mode |= 0010;
  137.   if ((prot & FIBF_OTR_EXECUTE))
  138.     mode |= 0001;
  139.  
  140.   if (fp->fib_DirEntryType > 0)
  141.     mode |= S_IFDIR;
  142.   else
  143.     mode |= S_IFREG;
  144.  
  145.   buf->st_mode = mode;
  146.   buf->st_nlink = 1;        /* Hard coded */
  147. }
  148.  
  149. static int lock_stat(BPTR l, struct stat *buf)
  150. {
  151.   struct FileInfoBlock *fp;
  152.  
  153.   fp = (struct FileInfoBlock *) AllocVec(sizeof(struct FileInfoBlock), MEMF_CLEAR);
  154.  
  155.   if (fp == NULL)
  156.   {
  157.     errno = ENOMEM;
  158.     return -1;
  159.   }
  160.  
  161.   if (GetMyFib(l, fp) == 0)
  162.   {
  163.     FreeVec(fp);
  164.     return -1;
  165.   }
  166.  
  167.   fill_in_buf(fp, buf);
  168.  
  169.   FreeVec(fp);
  170.  
  171.   return 0;
  172. }
  173.  
  174. static int GetMyFib(BPTR lock, struct FileInfoBlock *inf)
  175. {
  176.   struct MsgPort *dev;
  177.   LONG result;
  178.   struct InfoData id;
  179.  
  180.   if (lock != 0)
  181.   {
  182.     dev = btod(lock, struct FileLock *)->fl_Task;
  183.   }
  184.   else
  185.   {
  186.     dev = (struct MsgPort *) (((struct Process *) FindTask(0))->pr_FileSystemTask);
  187.   }
  188.  
  189.   result = DoPkt(dev, ACTION_EXAMINE_OBJECT, lock, dtob(inf), 0, 0, 0);
  190.   if (!result)
  191.   {
  192.     errno = __io2errno(IoErr());
  193.     return 0;
  194.   }
  195.  
  196.   memset(&id, 0, sizeof(struct InfoData));
  197.  
  198.   result = DoPkt(dev, ACTION_INFO, lock, dtob(&id), NULL, NULL, NULL);
  199.  
  200.   if (result)
  201.     blockSize = id.id_BytesPerBlock;
  202.   else
  203.     blockSize = 512;    /* assume */
  204.  
  205.   return 1;
  206. }
  207.