/* Original code (c) Acorn Computers Ltd, 1992-3 */

/* $Id: c._Free 3.1 93/03/09 23:12:41 brian Exp $ */

#include "FS.h"
/* #define DEBUG */

struct usage { int size, free, used; };

static char *fixid(char *id, char *buf)
{ strcpy(buf,FilingSystemName);
  switch (id[0])
  {
  case ':':
    strcat(buf,":"); break;
  default:
    strcat(buf,"::"); break;
  case '#':
    break;
  }
  strcat(buf,id);
  return buf;
}

_kernel_oserror *fsentry_free( FSEntry_Free_Parameter *parm )
{
  char *p;
  int l;
  char buf[256];
  struct usage *u;
  _kernel_oserror *err;
  _kernel_swi_regs r;
#ifdef DEBUG
  printf("Free(%d) %s\n",parm->reason,parm->device_id?parm->device_id:"NULL");
#endif
  switch ( parm->reason )
  {
  case FSEntry_Free_Reason_NoOp:
          return NULL;
  case FSEntry_Free_Reason_GetDeviceName:
        r.r[0]=37;
        r.r[1]=(int)fixid(parm->device_id,buf);
        r.r[2]=(int)&buf;
        r.r[3]=0;
        r.r[4]=0;
        r.r[5]=256;
        err = _kernel_swi(OS_FSControl,&r,&r);
          if (err)
          {
#ifdef DEBUG
  printf("***_Free: FSControl 37 on device %s failed %s\n",fixid(parm->device_id,buf),err->errmess);
#endif
            return err;
          }
          p = strchr(buf,'#');
          if (!p)
          { p=strchr(buf,':');
            if (p)
              p+=2;
            else
              p="";
          }
          l=strlen(p);
          if (l>=2 && p[l-1]=='$' && p[l-2]=='.')
            p[l-2]=0;
          strcpy( parm->third_parameter.name, p );
          parm->reason = strlen(p)+1;
          return NULL;
  case FSEntry_Free_Reason_GetFreeSpace:
          r.r[0]=49;
          r.r[1]=(int)fixid(parm->device_id,buf);
          err = _kernel_swi(OS_FSControl,&r,&r);
          if (err)
          {
#ifdef DEBUG
  printf("***_Free: FSControl 49 on device %s failed %s\n",fixid(parm->device_id,buf),err->errmess);
#endif
            return err;
          }

          u = (struct usage *)parm->third_parameter.buffer;
          u->size = r.r[2];
          u->free = r.r[0];
          u->used = u->size - u->free;
          return err;
  case FSEntry_Free_Reason_CompareDevice:
          /* Z set if name and special_field are on device_id */
          return NULL;
  default:
          return ERR(mb_BadParameters);
  }
}
