Files I had forgotten to add from Pavel's VFS split.

This commit is contained in:
Miguel de Icaza 1998-05-26 05:08:10 +00:00
parent d31976c59c
commit 6fc9e99a61
3 changed files with 459 additions and 0 deletions

270
vfs/shared.c Normal file
View File

@ -0,0 +1,270 @@
/*
* Large portions of tar.c & extfs.c were nearly same. I killed this
* redundancy, so code is maintainable, again.
*
* 1998 Pavel Machek
*/
static struct X_entry*
__X_find_entry (struct X_entry *dir, char *name,
struct X_loop_protect *list, int make_dirs, int make_file)
{
struct X_entry *pent, *pdir;
char *p, *q, *name_end;
char c;
if (*name == '/') { /* Handle absolute paths */
name++;
dir = dir->inode->archive->root_entry;
}
pent = dir;
p = name;
name_end = name + strlen (name);
q = strchr (p, '/');
c = '/';
if (!q)
q = strchr (p, 0);
for (; pent != NULL && c && *p; ){
c = *q;
*q = 0;
if (strcmp (p, ".")){
if (!strcmp (p, ".."))
pent = pent->dir;
else {
if ((pent = __X_resolve_symlinks (pent, list))==NULL){
*q = c;
return NULL;
}
if (c == '/' && !S_ISDIR (pent->inode->mode)){
*q = c;
notadir = 1;
return NULL;
}
pdir = pent;
for (pent = pent->inode->first_in_subdir; pent; pent = pent->next_in_dir)
/* Hack: I keep the original semanthic unless
q+1 would break in the strchr */
if (!strcmp (pent->name, p)){
if (q + 1 > name_end){
*q = c;
notadir = !S_ISDIR (pent->inode->mode);
return pent;
}
break;
}
/* When we load archive, we create automagically
* non-existant directories
*/
if (pent == NULL && make_dirs) {
pent = generate_entry (dir->inode->archive, p, pdir, S_IFDIR | 0777);
}
if (pent == NULL && make_file) {
pent = generate_entry (dir->inode->archive, p, pdir, 0777);
}
}
}
/* Next iteration */
*q = c;
p = q + 1;
q = strchr (p, '/');
if (!q)
q = strchr (p, 0);
}
if (pent == NULL)
Xerrno = ENOENT;
return pent;
}
static struct X_entry *X_find_entry (struct X_entry *dir, char *name, int make_dirs, int make_file)
{
struct X_entry *res;
errloop = 0;
notadir = 0;
res = __X_find_entry (dir, name, NULL, make_dirs, make_file);
if (res == NULL) {
if (errloop)
Xerrno = ELOOP;
else if (notadir)
Xerrno = ENOTDIR;
}
return res;
}
static int s_errno (void)
{
return Xerrno;
}
static void * s_opendir (char *dirname)
{
struct X_archive *archive;
char *q;
struct X_entry *entry;
struct X_entry **info;
if ((q = X_get_path (dirname, &archive, 1, 0)) == NULL)
return NULL;
entry = X_find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return NULL;
if ((entry = X_resolve_symlinks (entry)) == NULL)
return NULL;
if (!S_ISDIR (entry->inode->mode)) {
Xerrno = ENOTDIR;
return NULL;
}
info = (struct X_entry **) xmalloc (2*sizeof (struct X_entry *), "shared opendir");
info[0] = entry->inode->first_in_subdir;
info[1] = entry->inode->first_in_subdir;
return info;
}
static void * s_readdir (void *data)
{
static struct {
struct dirent dir;
#ifdef NEED_EXTRA_DIRENT_BUFFER
char extra_buffer [MC_MAXPATHLEN];
#endif
} dir;
struct X_entry **info = (struct X_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_in_dir;
return (void *)&dir;
}
static int s_telldir (void *data)
{
struct X_entry **info = (struct X_entry **) data;
struct X_entry *cur;
int num = 0;
cur = info[1];
while (cur!=NULL) {
if (cur == info[0]) return num;
num++;
cur = cur->next_in_dir;
}
return -1;
}
static void s_seekdir (void *data, int offset)
{
struct X_entry **info = (struct X_entry **) data;
int i;
info[0] = info[1];
for (i=0; i<offset; i++)
s_readdir( data );
}
static int s_closedir (void *data)
{
free (data);
return 0;
}
static void stat_move( struct stat *buf, struct X_inode *inode )
{
buf->st_dev = inode->dev;
buf->st_ino = inode->inode;
buf->st_mode = inode->mode;
buf->st_nlink = inode->nlink;
buf->st_uid = inode->uid;
buf->st_gid = inode->gid;
#ifdef HAVE_ST_RDEV
buf->st_rdev = inode->rdev;
#endif
buf->st_size = inode->size;
#ifdef HAVE_ST_BLKSIZE
buf->st_blksize = RECORDSIZE;
#endif
#ifdef HAVE_ST_BLOCKS
buf->st_blocks = (inode->size + RECORDSIZE - 1) / RECORDSIZE;
#endif
buf->st_atime = inode->atime;
buf->st_mtime = inode->mtime;
buf->st_ctime = inode->ctime;
}
static int s_internal_stat (char *path, struct stat *buf, int resolve)
{
struct X_archive *archive;
char *q;
struct X_entry *entry;
struct X_inode *inode;
char debugbuf[10240];
strcpy( debugbuf, path );
if ((q = X_get_path (path, &archive, 0, 0)) == NULL)
return -1;
entry = X_find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return -1;
if (resolve && (entry = X_resolve_symlinks (entry)) == NULL)
return -1;
inode = entry->inode;
stat_move( buf, inode );
return 0;
}
static int s_stat (char *path, struct stat *buf)
{
return s_internal_stat (path, buf, 1);
}
static int s_lstat (char *path, struct stat *buf)
{
return s_internal_stat (path, buf, 0);
}
static int s_fstat (void *data, struct stat *buf)
{
struct X_pseudofile *file = (struct X_pseudofile *)data;
struct X_inode *inode;
inode = file->entry->inode;
stat_move( buf, inode );
return 0;
}
static int s_readlink (char *path, char *buf, int size)
{
struct X_archive *archive;
char *q;
int i;
struct X_entry *entry;
if ((q = X_get_path (path, &archive, 0, 0)) == NULL)
return -1;
entry = X_find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return -1;
if (!S_ISLNK (entry->inode->mode)) {
Xerrno = EINVAL;
return -1;
}
if (size > (i = strlen (entry->inode->linkname))) {
size = i;
}
strncpy (buf, entry->inode->linkname, i);
return i;
}

189
vfs/util-alone.c Normal file
View File

@ -0,0 +1,189 @@
/*
* This is for making midnight commander's vfs stuff compile stand-alone
*/
#include <config.h>
#include <stdio.h>
#if defined(__os2__) /* OS/2 need io.h! .ado */
# include <io.h>
#endif
#include <stdlib.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <signal.h> /* my_system */
#include <limits.h> /* INT_MAX */
#ifndef SCO_FLAVOR
# include <sys/time.h> /* alex: sys/select.h defines struct timeval */
#endif /* SCO_FLAVOR */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <errno.h> /* my_system */
#ifdef SCO_FLAVOR
# include <sys/timeb.h> /* alex: for struct timeb, used in time.h */
#endif /* SCO_FLAVOR */
#include <time.h>
#ifndef OS2_NT
# include <pwd.h>
# include <grp.h>
#endif
#include <string.h>
#include <ctype.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#ifdef __linux__
# if defined(__GLIBC__) && (__GLIBC__ < 2)
# include <linux/termios.h> /* This is needed for TIOCLINUX */
# else
# include <termios.h>
# endif
# include <sys/ioctl.h>
#endif
#include "../src/util.h"
#include "vfs.h"
#include "callback.h"
int source_route = 0;
int cd_symlinks = 0;
/*
* Required functions to make mc's vfs layer compile stand-alone
*/
void *do_xmalloc (int size)
{
void *m = malloc (size);
if (!m)
vfs_die ("Memory exhausted\n");
return m;
}
/*
* We do not want/need many of midnight's functions, stub routines.
*/
void
enable_interrupt_key (void)
{
}
void
disable_interrupt_key (void)
{
}
int got_interrupt (void)
{
return 0;
}
void
rotate_dash (void)
{
}
char *
load_anon_passwd (void)
{
return NULL;
}
static char (*callbacks[NUM_CALLBACKS])(char *msg);
void
vfs_set_callback (int num, void *func)
{
if (num >= NUM_CALLBACKS)
vfs_die ("Attempt to set invalid callback.\n");
callbacks [num] = func;
}
static void
info_puts( char *s )
{
if (!callbacks [CALL_INFO])
fprintf (stderr, "%s\n", s);
else
callbacks [CALL_INFO](s);
}
static void
box_puts( char *s )
{
if (!callbacks [CALL_BOX])
fprintf (stderr, "%s\n", s);
else
callbacks [CALL_BOX](s);
}
char *
vfs_get_password (char *msg)
{
if (!callbacks [CALL_PASSWD])
return NULL;
else
callbacks [CALL_PASSWD](msg);
}
void
print_vfs_message (char *msg, ...)
{
char buf [4096];
va_list args;
va_start (args,msg);
vsnprintf (buf, sizeof (buf), msg, args);
info_puts (buf);
va_end (args);
}
void
wipe_password (char *passwd)
{
char *p = passwd;
for (;*p; p++)
*p = 0;
free (passwd);
}
int
exist_file (char *name)
{
return access (name, R_OK) == 0;
}
void
message_1s (int i, char *c1, char *c2)
{
char buf [4096];
snprintf (buf, sizeof (buf), c1, c2);
box_puts (buf);
}
void
message_2s (int i, char *c1, char *c2, char *c3)
{
char buf [4096];
snprintf (buf, sizeof (buf), c1, c2, c3 );
box_puts (buf );
}
void message_3s( int i, char *c1, char *c2, char *c3, const char *c4 )
{
char buf [4096];
snprintf (buf, sizeof (buf), c1, c2, c3, c4);
box_puts (buf);
}

0
vfs/util-alone.h Normal file
View File