mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
Files I had forgotten to add from Pavel's VFS split.
This commit is contained in:
parent
d31976c59c
commit
6fc9e99a61
270
vfs/shared.c
Normal file
270
vfs/shared.c
Normal 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
189
vfs/util-alone.c
Normal 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
0
vfs/util-alone.h
Normal file
Loading…
Reference in New Issue
Block a user