[PATCH]: Locale's abbreviated month & vfs



Hello!

There are some localised ftp-servers in the wild, and their output with locale's abbreviated months confuses mc's parser.

Below is a small patch to treat such dates as Jan 1 1970.

--
Regards,
Andrew V. Samoilov
ChangeLog:

	* vfs.c (is_localized_month): New function for locale's
	abbreviated month name as any 3 bytes long string without digits
	and control characters.
	(vfs_parse_filedate): Fallback to is_localized_month() if
	is_month() and is_dos_date() fail and set date to Jan 1 1970.
	(vfs_parse_ls_lga): Use is_localized_month().

--- vfs/vfs.c	Sun Dec 29 09:30:35 2002
+++ vfs/vfs.c	Fri Jan 31 11:33:39 2003
@@ -1392,8 +1392,26 @@ is_month (char *str, struct tm *tim)
     return 0;
 }
 
+/*
+ * Locale's abbreviated month name (Jan..Dec).
+ * Any 3 bytes long string without digits and control characters.
+ * isalpha() is locale specific, so it cannot be used if current
+ * locale is "C" and ftp server use Cyrrilic.
+ * TODO: Punctuation characters also cannot be part of month name.
+ */
 static int
-is_time (char *str, struct tm *tim)
+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;
 
@@ -1540,6 +1558,7 @@ vfs_parse_filedate (int idx, time_t *t)
     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;
@@ -1599,8 +1618,13 @@ vfs_parse_filedate (int idx, time_t *t)
 		got_year = 1;
 	    } else
 		return 0;	/* sscanf failed */
-	} else
-	    return 0;		/* unsupported format */
+	} 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 */
@@ -1635,7 +1659,7 @@ vfs_parse_filedate (int idx, time_t *t)
 
 	tim.tm_year--;
 
-    if ((*t = mktime (&tim)) < 0)
+    if (l10n || (*t = mktime (&tim)) < 0)
 	*t = 0;
     return idx;
 }
@@ -1691,17 +1715,18 @@ vfs_parse_ls_lga (const char *p, struct 
         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]))
-            break;
+    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 */	
+    /* We don't have gid */
     if (idx == 3 || (idx == 4 && (S_ISCHR(s->st_mode) || S_ISBLK (s->st_mode))))
         idx2 = 2;
-    else { 
+    else {
 	/* We have gid field */
 	if (is_num (2))
 	    s->st_gid = (gid_t) atol (columns [2]);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]