📄 vfsutil.c
字号:
/*
* 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 + -