コード例 #1
0
ファイル: UgUri.c プロジェクト: Endz0/uget
gchar*	ug_uri_get_filename (const gchar* str)
{
	UgUri	upart;

	ug_uri_init (&upart, str);
	return ug_uri_get_file ((UgUri*) &upart);
}
コード例 #2
0
ファイル: test-uglib.c プロジェクト: erdincay/uget2
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);
}
コード例 #3
0
ファイル: UgetNode.c プロジェクト: erdincay/uget2
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);
	}
}
コード例 #4
0
ファイル: UgUri.c プロジェクト: erdincay/uget2
char* ug_filename_from_uri (const char* str)
{
	UgUri  uuri;

	ug_uri_init (&uuri, str);
	return ug_uri_get_file ((UgUri*) &uuri);

}
コード例 #5
0
ファイル: UgtkDownloadForm.c プロジェクト: erdincay/uget2
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;
}
コード例 #6
0
ファイル: UgetCurl.c プロジェクト: erdincay/uget2
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;
}
コード例 #7
0
ファイル: UgetPluginAria2.c プロジェクト: erdincay/uget2
// 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;
}