Added vfs_uid for use by libvfs.so users (rpc.nfsd)

Added single file filesystem (sfs)
Added vfs_flags so library users can disable selected filesystems
Minor shuffling of functions so garbage collection works for library
This commit is contained in:
Pavel Machek 1998-08-25 16:00:16 +00:00
parent e3121ab349
commit 3d0a91d4a8
12 changed files with 658 additions and 25 deletions

View File

@ -95,7 +95,8 @@ distclean:
rm -f $(srcdir)/mcfn_install rm -f $(srcdir)/mcfn_install
@for I in $(alldirs); do cd $$I; $(MAKE) $@ || exit 1; cd ..; done @for I in $(alldirs); do cd $$I; $(MAKE) $@ || exit 1; cd ..; done
rm -f $(srcdir)/Makefile $(srcdir)/Make.common rm -f $(srcdir)/Makefile $(srcdir)/Make.common
rm -f lib/mc.ext mcfn_install vfs/extfs/ftplist vfs/extfs/zip vfs/extfs/zoo vfs/extfs/lslR vfs/extfs/lha vfs/extfs/cpio vfs/extfs/deb vfs/extfs/rar rm -f lib/mc.ext mcfn_install
rm -f vfs/extfs/{ftplist,uzip,uzoo,lslR,ulha,ucpio,deb,urar,uar}
rm -f $(srcdir)/config.log $(srcdir)/config.status rm -f $(srcdir)/config.log $(srcdir)/config.status
distdirs: distdirs:

View File

@ -107,6 +107,7 @@ void my_putenv (char*, char*);
#define EXECUTE_INTERNAL 1 #define EXECUTE_INTERNAL 1
#define EXECUTE_TEMPFILE 2 #define EXECUTE_TEMPFILE 2
#define EXECUTE_AS_SHELL 4 #define EXECUTE_AS_SHELL 4
#define EXECUTE_SETUID 8
int my_system (int flags, const char *shell, const char *command); int my_system (int flags, const char *shell, const char *command);
int my_system_get_child_pid (int flags, const char *shell, const char *command, pid_t *pid); int my_system_get_child_pid (int flags, const char *shell, const char *command, pid_t *pid);
void save_stop_handler (void); void save_stop_handler (void);

View File

@ -283,8 +283,10 @@ int my_system (int flags, const char *shell, const char *command)
#if 0 #if 0
prepare_environment (); prepare_environment ();
#endif #endif
if (flags & EXECUTE_SETUID)
setreuid (vfs_uid, vfs_uid);
if (as_shell_command) if (flags & EXECUTE_AS_SHELL)
execl (shell, shell, "-c", command, (char *) 0); execl (shell, shell, "-c", command, (char *) 0);
else else
execlp (shell, shell, command, (char *) 0); execlp (shell, shell, command, (char *) 0);

View File

@ -1,3 +1,15 @@
Tue Aug 25 17:54:17 1998 Pavel Machek <pavel@ucw.cz>
* Added vfs_uid for use by libvfs.so users (rpc.nfsd)
* Added single file filesystem (sfs)
* Added vfs_flags so library users can disable selected
filesystems
* Minor shuffling of functions so garbage collection works for
library
1998-08-20 Raja R Harinath <harinath@cs.umn.edu> 1998-08-20 Raja R Harinath <harinath@cs.umn.edu>
* Makefile.am (mad.c, mad.h): Create symlinks to counterparts in * Makefile.am (mad.c, mad.h): Create symlinks to counterparts in

148
vfs/Makefile.in Normal file
View File

@ -0,0 +1,148 @@
srcdir = @srcdir@
VPATH = @srcdir@
rootdir = $(srcdir)/..
@MCFG@@MCF@
CFLAGS = $(XCFLAGS)
CPPFLAGS = $(XCPPFLAGS)
LDFLAGS = $(XLDFLAGS)
DEFS = $(XDEFS)
LIBS = @LINTL@ @SHADOWLIB@ $(XLIBS) @TERMNET@ @PAMLIBS@ $(XLIB)
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -m 755
INSTALL_DATA = @INSTALL_DATA@
AR = @AR@
#
# VFS code
#
NETFILES = tcputil.o ftpfs.o mcfs.o utilvfs.o
NONETFILES = local.o vfs.o tar.o names.o container.o extfs.o sfs.o @undelfs_o@
VFSSRCS = local.c vfs.c mcfs.c tcputil.c tar.c names.c \
ftpfs.c container.c mcserv.c extfs.c undelfs.c utilvfs.c sfs.c
VFSHDRS = vfs.h mcfs.h tcputil.h tar.h container.h ftpfs.h names.h \
extfs.h
VFSOBJS = $(NONETFILES) @NETFILES@
EXTFS_MISC = README extfs.ini
EXTFS_CONST = a rpm hp48 mailfs patchfs
EXTFS_IN = deb.in lslR.in ucpio.in urar.in uzoo.in ftplist.in uar.in \
ulha.in uzip.in
EXTFS_OUT = deb lslR ucpio urar uzoo ftplist uar ulha uzip
EXTFSSTUFF = $(EXTFS_MISC) $(EXTFS_CONST) $(EXTFS_IN)
#
# Commands to build standalone version (.so)
#
VFSSOOBJS = tcputil.so ftpfs.so mcfs.so utilvfs.so local.so vfs.so tar.so names.so container.so extfs.so util-alone.so util.sor utilunix.sor sfs.so
%.sor: ../src/%.c
$(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) -DVFS_STANDALONE $< -o $@
%.so: %.c
$(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) -DVFS_STANDALONE $< -o $@
libvfs.so: $(VFSSOOBJS) libvfs.o
gcc $(VFSSOOBJS) libvfs.o -shared -o libvfs.so
#
# Distribution variables
#
DISTVFS = Makefile.in ChangeLog $(VFSSRCS) $(VFSHDRS)
all: @LIBVFS@ @mcserv@
.c.o:
$(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) $<
check:
@echo no tests are supplied.
checklinks:
@if test -f $(vfsdir)/mad.c; then echo ok; \
else $(MAKE) sourcelinks; fi
sourcelinks:
-cd $(vfsdir); $(LN_S) ../src/mad.c ../src/mad.h . >/dev/null 2>&1; true
mcserv: checklinks
$(MAKE) mcservx
mcservx: mcserv.o tcputil.o mad.o
$(CC) $(LDFLAGS) -o mcserv mcserv.o tcputil.o mad.o $(LIBS)
touch mcservx
libvfs-mc.a: $(VFSOBJS)
$(RMF) $@
$(AR) cr $@ $(VFSOBJS)
-$(RANLIB) $@
showlibdep:
@echo 'OBJS="$(VFSOBJS)"'
cross:
$(MAKE) CC=gcc-linux CPP="gcc-linux -E" \
CPPFLAGS="$(CPPFLAGS) -I/usr/local/lib/gcc-lib/i386-linux-linux/include/ncurses "
TAGS: $(VFSSRCS)
etags $(VFSSRCS)
clean:
$(RMF) mcserv *.o core a.out libvfs-mc.a mcservx libvfs.so
realclean: clean
$(RMF) .depend
$(RMF) TAGS
$(RMF) *~
distclean:
-$(RMF) $(srcdir)/*~ $(srcdir)/mcserv $(srcdir)/*.o $(srcdir)/a.out
-$(RMF) $(srcdir)/core $(srcdir)/libvfs-mc.a $(srcdir)/libvfs.so
-$(RMF) $(srcdir)/mad.c $(srcdir)/mad.h
-if test $(srcdir) = .; then $(MAKE) realclean; fi
-$(RMF) $(srcdir)/Makefile
install: @mcserv@ install.extfs
-(if test x@mcserv@ != x; then \
$(INSTALL_PROGRAM) mcserv $(DESTDIR)$(bindir)/$(binprefix)mcserv; \
fi)
install.extfs:
for I in $(EXTFS_MISC); do \
$(INSTALL_DATA) $(srcdir)/extfs/$$I \
$(DESTDIR)$(libdir)/extfs/$$I; \
done
for I in $(EXTFS_CONST) $(EXTFS_OUT); do \
$(INSTALL_PROGRAM) $(srcdir)/extfs/$$I \
$(DESTDIR)$(libdir)/extfs/$$I; \
done
uninstall:
for I in $(EXTFS_MISC); do \
$(RMF) $(DESTDIR)$(libdir)/extfs/$$I; \
done
for I in $(EXTFS_CONST) $(EXTFS_OUT); do \
$(RMF) $(DESTDIR)$(libdir)/extfs/$$I; \
done
-rmdir $(DESTDIR)$(libdir)/extfs
-$(RMF) $(DESTDIR)$(bindir)/$(binprefix)mcserv
distcopy:
$(CP) $(DISTVFS) ../../mc-$(VERSION)/vfs
cd extfs; $(CP) $(EXTFSSTUFF) ../../../mc-$(VERSION)/vfs/extfs
depend dep: mcdep
fastdeploc:
# ***Dependencies***Do not edit***
@DOTDEPEND@
# ***End of dependencies***

View File

@ -408,6 +408,14 @@ static char *extfs_get_path_mangle (char *inname, struct extfs_archive **archive
for (parc = first_archive; parc != NULL; parc = parc->next) for (parc = first_archive; parc != NULL; parc = parc->next)
if (parc->name) { if (parc->name) {
if (!strcmp (parc->name, archive_name)) { if (!strcmp (parc->name, archive_name)) {
struct stat *s=&(parc->extfsstat);
if (vfs_uid && (!(s->st_mode & 0004)))
if ((s->st_gid != vfs_gid) || !(s->st_mode & 0040))
if ((s->st_uid != vfs_uid) || !(s->st_mode & 0400))
return NULL;
/* This is not too secure - in some cases (/#mtools) files created
under user a are probably visible to everyone else since / usually
has permissions 755 */
vfs_stamp (&extfs_vfs_ops, (vfsid) parc); vfs_stamp (&extfs_vfs_ops, (vfsid) parc);
goto return_success; goto return_success;
} }
@ -601,7 +609,7 @@ static void *extfs_open (char *file, int flags, int mode)
" ", q, " ", entry->inode->local_filename, 0); " ", q, " ", entry->inode->local_filename, 0);
free (q); free (q);
free (archive_name); free (archive_name);
if (my_system (EXECUTE_AS_SHELL, shell, cmd) && !do_create){ if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID, shell, cmd) && !do_create){
free (entry->inode->local_filename); free (entry->inode->local_filename);
entry->inode->local_filename = NULL; entry->inode->local_filename = NULL;
free (cmd); free (cmd);
@ -664,7 +672,7 @@ static int extfs_close (void *data)
file->entry->inode->local_filename, 0); file->entry->inode->local_filename, 0);
free (archive_name); free (archive_name);
free (file_name); free (file_name);
if (my_system (EXECUTE_AS_SHELL, shell, cmd)) if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID, shell, cmd))
errno_code = EIO; errno_code = EIO;
free (cmd); free (cmd);
{ {

17
vfs/extfs/sfs.ini Normal file
View File

@ -0,0 +1,17 @@
#
# This is config for Single File fileSystem
#
gz/1 gzip < %1 > %3
ugz/1 gzip -d < %1 > %3
tar/1 tar cf %3 %1
tgz/1 tar czf %3 %1
uhtml/1 lynx -force_html -dump %1 > %3
uman/1 groff -Tascii -man %1 > %3
uue/1 uuenpipe < %1 > %3
uude/1 uudepipe < %1 > %3
crlf/1 todos < %1 > %3
cr/1 fromdos < %1 > %3
# Fixme: we need it to fail whenever it should
url:2 lynx -source `echo "%2" | sed 's-|-/-g'` > %3
nop/1 cat %1 > %3
strings/1 strings %1 > %3

View File

@ -13,6 +13,10 @@
#include "vfs.h" #include "vfs.h"
/* Note: Some of this functions are not static. This has rather good
* reason: exactly same functions would have to appear in sfs.c. This
* saves both computer's memory and my work. <pavel@ucw.cz>
* */
static void *local_open (char *file, int flags, int mode) static void *local_open (char *file, int flags, int mode)
{ {
@ -29,7 +33,7 @@ static void *local_open (char *file, int flags, int mode)
return local_info; return local_info;
} }
static int local_read (void *data, char *buffer, int count) int local_read (void *data, char *buffer, int count)
{ {
int n; int n;
@ -48,7 +52,7 @@ static int local_read (void *data, char *buffer, int count)
return n; return n;
} }
static int local_close (void *data) int local_close (void *data)
{ {
int fd; int fd;
@ -60,7 +64,7 @@ static int local_close (void *data)
return close (fd); return close (fd);
} }
static int local_errno (void) int local_errno (void)
{ {
return errno; return errno;
} }
@ -119,7 +123,7 @@ static int local_lstat (char *path, struct stat *buf)
#endif #endif
} }
static int local_fstat (void *data, struct stat *buf) int local_fstat (void *data, struct stat *buf)
{ {
return fstat (*((int *) data), buf); return fstat (*((int *) data), buf);
} }
@ -185,7 +189,7 @@ static int local_chdir (char *path)
return chdir (path); return chdir (path);
} }
static int local_lseek (void *data, off_t offset, int whence) int local_lseek (void *data, off_t offset, int whence)
{ {
int fd = * (int *) data; int fd = * (int *) data;

399
vfs/sfs.c Normal file
View File

@ -0,0 +1,399 @@
/*
* Single File fileSystem
*
* Copyright 1998 Pavel Machek, distribute under GPL
*
* This defines whole class of filesystems which contain single file
* inside. It is somehow similar to extfs, except that extfs makes
* whole virtual trees and we do only single virtual files. */
/*TODO Pridat sfs_fill_names na spravne misto.
Pridat tam nejake add_noncurrent_stamps().
*/
#include <config.h>
#include <errno.h>
#include <sys/types.h>
#include <malloc.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "../src/mad.h"
#include "../src/fs.h"
#include <fcntl.h>
#include "../src/util.h"
#include "../src/main.h"
#include "vfs.h"
char *shell = "/bin/bash";
struct cachedfile {
char *name, *cache;
uid_t uid;
struct cachedfile *next;
};
static struct cachedfile *head;
#define MAXFS 32
static int sfs_no = 0;
static char *sfs_prefix[ MAXFS ];
static char *sfs_command[ MAXFS ];
static int sfs_flags[ MAXFS ];
#define F_1 1
#define F_2 2
#define F_NOLOCALCOPY 4
#define F_FULLMATCH 8
static int uptodate( char *name, char *cache )
{
return 1;
}
static int vfmake( char *name, char *cache )
{
char *inpath, *op;
int w;
char pad [10240];
char *s, *t = pad;
int was_percent = 0;
vfs_split( name, &inpath, &op );
if ((w = sfs_which( op )) == -1)
vfs_die( "This cannot happen... Hopefully.\n" );
if ((sfs_flags[w] & F_1) || (!strcmp( name, "/" ))) ; else return -1;
/* if ((sfs_flags[w] & F_2) || (!inpath) || (!*inpath)); else return -1; */
if (!(sfs_flags[w] & F_NOLOCALCOPY))
name = mc_getlocalcopy( name );
else
name = strdup( name );
s = sfs_command[w];
#define COPY_CHAR if (t-pad>10200) return -1; else *t++ = *s;
#define COPY_STRING(a) if ((t-pad)+strlen(a)>10200) return -1; else { strcpy( t, a ); t+= strlen(a); }
while (*s) {
if (was_percent) {
switch (*s) {
case '1': COPY_STRING( name ); break;
case '2': COPY_STRING( op + strlen( sfs_prefix[w] ) ); break;
case '3': COPY_STRING( cache ); break;
case '%': COPY_CHAR; break;
}
was_percent = 0;
} else {
if (*s == '%') was_percent = 1;
else COPY_CHAR;
}
s++;
}
free( name );
if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID, shell, pad)) {
return -1;
}
return 0; /* OK */
}
static char *redirect( char *name )
{
struct cachedfile *cur = head;
uid_t uid = vfs_uid;
char *cache, *xname;
while (cur) {
if ((!strcmp( name, cur->name )) &&
(uid == cur->uid) &&
(uptodate( cur->name, cur->cache )))
return cur->cache;
cur = cur->next;
}
cache = tempnam( NULL, "sfs" );
xname = strdup( name );
if (!vfmake( name, cache )) {
cur = xmalloc( sizeof(struct cachedfile), "SFS cache" );
cur->name = xname;
cur->cache = strdup(cache);
cur->uid = uid;
cur->next = head;
head = cur;
return cache;
} else {
free(xname);
fprintf( stderr, "vfmake failed\n" );
}
return "/I_MUST_NOT_EXIST";
}
#define REDIR path = redirect( path );
static void *sfs_open (char *path, int flags, int mode)
{
int *sfs_info;
int fd;
REDIR;
fd = open (path, flags, mode);
if (fd == -1)
return 0;
sfs_info = (int *) xmalloc (sizeof (int), "SF fs");
*sfs_info = fd;
return sfs_info;
}
static int sfs_stat (char *path, struct stat *buf)
{
REDIR;
return stat (path, buf);
}
static int sfs_lstat (char *path, struct stat *buf)
{
REDIR;
#ifndef HAVE_STATLSTAT
return lstat (path,buf);
#else
return statlstat (path, buf);
#endif
}
static int sfs_chmod (char *path, int mode)
{
REDIR;
return chmod (path, mode);
}
static int sfs_chown (char *path, int owner, int group)
{
REDIR;
return chown (path, owner, group);
}
static int sfs_utime (char *path, struct utimbuf *times)
{
REDIR;
return utime (path, times);
}
static int sfs_readlink (char *path, char *buf, int size)
{
REDIR;
return readlink (path, buf, size);
}
#define CUR (*cur)
static vfsid sfs_getid (char *path, struct vfs_stamping **parent)
{ /* FIXME: what should I do? */
vfs *v;
vfsid id;
struct vfs_stamping *par;
struct cachedfile **cur = &head;
while (CUR) {
if ((!strcmp( path, CUR->name )) &&
(vfs_uid == CUR->uid))
break;
CUR = CUR->next;
}
if (!CUR)
vfs_die( "sfs_getid of noncached thingie?" );
*parent = NULL;
{
char *path2 = strdup( path );
v = vfs_split (path2, NULL, NULL);
id = (*v->getid) (path2, &par);
free( path2 );
}
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) cur;
}
static void sfs_free (vfsid id)
{
struct cachedfile **cur = (struct cachedfile **) id;
unlink( CUR->cache );
*cur = CUR->next;
}
#undef CUR
void sfs_fill_names (void (*func)(char *))
{
struct cachedfile *cur = head;
char *name;
while (cur){
(*func)(cur->name);
cur = cur->next;
}
}
static int sfs_nothingisopen (vfsid id)
{
return 0;
}
static char *sfs_getlocalcopy (char *path)
{
REDIR;
return strdup (path);
}
static void sfs_ungetlocalcopy (char *path, char *local, int has_changed)
{
}
#ifdef HAVE_MMAP
static caddr_t sfs_mmap (caddr_t addr, size_t len, int prot, int flags, void *data, off_t offset)
{
int fd = * (int *)data;
return mmap (addr, len, prot, flags, fd, offset);
}
static int sfs_munmap (caddr_t addr, size_t len, void *data)
{
return munmap (addr, len);
}
#endif
extern int local_close (void *data);
extern int local_read (void *data, char *buffer, int count);
extern int local_fstat (void *data, struct stat *buf);
extern int local_errno (void);
extern int local_lseek (void *data, off_t offset, int whence);
vfs sfs_vfs_ops = {
sfs_open,
local_close,
local_read,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
sfs_stat,
sfs_lstat,
local_fstat,
sfs_chmod,
sfs_chown,
sfs_utime,
sfs_readlink,
NULL,
NULL,
NULL,
NULL,
NULL,
local_errno,
local_lseek,
NULL,
sfs_getid,
sfs_nothingisopen,
sfs_free,
sfs_getlocalcopy,
sfs_ungetlocalcopy,
NULL,
NULL,
NULL,
NULL,
NULL
#ifdef HAVE_MMAP
,sfs_mmap,
sfs_munmap
#endif
};
void sfs_init (void)
{
FILE *cfg = fopen( LIBDIR "extfs/sfs.ini", "r" );
if (!cfg) {
fprintf( stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n" );
return;
}
sfs_no = 0;
while ( sfs_no < MAXFS ) {
char key[256];
char *c, *semi = NULL, flags = 0;
int i;
if (!fgets( key, 250, cfg ))
break;
if (*key == '#')
continue;
for (i=0; i<strlen(key); i++)
if ((key[i]==':') || (key[i]=='/'))
{ semi = key+i; if (key[i]=='/') { key[i]=0; flags |= F_FULLMATCH; } break; }
if (!semi) {
fprintf( stderr, "Warning: Invalid line %s in sfs.ini.\n", key );
continue;
}
c = semi + 1;
while ((*c != ' ') && (*c != 9)) {
switch (*c) {
case '1': flags |= F_1; break;
case '2': flags |= F_2; break;
case 'R': flags |= F_NOLOCALCOPY; break;
default:
fprintf( stderr, "Warning: Invalid flag %c in sfs.ini line %s.\n", c, key );
}
c++;
}
c++;
*(semi+1) = 0;
if ((semi = strchr( c, '\n')))
*semi = 0;
sfs_prefix [sfs_no] = strdup (key);
sfs_command [sfs_no] = strdup (c);
sfs_flags [sfs_no] = flags;
sfs_no++;
}
fclose(cfg);
}
int sfs_which (char *path)
{
int i;
for (i = 0; i < sfs_no; i++)
if (sfs_flags [i] & F_FULLMATCH) {
if (!strcmp (path, sfs_prefix [i]))
return i;
} else
if (!strncmp (path, sfs_prefix [i], strlen( sfs_prefix[i]) ))
return i;
return -1;
}

View File

@ -826,6 +826,10 @@ static char *tarfs_get_path_mangle (char *inname, struct tarfs_archive **archive
for (parc = first_archive; parc != NULL; parc = parc->next) for (parc = first_archive; parc != NULL; parc = parc->next)
if (!strcmp (parc->name, archive_name)) { if (!strcmp (parc->name, archive_name)) {
if (vfs_uid && (!(stat_buf.st_mode & 0004)))
if ((stat_buf.st_gid != vfs_gid) || !(stat_buf.st_mode & 0040))
if ((stat_buf.st_uid != vfs_uid) || !(stat_buf.st_mode & 0400))
return NULL;
/* Has the cached archive been changed on the disk? */ /* Has the cached archive been changed on the disk? */
if (parc->tarstat.st_mtime < stat_buf.st_mtime) { /* Yes, reload! */ if (parc->tarstat.st_mtime < stat_buf.st_mtime) { /* Yes, reload! */
(*tarfs_vfs_ops.free) ((vfsid) parc); (*tarfs_vfs_ops.free) ((vfsid) parc);
@ -1146,8 +1150,8 @@ static vfsid tar_getid (char *path, struct vfs_stamping **parent)
{ {
struct tarfs_archive *archive; struct tarfs_archive *archive;
vfs *v; vfs *v;
vfsid id;
char *p; char *p;
vfsid id;
struct vfs_stamping *par; struct vfs_stamping *par;
*parent = NULL; *parent = NULL;

View File

@ -19,8 +19,6 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define _VFS_VFS_C 1
#include <config.h> #include <config.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> /* For atol() */ #include <stdlib.h> /* For atol() */
@ -58,6 +56,12 @@ extern int get_other_type (void);
extern int extfs_which (char *path); extern int extfs_which (char *path);
int vfs_timeout = 60; /* VFS timeout in seconds */ int vfs_timeout = 60; /* VFS timeout in seconds */
int vfs_flags = /* Flags */
#ifdef VFS_STANDALONE
0;
#else
FL_ALWAYS_MAGIC;
#endif
extern int cd_symlinks; /* Defined in main.c */ extern int cd_symlinks; /* Defined in main.c */
@ -65,10 +69,16 @@ extern int cd_symlinks; /* Defined in main.c */
static vfs *current_vfs = &local_vfs_ops; static vfs *current_vfs = &local_vfs_ops;
char *current_dir = NULL; char *current_dir = NULL;
/*
* FIXME: this is broken. It depends on mc not crossing border on month!
*/
static int current_mday; static int current_mday;
static int current_mon; static int current_mon;
static int current_year; static int current_year;
uid_t vfs_uid = 0;
gid_t vfs_gid = 0;
/* Open files managed by the vfs layer */ /* Open files managed by the vfs layer */
#define MAX_VFS_FILES 100 #define MAX_VFS_FILES 100
static struct { static struct {
@ -92,24 +102,36 @@ static int get_bucket ()
vfs *vfs_type_from_op (char *path) vfs *vfs_type_from_op (char *path)
{ {
#ifdef USE_NETCODE #ifdef USE_NETCODE
if (!strncmp (path, "mc:", 3)) if (!(vfs_flags & FL_NO_MCFS) && !strncmp (path, "mc:", 3))
return &mcfs_vfs_ops; return &mcfs_vfs_ops;
if (!strncmp (path, "ftp:", 4)) if (!(vfs_flags & FL_NO_FTPFS) && !strncmp (path, "ftp:", 4))
return &ftpfs_vfs_ops; return &ftpfs_vfs_ops;
#endif #endif
#ifdef USE_EXT2FSLIB #ifdef USE_EXT2FSLIB
if (!strcmp (path, "undel")) if (!(vfs_flags & FL_NO_UNDELFS) && !strcmp (path, "undel"))
return &undelfs_vfs_ops; return &undelfs_vfs_ops;
#endif #endif
if (!strcmp (path, "utar")) if (!(vfs_flags & FL_NO_TARFS) && !strcmp (path, "utar"))
return &tarfs_vfs_ops; return &tarfs_vfs_ops;
if (extfs_which (path) != -1) if (!(vfs_flags & FL_NO_EXTFS) && extfs_which (path) != -1)
return &extfs_vfs_ops; return &extfs_vfs_ops;
if (!(vfs_flags & FL_NO_SFS) && sfs_which (path) != -1)
return &sfs_vfs_ops;
return NULL; return NULL;
} }
int path_magic( char *path )
{
int res;
res = !strncmp( path, "/#/", 3 );
if (res)
path[1] = '/';
return res || (vfs_flags & FL_ALWAYS_MAGIC);
}
/* /*
* Splits path '/p1:op/inpath' into inpath,op; returns which vfs it is. * Splits path '/p1#op/inpath' into inpath,op; returns which vfs it is.
* What is left in path is p1. You still want to free(path), you DON'T * What is left in path is p1. You still want to free(path), you DON'T
* want to free neither *inpath nor *op * want to free neither *inpath nor *op
*/ */
@ -651,7 +673,7 @@ char *vfs_canon (char *path)
return result; return result;
} }
/* So we have path of following form: /* So we have path of following form:
* /p1/p2:op/.././././p3:op/p4. Good luck. * /p1/p2#op/.././././p3#op/p4. Good luck.
*/ */
canonicalize_pathname (path); canonicalize_pathname (path);
@ -673,7 +695,6 @@ vfsid vfs_ncs_getid (vfs *nvfs, char *dir, struct vfs_stamping **par)
return nvfsid; return nvfsid;
} }
#ifndef VFS_STANDALONE
static int is_parent (vfs * nvfs, vfsid nvfsid, struct vfs_stamping *parent) static int is_parent (vfs * nvfs, vfsid nvfsid, struct vfs_stamping *parent)
{ {
struct vfs_stamping *stamp; struct vfs_stamping *stamp;
@ -682,7 +703,6 @@ static int is_parent (vfs * nvfs, vfsid nvfsid, struct vfs_stamping *parent)
break; break;
return (stamp ? 1 : 0); return (stamp ? 1 : 0);
} }
#endif
void vfs_add_noncurrent_stamps (vfs * oldvfs, vfsid oldvfsid, struct vfs_stamping *parent) void vfs_add_noncurrent_stamps (vfs * oldvfs, vfsid oldvfsid, struct vfs_stamping *parent)
{ {
@ -762,10 +782,11 @@ void vfs_add_noncurrent_stamps (vfs * oldvfs, vfsid oldvfsid, struct vfs_stampin
vfs_addstamp (stamp->v, stamp->id, stamp->parent); vfs_addstamp (stamp->v, stamp->id, stamp->parent);
} }
} }
#else
vfs_addstamp (oldvfs, oldvfsid, parent);
#endif #endif
} }
#ifndef VFS_STANDALONE
static void vfs_stamp_path (char *path) static void vfs_stamp_path (char *path)
{ {
vfs *vfs; vfs *vfs;
@ -780,7 +801,6 @@ static void vfs_stamp_path (char *path)
vfs_addstamp (stamp->v, stamp->id, stamp->parent); vfs_addstamp (stamp->v, stamp->id, stamp->parent);
vfs_rm_parents (par); vfs_rm_parents (par);
} }
#endif
#ifndef VFS_STANDALONE #ifndef VFS_STANDALONE
void vfs_add_current_stamps (void) void vfs_add_current_stamps (void)
@ -1041,6 +1061,9 @@ void mc_ungetlocalcopy (char *path, char *local, int has_changed)
free (path); free (path);
} }
/*
* Hmm, as timeout is minute or so, do we need to care about usecs?
*/
inline int timeoutcmp (struct timeval *t1, struct timeval *t2) inline int timeoutcmp (struct timeval *t1, struct timeval *t2)
{ {
return ((t1->tv_sec < t2->tv_sec) return ((t1->tv_sec < t2->tv_sec)
@ -1082,6 +1105,7 @@ void vfs_init (void)
ftpfs_init(); ftpfs_init();
#endif #endif
extfs_init (); extfs_init ();
sfs_init ();
vfs_setup_wd (); vfs_setup_wd ();
} }

View File

@ -2,7 +2,6 @@
#define __VFS_H #define __VFS_H
#ifdef VFS_STANDALONE #ifdef VFS_STANDALONE
#include "util-alone.h"
#undef USE_EXT2FSLIB #undef USE_EXT2FSLIB
#else #else
#define BROKEN_PATHS #define BROKEN_PATHS
@ -27,7 +26,6 @@ struct utimbuf {
#endif #endif
#ifdef USE_VFS #ifdef USE_VFS
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
#include <sys/mman.h> #include <sys/mman.h>
#endif #endif
@ -95,6 +93,7 @@ struct utimbuf {
extern vfs mcfs_vfs_ops; extern vfs mcfs_vfs_ops;
extern vfs extfs_vfs_ops; extern vfs extfs_vfs_ops;
extern vfs sfs_vfs_ops;
extern vfs undelfs_vfs_ops; extern vfs undelfs_vfs_ops;
@ -313,5 +312,19 @@ extern char *vfs_get_password (char *msg);
#define MCERR_DATA_ON_STDIN -5 #define MCERR_DATA_ON_STDIN -5
/* Data waiting on stdin to be processed */ /* Data waiting on stdin to be processed */
extern int vfs_flags;
extern uid_t vfs_uid;
extern gid_t vfs_gid;
#define FL_ALWAYS_MAGIC 1
#define FL_NO_MCFS 2
#define FL_NO_FTPFS 4
#define FL_NO_UNDELFS 8
#define FL_NO_TARFS 16
#define FL_NO_EXTFS 32
#define FL_NO_SFS 64
#endif /* __VFS_H */ #endif /* __VFS_H */