gchar* ug_uri_get_filename (const gchar* str) { UgUri upart; ug_uri_init (&upart, str); return ug_uri_get_file ((UgUri*) &upart); }
void test_uri (void) { char* temp; char* hosts[] = {"ftp.you.com", ".your.org", ".edu", NULL}; char* exts[] = {"png", "bmp", "jpg", NULL}; char* schemes[] = {"ftp", "http", "git", NULL}; // const char* uri = "ftp://i.am.ftp.you.com/file.bmp"; const char* uri = "http://my.and.your.org/file%200.png"; // const char* uri = "git://this.edu/file.jpg"; UgUri uuri; int index; puts ("\n--- test_uri:"); ug_uri_init (&uuri, uri); index = ug_uri_match_hosts (&uuri, hosts); printf ("ug_uri_match_hosts () return %d\n", index); index = ug_uri_match_schemes (&uuri, schemes); printf ("ug_uri_match_schemes () return %d\n", index); index = ug_uri_match_file_exts (&uuri, exts); printf ("ug_uri_match_file_exts () return %d\n", index); temp = ug_uri_get_file (&uuri); puts (temp); ug_free (temp); }
void uget_node_set_name_by_uri (UgetNode* node, UgUri* uuri) { const char* filename; int length; ug_free (node->name); if (uuri->scheme_len == 6 && strncmp (uuri->uri, "magnet", 6) == 0) { length = 0; filename = strstr (uuri->uri + uuri->file, "dn="); if (filename) { filename = filename + 3; length = strcspn (filename, "&"); node->name = ug_unescape_uri (filename, length); if (ug_utf8_get_invalid ((uint8_t*) node->name, NULL) != -1) { ug_free (node->name); node->name = ug_strndup (filename, length); } } } else { length = ug_uri_file (uuri, &filename); if (length == 0) node->name = ug_strdup (uuri->uri); else node->name = ug_uri_get_file (uuri); } }
char* ug_filename_from_uri (const char* str) { UgUri uuri; ug_uri_init (&uuri, str); return ug_uri_get_file ((UgUri*) &uuri); }
void ugtk_download_form_complete_entry (UgtkDownloadForm* dform) { const gchar* text; // gchar* temp; UgUri upart; gboolean completed = FALSE; // URL text = gtk_entry_get_text ((GtkEntry*) dform->uri_entry); ug_uri_init (&upart, text); if (upart.host != -1) { // disable changed flags dform->changed.enable = FALSE; #if 0 // complete file entry text = gtk_entry_get_text ((GtkEntry*) dform->file_entry); if (text[0] == 0 || dform->changed.file == FALSE) { temp = ug_uri_get_file (&upart); gtk_entry_set_text ((GtkEntry*) dform->file_entry, (temp) ? temp : "index.htm"); g_free (temp); } // complete user entry text = gtk_entry_get_text ((GtkEntry*) dform->username_entry); if (text[0] == 0 || dform->changed.user == FALSE) { temp = ug_uri_get_user (&upart); gtk_entry_set_text ((GtkEntry*) dform->username_entry, (temp) ? temp : ""); g_free (temp); } // complete password entry text = gtk_entry_get_text ((GtkEntry*) dform->password_entry); if (text[0] == 0 || dform->changed.password == FALSE) { temp = ug_uri_get_password (&upart); gtk_entry_set_text ((GtkEntry*) dform->password_entry, (temp) ? temp : ""); g_free (temp); } #endif // enable changed flags dform->changed.enable = TRUE; // status completed = TRUE; } #if 1 // check existing for file name else if (ug_uri_part_file (&upart, &text) > 0) { completed = TRUE; } #else // file extension else if (ug_uri_part_file_ext (&upart, &text) > 0) { // torrent or metalink file path if (*text == 'm' || *text == 'M' || *text == 't' || *text == 'T') completed = TRUE; } #endif else if (upart.path > 0 && upart.uri[upart.path] != 0) completed = TRUE; else if (gtk_widget_is_sensitive (dform->uri_entry) == FALSE) completed = TRUE; dform->completed = completed; }
static size_t uget_curl_header_http0 (char *buffer, size_t size, size_t nmemb, UgetCurl* ugcurl) { char* file; char* temp; int length; file = NULL; length = strlen (buffer); if (ugcurl->response == 0) { curl_easy_getinfo (ugcurl->curl, CURLINFO_RESPONSE_CODE, &ugcurl->response); // This will abort the transfer and return CURL_WRITE_ERROR. if (ugcurl->response >= 400) return 0; } if (length > 15 && strncasecmp (buffer, "Accept-Ranges: ", 15) == 0) { buffer += 15; if (strncasecmp (buffer, "none", 4) == 0) ugcurl->resumable = FALSE; else ugcurl->resumable = TRUE; } else if (length > 14 && strncasecmp (buffer, "Content-Type: ", 14) == 0) { buffer += 14; length = strcspn (buffer, "\r\n"); if (length >= 9 && strncasecmp (buffer, "text/html", 9) == 0) ugcurl->html = TRUE; else ugcurl->html = FALSE; } // handle HTTP header "Location:" else if (length > 10 && strncasecmp (buffer, "Location: ", 10) == 0) { // exclude header and character '\r', '\n' buffer += 10; length = strcspn (buffer, "\r\n"); if (ugcurl->header_store) { ug_free (ugcurl->header.uri); ugcurl->header.uri = ug_strndup (buffer, length); uget_curl_decide_scheme (ugcurl, ugcurl->header.uri); } else { temp = ug_strndup (buffer, length); uget_curl_decide_scheme (ugcurl, temp); ug_free (temp); } // decide login data (user & password) by scheme uget_curl_decide_login (ugcurl); // uget_curl_decide_scheme() has called ug_uri_init() // to initialize ugcurl->uri.part // ug_uri_init (&ugcurl->uri.part, ugcurl->header.uri); if (ugcurl->uri.part.file != -1 && ugcurl->header_store) { ug_free (ugcurl->header.filename); ugcurl->header.filename = ug_uri_get_file (&ugcurl->uri.part); } if (ugcurl->scheme_type == SCHEME_FTP) { curl_easy_setopt (ugcurl->curl, CURLOPT_HEADERFUNCTION, (curl_write_callback) uget_curl_header_ftp0); } } // handle HTTP header "Content-Location:" else if (length > 18 && strncasecmp (buffer, "Content-Location: ", 18) == 0) { // exclude header and character '\r', '\n' buffer += 18; temp = ug_strndup (buffer, strcspn (buffer, "\r\n")); ug_uri_init (&ugcurl->uri.part, temp); if (ugcurl->uri.part.file != -1 && ugcurl->header_store) { ug_free (ugcurl->header.filename); ugcurl->header.filename = ug_uri_get_file (&ugcurl->uri.part); } ug_free (temp); } // handle HTTP header "Content-Disposition:" else if (length > 21 && strncasecmp (buffer, "Content-Disposition: ", 21) == 0) { // exclude header and character '\r', '\n' buffer += 21; buffer = ug_strndup (buffer, strcspn (buffer, "\r\n")); // grab filename file = strstr (buffer, "filename="); if (file) { file += 9; // value of "filename=" if (file[0] != '\"') temp = ug_strndup (file, strcspn (file, ";")); else { file += 1; temp = ug_strndup (file, strcspn (file, "\"")); } // grab filename ug_uri_init (&ugcurl->uri.part, temp); if (ugcurl->uri.part.file != -1 && ugcurl->header_store) { ug_free (ugcurl->header.filename); ugcurl->header.filename = ug_uri_get_file (&ugcurl->uri.part); } ug_free (temp); } ug_free (buffer); } return nmemb; }
// return FALSE if plug-in was stopped. static int plugin_sync (UgetPluginAria2* plugin) { int index; UgetNode* node; UgetEvent* event; struct { UgetCommon* common; UgetProgress* progress; } temp; if (plugin->stopped == TRUE) return FALSE; if (plugin->synced == TRUE) return TRUE; node = plugin->node; // ------------------------------------------------ // update progress temp.progress = ug_info_realloc (&node->info, UgetProgressInfo); temp.progress->complete = plugin->completedLength; temp.progress->total = plugin->totalLength; temp.progress->download_speed = plugin->downloadSpeed; temp.progress->upload_speed = plugin->uploadSpeed; temp.progress->uploaded = plugin->uploadLength; temp.progress->consume_time = time(NULL) - plugin->start_time; // ratio if (temp.progress->uploaded && temp.progress->complete) temp.progress->ratio = (double)temp.progress->uploaded / (double)temp.progress->complete; else temp.progress->ratio = 0.0; // If total size is unknown, don't calculate percent. if (temp.progress->total) temp.progress->percent = (temp.progress->complete * 100) / temp.progress->total; else temp.progress->percent = 0; // If total size and average speed is unknown, don't calculate remain time. if (temp.progress->download_speed > 0 && temp.progress->total > 0) temp.progress->remain_time = (temp.progress->total - temp.progress->complete) / temp.progress->download_speed; // ------------------------------------------------ temp.common = ug_info_realloc (&node->info, UgetCommonInfo); // sync changed limit from UgetNode if (plugin->limit[1] != temp.common->max_upload_speed || plugin->limit[0] != temp.common->max_download_speed) { plugin->limit_by_user = TRUE; } // add nodes by files if (plugin->files_per_gid_prev != plugin->files_per_gid) { #ifndef NDEBUG // debug if (temp.common->debug_level) { printf ("n_files: old %d - new %d\n", plugin->files_per_gid_prev, plugin->files_per_gid); } #endif // add child node if aria2 add/create more files index = plugin->files_per_gid_prev; for (; index < plugin->files.length; index++) { if (plugin_insert_node (plugin, plugin->files.at[index].path, FALSE)) { #ifndef NDEBUG // debug if (temp.common->debug_level) printf ("new child node name = %s\n", plugin->files.at[index].path); #endif } } plugin->files_per_gid_prev = plugin->files_per_gid; } // change node name. if (plugin->node_named == FALSE && plugin->files_per_gid > 0) { plugin->node_named = TRUE; if (plugin->uri_type == URI_NET && temp.common->file == NULL) { ug_uri_init (&plugin->uri_part, node->children->name); index = plugin->uri_part.file; if (index != -1) { ug_free (node->name); node->name = ug_uri_get_file (&plugin->uri_part); event = uget_event_new (UGET_EVENT_NAME); uget_plugin_post ((UgetPlugin*) plugin, event); #ifndef NDEBUG // debug if (temp.common->debug_level) printf ("base node name = %s\n", node->name); #endif } } } switch (plugin->status) { case ARIA2_STATUS_ACTIVE: if (plugin->completedLength > 0 && plugin->completedLength == plugin->totalLength) { #ifndef NDEBUG // debug if (temp.common->debug_level) { if ((node->state & UGET_STATE_UPLOADING) == 0) printf ("uploading...\n"); } #endif node->state |= UGET_STATE_UPLOADING; } break; case ARIA2_STATUS_WAITING: // clear uploading state node->state &= ~UGET_STATE_UPLOADING; break; case ARIA2_STATUS_COMPLETE: // clear uploading state node->state &= ~UGET_STATE_UPLOADING; // remove completed gid ug_free (plugin->gids.at[0]); plugin->gids.length -= 1; memmove (plugin->gids.at, plugin->gids.at + 1, sizeof (char*) * plugin->gids.length); // If there is only one followed gid and file, change uri. if (plugin->gids.length == 1 && plugin->files.length == 1) { // If URI scheme is not "magnet" and aria2 runs in local device if (global.data->uri_remote == FALSE && plugin->uri_type != URI_MAGNET) { // change URI ug_free (temp.common->uri); ug_free (temp.common->file); temp.common->file = NULL; if (node->children && node->children->name) temp.common->uri = ug_strdup (node->children->name); else temp.common->uri = ug_strdup (plugin->files.at[0].path); uget_node_set_name_by_uri_string (node, temp.common->uri); // set node type node->children->type = UGET_NODE_ATTACHMENT; #ifndef NDEBUG // debug if (temp.common->debug_level) printf ("uri followed to %s\n", temp.common->uri); #endif } } // If no followed gid, it was completed. else if (plugin->gids.length == 0) { node->state |= UGET_STATE_COMPLETED; event = uget_event_new (UGET_EVENT_COMPLETED); uget_plugin_post ((UgetPlugin*)plugin, event); } // clear plugin->files ug_array_foreach (&plugin->files, (UgForeachFunc)aria2_file_clear, NULL); plugin->files.length = 0; plugin->files_per_gid = 0; plugin->files_per_gid_prev = 0; break; case ARIA2_STATUS_ERROR: // clear uploading state node->state &= ~UGET_STATE_UPLOADING; #ifdef NO_RETRY_IF_CONNECT_FAILED // download speed was too slow if (plugin->errorCode == 5) { #else // download speed was too slow or name resolution failed if (plugin->errorCode == 5 || plugin->errorCode == 19) { #endif // retry if (temp.common->retry_count < temp.common->retry_limit || temp.common->retry_limit == 0) { temp.common->retry_count++; plugin->restart = TRUE; #ifndef NDEBUG // debug if (temp.common->debug_level) printf ("retry %d\n", temp.common->retry_count); #endif } else { // plugin->node->state |= UGET_STATE_ERROR; event = uget_event_new_error ( UGET_EVENT_ERROR_TOO_MANY_RETRIES, NULL); uget_plugin_post ((UgetPlugin*) plugin, event); } } else { if (plugin->errorCode > 30) plugin->errorCode = 1; // if this is last gid. if (plugin->gids.length == 1) { // plugin->node->state |= UGET_STATE_ERROR; #ifdef HAVE_GLIB event = uget_event_new_error (0, gettext (error_string[plugin->errorCode])); #else event = uget_event_new_error (0, error_string[plugin->errorCode]); #endif uget_plugin_post ((UgetPlugin*)plugin, event); } } // remove stopped gid ug_free (plugin->gids.at[0]); plugin->gids.length -= 1; memmove (plugin->gids.at, plugin->gids.at + 1, sizeof (char*) * plugin->gids.length); break; case ARIA2_STATUS_REMOVED: // clear uploading state node->state &= ~UGET_STATE_UPLOADING; // debug event = uget_event_new_normal (0, _("aria2: gid was removed.")); uget_plugin_post ((UgetPlugin*)plugin, event); // remove completed gid ug_free (plugin->gids.at[0]); plugin->gids.length -= 1; memmove (plugin->gids.at, plugin->gids.at + 1, sizeof (char*) * plugin->gids.length); break; } // If we have followed gid, don't restart. if (plugin->gids.length > 0) plugin->restart = FALSE; else { #ifndef NDEBUG // debug if (temp.common->debug_level) printf ("gids.length = %d\n", plugin->gids.length); #endif // If no followed gid and no need to retry, it must stop. if (plugin->restart == FALSE) plugin->stopped = TRUE; else { plugin->retry_delay = temp.common->retry_delay; uget_aria2_request (global.data, plugin->start_request); } } // if plug-in was stopped, don't sync data with thread if (plugin->stopped == FALSE) plugin->synced = TRUE; return TRUE; } // ------------------------------------ static int plugin_insert_node (UgetPluginAria2* plugin, const char* fpath, int is_attachment) { UgetNode* node; char* ctrl_file; // aria2 magnet metadata file // if (plugin->uri_type == URI_MAGNET) { // if (strncmp ("[METADATA]", fpath, 10) == 0) // fpath += 10; // } for (node = plugin->node->children; node; node = node->next) { if (strcmp (node->name, fpath) == 0) return FALSE; } // aria2 control file must add first ctrl_file = ug_malloc (strlen (fpath) + 6 + 1); // + ".aria2" + '\0' ctrl_file[0] = 0; strcat (ctrl_file, fpath); strcat (ctrl_file, ".aria2"); node = uget_node_new (NULL); node->name = ctrl_file; node->type = UGET_NODE_ATTACHMENT; uget_node_prepend (plugin->node, node); // download file node = uget_node_new (NULL); node->name = ug_strdup (fpath); uget_node_prepend (plugin->node, node); if (is_attachment) node->type = UGET_NODE_ATTACHMENT; return TRUE; }