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

  1. head    1.2;
  2. access;
  3. symbols
  4.     version39-41:1.1;
  5. locks;
  6. comment    @ *  @;
  7.  
  8.  
  9. 1.2
  10. date    92.08.09.21.00.32;    author amiga;    state Exp;
  11. branches;
  12. next    1.1;
  13.  
  14. 1.1
  15. date    92.05.22.01.50.27;    author mwild;    state Exp;
  16. branches;
  17. next    ;
  18.  
  19.  
  20. desc
  21. @bsd4.4 [f]statfs/getfsinfo calls
  22. @
  23.  
  24.  
  25. 1.2
  26. log
  27. @add alternate fs id's...
  28. @
  29. text
  30. @/*
  31.  *  This file is part of ixemul.library for the Amiga.
  32.  *  Copyright (C) 1991, 1992  Markus M. Wild
  33.  *
  34.  *  This library is free software; you can redistribute it and/or
  35.  *  modify it under the terms of the GNU Library General Public
  36.  *  License as published by the Free Software Foundation; either
  37.  *  version 2 of the License, or (at your option) any later version.
  38.  *
  39.  *  This library is distributed in the hope that it will be useful,
  40.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  41.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  42.  *  Library General Public License for more details.
  43.  *
  44.  *  You should have received a copy of the GNU Library General Public
  45.  *  License along with this library; if not, write to the Free
  46.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  47.  *
  48.  *  $Id: statfs.c,v 1.1 1992/05/22 01:50:27 mwild Exp $
  49.  *
  50.  *  $Log: statfs.c,v $
  51.  *  Revision 1.1  1992/05/22  01:50:27  mwild
  52.  *  Initial revision
  53.  *
  54.  */
  55.  
  56. #define KERNEL
  57. #include "ixemul.h"
  58. #include <sys/mount.h>
  59.  
  60. #ifndef ID_FFS_DISK
  61. #define ID_FFS_DISK        (0x444F5301L)    /* 'DOS\1' */
  62. #define ID_INTER_DOS_DISK    (0x444F5302L)    /* 'DOS\2' */
  63. #define ID_INTER_FFS_DISK    (0x444F5303L)    /* 'DOS\3' */
  64. #define ID_MSDOS_DISK        (0x4d534400L)    /* 'MSD\0' */
  65. #endif
  66.  
  67. /* no comments here ;-) */
  68. #define ID_ALT_OFS_DISK        (0x444F5304L)    /* 'DOS\4' */
  69. #define ID_ALT_FFS_DISK        (0x444F5305L)    /* 'DOS\5' */
  70. #define ID_ALT_INTER_DOS_DISK    (0x444F5306L)    /* 'DOS\6' */
  71. #define ID_ALT_INTER_FFS_DISK    (0x444F5307L)    /* 'DOS\7' */
  72.  
  73.  
  74. /* this function fills in InfoData information from a statfs structure
  75.    that has at least its f_fsid field set to the handler */
  76.  
  77. static void
  78. internal_statfs (struct statfs *buf, struct InfoData *info, struct StandardPacket *sp)
  79. {
  80.   sp->sp_Pkt.dp_Port = u.u_sync_mp;
  81.   sp->sp_Pkt.dp_Type = ACTION_DISK_INFO;
  82.   sp->sp_Pkt.dp_Arg1 = CTOBPTR (info);
  83.   PutPacket ((struct MsgPort *) buf->f_fsid.val[0], sp);
  84.   __wait_sync_packet (sp);
  85.       
  86.   /* if packet is implemented on handler side */
  87.   if (sp->sp_Pkt.dp_Res1 == -1)
  88.     {
  89.       struct DeviceList *dl = BTOCPTR (info->id_VolumeNode);
  90.  
  91.       if (dl)
  92.     {
  93.           char *name = BTOCPTR (dl->dl_Name);
  94.       int len = (MNAMELEN - 2 < name[0]) ? MNAMELEN - 2 : name[0];
  95.  
  96.       /* use this field to represent the volume name */
  97.           bcopy (name + 1, buf->f_mntfromname + 1, len);
  98.           buf->f_mntfromname[0] = '/';
  99.           buf->f_mntfromname[len + 1] = 0;
  100.         }
  101.       else
  102.     /* for stuff like FIFO that doesn't have an associated volume */
  103.     strcpy (buf->f_mntfromname, buf->f_mntonname);
  104.  
  105.       switch (info->id_DiskType)
  106.         {
  107.         case ID_DOS_DISK:
  108.         case ID_ALT_OFS_DISK:
  109.           buf->f_type = MOUNT_ADOS_OFS;
  110.       break;
  111.           
  112.     case ID_FFS_DISK:
  113.     case ID_ALT_FFS_DISK:
  114.       buf->f_type = MOUNT_ADOS_FFS;
  115.       break;
  116.  
  117.     case ID_INTER_DOS_DISK:
  118.     case ID_ALT_INTER_DOS_DISK:
  119.       buf->f_type = MOUNT_ADOS_IOFS;
  120.       break;
  121.  
  122.     case ID_INTER_FFS_DISK:
  123.     case ID_ALT_INTER_FFS_DISK:
  124.       buf->f_type = MOUNT_ADOS_IFFS;
  125.       break;
  126.  
  127.     case ID_MSDOS_DISK:
  128.       buf->f_type = MOUNT_PC;
  129.       break;
  130.       
  131.     case 'NFS\0':    /* dunno, would be logical ;-)) */
  132.       buf->f_type = MOUNT_NFS;
  133.       break;
  134.       
  135.     case 'UFS\0':    /* did somebody already do this ??? */
  136.       buf->f_type = MOUNT_UFS;
  137.       break;
  138.  
  139.     default:          
  140.       buf->f_type = MOUNT_NONE;
  141.       break;
  142.     }
  143.         
  144.       buf->f_flags  = MNT_NOSUID | MNT_NODEV;
  145.       if (info->id_DiskState != ID_VALIDATED)
  146.         /* can be ID_WRITE_PROTECTED or ID_VALIDATING */
  147.     buf->f_flags |= MNT_RDONLY;
  148.         
  149.       buf->f_fsize  = info->id_BytesPerBlock;
  150.       buf->f_bsize  = info->id_BytesPerBlock * ix.ix_fs_buf_factor;
  151.       buf->f_blocks = info->id_NumBlocks;
  152.       buf->f_bfree =
  153.         buf->f_bavail = info->id_NumBlocks - info->id_NumBlocksUsed;
  154.       /* no inode information available, thus set to -1 */
  155.       buf->f_files =
  156.       buf->f_ffree = -1;
  157.    }
  158. }
  159.  
  160.  
  161.  
  162. int
  163. getfsstat (struct statfs *buf, long bufsize, int flags)
  164. {
  165.   int num_devs = 0;
  166.   struct statfs *orig_buf = buf;
  167.   long orig_bufsize = bufsize;
  168.   
  169.   struct DosLibrary *dl;
  170.   struct RootNode *rn;
  171.   struct DosInfo *di;
  172.   struct DevInfo *dv;
  173.   extern struct ixemul_base *ixemulbase;
  174.   
  175.   struct InfoData *info;
  176.   struct StandardPacket *sp;
  177.  
  178.   /* could probably use less drastic measures under 2.0... */
  179.   Forbid ();
  180.   dl = (struct DosLibrary *) ixemulbase->ix_dos_base;
  181.   rn = (struct RootNode *) dl->dl_Root;
  182.   di = BTOCPTR (rn->rn_Info);
  183.   for (dv = BTOCPTR (di->di_DevInfo); dv; dv = BTOCPTR (dv->dvi_Next))
  184.     {
  185.       if (dv->dvi_Type == DLT_DEVICE && dv->dvi_Task && dv->dvi_Name)
  186.     {
  187.       num_devs ++;
  188.       if (buf && bufsize >= sizeof (*buf))
  189.         {
  190.           char *name = BTOCPTR (dv->dvi_Name);
  191.           int len = (MNAMELEN - 2 < name[0]) ? MNAMELEN - 2 : name[0];
  192.  
  193.           /* only remember the name and the address of the
  194.              handler so that we can later send INFO packets there */
  195.           bzero (buf, sizeof (*buf));
  196.           bcopy (name + 1, buf->f_mntonname + 1, len);
  197.           buf->f_mntonname[0] = '/';
  198.           buf->f_mntonname[len + 1] = 0;
  199.           buf->f_fsid.val[1] = 0;
  200.           buf->f_fsid.val[0] = (long) dv->dvi_Task;
  201.           
  202.           buf++;
  203.           bufsize -= sizeof (struct statfs);
  204.         }
  205.     }
  206.     }
  207.   Permit ();
  208.  
  209.   if (! orig_buf || orig_bufsize < sizeof (struct statfs))
  210.     return num_devs;
  211.  
  212.   info = alloca (sizeof (*info) + 2);
  213.   info = LONG_ALIGN (info);
  214.  
  215.   sp = alloca (sizeof (*sp) + 2);
  216.   sp = LONG_ALIGN (sp);
  217.   __init_std_packet (sp);
  218.  
  219.   /* have a second run, and inquire more data from the associated volumes */
  220.   while (orig_buf < buf)
  221.     {
  222.       internal_statfs (orig_buf, info, sp);
  223.       orig_buf++;
  224.     }
  225.  
  226.   return num_devs;
  227. }
  228.  
  229. int
  230. fstatfs (int fd, struct statfs *buf)
  231. {
  232.   struct file *f = u.u_ofile[fd];
  233.   struct DosLibrary *dl;
  234.   struct RootNode *rn;
  235.   struct DosInfo *di;
  236.   struct DevInfo *dv;
  237.   extern struct ixemul_base *ixemulbase;
  238.   
  239.   struct InfoData *info;
  240.   struct StandardPacket *sp;
  241.  
  242.   if ((unsigned)fd < NOFILE && f)
  243.     {
  244.       if (! buf)
  245.         {
  246.           errno = EFAULT;
  247.           return -1;
  248.         }
  249.  
  250.       if (HANDLER_NIL (f) || f->f_type != DTYPE_FILE)
  251.         {
  252.           errno = EOPNOTSUPP;
  253.       return -1;
  254.     }
  255.  
  256.       bzero (buf, sizeof (struct statfs));
  257.       buf->f_fsid.val[1] = 0;
  258.       buf->f_fsid.val[0] = (long) f->f_fh->fh_Type;
  259.       /* could probably use less drastic measures under 2.0... */
  260.       Forbid ();
  261.       dl = (struct DosLibrary *) ixemulbase->ix_dos_base;
  262.       rn = (struct RootNode *) dl->dl_Root;
  263.       di = BTOCPTR (rn->rn_Info);
  264.       for (dv = BTOCPTR (di->di_DevInfo); dv; dv = BTOCPTR (dv->dvi_Next))
  265.         {
  266.           if (dv->dvi_Type == DLT_DEVICE && 
  267.           (struct MsgPort *) dv->dvi_Task == f->f_fh->fh_Type)
  268.         {
  269.           char *name = BTOCPTR (dv->dvi_Name);
  270.           int len = (MNAMELEN - 2 < name[0]) ? MNAMELEN - 2 : name[0];
  271.  
  272.           bcopy (name + 1, buf->f_mntonname + 1, len);
  273.           buf->f_mntonname[0] = '/';
  274.           buf->f_mntonname[len + 1] = 0;
  275.           break;
  276.         }
  277.     }
  278.       Permit ();
  279.  
  280.       if (! dv)
  281.     {
  282.       errno = EOPNOTSUPP;
  283.           return -1;
  284.         }
  285.  
  286.       info = alloca (sizeof (*info) + 2);
  287.       info = LONG_ALIGN (info);
  288.  
  289.       sp = alloca (sizeof (*sp) + 2);
  290.       sp = LONG_ALIGN (sp);
  291.       __init_std_packet (sp);
  292.  
  293.       internal_statfs (buf, info, sp);
  294.  
  295.       return 0;
  296.     }
  297.     
  298.   errno = EBADF;  
  299.   return -1;
  300. }
  301.  
  302.  
  303. int
  304. statfs (const char *path, struct statfs *buf)
  305. {
  306.   struct MsgPort *handler;
  307.   BPTR lock;
  308.   int omask, err;
  309.   struct DosLibrary *dl;
  310.   struct RootNode *rn;
  311.   struct DosInfo *di;
  312.   struct DevInfo *dv;
  313.   extern struct ixemul_base *ixemulbase;
  314.   
  315.   struct InfoData *info;
  316.   struct StandardPacket *sp;
  317.  
  318.   omask = syscall (SYS_sigsetmask, ~0);
  319.   lock = __lock (path, ACCESS_READ);
  320.   handler = lock ? ((struct FileLock *) BTOCPTR (lock))->fl_Task : 0;
  321.   err = __ioerr_to_errno (IoErr ());
  322.   if (lock)
  323.     __unlock (lock);
  324.   syscall (SYS_sigsetmask, omask);
  325.   
  326.   if (! handler)
  327.     {
  328.       errno = err;
  329.       return -1;
  330.     }
  331.   else
  332.     {
  333.       if (! buf)
  334.         {
  335.           errno = EFAULT;
  336.           return -1;
  337.         }
  338.  
  339.       bzero (buf, sizeof (struct statfs));
  340.       buf->f_fsid.val[1] = 0;
  341.       buf->f_fsid.val[0] = (long) handler;
  342.       /* could probably use less drastic measures under 2.0... */
  343.       Forbid ();
  344.       dl = (struct DosLibrary *) ixemulbase->ix_dos_base;
  345.       rn = (struct RootNode *) dl->dl_Root;
  346.       di = BTOCPTR (rn->rn_Info);
  347.       for (dv = BTOCPTR (di->di_DevInfo); dv; dv = BTOCPTR (dv->dvi_Next))
  348.         {
  349.           if (dv->dvi_Type == DLT_DEVICE && 
  350.           (struct MsgPort *) dv->dvi_Task == handler)
  351.         {
  352.           char *name = BTOCPTR (dv->dvi_Name);
  353.           int len = (MNAMELEN - 2 < name[0]) ? MNAMELEN - 2 : name[0];
  354.  
  355.           bcopy (name + 1, buf->f_mntonname + 1, len);
  356.           buf->f_mntonname[0] = '/';
  357.           buf->f_mntonname[len + 1] = 0;
  358.           break;
  359.         }
  360.     }
  361.       Permit ();
  362.  
  363.       if (! dv)
  364.     {
  365.       errno = EOPNOTSUPP;
  366.           return -1;
  367.         }
  368.  
  369.       info = alloca (sizeof (*info) + 2);
  370.       info = LONG_ALIGN (info);
  371.  
  372.       sp = alloca (sizeof (*sp) + 2);
  373.       sp = LONG_ALIGN (sp);
  374.       __init_std_packet (sp);
  375.  
  376.       internal_statfs (buf, info, sp);
  377.  
  378.       return 0;
  379.     }
  380. }
  381. @
  382.  
  383.  
  384. 1.1
  385. log
  386. @Initial revision
  387. @
  388. text
  389. @d19 1
  390. a19 1
  391.  *  $Id$
  392. d21 4
  393. a24 1
  394.  *  $Log$
  395. d38 7
  396. d79 1
  397. d84 1
  398. d89 1
  399. d94 1
  400. @
  401.