mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-11-05 12:27:53 +00:00
Code reformatting so it conforms to the Google C++ style guide. I chose that one because it's generally-accepted, but any style guide is okay with me. The important thing is to no longer have the random assortment of formatting that was there before.
git-svn-id: http://s3fs.googlecode.com/svn/trunk@211 df820570-a93a-0410-bd06-b72b767a4274
This commit is contained in:
parent
aebff8b8d2
commit
8e2652b233
@ -51,8 +51,7 @@ using namespace std;
|
|||||||
static long connect_timeout = 2;
|
static long connect_timeout = 2;
|
||||||
static time_t readwrite_timeout = 10;
|
static time_t readwrite_timeout = 10;
|
||||||
|
|
||||||
string
|
string urlEncode(const string &s);
|
||||||
urlEncode(const string &s);
|
|
||||||
|
|
||||||
#define VERIFY(s) if (true) { \
|
#define VERIFY(s) if (true) { \
|
||||||
int result = (s); \
|
int result = (s); \
|
||||||
@ -66,21 +65,22 @@ urlEncode(const string &s);
|
|||||||
}
|
}
|
||||||
|
|
||||||
class auto_fd {
|
class auto_fd {
|
||||||
int fd;
|
|
||||||
public:
|
public:
|
||||||
auto_fd(int fd): fd(fd) {
|
auto_fd(int fd): fd(fd) { }
|
||||||
}
|
|
||||||
~auto_fd() {
|
~auto_fd() {
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int get() {
|
int get() {
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
string
|
string str(T value) {
|
||||||
str(T value) {
|
|
||||||
stringstream tmp;
|
stringstream tmp;
|
||||||
tmp << value;
|
tmp << value;
|
||||||
return tmp.str();
|
return tmp.str();
|
||||||
@ -88,14 +88,12 @@ str(T value) {
|
|||||||
|
|
||||||
#define SPACES " \t\r\n"
|
#define SPACES " \t\r\n"
|
||||||
|
|
||||||
inline string trim_left (const string & s, const string & t = SPACES)
|
inline string trim_left(const string& s, const string& t = SPACES) {
|
||||||
{
|
|
||||||
string d(s);
|
string d(s);
|
||||||
return d.erase(0, s.find_first_not_of(t)) ;
|
return d.erase(0, s.find_first_not_of(t)) ;
|
||||||
} // end of trim_left
|
} // end of trim_left
|
||||||
|
|
||||||
inline string trim_right (const string & s, const string & t = SPACES)
|
inline string trim_right(const string &s, const string &t = SPACES) {
|
||||||
{
|
|
||||||
string d(s);
|
string d(s);
|
||||||
string::size_type i(d.find_last_not_of(t));
|
string::size_type i(d.find_last_not_of(t));
|
||||||
if (i == string::npos)
|
if (i == string::npos)
|
||||||
@ -104,14 +102,12 @@ inline string trim_right (const string & s, const string & t = SPACES)
|
|||||||
return d.erase(d.find_last_not_of(t) + 1);
|
return d.erase(d.find_last_not_of(t) + 1);
|
||||||
} // end of trim_right
|
} // end of trim_right
|
||||||
|
|
||||||
inline string trim (const string & s, const string & t = SPACES)
|
inline string trim(const string& s, const string& t = SPACES) {
|
||||||
{
|
|
||||||
string d(s);
|
string d(s);
|
||||||
return trim_left(trim_right(d, t), t);
|
return trim_left(trim_right(d, t), t);
|
||||||
} // end of trim
|
} // end of trim
|
||||||
|
|
||||||
class auto_lock {
|
class auto_lock {
|
||||||
pthread_mutex_t& lock;
|
|
||||||
public:
|
public:
|
||||||
auto_lock(pthread_mutex_t& lock) : lock(lock) {
|
auto_lock(pthread_mutex_t& lock) : lock(lock) {
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
@ -119,6 +115,9 @@ public:
|
|||||||
~auto_lock() {
|
~auto_lock() {
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_mutex_t& lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
static stack<CURL*> curl_handles;
|
static stack<CURL*> curl_handles;
|
||||||
@ -129,8 +128,8 @@ static map<CURL*, time_t> curl_times;
|
|||||||
static map<CURL*, progress_t> curl_progress;
|
static map<CURL*, progress_t> curl_progress;
|
||||||
|
|
||||||
// homegrown timeout mechanism
|
// homegrown timeout mechanism
|
||||||
static int
|
static int my_curl_progress(
|
||||||
my_curl_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) {
|
void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) {
|
||||||
CURL* curl = static_cast<CURL*>(clientp);
|
CURL* curl = static_cast<CURL*>(clientp);
|
||||||
|
|
||||||
time_t now = time(0);
|
time_t now = time(0);
|
||||||
@ -154,13 +153,12 @@ my_curl_progress(void *clientp, double dltotal, double dlnow, double ultotal, do
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURL*
|
static CURL* alloc_curl_handle() {
|
||||||
alloc_curl_handle() {
|
|
||||||
CURL* curl;
|
CURL* curl;
|
||||||
auto_lock lock(curl_handles_lock);
|
auto_lock lock(curl_handles_lock);
|
||||||
if (curl_handles.size() == 0)
|
if (curl_handles.size() == 0) {
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
else {
|
} else {
|
||||||
curl = curl_handles.top();
|
curl = curl_handles.top();
|
||||||
curl_handles.pop();
|
curl_handles.pop();
|
||||||
}
|
}
|
||||||
@ -183,8 +181,7 @@ alloc_curl_handle() {
|
|||||||
return curl;
|
return curl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void return_curl_handle(CURL* curl_handle) {
|
||||||
return_curl_handle(CURL* curl_handle) {
|
|
||||||
if (curl_handle != 0) {
|
if (curl_handle != 0) {
|
||||||
auto_lock lock(curl_handles_lock);
|
auto_lock lock(curl_handles_lock);
|
||||||
curl_handles.push(curl_handle);
|
curl_handles.push(curl_handle);
|
||||||
@ -194,10 +191,9 @@ return_curl_handle(CURL* curl_handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class auto_curl {
|
class auto_curl {
|
||||||
CURL* curl_handle;
|
|
||||||
public:
|
public:
|
||||||
auto_curl(): curl_handle(alloc_curl_handle()) {
|
auto_curl() : curl_handle(alloc_curl_handle()) { }
|
||||||
}
|
|
||||||
// auto_curl(CURL* curl): curl(curl) {
|
// auto_curl(CURL* curl): curl(curl) {
|
||||||
//// auto_lock lock(curl_handles_lock);
|
//// auto_lock lock(curl_handles_lock);
|
||||||
//// if (curl_handles.size() == 0)
|
//// if (curl_handles.size() == 0)
|
||||||
@ -218,9 +214,8 @@ public:
|
|||||||
// curl_handles.push(curl);
|
// curl_handles.push(curl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CURL* get() const {
|
|
||||||
return curl_handle;
|
CURL* get() const { return curl_handle; }
|
||||||
}
|
|
||||||
// CURL* release() {
|
// CURL* release() {
|
||||||
// CURL* tmp = curl;
|
// CURL* tmp = curl;
|
||||||
// curl = 0;
|
// curl = 0;
|
||||||
@ -233,15 +228,16 @@ public:
|
|||||||
// }
|
// }
|
||||||
// this->curl = curl;
|
// this->curl = curl;
|
||||||
// }
|
// }
|
||||||
operator CURL*() const {
|
operator CURL*() const { return curl_handle; }
|
||||||
return curl_handle;
|
|
||||||
}
|
private:
|
||||||
|
CURL* curl_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct curl_multi_remove_handle_functor {
|
struct curl_multi_remove_handle_functor {
|
||||||
CURLM* multi_handle;
|
CURLM* multi_handle;
|
||||||
curl_multi_remove_handle_functor(CURLM* multi_handle): multi_handle(multi_handle) {
|
curl_multi_remove_handle_functor(CURLM* multi_handle) : multi_handle(multi_handle) { }
|
||||||
}
|
|
||||||
void operator()(CURL* curl_handle) {
|
void operator()(CURL* curl_handle) {
|
||||||
curl_multi_remove_handle(multi_handle, curl_handle);
|
curl_multi_remove_handle(multi_handle, curl_handle);
|
||||||
return_curl_handle(curl_handle);
|
return_curl_handle(curl_handle);
|
||||||
@ -249,37 +245,38 @@ struct curl_multi_remove_handle_functor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class auto_curl_multi {
|
class auto_curl_multi {
|
||||||
CURLM* multi_handle;
|
|
||||||
vector<CURL*> curl_handles;
|
|
||||||
public:
|
public:
|
||||||
auto_curl_multi(): multi_handle(curl_multi_init()) {
|
auto_curl_multi(): multi_handle(curl_multi_init()) { }
|
||||||
}
|
|
||||||
~auto_curl_multi() {
|
~auto_curl_multi() {
|
||||||
curl_multi_cleanup(for_each(curl_handles.begin(), curl_handles.end(), curl_multi_remove_handle_functor(multi_handle)).multi_handle);
|
curl_multi_cleanup(for_each(curl_handles.begin(), curl_handles.end(),
|
||||||
}
|
curl_multi_remove_handle_functor(multi_handle)).multi_handle);
|
||||||
CURLM* get() const {
|
|
||||||
return multi_handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CURLM* get() const { return multi_handle; }
|
||||||
|
|
||||||
void add_curl(CURL* curl_handle) {
|
void add_curl(CURL* curl_handle) {
|
||||||
curl_handles.push_back(curl_handle);
|
curl_handles.push_back(curl_handle);
|
||||||
curl_multi_add_handle(multi_handle, curl_handle);
|
curl_multi_add_handle(multi_handle, curl_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CURLM* multi_handle;
|
||||||
|
vector<CURL*> curl_handles;
|
||||||
};
|
};
|
||||||
|
|
||||||
class auto_curl_slist {
|
class auto_curl_slist {
|
||||||
struct curl_slist* slist;
|
|
||||||
public:
|
public:
|
||||||
auto_curl_slist(): slist(0) {
|
auto_curl_slist() : slist(0) { }
|
||||||
}
|
~auto_curl_slist() { curl_slist_free_all(slist); }
|
||||||
~auto_curl_slist() {
|
|
||||||
curl_slist_free_all(slist);
|
struct curl_slist* get() const { return slist; }
|
||||||
}
|
|
||||||
struct curl_slist* get() const {
|
|
||||||
return slist;
|
|
||||||
}
|
|
||||||
void append(const string& s) {
|
void append(const string& s) {
|
||||||
slist = curl_slist_append(slist, s.c_str());
|
slist = curl_slist_append(slist, s.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct curl_slist* slist;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -oretries=2
|
// -oretries=2
|
||||||
@ -288,7 +285,6 @@ static int retries = 2;
|
|||||||
static string bucket;
|
static string bucket;
|
||||||
|
|
||||||
static string prepare_url(const char* url) {
|
static string prepare_url(const char* url) {
|
||||||
|
|
||||||
syslog(LOG_DEBUG, "URL is %s", url);
|
syslog(LOG_DEBUG, "URL is %s", url);
|
||||||
|
|
||||||
string url_str = str(url);
|
string url_str = str(url);
|
||||||
@ -300,7 +296,8 @@ static string prepare_url(const char* url){
|
|||||||
if(!strncasecmp(url_str.c_str(), "https://", 8)) {
|
if(!strncasecmp(url_str.c_str(), "https://", 8)) {
|
||||||
clipBy = 8;
|
clipBy = 8;
|
||||||
}
|
}
|
||||||
url_str = url_str.substr(0,clipBy) + bucket + "." + url_str.substr(clipBy,bucket_pos - clipBy) + url_str.substr((bucket_pos + bucket_size));
|
url_str = url_str.substr(0, clipBy) + bucket + "." + url_str.substr(clipBy, bucket_pos - clipBy)
|
||||||
|
+ url_str.substr((bucket_pos + bucket_size));
|
||||||
|
|
||||||
syslog(LOG_DEBUG, "URL changed is %s", url_str.c_str());
|
syslog(LOG_DEBUG, "URL changed is %s", url_str.c_str());
|
||||||
|
|
||||||
@ -310,23 +307,22 @@ static string prepare_url(const char* url){
|
|||||||
/**
|
/**
|
||||||
* @return fuse return code
|
* @return fuse return code
|
||||||
*/
|
*/
|
||||||
static int
|
static int my_curl_easy_perform(CURL* curl, FILE* f = 0) {
|
||||||
my_curl_easy_perform(CURL* curl, FILE* f = 0) {
|
|
||||||
char* url = new char[128];
|
char* url = new char[128];
|
||||||
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL , &url);
|
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL , &url);
|
||||||
syslog(LOG_DEBUG, "connecting to URL %s", url);
|
syslog(LOG_DEBUG, "connecting to URL %s", url);
|
||||||
|
|
||||||
// 1 attempt + retries...
|
// 1 attempt + retries...
|
||||||
int t = 1+retries;
|
int t = retries + 1;
|
||||||
while (t-- > 0) {
|
while (t-- > 0) {
|
||||||
if (f)
|
if (f)
|
||||||
rewind(f);
|
rewind(f);
|
||||||
CURLcode curlCode = curl_easy_perform(curl);
|
CURLcode curlCode = curl_easy_perform(curl);
|
||||||
if (curlCode == 0)
|
if (curlCode == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (curlCode == CURLE_OPERATION_TIMEDOUT)
|
if (curlCode == CURLE_OPERATION_TIMEDOUT) {
|
||||||
syslog(LOG_ERR, "###timeout");
|
syslog(LOG_ERR, "###timeout");
|
||||||
else if (curlCode == CURLE_HTTP_RETURNED_ERROR) {
|
} else if (curlCode == CURLE_HTTP_RETURNED_ERROR) {
|
||||||
long responseCode;
|
long responseCode;
|
||||||
if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode) != 0)
|
if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode) != 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@ -336,8 +332,9 @@ my_curl_easy_perform(CURL* curl, FILE* f = 0) {
|
|||||||
|
|
||||||
if (responseCode < 500)
|
if (responseCode < 500)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
} else
|
} else {
|
||||||
syslog(LOG_ERR, "###%s", curl_easy_strerror(curlCode));;
|
syslog(LOG_ERR, "###%s", curl_easy_strerror(curlCode));;
|
||||||
|
}
|
||||||
syslog(LOG_ERR, "###retrying...");
|
syslog(LOG_ERR, "###retrying...");
|
||||||
}
|
}
|
||||||
syslog(LOG_ERR, "###giving up");
|
syslog(LOG_ERR, "###giving up");
|
||||||
@ -371,8 +368,7 @@ static const char hexAlphabet[] = "0123456789ABCDEF";
|
|||||||
* taking into special consideration "/",
|
* taking into special consideration "/",
|
||||||
* otherwise regular urlEncode.
|
* otherwise regular urlEncode.
|
||||||
*/
|
*/
|
||||||
string
|
string urlEncode(const string &s) {
|
||||||
urlEncode(const string &s) {
|
|
||||||
string result;
|
string result;
|
||||||
for (unsigned i = 0; i < s.length(); ++i) {
|
for (unsigned i = 0; i < s.length(); ++i) {
|
||||||
if (s[i] == '/') // Note- special case for fuse paths...
|
if (s[i] == '/') // Note- special case for fuse paths...
|
||||||
@ -406,8 +402,7 @@ static const EVP_MD* evp_md = EVP_sha1();
|
|||||||
* Returns the current date
|
* Returns the current date
|
||||||
* in a format suitable for a HTTP request header.
|
* in a format suitable for a HTTP request header.
|
||||||
*/
|
*/
|
||||||
string
|
string get_date() {
|
||||||
get_date() {
|
|
||||||
char buf[100];
|
char buf[100];
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
|
strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
|
||||||
@ -422,8 +417,9 @@ get_date() {
|
|||||||
* @param date e.g., get_date()
|
* @param date e.g., get_date()
|
||||||
* @param resource e.g., "/pub"
|
* @param resource e.g., "/pub"
|
||||||
*/
|
*/
|
||||||
string
|
string calc_signature(
|
||||||
calc_signature(string method, string content_type, string date, curl_slist* headers, string resource) {
|
string method, string content_type, string date, curl_slist* headers, string resource) {
|
||||||
|
|
||||||
string Signature;
|
string Signature;
|
||||||
string StringToSign;
|
string StringToSign;
|
||||||
StringToSign += method + "\n";
|
StringToSign += method + "\n";
|
||||||
@ -468,17 +464,13 @@ calc_signature(string method, string content_type, string date, curl_slist* head
|
|||||||
}
|
}
|
||||||
|
|
||||||
// libcurl callback
|
// libcurl callback
|
||||||
static size_t
|
static size_t writeCallback(void* data, size_t blockSize, size_t numBlocks, void* userPtr) {
|
||||||
writeCallback(void* data, size_t blockSize, size_t numBlocks, void* userPtr) {
|
|
||||||
string* userString = static_cast<string*>(userPtr);
|
string* userString = static_cast<string*>(userPtr);
|
||||||
(*userString).append(reinterpret_cast<const char*>(data), blockSize*numBlocks);
|
(*userString).append(reinterpret_cast<const char*>(data), blockSize*numBlocks);
|
||||||
return blockSize * numBlocks;
|
return blockSize * numBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t header_callback(void *data,
|
static size_t header_callback(void *data, size_t blockSize, size_t numBlocks, void *userPtr) {
|
||||||
size_t blockSize,
|
|
||||||
size_t numBlocks,
|
|
||||||
void *userPtr) {
|
|
||||||
headers_t* headers = reinterpret_cast<headers_t*>(userPtr);
|
headers_t* headers = reinterpret_cast<headers_t*>(userPtr);
|
||||||
string header(reinterpret_cast<char*>(data), blockSize * numBlocks);
|
string header(reinterpret_cast<char*>(data), blockSize * numBlocks);
|
||||||
string key;
|
string key;
|
||||||
@ -492,22 +484,19 @@ static size_t header_callback(void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// safe variant of dirname
|
// safe variant of dirname
|
||||||
static string
|
static string mydirname(string path) {
|
||||||
mydirname(string path) {
|
|
||||||
// dirname clobbers path so let it operate on a tmp copy
|
// dirname clobbers path so let it operate on a tmp copy
|
||||||
return dirname(&path[0]);
|
return dirname(&path[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// safe variant of basename
|
// safe variant of basename
|
||||||
static string
|
static string mybasename(string path) {
|
||||||
mybasename(string path) {
|
|
||||||
// basename clobbers path so let it operate on a tmp copy
|
// basename clobbers path so let it operate on a tmp copy
|
||||||
return basename(&path[0]);
|
return basename(&path[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mkdir --parents
|
// mkdir --parents
|
||||||
static int
|
static int mkdirp(const string& path, mode_t mode) {
|
||||||
mkdirp(const string& path, mode_t mode) {
|
|
||||||
string base;
|
string base;
|
||||||
string component;
|
string component;
|
||||||
stringstream ss(path);
|
stringstream ss(path);
|
||||||
@ -525,8 +514,7 @@ mkdirp(const string& path, mode_t mode) {
|
|||||||
* @return fuse return code
|
* @return fuse return code
|
||||||
* TODO return pair<int, headers_t>?!?
|
* TODO return pair<int, headers_t>?!?
|
||||||
*/
|
*/
|
||||||
int
|
int get_headers(const char* path, headers_t& meta) {
|
||||||
get_headers(const char* path, headers_t& meta) {
|
|
||||||
|
|
||||||
string resource(urlEncode(service_path + bucket + path));
|
string resource(urlEncode(service_path + bucket + path));
|
||||||
string url(host + resource);
|
string url(host + resource);
|
||||||
@ -545,7 +533,8 @@ get_headers(const char* path, headers_t& meta) {
|
|||||||
string date = get_date();
|
string date = get_date();
|
||||||
headers.append("Date: " + date);
|
headers.append("Date: " + date);
|
||||||
headers.append("Content-Type: ");
|
headers.append("Content-Type: ");
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("HEAD", "", date, headers.get(), resource));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("HEAD", "", date, headers.get(), resource));
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
string my_url = prepare_url(url.c_str());
|
string my_url = prepare_url(url.c_str());
|
||||||
@ -572,8 +561,7 @@ get_headers(const char* path, headers_t& meta) {
|
|||||||
/**
|
/**
|
||||||
* get_local_fd
|
* get_local_fd
|
||||||
*/
|
*/
|
||||||
int
|
int get_local_fd(const char* path) {
|
||||||
get_local_fd(const char* path) {
|
|
||||||
string resource(urlEncode(service_path + bucket + path));
|
string resource(urlEncode(service_path + bucket + path));
|
||||||
string url(host + resource);
|
string url(host + resource);
|
||||||
|
|
||||||
@ -607,7 +595,8 @@ get_local_fd(const char* path) {
|
|||||||
|
|
||||||
char localMd5[2 * MD5_DIGEST_LENGTH+1];
|
char localMd5[2 * MD5_DIGEST_LENGTH+1];
|
||||||
sprintf(localMd5, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
sprintf(localMd5, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
md[0], md[1], md[2], md[3], md[4], md[5], md[6], md[7], md[8], md[9], md[10], md[11], md[12], md[13], md[14], md[15]);
|
md[0], md[1], md[2], md[3], md[4], md[5], md[6], md[7], md[8], md[9], md[10], md[11],
|
||||||
|
md[12], md[13], md[14], md[15]);
|
||||||
|
|
||||||
string remoteMd5(trim(responseHeaders["ETag"], "\""));
|
string remoteMd5(trim(responseHeaders["ETag"], "\""));
|
||||||
|
|
||||||
@ -655,7 +644,8 @@ get_local_fd(const char* path) {
|
|||||||
syslog(LOG_INFO, "LOCAL FD");
|
syslog(LOG_INFO, "LOCAL FD");
|
||||||
headers.append("Date: " + date);
|
headers.append("Date: " + date);
|
||||||
headers.append("Content-Type: ");
|
headers.append("Content-Type: ");
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("GET", "", date, headers.get(), resource));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("GET", "", date, headers.get(), resource));
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
cout << "downloading[path=" << path << "][fd=" << fd << "]" << endl;
|
cout << "downloading[path=" << path << "][fd=" << fd << "]" << endl;
|
||||||
@ -680,8 +670,7 @@ get_local_fd(const char* path) {
|
|||||||
* create or update s3 meta
|
* create or update s3 meta
|
||||||
* @return fuse return code
|
* @return fuse return code
|
||||||
*/
|
*/
|
||||||
static int
|
static int put_headers(const char* path, headers_t meta) {
|
||||||
put_headers(const char* path, headers_t meta) {
|
|
||||||
string resource = urlEncode(service_path + bucket + path);
|
string resource = urlEncode(service_path + bucket + path);
|
||||||
string url = host + resource;
|
string url = host + resource;
|
||||||
|
|
||||||
@ -721,7 +710,8 @@ put_headers(const char* path, headers_t meta) {
|
|||||||
headers.append("x-amz-storage-class:REDUCED_REDUNDANCY");
|
headers.append("x-amz-storage-class:REDUCED_REDUNDANCY");
|
||||||
}
|
}
|
||||||
|
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("PUT", ContentType, date, headers.get(), resource));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("PUT", ContentType, date, headers.get(), resource));
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
//###rewind(f);
|
//###rewind(f);
|
||||||
@ -741,8 +731,7 @@ put_headers(const char* path, headers_t meta) {
|
|||||||
* create or update s3 object
|
* create or update s3 object
|
||||||
* @return fuse return code
|
* @return fuse return code
|
||||||
*/
|
*/
|
||||||
static int
|
static int put_local_fd(const char* path, headers_t meta, int fd) {
|
||||||
put_local_fd(const char* path, headers_t meta, int fd) {
|
|
||||||
string resource = urlEncode(service_path + bucket + path);
|
string resource = urlEncode(service_path + bucket + path);
|
||||||
string url = host + resource;
|
string url = host + resource;
|
||||||
|
|
||||||
@ -789,7 +778,8 @@ put_local_fd(const char* path, headers_t meta, int fd) {
|
|||||||
headers.append("x-amz-storage-class:REDUCED_REDUNDANCY");
|
headers.append("x-amz-storage-class:REDUCED_REDUNDANCY");
|
||||||
}
|
}
|
||||||
|
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("PUT", ContentType, date, headers.get(), resource));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("PUT", ContentType, date, headers.get(), resource));
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
//###rewind(f);
|
//###rewind(f);
|
||||||
@ -805,8 +795,7 @@ put_local_fd(const char* path, headers_t meta, int fd) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_getattr(const char *path, struct stat *stbuf) {
|
||||||
s3fs_getattr(const char *path, struct stat *stbuf) {
|
|
||||||
cout << "getattr[path=" << path << "]" << endl;
|
cout << "getattr[path=" << path << "]" << endl;
|
||||||
memset(stbuf, 0, sizeof(struct stat));
|
memset(stbuf, 0, sizeof(struct stat));
|
||||||
if (strcmp(path, "/") == 0) {
|
if (strcmp(path, "/") == 0) {
|
||||||
@ -842,7 +831,8 @@ s3fs_getattr(const char *path, struct stat *stbuf) {
|
|||||||
string date = get_date();
|
string date = get_date();
|
||||||
headers.append("Date: " + date);
|
headers.append("Date: " + date);
|
||||||
headers.append("Content-Type: ");
|
headers.append("Content-Type: ");
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("HEAD", "", date, headers.get(), resource));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("HEAD", "", date, headers.get(), resource));
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
string my_url = prepare_url(url.c_str());
|
string my_url = prepare_url(url.c_str());
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, my_url.c_str());
|
curl_easy_setopt(curl, CURLOPT_URL, my_url.c_str());
|
||||||
@ -878,8 +868,7 @@ s3fs_getattr(const char *path, struct stat *stbuf) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_readlink(const char *path, char *buf, size_t size) {
|
||||||
s3fs_readlink(const char *path, char *buf, size_t size) {
|
|
||||||
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
--size; // reserve nil terminator
|
--size; // reserve nil terminator
|
||||||
@ -918,8 +907,7 @@ static mimes_t mimeTypes;
|
|||||||
* @param s e.g., "index.html"
|
* @param s e.g., "index.html"
|
||||||
* @return e.g., "text/html"
|
* @return e.g., "text/html"
|
||||||
*/
|
*/
|
||||||
string
|
string lookupMimeType(string s) {
|
||||||
lookupMimeType(string s) {
|
|
||||||
string result("application/octet-stream");
|
string result("application/octet-stream");
|
||||||
string::size_type last_pos = s.find_last_of('.');
|
string::size_type last_pos = s.find_last_of('.');
|
||||||
string::size_type first_pos = s.find_first_of('.');
|
string::size_type first_pos = s.find_first_of('.');
|
||||||
@ -975,8 +963,7 @@ lookupMimeType(string s) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_mknod(const char *path, mode_t mode, dev_t rdev) {
|
||||||
s3fs_mknod(const char *path, mode_t mode, dev_t rdev) {
|
|
||||||
// see man 2 mknod
|
// see man 2 mknod
|
||||||
// If pathname already exists, or is a symbolic link, this call fails with an EEXIST error.
|
// If pathname already exists, or is a symbolic link, this call fails with an EEXIST error.
|
||||||
cout << "mknod[path=" << path << "][mode=" << mode << "]" << endl;
|
cout << "mknod[path=" << path << "][mode=" << mode << "]" << endl;
|
||||||
@ -1001,7 +988,8 @@ s3fs_mknod(const char *path, mode_t mode, dev_t rdev) {
|
|||||||
headers.append("x-amz-meta-mode:" + str(mode));
|
headers.append("x-amz-meta-mode:" + str(mode));
|
||||||
headers.append("x-amz-meta-mtime:" + str(time(NULL)));
|
headers.append("x-amz-meta-mtime:" + str(time(NULL)));
|
||||||
headers.append("x-amz-meta-uid:" + str(getuid()));
|
headers.append("x-amz-meta-uid:" + str(getuid()));
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("PUT", contentType, date, headers.get(), resource));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("PUT", contentType, date, headers.get(), resource));
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
string my_url = prepare_url(url.c_str());
|
string my_url = prepare_url(url.c_str());
|
||||||
@ -1012,8 +1000,7 @@ s3fs_mknod(const char *path, mode_t mode, dev_t rdev) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_mkdir(const char *path, mode_t mode) {
|
||||||
s3fs_mkdir(const char *path, mode_t mode) {
|
|
||||||
cout << "mkdir[path=" << path << "][mode=" << mode << "]" << endl;
|
cout << "mkdir[path=" << path << "][mode=" << mode << "]" << endl;
|
||||||
|
|
||||||
string resource = urlEncode(service_path + bucket + path);
|
string resource = urlEncode(service_path + bucket + path);
|
||||||
@ -1035,7 +1022,8 @@ s3fs_mkdir(const char *path, mode_t mode) {
|
|||||||
headers.append("x-amz-meta-mode:" + str(mode));
|
headers.append("x-amz-meta-mode:" + str(mode));
|
||||||
headers.append("x-amz-meta-mtime:" + str(time(NULL)));
|
headers.append("x-amz-meta-mtime:" + str(time(NULL)));
|
||||||
headers.append("x-amz-meta-uid:" + str(getuid()));
|
headers.append("x-amz-meta-uid:" + str(getuid()));
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("PUT", "application/x-directory", date, headers.get(), resource));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("PUT", "application/x-directory", date, headers.get(), resource));
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
string my_url = prepare_url(url.c_str());
|
string my_url = prepare_url(url.c_str());
|
||||||
@ -1047,8 +1035,7 @@ s3fs_mkdir(const char *path, mode_t mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// aka rm
|
// aka rm
|
||||||
static int
|
static int s3fs_unlink(const char *path) {
|
||||||
s3fs_unlink(const char *path) {
|
|
||||||
cout << "unlink[path=" << path << "]" << endl;
|
cout << "unlink[path=" << path << "]" << endl;
|
||||||
|
|
||||||
string resource = urlEncode(service_path + bucket + path);
|
string resource = urlEncode(service_path + bucket + path);
|
||||||
@ -1063,7 +1050,8 @@ s3fs_unlink(const char *path) {
|
|||||||
string date = get_date();
|
string date = get_date();
|
||||||
headers.append("Date: " + date);
|
headers.append("Date: " + date);
|
||||||
headers.append("Content-Type: ");
|
headers.append("Content-Type: ");
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("DELETE", "", date, headers.get(), resource));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("DELETE", "", date, headers.get(), resource));
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
string my_url = prepare_url(url.c_str());
|
string my_url = prepare_url(url.c_str());
|
||||||
@ -1074,8 +1062,7 @@ s3fs_unlink(const char *path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_rmdir(const char *path) {
|
||||||
s3fs_rmdir(const char *path) {
|
|
||||||
cout << "rmdir[path=" << path << "]" << endl;
|
cout << "rmdir[path=" << path << "]" << endl;
|
||||||
|
|
||||||
// need to check if the directory is empty
|
// need to check if the directory is empty
|
||||||
@ -1103,14 +1090,16 @@ s3fs_rmdir(const char *path) {
|
|||||||
string date = get_date();
|
string date = get_date();
|
||||||
headers.append("Date: " + date);
|
headers.append("Date: " + date);
|
||||||
headers.append("ContentType: ");
|
headers.append("ContentType: ");
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("GET", "", date, headers.get(), resource + "/"));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("GET", "", date, headers.get(), resource + "/"));
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
VERIFY(my_curl_easy_perform(curl.get()));
|
VERIFY(my_curl_easy_perform(curl.get()));
|
||||||
|
|
||||||
cout << endl << responseText << endl;
|
cout << endl << responseText << endl;
|
||||||
if (responseText.find ("<CommonPrefixes>") != std::string::npos || responseText.find ("<ETag>") != std::string::npos ) {
|
if (responseText.find ("<CommonPrefixes>") != std::string::npos ||
|
||||||
|
responseText.find ("<ETag>") != std::string::npos ) {
|
||||||
// directory is not empty
|
// directory is not empty
|
||||||
cout << "[path=" << path << "] not empty" << endl;
|
cout << "[path=" << path << "] not empty" << endl;
|
||||||
return -ENOTEMPTY;
|
return -ENOTEMPTY;
|
||||||
@ -1129,7 +1118,8 @@ s3fs_rmdir(const char *path) {
|
|||||||
string date = get_date();
|
string date = get_date();
|
||||||
headers.append("Date: " + date);
|
headers.append("Date: " + date);
|
||||||
headers.append("Content-Type: ");
|
headers.append("Content-Type: ");
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("DELETE", "", date, headers.get(), resource));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("DELETE", "", date, headers.get(), resource));
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
string my_url = prepare_url(url.c_str());
|
string my_url = prepare_url(url.c_str());
|
||||||
@ -1140,8 +1130,7 @@ s3fs_rmdir(const char *path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_symlink(const char *from, const char *to) {
|
||||||
s3fs_symlink(const char *from, const char *to) {
|
|
||||||
cout << "symlink[from=" << from << "][to=" << to << "]" << endl;
|
cout << "symlink[from=" << from << "][to=" << to << "]" << endl;
|
||||||
|
|
||||||
headers_t headers;
|
headers_t headers;
|
||||||
@ -1158,8 +1147,7 @@ s3fs_symlink(const char *from, const char *to) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_rename(const char *from, const char *to) {
|
||||||
s3fs_rename(const char *from, const char *to) {
|
|
||||||
cout << "rename[from=" << from << "][to=" << to << "]" << endl;
|
cout << "rename[from=" << from << "][to=" << to << "]" << endl;
|
||||||
|
|
||||||
// preserve meta headers across rename
|
// preserve meta headers across rename
|
||||||
@ -1176,17 +1164,14 @@ s3fs_rename(const char *from, const char *to) {
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
return s3fs_unlink(from);
|
return s3fs_unlink(from);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_link(const char *from, const char *to) {
|
||||||
s3fs_link(const char *from, const char *to) {
|
|
||||||
cout << "link[from=" << from << "][to=" << to << "]" << endl;
|
cout << "link[from=" << from << "][to=" << to << "]" << endl;
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_chmod(const char *path, mode_t mode) {
|
||||||
s3fs_chmod(const char *path, mode_t mode) {
|
|
||||||
cout << "chmod[path=" << path << "][mode=" << mode << "]" << endl;
|
cout << "chmod[path=" << path << "][mode=" << mode << "]" << endl;
|
||||||
headers_t meta;
|
headers_t meta;
|
||||||
VERIFY(get_headers(path, meta));
|
VERIFY(get_headers(path, meta));
|
||||||
@ -1199,8 +1184,7 @@ s3fs_chmod(const char *path, mode_t mode) {
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
|
||||||
static int
|
static int s3fs_chown(const char *path, uid_t uid, gid_t gid) {
|
||||||
s3fs_chown(const char *path, uid_t uid, gid_t gid) {
|
|
||||||
cout << "chown[path=" << path << "]" << endl;
|
cout << "chown[path=" << path << "]" << endl;
|
||||||
|
|
||||||
headers_t meta;
|
headers_t meta;
|
||||||
@ -1219,8 +1203,7 @@ s3fs_chown(const char *path, uid_t uid, gid_t gid) {
|
|||||||
return put_headers(path, meta);
|
return put_headers(path, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_truncate(const char *path, off_t size) {
|
||||||
s3fs_truncate(const char *path, off_t size) {
|
|
||||||
//###TODO honor size?!?
|
//###TODO honor size?!?
|
||||||
|
|
||||||
cout << "truncate[path=" << path << "][size=" << size << "]" << endl;
|
cout << "truncate[path=" << path << "][size=" << size << "]" << endl;
|
||||||
@ -1240,8 +1223,7 @@ typedef map<int, int> s3fs_descriptors_t;
|
|||||||
static s3fs_descriptors_t s3fs_descriptors;
|
static s3fs_descriptors_t s3fs_descriptors;
|
||||||
static pthread_mutex_t s3fs_descriptors_lock;
|
static pthread_mutex_t s3fs_descriptors_lock;
|
||||||
|
|
||||||
static int
|
static int s3fs_open(const char *path, struct fuse_file_info *fi) {
|
||||||
s3fs_open(const char *path, struct fuse_file_info *fi) {
|
|
||||||
cout << "open[path=" << path << "][flags=" << fi->flags << "]" << endl;
|
cout << "open[path=" << path << "][flags=" << fi->flags << "]" << endl;
|
||||||
|
|
||||||
headers_t meta;
|
headers_t meta;
|
||||||
@ -1256,8 +1238,7 @@ s3fs_open(const char *path, struct fuse_file_info *fi) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
|
||||||
s3fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
|
|
||||||
//###cout << "read: " << path << endl;
|
//###cout << "read: " << path << endl;
|
||||||
int res = pread(fi->fh, buf, size, offset);
|
int res = pread(fi->fh, buf, size, offset);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
@ -1265,8 +1246,9 @@ s3fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_fi
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_write(
|
||||||
s3fs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
|
const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
|
||||||
|
|
||||||
//###cout << "write: " << path << endl;
|
//###cout << "write: " << path << endl;
|
||||||
int res = pwrite(fi->fh, buf, size, offset);
|
int res = pwrite(fi->fh, buf, size, offset);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
@ -1274,8 +1256,7 @@ s3fs_write(const char *path, const char *buf, size_t size, off_t offset, struct
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_statfs(const char *path, struct statvfs *stbuf) {
|
||||||
s3fs_statfs(const char *path, struct statvfs *stbuf) {
|
|
||||||
// 256T
|
// 256T
|
||||||
stbuf->f_bsize = 0X1000000;
|
stbuf->f_bsize = 0X1000000;
|
||||||
stbuf->f_blocks = 0X1000000;
|
stbuf->f_blocks = 0X1000000;
|
||||||
@ -1284,14 +1265,12 @@ s3fs_statfs(const char *path, struct statvfs *stbuf) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int get_flags(int fd) {
|
||||||
get_flags(int fd) {
|
|
||||||
auto_lock lock(s3fs_descriptors_lock);
|
auto_lock lock(s3fs_descriptors_lock);
|
||||||
return s3fs_descriptors[fd];
|
return s3fs_descriptors[fd];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_flush(const char *path, struct fuse_file_info *fi) {
|
||||||
s3fs_flush(const char *path, struct fuse_file_info *fi) {
|
|
||||||
int fd = fi->fh;
|
int fd = fi->fh;
|
||||||
cout << "flush[path=" << path << "][fd=" << fd << "]" << endl;
|
cout << "flush[path=" << path << "][fd=" << fd << "]" << endl;
|
||||||
// NOTE- fi->flags is not available here
|
// NOTE- fi->flags is not available here
|
||||||
@ -1305,8 +1284,7 @@ s3fs_flush(const char *path, struct fuse_file_info *fi) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_release(const char *path, struct fuse_file_info *fi) {
|
||||||
s3fs_release(const char *path, struct fuse_file_info *fi) {
|
|
||||||
int fd = fi->fh;
|
int fd = fi->fh;
|
||||||
cout << "release[path=" << path << "][fd=" << fd << "]" << endl;
|
cout << "release[path=" << path << "][fd=" << fd << "]" << endl;
|
||||||
if (close(fd) == -1)
|
if (close(fd) == -1)
|
||||||
@ -1314,8 +1292,7 @@ s3fs_release(const char *path, struct fuse_file_info *fi) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t
|
time_t my_timegm (struct tm *tm) {
|
||||||
my_timegm (struct tm *tm) {
|
|
||||||
time_t ret;
|
time_t ret;
|
||||||
char *tz;
|
char *tz;
|
||||||
|
|
||||||
@ -1349,22 +1326,22 @@ struct cleanup_stuff {
|
|||||||
delete stuff.responseHeaders;
|
delete stuff.responseHeaders;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class auto_stuff {
|
|
||||||
stuffMap_t stuffMap;
|
|
||||||
public:
|
|
||||||
auto_stuff() {
|
|
||||||
|
|
||||||
}
|
class auto_stuff {
|
||||||
|
public:
|
||||||
|
auto_stuff() { }
|
||||||
~auto_stuff() {
|
~auto_stuff() {
|
||||||
for_each(stuffMap.begin(), stuffMap.end(), cleanup_stuff());
|
for_each(stuffMap.begin(), stuffMap.end(), cleanup_stuff());
|
||||||
}
|
}
|
||||||
stuffMap_t& get() {
|
|
||||||
return stuffMap;
|
stuffMap_t& get() { return stuffMap; }
|
||||||
}
|
|
||||||
|
private:
|
||||||
|
stuffMap_t stuffMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int s3fs_readdir(
|
||||||
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) {
|
||||||
//cout << "readdir:"<< " path="<< path << endl;
|
//cout << "readdir:"<< " path="<< path << endl;
|
||||||
|
|
||||||
string NextMarker;
|
string NextMarker;
|
||||||
@ -1403,7 +1380,8 @@ s3fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
|
|||||||
string date = get_date();
|
string date = get_date();
|
||||||
headers.append("Date: " + date);
|
headers.append("Date: " + date);
|
||||||
headers.append("ContentType: ");
|
headers.append("ContentType: ");
|
||||||
headers.append("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("GET", "", date, headers.get(), resource + "/"));
|
headers.append("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("GET", "", date, headers.get(), resource + "/"));
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers.get());
|
||||||
|
|
||||||
@ -1420,7 +1398,10 @@ s3fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
|
|||||||
{
|
{
|
||||||
xmlDocPtr doc = xmlReadMemory(responseText.c_str(), responseText.size(), "", NULL, 0);
|
xmlDocPtr doc = xmlReadMemory(responseText.c_str(), responseText.size(), "", NULL, 0);
|
||||||
if (doc != NULL && doc->children != NULL) {
|
if (doc != NULL && doc->children != NULL) {
|
||||||
for (xmlNodePtr cur_node = doc->children->children; cur_node != NULL; cur_node = cur_node->next) {
|
for (xmlNodePtr cur_node = doc->children->children;
|
||||||
|
cur_node != NULL;
|
||||||
|
cur_node = cur_node->next) {
|
||||||
|
|
||||||
string cur_node_name(reinterpret_cast<const char *>(cur_node->name));
|
string cur_node_name(reinterpret_cast<const char *>(cur_node->name));
|
||||||
if (cur_node_name == "IsTruncated")
|
if (cur_node_name == "IsTruncated")
|
||||||
IsTruncated = reinterpret_cast<const char *>(cur_node->children->content);
|
IsTruncated = reinterpret_cast<const char *>(cur_node->children->content);
|
||||||
@ -1431,7 +1412,10 @@ s3fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
|
|||||||
string Key;
|
string Key;
|
||||||
string LastModified;
|
string LastModified;
|
||||||
string Size;
|
string Size;
|
||||||
for (xmlNodePtr sub_node = cur_node->children; sub_node != NULL; sub_node = sub_node->next) {
|
for (xmlNodePtr sub_node = cur_node->children;
|
||||||
|
sub_node != NULL;
|
||||||
|
sub_node = sub_node->next) {
|
||||||
|
|
||||||
if (sub_node->type == XML_ELEMENT_NODE) {
|
if (sub_node->type == XML_ELEMENT_NODE) {
|
||||||
string elementName = reinterpret_cast<const char*>(sub_node->name);
|
string elementName = reinterpret_cast<const char*>(sub_node->name);
|
||||||
if (sub_node->children != NULL) {
|
if (sub_node->children != NULL) {
|
||||||
@ -1473,9 +1457,13 @@ s3fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
|
|||||||
|
|
||||||
// requestHeaders
|
// requestHeaders
|
||||||
string date = get_date();
|
string date = get_date();
|
||||||
stuff.requestHeaders = curl_slist_append(stuff.requestHeaders, string("Date: "+date).c_str());
|
stuff.requestHeaders = curl_slist_append(
|
||||||
stuff.requestHeaders = curl_slist_append(stuff.requestHeaders, string("Content-Type: ").c_str());
|
stuff.requestHeaders, string("Date: " + date).c_str());
|
||||||
stuff.requestHeaders = curl_slist_append(stuff.requestHeaders, string("Authorization: AWS "+AWSAccessKeyId+":"+calc_signature("HEAD", "", date, stuff.requestHeaders, resource)).c_str());
|
stuff.requestHeaders = curl_slist_append(
|
||||||
|
stuff.requestHeaders, string("Content-Type: ").c_str());
|
||||||
|
stuff.requestHeaders = curl_slist_append(
|
||||||
|
stuff.requestHeaders, string("Authorization: AWS " + AWSAccessKeyId + ":" +
|
||||||
|
calc_signature("HEAD", "", date, stuff.requestHeaders, resource)).c_str());
|
||||||
curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, stuff.requestHeaders);
|
curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, stuff.requestHeaders);
|
||||||
|
|
||||||
// responseHeaders
|
// responseHeaders
|
||||||
@ -1494,8 +1482,7 @@ s3fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
|
|||||||
|
|
||||||
int running_handles;
|
int running_handles;
|
||||||
|
|
||||||
while (curl_multi_perform(multi_handle.get(), &running_handles) == CURLM_CALL_MULTI_PERFORM)
|
while (curl_multi_perform(multi_handle.get(), &running_handles) == CURLM_CALL_MULTI_PERFORM);
|
||||||
;
|
|
||||||
|
|
||||||
while (running_handles) {
|
while (running_handles) {
|
||||||
fd_set read_fd_set;
|
fd_set read_fd_set;
|
||||||
@ -1516,14 +1503,14 @@ s3fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
|
|||||||
timeout.tv_usec = 1000 * milliseconds % 1000000;
|
timeout.tv_usec = 1000 * milliseconds % 1000000;
|
||||||
|
|
||||||
int max_fd;
|
int max_fd;
|
||||||
VERIFY(curl_multi_fdset(multi_handle.get(), &read_fd_set, &write_fd_set, &exc_fd_set, &max_fd));
|
VERIFY(curl_multi_fdset(
|
||||||
|
multi_handle.get(), &read_fd_set, &write_fd_set, &exc_fd_set, &max_fd));
|
||||||
|
|
||||||
if (select(max_fd + 1, &read_fd_set, &write_fd_set, &exc_fd_set, &timeout) == -1)
|
if (select(max_fd + 1, &read_fd_set, &write_fd_set, &exc_fd_set, &timeout) == -1)
|
||||||
Yikes(-errno);
|
Yikes(-errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (curl_multi_perform(multi_handle.get(), &running_handles) == CURLM_CALL_MULTI_PERFORM)
|
while (curl_multi_perform(multi_handle.get(), &running_handles) == CURLM_CALL_MULTI_PERFORM);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int remaining_msgs = 1;
|
int remaining_msgs = 1;
|
||||||
@ -1542,14 +1529,16 @@ s3fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
|
|||||||
memset(&st, 0, sizeof(st));
|
memset(&st, 0, sizeof(st));
|
||||||
st.st_nlink = 1; // see fuse faq
|
st.st_nlink = 1; // see fuse faq
|
||||||
// mode
|
// mode
|
||||||
st.st_mode = strtoul((*stuff.responseHeaders)["x-amz-meta-mode"].c_str(), (char **)NULL, 10);
|
st.st_mode = strtoul(
|
||||||
|
(*stuff.responseHeaders)["x-amz-meta-mode"].c_str(), (char **)NULL, 10);
|
||||||
char* ContentType = 0;
|
char* ContentType = 0;
|
||||||
if (curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_TYPE, &ContentType) == 0) {
|
if (curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_TYPE, &ContentType) == 0) {
|
||||||
if (ContentType)
|
if (ContentType)
|
||||||
st.st_mode |= strcmp(ContentType, "application/x-directory") == 0 ? S_IFDIR : S_IFREG;
|
st.st_mode |= strcmp(ContentType, "application/x-directory") == 0 ? S_IFDIR : S_IFREG;
|
||||||
}
|
}
|
||||||
// mtime
|
// mtime
|
||||||
st.st_mtime = strtoul((*stuff.responseHeaders)["x-amz-meta-mtime"].c_str(), (char **)NULL, 10);
|
st.st_mtime = strtoul
|
||||||
|
((*stuff.responseHeaders)["x-amz-meta-mtime"].c_str(), (char **)NULL, 10);
|
||||||
if (st.st_mtime == 0) {
|
if (st.st_mtime == 0) {
|
||||||
long LastModified;
|
long LastModified;
|
||||||
if (curl_easy_getinfo(curl_handle, CURLINFO_FILETIME, &LastModified) == 0)
|
if (curl_easy_getinfo(curl_handle, CURLINFO_FILETIME, &LastModified) == 0)
|
||||||
@ -1588,8 +1577,7 @@ static pthread_mutex_t *mutex_buf = NULL;
|
|||||||
* @param line source file line number
|
* @param line source file line number
|
||||||
* @return none
|
* @return none
|
||||||
*/
|
*/
|
||||||
static void locking_function(int mode, int n, const char *file, int line)
|
static void locking_function(int mode, int n, const char *file, int line) {
|
||||||
{
|
|
||||||
if (mode & CRYPTO_LOCK) {
|
if (mode & CRYPTO_LOCK) {
|
||||||
pthread_mutex_lock(&mutex_buf[n]);
|
pthread_mutex_lock(&mutex_buf[n]);
|
||||||
} else {
|
} else {
|
||||||
@ -1654,15 +1642,13 @@ static void s3fs_destroy(void*) {
|
|||||||
pthread_mutex_destroy(&stat_cache_lock);
|
pthread_mutex_destroy(&stat_cache_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3fs_access(const char *path, int mask) {
|
||||||
s3fs_access(const char *path, int mask) {
|
|
||||||
//###cout << "###access[path=" << path << "]" << endl;
|
//###cout << "###access[path=" << path << "]" << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// aka touch
|
// aka touch
|
||||||
static int
|
static int s3fs_utimens(const char *path, const struct timespec ts[2]) {
|
||||||
s3fs_utimens(const char *path, const struct timespec ts[2]) {
|
|
||||||
cout << "utimens[path=" << path << "][mtime=" << str(ts[1].tv_sec) << "]" << endl;
|
cout << "utimens[path=" << path << "][mtime=" << str(ts[1].tv_sec) << "]" << endl;
|
||||||
headers_t meta;
|
headers_t meta;
|
||||||
VERIFY(get_headers(path, meta));
|
VERIFY(get_headers(path, meta));
|
||||||
@ -1672,8 +1658,7 @@ s3fs_utimens(const char *path, const struct timespec ts[2]) {
|
|||||||
return put_headers(path, meta);
|
return put_headers(path, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int my_fuse_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) {
|
||||||
my_fuse_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) {
|
|
||||||
if (key == FUSE_OPT_KEY_NONOPT) {
|
if (key == FUSE_OPT_KEY_NONOPT) {
|
||||||
if (bucket.size() == 0) {
|
if (bucket.size() == 0) {
|
||||||
bucket = arg;
|
bucket = arg;
|
||||||
@ -1686,6 +1671,7 @@ my_fuse_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == FUSE_OPT_KEY_OPT) {
|
if (key == FUSE_OPT_KEY_OPT) {
|
||||||
if (strstr(arg, "accessKeyId=") != 0) {
|
if (strstr(arg, "accessKeyId=") != 0) {
|
||||||
AWSAccessKeyId = strchr(arg, '=') + 1;
|
AWSAccessKeyId = strchr(arg, '=') + 1;
|
||||||
@ -1746,8 +1732,7 @@ string StringToLower(string strToConvert) {
|
|||||||
|
|
||||||
static struct fuse_operations s3fs_oper;
|
static struct fuse_operations s3fs_oper;
|
||||||
|
|
||||||
int
|
int main(int argc, char *argv[]) {
|
||||||
main(int argc, char *argv[]) {
|
|
||||||
memset(&s3fs_oper, 0, sizeof(s3fs_oper));
|
memset(&s3fs_oper, 0, sizeof(s3fs_oper));
|
||||||
|
|
||||||
struct fuse_args custom_args = FUSE_ARGS_INIT(argc, argv);
|
struct fuse_args custom_args = FUSE_ARGS_INIT(argc, argv);
|
||||||
@ -1759,7 +1744,8 @@ main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( StringToLower(bucket) != bucket ) {
|
if ( StringToLower(bucket) != bucket ) {
|
||||||
cout << argv[0] << ": bucket \"" << bucket.c_str() << "\" - buckets with upper case characters in their names are not supported" << endl;
|
cout << argv[0] << ": bucket \"" << bucket.c_str() <<
|
||||||
|
"\" - buckets with upper case characters in their names are not supported" << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1784,11 +1770,14 @@ main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (AWSAccessKeyId.size() == 0) {
|
if (AWSAccessKeyId.size() == 0) {
|
||||||
cout << argv[0] << ": " << "missing accessKeyId.. see /etc/passwd-s3fs or use, e.g., -o accessKeyId=aaa" << endl;
|
cout << argv[0] << ": " <<
|
||||||
|
"missing accessKeyId.. see /etc/passwd-s3fs or use, e.g., -o accessKeyId=aaa" << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (AWSSecretAccessKey.size() == 0) {
|
if (AWSSecretAccessKey.size() == 0) {
|
||||||
cout << argv[0] << ": " << "missing secretAccessKey... see /etc/passwd-s3fs or use, e.g., -o secretAccessKey=bbb" << endl;
|
cout << argv[0] << ": " <<
|
||||||
|
"missing secretAccessKey... see /etc/passwd-s3fs or use, e.g., -o secretAccessKey=bbb" <<
|
||||||
|
endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user