Undelfs was too broken for too long.
Этот коммит содержится в:
родитель
b95d74c493
Коммит
286c61a200
18
src/cmd.c
18
src/cmd.c
@ -272,6 +272,18 @@ void view_cmd (WPanel *panel)
|
|||||||
do_view_cmd (panel, 0);
|
do_view_cmd (panel, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void view_file_cmd (WPanel *panel)
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
|
||||||
|
panel = get_a_panel (panel);
|
||||||
|
filename = input_dialog (_(" View file "), _(" Filename:"), selection (panel)->fname);
|
||||||
|
if (!filename) return;
|
||||||
|
|
||||||
|
view_file (filename, 0, use_internal_view);
|
||||||
|
free (filename);
|
||||||
|
}
|
||||||
|
|
||||||
void view_simple_cmd (WPanel *panel)
|
void view_simple_cmd (WPanel *panel)
|
||||||
{
|
{
|
||||||
do_view_cmd (panel, 1);
|
do_view_cmd (panel, 1);
|
||||||
@ -1294,9 +1306,9 @@ void source_routing (void)
|
|||||||
void undelete_cmd (void)
|
void undelete_cmd (void)
|
||||||
{
|
{
|
||||||
nice_cd (_(" Undelete files on an ext2 file system "),
|
nice_cd (_(" Undelete files on an ext2 file system "),
|
||||||
_(" Enter the file system name where you want to run the\n "
|
_(" Enter device (without /dev/) to undelete\n "
|
||||||
" undelete file system on: (F1 for details)"),
|
" files on: (F1 for details)"),
|
||||||
"[Undelete File System]", "/#undel/", 0);
|
"[Undelete File System]", "/#undel:", 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
Sun Aug 30 13:19:49 1998 Pavel Machek <pavel@ucw.cz>
|
||||||
|
|
||||||
|
* undelfs.c: fixed, it has been broken for too long
|
||||||
|
|
||||||
|
* vfs.c, ../src/cmd.c: neccessary minor fixes to make undelfs work
|
||||||
|
|
||||||
|
* vfs.c: made more fields in *_vfs_ops optional, cleanup of errno
|
||||||
|
handling in case of NULL in *_vfs_ops.
|
||||||
|
|
||||||
|
* extfs.c, ftpfs.c, tar.c: made use of above change
|
||||||
|
|
||||||
|
* vfs.c: cleanup of macros generating mc_*()
|
||||||
|
|
||||||
|
* libvfs.c: adding variable mc_home
|
||||||
|
|
||||||
Thu Aug 27 19:45:31 1998 Pavel Roskin <pavel.roskin@ecsoft.co.uk>
|
Thu Aug 27 19:45:31 1998 Pavel Roskin <pavel.roskin@ecsoft.co.uk>
|
||||||
|
|
||||||
* extfs.c: mc_extfsdir was not defined in extfs_open()
|
* extfs.c: mc_extfsdir was not defined in extfs_open()
|
||||||
|
162
vfs/undelfs.c
162
vfs/undelfs.c
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
/* Assumptions:
|
/* Assumptions:
|
||||||
*
|
*
|
||||||
* 1. We don't handle directories (thus undelfs_getpath is easy to write).
|
* 1. We don't handle directories (thus undelfs_get_path is easy to write).
|
||||||
* 2. Files are on the local file system (we do not support vfs files
|
* 2. Files are on the local file system (we do not support vfs files
|
||||||
* because we would have to provide an io_manager for the ext2fs tools,
|
* because we would have to provide an io_manager for the ext2fs tools,
|
||||||
* and I don't think it would be too useful to undelete files
|
* and I don't think it would be too useful to undelete files
|
||||||
@ -86,7 +86,7 @@ static int undelfs_usage;
|
|||||||
#define READDIR_PTR_INIT 0
|
#define READDIR_PTR_INIT 0
|
||||||
|
|
||||||
static void
|
static void
|
||||||
undelfs_shutdown ()
|
undelfs_shutdown (void)
|
||||||
{
|
{
|
||||||
if (fs)
|
if (fs)
|
||||||
ext2fs_close (fs);
|
ext2fs_close (fs);
|
||||||
@ -107,33 +107,44 @@ undelfs_get_path (char *dirname, char **ext2_fname, char **file)
|
|||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
/* To look like filesystem, we have virtual directories
|
||||||
|
/#undel:XXX, which have no subdirectories. XXX is replaced with
|
||||||
|
hda5, sdb8 etc, which is assumed to live under /dev.
|
||||||
|
-- pavel@ucw.cz */
|
||||||
|
|
||||||
*ext2_fname = 0;
|
*ext2_fname = 0;
|
||||||
|
|
||||||
if (strncmp (dirname, "undel:", 6))
|
if (strncmp (dirname, "/#undel:", 8))
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
dirname += 6;
|
dirname += 8;
|
||||||
|
|
||||||
/* Since we don't allow subdirectories, it's easy to get a filename,
|
/* Since we don't allow subdirectories, it's easy to get a filename,
|
||||||
* just scan backwards for a slash
|
* just scan backwards for a slash */
|
||||||
*/
|
|
||||||
if (*dirname == 0)
|
if (*dirname == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = dirname + strlen (dirname);
|
p = dirname + strlen (dirname);
|
||||||
|
#if 0
|
||||||
|
/* Strip trailing ./
|
||||||
|
*/
|
||||||
if (p - dirname > 2 && *(p-1) == '/' && *(p-2) == '.')
|
if (p - dirname > 2 && *(p-1) == '/' && *(p-2) == '.')
|
||||||
*(p = p-2) = 0;
|
*(p = p-2) = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
while (p > dirname){
|
while (p > dirname){
|
||||||
if (*p == '/'){
|
if (*p == '/'){
|
||||||
*file = strdup (p+1);
|
*file = strdup (p+1);
|
||||||
*p = 0;
|
*p = 0;
|
||||||
*ext2_fname = strdup (dirname);
|
*ext2_fname = copy_strings ("/dev/", dirname, NULL);
|
||||||
*p = '/';
|
*p = '/';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p--;
|
p--;
|
||||||
}
|
}
|
||||||
|
*file = strdup ("");
|
||||||
|
*ext2_fname = copy_strings ("/dev/", dirname, NULL);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -159,7 +170,7 @@ lsdel_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt, void *private)
|
|||||||
* if we don't have enough memory
|
* if we don't have enough memory
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
undelfs_loaddel ()
|
undelfs_loaddel (void)
|
||||||
{
|
{
|
||||||
int retval, count;
|
int retval, count;
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
@ -519,13 +530,6 @@ undelfs_read (void *vfs_info, char *buffer, int count)
|
|||||||
return p->dest_buffer - buffer;
|
return p->dest_buffer - buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_write (void *vfs_info, char *buf, int count)
|
|
||||||
{
|
|
||||||
/* No writes allowed */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static long
|
static long
|
||||||
undelfs_getindex (char *path)
|
undelfs_getindex (char *path)
|
||||||
{
|
{
|
||||||
@ -608,48 +612,6 @@ undelfs_fstat (void *vfs_info, struct stat *buf)
|
|||||||
return do_stat (p->f_index, buf);
|
return do_stat (p->f_index, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_chmod(char *path, int mode)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_chown(char *path, int owner, int group)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_readlink(char *path, char *buf, int size)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_symlink(char *n1, char *n2)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_link(char *p1, char *p2)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_unlink(char *path)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_rename(char *p1, char *p2)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
undelfs_chdir(char *path)
|
undelfs_chdir(char *path)
|
||||||
{
|
{
|
||||||
@ -675,24 +637,13 @@ undelfs_chdir(char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
/* this has to stay here for now: vfs layer does not know how to emulate it */
|
||||||
undelfs_ferrno(void)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
undelfs_lseek(void *vfs_info, off_t offset, int whence)
|
undelfs_lseek(void *vfs_info, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_mknod(char *path, int mode, int dev)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static vfsid
|
static vfsid
|
||||||
undelfs_getid(char *path, struct vfs_stamping **parent)
|
undelfs_getid(char *path, struct vfs_stamping **parent)
|
||||||
{
|
{
|
||||||
@ -721,50 +672,11 @@ undelfs_free(vfsid id)
|
|||||||
undelfs_shutdown ();
|
undelfs_shutdown ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
|
||||||
undelfs_getlocalcopy(char *filename)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
undelfs_ungetlocalcopy(char *filename, char *local, int has_changed)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_mkdir(char *path, mode_t mode)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_rmdir(char *path)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
|
||||||
static caddr_t
|
|
||||||
undelfs_mmap(caddr_t addr, size_t len, int prot, int flags, void *vfs_info, off_t offset)
|
|
||||||
{
|
|
||||||
return (caddr_t) -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
undelfs_munmap(caddr_t addr, size_t len, void *vfs_info)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
vfs undelfs_vfs_ops = {
|
vfs undelfs_vfs_ops = {
|
||||||
undelfs_open,
|
undelfs_open,
|
||||||
undelfs_close,
|
undelfs_close,
|
||||||
undelfs_read,
|
undelfs_read,
|
||||||
undelfs_write,
|
NULL,
|
||||||
|
|
||||||
undelfs_opendir,
|
undelfs_opendir,
|
||||||
undelfs_readdir,
|
undelfs_readdir,
|
||||||
@ -776,35 +688,35 @@ vfs undelfs_vfs_ops = {
|
|||||||
undelfs_lstat,
|
undelfs_lstat,
|
||||||
undelfs_fstat,
|
undelfs_fstat,
|
||||||
|
|
||||||
undelfs_chmod,
|
NULL,
|
||||||
undelfs_chown,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
undelfs_readlink,
|
NULL, /* readlink */
|
||||||
undelfs_symlink,
|
NULL,
|
||||||
undelfs_link,
|
NULL,
|
||||||
undelfs_unlink,
|
NULL,
|
||||||
|
|
||||||
undelfs_rename,
|
NULL,
|
||||||
undelfs_chdir,
|
undelfs_chdir,
|
||||||
undelfs_ferrno,
|
NULL,
|
||||||
undelfs_lseek,
|
undelfs_lseek,
|
||||||
undelfs_mknod,
|
NULL,
|
||||||
|
|
||||||
undelfs_getid,
|
undelfs_getid,
|
||||||
undelfs_nothingisopen,
|
undelfs_nothingisopen,
|
||||||
undelfs_free,
|
undelfs_free,
|
||||||
|
|
||||||
undelfs_getlocalcopy,
|
NULL, /* get_local_copy */
|
||||||
undelfs_ungetlocalcopy,
|
NULL,
|
||||||
|
|
||||||
undelfs_mkdir,
|
NULL,
|
||||||
undelfs_rmdir,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
, undelfs_mmap,
|
, NULL,
|
||||||
undelfs_munmap
|
NULL
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
203
vfs/vfs.c
203
vfs/vfs.c
@ -108,7 +108,7 @@ vfs *vfs_type_from_op (char *path)
|
|||||||
return &ftpfs_vfs_ops;
|
return &ftpfs_vfs_ops;
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_EXT2FSLIB
|
#ifdef USE_EXT2FSLIB
|
||||||
if (!(vfs_flags & FL_NO_UNDELFS) && !strcmp (path, "undel"))
|
if (!(vfs_flags & FL_NO_UNDELFS) && !strncmp (path, "undel:", 6))
|
||||||
return &undelfs_vfs_ops;
|
return &undelfs_vfs_ops;
|
||||||
#endif
|
#endif
|
||||||
if (!(vfs_flags & FL_NO_TARFS) && !strcmp (path, "utar"))
|
if (!(vfs_flags & FL_NO_TARFS) && !strcmp (path, "utar"))
|
||||||
@ -309,7 +309,7 @@ int mc_open (char *file, int flags, ...)
|
|||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
if (!vfs->open)
|
if (!vfs->open)
|
||||||
vfs_die( "VFS must support open\n" );
|
vfs_die( "VFS must support open.\n" );
|
||||||
info = (*vfs->open) (file, flags, mode); /* open must be supported */
|
info = (*vfs->open) (file, flags, mode); /* open must be supported */
|
||||||
free (file);
|
free (file);
|
||||||
if (!info){
|
if (!info){
|
||||||
@ -337,12 +337,14 @@ int mc_open (char *file, int flags, ...)
|
|||||||
result = vfs->name ? (*vfs->name)callarg : -1; \
|
result = vfs->name ? (*vfs->name)callarg : -1; \
|
||||||
post \
|
post \
|
||||||
if (result == -1) \
|
if (result == -1) \
|
||||||
errno = ferrno (vfs); \
|
errno = vfs->name ? ferrno (vfs) : EOPNOTSUPP; \
|
||||||
return result; \
|
return result; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MC_NAMEOP(name, inarg, callarg) MC_OP (name, inarg, callarg, path = vfs_canon (path); vfs = vfs_type (path);, free (path); )
|
#define MC_NAMEOP(name, inarg, callarg) \
|
||||||
#define MC_HANDLEOP(name, inarg, callarg) MC_OP (name, inarg, callarg, if (handle == -1) return -1; vfs = vfs_op (handle);, )
|
MC_OP (name, inarg, callarg, path = vfs_canon (path); vfs = vfs_type (path);, free (path); )
|
||||||
|
#define MC_HANDLEOP(name, inarg, callarg) \
|
||||||
|
MC_OP (name, inarg, callarg, if (handle == -1) return -1; vfs = vfs_op (handle);, )
|
||||||
|
|
||||||
MC_HANDLEOP(read, (int handle, char *buffer, int count), (vfs_info (handle), buffer, count) );
|
MC_HANDLEOP(read, (int handle, char *buffer, int count), (vfs_info (handle), buffer, count) );
|
||||||
|
|
||||||
@ -380,7 +382,9 @@ int mc_close (int handle)
|
|||||||
if (handle < 3)
|
if (handle < 3)
|
||||||
return close (handle);
|
return close (handle);
|
||||||
|
|
||||||
result = (*vfs->close)(vfs_info (handle)); /* close must be supported */
|
if (!vfs->close)
|
||||||
|
vfs_die( "VFS must support close.\n" );
|
||||||
|
result = (*vfs->close)(vfs_info (handle));
|
||||||
vfs_free_bucket (handle);
|
vfs_free_bucket (handle);
|
||||||
if (result == -1)
|
if (result == -1)
|
||||||
errno = ferrno (vfs);
|
errno = ferrno (vfs);
|
||||||
@ -408,19 +412,16 @@ DIR *mc_opendir (char *dirname)
|
|||||||
|
|
||||||
info = vfs->opendir ? (*vfs->opendir)(dirname) : NULL;
|
info = vfs->opendir ? (*vfs->opendir)(dirname) : NULL;
|
||||||
free (dirname);
|
free (dirname);
|
||||||
|
if (p)
|
||||||
|
free (p);
|
||||||
if (!info){
|
if (!info){
|
||||||
errno = ferrno (vfs);
|
errno = vfs->opendir ? ferrno (vfs) : EOPNOTSUPP;
|
||||||
if (p)
|
|
||||||
free (p);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
handle = get_bucket ();
|
handle = get_bucket ();
|
||||||
vfs_file_table [handle].fs_info = info;
|
vfs_file_table [handle].fs_info = info;
|
||||||
vfs_file_table [handle].operations = vfs;
|
vfs_file_table [handle].operations = vfs;
|
||||||
|
|
||||||
if (p)
|
|
||||||
free (p);
|
|
||||||
|
|
||||||
handlep = (int *) xmalloc (sizeof (int), "opendir handle");
|
handlep = (int *) xmalloc (sizeof (int), "opendir handle");
|
||||||
*handlep = handle;
|
*handlep = handle;
|
||||||
return (DIR *) handlep;
|
return (DIR *) handlep;
|
||||||
@ -429,11 +430,29 @@ DIR *mc_opendir (char *dirname)
|
|||||||
/* This should strip the non needed part of a path name */
|
/* This should strip the non needed part of a path name */
|
||||||
#define vfs_name(x) x
|
#define vfs_name(x) x
|
||||||
|
|
||||||
#define MC_DIROP(name, type, inarg, callarg, onerr ) \
|
void mc_seekdir (DIR *dirp, int offset)
|
||||||
type mc_##name inarg \
|
{
|
||||||
|
int handle;
|
||||||
|
vfs *vfs;
|
||||||
|
|
||||||
|
if (!dirp){
|
||||||
|
errno = EFAULT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handle = *(int *) dirp;
|
||||||
|
vfs = vfs_op (handle);
|
||||||
|
if (vfs->seekdir)
|
||||||
|
(*vfs->seekdir) (vfs_info (handle), offset);
|
||||||
|
else
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MC_DIROP(name, type, onerr ) \
|
||||||
|
type mc_##name (DIR *dirp) \
|
||||||
{ \
|
{ \
|
||||||
int handle; \
|
int handle; \
|
||||||
vfs *vfs; \
|
vfs *vfs; \
|
||||||
|
type result; \
|
||||||
\
|
\
|
||||||
if (!dirp){ \
|
if (!dirp){ \
|
||||||
errno = EFAULT; \
|
errno = EFAULT; \
|
||||||
@ -441,28 +460,14 @@ type mc_##name inarg \
|
|||||||
} \
|
} \
|
||||||
handle = *(int *) dirp; \
|
handle = *(int *) dirp; \
|
||||||
vfs = vfs_op (handle); \
|
vfs = vfs_op (handle); \
|
||||||
return vfs->name ? (*vfs->name) callarg : onerr; \
|
result = vfs->name ? (*vfs->name) (vfs_info (handle)) : onerr; \
|
||||||
|
if (result == onerr) \
|
||||||
|
errno = vfs->name ? ferrno(vfs) : EOPNOTSUPP; \
|
||||||
|
return result; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MC_DIROP_VOID(name, inarg, callarg ) \
|
MC_DIROP (readdir, struct dirent *, NULL)
|
||||||
void mc_##name inarg \
|
MC_DIROP (telldir, int, -1)
|
||||||
{ \
|
|
||||||
int handle; \
|
|
||||||
vfs *vfs; \
|
|
||||||
\
|
|
||||||
if (!dirp){ \
|
|
||||||
errno = EFAULT; \
|
|
||||||
return; \
|
|
||||||
} \
|
|
||||||
handle = *(int *) dirp; \
|
|
||||||
vfs = vfs_op (handle); \
|
|
||||||
if (vfs->name) \
|
|
||||||
(*vfs->name) callarg; \
|
|
||||||
}
|
|
||||||
|
|
||||||
MC_DIROP (readdir, struct dirent *, (DIR *dirp), (vfs_info (handle)), NULL)
|
|
||||||
MC_DIROP_VOID (seekdir, (DIR *dirp, int offset), (vfs_info (handle), offset))
|
|
||||||
MC_DIROP (telldir, int, (DIR *dirp), (vfs_info (handle)), -1)
|
|
||||||
|
|
||||||
int mc_closedir (DIR *dirp)
|
int mc_closedir (DIR *dirp)
|
||||||
{
|
{
|
||||||
@ -514,7 +519,7 @@ char *mc_get_current_wd (char *buffer, int size)
|
|||||||
{
|
{
|
||||||
char *cwd = mc_return_cwd();
|
char *cwd = mc_return_cwd();
|
||||||
if (strlen (cwd) > size){
|
if (strlen (cwd) > size){
|
||||||
vfs_die ("Current_dir size overflow\n");
|
vfs_die ("Current_dir size overflow.\n");
|
||||||
}
|
}
|
||||||
strcpy (buffer, cwd);
|
strcpy (buffer, cwd);
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -527,73 +532,48 @@ MC_NAMEOP (readlink, (char *path, char *buf, int bufsiz), (vfs_name (path), buf,
|
|||||||
MC_NAMEOP (unlink, (char *path), (vfs_name (path)))
|
MC_NAMEOP (unlink, (char *path), (vfs_name (path)))
|
||||||
MC_NAMEOP (symlink, (char *name1, char *path), (vfs_name (name1), vfs_name (path)))
|
MC_NAMEOP (symlink, (char *name1, char *path), (vfs_name (name1), vfs_name (path)))
|
||||||
|
|
||||||
int mc_link (char *name1, char *name2)
|
#define MC_RENAMEOP(name) \
|
||||||
{
|
int mc_##name (char *name1, char *name2) \
|
||||||
vfs *vfs1;
|
{ \
|
||||||
vfs *vfs2;
|
vfs *vfs; \
|
||||||
int result;
|
int result; \
|
||||||
|
\
|
||||||
name1 = vfs_canon (name1);
|
name1 = vfs_canon (name1); \
|
||||||
vfs1 = vfs_type (name1);
|
vfs = vfs_type (name1); \
|
||||||
name2 = vfs_canon (name2);
|
name2 = vfs_canon (name2); \
|
||||||
vfs2 = vfs_type (name2);
|
if (vfs != vfs_type (name2)){ \
|
||||||
|
errno = EXDEV; \
|
||||||
if (vfs1 != vfs2){
|
free (name1); \
|
||||||
errno = EXDEV;
|
free (name2); \
|
||||||
free (name1);
|
return -1; \
|
||||||
free (name2);
|
} \
|
||||||
return -1;
|
\
|
||||||
}
|
result = vfs->name ? (*vfs->name)(vfs_name (name1), vfs_name (name2)) : -1; \
|
||||||
|
free (name1); \
|
||||||
result = (*vfs1->link)(vfs_name (name1), vfs_name (name2));
|
free (name2); \
|
||||||
free (name1);
|
if (result == -1) \
|
||||||
free (name2);
|
errno = vfs->name ? ferrno (vfs) : EOPNOTSUPP; \
|
||||||
if (result == -1){
|
return result; \
|
||||||
errno = (*vfs1->ferrno)();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MC_RENAMEOP (link);
|
||||||
|
MC_RENAMEOP (rename);
|
||||||
|
|
||||||
MC_HANDLEOP (write, (int handle, char *buf, int nbyte), (vfs_info (handle), buf, nbyte));
|
MC_HANDLEOP (write, (int handle, char *buf, int nbyte), (vfs_info (handle), buf, nbyte));
|
||||||
|
|
||||||
int mc_rename (char *path1, char *path2)
|
|
||||||
{
|
|
||||||
vfs *vfs1;
|
|
||||||
vfs *vfs2;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
path1 = vfs_canon (path1);
|
|
||||||
vfs1 = vfs_type (path1);
|
|
||||||
path2 = vfs_canon (path2);
|
|
||||||
vfs2 = vfs_type (path2);
|
|
||||||
|
|
||||||
if (vfs1 != vfs2){
|
|
||||||
errno = EXDEV;
|
|
||||||
free (path1);
|
|
||||||
free (path2);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = (*vfs1->rename)(vfs_name (path1), vfs_name (path2));
|
|
||||||
free (path1);
|
|
||||||
free (path2);
|
|
||||||
if (result == -1){
|
|
||||||
errno = (*vfs1->ferrno)();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
off_t mc_lseek (int fd, off_t offset, int whence)
|
off_t mc_lseek (int fd, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
vfs *vfs;
|
vfs *vfs;
|
||||||
|
int result;
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
vfs = vfs_op (fd);
|
vfs = vfs_op (fd);
|
||||||
return (*vfs->lseek)(vfs_info (fd), offset, whence);
|
result = vfs->lseek ? (*vfs->lseek)(vfs_info (fd), offset, whence) : -1;
|
||||||
|
if (result == -1)
|
||||||
|
errno = vfs->lseek ? ferrno (vfs) : EOPNOTSUPP;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -612,7 +592,7 @@ vfs_kill_dots (char *path, char *local)
|
|||||||
while (1){
|
while (1){
|
||||||
if (ISSLASH (*s)){
|
if (ISSLASH (*s)){
|
||||||
if (*last_slash != '/')
|
if (*last_slash != '/')
|
||||||
vfs_die ("/ not there\n");
|
vfs_die ("/ not there.\n");
|
||||||
|
|
||||||
if (ISSLASH (last_slash [1]))
|
if (ISSLASH (last_slash [1]))
|
||||||
t--;
|
t--;
|
||||||
@ -839,7 +819,7 @@ int mc_chdir (char *path)
|
|||||||
result = (*current_vfs->chdir)(vfs_name (b));
|
result = (*current_vfs->chdir)(vfs_name (b));
|
||||||
free (b);
|
free (b);
|
||||||
if (result == -1){
|
if (result == -1){
|
||||||
errno = (*current_vfs->ferrno)();
|
errno = ferrno (current_vfs);
|
||||||
free (current_dir);
|
free (current_dir);
|
||||||
current_vfs = vfs_type (a);
|
current_vfs = vfs_type (a);
|
||||||
current_dir = a;
|
current_dir = a;
|
||||||
@ -911,7 +891,7 @@ void vfs_setup_wd (void)
|
|||||||
mc_return_cwd(); /* mc_return_cwd will fixup current_dir for us */
|
mc_return_cwd(); /* mc_return_cwd will fixup current_dir for us */
|
||||||
|
|
||||||
if (strlen(current_dir)>MC_MAXPATHLEN-2)
|
if (strlen(current_dir)>MC_MAXPATHLEN-2)
|
||||||
vfs_die ("Current dir too long\n");
|
vfs_die ("Current dir too long.\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -939,9 +919,9 @@ mc_mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
|
|||||||
return (caddr_t) -1;
|
return (caddr_t) -1;
|
||||||
|
|
||||||
vfs = vfs_op (fd);
|
vfs = vfs_op (fd);
|
||||||
result = (*vfs->mmap)(addr, len, prot, flags, vfs_info (fd), offset);
|
result = vfs->mmap ? (*vfs->mmap)(addr, len, prot, flags, vfs_info (fd), offset) : (caddr_t)-1;
|
||||||
if (result == (caddr_t)-1){
|
if (result == (caddr_t)-1){
|
||||||
errno = (*vfs->ferrno)();
|
errno = ferrno (vfs);
|
||||||
return (caddr_t)-1;
|
return (caddr_t)-1;
|
||||||
}
|
}
|
||||||
mcm = (struct mc_mmapping *) xmalloc (sizeof (struct mc_mmapping), "vfs: mmap handling");
|
mcm = (struct mc_mmapping *) xmalloc (sizeof (struct mc_mmapping), "vfs: mmap handling");
|
||||||
@ -963,7 +943,8 @@ int mc_munmap (caddr_t addr, size_t len)
|
|||||||
mc_mmaparray = mcm->next;
|
mc_mmaparray = mcm->next;
|
||||||
else
|
else
|
||||||
mcm2->next = mcm->next;
|
mcm2->next = mcm->next;
|
||||||
(*mcm->vfs->munmap)(addr, len, mcm->vfs_info);
|
if (*mcm->vfs->munmap)
|
||||||
|
(*mcm->vfs->munmap)(addr, len, mcm->vfs_info);
|
||||||
free (mcm);
|
free (mcm);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1013,9 +994,8 @@ char *mc_getlocalcopy (char *path)
|
|||||||
result = vfs->getlocalcopy ? (*vfs->getlocalcopy)(vfs_name (path)) :
|
result = vfs->getlocalcopy ? (*vfs->getlocalcopy)(vfs_name (path)) :
|
||||||
mc_def_getlocalcopy (vfs_name (path));
|
mc_def_getlocalcopy (vfs_name (path));
|
||||||
free (path);
|
free (path);
|
||||||
if (result == NULL){
|
if (!result)
|
||||||
errno = ferrno (vfs);
|
errno = ferrno (vfs);
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1172,6 +1152,7 @@ void vfs_fill_names (void (*func)(char *))
|
|||||||
#endif
|
#endif
|
||||||
tarfs_fill_names (func);
|
tarfs_fill_names (func);
|
||||||
extfs_fill_names (func);
|
extfs_fill_names (func);
|
||||||
|
sfs_fill_names (func);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Following stuff (parse_ls_lga) is used by ftpfs and extfs */
|
/* Following stuff (parse_ls_lga) is used by ftpfs and extfs */
|
||||||
@ -1228,19 +1209,27 @@ static int is_time (char *str, struct tm *tim)
|
|||||||
|
|
||||||
static int is_year(char *str, struct tm *tim)
|
static int is_year(char *str, struct tm *tim)
|
||||||
{
|
{
|
||||||
|
/* Old code recognized 02904baa as year identification :-( */
|
||||||
long year;
|
long year;
|
||||||
|
|
||||||
if (!strchr(str, ':')) {
|
if (strchr(str,':'))
|
||||||
year = atol (str);
|
return 0;
|
||||||
if (year < 1900 || year > 3000)
|
if (strlen(str)!=4)
|
||||||
return (0);
|
return 0;
|
||||||
tim->tm_year = (int) (year - 1900);
|
if (sscanf(str, "%d", &year) != 1)
|
||||||
return (1);
|
return 0;
|
||||||
}
|
if (year < 1900 || year > 3000)
|
||||||
else
|
return 0;
|
||||||
return (0);
|
tim->tm_year = (int) (year - 1900);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: this is broken. Consider following entry:
|
||||||
|
-rwx------ 1 root root 1 Aug 31 10:04 2904 1234
|
||||||
|
where "2904 1234" is filename. Well, this code decodes it as year :-(.
|
||||||
|
*/
|
||||||
|
|
||||||
#define free_and_return(x) { free (p_copy); return (x); }
|
#define free_and_return(x) { free (p_copy); return (x); }
|
||||||
int parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
|
int parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
|
||||||
{
|
{
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user