123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /*
- FTP file system
- Copyright (C) 2006 Robson Braga Araujo <robsonbraga@gmail.com>
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
- */
- #ifndef __FreeBSD__
- #define _XOPEN_SOURCE 600
- #else
- #define _XOPEN_SOURCE
- #endif
- #include <time.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <glib.h>
- #include "ftpfs.h"
- #include "charset_utils.h"
- #include "ftpfs-ls.h"
- static int parse_dir_unix(const char *line,
- struct stat *sbuf,
- char *file,
- char *link) {
- char mode[12];
- long nlink = 1;
- char user[33];
- char group[33];
- unsigned long long size;
- char month[4];
- char day[3];
- char year[6];
- char date[20];
- struct tm tm;
- time_t tt;
- int res;
- memset(file, 0, sizeof(char)*1024);
- memset(&tm, 0, sizeof(tm));
- memset(&tt, 0, sizeof(tt));
- #define SPACES "%*[ \t]"
- res = sscanf(line,
- "%11s"
- "%lu" SPACES
- "%32s" SPACES
- "%32s" SPACES
- "%llu" SPACES
- "%3s" SPACES
- "%2s" SPACES
- "%5s" "%*c"
- "%1023c",
- mode, &nlink, user, group, &size, month, day, year, file);
- if (res < 9) {
- res = sscanf(line,
- "%11s"
- "%32s" SPACES
- "%32s" SPACES
- "%llu" SPACES
- "%3s" SPACES
- "%2s" SPACES
- "%5s" "%*c"
- "%1023c",
- mode, user, group, &size, month, day, year, file);
- if (res < 8) {
- return 0;
- }
- }
- #undef SPACES
- char *link_marker = strstr(file, " -> ");
- if (link_marker) {
- strcpy(link, link_marker + 4);
- *link_marker = '\0';
- }
- int i = 0;
- if (mode[i] == 'd') {
- sbuf->st_mode |= S_IFDIR;
- } else if (mode[i] == 'l') {
- sbuf->st_mode |= S_IFLNK;
- } else {
- sbuf->st_mode |= S_IFREG;
- }
- for (i = 1; i < 10; ++i) {
- if (mode[i] != '-') {
- sbuf->st_mode |= 1 << (9 - i);
- }
- }
- sbuf->st_nlink = nlink;
- sbuf->st_size = size;
- if (ftpfs.blksize) {
- sbuf->st_blksize = ftpfs.blksize;
- sbuf->st_blocks =
- ((size + ftpfs.blksize - 1) & ~((unsigned long long) ftpfs.blksize - 1)) >> 9;
- }
- sprintf(date,"%s,%s,%s", year, month, day);
- tt = time(NULL);
- gmtime_r(&tt, &tm);
- tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
- if(strchr(year, ':')) {
- int cur_mon = tm.tm_mon; // save current month
- strptime(date, "%H:%M,%b,%d", &tm);
- // Unix systems omit the year for the last six months
- if (cur_mon + 5 < tm.tm_mon) { // month from last year
- DEBUG(2, "correct year: cur_mon: %d, file_mon: %d\n", cur_mon, tm.tm_mon);
- tm.tm_year--; // correct the year
- }
- } else {
- strptime(date, "%Y,%b,%d", &tm);
- }
- sbuf->st_atime = sbuf->st_ctime = sbuf->st_mtime = mktime(&tm);
- return 1;
- }
- static int parse_dir_win(const char *line,
- struct stat *sbuf,
- char *file,
- char *link) {
- char date[9];
- char hour[8];
- char size[33];
- struct tm tm;
- time_t tt;
- int res;
- (void)link;
- memset(file, 0, sizeof(char)*1024);
- memset(&tm, 0, sizeof(tm));
- memset(&tt, 0, sizeof(tt));
- res = sscanf(line, "%8s%*[ \t]%7s%*[ \t]%32s%*[ \t]%1023c",
- date, hour, size, file);
- if (res < 4) {
- return 0;
- }
- DEBUG(2, "date: %s hour: %s size: %s file: %s\n", date, hour, size, file);
- tt = time(NULL);
- gmtime_r(&tt, &tm);
- tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
- strptime(date, "%m-%d-%y", &tm);
- strptime(hour, "%I:%M%p", &tm);
- sbuf->st_atime = sbuf->st_ctime = sbuf->st_mtime = mktime(&tm);
- sbuf->st_nlink = 1;
- if (!strcmp(size, "<DIR>")) {
- sbuf->st_mode |= S_IFDIR;
- } else {
- unsigned long long nsize = strtoull(size, NULL, 0);
- sbuf->st_mode |= S_IFREG;
- sbuf->st_size = nsize;
- if (ftpfs.blksize) {
- sbuf->st_blksize = ftpfs.blksize;
- sbuf->st_blocks =
- ((nsize + ftpfs.blksize - 1) & ~((unsigned long long) ftpfs.blksize - 1)) >> 9;
- }
- }
- return 1;
- }
- static int parse_dir_netware(const char *line,
- struct stat *sbuf,
- char *file,
- char *link) {
- (void) line;
- (void) sbuf;
- (void) file;
- (void) link;
- return 0;
- }
- int parse_dir(const char* list, const char* dir,
- const char* name, struct stat* sbuf,
- char* linkbuf, int linklen,
- off_t h, fuse_fill_dir_t filler, void *fuse_buf) {
- (void) h;
- char *file;
- char *link;
- const char *start = list;
- const char *end = list;
- char found = 0;
- struct stat stat_buf;
- if (sbuf) memset(sbuf, 0, sizeof(struct stat));
- if (name && sbuf && name[0] == '\0') {
- sbuf->st_mode |= S_IFDIR;
- sbuf->st_mode |= 0755;
- sbuf->st_size = 1024;
- sbuf->st_nlink = 1;
- return 0;
- }
- file = (char *)malloc(1024*sizeof(char));
- link = (char *)malloc(1024*sizeof(char));
- while ((end = strchr(start, '\n')) != NULL) {
- char* line;
- memset(&stat_buf, 0, sizeof(stat_buf));
- if (end > start && *(end-1) == '\r') end--;
- line = (char*)malloc(end - start + 1);
- strncpy(line, start, end - start);
- line[end - start] = '\0';
- start = *end == '\r' ? end + 2 : end + 1;
- stat_buf.st_uid = getuid();
- stat_buf.st_gid = getgid();
- if (ftpfs.codepage) {
- convert_charsets(ftpfs.codepage, ftpfs.iocharset, &line);
- }
- file[0] = link[0] = '\0';
- int res = parse_dir_unix(line, &stat_buf, file, link) ||
- parse_dir_win(line, &stat_buf, file, link) ||
- parse_dir_netware(line, &stat_buf, file, link);
- if (res) {
- char *full_path = g_strdup_printf("%s%s", dir, file);
- if (link[0]) {
- char *reallink;
- if (link[0] == '/' && ftpfs.symlink_prefix_len) {
- reallink = g_strdup_printf("%s%s", ftpfs.symlink_prefix, link);
- } else {
- reallink = g_strdup(link);
- }
- int linksize = strlen(reallink);
- cache_add_link(full_path, reallink, linksize+1);
- DEBUG(1, "cache_add_link: %s %s\n", full_path, reallink);
- if (linkbuf && linklen) {
- if (linksize > linklen) linksize = linklen - 1;
- strncpy(linkbuf, reallink, linksize);
- linkbuf[linksize] = '\0';
- }
- free(reallink);
- }
- if (filler) {
- filler(fuse_buf, file, &stat_buf, 0, 0);
- }
- if (name && !strcmp(name, file)) {
- if (sbuf) *sbuf = stat_buf;
- found = 1;
- }
- free(full_path);
- }
- free(line);
- }
- free(file);
- free(link);
- return !found;
- }
|