⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfsutil.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * FILENAME: vfsutil.c
 *
 * Copyright 1997- 2000 By InterNiche Technologies Inc. All rights reserved
 *
 *
 * MODULE: VFS
 *
 * ROUTINES: vfs_file_detail(), vfs_file_list(), 
 * ROUTINES: vfs_change_flag(), vfs_set_flag(), vfs_clear_flag(), 
 * ROUTINES: vfs_do_sync(), vfs_open_list(), vfs_dir(), 
 * ROUTINES: vfs_unit_scan_index(), vfs_unit_scan_file_name(), 
 * ROUTINES: vfs_unit_list(), vfs_unit_vfopen(), vfs_unit_vfclose(), 
 * ROUTINES: vfs_unit_vunlink(), vfs_unit_vfread(), vfs_unit_vfwrite(), 
 * ROUTINES: vfs_unit_vfseek(), vfs_unit_vftell(), vfs_unit_vgetc(), 
 * ROUTINES: vfs_unit_vferror(), vfs_unit_vclearerr(), 
 * ROUTINES: vfs_tog_log_file_name(), vfs_led_test(), vfs_init(), 
 *
 * PORTABLE: yes
 */

/* Additional Copyrights: */

/* vfsutil.c 
 * Portions Copyright 1996 by NetPort Software. All rights reserved. 
 * InterNiche virtual file system. This implements the vfopen(), 
 * vfread(), etc, calls the Embedded WEB servers and similar devices 
 * to do file IO. These calls lookup names, descriptors, etc, to see 
 * if the file is a "virtual" file in RAM/ROM/FLASH, or if it should 
 * fall through to the local disk system (if any) 
 * 12/26/98 - Separated from WebPort sources. -JB- 
 */

#include "vfsport.h" /* per-port include */
#include "vfsfiles.h"   /* overlay vfs stuff on system file IO */

#ifdef VFS_FILES

#include "menu.h"

#ifdef IN_MENUS

/* VFS system commands */

struct vfs_flag_map_struct
{
   char  flag_name;  /* how flag bit is identified in display */
   char  editable;   /* can flag bit be modified by user */
   unsigned short bit_mask;   /* mask representing position of bit */
};

/* the VFS commands use the following array to map vfs_file.flags field
   bits to displayable characters */
struct vfs_flag_map_struct vfs_flag_map[] =
{
   'H',  1, VF_HTMLCOMPRESSED,
   'B',  1, VF_AUTHBASIC,
   '5',  1, VF_AUTHMD5,
   'M',  1, VF_MAPFILE,
   'V',  0, VF_CVAR,
   'W',  1, VF_WRITE,
   'I',  0, VF_DYNAMICINFO,
   'D',  0, VF_DYNAMICDATA,
   'N',  1, VF_NONVOLATILE,
   'S',  0, VF_STALE,
#ifdef WEBPORT
   's',  0, 0, /* these last three are special cases */
   'c',  0, 0,
#endif   /* WEBPORT */
#ifdef HT_EXTDEV
   'm',  0  ,0,
#endif   /* HT_EXTDEV */
   0, 0, 0  /* array terminator */
};

#define  VFS_FLAG_MAP_LEN  (sizeof(vfs_flag_map)/sizeof(vfs_flag_map[0]))



/* FUNCTION: vfs_file_detail()
 * 
 * this function creates a detailed file directory listing for the
 * file addressed by the vfp parameter in the buffer addressed by buf
 *
 * PARAM1: struct vfs_file *vfp
 * PARAM2: char *buf
 *
 * RETURNS: 
 */

void vfs_file_detail(struct vfs_file * vfp, char * buf)
{
   int   i;
   char  name_string[FILENAMEMAX +  1];
   char  flag_string[VFS_FLAG_MAP_LEN  +  1];

   /* make a string containing the name of the file padded to
      the max file name length */
   strcpy(name_string,vfp->name);
   i = strlen(name_string);
   while (i < FILENAMEMAX)
      name_string[i++] = ' ';
   name_string[FILENAMEMAX] = 0;

   /* make a string listing the bits of vfp->flags */
   /* note that loop below terminates when bit_mask is 0 because the 
    * last 3 chars of the flags field are not derived from bits 
    * in the flags field
    */
   for (i = 0; vfs_flag_map[i].bit_mask; ++i)
   {
      flag_string[i] =
      (char) ((vfp->flags & vfs_flag_map[i].bit_mask)
       ? vfs_flag_map[i].flag_name : '-');
   }

#ifdef WEBPORT

   /* a non-null ssi_func field is represented by a 's' */
   flag_string[i] =
(char) (vfp->ssi_func ? vfs_flag_map[i].flag_name : '-');
   i++;

   /* a non-null cgi_func field is represented by a 'c' */
   flag_string[i] =
(char) (vfp->cgi_func ? vfs_flag_map[i].flag_name : '-');
   i++;

#endif   /* WEBPORT */

#ifdef HT_EXTDEV

   /* a non-null method field is represented by a 'm' */
   flag_string[i] =
(char) (vfp->method ? vfs_flag_map[i].flag_name : '-');
   i++;

#endif   /* HT_EXTDEV */

   /* terminate flags string */
   flag_string[i] = 0;

   /* format it all into the caller supplied buffer */
   /* its up to the caller to make sure the buffer is big enough */
   sprintf_t(buf,"%s %s %p %8lx %8lx %8lx",
    name_string,flag_string,vfp->data,
    vfp->real_size,vfp->comp_size,vfp->buf_size);
}



/* FUNCTION: vfs_file_list()
 * 
 * PARAM1: void *pio
 *
 * RETURNS: 
 */

int vfs_file_list(void * pio)
{
   struct vfs_file * vfp;
   int   file_count  =  0;
   char  buffer[80];

   /* lock the VFS */
   vfs_lock();

   /* for each file in the file list */
   for (vfp = vfsfiles; vfp; vfp = vfp->next)
   {
      /* create a line of file listing */
      vfs_file_detail(vfp,buffer);

      /* and write it out */
      ns_printf(pio,"%s\n",buffer);

      file_count++;
      if ( con_page(pio,file_count) )
         break ;
   }

   ns_printf(pio,"total files = %d\n",file_count);

#ifdef HT_RWVFS

   ns_printf(pio,"dynamically allocated files = %ld, buffer space = 0x%lx\n",
    vfs_total_dyna_files,vfs_total_rw_space);

#endif   /* HT_RWVFS */

   vfs_unlock();

   return 0;
}

#ifdef HT_RWVFS



/* FUNCTION: vfs_change_flag()
 * 
 * PARAM1: void *pio
 * PARAM2: int set
 *
 * RETURNS: 
 */

int vfs_change_flag(void * pio, int set)
{
   char *   arg1;
   char *   arg2  =  NULL;
   char *   cp;
   struct vfs_file * vfp;
   VFILE *vfd;
   struct vfs_flag_map_struct *  pmap;
   int   bit_changed =  FALSE;
   char  flag_name;
   char  file_name[FILENAMEMAX   +  1];

   /* scan out first and second args to command */
   arg1 = nextarg(((GEN_IO) pio)->inbuf);
   if (arg1)
      arg2 = nextarg(arg1);

   /* if two args are not present, tell the user how to do the command */
   if (!arg2 || !*arg2)
   {
      ns_printf(pio,"usage:%s <file name> <bit>\n",
       set ? "vfssetflag" : "vfsclearflag");
      return 1;
   }

   /* get pointer to space at end of first arg */
   cp = strchr(arg1,' ');
   /* it had better be non-NULL */
   if (!cp)
   {
      dtrap("vfsutil 0\n");
      return 2;
   }

   /* copy and null terminate the file name */
   MEMCPY(file_name,arg1,cp - arg1);
   file_name[cp - arg1] = 0;

   /* get the name of the flag from the second arg */
   flag_name = *arg2;

   /* search the flag map array for the specified flag name */
   for (pmap = vfs_flag_map;
       pmap < (vfs_flag_map + VFS_FLAG_MAP_LEN); ++pmap)
   {
      if (pmap->flag_name == flag_name)
         break;
   }

   /* if the search failed, tell the user */
   if (pmap >= vfs_flag_map + VFS_FLAG_MAP_LEN)
   {
      ns_printf(pio,"%c is not a valid bit identifier\n",flag_name);
      return 3;
   }

   /* if the flag is not editable, tell the user */
   if (!(pmap->editable))
   {
      ns_printf(pio,"Flag %c may not be modified\n",flag_name);
      return 4;
   }

   /* lock the VFS */
   vfs_lock();

   /* see if the file exists */
   vfp = vfslookup_locked(file_name);
   if (!vfp)
   {
      vfs_unlock();
      ns_printf(pio,"file name %s is not in the VFS\n",file_name);
      return 5;
   }

   /* open the file for read access */
   vfd = vfopen_locked(file_name,"r");

   /* since we already verified that the file exists above and we've 
    * locked the file system to prevent others from unlinking it, the 
    * above open should work. 
    * If it doesn't work, something is very wrong
    */
   if (!vfd)
   {
      vfs_unlock();
      dtrap("vfsutil 1\n");
      return 6;
   }

   /* if we are setting the bit, set it */
   if (set)
   {
      /* if its not set now */
      if (!(vfp->flags & pmap->bit_mask))
      {
         /* set it and flag that we changed it */
         vfp->flags |= pmap->bit_mask;
         bit_changed = TRUE;
      }
   }
   else  /* else reset it */
   {
      /* if its set now */
      if (vfp->flags & pmap->bit_mask)
      {
         /* reset it and flag that we changed it */
         vfp->flags &= ~(pmap->bit_mask);
         bit_changed = TRUE;
      }
   }

#ifdef HTML_COMPRESSION

   /* if its the compression bit we are fidding and we actually 
    * changed something, then we want to set the real_size field 
    * accordingly 
    */
   if ((pmap->bit_mask == VF_HTMLCOMPRESSED) && bit_changed)
   {
      /* if the compression bit is being turned off, then the "size 
       * before compression" is the same as its actual 
       * compressed size
       */
      if (!set)
         vfp->real_size = vfp->comp_size;
      else
      /* we are turning the compression bit on, so we need to run the 
       * decompression algorithm on the file to determine 
       * how big it was before it was compressed 
       */
      {
         unsigned long count;

         count = 0;
         while (vgetc_locked(vfd) != EOF)
            ++count;
         vfp->real_size = count;
      }
   }

#endif   /* HTML_COMPRESSION */

   /* if we actually changed something,
      set the stale bit so when we close the file, it will get synced */
   if (bit_changed)
      vfp->flags |= VF_STALE;

   vfclose_locked(vfd);

   vfs_unlock();

   return 0;   /* success */
}



/* FUNCTION: vfs_set_flag()
 * 
 * PARAM1: void *pio
 *
 * RETURNS: 
 */

int vfs_set_flag(void * pio)
{
   return vfs_change_flag(pio,TRUE);
}



/* FUNCTION: vfs_clear_flag()
 * 
 * PARAM1: void *pio
 *
 * RETURNS: 
 */

int vfs_clear_flag(void * pio)
{
   return vfs_change_flag(pio,FALSE);
}

#ifdef HT_SYNCDEV    /* Do we support sync to flash device? */



/* FUNCTION: vfs_do_sync()
 * 
 * PARAM1: void *pio
 *
 * RETURNS: 
 */

int vfs_do_sync(void * pio)
{
   /* this implementation will not be suitable for target systems in 
    * which vfs_sync() determines what it should do based on the 
    * parameter that is passed to it. this implementation only makes 
    * sense if vfs_sync() does the same thing, that is syncs the 
    * entire file system to backing store, irrespective of the 
    * parameter that is passed to it. if the target system's 
    * implementation of vfs_sync() DOES function differently based on 
    * the parameter passed to it, this command should be modified to 
    * allow the appropriate parameters to be passed to it
    */
   ns_printf(pio,"VFS sync initiated\n");
   vfs_lock();
   vfs_sync(NULL);
   vfs_unlock();
   ns_printf(pio,"VFS sync completed\n");

   return 0;
}
#endif   /* HT_SYNCDEV */

#endif   /* HT_RWVFS */



/* FUNCTION: vfs_open_list()
 * 
 * PARAM1: void *pio
 *
 * RETURNS: 
 */

int vfs_open_list(void * pio)
{
   VFILE * vfd;
   unsigned long count = 0;
   unsigned long orphans = 0;

   vfs_lock();

   for (vfd = vfiles; vfd; vfd = vfd->next)
   {
      /* if the file that the handle is pointing at still exists */
      if (vfd->file)
      {
         /* display its name */
         ns_printf(pio,"%s\n",vfd->file->name);
      }
      else  /* else the file was deleted since the open */
      {
         /* so just increment the count of orphans */
         orphans++;
      }
      count++;
   }

   vfs_unlock();
   ns_printf(pio,"total files open = %ld\n",count);
   if (orphans)
      ns_printf(pio,"total orphans = %ld\n",orphans);
   return 0;
}





/* FUNCTION: vfs_dir()
 * 
 * vfs_dir() - a vfs dir command for the menus
 *
 * PARAM1: void * pio
 *
 * RETURNS: 
 */

int
vfs_dir(void * pio)
{
   return vfs_file_list(pio);
}

#ifdef VFS_UNIT_TEST

/* code in here is used to unit test the VFS */
/* it was thrown together quick, so pardon the spare comments */

#define  VFS_NUM_UNIT_TEST_FDS   10

VFILE *vfs_unit_test_fds[VFS_NUM_UNIT_TEST_FDS];

unsigned int atoh(char *buf);
unsigned long atohl(char *buf);



/* FUNCTION: vfs_unit_scan_index()
 * 
 * PARAM1: void *pio
 * PARAM2: char *arg
 * PARAM3: unsigned int *pindex
 *
 * RETURNS: 
 */

int vfs_unit_scan_index(void * pio, char * arg, unsigned int * pindex)
{
   *pindex = atoh(arg);
   if (*pindex >= VFS_NUM_UNIT_TEST_FDS)
   {
      ns_printf(pio,"bad index 0x%x\n",*pindex);
      return 1;
   }
   return 0;
}



/* FUNCTION: vfs_unit_scan_file_name()
 * 
 * PARAM1: void *pio
 * PARAM2: char *arg
 * PARAM3: char *file_name
 *
 * RETURNS: 
 */

int vfs_unit_scan_file_name(void * pio, char * arg, char * file_name)
{
   char *   cp;

   /* get pointer to space at end of first arg */
   cp = strchr(arg,' ');

   /* if no space, make cp point to null and end of string */
   if (!cp)
      cp = arg + strlen(arg);

   /* check for too long */
   if ((cp - arg) > FILENAMEMAX)
   {
      ns_printf(pio,"bad file name\n");
      return 1;
   }

   /* copy and null terminate the file name */
   MEMCPY(file_name,arg,cp - arg);
   file_name[cp - arg] = 0;

   return 0;
}



/* FUNCTION: vfs_unit_list()
 * 
 * PARAM1: void *pio
 *
 * RETURNS: 
 */

int vfs_unit_list(void * pio)
{
   int   i;

   for (i = 0; i < VFS_NUM_UNIT_TEST_FDS; i++)
      ns_printf(pio,"%d %p\n",i,vfs_unit_test_fds[i]);
   return 0;
}



/* FUNCTION: vfs_unit_vfopen()
 * 
 * PARAM1: void *pio
 *
 * RETURNS: 
 */

int vfs_unit_vfopen(void * pio)
{
   char *   arg1;
   char *   arg2  =  NULL;
   char *   arg3  =  NULL;
   unsigned int index;
   VFILE *vfd;
   char  file_name[FILENAMEMAX   +  1];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -