diff --git a/gd_interface.c b/gd_interface.c index 994796e..5d0dbfc 100644 --- a/gd_interface.c +++ b/gd_interface.c @@ -138,10 +138,9 @@ char* load_file(const char* path, const char* name) /** Callback for libcurl for parsing json auth tokens. * */ -size_t curl_post_callback(void *data, size_t size, size_t nmemb, void *store) +int curl_post_callback(struct gdi_state *state, struct request_t *request) { - struct gdi_state *state = (struct gdi_state*) store; - struct json_object *json = json_tokener_parse(data); + struct json_object *json = json_tokener_parse(request->response.body.str); union func_u func; struct json_object *tmp = json_object_object_get(json, "error"); @@ -149,7 +148,7 @@ size_t curl_post_callback(void *data, size_t size, size_t nmemb, void *store) { fprintf(stderr, "Error: %s\n", json_object_get_string(tmp)); state->callback_error = 1; - return size*nmemb; + return 1; } tmp = json_object_object_get(json, "access_token"); @@ -183,10 +182,7 @@ size_t curl_post_callback(void *data, size_t size, size_t nmemb, void *store) tmp = json_object_object_get(json, "expires_in"); state->token_expiration = json_object_get_int(tmp); - // libcurl expects this to "read" as much data as it received from the server - // since json-c is doing all the work here, unless it errors we may as well - // return the size libcurl gave us for the data - return size*nmemb; + return 0; } void print_api_info(const char* path) @@ -349,52 +345,6 @@ int gdi_init(struct gdi_state* state) fstack_push(estack, state->curlmulti, &func, 3); /* Authenticate the application */ - - // Calculating the correct value is more trouble than it is worth - /* - char *complete_authuri = (char *) malloc(sizeof(char) * 3000); - if(complete_authuri == NULL) - goto init_fail; - func.func1 = free; - fstack_push(gstack, complete_authuri, &func, 1); - - char *iter = complete_authuri; - - // Create the authentication request URI - // There might be a cleaner way to do this... - iter += add_unencoded_str(iter, auth_uri, sizeof(auth_uri)); - iter += add_unencoded_str(iter, response_type_code, sizeof(response_type_code)); - iter += add_unencoded_str(iter, scope, sizeof(scope)); - - iter += add_encoded_uri(iter, email_scope, sizeof(email_scope)); - *iter = '+'; - ++iter; - - iter += add_encoded_uri(iter, profile_scope, sizeof(profile_scope)); - *iter = '+'; - ++iter; - - iter += add_encoded_uri(iter, docs_scope, sizeof(docs_scope)); - *iter = '+'; - ++iter; - - iter += add_encoded_uri(iter, docsguc_scope, sizeof(docsguc_scope)); - *iter = '+'; - ++iter; - - iter += add_encoded_uri(iter, spreadsheets_scope, sizeof(spreadsheets_scope)); - *iter = '+'; - ++iter; - - iter += add_unencoded_str(iter, redirect, sizeof(redirect)); - - iter += add_encoded_uri(iter, state->redirecturi, strlen(state->redirecturi)+1); - - iter += add_unencoded_str(iter, clientid, sizeof(clientid)); - - iter += add_unencoded_str(iter, state->clientid, strlen(state->clientid)+1); - */ - struct str_t complete_authuri; func.func1 = str_destroy; fstack_push(gstack, &complete_authuri, &func, 1); @@ -408,7 +358,7 @@ int gdi_init(struct gdi_state* state) struct str_t redirect_param; struct str_t scope_param; struct str_t client_id_param; - //struct str_t client_secret_param; + struct str_t client_secret_param; struct str_t grant_type_param; struct str_t *email_scope_str = str_urlencode_char(email_scope, 0); @@ -419,6 +369,7 @@ int gdi_init(struct gdi_state* state) struct str_t *redirecturi_str = str_urlencode_char(state->redirecturi, 0); struct str_t *clientid_str = str_urlencode_char(state->clientid, 0); + struct str_t *clientsecret_str = str_urlencode_char(state->clientsecrets, 0); str_init_create(&plus, "+", 0); @@ -430,33 +381,35 @@ int gdi_init(struct gdi_state* state) str_init_create(&redirect_param, "redirect_uri=", 0); str_init_create(&scope_param, "scope=", 0); str_init_create(&client_id_param, "client_id=", 0); - //str_init_create(&client_secret_param, "client_secret", 0); + str_init_create(&client_secret_param, "client_secret=", 0); str_init_create(&grant_type_param, "grant_type=authorization_code", 0); - const struct str_t const* uri_parts[] = - { - &que, - &response_type_code, - &, - &scope_param, - email_scope_str, - &plus, - profile_scope_str, - &plus, - docs_scope_str, - &plus, - docsguc_scope_str, - &plus, - spreadsheets_scope_str, - &, - &redirect_param, - redirecturi_str, - &, - &client_id_param, - clientid_str - }; - str_init_create(&complete_authuri, auth_uri, sizeof(auth_uri)); - str_concat(&complete_authuri, sizeof(uri_parts)/sizeof(const struct str_t const*), uri_parts); + { // So we can reuse variable name again + const struct str_t const* uri_parts[] = + { + &que, + &response_type_code, + &, + &scope_param, + email_scope_str, + &plus, + profile_scope_str, + &plus, + docs_scope_str, + &plus, + docsguc_scope_str, + &plus, + spreadsheets_scope_str, + &, + &redirect_param, + redirecturi_str, + &, + &client_id_param, + clientid_str + }; + str_init_create(&complete_authuri, auth_uri, 0); + str_concat(&complete_authuri, sizeof(uri_parts)/sizeof(const struct str_t const*), uri_parts); + } printf("Please open this in a web browser and authorize fuse-google-drive:\n%s\n", complete_authuri.str); @@ -501,39 +454,42 @@ int gdi_init(struct gdi_state* state) } // Prepare and make the request to exchange the code for an access token - CURL *auth_handle = curl_easy_init(); - if(auth_handle == NULL) - goto init_fail; - func.func1 = curl_easy_cleanup; - fstack_push(gstack, auth_handle, &func, 1); - - // Using complete_authuri to store POST data rather than allocating more space - /* - iter = complete_authuri; - iter += add_unencoded_str(iter, codeparameter, sizeof(codeparameter)); - iter += add_encoded_uri(iter, state->code, strlen(state->code)+1); - iter += add_unencoded_str(iter, clientid, sizeof(clientid)); - iter += add_encoded_uri(iter, state->clientid, strlen(state->clientid)+1); - iter += add_unencoded_str(iter, clientsecret, sizeof(clientsecret)); - iter += add_encoded_uri(iter, state->clientsecrets, strlen(state->clientsecrets)+1); - iter += add_unencoded_str(iter, redirect, sizeof(redirect)); - iter += add_encoded_uri(iter, state->redirecturi, strlen(state->redirecturi)+1); - iter += add_unencoded_str(iter, granttype, sizeof(granttype)); - - // TODO: errors - //curl_easy_setopt(auth_handle, CURLOPT_VERBOSE, 1); - curl_easy_setopt(auth_handle, CURLOPT_USE_SSL, CURLUSESSL_ALL); // SSL - curl_easy_setopt(auth_handle, CURLOPT_URL, token_uri); // set URI - curl_easy_setopt(auth_handle, CURLOPT_POSTFIELDS, complete_authuri); // BODY - // set curl_post_callback for parsing the server response - curl_easy_setopt(auth_handle, CURLOPT_WRITEFUNCTION, curl_post_callback); - // set curl_post_callback's last parameter to state - curl_easy_setopt(auth_handle, CURLOPT_WRITEDATA, state); - curl_easy_perform(auth_handle); // POST - if(state->callback_error) - goto init_fail; + str_clear(&complete_authuri); + + struct str_t *code_str = str_urlencode_char(code, 0); + { + const struct str_t const* uri_parts[] = + { + &code_param, + code_str, + &, + &client_id_param, + clientid_str, + &, + &client_secret_param, + clientsecret_str, + &, + &redirect_param, + redirecturi_str, + &, + &grant_type_param + }; + str_init(&complete_authuri); + if(str_concat(&complete_authuri, sizeof(uri_parts)/sizeof(const struct str_t const*), uri_parts)) + goto init_fail; + printf("%s\n", complete_authuri.str); + + struct str_t token_uri_str; + str_init_create(&token_uri_str, token_uri, 0); + + struct request_t request; + ci_init(&request, &token_uri_str, 0, NULL, complete_authuri.str, POST); + ci_request(&request); + if(curl_post_callback(state, &request)) + goto init_fail; + ci_destroy(&request); + } - */ create_oauth_header(state); gdi_get_file_list(state); if(create_hash_table(state->num_files*4, state->head)) @@ -691,7 +647,7 @@ void gdi_get_file_list(struct gdi_state *state) struct str_t* next = NULL; struct request_t request; - ci_init(&request, &uri, 1, &state->oauth_header, GET); + ci_init(&request, &uri, 1, &state->oauth_header, NULL, GET); do { @@ -724,7 +680,7 @@ int gdi_check_update(struct gdi_state* state, struct gd_fs_entry_t* entry) if(entry->md5set) { struct request_t request; - ci_init(&request, &entry->feed, 1, &state->oauth_header, GET); + ci_init(&request, &entry->feed, 1, &state->oauth_header, NULL, GET); ci_request(&request); struct str_t* md5 = xml_get_md5sum(&request.response.body); @@ -755,7 +711,7 @@ int gdi_load(struct gdi_state* state, struct gd_fs_entry_t* entry) ret = 0; break; case 1: - ci_init(&request, &entry->src, 1, &state->oauth_header, GET); + ci_init(&request, &entry->src, 1, &state->oauth_header, NULL, GET); ci_request(&request); str_swap(&request.response.body, &entry->cache); @@ -767,7 +723,7 @@ int gdi_load(struct gdi_state* state, struct gd_fs_entry_t* entry) else { struct request_t request; - ci_init(&request, &entry->src, 1, &state->oauth_header, GET); + ci_init(&request, &entry->src, 1, &state->oauth_header, NULL, GET); ci_request(&request); str_swap(&request.response.body, &entry->cache); diff --git a/str.c b/str.c index 942e152..f57efe5 100644 --- a/str.c +++ b/str.c @@ -38,6 +38,15 @@ int str_init_create(struct str_t* str, const char const* value, size_t size) return str_char_concat(str, value, size); } +int str_clear(struct str_t* str) +{ + if(!str) + return 0; + memset(str->str, 0, str->reserved); + str->len = 0; + return 0; +} + int str_destroy(struct str_t* str) { if(!str) @@ -61,7 +70,7 @@ int str_concat(struct str_t* str, size_t str_count, const struct str_t const* st // Copy strings[] values into str for(count = 0; count < str_count; ++count) { - memcpy(str->str + ((str->len) ? str->len - 1 : 0), strings[count]->str, strings[count]->len); + memcpy(str->str + str->len, strings[count]->str, strings[count]->len); str->len += strings[count]->len; } // Terminate with null diff --git a/str.h b/str.h index ffac65d..f772593 100644 --- a/str.h +++ b/str.h @@ -30,6 +30,7 @@ struct str_t { void str_init(struct str_t* str); int str_init_create(struct str_t* str, const char const* value, size_t size); int str_destroy(struct str_t* str); +int str_clear(struct str_t* str); int str_resize(struct str_t *str, size_t new_size);