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>
|
||||
|
||||
* 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++)
|
||||
close (i);
|
||||
|
||||
*pid = fork ();
|
||||
if (!(flags & EXECUTE_WAIT))
|
||||
*pid = fork ();
|
||||
|
||||
if (*pid == 0){
|
||||
if (flags & EXECUTE_AS_SHELL)
|
||||
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);
|
||||
}
|
||||
if (*pid != 0 && (flags & EXECUTE_WAIT)){
|
||||
int status;
|
||||
|
||||
waitpid (*pid, &status, 0);
|
||||
}
|
||||
sigaction (SIGINT, &save_intr, NULL);
|
||||
sigaction (SIGQUIT, &save_quit, NULL);
|
||||
sigaction (SIGTSTP, &save_stop, NULL);
|
||||
|
||||
#ifdef SCO_FLAVOR
|
||||
waitpid(-1, NULL, WNOHANG);
|
||||
#endif /* SCO_FLAVOR */
|
||||
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,7 @@ void my_putenv (char*, char*);
|
||||
#define EXECUTE_TEMPFILE 2
|
||||
#define EXECUTE_AS_SHELL 4
|
||||
#define EXECUTE_SETUID 8
|
||||
#define EXECUTE_WAIT 16
|
||||
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);
|
||||
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>
|
||||
|
||||
* 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;
|
||||
|
||||
ino = xmalloc(sizeof (vfs_s_inode), "Dcache inode");
|
||||
if (!ino) return NULL;
|
||||
if (!ino)
|
||||
return 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)
|
||||
entry->name = strdup (name);
|
||||
else entry->name = NULL;
|
||||
else
|
||||
entry->name = NULL;
|
||||
entry->dir = NULL;
|
||||
entry->next = 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)
|
||||
{
|
||||
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 */
|
||||
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;
|
||||
if (ent->prevp) { /* It is possible that we are deleting freshly created entry */
|
||||
*ent->prevp = ent->next;
|
||||
if (ent->next) ent->next->prevp = ent->prevp;
|
||||
if (ent->next)
|
||||
ent->next->prevp = ent->prevp;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
for(ep = &dir->subdir; *ep != NULL; ep = &((*ep)->next));
|
||||
for (ep = &dir->subdir; *ep != NULL; ep = &((*ep)->next))
|
||||
;
|
||||
ent->prevp = ep;
|
||||
ent->next = NULL;
|
||||
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)
|
||||
{
|
||||
char *s;
|
||||
vfs_s_entry* ent = NULL;
|
||||
|
||||
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);
|
||||
result = MEDATA->open_archive (me, super, archive_name, op);
|
||||
@ -523,8 +528,10 @@ void * vfs_s_opendir (vfs *me, char *dirname)
|
||||
struct dirhandle *info;
|
||||
|
||||
dir = vfs_s_inode_from_path (me, dirname, FL_DIR | FL_FOLLOW);
|
||||
if (!dir) return NULL;
|
||||
if (!S_ISDIR (dir->st.st_mode)) ERRNOR (ENOTDIR, NULL);
|
||||
if (!dir)
|
||||
return NULL;
|
||||
if (!S_ISDIR (dir->st.st_mode))
|
||||
ERRNOR (ENOTDIR, NULL);
|
||||
|
||||
dir->st.st_nlink++;
|
||||
#if 0
|
||||
@ -556,7 +563,7 @@ void * vfs_s_readdir (void *data)
|
||||
strcpy (&(dir.dir.d_name [0]), info->cur->name);
|
||||
else
|
||||
vfs_die( "Null in structure-can not happen");
|
||||
|
||||
|
||||
#ifndef DIRENT_LENGTH_COMPUTED
|
||||
dir.d_namlen = strlen (dir.dir.d_name);
|
||||
#endif
|
||||
@ -573,7 +580,8 @@ int vfs_s_telldir (void *data)
|
||||
|
||||
cur = info->dir->subdir;
|
||||
while (cur!=NULL) {
|
||||
if (cur == info->cur) return num;
|
||||
if (cur == info->cur)
|
||||
return num;
|
||||
num++;
|
||||
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;
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
@ -640,9 +649,11 @@ int vfs_s_readlink (vfs *me, char *path, char *buf, int size)
|
||||
struct vfs_s_inode *ino;
|
||||
|
||||
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);
|
||||
*(buf+size-1) = 0;
|
||||
return strlen(buf);
|
||||
@ -681,7 +692,8 @@ void *vfs_s_open (vfs *me, char *file, int flags, int mode)
|
||||
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->pos = 0;
|
||||
@ -810,8 +822,10 @@ int vfs_s_close (void *fh)
|
||||
res = MEDATA->fh_close (me, fh);
|
||||
if (FH->changed && MEDATA->file_store) {
|
||||
char *s = vfs_s_fullpath( me, FH->ino );
|
||||
if (!s) res = -1;
|
||||
else res = MEDATA->file_store (me, FH_SUPER, s, FH->ino->localname);
|
||||
if (!s)
|
||||
res = -1;
|
||||
else
|
||||
res = MEDATA->file_store (me, FH_SUPER, s, FH->ino->localname);
|
||||
vfs_s_invalidate(me, FH_SUPER);
|
||||
}
|
||||
if (FH->handle)
|
||||
@ -848,7 +862,9 @@ void
|
||||
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 );
|
||||
if (!ino->subdir) printf ("FILE\n");
|
||||
if (!ino->subdir)
|
||||
printf ("FILE\n");
|
||||
|
||||
else
|
||||
{
|
||||
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;
|
||||
char *str;
|
||||
int n, status;
|
||||
int status;
|
||||
FILE *logfile = MEDATA->logfile;
|
||||
|
||||
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
|
||||
static char reply_str [80];
|
||||
|
||||
static struct direntry *_get_file_entry(struct connection *bucket,
|
||||
char *file_name, int op, int flags);
|
||||
static struct direntry *_get_file_entry (struct connection *bucket,
|
||||
char *file_name, int op, int flags);
|
||||
|
||||
static char *ftpfs_get_current_directory (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;
|
||||
|
||||
for (;;) {
|
||||
if (!get_line(sock, answer, sizeof(answer), '\n')) {
|
||||
if (!get_line (sock, answer, sizeof (answer), '\n')){
|
||||
if (string_buf)
|
||||
*string_buf = 0;
|
||||
code = 421;
|
||||
return 4;
|
||||
}
|
||||
switch(sscanf(answer, "%d", &code)) {
|
||||
switch (sscanf(answer, "%d", &code)){
|
||||
case 0:
|
||||
if (string_buf) {
|
||||
strncpy(string_buf, answer, string_len - 1);
|
||||
strncpy (string_buf, answer, string_len - 1);
|
||||
*(string_buf + string_len - 1) = 0;
|
||||
}
|
||||
code = 500;
|
||||
@ -201,19 +201,19 @@ get_reply (int sock, char *string_buf, int string_len)
|
||||
case 1:
|
||||
if (answer[3] == '-') {
|
||||
while (1) {
|
||||
if (!get_line(sock, answer, sizeof(answer), '\n')) {
|
||||
if (!get_line (sock, answer, sizeof(answer), '\n')){
|
||||
if (string_buf)
|
||||
*string_buf = 0;
|
||||
code = 421;
|
||||
return 4;
|
||||
}
|
||||
if ((sscanf(answer, "%d", &i) > 0) &&
|
||||
if ((sscanf (answer, "%d", &i) > 0) &&
|
||||
(code == i) && (answer[3] == ' '))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (string_buf) {
|
||||
strncpy(string_buf, answer, string_len - 1);
|
||||
if (string_buf){
|
||||
strncpy (string_buf, answer, string_len - 1);
|
||||
*(string_buf + string_len - 1) = 0;
|
||||
}
|
||||
return code / 100;
|
||||
@ -226,7 +226,7 @@ command (struct connection *bucket, int wait_reply, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *str, *fmt_str;
|
||||
int n, status;
|
||||
int status;
|
||||
int sock = qsock (bucket);
|
||||
|
||||
va_start (ap, fmt);
|
||||
@ -275,7 +275,7 @@ connection_close (void *data)
|
||||
struct connection *bucket = data;
|
||||
|
||||
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");
|
||||
close(qsock(bucket));
|
||||
}
|
||||
@ -294,7 +294,8 @@ static int
|
||||
changetype (struct connection *bucket, int binary)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return binary;
|
||||
@ -316,19 +317,20 @@ login_server (struct connection *bucket, char *netrcpass)
|
||||
if (netrcpass)
|
||||
op = strdup (netrcpass);
|
||||
else {
|
||||
if (!strcmp (quser(bucket), "anonymous") ||
|
||||
!strcmp (quser(bucket), "ftp")) {
|
||||
op = strdup(ftpfs_anonymous_passwd);
|
||||
if (!strcmp (quser (bucket), "anonymous") ||
|
||||
!strcmp (quser (bucket), "ftp")) {
|
||||
op = strdup (ftpfs_anonymous_passwd);
|
||||
anon = 1;
|
||||
} else {
|
||||
char *p;
|
||||
|
||||
if (!bucket->password){
|
||||
p = copy_strings (" FTP: Password required for ", quser(bucket),
|
||||
p = copy_strings (" FTP: Password required for ", quser (bucket),
|
||||
" ", NULL);
|
||||
op = vfs_get_password (p);
|
||||
free (p);
|
||||
if (op == NULL) ERRNOR (EPERM, 0);
|
||||
if (op == NULL)
|
||||
ERRNOR (EPERM, 0);
|
||||
bucket->password = strdup (op);
|
||||
} else
|
||||
op = strdup (bucket->password);
|
||||
@ -347,44 +349,47 @@ login_server (struct connection *bucket, char *netrcpass)
|
||||
#if defined(HSC_PROXY)
|
||||
char *p, *host;
|
||||
int port;
|
||||
p = my_get_host_and_username(ftpfs_proxy_host, &host, &proxyname,
|
||||
&port, &proxypass);
|
||||
p = my_get_host_and_username (ftpfs_proxy_host, &host, &proxyname,
|
||||
&port, &proxypass);
|
||||
if (p)
|
||||
free (p);
|
||||
|
||||
free(host);
|
||||
free (host);
|
||||
if (proxypass)
|
||||
wipe_password (proxypass);
|
||||
p = copy_strings(" Proxy: Password required for ", proxyname, " ",
|
||||
NULL);
|
||||
p = copy_strings (" Proxy: Password required for ", proxyname, " ",
|
||||
NULL);
|
||||
proxypass = vfs_get_password (p);
|
||||
free(p);
|
||||
free (p);
|
||||
if (proxypass == NULL) {
|
||||
wipe_password (pass);
|
||||
free (proxyname);
|
||||
ERRNOR (EPERM, 0);
|
||||
}
|
||||
name = strdup(quser (bucket));
|
||||
name = strdup (quser (bucket));
|
||||
#else
|
||||
name = copy_strings (quser(bucket), "@",
|
||||
qhost(bucket)[0] == '!' ? qhost(bucket)+1 : qhost(bucket), 0);
|
||||
name = copy_strings (quser (bucket), "@",
|
||||
qhost (bucket)[0] == '!' ? qhost (bucket)+1 : qhost (bucket), 0);
|
||||
#endif
|
||||
} else
|
||||
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 (qproxy(bucket)) {
|
||||
print_vfs_message("ftpfs: sending proxy login name");
|
||||
if (qproxy (bucket)){
|
||||
print_vfs_message ("ftpfs: sending proxy login name");
|
||||
if (command (bucket, 1, "USER %s", proxyname) != CONTINUE)
|
||||
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)
|
||||
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;
|
||||
print_vfs_message("ftpfs: connected to %s", qhost(bucket)+1);
|
||||
|
||||
print_vfs_message ("ftpfs: connected to %s", qhost (bucket)+1);
|
||||
if (0) {
|
||||
proxyfail:
|
||||
bucket->failed_on_login = 1;
|
||||
@ -401,17 +406,17 @@ login_server (struct connection *bucket, char *netrcpass)
|
||||
free (proxyname);
|
||||
}
|
||||
#endif
|
||||
print_vfs_message("ftpfs: sending login name");
|
||||
print_vfs_message ("ftpfs: sending login name");
|
||||
code = command (bucket, WAIT_REPLY, "USER %s", name);
|
||||
|
||||
switch (code){
|
||||
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)
|
||||
break;
|
||||
|
||||
case COMPLETE:
|
||||
print_vfs_message("ftpfs: logged in");
|
||||
print_vfs_message ("ftpfs: logged in");
|
||||
wipe_password (pass);
|
||||
free (name);
|
||||
return 1;
|
||||
@ -426,7 +431,7 @@ login_server (struct connection *bucket, char *netrcpass)
|
||||
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:
|
||||
wipe_password (pass);
|
||||
free (name);
|
||||
@ -566,17 +571,17 @@ ftpfs_get_proxy_host_and_port (char *proxy, char **host, int *port)
|
||||
#else
|
||||
#define PORT 21
|
||||
#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)
|
||||
wipe_password (pass);
|
||||
if (dir)
|
||||
free(dir);
|
||||
free (dir);
|
||||
}
|
||||
|
||||
static int
|
||||
ftpfs_open_socket(struct connection *bucket)
|
||||
ftpfs_open_socket (struct connection *bucket)
|
||||
{
|
||||
struct sockaddr_in server_address;
|
||||
struct hostent *hp;
|
||||
@ -586,7 +591,7 @@ ftpfs_open_socket(struct connection *bucket)
|
||||
int free_host = 0;
|
||||
|
||||
/* Use a proxy host? */
|
||||
host = qhost(bucket);
|
||||
host = qhost (bucket);
|
||||
|
||||
if (!host || !*host){
|
||||
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 */
|
||||
if (qproxy(bucket)) {
|
||||
if (qproxy (bucket)){
|
||||
ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &port);
|
||||
free_host = 1;
|
||||
}
|
||||
@ -607,9 +612,9 @@ ftpfs_open_socket(struct connection *bucket)
|
||||
if (server_address.sin_addr.s_addr != -1)
|
||||
server_address.sin_family = AF_INET;
|
||||
else {
|
||||
hp = gethostbyname(host);
|
||||
hp = gethostbyname (host);
|
||||
if (hp == NULL){
|
||||
print_vfs_message("ftpfs: Invalid host address.");
|
||||
print_vfs_message ("ftpfs: Invalid host address.");
|
||||
my_errno = EINVAL;
|
||||
if (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);
|
||||
|
||||
print_vfs_message("ftpfs: making connection to %s", host);
|
||||
print_vfs_message ("ftpfs: making connection to %s", host);
|
||||
if (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,
|
||||
sizeof (server_address)) < 0){
|
||||
my_errno = errno;
|
||||
if (errno == EINTR && got_interrupt())
|
||||
print_vfs_message("ftpfs: connection interrupted by user");
|
||||
if (errno == EINTR && got_interrupt ())
|
||||
print_vfs_message ("ftpfs: connection interrupted by user");
|
||||
else
|
||||
print_vfs_message("ftpfs: connection to server failed: %s",
|
||||
unix_error_string(errno));
|
||||
print_vfs_message ("ftpfs: connection to server failed: %s",
|
||||
unix_error_string(errno));
|
||||
disable_interrupt_key();
|
||||
close (my_socket);
|
||||
return -1;
|
||||
@ -665,7 +670,8 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
|
||||
bucket = xmalloc(sizeof(struct connection),
|
||||
"struct connection");
|
||||
|
||||
if (bucket == NULL) ERRNOR (ENOMEM, NULL);
|
||||
if (bucket == NULL)
|
||||
ERRNOR (ENOMEM, NULL);
|
||||
#ifdef HAVE_MAD
|
||||
{
|
||||
extern void *watch_free_pointer;
|
||||
@ -674,15 +680,15 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
|
||||
watch_free_pointer = host;
|
||||
}
|
||||
#endif
|
||||
qhost(bucket) = strdup (host);
|
||||
quser(bucket) = strdup (user);
|
||||
qcdir(bucket) = NULL;
|
||||
qport(bucket) = port;
|
||||
qlock(bucket) = 0;
|
||||
qhome(bucket) = NULL;
|
||||
qproxy(bucket)= 0;
|
||||
qupdir(bucket)= 0;
|
||||
qdcache(bucket)=0;
|
||||
qhost (bucket) = strdup (host);
|
||||
quser (bucket) = strdup (user);
|
||||
qcdir (bucket) = NULL;
|
||||
qport (bucket) = port;
|
||||
qlock (bucket) = 0;
|
||||
qhome (bucket) = NULL;
|
||||
qproxy (bucket)= 0;
|
||||
qupdir (bucket)= 0;
|
||||
qdcache (bucket)=0;
|
||||
bucket->__inode_counter = 0;
|
||||
bucket->lock = 0;
|
||||
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)
|
||||
bucket->use_passive_connection = 0;
|
||||
|
||||
if ((qdcache(bucket) = linklist_init()) == NULL) {
|
||||
if ((qdcache (bucket) = linklist_init ()) == NULL) {
|
||||
my_errno = ENOMEM;
|
||||
free (qhost(bucket));
|
||||
free (quser(bucket));
|
||||
free (qhost (bucket));
|
||||
free (quser (bucket));
|
||||
free (bucket);
|
||||
return NULL;
|
||||
}
|
||||
@ -708,13 +714,13 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
|
||||
do {
|
||||
bucket->failed_on_login = 0;
|
||||
|
||||
qsock(bucket) = ftpfs_open_socket(bucket);
|
||||
if (qsock(bucket) == -1) {
|
||||
qsock (bucket) = ftpfs_open_socket (bucket);
|
||||
if (qsock (bucket) == -1) {
|
||||
free_bucket (bucket);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (login_server(bucket, netrcpass)) {
|
||||
if (login_server (bucket, netrcpass)) {
|
||||
/* Logged in, no need to retry the connection */
|
||||
break;
|
||||
} else {
|
||||
@ -743,15 +749,15 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
|
||||
}
|
||||
} while (retry_seconds);
|
||||
|
||||
qhome(bucket) = ftpfs_get_current_directory (bucket);
|
||||
if (!qhome(bucket))
|
||||
qhome(bucket) = strdup ("/");
|
||||
qupdir(bucket) = strdup ("/"); /* FIXME: I changed behavior to ignore last_current_dir */
|
||||
qhome (bucket) = ftpfs_get_current_directory (bucket);
|
||||
if (!qhome (bucket))
|
||||
qhome (bucket) = strdup ("/");
|
||||
qupdir (bucket) = strdup ("/"); /* FIXME: I changed behavior to ignore last_current_dir */
|
||||
return bucket;
|
||||
}
|
||||
|
||||
static int
|
||||
is_connection_closed(struct connection *bucket)
|
||||
is_connection_closed (struct connection *bucket)
|
||||
{
|
||||
fd_set rset;
|
||||
struct timeval t;
|
||||
@ -761,16 +767,16 @@ is_connection_closed(struct connection *bucket)
|
||||
}
|
||||
t.tv_sec = 0;
|
||||
t.tv_usec = 0;
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(qsock(bucket), &rset);
|
||||
FD_ZERO (&rset);
|
||||
FD_SET (qsock (bucket), &rset);
|
||||
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)
|
||||
return 1;
|
||||
return 0;
|
||||
#if 0
|
||||
if (FD_ISSET(qsock(bucket), &rset)) {
|
||||
n = read(qsock(bucket), &read_ahead, sizeof(read_ahead));
|
||||
if (FD_ISSET (qsock(bucket), &rset)) {
|
||||
n = read (qsock(bucket), &read_ahead, sizeof (read_ahead));
|
||||
if (n <= 0)
|
||||
return 1;
|
||||
} else
|
||||
@ -790,47 +796,48 @@ open_link (char *host, char *user, int port, char *netrcpass)
|
||||
for (lptr = connections_list->next;
|
||||
lptr != connections_list; lptr = lptr->next) {
|
||||
bucket = lptr->data;
|
||||
if ((strcmp (host, qhost(bucket)) == 0) &&
|
||||
(strcmp (user, quser(bucket)) == 0) &&
|
||||
(port == qport(bucket))) {
|
||||
if ((strcmp (host, qhost (bucket)) == 0) &&
|
||||
(strcmp (user, quser (bucket)) == 0) &&
|
||||
(port == qport (bucket))) {
|
||||
|
||||
/* check the connection is closed or not, just hack */
|
||||
if (is_connection_closed(bucket)) {
|
||||
flush_all_directory(bucket);
|
||||
sock = ftpfs_open_socket(bucket);
|
||||
if (is_connection_closed (bucket)) {
|
||||
flush_all_directory (bucket);
|
||||
sock = ftpfs_open_socket (bucket);
|
||||
if (sock != -1) {
|
||||
close(qsock(bucket));
|
||||
qsock(bucket) = sock;
|
||||
if (login_server(bucket, netrcpass))
|
||||
close (qsock (bucket));
|
||||
qsock (bucket) = sock;
|
||||
if (login_server (bucket, netrcpass))
|
||||
return bucket;
|
||||
}
|
||||
|
||||
/* connection refused */
|
||||
lptr->prev->next = lptr->next;
|
||||
lptr->next->prev = lptr->prev;
|
||||
connection_destructor(bucket);
|
||||
connection_destructor (bucket);
|
||||
return NULL;
|
||||
}
|
||||
return bucket;
|
||||
}
|
||||
}
|
||||
bucket = open_command_connection(host, user, port, netrcpass);
|
||||
bucket = open_command_connection (host, user, port, netrcpass);
|
||||
if (bucket == NULL)
|
||||
return NULL;
|
||||
if (!linklist_insert(connections_list, bucket)) {
|
||||
if (!linklist_insert (connections_list, bucket)) {
|
||||
my_errno = ENOMEM;
|
||||
connection_destructor(bucket);
|
||||
connection_destructor (bucket);
|
||||
return NULL;
|
||||
}
|
||||
return bucket;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
if (command(bucket, NONE, "PWD") == COMPLETE &&
|
||||
if (command (bucket, NONE, "PWD") == COMPLETE &&
|
||||
get_reply(qsock(bucket), buf, sizeof(buf)) == COMPLETE) {
|
||||
bufp = NULL;
|
||||
for (bufq = buf; *bufq; bufq++)
|
||||
@ -900,9 +907,11 @@ initconn (struct connection *bucket)
|
||||
data_addr.sin_port = 0;
|
||||
|
||||
pe = getprotobyname("tcp");
|
||||
if (pe == NULL) ERRNOR (EIO, -1);
|
||||
if (pe == NULL)
|
||||
ERRNOR (EIO, -1);
|
||||
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
|
||||
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);
|
||||
else
|
||||
j = command (bucket, WAIT_REPLY, "%s", cmd);
|
||||
if (j != PRELIM) ERRNOR (EPERM, -1);
|
||||
if (j != PRELIM)
|
||||
ERRNOR (EPERM, -1);
|
||||
enable_interrupt_key();
|
||||
if (bucket->use_passive_connection)
|
||||
data = s;
|
||||
@ -1222,7 +1232,8 @@ retrieve_dir(struct connection *bucket, char *remote_path, int resolve_symlinks)
|
||||
}
|
||||
|
||||
file_list = linklist_init();
|
||||
if (file_list == NULL) ERRNOR (ENOMEM, NULL);
|
||||
if (file_list == NULL)
|
||||
ERRNOR (ENOMEM, NULL);
|
||||
dcache = xmalloc(sizeof(struct dir),
|
||||
"struct dir");
|
||||
if (dcache == NULL) {
|
||||
@ -1384,7 +1395,8 @@ store_file(struct direntry *fe)
|
||||
|
||||
local_handle = open(fe->local_filename, O_RDONLY);
|
||||
unlink (fe->local_filename);
|
||||
if (local_handle == -1) ERRNOR (EIO, 0);
|
||||
if (local_handle == -1)
|
||||
ERRNOR (EIO, 0);
|
||||
fstat(local_handle, &s);
|
||||
sock = open_data_connection(fe->bucket, "STOR", fe->remote_filename, TYPE_BINARY, 0);
|
||||
if (sock < 0) {
|
||||
@ -1435,7 +1447,8 @@ store_file(struct direntry *fe)
|
||||
disable_interrupt_key();
|
||||
close(sock);
|
||||
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;
|
||||
error_return:
|
||||
disable_interrupt_key();
|
||||
@ -1473,7 +1486,8 @@ linear_read (struct direntry *fe, void *buf, int len)
|
||||
break;
|
||||
}
|
||||
|
||||
if (n<0) linear_abort(fe);
|
||||
if (n<0)
|
||||
linear_abort(fe);
|
||||
|
||||
if (!n) {
|
||||
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);
|
||||
if (flags & OPT_IGNORE_ERROR)
|
||||
r = COMPLETE;
|
||||
if (r != COMPLETE) ERRNOR (EPERM, -1);
|
||||
if (r != COMPLETE)
|
||||
ERRNOR (EPERM, -1);
|
||||
if (flush_directory_cache)
|
||||
flush_all_directory(bucket);
|
||||
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
|
||||
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;
|
||||
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_FULLMATCH 8
|
||||
|
||||
static int uptodate( char *name, char *cache )
|
||||
static int uptodate (char *name, char *cache)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vfmake( vfs *me, char *name, char *cache )
|
||||
static int vfmake (vfs *me, char *name, char *cache)
|
||||
{
|
||||
char *inpath, *op;
|
||||
int w;
|
||||
@ -63,72 +63,77 @@ static int vfmake( vfs *me, char *name, char *cache )
|
||||
char *s, *t = pad;
|
||||
int was_percent = 0;
|
||||
|
||||
vfs_split( name, &inpath, &op );
|
||||
if ((w = (*me->which)( me, op )) == -1)
|
||||
vfs_die( "This cannot happen... Hopefully.\n" );
|
||||
vfs_split (name, &inpath, &op);
|
||||
if ((w = (*me->which) (me, op)) == -1)
|
||||
vfs_die ("This cannot happen... Hopefully.\n");
|
||||
|
||||
if ((sfs_flags[w] & F_1) || (!strcmp( name, "/" ))) ; else return -1;
|
||||
if ((sfs_flags[w] & F_1) || (!strcmp (name, "/"))) ; else return -1;
|
||||
/* if ((sfs_flags[w] & F_2) || (!inpath) || (!*inpath)); else return -1; */
|
||||
if (!(sfs_flags[w] & F_NOLOCALCOPY))
|
||||
name = mc_getlocalcopy( name );
|
||||
name = mc_getlocalcopy (name);
|
||||
else
|
||||
name = strdup( name );
|
||||
name = strdup (name);
|
||||
s = sfs_command[w];
|
||||
#define COPY_CHAR if (t-pad>10200) return -1; else *t++ = *s;
|
||||
#define COPY_STRING(a) if ((t-pad)+strlen(a)>10200) return -1; else { strcpy( t, a ); t+= strlen(a); }
|
||||
#define COPY_STRING(a) if ((t-pad)+strlen(a)>10200) return -1; else { strcpy (t, a); t+= strlen(a); }
|
||||
while (*s) {
|
||||
if (was_percent) {
|
||||
switch (*s) {
|
||||
case '1': COPY_STRING( name ); break;
|
||||
case '2': COPY_STRING( op + strlen( sfs_prefix[w] ) ); break;
|
||||
case '3': COPY_STRING( cache ); break;
|
||||
case '1': COPY_STRING (name); break;
|
||||
case '2': COPY_STRING (op + strlen (sfs_prefix[w])); break;
|
||||
case '3': COPY_STRING (cache); break;
|
||||
case '%': COPY_CHAR; break;
|
||||
}
|
||||
was_percent = 0;
|
||||
} else {
|
||||
if (*s == '%') was_percent = 1;
|
||||
else COPY_CHAR;
|
||||
if (*s == '%')
|
||||
was_percent = 1;
|
||||
else
|
||||
COPY_CHAR;
|
||||
}
|
||||
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 0; /* OK */
|
||||
}
|
||||
|
||||
static char *redirect( vfs *me, char *name )
|
||||
static char *
|
||||
redirect (vfs *me, char *name)
|
||||
{
|
||||
struct cachedfile *cur = head;
|
||||
uid_t uid = vfs_uid;
|
||||
char *cache, *xname;
|
||||
int handle;
|
||||
|
||||
while (cur) {
|
||||
if ((!strcmp( name, cur->name )) &&
|
||||
while (cur){
|
||||
if ((!strcmp (name, cur->name)) &&
|
||||
(uid == cur->uid) &&
|
||||
(uptodate( cur->name, cur->cache )))
|
||||
/* FIXME: when not uptodate, we might want to kill cache
|
||||
* file immediately, not to wait until timeout. */ {
|
||||
vfs_stamp( &vfs_sfs_ops, cur );
|
||||
return cur->cache;
|
||||
(uptodate (cur->name, cur->cache)))
|
||||
/* FIXME: when not uptodate, we might want to kill cache
|
||||
* file immediately, not to wait until timeout. */ {
|
||||
vfs_stamp (&vfs_sfs_ops, cur);
|
||||
return cur->cache;
|
||||
}
|
||||
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)
|
||||
return "/SOMEONE_PLAYING_DIRTY_TMP_TRICKS_ON_US";
|
||||
close(handle);
|
||||
|
||||
xname = strdup( name );
|
||||
if (!vfmake( me, name, cache )) {
|
||||
cur = xmalloc( sizeof(struct cachedfile), "SFS cache" );
|
||||
close (handle);
|
||||
|
||||
xname = strdup (name);
|
||||
if (!vfmake (me, name, cache)){
|
||||
cur = xmalloc (sizeof(struct cachedfile), "SFS cache");
|
||||
cur->name = xname;
|
||||
cur->cache = strdup(cache);
|
||||
cur->cache = cache;
|
||||
cur->uid = uid;
|
||||
cur->next = head;
|
||||
head = cur;
|
||||
@ -143,14 +148,13 @@ static char *redirect( vfs *me, char *name )
|
||||
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 fd;
|
||||
|
||||
REDIR;
|
||||
path = redirect (me, path);
|
||||
fd = open (path, flags, mode);
|
||||
if (fd == -1)
|
||||
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)
|
||||
{
|
||||
REDIR;
|
||||
path = redirect (me, path);
|
||||
return stat (path, buf);
|
||||
}
|
||||
|
||||
static int sfs_lstat (vfs *me, char *path, struct stat *buf)
|
||||
{
|
||||
REDIR;
|
||||
path = redirect (me, path);
|
||||
#ifndef HAVE_STATLSTAT
|
||||
return lstat (path,buf);
|
||||
#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)
|
||||
{
|
||||
REDIR;
|
||||
path = redirect (me, path);
|
||||
return chmod (path, mode);
|
||||
}
|
||||
|
||||
static int sfs_chown (vfs *me, char *path, int owner, int group)
|
||||
{
|
||||
REDIR;
|
||||
path = redirect (me, path);
|
||||
return chown (path, owner, group);
|
||||
}
|
||||
|
||||
static int sfs_utime (vfs *me, char *path, struct utimbuf *times)
|
||||
{
|
||||
REDIR;
|
||||
path = redirect (me, path);
|
||||
return utime (path, times);
|
||||
}
|
||||
|
||||
static int sfs_readlink (vfs *me, char *path, char *buf, int size)
|
||||
{
|
||||
REDIR;
|
||||
path = redirect (me, path);
|
||||
return readlink (path, buf, size);
|
||||
}
|
||||
|
||||
@ -220,10 +224,10 @@ static vfsid sfs_getid (vfs *me, char *path, struct vfs_stamping **parent)
|
||||
*parent = NULL;
|
||||
|
||||
{
|
||||
char *path2 = strdup( path );
|
||||
char *path2 = strdup (path);
|
||||
v = vfs_split (path2, NULL, NULL);
|
||||
id = (*v->getid) (v, path2, &par);
|
||||
free( path2 );
|
||||
free (path2);
|
||||
}
|
||||
|
||||
if (id != (vfsid)-1) {
|
||||
@ -272,7 +276,7 @@ static int sfs_nothingisopen (vfsid id)
|
||||
|
||||
static char *sfs_getlocalcopy (vfs *me, char *path)
|
||||
{
|
||||
REDIR;
|
||||
path = redirect (me, 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)
|
||||
{
|
||||
FILE *cfg = fopen( LIBDIR "extfs/sfs.ini", "r" );
|
||||
if (!cfg) {
|
||||
fprintf( stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n" );
|
||||
FILE *cfg = fopen (LIBDIR "extfs/sfs.ini", "r");
|
||||
|
||||
if (!cfg){
|
||||
fprintf (stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sfs_no = 0;
|
||||
while ( sfs_no < MAXFS ) {
|
||||
while (sfs_no < MAXFS){
|
||||
char key[256];
|
||||
char *c, *semi = NULL, flags = 0;
|
||||
int i;
|
||||
|
||||
if (!fgets( key, 250, cfg ))
|
||||
if (!fgets (key, 250, cfg))
|
||||
break;
|
||||
|
||||
if (*key == '#')
|
||||
continue;
|
||||
|
||||
for (i=0; i<strlen(key); i++)
|
||||
if ((key[i]==':') || (key[i]=='/'))
|
||||
{ semi = key+i; if (key[i]=='/') { key[i]=0; flags |= F_FULLMATCH; } break; }
|
||||
for (i = 0; i < strlen (key); i++)
|
||||
if ((key[i]==':') || (key[i]=='/')){
|
||||
semi = key+i;
|
||||
if (key [i] == '/'){
|
||||
key [i] = 0;
|
||||
flags |= F_FULLMATCH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!semi) {
|
||||
fprintf( stderr, "Warning: Invalid line %s in sfs.ini.\n", key );
|
||||
if (!semi){
|
||||
fprintf (stderr, "Warning: Invalid line %s in sfs.ini.\n", key);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -316,13 +327,13 @@ static int sfs_init (vfs *me)
|
||||
case '2': flags |= F_2; break;
|
||||
case 'R': flags |= F_NOLOCALCOPY; break;
|
||||
default:
|
||||
fprintf( stderr, "Warning: Invalid flag %c in sfs.ini line %s.\n", *c, key );
|
||||
fprintf (stderr, "Warning: Invalid flag %c in sfs.ini line %s.\n", *c, key);
|
||||
}
|
||||
c++;
|
||||
}
|
||||
c++;
|
||||
*(semi+1) = 0;
|
||||
if ((semi = strchr( c, '\n')))
|
||||
if ((semi = strchr (c, '\n')))
|
||||
*semi = 0;
|
||||
|
||||
sfs_prefix [sfs_no] = strdup (key);
|
||||
@ -330,22 +341,25 @@ static int sfs_init (vfs *me)
|
||||
sfs_flags [sfs_no] = flags;
|
||||
sfs_no++;
|
||||
}
|
||||
fclose(cfg);
|
||||
fclose (cfg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sfs_done (vfs *me)
|
||||
static void
|
||||
sfs_done (vfs *me)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<sfs_no; i++) {
|
||||
free(sfs_prefix [i]);
|
||||
free(sfs_command [i]);
|
||||
|
||||
for (i = 0; i < sfs_no; i++){
|
||||
free (sfs_prefix [i]);
|
||||
free (sfs_command [i]);
|
||||
sfs_prefix [i] = sfs_command [i] = NULL;
|
||||
}
|
||||
sfs_no = 0;
|
||||
}
|
||||
|
||||
static int sfs_which (vfs *me, char *path)
|
||||
static int
|
||||
sfs_which (vfs *me, char *path)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -354,7 +368,7 @@ static int sfs_which (vfs *me, char *path)
|
||||
if (!strcmp (path, sfs_prefix [i]))
|
||||
return i;
|
||||
} else
|
||||
if (!strncmp (path, sfs_prefix [i], strlen( sfs_prefix[i]) ))
|
||||
if (!strncmp (path, sfs_prefix [i], strlen (sfs_prefix [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 *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 */
|
||||
current_tar_position += RECORDSIZE;
|
||||
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,
|
||||
* 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 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);
|
||||
if (NULL == header)
|
||||
return EOF;
|
||||
return STATUS_EOF;
|
||||
|
||||
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;
|
||||
signed_sum += ' ' * sizeof header->header.chksum;
|
||||
|
||||
if (sum == 8 * ' ') {
|
||||
/*
|
||||
* This is a zeroed record...whole record is 0's except
|
||||
* for the 8 blanks we faked for the checksum field.
|
||||
*/
|
||||
return 2;
|
||||
}
|
||||
/*
|
||||
* This is a zeroed record...whole record is 0's except
|
||||
* for the 8 blanks we faked for the checksum field.
|
||||
*/
|
||||
if (sum == 8 * ' ')
|
||||
return STATUS_EOFMARK;
|
||||
|
||||
if (sum != recsum && signed_sum != recsum)
|
||||
return 0;
|
||||
return STATUS_BADCHECKSUM;
|
||||
|
||||
/*
|
||||
* linkflag on BSDI tar (pax) always '\000'
|
||||
*/
|
||||
if(header->header.linkflag == '\000' &&
|
||||
strlen(header->header.arch_name) &&
|
||||
header->header.arch_name[strlen(header->header.arch_name) - 1] == '/')
|
||||
if (header->header.linkflag == '\000' &&
|
||||
strlen(header->header.arch_name) &&
|
||||
header->header.arch_name[strlen(header->header.arch_name) - 1] == '/')
|
||||
header->header.linkflag = LF_DIR;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Good record. Decode file size and return.
|
||||
*/
|
||||
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;
|
||||
if (data == NULL) {
|
||||
message_1s (1, MSG_ERROR, _("Unexpected EOF on archive file"));
|
||||
return 0;
|
||||
return STATUS_BADCHECKSUM;
|
||||
}
|
||||
written = RECORDSIZE;
|
||||
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);
|
||||
if (parent == NULL) {
|
||||
message_1s (1, MSG_ERROR, _("Inconsistent tar archive"));
|
||||
return 0;
|
||||
return STATUS_BADCHECKSUM;
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
int status = 3; /* Initial status at start of archive */
|
||||
int prev_status;
|
||||
ReadStatus status = STATUS_EOFMARK; /* Initial status at start of archive */
|
||||
ReadStatus prev_status;
|
||||
int tard;
|
||||
|
||||
current_tar_position = 0;
|
||||
@ -378,33 +389,45 @@ static int open_archive (vfs *me, vfs_s_super *archive, char *name, char *op)
|
||||
for (;;) {
|
||||
prev_status = status;
|
||||
status = read_header (me, archive, tard);
|
||||
|
||||
|
||||
switch (status) {
|
||||
|
||||
case 1: /* Valid header */
|
||||
skip_n_records (archive, tard, (hstat.st_size + RECORDSIZE - 1) / RECORDSIZE);
|
||||
continue;
|
||||
/*
|
||||
* If the previous header was good, tell them
|
||||
* that we are skipping bad ones.
|
||||
*/
|
||||
case 0: /* Invalid header */
|
||||
switch (prev_status) {
|
||||
case 3: /* Error on first record */
|
||||
case STATUS_SUCCESS:
|
||||
skip_n_records (archive, tard, (hstat.st_size + RECORDSIZE - 1) / RECORDSIZE);
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Invalid header:
|
||||
*
|
||||
* If the previous header was good, tell them
|
||||
* that we are skipping bad ones.
|
||||
*/
|
||||
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);
|
||||
/* FALL THRU */
|
||||
case 2: /* Error after record of zeroes */
|
||||
case 1: /* Error after header rec */
|
||||
#if 0
|
||||
message_1s (0, " Warning ", "Skipping to next file header...");
|
||||
#endif
|
||||
case 0: /* Error after error */
|
||||
|
||||
/* Error after header rec */
|
||||
case STATUS_SUCCESS:
|
||||
/* Error after error */
|
||||
|
||||
case STATUS_BADCHECKSUM:
|
||||
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 */
|
||||
/* FALL THRU */
|
||||
case EOF: /* End of archive */
|
||||
|
||||
case STATUS_EOF: /* End of archive */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
39
vfs/vfs.c
39
vfs/vfs.c
@ -116,10 +116,13 @@ vfs_register (vfs *vfs)
|
||||
{
|
||||
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;
|
||||
|
||||
if (!res) return 0;
|
||||
if (!res)
|
||||
return 0;
|
||||
|
||||
vfs->next = vfs_list;
|
||||
vfs_list = vfs;
|
||||
@ -132,7 +135,8 @@ vfs_type_from_op (char *path)
|
||||
{
|
||||
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){
|
||||
if (vfs->which) {
|
||||
@ -156,14 +160,15 @@ vfs_strip_suffix_from_filename (char *filename)
|
||||
char *semi;
|
||||
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);
|
||||
if (!(semi = strrchr (p, '#')))
|
||||
return p;
|
||||
|
||||
for (vfs = vfs_list; vfs != &vfs_local_ops; vfs = vfs->next){
|
||||
if (vfs->which) {
|
||||
if (vfs->which){
|
||||
if ((*vfs->which) (vfs, semi + 1) == -1)
|
||||
continue;
|
||||
*semi = '\0'; /* Found valid suffix */
|
||||
@ -203,7 +208,8 @@ vfs_split (char *path, char **inpath, char **op)
|
||||
char *slash;
|
||||
vfs *ret;
|
||||
|
||||
if (!path) vfs_die("Can not split NULL");
|
||||
if (!path)
|
||||
vfs_die("Can not split NULL");
|
||||
|
||||
semi = strrchr (path, '#');
|
||||
if (!semi || !path_magic(path))
|
||||
@ -243,7 +249,9 @@ vfs_rosplit (char *path)
|
||||
char *slash;
|
||||
vfs *ret;
|
||||
|
||||
if (!path) vfs_die( "Can not rosplit NULL" );
|
||||
if (!path)
|
||||
vfs_die ("Can not rosplit NULL");
|
||||
|
||||
semi = strrchr (path, '#');
|
||||
|
||||
if (!semi || !path_magic (path))
|
||||
@ -463,7 +471,8 @@ mc_setctl (char *path, int ctlop, char *arg)
|
||||
int result;
|
||||
|
||||
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);
|
||||
vfs = vfs_type (path);
|
||||
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 *
|
||||
vfs_canon (char *path)
|
||||
{
|
||||
if (!path) vfs_die("Can not canonize NULL");
|
||||
if (!path)
|
||||
vfs_die("Can not canonize NULL");
|
||||
|
||||
/* Tilde expansion */
|
||||
if (*path == '~'){
|
||||
@ -726,9 +736,9 @@ vfs_canon (char *path)
|
||||
* So we have path of following form:
|
||||
* /p1/p2#op/.././././p3#op/p4. Good luck.
|
||||
*/
|
||||
mad_check( "(pre-canonicalize)", 0);
|
||||
mad_check("(pre-canonicalize)", 0);
|
||||
canonicalize_pathname (path);
|
||||
mad_check( "(post-canonicalize)", 0);
|
||||
mad_check("(post-canonicalize)", 0);
|
||||
|
||||
return strdup (path);
|
||||
}
|
||||
@ -1476,7 +1486,7 @@ int vfs_parse_filedate(int idx, time_t *t)
|
||||
char *p;
|
||||
struct tm tim;
|
||||
int d[3];
|
||||
int swap, got_year = 0;
|
||||
int got_year = 0;
|
||||
|
||||
/* Let's setup default time values */
|
||||
tim.tm_year = current_year;
|
||||
@ -1577,7 +1587,7 @@ int vfs_parse_filedate(int idx, time_t *t)
|
||||
int
|
||||
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;
|
||||
char *p_copy;
|
||||
|
||||
@ -1644,13 +1654,12 @@ vfs_parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
|
||||
|
||||
/* This is device */
|
||||
if (S_ISCHR (s->st_mode) || S_ISBLK (s->st_mode)){
|
||||
|
||||
int maj, min;
|
||||
|
||||
if (!is_num (idx2) || sscanf(columns [idx2], " %d,", &maj) != 1)
|
||||
goto error;
|
||||
|
||||
if (!is_num (++idx2) || sscanf(columns [idx2], " %li", &min) != 1)
|
||||
if (!is_num (++idx2) || sscanf(columns [idx2], " %d", &min) != 1)
|
||||
goto error;
|
||||
|
||||
#ifdef HAVE_ST_RDEV
|
||||
|
@ -145,35 +145,52 @@ struct vfs_s_data {
|
||||
};
|
||||
|
||||
/* entries and inodes */
|
||||
vfs_s_inode *vfs_s_new_inode (vfs *me, vfs_s_super *super, struct stat *initstat);
|
||||
vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode);
|
||||
void vfs_s_free_entry (vfs *me, vfs_s_entry *ent);
|
||||
void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir, vfs_s_entry *ent);
|
||||
struct stat *vfs_s_default_stat (vfs *me, mode_t mode);
|
||||
void vfs_s_add_dots (vfs *me, vfs_s_inode *dir, vfs_s_inode *parent);
|
||||
struct vfs_s_entry *vfs_s_generate_entry (vfs *me, char *name, struct vfs_s_inode *parent, 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);
|
||||
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);
|
||||
struct vfs_s_entry *vfs_s_resolve_symlink (vfs *me, vfs_s_entry *entry, int follow);
|
||||
vfs_s_inode *vfs_s_new_inode (vfs *me, vfs_s_super *super,
|
||||
struct stat *initstat);
|
||||
vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode);
|
||||
void vfs_s_free_entry (vfs *me, vfs_s_entry *ent);
|
||||
void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir,
|
||||
vfs_s_entry *ent);
|
||||
struct stat *vfs_s_default_stat (vfs *me, mode_t mode);
|
||||
|
||||
void vfs_s_add_dots (vfs *me, vfs_s_inode *dir,
|
||||
vfs_s_inode *parent);
|
||||
vfs_s_entry *vfs_s_generate_entry (vfs *me, char *name,
|
||||
struct vfs_s_inode *parent, 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);
|
||||
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 */
|
||||
vfs_s_super *vfs_s_new_super (vfs *me);
|
||||
void vfs_s_free_super (vfs *me, vfs_s_super *super);
|
||||
vfs_s_super *vfs_s_new_super (vfs *me);
|
||||
void vfs_s_free_super (vfs *me, vfs_s_super *super);
|
||||
|
||||
/* outside interface */
|
||||
char *vfs_s_get_path_mangle (vfs *me, char *inname, vfs_s_super **archive, int flags);
|
||||
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_get_path_mangle (vfs *me, char *inname, vfs_s_super **archive,
|
||||
int flags);
|
||||
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 */
|
||||
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);
|
||||
void * vfs_s_opendir (vfs *me, char *dirname);
|
||||
void * vfs_s_readdir (void *data);
|
||||
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);
|
||||
void *vfs_s_opendir (vfs *me, char *dirname);
|
||||
void *vfs_s_readdir (void *data);
|
||||
int vfs_s_telldir (void *data);
|
||||
void vfs_s_seekdir (void *data, int offset);
|
||||
int vfs_s_closedir (void *data);
|
||||
int vfs_s_chdir (vfs *me, char *path);
|
||||
|
||||
/* stat & friends */
|
||||
int vfs_s_stat (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_lseek (void *fh, off_t offset, int whence);
|
||||
int vfs_s_close (void *fh);
|
||||
|
||||
/* mc support */
|
||||
void vfs_s_fill_names (vfs *me, void (*func)(char *));
|
||||
int vfs_s_ferrno(vfs *me);
|
||||
void vfs_s_dump(vfs *me, char *prefix, vfs_s_inode *ino);
|
||||
char *vfs_s_getlocalcopy (vfs *me, char *path);
|
||||
|
||||
/* stamping support */
|
||||
vfsid vfs_s_getid (vfs *me, char *path, struct vfs_stamping **parent);
|
||||
int vfs_s_nothingisopen (vfsid id);
|
||||
void vfs_s_free (vfsid id);
|
||||
int vfs_s_setctl (vfs *me, char *path, int ctlop, char *arg);
|
||||
|
||||
/* network filesystems support */
|
||||
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);
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user