home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / fileutil / rh / stat_os2.c < prev   
C/C++ Source or Header  |  1990-02-13  |  5KB  |  197 lines

  1. /***
  2. *os2/stat.c - OS/2 get file status
  3. *
  4. *   Copyright (c) 1985-1988, Microsoft Corporation.  All rights reserved.
  5. *
  6. *Purpose:
  7. *   defines stat() - get file status
  8. *
  9. *******************************************************************************/
  10.  
  11. #include <stdio.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <errno.h>
  15. #include <ctype.h>
  16. #include <msdos.h>
  17. #include <dostypes.h>
  18. #include <register.h>
  19. #include <dos.h>
  20. #include <doscalls.h>
  21. #include <string.h>
  22. #include <internal.h>
  23. #include <stdlib.h>
  24. #include <direct.h>
  25.  
  26.  
  27. #define STRPBRK strpbrk
  28.  
  29. #define ISSLASH(a)  ((a) == '\\' || (a) == '/')
  30.  
  31. #define EXT(a) stricmp(p,a)
  32.  
  33. /***
  34. *static unsigned near _dtoxmode(attr, name) -
  35. *
  36. *Purpose:
  37. *
  38. *Entry:
  39. *
  40. *Exit:
  41. *
  42. *Exceptions:
  43. *
  44. *******************************************************************************/
  45.  
  46. static unsigned near _dtoxmode(int attr, char *name)
  47. {
  48.     REG1 unsigned uxmode;
  49.     unsigned dosmode;
  50.     REG2 char *p;
  51.  
  52.     dosmode = attr & 0xff;
  53.     if ((p = name)[1] == ':')
  54.         p += 2;
  55.  
  56.     /* check to see if this is a directory - note we must make a special
  57.      * check for the root, which DOS thinks is not a directory
  58.      */
  59.  
  60.     uxmode = (( ISSLASH(*p) && !p[1]) || (dosmode & A_D)
  61.         || !*p) ? S_IFDIR|S_IEXEC : S_IFREG;
  62.  
  63.     /* If attribute byte has system bit set, assume read-only */
  64.  
  65.     uxmode |= (dosmode & (A_S|A_RO)) ? S_IREAD : (S_IREAD|S_IWRITE);
  66.  
  67.     /* see if file appears to be executable - check extension of name */
  68.  
  69.     if (p = strrchr(name, '.')) {
  70.         if ( !EXT(".exe") || !EXT(".bat") || !EXT(".com") )
  71.             uxmode |= S_IEXEC;
  72.     }
  73.  
  74.     /* propagate user read/write/execute bits to group/other fields */
  75.  
  76.     uxmode |= (uxmode & 0700) >> 3;
  77.     uxmode |= (uxmode & 0700) >> 6;
  78.  
  79.     return(uxmode);
  80. }
  81.  
  82.  
  83. /***
  84. *int stat(name, buf) - get file status info
  85. *
  86. *Purpose:
  87. *   stat obtains information about the file and stores it in the structure
  88. *   pointed to by buf.
  89. *
  90. *Entry:
  91. *   char *name -    pathname of given file
  92. *   struct stat *buffer - pointer to buffer to store info in
  93. *
  94. *Exit:
  95. *   fills in structure pointed to by buffer
  96. *   returns 0 if successful
  97. *   returns -1 and sets errno if unsuccessful
  98. *
  99. *Exceptions:
  100. *
  101. *******************************************************************************/
  102.  
  103.  
  104. int  stat( REG1 char *name, REG2 struct stat *buf)
  105. {
  106.     struct FileFindBuf findbuf;
  107.     unsigned findcount = 1;     /* Find only 1 match */
  108.     unsigned findhandle = -1;   /* any unused handle */
  109.  
  110.     char * oldcwd;          /* Pointer to current directory */
  111.  
  112.     unsigned long dmap;     /* Valid Drive Map (ignored) */
  113.     int drive;          /* A: = 1, B: = 2, etc. */
  114.  
  115.     /* Don't allow wildcards to be interpreted by system */
  116.  
  117.     if (strpbrk(name, "?*")) {
  118.         errno = ENOENT;
  119.         _doserrno = E_nofile;
  120.         return(-1);
  121.     }
  122.  
  123.     /* Try to get disk from name.  If none, get current disk.  */
  124.  
  125.     if (name[1] == ':'){
  126.  
  127.         drive = tolower(*name) - 'a' + 1;
  128.     }
  129.     else
  130.         (void) DOSQCURDISK((unsigned far *) &drive,
  131.         (unsigned long far *) &dmap);
  132.  
  133.     /* Call Find Match File */
  134.  
  135.     errno = ENOENT;
  136.  
  137.     if (DOSFINDFIRST((char far *)name, (unsigned far *)&findhandle, A_D|A_S|A_H,
  138.     (struct FileFindBuf far *) &findbuf, sizeof(findbuf),
  139.     (unsigned far *) &findcount, 0L)) {
  140.  
  141.         if ( STRPBRK(name, "./\\") ) {  /* Possible root directory? */
  142.             if ( ! ( oldcwd = _getdcwd(drive, NULL, -1) ) )
  143.                 return( -1 );
  144.             if ( chdir( name ) != -1 ) {
  145.                 chdir( oldcwd ); /* Must be a root directory */
  146.                 free( oldcwd );
  147.             }
  148.             else {
  149.                 free( oldcwd );
  150.                 return( -1 );
  151.             }
  152.  
  153.             findbuf.attributes = A_D;
  154.             findbuf.file_size = 0L;
  155.             findbuf.write_date = (1 << 5) + 1; /* 1 January 1980 */
  156.             findbuf.write_time = 0;        /* 00:00:00 */
  157.             findbuf.access_date =
  158.                 findbuf.create_date =
  159.                 findbuf.access_time =
  160.                 findbuf.create_time = 0;
  161.         }
  162.         else
  163.             return( -1 );
  164.  
  165.     }
  166.     else
  167.         DOSFINDCLOSE(findhandle);   /* Release Find handle */
  168.  
  169.     /* Fill in buf */
  170.  
  171.     buf->st_uid = buf->st_gid = buf->st_ino = 0;
  172.  
  173.     buf->st_rdev = buf->st_dev = drive - 1; /* A=0, B=1, etc. */
  174.  
  175.     /* now set the common fields */
  176.  
  177.     buf->st_mode = _dtoxmode(findbuf.attributes, name);
  178.     buf->st_nlink = 1;
  179.     buf->st_size = findbuf.file_size;
  180.     buf->st_mtime = XTIME(findbuf.write_date, findbuf.write_time);
  181.  
  182.     /*
  183.      * If create and access times are 0L, use modification time instead
  184.      */
  185.     if( findbuf.create_date || findbuf.create_time )
  186.         buf->st_ctime = XTIME(findbuf.create_date, findbuf.create_time);
  187.     else
  188.         buf->st_ctime = buf->st_mtime;
  189.  
  190.     if( findbuf.access_date || findbuf.access_time )
  191.         buf->st_atime = XTIME(findbuf.access_date, findbuf.access_time);
  192.     else
  193.         buf->st_atime = buf->st_mtime;
  194.  
  195.     return(0);
  196. }
  197.