From cbd0716730ad16dc64392ab0f966a08b3a1efd76 Mon Sep 17 00:00:00 2001 From: braga Date: Wed, 5 Apr 2006 01:36:57 +0000 Subject: [PATCH] Separated ftp listing parser module. It now supports Windows NT listings. Added unittests for the listing parser module. --- Makefile.am | 9 +- cache.h | 5 + configure.ac | 4 +- ftpfs-ls.c | 229 +++++++++++++++++++++++++++++++++++ ftpfs-ls.h | 11 ++ ftpfs.c | 248 ++------------------------------------ ftpfs.h | 55 +++++++++ tests/Makefile.am | 13 ++ tests/ftpfs-ls_unittest.c | 100 +++++++++++++++ tests/run_tests.sh | 17 +++ 10 files changed, 450 insertions(+), 241 deletions(-) create mode 100644 ftpfs-ls.c create mode 100644 ftpfs-ls.h create mode 100644 ftpfs.h create mode 100644 tests/Makefile.am create mode 100644 tests/ftpfs-ls_unittest.c create mode 100755 tests/run_tests.sh diff --git a/Makefile.am b/Makefile.am index ca6f458..f839db3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,18 @@ ## Process this file with automake to produce Makefile.in SUBDIRS = compat +DIST_SUBDIRS = $(SUBDIRS) tests + bin_PROGRAMS = curlftpfs -curlftpfs_SOURCES = ftpfs.c cache.c cache.h +curlftpfs_SOURCES = ftpfs.c ftpfs.h cache.c cache.h ftpfs-ls.c ftpfs-ls.h curlftpfs_CPPFLAGS = -DFUSE_USE_VERSION=25 if FUSE_OPT_COMPAT curlftpfs_LDADD = compat/libcompat.la endif + +check: test + +test: + @(cd tests; $(MAKE) test) diff --git a/cache.h b/cache.h index c523e0d..97053d7 100644 --- a/cache.h +++ b/cache.h @@ -1,3 +1,6 @@ +#ifndef __CURLFTPFS_CACHE_H__ +#define __CURLFTPFS_CACHE_H__ + /* Caching file system proxy Copyright (C) 2004 Miklos Szeredi @@ -27,3 +30,5 @@ int cache_parse_options(struct fuse_args *args); void cache_add_attr(const char *path, const struct stat *stbuf); void cache_add_dir(const char *path, char **dir); void cache_add_link(const char *path, const char *link, size_t size); + +#endif /* __CURLFTPFS_CACHE_H__ */ diff --git a/configure.ac b/configure.ac index d89a3ab..48f555d 100644 --- a/configure.ac +++ b/configure.ac @@ -20,9 +20,9 @@ LIBS="$GLIB_LIBS $FUSE_LIBS $LIBCURL" have_fuse_opt_parse=no AC_CHECK_FUNC([fuse_opt_parse], [have_fuse_opt_parse=yes]) if test "$have_fuse_opt_parse" = no; then - CFLAGS="$CFLAGS -Icompat" + CFLAGS="$CFLAGS -Icompat -I../compat" fi AM_CONDITIONAL(FUSE_OPT_COMPAT, test "$have_fuse_opt_parse" = no) -AC_CONFIG_FILES([Makefile compat/Makefile]) +AC_CONFIG_FILES([Makefile compat/Makefile tests/Makefile]) AC_OUTPUT diff --git a/ftpfs-ls.c b/ftpfs-ls.c new file mode 100644 index 0000000..6baa7c6 --- /dev/null +++ b/ftpfs-ls.c @@ -0,0 +1,229 @@ +#define _XOPEN_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ftpfs.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]; + 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)); + + res = sscanf(line, "%11s%*[ \t]%lu%*[ \t]%32s%*[ \t]%32s%*[ \t]%lu%*[ \t]%3s%*[ \t]%2s%*[ \t]%5s%*[ \t]%1023c", + mode, &nlink, user, group, &size, month, day, year, file); + if (res < 9) { + res = sscanf(line, "%11s%*[ \t]%32s%*[ \t]%32s%*[ \t]%lu%*[ \t]%3s%*[ \t]%2s%*[ \t]%5s%*[ \t]%1023c", + mode, user, group, &size, month, day, year, file); + if (res < 8) { + return 0; + } + } + + 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) & ~(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, ':')) + strptime(date, "%H:%M,%b,%d", &tm); + 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("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, "")) { + sbuf->st_mode |= S_IFDIR; + } else { + int nsize = strtol(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) & ~(ftpfs.blksize - 1)) >> 9; + } + } + + return 1; +} + +static int parse_dir_netware(const char *line, + struct stat *sbuf, + char *file, + char *link) { + return 0; +} + + +int parse_dir(const char* list, const char* dir, + const char* name, struct stat* sbuf, + char* linkbuf, int linklen, + fuse_cache_dirh_t h, fuse_cache_dirfil_t filler) { + 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; + 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; + + 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("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 (h && filler) { + DEBUG("filler: %s\n", file); + filler(h, file, &stat_buf); + } else { + DEBUG("cache_add_attr: %s\n", full_path); + cache_add_attr(full_path, &stat_buf); + } + + DEBUG("comparing %s %s\n", name, file); + if (name && !strcmp(name, file)) { + if (sbuf) *sbuf = stat_buf; + found = 1; + } + } + + free(line); + } + + free(file); + free(link); + + return !found; +} diff --git a/ftpfs-ls.h b/ftpfs-ls.h new file mode 100644 index 0000000..e7262a0 --- /dev/null +++ b/ftpfs-ls.h @@ -0,0 +1,11 @@ +#ifndef __CURLFTPFS_FTPFS_LS_H__ +#define __CURLFTPFS_FTPFS_LS_H__ + +#include "cache.h" + +int parse_dir(const char* list, const char* dir, + const char* name, struct stat* sbuf, + char* linkbuf, int linklen, + fuse_cache_dirh_t h, fuse_cache_dirfil_t filler); + +#endif /* __CURLFTPFS_FTPFS_LS_H__ */ diff --git a/ftpfs.c b/ftpfs.c index e588a01..0c29746 100644 --- a/ftpfs.c +++ b/ftpfs.c @@ -19,61 +19,16 @@ #include #include #include -#include -#include #include +#include "ftpfs-ls.h" #include "cache.h" +#include "ftpfs.h" #define CURLFTPFS_BAD_NOBODY 0x070f02 #define CURLFTPFS_BAD_SSL 0x070f03 -static char* MonthStrings[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - -struct ftpfs { - char* host; - char* mountpoint; - CURL* connection; - unsigned blksize; - GHashTable *filetab; - int verbose; - int debug; - int transform_symlinks; - int disable_epsv; - int tcp_nodelay; - int disable_eprt; - int connect_timeout; - int use_ssl; - int no_verify_hostname; - char* cert; - char* cert_type; - char* key; - char* key_type; - char* key_password; - char* engine; - char* cacert; - char* capath; - char* ciphers; - char* interface; - char* krb4; - char* proxy; - int proxytunnel; - int proxyanyauth; - int proxybasic; - int proxydigest; - int proxyntlm; - char* user; - char* proxy_user; - int ssl_version; - int ip_version; - char symlink_prefix[PATH_MAX+1]; - size_t symlink_prefix_len; - curl_version_info_data* curl_version; - int safe_nobody; -}; - -static struct ftpfs ftpfs; +struct ftpfs ftpfs; static char error_buf[CURL_ERROR_SIZE]; struct buffer { @@ -84,13 +39,6 @@ struct buffer { static void usage(const char* progname); static char* get_dir_path(const char* path, int strip); -static int parse_dir(struct buffer* buf, const char* dir, - const char* name, struct stat* sbuf, - char* linkbuf, int linklen, - fuse_cache_dirh_t h, fuse_cache_dirfil_t filler); - -#define DEBUG(args...) \ - do { if (ftpfs.debug) fprintf(stderr, args); } while(0) static inline void buf_init(struct buffer* buf, size_t size) { @@ -344,7 +292,6 @@ static size_t read_data(void *ptr, size_t size, size_t nmemb, void *data) { static int ftpfs_getdir(const char* path, fuse_cache_dirh_t h, fuse_cache_dirfil_t filler) { - int err; CURLcode curl_res; char* dir_path = get_dir_path(path, 0); @@ -360,7 +307,7 @@ static int ftpfs_getdir(const char* path, fuse_cache_dirh_t h, } buf_add_mem(&buf, "\0", 1); - err = parse_dir(&buf, dir_path + strlen(ftpfs.host) - 1, NULL, NULL, NULL, 0, h, filler); + parse_dir(buf.p, dir_path + strlen(ftpfs.host) - 1, NULL, NULL, NULL, 0, h, filler); free(dir_path); buf_free(&buf); @@ -386,183 +333,6 @@ static char* get_dir_path(const char* path, int strip) { return ret; } -static int parse_dir(struct buffer* buf, const char* dir, - const char* name, struct stat* sbuf, - char* linkbuf, int linklen, - fuse_cache_dirh_t h, fuse_cache_dirfil_t filler) { - char *start = buf->p; - char *end = buf->p; - char found = 0; - - 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; - return 0; - } - - while ((end = strchr(start, '\n')) != NULL) - { - char* line; - char* file; - struct stat stat_buf; - 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; - - if (!strncmp(line, "total", 5)) continue; - - int i = 0; - char *p; - if (line[i] == 'd') { - stat_buf.st_mode |= S_IFDIR; - } else if (line[i] == 'l') { - stat_buf.st_mode |= S_IFLNK; - } else { - stat_buf.st_mode |= S_IFREG; - } - for (i = 1; i < 10; ++i) { - if (line[i] != '-') { - stat_buf.st_mode |= 1 << (9 - i); - } - } - - // Advance whitespace - while (line[i] && isspace(line[i])) ++i; - - stat_buf.st_nlink = strtol(line+i, &p, 10); - i = p - line; - - // Advance whitespace - while (line[i] && isspace(line[i])) ++i; - // Advance username - while (line[i] && !isspace(line[i])) ++i; - // Advance whitespace - while (line[i] && isspace(line[i])) ++i; - // Advance group - while (line[i] && !isspace(line[i])) ++i; - - off_t size = strtol(line+i, &p, 10); - stat_buf.st_size = size; - if (ftpfs.blksize) { - stat_buf.st_blksize = ftpfs.blksize; - stat_buf.st_blocks = - ((size + ftpfs.blksize - 1) & ~(ftpfs.blksize - 1)) >> 9; - } - - i = p - line; - ++i; - - // Date - int month; - for (month = 0; month < 12; ++month) { - if (!strncmp(MonthStrings[month], line+i, 3)) break; - } - if (month < 12) { - i += 3; - int day = strtol(line+i, &p, 10); - if (p != line+i) { - i = p - line; - int year_or_hour = strtol(line+i, &p, 10); - struct tm current_time; - time_t now = time(NULL); - localtime_r(&now, ¤t_time); - if (p != line+i) { - i = p - line; - struct tm parsed_time; - memset(&parsed_time, 0, sizeof(parsed_time)); - if (*p == ':') { - // Hour - ++i; - int minute = strtol(line+i, &p, 10); - i = p - line; - parsed_time.tm_mday = day; - parsed_time.tm_mon = month; - parsed_time.tm_year = current_time.tm_year; - parsed_time.tm_hour = year_or_hour; - parsed_time.tm_min = minute; - stat_buf.st_atime = mktime(&parsed_time); - if (stat_buf.st_atime > now) { - parsed_time.tm_year--; - stat_buf.st_atime = mktime(&parsed_time); - } - stat_buf.st_mtime = stat_buf.st_atime; - stat_buf.st_ctime = stat_buf.st_atime; - } else { - // Year - parsed_time.tm_mday = day; - parsed_time.tm_mon = month; - parsed_time.tm_year = year_or_hour - 1900; - stat_buf.st_atime = mktime(&parsed_time); - stat_buf.st_mtime = stat_buf.st_atime; - stat_buf.st_ctime = stat_buf.st_atime; - } - } - } - } - - // Symbolic links - const char* link = strstr(line, " -> "); - - file = line + i + 1; - if (link) { - file = g_strndup(file, link - file); - } else { - file = g_strdup(file); - } - DEBUG("%s\n", file); - - char *full_path = g_strdup_printf("%s%s", dir, file); - - if (link) { - link += 4; - 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("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 (h && filler) { - DEBUG("filler: %s\n", file); - filler(h, file, &stat_buf); - } else { - DEBUG("cache_add_attr: %s\n", full_path); - cache_add_attr(full_path, &stat_buf); - } - - if (name && !strcmp(name, file)) { - if (sbuf) *sbuf = stat_buf; - found = 1; - } - - free(full_path); - free(line); - free(file); - } - - if (found) return 0; - return -ENOENT; -} - static int ftpfs_getattr(const char* path, struct stat* sbuf) { int err; CURLcode curl_res; @@ -582,11 +352,12 @@ static int ftpfs_getattr(const char* path, struct stat* sbuf) { char* name = strrchr(path, '/'); ++name; - err = parse_dir(&buf, dir_path + strlen(ftpfs.host) - 1, name, sbuf, NULL, 0, NULL, NULL); + err = parse_dir(buf.p, dir_path + strlen(ftpfs.host) - 1, name, sbuf, NULL, 0, NULL, NULL); free(dir_path); buf_free(&buf); - return err; + if (err) return -ENOENT; + return 0; } static int ftpfs_open(const char* path, struct fuse_file_info* fi) { @@ -880,11 +651,12 @@ static int ftpfs_readlink(const char *path, char *linkbuf, size_t size) { char* name = strrchr(path, '/'); ++name; - err = parse_dir(&buf, dir_path + strlen(ftpfs.host) - 1, name, NULL, linkbuf, size, NULL, NULL); + err = parse_dir(buf.p, dir_path + strlen(ftpfs.host) - 1, name, NULL, linkbuf, size, NULL, NULL); free(dir_path); buf_free(&buf); - return err; + if (err) return -ENOENT; + return 0; } #if FUSE_VERSION >= 25 diff --git a/ftpfs.h b/ftpfs.h new file mode 100644 index 0000000..f9b4304 --- /dev/null +++ b/ftpfs.h @@ -0,0 +1,55 @@ +#ifndef __CURLFTPFS_FTPFS_H__ +#define __CURLFTPFS_FTPFS_H__ + +#include +#include +#include + +struct ftpfs { + char* host; + char* mountpoint; + CURL* connection; + unsigned blksize; + GHashTable *filetab; + int verbose; + int debug; + int transform_symlinks; + int disable_epsv; + int tcp_nodelay; + int disable_eprt; + int connect_timeout; + int use_ssl; + int no_verify_hostname; + char* cert; + char* cert_type; + char* key; + char* key_type; + char* key_password; + char* engine; + char* cacert; + char* capath; + char* ciphers; + char* interface; + char* krb4; + char* proxy; + int proxytunnel; + int proxyanyauth; + int proxybasic; + int proxydigest; + int proxyntlm; + char* user; + char* proxy_user; + int ssl_version; + int ip_version; + char symlink_prefix[PATH_MAX+1]; + size_t symlink_prefix_len; + curl_version_info_data* curl_version; + int safe_nobody; +}; + +extern struct ftpfs ftpfs; + +#define DEBUG(args...) \ + do { if (ftpfs.debug) fprintf(stderr, args); } while(0) + +#endif /* __CURLFTPFS_FTPFS_H__ */ diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..5a1a164 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,13 @@ +EXTRA_DIST = run_tests.sh + +noinst_PROGRAMS = ftpfs-ls_unittest + +ftpfs_ls_unittest_SOURCES = ftpfs-ls_unittest.c ../ftpfs-ls.c ../ftpfs-ls.h ../cache.h ../cache.c +ftpfs_ls_unittest_CPPFLAGS = -DFUSE_USE_VERSION=25 + +if FUSE_OPT_COMPAT +ftpfs_ls_unittest_LDADD = ../compat/libcompat.la +endif + +test: all + @./run_tests.sh diff --git a/tests/ftpfs-ls_unittest.c b/tests/ftpfs-ls_unittest.c new file mode 100644 index 0000000..a652b38 --- /dev/null +++ b/tests/ftpfs-ls_unittest.c @@ -0,0 +1,100 @@ +#include "ftpfs.h" +#include "ftpfs-ls.h" +#include +#include +#include +#include + +struct ftpfs ftpfs; + +#define check(sbuf, dev, ino, mode, nlink, uid, gid, \ + rdev, size, blksize, blocks, date) \ + do { \ + struct tm tm; \ + time_t tt; \ + memset(&tm, 0, sizeof(tm)); \ + strptime(date, "%H:%M:%S %d/%m/%Y", &tm); \ + tt = mktime(&tm); \ + assert(sbuf.st_dev == dev); \ + assert(sbuf.st_ino == ino); \ + assert(sbuf.st_mode == mode); \ + assert(sbuf.st_nlink == nlink); \ + assert(sbuf.st_uid == uid); \ + assert(sbuf.st_gid == gid); \ + assert(sbuf.st_rdev == rdev); \ + assert(sbuf.st_size == size); \ + assert(sbuf.st_blksize == blksize); \ + assert(sbuf.st_blocks == blocks); \ + assert(sbuf.st_atime == tt); \ + assert(sbuf.st_ctime == tt); \ + assert(sbuf.st_mtime == tt); \ + } while (0); + +int main(int argc, char **argv) { + const char *list; + struct fuse_cache_operations dummy_oper; + struct stat sbuf; + int err; + struct fuse_args args = FUSE_ARGS_INIT(argc, argv); + char linkbuf[1024]; + char year[5]; + char date[20]; + time_t tt; + + tt = time(NULL); + strftime(year, 5, "%Y", gmtime(&tt)); + ftpfs.blksize = 4096; + + memset(&dummy_oper, 0, sizeof(dummy_oper)); + err = cache_parse_options(&args); + cache_init(&dummy_oper); + + list = "05-22-03 12:13PM chinese_pr\r\n"; + err = parse_dir(list, "/", "chinese_pr", &sbuf, NULL, 0, NULL, NULL); + assert(err == 0); + check(sbuf, 0, 0, S_IFDIR, 1, 0, 0, 0, 0, 0, 0, "12:13:00 22/05/2003"); + + err = parse_dir(list, "/", "hinese_pr", &sbuf, NULL, 0, NULL, NULL); + assert(err == 1); + + list = "05-14-03 02:49PM 40448 PR_AU13_CH.doc\r\n"; + err = parse_dir(list, "/", "PR_AU13_CH.doc", &sbuf, NULL, 0, NULL, NULL); + assert(err == 0); + check(sbuf, 0, 0, S_IFREG, 1, 0, 0, 0, 40448, 4096, 80, "14:49:00 14/05/2003"); + + list = "11-25-04 09:17AM 20075882 242_310_Condor_en_ok.pdf\r\n"; + err = parse_dir(list, "/", "242_310_Condor_en_ok.pdf", &sbuf, NULL, 0, NULL, NULL); + assert(err == 0); + check(sbuf, 0, 0, S_IFREG, 1, 0, 0, 0, 20075882, 4096, 39216, "09:17:00 25/11/2004"); + + list = "lrwxrwxrwx 1 1 17 Nov 24 2002 lg -> cidirb/documentos\r\n"; + err = parse_dir(list, "/", "lg", &sbuf, linkbuf, 1024, NULL, NULL); + assert(err == 0); + assert(!strcmp(linkbuf, "cidirb/documentos")); + check(sbuf, 0, 0, S_IFLNK|S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH, 1, 0, 0, 0, 17, 4096, 8, "00:00:00 24/11/2002"); + + list = "lrwxrwxrwx 1 1137 1100 14 Mar 12 2004 molbio -> Science/molbio\r\n"; + err = parse_dir(list, "/", "molbio", &sbuf, linkbuf, 1024, NULL, NULL); + assert(err == 0); + assert(!strcmp(linkbuf, "Science/molbio")); + check(sbuf, 0, 0, S_IFLNK|S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH, 1, 0, 0, 0, 14, 4096, 8, "00:00:00 12/03/2004"); + + list = "drwxr-xr-x 4 robson users 4096 Apr 3 15:50 tests\r\n"; + err = parse_dir(list, "/", "tests", &sbuf, NULL, 0, NULL, NULL); + assert(err == 0); + sprintf(date, "15:50:00 03/04/%s", year); + check(sbuf, 0, 0, S_IFDIR|S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, 4, 0, 0, 0, 4096, 4096, 8, date); + + list = "dr-xr-xr-x 2 root 512 Apr 8 1994 etc\r\n"; + err = parse_dir(list, "/", "etc", &sbuf, NULL, 0, NULL, NULL); + assert(err == 0); + check(sbuf, 0, 0, S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, 2, 0, 0, 0, 512, 4096, 8, "00:00:00 08/04/1994"); + + list = "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z\r\n"; + err = parse_dir(list, "/", "ls-lR.Z", &sbuf, NULL, 0, NULL, NULL); + assert(err == 0); + sprintf(date, "10:18:00 10/07/%s", year); + check(sbuf, 0, 0, S_IFREG, 1, 0, 0, 0, 1803128, 4096, 3528, date); + + return 0; +} diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100755 index 0000000..e470ef7 --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +echo "Running unittests:" + +failed=0 +for i in *_unittest; do + echo -n "$i... " + `./$i > /dev/null 2>&1` + if [ $? == 0 ]; then + echo "PASS" + else + echo "FAILED" + failed=1; + fi +done + +exit $failed