mirror of https://github.com/MidnightCommander/mc
BIG changes: tar now uses brand-new direntry.c. Hope it does not hurt
too much.
This commit is contained in:
parent
96f4d6c760
commit
37e364fe67
|
@ -1,3 +1,37 @@
|
|||
Thu Oct 22 22:24:44 1998 Pavel Machek <pavel@bug.ucw.cz>
|
||||
|
||||
* README: added. If you are using emacs or hacking libvfs, please
|
||||
read this one.
|
||||
|
||||
* direntry.{c,h}: new library created, so that same entry/inode
|
||||
code does not have to be copied in every handler
|
||||
|
||||
* tar.c: converted to use direntry.c library
|
||||
|
||||
* ftpfs.c: small updates to make code look nicer
|
||||
|
||||
Mon Oct 19 19:40:58 1998 Pavel Machek <pavel@bug.ucw.cz>
|
||||
|
||||
* vfs.h (&more): killed ERRNOR() from vfs.h and put it into files
|
||||
which actually need it.
|
||||
|
||||
* extfs.c: extfs_current_dir killed - it was unneccessary.
|
||||
|
||||
* mcfs.c (mcfs_get_path): It is possible for path not to begin
|
||||
with /#mc:, for example if user does /etc/#mc:. (It is not
|
||||
correct, of course). Return error, but do not vfs_die().
|
||||
|
||||
Sun Oct 18 23:48:00 1998 Pavel Machek <pavel@bug.ucw.cz>
|
||||
|
||||
* lib/mc.ext.in: cpio support fixed. It was broken since time we
|
||||
started to do #ext syntax.
|
||||
|
||||
Sat Oct 17 20:43:20 1998 Pavel Machek <pavel@bug.ucw.cz>
|
||||
|
||||
* vfs.c (mc_open): die() if open is unsupported. If filesytem does
|
||||
not support open, it is probably stupid typo, so we want bug to be
|
||||
fixed.
|
||||
|
||||
Thu Oct 22 20:30:28 1998 Norbert Warmuth <nwarmuth@privat.circular.de>
|
||||
|
||||
* ftpfs.c (resolve_symlink, retrieve_dir): Don't timeout and
|
||||
|
|
|
@ -0,0 +1,639 @@
|
|||
/* Directory cache support -- so that you do not have copy of this in
|
||||
* each and every filesystem.
|
||||
*
|
||||
* Written at 1998 by Pavel Machek <pavel@ucw.cz>, distribute under LGPL.
|
||||
*
|
||||
* Based on tar.c from midnight and archives.[ch] from avfs by Miklos
|
||||
* Szeredi (mszeredi@inf.bme.hu) */
|
||||
|
||||
#include "direntry.h"
|
||||
|
||||
#define CALL(x) if (MEDATA->x) MEDATA->x
|
||||
|
||||
vfs_s_inode *vfs_s_new_inode (vfs *me, struct stat *initstat)
|
||||
{
|
||||
vfs_s_inode *ino;
|
||||
|
||||
ino = xmalloc(sizeof (vfs_s_inode), "Dcache inode");
|
||||
if (!ino) return NULL;
|
||||
|
||||
ino->linkname = ino->localname = NULL;
|
||||
ino->subdir = NULL;
|
||||
if (initstat)
|
||||
ino->st = *initstat;
|
||||
ino->st.st_nlink = 0;
|
||||
|
||||
CALL(init_inode) (me, ino);
|
||||
|
||||
return ino;
|
||||
}
|
||||
|
||||
vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode)
|
||||
{
|
||||
vfs_s_entry *entry;
|
||||
|
||||
entry = (struct vfs_s_entry *) xmalloc (sizeof (struct vfs_s_entry), "Dcache entry");
|
||||
|
||||
entry->name = strdup (name);
|
||||
entry->dir = NULL;
|
||||
entry->next = NULL;
|
||||
entry->prevp = NULL;
|
||||
entry->ino = inode;
|
||||
CALL(init_entry) (me, entry);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void vfs_s_free_entry (vfs *me, vfs_s_entry *ent)
|
||||
{
|
||||
*ent->prevp = ent->next;
|
||||
if (ent->next) ent->next->prevp = ent->prevp;
|
||||
|
||||
printf( "Freeing : %s\n", ent->name);
|
||||
free(ent->name);
|
||||
ent->name = NULL;
|
||||
if(ent->ino->st.st_nlink == 1) {
|
||||
CALL(free_inode) (me, ent->ino);
|
||||
ifree(ent->ino->linkname);
|
||||
ifree(ent->ino->localname);
|
||||
ifree(ent->ino);
|
||||
ent->ino = NULL;
|
||||
} else ent->ino->st.st_nlink--;
|
||||
|
||||
free(ent);
|
||||
}
|
||||
|
||||
void vfs_s_free_tree (vfs *me, vfs_s_inode *dir, vfs_s_inode *parentdir)
|
||||
{
|
||||
vfs_s_entry *ent;
|
||||
|
||||
while(dir->subdir) {
|
||||
ent = dir->subdir;
|
||||
if(ent->ino != dir && ent->ino != parentdir) vfs_s_free_tree(me, ent->ino, dir);
|
||||
vfs_s_free_entry(me, ent);
|
||||
}
|
||||
}
|
||||
|
||||
void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir, vfs_s_entry *ent)
|
||||
{
|
||||
vfs_s_entry **ep;
|
||||
|
||||
for(ep = &dir->subdir; *ep != NULL; ep = &((*ep)->next));
|
||||
ent->prevp = ep;
|
||||
ent->next = NULL;
|
||||
ent->dir = dir;
|
||||
*ep = ent;
|
||||
|
||||
ent->ino->st.st_nlink++;
|
||||
}
|
||||
|
||||
struct stat *vfs_s_default_stat (vfs *me, mode_t mode)
|
||||
{
|
||||
static struct stat st;
|
||||
int myumask;
|
||||
|
||||
myumask = umask (022);
|
||||
umask (myumask);
|
||||
mode &= ~myumask;
|
||||
|
||||
st.st_mode = mode;
|
||||
st.st_ino = MEDATA->inode_counter++;
|
||||
st.st_dev = MEDATA->rdev;
|
||||
st.st_rdev = 0;
|
||||
st.st_uid = getuid ();
|
||||
st.st_gid = getgid ();
|
||||
st.st_size = 0;
|
||||
st.st_mtime = st.st_atime = st.st_ctime = time (NULL);
|
||||
st.st_nlink = 1;
|
||||
|
||||
return &st;
|
||||
}
|
||||
|
||||
void vfs_s_add_dots (vfs *me, vfs_s_inode *dir, vfs_s_inode *parent)
|
||||
{
|
||||
struct vfs_s_entry *dot, *dotdot;
|
||||
|
||||
if (!parent)
|
||||
parent = dir;
|
||||
dot = vfs_s_new_entry (me, ".", dir);
|
||||
dot->ino = dir;
|
||||
dotdot = vfs_s_new_entry (me, "..", parent);
|
||||
dot->ino = parent;
|
||||
vfs_s_insert_entry(me, dir, dot);
|
||||
vfs_s_insert_entry(me, dir, dotdot);
|
||||
dir->st.st_nlink += 2;
|
||||
}
|
||||
|
||||
struct vfs_s_entry *vfs_s_generate_entry (vfs *me, char *name, struct vfs_s_inode *parent, mode_t mode)
|
||||
{
|
||||
struct vfs_s_inode *inode;
|
||||
struct vfs_s_entry *entry;
|
||||
struct stat *st;
|
||||
|
||||
st = vfs_s_default_stat (me, mode);
|
||||
inode = vfs_s_new_inode (me, st);
|
||||
if (S_ISDIR (mode))
|
||||
vfs_s_add_dots (me, inode, parent);
|
||||
|
||||
entry = vfs_s_new_entry (me, name, inode);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/* We were asked to create entries automagically
|
||||
*/
|
||||
vfs_s_entry *vfs_s_automake(vfs *me, vfs_s_inode *dir, char *path, int flags)
|
||||
{
|
||||
struct vfs_s_entry *res;
|
||||
char *sep = strchr( path, DIR_SEP_CHAR );
|
||||
if (sep) *sep = 0;
|
||||
res = vfs_s_generate_entry(me, path, dir, flags & FL_MKDIR ? (0777 | S_IFDIR) : 0777 );
|
||||
if (sep) *sep = DIR_SEP_CHAR;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Follow > 0: follow links, serves as loop protect,
|
||||
* == -1: do not follow links
|
||||
*/
|
||||
vfs_s_entry *vfs_s_find_entry(vfs *me, vfs_s_inode *root, char *path, int follow, int flags)
|
||||
{
|
||||
unsigned int pseg;
|
||||
vfs_s_entry* ent = NULL;
|
||||
int found;
|
||||
|
||||
while(1) {
|
||||
for(pseg = 0; path[pseg] == DIR_SEP_CHAR; pseg++);
|
||||
if(!path[pseg]) return ent;
|
||||
path += pseg;
|
||||
|
||||
for(pseg = 0; path[pseg] && path[pseg] != DIR_SEP_CHAR; pseg++);
|
||||
|
||||
found = 0;
|
||||
for(ent = root->subdir; ent != NULL; ent = ent->next)
|
||||
if(strlen(ent->name) == pseg && strncmp(ent->name, path, pseg) == 0)
|
||||
/* FOUND! */
|
||||
break;
|
||||
|
||||
if (!ent && (flags & (FL_MKFILE | FL_MKDIR)))
|
||||
ent = vfs_s_automake(me, root, path+pseg, flags);
|
||||
if (!ent) ERRNOR (ENOENT, NULL);
|
||||
path += pseg;
|
||||
if (!vfs_s_resolve_symlink(me, ent, follow)) return NULL;
|
||||
root = ent->ino;
|
||||
}
|
||||
}
|
||||
|
||||
vfs_s_inode *vfs_s_find_inode(vfs *me, vfs_s_inode *root, char *path, int follow, int flags)
|
||||
{
|
||||
vfs_s_entry *ent;
|
||||
if (!path || !path[0])
|
||||
return root;
|
||||
ent = vfs_s_find_entry(me, root, path, follow, flags);
|
||||
if (!ent)
|
||||
return NULL;
|
||||
return ent->ino;
|
||||
}
|
||||
|
||||
vfs_s_inode *vfs_s_find_root(vfs *me, vfs_s_entry *entry)
|
||||
{
|
||||
vfs_die("Implement me");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vfs_s_entry *vfs_s_resolve_symlink (vfs *me, vfs_s_entry *entry, int follow)
|
||||
{
|
||||
vfs_s_inode *dir;
|
||||
if (follow == -1)
|
||||
return entry;
|
||||
if (follow == 0)
|
||||
ERRNOR (ELOOP, NULL);
|
||||
if (!entry)
|
||||
ERRNOR (ENOENT, NULL);
|
||||
if (!S_ISLNK(entry->ino->st.st_mode))
|
||||
return entry;
|
||||
|
||||
/* We have to handle "/" by ourself; "." and ".." have
|
||||
corresponding entries, so there's no problem with them. */
|
||||
if (*entry->ino->linkname == '/') dir = vfs_s_find_root(me, entry);
|
||||
else dir = entry->dir;
|
||||
return vfs_s_find_entry (me, dir, entry->ino->linkname, follow-1, 0);
|
||||
}
|
||||
|
||||
/* Ook, these were functions around direcory entries / inodes */
|
||||
/* -------------------------------- superblock games -------------------------- */
|
||||
|
||||
vfs_s_super *vfs_s_new_super (vfs *me)
|
||||
{
|
||||
vfs_s_super *super;
|
||||
|
||||
super = xmalloc( sizeof( struct vfs_s_super ), "Direntry: superblock" );
|
||||
super->root = NULL;
|
||||
super->name = NULL;
|
||||
super->fd_usage = 0;
|
||||
super->me = me;
|
||||
|
||||
super->next = MEDATA->supers;
|
||||
super->prevp = &MEDATA->supers;
|
||||
|
||||
if (MEDATA->supers != NULL) MEDATA->supers->prevp = &super->next;
|
||||
MEDATA->supers = super;
|
||||
return super;
|
||||
}
|
||||
|
||||
void vfs_s_free_super (vfs *me, vfs_s_super *super)
|
||||
{
|
||||
if (super->root)
|
||||
vfs_s_free_tree (me, super->root, NULL);
|
||||
|
||||
*super->prevp = super->next;
|
||||
if (super->next) super->next->prevp = super->prevp;
|
||||
|
||||
CALL(free_archive) (me, super);
|
||||
free(super);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
static void vfs_s_stamp_me (vfs *me, struct vfs_s_super *psup, char *fs_name)
|
||||
{
|
||||
struct vfs_stamping *parent;
|
||||
vfs *v;
|
||||
|
||||
v = vfs_type (fs_name);
|
||||
if (v == &vfs_local_ops) {
|
||||
parent = NULL;
|
||||
} else {
|
||||
parent = xmalloc (sizeof (struct vfs_stamping), "vfs stamping");
|
||||
parent->v = v;
|
||||
parent->next = 0;
|
||||
parent->id = (*v->getid) (v, fs_name, &(parent->parent));
|
||||
}
|
||||
vfs_add_noncurrent_stamps (&vfs_tarfs_ops, (vfsid) psup, parent);
|
||||
vfs_rm_parents (parent);
|
||||
}
|
||||
|
||||
char *vfs_s_get_path_mangle (vfs *me, char *inname, struct vfs_s_super **archive, int flags)
|
||||
{
|
||||
char *local, *op, *archive_name;
|
||||
int result = -1;
|
||||
struct vfs_s_super *psup;
|
||||
void *cookie;
|
||||
|
||||
archive_name = inname;
|
||||
vfs_split( inname, &local, &op );
|
||||
if (!local)
|
||||
local = "";
|
||||
|
||||
if (! (cookie = MEDATA->archive_check (me, archive_name, op)))
|
||||
return NULL;
|
||||
|
||||
for (psup = MEDATA->supers; psup != NULL; psup = psup->next) {
|
||||
int i; /* 0 == other, 1 == same, return it, 2 == other but stop scanning */
|
||||
if ((i = MEDATA->archive_same (me, psup, archive_name, cookie))) {
|
||||
if (i==1) goto return_success;
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FL_NO_OPEN) ERRNOR (EIO, NULL);
|
||||
|
||||
psup = vfs_s_new_super (me);
|
||||
result = MEDATA->open_archive (me, psup, archive_name, op);
|
||||
if (result == -1) {
|
||||
vfs_s_free_super (me, psup);
|
||||
ERRNOR (EIO, NULL);
|
||||
}
|
||||
|
||||
vfs_s_stamp_me (me, psup, archive_name);
|
||||
|
||||
return_success:
|
||||
*archive = psup;
|
||||
return local;
|
||||
}
|
||||
|
||||
char *vfs_s_get_path (vfs *me, char *inname, struct vfs_s_super **archive, int flags)
|
||||
{
|
||||
char *buf = strdup( inname );
|
||||
char *res = vfs_s_get_path_mangle( me, buf, archive, flags );
|
||||
char *res2 = NULL;
|
||||
if (res)
|
||||
res2 = strdup(res);
|
||||
free(buf);
|
||||
return res2;
|
||||
}
|
||||
|
||||
/* Support of archives */
|
||||
/* ========================== readdir & friends ========================================= */
|
||||
|
||||
vfs_s_inode *vfs_s_inode_from_path (vfs *me, char *name, int flags)
|
||||
{
|
||||
struct vfs_s_super *super;
|
||||
char *q;
|
||||
struct vfs_s_inode *ino;
|
||||
|
||||
if (!(q = vfs_s_get_path_mangle (me, name, &super, 0)))
|
||||
return NULL;
|
||||
|
||||
ino = vfs_s_find_inode (me, super->root, q, flags & FL_FOLLOW ? FOLLOW : NO_FOLLOW, FL_NONE);
|
||||
if (ino) return ino;
|
||||
|
||||
if ((flags & FL_DIR) && MEDATA->load_dir) {
|
||||
MEDATA->load_dir (me, super, q);
|
||||
ino = vfs_s_find_inode (me, super->root, q, flags & FL_FOLLOW ? FOLLOW : NO_FOLLOW, FL_NONE);
|
||||
}
|
||||
|
||||
return ino;
|
||||
}
|
||||
|
||||
void * vfs_s_opendir (vfs *me, char *dirname)
|
||||
{
|
||||
struct vfs_s_inode *ino;
|
||||
struct vfs_s_entry **info;
|
||||
|
||||
ino = vfs_s_inode_from_path (me, dirname, FL_DIR | FL_FOLLOW);
|
||||
if (!ino) return NULL;
|
||||
if (!S_ISDIR (ino->st.st_mode)) ERRNOR (ENOTDIR, NULL);
|
||||
|
||||
info = (struct vfs_s_entry **) xmalloc (2*sizeof (struct vfs_s_entry *), "Dentry opendir");
|
||||
info[0] = ino->subdir;
|
||||
info[1] = ino->subdir;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void * vfs_s_readdir (void *data)
|
||||
{
|
||||
static struct {
|
||||
struct dirent dir;
|
||||
#ifdef NEED_EXTRA_DIRENT_BUFFER
|
||||
char extra_buffer [MC_MAXPATHLEN];
|
||||
#endif
|
||||
} dir;
|
||||
|
||||
struct vfs_s_entry **info = (struct vfs_s_entry **) data;
|
||||
|
||||
if (!*info)
|
||||
return NULL;
|
||||
|
||||
strcpy (&(dir.dir.d_name [0]), (*info)->name);
|
||||
|
||||
#ifndef DIRENT_LENGTH_COMPUTED
|
||||
dir.d_namlen = strlen (dir.dir.d_name);
|
||||
#endif
|
||||
*info = (*info)->next;
|
||||
|
||||
return (void *)&dir;
|
||||
}
|
||||
|
||||
int vfs_s_telldir (void *data)
|
||||
{
|
||||
struct vfs_s_entry **info = (struct vfs_s_entry **) data;
|
||||
struct vfs_s_entry *cur;
|
||||
int num = 0;
|
||||
|
||||
cur = info[1];
|
||||
while (cur!=NULL) {
|
||||
if (cur == info[0]) return num;
|
||||
num++;
|
||||
cur = cur->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void vfs_s_seekdir (void *data, int offset)
|
||||
{
|
||||
struct vfs_s_entry **info = (struct vfs_s_entry **) data;
|
||||
int i;
|
||||
info[0] = info[1];
|
||||
for (i=0; i<offset; i++)
|
||||
vfs_s_readdir( data );
|
||||
}
|
||||
|
||||
int vfs_s_closedir (void *data)
|
||||
{
|
||||
free (data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vfs_s_chdir (vfs *me, char *path)
|
||||
{
|
||||
void *data;
|
||||
if (!(data = vfs_s_opendir( me, path )))
|
||||
return -1;
|
||||
vfs_s_closedir(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* =========================== stat and friends ============================== */
|
||||
|
||||
static int vfs_s_internal_stat (vfs *me, char *path, struct stat *buf, int flag)
|
||||
{
|
||||
struct vfs_s_inode *ino;
|
||||
|
||||
if (!(ino = vfs_s_inode_from_path( me, path, flag ))) return -1;
|
||||
*buf = ino->st;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vfs_s_stat (vfs *me, char *path, struct stat *buf)
|
||||
{
|
||||
return vfs_s_internal_stat (me, path, buf, FL_FOLLOW);
|
||||
}
|
||||
|
||||
int vfs_s_lstat (vfs *me, char *path, struct stat *buf)
|
||||
{
|
||||
return vfs_s_internal_stat (me, path, buf, FL_NONE);
|
||||
}
|
||||
|
||||
int vfs_s_fstat (void *fh, struct stat *buf)
|
||||
{
|
||||
*buf = FH->ino->st;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vfs_s_readlink (vfs *me, char *path, char *buf, int size)
|
||||
{
|
||||
struct vfs_s_inode *ino;
|
||||
|
||||
ino = vfs_s_inode_from_path(me, path, 0);
|
||||
if (!ino) return -1;
|
||||
|
||||
if (!S_ISLNK (ino->st.st_mode)) ERRNOR (EINVAL, -1);
|
||||
strncpy (buf, ino->linkname, size);
|
||||
*(buf+size-1) = 0;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
void *vfs_s_open (vfs *me, char *file, int flags, int mode)
|
||||
{
|
||||
struct vfs_s_fh *fh;
|
||||
vfs_s_super *super;
|
||||
char *q;
|
||||
struct vfs_s_inode *ino;
|
||||
|
||||
if ((q = vfs_s_get_path_mangle (me, file, &super, 0)) == NULL)
|
||||
return NULL;
|
||||
if (!(ino = vfs_s_find_inode (me, super->root, q, FOLLOW, FL_NONE)))
|
||||
return NULL;
|
||||
if (S_ISDIR (ino->st.st_mode)) ERRNOR (EISDIR, NULL);
|
||||
if ((flags & O_ACCMODE) != O_RDONLY) ERRNOR (EROFS, NULL);
|
||||
|
||||
fh = (struct vfs_s_fh *) xmalloc (sizeof (struct vfs_s_fh), "Direntry: filehandle");
|
||||
fh->super = super;
|
||||
fh->pos = 0;
|
||||
fh->ino = ino;
|
||||
fh->handle = -1;
|
||||
if (MEDATA->fh_open)
|
||||
if (MEDATA->fh_open (me, fh)) {
|
||||
free(fh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* i.e. we had no open files and now we have one */
|
||||
vfs_rmstamp (&vfs_tarfs_ops, (vfsid) super, 1);
|
||||
super->fd_usage++;
|
||||
return fh;
|
||||
}
|
||||
|
||||
int vfs_s_lseek (void *fh, off_t offset, int whence)
|
||||
{
|
||||
off_t size = FH->ino->st.st_size;
|
||||
switch (whence) {
|
||||
case SEEK_CUR:
|
||||
offset += FH->pos; break;
|
||||
case SEEK_END:
|
||||
offset += size; break;
|
||||
}
|
||||
if (offset < 0)
|
||||
FH->pos = 0;
|
||||
else if (offset < size)
|
||||
FH->pos = offset;
|
||||
else
|
||||
FH->pos = size;
|
||||
return FH->pos;
|
||||
}
|
||||
|
||||
int vfs_s_close (void *fh)
|
||||
{
|
||||
vfs *me = FH->super->me;
|
||||
|
||||
FH->super->fd_usage--;
|
||||
if (!FH->super->fd_usage) {
|
||||
struct vfs_stamping *parent;
|
||||
vfs *v;
|
||||
|
||||
v = vfs_type (FH->super->name);
|
||||
if (v == &vfs_local_ops) {
|
||||
parent = NULL;
|
||||
} else {
|
||||
parent = xmalloc (sizeof (struct vfs_stamping), "vfs stamping");
|
||||
parent->v = v;
|
||||
parent->next = 0;
|
||||
parent->id = (*v->getid) (v, FH->super->name, &(parent->parent));
|
||||
}
|
||||
vfs_add_noncurrent_stamps (&vfs_tarfs_ops, (vfsid) (FH->super), parent);
|
||||
vfs_rm_parents (parent);
|
||||
}
|
||||
CALL(fh_close) (me, fh);
|
||||
if (FH->handle)
|
||||
mc_close(FH->handle);
|
||||
|
||||
free (fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------- mc support ---------------------------- */
|
||||
|
||||
void vfs_s_fill_names (vfs *me, void (*func)(char *))
|
||||
{
|
||||
struct vfs_s_super *a = MEDATA->supers;
|
||||
char *name;
|
||||
|
||||
while (a){
|
||||
name = copy_strings ( a->name, "#", me->prefix, "/",
|
||||
/* a->current_dir->name, */ 0);
|
||||
(*func)(name);
|
||||
free (name);
|
||||
a = a->next;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
vfs_s_ferrno(vfs *me)
|
||||
{
|
||||
return me->verrno;
|
||||
}
|
||||
|
||||
void
|
||||
vfs_s_dump(vfs *me, char *prefix, vfs_s_inode *ino)
|
||||
{
|
||||
printf( "%s %s %d ", prefix, S_ISDIR(ino->st.st_mode) ? "DIR" : "FILE", ino->st.st_mode );
|
||||
if (!ino->subdir) printf ("FILE\n");
|
||||
else
|
||||
{
|
||||
struct vfs_s_entry *ent;
|
||||
ent = ino->subdir;
|
||||
while(ent) {
|
||||
char *s;
|
||||
s = copy_strings(prefix, "/", ent->name, NULL );
|
||||
if (ent->name[0] == '.')
|
||||
printf("%s IGNORED\n", s);
|
||||
else
|
||||
vfs_s_dump(me, s, ent->ino);
|
||||
free(s);
|
||||
ent = ent->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *vfs_s_getlocalcopy (vfs *me, char *path)
|
||||
{
|
||||
struct vfs_s_inode *ino;
|
||||
char buf[MC_MAXPATHLEN];
|
||||
|
||||
strcpy( buf, path );
|
||||
ino = vfs_s_inode_from_path (me, path, FL_FOLLOW | FL_NONE);
|
||||
|
||||
if (!ino->localname)
|
||||
ino->localname = mc_def_getlocalcopy (me, buf);
|
||||
return ino->localname;
|
||||
}
|
||||
|
||||
/* ----------------------------- Stamping support ----------------------------- */
|
||||
|
||||
vfsid vfs_s_getid (vfs *me, char *path, struct vfs_stamping **parent)
|
||||
{
|
||||
vfs_s_super *archive;
|
||||
vfs *v;
|
||||
char *p;
|
||||
vfsid id;
|
||||
struct vfs_stamping *par;
|
||||
|
||||
*parent = NULL;
|
||||
if (!(p = vfs_s_get_path (me, path, &archive, FL_NO_OPEN)))
|
||||
return (vfsid) -1;
|
||||
free(p);
|
||||
v = vfs_type (archive->name);
|
||||
id = (*v->getid) (v, archive->name, &par);
|
||||
if (id != (vfsid)-1) {
|
||||
*parent = xmalloc (sizeof (struct vfs_stamping), "vfs stamping");
|
||||
(*parent)->v = v;
|
||||
(*parent)->id = id;
|
||||
(*parent)->parent = par;
|
||||
(*parent)->next = NULL;
|
||||
}
|
||||
return (vfsid) archive;
|
||||
}
|
||||
|
||||
int vfs_s_nothingisopen (vfsid id)
|
||||
{
|
||||
if (((vfs_s_super *)id)->fd_usage <= 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vfs_s_free (vfsid id)
|
||||
{
|
||||
vfs_s_free_super (((vfs_s_super *)id)->me, (vfs_s_super *)id);
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
#ifndef DIRENTRY_H
|
||||
#define DIRENTRY_H
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../src/fs.h"
|
||||
#include "../src/util.h"
|
||||
#include "../src/mem.h"
|
||||
#include "../src/mad.h"
|
||||
#include "vfs.h"
|
||||
|
||||
|
||||
#define FOLLOW 15
|
||||
#define NO_FOLLOW -1
|
||||
|
||||
/* For vfs_s_find_entry */
|
||||
#define FL_NONE 0
|
||||
#define FL_MKDIR 1
|
||||
#define FL_MKFILE 2
|
||||
|
||||
/* For open_super */
|
||||
#define FL_NO_OPEN 1
|
||||
|
||||
/* For vfs_s_entry_from_path */
|
||||
#define FL_FOLLOW 1
|
||||
#define FL_DIR 2
|
||||
|
||||
typedef struct vfs_s_entry {
|
||||
struct vfs_s_entry **prevp, *next;
|
||||
struct vfs_s_inode *dir; /* Directory we are in - FIXME: is this needed? */
|
||||
char *name; /* Name of this entry */
|
||||
struct vfs_s_inode *ino; /* ... and its inode */
|
||||
} vfs_s_entry;
|
||||
|
||||
typedef struct vfs_s_inode {
|
||||
struct vfs_s_entry *subdir;
|
||||
struct stat st; /* Parameters of this inode */
|
||||
char *linkname; /* Symlink's contents */
|
||||
char *localname; /* filename of local file, if we have one */
|
||||
|
||||
union {
|
||||
struct {
|
||||
long data_offset;
|
||||
} tar;
|
||||
} u;
|
||||
} vfs_s_inode;
|
||||
|
||||
typedef struct vfs_s_super {
|
||||
struct vfs_s_super **prevp, *next;
|
||||
vfs *me;
|
||||
vfs_s_inode *root;
|
||||
char *name; /* My name, whatever it means */
|
||||
int fd_usage; /* Usage count of this superblock */
|
||||
|
||||
union {
|
||||
struct {
|
||||
int fd;
|
||||
struct stat tarstat;
|
||||
} tar;
|
||||
} u;
|
||||
} vfs_s_super;
|
||||
|
||||
typedef struct vfs_s_fh {
|
||||
struct vfs_s_super *super; /* Is this field needed? */
|
||||
struct vfs_s_inode *ino;
|
||||
long pos; /* This is for module's use */
|
||||
int handle; /* This is for module's use, but if != -1, will be mc_close()d */
|
||||
} vfs_s_fh;
|
||||
|
||||
struct vfs_s_data {
|
||||
struct vfs_s_super *supers;
|
||||
int inode_counter;
|
||||
dev_t rdev;
|
||||
|
||||
int (*init_inode) (vfs *me, vfs_s_inode *ino);
|
||||
void (*free_inode) (vfs *me, vfs_s_inode *ino);
|
||||
int (*init_entry) (vfs *me, vfs_s_entry *entry);
|
||||
|
||||
void* (*archive_check) (vfs *me, char *name, char *op);
|
||||
int (*archive_same) (vfs *me, vfs_s_super *psup, char *archive_name, void *cookie);
|
||||
int (*open_archive) (vfs *me, vfs_s_super *psup, char *archive_name, char *op);
|
||||
void (*free_archive) (vfs *me, vfs_s_super *psup);
|
||||
|
||||
int (*load_dir) (vfs *me, vfs_s_super *super, char *q);
|
||||
|
||||
int (*fh_open) (vfs *me, vfs_s_fh *fh);
|
||||
int (*fh_close) (vfs *me, vfs_s_fh *fh);
|
||||
};
|
||||
|
||||
/* entries and inodes */
|
||||
vfs_s_inode *vfs_s_new_inode (vfs *me, struct stat *initstat);
|
||||
vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode);
|
||||
void vfs_s_free_entry (vfs *me, vfs_s_entry *ent);
|
||||
void vfs_s_free_tree (vfs *me, vfs_s_inode *dir, vfs_s_inode *parentdir);
|
||||
void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir, vfs_s_entry *ent);
|
||||
struct stat *vfs_s_default_stat (vfs *me, mode_t mode);
|
||||
void vfs_s_add_dots (vfs *me, vfs_s_inode *dir, vfs_s_inode *parent);
|
||||
struct vfs_s_entry *vfs_s_generate_entry (vfs *me, char *name, struct vfs_s_inode *parent, mode_t mode);
|
||||
vfs_s_entry *vfs_s_automake(vfs *me, vfs_s_inode *dir, char *path, int flags);
|
||||
vfs_s_entry *vfs_s_find_entry(vfs *me, vfs_s_inode *root, char *path, int follow, int flags);
|
||||
vfs_s_inode *vfs_s_find_inode(vfs *me, vfs_s_inode *root, char *path, int follow, int flags);
|
||||
vfs_s_inode *vfs_s_find_root(vfs *me, vfs_s_entry *entry);
|
||||
struct vfs_s_entry *vfs_s_resolve_symlink (vfs *me, struct vfs_s_entry *entry, int follow);
|
||||
/* superblock games */
|
||||
vfs_s_super *vfs_s_new_super (vfs *me);
|
||||
void vfs_s_free_super (vfs *me, vfs_s_super *super);
|
||||
/* outside interface */
|
||||
char *vfs_s_get_path_mangle (vfs *me, char *inname, struct vfs_s_super **archive, int flags);
|
||||
char *vfs_s_get_path (vfs *me, char *inname, struct vfs_s_super **archive, int flags);
|
||||
/* readdir & friends */
|
||||
vfs_s_inode *vfs_s_inode_from_path (vfs *me, char *name, int flags);
|
||||
void * vfs_s_opendir (vfs *me, char *dirname);
|
||||
void * vfs_s_readdir (void *data);
|
||||
int vfs_s_telldir (void *data);
|
||||
void vfs_s_seekdir (void *data, int offset);
|
||||
int vfs_s_closedir (void *data);
|
||||
int vfs_s_chdir (vfs *me, char *path);
|
||||
/* stat & friends */
|
||||
int vfs_s_stat (vfs *me, char *path, struct stat *buf);
|
||||
int vfs_s_lstat (vfs *me, char *path, struct stat *buf);
|
||||
int vfs_s_fstat (void *fh, struct stat *buf);
|
||||
int vfs_s_readlink (vfs *me, char *path, char *buf, int size);
|
||||
void *vfs_s_open (vfs *me, char *file, int flags, int mode);
|
||||
int vfs_s_lseek (void *fh, off_t offset, int whence);
|
||||
int vfs_s_close (void *fh);
|
||||
/* mc support */
|
||||
void vfs_s_fill_names (vfs *me, void (*func)(char *));
|
||||
int vfs_s_ferrno(vfs *me);
|
||||
void vfs_s_dump(vfs *me, char *prefix, vfs_s_inode *ino);
|
||||
char *vfs_s_getlocalcopy (vfs *me, char *path);
|
||||
/* stamping support */
|
||||
vfsid vfs_s_getid (vfs *me, char *path, struct vfs_stamping **parent);
|
||||
int vfs_s_nothingisopen (vfsid id);
|
||||
void vfs_s_free (vfsid id);
|
||||
|
||||
/* If non-null, FREE */
|
||||
#define ifree(ptr) do { if (ptr) free(ptr); } while (0)
|
||||
|
||||
#define MEDATA ((struct vfs_s_data *) me->data)
|
||||
#define ERRNOR(a, b) do { me->verrno = a; return b; } while (0)
|
||||
#define FH ((struct vfs_s_fh *) fh)
|
||||
|
||||
#endif
|
12
vfs/extfs.c
12
vfs/extfs.c
|
@ -47,6 +47,8 @@
|
|||
#include "vfs.h"
|
||||
#include "extfs.h"
|
||||
|
||||
#define ERRNOR(x,y) do { my_errno = x; return y; } while(0)
|
||||
|
||||
static struct entry *
|
||||
find_entry (struct entry *dir, char *name, int make_dirs, int make_file);
|
||||
static int extfs_which (vfs *me, char *path);
|
||||
|
@ -54,8 +56,6 @@ static int extfs_which (vfs *me, char *path);
|
|||
static struct archive *first_archive = NULL;
|
||||
static int my_errno = 0;
|
||||
static struct stat hstat; /* Stat struct corresponding */
|
||||
static char *current_file_name, *current_link_name;
|
||||
static char *extfs_current_dir;
|
||||
|
||||
#define MAXEXTFS 32
|
||||
static char *extfs_prefixes [MAXEXTFS];
|
||||
|
@ -267,6 +267,8 @@ static int read_archive (int fstype, char *name, struct archive **pparc)
|
|||
FILE *extfsd;
|
||||
char *buffer;
|
||||
struct archive *current_archive;
|
||||
char *current_file_name, *current_link_name;
|
||||
|
||||
|
||||
if ((extfsd = open_archive (fstype, name, ¤t_archive)) == NULL) {
|
||||
message_3s (1, MSG_ERROR, _("Couldn't open %s archive\n%s"),
|
||||
|
@ -752,9 +754,6 @@ static int extfs_chdir (vfs *me, char *path)
|
|||
entry->inode->archive->name, "#", extfs_prefixes [entry->inode->archive->fstype],
|
||||
"/", q, NULL);
|
||||
my_errno = 0;
|
||||
if (extfs_current_dir)
|
||||
free (extfs_current_dir);
|
||||
extfs_current_dir = res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -950,9 +949,6 @@ static void extfs_done (vfs *me)
|
|||
for (i = 0; i < extfs_no; i++ )
|
||||
free (extfs_prefixes [i]);
|
||||
extfs_no = 0;
|
||||
if (extfs_current_dir)
|
||||
free (extfs_current_dir);
|
||||
extfs_current_dir = 0;
|
||||
}
|
||||
|
||||
static int extfs_setctl (vfs *me, char *path, int ctlop, char *arg)
|
||||
|
|
|
@ -75,6 +75,8 @@
|
|||
# define MAXHOSTNAMELEN 64
|
||||
#endif
|
||||
|
||||
#define ERRNOR(x,y) do { my_errno = x; return y; } while(0)
|
||||
|
||||
/*
|
||||
* Reply codes.
|
||||
*/
|
||||
|
@ -582,7 +584,7 @@ store_file(struct direntry *fe)
|
|||
|
||||
fstat(local_handle, &s);
|
||||
|
||||
/* Use this as stor: ( dd block ; dd malyblock ) | ( cat > file; cat > /dev/null ) */
|
||||
/* Use this as stor: ( dd block ; dd smallblock ) | ( cat > file; cat > /dev/null ) */
|
||||
|
||||
print_vfs_message("FISH: store: sending command..." );
|
||||
if (command (fe->bucket, WAIT_REPLY,
|
||||
|
|
59
vfs/ftpfs.c
59
vfs/ftpfs.c
|
@ -92,6 +92,7 @@
|
|||
# define MAXHOSTNAMELEN 64
|
||||
#endif
|
||||
|
||||
#define ERRNOR(x,y) do { my_errno = x; return y; } while(0)
|
||||
#define UPLOAD_ZERO_LENGTH_FILE
|
||||
|
||||
static int my_errno;
|
||||
|
@ -369,38 +370,17 @@ login_server (struct connection *bucket, char *netrcpass)
|
|||
#if defined(HSC_PROXY)
|
||||
if (qproxy(bucket)) {
|
||||
print_vfs_message("ftpfs: sending proxy login name");
|
||||
if (command (bucket, 1, "USER %s", proxyname) == CONTINUE) {
|
||||
print_vfs_message("ftpfs: sending proxy user password");
|
||||
if (command (bucket, 1, "PASS %s", proxypass) == COMPLETE)
|
||||
{
|
||||
print_vfs_message("ftpfs: proxy authentication succeeded");
|
||||
if (command (bucket, 1, "SITE %s", qhost(bucket)+1) ==
|
||||
COMPLETE) {
|
||||
print_vfs_message("ftpfs: connected to %s", qhost(bucket)+1);
|
||||
}
|
||||
else {
|
||||
bucket->failed_on_login = 1;
|
||||
/* my_errno = E; */
|
||||
if (proxypass)
|
||||
wipe_password (proxypass);
|
||||
wipe_password (pass);
|
||||
free (proxyname);
|
||||
free (name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bucket->failed_on_login = 1;
|
||||
/* my_errno = E; */
|
||||
if (proxypass)
|
||||
wipe_password (proxypass);
|
||||
wipe_password (pass);
|
||||
free (proxyname);
|
||||
free (name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (command (bucket, 1, "USER %s", proxyname) != CONTINUE)
|
||||
goto proxyfail;
|
||||
print_vfs_message("ftpfs: sending proxy user password");
|
||||
if (command (bucket, 1, "PASS %s", proxypass) != COMPLETE)
|
||||
goto proxyfail;
|
||||
print_vfs_message("ftpfs: proxy authentication succeeded");
|
||||
if (command (bucket, 1, "SITE %s", qhost(bucket)+1) != COMPLETE)
|
||||
goto proxyfail;
|
||||
print_vfs_message("ftpfs: connected to %s", qhost(bucket)+1);
|
||||
if (0) {
|
||||
proxyfail:
|
||||
bucket->failed_on_login = 1;
|
||||
/* my_errno = E; */
|
||||
if (proxypass)
|
||||
|
@ -408,7 +388,7 @@ login_server (struct connection *bucket, char *netrcpass)
|
|||
wipe_password (pass);
|
||||
free (proxyname);
|
||||
free (name);
|
||||
return 0;
|
||||
ERRNOR (EPERM, 0);
|
||||
}
|
||||
if (proxypass)
|
||||
wipe_password (proxypass);
|
||||
|
@ -437,19 +417,14 @@ login_server (struct connection *bucket, char *netrcpass)
|
|||
wipe_password (bucket->password);
|
||||
bucket->password = 0;
|
||||
|
||||
/* This matches the end of the code below, just to make it
|
||||
* obvious to the optimizer
|
||||
*/
|
||||
wipe_password (pass);
|
||||
free (name);
|
||||
return 0;
|
||||
goto login_fail;
|
||||
}
|
||||
}
|
||||
print_vfs_message ("ftpfs: Login incorrect for user %s ", quser(bucket));
|
||||
my_errno = EPERM;
|
||||
login_fail:
|
||||
wipe_password (pass);
|
||||
free (name);
|
||||
return 0;
|
||||
ERRNOR (EPERM, 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SETSOCKOPT
|
||||
|
@ -1487,7 +1462,7 @@ ftpfs_init_passwd(void)
|
|||
return;
|
||||
|
||||
if ((passwd_info = getpwuid (geteuid ())) == NULL)
|
||||
p = "guest";
|
||||
p = "unknown";
|
||||
else
|
||||
p = passwd_info->pw_name;
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
|
|
10
vfs/mcfs.c
10
vfs/mcfs.c
|
@ -363,9 +363,8 @@ static char *mcfs_get_path (mcfs_connection **mc, char *path)
|
|||
int port;
|
||||
|
||||
/* An absolute path name, try to determine connection socket */
|
||||
if (strncmp (path, "/#mc:", 5)) {
|
||||
vfs_die( "Mcfs: this should not happen.\n" );
|
||||
}
|
||||
if (strncmp (path, "/#mc:", 5))
|
||||
return NULL;
|
||||
path += 5;
|
||||
|
||||
/* Port = 0 means that open_tcp_link will try to contact the
|
||||
|
@ -1078,9 +1077,8 @@ my_forget (char *path)
|
|||
char *host, *user, *pass, *p;
|
||||
int port, i, vers;
|
||||
|
||||
if (strncmp (path, "/#mc:", 5)) {
|
||||
vfs_die( "Mcfs: this should not happen.\n" );
|
||||
}
|
||||
if (strncmp (path, "/#mc:", 5))
|
||||
return NULL;
|
||||
path += 5;
|
||||
if (path[0] == '/' && path[1] == '/')
|
||||
path += 2;
|
||||
|
|
10
vfs/sfs.c
10
vfs/sfs.c
|
@ -7,8 +7,10 @@
|
|||
* inside. It is somehow similar to extfs, except that extfs makes
|
||||
* whole virtual trees and we do only single virtual files.
|
||||
*
|
||||
* Namespace: exports vfs_sfs_ops, shell (FIXME)
|
||||
*/
|
||||
* If you want to gunzip something, you should open it with #ugz
|
||||
* suffix, DON'T try to gunzip it yourself.
|
||||
*
|
||||
* Namespace: exports vfs_sfs_ops, shell (FIXME) */
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
|
@ -97,7 +99,6 @@ static int vfmake( vfs *me, char *name, char *cache )
|
|||
return 0; /* OK */
|
||||
}
|
||||
|
||||
#define CUR (*cur)
|
||||
static char *redirect( vfs *me, char *name )
|
||||
{
|
||||
struct cachedfile *cur = head;
|
||||
|
@ -131,7 +132,6 @@ static char *redirect( vfs *me, char *name )
|
|||
return cache;
|
||||
} else {
|
||||
free(xname);
|
||||
fprintf( stderr, "vfmake failed\n" );
|
||||
}
|
||||
return "/I_MUST_NOT_EXIST";
|
||||
}
|
||||
|
@ -194,6 +194,7 @@ static int sfs_readlink (vfs *me, char *path, char *buf, int size)
|
|||
return readlink (path, buf, size);
|
||||
}
|
||||
|
||||
#define CUR (*cur)
|
||||
static vfsid sfs_getid (vfs *me, char *path, struct vfs_stamping **parent)
|
||||
{ /* FIXME: what should I do? */
|
||||
vfs *v;
|
||||
|
@ -234,6 +235,7 @@ static void sfs_free (vfsid id)
|
|||
struct cachedfile *which = (struct cachedfile *) id;
|
||||
struct cachedfile **cur = &head;
|
||||
|
||||
message_1s(1, "%s", "Freeing sfs file" );
|
||||
unlink( CUR->cache );
|
||||
while (CUR) {
|
||||
if (CUR == which)
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* Large portions of tar.c & extfs.c were nearly same. I killed this
|
||||
* redundancy, so code is maintainable, again.
|
||||
*
|
||||
* Actually, tar no longer uses this code :-).
|
||||
*
|
||||
* 1998 Pavel Machek
|
||||
*
|
||||
* Namespace: no pollution.
|
||||
|
|
79
vfs/tar.h
79
vfs/tar.h
|
@ -154,82 +154,3 @@ union record {
|
|||
* output to the output of 4.2BSD tar, for debugging.
|
||||
*/
|
||||
#define f_standard (!f_oldarch)
|
||||
|
||||
#ifndef TAR_NAMES
|
||||
|
||||
struct inode;
|
||||
|
||||
struct entry {
|
||||
int has_changed;
|
||||
long header_offset; /* -1 if not in stored in archive */
|
||||
int header_size;
|
||||
struct entry *next_in_dir;
|
||||
struct entry *dir;
|
||||
long extended_offset; /* -1 if not present */
|
||||
int extended_size;
|
||||
|
||||
char *name;
|
||||
struct inode *inode;
|
||||
};
|
||||
|
||||
struct archive;
|
||||
|
||||
struct inode {
|
||||
int has_changed;
|
||||
int is_open;
|
||||
nlink_t nlink;
|
||||
struct entry *first_in_subdir; /* only used if linkflag == L_DIR */
|
||||
struct entry *last_in_subdir;
|
||||
long data_offset;
|
||||
char *local_filename;
|
||||
ino_t inode; /* This is inode # */
|
||||
dev_t dev; /* This is an internal identification of the tar archive */
|
||||
struct archive *archive; /* And this is an archive structure */
|
||||
dev_t rdev;
|
||||
int std; /* 0 if old Unix inode */
|
||||
|
||||
umode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int size;
|
||||
time_t mtime;
|
||||
char linkflag;
|
||||
char *linkname;
|
||||
time_t atime;
|
||||
time_t ctime;
|
||||
};
|
||||
|
||||
struct archive {
|
||||
char *name;
|
||||
struct stat tarstat;
|
||||
int is_gzipped;
|
||||
dev_t rdev;
|
||||
ino_t __inode_counter;
|
||||
struct entry *root_entry;
|
||||
struct entry *current_dir;
|
||||
struct archive *next;
|
||||
long current_tar_position;
|
||||
int fd;
|
||||
int fd_usage; /* Zero means fd is invalid, otherwise is number of
|
||||
pseudofiles that have the archive open */
|
||||
char *tmpname; /* For case of is_gzipped == 2 */
|
||||
/* This part is only for gzipped archives: (growable buffers) */
|
||||
union record *block_first;
|
||||
int count_first; /* In records */
|
||||
union record **block_ptr;
|
||||
int count_blocks; /* In blocks */
|
||||
union record *current_record; /* position when reading */
|
||||
};
|
||||
|
||||
/* This constant determines how many RECORDSIZE blocks are in one growing
|
||||
chunk */
|
||||
#define TAR_GROWING_CHUNK_SIZE 64
|
||||
|
||||
enum {
|
||||
tar_normal,
|
||||
targz_growing,
|
||||
tar_uncompressed_local
|
||||
};
|
||||
|
||||
#endif /* ! TAR_NAMES */
|
||||
|
||||
|
|
|
@ -386,7 +386,7 @@ mc_open (char *file, int flags, ...)
|
|||
va_end (ap);
|
||||
|
||||
if (!vfs->open)
|
||||
return -1;
|
||||
vfs_die ("VFS must support open.\n");
|
||||
|
||||
info = (*vfs->open) (vfs, file, flags, mode); /* open must be supported */
|
||||
free (file);
|
||||
|
@ -1225,7 +1225,6 @@ vfs_shut (void)
|
|||
if (current_dir)
|
||||
free (current_dir);
|
||||
|
||||
|
||||
for (vfs=vfs_list; vfs; vfs=vfs->next)
|
||||
if (vfs->done)
|
||||
(*vfs->done) (vfs);
|
||||
|
|
|
@ -37,7 +37,7 @@ struct utimbuf {
|
|||
/*
|
||||
* Notice: Andrej Borsenkow <borsenkow.msk@sni.de> reports system
|
||||
* (RelianUNIX), where it is bad idea to define struct vfs. That system
|
||||
* umust include called <sys/vfs.h>, which contains things like vfs_t.
|
||||
* has include called <sys/vfs.h>, which contains things like vfs_t.
|
||||
*/
|
||||
|
||||
typedef struct _vfs vfs;
|
||||
|
@ -48,7 +48,7 @@ struct utimbuf {
|
|||
int flags;
|
||||
#define F_EXEC 1
|
||||
#define F_NET 2
|
||||
char *prefix; /* "#fish:" */
|
||||
char *prefix; /* "fish:" */
|
||||
void *data; /* this is for filesystem's own use */
|
||||
int verrno; /* can't use errno because glibc2 might define errno as function */
|
||||
|
||||
|
@ -350,8 +350,6 @@ extern void mc_vfs_init( void );
|
|||
extern void mc_vfs_done( void );
|
||||
#endif
|
||||
|
||||
#define ERRNOR(x,y) do { my_errno = x; return y; } while(0)
|
||||
|
||||
#define O_ALL (O_CREAT | O_EXCL | O_NOCTTY | O_NDELAY | O_SYNC | O_WRONLY | O_RDWR | O_RDONLY)
|
||||
/* Midnight commander code should _not_ use other flags than those
|
||||
listed above and O_APPEND */
|
||||
|
@ -391,4 +389,6 @@ extern void mc_vfs_done( void );
|
|||
#define MMAPNULL
|
||||
#endif
|
||||
|
||||
#define DIR_SEP_CHAR '/'
|
||||
|
||||
#endif /* __VFS_H */
|
||||
|
|
Loading…
Reference in New Issue