1
1

Undelfs was too broken for too long.

Этот коммит содержится в:
Pavel Machek 1998-08-31 10:02:52 +00:00
родитель b95d74c493
Коммит 286c61a200
4 изменённых файлов: 163 добавлений и 235 удалений

Просмотреть файл

@ -272,6 +272,18 @@ void view_cmd (WPanel *panel)
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)
{
do_view_cmd (panel, 1);
@ -1294,9 +1306,9 @@ void source_routing (void)
void undelete_cmd (void)
{
nice_cd (_(" Undelete files on an ext2 file system "),
_(" Enter the file system name where you want to run the\n "
" undelete file system on: (F1 for details)"),
"[Undelete File System]", "/#undel/", 0);
_(" Enter device (without /dev/) to undelete\n "
" files on: (F1 for details)"),
"[Undelete File System]", "/#undel:", 0);
}
#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>
* extfs.c: mc_extfsdir was not defined in extfs_open()

Просмотреть файл

@ -26,7 +26,7 @@
/* 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
* 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
@ -86,7 +86,7 @@ static int undelfs_usage;
#define READDIR_PTR_INIT 0
static void
undelfs_shutdown ()
undelfs_shutdown (void)
{
if (fs)
ext2fs_close (fs);
@ -107,33 +107,44 @@ undelfs_get_path (char *dirname, char **ext2_fname, char **file)
{
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;
if (strncmp (dirname, "undel:", 6))
if (strncmp (dirname, "/#undel:", 8))
return;
else
dirname += 6;
dirname += 8;
/* 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)
return;
p = dirname + strlen (dirname);
#if 0
/* Strip trailing ./
*/
if (p - dirname > 2 && *(p-1) == '/' && *(p-2) == '.')
*(p = p-2) = 0;
#endif
while (p > dirname){
if (*p == '/'){
*file = strdup (p+1);
*p = 0;
*ext2_fname = strdup (dirname);
*ext2_fname = copy_strings ("/dev/", dirname, NULL);
*p = '/';
return;
}
p--;
}
*file = strdup ("");
*ext2_fname = copy_strings ("/dev/", dirname, NULL);
return;
}
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
*/
static int
undelfs_loaddel ()
undelfs_loaddel (void)
{
int retval, count;
ino_t ino;
@ -519,13 +530,6 @@ undelfs_read (void *vfs_info, char *buffer, int count)
return p->dest_buffer - buffer;
}
static int
undelfs_write (void *vfs_info, char *buf, int count)
{
/* No writes allowed */
return -1;
}
static long
undelfs_getindex (char *path)
{
@ -608,48 +612,6 @@ undelfs_fstat (void *vfs_info, struct stat *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
undelfs_chdir(char *path)
{
@ -675,24 +637,13 @@ undelfs_chdir(char *path)
return 0;
}
static int
undelfs_ferrno(void)
{
return -1;
}
/* this has to stay here for now: vfs layer does not know how to emulate it */
static int
undelfs_lseek(void *vfs_info, off_t offset, int whence)
{
return -1;
}
static int
undelfs_mknod(char *path, int mode, int dev)
{
return -1;
}
static vfsid
undelfs_getid(char *path, struct vfs_stamping **parent)
{
@ -721,50 +672,11 @@ undelfs_free(vfsid id)
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 = {
undelfs_open,
undelfs_close,
undelfs_read,
undelfs_write,
NULL,
undelfs_opendir,
undelfs_readdir,
@ -776,35 +688,35 @@ vfs undelfs_vfs_ops = {
undelfs_lstat,
undelfs_fstat,
undelfs_chmod,
undelfs_chown,
NULL,
NULL,
NULL,
undelfs_readlink,
undelfs_symlink,
undelfs_link,
undelfs_unlink,
NULL, /* readlink */
NULL,
NULL,
NULL,
undelfs_rename,
NULL,
undelfs_chdir,
undelfs_ferrno,
undelfs_lseek,
undelfs_mknod,
NULL,
undelfs_lseek,
NULL,
undelfs_getid,
undelfs_nothingisopen,
undelfs_free,
undelfs_getlocalcopy,
undelfs_ungetlocalcopy,
NULL, /* get_local_copy */
NULL,
undelfs_mkdir,
undelfs_rmdir,
NULL,
NULL,
NULL,
NULL,
NULL
#ifdef HAVE_MMAP
, undelfs_mmap,
undelfs_munmap
, NULL,
NULL
#endif
};

203
vfs/vfs.c
Просмотреть файл

@ -108,7 +108,7 @@ vfs *vfs_type_from_op (char *path)
return &ftpfs_vfs_ops;
#endif
#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;
#endif
if (!(vfs_flags & FL_NO_TARFS) && !strcmp (path, "utar"))
@ -309,7 +309,7 @@ int mc_open (char *file, int flags, ...)
va_end (ap);
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 */
free (file);
if (!info){
@ -337,12 +337,14 @@ int mc_open (char *file, int flags, ...)
result = vfs->name ? (*vfs->name)callarg : -1; \
post \
if (result == -1) \
errno = ferrno (vfs); \
errno = vfs->name ? ferrno (vfs) : EOPNOTSUPP; \
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_HANDLEOP(name, inarg, callarg) MC_OP (name, inarg, callarg, if (handle == -1) return -1; vfs = vfs_op (handle);, )
#define MC_NAMEOP(name, inarg, callarg) \
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) );
@ -380,7 +382,9 @@ int mc_close (int handle)
if (handle < 3)
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);
if (result == -1)
errno = ferrno (vfs);
@ -408,19 +412,16 @@ DIR *mc_opendir (char *dirname)
info = vfs->opendir ? (*vfs->opendir)(dirname) : NULL;
free (dirname);
if (p)
free (p);
if (!info){
errno = ferrno (vfs);
if (p)
free (p);
errno = vfs->opendir ? ferrno (vfs) : EOPNOTSUPP;
return NULL;
}
handle = get_bucket ();
vfs_file_table [handle].fs_info = info;
vfs_file_table [handle].operations = vfs;
if (p)
free (p);
handlep = (int *) xmalloc (sizeof (int), "opendir handle");
*handlep = handle;
return (DIR *) handlep;
@ -429,11 +430,29 @@ DIR *mc_opendir (char *dirname)
/* This should strip the non needed part of a path name */
#define vfs_name(x) x
#define MC_DIROP(name, type, inarg, callarg, onerr ) \
type mc_##name inarg \
void mc_seekdir (DIR *dirp, int offset)
{
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; \
vfs *vfs; \
type result; \
\
if (!dirp){ \
errno = EFAULT; \
@ -441,28 +460,14 @@ type mc_##name inarg \
} \
handle = *(int *) dirp; \
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 ) \
void mc_##name inarg \
{ \
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)
MC_DIROP (readdir, struct dirent *, NULL)
MC_DIROP (telldir, int, -1)
int mc_closedir (DIR *dirp)
{
@ -514,7 +519,7 @@ char *mc_get_current_wd (char *buffer, int size)
{
char *cwd = mc_return_cwd();
if (strlen (cwd) > size){
vfs_die ("Current_dir size overflow\n");
vfs_die ("Current_dir size overflow.\n");
}
strcpy (buffer, cwd);
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 (symlink, (char *name1, char *path), (vfs_name (name1), vfs_name (path)))
int mc_link (char *name1, char *name2)
{
vfs *vfs1;
vfs *vfs2;
int result;
name1 = vfs_canon (name1);
vfs1 = vfs_type (name1);
name2 = vfs_canon (name2);
vfs2 = vfs_type (name2);
if (vfs1 != vfs2){
errno = EXDEV;
free (name1);
free (name2);
return -1;
}
result = (*vfs1->link)(vfs_name (name1), vfs_name (name2));
free (name1);
free (name2);
if (result == -1){
errno = (*vfs1->ferrno)();
return -1;
}
return result;
#define MC_RENAMEOP(name) \
int mc_##name (char *name1, char *name2) \
{ \
vfs *vfs; \
int result; \
\
name1 = vfs_canon (name1); \
vfs = vfs_type (name1); \
name2 = vfs_canon (name2); \
if (vfs != vfs_type (name2)){ \
errno = EXDEV; \
free (name1); \
free (name2); \
return -1; \
} \
\
result = vfs->name ? (*vfs->name)(vfs_name (name1), vfs_name (name2)) : -1; \
free (name1); \
free (name2); \
if (result == -1) \
errno = vfs->name ? ferrno (vfs) : EOPNOTSUPP; \
return result; \
}
MC_RENAMEOP (link);
MC_RENAMEOP (rename);
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)
{
vfs *vfs;
int result;
if (fd == -1)
return -1;
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){
if (ISSLASH (*s)){
if (*last_slash != '/')
vfs_die ("/ not there\n");
vfs_die ("/ not there.\n");
if (ISSLASH (last_slash [1]))
t--;
@ -839,7 +819,7 @@ int mc_chdir (char *path)
result = (*current_vfs->chdir)(vfs_name (b));
free (b);
if (result == -1){
errno = (*current_vfs->ferrno)();
errno = ferrno (current_vfs);
free (current_dir);
current_vfs = vfs_type (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 */
if (strlen(current_dir)>MC_MAXPATHLEN-2)
vfs_die ("Current dir too long\n");
vfs_die ("Current dir too long.\n");
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;
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){
errno = (*vfs->ferrno)();
errno = ferrno (vfs);
return (caddr_t)-1;
}
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;
else
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);
return 0;
}
@ -1013,9 +994,8 @@ char *mc_getlocalcopy (char *path)
result = vfs->getlocalcopy ? (*vfs->getlocalcopy)(vfs_name (path)) :
mc_def_getlocalcopy (vfs_name (path));
free (path);
if (result == NULL){
if (!result)
errno = ferrno (vfs);
}
return result;
}
@ -1172,6 +1152,7 @@ void vfs_fill_names (void (*func)(char *))
#endif
tarfs_fill_names (func);
extfs_fill_names (func);
sfs_fill_names (func);
}
/* 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)
{
/* Old code recognized 02904baa as year identification :-( */
long year;
if (!strchr(str, ':')) {
year = atol (str);
if (year < 1900 || year > 3000)
return (0);
tim->tm_year = (int) (year - 1900);
return (1);
}
else
return (0);
if (strchr(str,':'))
return 0;
if (strlen(str)!=4)
return 0;
if (sscanf(str, "%d", &year) != 1)
return 0;
if (year < 1900 || year > 3000)
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); }
int parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
{