示例#1
0
文件: parse_ls_vga.c 项目: inso/mc
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 expect:
           3 fields max or we'll see oddities with certain file names.
           So both year and time is not allowed.
           Mon DD hh:mm[:ss]
           Mon DD YYYY
           But in case of extfs we allow these date formats:
           MM-DD-YY hh:mm[:ss]
           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 or year */
    if (is_num (idx) && (is_time (columns[idx], &tim) || (got_year = is_year (columns[idx], &tim))))
        idx++;
    else
        return 0;               /* Neither time nor 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--;

    *t = mktime (&tim);
    if (l10n || (*t < 0))
        *t = 0;
    return idx;
}
示例#2
0
文件: parse_ls_vga.c 项目: inso/mc
gboolean
vfs_parse_ls_lga (const char *p, struct stat * s, char **filename, char **linkname,
                  size_t * num_spaces)
{
    int idx, idx2, num_cols;
    int i;
    char *p_copy = NULL;
    char *t = NULL;
    const char *line = p;
    size_t skipped;

    if (strncmp (p, "total", 5) == 0)
        return FALSE;

    if (!vfs_parse_filetype (p, &skipped, &s->st_mode))
        goto error;
    p += skipped;

    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
    {
        size_t lc_skipped;
        mode_t perms;

        if (!vfs_parse_fileperms (p, &lc_skipped, &perms))
            goto error;
        p += lc_skipped;
        s->st_mode |= perms;
    }

    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;

        /* Corner case: there is no whitespace(s) between maj & min */
        if (!is_num (idx2) && idx2 == 2)
        {
            if (!is_num (++idx2) || sscanf (columns[idx2], " %d,%d", &maj, &min) != 2)
                goto error;
        }
        else
        {
            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 = makedev (maj, min);
#endif
        s->st_size = 0;

    }
    else
    {
        /* Common file size */
        if (!is_num (idx2))
            goto error;

        s->st_size = (off_t) g_ascii_strtoll (columns[idx2], NULL, 10);
#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

    if (num_spaces != NULL)
    {
        *num_spaces = column_ptr[idx] - column_ptr[idx - 1] - strlen (columns[idx - 1]);
        if (strcmp (columns[idx], "..") == 0)
            vfs_parce_ls_final_num_spaces = *num_spaces;
    }

    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 p2 = strlen (t);
        if ((--p2 > 0) && (t[p2] == '\r' || t[p2] == '\n'))
            t[p2] = 0;
        if ((--p2 > 0) && (t[p2] == '\r' || t[p2] == '\n'))
            t[p2] = 0;
    }

    g_free (p_copy);
    return TRUE;

  error:
    {
        static int errorcount = 0;

        if (++errorcount < 5)
        {
            message (D_ERROR, _("Cannot parse:"), "%s", (p_copy && *p_copy) ? p_copy : line);
        }
        else if (errorcount == 5)
            message (D_ERROR, MSG_ERROR, _("More parsing errors will be ignored."));
    }

    g_free (p_copy);
    return FALSE;
}
示例#3
0
static time_t
decode_broken_date (struct _date_token *tokens, int *tzone)
{
	gboolean got_wday, got_month, got_tzone;
	int hour, min, sec, offset, n;
	struct _date_token *token;
	struct tm tm;
	time_t time;

	memset ((void *) &tm, 0, sizeof (struct tm));
	got_wday = got_month = got_tzone = FALSE;
	offset = 0;

	token = tokens;
	while (token) {
		if (is_weekday (token) && !got_wday) {
			if ((n = get_wday (token->start, token->len)) != -1) {
				d(printf ("weekday; "));
				got_wday = TRUE;
				tm.tm_wday = n;
				goto next_token;
			}
		}

		if (is_month (token) && !got_month) {
			if ((n = get_month (token->start, token->len)) != -1) {
				d(printf ("month; "));
				got_month = TRUE;
				tm.tm_mon = n;
				goto next_token;
			}
		}

		if (is_time (token) && !tm.tm_hour && !tm.tm_min && !tm.tm_sec) {
			if (get_time (token->start, token->len, &hour, &min, &sec)) {
				d(printf ("time; "));
				tm.tm_hour = hour;
				tm.tm_min = min;
				tm.tm_sec = sec;
				goto next_token;
			}
		}

		if (is_tzone (token) && !got_tzone) {
			struct _date_token *t = token;

			if ((n = get_tzone (&t)) != -1) {
				d(printf ("tzone; "));
				got_tzone = TRUE;
				offset = n;
				goto next_token;
			}
		}

		if (is_numeric (token)) {
			if (token->len == 4 && !tm.tm_year) {
				if ((n = get_year (token->start, token->len)) != -1) {
					d(printf ("year; "));
					tm.tm_year = n - 1900;
					goto next_token;
				}
			} else {
				if (!got_month && !got_wday && token->next && is_numeric (token->next)) {
					d(printf ("mon; "));
					n = decode_int (token->start, token->len);
					got_month = TRUE;
					tm.tm_mon = n - 1;
					goto next_token;
				} else if (!tm.tm_mday && (n = get_mday (token->start, token->len)) != -1) {
					d(printf ("mday; "));
					tm.tm_mday = n;
					goto next_token;
				} else if (!tm.tm_year) {
					d(printf ("2-digit year; "));
					n = get_year (token->start, token->len);
					tm.tm_year = n - 1900;
					goto next_token;
				}
			}
		}

		d(printf ("???; "));

	next_token:

		token = token->next;
	}

	d(printf ("\n"));

	time = e_mktime_utc (&tm);

	/* time is now GMT of the time we want, but not offset by the timezone ... */

	/* this should convert the time to the GMT equiv time */
	time -= ((offset / 100) * 60 * 60) + (offset % 100) * 60;

	if (tzone)
		*tzone = offset;

	return time;
}