#include <stdlib.h>
#include <dirent.h>
#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include "s3access.h"
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)
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;
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)
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;
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
#include "fcgiapp.h"
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)
}
+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)
{
}
-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");
}
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);
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", ""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");