Lots of changes:
- SFS-based file systems now work on GNOME edition, I was not waiting for child process to finish decompressing. - VFS code cleanup. I am going to eventually get rid of all the macro-mania that has creeped into the vfs layer. Miguel
Этот коммит содержится в:
родитель
a7170a4f7a
Коммит
85f17a4dc6
@ -1,3 +1,18 @@
|
|||||||
|
1999-01-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||||
|
|
||||||
|
* gutil.c (my_system_get_child_pid): Acknowledge new EXECUTE_WAIT
|
||||||
|
flag. This is required by the vfs code.
|
||||||
|
|
||||||
|
1999-01-06 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||||
|
|
||||||
|
* gscreen.c (panel_create_file_list, panel_create_icon_display):
|
||||||
|
I got excited adding the gtk_drag_source_set. I generate those
|
||||||
|
events myself, no need to put them here.
|
||||||
|
|
||||||
|
1999-01-04 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||||
|
|
||||||
|
* gwidget.c (stock_from_text): Return this value.
|
||||||
|
|
||||||
1999-01-08 Jonathan Blandford <jrb@redhat.com>
|
1999-01-08 Jonathan Blandford <jrb@redhat.com>
|
||||||
|
|
||||||
* glayout.c: now open the new (non-functional) dialog box. If you
|
* glayout.c: now open the new (non-functional) dialog box. If you
|
||||||
|
@ -73,7 +73,9 @@ int my_system_get_child_pid (int flags, const char *shell, const char *command,
|
|||||||
for (i = 3; i < top; i++)
|
for (i = 3; i < top; i++)
|
||||||
close (i);
|
close (i);
|
||||||
|
|
||||||
*pid = fork ();
|
if (!(flags & EXECUTE_WAIT))
|
||||||
|
*pid = fork ();
|
||||||
|
|
||||||
if (*pid == 0){
|
if (*pid == 0){
|
||||||
if (flags & EXECUTE_AS_SHELL)
|
if (flags & EXECUTE_AS_SHELL)
|
||||||
execl (shell, shell, "-c", command, (char *) 0);
|
execl (shell, shell, "-c", command, (char *) 0);
|
||||||
@ -94,14 +96,15 @@ int my_system_get_child_pid (int flags, const char *shell, const char *command,
|
|||||||
*/
|
*/
|
||||||
_exit (0);
|
_exit (0);
|
||||||
}
|
}
|
||||||
|
if (*pid != 0 && (flags & EXECUTE_WAIT)){
|
||||||
|
int status;
|
||||||
|
|
||||||
|
waitpid (*pid, &status, 0);
|
||||||
|
}
|
||||||
sigaction (SIGINT, &save_intr, NULL);
|
sigaction (SIGINT, &save_intr, NULL);
|
||||||
sigaction (SIGQUIT, &save_quit, NULL);
|
sigaction (SIGQUIT, &save_quit, NULL);
|
||||||
sigaction (SIGTSTP, &save_stop, NULL);
|
sigaction (SIGTSTP, &save_stop, NULL);
|
||||||
|
|
||||||
#ifdef SCO_FLAVOR
|
|
||||||
waitpid(-1, NULL, WNOHANG);
|
|
||||||
#endif /* SCO_FLAVOR */
|
|
||||||
|
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ void my_putenv (char*, char*);
|
|||||||
#define EXECUTE_TEMPFILE 2
|
#define EXECUTE_TEMPFILE 2
|
||||||
#define EXECUTE_AS_SHELL 4
|
#define EXECUTE_AS_SHELL 4
|
||||||
#define EXECUTE_SETUID 8
|
#define EXECUTE_SETUID 8
|
||||||
|
#define EXECUTE_WAIT 16
|
||||||
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);
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
1999-01-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||||
|
|
||||||
|
* sfs.c (redirect): tempnam returns a malloc()ed buffer.
|
||||||
|
|
||||||
Sat Jan 9 19:15:00 1999 Norbert Warmuth <nwarmuth@privat.circular.de>
|
Sat Jan 9 19:15:00 1999 Norbert Warmuth <nwarmuth@privat.circular.de>
|
||||||
|
|
||||||
* vfs.c (vfs_timeout_handler): Guard from recursive invocation.
|
* vfs.c (vfs_timeout_handler): Guard from recursive invocation.
|
||||||
|
@ -35,7 +35,8 @@ vfs_s_inode *vfs_s_new_inode (vfs *me, vfs_s_super *super, struct stat *initstat
|
|||||||
vfs_s_inode *ino;
|
vfs_s_inode *ino;
|
||||||
|
|
||||||
ino = xmalloc(sizeof (vfs_s_inode), "Dcache inode");
|
ino = xmalloc(sizeof (vfs_s_inode), "Dcache inode");
|
||||||
if (!ino) return NULL;
|
if (!ino)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
ino->linkname = ino->localname = NULL;
|
ino->linkname = ino->localname = NULL;
|
||||||
@ -66,7 +67,8 @@ vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode)
|
|||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
entry->name = strdup (name);
|
entry->name = strdup (name);
|
||||||
else entry->name = NULL;
|
else
|
||||||
|
entry->name = NULL;
|
||||||
entry->dir = NULL;
|
entry->dir = NULL;
|
||||||
entry->next = NULL;
|
entry->next = NULL;
|
||||||
entry->prevp = NULL;
|
entry->prevp = NULL;
|
||||||
@ -79,7 +81,8 @@ vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode)
|
|||||||
|
|
||||||
void vfs_s_free_inode (vfs *me, vfs_s_inode *ino)
|
void vfs_s_free_inode (vfs *me, vfs_s_inode *ino)
|
||||||
{
|
{
|
||||||
if (!ino) vfs_die("Don't pass NULL to me");
|
if (!ino)
|
||||||
|
vfs_die ("Don't pass NULL to me");
|
||||||
|
|
||||||
/* ==0 can happen if freshly created entry is deleted */
|
/* ==0 can happen if freshly created entry is deleted */
|
||||||
if(ino->st.st_nlink <= 1) {
|
if(ino->st.st_nlink <= 1) {
|
||||||
@ -106,7 +109,8 @@ void vfs_s_free_entry (vfs *me, vfs_s_entry *ent)
|
|||||||
int is_dot = 0;
|
int is_dot = 0;
|
||||||
if (ent->prevp) { /* It is possible that we are deleting freshly created entry */
|
if (ent->prevp) { /* It is possible that we are deleting freshly created entry */
|
||||||
*ent->prevp = ent->next;
|
*ent->prevp = ent->next;
|
||||||
if (ent->next) ent->next->prevp = ent->prevp;
|
if (ent->next)
|
||||||
|
ent->next->prevp = ent->prevp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent->name) {
|
if (ent->name) {
|
||||||
@ -129,7 +133,8 @@ void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir, vfs_s_entry *ent)
|
|||||||
{
|
{
|
||||||
vfs_s_entry **ep;
|
vfs_s_entry **ep;
|
||||||
|
|
||||||
for(ep = &dir->subdir; *ep != NULL; ep = &((*ep)->next));
|
for (ep = &dir->subdir; *ep != NULL; ep = &((*ep)->next))
|
||||||
|
;
|
||||||
ent->prevp = ep;
|
ent->prevp = ep;
|
||||||
ent->next = NULL;
|
ent->next = NULL;
|
||||||
ent->dir = dir;
|
ent->dir = dir;
|
||||||
@ -251,7 +256,6 @@ static void split_dir_name(vfs *me, char *path, char **dir, char **name, char **
|
|||||||
|
|
||||||
vfs_s_entry *vfs_s_find_entry_linear(vfs *me, vfs_s_inode *root, char *path, int follow, int flags)
|
vfs_s_entry *vfs_s_find_entry_linear(vfs *me, vfs_s_inode *root, char *path, int follow, int flags)
|
||||||
{
|
{
|
||||||
char *s;
|
|
||||||
vfs_s_entry* ent = NULL;
|
vfs_s_entry* ent = NULL;
|
||||||
|
|
||||||
if (!(flags & FL_DIR)) {
|
if (!(flags & FL_DIR)) {
|
||||||
@ -435,7 +439,8 @@ char *vfs_s_get_path_mangle (vfs *me, char *inname, struct vfs_s_super **archive
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & FL_NO_OPEN) ERRNOR (EIO, NULL);
|
if (flags & FL_NO_OPEN)
|
||||||
|
ERRNOR (EIO, NULL);
|
||||||
|
|
||||||
super = vfs_s_new_super (me);
|
super = vfs_s_new_super (me);
|
||||||
result = MEDATA->open_archive (me, super, archive_name, op);
|
result = MEDATA->open_archive (me, super, archive_name, op);
|
||||||
@ -523,8 +528,10 @@ void * vfs_s_opendir (vfs *me, char *dirname)
|
|||||||
struct dirhandle *info;
|
struct dirhandle *info;
|
||||||
|
|
||||||
dir = vfs_s_inode_from_path (me, dirname, FL_DIR | FL_FOLLOW);
|
dir = vfs_s_inode_from_path (me, dirname, FL_DIR | FL_FOLLOW);
|
||||||
if (!dir) return NULL;
|
if (!dir)
|
||||||
if (!S_ISDIR (dir->st.st_mode)) ERRNOR (ENOTDIR, NULL);
|
return NULL;
|
||||||
|
if (!S_ISDIR (dir->st.st_mode))
|
||||||
|
ERRNOR (ENOTDIR, NULL);
|
||||||
|
|
||||||
dir->st.st_nlink++;
|
dir->st.st_nlink++;
|
||||||
#if 0
|
#if 0
|
||||||
@ -556,7 +563,7 @@ void * vfs_s_readdir (void *data)
|
|||||||
strcpy (&(dir.dir.d_name [0]), info->cur->name);
|
strcpy (&(dir.dir.d_name [0]), info->cur->name);
|
||||||
else
|
else
|
||||||
vfs_die( "Null in structure-can not happen");
|
vfs_die( "Null in structure-can not happen");
|
||||||
|
|
||||||
#ifndef DIRENT_LENGTH_COMPUTED
|
#ifndef DIRENT_LENGTH_COMPUTED
|
||||||
dir.d_namlen = strlen (dir.dir.d_name);
|
dir.d_namlen = strlen (dir.dir.d_name);
|
||||||
#endif
|
#endif
|
||||||
@ -573,7 +580,8 @@ int vfs_s_telldir (void *data)
|
|||||||
|
|
||||||
cur = info->dir->subdir;
|
cur = info->dir->subdir;
|
||||||
while (cur!=NULL) {
|
while (cur!=NULL) {
|
||||||
if (cur == info->cur) return num;
|
if (cur == info->cur)
|
||||||
|
return num;
|
||||||
num++;
|
num++;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
@ -614,7 +622,8 @@ static int vfs_s_internal_stat (vfs *me, char *path, struct stat *buf, int flag)
|
|||||||
{
|
{
|
||||||
struct vfs_s_inode *ino;
|
struct vfs_s_inode *ino;
|
||||||
|
|
||||||
if (!(ino = vfs_s_inode_from_path( me, path, flag ))) return -1;
|
if (!(ino = vfs_s_inode_from_path( me, path, flag )))
|
||||||
|
return -1;
|
||||||
*buf = ino->st;
|
*buf = ino->st;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -640,9 +649,11 @@ int vfs_s_readlink (vfs *me, char *path, char *buf, int size)
|
|||||||
struct vfs_s_inode *ino;
|
struct vfs_s_inode *ino;
|
||||||
|
|
||||||
ino = vfs_s_inode_from_path(me, path, 0);
|
ino = vfs_s_inode_from_path(me, path, 0);
|
||||||
if (!ino) return -1;
|
if (!ino)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (!S_ISLNK (ino->st.st_mode)) ERRNOR (EINVAL, -1);
|
if (!S_ISLNK (ino->st.st_mode))
|
||||||
|
ERRNOR (EINVAL, -1);
|
||||||
strncpy (buf, ino->linkname, size);
|
strncpy (buf, ino->linkname, size);
|
||||||
*(buf+size-1) = 0;
|
*(buf+size-1) = 0;
|
||||||
return strlen(buf);
|
return strlen(buf);
|
||||||
@ -681,7 +692,8 @@ void *vfs_s_open (vfs *me, char *file, int flags, int mode)
|
|||||||
was_changed = 1;
|
was_changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISDIR (ino->st.st_mode)) ERRNOR (EISDIR, NULL);
|
if (S_ISDIR (ino->st.st_mode))
|
||||||
|
ERRNOR (EISDIR, NULL);
|
||||||
|
|
||||||
fh = (struct vfs_s_fh *) xmalloc (sizeof (struct vfs_s_fh), "Direntry: filehandle");
|
fh = (struct vfs_s_fh *) xmalloc (sizeof (struct vfs_s_fh), "Direntry: filehandle");
|
||||||
fh->pos = 0;
|
fh->pos = 0;
|
||||||
@ -810,8 +822,10 @@ int vfs_s_close (void *fh)
|
|||||||
res = MEDATA->fh_close (me, fh);
|
res = MEDATA->fh_close (me, fh);
|
||||||
if (FH->changed && MEDATA->file_store) {
|
if (FH->changed && MEDATA->file_store) {
|
||||||
char *s = vfs_s_fullpath( me, FH->ino );
|
char *s = vfs_s_fullpath( me, FH->ino );
|
||||||
if (!s) res = -1;
|
if (!s)
|
||||||
else res = MEDATA->file_store (me, FH_SUPER, s, FH->ino->localname);
|
res = -1;
|
||||||
|
else
|
||||||
|
res = MEDATA->file_store (me, FH_SUPER, s, FH->ino->localname);
|
||||||
vfs_s_invalidate(me, FH_SUPER);
|
vfs_s_invalidate(me, FH_SUPER);
|
||||||
}
|
}
|
||||||
if (FH->handle)
|
if (FH->handle)
|
||||||
@ -848,7 +862,9 @@ void
|
|||||||
vfs_s_dump(vfs *me, char *prefix, vfs_s_inode *ino)
|
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 );
|
printf( "%s %s %d ", prefix, S_ISDIR(ino->st.st_mode) ? "DIR" : "FILE", ino->st.st_mode );
|
||||||
if (!ino->subdir) printf ("FILE\n");
|
if (!ino->subdir)
|
||||||
|
printf ("FILE\n");
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct vfs_s_entry *ent;
|
struct vfs_s_entry *ent;
|
||||||
|
@ -104,7 +104,7 @@ static int command (vfs *me, vfs_s_super *super, int wait_reply, char *fmt, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *str;
|
char *str;
|
||||||
int n, status;
|
int status;
|
||||||
FILE *logfile = MEDATA->logfile;
|
FILE *logfile = MEDATA->logfile;
|
||||||
|
|
||||||
va_start (ap, fmt);
|
va_start (ap, fmt);
|
||||||
|
215
vfs/ftpfs.c
215
vfs/ftpfs.c
@ -143,8 +143,8 @@ static struct linklist *connections_list;
|
|||||||
#define WANT_STRING 0x02
|
#define WANT_STRING 0x02
|
||||||
static char reply_str [80];
|
static char reply_str [80];
|
||||||
|
|
||||||
static struct direntry *_get_file_entry(struct connection *bucket,
|
static struct direntry *_get_file_entry (struct connection *bucket,
|
||||||
char *file_name, int op, int flags);
|
char *file_name, int op, int flags);
|
||||||
|
|
||||||
static char *ftpfs_get_current_directory (struct connection *bucket);
|
static char *ftpfs_get_current_directory (struct connection *bucket);
|
||||||
static int ftpfs_chdir_internal (struct connection *bucket,
|
static int ftpfs_chdir_internal (struct connection *bucket,
|
||||||
@ -184,16 +184,16 @@ get_reply (int sock, char *string_buf, int string_len)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!get_line(sock, answer, sizeof(answer), '\n')) {
|
if (!get_line (sock, answer, sizeof (answer), '\n')){
|
||||||
if (string_buf)
|
if (string_buf)
|
||||||
*string_buf = 0;
|
*string_buf = 0;
|
||||||
code = 421;
|
code = 421;
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
switch(sscanf(answer, "%d", &code)) {
|
switch (sscanf(answer, "%d", &code)){
|
||||||
case 0:
|
case 0:
|
||||||
if (string_buf) {
|
if (string_buf) {
|
||||||
strncpy(string_buf, answer, string_len - 1);
|
strncpy (string_buf, answer, string_len - 1);
|
||||||
*(string_buf + string_len - 1) = 0;
|
*(string_buf + string_len - 1) = 0;
|
||||||
}
|
}
|
||||||
code = 500;
|
code = 500;
|
||||||
@ -201,19 +201,19 @@ get_reply (int sock, char *string_buf, int string_len)
|
|||||||
case 1:
|
case 1:
|
||||||
if (answer[3] == '-') {
|
if (answer[3] == '-') {
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!get_line(sock, answer, sizeof(answer), '\n')) {
|
if (!get_line (sock, answer, sizeof(answer), '\n')){
|
||||||
if (string_buf)
|
if (string_buf)
|
||||||
*string_buf = 0;
|
*string_buf = 0;
|
||||||
code = 421;
|
code = 421;
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
if ((sscanf(answer, "%d", &i) > 0) &&
|
if ((sscanf (answer, "%d", &i) > 0) &&
|
||||||
(code == i) && (answer[3] == ' '))
|
(code == i) && (answer[3] == ' '))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (string_buf) {
|
if (string_buf){
|
||||||
strncpy(string_buf, answer, string_len - 1);
|
strncpy (string_buf, answer, string_len - 1);
|
||||||
*(string_buf + string_len - 1) = 0;
|
*(string_buf + string_len - 1) = 0;
|
||||||
}
|
}
|
||||||
return code / 100;
|
return code / 100;
|
||||||
@ -226,7 +226,7 @@ command (struct connection *bucket, int wait_reply, char *fmt, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *str, *fmt_str;
|
char *str, *fmt_str;
|
||||||
int n, status;
|
int status;
|
||||||
int sock = qsock (bucket);
|
int sock = qsock (bucket);
|
||||||
|
|
||||||
va_start (ap, fmt);
|
va_start (ap, fmt);
|
||||||
@ -275,7 +275,7 @@ connection_close (void *data)
|
|||||||
struct connection *bucket = data;
|
struct connection *bucket = data;
|
||||||
|
|
||||||
if (qsock (bucket) != -1){
|
if (qsock (bucket) != -1){
|
||||||
print_vfs_message ("ftpfs: Disconnecting from %s", qhost(bucket));
|
print_vfs_message ("ftpfs: Disconnecting from %s", qhost (bucket));
|
||||||
command(bucket, NONE, "QUIT");
|
command(bucket, NONE, "QUIT");
|
||||||
close(qsock(bucket));
|
close(qsock(bucket));
|
||||||
}
|
}
|
||||||
@ -294,7 +294,8 @@ static int
|
|||||||
changetype (struct connection *bucket, int binary)
|
changetype (struct connection *bucket, int binary)
|
||||||
{
|
{
|
||||||
if (binary != bucket->isbinary) {
|
if (binary != bucket->isbinary) {
|
||||||
if (command (bucket, WAIT_REPLY, "TYPE %c", binary ? 'I' : 'A') != COMPLETE) ERRNOR (EIO, -1);
|
if (command (bucket, WAIT_REPLY, "TYPE %c", binary ? 'I' : 'A') != COMPLETE)
|
||||||
|
ERRNOR (EIO, -1);
|
||||||
bucket->isbinary = binary;
|
bucket->isbinary = binary;
|
||||||
}
|
}
|
||||||
return binary;
|
return binary;
|
||||||
@ -316,19 +317,20 @@ login_server (struct connection *bucket, char *netrcpass)
|
|||||||
if (netrcpass)
|
if (netrcpass)
|
||||||
op = strdup (netrcpass);
|
op = strdup (netrcpass);
|
||||||
else {
|
else {
|
||||||
if (!strcmp (quser(bucket), "anonymous") ||
|
if (!strcmp (quser (bucket), "anonymous") ||
|
||||||
!strcmp (quser(bucket), "ftp")) {
|
!strcmp (quser (bucket), "ftp")) {
|
||||||
op = strdup(ftpfs_anonymous_passwd);
|
op = strdup (ftpfs_anonymous_passwd);
|
||||||
anon = 1;
|
anon = 1;
|
||||||
} else {
|
} else {
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if (!bucket->password){
|
if (!bucket->password){
|
||||||
p = copy_strings (" FTP: Password required for ", quser(bucket),
|
p = copy_strings (" FTP: Password required for ", quser (bucket),
|
||||||
" ", NULL);
|
" ", NULL);
|
||||||
op = vfs_get_password (p);
|
op = vfs_get_password (p);
|
||||||
free (p);
|
free (p);
|
||||||
if (op == NULL) ERRNOR (EPERM, 0);
|
if (op == NULL)
|
||||||
|
ERRNOR (EPERM, 0);
|
||||||
bucket->password = strdup (op);
|
bucket->password = strdup (op);
|
||||||
} else
|
} else
|
||||||
op = strdup (bucket->password);
|
op = strdup (bucket->password);
|
||||||
@ -347,44 +349,47 @@ login_server (struct connection *bucket, char *netrcpass)
|
|||||||
#if defined(HSC_PROXY)
|
#if defined(HSC_PROXY)
|
||||||
char *p, *host;
|
char *p, *host;
|
||||||
int port;
|
int port;
|
||||||
p = my_get_host_and_username(ftpfs_proxy_host, &host, &proxyname,
|
p = my_get_host_and_username (ftpfs_proxy_host, &host, &proxyname,
|
||||||
&port, &proxypass);
|
&port, &proxypass);
|
||||||
if (p)
|
if (p)
|
||||||
free (p);
|
free (p);
|
||||||
|
|
||||||
free(host);
|
free (host);
|
||||||
if (proxypass)
|
if (proxypass)
|
||||||
wipe_password (proxypass);
|
wipe_password (proxypass);
|
||||||
p = copy_strings(" Proxy: Password required for ", proxyname, " ",
|
p = copy_strings (" Proxy: Password required for ", proxyname, " ",
|
||||||
NULL);
|
NULL);
|
||||||
proxypass = vfs_get_password (p);
|
proxypass = vfs_get_password (p);
|
||||||
free(p);
|
free (p);
|
||||||
if (proxypass == NULL) {
|
if (proxypass == NULL) {
|
||||||
wipe_password (pass);
|
wipe_password (pass);
|
||||||
free (proxyname);
|
free (proxyname);
|
||||||
ERRNOR (EPERM, 0);
|
ERRNOR (EPERM, 0);
|
||||||
}
|
}
|
||||||
name = strdup(quser (bucket));
|
name = strdup (quser (bucket));
|
||||||
#else
|
#else
|
||||||
name = copy_strings (quser(bucket), "@",
|
name = copy_strings (quser (bucket), "@",
|
||||||
qhost(bucket)[0] == '!' ? qhost(bucket)+1 : qhost(bucket), 0);
|
qhost (bucket)[0] == '!' ? qhost (bucket)+1 : qhost (bucket), 0);
|
||||||
#endif
|
#endif
|
||||||
} else
|
} else
|
||||||
name = strdup (quser (bucket));
|
name = strdup (quser (bucket));
|
||||||
|
|
||||||
if (get_reply (qsock(bucket), NULL, 0) == COMPLETE) {
|
if (get_reply (qsock (bucket), NULL, 0) == COMPLETE) {
|
||||||
#if defined(HSC_PROXY)
|
#if defined(HSC_PROXY)
|
||||||
if (qproxy(bucket)) {
|
if (qproxy (bucket)){
|
||||||
print_vfs_message("ftpfs: sending proxy login name");
|
print_vfs_message ("ftpfs: sending proxy login name");
|
||||||
if (command (bucket, 1, "USER %s", proxyname) != CONTINUE)
|
if (command (bucket, 1, "USER %s", proxyname) != CONTINUE)
|
||||||
goto proxyfail;
|
goto proxyfail;
|
||||||
print_vfs_message("ftpfs: sending proxy user password");
|
|
||||||
|
print_vfs_message ("ftpfs: sending proxy user password");
|
||||||
if (command (bucket, 1, "PASS %s", proxypass) != COMPLETE)
|
if (command (bucket, 1, "PASS %s", proxypass) != COMPLETE)
|
||||||
goto proxyfail;
|
goto proxyfail;
|
||||||
print_vfs_message("ftpfs: proxy authentication succeeded");
|
|
||||||
if (command (bucket, 1, "SITE %s", qhost(bucket)+1) != COMPLETE)
|
print_vfs_message ("ftpfs: proxy authentication succeeded");
|
||||||
|
if (command (bucket, 1, "SITE %s", qhost (bucket)+1) != COMPLETE)
|
||||||
goto proxyfail;
|
goto proxyfail;
|
||||||
print_vfs_message("ftpfs: connected to %s", qhost(bucket)+1);
|
|
||||||
|
print_vfs_message ("ftpfs: connected to %s", qhost (bucket)+1);
|
||||||
if (0) {
|
if (0) {
|
||||||
proxyfail:
|
proxyfail:
|
||||||
bucket->failed_on_login = 1;
|
bucket->failed_on_login = 1;
|
||||||
@ -401,17 +406,17 @@ login_server (struct connection *bucket, char *netrcpass)
|
|||||||
free (proxyname);
|
free (proxyname);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
print_vfs_message("ftpfs: sending login name");
|
print_vfs_message ("ftpfs: sending login name");
|
||||||
code = command (bucket, WAIT_REPLY, "USER %s", name);
|
code = command (bucket, WAIT_REPLY, "USER %s", name);
|
||||||
|
|
||||||
switch (code){
|
switch (code){
|
||||||
case CONTINUE:
|
case CONTINUE:
|
||||||
print_vfs_message("ftpfs: sending user password");
|
print_vfs_message ("ftpfs: sending user password");
|
||||||
if (command (bucket, WAIT_REPLY, "PASS %s", pass) != COMPLETE)
|
if (command (bucket, WAIT_REPLY, "PASS %s", pass) != COMPLETE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMPLETE:
|
case COMPLETE:
|
||||||
print_vfs_message("ftpfs: logged in");
|
print_vfs_message ("ftpfs: logged in");
|
||||||
wipe_password (pass);
|
wipe_password (pass);
|
||||||
free (name);
|
free (name);
|
||||||
return 1;
|
return 1;
|
||||||
@ -426,7 +431,7 @@ login_server (struct connection *bucket, char *netrcpass)
|
|||||||
goto login_fail;
|
goto login_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print_vfs_message ("ftpfs: Login incorrect for user %s ", quser(bucket));
|
print_vfs_message ("ftpfs: Login incorrect for user %s ", quser (bucket));
|
||||||
login_fail:
|
login_fail:
|
||||||
wipe_password (pass);
|
wipe_password (pass);
|
||||||
free (name);
|
free (name);
|
||||||
@ -566,17 +571,17 @@ ftpfs_get_proxy_host_and_port (char *proxy, char **host, int *port)
|
|||||||
#else
|
#else
|
||||||
#define PORT 21
|
#define PORT 21
|
||||||
#endif
|
#endif
|
||||||
dir = vfs_split_url(proxy, host, &user, port, &pass, PORT, URL_DEFAULTANON);
|
dir = vfs_split_url (proxy, host, &user, port, &pass, PORT, URL_DEFAULTANON);
|
||||||
|
|
||||||
free(user);
|
free (user);
|
||||||
if (pass)
|
if (pass)
|
||||||
wipe_password (pass);
|
wipe_password (pass);
|
||||||
if (dir)
|
if (dir)
|
||||||
free(dir);
|
free (dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ftpfs_open_socket(struct connection *bucket)
|
ftpfs_open_socket (struct connection *bucket)
|
||||||
{
|
{
|
||||||
struct sockaddr_in server_address;
|
struct sockaddr_in server_address;
|
||||||
struct hostent *hp;
|
struct hostent *hp;
|
||||||
@ -586,7 +591,7 @@ ftpfs_open_socket(struct connection *bucket)
|
|||||||
int free_host = 0;
|
int free_host = 0;
|
||||||
|
|
||||||
/* Use a proxy host? */
|
/* Use a proxy host? */
|
||||||
host = qhost(bucket);
|
host = qhost (bucket);
|
||||||
|
|
||||||
if (!host || !*host){
|
if (!host || !*host){
|
||||||
print_vfs_message ("ftpfs: Invalid host name.");
|
print_vfs_message ("ftpfs: Invalid host name.");
|
||||||
@ -595,7 +600,7 @@ ftpfs_open_socket(struct connection *bucket)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Hosts to connect to that start with a ! should use proxy */
|
/* Hosts to connect to that start with a ! should use proxy */
|
||||||
if (qproxy(bucket)) {
|
if (qproxy (bucket)){
|
||||||
ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &port);
|
ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &port);
|
||||||
free_host = 1;
|
free_host = 1;
|
||||||
}
|
}
|
||||||
@ -607,9 +612,9 @@ ftpfs_open_socket(struct connection *bucket)
|
|||||||
if (server_address.sin_addr.s_addr != -1)
|
if (server_address.sin_addr.s_addr != -1)
|
||||||
server_address.sin_family = AF_INET;
|
server_address.sin_family = AF_INET;
|
||||||
else {
|
else {
|
||||||
hp = gethostbyname(host);
|
hp = gethostbyname (host);
|
||||||
if (hp == NULL){
|
if (hp == NULL){
|
||||||
print_vfs_message("ftpfs: Invalid host address.");
|
print_vfs_message ("ftpfs: Invalid host address.");
|
||||||
my_errno = EINVAL;
|
my_errno = EINVAL;
|
||||||
if (free_host)
|
if (free_host)
|
||||||
free (host);
|
free (host);
|
||||||
@ -634,20 +639,20 @@ ftpfs_open_socket(struct connection *bucket)
|
|||||||
}
|
}
|
||||||
setup_source_route (my_socket, server_address.sin_addr.s_addr);
|
setup_source_route (my_socket, server_address.sin_addr.s_addr);
|
||||||
|
|
||||||
print_vfs_message("ftpfs: making connection to %s", host);
|
print_vfs_message ("ftpfs: making connection to %s", host);
|
||||||
if (free_host)
|
if (free_host)
|
||||||
free (host);
|
free (host);
|
||||||
|
|
||||||
enable_interrupt_key(); /* clear the interrupt flag */
|
enable_interrupt_key (); /* clear the interrupt flag */
|
||||||
|
|
||||||
if (connect (my_socket, (struct sockaddr *) &server_address,
|
if (connect (my_socket, (struct sockaddr *) &server_address,
|
||||||
sizeof (server_address)) < 0){
|
sizeof (server_address)) < 0){
|
||||||
my_errno = errno;
|
my_errno = errno;
|
||||||
if (errno == EINTR && got_interrupt())
|
if (errno == EINTR && got_interrupt ())
|
||||||
print_vfs_message("ftpfs: connection interrupted by user");
|
print_vfs_message ("ftpfs: connection interrupted by user");
|
||||||
else
|
else
|
||||||
print_vfs_message("ftpfs: connection to server failed: %s",
|
print_vfs_message ("ftpfs: connection to server failed: %s",
|
||||||
unix_error_string(errno));
|
unix_error_string(errno));
|
||||||
disable_interrupt_key();
|
disable_interrupt_key();
|
||||||
close (my_socket);
|
close (my_socket);
|
||||||
return -1;
|
return -1;
|
||||||
@ -665,7 +670,8 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
|
|||||||
bucket = xmalloc(sizeof(struct connection),
|
bucket = xmalloc(sizeof(struct connection),
|
||||||
"struct connection");
|
"struct connection");
|
||||||
|
|
||||||
if (bucket == NULL) ERRNOR (ENOMEM, NULL);
|
if (bucket == NULL)
|
||||||
|
ERRNOR (ENOMEM, NULL);
|
||||||
#ifdef HAVE_MAD
|
#ifdef HAVE_MAD
|
||||||
{
|
{
|
||||||
extern void *watch_free_pointer;
|
extern void *watch_free_pointer;
|
||||||
@ -674,15 +680,15 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
|
|||||||
watch_free_pointer = host;
|
watch_free_pointer = host;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
qhost(bucket) = strdup (host);
|
qhost (bucket) = strdup (host);
|
||||||
quser(bucket) = strdup (user);
|
quser (bucket) = strdup (user);
|
||||||
qcdir(bucket) = NULL;
|
qcdir (bucket) = NULL;
|
||||||
qport(bucket) = port;
|
qport (bucket) = port;
|
||||||
qlock(bucket) = 0;
|
qlock (bucket) = 0;
|
||||||
qhome(bucket) = NULL;
|
qhome (bucket) = NULL;
|
||||||
qproxy(bucket)= 0;
|
qproxy (bucket)= 0;
|
||||||
qupdir(bucket)= 0;
|
qupdir (bucket)= 0;
|
||||||
qdcache(bucket)=0;
|
qdcache (bucket)=0;
|
||||||
bucket->__inode_counter = 0;
|
bucket->__inode_counter = 0;
|
||||||
bucket->lock = 0;
|
bucket->lock = 0;
|
||||||
bucket->use_proxy = ftpfs_check_proxy (host);
|
bucket->use_proxy = ftpfs_check_proxy (host);
|
||||||
@ -696,10 +702,10 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
|
|||||||
if (bucket->use_proxy)
|
if (bucket->use_proxy)
|
||||||
bucket->use_passive_connection = 0;
|
bucket->use_passive_connection = 0;
|
||||||
|
|
||||||
if ((qdcache(bucket) = linklist_init()) == NULL) {
|
if ((qdcache (bucket) = linklist_init ()) == NULL) {
|
||||||
my_errno = ENOMEM;
|
my_errno = ENOMEM;
|
||||||
free (qhost(bucket));
|
free (qhost (bucket));
|
||||||
free (quser(bucket));
|
free (quser (bucket));
|
||||||
free (bucket);
|
free (bucket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -708,13 +714,13 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
|
|||||||
do {
|
do {
|
||||||
bucket->failed_on_login = 0;
|
bucket->failed_on_login = 0;
|
||||||
|
|
||||||
qsock(bucket) = ftpfs_open_socket(bucket);
|
qsock (bucket) = ftpfs_open_socket (bucket);
|
||||||
if (qsock(bucket) == -1) {
|
if (qsock (bucket) == -1) {
|
||||||
free_bucket (bucket);
|
free_bucket (bucket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (login_server(bucket, netrcpass)) {
|
if (login_server (bucket, netrcpass)) {
|
||||||
/* Logged in, no need to retry the connection */
|
/* Logged in, no need to retry the connection */
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -743,15 +749,15 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
|
|||||||
}
|
}
|
||||||
} while (retry_seconds);
|
} while (retry_seconds);
|
||||||
|
|
||||||
qhome(bucket) = ftpfs_get_current_directory (bucket);
|
qhome (bucket) = ftpfs_get_current_directory (bucket);
|
||||||
if (!qhome(bucket))
|
if (!qhome (bucket))
|
||||||
qhome(bucket) = strdup ("/");
|
qhome (bucket) = strdup ("/");
|
||||||
qupdir(bucket) = strdup ("/"); /* FIXME: I changed behavior to ignore last_current_dir */
|
qupdir (bucket) = strdup ("/"); /* FIXME: I changed behavior to ignore last_current_dir */
|
||||||
return bucket;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_connection_closed(struct connection *bucket)
|
is_connection_closed (struct connection *bucket)
|
||||||
{
|
{
|
||||||
fd_set rset;
|
fd_set rset;
|
||||||
struct timeval t;
|
struct timeval t;
|
||||||
@ -761,16 +767,16 @@ is_connection_closed(struct connection *bucket)
|
|||||||
}
|
}
|
||||||
t.tv_sec = 0;
|
t.tv_sec = 0;
|
||||||
t.tv_usec = 0;
|
t.tv_usec = 0;
|
||||||
FD_ZERO(&rset);
|
FD_ZERO (&rset);
|
||||||
FD_SET(qsock(bucket), &rset);
|
FD_SET (qsock (bucket), &rset);
|
||||||
while (1) {
|
while (1) {
|
||||||
if (select(qsock(bucket) + 1, &rset, NULL, NULL, &t) < 0)
|
if (select (qsock (bucket) + 1, &rset, NULL, NULL, &t) < 0)
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
#if 0
|
#if 0
|
||||||
if (FD_ISSET(qsock(bucket), &rset)) {
|
if (FD_ISSET (qsock(bucket), &rset)) {
|
||||||
n = read(qsock(bucket), &read_ahead, sizeof(read_ahead));
|
n = read (qsock(bucket), &read_ahead, sizeof (read_ahead));
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
@ -790,47 +796,48 @@ open_link (char *host, char *user, int port, char *netrcpass)
|
|||||||
for (lptr = connections_list->next;
|
for (lptr = connections_list->next;
|
||||||
lptr != connections_list; lptr = lptr->next) {
|
lptr != connections_list; lptr = lptr->next) {
|
||||||
bucket = lptr->data;
|
bucket = lptr->data;
|
||||||
if ((strcmp (host, qhost(bucket)) == 0) &&
|
if ((strcmp (host, qhost (bucket)) == 0) &&
|
||||||
(strcmp (user, quser(bucket)) == 0) &&
|
(strcmp (user, quser (bucket)) == 0) &&
|
||||||
(port == qport(bucket))) {
|
(port == qport (bucket))) {
|
||||||
|
|
||||||
/* check the connection is closed or not, just hack */
|
/* check the connection is closed or not, just hack */
|
||||||
if (is_connection_closed(bucket)) {
|
if (is_connection_closed (bucket)) {
|
||||||
flush_all_directory(bucket);
|
flush_all_directory (bucket);
|
||||||
sock = ftpfs_open_socket(bucket);
|
sock = ftpfs_open_socket (bucket);
|
||||||
if (sock != -1) {
|
if (sock != -1) {
|
||||||
close(qsock(bucket));
|
close (qsock (bucket));
|
||||||
qsock(bucket) = sock;
|
qsock (bucket) = sock;
|
||||||
if (login_server(bucket, netrcpass))
|
if (login_server (bucket, netrcpass))
|
||||||
return bucket;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* connection refused */
|
/* connection refused */
|
||||||
lptr->prev->next = lptr->next;
|
lptr->prev->next = lptr->next;
|
||||||
lptr->next->prev = lptr->prev;
|
lptr->next->prev = lptr->prev;
|
||||||
connection_destructor(bucket);
|
connection_destructor (bucket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return bucket;
|
return bucket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bucket = open_command_connection(host, user, port, netrcpass);
|
bucket = open_command_connection (host, user, port, netrcpass);
|
||||||
if (bucket == NULL)
|
if (bucket == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!linklist_insert(connections_list, bucket)) {
|
if (!linklist_insert (connections_list, bucket)) {
|
||||||
my_errno = ENOMEM;
|
my_errno = ENOMEM;
|
||||||
connection_destructor(bucket);
|
connection_destructor (bucket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return bucket;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The returned directory should always contain a trailing slash */
|
/* The returned directory should always contain a trailing slash */
|
||||||
static char *ftpfs_get_current_directory(struct connection *bucket)
|
static char *
|
||||||
|
ftpfs_get_current_directory (struct connection *bucket)
|
||||||
{
|
{
|
||||||
char buf[4096], *bufp, *bufq;
|
char buf[4096], *bufp, *bufq;
|
||||||
|
|
||||||
if (command(bucket, NONE, "PWD") == COMPLETE &&
|
if (command (bucket, NONE, "PWD") == COMPLETE &&
|
||||||
get_reply(qsock(bucket), buf, sizeof(buf)) == COMPLETE) {
|
get_reply(qsock(bucket), buf, sizeof(buf)) == COMPLETE) {
|
||||||
bufp = NULL;
|
bufp = NULL;
|
||||||
for (bufq = buf; *bufq; bufq++)
|
for (bufq = buf; *bufq; bufq++)
|
||||||
@ -900,9 +907,11 @@ initconn (struct connection *bucket)
|
|||||||
data_addr.sin_port = 0;
|
data_addr.sin_port = 0;
|
||||||
|
|
||||||
pe = getprotobyname("tcp");
|
pe = getprotobyname("tcp");
|
||||||
if (pe == NULL) ERRNOR (EIO, -1);
|
if (pe == NULL)
|
||||||
|
ERRNOR (EIO, -1);
|
||||||
data = socket (AF_INET, SOCK_STREAM, pe->p_proto);
|
data = socket (AF_INET, SOCK_STREAM, pe->p_proto);
|
||||||
if (data < 0) ERRNOR (EIO, -1);
|
if (data < 0)
|
||||||
|
ERRNOR (EIO, -1);
|
||||||
|
|
||||||
#ifdef ORIGINAL_CONNECT_CODE
|
#ifdef ORIGINAL_CONNECT_CODE
|
||||||
if (bucket->use_source_route){
|
if (bucket->use_source_route){
|
||||||
@ -965,7 +974,8 @@ open_data_connection (struct connection *bucket, char *cmd, char *remote,
|
|||||||
j = command (bucket, WAIT_REPLY, "%s %s", cmd, remote);
|
j = command (bucket, WAIT_REPLY, "%s %s", cmd, remote);
|
||||||
else
|
else
|
||||||
j = command (bucket, WAIT_REPLY, "%s", cmd);
|
j = command (bucket, WAIT_REPLY, "%s", cmd);
|
||||||
if (j != PRELIM) ERRNOR (EPERM, -1);
|
if (j != PRELIM)
|
||||||
|
ERRNOR (EPERM, -1);
|
||||||
enable_interrupt_key();
|
enable_interrupt_key();
|
||||||
if (bucket->use_passive_connection)
|
if (bucket->use_passive_connection)
|
||||||
data = s;
|
data = s;
|
||||||
@ -1222,7 +1232,8 @@ retrieve_dir(struct connection *bucket, char *remote_path, int resolve_symlinks)
|
|||||||
}
|
}
|
||||||
|
|
||||||
file_list = linklist_init();
|
file_list = linklist_init();
|
||||||
if (file_list == NULL) ERRNOR (ENOMEM, NULL);
|
if (file_list == NULL)
|
||||||
|
ERRNOR (ENOMEM, NULL);
|
||||||
dcache = xmalloc(sizeof(struct dir),
|
dcache = xmalloc(sizeof(struct dir),
|
||||||
"struct dir");
|
"struct dir");
|
||||||
if (dcache == NULL) {
|
if (dcache == NULL) {
|
||||||
@ -1384,7 +1395,8 @@ store_file(struct direntry *fe)
|
|||||||
|
|
||||||
local_handle = open(fe->local_filename, O_RDONLY);
|
local_handle = open(fe->local_filename, O_RDONLY);
|
||||||
unlink (fe->local_filename);
|
unlink (fe->local_filename);
|
||||||
if (local_handle == -1) ERRNOR (EIO, 0);
|
if (local_handle == -1)
|
||||||
|
ERRNOR (EIO, 0);
|
||||||
fstat(local_handle, &s);
|
fstat(local_handle, &s);
|
||||||
sock = open_data_connection(fe->bucket, "STOR", fe->remote_filename, TYPE_BINARY, 0);
|
sock = open_data_connection(fe->bucket, "STOR", fe->remote_filename, TYPE_BINARY, 0);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
@ -1435,7 +1447,8 @@ store_file(struct direntry *fe)
|
|||||||
disable_interrupt_key();
|
disable_interrupt_key();
|
||||||
close(sock);
|
close(sock);
|
||||||
close(local_handle);
|
close(local_handle);
|
||||||
if (get_reply (qsock (fe->bucket), NULL, 0) != COMPLETE) ERRNOR (EIO, 0);
|
if (get_reply (qsock (fe->bucket), NULL, 0) != COMPLETE)
|
||||||
|
ERRNOR (EIO, 0);
|
||||||
return 1;
|
return 1;
|
||||||
error_return:
|
error_return:
|
||||||
disable_interrupt_key();
|
disable_interrupt_key();
|
||||||
@ -1473,7 +1486,8 @@ linear_read (struct direntry *fe, void *buf, int len)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n<0) linear_abort(fe);
|
if (n<0)
|
||||||
|
linear_abort(fe);
|
||||||
|
|
||||||
if (!n) {
|
if (!n) {
|
||||||
if ((get_reply (qsock (fe->bucket), NULL, 0) != COMPLETE)) {
|
if ((get_reply (qsock (fe->bucket), NULL, 0) != COMPLETE)) {
|
||||||
@ -1531,7 +1545,8 @@ send_ftp_command(char *filename, char *cmd, int flags)
|
|||||||
vfs_add_noncurrent_stamps (&vfs_ftpfs_ops, (vfsid) bucket, NULL);
|
vfs_add_noncurrent_stamps (&vfs_ftpfs_ops, (vfsid) bucket, NULL);
|
||||||
if (flags & OPT_IGNORE_ERROR)
|
if (flags & OPT_IGNORE_ERROR)
|
||||||
r = COMPLETE;
|
r = COMPLETE;
|
||||||
if (r != COMPLETE) ERRNOR (EPERM, -1);
|
if (r != COMPLETE)
|
||||||
|
ERRNOR (EPERM, -1);
|
||||||
if (flush_directory_cache)
|
if (flush_directory_cache)
|
||||||
flush_all_directory(bucket);
|
flush_all_directory(bucket);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -211,7 +211,8 @@ static int mcfs_login_server (int my_socket, char *user, int port,
|
|||||||
|
|
||||||
/* This used to be in utilvfs.c, but as it deals with portmapper, it
|
/* This used to be in utilvfs.c, but as it deals with portmapper, it
|
||||||
is probably usefull for mcfs */
|
is probably usefull for mcfs */
|
||||||
static int open_tcp_link (char *host, int *port, int *version, char *caller)
|
int
|
||||||
|
open_tcp_link (char *host, int *port, int *version, char *caller)
|
||||||
{
|
{
|
||||||
struct sockaddr_in server_address;
|
struct sockaddr_in server_address;
|
||||||
unsigned long inaddr;
|
unsigned long inaddr;
|
||||||
|
140
vfs/sfs.c
140
vfs/sfs.c
@ -50,12 +50,12 @@ static int sfs_flags[ MAXFS ];
|
|||||||
#define F_NOLOCALCOPY 4
|
#define F_NOLOCALCOPY 4
|
||||||
#define F_FULLMATCH 8
|
#define F_FULLMATCH 8
|
||||||
|
|
||||||
static int uptodate( char *name, char *cache )
|
static int uptodate (char *name, char *cache)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vfmake( vfs *me, char *name, char *cache )
|
static int vfmake (vfs *me, char *name, char *cache)
|
||||||
{
|
{
|
||||||
char *inpath, *op;
|
char *inpath, *op;
|
||||||
int w;
|
int w;
|
||||||
@ -63,72 +63,77 @@ static int vfmake( vfs *me, char *name, char *cache )
|
|||||||
char *s, *t = pad;
|
char *s, *t = pad;
|
||||||
int was_percent = 0;
|
int was_percent = 0;
|
||||||
|
|
||||||
vfs_split( name, &inpath, &op );
|
vfs_split (name, &inpath, &op);
|
||||||
if ((w = (*me->which)( me, op )) == -1)
|
if ((w = (*me->which) (me, op)) == -1)
|
||||||
vfs_die( "This cannot happen... Hopefully.\n" );
|
vfs_die ("This cannot happen... Hopefully.\n");
|
||||||
|
|
||||||
if ((sfs_flags[w] & F_1) || (!strcmp( name, "/" ))) ; else return -1;
|
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_2) || (!inpath) || (!*inpath)); else return -1; */
|
||||||
if (!(sfs_flags[w] & F_NOLOCALCOPY))
|
if (!(sfs_flags[w] & F_NOLOCALCOPY))
|
||||||
name = mc_getlocalcopy( name );
|
name = mc_getlocalcopy (name);
|
||||||
else
|
else
|
||||||
name = strdup( name );
|
name = strdup (name);
|
||||||
s = sfs_command[w];
|
s = sfs_command[w];
|
||||||
#define COPY_CHAR if (t-pad>10200) return -1; else *t++ = *s;
|
#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); }
|
#define COPY_STRING(a) if ((t-pad)+strlen(a)>10200) return -1; else { strcpy (t, a); t+= strlen(a); }
|
||||||
while (*s) {
|
while (*s) {
|
||||||
if (was_percent) {
|
if (was_percent) {
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case '1': COPY_STRING( name ); break;
|
case '1': COPY_STRING (name); break;
|
||||||
case '2': COPY_STRING( op + strlen( sfs_prefix[w] ) ); break;
|
case '2': COPY_STRING (op + strlen (sfs_prefix[w])); break;
|
||||||
case '3': COPY_STRING( cache ); break;
|
case '3': COPY_STRING (cache); break;
|
||||||
case '%': COPY_CHAR; break;
|
case '%': COPY_CHAR; break;
|
||||||
}
|
}
|
||||||
was_percent = 0;
|
was_percent = 0;
|
||||||
} else {
|
} else {
|
||||||
if (*s == '%') was_percent = 1;
|
if (*s == '%')
|
||||||
else COPY_CHAR;
|
was_percent = 1;
|
||||||
|
else
|
||||||
|
COPY_CHAR;
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
free( name );
|
free (name);
|
||||||
|
|
||||||
if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID, "/bin/sh", pad)) {
|
if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID | EXECUTE_WAIT, "/bin/sh", pad)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; /* OK */
|
return 0; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *redirect( vfs *me, char *name )
|
static char *
|
||||||
|
redirect (vfs *me, char *name)
|
||||||
{
|
{
|
||||||
struct cachedfile *cur = head;
|
struct cachedfile *cur = head;
|
||||||
uid_t uid = vfs_uid;
|
uid_t uid = vfs_uid;
|
||||||
char *cache, *xname;
|
char *cache, *xname;
|
||||||
int handle;
|
int handle;
|
||||||
|
|
||||||
while (cur) {
|
while (cur){
|
||||||
if ((!strcmp( name, cur->name )) &&
|
if ((!strcmp (name, cur->name)) &&
|
||||||
(uid == cur->uid) &&
|
(uid == cur->uid) &&
|
||||||
(uptodate( cur->name, cur->cache )))
|
(uptodate (cur->name, cur->cache)))
|
||||||
/* FIXME: when not uptodate, we might want to kill cache
|
/* FIXME: when not uptodate, we might want to kill cache
|
||||||
* file immediately, not to wait until timeout. */ {
|
* file immediately, not to wait until timeout. */ {
|
||||||
vfs_stamp( &vfs_sfs_ops, cur );
|
vfs_stamp (&vfs_sfs_ops, cur);
|
||||||
return cur->cache;
|
return cur->cache;
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
cache = tempnam( NULL, "sfs" );
|
|
||||||
handle = open(cache, O_RDWR | O_CREAT | O_EXCL, 0600);
|
cache = tempnam (NULL, "sfs");
|
||||||
|
handle = open (cache, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
if (handle == -1)
|
if (handle == -1)
|
||||||
return "/SOMEONE_PLAYING_DIRTY_TMP_TRICKS_ON_US";
|
return "/SOMEONE_PLAYING_DIRTY_TMP_TRICKS_ON_US";
|
||||||
close(handle);
|
|
||||||
|
|
||||||
xname = strdup( name );
|
close (handle);
|
||||||
if (!vfmake( me, name, cache )) {
|
|
||||||
cur = xmalloc( sizeof(struct cachedfile), "SFS cache" );
|
xname = strdup (name);
|
||||||
|
if (!vfmake (me, name, cache)){
|
||||||
|
cur = xmalloc (sizeof(struct cachedfile), "SFS cache");
|
||||||
cur->name = xname;
|
cur->name = xname;
|
||||||
cur->cache = strdup(cache);
|
cur->cache = cache;
|
||||||
cur->uid = uid;
|
cur->uid = uid;
|
||||||
cur->next = head;
|
cur->next = head;
|
||||||
head = cur;
|
head = cur;
|
||||||
@ -143,14 +148,13 @@ static char *redirect( vfs *me, char *name )
|
|||||||
return "/I_MUST_NOT_EXIST";
|
return "/I_MUST_NOT_EXIST";
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REDIR path = redirect( me, path );
|
static void *
|
||||||
|
sfs_open (vfs *me, char *path, int flags, int mode)
|
||||||
static void *sfs_open (vfs *me, char *path, int flags, int mode)
|
|
||||||
{
|
{
|
||||||
int *sfs_info;
|
int *sfs_info;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
REDIR;
|
path = redirect (me, path);
|
||||||
fd = open (path, flags, mode);
|
fd = open (path, flags, mode);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return 0;
|
return 0;
|
||||||
@ -163,13 +167,13 @@ static void *sfs_open (vfs *me, char *path, int flags, int mode)
|
|||||||
|
|
||||||
static int sfs_stat (vfs *me, char *path, struct stat *buf)
|
static int sfs_stat (vfs *me, char *path, struct stat *buf)
|
||||||
{
|
{
|
||||||
REDIR;
|
path = redirect (me, path);
|
||||||
return stat (path, buf);
|
return stat (path, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sfs_lstat (vfs *me, char *path, struct stat *buf)
|
static int sfs_lstat (vfs *me, char *path, struct stat *buf)
|
||||||
{
|
{
|
||||||
REDIR;
|
path = redirect (me, path);
|
||||||
#ifndef HAVE_STATLSTAT
|
#ifndef HAVE_STATLSTAT
|
||||||
return lstat (path,buf);
|
return lstat (path,buf);
|
||||||
#else
|
#else
|
||||||
@ -179,25 +183,25 @@ static int sfs_lstat (vfs *me, char *path, struct stat *buf)
|
|||||||
|
|
||||||
static int sfs_chmod (vfs *me, char *path, int mode)
|
static int sfs_chmod (vfs *me, char *path, int mode)
|
||||||
{
|
{
|
||||||
REDIR;
|
path = redirect (me, path);
|
||||||
return chmod (path, mode);
|
return chmod (path, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sfs_chown (vfs *me, char *path, int owner, int group)
|
static int sfs_chown (vfs *me, char *path, int owner, int group)
|
||||||
{
|
{
|
||||||
REDIR;
|
path = redirect (me, path);
|
||||||
return chown (path, owner, group);
|
return chown (path, owner, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sfs_utime (vfs *me, char *path, struct utimbuf *times)
|
static int sfs_utime (vfs *me, char *path, struct utimbuf *times)
|
||||||
{
|
{
|
||||||
REDIR;
|
path = redirect (me, path);
|
||||||
return utime (path, times);
|
return utime (path, times);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sfs_readlink (vfs *me, char *path, char *buf, int size)
|
static int sfs_readlink (vfs *me, char *path, char *buf, int size)
|
||||||
{
|
{
|
||||||
REDIR;
|
path = redirect (me, path);
|
||||||
return readlink (path, buf, size);
|
return readlink (path, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,10 +224,10 @@ static vfsid sfs_getid (vfs *me, char *path, struct vfs_stamping **parent)
|
|||||||
*parent = NULL;
|
*parent = NULL;
|
||||||
|
|
||||||
{
|
{
|
||||||
char *path2 = strdup( path );
|
char *path2 = strdup (path);
|
||||||
v = vfs_split (path2, NULL, NULL);
|
v = vfs_split (path2, NULL, NULL);
|
||||||
id = (*v->getid) (v, path2, &par);
|
id = (*v->getid) (v, path2, &par);
|
||||||
free( path2 );
|
free (path2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id != (vfsid)-1) {
|
if (id != (vfsid)-1) {
|
||||||
@ -272,7 +276,7 @@ static int sfs_nothingisopen (vfsid id)
|
|||||||
|
|
||||||
static char *sfs_getlocalcopy (vfs *me, char *path)
|
static char *sfs_getlocalcopy (vfs *me, char *path)
|
||||||
{
|
{
|
||||||
REDIR;
|
path = redirect (me, path);
|
||||||
return strdup (path);
|
return strdup (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,30 +286,37 @@ static void sfs_ungetlocalcopy (vfs *me, char *path, char *local, int has_change
|
|||||||
|
|
||||||
static int sfs_init (vfs *me)
|
static int sfs_init (vfs *me)
|
||||||
{
|
{
|
||||||
FILE *cfg = fopen( LIBDIR "extfs/sfs.ini", "r" );
|
FILE *cfg = fopen (LIBDIR "extfs/sfs.ini", "r");
|
||||||
if (!cfg) {
|
|
||||||
fprintf( stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n" );
|
if (!cfg){
|
||||||
|
fprintf (stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sfs_no = 0;
|
sfs_no = 0;
|
||||||
while ( sfs_no < MAXFS ) {
|
while (sfs_no < MAXFS){
|
||||||
char key[256];
|
char key[256];
|
||||||
char *c, *semi = NULL, flags = 0;
|
char *c, *semi = NULL, flags = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!fgets( key, 250, cfg ))
|
if (!fgets (key, 250, cfg))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (*key == '#')
|
if (*key == '#')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (i=0; i<strlen(key); i++)
|
for (i = 0; i < strlen (key); i++)
|
||||||
if ((key[i]==':') || (key[i]=='/'))
|
if ((key[i]==':') || (key[i]=='/')){
|
||||||
{ semi = key+i; if (key[i]=='/') { key[i]=0; flags |= F_FULLMATCH; } break; }
|
semi = key+i;
|
||||||
|
if (key [i] == '/'){
|
||||||
|
key [i] = 0;
|
||||||
|
flags |= F_FULLMATCH;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!semi) {
|
if (!semi){
|
||||||
fprintf( stderr, "Warning: Invalid line %s in sfs.ini.\n", key );
|
fprintf (stderr, "Warning: Invalid line %s in sfs.ini.\n", key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,13 +327,13 @@ static int sfs_init (vfs *me)
|
|||||||
case '2': flags |= F_2; break;
|
case '2': flags |= F_2; break;
|
||||||
case 'R': flags |= F_NOLOCALCOPY; break;
|
case 'R': flags |= F_NOLOCALCOPY; break;
|
||||||
default:
|
default:
|
||||||
fprintf( stderr, "Warning: Invalid flag %c in sfs.ini line %s.\n", *c, key );
|
fprintf (stderr, "Warning: Invalid flag %c in sfs.ini line %s.\n", *c, key);
|
||||||
}
|
}
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
c++;
|
c++;
|
||||||
*(semi+1) = 0;
|
*(semi+1) = 0;
|
||||||
if ((semi = strchr( c, '\n')))
|
if ((semi = strchr (c, '\n')))
|
||||||
*semi = 0;
|
*semi = 0;
|
||||||
|
|
||||||
sfs_prefix [sfs_no] = strdup (key);
|
sfs_prefix [sfs_no] = strdup (key);
|
||||||
@ -330,22 +341,25 @@ static int sfs_init (vfs *me)
|
|||||||
sfs_flags [sfs_no] = flags;
|
sfs_flags [sfs_no] = flags;
|
||||||
sfs_no++;
|
sfs_no++;
|
||||||
}
|
}
|
||||||
fclose(cfg);
|
fclose (cfg);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sfs_done (vfs *me)
|
static void
|
||||||
|
sfs_done (vfs *me)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<sfs_no; i++) {
|
|
||||||
free(sfs_prefix [i]);
|
for (i = 0; i < sfs_no; i++){
|
||||||
free(sfs_command [i]);
|
free (sfs_prefix [i]);
|
||||||
|
free (sfs_command [i]);
|
||||||
sfs_prefix [i] = sfs_command [i] = NULL;
|
sfs_prefix [i] = sfs_command [i] = NULL;
|
||||||
}
|
}
|
||||||
sfs_no = 0;
|
sfs_no = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sfs_which (vfs *me, char *path)
|
static int
|
||||||
|
sfs_which (vfs *me, char *path)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -354,7 +368,7 @@ static int sfs_which (vfs *me, char *path)
|
|||||||
if (!strcmp (path, sfs_prefix [i]))
|
if (!strcmp (path, sfs_prefix [i]))
|
||||||
return i;
|
return i;
|
||||||
} else
|
} else
|
||||||
if (!strncmp (path, sfs_prefix [i], strlen( sfs_prefix[i]) ))
|
if (!strncmp (path, sfs_prefix [i], strlen (sfs_prefix [i])))
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
|
|
||||||
|
101
vfs/tar.c
101
vfs/tar.c
@ -124,9 +124,13 @@ static int tar_open_archive (vfs *me, char *name, vfs_s_super *archive)
|
|||||||
|
|
||||||
static union record rec_buf;
|
static union record rec_buf;
|
||||||
|
|
||||||
static union record *get_next_record (vfs_s_super *archive, int tard)
|
static union record *
|
||||||
|
get_next_record (vfs_s_super *archive, int tard)
|
||||||
{
|
{
|
||||||
if (mc_read (tard, rec_buf.charptr, RECORDSIZE) != RECORDSIZE)
|
int n;
|
||||||
|
|
||||||
|
n = mc_read (tard, rec_buf.charptr, RECORDSIZE);
|
||||||
|
if (n != RECORDSIZE)
|
||||||
return NULL; /* An error has occurred */
|
return NULL; /* An error has occurred */
|
||||||
current_tar_position += RECORDSIZE;
|
current_tar_position += RECORDSIZE;
|
||||||
return &rec_buf;
|
return &rec_buf;
|
||||||
@ -183,12 +187,19 @@ static void fill_stat_from_header (vfs *me, struct stat *st, union record *heade
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
STATUS_BADCHECKSUM,
|
||||||
|
STATUS_SUCCESS,
|
||||||
|
STATUS_EOFMARK,
|
||||||
|
STATUS_EOF,
|
||||||
|
} ReadStatus;
|
||||||
/*
|
/*
|
||||||
* Return 1 for success, 0 if the checksum is bad, EOF on eof,
|
* Return 1 for success, 0 if the checksum is bad, EOF on eof,
|
||||||
* 2 for a record full of zeros (EOF marker).
|
* 2 for a record full of zeros (EOF marker).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int read_header (vfs *me, vfs_s_super *archive, int tard)
|
static ReadStatus
|
||||||
|
read_header (vfs *me, vfs_s_super *archive, int tard)
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
register long sum, signed_sum, recsum;
|
register long sum, signed_sum, recsum;
|
||||||
@ -204,7 +215,7 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
|
|||||||
|
|
||||||
header = get_next_record (archive, tard);
|
header = get_next_record (archive, tard);
|
||||||
if (NULL == header)
|
if (NULL == header)
|
||||||
return EOF;
|
return STATUS_EOF;
|
||||||
|
|
||||||
recsum = from_oct (8, header->header.chksum);
|
recsum = from_oct (8, header->header.chksum);
|
||||||
|
|
||||||
@ -227,25 +238,25 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
|
|||||||
sum += ' ' * sizeof header->header.chksum;
|
sum += ' ' * sizeof header->header.chksum;
|
||||||
signed_sum += ' ' * sizeof header->header.chksum;
|
signed_sum += ' ' * sizeof header->header.chksum;
|
||||||
|
|
||||||
if (sum == 8 * ' ') {
|
/*
|
||||||
/*
|
* This is a zeroed record...whole record is 0's except
|
||||||
* This is a zeroed record...whole record is 0's except
|
* for the 8 blanks we faked for the checksum field.
|
||||||
* for the 8 blanks we faked for the checksum field.
|
*/
|
||||||
*/
|
if (sum == 8 * ' ')
|
||||||
return 2;
|
return STATUS_EOFMARK;
|
||||||
}
|
|
||||||
if (sum != recsum && signed_sum != recsum)
|
if (sum != recsum && signed_sum != recsum)
|
||||||
return 0;
|
return STATUS_BADCHECKSUM;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* linkflag on BSDI tar (pax) always '\000'
|
* linkflag on BSDI tar (pax) always '\000'
|
||||||
*/
|
*/
|
||||||
if(header->header.linkflag == '\000' &&
|
if (header->header.linkflag == '\000' &&
|
||||||
strlen(header->header.arch_name) &&
|
strlen(header->header.arch_name) &&
|
||||||
header->header.arch_name[strlen(header->header.arch_name) - 1] == '/')
|
header->header.arch_name[strlen(header->header.arch_name) - 1] == '/')
|
||||||
header->header.linkflag = LF_DIR;
|
header->header.linkflag = LF_DIR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Good record. Decode file size and return.
|
* Good record. Decode file size and return.
|
||||||
*/
|
*/
|
||||||
if (header->header.linkflag == LF_LINK || header->header.linkflag == LF_DIR)
|
if (header->header.linkflag == LF_LINK || header->header.linkflag == LF_DIR)
|
||||||
@ -270,7 +281,7 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
|
|||||||
data = get_next_record (archive, tard)->charptr;
|
data = get_next_record (archive, tard)->charptr;
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
message_1s (1, MSG_ERROR, _("Unexpected EOF on archive file"));
|
message_1s (1, MSG_ERROR, _("Unexpected EOF on archive file"));
|
||||||
return 0;
|
return STATUS_BADCHECKSUM;
|
||||||
}
|
}
|
||||||
written = RECORDSIZE;
|
written = RECORDSIZE;
|
||||||
if (written > size)
|
if (written > size)
|
||||||
@ -325,7 +336,7 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
|
|||||||
parent = vfs_s_find_inode (me, archive->root, q, LINK_NO_FOLLOW, FL_MKDIR);
|
parent = vfs_s_find_inode (me, archive->root, q, LINK_NO_FOLLOW, FL_MKDIR);
|
||||||
if (parent == NULL) {
|
if (parent == NULL) {
|
||||||
message_1s (1, MSG_ERROR, _("Inconsistent tar archive"));
|
message_1s (1, MSG_ERROR, _("Inconsistent tar archive"));
|
||||||
return 0;
|
return STATUS_BADCHECKSUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header->header.linkflag == LF_LINK) {
|
if (header->header.linkflag == LF_LINK) {
|
||||||
@ -357,7 +368,7 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
|
|||||||
while (get_next_record (archive, tard)->ext_hdr.isextended);
|
while (get_next_record (archive, tard)->ext_hdr.isextended);
|
||||||
inode->u.tar.data_offset = current_tar_position;
|
inode->u.tar.data_offset = current_tar_position;
|
||||||
}
|
}
|
||||||
return 1;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,8 +378,8 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
|
|||||||
*/
|
*/
|
||||||
static int open_archive (vfs *me, vfs_s_super *archive, char *name, char *op)
|
static int open_archive (vfs *me, vfs_s_super *archive, char *name, char *op)
|
||||||
{
|
{
|
||||||
int status = 3; /* Initial status at start of archive */
|
ReadStatus status = STATUS_EOFMARK; /* Initial status at start of archive */
|
||||||
int prev_status;
|
ReadStatus prev_status;
|
||||||
int tard;
|
int tard;
|
||||||
|
|
||||||
current_tar_position = 0;
|
current_tar_position = 0;
|
||||||
@ -378,33 +389,45 @@ static int open_archive (vfs *me, vfs_s_super *archive, char *name, char *op)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
prev_status = status;
|
prev_status = status;
|
||||||
status = read_header (me, archive, tard);
|
status = read_header (me, archive, tard);
|
||||||
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
|
||||||
case 1: /* Valid header */
|
case STATUS_SUCCESS:
|
||||||
skip_n_records (archive, tard, (hstat.st_size + RECORDSIZE - 1) / RECORDSIZE);
|
skip_n_records (archive, tard, (hstat.st_size + RECORDSIZE - 1) / RECORDSIZE);
|
||||||
continue;
|
continue;
|
||||||
/*
|
|
||||||
* If the previous header was good, tell them
|
/*
|
||||||
* that we are skipping bad ones.
|
* Invalid header:
|
||||||
*/
|
*
|
||||||
case 0: /* Invalid header */
|
* If the previous header was good, tell them
|
||||||
switch (prev_status) {
|
* that we are skipping bad ones.
|
||||||
case 3: /* Error on first record */
|
*/
|
||||||
|
case STATUS_BADCHECKSUM:
|
||||||
|
switch (prev_status){
|
||||||
|
|
||||||
|
/* Error on first record */
|
||||||
|
case STATUS_EOFMARK:
|
||||||
message_2s (1, MSG_ERROR, _("Hmm,...\n%s\ndoesn't look like a tar archive."), name);
|
message_2s (1, MSG_ERROR, _("Hmm,...\n%s\ndoesn't look like a tar archive."), name);
|
||||||
/* FALL THRU */
|
/* FALL THRU */
|
||||||
case 2: /* Error after record of zeroes */
|
|
||||||
case 1: /* Error after header rec */
|
/* Error after header rec */
|
||||||
#if 0
|
case STATUS_SUCCESS:
|
||||||
message_1s (0, " Warning ", "Skipping to next file header...");
|
/* Error after error */
|
||||||
#endif
|
|
||||||
case 0: /* Error after error */
|
case STATUS_BADCHECKSUM:
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
case STATUS_EOF:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 2: /* Record of zeroes */
|
/* Record of zeroes */
|
||||||
|
case STATUS_EOFMARK:
|
||||||
status = prev_status; /* If error after 0's */
|
status = prev_status; /* If error after 0's */
|
||||||
/* FALL THRU */
|
/* FALL THRU */
|
||||||
case EOF: /* End of archive */
|
|
||||||
|
case STATUS_EOF: /* End of archive */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
39
vfs/vfs.c
39
vfs/vfs.c
@ -116,10 +116,13 @@ vfs_register (vfs *vfs)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (!vfs) vfs_die("You can not register NULL.");
|
if (!vfs)
|
||||||
|
vfs_die("You can not register NULL.");
|
||||||
|
|
||||||
res = (vfs->init) ? (*vfs->init)(vfs) : 1;
|
res = (vfs->init) ? (*vfs->init)(vfs) : 1;
|
||||||
|
|
||||||
if (!res) return 0;
|
if (!res)
|
||||||
|
return 0;
|
||||||
|
|
||||||
vfs->next = vfs_list;
|
vfs->next = vfs_list;
|
||||||
vfs_list = vfs;
|
vfs_list = vfs;
|
||||||
@ -132,7 +135,8 @@ vfs_type_from_op (char *path)
|
|||||||
{
|
{
|
||||||
vfs *vfs;
|
vfs *vfs;
|
||||||
|
|
||||||
if (!path) vfs_die( "vfs_type_from_op got NULL: impossible" );
|
if (!path)
|
||||||
|
vfs_die ("vfs_type_from_op got NULL: impossible");
|
||||||
|
|
||||||
for (vfs = vfs_list; vfs != &vfs_local_ops; vfs = vfs->next){
|
for (vfs = vfs_list; vfs != &vfs_local_ops; vfs = vfs->next){
|
||||||
if (vfs->which) {
|
if (vfs->which) {
|
||||||
@ -156,14 +160,15 @@ vfs_strip_suffix_from_filename (char *filename)
|
|||||||
char *semi;
|
char *semi;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if (!filename) vfs_die( "vfs_strip_suffix_from_path got NULL: impossible" );
|
if (!filename)
|
||||||
|
vfs_die("vfs_strip_suffix_from_path got NULL: impossible");
|
||||||
|
|
||||||
p = strdup (filename);
|
p = strdup (filename);
|
||||||
if (!(semi = strrchr (p, '#')))
|
if (!(semi = strrchr (p, '#')))
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
for (vfs = vfs_list; vfs != &vfs_local_ops; vfs = vfs->next){
|
for (vfs = vfs_list; vfs != &vfs_local_ops; vfs = vfs->next){
|
||||||
if (vfs->which) {
|
if (vfs->which){
|
||||||
if ((*vfs->which) (vfs, semi + 1) == -1)
|
if ((*vfs->which) (vfs, semi + 1) == -1)
|
||||||
continue;
|
continue;
|
||||||
*semi = '\0'; /* Found valid suffix */
|
*semi = '\0'; /* Found valid suffix */
|
||||||
@ -203,7 +208,8 @@ vfs_split (char *path, char **inpath, char **op)
|
|||||||
char *slash;
|
char *slash;
|
||||||
vfs *ret;
|
vfs *ret;
|
||||||
|
|
||||||
if (!path) vfs_die("Can not split NULL");
|
if (!path)
|
||||||
|
vfs_die("Can not split NULL");
|
||||||
|
|
||||||
semi = strrchr (path, '#');
|
semi = strrchr (path, '#');
|
||||||
if (!semi || !path_magic(path))
|
if (!semi || !path_magic(path))
|
||||||
@ -243,7 +249,9 @@ vfs_rosplit (char *path)
|
|||||||
char *slash;
|
char *slash;
|
||||||
vfs *ret;
|
vfs *ret;
|
||||||
|
|
||||||
if (!path) vfs_die( "Can not rosplit NULL" );
|
if (!path)
|
||||||
|
vfs_die ("Can not rosplit NULL");
|
||||||
|
|
||||||
semi = strrchr (path, '#');
|
semi = strrchr (path, '#');
|
||||||
|
|
||||||
if (!semi || !path_magic (path))
|
if (!semi || !path_magic (path))
|
||||||
@ -463,7 +471,8 @@ mc_setctl (char *path, int ctlop, char *arg)
|
|||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
vfs_die( "You don't want to pass NULL to mc_setctl." );
|
vfs_die("You don't want to pass NULL to mc_setctl.");
|
||||||
|
|
||||||
path = vfs_canon (path);
|
path = vfs_canon (path);
|
||||||
vfs = vfs_type (path);
|
vfs = vfs_type (path);
|
||||||
result = vfs->setctl ? (*vfs->setctl)(vfs, path, ctlop, arg) : 0;
|
result = vfs->setctl ? (*vfs->setctl)(vfs, path, ctlop, arg) : 0;
|
||||||
@ -693,7 +702,8 @@ off_t mc_lseek (int fd, off_t offset, int whence)
|
|||||||
char *
|
char *
|
||||||
vfs_canon (char *path)
|
vfs_canon (char *path)
|
||||||
{
|
{
|
||||||
if (!path) vfs_die("Can not canonize NULL");
|
if (!path)
|
||||||
|
vfs_die("Can not canonize NULL");
|
||||||
|
|
||||||
/* Tilde expansion */
|
/* Tilde expansion */
|
||||||
if (*path == '~'){
|
if (*path == '~'){
|
||||||
@ -726,9 +736,9 @@ vfs_canon (char *path)
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
mad_check( "(pre-canonicalize)", 0);
|
mad_check("(pre-canonicalize)", 0);
|
||||||
canonicalize_pathname (path);
|
canonicalize_pathname (path);
|
||||||
mad_check( "(post-canonicalize)", 0);
|
mad_check("(post-canonicalize)", 0);
|
||||||
|
|
||||||
return strdup (path);
|
return strdup (path);
|
||||||
}
|
}
|
||||||
@ -1476,7 +1486,7 @@ int vfs_parse_filedate(int idx, time_t *t)
|
|||||||
char *p;
|
char *p;
|
||||||
struct tm tim;
|
struct tm tim;
|
||||||
int d[3];
|
int d[3];
|
||||||
int swap, got_year = 0;
|
int got_year = 0;
|
||||||
|
|
||||||
/* Let's setup default time values */
|
/* Let's setup default time values */
|
||||||
tim.tm_year = current_year;
|
tim.tm_year = current_year;
|
||||||
@ -1577,7 +1587,7 @@ int vfs_parse_filedate(int idx, time_t *t)
|
|||||||
int
|
int
|
||||||
vfs_parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
|
vfs_parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
|
||||||
{
|
{
|
||||||
int idx, idx2, num_cols, isconc = 0;
|
int idx, idx2, num_cols;
|
||||||
int i;
|
int i;
|
||||||
char *p_copy;
|
char *p_copy;
|
||||||
|
|
||||||
@ -1644,13 +1654,12 @@ vfs_parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
|
|||||||
|
|
||||||
/* This is device */
|
/* This is device */
|
||||||
if (S_ISCHR (s->st_mode) || S_ISBLK (s->st_mode)){
|
if (S_ISCHR (s->st_mode) || S_ISBLK (s->st_mode)){
|
||||||
|
|
||||||
int maj, min;
|
int maj, min;
|
||||||
|
|
||||||
if (!is_num (idx2) || sscanf(columns [idx2], " %d,", &maj) != 1)
|
if (!is_num (idx2) || sscanf(columns [idx2], " %d,", &maj) != 1)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!is_num (++idx2) || sscanf(columns [idx2], " %li", &min) != 1)
|
if (!is_num (++idx2) || sscanf(columns [idx2], " %d", &min) != 1)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
#ifdef HAVE_ST_RDEV
|
#ifdef HAVE_ST_RDEV
|
||||||
|
@ -145,35 +145,52 @@ struct vfs_s_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* entries and inodes */
|
/* entries and inodes */
|
||||||
vfs_s_inode *vfs_s_new_inode (vfs *me, vfs_s_super *super, struct stat *initstat);
|
vfs_s_inode *vfs_s_new_inode (vfs *me, vfs_s_super *super,
|
||||||
vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode);
|
struct stat *initstat);
|
||||||
void vfs_s_free_entry (vfs *me, vfs_s_entry *ent);
|
vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode);
|
||||||
void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir, vfs_s_entry *ent);
|
void vfs_s_free_entry (vfs *me, vfs_s_entry *ent);
|
||||||
struct stat *vfs_s_default_stat (vfs *me, mode_t mode);
|
void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir,
|
||||||
void vfs_s_add_dots (vfs *me, vfs_s_inode *dir, vfs_s_inode *parent);
|
vfs_s_entry *ent);
|
||||||
struct vfs_s_entry *vfs_s_generate_entry (vfs *me, char *name, struct vfs_s_inode *parent, mode_t mode);
|
struct stat *vfs_s_default_stat (vfs *me, 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_tree(vfs *me, vfs_s_inode *root, char *path, int follow, int flags);
|
void vfs_s_add_dots (vfs *me, vfs_s_inode *dir,
|
||||||
vfs_s_entry *vfs_s_find_entry_linear(vfs *me, vfs_s_inode *root, char *path, int follow, int flags);
|
vfs_s_inode *parent);
|
||||||
vfs_s_inode *vfs_s_find_inode(vfs *me, vfs_s_inode *root, char *path, int follow, int flags);
|
vfs_s_entry *vfs_s_generate_entry (vfs *me, char *name,
|
||||||
vfs_s_inode *vfs_s_find_root(vfs *me, vfs_s_entry *entry);
|
struct vfs_s_inode *parent, mode_t mode);
|
||||||
struct vfs_s_entry *vfs_s_resolve_symlink (vfs *me, vfs_s_entry *entry, int follow);
|
vfs_s_entry *vfs_s_automake (vfs *me, vfs_s_inode *dir, char *path,
|
||||||
|
int flags);
|
||||||
|
vfs_s_entry *vfs_s_find_entry_tree (vfs *me, vfs_s_inode *root, char *path,
|
||||||
|
int follow, int flags);
|
||||||
|
vfs_s_entry *vfs_s_find_entry_linear (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);
|
||||||
|
vfs_s_entry *vfs_s_resolve_symlink (vfs *me, vfs_s_entry *entry,
|
||||||
|
int follow);
|
||||||
|
|
||||||
/* superblock games */
|
/* superblock games */
|
||||||
vfs_s_super *vfs_s_new_super (vfs *me);
|
vfs_s_super *vfs_s_new_super (vfs *me);
|
||||||
void vfs_s_free_super (vfs *me, vfs_s_super *super);
|
void vfs_s_free_super (vfs *me, vfs_s_super *super);
|
||||||
|
|
||||||
/* outside interface */
|
/* outside interface */
|
||||||
char *vfs_s_get_path_mangle (vfs *me, char *inname, vfs_s_super **archive, int flags);
|
char *vfs_s_get_path_mangle (vfs *me, char *inname, vfs_s_super **archive,
|
||||||
char *vfs_s_get_path (vfs *me, char *inname, vfs_s_super **archive, int flags);
|
int flags);
|
||||||
void vfs_s_invalidate (vfs *me, vfs_s_super *super);
|
char *vfs_s_get_path (vfs *me, char *inname, vfs_s_super **archive,
|
||||||
|
int flags);
|
||||||
|
void vfs_s_invalidate (vfs *me, vfs_s_super *super);
|
||||||
|
char *vfs_s_fullpath (vfs *me, vfs_s_inode *ino);
|
||||||
|
|
||||||
/* readdir & friends */
|
/* readdir & friends */
|
||||||
vfs_s_super *vfs_s_super_from_path (vfs *me, char *name);
|
vfs_s_super *vfs_s_super_from_path (vfs *me, char *name);
|
||||||
vfs_s_inode *vfs_s_inode_from_path (vfs *me, char *name, int flags);
|
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_opendir (vfs *me, char *dirname);
|
||||||
void * vfs_s_readdir (void *data);
|
void *vfs_s_readdir (void *data);
|
||||||
int vfs_s_telldir (void *data);
|
int vfs_s_telldir (void *data);
|
||||||
void vfs_s_seekdir (void *data, int offset);
|
void vfs_s_seekdir (void *data, int offset);
|
||||||
int vfs_s_closedir (void *data);
|
int vfs_s_closedir (void *data);
|
||||||
int vfs_s_chdir (vfs *me, char *path);
|
int vfs_s_chdir (vfs *me, char *path);
|
||||||
|
|
||||||
/* stat & friends */
|
/* stat & friends */
|
||||||
int vfs_s_stat (vfs *me, char *path, struct stat *buf);
|
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_lstat (vfs *me, char *path, struct stat *buf);
|
||||||
@ -184,16 +201,19 @@ int vfs_s_read (void *fh, char *buffer, int count);
|
|||||||
int vfs_s_write (void *fh, char *buffer, int count);
|
int vfs_s_write (void *fh, char *buffer, int count);
|
||||||
int vfs_s_lseek (void *fh, off_t offset, int whence);
|
int vfs_s_lseek (void *fh, off_t offset, int whence);
|
||||||
int vfs_s_close (void *fh);
|
int vfs_s_close (void *fh);
|
||||||
|
|
||||||
/* mc support */
|
/* mc support */
|
||||||
void vfs_s_fill_names (vfs *me, void (*func)(char *));
|
void vfs_s_fill_names (vfs *me, void (*func)(char *));
|
||||||
int vfs_s_ferrno(vfs *me);
|
int vfs_s_ferrno(vfs *me);
|
||||||
void vfs_s_dump(vfs *me, char *prefix, vfs_s_inode *ino);
|
void vfs_s_dump(vfs *me, char *prefix, vfs_s_inode *ino);
|
||||||
char *vfs_s_getlocalcopy (vfs *me, char *path);
|
char *vfs_s_getlocalcopy (vfs *me, char *path);
|
||||||
|
|
||||||
/* stamping support */
|
/* stamping support */
|
||||||
vfsid vfs_s_getid (vfs *me, char *path, struct vfs_stamping **parent);
|
vfsid vfs_s_getid (vfs *me, char *path, struct vfs_stamping **parent);
|
||||||
int vfs_s_nothingisopen (vfsid id);
|
int vfs_s_nothingisopen (vfsid id);
|
||||||
void vfs_s_free (vfsid id);
|
void vfs_s_free (vfsid id);
|
||||||
int vfs_s_setctl (vfs *me, char *path, int ctlop, char *arg);
|
int vfs_s_setctl (vfs *me, char *path, int ctlop, char *arg);
|
||||||
|
|
||||||
/* network filesystems support */
|
/* network filesystems support */
|
||||||
int vfs_s_select_on_two (int fd1, int fd2);
|
int vfs_s_select_on_two (int fd1, int fd2);
|
||||||
int vfs_s_get_line (vfs *me, int sock, char *buf, int buf_len, char term);
|
int vfs_s_get_line (vfs *me, int sock, char *buf, int buf_len, char term);
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user