From 4320680bfc8a6d72adc946bfb04ad523ced11d15 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 12 Jun 2009 16:50:59 -0700 Subject: [PATCH] s3: return objects mtime --- src/s3/s3access.h | 11 +++++++++-- src/s3/s3fs.cc | 36 +++++++++++++++++++++++++++------- src/s3/s3gw.cc | 50 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 74 insertions(+), 23 deletions(-) diff --git a/src/s3/s3access.h b/src/s3/s3access.h index ca39d45770923..3d55929346904 100644 --- a/src/s3/s3access.h +++ b/src/s3/s3access.h @@ -1,14 +1,21 @@ #ifndef __S3ACCESS_H #define __S3ACCESS_H +#include #include #include typedef void *S3AccessHandle; +struct S3ObjEnt { + std::string name; + size_t size; + time_t mtime; +}; + int list_buckets_init(std::string& id, S3AccessHandle *handle); -int list_buckets_next(std::string& id, char *buf, int size, S3AccessHandle *handle); +int list_buckets_next(std::string& id, S3ObjEnt& obj, S3AccessHandle *handle); -int list_objects(std::string& id, std::string& bucket, int max, std::string& prefix, std::string& marker, std::vector& result); +int list_objects(std::string& id, std::string& bucket, int max, std::string& prefix, std::string& marker, std::vector& result); #endif diff --git a/src/s3/s3fs.cc b/src/s3/s3fs.cc index 82047572d000e..2d7671d9865c3 100644 --- a/src/s3/s3fs.cc +++ b/src/s3/s3fs.cc @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include #include "s3access.h" @@ -16,9 +19,11 @@ struct s3fs_state { DIR *dir; }; +#define DIR_NAME "/tmp/s3" + int list_buckets_init(string& id, S3AccessHandle *handle) { - DIR *dir = opendir("/tmp/s3"); + DIR *dir = opendir(DIR_NAME); struct s3fs_state *state; if (!dir) @@ -35,10 +40,11 @@ int list_buckets_init(string& id, S3AccessHandle *handle) return 0; } -int list_buckets_next(string& id, char *buf, int size, S3AccessHandle *handle) +int list_buckets_next(string& id, S3ObjEnt& obj, S3AccessHandle *handle) { struct s3fs_state *state; struct dirent *dirent; +#define BUF_SIZE 512 if (!handle) return -EINVAL; @@ -58,18 +64,25 @@ int list_buckets_next(string& id, char *buf, int size, S3AccessHandle *handle) if (dirent->d_name[0] == '.') continue; - snprintf(buf, size, "%s", dirent->d_name); + obj.name = dirent->d_name; + + char buf[BUF_SIZE]; + struct stat statbuf; + snprintf(buf, BUF_SIZE, "%s/%s", DIR_NAME, obj.name.c_str()); + if (stat(buf, &statbuf) < 0) + continue; + obj.mtime = statbuf.st_mtime; + obj.size = statbuf.st_size; return 0; } } -int list_objects(string& id, string& bucket, int max, string& prefix, string& marker, vector& result) +int list_objects(string& id, string& bucket, int max, string& prefix, string& marker, vector& result) { map dir_map; -#define BUF_SIZE 512 char path[BUF_SIZE]; - snprintf(path, BUF_SIZE, "/tmp/s3/%s", bucket.c_str()); + snprintf(path, BUF_SIZE, "%s/%s", DIR_NAME, bucket.c_str()); DIR *dir = opendir(path); if (!dir) @@ -106,7 +119,16 @@ int list_objects(string& id, string& bucket, int max, string& prefix, string& ma result.clear(); int i; for (i=0; ifirst); + S3ObjEnt obj; + char buf[BUF_SIZE]; + struct stat statbuf; + obj.name = iter->first; + snprintf(buf, BUF_SIZE, "%s/%s", path, obj.name.c_str()); + if (stat(buf, &statbuf) < 0) + continue; + obj.mtime = statbuf.st_mtime; + obj.size = statbuf.st_size; + result.push_back(obj); } return i; diff --git a/src/s3/s3gw.cc b/src/s3/s3gw.cc index 293e1a8fe189e..c860c9050fb4c 100644 --- a/src/s3/s3gw.cc +++ b/src/s3/s3gw.cc @@ -1,6 +1,7 @@ #include #include #include +#include #include "fcgiapp.h" @@ -134,9 +135,18 @@ static void close_section(struct req_state *s, const char *name) FCGX_FPrintF(s->out, "%*s\n", s->indent, "", name); } -static void dump_value(struct req_state *s, const char *name, const char *val) +static void dump_value(struct req_state *s, const char *name, const char *fmt, ...) { - FCGX_FPrintF(s->out, "%*s<%s>%s\n", s->indent, "", name, val, name); +#define LARGE_SIZE 8192 + char buf[LARGE_SIZE]; + va_list ap; + + va_start(ap, fmt); + int n = vsnprintf(buf, LARGE_SIZE, fmt, ap); + va_end(ap); + if (n >= LARGE_SIZE) + return; + FCGX_FPrintF(s->out, "%*s<%s>%s\n", s->indent, "", name, buf, name); } static void dump_entry(struct req_state *s, const char *val) @@ -145,6 +155,19 @@ static void dump_entry(struct req_state *s, const char *val) } +static void dump_time(struct req_state *s, const char *name, time_t *t) +{ +#define TIME_BUF_SIZE 128 + char buf[TIME_BUF_SIZE]; + struct tm *tmp = localtime(t); + if (tmp == NULL) + return; + + if (strftime(buf, sizeof(buf), "%Y-%m-%dT%T.000Z", tmp) == 0) + return; + + dump_value(s, name, buf); +} static void dump_owner(struct req_state *s, const char *id, int id_size, const char *name) { @@ -174,11 +197,11 @@ static void list_all_buckets_end(struct req_state *s) } -static void dump_bucket(struct req_state *s, const char *name, const char *date) +static void dump_bucket(struct req_state *s, S3ObjEnt& obj) { open_section(s, "Bucket"); - dump_value(s, "Name", name); - dump_value(s, "CreationDate", date); + dump_value(s, "Name", obj.name.c_str()); + dump_time(s, "CreationDate", &obj.mtime); close_section(s, "Bucket"); } @@ -187,17 +210,16 @@ void do_list_buckets(struct req_state *s) string id = "0123456789ABCDEF"; S3AccessHandle handle; int r; -#define BUF_SIZE 256 - char buf[BUF_SIZE]; + S3ObjEnt obj; list_all_buckets_start(s); dump_owner(s, (const char *)id.c_str(), id.size(), "foobi"); r = list_buckets_init(id, &handle); open_section(s, "Buckets"); while (r >= 0) { - r = list_buckets_next(id, buf, BUF_SIZE, &handle); + r = list_buckets_next(id, obj, &handle); if (r < 0) continue; - dump_bucket(s, buf, "123123"); + dump_bucket(s, obj); } close_section(s, "Buckets"); list_all_buckets_end(s); @@ -255,16 +277,16 @@ void do_list_objects(struct req_state *s) if (!delimiter.empty()) dump_value(s, "Delimiter", delimiter.c_str()); - vector objs; + vector objs; int r = list_objects(id, bucket, max, prefix, marker, objs); if (r >= 0) { - vector::iterator iter; + vector::iterator iter; for (iter = objs.begin(); iter != objs.end(); ++iter) { open_section(s, "Contents"); - dump_value(s, "Key", iter->c_str()); - dump_value(s, "LastModified", "2006-01-01T12:00:00.000Z"); + dump_value(s, "Key", iter->name.c_str()); + dump_time(s, "LastModified", &iter->mtime); dump_value(s, "ETag", ""828ef3fdfa96f00ad9f27c383fc9ac7f""); - dump_value(s, "Size", "5"); + dump_value(s, "Size", "%lld", iter->size); dump_value(s, "StorageClass", "STANDARD"); dump_owner(s, (const char *)&id, sizeof(id), "foobi"); close_section(s, "Contents"); -- 2.39.5