home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / LIB / stat.lzh / STAT / stat.c < prev    next >
Text File  |  1991-08-29  |  5KB  |  220 lines

  1. /*
  2.     Unix-like stat and fstat functions for OS/9 (version 2.2)
  3.     by Richard W.M. Jones
  4.     free software
  5.     August 1991
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <modes.h>
  10. #include <dir.h>
  11. #include <direct.h>
  12. #include <time.h>
  13. #include <strings.h>
  14. #include <module.h>
  15.  
  16. #include "stat.h"
  17.  
  18. /*----- stat function -----*/
  19.  
  20. int
  21. stat(pathname,buf)
  22. register char *pathname;
  23. register struct stat *buf;
  24. {
  25.     register int fd,r;
  26.  
  27.     fd=open(pathname,S_IREAD);
  28.     if(fd<0)
  29.     {
  30.         fd=open(pathname,S_IFDIR|S_IREAD);    /* open as a directory */
  31.         if(fd<0)                    /* not a directory */
  32.             return(-1);
  33.     }
  34.     r=fstat(fd,buf);
  35.     close(fd);
  36.     return(r);
  37. }
  38.  
  39. /*----- fstat function -----*/
  40.  
  41. int
  42. fstat(path,buf)
  43. register int path;
  44. register struct stat *buf;
  45. {
  46.     struct fildes fildes_buf;
  47.     struct tm tp;
  48.     register int mode,isdev=0,gfd=0,modaccess,modowner;
  49.     register mod_dev *mod;
  50.     char devn[32], fmgrn[32];
  51.  
  52.     /* clear the stat buffer to default values, so programs that don't detect
  53.         stat errors will not die */
  54.     buf->st_dev=buf->st_ino=buf->st_mode=buf->st_nlink=buf->st_uid=
  55.         buf->st_gid=buf->st_size=0;
  56.     buf->st_atime=buf->st_ctime=buf->st_mtime=-1;
  57.  
  58.     /* first, get the associated device name */
  59.     if(_gs_devn(path,devn)<0)
  60.         return(-1);                        /* no device name??? */
  61.  
  62.     /* look for recognisable device names */
  63.     if(!strcmp(devn,"pipe"))
  64.     {
  65.         mode=S_IFIFO;                    /* it's a pipe */
  66.         gfd=1;
  67.     } else
  68.     if(!strcmp(devn,"socket"))
  69.     {
  70.         mode=S_IFSOCK;                    /* it's a socket */
  71.         isdev=1;
  72.     }
  73.  
  74.     /* now find out more from the module header of the device descriptor */
  75.     mod=(mod_dev *)modlink(devn,0);
  76.     if(mod==(mod_dev *)-1)
  77.         return(-1);                        /* link failed */
  78.  
  79.     /* copy the file manager name and access permissions out and unlink */
  80.     strcpy(fmgrn,(char *)mod+(int)(mod->_mfmgr));
  81.     strlwr(fmgrn);                        /* to lower case */
  82.     modaccess=mod->_mh._maccess;        /* get the module permissions */
  83.     modowner=mod->_mh._mowner;            /* get the module owner */
  84.     munlink(mod);                        /* unlink from the module */
  85.  
  86.     /* look for a recognisable file manager */
  87.     if(!isdev && !gfd)                    /* mode not determined already */
  88.     {
  89.         if(!strcmp(fmgrn,"scf") || !strcmp(fmgrn,"sbf") ||
  90.             !strcmp(fmgrn,"pkman"))
  91.         {
  92.             mode=S_IFCHR;                /* character special */
  93.             isdev=1;
  94.         } else
  95.         if(!strcmp(fmgrn,"sockman"))
  96.         {
  97.             mode=S_IFSOCK;                /* socket */
  98.             isdev=1;
  99.         } else
  100.         if(!strcmp(fmgrn,"rbf"))
  101.         {
  102.             isdev=1; gfd=1;                /* could be block special,
  103.                                             regular file or directory */
  104.         } else
  105.         {
  106.             mode=0;                        /* unknown device */
  107.             isdev=1;
  108.         }
  109.     }
  110.  
  111.     /* if it is a file with a file descriptor, then get the file descriptor */
  112.     if(gfd && !isdev)                    /* pipe */
  113.         if(_gs_gfd(path,&fildes_buf,sizeof(struct fildes))<0)
  114.             return(-1);                    /* stat failed */
  115.     if(gfd && isdev)                    /* regular file, block special or
  116.                                             directory */
  117.     {
  118.         if(_gs_gfd(path,&fildes_buf,sizeof(struct fildes))<0)
  119.         {
  120.             mode=S_IFBLK;
  121.             gfd=0;                        /* must be block special */
  122.         }
  123.         else
  124.         {
  125.             if(fildes_buf.fd_att & S_IFDIR)
  126.                 mode=S_IFDIR;            /* must be directory */
  127.             else
  128.                 mode=S_IFREG;            /* must be regular file */
  129.             isdev=0;
  130.         }
  131.     }
  132.  
  133.     /* convert file descriptor to stat structure */
  134.     if(gfd)
  135.     {
  136.         /* create a suitable stat structure for a regular file */
  137.         buf->st_dev=0;                    /* no devices in OS/9 */
  138.         buf->st_ino=0;                    /* no inodes in OS/9 */
  139.         buf->st_uid=fildes_buf.fd_own[1];            /* get uid */
  140.         buf->st_gid=fildes_buf.fd_own[0];            /* get gid */
  141.         buf->st_size=*(long *)fildes_buf.fd_fsize;    /* get filesize */
  142.         buf->st_nlink=fildes_buf.fd_link;            /* link count */
  143.         buf->st_mode=mode | (fildes_buf.fd_att & 0x7F);    /* OS/9 attributes */
  144.         buf->st_atime=time(NULL);        /* last access time is now! */
  145.  
  146.         /* convert dates from strange OS/9 format to reasonable unix format */
  147.         tp.tm_sec=0;
  148.         tp.tm_min=fildes_buf.fd_date[4];
  149.         tp.tm_hour=fildes_buf.fd_date[3];
  150.         tp.tm_mday=fildes_buf.fd_date[2];
  151.         tp.tm_mon=fildes_buf.fd_date[1]-1;
  152.         tp.tm_year=fildes_buf.fd_date[0];
  153.         tp.tm_wday=tp.tm_yday=tp.tm_isdst=-1;
  154.         buf->st_mtime=mktime(&tp);        /* file modify time */
  155.  
  156.         if(!(mode & S_IFIFO))            /* creation date meaningless on
  157.                                             OS/9 pipes (why? who knows) */
  158.         {
  159.             tp.tm_sec=tp.tm_min=tp.tm_hour=0;
  160.             tp.tm_mday=fildes_buf.fd_dcr[2];
  161.             tp.tm_mon=fildes_buf.fd_dcr[1]-1;
  162.             tp.tm_year=fildes_buf.fd_dcr[0];
  163.             tp.tm_wday=tp.tm_yday=tp.tm_isdst=-1;
  164.             buf->st_ctime=mktime(&tp);    /* create (inode changed) time */
  165.         }
  166.  
  167.         /* all done */
  168.         return(0);
  169.     }
  170.  
  171.     /* if its a device, then fill in the stat buffer using data from the
  172.         module header */
  173.     if(isdev)
  174.     {
  175.         /* fields not applicable */
  176.         buf->st_dev=0;                    /* no device numbers */
  177.         buf->st_ino=0;                    /* no inodes */
  178.         buf->st_size=0;                    /* no size */
  179.         buf->st_mtime=buf->st_ctime=-1;    /* these values aren't stored */
  180.  
  181.         /* convert permissions/times in module header into a suitable format */
  182.         buf->st_mode=mode | conv_modperms(modaccess);
  183.         buf->st_atime=time(NULL);        /* last access time is now */
  184.         buf->st_gid=modowner >> 8;        /* gid */
  185.         buf->st_uid=modowner & 0xFF;    /* uid */
  186.  
  187.         /* successful stat */
  188.         return(0);
  189.     }
  190.     return(-1);
  191. }
  192.  
  193. /*----- static functions -----*/
  194.  
  195. /* convert module permissions into stat permissions */
  196.  
  197. static int
  198. conv_modperms(modperms)
  199. register int modperms;
  200. {
  201.     register int r;
  202.  
  203.     r=modperms & MP_OWNER_MASK;
  204.     r |= ((modperms & MP_WORLD_MASK) >> 5);
  205.     return(r);
  206. }
  207.  
  208. /* convert string to lower case */
  209.  
  210. static
  211. strlwr(s)
  212. char *s;
  213. {
  214.     while(*s)
  215.     {
  216.         *s=tolower(*s);
  217.         ++s;
  218.     }
  219. }
  220.