浏览代码

2006-11-09 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	To add Metalink location option:
	
	* src/MetalinkRequestInfo.cc
	(execute): Call MetalinkEntry::setLocationPreference()
	* src/main.cc
	(showUsage): Added the help message for --metalink-location 
option.
	(main): Added --metalink-location option.
	* src/prefs.h
	(PREF_METALINK_LOCATION): New definition.
	* src/MetalinkEntry.cc
	(AddLocationPreference): New function object.
	(setLocationPreference): New function.
	* src/Xml2MetalinkProcessor.cc
	(getResource): Set location attribute to MetalinkResource

	To show URLs to download

	* src/UrlRequestInfo.h
	(printUrls): New function.

	To add multiple <file> Metalink support:

	* src/MetalinkEntry.h
	(MetalinkResources): Removed.
	(setLocationPreference): New function.
	(MetalinkEntryHandle): New type definition.
	(MetalinkEntries): New type definition.
	* src/Xml2MetalinkProcessor.h
	(getEntry): MetalinkEntry* -> MetalinkEntryHandle
	(getResource): MetalinkResource* -> MetalinkResourceHandle
	(parseFile): Metalinker* -> MetalinkerHandle
	* src/UrlRequestInfo.h
	(execute): RequestInfo* -> RequestInfos
	* src/MetalinkRequestInfo.cc
	(AccumulateNonP2PUrl): MetalinkResource* -> 
MetalinkResourceHandle
	(FindBitTorrentUrl): MetalinkResource* -> MetalinkResourceHandle
	(execute): RequestInfo* -> RequestInfos
	Added multiple <file> support. Print filename when it is queued.
	* src/MetalinkRequestInfo.h
	(execute): RequestInfo* -> RequestInfos
	(getDownloadEngine): Removed.
	* src/RequestInfo.h
	(RequestInfoHandle): New type definition.
	(RequestInfos): New type definition.
	(execute): RequestInfo* -> RequestInfos
	(getDownloadEngine): Removed.
	* src/MetalinkResource.h
	(MetalinkResourceHandle): New type definition.
	(MetalinkResources): New type definition.
	* src/MetalinkEntry.cc
	(~MetalinkEntry): Removed the deletion of the elements of 
resources,
	because the element is now of type MetalinkResourceHandle.
	(PrefOrder): MetalinkResource* -> MetalinkResourceHandle
	(Supported): MetalinkResource* -> MetalinkResourceHandle
	(dropUnsupportedResource): Removed the deletion of the elements 
of
	resources because the element is now of type 
MetalinkResourceHandle.
	* src/Xml2MetalinkProcessor.cc
	(parseFile): Metalinker* -> MetalinkerHandle
	MetalinkEntry* -> MetalinkEntryHandle
	Removed try-catch block.
	(getEntry): MetalinkEntry* -> MetalinkEntryHandle
	MetalinkResource* -> MetalinkResourceHandle
	Removed try-catch block.
	(getResource): MetalinkResource* -> MetalinkResourceHandle
	Free result by using xmlXPathFreeObject()
	* src/Metalinker.cc
	(~Metalinker): Removed the deletion of entries.
	MetalinkEntry* -> MetalinkEntryHandle
	(queryEntry): Add multiple <file> Metalink support.
	* src/Metalinker.h
	(MetalinkEntries): Removed.
	(queryEntry): MetalinkEntry* -> MetalinkEntries
	* src/MetalinkProcessor.h
	(parseFile): Metalinker* -> MetalinkerHandle
	
	Bug fixes:

	* src/PeerChokeCommand.cc
	(execute): cat01->cat02
	* src/DefaultPieceStorage.cc
	(DefaultPieceStorage): Added diskAdaptor(0)
	* src/TrackerWatcherComand.cc:
	(execute): Use btAnnounce->noMoreAnnounce()
	to determin whether the function returns true or not.
	* src/TrackerUpdateCommand.cc:
	(execute): Use btAnnounce->noMoreAnnounce()
	to determin whether the function returns true or not.
	* src/FtpConnection.cc
	(bulkReceiveResponse): Throw DlRetryEx if EOF got.
	This is the fix of the busy loop bug.
	* src/DownloadCommand.cc
	(DownloadCommand): Reuse PeerStat. segmentMan->getPeerStat() 
returns
	cached PeerStat.
	
	The value of "name" entry in torrent file is now set by
	*DiskAdaptor::setTopDir(...) methods.
	
	* src/MultiDiskAdaptor.h
	(topDir): New variable.
	(setTopDir): New function.
	(getTopDir): New function.
	* src/MultiDiskAdaptor.cc
	(getFilePath): Concat storDir, "/" and topDir.
	(mkdir): Use getFilePath() to get the directory path for output.
	* src/DefaultPieceStorage.cc
	(initStorage): Set the value of "name" entry to 
MultiDiskAdaptor,
	CopyDiskAdaptor.
	* src/CopyDiskAdaptor.h
	(topDir): New variable.
	(setTopDir): New function.
	(getTopDir): New function.
	* src/CopyDiskAdaptor.cc
	(fixFilename): Updated.
	
	Misc

	* src/UrlRequestInfo.h
	(e): Removed.
	(UrlRequestInfo): Removed e.
	(getDownloadEngine): Removed.
	* src/UrlRequestInfo.cc
	(handler): Rewritten.
	(printUrls): New function.
	(execute): Call printUrls().
	
	* src/HandshakeMessage.cc
	(check): peerinteraction->getBtContext() -> btContext

	* src/PeerInteraction.h
	(getBtContext): Removed.

	* src/TorrentRequestInfo.h
	(execute): RequestInfo* -> RequestInfos
	(getDownloadEngine): Removed.
	* src/TorrentRequestInfo.cc
	(haltRequested): Removed.
	(btHaltRequested): New variable.
	(torrentHandler): haltRequested -> btHaltRequested
	(execute): RequestInfo* -> RequestInfos
	* src/TorrentConsoleDownloadEngine.cc
	(afterEachIteration): haltRequested -> btHaltRequested.
	
	* src/ConsoleDownloadEngine.h
	(initStatistics): Added virtual.
	(calculateStatistics): Added virtual.
	(onEndOfRun): Added virtual.
	(afterEachIteration): Added virtual.
	* src/ConsoleDownloadEngine.cc
	(haltRequested): New variable.
	(afterEachIteration): New function.

	* src/main.cc
	(requestInfo): Removed.

	* src/SegmentMan.cc
	(findSlowerSegmentEntry): Refactored.
Tatsuhiro Tsujikawa 19 年之前
父节点
当前提交
8d0ef717e1

+ 159 - 0
ChangeLog

@@ -1,3 +1,162 @@
+2006-11-09  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	To add Metalink location option:
+	
+	* src/MetalinkRequestInfo.cc
+	(execute): Call MetalinkEntry::setLocationPreference()
+	* src/main.cc
+	(showUsage): Added the help message for --metalink-location option.
+	(main): Added --metalink-location option.
+	* src/prefs.h
+	(PREF_METALINK_LOCATION): New definition.
+	* src/MetalinkEntry.cc
+	(AddLocationPreference): New function object.
+	(setLocationPreference): New function.
+	* src/Xml2MetalinkProcessor.cc
+	(getResource): Set location attribute to MetalinkResource
+
+	To show URLs to download
+
+	* src/UrlRequestInfo.h
+	(printUrls): New function.
+
+	To add multiple <file> Metalink support:
+
+	* src/MetalinkEntry.h
+	(MetalinkResources): Removed.
+	(setLocationPreference): New function.
+	(MetalinkEntryHandle): New type definition.
+	(MetalinkEntries): New type definition.
+	* src/Xml2MetalinkProcessor.h
+	(getEntry): MetalinkEntry* -> MetalinkEntryHandle
+	(getResource): MetalinkResource* -> MetalinkResourceHandle
+	(parseFile): Metalinker* -> MetalinkerHandle
+	* src/UrlRequestInfo.h
+	(execute): RequestInfo* -> RequestInfos
+	* src/MetalinkRequestInfo.cc
+	(AccumulateNonP2PUrl): MetalinkResource* -> MetalinkResourceHandle
+	(FindBitTorrentUrl): MetalinkResource* -> MetalinkResourceHandle
+	(execute): RequestInfo* -> RequestInfos
+	Added multiple <file> support. Print filename when it is queued.
+	* src/MetalinkRequestInfo.h
+	(execute): RequestInfo* -> RequestInfos
+	(getDownloadEngine): Removed.
+	* src/RequestInfo.h
+	(RequestInfoHandle): New type definition.
+	(RequestInfos): New type definition.
+	(execute): RequestInfo* -> RequestInfos
+	(getDownloadEngine): Removed.
+	* src/MetalinkResource.h
+	(MetalinkResourceHandle): New type definition.
+	(MetalinkResources): New type definition.
+	* src/MetalinkEntry.cc
+	(~MetalinkEntry): Removed the deletion of the elements of resources,
+	because the element is now of type MetalinkResourceHandle.
+	(PrefOrder): MetalinkResource* -> MetalinkResourceHandle
+	(Supported): MetalinkResource* -> MetalinkResourceHandle
+	(dropUnsupportedResource): Removed the deletion of the elements of
+	resources because the element is now of type MetalinkResourceHandle.
+	* src/Xml2MetalinkProcessor.cc
+	(parseFile): Metalinker* -> MetalinkerHandle
+	MetalinkEntry* -> MetalinkEntryHandle
+	Removed try-catch block.
+	(getEntry): MetalinkEntry* -> MetalinkEntryHandle
+	MetalinkResource* -> MetalinkResourceHandle
+	Removed try-catch block.
+	(getResource): MetalinkResource* -> MetalinkResourceHandle
+	Free result by using xmlXPathFreeObject()
+	* src/Metalinker.cc
+	(~Metalinker): Removed the deletion of entries.
+	MetalinkEntry* -> MetalinkEntryHandle
+	(queryEntry): Add multiple <file> Metalink support.
+	* src/Metalinker.h
+	(MetalinkEntries): Removed.
+	(queryEntry): MetalinkEntry* -> MetalinkEntries
+	* src/MetalinkProcessor.h
+	(parseFile): Metalinker* -> MetalinkerHandle
+	
+	Bug fixes:
+
+	* src/PeerChokeCommand.cc
+	(execute): cat01->cat02
+	* src/DefaultPieceStorage.cc
+	(DefaultPieceStorage): Added diskAdaptor(0)
+	* src/TrackerWatcherComand.cc:
+	(execute): Use btAnnounce->noMoreAnnounce()
+	to determin whether the function returns true or not.
+	* src/TrackerUpdateCommand.cc:
+	(execute): Use btAnnounce->noMoreAnnounce()
+	to determin whether the function returns true or not.
+	* src/FtpConnection.cc
+	(bulkReceiveResponse): Throw DlRetryEx if EOF got.
+	This is the fix of the busy loop bug.
+	* src/DownloadCommand.cc
+	(DownloadCommand): Reuse PeerStat. segmentMan->getPeerStat() returns
+	cached PeerStat.
+	
+	The value of "name" entry in torrent file is now set by
+	*DiskAdaptor::setTopDir(...) methods.
+	
+	* src/MultiDiskAdaptor.h
+	(topDir): New variable.
+	(setTopDir): New function.
+	(getTopDir): New function.
+	* src/MultiDiskAdaptor.cc
+	(getFilePath): Concat storDir, "/" and topDir.
+	(mkdir): Use getFilePath() to get the directory path for output.
+	* src/DefaultPieceStorage.cc
+	(initStorage): Set the value of "name" entry to MultiDiskAdaptor,
+	CopyDiskAdaptor.
+	* src/CopyDiskAdaptor.h
+	(topDir): New variable.
+	(setTopDir): New function.
+	(getTopDir): New function.
+	* src/CopyDiskAdaptor.cc
+	(fixFilename): Updated.
+	
+	Misc
+
+	* src/UrlRequestInfo.h
+	(e): Removed.
+	(UrlRequestInfo): Removed e.
+	(getDownloadEngine): Removed.
+	* src/UrlRequestInfo.cc
+	(handler): Rewritten.
+	(printUrls): New function.
+	(execute): Call printUrls().
+	
+	* src/HandshakeMessage.cc
+	(check): peerinteraction->getBtContext() -> btContext
+
+	* src/PeerInteraction.h
+	(getBtContext): Removed.
+
+	* src/TorrentRequestInfo.h
+	(execute): RequestInfo* -> RequestInfos
+	(getDownloadEngine): Removed.
+	* src/TorrentRequestInfo.cc
+	(haltRequested): Removed.
+	(btHaltRequested): New variable.
+	(torrentHandler): haltRequested -> btHaltRequested
+	(execute): RequestInfo* -> RequestInfos
+	* src/TorrentConsoleDownloadEngine.cc
+	(afterEachIteration): haltRequested -> btHaltRequested.
+	
+	* src/ConsoleDownloadEngine.h
+	(initStatistics): Added virtual.
+	(calculateStatistics): Added virtual.
+	(onEndOfRun): Added virtual.
+	(afterEachIteration): Added virtual.
+	* src/ConsoleDownloadEngine.cc
+	(haltRequested): New variable.
+	(afterEachIteration): New function.
+
+	* src/main.cc
+	(requestInfo): Removed.
+
+	* src/SegmentMan.cc
+	(findSlowerSegmentEntry): Refactored.
+	
 2006-11-05  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	To divide TorrentMan into 6 classes: BtContext, BtRuntime,

+ 0 - 3
TODO

@@ -13,11 +13,8 @@
 * ipv6(RFC2428 for ftp)
 * Add silent mode.
 * Save URLs and command-line arguments to .aria2 file.
-* Add multi-file metalink support.
 * Add a control port for GUI frontend
 * Add a version header to .aria2 file to check the compatibiliy.
 * Use SharedHandle where it is useful.
-* Add support for "announce-list".
 * Rewrite Util::countBit
-* Add the ability to display filename or URL to be downloaded in metalink mode. 
 * Add Turkish translation.

+ 2 - 1
po/POTFILES

@@ -6,4 +6,5 @@
      ../src/main.cc \
      ../src/DefaultPieceStorage.cc \
      ../src/DefaultBtAnnounce.cc \
-     ../src/DefaultBtProgressInfoFile.cc
+     ../src/DefaultBtProgressInfoFile.cc \
+     ../src/ConsoleDownloadEngine.cc

+ 1 - 1
po/POTFILES.in

@@ -7,4 +7,4 @@ src/main.cc
 src/DefaultPieceStorage.cc
 src/DefaultBtAnnounce.cc
 src/DefaultBtProgressInfoFile.cc
-
+src/ConsoleDownloadEngine.cc

+ 92 - 88
po/aria2c.pot

@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
-"POT-Creation-Date: 2006-11-06 00:12+0900\n"
+"POT-Creation-Date: 2006-11-09 01:22+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,14 +16,14 @@ msgstr ""
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: src/RequestInfo.h:97
+#: src/RequestInfo.h:102
 #, c-format
 msgid ""
 "\n"
 "The download was complete. <%s>\n"
 msgstr ""
 
-#: src/RequestInfo.h:105
+#: src/RequestInfo.h:110
 #, c-format
 msgid ""
 "\n"
@@ -353,28 +353,16 @@ msgstr ""
 msgid "Files:"
 msgstr ""
 
-#: src/UrlRequestInfo.cc:76
-#, c-format
-msgid ""
-"\n"
-"stopping application...\n"
-msgstr ""
-
-#: src/UrlRequestInfo.cc:81
-#, c-format
-msgid "done\n"
-msgstr ""
-
-#: src/UrlRequestInfo.cc:105
+#: src/UrlRequestInfo.cc:99
 #, c-format
 msgid "Unrecognized URL or unsupported protocol: %s\n"
 msgstr ""
 
-#: src/main.cc:87
+#: src/main.cc:86
 msgid " version "
 msgstr ""
 
-#: src/main.cc:94
+#: src/main.cc:93
 msgid ""
 "This program is free software; you can redistribute it and/or modify\n"
 "it under the terms of the GNU General Public License as published by\n"
@@ -392,50 +380,50 @@ msgid ""
 "USA\n"
 msgstr ""
 
-#: src/main.cc:108
+#: src/main.cc:107
 #, c-format
 msgid "Contact Info: %s\n"
 msgstr ""
 
-#: src/main.cc:114
+#: src/main.cc:113
 #, c-format
 msgid "Usage: %s [options] URL ...\n"
 msgstr ""
 
-#: src/main.cc:116
+#: src/main.cc:115
 #, c-format
 msgid "       %s [options] -T TORRENT_FILE FILE ...\n"
 msgstr ""
 
-#: src/main.cc:119
+#: src/main.cc:118
 #, c-format
 msgid "       %s [options] -M METALINK_FILE\n"
 msgstr ""
 
-#: src/main.cc:122
+#: src/main.cc:121
 msgid "Options:"
 msgstr ""
 
-#: src/main.cc:123
+#: src/main.cc:122
 msgid " -d, --dir=DIR                The directory to store downloaded file."
 msgstr ""
 
-#: src/main.cc:124
+#: src/main.cc:123
 msgid " -o, --out=FILE               The file name for downloaded file."
 msgstr ""
 
-#: src/main.cc:125
+#: src/main.cc:124
 msgid ""
 " -l, --log=LOG                The file path to store log. If '-' is "
 "specified,\n"
 "                              log is written to stdout."
 msgstr ""
 
-#: src/main.cc:127
+#: src/main.cc:126
 msgid " -D, --daemon                 Run as daemon."
 msgstr ""
 
-#: src/main.cc:128
+#: src/main.cc:127
 msgid ""
 " -s, --split=N                Download a file using N connections. N must "
 "be\n"
@@ -445,57 +433,57 @@ msgid ""
 "                              N connections."
 msgstr ""
 
-#: src/main.cc:132
+#: src/main.cc:131
 msgid ""
 " --retry-wait=SEC             Set amount of time in second between requests\n"
 "                              for errors. Specify a value between 0 and 60.\n"
 "                              Default: 5"
 msgstr ""
 
-#: src/main.cc:135
+#: src/main.cc:134
 msgid " -t, --timeout=SEC            Set timeout in second. Default: 60"
 msgstr ""
 
-#: src/main.cc:136
+#: src/main.cc:135
 msgid ""
 " -m, --max-tries=N            Set number of tries. 0 means unlimited.\n"
 "                              Default: 5"
 msgstr ""
 
-#: src/main.cc:144
+#: src/main.cc:143
 msgid ""
 " --http-proxy=HOST:PORT       Use HTTP proxy server. This affects to all\n"
 "                              URLs."
 msgstr ""
 
-#: src/main.cc:146
+#: src/main.cc:145
 msgid " --http-user=USER             Set HTTP user. This affects to all URLs."
 msgstr ""
 
-#: src/main.cc:147
+#: src/main.cc:146
 msgid ""
 " --http-passwd=PASSWD         Set HTTP password. This affects to all URLs."
 msgstr ""
 
-#: src/main.cc:148
+#: src/main.cc:147
 msgid ""
 " --http-proxy-user=USER       Set HTTP proxy user. This affects to all URLs"
 msgstr ""
 
-#: src/main.cc:149
+#: src/main.cc:148
 msgid ""
 " --http-proxy-passwd=PASSWD   Set HTTP proxy password. This affects to all "
 "URLs."
 msgstr ""
 
-#: src/main.cc:150
+#: src/main.cc:149
 msgid ""
 " --http-proxy-method=METHOD   Set the method to use in proxy request.\n"
 "                              METHOD is either 'get' or 'tunnel'.\n"
 "                              Default: tunnel"
 msgstr ""
 
-#: src/main.cc:153
+#: src/main.cc:152
 msgid ""
 " --http-auth-scheme=SCHEME    Set HTTP authentication scheme. Currently, "
 "basic\n"
@@ -503,23 +491,23 @@ msgid ""
 "                              Default: basic"
 msgstr ""
 
-#: src/main.cc:156
+#: src/main.cc:155
 msgid " --referer=REFERER            Set Referer. This affects to all URLs."
 msgstr ""
 
-#: src/main.cc:157
+#: src/main.cc:156
 msgid ""
 " --ftp-user=USER              Set FTP user. This affects to all URLs.\n"
 "                              Default: anonymous"
 msgstr ""
 
-#: src/main.cc:159
+#: src/main.cc:158
 msgid ""
 " --ftp-passwd=PASSWD          Set FTP password. This affects to all URLs.\n"
 "                              Default: ARIA2USER@"
 msgstr ""
 
-#: src/main.cc:161
+#: src/main.cc:160
 msgid ""
 " --ftp-type=TYPE              Set FTP transfer type. TYPE is either "
 "'binary'\n"
@@ -527,11 +515,11 @@ msgid ""
 "                              Default: binary"
 msgstr ""
 
-#: src/main.cc:164
+#: src/main.cc:163
 msgid " -p, --ftp-pasv               Use passive mode in FTP."
 msgstr ""
 
-#: src/main.cc:165
+#: src/main.cc:164
 msgid ""
 " --ftp-via-http-proxy=METHOD  Use HTTP proxy in FTP. METHOD is either 'get' "
 "or\n"
@@ -539,7 +527,7 @@ msgid ""
 "                              Default: tunnel"
 msgstr ""
 
-#: src/main.cc:168
+#: src/main.cc:167
 msgid ""
 " --lowest-speed-limit=SPEED   Close connection if download speed is lower "
 "than\n"
@@ -552,7 +540,7 @@ msgid ""
 "                              Default: 0"
 msgstr ""
 
-#: src/main.cc:175
+#: src/main.cc:174
 msgid ""
 " --max-download-limit=SPEED   Set max download speed in bytes per sec.\n"
 "                              0 means unrestricted.\n"
@@ -560,11 +548,11 @@ msgid ""
 "                              Default: 0"
 msgstr ""
 
-#: src/main.cc:180
+#: src/main.cc:179
 msgid " -T, --torrent-file=TORRENT_FILE  The file path to .torrent file."
 msgstr ""
 
-#: src/main.cc:181
+#: src/main.cc:180
 msgid ""
 " --follow-torrent=true|false  Setting this option to false prevents aria2 "
 "to\n"
@@ -573,25 +561,25 @@ msgid ""
 "                              Default: true"
 msgstr ""
 
-#: src/main.cc:185
+#: src/main.cc:184
 msgid ""
 " -S, --show-files             Print file listing of .torrent file and exit."
 msgstr ""
 
-#: src/main.cc:186
+#: src/main.cc:185
 msgid ""
 " --direct-file-mapping=true|false Directly read from and write to each file\n"
 "                              mentioned in .torrent file.\n"
 "                              Default: true"
 msgstr ""
 
-#: src/main.cc:189
+#: src/main.cc:188
 msgid ""
 " --listen-port=PORT           Set port number to listen to for peer "
 "connection."
 msgstr ""
 
-#: src/main.cc:190
+#: src/main.cc:189
 msgid ""
 " --max-upload-limit=SPEED     Set max upload speed in bytes per sec.\n"
 "                              0 means unrestricted.\n"
@@ -599,7 +587,7 @@ msgid ""
 "                              Default: 0"
 msgstr ""
 
-#: src/main.cc:194
+#: src/main.cc:193
 msgid ""
 " --select-file=INDEX...       Set file to download by specifing its index.\n"
 "                              You can know file index through --show-files\n"
@@ -611,13 +599,13 @@ msgid ""
 "                              ',' and '-' can be used together."
 msgstr ""
 
-#: src/main.cc:200
+#: src/main.cc:199
 msgid ""
 " --seed-time=MINUTES          Specify seeding time in minutes. See also\n"
 "                              --seed-ratio option."
 msgstr ""
 
-#: src/main.cc:202
+#: src/main.cc:201
 msgid ""
 " --seed-ratio=RATIO           Specify share ratio. Seed completed torrents "
 "until\n"
@@ -628,11 +616,11 @@ msgid ""
 "                              the conditions is satisfied."
 msgstr ""
 
-#: src/main.cc:209
+#: src/main.cc:208
 msgid " -M, --metalink-file=METALINK_FILE The file path to .metalink file."
 msgstr ""
 
-#: src/main.cc:210
+#: src/main.cc:209
 msgid ""
 " -C, --metalink-servers=NUM_SERVERS The number of servers to connect to\n"
 "                              simultaneously. If more than one connection "
@@ -641,19 +629,23 @@ msgid ""
 "                              Default: 15"
 msgstr ""
 
-#: src/main.cc:214
+#: src/main.cc:213
 msgid " --metalink-version=VERSION   The version of file to download."
 msgstr ""
 
-#: src/main.cc:215
+#: src/main.cc:214
 msgid " --metalink-language=LANGUAGE The language of file to download."
 msgstr ""
 
-#: src/main.cc:216
+#: src/main.cc:215
 msgid ""
 " --metalink-os=OS             The operating system the file is targeted."
 msgstr ""
 
+#: src/main.cc:216
+msgid " --metalink-location=LOCATION The location of the prefered server."
+msgstr ""
+
 #: src/main.cc:217
 msgid ""
 " --follow-metalink=true|false  Setting this option to false prevents aria2 "
@@ -736,117 +728,129 @@ msgstr ""
 msgid "Report bugs to %s"
 msgstr ""
 
-#: src/main.cc:403
+#: src/main.cc:404
 msgid "unrecognized proxy format"
 msgstr ""
 
-#: src/main.cc:430
+#: src/main.cc:431
 msgid "Currently, supported authentication scheme is basic."
 msgstr ""
 
-#: src/main.cc:439
+#: src/main.cc:440
 msgid "retry-wait must be between 0 and 60."
 msgstr ""
 
-#: src/main.cc:456
+#: src/main.cc:457
 msgid "ftp-type must be either 'binary' or 'ascii'."
 msgstr ""
 
-#: src/main.cc:465
+#: src/main.cc:466
 msgid "ftp-via-http-proxy must be either 'get' or 'tunnel'."
 msgstr ""
 
-#: src/main.cc:473
+#: src/main.cc:474
 msgid "min-segment-size invalid"
 msgstr ""
 
-#: src/main.cc:484
+#: src/main.cc:485
 msgid "http-proxy-method must be either 'get' or 'tunnel'."
 msgstr ""
 
-#: src/main.cc:492
+#: src/main.cc:493
 msgid "listen-port must be between 1024 and 65535."
 msgstr ""
 
-#: src/main.cc:505
+#: src/main.cc:506
 msgid "follow-torrent must be either 'true' or 'false'."
 msgstr ""
 
-#: src/main.cc:519
+#: src/main.cc:520
 msgid "direct-file-mapping must be either 'true' or 'false'."
 msgstr ""
 
-#: src/main.cc:530
+#: src/main.cc:531
 msgid "upload-limit must be greater than or equal to 0."
 msgstr ""
 
-#: src/main.cc:543
+#: src/main.cc:544
 msgid "seed-time must be greater than or equal to 0."
 msgstr ""
 
-#: src/main.cc:553
+#: src/main.cc:554
 msgid "seed-ratio must be greater than or equal to 0.0."
 msgstr ""
 
-#: src/main.cc:563
+#: src/main.cc:564
 msgid "max-upload-limit must be greater than or equal to 0"
 msgstr ""
 
-#: src/main.cc:585
+#: src/main.cc:586
 msgid "follow-metalink must be either 'true' or 'false'."
 msgstr ""
 
-#: src/main.cc:593
+#: src/main.cc:597
 msgid "lowest-speed-limit must be greater than or equal to 0"
 msgstr ""
 
-#: src/main.cc:603
+#: src/main.cc:607
 msgid "max-download-limit must be greater than or equal to 0"
 msgstr ""
 
-#: src/main.cc:632
+#: src/main.cc:636
 msgid "split must be between 1 and 5."
 msgstr ""
 
-#: src/main.cc:645
+#: src/main.cc:649
 msgid "timeout must be between 1 and 600"
 msgstr ""
 
-#: src/main.cc:654
+#: src/main.cc:658
 msgid "max-tries invalid"
 msgstr ""
 
-#: src/main.cc:676
+#: src/main.cc:680
 msgid "metalink-servers must be greater than 0."
 msgstr ""
 
-#: src/main.cc:696
+#: src/main.cc:700
 msgid "specify at least one URL"
 msgstr ""
 
-#: src/main.cc:703
+#: src/main.cc:707
 msgid "daemon failed"
 msgstr ""
 
-#: src/main.cc:766
+#: src/main.cc:775
 msgid ""
 "Now verifying checksum.\n"
 "This may take some time depending on your PC environment and the size of "
 "file."
 msgstr ""
 
-#: src/main.cc:770
+#: src/main.cc:779
 msgid "checksum OK."
 msgstr ""
 
-#: src/main.cc:773
+#: src/main.cc:782
 msgid "checksum ERROR."
 msgstr ""
 
-#: src/DefaultPieceStorage.cc:219
+#: src/DefaultPieceStorage.cc:220
 msgid "Download of selected files was complete."
 msgstr ""
 
-#: src/DefaultPieceStorage.cc:222
+#: src/DefaultPieceStorage.cc:223
 msgid "The download was complete."
 msgstr ""
+
+#: src/ConsoleDownloadEngine.cc:108
+#, c-format
+msgid ""
+"\n"
+"stopping application...\n"
+msgstr ""
+
+#: src/ConsoleDownloadEngine.cc:112
+#, c-format
+msgid "done\n"
+msgstr ""

二进制
po/de.gmo


+ 94 - 90
po/de.po

@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
-"POT-Creation-Date: 2006-11-06 00:12+0900\n"
+"POT-Creation-Date: 2006-11-09 01:22+0900\n"
 "PO-Revision-Date: 2006-05-05 19:44+0900\n"
 "Last-Translator: Hermann J. Beckers <hj.beckers@onlinehome.de>\n"
 "Language-Team: deutsch <de@li.org>\n"
@@ -16,7 +16,7 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.3\n"
 
-#: src/RequestInfo.h:97
+#: src/RequestInfo.h:102
 #, c-format
 msgid ""
 "\n"
@@ -25,7 +25,7 @@ msgstr ""
 "\n"
 "Abruf ist vollständig. <%s>\n"
 
-#: src/RequestInfo.h:105
+#: src/RequestInfo.h:110
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -366,30 +366,16 @@ msgstr "Fehler beim Binden an Port aufgetreten.\n"
 msgid "Files:"
 msgstr "Dateien:"
 
-#: src/UrlRequestInfo.cc:76
-#, c-format
-msgid ""
-"\n"
-"stopping application...\n"
-msgstr ""
-"\n"
-"Anwendung wird gestoppt ...\n"
-
-#: src/UrlRequestInfo.cc:81
-#, c-format
-msgid "done\n"
-msgstr "erledigt\n"
-
-#: src/UrlRequestInfo.cc:105
+#: src/UrlRequestInfo.cc:99
 #, c-format
 msgid "Unrecognized URL or unsupported protocol: %s\n"
 msgstr "URL nicht erkannt oder nicht unterstütztes Protokoll: %s\n"
 
-#: src/main.cc:87
+#: src/main.cc:86
 msgid " version "
 msgstr " Version "
 
-#: src/main.cc:94
+#: src/main.cc:93
 #, fuzzy
 msgid ""
 "This program is free software; you can redistribute it and/or modify\n"
@@ -421,41 +407,41 @@ msgstr ""
 "along with this program; if not, write to the Free Software\n"
 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"
 
-#: src/main.cc:108
+#: src/main.cc:107
 #, c-format
 msgid "Contact Info: %s\n"
 msgstr "Kontakt-Info: %s\n"
 
-#: src/main.cc:114
+#: src/main.cc:113
 #, c-format
 msgid "Usage: %s [options] URL ...\n"
 msgstr "Aufruf: %s [Optionen] URL ...\n"
 
-#: src/main.cc:116
+#: src/main.cc:115
 #, c-format
 msgid "       %s [options] -T TORRENT_FILE FILE ...\n"
 msgstr "       %s [Optionen] -T TORRENT_FILE FILE ...\n"
 
-#: src/main.cc:119
+#: src/main.cc:118
 #, fuzzy, c-format
 msgid "       %s [options] -M METALINK_FILE\n"
 msgstr "       %s [Optionen] -T TORRENT_FILE FILE ...\n"
 
-#: src/main.cc:122
+#: src/main.cc:121
 msgid "Options:"
 msgstr "Optionen:"
 
-#: src/main.cc:123
+#: src/main.cc:122
 msgid " -d, --dir=DIR                The directory to store downloaded file."
 msgstr ""
 " -d, --dir=DIR                Verzeichnis zum Speichern der abgerufenen "
 "Datei."
 
-#: src/main.cc:124
+#: src/main.cc:123
 msgid " -o, --out=FILE               The file name for downloaded file."
 msgstr " -o, --out=FILE               Dateiname für die abgerufene Datei."
 
-#: src/main.cc:125
+#: src/main.cc:124
 msgid ""
 " -l, --log=LOG                The file path to store log. If '-' is "
 "specified,\n"
@@ -466,11 +452,11 @@ msgstr ""
 "                              wird das Log auf die Standardausgabe "
 "geschrieben."
 
-#: src/main.cc:127
+#: src/main.cc:126
 msgid " -D, --daemon                 Run as daemon."
 msgstr " -D, --daemon                 Start als Daemon-Prozeß."
 
-#: src/main.cc:128
+#: src/main.cc:127
 msgid ""
 " -s, --split=N                Download a file using N connections. N must "
 "be\n"
@@ -486,7 +472,7 @@ msgstr ""
 "                              Daher verbindet sich aria2 zu jeder URL mit\n"
 "                              N Verbindungen."
 
-#: src/main.cc:132
+#: src/main.cc:131
 msgid ""
 " --retry-wait=SEC             Set amount of time in second between requests\n"
 "                              for errors. Specify a value between 0 and 60.\n"
@@ -498,12 +484,12 @@ msgstr ""
 "und 60 an.\n"
 "                              Fehlwert: 5"
 
-#: src/main.cc:135
+#: src/main.cc:134
 msgid " -t, --timeout=SEC            Set timeout in second. Default: 60"
 msgstr ""
 " -t, --timeout=SEC            Setzt Wartezeit in Sekunden. Fehlwert: 60"
 
-#: src/main.cc:136
+#: src/main.cc:135
 msgid ""
 " -m, --max-tries=N            Set number of tries. 0 means unlimited.\n"
 "                              Default: 5"
@@ -511,7 +497,7 @@ msgstr ""
 " -m, --max-tries=N            Anzahl Versuche. 0 bedeutet unbegrenzt.\n"
 "                              Fehlwert: 5"
 
-#: src/main.cc:144
+#: src/main.cc:143
 msgid ""
 " --http-proxy=HOST:PORT       Use HTTP proxy server. This affects to all\n"
 "                              URLs."
@@ -519,26 +505,26 @@ msgstr ""
 " --http-proxy=HOST:PORT       HTTP-Proxyserver benutzen. Dies betrifft alle\n"
 "                              URLs."
 
-#: src/main.cc:146
+#: src/main.cc:145
 msgid " --http-user=USER             Set HTTP user. This affects to all URLs."
 msgstr ""
 " --http-user=USER             HTTP-Anwendername angeben. Dies betrifft alle "
 "URLs."
 
-#: src/main.cc:147
+#: src/main.cc:146
 msgid ""
 " --http-passwd=PASSWD         Set HTTP password. This affects to all URLs."
 msgstr ""
 " --http-passwd=PASSWD         HTTP-Passwort setzen. Dies betrifft alle URLs."
 
-#: src/main.cc:148
+#: src/main.cc:147
 msgid ""
 " --http-proxy-user=USER       Set HTTP proxy user. This affects to all URLs"
 msgstr ""
 " --http-proxy-user=USER       HTTP-Proxy-Anwender setzen. Dies betrifft alle "
 "URLs."
 
-#: src/main.cc:149
+#: src/main.cc:148
 msgid ""
 " --http-proxy-passwd=PASSWD   Set HTTP proxy password. This affects to all "
 "URLs."
@@ -546,7 +532,7 @@ msgstr ""
 " --http-proxy-passwd=PASSWD   HTTP-Proxy-Passwort setzen. Dies betrifft alle "
 "URLs."
 
-#: src/main.cc:150
+#: src/main.cc:149
 msgid ""
 " --http-proxy-method=METHOD   Set the method to use in proxy request.\n"
 "                              METHOD is either 'get' or 'tunnel'.\n"
@@ -557,7 +543,7 @@ msgstr ""
 "                              METHOD ist entweder 'get' oder 'tunnel'.\n"
 "                              Fehlwert: tunnel"
 
-#: src/main.cc:153
+#: src/main.cc:152
 msgid ""
 " --http-auth-scheme=SCHEME    Set HTTP authentication scheme. Currently, "
 "basic\n"
@@ -569,11 +555,11 @@ msgstr ""
 "                              das einzig zulässige Schema.\n"
 "                              Fehlwert: basic"
 
-#: src/main.cc:156
+#: src/main.cc:155
 msgid " --referer=REFERER            Set Referer. This affects to all URLs."
 msgstr " --referer=REFERER            Referer setzen. Dies betrifft alle URLs."
 
-#: src/main.cc:157
+#: src/main.cc:156
 msgid ""
 " --ftp-user=USER              Set FTP user. This affects to all URLs.\n"
 "                              Default: anonymous"
@@ -581,7 +567,7 @@ msgstr ""
 " --ftp-user=USER              FTP-Anwender setzen. Dies betrifft alle URLs.\n"
 "                              Fehlwert: anonymous"
 
-#: src/main.cc:159
+#: src/main.cc:158
 msgid ""
 " --ftp-passwd=PASSWD          Set FTP password. This affects to all URLs.\n"
 "                              Default: ARIA2USER@"
@@ -589,7 +575,7 @@ msgstr ""
 " --ftp-passwd=PASSWD          FTP-Passwort setzen. Dies betrifft alle URLs.\n"
 "                              Fehlwert: ARIA2USER@"
 
-#: src/main.cc:161
+#: src/main.cc:160
 msgid ""
 " --ftp-type=TYPE              Set FTP transfer type. TYPE is either "
 "'binary'\n"
@@ -601,11 +587,11 @@ msgstr ""
 "                              oder 'ascii'.\n"
 "                              Fehlwert: binary"
 
-#: src/main.cc:164
+#: src/main.cc:163
 msgid " -p, --ftp-pasv               Use passive mode in FTP."
 msgstr " -p, --ftp-pasv               Passiv-Modus für FTP benutzen."
 
-#: src/main.cc:165
+#: src/main.cc:164
 msgid ""
 " --ftp-via-http-proxy=METHOD  Use HTTP proxy in FTP. METHOD is either 'get' "
 "or\n"
@@ -617,7 +603,7 @@ msgstr ""
 "                              'tunnel'.\n"
 "                              Fehlwert: tunnel"
 
-#: src/main.cc:168
+#: src/main.cc:167
 #, fuzzy
 msgid ""
 " --lowest-speed-limit=SPEED   Close connection if download speed is lower "
@@ -636,7 +622,7 @@ msgstr ""
 "und 60 an.\n"
 "                              Fehlwert: 5"
 
-#: src/main.cc:175
+#: src/main.cc:174
 #, fuzzy
 msgid ""
 " --max-download-limit=SPEED   Set max download speed in bytes per sec.\n"
@@ -650,11 +636,11 @@ msgstr ""
 "und 60 an.\n"
 "                              Fehlwert: 5"
 
-#: src/main.cc:180
+#: src/main.cc:179
 msgid " -T, --torrent-file=TORRENT_FILE  The file path to .torrent file."
 msgstr " -T, --torrent-file=TORRENT_FILE  Datenpfad zur torrent-Datei."
 
-#: src/main.cc:181
+#: src/main.cc:180
 msgid ""
 " --follow-torrent=true|false  Setting this option to false prevents aria2 "
 "to\n"
@@ -669,14 +655,14 @@ msgstr ""
 "                              auf .torrent endet.\n"
 "                              Fehlwert: true"
 
-#: src/main.cc:185
+#: src/main.cc:184
 msgid ""
 " -S, --show-files             Print file listing of .torrent file and exit."
 msgstr ""
 " -S, --show-files             Dateiliste der .torrent-Datei ausgeben und "
 "beenden."
 
-#: src/main.cc:186
+#: src/main.cc:185
 msgid ""
 " --direct-file-mapping=true|false Directly read from and write to each file\n"
 "                              mentioned in .torrent file.\n"
@@ -686,7 +672,7 @@ msgstr ""
 "                              .torrent-Datei erwähnten Datei.\n"
 "                              Fehlwert: true"
 
-#: src/main.cc:189
+#: src/main.cc:188
 msgid ""
 " --listen-port=PORT           Set port number to listen to for peer "
 "connection."
@@ -694,7 +680,7 @@ msgstr ""
 " --listen-port=PORT           Port-Nummer zum Lauschen auf Peer-Verbindungen "
 "setzen."
 
-#: src/main.cc:190
+#: src/main.cc:189
 #, fuzzy
 msgid ""
 " --max-upload-limit=SPEED     Set max upload speed in bytes per sec.\n"
@@ -708,7 +694,7 @@ msgstr ""
 "und 60 an.\n"
 "                              Fehlwert: 5"
 
-#: src/main.cc:194
+#: src/main.cc:193
 msgid ""
 " --select-file=INDEX...       Set file to download by specifing its index.\n"
 "                              You can know file index through --show-files\n"
@@ -728,7 +714,7 @@ msgstr ""
 "                              Sie können auch '-' verwenden wie in \"1-5\".\n"
 "                              ',' und '-' können zusammen benutzt werden."
 
-#: src/main.cc:200
+#: src/main.cc:199
 #, fuzzy
 msgid ""
 " --seed-time=MINUTES          Specify seeding time in minutes. See also\n"
@@ -737,7 +723,7 @@ msgstr ""
 " -m, --max-tries=N            Anzahl Versuche. 0 bedeutet unbegrenzt.\n"
 "                              Fehlwert: 5"
 
-#: src/main.cc:202
+#: src/main.cc:201
 #, fuzzy
 msgid ""
 " --seed-ratio=RATIO           Specify share ratio. Seed completed torrents "
@@ -755,12 +741,12 @@ msgstr ""
 "                              Daher verbindet sich aria2 zu jeder URL mit\n"
 "                              N Verbindungen."
 
-#: src/main.cc:209
+#: src/main.cc:208
 #, fuzzy
 msgid " -M, --metalink-file=METALINK_FILE The file path to .metalink file."
 msgstr " -T, --torrent-file=TORRENT_FILE  Datenpfad zur torrent-Datei."
 
-#: src/main.cc:210
+#: src/main.cc:209
 #, fuzzy
 msgid ""
 " -C, --metalink-servers=NUM_SERVERS The number of servers to connect to\n"
@@ -776,19 +762,23 @@ msgstr ""
 "                              auf .torrent endet.\n"
 "                              Fehlwert: true"
 
-#: src/main.cc:214
+#: src/main.cc:213
 msgid " --metalink-version=VERSION   The version of file to download."
 msgstr ""
 
-#: src/main.cc:215
+#: src/main.cc:214
 msgid " --metalink-language=LANGUAGE The language of file to download."
 msgstr ""
 
-#: src/main.cc:216
+#: src/main.cc:215
 msgid ""
 " --metalink-os=OS             The operating system the file is targeted."
 msgstr ""
 
+#: src/main.cc:216
+msgid " --metalink-location=LOCATION The location of the prefered server."
+msgstr ""
+
 #: src/main.cc:217
 #, fuzzy
 msgid ""
@@ -888,132 +878,146 @@ msgstr ""
 msgid "Report bugs to %s"
 msgstr "Fehler an %s melden"
 
-#: src/main.cc:403
+#: src/main.cc:404
 msgid "unrecognized proxy format"
 msgstr "nicht erkanntes Proxy-Format"
 
-#: src/main.cc:430
+#: src/main.cc:431
 msgid "Currently, supported authentication scheme is basic."
 msgstr "Derzeit unterstütztes Authentifizierungsschema ist basic."
 
-#: src/main.cc:439
+#: src/main.cc:440
 msgid "retry-wait must be between 0 and 60."
 msgstr "retry-wait muss zwischen 0 und 60 liegen."
 
-#: src/main.cc:456
+#: src/main.cc:457
 msgid "ftp-type must be either 'binary' or 'ascii'."
 msgstr "ftp-type muss entweder 'binary' oder 'ascii' sein."
 
-#: src/main.cc:465
+#: src/main.cc:466
 msgid "ftp-via-http-proxy must be either 'get' or 'tunnel'."
 msgstr "ftp-via-http-proxy muss entweder 'get' oder 'tunnel' sein."
 
-#: src/main.cc:473
+#: src/main.cc:474
 msgid "min-segment-size invalid"
 msgstr "min-segment-size ungültig"
 
-#: src/main.cc:484
+#: src/main.cc:485
 msgid "http-proxy-method must be either 'get' or 'tunnel'."
 msgstr "http-proxy-method muss entweder 'get' oder 'tunnel' sein."
 
-#: src/main.cc:492
+#: src/main.cc:493
 msgid "listen-port must be between 1024 and 65535."
 msgstr "listen-port muss zwischen 1024 und 65535 liegen."
 
-#: src/main.cc:505
+#: src/main.cc:506
 msgid "follow-torrent must be either 'true' or 'false'."
 msgstr "follow-torrent muss entweder 'true' oder 'false' sein."
 
-#: src/main.cc:519
+#: src/main.cc:520
 msgid "direct-file-mapping must be either 'true' or 'false'."
 msgstr "direct-file-mapping muss entweder 'true' oder 'false' sein."
 
-#: src/main.cc:530
+#: src/main.cc:531
 msgid "upload-limit must be greater than or equal to 0."
 msgstr "upload-limit muss größer oder gleich 0 sein."
 
-#: src/main.cc:543
+#: src/main.cc:544
 #, fuzzy
 msgid "seed-time must be greater than or equal to 0."
 msgstr "upload-limit muss größer oder gleich 0 sein."
 
-#: src/main.cc:553
+#: src/main.cc:554
 #, fuzzy
 msgid "seed-ratio must be greater than or equal to 0.0."
 msgstr "upload-limit muss größer oder gleich 0 sein."
 
-#: src/main.cc:563
+#: src/main.cc:564
 #, fuzzy
 msgid "max-upload-limit must be greater than or equal to 0"
 msgstr "upload-limit muss größer oder gleich 0 sein."
 
-#: src/main.cc:585
+#: src/main.cc:586
 #, fuzzy
 msgid "follow-metalink must be either 'true' or 'false'."
 msgstr "follow-torrent muss entweder 'true' oder 'false' sein."
 
-#: src/main.cc:593
+#: src/main.cc:597
 #, fuzzy
 msgid "lowest-speed-limit must be greater than or equal to 0"
 msgstr "upload-limit muss größer oder gleich 0 sein."
 
-#: src/main.cc:603
+#: src/main.cc:607
 #, fuzzy
 msgid "max-download-limit must be greater than or equal to 0"
 msgstr "upload-limit muss größer oder gleich 0 sein."
 
-#: src/main.cc:632
+#: src/main.cc:636
 msgid "split must be between 1 and 5."
 msgstr "split muss zwischen 1 und 5 liegen."
 
-#: src/main.cc:645
+#: src/main.cc:649
 msgid "timeout must be between 1 and 600"
 msgstr "timeout muss zwischen 1 und 600 liegen."
 
-#: src/main.cc:654
+#: src/main.cc:658
 msgid "max-tries invalid"
 msgstr "max-tries ungültig"
 
-#: src/main.cc:676
+#: src/main.cc:680
 #, fuzzy
 msgid "metalink-servers must be greater than 0."
 msgstr "upload-limit muss größer oder gleich 0 sein."
 
-#: src/main.cc:696
+#: src/main.cc:700
 msgid "specify at least one URL"
 msgstr "Geben Sie zumindest eine URL an"
 
-#: src/main.cc:703
+#: src/main.cc:707
 msgid "daemon failed"
 msgstr "Daemon-Start nicht erfolgreich"
 
-#: src/main.cc:766
+#: src/main.cc:775
 msgid ""
 "Now verifying checksum.\n"
 "This may take some time depending on your PC environment and the size of "
 "file."
 msgstr ""
 
-#: src/main.cc:770
+#: src/main.cc:779
 msgid "checksum OK."
 msgstr ""
 
-#: src/main.cc:773
+#: src/main.cc:782
 msgid "checksum ERROR."
 msgstr ""
 
-#: src/DefaultPieceStorage.cc:219
+#: src/DefaultPieceStorage.cc:220
 #, fuzzy
 msgid "Download of selected files was complete."
 msgstr " Nur ausgewählte Dateien abrufen:"
 
-#: src/DefaultPieceStorage.cc:222
+#: src/DefaultPieceStorage.cc:223
 #, fuzzy
 msgid "The download was complete."
 msgstr ""
 "\n"
 "Abruf ist vollständig. <%s>\n"
 
+#: src/ConsoleDownloadEngine.cc:108
+#, c-format
+msgid ""
+"\n"
+"stopping application...\n"
+msgstr ""
+"\n"
+"Anwendung wird gestoppt ...\n"
+
+#: src/ConsoleDownloadEngine.cc:112
+#, c-format
+msgid "done\n"
+msgstr "erledigt\n"
+
 #, fuzzy
 #~ msgid ""
 #~ " --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n"

二进制
po/ja.gmo


+ 95 - 91
po/ja.po

@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: aria2c 0.2.1\n"
 "Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
-"POT-Creation-Date: 2006-11-06 00:12+0900\n"
-"PO-Revision-Date: 2006-10-01 22:31+0900\n"
+"POT-Creation-Date: 2006-11-09 01:22+0900\n"
+"PO-Revision-Date: 2006-11-09 01:23+0900\n"
 "Last-Translator: Tatsuhiro Tsujikawa <tujikawa@rednoah.com>\n"
 "Language-Team: Japanese <ja@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -16,7 +16,7 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
 
-#: src/RequestInfo.h:97
+#: src/RequestInfo.h:102
 #, c-format
 msgid ""
 "\n"
@@ -25,7 +25,7 @@ msgstr ""
 "\n"
 "<%s> のダウンロードが完了しました.\n"
 
-#: src/RequestInfo.h:105
+#: src/RequestInfo.h:110
 #, c-format
 msgid ""
 "\n"
@@ -370,32 +370,18 @@ msgstr "
 msgid "Files:"
 msgstr "ファイル:"
 
-#: src/UrlRequestInfo.cc:76
-#, c-format
-msgid ""
-"\n"
-"stopping application...\n"
-msgstr ""
-"\n"
-"アプリケーションを終了しています...\n"
-
-#: src/UrlRequestInfo.cc:81
-#, c-format
-msgid "done\n"
-msgstr "完了\n"
-
-#: src/UrlRequestInfo.cc:105
+#: src/UrlRequestInfo.cc:99
 #, c-format
 msgid "Unrecognized URL or unsupported protocol: %s\n"
 msgstr ""
 "%s は, 理解できない URL フォーマット, または, サポートされないプロトコルで"
 "す.\n"
 
-#: src/main.cc:87
+#: src/main.cc:86
 msgid " version "
 msgstr " バージョン "
 
-#: src/main.cc:94
+#: src/main.cc:93
 msgid ""
 "This program is free software; you can redistribute it and/or modify\n"
 "it under the terms of the GNU General Public License as published by\n"
@@ -427,41 +413,41 @@ msgstr ""
 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  "
 "USA\n"
 
-#: src/main.cc:108
+#: src/main.cc:107
 #, c-format
 msgid "Contact Info: %s\n"
 msgstr "連絡先: %s\n"
 
-#: src/main.cc:114
+#: src/main.cc:113
 #, c-format
 msgid "Usage: %s [options] URL ...\n"
 msgstr "使い方: %s [オプション] URL ...\n"
 
-#: src/main.cc:116
+#: src/main.cc:115
 #, c-format
 msgid "       %s [options] -T TORRENT_FILE FILE ...\n"
 msgstr "        %s [オプション] -T TORRENT_FILE FILE ...\n"
 
-#: src/main.cc:119
+#: src/main.cc:118
 #, c-format
 msgid "       %s [options] -M METALINK_FILE\n"
 msgstr "        %s [オプション] -M METALINK_FILE\n"
 
-#: src/main.cc:122
+#: src/main.cc:121
 msgid "Options:"
 msgstr "オプション:"
 
-#: src/main.cc:123
+#: src/main.cc:122
 msgid " -d, --dir=DIR                The directory to store downloaded file."
 msgstr ""
 " -d, --dir=DIR                ダウンロードしたファイルを保存するディレクトリ."
 
-#: src/main.cc:124
+#: src/main.cc:123
 msgid " -o, --out=FILE               The file name for downloaded file."
 msgstr ""
 " -o, --out=FILE               ダウンロードしたファイルの保存先ファイル名."
 
-#: src/main.cc:125
+#: src/main.cc:124
 msgid ""
 " -l, --log=LOG                The file path to store log. If '-' is "
 "specified,\n"
@@ -471,11 +457,11 @@ msgstr ""
 "力\n"
 "                              に出力します."
 
-#: src/main.cc:127
+#: src/main.cc:126
 msgid " -D, --daemon                 Run as daemon."
 msgstr " -D, --daemon                 デーモンとして起動します."
 
-#: src/main.cc:128
+#: src/main.cc:127
 msgid ""
 " -s, --split=N                Download a file using N connections. N must "
 "be\n"
@@ -494,7 +480,7 @@ msgstr ""
 "ショ\n"
 "                              ンを確立します."
 
-#: src/main.cc:132
+#: src/main.cc:131
 msgid ""
 " --retry-wait=SEC             Set amount of time in second between requests\n"
 "                              for errors. Specify a value between 0 and 60.\n"
@@ -505,13 +491,13 @@ msgstr ""
 "                              す. 0 - 60 の値を指定してください.\n"
 "                              デフォルト値: 5"
 
-#: src/main.cc:135
+#: src/main.cc:134
 msgid " -t, --timeout=SEC            Set timeout in second. Default: 60"
 msgstr ""
 " -t, --timeout=SEC            タイムアウトとなる時間を秒で指定します.\n"
 "                              デフォルト値: 60"
 
-#: src/main.cc:136
+#: src/main.cc:135
 msgid ""
 " -m, --max-tries=N            Set number of tries. 0 means unlimited.\n"
 "                              Default: 5"
@@ -520,7 +506,7 @@ msgstr ""
 "行\n"
 "                              します. デフォルト値: 5"
 
-#: src/main.cc:144
+#: src/main.cc:143
 msgid ""
 " --http-proxy=HOST:PORT       Use HTTP proxy server. This affects to all\n"
 "                              URLs."
@@ -529,14 +515,14 @@ msgstr ""
 "シ\n"
 "                              ョンはすべての URL に影響します."
 
-#: src/main.cc:146
+#: src/main.cc:145
 msgid " --http-user=USER             Set HTTP user. This affects to all URLs."
 msgstr ""
 " --http-user=USER             HTTP での認証ユーザーを指定します. このオプショ"
 "ン\n"
 "                              はすべての URL に影響します."
 
-#: src/main.cc:147
+#: src/main.cc:146
 msgid ""
 " --http-passwd=PASSWD         Set HTTP password. This affects to all URLs."
 msgstr ""
@@ -544,7 +530,7 @@ msgstr ""
 "ショ\n"
 "                              ンはすべての URL に影響します."
 
-#: src/main.cc:148
+#: src/main.cc:147
 msgid ""
 " --http-proxy-user=USER       Set HTTP proxy user. This affects to all URLs"
 msgstr ""
@@ -554,7 +540,7 @@ msgstr ""
 "ま\n"
 "                              す."
 
-#: src/main.cc:149
+#: src/main.cc:148
 msgid ""
 " --http-proxy-passwd=PASSWD   Set HTTP proxy password. This affects to all "
 "URLs."
@@ -565,7 +551,7 @@ msgstr ""
 "し\n"
 "                              ます."
 
-#: src/main.cc:150
+#: src/main.cc:149
 msgid ""
 " --http-proxy-method=METHOD   Set the method to use in proxy request.\n"
 "                              METHOD is either 'get' or 'tunnel'.\n"
@@ -576,7 +562,7 @@ msgstr ""
 "                              す. 'get' または 'tunnel' を指定してください.\n"
 "                              デフォルト値: tunnel"
 
-#: src/main.cc:153
+#: src/main.cc:152
 msgid ""
 " --http-auth-scheme=SCHEME    Set HTTP authentication scheme. Currently, "
 "basic\n"
@@ -588,14 +574,14 @@ msgstr ""
 "                              いるのは basic です. \n"
 "                              デフォルト値: basic"
 
-#: src/main.cc:156
+#: src/main.cc:155
 msgid " --referer=REFERER            Set Referer. This affects to all URLs."
 msgstr ""
 " --referer=REFERER            リファラーを指定します. このオプションはすべて"
 "の\n"
 "                               URL に影響します."
 
-#: src/main.cc:157
+#: src/main.cc:156
 msgid ""
 " --ftp-user=USER              Set FTP user. This affects to all URLs.\n"
 "                              Default: anonymous"
@@ -605,7 +591,7 @@ msgstr ""
 "                              はすべての URL に影響します.\n"
 "                              デフォルト値: anonymous"
 
-#: src/main.cc:159
+#: src/main.cc:158
 msgid ""
 " --ftp-passwd=PASSWD          Set FTP password. This affects to all URLs.\n"
 "                              Default: ARIA2USER@"
@@ -615,7 +601,7 @@ msgstr ""
 "                              ンはすべての URL に影響します.\n"
 "                              デフォルト値: ARIA2USER@"
 
-#: src/main.cc:161
+#: src/main.cc:160
 msgid ""
 " --ftp-type=TYPE              Set FTP transfer type. TYPE is either "
 "'binary'\n"
@@ -626,11 +612,11 @@ msgstr ""
 "                              'ascii' を指定してください. デフォルト値: "
 "binary"
 
-#: src/main.cc:164
+#: src/main.cc:163
 msgid " -p, --ftp-pasv               Use passive mode in FTP."
 msgstr " -p, --ftp-pasv               FTP で passive モードを使用します."
 
-#: src/main.cc:165
+#: src/main.cc:164
 msgid ""
 " --ftp-via-http-proxy=METHOD  Use HTTP proxy in FTP. METHOD is either 'get' "
 "or\n"
@@ -643,7 +629,7 @@ msgstr ""
 "く\n"
 "                              ださい. デフォルト値: tunnel"
 
-#: src/main.cc:168
+#: src/main.cc:167
 msgid ""
 " --lowest-speed-limit=SPEED   Close connection if download speed is lower "
 "than\n"
@@ -666,7 +652,7 @@ msgstr ""
 "                              ードには影響しません.\n"
 "                              デフォルト値: 0"
 
-#: src/main.cc:175
+#: src/main.cc:174
 msgid ""
 " --max-download-limit=SPEED   Set max download speed in bytes per sec.\n"
 "                              0 means unrestricted.\n"
@@ -681,11 +667,11 @@ msgstr ""
 "1024K).\n"
 "                              デフォルト値: 0"
 
-#: src/main.cc:180
+#: src/main.cc:179
 msgid " -T, --torrent-file=TORRENT_FILE  The file path to .torrent file."
 msgstr " -T, --torrent-file=TORRENT_FILE  .torrent ファイルのパスを指定."
 
-#: src/main.cc:181
+#: src/main.cc:180
 msgid ""
 " --follow-torrent=true|false  Setting this option to false prevents aria2 "
 "to\n"
@@ -700,7 +686,7 @@ msgstr ""
 "                              は, BitTorrent モードに入りません.\n"
 "                              デフォルト値: true"
 
-#: src/main.cc:185
+#: src/main.cc:184
 msgid ""
 " -S, --show-files             Print file listing of .torrent file and exit."
 msgstr ""
@@ -708,7 +694,7 @@ msgstr ""
 "し\n"
 "                              終了します."
 
-#: src/main.cc:186
+#: src/main.cc:185
 msgid ""
 " --direct-file-mapping=true|false Directly read from and write to each file\n"
 "                              mentioned in .torrent file.\n"
@@ -719,14 +705,14 @@ msgstr ""
 "                              します.\n"
 "                              デフォルト値: true"
 
-#: src/main.cc:189
+#: src/main.cc:188
 msgid ""
 " --listen-port=PORT           Set port number to listen to for peer "
 "connection."
 msgstr ""
 " --listen-port=PORT           ピアからの接続を受け付けるポート番号を指定."
 
-#: src/main.cc:190
+#: src/main.cc:189
 msgid ""
 " --max-upload-limit=SPEED     Set max upload speed in bytes per sec.\n"
 "                              0 means unrestricted.\n"
@@ -741,7 +727,7 @@ msgstr ""
 "1024K).\n"
 "                              デフォルト値: 0"
 
-#: src/main.cc:194
+#: src/main.cc:193
 msgid ""
 " --select-file=INDEX...       Set file to download by specifing its index.\n"
 "                              You can know file index through --show-files\n"
@@ -762,7 +748,7 @@ msgstr ""
 "                              また, '-' を使って範囲指定もできます: \"1-5\"\n"
 "                              ',' と '-' は組み合わせて使うことができます."
 
-#: src/main.cc:200
+#: src/main.cc:199
 msgid ""
 " --seed-time=MINUTES          Specify seeding time in minutes. See also\n"
 "                              --seed-ratio option."
@@ -770,7 +756,7 @@ msgstr ""
 " --seed-time=MINUTES          シードを行う時間を分単位で指定します. \n"
 "                              --seed-ratio オプションも参照してください."
 
-#: src/main.cc:202
+#: src/main.cc:201
 msgid ""
 " --seed-ratio=RATIO           Specify share ratio. Seed completed torrents "
 "until\n"
@@ -789,11 +775,11 @@ msgstr ""
 "く\n"
 "                              とも一方の条件が成立するとシードを終了します."
 
-#: src/main.cc:209
+#: src/main.cc:208
 msgid " -M, --metalink-file=METALINK_FILE The file path to .metalink file."
 msgstr " -M, --metalink-file=METALINK_FILE .metalink ファイルのパスを指定."
 
-#: src/main.cc:210
+#: src/main.cc:209
 msgid ""
 " -C, --metalink-servers=NUM_SERVERS The number of servers to connect to\n"
 "                              simultaneously. If more than one connection "
@@ -807,15 +793,15 @@ msgstr ""
 "                              使用してください.\n"
 "                              デフォルト値: 15"
 
-#: src/main.cc:214
+#: src/main.cc:213
 msgid " --metalink-version=VERSION   The version of file to download."
 msgstr " --metalink-version=VERSION   ダウンロードするファイルのバージョン."
 
-#: src/main.cc:215
+#: src/main.cc:214
 msgid " --metalink-language=LANGUAGE The language of file to download."
 msgstr " --metalink-language=LANGUAGE ダウンロードするファイルの言語."
 
-#: src/main.cc:216
+#: src/main.cc:215
 msgid ""
 " --metalink-os=OS             The operating system the file is targeted."
 msgstr ""
@@ -823,6 +809,10 @@ msgstr ""
 "レー\n"
 "                              ティング・システム."
 
+#: src/main.cc:216
+msgid " --metalink-location=LOCATION The location of the prefered server."
+msgstr " --metalink-location=LOCATION 優先的にダウンロードするサーバーの場所."
+
 #: src/main.cc:217
 msgid ""
 " --follow-metalink=true|false  Setting this option to false prevents aria2 "
@@ -918,99 +908,99 @@ msgstr " 
 msgid "Report bugs to %s"
 msgstr "バグレポートはこちらへ: %s"
 
-#: src/main.cc:403
+#: src/main.cc:404
 msgid "unrecognized proxy format"
 msgstr "理解できないProxyフォーマットです."
 
-#: src/main.cc:430
+#: src/main.cc:431
 msgid "Currently, supported authentication scheme is basic."
 msgstr "現在サポートされている認証方法は basic です."
 
-#: src/main.cc:439
+#: src/main.cc:440
 msgid "retry-wait must be between 0 and 60."
 msgstr "retry-wait は 0 から 60 の間で指定してください."
 
-#: src/main.cc:456
+#: src/main.cc:457
 msgid "ftp-type must be either 'binary' or 'ascii'."
 msgstr "ftp-type は 'binary' または 'ascii' を指定してください."
 
-#: src/main.cc:465
+#: src/main.cc:466
 msgid "ftp-via-http-proxy must be either 'get' or 'tunnel'."
 msgstr "ftp-via-http-proxy は 'get' または 'tunnel' を指定してください."
 
-#: src/main.cc:473
+#: src/main.cc:474
 msgid "min-segment-size invalid"
 msgstr "min-segment-size が不正です."
 
-#: src/main.cc:484
+#: src/main.cc:485
 msgid "http-proxy-method must be either 'get' or 'tunnel'."
 msgstr "http-proxy-method は 'get' または 'tunnel' を指定してください."
 
-#: src/main.cc:492
+#: src/main.cc:493
 msgid "listen-port must be between 1024 and 65535."
 msgstr "listen-port は 1024 - 65535 の値を指定してください."
 
-#: src/main.cc:505
+#: src/main.cc:506
 msgid "follow-torrent must be either 'true' or 'false'."
 msgstr "follow-torrent は 'true' または 'false を指定してください."
 
-#: src/main.cc:519
+#: src/main.cc:520
 msgid "direct-file-mapping must be either 'true' or 'false'."
 msgstr "direct-file-mapping は 'true' または 'false を指定してください."
 
-#: src/main.cc:530
+#: src/main.cc:531
 msgid "upload-limit must be greater than or equal to 0."
 msgstr "upload-limit は 0 以上の数を指定してください."
 
-#: src/main.cc:543
+#: src/main.cc:544
 msgid "seed-time must be greater than or equal to 0."
 msgstr "seed-time は 0 以上の数を指定してください."
 
-#: src/main.cc:553
+#: src/main.cc:554
 msgid "seed-ratio must be greater than or equal to 0.0."
 msgstr "seed-ratio は 0.0 以上の数を指定してください."
 
-#: src/main.cc:563
+#: src/main.cc:564
 msgid "max-upload-limit must be greater than or equal to 0"
 msgstr "max-upload-limit は 0 以上の数を指定してください."
 
-#: src/main.cc:585
+#: src/main.cc:586
 msgid "follow-metalink must be either 'true' or 'false'."
 msgstr "follow-metalink は 'true' または 'false を指定してください."
 
-#: src/main.cc:593
+#: src/main.cc:597
 msgid "lowest-speed-limit must be greater than or equal to 0"
 msgstr "lowest-speed-limit は 0 以上の数を指定してください."
 
-#: src/main.cc:603
+#: src/main.cc:607
 msgid "max-download-limit must be greater than or equal to 0"
 msgstr "max-download-limit は 0 以上の数を指定してください."
 
-#: src/main.cc:632
+#: src/main.cc:636
 msgid "split must be between 1 and 5."
 msgstr "split は 1 - 5 の値を指定してください."
 
-#: src/main.cc:645
+#: src/main.cc:649
 msgid "timeout must be between 1 and 600"
 msgstr "timeout は 1 - 600 の値を指定してください."
 
-#: src/main.cc:654
+#: src/main.cc:658
 msgid "max-tries invalid"
 msgstr "max-tries が不正です."
 
-#: src/main.cc:676
+#: src/main.cc:680
 msgid "metalink-servers must be greater than 0."
 msgstr "metalink-servers は 0 以上の数を指定してください."
 
-#: src/main.cc:696
+#: src/main.cc:700
 msgid "specify at least one URL"
 msgstr "一個以上の URL を指定してください."
 
-#: src/main.cc:703
+#: src/main.cc:707
 msgid "daemon failed"
 msgstr "デーモン起動に失敗"
 
-#: src/main.cc:766
+#: src/main.cc:775
 msgid ""
 "Now verifying checksum.\n"
 "This may take some time depending on your PC environment and the size of "
@@ -1019,22 +1009,36 @@ msgstr ""
 "チェックサムを検査しています.\n"
 "お使いの PC 環境とファイルサイズにより, ある程度の時間がかかります."
 
-#: src/main.cc:770
+#: src/main.cc:779
 msgid "checksum OK."
 msgstr "チェックサム OK."
 
-#: src/main.cc:773
+#: src/main.cc:782
 msgid "checksum ERROR."
 msgstr "チェックサム エラー."
 
-#: src/DefaultPieceStorage.cc:219
+#: src/DefaultPieceStorage.cc:220
 msgid "Download of selected files was complete."
 msgstr "ご指定のファイルのダウンロードが完了."
 
-#: src/DefaultPieceStorage.cc:222
+#: src/DefaultPieceStorage.cc:223
 msgid "The download was complete."
 msgstr "ダウンロードが完了."
 
+#: src/ConsoleDownloadEngine.cc:108
+#, c-format
+msgid ""
+"\n"
+"stopping application...\n"
+msgstr ""
+"\n"
+"アプリケーションを終了しています...\n"
+
+#: src/ConsoleDownloadEngine.cc:112
+#, c-format
+msgid "done\n"
+msgstr "完了\n"
+
 #~ msgid ""
 #~ " --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n"
 #~ "                              K or M(1K = 1024, 1M = 1024K). This\n"

二进制
po/ru.gmo


+ 94 - 90
po/ru.po

@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ru\n"
 "Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
-"POT-Creation-Date: 2006-11-06 00:12+0900\n"
+"POT-Creation-Date: 2006-11-09 01:22+0900\n"
 "PO-Revision-Date: 2006-07-28 18:04+0600\n"
 "Last-Translator: Azamat H. Hackimov <azamat.hackimov@gmail.com>\n"
 "Language-Team:  <ru@li.org>\n"
@@ -21,7 +21,7 @@ msgstr ""
 "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
 "X-Generator: KBabel 1.11.2\n"
 
-#: src/RequestInfo.h:97
+#: src/RequestInfo.h:102
 #, c-format
 msgid ""
 "\n"
@@ -30,7 +30,7 @@ msgstr ""
 "\n"
 "Скачивание завершено. <%s>\n"
 
-#: src/RequestInfo.h:105
+#: src/RequestInfo.h:110
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -368,30 +368,16 @@ msgstr "Ошибка при открытии порта.\n"
 msgid "Files:"
 msgstr "Файлы:"
 
-#: src/UrlRequestInfo.cc:76
-#, c-format
-msgid ""
-"\n"
-"stopping application...\n"
-msgstr ""
-"\n"
-"остановка приложения...\n"
-
-#: src/UrlRequestInfo.cc:81
-#, c-format
-msgid "done\n"
-msgstr "завершено\n"
-
-#: src/UrlRequestInfo.cc:105
+#: src/UrlRequestInfo.cc:99
 #, c-format
 msgid "Unrecognized URL or unsupported protocol: %s\n"
 msgstr "Неправильный URL или неподдерживаемый протокол: %s\n"
 
-#: src/main.cc:87
+#: src/main.cc:86
 msgid " version "
 msgstr " версия "
 
-#: src/main.cc:94
+#: src/main.cc:93
 #, fuzzy
 msgid ""
 "This program is free software; you can redistribute it and/or modify\n"
@@ -423,39 +409,39 @@ msgstr ""
 "along with this program; if not, write to the Free Software\n"
 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"
 
-#: src/main.cc:108
+#: src/main.cc:107
 #, c-format
 msgid "Contact Info: %s\n"
 msgstr "Связь с автором: %s\n"
 
-#: src/main.cc:114
+#: src/main.cc:113
 #, c-format
 msgid "Usage: %s [options] URL ...\n"
 msgstr "Использование: %s [параметры] URL ...\n"
 
-#: src/main.cc:116
+#: src/main.cc:115
 #, c-format
 msgid "       %s [options] -T TORRENT_FILE FILE ...\n"
 msgstr "       %s [параметры] -T TORRENT_FILE FILE ...\n"
 
-#: src/main.cc:119
+#: src/main.cc:118
 #, c-format
 msgid "       %s [options] -M METALINK_FILE\n"
 msgstr "       %s [параметры] -M METALINK_FILE\n"
 
-#: src/main.cc:122
+#: src/main.cc:121
 msgid "Options:"
 msgstr "Параметры:"
 
-#: src/main.cc:123
+#: src/main.cc:122
 msgid " -d, --dir=DIR                The directory to store downloaded file."
 msgstr " -d, --dir=DIR                Каталог для сохранения скачанных файлов."
 
-#: src/main.cc:124
+#: src/main.cc:123
 msgid " -o, --out=FILE               The file name for downloaded file."
 msgstr " -o, --out=FILE               Имя файла для скачанного файла."
 
-#: src/main.cc:125
+#: src/main.cc:124
 msgid ""
 " -l, --log=LOG                The file path to store log. If '-' is "
 "specified,\n"
@@ -464,11 +450,11 @@ msgstr ""
 " -l, --log=LOG                Имя файла для логов. Если указано \"-\",\n"
 "                              логи будут выведены в stdout."
 
-#: src/main.cc:127
+#: src/main.cc:126
 msgid " -D, --daemon                 Run as daemon."
 msgstr " -D, --daemon                 Запустить в качестве демона."
 
-#: src/main.cc:128
+#: src/main.cc:127
 msgid ""
 " -s, --split=N                Download a file using N connections. N must "
 "be\n"
@@ -484,7 +470,7 @@ msgstr ""
 "                              Следуя этому, aria2 соединяется к каждому URL\n"
 "                              используя N соединений."
 
-#: src/main.cc:132
+#: src/main.cc:131
 msgid ""
 " --retry-wait=SEC             Set amount of time in second between requests\n"
 "                              for errors. Specify a value between 0 and 60.\n"
@@ -495,12 +481,12 @@ msgstr ""
 "60.\n"
 "                              По умолчанию: 5"
 
-#: src/main.cc:135
+#: src/main.cc:134
 msgid " -t, --timeout=SEC            Set timeout in second. Default: 60"
 msgstr ""
 " -t, --timeout=SEC            Установить таймаут в секундах. По умолчанию: 60"
 
-#: src/main.cc:136
+#: src/main.cc:135
 msgid ""
 " -m, --max-tries=N            Set number of tries. 0 means unlimited.\n"
 "                              Default: 5"
@@ -508,7 +494,7 @@ msgstr ""
 " -m, --max-tries=N            Установить число попыток. 0 означает\n"
 "                              неограниченное число. По умолчанию: 5"
 
-#: src/main.cc:144
+#: src/main.cc:143
 msgid ""
 " --http-proxy=HOST:PORT       Use HTTP proxy server. This affects to all\n"
 "                              URLs."
@@ -517,27 +503,27 @@ msgstr ""
 "на\n"
 "                              все URL."
 
-#: src/main.cc:146
+#: src/main.cc:145
 msgid " --http-user=USER             Set HTTP user. This affects to all URLs."
 msgstr ""
 " --http-user=USER             Установить пользователя для HTTP. Это влияет "
 "на все URL."
 
-#: src/main.cc:147
+#: src/main.cc:146
 msgid ""
 " --http-passwd=PASSWD         Set HTTP password. This affects to all URLs."
 msgstr ""
 " --http-passwd=PASSWD         Установить пароль для HTTP. Это влияет на все "
 "URL."
 
-#: src/main.cc:148
+#: src/main.cc:147
 msgid ""
 " --http-proxy-user=USER       Set HTTP proxy user. This affects to all URLs"
 msgstr ""
 " --http-proxy-user=USER       Установить пользователя для прокси HTTP. Это "
 "влияет на все URL."
 
-#: src/main.cc:149
+#: src/main.cc:148
 msgid ""
 " --http-proxy-passwd=PASSWD   Set HTTP proxy password. This affects to all "
 "URLs."
@@ -545,7 +531,7 @@ msgstr ""
 " --http-proxy-passwd=PASSWD   Установить пароль для прокси HTTP. Это влияет "
 "на все URL."
 
-#: src/main.cc:150
+#: src/main.cc:149
 msgid ""
 " --http-proxy-method=METHOD   Set the method to use in proxy request.\n"
 "                              METHOD is either 'get' or 'tunnel'.\n"
@@ -557,7 +543,7 @@ msgstr ""
 "                              или \"tunnel\".\n"
 "                              По умолчанию: tunnel"
 
-#: src/main.cc:153
+#: src/main.cc:152
 msgid ""
 " --http-auth-scheme=SCHEME    Set HTTP authentication scheme. Currently, "
 "basic\n"
@@ -568,12 +554,12 @@ msgstr ""
 "                              момент доступна только схема \"basic\"\n"
 "                              По умолчанию: basic"
 
-#: src/main.cc:156
+#: src/main.cc:155
 msgid " --referer=REFERER            Set Referer. This affects to all URLs."
 msgstr ""
 " --referer=REFERER            Установить реферер. Это влияет на все URL."
 
-#: src/main.cc:157
+#: src/main.cc:156
 msgid ""
 " --ftp-user=USER              Set FTP user. This affects to all URLs.\n"
 "                              Default: anonymous"
@@ -582,7 +568,7 @@ msgstr ""
 "URL.\n"
 "                              По умолчанию: anonymous"
 
-#: src/main.cc:159
+#: src/main.cc:158
 msgid ""
 " --ftp-passwd=PASSWD          Set FTP password. This affects to all URLs.\n"
 "                              Default: ARIA2USER@"
@@ -590,7 +576,7 @@ msgstr ""
 " --ftp-passwd=PASSWD          Установить пароль FTP. Это влияет на все URL.\n"
 "                              По умолчанию: ARIA2USER@"
 
-#: src/main.cc:161
+#: src/main.cc:160
 msgid ""
 " --ftp-type=TYPE              Set FTP transfer type. TYPE is either "
 "'binary'\n"
@@ -601,11 +587,11 @@ msgstr ""
 "                              или \"binary\", или \"ascii\".\n"
 "                              По умолчанию: binary"
 
-#: src/main.cc:164
+#: src/main.cc:163
 msgid " -p, --ftp-pasv               Use passive mode in FTP."
 msgstr " -p, --ftp-pasv               Использовать пассивный режим для FTP."
 
-#: src/main.cc:165
+#: src/main.cc:164
 msgid ""
 " --ftp-via-http-proxy=METHOD  Use HTTP proxy in FTP. METHOD is either 'get' "
 "or\n"
@@ -617,7 +603,7 @@ msgstr ""
 "                              быть \"get\" или \"tunnel\".\n"
 "                              По умолчанию: tunnel"
 
-#: src/main.cc:168
+#: src/main.cc:167
 #, fuzzy
 msgid ""
 " --lowest-speed-limit=SPEED   Close connection if download speed is lower "
@@ -635,7 +621,7 @@ msgstr ""
 "60.\n"
 "                              По умолчанию: 5"
 
-#: src/main.cc:175
+#: src/main.cc:174
 #, fuzzy
 msgid ""
 " --max-download-limit=SPEED   Set max download speed in bytes per sec.\n"
@@ -648,11 +634,11 @@ msgstr ""
 "60.\n"
 "                              По умолчанию: 5"
 
-#: src/main.cc:180
+#: src/main.cc:179
 msgid " -T, --torrent-file=TORRENT_FILE  The file path to .torrent file."
 msgstr " -T, --torrent-file=TORRENT_FILE  Путь до .torrent-файла."
 
-#: src/main.cc:181
+#: src/main.cc:180
 msgid ""
 " --follow-torrent=true|false  Setting this option to false prevents aria2 "
 "to\n"
@@ -666,13 +652,13 @@ msgstr ""
 "                              файлы.\n"
 "                              По умолчанию: true"
 
-#: src/main.cc:185
+#: src/main.cc:184
 msgid ""
 " -S, --show-files             Print file listing of .torrent file and exit."
 msgstr ""
 " -S, --show-files             Вывести перечисленные .torrent файлы и выйти."
 
-#: src/main.cc:186
+#: src/main.cc:185
 msgid ""
 " --direct-file-mapping=true|false Directly read from and write to each file\n"
 "                              mentioned in .torrent file.\n"
@@ -682,14 +668,14 @@ msgstr ""
 "                              описанный в .torrent-файл.\n"
 "                              По умолчанию: true"
 
-#: src/main.cc:189
+#: src/main.cc:188
 msgid ""
 " --listen-port=PORT           Set port number to listen to for peer "
 "connection."
 msgstr ""
 " --listen-port=PORT           Установить порт для прослушивания соединения."
 
-#: src/main.cc:190
+#: src/main.cc:189
 #, fuzzy
 msgid ""
 " --max-upload-limit=SPEED     Set max upload speed in bytes per sec.\n"
@@ -702,7 +688,7 @@ msgstr ""
 "60.\n"
 "                              По умолчанию: 5"
 
-#: src/main.cc:194
+#: src/main.cc:193
 msgid ""
 " --select-file=INDEX...       Set file to download by specifing its index.\n"
 "                              You can know file index through --show-files\n"
@@ -721,7 +707,7 @@ msgstr ""
 "                              Также вы можете использовать тире (\"1-5\").\n"
 "                              \",\" и \"-\" могут быть использованы вместе."
 
-#: src/main.cc:200
+#: src/main.cc:199
 #, fuzzy
 msgid ""
 " --seed-time=MINUTES          Specify seeding time in minutes. See also\n"
@@ -730,7 +716,7 @@ msgstr ""
 " -m, --max-tries=N            Установить число попыток. 0 означает\n"
 "                              неограниченное число. По умолчанию: 5"
 
-#: src/main.cc:202
+#: src/main.cc:201
 #, fuzzy
 msgid ""
 " --seed-ratio=RATIO           Specify share ratio. Seed completed torrents "
@@ -748,11 +734,11 @@ msgstr ""
 "                              Следуя этому, aria2 соединяется к каждому URL\n"
 "                              используя N соединений."
 
-#: src/main.cc:209
+#: src/main.cc:208
 msgid " -M, --metalink-file=METALINK_FILE The file path to .metalink file."
 msgstr " -M, --metalink-file=METALINK_FILE Путь к .metalink-файлу."
 
-#: src/main.cc:210
+#: src/main.cc:209
 msgid ""
 " -C, --metalink-servers=NUM_SERVERS The number of servers to connect to\n"
 "                              simultaneously. If more than one connection "
@@ -766,19 +752,23 @@ msgstr ""
 "параметр -s.\n"
 "                              По умолчанию: 15"
 
-#: src/main.cc:214
+#: src/main.cc:213
 msgid " --metalink-version=VERSION   The version of file to download."
 msgstr " --metalink-version=VERSION   Версия файла для скачивания."
 
-#: src/main.cc:215
+#: src/main.cc:214
 msgid " --metalink-language=LANGUAGE The language of file to download."
 msgstr " --metalink-language=LANGUAGE Язык файла для скачивания."
 
-#: src/main.cc:216
+#: src/main.cc:215
 msgid ""
 " --metalink-os=OS             The operating system the file is targeted."
 msgstr " --metalink-os=OS             Целевая операционная система файла."
 
+#: src/main.cc:216
+msgid " --metalink-location=LOCATION The location of the prefered server."
+msgstr ""
+
 #: src/main.cc:217
 msgid ""
 " --follow-metalink=true|false  Setting this option to false prevents aria2 "
@@ -870,130 +860,144 @@ msgstr " Скачивание metalink с настройками:"
 msgid "Report bugs to %s"
 msgstr "Сообщения об ошибках направляйте на адрес %s"
 
-#: src/main.cc:403
+#: src/main.cc:404
 msgid "unrecognized proxy format"
 msgstr "неизвестный формат прокси"
 
-#: src/main.cc:430
+#: src/main.cc:431
 msgid "Currently, supported authentication scheme is basic."
 msgstr "Поддерживаемая схема аутентификации - \"basic\"."
 
-#: src/main.cc:439
+#: src/main.cc:440
 msgid "retry-wait must be between 0 and 60."
 msgstr "retry-wait должен быть в пределах 0..60"
 
-#: src/main.cc:456
+#: src/main.cc:457
 msgid "ftp-type must be either 'binary' or 'ascii'."
 msgstr "ftp-type должен быть \"binary\" или \"ascii\"."
 
-#: src/main.cc:465
+#: src/main.cc:466
 msgid "ftp-via-http-proxy must be either 'get' or 'tunnel'."
 msgstr "ftp-via-http-proxy должен быть \"get\" или \"tunnel\"."
 
-#: src/main.cc:473
+#: src/main.cc:474
 msgid "min-segment-size invalid"
 msgstr "min-segment-size неверен"
 
-#: src/main.cc:484
+#: src/main.cc:485
 msgid "http-proxy-method must be either 'get' or 'tunnel'."
 msgstr "http-proxy-method должен быть \"get\" или \"tunnel\"."
 
-#: src/main.cc:492
+#: src/main.cc:493
 msgid "listen-port must be between 1024 and 65535."
 msgstr "listen-port должен быть в пределах 1024..65535."
 
-#: src/main.cc:505
+#: src/main.cc:506
 msgid "follow-torrent must be either 'true' or 'false'."
 msgstr "follow-torrent должен быть 'true' или 'false'."
 
-#: src/main.cc:519
+#: src/main.cc:520
 msgid "direct-file-mapping must be either 'true' or 'false'."
 msgstr "direct-file-mapping должен быть 'true' или 'false'."
 
-#: src/main.cc:530
+#: src/main.cc:531
 msgid "upload-limit must be greater than or equal to 0."
 msgstr "upload-limit должен быть не меньше 0."
 
-#: src/main.cc:543
+#: src/main.cc:544
 #, fuzzy
 msgid "seed-time must be greater than or equal to 0."
 msgstr "upload-limit должен быть не меньше 0."
 
-#: src/main.cc:553
+#: src/main.cc:554
 #, fuzzy
 msgid "seed-ratio must be greater than or equal to 0.0."
 msgstr "upload-limit должен быть не меньше 0."
 
-#: src/main.cc:563
+#: src/main.cc:564
 #, fuzzy
 msgid "max-upload-limit must be greater than or equal to 0"
 msgstr "upload-limit должен быть не меньше 0."
 
-#: src/main.cc:585
+#: src/main.cc:586
 msgid "follow-metalink must be either 'true' or 'false'."
 msgstr "follow-metalink должен быть 'true' или 'false'."
 
-#: src/main.cc:593
+#: src/main.cc:597
 #, fuzzy
 msgid "lowest-speed-limit must be greater than or equal to 0"
 msgstr "upload-limit должен быть не меньше 0."
 
-#: src/main.cc:603
+#: src/main.cc:607
 #, fuzzy
 msgid "max-download-limit must be greater than or equal to 0"
 msgstr "upload-limit должен быть не меньше 0."
 
-#: src/main.cc:632
+#: src/main.cc:636
 msgid "split must be between 1 and 5."
 msgstr "split должен быть находится в пределах 1..5."
 
-#: src/main.cc:645
+#: src/main.cc:649
 msgid "timeout must be between 1 and 600"
 msgstr "таймаут должен быть в пределах 1..600"
 
-#: src/main.cc:654
+#: src/main.cc:658
 msgid "max-tries invalid"
 msgstr "неверный max-tries"
 
-#: src/main.cc:676
+#: src/main.cc:680
 msgid "metalink-servers must be greater than 0."
 msgstr "metalink-servers должен быть больше 0"
 
-#: src/main.cc:696
+#: src/main.cc:700
 msgid "specify at least one URL"
 msgstr "укажите по крайней мере один URL"
 
-#: src/main.cc:703
+#: src/main.cc:707
 msgid "daemon failed"
 msgstr "ошибка демона"
 
-#: src/main.cc:766
+#: src/main.cc:775
 msgid ""
 "Now verifying checksum.\n"
 "This may take some time depending on your PC environment and the size of "
 "file."
 msgstr ""
 
-#: src/main.cc:770
+#: src/main.cc:779
 msgid "checksum OK."
 msgstr ""
 
-#: src/main.cc:773
+#: src/main.cc:782
 msgid "checksum ERROR."
 msgstr ""
 
-#: src/DefaultPieceStorage.cc:219
+#: src/DefaultPieceStorage.cc:220
 #, fuzzy
 msgid "Download of selected files was complete."
 msgstr " Скачать только выбранные файлы:"
 
-#: src/DefaultPieceStorage.cc:222
+#: src/DefaultPieceStorage.cc:223
 #, fuzzy
 msgid "The download was complete."
 msgstr ""
 "\n"
 "Скачивание завершено. <%s>\n"
 
+#: src/ConsoleDownloadEngine.cc:108
+#, c-format
+msgid ""
+"\n"
+"stopping application...\n"
+msgstr ""
+"\n"
+"остановка приложения...\n"
+
+#: src/ConsoleDownloadEngine.cc:112
+#, c-format
+msgid "done\n"
+msgstr "завершено\n"
+
 #, fuzzy
 #~ msgid ""
 #~ " --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n"

+ 14 - 0
src/ConsoleDownloadEngine.cc

@@ -34,6 +34,9 @@
 /* copyright --> */
 #include "ConsoleDownloadEngine.h"
 #include "Util.h"
+#include <signal.h>
+
+volatile sig_atomic_t haltRequested = 0;
 
 ConsoleDownloadEngine::ConsoleDownloadEngine() {}
 
@@ -99,3 +102,14 @@ void ConsoleDownloadEngine::onEndOfRun() {
     segmentMan->save();
   }
 }
+
+void ConsoleDownloadEngine::afterEachIteration() {
+  if(haltRequested) {
+    printf(_("\nstopping application...\n"));
+    fflush(stdout);
+    segmentMan->save();
+    segmentMan->diskWriter->closeFile();
+    printf(_("done\n"));
+    exit(EXIT_SUCCESS);
+  }
+}

+ 4 - 3
src/ConsoleDownloadEngine.h

@@ -54,9 +54,10 @@ private:
   int eta;
 protected:
   void sendStatistics(long long int currentSize, long long int totalSize);
-  void initStatistics();
-  void calculateStatistics();
-  void onEndOfRun();
+  virtual void initStatistics();
+  virtual void calculateStatistics();
+  virtual void onEndOfRun();
+  virtual void afterEachIteration();
 public:
   ConsoleDownloadEngine();
   ~ConsoleDownloadEngine();

+ 6 - 4
src/CopyDiskAdaptor.cc

@@ -50,10 +50,12 @@ void CopyDiskAdaptor::fixFilename() {
   for(FileEntries::iterator itr = fileEntries.begin();
       itr != fileEntries.end(); itr++) {
     if(!(*itr)->isExtracted() && (*itr)->isRequested()) {
-      (*itr)->setupDir(storeDir);
-      string dest = storeDir+"/"+(*itr)->getPath();
-      logger->info("writing file %s", dest.c_str());
-      Util::rangedFileCopy(dest, getFilePath(), offset, (*itr)->getLength());
+      string topDirPath = storeDir+"/"+topDir;
+      (*itr)->setupDir(topDirPath);
+      string destFilePath = topDirPath+"/"+(*itr)->getPath();
+      logger->info("writing file %s", destFilePath.c_str());
+      Util::rangedFileCopy(destFilePath, getFilePath(),
+			   offset, (*itr)->getLength());
       (*itr)->setExtracted(true);
     }
     offset += (*itr)->getLength();

+ 10 - 0
src/CopyDiskAdaptor.h

@@ -41,6 +41,8 @@
 class CopyDiskAdaptor : public DiskAdaptor {
 private:
   string tempFilename;
+  string topDir;
+
   void fixFilename();
 protected:
   string getFilePath() const;
@@ -55,6 +57,14 @@ public:
     this->tempFilename = tempFilename;
   }
   string getTempFile() const { return this->tempFilename; }
+
+  void setTopDir(const string& topDir) {
+    this->topDir = topDir;
+  }
+
+  const string& getTopDir() const {
+    return topDir;
+  }
 };
 
 #endif // _D_COPY_DISK_ADAPTOR_H_

+ 5 - 3
src/DefaultPieceStorage.cc

@@ -45,6 +45,7 @@
 
 DefaultPieceStorage::DefaultPieceStorage(BtContextHandle btContext, const Option* option):
   btContext(btContext),
+  diskAdaptor(0),
   endGamePieceNum(END_GAME_PIECE_NUM),
   option(option)
 {
@@ -349,18 +350,19 @@ void DefaultPieceStorage::initStorage() {
       diskAdaptor = new DirectDiskAdaptor(new DefaultDiskWriter(btContext->getTotalLength()));
     } else {
       diskAdaptor = new MultiDiskAdaptor(new MultiDiskWriter(btContext->getPieceLength()));
+      ((MultiDiskAdaptor*)diskAdaptor)->setTopDir(btContext->getName());
     }
   } else {
     diskAdaptor = new CopyDiskAdaptor(new PreAllocationDiskWriter(btContext->getTotalLength()));
     ((CopyDiskAdaptor*)diskAdaptor)->setTempFilename(btContext->getName()+".a2tmp");
+    if(btContext->getFileMode() == BtContext::MULTI) {
+      ((CopyDiskAdaptor*)diskAdaptor)->setTopDir(btContext->getName());
+    }
   }
   string storeDir = option->get(PREF_DIR);
   if(storeDir == "") {
     storeDir = ".";
   }
-  if(btContext->getFileMode() == BtContext::MULTI) {
-    storeDir += "/"+btContext->getName();
-  }
   diskAdaptor->setStoreDir(storeDir);
   diskAdaptor->setFileEntries(btContext->getFileEntries());
 }

+ 5 - 2
src/DownloadCommand.cc

@@ -47,9 +47,12 @@ DownloadCommand::DownloadCommand(int cuid,
 				 DownloadEngine* e,
 				 const SocketHandle& s):
   AbstractCommand(cuid, req, e, s), lastSize(0) {
-  PeerStatHandle peerStat = PeerStatHandle(new PeerStat(cuid));
+  PeerStatHandle peerStat = this->e->segmentMan->getPeerStat(cuid);
+  if(!peerStat.get()) {
+    peerStat = PeerStatHandle(new PeerStat(cuid));
+    this->e->segmentMan->registerPeerStat(peerStat);
+  }
   peerStat->downloadStart();
-  this->e->segmentMan->registerPeerStat(peerStat);
 }
 
 DownloadCommand::~DownloadCommand() {

+ 3 - 0
src/FtpConnection.cc

@@ -161,6 +161,9 @@ bool FtpConnection::bulkReceiveResponse(pair<int, string>& response) {
   while(socket->isReadable(0)) {
     int size = sizeof(buf)-1;
     socket->readData(buf, size);
+    if(size == 0) {
+      throw new DlRetryEx(EX_GOT_EOF);
+    }
     buf[size] = '\0';
     strbuf += buf;
   }

+ 1 - 2
src/HandshakeMessage.cc

@@ -92,8 +92,7 @@ string HandshakeMessage::toString() const {
 }
 
 void HandshakeMessage::check() const {
-  PeerMessageUtil::checkHandshake(this,
-				  peerInteraction->getBtContext()->getInfoHash());
+  PeerMessageUtil::checkHandshake(this, btContext->getInfoHash());
 }
 
 bool HandshakeMessage::isFastExtensionSupported() const {

+ 23 - 5
src/MetalinkEntry.cc

@@ -38,13 +38,32 @@
 
 MetalinkEntry::MetalinkEntry() {}
 
-MetalinkEntry::~MetalinkEntry() {
-  for_each(resources.begin(), resources.end(), Deleter());
+MetalinkEntry::~MetalinkEntry() {}
+
+class AddLocationPreference {
+private:
+  string location;
+  int preferenceToAdd;
+public:
+  AddLocationPreference(const string& location, int preferenceToAdd):
+    location(location), preferenceToAdd(preferenceToAdd) {}
+
+  void operator()(MetalinkResourceHandle& res) {
+    if(res->location == location) {
+      res->preference += preferenceToAdd;
+    }
+  }
+};
+
+void MetalinkEntry::setLocationPreference(const string& location, int preferenceToAdd) {
+  for_each(resources.begin(), resources.end(),
+	   AddLocationPreference(location, preferenceToAdd));
 }
 
 class PrefOrder {
 public:
-  bool operator()(const MetalinkResource* res1, const MetalinkResource* res2) {
+  bool operator()(const MetalinkResourceHandle& res1,
+		  const MetalinkResourceHandle& res2) {
     return res1->preference > res2->preference;
   }
 };
@@ -56,7 +75,7 @@ void MetalinkEntry::reorderResourcesByPreference() {
 
 class Supported {
 public:
-  bool operator()(const MetalinkResource* res) {
+  bool operator()(const MetalinkResourceHandle& res) {
     switch(res->type) {
     case MetalinkResource::TYPE_FTP:
     case MetalinkResource::TYPE_HTTP:
@@ -74,6 +93,5 @@ public:
 void MetalinkEntry::dropUnsupportedResource() {
   MetalinkResources::iterator split =
     partition(resources.begin(), resources.end(), Supported());
-  for_each(split, resources.end(), Deleter());
   resources.erase(split, resources.end());
 }

+ 5 - 2
src/MetalinkEntry.h

@@ -40,8 +40,6 @@
 #include "Checksum.h"
 #include <deque>
 
-typedef deque<MetalinkResource*> MetalinkResources;
-
 class MetalinkEntry {
 public:
   string filename;
@@ -71,6 +69,11 @@ public:
   void dropUnsupportedResource();
 
   void reorderResourcesByPreference();
+  
+  void setLocationPreference(const string& location, int preferenceToAdd);
 };
 
+typedef SharedHandle<MetalinkEntry> MetalinkEntryHandle;
+typedef deque<MetalinkEntryHandle> MetalinkEntries;
+
 #endif // _D_METALINK_ENTRY_H_

+ 1 - 1
src/MetalinkProcessor.h

@@ -42,7 +42,7 @@ class MetalinkProcessor {
 public:
   virtual ~MetalinkProcessor() {}
 
-  virtual Metalinker* parseFile(const string& filename) = 0;
+  virtual MetalinkerHandle parseFile(const string& filename) = 0;
 };
 
 #endif // _D_METALINK_PROCESSOR_H_

+ 46 - 36
src/MetalinkRequestInfo.cc

@@ -48,7 +48,7 @@ public:
     :urlsPtr(urlsPtr),
      split(split) {}
 
-  void operator()(const MetalinkResource* resource) {
+  void operator()(const MetalinkResourceHandle& resource) {
     switch(resource->type) {
     case MetalinkResource::TYPE_HTTP:
     case MetalinkResource::TYPE_HTTPS:
@@ -65,7 +65,7 @@ class FindBitTorrentUrl {
 public:
   FindBitTorrentUrl() {}
 
-  bool operator()(const MetalinkResource* resource) {
+  bool operator()(const MetalinkResourceHandle& resource) {
     if(resource->type == MetalinkResource::TYPE_BITTORRENT) {
       return true;
     } else {
@@ -74,51 +74,61 @@ public:
   }
 };
 
-RequestInfo* MetalinkRequestInfo::execute() {
-  RequestInfo* next = 0;
+RequestInfos MetalinkRequestInfo::execute() {
   Xml2MetalinkProcessor proc;
-  Metalinker* metalinker = 0;
+  RequestInfos nextReqInfos;
   try {
-    metalinker = proc.parseFile(metalinkFile);
-    
-    MetalinkEntry* entry =
+    MetalinkerHandle metalinker = proc.parseFile(metalinkFile);
+    MetalinkEntries entries =
       metalinker->queryEntry(op->get(PREF_METALINK_VERSION),
 			     op->get(PREF_METALINK_LANGUAGE),
 			     op->get(PREF_METALINK_OS));
-    if(entry == 0) {
+    if(entries.size() == 0) {
       printf("No file matched with your preference.\n");
       throw new DlAbortEx("No file matched with your preference.");
     }
-    entry->dropUnsupportedResource();
-    MetalinkResources::iterator itr =
-      find_if(entry->resources.begin(),
-	      entry->resources.end(),
-	      FindBitTorrentUrl());
-    Strings urls;
-    int maxConnection = 0;
-    Checksum checksum;
-    if(itr == entry->resources.end()) {
-      entry->reorderResourcesByPreference();
+    for(MetalinkEntries::iterator itr = entries.begin(); itr != entries.end();
+	itr++) {
+      MetalinkEntryHandle& entry = *itr;
+      if(op->defined(PREF_METALINK_LOCATION)) {
+	entry->setLocationPreference(op->get(PREF_METALINK_LOCATION), 100);
+      }
+      entry->dropUnsupportedResource();
+      if(entry->resources.size() == 0) {
+	continue;
+      }
+      logger->notice("Metalink: Queueing %s for download.",
+		     entry->filename.c_str());
+      MetalinkResources::iterator itr =
+	find_if(entry->resources.begin(),
+		entry->resources.end(),
+		FindBitTorrentUrl());
+      Strings urls;
+      int maxConnection = 0;
+      Checksum checksum;
+      if(itr == entry->resources.end()) {
+	entry->reorderResourcesByPreference();
 	
-      for_each(entry->resources.begin(), entry->resources.end(),
-	       AccumulateNonP2PUrl(&urls, op->getAsInt(PREF_SPLIT)));
-      maxConnection =
-	op->getAsInt(PREF_METALINK_SERVERS)*op->getAsInt(PREF_SPLIT);
+	for_each(entry->resources.begin(), entry->resources.end(),
+		 AccumulateNonP2PUrl(&urls, op->getAsInt(PREF_SPLIT)));
+	maxConnection =
+	  op->getAsInt(PREF_METALINK_SERVERS)*op->getAsInt(PREF_SPLIT);
 	
-      // TODO
-      // set checksum
-      checksum = entry->checksum;
-    } else {
-      // BitTorrent downloading
-      urls.push_back((*itr)->url);
+	// TODO
+	// set checksum
+	checksum = entry->checksum;
+      } else {
+	// BitTorrent downloading
+	urls.push_back((*itr)->url);
+      }
+      RequestInfoHandle reqInfo(new UrlRequestInfo(urls, maxConnection, op));
+      reqInfo->setChecksum(checksum);
+      nextReqInfos.push_front(reqInfo);
     }
-    next = new UrlRequestInfo(urls, maxConnection, op);
-    next->setChecksum(checksum);
-  } catch(Exception* e) {
-    logger->error("Exception caught", e);
-    delete e;
+  } catch(Exception* ex) {
+    logger->error("Exception caught", ex);
+    delete ex;
     fail = true;
   }
-  delete metalinker;
-  return next;
+  return nextReqInfos;
 }

+ 1 - 3
src/MetalinkRequestInfo.h

@@ -46,9 +46,7 @@ public:
     metalinkFile(metalinkFile) {}
   virtual ~MetalinkRequestInfo() {}
 
-  virtual RequestInfo* execute();
-
-  virtual DownloadEngine* getDownloadEngine() { return 0; }
+  virtual RequestInfos execute();
 };
 
 #endif // _D_METALINK_REQUEST_INFO_H_

+ 3 - 0
src/MetalinkResource.h

@@ -66,4 +66,7 @@ public:
   }
 };
 
+typedef SharedHandle<MetalinkResource> MetalinkResourceHandle;
+typedef deque<MetalinkResourceHandle> MetalinkResources;
+
 #endif // _D_METALINK_RESOURCE_H_

+ 16 - 18
src/Metalinker.cc

@@ -38,9 +38,7 @@
 Metalinker::Metalinker() {
 }
 
-Metalinker::~Metalinker() {
-  for_each(entries.begin(), entries.end(), Deleter());
-}
+Metalinker::~Metalinker() {}
 
 class EntryQuery {
 private:
@@ -50,10 +48,12 @@ private:
 public:
   EntryQuery(const string& version,
 	     const string& language,
-	     const string& os):version(version),
-			       language(language),
-			       os(os) {}
-  bool operator()(const MetalinkEntry* entry) {
+	     const string& os):
+    version(version),
+    language(language),
+    os(os) {}
+
+  bool operator()(const MetalinkEntryHandle& entry) {
     if(!version.empty()) {
       if(version != entry->version) {
 	return false;
@@ -73,15 +73,13 @@ public:
   }
 };
 
-MetalinkEntry* Metalinker::queryEntry(const string& version,
-				      const string& language,
-				      const string& os) const {
-  MetalinkEntries::const_iterator itr =
-    find_if(entries.begin(), entries.end(),
-	    EntryQuery(version, language, os));
-  if(itr == entries.end()) {
-    return NULL;
-  } else {
-    return *itr;
-  }
+MetalinkEntries Metalinker::queryEntry(const string& version,
+				       const string& language,
+				       const string& os) const {
+  MetalinkEntries resultEntries(entries.begin(), entries.end());
+  MetalinkEntries::iterator split =
+    partition(resultEntries.begin(), resultEntries.end(),
+	      EntryQuery(version, language, os));
+  resultEntries.erase(split, resultEntries.end());
+  return resultEntries;
 }

+ 5 - 5
src/Metalinker.h

@@ -40,12 +40,9 @@
 #include <deque>
 #include <libxml/xpath.h>
 
-typedef deque<MetalinkEntry*> MetalinkEntries;
-
 class Metalinker {
 public:
   MetalinkEntries entries;
-
 public:
   Metalinker();
   ~Metalinker();
@@ -57,8 +54,11 @@ public:
     return *this;
   }
 
-  MetalinkEntry* queryEntry(const string& version, const string& language,
-			    const string& os) const;
+  MetalinkEntries queryEntry(const string& version,
+			     const string& language,
+			     const string& os) const;
 };
 
+typedef SharedHandle<Metalinker> MetalinkerHandle;
+
 #endif // _D_METALINKER_H_

+ 2 - 2
src/MultiDiskAdaptor.cc

@@ -43,13 +43,13 @@ void MultiDiskAdaptor::setDiskWriterFileEntries() {
 }
 
 string MultiDiskAdaptor::getFilePath() const {
-  return storeDir;
+  return storeDir+"/"+topDir;
 }
 
 void MultiDiskAdaptor::mkdir() const {
   for(FileEntries::const_iterator itr = fileEntries.begin();
       itr != fileEntries.end(); itr++) {
-    (*itr)->setupDir(storeDir);
+    (*itr)->setupDir(getFilePath());
   }
 }
 

+ 10 - 0
src/MultiDiskAdaptor.h

@@ -40,6 +40,8 @@
 
 class MultiDiskAdaptor : public DiskAdaptor {
 private:
+  string topDir;
+
   void setDiskWriterFileEntries();
   void mkdir() const;
 protected:
@@ -48,6 +50,14 @@ public:
   MultiDiskAdaptor(MultiDiskWriter* diskWriter);
   virtual ~MultiDiskAdaptor();
 
+  void setTopDir(const string& topDir) {
+    this->topDir = topDir;
+  }
+
+  const string& getTopDir() const {
+    return topDir;
+  }
+
   virtual void openFile();
   virtual void initAndOpenFile();
   virtual void openExistingFile();

+ 2 - 2
src/PeerChokeCommand.cc

@@ -136,11 +136,11 @@ bool PeerChokeCommand::execute() {
 	peer->optUnchoking = false;
 	itr = peers.erase(itr);
 	if(pieceStorage->downloadFinished()) {
-	  logger->debug("cat01, unchoking %s, upload speed=%d",
+	  logger->debug("cat02, unchoking %s, upload speed=%d",
 			peer->ipaddr.c_str(),
 			peer->calculateUploadSpeed());
 	} else {
-	  logger->debug("cat01, unchoking %s, download speed=%d",
+	  logger->debug("cat02, unchoking %s, download speed=%d",
 			peer->ipaddr.c_str(),
 			peer->calculateDownloadSpeed());
 	}

+ 0 - 2
src/PeerInteraction.h

@@ -96,8 +96,6 @@ public:
 
   int countMessageInQueue() const;
 
-  BtContextHandle getBtContext() const { return btContext; }
-
   PeerConnection* getPeerConnection() const { return peerConnection; }
 
   // If this object has nullPiece, then return false, otherwise true

+ 7 - 7
src/PeerStat.h

@@ -51,10 +51,10 @@ private:
   SpeedCalc downloadSpeed;
   SpeedCalc uploadSpeed;
   Time downloadStartTime;
-  STATUS status;
+  PeerStat::STATUS status;
 public:
 
-  PeerStat(int cuid = 0):cuid(cuid), status(IDLE) {}
+  PeerStat(int cuid = 0):cuid(cuid), status(PeerStat::IDLE) {}
 
   ~PeerStat() {}
 
@@ -97,27 +97,27 @@ public:
     downloadSpeed.reset();
     uploadSpeed.reset();
     downloadStartTime.reset();
-    status = IDLE;
+    status = PeerStat::IDLE;
   }
 
   void downloadStart() {
     reset();
-    status = ACTIVE;
+    status = PeerStat::ACTIVE;
   }
 
   void downloadStop() {
-    status = IDLE;
+    status = PeerStat::IDLE;
   }
 
   void requestIdle() {
-    status = REQUEST_IDLE;
+    status = PeerStat::REQUEST_IDLE;
   }
 
   const Time& getDownloadStartTime() const {
     return downloadStartTime;
   }
 
-  STATUS getStatus() const {
+  PeerStat::STATUS getStatus() const {
     return status;
   }
 

+ 6 - 3
src/RequestInfo.h

@@ -85,6 +85,11 @@ public:
   }
 };
 
+class RequestInfo;
+
+typedef SharedHandle<RequestInfo> RequestInfoHandle;
+typedef deque<RequestInfoHandle> RequestInfos;
+
 class RequestInfo {
 protected:
   Option* op;
@@ -115,9 +120,7 @@ public:
   }
   virtual ~RequestInfo() {}
 
-  virtual RequestInfo* execute() = 0;
-
-  virtual DownloadEngine* getDownloadEngine() = 0;
+  virtual RequestInfos execute() = 0;
 
   bool isFail() const { return fail; }
 

+ 5 - 5
src/SegmentMan.cc

@@ -307,13 +307,13 @@ SegmentEntryHandle SegmentMan::findSlowerSegmentEntry(const PeerStatHandle& peer
       continue;
     }
     PeerStatHandle p = getPeerStat(segmentEntry->cuid);
-    if(!p.get() || p->getCuid() == peerStat->getCuid()) {
+    if(!p.get() || p->getCuid() == peerStat->getCuid() ||
+       p->getStatus() != PeerStat::ACTIVE ||
+       !p->getDownloadStartTime().elapsed(option->getAsInt(PREF_STARTUP_IDLE_TIME))) {
       continue;
     }
-    int pSpeed = p->calculateDownloadSpeed();
-    if(p->getStatus() == PeerStat::ACTIVE &&
-       p->getDownloadStartTime().elapsed(option->getAsInt(PREF_STARTUP_IDLE_TIME)) &&
-       pSpeed < speed) {
+    int pSpeed = p->calculateDownloadSpeed(); 
+    if(pSpeed < speed) {
       speed = pSpeed;
       slowSegmentEntry = segmentEntry;
     }

+ 2 - 2
src/TorrentConsoleDownloadEngine.cc

@@ -36,7 +36,7 @@
 #include "Util.h"
 #include <signal.h>
 
-volatile sig_atomic_t haltRequested = 0;
+volatile sig_atomic_t btHaltRequested = 0;
 
 TorrentConsoleDownloadEngine::TorrentConsoleDownloadEngine() {}
 
@@ -64,7 +64,7 @@ void TorrentConsoleDownloadEngine::sendStatistics() {
 }
 
 void TorrentConsoleDownloadEngine::afterEachIteration() {
-  if(haltRequested) {
+  if(btHaltRequested) {
     btRuntime->setHalt(true);
   }
   TorrentDownloadEngine::afterEachIteration();

+ 5 - 5
src/TorrentRequestInfo.cc

@@ -42,19 +42,19 @@
 extern RequestInfo* requestInfo;
 extern void setSignalHander(int signal, void (*handler)(int), int flags);
 extern bool timeoutSpecified;
-extern volatile sig_atomic_t haltRequested;
+extern volatile sig_atomic_t btHaltRequested;
 
 void torrentHandler(int signal) {
-  haltRequested = 1;
+  btHaltRequested = 1;
 }
 
-RequestInfo* TorrentRequestInfo::execute() {
+RequestInfos TorrentRequestInfo::execute() {
   BtContextHandle btContext(new DefaultBtContext());
   btContext->load(torrentFile);
   
   if(op->get(PREF_SHOW_FILES) == V_TRUE) {
     showFileEntry(btContext);
-    return 0;
+    return RequestInfos();
   }
   if(!timeoutSpecified) {
     op->put(PREF_TIMEOUT, "180");
@@ -82,7 +82,7 @@ RequestInfo* TorrentRequestInfo::execute() {
   setSignalHander(SIGINT, SIG_DFL, 0);
   setSignalHander(SIGTERM, SIG_DFL, 0);
   
-  return 0;
+  return RequestInfos();
 }
 
 void TorrentRequestInfo::showFileEntry(const BtContextHandle& btContext)

+ 1 - 5
src/TorrentRequestInfo.h

@@ -52,15 +52,11 @@ public:
 
   virtual ~TorrentRequestInfo() {}
 
-  virtual RequestInfo* execute();
+  virtual RequestInfos execute();
 
   void setTargetFiles(const Strings& targetFiles) {
     this->targetFiles = targetFiles;
   }
-
-  virtual DownloadEngine* getDownloadEngine() {
-    return 0;
-  }
 };
 
 #endif // _D_TORRENT_REQUEST_INFO_H_

+ 2 - 6
src/TrackerUpdateCommand.cc

@@ -83,7 +83,7 @@ char* TrackerUpdateCommand::getTrackerResponse(size_t& trackerResponseLength) {
 }
 
 bool TrackerUpdateCommand::execute() {
-  if(e->segmentMan->errors > 0 && btRuntime->isHalt()) {
+  if(btAnnounce->noMoreAnnounce()) {
     return true;
   }
   if(!e->segmentMan->finished()) {
@@ -123,10 +123,6 @@ bool TrackerUpdateCommand::execute() {
   if(trackerResponse) {
     delete [] trackerResponse;
   }
-  if(btRuntime->isHalt()) {
-    return true;
-  } else {
-    return prepareForRetry();
-  }
+  return prepareForRetry();
 }
 

+ 1 - 3
src/TrackerWatcherCommand.cc

@@ -49,9 +49,7 @@ TrackerWatcherCommand::~TrackerWatcherCommand() {}
 
 
 bool TrackerWatcherCommand::execute() {
-  if(btRuntime->isHalt() &&
-     e->segmentMan->errors > 0 && btAnnounce->isAllAnnounceFailed() ||
-     btAnnounce->noMoreAnnounce()) {
+  if(btAnnounce->noMoreAnnounce()) {
     return true;
   }
   Command* command = createCommand();

+ 19 - 17
src/UrlRequestInfo.cc

@@ -38,8 +38,8 @@
 #include "prefs.h"
 #include "DownloadEngineFactory.h"
 
-extern RequestInfo* requestInfo;
 extern void setSignalHander(int signal, void (*handler)(int), int flags);
+extern volatile sig_atomic_t haltRequested;
 
 void UrlRequestInfo::adjustRequestSize(Requests& requests,
 				       Requests& reserved,
@@ -73,13 +73,7 @@ RequestInfo* UrlRequestInfo::createNextRequestInfo() const
 }
 
 void handler(int signal) {
-  printf(_("\nstopping application...\n"));
-  fflush(stdout);
-  requestInfo->getDownloadEngine()->segmentMan->save();
-  requestInfo->getDownloadEngine()->segmentMan->diskWriter->closeFile();
-  delete requestInfo->getDownloadEngine();
-  printf(_("done\n"));
-  exit(EXIT_SUCCESS);
+  haltRequested = true;
 }
 
 class CreateRequest {
@@ -109,9 +103,16 @@ public:
   }
 };
 
-RequestInfo* UrlRequestInfo::execute() {
+void UrlRequestInfo::printUrls(const Strings& urls) const {
+  for(Strings::const_iterator itr = urls.begin(); itr != urls.end(); itr++) {
+    logger->notice("Adding URL: %s", itr->c_str());
+  }
+}
+
+RequestInfos UrlRequestInfo::execute() {
   Requests requests;
   Requests reserved;
+  printUrls(urls);
   for_each(urls.begin(), urls.end(),
 	   CreateRequest(&requests,
 			 op->get(PREF_REFERER),
@@ -119,7 +120,7 @@ RequestInfo* UrlRequestInfo::execute() {
   
   adjustRequestSize(requests, reserved, maxConnections);
   
-  e = DownloadEngineFactory::newConsoleEngine(op, requests, reserved);
+  SharedHandle<ConsoleDownloadEngine> e(DownloadEngineFactory::newConsoleEngine(op, requests, reserved));
   
   setSignalHander(SIGINT, handler, 0);
   setSignalHander(SIGTERM, handler, 0);
@@ -140,16 +141,17 @@ RequestInfo* UrlRequestInfo::execute() {
       e->segmentMan->diskWriter->closeFile();
       printDownloadAbortMessage();
     }
-  } catch(Exception *e) {
-    logger->error("Exception caught", e);
-    delete e;
+  } catch(Exception *ex) {
+    logger->error("Exception caught", ex);
+    delete ex;
     fail = true;
   }
+  RequestInfos nextReqInfos;
+  if(next) {
+    nextReqInfos.push_front(next);
+  }
   setSignalHander(SIGINT, SIG_DFL, 0);
   setSignalHander(SIGTERM, SIG_DFL, 0);
   
-  delete e;
-  e = 0;
-  
-  return next;
+  return nextReqInfos;
 }

+ 4 - 9
src/UrlRequestInfo.h

@@ -41,25 +41,20 @@ class UrlRequestInfo : public RequestInfo {
 private:
   Strings urls;
   int maxConnections;
-  DownloadEngine* e;
-
   RequestInfo* createNextRequestInfo() const;
   void adjustRequestSize(Requests& requests,
 			 Requests& reserved,
 			 int maxConnections) const;
+  void printUrls(const Strings& urls) const;
 public:
   UrlRequestInfo(const Strings& urls, int maxConnections, Option* op):
     RequestInfo(op),
     urls(urls),
-    maxConnections(maxConnections),
-    e(0) {}
-  virtual ~UrlRequestInfo() {}
+    maxConnections(maxConnections) {}
 
-  virtual RequestInfo* execute();
+  virtual ~UrlRequestInfo() {}
 
-  virtual DownloadEngine* getDownloadEngine() {
-    return e;
-  }
+  virtual RequestInfos execute();
 };
 
 #endif // _D_URL_REQUEST_INFO_H_

+ 81 - 83
src/Xml2MetalinkProcessor.cc

@@ -39,7 +39,7 @@
 #include <libxml/xpath.h>
 #include <libxml/xpathInternals.h>
 
-Xml2MetalinkProcessor::Xml2MetalinkProcessor():doc(NULL), context(NULL) {}
+Xml2MetalinkProcessor::Xml2MetalinkProcessor():doc(0), context(0) {}
 
 Xml2MetalinkProcessor::~Xml2MetalinkProcessor() {
   release();
@@ -48,141 +48,139 @@ Xml2MetalinkProcessor::~Xml2MetalinkProcessor() {
 void Xml2MetalinkProcessor::release() {
   if(context) {
     xmlXPathFreeContext(context);
-    context = NULL;
+    context = 0;
   }
   if(doc) {
     xmlFreeDoc(doc);
-    doc = NULL;
+    doc = 0;
   }
 }
 
-Metalinker* Xml2MetalinkProcessor::parseFile(const string& filename) {
+MetalinkerHandle Xml2MetalinkProcessor::parseFile(const string& filename) {
   release();
   doc = xmlParseFile(filename.c_str());
-  if(doc == NULL) {
+  if(!doc) {
     throw new DlAbortEx("Cannot parse metalink file %s", filename.c_str());
   }
   context = xmlXPathNewContext(doc);
-  if(context == NULL) {
+  if(!context) {
     throw new DlAbortEx("Cannot create new xpath context");
   }
   string defaultNamespace = "http://www.metalinker.org/";
   if(xmlXPathRegisterNs(context, (xmlChar*)"m",
 			(xmlChar*)defaultNamespace.c_str()) != 0) {
-    throw new DlAbortEx("Cannot register namespace %s", defaultNamespace.c_str());
+    throw new DlAbortEx("Cannot register namespace %s",
+			defaultNamespace.c_str());
   }
   
   string xpath = "/m:metalink/m:files/m:file";
-  Metalinker* metalinker = new Metalinker();
-  try {
-    for(int index = 1; 1; index++) {
-      MetalinkEntry* entry = getEntry(xpath+"["+Util::itos(index)+"]");
-      if(entry == NULL) {
-	break;
-      } else {
-	metalinker->entries.push_back(entry);
-      }
+  MetalinkerHandle metalinker(new Metalinker());
+  for(int index = 1; 1; index++) {
+    MetalinkEntryHandle entry = getEntry(xpath+"["+Util::itos(index)+"]");
+    if(!entry.get()) {
+      break;
+    } else {
+      metalinker->entries.push_back(entry);
     }
-  } catch(Exception* e) {
-    delete metalinker;
-    throw;
   }
   return metalinker;
 }
 
-MetalinkEntry* Xml2MetalinkProcessor::getEntry(const string& xpath) {
+MetalinkEntryHandle Xml2MetalinkProcessor::getEntry(const string& xpath) {
   xmlXPathObjectPtr result = xpathEvaluation(xpath);
-  if(result == NULL) {
-    return NULL;
+  if(!result) {
+    return 0;
   }
+  xmlNodeSetPtr nodeSet = result->nodesetval;
+  xmlNodePtr node = nodeSet->nodeTab[0];
+  string filename = Util::trim(xmlAttribute(node, "name"));
   xmlXPathFreeObject(result);
-  MetalinkEntry* entry = new MetalinkEntry();
-  try {
-    entry->version = Util::trim(xpathContent(xpath+"/m:version"));
-    entry->language = Util::trim(xpathContent(xpath+"/m:language"));
-    entry->os = Util::trim(xpathContent(xpath+"/m:os"));
+
+  MetalinkEntryHandle entry(new MetalinkEntry());
+
+  entry->filename = filename;
+
+  entry->version = Util::trim(xpathContent(xpath+"/m:version"));
+  entry->language = Util::trim(xpathContent(xpath+"/m:language"));
+  entry->os = Util::trim(xpathContent(xpath+"/m:os"));
 #ifdef ENABLE_MESSAGE_DIGEST
-    string md;
-    md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"sha1\"]")));
+  string md;
+  md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"sha1\"]")));
+  if(md.size() > 0) {
+    entry->checksum.setMessageDigest(md);
+    entry->checksum.setDigestAlgo(DIGEST_ALGO_SHA1);
+  } else {
+    md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"md5\"]")));
     if(md.size() > 0) {
       entry->checksum.setMessageDigest(md);
-      entry->checksum.setDigestAlgo(DIGEST_ALGO_SHA1);
-    } else {
-      md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"md5\"]")));
-      if(md.size() > 0) {
-	entry->checksum.setMessageDigest(md);
-	entry->checksum.setDigestAlgo(DIGEST_ALGO_MD5);
-      }
+      entry->checksum.setDigestAlgo(DIGEST_ALGO_MD5);
     }
+  }
 #endif // ENABLE_MESSAGE_DIGEST
-    for(int index = 1; 1; index++) {
-      MetalinkResource* resource =
-	getResource(xpath+"/m:resources/m:url["+Util::itos(index)+"]");
-      if(resource == NULL) {
-	break;
-      } else {
-	entry->resources.push_back(resource);
-      }
+  for(int index = 1; 1; index++) {
+    MetalinkResourceHandle resource(getResource(xpath+"/m:resources/m:url["+Util::itos(index)+"]"));
+    if(!resource.get()) {
+      break;
+    } else {
+      entry->resources.push_back(resource);
     }
-  } catch(Exception* e) {
-    delete entry;
-    throw;
   }
-
   return entry;
 }
 
-MetalinkResource* Xml2MetalinkProcessor::getResource(const string& xpath) {
+MetalinkResourceHandle Xml2MetalinkProcessor::getResource(const string& xpath) {
   xmlXPathObjectPtr result = xpathEvaluation(xpath);
-  if(result == NULL) {
-    return NULL;
-  }
-  MetalinkResource* resource = new MetalinkResource();
-  try {
-    xmlNodeSetPtr nodeSet = result->nodesetval;
-    xmlNodePtr node = nodeSet->nodeTab[0];
-    string type = Util::trim(xmlAttribute(node, "type"));
-    if(type == "ftp") {
-      resource->type = MetalinkResource::TYPE_FTP;
-    } else if(type == "http") {
-      resource->type = MetalinkResource::TYPE_HTTP;
-    } else if(type == "https") {
-      resource->type = MetalinkResource::TYPE_HTTPS;
-    } else if(type == "bittorrent") {
-      resource->type = MetalinkResource::TYPE_BITTORRENT;
-    } else {
-      resource->type = MetalinkResource::TYPE_NOT_SUPPORTED;
-    }
-    string pref = Util::trim(xmlAttribute(node, "preference"));
-    if(pref.empty()) {
-      resource->preference = 100;
-    } else {
-      resource->preference = STRTOLL(pref.c_str());
-    }
-    resource->url = Util::trim(xmlContent(node));
-  } catch(Exception* e) {
-    delete resource;
-    throw e;
+  if(!result) {
+    return 0;
+  }
+  MetalinkResourceHandle resource(new MetalinkResource());
+
+  xmlNodeSetPtr nodeSet = result->nodesetval;
+  xmlNodePtr node = nodeSet->nodeTab[0];
+  string type = Util::trim(xmlAttribute(node, "type"));
+
+  if(type == "ftp") {
+    resource->type = MetalinkResource::TYPE_FTP;
+  } else if(type == "http") {
+    resource->type = MetalinkResource::TYPE_HTTP;
+  } else if(type == "https") {
+    resource->type = MetalinkResource::TYPE_HTTPS;
+  } else if(type == "bittorrent") {
+    resource->type = MetalinkResource::TYPE_BITTORRENT;
+  } else {
+    resource->type = MetalinkResource::TYPE_NOT_SUPPORTED;
   }
+  string pref = Util::trim(xmlAttribute(node, "preference"));
+  if(pref.empty()) {
+    resource->preference = 100;
+  } else {
+    resource->preference = STRTOLL(pref.c_str());
+  }
+  resource->location = Util::trim(xmlAttribute(node, "location"));
+
+  resource->url = Util::trim(xmlContent(node));
+
+  xmlXPathFreeObject(result);
+
   return resource;
 }
 
 xmlXPathObjectPtr Xml2MetalinkProcessor::xpathEvaluation(const string& xpath) {
   xmlXPathObjectPtr result = xmlXPathEvalExpression((xmlChar*)xpath.c_str(),
 						    context);
-  if(result == NULL) {
+  if(!result) {
     throw new DlAbortEx("Cannot evaluate xpath %s", xpath.c_str());
   }
   if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
     xmlXPathFreeObject(result);
-    return NULL;
+    return 0;
   }
   return result;
 }
 
 string Xml2MetalinkProcessor::xmlAttribute(xmlNodePtr node, const string& attrName) {
   xmlChar* temp = xmlGetNoNsProp(node, (xmlChar*)attrName.c_str());
-  if(temp == NULL) {
+  if(!temp) {
     return "";
   } else {
     string attr = (char*)temp;
@@ -193,7 +191,7 @@ string Xml2MetalinkProcessor::xmlAttribute(xmlNodePtr node, const string& attrNa
 
 string Xml2MetalinkProcessor::xmlContent(xmlNodePtr node) {
   xmlChar* temp = xmlNodeGetContent(node);
-  if(temp == NULL) {
+  if(!temp) {
     return "";
   } else {
     string content = (char*)temp;
@@ -204,7 +202,7 @@ string Xml2MetalinkProcessor::xmlContent(xmlNodePtr node) {
 
 string Xml2MetalinkProcessor::xpathContent(const string& xpath) {
   xmlXPathObjectPtr result = xpathEvaluation(xpath);
-  if(result == NULL) {
+  if(!result) {
     return "";
   }
   xmlNodeSetPtr nodeSet = result->nodesetval;

+ 3 - 3
src/Xml2MetalinkProcessor.h

@@ -44,8 +44,8 @@ private:
   xmlDocPtr doc;
   xmlXPathContextPtr context;
 
-  MetalinkEntry* getEntry(const string& xpath);
-  MetalinkResource* getResource(const string& xpath);
+  MetalinkEntryHandle getEntry(const string& xpath);
+  MetalinkResourceHandle getResource(const string& xpath);
 
   xmlXPathObjectPtr xpathEvaluation(const string& xpath);
   string xpathContent(const string& xpath);
@@ -57,7 +57,7 @@ public:
   Xml2MetalinkProcessor();
   virtual ~Xml2MetalinkProcessor();
 
-  virtual Metalinker* parseFile(const string& filename);
+  virtual MetalinkerHandle parseFile(const string& filename);
   
 };
 

+ 26 - 19
src/main.cc

@@ -72,7 +72,6 @@ extern int optind, opterr, optopt;
 
 using namespace std;
 
-RequestInfo* requestInfo;
 bool timeoutSpecified;
 
 void setSignalHander(int signal, void (*handler)(int), int flags) {
@@ -214,6 +213,7 @@ void showUsage() {
   cout << _(" --metalink-version=VERSION   The version of file to download.") << endl;
   cout << _(" --metalink-language=LANGUAGE The language of file to download.") << endl;
   cout << _(" --metalink-os=OS             The operating system the file is targeted.") << endl;
+  cout << _(" --metalink-location=LOCATION The location of the prefered server.") << endl;
   cout << _(" --follow-metalink=true|false  Setting this option to false prevents aria2 to\n"
 	    "                              enter Metalink mode even if the filename of\n"
 	    "                              downloaded file ends with .metalink.\n"
@@ -382,6 +382,7 @@ int main(int argc, char* argv[]) {
       { "metalink-language", required_argument, &lopt, 101 },
       { "metalink-os", required_argument, &lopt, 102 },
       { "follow-metalink", required_argument, &lopt, 103 },
+      { "metalink-location", required_argument, &lopt, 104 },
 #endif // ENABLE_METALINK
       { "version", no_argument, NULL, 'v' },
       { "help", no_argument, NULL, 'h' },
@@ -587,6 +588,9 @@ int main(int argc, char* argv[]) {
 	  exit(EXIT_FAILURE);
 	}
 	break;
+      case 104:
+	op->put(PREF_METALINK_LOCATION, optarg);
+	break;
       case 200: {
 	int limit = getRealSize(optarg);
 	if(limit < 0) {
@@ -725,7 +729,7 @@ int main(int argc, char* argv[]) {
   } else {
     LogFactory::setLogFile("/dev/null");
   }
-  // make sure logger is configured properly.
+  int exitStatus = EXIT_SUCCESS;
   try {
     Logger* logger = LogFactory::getInstance();
     logger->info("%s %s", PACKAGE, PACKAGE_VERSION);
@@ -733,49 +737,52 @@ int main(int argc, char* argv[]) {
 
     setSignalHander(SIGPIPE, SIG_IGN, 0);
 
-    requestInfo = 0;
+    RequestInfo* firstReqInfo = 0;
 #ifdef ENABLE_BITTORRENT
     if(op->defined(PREF_TORRENT_FILE)) {
-      requestInfo = new TorrentRequestInfo(op->get(PREF_TORRENT_FILE),
+      firstReqInfo = new TorrentRequestInfo(op->get(PREF_TORRENT_FILE),
 					   op);
       Strings targetFiles;
       if(op->defined(PREF_TORRENT_FILE) && !args.empty()) {
 	targetFiles = args;
       }
-      ((TorrentRequestInfo*)requestInfo)->setTargetFiles(targetFiles);
+      ((TorrentRequestInfo*)firstReqInfo)->setTargetFiles(targetFiles);
     }
     else
 #endif // ENABLE_BITTORRENT
 #ifdef ENABLE_METALINK
       if(op->defined(PREF_METALINK_FILE)) {
-	requestInfo = new MetalinkRequestInfo(op->get(PREF_METALINK_FILE),
+	firstReqInfo = new MetalinkRequestInfo(op->get(PREF_METALINK_FILE),
 					      op);
       } else
 #endif // ENABLE_METALINK
 	{
-	  requestInfo = new UrlRequestInfo(args, 0, op);
+	  firstReqInfo = new UrlRequestInfo(args, 0, op);
 	}
 
-    while(requestInfo) {
-      RequestInfo* next = requestInfo->execute();
-      if(requestInfo->isFail()) {
-	delete requestInfo;
-	exit(EXIT_FAILURE);
-      }
-      if(requestInfo->getFileInfo().checkReady()) {
+    RequestInfos reqInfos;
+    if(firstReqInfo) {
+      reqInfos.push_front(firstReqInfo);
+    }
+    while(reqInfos.size()) {
+      RequestInfoHandle reqInfo = reqInfos.front();
+      reqInfos.pop_front();
+      RequestInfos nextReqInfos = reqInfo->execute();
+      copy(nextReqInfos.begin(), nextReqInfos.end(), front_inserter(reqInfos));
+      if(reqInfo->isFail()) {
+	exitStatus = EXIT_FAILURE;
+      } else if(reqInfo->getFileInfo().checkReady()) {
 	cout << _("Now verifying checksum.\n"
 		  "This may take some time depending on your PC environment"
 		  " and the size of file.") << endl;
-	if(requestInfo->getFileInfo().check()) {
+	if(reqInfo->getFileInfo().check()) {
 	  cout << _("checksum OK.") << endl;
 	} else {
 	  // TODO
 	  cout << _("checksum ERROR.") << endl;
-	  exit(EXIT_FAILURE);
+	  exitStatus = EXIT_FAILURE;
 	}
       }
-      delete requestInfo;
-      requestInfo = next;
     }
   } catch(Exception* ex) {
     cerr << ex->getMsg() << endl;
@@ -791,5 +798,5 @@ int main(int argc, char* argv[]) {
   xmlCleanupParser();
 #endif // ENABLE_METALINK
   FeatureConfig::release();
-  return 0;
+  return exitStatus;
 }

+ 2 - 0
src/prefs.h

@@ -163,6 +163,8 @@
 #define PREF_METALINK_LANGUAGE "metalink_language"
 // values: a string
 #define PREF_METALINK_OS "metalink_os"
+// values: a string
+#define PREF_METALINK_LOCATION "metalink_location"
 // values: 1*digit
 #define PREF_METALINK_SERVERS "metalink_servers"
 // values: true | false

+ 17 - 16
test/MetalinkerTest.cc

@@ -23,12 +23,12 @@ public:
 CPPUNIT_TEST_SUITE_REGISTRATION( MetalinkerTest );
 
 void MetalinkerTest::testQueryEntry() {
-  Metalinker* metalinker = new Metalinker();
-  MetalinkEntry* entry1 = new MetalinkEntry();
+  MetalinkerHandle metalinker(new Metalinker());
+  MetalinkEntryHandle entry1(new MetalinkEntry());
   entry1->version = "0.5.2";
   entry1->language = "en-US";
   entry1->os = "Linux-x86";
-  MetalinkEntry* entry2 = new MetalinkEntry();
+  MetalinkEntryHandle entry2(new MetalinkEntry());
   entry2->version = "0.5.1";
   entry2->language = "ja-JP";
   entry2->os = "Linux-m68k";
@@ -42,25 +42,26 @@ void MetalinkerTest::testQueryEntry() {
   version = "0.5.1";
   language = "ja-JP";
   os = "Linux-m68k";
-  MetalinkEntry* entry = metalinker->queryEntry(version,
-						language,
-						os);
-  CPPUNIT_ASSERT_EQUAL(string("0.5.1"), entry->version);
-  CPPUNIT_ASSERT_EQUAL(string("ja-JP"), entry->language);
-  CPPUNIT_ASSERT_EQUAL(string("Linux-m68k"), entry->os);
+  MetalinkEntries entries = metalinker->queryEntry(version,
+						 language,
+						 os);
+  CPPUNIT_ASSERT_EQUAL((size_t)1, entries.size());
+  CPPUNIT_ASSERT_EQUAL(string("0.5.1"), entries.at(0)->version);
+  CPPUNIT_ASSERT_EQUAL(string("ja-JP"), entries.at(0)->language);
+  CPPUNIT_ASSERT_EQUAL(string("Linux-m68k"), entries.at(0)->os);
 
   version = "0.6.0";
   language = "";
   os = "";
-  CPPUNIT_ASSERT(!metalinker->queryEntry(version, language, os));
+  CPPUNIT_ASSERT_EQUAL((size_t)0,
+		       metalinker->queryEntry(version, language, os).size());
 
   version = "0.5.2";
   language = "";
   os = "";
-  entry = metalinker->queryEntry(version, language, os);
-  CPPUNIT_ASSERT_EQUAL(string("0.5.2"), entry->version);
-  CPPUNIT_ASSERT_EQUAL(string("en-US"), entry->language);
-  CPPUNIT_ASSERT_EQUAL(string("Linux-x86"), entry->os);
-
-  delete metalinker;
+  entries = metalinker->queryEntry(version, language, os);
+  CPPUNIT_ASSERT_EQUAL((size_t)1, entries.size());
+  CPPUNIT_ASSERT_EQUAL(string("0.5.2"), entries.at(0)->version);
+  CPPUNIT_ASSERT_EQUAL(string("en-US"), entries.at(0)->language);
+  CPPUNIT_ASSERT_EQUAL(string("Linux-x86"), entries.at(0)->os);
 }

+ 7 - 7
test/Xml2MetalinkProcessorTest.cc

@@ -26,10 +26,10 @@ CPPUNIT_TEST_SUITE_REGISTRATION( Xml2MetalinkProcessorTest );
 
 void Xml2MetalinkProcessorTest::testParseFile() {
   Xml2MetalinkProcessor proc;
-  Metalinker* metalinker = proc.parseFile("test.xml");
+  MetalinkerHandle metalinker = proc.parseFile("test.xml");
 
   MetalinkEntries::iterator entryItr = metalinker->entries.begin();
-  MetalinkEntry* entry1 = *entryItr;
+  MetalinkEntryHandle entry1 = *entryItr;
   CPPUNIT_ASSERT_EQUAL(string("0.5.2"), entry1->version);
   CPPUNIT_ASSERT_EQUAL(string("en-US"), entry1->language);
   CPPUNIT_ASSERT_EQUAL(string("Linux-x86"), entry1->os);
@@ -38,27 +38,27 @@ void Xml2MetalinkProcessorTest::testParseFile() {
   CPPUNIT_ASSERT(DIGEST_ALGO_SHA1 == entry1->checksum.getDigestAlgo());
 
   MetalinkResources::iterator resourceItr1 = entry1->resources.begin();
-  MetalinkResource* resource1 = *resourceItr1;
+  MetalinkResourceHandle resource1 = *resourceItr1;
   CPPUNIT_ASSERT_EQUAL((int)MetalinkResource::TYPE_FTP, resource1->type);
+  CPPUNIT_ASSERT_EQUAL(string("jp"), resource1->location);
   CPPUNIT_ASSERT_EQUAL(100, resource1->preference);
   CPPUNIT_ASSERT_EQUAL(string("ftp://ftphost/aria2-0.5.2.tar.bz2"),
 		       resource1->url);
   resourceItr1++;
-  MetalinkResource* resource2 = *resourceItr1;
+  MetalinkResourceHandle resource2 = *resourceItr1;
   CPPUNIT_ASSERT_EQUAL((int)MetalinkResource::TYPE_HTTP, resource2->type);
+  CPPUNIT_ASSERT_EQUAL(string("us"), resource2->location);
   CPPUNIT_ASSERT_EQUAL(100, resource2->preference);
   CPPUNIT_ASSERT_EQUAL(string("http://httphost/aria2-0.5.2.tar.bz2"),
 		       resource2->url);
 
   entryItr++;
 
-  MetalinkEntry* entry2 = *entryItr;
+  MetalinkEntryHandle entry2 = *entryItr;
   CPPUNIT_ASSERT_EQUAL(string("0.5.1"), entry2->version);
   CPPUNIT_ASSERT_EQUAL(string("ja-JP"), entry2->language);
   CPPUNIT_ASSERT_EQUAL(string("Linux-m68k"), entry2->os);
   CPPUNIT_ASSERT_EQUAL(string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
 		       entry2->checksum.getMessageDigest());
   CPPUNIT_ASSERT(DIGEST_ALGO_SHA1 == entry2->checksum.getDigestAlgo());
-
-  delete metalinker;
 }

+ 2 - 2
test/test.xml

@@ -15,8 +15,8 @@
         <hash type="sha1">a96cf3f0266b91d87d5124cf94326422800b627d</hash>
       </verification>
       <resources>
-        <url type="ftp" preference="100">ftp://ftphost/aria2-0.5.2.tar.bz2</url>
-        <url type="http" preference="100">http://httphost/aria2-0.5.2.tar.bz2</url>
+        <url type="ftp" location="jp" preference="100">ftp://ftphost/aria2-0.5.2.tar.bz2</url>
+        <url type="http" location="us" preference="100">http://httphost/aria2-0.5.2.tar.bz2</url>
       </resources>
     </file>
     <file name="aria2-0.5.1.tar.bz2">