Return value is needed for mc_[un]getlocalcopy.
Этот коммит содержится в:
родитель
06ff41e71b
Коммит
1139602a9b
@ -1,3 +1,12 @@
|
||||
1999-11-11 Pavel Machek <pavel@artax.karlin.mff.cuni.cz>
|
||||
|
||||
* *.c (mc_[un]getlocalcopy): we really need some return value,
|
||||
because we can have errors
|
||||
|
||||
* fish.c: don't use directory expiration, it does not work,
|
||||
use retrieve_file from direntry.c
|
||||
|
||||
|
||||
1999-02-17 Pavel Machek <pavel@bug.ucw.cz>
|
||||
|
||||
* direntry.c (vfs_s_getlocalcopy): fixed segfault, getlocalcopy's
|
||||
|
@ -1025,7 +1025,7 @@ static char *extfs_getlocalcopy (vfs *me, char *path)
|
||||
return p;
|
||||
}
|
||||
|
||||
static void extfs_ungetlocalcopy (vfs *me, char *path, char *local, int has_changed)
|
||||
static int extfs_ungetlocalcopy (vfs *me, char *path, char *local, int has_changed)
|
||||
{
|
||||
struct pseudofile *fp =
|
||||
(struct pseudofile *) extfs_open (me, path, O_WRONLY, 0);
|
||||
@ -1036,11 +1036,11 @@ static void extfs_ungetlocalcopy (vfs *me, char *path, char *local, int has_chan
|
||||
fp->entry->inode->has_changed = has_changed;
|
||||
fp->archive->fd_usage--;
|
||||
extfs_close ((void *) fp);
|
||||
return;
|
||||
return 0;
|
||||
} else {
|
||||
/* Should not happen */
|
||||
extfs_close ((void *) fp);
|
||||
mc_def_ungetlocalcopy (me, path, local, has_changed);
|
||||
return mc_def_ungetlocalcopy (me, path, local, has_changed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ struct inode {
|
||||
dev_t dev; /* This is an internal identification of the extfs archive */
|
||||
struct archive *archive; /* And this is an archive structure */
|
||||
dev_t rdev;
|
||||
umode_t mode;
|
||||
mode_t mode; /* What is umode_t? It will not compile for me, changed it t mode_t */
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int size;
|
||||
|
80
vfs/fish.c
80
vfs/fish.c
@ -261,7 +261,7 @@ open_archive_int (vfs *me, vfs_s_super *super)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
open_archive (vfs *me, vfs_s_super *super, char *archive_name, char *op)
|
||||
{
|
||||
char *host, *user, *password;
|
||||
@ -302,12 +302,11 @@ fish_which (vfs *me, char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
dir_uptodate(vfs *me, vfs_s_inode *ino)
|
||||
{
|
||||
struct timeval tim;
|
||||
|
||||
return 1; /* Timeouting of directories does not work too well :-(. */
|
||||
gettimeofday(&tim, NULL);
|
||||
if (force_expiration) {
|
||||
force_expiration = 0;
|
||||
@ -350,7 +349,7 @@ dir_load(vfs *me, vfs_s_inode *dir, char *remote_path)
|
||||
me->verrno = ECONNRESET;
|
||||
goto error;
|
||||
}
|
||||
if (logfile){
|
||||
if (logfile) {
|
||||
fputs (buffer, logfile);
|
||||
fputs ("\n", logfile);
|
||||
fflush (logfile);
|
||||
@ -420,11 +419,8 @@ dir_load(vfs *me, vfs_s_inode *dir, char *remote_path)
|
||||
|
||||
vfs_s_free_entry (me, ent);
|
||||
me->verrno = E_REMOTE;
|
||||
if (decode_reply(buffer+4, 0) != COMPLETE)
|
||||
goto error;
|
||||
|
||||
print_vfs_message(_("fish: got listing"));
|
||||
return 0;
|
||||
if (decode_reply(buffer+4, 0) == COMPLETE)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
print_vfs_message(_("fish: failed"));
|
||||
@ -676,74 +672,10 @@ static int fish_rmdir (vfs *me, char *path)
|
||||
POSTFIX(OPT_FLUSH);
|
||||
}
|
||||
|
||||
static int retrieve_file(vfs *me, struct vfs_s_inode *ino)
|
||||
{
|
||||
/* If you want reget, you'll have to open file with O_LINEAR */
|
||||
int total = 0;
|
||||
char buffer[8192];
|
||||
int handle, n;
|
||||
int stat_size = ino->st.st_size;
|
||||
struct vfs_s_fh fh;
|
||||
|
||||
memset(&fh, 0, sizeof(fh));
|
||||
|
||||
fh.ino = ino;
|
||||
if (!(ino->localname = tempnam (NULL, me->name))) ERRNOR (ENOMEM, 0);
|
||||
|
||||
handle = open(ino->localname, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600);
|
||||
if (handle == -1) {
|
||||
me->verrno = errno;
|
||||
goto error_4;
|
||||
}
|
||||
|
||||
if (!MEDATA->linear_start (me, &fh, 0))
|
||||
goto error_3;
|
||||
|
||||
/* Clear the interrupt status */
|
||||
|
||||
while (1) {
|
||||
n = linear_read(me, &fh, buffer, sizeof(buffer));
|
||||
if (n < 0)
|
||||
goto error_1;
|
||||
if (!n)
|
||||
break;
|
||||
|
||||
total += n;
|
||||
vfs_print_stats (me->name, "Getting file", ino->ent->name, total, stat_size);
|
||||
|
||||
if (write(handle, buffer, n) < 0) {
|
||||
me->verrno = errno;
|
||||
goto error_1;
|
||||
}
|
||||
}
|
||||
linear_close(me, &fh);
|
||||
close(handle);
|
||||
|
||||
if (stat (ino->localname, &ino->u.fish.local_stat) < 0)
|
||||
ino->u.fish.local_stat.st_mtime = 0;
|
||||
|
||||
return 0;
|
||||
error_1:
|
||||
linear_close(me, &fh);
|
||||
error_3:
|
||||
disable_interrupt_key();
|
||||
close(handle);
|
||||
unlink(ino->localname);
|
||||
error_4:
|
||||
g_free(ino->localname);
|
||||
ino->localname = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int fish_fh_open (vfs *me, vfs_s_fh *fh, int flags, int mode)
|
||||
{
|
||||
if (IS_LINEAR(mode)) {
|
||||
message_1s(1, "Linear mode requested", "?!" );
|
||||
fh->linear = LS_LINEAR_CLOSED;
|
||||
return 0;
|
||||
}
|
||||
if (!fh->ino->localname)
|
||||
if (retrieve_file (me, fh->ino)==-1)
|
||||
if (vfs_s_retrieve_file (me, fh->ino)==-1)
|
||||
return -1;
|
||||
if (!fh->ino->localname)
|
||||
vfs_die( "retrieve_file failed to fill in localname" );
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
@ -10,6 +9,7 @@
|
||||
#include "utilvfs.h"
|
||||
|
||||
#include "vfs.h"
|
||||
#include <config.h>
|
||||
#include "local.h"
|
||||
|
||||
/* Note: Some of this functions are not static. This has rather good
|
||||
@ -265,9 +265,10 @@ local_getlocalcopy (vfs *me, char *path)
|
||||
return g_strdup (path);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
local_ungetlocalcopy (vfs *me, char *path, char *local, int has_changed)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
|
@ -281,8 +281,10 @@ static char *sfs_getlocalcopy (vfs *me, char *path)
|
||||
return g_strdup (path);
|
||||
}
|
||||
|
||||
static void sfs_ungetlocalcopy (vfs *me, char *path, char *local, int has_changed)
|
||||
static int sfs_ungetlocalcopy (vfs *me, char *path, char *local, int has_changed)
|
||||
{
|
||||
g_free(local);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sfs_init (vfs *me)
|
||||
|
@ -255,7 +255,7 @@ s_get_path (struct connection **bucket, char *path, char *name)
|
||||
}
|
||||
|
||||
void
|
||||
X_flushdir (void)
|
||||
ftpfs_flushdir (void)
|
||||
{
|
||||
force_expiration = 1;
|
||||
}
|
||||
|
@ -481,10 +481,12 @@ static int tar_read (void *fh, char *buffer, int count)
|
||||
return count;
|
||||
}
|
||||
|
||||
static void tar_ungetlocalcopy (vfs *me, char *path, char *local, int has_changed)
|
||||
static int tar_ungetlocalcopy (vfs *me, char *path, char *local, int has_changed)
|
||||
{
|
||||
/* We do just nothing. (We are read only and do not need to free local,
|
||||
since it will be freed when tar archive will be freed */
|
||||
/* We have to report error if file has changed */
|
||||
ERRNOR (EROFS, -has_changed);
|
||||
}
|
||||
|
||||
static int tar_fh_open (vfs *me, vfs_s_fh *fh, int flags, int mode)
|
||||
|
@ -351,7 +351,7 @@ undelfs_readdir (void *vfs_info)
|
||||
delarray [readdir_ptr].num_blocks);
|
||||
readdir_ptr++;
|
||||
|
||||
#ifndef DIRENT_LENGTH_COMPUTED
|
||||
#if 0
|
||||
undelfs_readdir_data.dent.d_namlen = strlen (undelfs_readdir_data.dent.d_name);
|
||||
#endif
|
||||
return &undelfs_readdir_data;
|
||||
|
96
vfs/vfs.c
96
vfs/vfs.c
@ -1079,22 +1079,32 @@ mc_def_getlocalcopy (vfs *vfs, char *filename)
|
||||
return NULL;
|
||||
tmp = tempnam (NULL, "mclocalcopy");
|
||||
fdout = open (tmp, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, 0600);
|
||||
if (fdout == -1){
|
||||
mc_close (fdin);
|
||||
g_free (tmp);
|
||||
return NULL;
|
||||
}
|
||||
if (fdout == -1)
|
||||
goto fail;
|
||||
while ((i = mc_read (fdin, buffer, sizeof (buffer))) == sizeof (buffer)){
|
||||
write (fdout, buffer, i);
|
||||
}
|
||||
if (i != -1)
|
||||
write (fdout, buffer, i);
|
||||
mc_close (fdin);
|
||||
close (fdout);
|
||||
if (i == -1)
|
||||
goto fail;
|
||||
if (write (fdout, buffer, i)==-1)
|
||||
goto fail;
|
||||
i = mc_close (fdin);
|
||||
fdin = -1;
|
||||
if (i==-1)
|
||||
goto fail;
|
||||
if (close (fdout)==-1)
|
||||
goto fail;
|
||||
|
||||
if (mc_stat (filename, &mystat) != -1){
|
||||
chmod (tmp, mystat.st_mode);
|
||||
}
|
||||
return tmp;
|
||||
|
||||
fail:
|
||||
if (fdout) close(fdout);
|
||||
if (fdin) mc_close (fdin);
|
||||
g_free (tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
@ -1113,48 +1123,61 @@ mc_getlocalcopy (char *path)
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
mc_def_ungetlocalcopy (vfs *vfs, char *filename, char *local, int has_changed)
|
||||
{
|
||||
{ /* Dijkstra probably hates me... But he should teach me how to do this nicely. */
|
||||
int fdin = -1, fdout = -1, i;
|
||||
if (has_changed){
|
||||
int fdin, fdout, i;
|
||||
char buffer [8192];
|
||||
|
||||
fdin = open (local, O_RDONLY);
|
||||
if (fdin == -1){
|
||||
unlink (local);
|
||||
g_free (local);
|
||||
return;
|
||||
}
|
||||
if (fdin == -1)
|
||||
goto failed;
|
||||
fdout = mc_open (filename, O_WRONLY | O_TRUNC);
|
||||
if (fdout == -1){
|
||||
close (fdin);
|
||||
unlink (local);
|
||||
g_free (local);
|
||||
return;
|
||||
}
|
||||
if (fdout == -1)
|
||||
goto failed;
|
||||
while ((i = read (fdin, buffer, sizeof (buffer))) == sizeof (buffer)){
|
||||
mc_write (fdout, buffer, i);
|
||||
}
|
||||
if (i != -1)
|
||||
mc_write (fdout, buffer, i);
|
||||
close (fdin);
|
||||
mc_close (fdout);
|
||||
if (i == -1)
|
||||
goto failed;
|
||||
|
||||
if (mc_write (fdout, buffer, i) == -1)
|
||||
goto failed;
|
||||
|
||||
if (close (fdin)==-1)
|
||||
goto failed;
|
||||
if (mc_close (fdout)==-1) {
|
||||
fdout = -1;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
unlink (local);
|
||||
g_free (local);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
message_1s (1, "Changes to file lost", filename);
|
||||
if (fdout) mc_close(fdout);
|
||||
if (fdin) close(fdin);
|
||||
unlink (local);
|
||||
g_free (local);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
mc_ungetlocalcopy (char *path, char *local, int has_changed)
|
||||
{
|
||||
vfs *vfs;
|
||||
int res;
|
||||
|
||||
path = vfs_canon (path);
|
||||
vfs = vfs_type (path);
|
||||
vfs->ungetlocalcopy ? (*vfs->ungetlocalcopy)(vfs, vfs_name (path), local, has_changed) :
|
||||
mc_def_ungetlocalcopy (vfs, vfs_name (path), local, has_changed);
|
||||
/* FIXME: errors are ignored at this point */
|
||||
g_free (path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1167,10 +1190,13 @@ timeoutcmp (struct timeval *t1, struct timeval *t2)
|
||||
|| ((t1->tv_sec == t2->tv_sec) && (t1->tv_usec <= t2->tv_usec)));
|
||||
}
|
||||
|
||||
/* This is called from timeout handler with now = 0, or can be called
|
||||
with now = 1 to force freeing all filesystems that are not in use */
|
||||
|
||||
void
|
||||
vfs_timeout_handler (void)
|
||||
vfs_expire (int now)
|
||||
{
|
||||
static int locked;
|
||||
static int locked = 0;
|
||||
struct timeval time;
|
||||
struct vfs_stamping *stamp, *st;
|
||||
|
||||
@ -1184,7 +1210,7 @@ vfs_timeout_handler (void)
|
||||
time.tv_sec -= vfs_timeout;
|
||||
|
||||
for (stamp = stamps; stamp != NULL;){
|
||||
if (timeoutcmp (&stamp->time, &time)){
|
||||
if (now || (timeoutcmp (&stamp->time, &time))){
|
||||
st = stamp->next;
|
||||
(*stamp->v->free) (stamp->id);
|
||||
vfs_rmstamp (stamp->v, stamp->id, 0);
|
||||
@ -1195,12 +1221,18 @@ vfs_timeout_handler (void)
|
||||
locked = 0;
|
||||
}
|
||||
|
||||
void
|
||||
vfs_timeout_handler (void)
|
||||
{
|
||||
vfs_expire (0);
|
||||
}
|
||||
|
||||
void
|
||||
vfs_init (void)
|
||||
{
|
||||
time_t current_time;
|
||||
struct tm *t;
|
||||
|
||||
|
||||
memset (vfs_file_table, 0, sizeof (vfs_file_table));
|
||||
current_time = time (NULL);
|
||||
t = localtime (¤t_time);
|
||||
|
13
vfs/vfs.h
13
vfs/vfs.h
@ -60,8 +60,8 @@ struct utimbuf {
|
||||
vfs *next;
|
||||
char *name; /* "FIles over SHell" */
|
||||
int flags;
|
||||
#define F_EXEC 1
|
||||
#define F_NET 2
|
||||
#define F_EXEC 1 /* Filesystem needs to execute external programs */
|
||||
#define F_NET 2 /* Filesystem needs to access network */
|
||||
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 */
|
||||
@ -108,7 +108,7 @@ struct utimbuf {
|
||||
void (*free) (vfsid id);
|
||||
|
||||
char *(*getlocalcopy) (vfs *me, char *filename);
|
||||
void (*ungetlocalcopy) (vfs *me, char *filename, char *local,
|
||||
int (*ungetlocalcopy) (vfs *me, char *filename, char *local,
|
||||
int has_changed);
|
||||
|
||||
int (*mkdir) (vfs *me, char *path, mode_t mode);
|
||||
@ -175,6 +175,7 @@ struct utimbuf {
|
||||
void vfs_add_current_stamps (void);
|
||||
void vfs_free_resources(char *path);
|
||||
void vfs_timeout_handler ();
|
||||
void vfs_expire (int);
|
||||
int vfs_timeouts ();
|
||||
|
||||
void vfs_fill_names (void (*)(char *));
|
||||
@ -222,9 +223,9 @@ struct utimbuf {
|
||||
int mc_mkdir (char *path, mode_t mode);
|
||||
|
||||
char *mc_getlocalcopy (char *filename);
|
||||
void mc_ungetlocalcopy (char *filename, char *local, int has_changed);
|
||||
int mc_ungetlocalcopy (char *filename, char *local, int has_changed);
|
||||
char *mc_def_getlocalcopy (vfs *vfs, char *filename);
|
||||
void mc_def_ungetlocalcopy (vfs *vfs, char *filename, char *local, int has_changed);
|
||||
int mc_def_ungetlocalcopy (vfs *vfs, char *filename, char *local, int has_changed);
|
||||
int mc_ctl (int fd, int ctlop, int arg);
|
||||
int mc_setctl (char *path, int ctlop, char *arg);
|
||||
#ifdef HAVE_MMAP
|
||||
@ -303,7 +304,7 @@ struct utimbuf {
|
||||
typedef int vfs;
|
||||
|
||||
# define mc_getlocalcopy(x) NULL
|
||||
# define mc_ungetlocalcopy(x,y,z)
|
||||
# define mc_ungetlocalcopy(x,y,z) 0
|
||||
|
||||
# define ftpfs_hint_reread(x)
|
||||
# define ftpfs_flushdir()
|
||||
|
@ -61,6 +61,9 @@ typedef struct vfs_s_inode {
|
||||
struct timeval timestamp;
|
||||
struct stat local_stat;
|
||||
} fish;
|
||||
struct {
|
||||
struct timeval timestamp;
|
||||
} ftp;
|
||||
} u;
|
||||
int magic;
|
||||
#define INODE_MAGIC 0x93451656
|
||||
@ -88,9 +91,28 @@ typedef struct vfs_s_super {
|
||||
int flags;
|
||||
} fish;
|
||||
struct {
|
||||
int sockr, sockw;
|
||||
int sock;
|
||||
char *home, *cwdir;
|
||||
char *host, *user;
|
||||
char *password;
|
||||
int port;
|
||||
|
||||
char *proxy;
|
||||
int failed_on_login; /* used to pass the failure reason to upper levels */
|
||||
int use_proxy; /* use a proxy server */
|
||||
int result_pending;
|
||||
int use_source_route;
|
||||
int use_passive_connection;
|
||||
int remote_is_amiga; /* No leading slash allowed for AmiTCP (Amiga) */
|
||||
int isbinary;
|
||||
int cwd_defered; /* current_directory was changed but CWD command hasn't
|
||||
been sent yet */
|
||||
int strict; /* ftp server doesn't understand
|
||||
"LIST -la <path>"; use "CWD <path>"/
|
||||
"LIST" instead */
|
||||
#define RFC_AUTODETECT 0
|
||||
#define RFC_DARING 1
|
||||
#define RFC_STRICT 2
|
||||
} ftp;
|
||||
} u;
|
||||
int magic;
|
||||
@ -107,6 +129,9 @@ typedef struct vfs_s_fh {
|
||||
struct {
|
||||
int got, total;
|
||||
} fish;
|
||||
struct {
|
||||
int sock;
|
||||
} ftp;
|
||||
} u;
|
||||
int magic;
|
||||
#define FH_MAGIC 0x91324682
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user