Browse Source

* vfs.c: Move all parsing code, vfs_die() and vfs_get_password()
to utilvfs.c, vfs_print_stats() to direntry.c.
* utilvfs.c (vfs_parse_ls_lga): Disable caching current date,
it's done incorrectly.

Pavel Roskin 21 years ago
parent
commit
0318ed5d0b
6 changed files with 670 additions and 603 deletions
  1. 7 0
      vfs/ChangeLog
  2. 24 2
      vfs/direntry.c
  3. 623 0
      vfs/utilvfs.c
  4. 13 2
      vfs/utilvfs.h
  5. 3 585
      vfs/vfs.c
  6. 0 14
      vfs/vfs.h

+ 7 - 0
vfs/ChangeLog

@@ -1,3 +1,10 @@
+2003-11-05  Pavel Roskin  <proski@gnu.org>
+
+	* vfs.c: Move all parsing code, vfs_die() and vfs_get_password()
+	to utilvfs.c, vfs_print_stats() to direntry.c.
+	* utilvfs.c (vfs_parse_ls_lga): Disable caching current date,
+	it's done incorrectly.
+
 2003-11-04  Pavel Roskin  <proski@gnu.org>
 2003-11-04  Pavel Roskin  <proski@gnu.org>
 
 
 	* vfs.c: Allocate handles dynamically.
 	* vfs.c: Allocate handles dynamically.

+ 24 - 2
vfs/direntry.c

@@ -888,6 +888,28 @@ vfs_s_close (void *fh)
     return res;
     return res;
 }
 }
 
 
+static void
+vfs_s_print_stats (const char *fs_name, const char *action,
+		   const char *file_name, off_t have, off_t need)
+{
+    static char *i18n_percent_transf_format = NULL, *i18n_transf_format =
+	NULL;
+
+    if (i18n_percent_transf_format == NULL) {
+	i18n_percent_transf_format =
+	    _("%s: %s: %s %3d%% (%lu bytes transferred)");
+	i18n_transf_format = _("%s: %s: %s %lu bytes transferred");
+    }
+
+    if (need)
+	print_vfs_message (i18n_percent_transf_format, fs_name, action,
+			   file_name, (int) ((double) have * 100 / need),
+			   (unsigned long) have);
+    else
+	print_vfs_message (i18n_transf_format, fs_name, action, file_name,
+			   (unsigned long) have);
+}
+
 int
 int
 vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino)
 vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino)
 {
 {
@@ -922,8 +944,8 @@ vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino)
 	    goto error_1;
 	    goto error_1;
 
 
 	total += n;
 	total += n;
-	vfs_print_stats (me->name, _("Getting file"), ino->ent->name,
-			 total, stat_size);
+	vfs_s_print_stats (me->name, _("Getting file"), ino->ent->name,
+			   total, stat_size);
 
 
 	if (got_interrupt ())
 	if (got_interrupt ())
 	    goto error_1;
 	    goto error_1;

+ 623 - 0
vfs/utilvfs.c

@@ -234,3 +234,626 @@ vfs_mkstemps (char **pname, const char *prefix, const char *basename)
     g_free (suffix);
     g_free (suffix);
     return fd;
     return fd;
 }
 }
+
+/* Parsing code is used by ftpfs, fish and extfs */
+#define MAXCOLS		30
+
+static char *columns[MAXCOLS];	/* Points to the string in column n */
+static int column_ptr[MAXCOLS];	/* Index from 0 to the starting positions of the columns */
+
+int
+vfs_split_text (char *p)
+{
+    char *original = p;
+    int numcols;
+
+    memset (columns, 0, sizeof (columns));
+
+    for (numcols = 0; *p && numcols < MAXCOLS; numcols++) {
+	while (*p == ' ' || *p == '\r' || *p == '\n') {
+	    *p = 0;
+	    p++;
+	}
+	columns[numcols] = p;
+	column_ptr[numcols] = p - original;
+	while (*p && *p != ' ' && *p != '\r' && *p != '\n')
+	    p++;
+    }
+    return numcols;
+}
+
+static int
+is_num (int idx)
+{
+    char *column = columns[idx];
+
+    if (!column || column[0] < '0' || column[0] > '9')
+	return 0;
+
+    return 1;
+}
+
+/* Return 1 for MM-DD-YY and MM-DD-YYYY */
+static int
+is_dos_date (const char *str)
+{
+    int len;
+
+    if (!str)
+	return 0;
+
+    len = strlen (str);
+    if (len != 8 && len != 10)
+	return 0;
+
+    if (str[2] != str[5])
+	return 0;
+
+    if (!strchr ("\\-/", (int) str[2]))
+	return 0;
+
+    return 1;
+}
+
+static int
+is_week (const char *str, struct tm *tim)
+{
+    static const char *week = "SunMonTueWedThuFriSat";
+    char *pos;
+
+    if (!str)
+	return 0;
+
+    if ((pos = strstr (week, str)) != NULL) {
+	if (tim != NULL)
+	    tim->tm_wday = (pos - week) / 3;
+	return 1;
+    }
+    return 0;
+}
+
+static int
+is_month (const char *str, struct tm *tim)
+{
+    static const char *month = "JanFebMarAprMayJunJulAugSepOctNovDec";
+    char *pos;
+
+    if (!str)
+	return 0;
+
+    if ((pos = strstr (month, str)) != NULL) {
+	if (tim != NULL)
+	    tim->tm_mon = (pos - month) / 3;
+	return 1;
+    }
+    return 0;
+}
+
+/*
+ * Check for possible locale's abbreviated month name (Jan..Dec).
+ * Any 3 bytes long string without digit and control characters.
+ * isalpha() is locale specific, so it cannot be used if current
+ * locale is "C" and ftp server use Cyrillic.
+ * TODO: Punctuation characters also cannot be part of month name.
+ * NB: It is assumed there are no whitespaces in month.
+ */
+static int
+is_localized_month (const unsigned char *month)
+{
+    int i = 0;
+    while ((i < 3) && *month && !isdigit (*month) && !iscntrl (*month)) {
+	i++;
+	month++;
+    }
+    return ((i == 3) && (*month == 0));
+}
+
+static int
+is_time (const char *str, struct tm *tim)
+{
+    char *p, *p2;
+
+    if (!str)
+	return 0;
+
+    if ((p = strchr (str, ':')) && (p2 = strrchr (str, ':'))) {
+	if (p != p2) {
+	    if (sscanf
+		(str, "%2d:%2d:%2d", &tim->tm_hour, &tim->tm_min,
+		 &tim->tm_sec) != 3)
+		return 0;
+	} else {
+	    if (sscanf (str, "%2d:%2d", &tim->tm_hour, &tim->tm_min) != 2)
+		return 0;
+	}
+    } else
+	return 0;
+
+    return 1;
+}
+
+static int
+is_year (char *str, struct tm *tim)
+{
+    long year;
+
+    if (!str)
+	return 0;
+
+    if (strchr (str, ':'))
+	return 0;
+
+    if (strlen (str) != 4)
+	return 0;
+
+    if (sscanf (str, "%ld", &year) != 1)
+	return 0;
+
+    if (year < 1900 || year > 3000)
+	return 0;
+
+    tim->tm_year = (int) (year - 1900);
+
+    return 1;
+}
+
+/*
+ * FIXME: this is broken. Consider following entry:
+ * -rwx------   1 root     root            1 Aug 31 10:04 2904 1234
+ * where "2904 1234" is filename. Well, this code decodes it as year :-(.
+ */
+
+int
+vfs_parse_filetype (char c)
+{
+    switch (c) {
+    case 'd':
+	return S_IFDIR;
+    case 'b':
+	return S_IFBLK;
+    case 'c':
+	return S_IFCHR;
+    case 'l':
+	return S_IFLNK;
+    case 's':			/* Socket */
+#ifdef S_IFSOCK
+	return S_IFSOCK;
+#else
+	/* If not supported, we fall through to IFIFO */
+	return S_IFIFO;
+#endif
+    case 'D':			/* Solaris door */
+#ifdef S_IFDOOR
+	return S_IFDOOR;
+#else
+	return S_IFIFO;
+#endif
+    case 'p':
+	return S_IFIFO;
+    case 'm':
+    case 'n':			/* Don't know what these are :-) */
+    case '-':
+    case '?':
+	return S_IFREG;
+    default:
+	return -1;
+    }
+}
+
+int
+vfs_parse_filemode (const char *p)
+{				/* converts rw-rw-rw- into 0666 */
+    int res = 0;
+    switch (*(p++)) {
+    case 'r':
+	res |= 0400;
+	break;
+    case '-':
+	break;
+    default:
+	return -1;
+    }
+    switch (*(p++)) {
+    case 'w':
+	res |= 0200;
+	break;
+    case '-':
+	break;
+    default:
+	return -1;
+    }
+    switch (*(p++)) {
+    case 'x':
+	res |= 0100;
+	break;
+    case 's':
+	res |= 0100 | S_ISUID;
+	break;
+    case 'S':
+	res |= S_ISUID;
+	break;
+    case '-':
+	break;
+    default:
+	return -1;
+    }
+    switch (*(p++)) {
+    case 'r':
+	res |= 0040;
+	break;
+    case '-':
+	break;
+    default:
+	return -1;
+    }
+    switch (*(p++)) {
+    case 'w':
+	res |= 0020;
+	break;
+    case '-':
+	break;
+    default:
+	return -1;
+    }
+    switch (*(p++)) {
+    case 'x':
+	res |= 0010;
+	break;
+    case 's':
+	res |= 0010 | S_ISGID;
+	break;
+    case 'l':			/* Solaris produces these */
+    case 'S':
+	res |= S_ISGID;
+	break;
+    case '-':
+	break;
+    default:
+	return -1;
+    }
+    switch (*(p++)) {
+    case 'r':
+	res |= 0004;
+	break;
+    case '-':
+	break;
+    default:
+	return -1;
+    }
+    switch (*(p++)) {
+    case 'w':
+	res |= 0002;
+	break;
+    case '-':
+	break;
+    default:
+	return -1;
+    }
+    switch (*(p++)) {
+    case 'x':
+	res |= 0001;
+	break;
+    case 't':
+	res |= 0001 | S_ISVTX;
+	break;
+    case 'T':
+	res |= S_ISVTX;
+	break;
+    case '-':
+	break;
+    default:
+	return -1;
+    }
+    return res;
+}
+
+/* This function parses from idx in the columns[] array */
+int
+vfs_parse_filedate (int idx, time_t *t)
+{
+    char *p;
+    struct tm tim;
+    int d[3];
+    int got_year = 0;
+    int l10n = 0;		/* Locale's abbreviated month name */
+    time_t current_time;
+    struct tm *local_time;
+
+    /* Let's setup default time values */
+    current_time = time (NULL);
+    local_time = localtime (&current_time);
+    tim.tm_mday = local_time->tm_mday;
+    tim.tm_mon = local_time->tm_mon;
+    tim.tm_year = local_time->tm_year;
+
+    tim.tm_hour = 0;
+    tim.tm_min = 0;
+    tim.tm_sec = 0;
+    tim.tm_isdst = -1;		/* Let mktime() try to guess correct dst offset */
+
+    p = columns[idx++];
+
+    /* We eat weekday name in case of extfs */
+    if (is_week (p, &tim))
+	p = columns[idx++];
+
+    /* Month name */
+    if (is_month (p, &tim)) {
+	/* And we expect, it followed by day number */
+	if (is_num (idx))
+	    tim.tm_mday = (int) atol (columns[idx++]);
+	else
+	    return 0;		/* No day */
+
+    } else {
+	/* We usually expect:
+	   Mon DD hh:mm
+	   Mon DD  YYYY
+	   But in case of extfs we allow these date formats:
+	   Mon DD YYYY hh:mm
+	   Mon DD hh:mm YYYY
+	   Wek Mon DD hh:mm:ss YYYY
+	   MM-DD-YY hh:mm
+	   where Mon is Jan-Dec, DD, MM, YY two digit day, month, year,
+	   YYYY four digit year, hh, mm, ss two digit hour, minute or second. */
+
+	/* Special case with MM-DD-YY or MM-DD-YYYY */
+	if (is_dos_date (p)) {
+	    p[2] = p[5] = '-';
+
+	    if (sscanf (p, "%2d-%2d-%d", &d[0], &d[1], &d[2]) == 3) {
+		/* Months are zero based */
+		if (d[0] > 0)
+		    d[0]--;
+
+		if (d[2] > 1900) {
+		    d[2] -= 1900;
+		} else {
+		    /* Y2K madness */
+		    if (d[2] < 70)
+			d[2] += 100;
+		}
+
+		tim.tm_mon = d[0];
+		tim.tm_mday = d[1];
+		tim.tm_year = d[2];
+		got_year = 1;
+	    } else
+		return 0;	/* sscanf failed */
+	} else {
+	    /* Locale's abbreviated month name followed by day number */
+	    if (is_localized_month (p) && (is_num (idx++)))
+		l10n = 1;
+	    else
+		return 0;	/* unsupported format */
+	}
+    }
+
+    /* Here we expect to find time and/or year */
+
+    if (is_num (idx)) {
+	if (is_time (columns[idx], &tim)
+	    || (got_year = is_year (columns[idx], &tim))) {
+	    idx++;
+
+	    /* This is a special case for ctime() or Mon DD YYYY hh:mm */
+	    if (is_num (idx) && (columns[idx + 1][0])) {
+		if (got_year) {
+		    if (is_time (columns[idx], &tim))
+			idx++;	/* time also */
+		} else {
+		    if ((got_year = is_year (columns[idx], &tim)))
+			idx++;	/* year also */
+		}
+	    }
+	}			/* only time or date */
+    } else
+	return 0;		/* Nor time or date */
+
+    /*
+     * If the date is less than 6 months in the past, it is shown without year
+     * other dates in the past or future are shown with year but without time
+     * This does not check for years before 1900 ... I don't know, how
+     * to represent them at all
+     */
+    if (!got_year && local_time->tm_mon < 6
+	&& local_time->tm_mon < tim.tm_mon
+	&& tim.tm_mon - local_time->tm_mon >= 6)
+
+	tim.tm_year--;
+
+    if (l10n || (*t = mktime (&tim)) < 0)
+	*t = 0;
+    return idx;
+}
+
+int
+vfs_parse_ls_lga (const char *p, struct stat *s, char **filename,
+		  char **linkname)
+{
+    int idx, idx2, num_cols;
+    int i;
+    char *p_copy = NULL;
+    char *t = NULL;
+    const char *line = p;
+
+    if (strncmp (p, "total", 5) == 0)
+	return 0;
+
+    if ((i = vfs_parse_filetype (*(p++))) == -1)
+	goto error;
+
+    s->st_mode = i;
+    if (*p == ' ')		/* Notwell 4 */
+	p++;
+    if (*p == '[') {
+	if (strlen (p) <= 8 || p[8] != ']')
+	    goto error;
+	/* Should parse here the Notwell permissions :) */
+	if (S_ISDIR (s->st_mode))
+	    s->st_mode |=
+		(S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IXUSR | S_IXGRP
+		 | S_IXOTH);
+	else
+	    s->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
+	p += 9;
+    } else {
+	if ((i = vfs_parse_filemode (p)) == -1)
+	    goto error;
+	s->st_mode |= i;
+	p += 9;
+
+	/* This is for an extra ACL attribute (HP-UX) */
+	if (*p == '+')
+	    p++;
+    }
+
+    p_copy = g_strdup (p);
+    num_cols = vfs_split_text (p_copy);
+
+    s->st_nlink = atol (columns[0]);
+    if (s->st_nlink <= 0)
+	goto error;
+
+    if (!is_num (1))
+	s->st_uid = vfs_finduid (columns[1]);
+    else
+	s->st_uid = (uid_t) atol (columns[1]);
+
+    /* Mhm, the ls -lg did not produce a group field */
+    for (idx = 3; idx <= 5; idx++)
+	if (is_month (columns[idx], NULL) || is_week (columns[idx], NULL)
+	    || is_dos_date (columns[idx])
+	    || is_localized_month (columns[idx]))
+	    break;
+
+    if (idx == 6
+	|| (idx == 5 && !S_ISCHR (s->st_mode) && !S_ISBLK (s->st_mode)))
+	goto error;
+
+    /* We don't have gid */
+    if (idx == 3
+	|| (idx == 4 && (S_ISCHR (s->st_mode) || S_ISBLK (s->st_mode))))
+	idx2 = 2;
+    else {
+	/* We have gid field */
+	if (is_num (2))
+	    s->st_gid = (gid_t) atol (columns[2]);
+	else
+	    s->st_gid = vfs_findgid (columns[2]);
+	idx2 = 3;
+    }
+
+    /* 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], " %d", &min) != 1)
+	    goto error;
+
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+	s->st_rdev = ((maj & 0xff) << 8) | (min & 0xffff00ff);
+#endif
+	s->st_size = 0;
+
+    } else {
+	/* Common file size */
+	if (!is_num (idx2))
+	    goto error;
+
+	s->st_size = (size_t) atol (columns[idx2]);
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+	s->st_rdev = 0;
+#endif
+    }
+
+    idx = vfs_parse_filedate (idx, &s->st_mtime);
+    if (!idx)
+	goto error;
+    /* Use resulting time value */
+    s->st_atime = s->st_ctime = s->st_mtime;
+    /* s->st_dev and s->st_ino must be initialized by vfs_s_new_inode () */
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+    s->st_blksize = 512;
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+    s->st_blocks = (s->st_size + 511) / 512;
+#endif
+
+    for (i = idx + 1, idx2 = 0; i < num_cols; i++)
+	if (strcmp (columns[i], "->") == 0) {
+	    idx2 = i;
+	    break;
+	}
+
+    if (((S_ISLNK (s->st_mode) || (num_cols == idx + 3 && s->st_nlink > 1)))	/* Maybe a hardlink? (in extfs) */
+	&&idx2) {
+
+	if (filename) {
+	    *filename =
+		g_strndup (p + column_ptr[idx],
+			   column_ptr[idx2] - column_ptr[idx] - 1);
+	}
+	if (linkname) {
+	    t = g_strdup (p + column_ptr[idx2 + 1]);
+	    *linkname = t;
+	}
+    } else {
+	/* Extract the filename from the string copy, not from the columns
+	 * this way we have a chance of entering hidden directories like ". ."
+	 */
+	if (filename) {
+	    /*
+	     * filename = g_strdup (columns [idx++]);
+	     */
+
+	    t = g_strdup (p + column_ptr[idx]);
+	    *filename = t;
+	}
+	if (linkname)
+	    *linkname = NULL;
+    }
+
+    if (t) {
+	int p = strlen (t);
+	if ((--p > 0) && (t[p] == '\r' || t[p] == '\n'))
+	    t[p] = 0;
+	if ((--p > 0) && (t[p] == '\r' || t[p] == '\n'))
+	    t[p] = 0;
+    }
+
+    g_free (p_copy);
+    return 1;
+
+  error:
+    {
+	static int errorcount = 0;
+
+	if (++errorcount < 5) {
+	    message (1, _("Cannot parse:"),
+		     (p_copy && *p_copy) ? p_copy : line);
+	} else if (errorcount == 5)
+	    message (1, _("Error"),
+		     _("More parsing errors will be ignored."));
+    }
+
+    g_free (p_copy);
+    return 0;
+}
+
+void
+vfs_die (const char *m)
+{
+    message (1, _("Internal error:"), m);
+    exit (1);
+}
+
+char *
+vfs_get_password (char *msg)
+{
+    return (char *) input_dialog (msg, _("Password:"), INPUT_PASSWORD);
+}
+

+ 13 - 2
vfs/utilvfs.h

@@ -11,11 +11,22 @@
 #define URL_ALLOW_ANON 1
 #define URL_ALLOW_ANON 1
 #define URL_NOSLASH 2
 #define URL_NOSLASH 2
 
 
+int vfs_finduid (char *name);
+int vfs_findgid (char *name);
+
 char *vfs_split_url (const char *path, char **host, char **user, int *port,
 char *vfs_split_url (const char *path, char **host, char **user, int *port,
 		     char **pass, int default_port, int flags);
 		     char **pass, int default_port, int flags);
+int vfs_split_text (char *p);
+char *vfs_translate_url (const char *);
 
 
-int vfs_finduid (char *name);
-int vfs_findgid (char *name);
 int vfs_mkstemps (char **pname, const char *prefix, const char *basename);
 int vfs_mkstemps (char **pname, const char *prefix, const char *basename);
+void vfs_die (const char *msg);
+char *vfs_get_password (char *msg);
+
+int vfs_parse_ls_lga (const char *p, struct stat *s, char **filename,
+		      char **linkname);
+int vfs_parse_filetype (char c);
+int vfs_parse_filemode (const char *p);
+int vfs_parse_filedate (int idx, time_t *t);
 
 
 #endif				/* !__UTILVFS_H */
 #endif				/* !__UTILVFS_H */

+ 3 - 585
vfs/vfs.c

@@ -58,13 +58,6 @@ int vfs_timeout = 60; /* VFS timeout in seconds */
 static struct vfs_class *current_vfs;
 static struct vfs_class *current_vfs;
 static char *current_dir;
 static char *current_dir;
 
 
-/*
- * FIXME: this is broken. It depends on mc not crossing border on month!
- */
-static int current_mday;
-static int current_mon;
-static int current_year;
-
 struct vfs_openfile {
 struct vfs_openfile {
     int handle;
     int handle;
     struct vfs_class *vclass;
     struct vfs_class *vclass;
@@ -1223,15 +1216,6 @@ vfs_timeout_handler (void)
 void
 void
 vfs_init (void)
 vfs_init (void)
 {
 {
-    time_t current_time;
-    struct tm *t;
-
-    current_time = time (NULL);
-    t = localtime (&current_time);
-    current_mday = t->tm_mday;
-    current_mon  = t->tm_mon;
-    current_year = t->tm_year;
-
     /* localfs needs to be the first one */
     /* localfs needs to be the first one */
     init_localfs();
     init_localfs();
     /* fallback value for vfs_get_class() */
     /* fallback value for vfs_get_class() */
@@ -1301,572 +1285,6 @@ vfs_fill_names (void (*func)(char *))
 	    (*vfs->fill_names) (vfs, func);
 	    (*vfs->fill_names) (vfs, func);
 }
 }
 
 
-/* Following stuff (parse_ls_lga) is used by ftpfs and extfs */
-#define MAXCOLS		30
-
-static char *columns [MAXCOLS];	/* Points to the string in column n */
-static int   column_ptr [MAXCOLS]; /* Index from 0 to the starting positions of the columns */
-
-int
-vfs_split_text (char *p)
-{
-    char *original = p;
-    int  numcols;
-
-    memset (columns, 0, sizeof (columns));
-
-    for (numcols = 0; *p && numcols < MAXCOLS; numcols++){
-	while (*p == ' ' || *p == '\r' || *p == '\n'){
-	    *p = 0;
-	    p++;
-	}
-	columns [numcols] = p;
-	column_ptr [numcols] = p - original;
-	while (*p && *p != ' ' && *p != '\r' && *p != '\n')
-	    p++;
-    }
-    return numcols;
-}
-
-static int
-is_num (int idx)
-{
-    char *column = columns[idx];
-
-    if (!column || column[0] < '0' || column[0] > '9')
-	return 0;
-
-    return 1;
-}
-
-/* Return 1 for MM-DD-YY and MM-DD-YYYY */
-static int
-is_dos_date (const char *str)
-{
-    int len;
-
-    if (!str)
-	return 0;
-
-    len = strlen (str);
-    if (len != 8 && len != 10)
-	return 0;
-
-    if (str[2] != str[5])
-	return 0;
-
-    if (!strchr ("\\-/", (int) str[2]))
-	return 0;
-
-    return 1;
-}
-
-static int
-is_week (const char *str, struct tm *tim)
-{
-    static const char *week = "SunMonTueWedThuFriSat";
-    char *pos;
-
-    if (!str)
-	return 0;
-
-    if ((pos = strstr (week, str)) != NULL) {
-	if (tim != NULL)
-	    tim->tm_wday = (pos - week) / 3;
-	return 1;
-    }
-    return 0;
-}
-
-static int
-is_month (const char *str, struct tm *tim)
-{
-    static const char *month = "JanFebMarAprMayJunJulAugSepOctNovDec";
-    char *pos;
-
-    if (!str)
-	return 0;
-
-    if ((pos = strstr (month, str)) != NULL) {
-	if (tim != NULL)
-	    tim->tm_mon = (pos - month) / 3;
-	return 1;
-    }
-    return 0;
-}
-
-/*
- * Check for possible locale's abbreviated month name (Jan..Dec).
- * Any 3 bytes long string without digit and control characters.
- * isalpha() is locale specific, so it cannot be used if current
- * locale is "C" and ftp server use Cyrillic.
- * TODO: Punctuation characters also cannot be part of month name.
- * NB: It is assumed there are no whitespaces in month.
- */
-static int
-is_localized_month (const unsigned char *month)
-{
-    int i = 0;
-    while ((i < 3) && *month && !isdigit (*month) && !iscntrl (*month)) {
-	i++;
-	month++;
-    }
-    return ((i == 3) && (*month == 0));
-}
-
-static int
-is_time (const char *str, struct tm *tim)
-{
-    char *p, *p2;
-
-    if (!str)
-	return 0;
-
-    if ((p = strchr (str, ':')) && (p2 = strrchr (str, ':'))) {
-	if (p != p2) {
-	    if (sscanf
-		(str, "%2d:%2d:%2d", &tim->tm_hour, &tim->tm_min,
-		 &tim->tm_sec) != 3)
-		return 0;
-	} else {
-	    if (sscanf (str, "%2d:%2d", &tim->tm_hour, &tim->tm_min) != 2)
-		return 0;
-	}
-    } else
-	return 0;
-
-    return 1;
-}
-
-static int is_year (char *str, struct tm *tim)
-{
-    long year;
-
-    if (!str)
-	return 0;
-
-    if (strchr (str, ':'))
-	return 0;
-
-    if (strlen (str) != 4)
-	return 0;
-
-    if (sscanf (str, "%ld", &year) != 1)
-	return 0;
-
-    if (year < 1900 || year > 3000)
-	return 0;
-
-    tim->tm_year = (int) (year - 1900);
-
-    return 1;
-}
-
-/*
- * FIXME: this is broken. Consider following entry:
- * -rwx------   1 root     root            1 Aug 31 10:04 2904 1234
- * where "2904 1234" is filename. Well, this code decodes it as year :-(.
- */
-
-int
-vfs_parse_filetype (char c)
-{
-    switch (c) {
-	case 'd': return S_IFDIR;
-	case 'b': return S_IFBLK;
-	case 'c': return S_IFCHR;
-	case 'l': return S_IFLNK;
-	case 's': /* Socket */
-#ifdef S_IFSOCK
-		return S_IFSOCK;
-#else
-		/* If not supported, we fall through to IFIFO */
-		return S_IFIFO;
-#endif
-	case 'D': /* Solaris door */
-#ifdef S_IFDOOR
-		return S_IFDOOR;
-#else
-		return S_IFIFO;
-#endif
-	case 'p': return S_IFIFO;
-	case 'm': case 'n':		/* Don't know what these are :-) */
-	case '-': case '?': return S_IFREG;
-	default: return -1;
-    }
-}
-
-int vfs_parse_filemode (const char *p)
-{	/* converts rw-rw-rw- into 0666 */
-    int res = 0;
-    switch (*(p++)){
-	case 'r': res |= 0400; break;
-	case '-': break;
-	default: return -1;
-    }
-    switch (*(p++)){
-	case 'w': res |= 0200; break;
-	case '-': break;
-	default: return -1;
-    }
-    switch (*(p++)){
-	case 'x': res |= 0100; break;
-	case 's': res |= 0100 | S_ISUID; break;
-	case 'S': res |= S_ISUID; break;
-	case '-': break;
-	default: return -1;
-    }
-    switch (*(p++)){
-	case 'r': res |= 0040; break;
-	case '-': break;
-	default: return -1;
-    }
-    switch (*(p++)){
-	case 'w': res |= 0020; break;
-	case '-': break;
-	default: return -1;
-    }
-    switch (*(p++)){
-	case 'x': res |= 0010; break;
-	case 's': res |= 0010 | S_ISGID; break;
-        case 'l': /* Solaris produces these */
-	case 'S': res |= S_ISGID; break;
-	case '-': break;
-	default: return -1;
-    }
-    switch (*(p++)){
-	case 'r': res |= 0004; break;
-	case '-': break;
-	default: return -1;
-    }
-    switch (*(p++)){
-	case 'w': res |= 0002; break;
-	case '-': break;
-	default: return -1;
-    }
-    switch (*(p++)){
-	case 'x': res |= 0001; break;
-	case 't': res |= 0001 | S_ISVTX; break;
-	case 'T': res |= S_ISVTX; break;
-	case '-': break;
-	default: return -1;
-    }
-    return res;
-}
-
-/* This function parses from idx in the columns[] array */
-int
-vfs_parse_filedate (int idx, time_t *t)
-{
-    char *p;
-    struct tm tim;
-    int d[3];
-    int got_year = 0;
-    int l10n = 0;		/* Locale's abbreviated month name */
-
-    /* Let's setup default time values */
-    tim.tm_year = current_year;
-    tim.tm_mon = current_mon;
-    tim.tm_mday = current_mday;
-    tim.tm_hour = 0;
-    tim.tm_min = 0;
-    tim.tm_sec = 0;
-    tim.tm_isdst = -1;		/* Let mktime() try to guess correct dst offset */
-
-    p = columns[idx++];
-
-    /* We eat weekday name in case of extfs */
-    if (is_week (p, &tim))
-	p = columns[idx++];
-
-    /* Month name */
-    if (is_month (p, &tim)) {
-	/* And we expect, it followed by day number */
-	if (is_num (idx))
-	    tim.tm_mday = (int) atol (columns[idx++]);
-	else
-	    return 0;		/* No day */
-
-    } else {
-	/* We usually expect:
-	   Mon DD hh:mm
-	   Mon DD  YYYY
-	   But in case of extfs we allow these date formats:
-	   Mon DD YYYY hh:mm
-	   Mon DD hh:mm YYYY
-	   Wek Mon DD hh:mm:ss YYYY
-	   MM-DD-YY hh:mm
-	   where Mon is Jan-Dec, DD, MM, YY two digit day, month, year,
-	   YYYY four digit year, hh, mm, ss two digit hour, minute or second. */
-
-	/* Special case with MM-DD-YY or MM-DD-YYYY */
-	if (is_dos_date (p)) {
-	    p[2] = p[5] = '-';
-
-	    if (sscanf (p, "%2d-%2d-%d", &d[0], &d[1], &d[2]) == 3) {
-		/* Months are zero based */
-		if (d[0] > 0)
-		    d[0]--;
-
-		if (d[2] > 1900) {
-		    d[2] -= 1900;
-		} else {
-		    /* Y2K madness */
-		    if (d[2] < 70)
-			d[2] += 100;
-		}
-
-		tim.tm_mon = d[0];
-		tim.tm_mday = d[1];
-		tim.tm_year = d[2];
-		got_year = 1;
-	    } else
-		return 0;	/* sscanf failed */
-	} else {
-	    /* Locale's abbreviated month name followed by day number */
-	    if (is_localized_month (p) && (is_num (idx++)))
-		l10n = 1;
-	    else
-		return 0;	/* unsupported format */
-	}
-    }
-
-    /* Here we expect to find time and/or year */
-
-    if (is_num (idx)) {
-	if (is_time (columns[idx], &tim)
-	    || (got_year = is_year (columns[idx], &tim))) {
-	    idx++;
-
-	    /* This is a special case for ctime() or Mon DD YYYY hh:mm */
-	    if (is_num (idx) && (columns[idx + 1][0])) {
-		if (got_year) {
-		    if (is_time (columns[idx], &tim))
-			idx++;	/* time also */
-		} else {
-		    if ((got_year = is_year (columns[idx], &tim)))
-			idx++;	/* year also */
-		}
-	    }
-	}			/* only time or date */
-    } else
-	return 0;		/* Nor time or date */
-
-    /*
-     * If the date is less than 6 months in the past, it is shown without year
-     * other dates in the past or future are shown with year but without time
-     * This does not check for years before 1900 ... I don't know, how
-     * to represent them at all
-     */
-    if (!got_year && current_mon < 6 && current_mon < tim.tm_mon
-	&& tim.tm_mon - current_mon >= 6)
-
-	tim.tm_year--;
-
-    if (l10n || (*t = mktime (&tim)) < 0)
-	*t = 0;
-    return idx;
-}
-
-int
-vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linkname)
-{
-    int idx, idx2, num_cols;
-    int i;
-    char *p_copy = NULL;
-    char *t = NULL;
-    const char *line = p;
-
-    if (strncmp (p, "total", 5) == 0)
-        return 0;
-
-    if ((i = vfs_parse_filetype(*(p++))) == -1)
-        goto error;
-
-    s->st_mode = i;
-    if (*p == ' ')	/* Notwell 4 */
-        p++;
-    if (*p == '['){
-	if (strlen (p) <= 8 || p [8] != ']')
-	    goto error;
-	/* Should parse here the Notwell permissions :) */
-	if (S_ISDIR (s->st_mode))
-	    s->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IXUSR | S_IXGRP | S_IXOTH);
-	else
-	    s->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
-	p += 9;
-    } else {
-	if ((i = vfs_parse_filemode(p)) == -1)
-	    goto error;
-        s->st_mode |= i;
-	p += 9;
-
-        /* This is for an extra ACL attribute (HP-UX) */
-        if (*p == '+')
-            p++;
-    }
-
-    p_copy = g_strdup(p);
-    num_cols = vfs_split_text (p_copy);
-
-    s->st_nlink = atol (columns [0]);
-    if (s->st_nlink <= 0)
-        goto error;
-
-    if (!is_num (1))
-	s->st_uid = vfs_finduid (columns [1]);
-    else
-        s->st_uid = (uid_t) atol (columns [1]);
-
-    /* Mhm, the ls -lg did not produce a group field */
-    for (idx = 3; idx <= 5; idx++)
-	if (is_month (columns[idx], NULL) || is_week (columns[idx], NULL)
-	    || is_dos_date (columns[idx]) || is_localized_month (columns[idx]))
-	    break;
-
-    if (idx == 6 || (idx == 5 && !S_ISCHR (s->st_mode) && !S_ISBLK (s->st_mode)))
-	goto error;
-
-    /* We don't have gid */
-    if (idx == 3 || (idx == 4 && (S_ISCHR(s->st_mode) || S_ISBLK (s->st_mode))))
-        idx2 = 2;
-    else {
-	/* We have gid field */
-	if (is_num (2))
-	    s->st_gid = (gid_t) atol (columns [2]);
-	else
-	    s->st_gid = vfs_findgid (columns [2]);
-	idx2 = 3;
-    }
-
-    /* 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], " %d", &min) != 1)
-	    goto error;
-
-#ifdef HAVE_STRUCT_STAT_ST_RDEV
-	s->st_rdev = ((maj & 0xff) << 8) | (min & 0xffff00ff);
-#endif
-	s->st_size = 0;
-
-    } else {
-	/* Common file size */
-	if (!is_num (idx2))
-	    goto error;
-
-	s->st_size = (size_t) atol (columns [idx2]);
-#ifdef HAVE_STRUCT_STAT_ST_RDEV
-	s->st_rdev = 0;
-#endif
-    }
-
-    idx = vfs_parse_filedate (idx, &s->st_mtime);
-    if (!idx)
-        goto error;
-    /* Use resulting time value */
-    s->st_atime = s->st_ctime = s->st_mtime;
-    /* s->st_dev and s->st_ino must be initialized by vfs_s_new_inode () */
-#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
-    s->st_blksize = 512;
-#endif
-#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
-    s->st_blocks = (s->st_size + 511) / 512;
-#endif
-
-    for (i = idx + 1, idx2 = 0; i < num_cols; i++ )
-	if (strcmp (columns [i], "->") == 0){
-	    idx2 = i;
-	    break;
-	}
-
-    if (((S_ISLNK (s->st_mode) ||
-        (num_cols == idx + 3 && s->st_nlink > 1))) /* Maybe a hardlink? (in extfs) */
-        && idx2){
-
-	if (filename){
-	    *filename = g_strndup (p + column_ptr [idx], column_ptr [idx2] - column_ptr [idx] - 1);
-	}
-	if (linkname){
-	    t = g_strdup (p + column_ptr [idx2+1]);
-	    *linkname = t;
-	}
-    } else {
-	/* Extract the filename from the string copy, not from the columns
-	 * this way we have a chance of entering hidden directories like ". ."
-	 */
-	if (filename){
-	    /*
-	     * filename = g_strdup (columns [idx++]);
-	     */
-
-	    t = g_strdup (p + column_ptr [idx]);
-	    *filename = t;
-	}
-	if (linkname)
-	    *linkname = NULL;
-    }
-
-    if (t) {
-	int p = strlen (t);
-	if ((--p > 0) && (t [p] == '\r' || t [p] == '\n'))
-	    t [p] = 0;
-	if ((--p > 0) && (t [p] == '\r' || t [p] == '\n'))
-	    t [p] = 0;
-    }
-
-    g_free (p_copy);
-    return 1;
-
-error:
-    {
-      static int errorcount = 0;
-
-      if (++errorcount < 5) {
-	message (1, _("Cannot parse:"), (p_copy && *p_copy) ? p_copy : line);
-      } else if (errorcount == 5)
-	message (1, _("Error"), _("More parsing errors will be ignored."));
-    }
-
-    g_free (p_copy);
-    return 0;
-}
-
-void
-vfs_die (const char *m)
-{
-    message (1, _("Internal error:"), m);
-    exit (1);
-}
-
-void
-vfs_print_stats (const char *fs_name, const char *action, const char *file_name, off_t have, off_t need)
-{
-    static char *i18n_percent_transf_format = NULL, *i18n_transf_format = NULL;
-
-    if (i18n_percent_transf_format == NULL) {
-	i18n_percent_transf_format = _("%s: %s: %s %3d%% (%lu bytes transferred)");
-	i18n_transf_format = _("%s: %s: %s %lu bytes transferred");
-    }
-
-    if (need) 
-	print_vfs_message (i18n_percent_transf_format, fs_name, action,
-			   file_name, (int)((double)have*100/need), (unsigned long) have);
-    else
-	print_vfs_message (i18n_transf_format,
-			   fs_name, action, file_name, (unsigned long) have);
-}
-
-char *
-vfs_get_password (char *msg)
-{
-    return (char *) input_dialog (msg, _("Password:"), INPUT_PASSWORD);
-}
-
 /*
 /*
  * Returns vfs path corresponding to given url. If passed string is
  * Returns vfs path corresponding to given url. If passed string is
  * not recognized as url, g_strdup(url) is returned.
  * not recognized as url, g_strdup(url) is returned.
@@ -1875,11 +1293,11 @@ char *
 vfs_translate_url (const char *url)
 vfs_translate_url (const char *url)
 {
 {
     if (strncmp (url, "ftp://", 6) == 0)
     if (strncmp (url, "ftp://", 6) == 0)
-        return  g_strconcat ("/#ftp:", url + 6, NULL);
+	return g_strconcat ("/#ftp:", url + 6, NULL);
     else if (strncmp (url, "a:", 2) == 0)
     else if (strncmp (url, "a:", 2) == 0)
-        return  g_strdup ("/#a");
+	return g_strdup ("/#a");
     else
     else
-        return g_strdup (url);
+	return g_strdup (url);
 }
 }
 
 
 
 

+ 0 - 14
vfs/vfs.h

@@ -187,17 +187,6 @@ caddr_t mc_mmap (caddr_t, size_t, int, int, int, off_t);
 int mc_munmap (caddr_t addr, size_t len);
 int mc_munmap (caddr_t addr, size_t len);
 #endif				/* HAVE_MMAP */
 #endif				/* HAVE_MMAP */
 
 
-/* These functions are meant for use by vfs modules */
-int vfs_parse_ls_lga (const char *p, struct stat *s, char **filename,
-		      char **linkname);
-int vfs_split_text (char *p);
-int vfs_parse_filetype (char c);
-int vfs_parse_filemode (const char *p);
-int vfs_parse_filedate (int idx, time_t * t);
-
-void vfs_die (const char *msg);
-char *vfs_get_password (char *msg);
-
 #ifdef WITH_SMBFS
 #ifdef WITH_SMBFS
 /* Interface for requesting SMB credentials.  */
 /* Interface for requesting SMB credentials.  */
 struct smb_authinfo {
 struct smb_authinfo {
@@ -214,9 +203,6 @@ struct smb_authinfo *vfs_smb_get_authinfo (const char *host,
 					   const char *user);
 					   const char *user);
 #endif				/* WITH_SMBFS */
 #endif				/* WITH_SMBFS */
 
 
-void vfs_print_stats (const char *fs_name, const char *action,
-		      const char *file_name, off_t have, off_t need);
-
 /* Operations for mc_ctl - on open file */
 /* Operations for mc_ctl - on open file */
 enum {
 enum {
     VFS_CTL_IS_NOTREADY
     VFS_CTL_IS_NOTREADY