static int cfs_fgetattr(const char* path, struct stat* stbuf, struct fuse_file_info* info) { debugf(DBG_LEVEL_NORM, KBLU "cfs_fgetattr(%s)", path); openfile* of = (openfile*)(uintptr_t)info->fh; if (of) { //get file. if not in cache will be downloaded. dir_entry* de = path_info(path); if (!de) { debug_list_cache_content(); debugf(DBG_LEVEL_NORM, KBLU"exit 1: cfs_fgetattr(%s) "KYEL"not-in-cache/cloud", path); return -ENOENT; } int default_mode_file; if (option_enable_chmod) default_mode_file = de->chmod; else default_mode_file = 0666; stbuf->st_size = cloudfs_file_size(of->fd); stbuf->st_mode = S_IFREG | default_mode_file; stbuf->st_nlink = 1; debugf(DBG_LEVEL_NORM, KBLU "exit 0: cfs_fgetattr(%s)", path); return 0; } debugf(DBG_LEVEL_NORM, KRED "exit 1: cfs_fgetattr(%s)", path); return -ENOENT; }
static int cfs_fgetattr(const char *path, struct stat *stbuf, struct fuse_file_info *info) { openfile *of = (openfile *)(uintptr_t)info->fh; if (of) { stbuf->st_size = cloudfs_file_size(of->fd); stbuf->st_mode = S_IFREG | 0666; stbuf->st_nlink = 1; return 0; } return -ENOENT; }
static int cfs_flush(const char *path, struct fuse_file_info *info) { openfile *of = (openfile *)(uintptr_t)info->fh; if (of) { update_dir_cache(path, cloudfs_file_size(of->fd), 0, 0); if (of->flags & O_RDWR || of->flags & O_WRONLY) { FILE *fp = fdopen(dup(of->fd), "r"); rewind(fp); if (!cloudfs_object_read_fp(path, fp)) { fclose(fp); return -ENOENT; } fclose(fp); } } return 0; }
static int send_request(char *method, const char *path, FILE *fp, xmlParserCtxtPtr xmlctx, curl_slist *extra_headers) { char url[MAX_URL_SIZE]; char *slash; long response = -1; int tries = 0; if (!storage_url[0]) { debugf("send_request with no storage_url?"); abort(); } while ((slash = strstr(path, "%2F")) || (slash = strstr(path, "%2f"))) { *slash = '/'; memmove(slash+1, slash+3, strlen(slash+3)+1); } while (*path == '/') path++; snprintf(url, sizeof(url), "%s/%s", storage_url, path); // retry on failures for (tries = 0; tries < REQUEST_RETRIES; tries++) { CURL *curl = get_connection(path); if (rhel5_mode) curl_easy_setopt(curl, CURLOPT_CAINFO, RHEL5_CERTIFICATE_FILE); curl_slist *headers = NULL; curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_HEADER, 0); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, verify_ssl); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); curl_easy_setopt(curl, CURLOPT_VERBOSE, debug); add_header(&headers, "X-Auth-Token", storage_token); if (!strcasecmp(method, "MKDIR")) { curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0); add_header(&headers, "Content-Type", "application/directory"); } else if (!strcasecmp(method, "PUT") && fp) { rewind(fp); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); curl_easy_setopt(curl, CURLOPT_INFILESIZE, cloudfs_file_size(fileno(fp))); curl_easy_setopt(curl, CURLOPT_READDATA, fp); } else if (!strcasecmp(method, "GET")) { if (fp) { rewind(fp); // make sure the file is ready for a-writin' fflush(fp); if (ftruncate(fileno(fp), 0) < 0) { debugf("ftruncate failed. I don't know what to do about that."); abort(); } curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); } else if (xmlctx) { curl_easy_setopt(curl, CURLOPT_WRITEDATA, xmlctx); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &xml_dispatch); } } else curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method); /* add the headers from extra_headers if any */ curl_slist *extra; for (extra = extra_headers; extra; extra = extra->next) { debugf("adding header: %s", extra->data); headers = curl_slist_append(headers, extra->data); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_perform(curl); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); curl_slist_free_all(headers); curl_easy_reset(curl); return_connection(curl); if (response >= 200 && response < 400) return response; sleep(8 << tries); // backoff if (response == 401 && !cloudfs_connect()) // re-authenticate on 401s return response; if (xmlctx) xmlCtxtResetPush(xmlctx, NULL, 0, NULL, NULL); } return response; }