home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / MPW / gawk 2.11.1r3 / Sources / missing.d / stat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-08  |  6.1 KB  |  290 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. File        :    stat.c            -    Macintosh implementation of stat()
  3. Author    :    Matthias Neeracher
  4. Started    :    28May91                                Language    :    MPW C
  5.                 28May91    MN    Created
  6.                 28May91    MN    isatty()
  7. Last        :    28May91
  8.  
  9. Copyright (c) 1991, Matthias Neeracher
  10.  
  11. Permission is granted to anyone to use this software for any
  12. purpose on any computer system, and to redistribute it freely,
  13. subject to the following restrictions:
  14.  
  15. 1. The author is not responsible for the consequences of use of
  16.     this software, no matter how awful, even if they arise
  17.     from defects in it.
  18.  
  19. 2. The origin of this software must not be misrepresented, either
  20.     by explicit claim or by omission.
  21.  
  22. 3. Altered versions must be plainly marked as such, and must not
  23.     be misrepresented as being the original software.
  24.  
  25. *********************************************************************/
  26.  
  27. #include <stat.h>
  28. #include <string.h>
  29. #include <ioctl.h>
  30. #include <errno.h>
  31. #include <Errors.h>
  32. #include <Files.h>
  33.  
  34. /* As the field names of a CInfoParamBlockRec are spelled inconsistently,
  35.     we have to use manual casts.
  36. */
  37.  
  38. #define FILEINFO(cb)    (*(HFileInfo *) (cb))
  39. #define DIRINFO(cb)    (*(DirInfo *) (cb))
  40.  
  41. OSErr    GetCatInfo(char * path, CInfoPBPtr cb)
  42. {
  43.     char    *    nextPath;
  44.     char    *  tryPath;
  45.     OSErr        err;
  46.     Str255    name;
  47.  
  48.     DIRINFO(cb).ioNamePtr    =    name;
  49.     DIRINFO(cb).ioDrDirID    =    0;
  50.     DIRINFO(cb).ioVRefNum    =    0;
  51.     DIRINFO(cb).ioFDirIndex    =    0;
  52.  
  53.     /* handle very long pathnames */
  54.  
  55.     while (strlen(path) > 255)    {
  56.         for (nextPath    =    path; tryPath = strchr(nextPath, ':'); nextPath = tryPath)
  57.             if (tryPath-nextPath > 31)
  58.                 return bdNamErr;
  59.             else if (tryPath-path > 255)
  60.                 break;
  61.  
  62.         if (nextPath == path && !tryPath)
  63.             return bdNamErr;
  64.  
  65.         name[0]    =    nextPath-path;
  66.         strncpy((char *) name+1, path, name[0]);
  67.  
  68.         if (err = PBGetCatInfo(cb, false))
  69.             return err;
  70.  
  71.         if (!(DIRINFO(cb).ioFlAttrib & 0x10))
  72.             return bdNamErr;
  73.  
  74.         DIRINFO(cb).ioFDirIndex    =    0;
  75.  
  76.         path    =    nextPath+1;
  77.     }
  78.     
  79.     name[0]    =    strlen(path);
  80.     strncpy((char *) name+1, path, name[0]);
  81.  
  82.     return PBGetCatInfo(cb, false);
  83. }
  84.  
  85. OSErr    GetFDCatInfo(int fd, CInfoPBPtr cb)
  86. {
  87.     short                fRef;
  88.     OSErr                err;
  89.     FCBPBRec            fcb;
  90.     Str255            fname;
  91.  
  92.     if (ioctl(fd, FIOREFNUM, (long *) &fRef) == -1)
  93.         return fnfErr;
  94.  
  95.     fcb.ioNamePtr    =     fname;
  96.     fcb.ioRefNum    =    fRef;
  97.     fcb.ioFCBIndx    =     0;
  98.     if (err = PBGetFCBInfo(&fcb, false))
  99.         return err;
  100.  
  101.     FILEINFO(cb).ioNamePtr        =    fname;
  102.     FILEINFO(cb).ioDirID        =    fcb.ioFCBParID;
  103.     FILEINFO(cb).ioVRefNum        =    fcb.ioFCBVRefNum;
  104.     FILEINFO(cb).ioFDirIndex    =    0;
  105.  
  106.     return PBGetCatInfo(cb, false);
  107. }
  108.  
  109. OSErr GetVolume(char * path, ParmBlkPtr pb)
  110. {
  111.     char *    volEnd;
  112.     OSErr        err;
  113.     WDPBRec    wd;
  114.     Str255    name;
  115.  
  116.     volEnd    =    strchr(path, ':');
  117.  
  118.     pb->volumeParam.ioNamePtr    =    name;
  119.  
  120.     if (path[0] == ':' || !volEnd)     {
  121.         if (err = PBGetVol(pb, false))
  122.             return err;
  123.         
  124.         wd.ioNamePtr    =    name;
  125.         wd.ioVRefNum    =     pb->volumeParam.ioVRefNum;
  126.         wd.ioWDIndex    =    0;
  127.         if (!PBGetWDInfo(&wd, false))
  128.             pb->volumeParam.ioVRefNum    =    wd.ioWDVRefNum;
  129.             
  130.         pb->volumeParam.ioVolIndex    =    0;
  131.     } else {
  132.         pb->volumeParam.ioVolIndex    =    -1;
  133.  
  134.         name[0]    =    volEnd-path;
  135.         strncpy((char *) name+1, path, name[0]);
  136.     }
  137.  
  138.     return PBGetVInfo(pb, false);
  139. }
  140.  
  141. OSErr GetFDVolume(int fd, ParmBlkPtr pb)
  142. {
  143.     OSErr                err;
  144.     short                fRef;
  145.     Str255            name;
  146.     FCBPBRec            fcb;
  147.  
  148.     if (ioctl(fd, FIOREFNUM, (long *) &fRef) == -1)
  149.         return fnfErr;
  150.  
  151.     fcb.ioNamePtr    =     name;
  152.     fcb.ioRefNum    =    fRef;
  153.     fcb.ioFCBIndx    =     0;
  154.     if (err = PBGetFCBInfo(&fcb, false))
  155.         return err;
  156.  
  157.     pb->volumeParam.ioNamePtr    =    name;
  158.     pb->volumeParam.ioVRefNum    =    fcb.ioFCBVRefNum;
  159.     pb->volumeParam.ioVolIndex    =    0;
  160.  
  161.     return PBGetVInfo(pb, false);
  162. }
  163.  
  164. int    do_stat(CInfoPBPtr cb, ParmBlkPtr pb, struct stat * buf)
  165. {
  166.  
  167.     buf->st_dev        =    pb->ioParam.ioVRefNum;
  168.     buf->st_ino        =    FILEINFO(cb).ioDirID;
  169.     buf->st_nlink    =    1;
  170.     buf->st_uid        =    0;
  171.     buf->st_gid        =    0;
  172.     buf->st_rdev    =    0;
  173.     buf->st_atime    =    FILEINFO(cb).ioFlMdDat;
  174.     buf->st_mtime    =    FILEINFO(cb).ioFlMdDat;
  175.     buf->st_ctime    =    FILEINFO(cb).ioFlCrDat;
  176.     buf->st_blksize=    pb->volumeParam.ioVAlBlkSiz;
  177.  
  178.     if (FILEINFO(cb).ioFlAttrib & 0x10)    {
  179.         buf->st_mode    =    S_IFDIR | 0777;
  180.         buf->st_size    =    buf->st_blksize;    /* Not known for directories    */
  181.     } else {
  182.         buf->st_mode    =    S_IFREG | 0666;
  183.  
  184.         if (FILEINFO(cb).ioFlAttrib & 0x01)
  185.             buf->st_mode&=    0222;
  186.  
  187.         if (FILEINFO(cb).ioFlFndrInfo.fdType == 'APPL')
  188.             buf->st_mode|=    0111;
  189.  
  190.         buf->st_size    =    FILEINFO(cb).ioFlLgLen;        /* Resource fork is ignored    */
  191.     }
  192.  
  193.     buf->st_blocks    =    (buf->st_size + buf->st_blksize - 1) / buf->st_blksize;
  194.  
  195.     return 0;
  196. }
  197.  
  198. int    stat(char * path, struct stat * buf)
  199. {
  200.     CInfoPBRec        cb;
  201.     ParamBlockRec    pb;
  202.  
  203.     if (GetCatInfo(path, &cb) || GetVolume(path, &pb)) {
  204.         errno = ENOENT;
  205.  
  206.         return -1;
  207.     } else
  208.         return do_stat(&cb, &pb, buf);
  209. }
  210.  
  211. int    lstat(char * path, struct stat * buf)
  212. {
  213.     return stat(path, buf);
  214. }
  215.  
  216. int    fstat(int fd, struct stat * buf)
  217. {
  218.     CInfoPBRec        cb;
  219.     ParamBlockRec    pb;
  220.  
  221.     if (!ioctl(fd, FIOINTERACTIVE, NULL))    {    /* MPW window */
  222.         buf->st_dev            =    0;
  223.         buf->st_ino            =    0;
  224.         buf->st_mode        =    S_IFCHR | 0777;
  225.         buf->st_nlink        =    1;
  226.         buf->st_uid            =    0;
  227.         buf->st_gid            =    0;
  228.         buf->st_rdev        =    0;
  229.         buf->st_size        =    1;
  230.         buf->st_atime        =    time(NULL);
  231.         buf->st_mtime        =    time(NULL);
  232.         buf->st_ctime        =    time(NULL);
  233.         buf->st_blksize    =    1;
  234.         buf->st_blocks        =    1;
  235.  
  236.         return 0;
  237.     }
  238.  
  239.     if (GetFDCatInfo(fd, &cb) || GetFDVolume(fd, &pb)) {
  240.         errno = ENOENT;
  241.  
  242.         return -1;
  243.     } else
  244.         return do_stat(&cb, &pb, buf);
  245. }
  246.  
  247. int isatty(int fd)
  248. {
  249.     return !ioctl(fd, FIOINTERACTIVE, NULL);
  250. }
  251.  
  252. #ifdef test
  253.  
  254. #include <stdio.h>
  255.  
  256. #define DUMP(EXPR, MODE)    printf("%s = %"#MODE"\n", #EXPR, EXPR);
  257.  
  258. int main(int argc, char ** argv)
  259. {
  260.     int             res;
  261.     struct stat    statbuf;
  262.  
  263.     printf("StdIn is %s TTY.\n", isatty(0)?"a":"no");
  264.     printf("StdOut is %s TTY.\n", isatty(1)?"a":"no");
  265.     printf("StdErr is %s TTY.\n\n", isatty(2)?"a":"no");
  266.     
  267.     if (argc == 1)
  268.         res = fstat(0, &statbuf);
  269.     else
  270.         res = stat(argv[1], &statbuf);
  271.  
  272.     if (res)
  273.         printf("Error occurred.\n");
  274.     else {
  275.         DUMP(statbuf.st_dev,d);
  276.         DUMP(statbuf.st_ino,d);
  277.         DUMP(statbuf.st_mode,#o);
  278.         DUMP(statbuf.st_nlink,d);
  279.         DUMP(statbuf.st_uid,d);
  280.         DUMP(statbuf.st_gid,d);
  281.         DUMP(statbuf.st_rdev,d);
  282.         DUMP(statbuf.st_size,d);
  283.         DUMP(statbuf.st_atime,u);
  284.         DUMP(statbuf.st_mtime,u);
  285.         DUMP(statbuf.st_ctime,u);
  286.         DUMP(statbuf.st_blksize,d);
  287.         DUMP(statbuf.st_blocks,d);
  288.     }
  289. }
  290. #endif