]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
s3: return objects mtime
authorYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 12 Jun 2009 23:50:59 +0000 (16:50 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 12 Jun 2009 23:50:59 +0000 (16:50 -0700)
src/s3/s3access.h
src/s3/s3fs.cc
src/s3/s3gw.cc

index ca39d45770923d2b85af67acb5b2c93a5cca2188..3d559293469043c80e5499b8102711e8583ac0a1 100644 (file)
@@ -1,14 +1,21 @@
 #ifndef __S3ACCESS_H
 #define __S3ACCESS_H
 
+#include <time.h>
 #include <string>
 #include <vector>
 
 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<std::string>& result);
+int list_objects(std::string& id, std::string& bucket, int max, std::string& prefix, std::string& marker, std::vector<S3ObjEnt>& result);
 
 #endif
index 82047572d000ec6bcde8294e4d3233540a76a8f8..2d7671d9865c3942ce9da67be5609bb423920edf 100644 (file)
@@ -3,6 +3,9 @@
 #include <stdlib.h>
 #include <dirent.h>
 #include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #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<string>& result)
+int list_objects(string& id, string& bucket, int max, string& prefix, string& marker, vector<S3ObjEnt>& result)
 {
   map<string, bool> 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; i<max && iter != dir_map.end(); i++, ++iter) {
-    result.push_back(iter->first);
+    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;
index 293e1a8fe189e4fd4341d03742db3e5482f5ba89..c860c9050fb4cd46bd7c1c41ec0e98ef9f785b8c 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdarg.h>
 
 #include "fcgiapp.h"
 
@@ -134,9 +135,18 @@ static void close_section(struct req_state *s, const char *name)
   FCGX_FPrintF(s->out, "%*s</%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</%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</%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<string> objs;
+  vector<S3ObjEnt> objs;
   int r = list_objects(id, bucket, max, prefix, marker, objs);
   if (r >= 0) {
-    vector<string>::iterator iter;
+    vector<S3ObjEnt>::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", "&quot;828ef3fdfa96f00ad9f27c383fc9ac7f&quot;");
-      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");