Support for mounting a remote directory (issue #7).

- fixed a bug in the file cache, it was attempting to set the mtime
    on symlinks
  - general code cleanup; moved some string functions to string_util.cpp


git-svn-id: http://s3fs.googlecode.com/svn/trunk@345 df820570-a93a-0410-bd06-b72b767a4274
This commit is contained in:
ben.lemasurier@gmail.com 2011-06-26 00:37:52 +00:00
parent 94d72bdaf3
commit 1597dfe659
6 changed files with 703 additions and 620 deletions

2
README
View File

@ -38,7 +38,7 @@ Usage:
In order to use s3fs, make sure you have the Access Key and the Secret Key handy. (refer to the wiki) In order to use s3fs, make sure you have the Access Key and the Secret Key handy. (refer to the wiki)
First, create a directory where to mount the S3 bucket you want to use. First, create a directory where to mount the S3 bucket you want to use.
Example (as root): mkdir -p /mnt/s3 Example (as root): mkdir -p /mnt/s3
Then run: s3fs mybucket /mnt/s3 Then run: s3fs mybucket[:path] /mnt/s3
This will mount your bucket to /mnt/s3. You can do a simple "ls -l /mnt/s3" to see the content of your bucket. This will mount your bucket to /mnt/s3. You can do a simple "ls -l /mnt/s3" to see the content of your bucket.

View File

@ -4,7 +4,7 @@ S3FS \- FUSE-based file system backed by Amazon S3
.SH SYNOPSIS .SH SYNOPSIS
.SS mounting .SS mounting
.TP .TP
\fBs3fs bucket mountpoint \fP [options] \fBs3fs bucket[:path] mountpoint \fP [options]
.SS unmounting .SS unmounting
.TP .TP
\fBumount mountpoint \fBumount mountpoint

File diff suppressed because it is too large Load Diff

View File

@ -29,18 +29,20 @@ time_t readwrite_timeout = 30;
int retries = 2; int retries = 2;
static std::string bucket; bool debug = 0;
bool foreground = 0;
bool service_validated = false;
static std::string host = "http://s3.amazonaws.com";
static std::string service_path = "/";
std::string bucket = "";
std::string mount_prefix = "";
static std::string mountpoint; static std::string mountpoint;
std::string program_name; std::string program_name;
static std::string AWSAccessKeyId; static std::string AWSAccessKeyId;
static std::string AWSSecretAccessKey; static std::string AWSSecretAccessKey;
static std::string host = "http://s3.amazonaws.com";
static mode_t root_mode = 0; static mode_t root_mode = 0;
static std::string service_path = "/";
static std::string passwd_file = ""; static std::string passwd_file = "";
bool debug = 0;
static bool utility_mode = 0; static bool utility_mode = 0;
bool foreground = 0;
unsigned long max_stat_cache_size = 10000; unsigned long max_stat_cache_size = 10000;
// if .size()==0 then local file cache is disabled // if .size()==0 then local file cache is disabled
@ -81,12 +83,12 @@ static pthread_mutex_t *mutex_buf = NULL;
static struct fuse_operations s3fs_oper; static struct fuse_operations s3fs_oper;
std::string urlEncode(const std::string &s);
std::string lookupMimeType(std::string); std::string lookupMimeType(std::string);
std::string initiate_multipart_upload(const char *path, off_t size, headers_t meta); std::string initiate_multipart_upload(const char *path, off_t size, headers_t meta);
std::string upload_part(const char *path, const char *source, int part_number, std::string upload_id); std::string upload_part(const char *path, const char *source, int part_number, std::string upload_id);
static int complete_multipart_upload(const char *path, std::string upload_id, std::vector <file_part> parts); static int complete_multipart_upload(const char *path, std::string upload_id, std::vector <file_part> parts);
std::string md5sum(int fd); std::string md5sum(int fd);
char *get_realpath(const char *path);
static int s3fs_getattr(const char *path, struct stat *stbuf); static int s3fs_getattr(const char *path, struct stat *stbuf);
static int s3fs_readlink(const char *path, char *buf, size_t size); static int s3fs_readlink(const char *path, char *buf, size_t size);
@ -112,6 +114,7 @@ static int s3fs_readdir(
const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi); const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi);
static int s3fs_access(const char *path, int mask); static int s3fs_access(const char *path, int mask);
static int s3fs_utimens(const char *path, const struct timespec ts[2]); static int s3fs_utimens(const char *path, const struct timespec ts[2]);
static int remote_mountpath_exists(const char *path);
static void* s3fs_init(struct fuse_conn_info *conn); static void* s3fs_init(struct fuse_conn_info *conn);
static void s3fs_destroy(void*); static void s3fs_destroy(void*);

View File

@ -17,14 +17,23 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include <string.h>
#include <syslog.h>
#include <sstream>
#include <string>
#include "string_util.h" #include "string_util.h"
using namespace std;
static const char hexAlphabet[] = "0123456789ABCDEF";
string lower(string s) { string lower(string s) {
// change each character of the string to lower case // change each character of the string to lower case
for (unsigned int i = 0; i < s.length(); i++) { for(unsigned int i = 0; i < s.length(); i++)
s[i] = tolower(s[i]); s[i] = tolower(s[i]);
}
return s; return s;
} }
@ -34,3 +43,86 @@ string IntToStr(int n) {
return result.str(); return result.str();
} }
string trim_left(const string &s, const string &t /* = SPACES */) {
string d(s);
return d.erase(0, s.find_first_not_of(t));
}
string trim_right(const string &s, const string &t /* = SPACES */) {
string d(s);
string::size_type i(d.find_last_not_of(t));
if (i == string::npos)
return "";
else
return d.erase(d.find_last_not_of(t) + 1);
}
string trim(const string &s, const string &t /* = SPACES */) {
string d(s);
return trim_left(trim_right(d, t), t);
}
/**
* urlEncode a fuse path,
* taking into special consideration "/",
* otherwise regular urlEncode.
*/
string urlEncode(const string &s) {
string result;
for (unsigned i = 0; i < s.length(); ++i) {
if (s[i] == '/') // Note- special case for fuse paths...
result += s[i];
else if (isalnum(s[i]))
result += s[i];
else if (s[i] == '.' || s[i] == '-' || s[i] == '*' || s[i] == '_')
result += s[i];
else if (s[i] == ' ')
result += '+';
else {
result += "%";
result += hexAlphabet[static_cast<unsigned char>(s[i]) / 16];
result += hexAlphabet[static_cast<unsigned char>(s[i]) % 16];
}
}
return result;
}
string prepare_url(const char* url) {
if(debug)
syslog(LOG_DEBUG, "URL is %s", url);
string uri;
string host;
string path;
string url_str = str(url);
string token = str("/" + bucket);
int bucket_pos = url_str.find(token);
int bucket_length = token.size();
int uri_length = 7;
if(!strncasecmp(url_str.c_str(), "https://", 8))
uri_length = 8;
uri = url_str.substr(0, uri_length);
host = bucket + "." + url_str.substr(uri_length, bucket_pos - uri_length).c_str();
path = url_str.substr((bucket_pos + bucket_length));
url_str = uri + host + path;
if(debug)
syslog(LOG_DEBUG, "URL changed is %s", url_str.c_str());
return str(url_str);
}
/**
* Returns the current date
* in a format suitable for a HTTP request header.
*/
string get_date() {
char buf[100];
time_t t = time(NULL);
strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
return buf;
}

View File

@ -4,40 +4,34 @@
/* /*
* A collection of string utilities for manipulating URLs and HTTP responses. * A collection of string utilities for manipulating URLs and HTTP responses.
*/ */
#include <sstream> #include <string.h>
#include <syslog.h>
#include <string> #include <string>
#include <sstream>
#define SPACES " \t\r\n" #define SPACES " \t\r\n"
using namespace std; template<typename T> std::string str(T value) {
std::stringstream s;
template<typename T> string str(T value) { s << value;
stringstream tmp; return s.str();
tmp << value;
return tmp.str();
} }
inline string trim_left(const string &s, const string &t = SPACES) { extern bool debug;
string d(s); extern bool foreground;
return d.erase(0, s.find_first_not_of(t)); extern bool service_validated;
}
inline string trim_right(const string &s, const string &t = SPACES) { extern std::string bucket;
string d(s);
string::size_type i(d.find_last_not_of(t));
if (i == string::npos)
return "";
else
return d.erase(d.find_last_not_of(t) + 1);
}
inline string trim(const string &s, const string &t = SPACES) { std::string trim_left(const std::string &s, const std::string &t = SPACES);
string d(s); std::string trim_right(const std::string &s, const std::string &t = SPACES);
return trim_left(trim_right(d, t), t); std::string trim(const std::string &s, const std::string &t = SPACES);
} std::string lower(std::string s);
std::string IntToStr(int);
string lower(string s); std::string get_date();
string IntToStr(int); std::string urlEncode(const std::string &s);
std::string prepare_url(const char* url);
#endif // S3FS_STRING_UTIL_H_ #endif // S3FS_STRING_UTIL_H_