diff --git a/ChangeLog b/ChangeLog index 3ff83770..1c491187 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2006-03-17 Tatsuhiro Tsujikawa + + * SocketCore.cc: remove the assignment of addrinfo.ai_addr. + 2006-03-09 Tatsuhiro Tsujikawa * ChunkedEncoding.{h,cc}: fixed the bug that if chunk data is binary, diff --git a/TODO b/TODO index e05708c1..671f9b44 100644 --- a/TODO +++ b/TODO @@ -5,4 +5,8 @@ * Better HTTP status handling * Download files listed in a specifed file. * check MD5 checksum -* Add the feature which adds or removes URLs on-the-fly. \ No newline at end of file +* Add the feature which adds or removes URLs on-the-fly. +* Tracker UDP protocol +* no-compact peers format +* Add port range command-line option +* Add max peers command-line option \ No newline at end of file diff --git a/po/aria2c.pot b/po/aria2c.pot index d6c5bf3c..3c0f1734 100644 --- a/po/aria2c.pot +++ b/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-03-07 22:57+0900\n" +"POT-Creation-Date: 2006-03-21 23:10+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -77,122 +77,135 @@ msgstr "" msgid "CUID#%d - Unregistering cuid from segmentManager." msgstr "" -#: src/message.h:39 +#: src/message.h:48 #, c-format msgid "The segment file %s exists." msgstr "" -#: src/message.h:40 +#: src/message.h:49 #, c-format msgid "The segment file %s does not exist." msgstr "" -#: src/message.h:41 +#: src/message.h:50 #, c-format msgid "Saving the segment file %s" msgstr "" -#: src/message.h:42 +#: src/message.h:51 msgid "The segment file was saved successfully." msgstr "" -#: src/message.h:43 +#: src/message.h:52 #, c-format msgid "Loading the segment file %s." msgstr "" -#: src/message.h:44 +#: src/message.h:53 msgid "The segment file was loaded successfully." msgstr "" -#: src/message.h:46 +#: src/message.h:55 msgid "Timeout." msgstr "" -#: src/message.h:47 +#: src/message.h:56 msgid "Invalid chunk size." msgstr "" -#: src/message.h:48 +#: src/message.h:57 #, c-format msgid "Too large chunk. size = %d" msgstr "" -#: src/message.h:49 +#: src/message.h:58 msgid "Invalid header." msgstr "" -#: src/message.h:50 +#: src/message.h:59 msgid "Invalid response." msgstr "" -#: src/message.h:51 +#: src/message.h:60 msgid "No header found." msgstr "" -#: src/message.h:52 +#: src/message.h:61 msgid "No status header." msgstr "" -#: src/message.h:53 +#: src/message.h:62 msgid "Proxy connection failed." msgstr "" -#: src/message.h:54 +#: src/message.h:63 msgid "Connection failed." msgstr "" -#: src/message.h:55 +#: src/message.h:64 #, c-format msgid "" "The requested filename and the previously registered one are not same. %s != " "%s" msgstr "" -#: src/message.h:56 +#: src/message.h:65 #, c-format msgid "The response status is not successful. status = %d" msgstr "" -#: src/message.h:57 +#: src/message.h:66 #, c-format msgid "Too large file size. size = %lld" msgstr "" -#: src/message.h:58 +#: src/message.h:67 #, c-format msgid "Transfer encoding %s is not supported." msgstr "" -#: src/message.h:59 +#: src/message.h:68 msgid "SSL initialization failed." msgstr "" -#: src/message.h:60 +#: src/message.h:69 #, c-format msgid "Size mismatch %lld != %lld" msgstr "" -#: src/message.h:61 +#: src/message.h:70 msgid "Got EOF from the server." msgstr "" -#: src/main.cc:57 +#: src/main.cc:58 +#, c-format +msgid "" +"\n" +"The download was complete. <%s>\n" +msgstr "" + +#: src/main.cc:62 +msgid "" +"\n" +"The download was not complete because of errors. Check the log.\n" +msgstr "" + +#: src/main.cc:73 src/main.cc:82 msgid "" "\n" "SIGINT signal received." msgstr "" -#: src/main.cc:72 +#: src/main.cc:104 #, c-format msgid "Unrecognized URL or unsupported protocol: %s\n" msgstr "" -#: src/main.cc:78 +#: src/main.cc:110 msgid " version " msgstr "" -#: src/main.cc:82 +#: src/main.cc:114 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" @@ -209,40 +222,40 @@ msgid "" "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" msgstr "" -#: src/main.cc:96 +#: src/main.cc:128 #, c-format msgid "Contact Info: %s\n" msgstr "" -#: src/main.cc:102 +#: src/main.cc:134 #, c-format msgid "Usage: %s [options] URL ...\n" msgstr "" -#: src/main.cc:104 +#: src/main.cc:136 msgid "Options:" msgstr "" -#: src/main.cc:105 +#: src/main.cc:137 msgid " -d, --dir=DIR The directory to store downloaded file." msgstr "" -#: src/main.cc:106 +#: src/main.cc:138 msgid " -o, --out=FILE The file name for downloaded file." msgstr "" -#: src/main.cc:107 +#: src/main.cc:139 msgid "" " -l, --log=LOG The file path to store log. If '-' is " "specified,\n" " log is written to stdout." msgstr "" -#: src/main.cc:109 +#: src/main.cc:141 msgid " -D, --daemon Run as daemon." msgstr "" -#: src/main.cc:110 +#: src/main.cc:142 msgid "" " -s, --split=N Download a file using N connections. N must " "be\n" @@ -252,24 +265,24 @@ msgid "" " N connections." msgstr "" -#: src/main.cc:114 +#: src/main.cc:146 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:117 +#: src/main.cc:149 msgid " -t, --timeout=SEC Set timeout in second. Default: 60" msgstr "" -#: src/main.cc:118 +#: src/main.cc:150 msgid "" " -m, --max-tries=N Set number of tries. 0 means unlimited.\n" " Default: 5" msgstr "" -#: src/main.cc:120 +#: src/main.cc:152 msgid "" " --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n" " K or M(1K = 1024, 1M = 1024K). This\n" @@ -277,40 +290,40 @@ msgid "" " 1024." msgstr "" -#: src/main.cc:124 +#: src/main.cc:156 msgid "" " --http-proxy=HOST:PORT Use HTTP proxy server. This affects to all\n" " URLs." msgstr "" -#: src/main.cc:126 +#: src/main.cc:158 msgid " --http-user=USER Set HTTP user. This affects to all URLs." msgstr "" -#: src/main.cc:127 +#: src/main.cc:159 msgid "" " --http-passwd=PASSWD Set HTTP password. This affects to all URLs." msgstr "" -#: src/main.cc:128 +#: src/main.cc:160 msgid "" " --http-proxy-user=USER Set HTTP proxy user. This affects to all URLs" msgstr "" -#: src/main.cc:129 +#: src/main.cc:161 msgid "" " --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects to all " "URLs." msgstr "" -#: src/main.cc:130 +#: src/main.cc:162 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:133 +#: src/main.cc:165 msgid "" " --http-auth-scheme=SCHEME Set HTTP authentication scheme. Currently, " "basic\n" @@ -321,23 +334,23 @@ msgid "" " as well as --http-user and --http-passwd." msgstr "" -#: src/main.cc:137 +#: src/main.cc:169 msgid " --referer=REFERER Set Referer. This affects to all URLs." msgstr "" -#: src/main.cc:138 +#: src/main.cc:170 msgid "" " --ftp-user=USER Set FTP user. This affects to all URLs.\n" " Default: anonymous" msgstr "" -#: src/main.cc:140 +#: src/main.cc:172 msgid "" " --ftp-passwd=PASSWD Set FTP password. This affects to all URLs.\n" " Default: ARIA2USER@" msgstr "" -#: src/main.cc:142 +#: src/main.cc:174 msgid "" " --ftp-type=TYPE Set FTP transfer type. TYPE is either " "'binary'\n" @@ -345,11 +358,11 @@ msgid "" " Default: binary" msgstr "" -#: src/main.cc:145 +#: src/main.cc:177 msgid " -p, --ftp-pasv Use passive mode in FTP." msgstr "" -#: src/main.cc:146 +#: src/main.cc:178 msgid "" " --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' " "or\n" @@ -357,98 +370,106 @@ msgid "" " Default: tunnel" msgstr "" -#: src/main.cc:149 +#: src/main.cc:181 +msgid " --torrent-file=TORRENT_FILE The file path to .torrent file." +msgstr "" + +#: src/main.cc:182 +msgid "" +" --follow-torrent=true|false Setting this option to false prevents aria2 " +"to\n" +" enter BitTorrent mode even if the filename of\n" +" downloaded file ends with .torrent.\n" +" Default: true" +msgstr "" + +#: src/main.cc:186 msgid " -v, --version Print the version number and exit." msgstr "" -#: src/main.cc:150 +#: src/main.cc:187 msgid " -h, --help Print this message and exit." msgstr "" -#: src/main.cc:153 +#: src/main.cc:190 msgid "" " You can specify multiple URLs. All URLs must point to the same file\n" " or downloading fails." msgstr "" -#: src/main.cc:156 +#: src/main.cc:193 msgid "Examples:" msgstr "" -#: src/main.cc:157 +#: src/main.cc:194 msgid " Download a file by 1 connection:" msgstr "" -#: src/main.cc:159 +#: src/main.cc:196 msgid " Download a file by 2 connections:" msgstr "" -#: src/main.cc:161 +#: src/main.cc:198 msgid " Download a file by 2 connections, each connects to a different server:" msgstr "" -#: src/main.cc:163 +#: src/main.cc:200 msgid " You can mix up different protocols:" msgstr "" -#: src/main.cc:166 +#: src/main.cc:202 +msgid " Download a torrent" +msgstr "" + +#: src/main.cc:205 #, c-format msgid "Reports bugs to %s" msgstr "" -#: src/main.cc:240 +#: src/main.cc:284 msgid "unrecognized proxy format" msgstr "" -#: src/main.cc:266 +#: src/main.cc:310 msgid "Currently, supported authentication scheme is basic." msgstr "" -#: src/main.cc:275 +#: src/main.cc:319 msgid "retry-wait must be between 0 and 60." msgstr "" -#: src/main.cc:292 +#: src/main.cc:336 msgid "ftp-type must be either 'binary' or 'ascii'." msgstr "" -#: src/main.cc:301 +#: src/main.cc:345 msgid "ftp-via-http-proxy must be either 'get' or 'tunnel'." msgstr "" -#: src/main.cc:319 +#: src/main.cc:363 msgid "min-segment-size invalid" msgstr "" -#: src/main.cc:330 +#: src/main.cc:374 msgid "http-proxy-method must be either 'get' or 'tunnel'." msgstr "" -#: src/main.cc:357 +#: src/main.cc:388 +msgid "follow-torrent must be either 'true' or 'false'." +msgstr "" + +#: src/main.cc:414 msgid "split must be between 1 and 5." msgstr "" -#: src/main.cc:367 +#: src/main.cc:424 msgid "timeout must be between 1 and 600" msgstr "" -#: src/main.cc:376 +#: src/main.cc:433 msgid "max-tries invalid" msgstr "" -#: src/main.cc:398 +#: src/main.cc:456 msgid "specify at least one URL" msgstr "" - -#: src/main.cc:449 -#, c-format -msgid "" -"\n" -"The download was complete. <%s>\n" -msgstr "" - -#: src/main.cc:451 -msgid "" -"\n" -"The download was not complete because of errors. Check the log.\n" -msgstr "" diff --git a/po/ja.gmo b/po/ja.gmo index da5d6ee6..087c4e0a 100644 Binary files a/po/ja.gmo and b/po/ja.gmo differ diff --git a/po/ja.po b/po/ja.po index 7a4f6564..ce5e6f8d 100644 --- a/po/ja.po +++ b/po/ja.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: aria2c 0.2.1\n" "Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n" -"POT-Creation-Date: 2006-03-07 22:57+0900\n" +"POT-Creation-Date: 2006-03-21 23:10+0900\n" "PO-Revision-Date: 2006-03-05 15:21+0900\n" "Last-Translator: Tatsuhiro Tsujikawa \n" "Language-Team: Japanese \n" @@ -85,107 +85,124 @@ msgstr "" msgid "CUID#%d - Unregistering cuid from segmentManager." msgstr "CUID#%d - cuid をセグメントマネジャーから削除します." -#: src/message.h:39 +#: src/message.h:48 #, c-format msgid "The segment file %s exists." msgstr "セグメントファイル %s が存在します." -#: src/message.h:40 +#: src/message.h:49 #, c-format msgid "The segment file %s does not exist." msgstr "セグメントファイル %s が存在しません." -#: src/message.h:41 +#: src/message.h:50 #, c-format msgid "Saving the segment file %s" msgstr "セグメントファイル %s を保存しています." -#: src/message.h:42 +#: src/message.h:51 msgid "The segment file was saved successfully." msgstr "セグメントファイルの保存が完了しました." -#: src/message.h:43 +#: src/message.h:52 #, c-format msgid "Loading the segment file %s." msgstr "セグメントファイル %s をロードしています." -#: src/message.h:44 +#: src/message.h:53 msgid "The segment file was loaded successfully." msgstr "セグメントファイルのロードが完了しました." -#: src/message.h:46 +#: src/message.h:55 msgid "Timeout." msgstr "タイムアウトしました." -#: src/message.h:47 +#: src/message.h:56 msgid "Invalid chunk size." msgstr "chunk サイズが不正です." -#: src/message.h:48 +#: src/message.h:57 #, c-format msgid "Too large chunk. size = %d" msgstr "chunk サイズ (%d) が大きすぎます." -#: src/message.h:49 +#: src/message.h:58 msgid "Invalid header." msgstr "ヘッダーが不正です." -#: src/message.h:50 +#: src/message.h:59 msgid "Invalid response." msgstr "サーバーから不正なレスポンスを受け取りました." -#: src/message.h:51 +#: src/message.h:60 msgid "No header found." msgstr "ヘッダーが見つかりません." -#: src/message.h:52 +#: src/message.h:61 msgid "No status header." msgstr "status ヘッダーが見つかりません." -#: src/message.h:53 +#: src/message.h:62 msgid "Proxy connection failed." msgstr "Proxy 接続に失敗しました." -#: src/message.h:54 +#: src/message.h:63 msgid "Connection failed." msgstr "接続に失敗しました." -#: src/message.h:55 +#: src/message.h:64 #, c-format msgid "" "The requested filename and the previously registered one are not same. %s != " "%s" msgstr "リクエストしたファイル名 (%s) と登録済みファイル名 (%s) が異なります." -#: src/message.h:56 +#: src/message.h:65 #, c-format msgid "The response status is not successful. status = %d" msgstr "レスポンスのステータス (%d) が異常です." -#: src/message.h:57 +#: src/message.h:66 #, c-format msgid "Too large file size. size = %lld" msgstr "ファイルサイズ (%lld) が大きすぎます." -#: src/message.h:58 +#: src/message.h:67 #, c-format msgid "Transfer encoding %s is not supported." msgstr "トランスファー・エンコーディング %s はサポートされていません." -#: src/message.h:59 +#: src/message.h:68 msgid "SSL initialization failed." msgstr "SSL 初期化に失敗しました." -#: src/message.h:60 +#: src/message.h:69 #, c-format msgid "Size mismatch %lld != %lld" msgstr "サイズが合いません (%lld != %lld)" -#: src/message.h:61 +#: src/message.h:70 msgid "Got EOF from the server." msgstr "サーバーから EOF を受けとりました." -#: src/main.cc:57 +#: src/main.cc:58 +#, c-format +msgid "" +"\n" +"The download was complete. <%s>\n" +msgstr "" +"\n" +"<%s> のダウンロードが完了しました.\n" + +#: src/main.cc:62 +msgid "" +"\n" +"The download was not complete because of errors. Check the log.\n" +msgstr "" +"\n" +"ダウンロードはエラーのため完了していません. ログを確認してください.\n" + +#: src/main.cc:73 src/main.cc:82 msgid "" "\n" "SIGINT signal received." @@ -193,18 +210,18 @@ msgstr "" "\n" "SIGINT シグナルを受け取りました." -#: src/main.cc:72 +#: src/main.cc:104 #, c-format msgid "Unrecognized URL or unsupported protocol: %s\n" msgstr "" "%s は, 理解できない URL フォーマット, または, サポートされないプロトコルで" "す.\n" -#: src/main.cc:78 +#: src/main.cc:110 msgid " version " msgstr " バージョン " -#: src/main.cc:82 +#: src/main.cc:114 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" @@ -235,31 +252,31 @@ msgstr "" "Temple Place, Suite 330, Boston, MA 02111-1307 USA)。\n" "(訳: http://www.opensource.jp/gpl/gpl.ja.html.euc-jp)\n" -#: src/main.cc:96 +#: src/main.cc:128 #, c-format msgid "Contact Info: %s\n" msgstr "連絡先: %s\n" -#: src/main.cc:102 +#: src/main.cc:134 #, c-format msgid "Usage: %s [options] URL ...\n" msgstr "使い方: %s [オプション] URL ...\n" -#: src/main.cc:104 +#: src/main.cc:136 msgid "Options:" msgstr "オプション:" -#: src/main.cc:105 +#: src/main.cc:137 msgid " -d, --dir=DIR The directory to store downloaded file." msgstr "" " -d, --dir=DIR ダウンロードしたファイルを保存するディレクトリ." -#: src/main.cc:106 +#: src/main.cc:138 msgid " -o, --out=FILE The file name for downloaded file." msgstr "" " -o, --out=FILE ダウンロードしたファイルの保存先ファイル名." -#: src/main.cc:107 +#: src/main.cc:139 msgid "" " -l, --log=LOG The file path to store log. If '-' is " "specified,\n" @@ -269,11 +286,11 @@ msgstr "" "力\n" " に出力します." -#: src/main.cc:109 +#: src/main.cc:141 msgid " -D, --daemon Run as daemon." msgstr " -D, --daemon デーモンとして起動します." -#: src/main.cc:110 +#: src/main.cc:142 msgid "" " -s, --split=N Download a file using N connections. N must " "be\n" @@ -292,7 +309,7 @@ msgstr "" "ショ\n" " ンを確立します." -#: src/main.cc:114 +#: src/main.cc:146 msgid "" " --retry-wait=SEC Set amount of time in second between requests\n" " for errors. Specify a value between 0 and 60.\n" @@ -303,13 +320,13 @@ msgstr "" " す. 0 - 60 の値を指定してください.\n" " デフォルト値: 5" -#: src/main.cc:117 +#: src/main.cc:149 msgid " -t, --timeout=SEC Set timeout in second. Default: 60" msgstr "" " -t, --timeout=SEC タイムアウトとなる時間を秒で指定します.\n" " デフォルト値: 60" -#: src/main.cc:118 +#: src/main.cc:150 msgid "" " -m, --max-tries=N Set number of tries. 0 means unlimited.\n" " Default: 5" @@ -318,7 +335,7 @@ msgstr "" "行\n" " します. デフォルト値: 5" -#: src/main.cc:120 +#: src/main.cc:152 msgid "" " --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n" " K or M(1K = 1024, 1M = 1024K). This\n" @@ -331,7 +348,7 @@ msgstr "" "1024K).\n" " 1024 以上の値を指定してください." -#: src/main.cc:124 +#: src/main.cc:156 msgid "" " --http-proxy=HOST:PORT Use HTTP proxy server. This affects to all\n" " URLs." @@ -340,14 +357,14 @@ msgstr "" "シ\n" " ョンはすべての URL に影響します." -#: src/main.cc:126 +#: src/main.cc:158 msgid " --http-user=USER Set HTTP user. This affects to all URLs." msgstr "" " --http-user=USER HTTP での認証ユーザーを指定します. このオプショ" "ン\n" " はすべての URL に影響します." -#: src/main.cc:127 +#: src/main.cc:159 msgid "" " --http-passwd=PASSWD Set HTTP password. This affects to all URLs." msgstr "" @@ -355,7 +372,7 @@ msgstr "" "ショ\n" " ンはすべての URL に影響します." -#: src/main.cc:128 +#: src/main.cc:160 msgid "" " --http-proxy-user=USER Set HTTP proxy user. This affects to all URLs" msgstr "" @@ -365,7 +382,7 @@ msgstr "" "ま\n" " す." -#: src/main.cc:129 +#: src/main.cc:161 msgid "" " --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects to all " "URLs." @@ -376,7 +393,7 @@ msgstr "" "し\n" " ます." -#: src/main.cc:130 +#: src/main.cc:162 msgid "" " --http-proxy-method=METHOD Set the method to use in proxy request.\n" " METHOD is either 'get' or 'tunnel'.\n" @@ -387,7 +404,7 @@ msgstr "" " す. 'get' または 'tunnel' を指定してください.\n" " デフォルト値: tunnel" -#: src/main.cc:133 +#: src/main.cc:165 msgid "" " --http-auth-scheme=SCHEME Set HTTP authentication scheme. Currently, " "basic\n" @@ -405,14 +422,14 @@ msgstr "" "定\n" " する必要があります." -#: src/main.cc:137 +#: src/main.cc:169 msgid " --referer=REFERER Set Referer. This affects to all URLs." msgstr "" " --referer=REFERER リファラーを指定します. このオプションはすべて" "の\n" " URL に影響します." -#: src/main.cc:138 +#: src/main.cc:170 msgid "" " --ftp-user=USER Set FTP user. This affects to all URLs.\n" " Default: anonymous" @@ -422,7 +439,7 @@ msgstr "" " はすべての URL に影響します.\n" " デフォルト値: anonymous" -#: src/main.cc:140 +#: src/main.cc:172 msgid "" " --ftp-passwd=PASSWD Set FTP password. This affects to all URLs.\n" " Default: ARIA2USER@" @@ -432,7 +449,7 @@ msgstr "" " ンはすべての URL に影響します.\n" " デフォルト値: ARIA2USER@" -#: src/main.cc:142 +#: src/main.cc:174 msgid "" " --ftp-type=TYPE Set FTP transfer type. TYPE is either " "'binary'\n" @@ -443,11 +460,11 @@ msgstr "" " 'ascii' を指定してください. デフォルト値: " "binary" -#: src/main.cc:145 +#: src/main.cc:177 msgid " -p, --ftp-pasv Use passive mode in FTP." msgstr " -p, --ftp-pasv FTP で passive モードを使用します." -#: src/main.cc:146 +#: src/main.cc:178 msgid "" " --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' " "or\n" @@ -460,16 +477,29 @@ msgstr "" "く\n" " ださい. デフォルト値: tunnel" -#: src/main.cc:149 +#: src/main.cc:181 +msgid " --torrent-file=TORRENT_FILE The file path to .torrent file." +msgstr "" + +#: src/main.cc:182 +msgid "" +" --follow-torrent=true|false Setting this option to false prevents aria2 " +"to\n" +" enter BitTorrent mode even if the filename of\n" +" downloaded file ends with .torrent.\n" +" Default: true" +msgstr "" + +#: src/main.cc:186 msgid " -v, --version Print the version number and exit." msgstr " -v, --version バージョン番号を表示し, 終了します." -#: src/main.cc:150 +#: src/main.cc:187 msgid " -h, --help Print this message and exit." msgstr "" " -h, --help このヘルプメッセージを表示し, 終了します." -#: src/main.cc:153 +#: src/main.cc:190 msgid "" " You can specify multiple URLs. All URLs must point to the same file\n" " or downloading fails." @@ -478,88 +508,81 @@ msgstr "" "れ\n" " ばなりません. さもなくばダウンロードは失敗します." -#: src/main.cc:156 +#: src/main.cc:193 msgid "Examples:" msgstr "例:" -#: src/main.cc:157 +#: src/main.cc:194 msgid " Download a file by 1 connection:" msgstr " 1 コネクションでのダウンロード:" -#: src/main.cc:159 +#: src/main.cc:196 msgid " Download a file by 2 connections:" msgstr " 2 コネクションでのダウンロード:" -#: src/main.cc:161 +#: src/main.cc:198 msgid " Download a file by 2 connections, each connects to a different server:" msgstr " 二つの異なるサーバーに接続してダウンロード:" -#: src/main.cc:163 +#: src/main.cc:200 msgid " You can mix up different protocols:" msgstr " 異なるプロトコルを混合させてダウンロード:" -#: src/main.cc:166 +#: src/main.cc:202 +#, fuzzy +msgid " Download a torrent" +msgstr "CUID#%d - ダウンロードを中止します." + +#: src/main.cc:205 #, c-format msgid "Reports bugs to %s" msgstr "バグレポートはこちらへ: %s" -#: src/main.cc:240 +#: src/main.cc:284 msgid "unrecognized proxy format" msgstr "理解できないProxyフォーマットです." -#: src/main.cc:266 +#: src/main.cc:310 msgid "Currently, supported authentication scheme is basic." msgstr "現在サポートされている認証方法は basic です." -#: src/main.cc:275 +#: src/main.cc:319 msgid "retry-wait must be between 0 and 60." msgstr "retry-wait は 0 から 60 の間で指定してください." -#: src/main.cc:292 +#: src/main.cc:336 msgid "ftp-type must be either 'binary' or 'ascii'." msgstr "ftp-type は 'binary' または 'ascii' を指定してください." -#: src/main.cc:301 +#: src/main.cc:345 msgid "ftp-via-http-proxy must be either 'get' or 'tunnel'." msgstr "ftp-via-http-proxy は 'get' または 'tunnel' を指定してください." -#: src/main.cc:319 +#: src/main.cc:363 msgid "min-segment-size invalid" msgstr "min-segment-size が不正です." -#: src/main.cc:330 +#: src/main.cc:374 msgid "http-proxy-method must be either 'get' or 'tunnel'." msgstr "http-proxy-method は 'get' または 'tunnel' を指定してください." -#: src/main.cc:357 +#: src/main.cc:388 +#, fuzzy +msgid "follow-torrent must be either 'true' or 'false'." +msgstr "ftp-type は 'binary' または 'ascii' を指定してください." + +#: src/main.cc:414 msgid "split must be between 1 and 5." msgstr "split は 1 - 5 の値を指定してください." -#: src/main.cc:367 +#: src/main.cc:424 msgid "timeout must be between 1 and 600" msgstr "timeout は 1 - 600 の値を指定してください." -#: src/main.cc:376 +#: src/main.cc:433 msgid "max-tries invalid" msgstr "max-tries が不正です." -#: src/main.cc:398 +#: src/main.cc:456 msgid "specify at least one URL" msgstr "一個以上の URL を指定してください." - -#: src/main.cc:449 -#, c-format -msgid "" -"\n" -"The download was complete. <%s>\n" -msgstr "" -"\n" -"<%s> のダウンロードが完了しました.\n" - -#: src/main.cc:451 -msgid "" -"\n" -"The download was not complete because of errors. Check the log.\n" -msgstr "" -"\n" -"ダウンロードはエラーのため完了していません. ログを確認してください.\n" diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc index 501b1bbf..7cdf75e7 100644 --- a/src/AbstractDiskWriter.cc +++ b/src/AbstractDiskWriter.cc @@ -27,6 +27,8 @@ #include #include "DlAbortEx.h" #include "File.h" +#include +#include "Util.h" AbstractDiskWriter::AbstractDiskWriter():fd(0) {} @@ -49,7 +51,7 @@ void AbstractDiskWriter::openExistingFile(string filename) { throw new DlAbortEx(strerror(errno)); } - if((fd = open(filename.c_str(), O_WRONLY, S_IRUSR|S_IWUSR)) < 0) { + if((fd = open(filename.c_str(), O_RDWR, S_IRUSR|S_IWUSR)) < 0) { throw new DlAbortEx(strerror(errno)); } } @@ -60,7 +62,7 @@ void AbstractDiskWriter::createFile(string filename, int addFlags) { // if(filename.empty()) { // filename = "index.html"; // } - if((fd = open(filename.c_str(), O_CREAT|O_WRONLY|O_TRUNC|addFlags, S_IRUSR|S_IWUSR)) < 0) { + if((fd = open(filename.c_str(), O_CREAT|O_RDWR|O_TRUNC|addFlags, S_IRUSR|S_IWUSR)) < 0) { throw new DlAbortEx(strerror(errno)); } } @@ -70,3 +72,60 @@ void AbstractDiskWriter::writeDataInternal(const char* data, int len) { throw new DlAbortEx(strerror(errno)); } } + +int AbstractDiskWriter::readDataInternal(char* data, int len) { + int ret; + if((ret = read(fd, data, len)) < 0) { + throw new DlAbortEx(strerror(errno)); + } + return ret; +} + +string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) { + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL); + + try { + int BUFSIZE = 4096; + char buf[BUFSIZE]; + for(int i = 0; i < length/BUFSIZE; i++) { + if(BUFSIZE != readData(buf, BUFSIZE, offset)) { + throw "error"; + } + EVP_DigestUpdate(&ctx, buf, BUFSIZE); + offset += BUFSIZE; + } + int r = length%BUFSIZE; + if(r > 0) { + if(r != readData(buf, r, offset)) { + throw "error"; + } + EVP_DigestUpdate(&ctx, buf, r); + } + unsigned char hashValue[20]; + int len; + EVP_DigestFinal_ex(&ctx, hashValue, (unsigned int*)&len); + EVP_MD_CTX_cleanup(&ctx); + return Util::toHex(hashValue, 20); + } catch(string ex) { + EVP_MD_CTX_cleanup(&ctx); + throw new DlAbortEx(strerror(errno)); + } +} + +void AbstractDiskWriter::seek(long long int offset) { + if(offset != lseek(fd, offset, SEEK_SET)) { + throw new DlAbortEx(strerror(errno)); + } +} + +void AbstractDiskWriter::writeData(const char* data, int len, long long int offset) { + seek(offset); + writeDataInternal(data, len); +} + +int AbstractDiskWriter::readData(char* data, int len, long long int offset) { + seek(offset); + return readDataInternal(data, len); +} diff --git a/src/AbstractDiskWriter.h b/src/AbstractDiskWriter.h index c32ddc34..b5221170 100644 --- a/src/AbstractDiskWriter.h +++ b/src/AbstractDiskWriter.h @@ -31,6 +31,7 @@ protected: void createFile(string filename, int addFlags = 0); void writeDataInternal(const char* data, int len); + int readDataInternal(char* data, int len); public: AbstractDiskWriter(); virtual ~AbstractDiskWriter(); @@ -38,6 +39,14 @@ public: void closeFile(); void openExistingFile(string filename); + + string sha1Sum(long long int offset, long long int length); + + void seek(long long int offset); + + void writeData(const char* data, int len, long long int offset); + + int readData(char* data, int len, long long int offset); }; #endif // _D_ABSTRACT_DISK_WRITER_H_ diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc new file mode 100644 index 00000000..d0041fe6 --- /dev/null +++ b/src/BitfieldMan.cc @@ -0,0 +1,277 @@ +/* */ +#include "BitfieldMan.h" +#include + +BitfieldMan::BitfieldMan(int blockLength, long long int totalLength) + :blockLength(blockLength), totalLength(totalLength) { + if(blockLength > 0 && totalLength > 0) { + blocks = totalLength/blockLength+(totalLength%blockLength ? 1 : 0); + bitfieldLength = blocks/8+(blocks%8 ? 1 : 0); + bitfield = new unsigned char[bitfieldLength]; + useBitfield = new unsigned char[bitfieldLength]; + memset(bitfield, 0, bitfieldLength); + memset(useBitfield, 0, bitfieldLength); + } +} + +BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan) { + blockLength = bitfieldMan.blockLength; + totalLength = bitfieldMan.totalLength; + blocks = bitfieldMan.blocks; + bitfieldLength = bitfieldMan.bitfieldLength; + bitfield = new unsigned char[bitfieldLength]; + useBitfield = new unsigned char[bitfieldLength]; + memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength); + memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength); +} + +BitfieldMan::~BitfieldMan() { + delete [] bitfield; + delete [] useBitfield; +} + +BitfieldMan& BitfieldMan::operator=(const BitfieldMan& bitfieldMan) { + if(this != &bitfieldMan) { + blockLength = bitfieldMan.blockLength; + totalLength = bitfieldMan.totalLength; + if(bitfieldLength != bitfieldMan.bitfieldLength) { + delete [] bitfield; + delete [] useBitfield; + bitfield = new unsigned char[bitfieldMan.bitfieldLength]; + useBitfield = new unsigned char[bitfieldMan.bitfieldLength]; + } + blocks = bitfieldMan.blocks; + bitfieldLength = bitfieldMan.bitfieldLength; + memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength); + memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength); + } + return *this; +} + +int BitfieldMan::countSetBit(const unsigned char* bitfield, int len) const { + int count = 0; + for(int i = 0; i < len; i++) { + unsigned char bit = bitfield[i]; + for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { + unsigned char mask = 1 << bs; + if(bit & mask) { + count++; + } + } + } + return count; +} + +int BitfieldMan::getMissingIndexRandomly(const unsigned char* bitfield, int len, int randMax) const { + int index = -1; + int nth = 1+(int)(((double)randMax)*random()/(RAND_MAX+1.0)); + for(int i = 0; i < len && index == -1; i++) { + unsigned char bit = bitfield[i]; + for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { + unsigned char mask = 1 << bs; + if(bit & mask) { + nth--; + if(nth == 0) { + index = i*8+7-bs; + break; + } + } + } + } + return index; +} + +int BitfieldMan::getMissingIndex(const unsigned char* peerBitfield, int length) const { + if(bitfieldLength != length) { + return -1; + } + unsigned char* tempBitfield = new unsigned char[bitfieldLength]; + for(int i = 0; i < bitfieldLength; i++) { + tempBitfield[i] = peerBitfield[i] & ~bitfield[i]; + } + int max = countSetBit(tempBitfield, bitfieldLength); + int index = getMissingIndexRandomly(tempBitfield, bitfieldLength, max); + return index; +} + +int BitfieldMan::getMissingUnusedIndex(const unsigned char* peerBitfield, int length) const { + if(bitfieldLength != length) { + return -1; + } + unsigned char* tempBitfield = new unsigned char[bitfieldLength]; + for(int i = 0; i < bitfieldLength; i++) { + tempBitfield[i] = peerBitfield[i] & ~bitfield[i] & ~useBitfield[i]; + } + int max = countSetBit(tempBitfield, bitfieldLength); + /* + int max = 0; + for(int i = 0; i < bitfieldLength; i++) { + unsigned char bit = tempBitfield[i]; + for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { + unsigned char mask = 1 << bs; + if(bit & mask) { + max++; + } + } + } + */ + int index = getMissingIndexRandomly(tempBitfield, bitfieldLength, max); + /* + int index = -1; + int nth = 1+(int)(((double)max)*random()/(RAND_MAX+1.0)); + for(int i = 0; i < bitfieldLength && index == -1; i++) { + unsigned char bit = tempBitfield[i]; + for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { + unsigned char mask = 1 << bs; + if(bit & mask) { + nth--; + if(nth == 0) { + index = i*8+7-bs; + break; + } + } + } + } + */ + return index; +} + +int BitfieldMan::getFirstMissingUnusedIndex(const unsigned char* peerBitfield, int length) const { + if(bitfieldLength != length) { + return -1; + } + for(int i = 0; i < bitfieldLength; i++) { + unsigned char bit = peerBitfield[i] & ~bitfield[i] & ~useBitfield[i]; + for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { + unsigned char mask = 1 << bs; + if(bit & mask) { + return i*8+7-bs; + } + } + } + return -1; +} + +int BitfieldMan::getFirstMissingUnusedIndex() const { + for(int i = 0; i < bitfieldLength; i++) { + unsigned char bit = ~bitfield[i] & ~useBitfield[i]; + for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { + unsigned char mask = 1 << bs; + if(bit & mask) { + return i*8+7-bs; + } + } + } + return -1; +} + +vector BitfieldMan::getAllMissingIndexes() const { + vector missingIndexes; + for(int i = 0; i < bitfieldLength; i++) { + unsigned char bit = ~bitfield[i]; + for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) { + unsigned char mask = 1 << bs; + if(bit & mask) { + missingIndexes.push_back(i*8+7-bs); + } + } + } + return missingIndexes; +} + +int BitfieldMan::countMissingBlock() const { + return blocks-countSetBit(bitfield, bitfieldLength); +} + +bool BitfieldMan::setUseBit(int index) { + if(blocks <= index) { return false; } + unsigned char mask = 128 >> index%8; + useBitfield[index/8] |= mask; + return true; +} + +bool BitfieldMan::unsetUseBit(int index) { + if(blocks <= index) { return false; } + unsigned char mask = 128 >> index%8; + useBitfield[index/8] &= ~mask; + return true; +} + +bool BitfieldMan::setBit(int index) { + if(blocks <= index) { return false; } + unsigned char mask = 128 >> index%8; + bitfield[index/8] |= mask; + return true; +} +bool BitfieldMan::unsetBit(int index) { + if(blocks <= index) { return false; } + unsigned char mask = 128 >> index%8; + bitfield[index/8] &= ~mask; + return true; +} + +bool BitfieldMan::isAllBitSet() const { + for(int i = 0; i < bitfieldLength-1; i++) { + if(bitfield[i] != 0xff) { + return false; + } + } + unsigned char b = ~((128 >> (blocks-1)%8)-1); + if(bitfield[bitfieldLength-1] != b) { + return false; + } + return true; +} + +bool BitfieldMan::isBitSetInternal(const unsigned char* bitfield, int index) const { + if(blocks <= index) { return false; } + unsigned char mask = 128 >> index%8; + return (bitfield[index/8] & mask) != 0; +} + +bool BitfieldMan::isBitSet(int index) const { + return isBitSetInternal(bitfield, index); +} + +bool BitfieldMan::isUseBitSet(int index) const { + return isBitSetInternal(useBitfield, index); +} + +void BitfieldMan::setBitfield(const unsigned char* bitfield, int bitfieldLength) { + if(this->bitfieldLength != bitfieldLength) { + return; + } + memcpy(this->bitfield, bitfield, this->bitfieldLength); + memset(this->useBitfield, 0, this->bitfieldLength); +} + +void BitfieldMan::clearAllBit() { + memset(this->bitfield, 0, this->bitfieldLength); + memset(this->useBitfield, 0, this->bitfieldLength); +} + +void BitfieldMan::setAllBit() { + for(int i = 0; i < blocks; i++) { + setBit(i); + } +} diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h new file mode 100644 index 00000000..28f2f026 --- /dev/null +++ b/src/BitfieldMan.h @@ -0,0 +1,90 @@ +/* */ +#ifndef _D_BITFIELD_MAN_H_ +#define _D_BITFIELD_MAN_H_ + +#include "common.h" +#include + +class BitfieldMan { +private: + int blockLength; + long long int totalLength; + unsigned char* bitfield; + unsigned char* useBitfield; + int bitfieldLength; + int blocks; + + int countSetBit(const unsigned char* bitfield, int len) const; + int getMissingIndexRandomly(const unsigned char* bitfield, int len, int randMax) const; + bool isBitSetInternal(const unsigned char* bitfield, int index) const; +public: + BitfieldMan(int blockLength, long long int totalLength); + BitfieldMan(const BitfieldMan& bitfieldMan); + ~BitfieldMan(); + + BitfieldMan& operator=(const BitfieldMan& bitfieldMan); + + int getBlockLength() const { return blockLength; } + int getLastBlockLength() const { + return totalLength-blockLength*(blocks-1); + } + int getBlockLength(int index) const { + if(index == blocks-1) { + return getLastBlockLength(); + } else if(0 <= index && index < blocks-1) { + return getBlockLength(); + } else { + return 0; + } + } + long long int getTotalLength() const { return totalLength; } + + int getMissingIndex(const unsigned char* bitfield, int len) const; + int getFirstMissingUnusedIndex(const unsigned char* bitfield, int len) const; + int getFirstMissingUnusedIndex() const; + int getMissingUnusedIndex(const unsigned char* bitfield, int len) const; + vector getAllMissingIndexes() const; + int countMissingBlock() const; + bool setUseBit(int index); + bool unsetUseBit(int index); + + bool setBit(int index); + bool unsetBit(int index); + + bool isBitSet(int index) const; + bool isUseBitSet(int index) const; + + bool isAllBitSet() const; + + const unsigned char* getBitfield() const { return bitfield; } + int getBitfieldLength() const { return bitfieldLength; } + + int countBlock() const { return blocks; } + + void setBitfield(const unsigned char* bitfield, int bitfieldLength); + + void clearAllBit(); + void setAllBit(); +}; + +#endif // _D_BITFIELD_MAN_H_ diff --git a/src/ConsoleDownloadEngine.cc b/src/ConsoleDownloadEngine.cc index 44efd279..aa0bac17 100644 --- a/src/ConsoleDownloadEngine.cc +++ b/src/ConsoleDownloadEngine.cc @@ -35,3 +35,37 @@ void ConsoleDownloadEngine::sendStatistics(long long int currentSize, long long speed/1000.0 << "KB/s " << "(" << commands.size() << " connections)" << flush; } + +void ConsoleDownloadEngine::initStatistics() { + cp.tv_sec = cp.tv_usec = 0; + speed = 0; + psize = 0; +} + +void ConsoleDownloadEngine::calculateStatistics() { + long long int dlSize = segmentMan->getDownloadedSize(); + struct timeval now; + gettimeofday(&now, NULL); + if(cp.tv_sec == 0 && cp.tv_usec == 0) { + cp = now; + psize = dlSize; + } else { + long long int elapsed = Util::difftv(now, cp); + if(elapsed >= 500000) { + int nspeed = (int)((dlSize-psize)/(elapsed/1000000.0)); + speed = (nspeed+speed)/2; + cp = now; + psize = dlSize; + sendStatistics(dlSize, segmentMan->totalSize); + } + } +} + +void ConsoleDownloadEngine::onEndOfRun() { + diskWriter->closeFile(); + if(segmentMan->finished()) { + segmentMan->remove(); + } else { + segmentMan->save(); + } +} diff --git a/src/ConsoleDownloadEngine.h b/src/ConsoleDownloadEngine.h index 80b2ceb6..64d787d7 100644 --- a/src/ConsoleDownloadEngine.h +++ b/src/ConsoleDownloadEngine.h @@ -25,8 +25,15 @@ #include "DownloadEngine.h" class ConsoleDownloadEngine : public DownloadEngine { +private: + struct timeval cp; + long long int psize; + int speed; protected: void sendStatistics(long long int currentSize, long long int totalSize); + void initStatistics(); + void calculateStatistics(); + void onEndOfRun(); public: ConsoleDownloadEngine(); ~ConsoleDownloadEngine(); diff --git a/src/Data.cc b/src/Data.cc new file mode 100644 index 00000000..b3d49f02 --- /dev/null +++ b/src/Data.cc @@ -0,0 +1,81 @@ +/* */ +#include "Data.h" +#include "MetaEntryVisitor.h" + +Data::Data(const char* data, int len, bool number):number(number) { + if(data == NULL) { + this->data = NULL; + this->len = 0; + } else { + this->data = new char[len]; + memcpy(this->data, data, len); + this->len = len; + } +} + +Data::~Data() { + delete [] data; +} + +string Data::toString() const { + if(len == 0) { + return ""; + } else { + char* temp = new char[len+1]; + memcpy(temp, data, len); + temp[len] = '\0'; + return string(temp); + } +} + +const char* Data::getData() const { + if(this->len == 0) { + return NULL; + } else { + return data; + } +} + +int Data::getLen() const { + return len; +} + +int Data::toInt() const { + return (int)toLLInt(); +} + +long long int Data::toLLInt() const { + if(len == 0) { + return 0; + } else { + return strtoll(data, NULL, 10); + } +} + +bool Data::isNumber() const { + return number; +} + +void Data::accept(MetaEntryVisitor* v) const { + v->visit(this); +} diff --git a/src/Data.h b/src/Data.h new file mode 100644 index 00000000..e7571697 --- /dev/null +++ b/src/Data.h @@ -0,0 +1,54 @@ +/* */ +#ifndef _D_DATA_H_ +#define _D_DATA_H_ + +#include "MetaEntry.h" +#include + +using namespace std; + +class Data : public MetaEntry { +private: + int len; + char* data; + bool number; +public: + /** + * This class stores the copy of data. So caller must take care of freeing + * memory of data. + */ + Data(const char* data, int len, bool number = false); + ~Data(); + + string toString() const; + int toInt() const; + long long int toLLInt() const; + + const char* getData() const; + int getLen() const; + bool isNumber() const; + + void accept(MetaEntryVisitor* v) const; +}; + +#endif // _D_DATA_H_ diff --git a/src/DefaultDiskWriter.cc b/src/DefaultDiskWriter.cc index ce7dd752..be71fbfc 100644 --- a/src/DefaultDiskWriter.cc +++ b/src/DefaultDiskWriter.cc @@ -30,10 +30,3 @@ DefaultDiskWriter::~DefaultDiskWriter() {} void DefaultDiskWriter::initAndOpenFile(string filename) { createFile(filename); } - -void DefaultDiskWriter::writeData(const char* data, int len, long long int offset) { - if(offset != lseek(fd, offset, SEEK_SET)) { - throw new DlAbortEx(strerror(errno)); - } - writeDataInternal(data, len); -} diff --git a/src/DefaultDiskWriter.h b/src/DefaultDiskWriter.h index c210f40b..91dc4814 100644 --- a/src/DefaultDiskWriter.h +++ b/src/DefaultDiskWriter.h @@ -30,8 +30,6 @@ public: ~DefaultDiskWriter(); void initAndOpenFile(string filename); - - void writeData(const char* data, int len, long long int position); }; #endif // _D_DEFAULT_DISK_WRITER_H_ diff --git a/src/Dictionary.cc b/src/Dictionary.cc new file mode 100644 index 00000000..1c46323c --- /dev/null +++ b/src/Dictionary.cc @@ -0,0 +1,57 @@ +/* */ +#include "Dictionary.h" +#include "MetaEntryVisitor.h" + +Dictionary::Dictionary() {} + +Dictionary::~Dictionary() { + clearTable(); +} + +void Dictionary::clearTable() { + for(MetaTable::iterator itr = table.begin(); itr != table.end(); itr++) { + delete itr->second; + } +} + +const MetaEntry* Dictionary::get(string name) const { + MetaTable::const_iterator itr = table.find(name); + if(itr == table.end()) { + return NULL; + } else { + return itr->second; + } +} + +void Dictionary::put(string name, MetaEntry* entry) { + table[name] = entry; + order.push_back(name); +} + +void Dictionary::accept(MetaEntryVisitor* v) const { + v->visit(this); +} + +const vector& Dictionary::getOrder() const { + return order; +} diff --git a/src/Dictionary.h b/src/Dictionary.h new file mode 100644 index 00000000..07837741 --- /dev/null +++ b/src/Dictionary.h @@ -0,0 +1,51 @@ +/* */ +#ifndef _D_DICTIONARY_H_ +#define _D_DICTIONARY_H_ + +#include "MetaEntry.h" +#include +#include +#include + +using namespace std; + +typedef map MetaTable; + +class Dictionary : public MetaEntry { +private: + MetaTable table; + vector order; + void clearTable(); +public: + Dictionary(); + ~Dictionary(); + + const MetaEntry* get(string name) const; + void put(string name, MetaEntry* entry); + + void accept(MetaEntryVisitor* v) const; + const vector& getOrder() const; + +}; + +#endif // _D_DICTIONARY_H_ diff --git a/src/Directory.cc b/src/Directory.cc new file mode 100644 index 00000000..7bc20396 --- /dev/null +++ b/src/Directory.cc @@ -0,0 +1,59 @@ +/* */ +#include "Directory.h" +#include "File.h" +#include "DlAbortEx.h" +#include +#include +#include + +Directory::Directory(string name):name(name) {} + +Directory::~Directory() { + for(Files::iterator itr = files.begin(); itr != files.end(); itr++) { + delete *itr; + } +} + +void Directory::createDir(string parentDir, bool recursive) const { + string path = parentDir+"/"+name; + File f(path); + if(f.exists()) { + if(!f.isDir()) { + throw new DlAbortEx("%s is already exists and it is not a directory.", + path.c_str()); + } + } else { + if(mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR) == -1) { + throw new DlAbortEx(strerror(errno)); + } + } + if(recursive) { + for(Files::const_iterator itr = files.begin(); itr != files.end(); itr++) { + (*itr)->createDir(path, true); + } + } +} + +void Directory::addFile(Directory* directory) { + files.push_back(directory); +} diff --git a/src/Directory.h b/src/Directory.h new file mode 100644 index 00000000..700aa441 --- /dev/null +++ b/src/Directory.h @@ -0,0 +1,44 @@ +/* */ +#ifndef _D_DIRECTORY_H_ +#define _D_DIRECTORY_H_ + +#include "common.h" +#include +#include + +class Directory { + +typedef vector Files; + +private: + string name; + Files files; +public: + Directory(string name); + ~Directory(); + + void createDir(string parentDir, bool recursive) const; + void addFile(Directory* directory); +}; + +#endif // _D_DIRECTORY_H_ diff --git a/src/DiskWriter.h b/src/DiskWriter.h index 96735882..d92419d3 100644 --- a/src/DiskWriter.h +++ b/src/DiskWriter.h @@ -64,6 +64,12 @@ public: * @param position the offset of this binary stream */ virtual void writeData(const char* data, int len, long long int position = 0) = 0; + + virtual int readData(char* data, int len, long long int position) = 0; + + virtual string sha1Sum(long long int offset, long long int length) = 0; + + virtual void seek(long long int offset) = 0; }; #endif // _D_DISK_WRITER_H_ diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc index 25a2f3fe..57bdb831 100644 --- a/src/DownloadEngine.cc +++ b/src/DownloadEngine.cc @@ -29,7 +29,7 @@ using namespace std; -DownloadEngine::DownloadEngine():noWait(false) {} +DownloadEngine::DownloadEngine():noWait(false), segmentMan(NULL) {} DownloadEngine::~DownloadEngine() { assert(rsockets.empty()); @@ -47,43 +47,23 @@ void DownloadEngine::run() { delete(com); } } + shortSleep(); if(!noWait && !commands.empty()) { waitData(); } noWait = false; calculateStatistics(); } - diskWriter->closeFile(); - if(segmentMan->finished()) { - segmentMan->remove(); - } else { - segmentMan->save(); - } + onEndOfRun(); } -void DownloadEngine::initStatistics() { - cp.tv_sec = cp.tv_usec = 0; - speed = 0; - psize = 0; -} - -void DownloadEngine::calculateStatistics() { - long long int dlSize = segmentMan->getDownloadedSize(); - struct timeval now; - gettimeofday(&now, NULL); - if(cp.tv_sec == 0 && cp.tv_usec == 0) { - cp = now; - psize = dlSize; - } else { - long long int elapsed = Util::difftv(now, cp); - if(elapsed >= 500000) { - int nspeed = (int)((dlSize-psize)/(elapsed/1000000.0)); - speed = (nspeed+speed)/2; - cp = now; - psize = dlSize; - sendStatistics(dlSize, segmentMan->totalSize); - } - } +void DownloadEngine::shortSleep() const { + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 1000; + fd_set rfds; + FD_ZERO(&rfds); + select(0, &rfds, NULL, NULL, &tv); } void DownloadEngine::waitData() { diff --git a/src/DownloadEngine.h b/src/DownloadEngine.h index d5d6b290..1a9fc742 100644 --- a/src/DownloadEngine.h +++ b/src/DownloadEngine.h @@ -41,15 +41,13 @@ private: vector rsockets; vector wsockets; + void shortSleep() const; bool addSocket(vector& sockets, Socket* socket); bool deleteSocket(vector& sockets, Socket* socket); - struct timeval cp; - long long int psize; - void initStatistics(); - void calculateStatistics(); protected: - int speed; - virtual void sendStatistics(long long int currentSize, long long int totalSize) {}; + virtual void initStatistics() = 0; + virtual void calculateStatistics() = 0; + virtual void onEndOfRun() = 0; public: bool noWait; queue commands; diff --git a/src/File.cc b/src/File.cc index e5dc24e2..683fa99a 100644 --- a/src/File.cc +++ b/src/File.cc @@ -62,3 +62,11 @@ bool File::remove() { return false; } } + +long long int File::size() { + struct stat fstat; + if(fillStat(fstat) < 0) { + return 0; + } + return fstat.st_size; +} diff --git a/src/File.h b/src/File.h index f450fb97..fa11f4c1 100644 --- a/src/File.h +++ b/src/File.h @@ -58,6 +58,8 @@ public: * If name denotes a directory, it must be empty in order to delete. */ bool remove(); + + long long int size(); }; #endif // _D_FILE_H_ diff --git a/src/HandshakeMessage.h b/src/HandshakeMessage.h new file mode 100644 index 00000000..b67a210f --- /dev/null +++ b/src/HandshakeMessage.h @@ -0,0 +1,47 @@ +/* */ +#ifndef _D_HANDSHAKE_MESSAGE_H_ +#define _D_HANDSHAKE_MESSAGE_H_ + +#include "common.h" +#include "Util.h" + +#define PSTR "BitTorrent protocol" +#define HANDSHAKE_MESSAGE_LENGTH 68 + +class HandshakeMessage { +public: + char pstrlen; + string pstr; + unsigned char infoHash[20]; + char peerId[20]; +public: + HandshakeMessage() {} + ~HandshakeMessage() {} + + string toString() const { + return "handshake peerId="+ + Util::urlencode((unsigned char*)peerId, sizeof(peerId)); + } +}; + +#endif // _D_HANDSHAKE_MESSAGE_H_ diff --git a/src/HttpConnection.cc b/src/HttpConnection.cc index 8122141d..f93faead 100644 --- a/src/HttpConnection.cc +++ b/src/HttpConnection.cc @@ -27,7 +27,7 @@ #include "prefs.h" HttpConnection::HttpConnection(int cuid, const Socket* socket, const Request* req, const Option* op, const Logger* logger): - cuid(cuid), socket(socket), req(req), option(op), logger(logger) {} + cuid(cuid), socket(socket), req(req), option(op), logger(logger), headerBufLength(0) {} void HttpConnection::sendRequest(const Segment& segment) const { string request = createRequest(segment); @@ -101,39 +101,60 @@ string HttpConnection::createRequest(const Segment& segment) const { return request; } -int HttpConnection::receiveResponse(HttpHeader& headers) { - char buf[512]; - while(socket->isReadable(0)) { - int size = sizeof(buf)-1; - socket->peekData(buf, size); - if(size == 0) { - throw new DlRetryEx(EX_INVALID_RESPONSE); - } - buf[size] = '\0'; - int hlenTemp = header.size(); - header += buf; - string::size_type p; - if((p = header.find("\r\n\r\n")) == string::npos) { - socket->readData(buf, size); - } else { - if(Util::endsWith(header, "\r\n\r\n")) { - socket->readData(buf, size); - } else { - header.erase(p+4); - size = p+4-hlenTemp; - socket->readData(buf, size); - } - break; +int HttpConnection::findEndOfHeader(const char* buf, const char* substr, int bufLength) const { + const char* p = buf; + while(bufLength > p-buf && bufLength-(p-buf) >= (int)strlen(substr)) { + if(memcmp(p, substr, strlen(substr)) == 0) { + return p-buf; } + p++; } - if(!Util::endsWith(header, "\r\n\r\n")) { + return -1; +} + +int HttpConnection::receiveResponse(HttpHeader& headers) { + //char buf[512]; + string header; + int delimiterSwith = 0; + char* delimiters[] = { "\r\n", "\n" }; + + int size = HEADERBUF_SIZE-headerBufLength; + if(size < 0) { + // TODO too large header + throw new DlRetryEx("too large header > 4096"); + } + socket->peekData(headerBuf+headerBufLength, size); + if(size == 0) { + throw new DlRetryEx(EX_INVALID_RESPONSE); + } + //buf[size] = '\0'; + int hlenTemp = headerBufLength+size; + //header += buf; + //string::size_type p; + int eohIndex; + if((eohIndex = findEndOfHeader(headerBuf, "\r\n\r\n", hlenTemp)) == -1 && + (eohIndex = findEndOfHeader(headerBuf, "\n\n", hlenTemp)) == -1) { + socket->readData(headerBuf+headerBufLength, size); + } else { + if(eohIndex[headerBuf] == '\n') { + // for crapping non-standard HTTP server + delimiterSwith = 1; + } else { + delimiterSwith = 0; + } + headerBuf[eohIndex+strlen(delimiters[delimiterSwith])*2] = '\0'; + header = headerBuf; + size = eohIndex+strlen(delimiters[delimiterSwith])*2-headerBufLength; + socket->readData(headerBuf+headerBufLength, size); + } + if(!Util::endsWith(header, "\r\n\r\n") && !Util::endsWith(header, "\n\n")) { return 0; } // OK, we got all headers. logger->info(MSG_RECEIVE_RESPONSE, cuid, header.c_str()); string::size_type p, np; p = np = 0; - np = header.find("\r\n", p); + np = header.find(delimiters[delimiterSwith], p); if(np == string::npos) { throw new DlRetryEx(EX_NO_STATUS_HEADER); } @@ -141,7 +162,7 @@ int HttpConnection::receiveResponse(HttpHeader& headers) { string status = header.substr(9, 3); p = np+2; // retreive status name-value pairs, then push these into map - while((np = header.find("\r\n", p)) != string::npos && np != p) { + while((np = header.find(delimiters[delimiterSwith], p)) != string::npos && np != p) { string line = header.substr(p, np-p); p = np+2; pair hp; diff --git a/src/HttpConnection.h b/src/HttpConnection.h index 33b14caf..c3e1deba 100644 --- a/src/HttpConnection.h +++ b/src/HttpConnection.h @@ -33,10 +33,13 @@ using namespace std; +#define HEADERBUF_SIZE 4096 + class HttpConnection { private: string getHost(const string& host, int port) const; string createRequest(const Segment& segment) const; + int findEndOfHeader(const char* buf, const char* substr, int bufLength) const; bool useProxy() const; bool useProxyAuth() const; bool useProxyGet() const; @@ -46,7 +49,8 @@ private: const Request* req; const Option* option; const Logger* logger; - string header; + char headerBuf[HEADERBUF_SIZE+1]; + int headerBufLength; public: HttpConnection(int cuid, const Socket* socket, const Request* req, const Option* op, const Logger* logger); diff --git a/src/HttpRequestCommand.cc b/src/HttpRequestCommand.cc index 42090bef..84439b6b 100644 --- a/src/HttpRequestCommand.cc +++ b/src/HttpRequestCommand.cc @@ -21,9 +21,6 @@ /* copyright --> */ #include "HttpRequestCommand.h" #include "HttpResponseCommand.h" -#include "HttpInitiateConnectionCommand.h" -#include "Socket.h" -#include "Util.h" #include "HttpConnection.h" HttpRequestCommand::HttpRequestCommand(int cuid, Request* req, DownloadEngine* e, Socket* s):AbstractCommand(cuid, req, e, s) { @@ -43,7 +40,11 @@ bool HttpRequestCommand::executeInternal(Segment seg) { req->seg = seg; http.sendRequest(seg); - HttpResponseCommand* command = new HttpResponseCommand(cuid, req, e, socket); + Command* command = getNextCommand(); e->commands.push(command); return true; } + +Command* HttpRequestCommand::getNextCommand() const { + return new HttpResponseCommand(cuid, req, e, socket); +} diff --git a/src/HttpRequestCommand.h b/src/HttpRequestCommand.h index 2e1b4cef..f387cdce 100644 --- a/src/HttpRequestCommand.h +++ b/src/HttpRequestCommand.h @@ -27,7 +27,7 @@ class HttpRequestCommand:public AbstractCommand { protected: bool executeInternal(Segment segment); - + Command* getNextCommand() const; public: HttpRequestCommand(int cuid, Request* req, DownloadEngine* e, Socket* s); ~HttpRequestCommand(); diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc index fd2526b8..48783d24 100644 --- a/src/HttpResponseCommand.cc +++ b/src/HttpResponseCommand.cc @@ -26,6 +26,9 @@ #include "HttpInitiateConnectionCommand.h" #include "message.h" #include "Util.h" +#include "TrackerDownloadCommand.h" +// TODO +#include "TorrentDownloadEngine.h" HttpResponseCommand::HttpResponseCommand(int cuid, Request* req, DownloadEngine* e, Socket* s): AbstractCommand(cuid, req, e, s) { @@ -89,6 +92,15 @@ bool HttpResponseCommand::handleRedirect(string url, const HttpHeader& headers) } bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) { + // TODO quick and dirty way + if(req->isTorrent) { + long long int size = headers.getFirstAsLLInt("Content-Length"); + e->segmentMan->totalSize = size; + e->segmentMan->isSplittable = false; + createHttpDownloadCommand(); + return true; + } + long long int size = headers.getFirstAsLLInt("Content-Length"); if(size == LONG_LONG_MAX || size < 0) { throw new DlAbortEx(EX_TOO_LARGE_FILE, size); @@ -126,16 +138,22 @@ bool HttpResponseCommand::handleOtherEncoding(string transferEncoding, const Htt } void HttpResponseCommand::createHttpDownloadCommand(string transferEncoding) { - HttpDownloadCommand* command = new HttpDownloadCommand(cuid, req, e, socket); - TransferEncoding* enc = NULL; - if(transferEncoding.size() && (enc = command->getTransferEncoding(transferEncoding)) == NULL) { - delete(command); - throw new DlAbortEx(EX_TRANSFER_ENCODING_NOT_SUPPORTED, transferEncoding.c_str()); - } else { - if(enc != NULL) { - command->transferEncoding = transferEncoding; - enc->init(); + if(!req->isTorrent) { + HttpDownloadCommand* command = new HttpDownloadCommand(cuid, req, e, socket); + TransferEncoding* enc = NULL; + if(transferEncoding.size() && (enc = command->getTransferEncoding(transferEncoding)) == NULL) { + delete(command); + throw new DlAbortEx(EX_TRANSFER_ENCODING_NOT_SUPPORTED, transferEncoding.c_str()); + } else { + if(enc != NULL) { + command->transferEncoding = transferEncoding; + enc->init(); + } + e->commands.push(command); } + } else { + // TODO + TrackerDownloadCommand* command = new TrackerDownloadCommand(cuid, req, (TorrentDownloadEngine*)e, socket); e->commands.push(command); } } diff --git a/src/List.cc b/src/List.cc new file mode 100644 index 00000000..be123769 --- /dev/null +++ b/src/List.cc @@ -0,0 +1,47 @@ +/* */ +#include "List.h" +#include "MetaEntryVisitor.h" + +List::List() {} + +List::~List() { + clearList(); +} + +void List::clearList() { + for(MetaList::iterator itr = mlist.begin(); itr != mlist.end(); itr++) { + delete *itr; + } +} + +void List::add(MetaEntry* entry) { + mlist.push_back(entry); +} + +const MetaList& List::getList() const { + return mlist; +} + +void List::accept(MetaEntryVisitor* v) const { + v->visit(this); +} diff --git a/src/List.h b/src/List.h new file mode 100644 index 00000000..64c2a462 --- /dev/null +++ b/src/List.h @@ -0,0 +1,48 @@ +/* */ +#ifndef _D_LIST_H_ +#define _D_LIST_H_ + +#include "MetaEntry.h" +#include + +using namespace std; + +typedef vector MetaList; + +class List : public MetaEntry { +private: + MetaList mlist; + + void clearList(); +public: + List(); + ~List(); + + void add(MetaEntry* entry); + + const MetaList& getList() const; + + void accept(MetaEntryVisitor* v) const; +}; + +#endif // _D_LIST_H_ diff --git a/src/Makefile.am b/src/Makefile.am index da3e770e..fa85602d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,11 +41,41 @@ SRCS = Socket.cc Socket.h\ ChunkedEncoding.cc ChunkedEncoding.h\ DiskWriter.h\ DefaultDiskWriter.cc DefaultDiskWriter.h\ + PreAllocationDiskWriter.cc PreAllocationDiskWriter.h\ AbstractDiskWriter.cc AbstractDiskWriter.h\ File.cc File.h\ Option.cc Option.h\ Base64.cc Base64.h\ - CookieBox.cc CookieBox.h + CookieBox.cc CookieBox.h\ + MetaEntry.h\ + Data.cc Data.h\ + Dictionary.cc Dictionary.h\ + List.cc List.h\ + MetaFileUtil.cc MetaFileUtil.h\ + MetaEntryVisitor.h\ + ShaVisitor.cc ShaVisitor.h\ + TrackerInitCommand.cc TrackerInitCommand.h\ + TrackerDownloadCommand.cc TrackerDownloadCommand.h\ + TrackerUpdateCommand.cc TrackerUpdateCommand.h\ + TorrentMan.cc TorrentMan.h\ + PeerConnection.cc PeerConnection.h\ + PeerMessageUtil.cc PeerMessageUtil.h\ + PeerAbstractCommand.cc PeerAbstractCommand.h\ + PeerInitiateConnectionCommand.cc PeerInitiateConnectionCommand.h\ + PeerInteractionCommand.cc PeerInteractionCommand.h\ + Peer.cc Peer.h\ + BitfieldMan.cc BitfieldMan.h\ + TorrentDownloadEngine.cc TorrentDownloadEngine.h\ + TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\ + PeerListenCommand.cc PeerListenCommand.h\ + PendingMessage.cc PendingMessage.h\ + PeerMessage.cc PeerMessage.h\ + HandshakeMessage.h\ + Piece.cc Piece.h\ + RequestSlot.cc RequestSlot.h\ + RequestSlotMan.cc RequestSlotMan.h\ + TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\ + Directory.cc Directory.h noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ diff --git a/src/Makefile.in b/src/Makefile.in index 100443ea..fd10d964 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -91,9 +91,32 @@ am__objects_1 = libaria2c_a-Socket.$(OBJEXT) \ libaria2c_a-SimpleLogger.$(OBJEXT) \ libaria2c_a-ChunkedEncoding.$(OBJEXT) \ libaria2c_a-DefaultDiskWriter.$(OBJEXT) \ + libaria2c_a-PreAllocationDiskWriter.$(OBJEXT) \ libaria2c_a-AbstractDiskWriter.$(OBJEXT) \ libaria2c_a-File.$(OBJEXT) libaria2c_a-Option.$(OBJEXT) \ - libaria2c_a-Base64.$(OBJEXT) libaria2c_a-CookieBox.$(OBJEXT) + libaria2c_a-Base64.$(OBJEXT) libaria2c_a-CookieBox.$(OBJEXT) \ + libaria2c_a-Data.$(OBJEXT) libaria2c_a-Dictionary.$(OBJEXT) \ + libaria2c_a-List.$(OBJEXT) libaria2c_a-MetaFileUtil.$(OBJEXT) \ + libaria2c_a-ShaVisitor.$(OBJEXT) \ + libaria2c_a-TrackerInitCommand.$(OBJEXT) \ + libaria2c_a-TrackerDownloadCommand.$(OBJEXT) \ + libaria2c_a-TrackerUpdateCommand.$(OBJEXT) \ + libaria2c_a-TorrentMan.$(OBJEXT) \ + libaria2c_a-PeerConnection.$(OBJEXT) \ + libaria2c_a-PeerMessageUtil.$(OBJEXT) \ + libaria2c_a-PeerAbstractCommand.$(OBJEXT) \ + libaria2c_a-PeerInitiateConnectionCommand.$(OBJEXT) \ + libaria2c_a-PeerInteractionCommand.$(OBJEXT) \ + libaria2c_a-Peer.$(OBJEXT) libaria2c_a-BitfieldMan.$(OBJEXT) \ + libaria2c_a-TorrentDownloadEngine.$(OBJEXT) \ + libaria2c_a-TorrentConsoleDownloadEngine.$(OBJEXT) \ + libaria2c_a-PeerListenCommand.$(OBJEXT) \ + libaria2c_a-PendingMessage.$(OBJEXT) \ + libaria2c_a-PeerMessage.$(OBJEXT) libaria2c_a-Piece.$(OBJEXT) \ + libaria2c_a-RequestSlot.$(OBJEXT) \ + libaria2c_a-RequestSlotMan.$(OBJEXT) \ + libaria2c_a-TorrentAutoSaveCommand.$(OBJEXT) \ + libaria2c_a-Directory.$(OBJEXT) am_libaria2c_a_OBJECTS = $(am__objects_1) libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS) am__installdirs = "$(DESTDIR)$(bindir)" @@ -275,11 +298,41 @@ SRCS = Socket.cc Socket.h\ ChunkedEncoding.cc ChunkedEncoding.h\ DiskWriter.h\ DefaultDiskWriter.cc DefaultDiskWriter.h\ + PreAllocationDiskWriter.cc PreAllocationDiskWriter.h\ AbstractDiskWriter.cc AbstractDiskWriter.h\ File.cc File.h\ Option.cc Option.h\ Base64.cc Base64.h\ - CookieBox.cc CookieBox.h + CookieBox.cc CookieBox.h\ + MetaEntry.h\ + Data.cc Data.h\ + Dictionary.cc Dictionary.h\ + List.cc List.h\ + MetaFileUtil.cc MetaFileUtil.h\ + MetaEntryVisitor.h\ + ShaVisitor.cc ShaVisitor.h\ + TrackerInitCommand.cc TrackerInitCommand.h\ + TrackerDownloadCommand.cc TrackerDownloadCommand.h\ + TrackerUpdateCommand.cc TrackerUpdateCommand.h\ + TorrentMan.cc TorrentMan.h\ + PeerConnection.cc PeerConnection.h\ + PeerMessageUtil.cc PeerMessageUtil.h\ + PeerAbstractCommand.cc PeerAbstractCommand.h\ + PeerInitiateConnectionCommand.cc PeerInitiateConnectionCommand.h\ + PeerInteractionCommand.cc PeerInteractionCommand.h\ + Peer.cc Peer.h\ + BitfieldMan.cc BitfieldMan.h\ + TorrentDownloadEngine.cc TorrentDownloadEngine.h\ + TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\ + PeerListenCommand.cc PeerListenCommand.h\ + PendingMessage.cc PendingMessage.h\ + PeerMessage.cc PeerMessage.h\ + HandshakeMessage.h\ + Piece.cc Piece.h\ + RequestSlot.cc RequestSlot.h\ + RequestSlotMan.cc RequestSlotMan.h\ + TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\ + Directory.cc Directory.h noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) @@ -366,10 +419,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-AbstractCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-AbstractDiskWriter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Base64.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-BitfieldMan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-ChunkedEncoding.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-ConsoleDownloadEngine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-CookieBox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Data.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-DefaultDiskWriter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Dictionary.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Directory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-DownloadCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-DownloadEngine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-File.Po@am__quote@ @@ -388,16 +445,39 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-HttpRequestCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-HttpResponseCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-InitiateConnectionCommandFactory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-List.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-MetaFileUtil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Option.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Peer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-PeerAbstractCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-PeerConnection.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-PeerInitiateConnectionCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-PeerInteractionCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-PeerListenCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-PeerMessage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-PeerMessageUtil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-PendingMessage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Piece.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-PreAllocationDiskWriter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Request.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-RequestSlot.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-RequestSlotMan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-SegmentMan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-SegmentSplitter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-ShaVisitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-SimpleLogger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-SleepCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Socket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-SocketCore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-SplitFirstSegmentSplitter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-SplitSlowestSegmentSplitter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-TorrentAutoSaveCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-TorrentConsoleDownloadEngine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-TorrentDownloadEngine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-TorrentMan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-TrackerDownloadCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-TrackerInitCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-TrackerUpdateCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaria2c_a-Util.Po@am__quote@ .cc.o: @@ -848,6 +928,20 @@ libaria2c_a-DefaultDiskWriter.obj: DefaultDiskWriter.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-DefaultDiskWriter.obj `if test -f 'DefaultDiskWriter.cc'; then $(CYGPATH_W) 'DefaultDiskWriter.cc'; else $(CYGPATH_W) '$(srcdir)/DefaultDiskWriter.cc'; fi` +libaria2c_a-PreAllocationDiskWriter.o: PreAllocationDiskWriter.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PreAllocationDiskWriter.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-PreAllocationDiskWriter.Tpo" -c -o libaria2c_a-PreAllocationDiskWriter.o `test -f 'PreAllocationDiskWriter.cc' || echo '$(srcdir)/'`PreAllocationDiskWriter.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PreAllocationDiskWriter.Tpo" "$(DEPDIR)/libaria2c_a-PreAllocationDiskWriter.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PreAllocationDiskWriter.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PreAllocationDiskWriter.cc' object='libaria2c_a-PreAllocationDiskWriter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PreAllocationDiskWriter.o `test -f 'PreAllocationDiskWriter.cc' || echo '$(srcdir)/'`PreAllocationDiskWriter.cc + +libaria2c_a-PreAllocationDiskWriter.obj: PreAllocationDiskWriter.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PreAllocationDiskWriter.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-PreAllocationDiskWriter.Tpo" -c -o libaria2c_a-PreAllocationDiskWriter.obj `if test -f 'PreAllocationDiskWriter.cc'; then $(CYGPATH_W) 'PreAllocationDiskWriter.cc'; else $(CYGPATH_W) '$(srcdir)/PreAllocationDiskWriter.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PreAllocationDiskWriter.Tpo" "$(DEPDIR)/libaria2c_a-PreAllocationDiskWriter.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PreAllocationDiskWriter.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PreAllocationDiskWriter.cc' object='libaria2c_a-PreAllocationDiskWriter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PreAllocationDiskWriter.obj `if test -f 'PreAllocationDiskWriter.cc'; then $(CYGPATH_W) 'PreAllocationDiskWriter.cc'; else $(CYGPATH_W) '$(srcdir)/PreAllocationDiskWriter.cc'; fi` + libaria2c_a-AbstractDiskWriter.o: AbstractDiskWriter.cc @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-AbstractDiskWriter.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-AbstractDiskWriter.Tpo" -c -o libaria2c_a-AbstractDiskWriter.o `test -f 'AbstractDiskWriter.cc' || echo '$(srcdir)/'`AbstractDiskWriter.cc; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-AbstractDiskWriter.Tpo" "$(DEPDIR)/libaria2c_a-AbstractDiskWriter.Po"; else rm -f "$(DEPDIR)/libaria2c_a-AbstractDiskWriter.Tpo"; exit 1; fi @@ -918,6 +1012,370 @@ libaria2c_a-CookieBox.obj: CookieBox.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-CookieBox.obj `if test -f 'CookieBox.cc'; then $(CYGPATH_W) 'CookieBox.cc'; else $(CYGPATH_W) '$(srcdir)/CookieBox.cc'; fi` +libaria2c_a-Data.o: Data.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Data.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-Data.Tpo" -c -o libaria2c_a-Data.o `test -f 'Data.cc' || echo '$(srcdir)/'`Data.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Data.Tpo" "$(DEPDIR)/libaria2c_a-Data.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Data.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Data.cc' object='libaria2c_a-Data.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Data.o `test -f 'Data.cc' || echo '$(srcdir)/'`Data.cc + +libaria2c_a-Data.obj: Data.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Data.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-Data.Tpo" -c -o libaria2c_a-Data.obj `if test -f 'Data.cc'; then $(CYGPATH_W) 'Data.cc'; else $(CYGPATH_W) '$(srcdir)/Data.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Data.Tpo" "$(DEPDIR)/libaria2c_a-Data.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Data.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Data.cc' object='libaria2c_a-Data.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Data.obj `if test -f 'Data.cc'; then $(CYGPATH_W) 'Data.cc'; else $(CYGPATH_W) '$(srcdir)/Data.cc'; fi` + +libaria2c_a-Dictionary.o: Dictionary.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Dictionary.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-Dictionary.Tpo" -c -o libaria2c_a-Dictionary.o `test -f 'Dictionary.cc' || echo '$(srcdir)/'`Dictionary.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Dictionary.Tpo" "$(DEPDIR)/libaria2c_a-Dictionary.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Dictionary.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Dictionary.cc' object='libaria2c_a-Dictionary.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Dictionary.o `test -f 'Dictionary.cc' || echo '$(srcdir)/'`Dictionary.cc + +libaria2c_a-Dictionary.obj: Dictionary.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Dictionary.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-Dictionary.Tpo" -c -o libaria2c_a-Dictionary.obj `if test -f 'Dictionary.cc'; then $(CYGPATH_W) 'Dictionary.cc'; else $(CYGPATH_W) '$(srcdir)/Dictionary.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Dictionary.Tpo" "$(DEPDIR)/libaria2c_a-Dictionary.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Dictionary.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Dictionary.cc' object='libaria2c_a-Dictionary.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Dictionary.obj `if test -f 'Dictionary.cc'; then $(CYGPATH_W) 'Dictionary.cc'; else $(CYGPATH_W) '$(srcdir)/Dictionary.cc'; fi` + +libaria2c_a-List.o: List.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-List.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-List.Tpo" -c -o libaria2c_a-List.o `test -f 'List.cc' || echo '$(srcdir)/'`List.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-List.Tpo" "$(DEPDIR)/libaria2c_a-List.Po"; else rm -f "$(DEPDIR)/libaria2c_a-List.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='List.cc' object='libaria2c_a-List.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-List.o `test -f 'List.cc' || echo '$(srcdir)/'`List.cc + +libaria2c_a-List.obj: List.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-List.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-List.Tpo" -c -o libaria2c_a-List.obj `if test -f 'List.cc'; then $(CYGPATH_W) 'List.cc'; else $(CYGPATH_W) '$(srcdir)/List.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-List.Tpo" "$(DEPDIR)/libaria2c_a-List.Po"; else rm -f "$(DEPDIR)/libaria2c_a-List.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='List.cc' object='libaria2c_a-List.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-List.obj `if test -f 'List.cc'; then $(CYGPATH_W) 'List.cc'; else $(CYGPATH_W) '$(srcdir)/List.cc'; fi` + +libaria2c_a-MetaFileUtil.o: MetaFileUtil.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-MetaFileUtil.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-MetaFileUtil.Tpo" -c -o libaria2c_a-MetaFileUtil.o `test -f 'MetaFileUtil.cc' || echo '$(srcdir)/'`MetaFileUtil.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-MetaFileUtil.Tpo" "$(DEPDIR)/libaria2c_a-MetaFileUtil.Po"; else rm -f "$(DEPDIR)/libaria2c_a-MetaFileUtil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MetaFileUtil.cc' object='libaria2c_a-MetaFileUtil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-MetaFileUtil.o `test -f 'MetaFileUtil.cc' || echo '$(srcdir)/'`MetaFileUtil.cc + +libaria2c_a-MetaFileUtil.obj: MetaFileUtil.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-MetaFileUtil.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-MetaFileUtil.Tpo" -c -o libaria2c_a-MetaFileUtil.obj `if test -f 'MetaFileUtil.cc'; then $(CYGPATH_W) 'MetaFileUtil.cc'; else $(CYGPATH_W) '$(srcdir)/MetaFileUtil.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-MetaFileUtil.Tpo" "$(DEPDIR)/libaria2c_a-MetaFileUtil.Po"; else rm -f "$(DEPDIR)/libaria2c_a-MetaFileUtil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MetaFileUtil.cc' object='libaria2c_a-MetaFileUtil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-MetaFileUtil.obj `if test -f 'MetaFileUtil.cc'; then $(CYGPATH_W) 'MetaFileUtil.cc'; else $(CYGPATH_W) '$(srcdir)/MetaFileUtil.cc'; fi` + +libaria2c_a-ShaVisitor.o: ShaVisitor.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-ShaVisitor.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-ShaVisitor.Tpo" -c -o libaria2c_a-ShaVisitor.o `test -f 'ShaVisitor.cc' || echo '$(srcdir)/'`ShaVisitor.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-ShaVisitor.Tpo" "$(DEPDIR)/libaria2c_a-ShaVisitor.Po"; else rm -f "$(DEPDIR)/libaria2c_a-ShaVisitor.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ShaVisitor.cc' object='libaria2c_a-ShaVisitor.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-ShaVisitor.o `test -f 'ShaVisitor.cc' || echo '$(srcdir)/'`ShaVisitor.cc + +libaria2c_a-ShaVisitor.obj: ShaVisitor.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-ShaVisitor.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-ShaVisitor.Tpo" -c -o libaria2c_a-ShaVisitor.obj `if test -f 'ShaVisitor.cc'; then $(CYGPATH_W) 'ShaVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/ShaVisitor.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-ShaVisitor.Tpo" "$(DEPDIR)/libaria2c_a-ShaVisitor.Po"; else rm -f "$(DEPDIR)/libaria2c_a-ShaVisitor.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ShaVisitor.cc' object='libaria2c_a-ShaVisitor.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-ShaVisitor.obj `if test -f 'ShaVisitor.cc'; then $(CYGPATH_W) 'ShaVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/ShaVisitor.cc'; fi` + +libaria2c_a-TrackerInitCommand.o: TrackerInitCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TrackerInitCommand.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-TrackerInitCommand.Tpo" -c -o libaria2c_a-TrackerInitCommand.o `test -f 'TrackerInitCommand.cc' || echo '$(srcdir)/'`TrackerInitCommand.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TrackerInitCommand.Tpo" "$(DEPDIR)/libaria2c_a-TrackerInitCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TrackerInitCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TrackerInitCommand.cc' object='libaria2c_a-TrackerInitCommand.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TrackerInitCommand.o `test -f 'TrackerInitCommand.cc' || echo '$(srcdir)/'`TrackerInitCommand.cc + +libaria2c_a-TrackerInitCommand.obj: TrackerInitCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TrackerInitCommand.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-TrackerInitCommand.Tpo" -c -o libaria2c_a-TrackerInitCommand.obj `if test -f 'TrackerInitCommand.cc'; then $(CYGPATH_W) 'TrackerInitCommand.cc'; else $(CYGPATH_W) '$(srcdir)/TrackerInitCommand.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TrackerInitCommand.Tpo" "$(DEPDIR)/libaria2c_a-TrackerInitCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TrackerInitCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TrackerInitCommand.cc' object='libaria2c_a-TrackerInitCommand.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TrackerInitCommand.obj `if test -f 'TrackerInitCommand.cc'; then $(CYGPATH_W) 'TrackerInitCommand.cc'; else $(CYGPATH_W) '$(srcdir)/TrackerInitCommand.cc'; fi` + +libaria2c_a-TrackerDownloadCommand.o: TrackerDownloadCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TrackerDownloadCommand.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-TrackerDownloadCommand.Tpo" -c -o libaria2c_a-TrackerDownloadCommand.o `test -f 'TrackerDownloadCommand.cc' || echo '$(srcdir)/'`TrackerDownloadCommand.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TrackerDownloadCommand.Tpo" "$(DEPDIR)/libaria2c_a-TrackerDownloadCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TrackerDownloadCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TrackerDownloadCommand.cc' object='libaria2c_a-TrackerDownloadCommand.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TrackerDownloadCommand.o `test -f 'TrackerDownloadCommand.cc' || echo '$(srcdir)/'`TrackerDownloadCommand.cc + +libaria2c_a-TrackerDownloadCommand.obj: TrackerDownloadCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TrackerDownloadCommand.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-TrackerDownloadCommand.Tpo" -c -o libaria2c_a-TrackerDownloadCommand.obj `if test -f 'TrackerDownloadCommand.cc'; then $(CYGPATH_W) 'TrackerDownloadCommand.cc'; else $(CYGPATH_W) '$(srcdir)/TrackerDownloadCommand.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TrackerDownloadCommand.Tpo" "$(DEPDIR)/libaria2c_a-TrackerDownloadCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TrackerDownloadCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TrackerDownloadCommand.cc' object='libaria2c_a-TrackerDownloadCommand.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TrackerDownloadCommand.obj `if test -f 'TrackerDownloadCommand.cc'; then $(CYGPATH_W) 'TrackerDownloadCommand.cc'; else $(CYGPATH_W) '$(srcdir)/TrackerDownloadCommand.cc'; fi` + +libaria2c_a-TrackerUpdateCommand.o: TrackerUpdateCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TrackerUpdateCommand.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-TrackerUpdateCommand.Tpo" -c -o libaria2c_a-TrackerUpdateCommand.o `test -f 'TrackerUpdateCommand.cc' || echo '$(srcdir)/'`TrackerUpdateCommand.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TrackerUpdateCommand.Tpo" "$(DEPDIR)/libaria2c_a-TrackerUpdateCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TrackerUpdateCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TrackerUpdateCommand.cc' object='libaria2c_a-TrackerUpdateCommand.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TrackerUpdateCommand.o `test -f 'TrackerUpdateCommand.cc' || echo '$(srcdir)/'`TrackerUpdateCommand.cc + +libaria2c_a-TrackerUpdateCommand.obj: TrackerUpdateCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TrackerUpdateCommand.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-TrackerUpdateCommand.Tpo" -c -o libaria2c_a-TrackerUpdateCommand.obj `if test -f 'TrackerUpdateCommand.cc'; then $(CYGPATH_W) 'TrackerUpdateCommand.cc'; else $(CYGPATH_W) '$(srcdir)/TrackerUpdateCommand.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TrackerUpdateCommand.Tpo" "$(DEPDIR)/libaria2c_a-TrackerUpdateCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TrackerUpdateCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TrackerUpdateCommand.cc' object='libaria2c_a-TrackerUpdateCommand.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TrackerUpdateCommand.obj `if test -f 'TrackerUpdateCommand.cc'; then $(CYGPATH_W) 'TrackerUpdateCommand.cc'; else $(CYGPATH_W) '$(srcdir)/TrackerUpdateCommand.cc'; fi` + +libaria2c_a-TorrentMan.o: TorrentMan.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TorrentMan.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-TorrentMan.Tpo" -c -o libaria2c_a-TorrentMan.o `test -f 'TorrentMan.cc' || echo '$(srcdir)/'`TorrentMan.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TorrentMan.Tpo" "$(DEPDIR)/libaria2c_a-TorrentMan.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TorrentMan.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentMan.cc' object='libaria2c_a-TorrentMan.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TorrentMan.o `test -f 'TorrentMan.cc' || echo '$(srcdir)/'`TorrentMan.cc + +libaria2c_a-TorrentMan.obj: TorrentMan.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TorrentMan.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-TorrentMan.Tpo" -c -o libaria2c_a-TorrentMan.obj `if test -f 'TorrentMan.cc'; then $(CYGPATH_W) 'TorrentMan.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentMan.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TorrentMan.Tpo" "$(DEPDIR)/libaria2c_a-TorrentMan.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TorrentMan.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentMan.cc' object='libaria2c_a-TorrentMan.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TorrentMan.obj `if test -f 'TorrentMan.cc'; then $(CYGPATH_W) 'TorrentMan.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentMan.cc'; fi` + +libaria2c_a-PeerConnection.o: PeerConnection.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerConnection.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerConnection.Tpo" -c -o libaria2c_a-PeerConnection.o `test -f 'PeerConnection.cc' || echo '$(srcdir)/'`PeerConnection.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerConnection.Tpo" "$(DEPDIR)/libaria2c_a-PeerConnection.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerConnection.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerConnection.cc' object='libaria2c_a-PeerConnection.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerConnection.o `test -f 'PeerConnection.cc' || echo '$(srcdir)/'`PeerConnection.cc + +libaria2c_a-PeerConnection.obj: PeerConnection.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerConnection.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerConnection.Tpo" -c -o libaria2c_a-PeerConnection.obj `if test -f 'PeerConnection.cc'; then $(CYGPATH_W) 'PeerConnection.cc'; else $(CYGPATH_W) '$(srcdir)/PeerConnection.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerConnection.Tpo" "$(DEPDIR)/libaria2c_a-PeerConnection.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerConnection.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerConnection.cc' object='libaria2c_a-PeerConnection.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerConnection.obj `if test -f 'PeerConnection.cc'; then $(CYGPATH_W) 'PeerConnection.cc'; else $(CYGPATH_W) '$(srcdir)/PeerConnection.cc'; fi` + +libaria2c_a-PeerMessageUtil.o: PeerMessageUtil.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerMessageUtil.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerMessageUtil.Tpo" -c -o libaria2c_a-PeerMessageUtil.o `test -f 'PeerMessageUtil.cc' || echo '$(srcdir)/'`PeerMessageUtil.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerMessageUtil.Tpo" "$(DEPDIR)/libaria2c_a-PeerMessageUtil.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerMessageUtil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerMessageUtil.cc' object='libaria2c_a-PeerMessageUtil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerMessageUtil.o `test -f 'PeerMessageUtil.cc' || echo '$(srcdir)/'`PeerMessageUtil.cc + +libaria2c_a-PeerMessageUtil.obj: PeerMessageUtil.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerMessageUtil.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerMessageUtil.Tpo" -c -o libaria2c_a-PeerMessageUtil.obj `if test -f 'PeerMessageUtil.cc'; then $(CYGPATH_W) 'PeerMessageUtil.cc'; else $(CYGPATH_W) '$(srcdir)/PeerMessageUtil.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerMessageUtil.Tpo" "$(DEPDIR)/libaria2c_a-PeerMessageUtil.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerMessageUtil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerMessageUtil.cc' object='libaria2c_a-PeerMessageUtil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerMessageUtil.obj `if test -f 'PeerMessageUtil.cc'; then $(CYGPATH_W) 'PeerMessageUtil.cc'; else $(CYGPATH_W) '$(srcdir)/PeerMessageUtil.cc'; fi` + +libaria2c_a-PeerAbstractCommand.o: PeerAbstractCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerAbstractCommand.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerAbstractCommand.Tpo" -c -o libaria2c_a-PeerAbstractCommand.o `test -f 'PeerAbstractCommand.cc' || echo '$(srcdir)/'`PeerAbstractCommand.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerAbstractCommand.Tpo" "$(DEPDIR)/libaria2c_a-PeerAbstractCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerAbstractCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerAbstractCommand.cc' object='libaria2c_a-PeerAbstractCommand.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerAbstractCommand.o `test -f 'PeerAbstractCommand.cc' || echo '$(srcdir)/'`PeerAbstractCommand.cc + +libaria2c_a-PeerAbstractCommand.obj: PeerAbstractCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerAbstractCommand.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerAbstractCommand.Tpo" -c -o libaria2c_a-PeerAbstractCommand.obj `if test -f 'PeerAbstractCommand.cc'; then $(CYGPATH_W) 'PeerAbstractCommand.cc'; else $(CYGPATH_W) '$(srcdir)/PeerAbstractCommand.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerAbstractCommand.Tpo" "$(DEPDIR)/libaria2c_a-PeerAbstractCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerAbstractCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerAbstractCommand.cc' object='libaria2c_a-PeerAbstractCommand.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerAbstractCommand.obj `if test -f 'PeerAbstractCommand.cc'; then $(CYGPATH_W) 'PeerAbstractCommand.cc'; else $(CYGPATH_W) '$(srcdir)/PeerAbstractCommand.cc'; fi` + +libaria2c_a-PeerInitiateConnectionCommand.o: PeerInitiateConnectionCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerInitiateConnectionCommand.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerInitiateConnectionCommand.Tpo" -c -o libaria2c_a-PeerInitiateConnectionCommand.o `test -f 'PeerInitiateConnectionCommand.cc' || echo '$(srcdir)/'`PeerInitiateConnectionCommand.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerInitiateConnectionCommand.Tpo" "$(DEPDIR)/libaria2c_a-PeerInitiateConnectionCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerInitiateConnectionCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerInitiateConnectionCommand.cc' object='libaria2c_a-PeerInitiateConnectionCommand.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerInitiateConnectionCommand.o `test -f 'PeerInitiateConnectionCommand.cc' || echo '$(srcdir)/'`PeerInitiateConnectionCommand.cc + +libaria2c_a-PeerInitiateConnectionCommand.obj: PeerInitiateConnectionCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerInitiateConnectionCommand.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerInitiateConnectionCommand.Tpo" -c -o libaria2c_a-PeerInitiateConnectionCommand.obj `if test -f 'PeerInitiateConnectionCommand.cc'; then $(CYGPATH_W) 'PeerInitiateConnectionCommand.cc'; else $(CYGPATH_W) '$(srcdir)/PeerInitiateConnectionCommand.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerInitiateConnectionCommand.Tpo" "$(DEPDIR)/libaria2c_a-PeerInitiateConnectionCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerInitiateConnectionCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerInitiateConnectionCommand.cc' object='libaria2c_a-PeerInitiateConnectionCommand.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerInitiateConnectionCommand.obj `if test -f 'PeerInitiateConnectionCommand.cc'; then $(CYGPATH_W) 'PeerInitiateConnectionCommand.cc'; else $(CYGPATH_W) '$(srcdir)/PeerInitiateConnectionCommand.cc'; fi` + +libaria2c_a-PeerInteractionCommand.o: PeerInteractionCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerInteractionCommand.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerInteractionCommand.Tpo" -c -o libaria2c_a-PeerInteractionCommand.o `test -f 'PeerInteractionCommand.cc' || echo '$(srcdir)/'`PeerInteractionCommand.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerInteractionCommand.Tpo" "$(DEPDIR)/libaria2c_a-PeerInteractionCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerInteractionCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerInteractionCommand.cc' object='libaria2c_a-PeerInteractionCommand.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerInteractionCommand.o `test -f 'PeerInteractionCommand.cc' || echo '$(srcdir)/'`PeerInteractionCommand.cc + +libaria2c_a-PeerInteractionCommand.obj: PeerInteractionCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerInteractionCommand.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerInteractionCommand.Tpo" -c -o libaria2c_a-PeerInteractionCommand.obj `if test -f 'PeerInteractionCommand.cc'; then $(CYGPATH_W) 'PeerInteractionCommand.cc'; else $(CYGPATH_W) '$(srcdir)/PeerInteractionCommand.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerInteractionCommand.Tpo" "$(DEPDIR)/libaria2c_a-PeerInteractionCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerInteractionCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerInteractionCommand.cc' object='libaria2c_a-PeerInteractionCommand.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerInteractionCommand.obj `if test -f 'PeerInteractionCommand.cc'; then $(CYGPATH_W) 'PeerInteractionCommand.cc'; else $(CYGPATH_W) '$(srcdir)/PeerInteractionCommand.cc'; fi` + +libaria2c_a-Peer.o: Peer.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Peer.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-Peer.Tpo" -c -o libaria2c_a-Peer.o `test -f 'Peer.cc' || echo '$(srcdir)/'`Peer.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Peer.Tpo" "$(DEPDIR)/libaria2c_a-Peer.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Peer.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Peer.cc' object='libaria2c_a-Peer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Peer.o `test -f 'Peer.cc' || echo '$(srcdir)/'`Peer.cc + +libaria2c_a-Peer.obj: Peer.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Peer.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-Peer.Tpo" -c -o libaria2c_a-Peer.obj `if test -f 'Peer.cc'; then $(CYGPATH_W) 'Peer.cc'; else $(CYGPATH_W) '$(srcdir)/Peer.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Peer.Tpo" "$(DEPDIR)/libaria2c_a-Peer.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Peer.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Peer.cc' object='libaria2c_a-Peer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Peer.obj `if test -f 'Peer.cc'; then $(CYGPATH_W) 'Peer.cc'; else $(CYGPATH_W) '$(srcdir)/Peer.cc'; fi` + +libaria2c_a-BitfieldMan.o: BitfieldMan.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-BitfieldMan.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-BitfieldMan.Tpo" -c -o libaria2c_a-BitfieldMan.o `test -f 'BitfieldMan.cc' || echo '$(srcdir)/'`BitfieldMan.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-BitfieldMan.Tpo" "$(DEPDIR)/libaria2c_a-BitfieldMan.Po"; else rm -f "$(DEPDIR)/libaria2c_a-BitfieldMan.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BitfieldMan.cc' object='libaria2c_a-BitfieldMan.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-BitfieldMan.o `test -f 'BitfieldMan.cc' || echo '$(srcdir)/'`BitfieldMan.cc + +libaria2c_a-BitfieldMan.obj: BitfieldMan.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-BitfieldMan.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-BitfieldMan.Tpo" -c -o libaria2c_a-BitfieldMan.obj `if test -f 'BitfieldMan.cc'; then $(CYGPATH_W) 'BitfieldMan.cc'; else $(CYGPATH_W) '$(srcdir)/BitfieldMan.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-BitfieldMan.Tpo" "$(DEPDIR)/libaria2c_a-BitfieldMan.Po"; else rm -f "$(DEPDIR)/libaria2c_a-BitfieldMan.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BitfieldMan.cc' object='libaria2c_a-BitfieldMan.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-BitfieldMan.obj `if test -f 'BitfieldMan.cc'; then $(CYGPATH_W) 'BitfieldMan.cc'; else $(CYGPATH_W) '$(srcdir)/BitfieldMan.cc'; fi` + +libaria2c_a-TorrentDownloadEngine.o: TorrentDownloadEngine.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TorrentDownloadEngine.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-TorrentDownloadEngine.Tpo" -c -o libaria2c_a-TorrentDownloadEngine.o `test -f 'TorrentDownloadEngine.cc' || echo '$(srcdir)/'`TorrentDownloadEngine.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TorrentDownloadEngine.Tpo" "$(DEPDIR)/libaria2c_a-TorrentDownloadEngine.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TorrentDownloadEngine.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentDownloadEngine.cc' object='libaria2c_a-TorrentDownloadEngine.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TorrentDownloadEngine.o `test -f 'TorrentDownloadEngine.cc' || echo '$(srcdir)/'`TorrentDownloadEngine.cc + +libaria2c_a-TorrentDownloadEngine.obj: TorrentDownloadEngine.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TorrentDownloadEngine.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-TorrentDownloadEngine.Tpo" -c -o libaria2c_a-TorrentDownloadEngine.obj `if test -f 'TorrentDownloadEngine.cc'; then $(CYGPATH_W) 'TorrentDownloadEngine.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentDownloadEngine.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TorrentDownloadEngine.Tpo" "$(DEPDIR)/libaria2c_a-TorrentDownloadEngine.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TorrentDownloadEngine.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentDownloadEngine.cc' object='libaria2c_a-TorrentDownloadEngine.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TorrentDownloadEngine.obj `if test -f 'TorrentDownloadEngine.cc'; then $(CYGPATH_W) 'TorrentDownloadEngine.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentDownloadEngine.cc'; fi` + +libaria2c_a-TorrentConsoleDownloadEngine.o: TorrentConsoleDownloadEngine.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TorrentConsoleDownloadEngine.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-TorrentConsoleDownloadEngine.Tpo" -c -o libaria2c_a-TorrentConsoleDownloadEngine.o `test -f 'TorrentConsoleDownloadEngine.cc' || echo '$(srcdir)/'`TorrentConsoleDownloadEngine.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TorrentConsoleDownloadEngine.Tpo" "$(DEPDIR)/libaria2c_a-TorrentConsoleDownloadEngine.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TorrentConsoleDownloadEngine.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentConsoleDownloadEngine.cc' object='libaria2c_a-TorrentConsoleDownloadEngine.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TorrentConsoleDownloadEngine.o `test -f 'TorrentConsoleDownloadEngine.cc' || echo '$(srcdir)/'`TorrentConsoleDownloadEngine.cc + +libaria2c_a-TorrentConsoleDownloadEngine.obj: TorrentConsoleDownloadEngine.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TorrentConsoleDownloadEngine.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-TorrentConsoleDownloadEngine.Tpo" -c -o libaria2c_a-TorrentConsoleDownloadEngine.obj `if test -f 'TorrentConsoleDownloadEngine.cc'; then $(CYGPATH_W) 'TorrentConsoleDownloadEngine.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentConsoleDownloadEngine.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TorrentConsoleDownloadEngine.Tpo" "$(DEPDIR)/libaria2c_a-TorrentConsoleDownloadEngine.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TorrentConsoleDownloadEngine.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentConsoleDownloadEngine.cc' object='libaria2c_a-TorrentConsoleDownloadEngine.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TorrentConsoleDownloadEngine.obj `if test -f 'TorrentConsoleDownloadEngine.cc'; then $(CYGPATH_W) 'TorrentConsoleDownloadEngine.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentConsoleDownloadEngine.cc'; fi` + +libaria2c_a-PeerListenCommand.o: PeerListenCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerListenCommand.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerListenCommand.Tpo" -c -o libaria2c_a-PeerListenCommand.o `test -f 'PeerListenCommand.cc' || echo '$(srcdir)/'`PeerListenCommand.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerListenCommand.Tpo" "$(DEPDIR)/libaria2c_a-PeerListenCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerListenCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerListenCommand.cc' object='libaria2c_a-PeerListenCommand.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerListenCommand.o `test -f 'PeerListenCommand.cc' || echo '$(srcdir)/'`PeerListenCommand.cc + +libaria2c_a-PeerListenCommand.obj: PeerListenCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerListenCommand.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerListenCommand.Tpo" -c -o libaria2c_a-PeerListenCommand.obj `if test -f 'PeerListenCommand.cc'; then $(CYGPATH_W) 'PeerListenCommand.cc'; else $(CYGPATH_W) '$(srcdir)/PeerListenCommand.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerListenCommand.Tpo" "$(DEPDIR)/libaria2c_a-PeerListenCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerListenCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerListenCommand.cc' object='libaria2c_a-PeerListenCommand.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerListenCommand.obj `if test -f 'PeerListenCommand.cc'; then $(CYGPATH_W) 'PeerListenCommand.cc'; else $(CYGPATH_W) '$(srcdir)/PeerListenCommand.cc'; fi` + +libaria2c_a-PendingMessage.o: PendingMessage.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PendingMessage.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-PendingMessage.Tpo" -c -o libaria2c_a-PendingMessage.o `test -f 'PendingMessage.cc' || echo '$(srcdir)/'`PendingMessage.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PendingMessage.Tpo" "$(DEPDIR)/libaria2c_a-PendingMessage.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PendingMessage.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PendingMessage.cc' object='libaria2c_a-PendingMessage.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PendingMessage.o `test -f 'PendingMessage.cc' || echo '$(srcdir)/'`PendingMessage.cc + +libaria2c_a-PendingMessage.obj: PendingMessage.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PendingMessage.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-PendingMessage.Tpo" -c -o libaria2c_a-PendingMessage.obj `if test -f 'PendingMessage.cc'; then $(CYGPATH_W) 'PendingMessage.cc'; else $(CYGPATH_W) '$(srcdir)/PendingMessage.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PendingMessage.Tpo" "$(DEPDIR)/libaria2c_a-PendingMessage.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PendingMessage.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PendingMessage.cc' object='libaria2c_a-PendingMessage.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PendingMessage.obj `if test -f 'PendingMessage.cc'; then $(CYGPATH_W) 'PendingMessage.cc'; else $(CYGPATH_W) '$(srcdir)/PendingMessage.cc'; fi` + +libaria2c_a-PeerMessage.o: PeerMessage.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerMessage.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerMessage.Tpo" -c -o libaria2c_a-PeerMessage.o `test -f 'PeerMessage.cc' || echo '$(srcdir)/'`PeerMessage.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerMessage.Tpo" "$(DEPDIR)/libaria2c_a-PeerMessage.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerMessage.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerMessage.cc' object='libaria2c_a-PeerMessage.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerMessage.o `test -f 'PeerMessage.cc' || echo '$(srcdir)/'`PeerMessage.cc + +libaria2c_a-PeerMessage.obj: PeerMessage.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-PeerMessage.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-PeerMessage.Tpo" -c -o libaria2c_a-PeerMessage.obj `if test -f 'PeerMessage.cc'; then $(CYGPATH_W) 'PeerMessage.cc'; else $(CYGPATH_W) '$(srcdir)/PeerMessage.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-PeerMessage.Tpo" "$(DEPDIR)/libaria2c_a-PeerMessage.Po"; else rm -f "$(DEPDIR)/libaria2c_a-PeerMessage.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerMessage.cc' object='libaria2c_a-PeerMessage.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-PeerMessage.obj `if test -f 'PeerMessage.cc'; then $(CYGPATH_W) 'PeerMessage.cc'; else $(CYGPATH_W) '$(srcdir)/PeerMessage.cc'; fi` + +libaria2c_a-Piece.o: Piece.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Piece.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-Piece.Tpo" -c -o libaria2c_a-Piece.o `test -f 'Piece.cc' || echo '$(srcdir)/'`Piece.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Piece.Tpo" "$(DEPDIR)/libaria2c_a-Piece.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Piece.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Piece.cc' object='libaria2c_a-Piece.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Piece.o `test -f 'Piece.cc' || echo '$(srcdir)/'`Piece.cc + +libaria2c_a-Piece.obj: Piece.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Piece.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-Piece.Tpo" -c -o libaria2c_a-Piece.obj `if test -f 'Piece.cc'; then $(CYGPATH_W) 'Piece.cc'; else $(CYGPATH_W) '$(srcdir)/Piece.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Piece.Tpo" "$(DEPDIR)/libaria2c_a-Piece.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Piece.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Piece.cc' object='libaria2c_a-Piece.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Piece.obj `if test -f 'Piece.cc'; then $(CYGPATH_W) 'Piece.cc'; else $(CYGPATH_W) '$(srcdir)/Piece.cc'; fi` + +libaria2c_a-RequestSlot.o: RequestSlot.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-RequestSlot.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-RequestSlot.Tpo" -c -o libaria2c_a-RequestSlot.o `test -f 'RequestSlot.cc' || echo '$(srcdir)/'`RequestSlot.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-RequestSlot.Tpo" "$(DEPDIR)/libaria2c_a-RequestSlot.Po"; else rm -f "$(DEPDIR)/libaria2c_a-RequestSlot.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='RequestSlot.cc' object='libaria2c_a-RequestSlot.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-RequestSlot.o `test -f 'RequestSlot.cc' || echo '$(srcdir)/'`RequestSlot.cc + +libaria2c_a-RequestSlot.obj: RequestSlot.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-RequestSlot.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-RequestSlot.Tpo" -c -o libaria2c_a-RequestSlot.obj `if test -f 'RequestSlot.cc'; then $(CYGPATH_W) 'RequestSlot.cc'; else $(CYGPATH_W) '$(srcdir)/RequestSlot.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-RequestSlot.Tpo" "$(DEPDIR)/libaria2c_a-RequestSlot.Po"; else rm -f "$(DEPDIR)/libaria2c_a-RequestSlot.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='RequestSlot.cc' object='libaria2c_a-RequestSlot.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-RequestSlot.obj `if test -f 'RequestSlot.cc'; then $(CYGPATH_W) 'RequestSlot.cc'; else $(CYGPATH_W) '$(srcdir)/RequestSlot.cc'; fi` + +libaria2c_a-RequestSlotMan.o: RequestSlotMan.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-RequestSlotMan.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-RequestSlotMan.Tpo" -c -o libaria2c_a-RequestSlotMan.o `test -f 'RequestSlotMan.cc' || echo '$(srcdir)/'`RequestSlotMan.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-RequestSlotMan.Tpo" "$(DEPDIR)/libaria2c_a-RequestSlotMan.Po"; else rm -f "$(DEPDIR)/libaria2c_a-RequestSlotMan.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='RequestSlotMan.cc' object='libaria2c_a-RequestSlotMan.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-RequestSlotMan.o `test -f 'RequestSlotMan.cc' || echo '$(srcdir)/'`RequestSlotMan.cc + +libaria2c_a-RequestSlotMan.obj: RequestSlotMan.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-RequestSlotMan.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-RequestSlotMan.Tpo" -c -o libaria2c_a-RequestSlotMan.obj `if test -f 'RequestSlotMan.cc'; then $(CYGPATH_W) 'RequestSlotMan.cc'; else $(CYGPATH_W) '$(srcdir)/RequestSlotMan.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-RequestSlotMan.Tpo" "$(DEPDIR)/libaria2c_a-RequestSlotMan.Po"; else rm -f "$(DEPDIR)/libaria2c_a-RequestSlotMan.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='RequestSlotMan.cc' object='libaria2c_a-RequestSlotMan.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-RequestSlotMan.obj `if test -f 'RequestSlotMan.cc'; then $(CYGPATH_W) 'RequestSlotMan.cc'; else $(CYGPATH_W) '$(srcdir)/RequestSlotMan.cc'; fi` + +libaria2c_a-TorrentAutoSaveCommand.o: TorrentAutoSaveCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TorrentAutoSaveCommand.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-TorrentAutoSaveCommand.Tpo" -c -o libaria2c_a-TorrentAutoSaveCommand.o `test -f 'TorrentAutoSaveCommand.cc' || echo '$(srcdir)/'`TorrentAutoSaveCommand.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TorrentAutoSaveCommand.Tpo" "$(DEPDIR)/libaria2c_a-TorrentAutoSaveCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TorrentAutoSaveCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentAutoSaveCommand.cc' object='libaria2c_a-TorrentAutoSaveCommand.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TorrentAutoSaveCommand.o `test -f 'TorrentAutoSaveCommand.cc' || echo '$(srcdir)/'`TorrentAutoSaveCommand.cc + +libaria2c_a-TorrentAutoSaveCommand.obj: TorrentAutoSaveCommand.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-TorrentAutoSaveCommand.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-TorrentAutoSaveCommand.Tpo" -c -o libaria2c_a-TorrentAutoSaveCommand.obj `if test -f 'TorrentAutoSaveCommand.cc'; then $(CYGPATH_W) 'TorrentAutoSaveCommand.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentAutoSaveCommand.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-TorrentAutoSaveCommand.Tpo" "$(DEPDIR)/libaria2c_a-TorrentAutoSaveCommand.Po"; else rm -f "$(DEPDIR)/libaria2c_a-TorrentAutoSaveCommand.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentAutoSaveCommand.cc' object='libaria2c_a-TorrentAutoSaveCommand.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-TorrentAutoSaveCommand.obj `if test -f 'TorrentAutoSaveCommand.cc'; then $(CYGPATH_W) 'TorrentAutoSaveCommand.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentAutoSaveCommand.cc'; fi` + +libaria2c_a-Directory.o: Directory.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Directory.o -MD -MP -MF "$(DEPDIR)/libaria2c_a-Directory.Tpo" -c -o libaria2c_a-Directory.o `test -f 'Directory.cc' || echo '$(srcdir)/'`Directory.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Directory.Tpo" "$(DEPDIR)/libaria2c_a-Directory.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Directory.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Directory.cc' object='libaria2c_a-Directory.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Directory.o `test -f 'Directory.cc' || echo '$(srcdir)/'`Directory.cc + +libaria2c_a-Directory.obj: Directory.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -MT libaria2c_a-Directory.obj -MD -MP -MF "$(DEPDIR)/libaria2c_a-Directory.Tpo" -c -o libaria2c_a-Directory.obj `if test -f 'Directory.cc'; then $(CYGPATH_W) 'Directory.cc'; else $(CYGPATH_W) '$(srcdir)/Directory.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libaria2c_a-Directory.Tpo" "$(DEPDIR)/libaria2c_a-Directory.Po"; else rm -f "$(DEPDIR)/libaria2c_a-Directory.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Directory.cc' object='libaria2c_a-Directory.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaria2c_a_CXXFLAGS) $(CXXFLAGS) -c -o libaria2c_a-Directory.obj `if test -f 'Directory.cc'; then $(CYGPATH_W) 'Directory.cc'; else $(CYGPATH_W) '$(srcdir)/Directory.cc'; fi` + aria2c-main.o: main.cc @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-main.o -MD -MP -MF "$(DEPDIR)/aria2c-main.Tpo" -c -o aria2c-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-main.Tpo" "$(DEPDIR)/aria2c-main.Po"; else rm -f "$(DEPDIR)/aria2c-main.Tpo"; exit 1; fi diff --git a/src/MetaEntry.h b/src/MetaEntry.h new file mode 100644 index 00000000..92176221 --- /dev/null +++ b/src/MetaEntry.h @@ -0,0 +1,40 @@ +/* */ +#ifndef _D_META_ENTRY_H_ +#define _D_META_ENTRY_H_ + +//#include "MetaEntryVisitor.h" +#include "common.h" + +class MetaEntryVisitor; + +class MetaEntry { +protected: + MetaEntry() {} +public: + virtual ~MetaEntry() {} + + virtual void accept(MetaEntryVisitor* v) const = 0; + +}; + +#endif // _D_META_ENTRY_H_ diff --git a/src/MetaEntryVisitor.h b/src/MetaEntryVisitor.h new file mode 100644 index 00000000..e4bfe42f --- /dev/null +++ b/src/MetaEntryVisitor.h @@ -0,0 +1,34 @@ +/* */ +#ifndef _D_META_ENTRY_VISITOR_H_ +#define _D_META_ENTRY_VISITOR_H_ + +#include "MetaEntry.h" + +class MetaEntryVisitor { +public: + virtual ~MetaEntryVisitor() {} + + virtual void visit(const MetaEntry* e) = 0; +}; + +#endif // _D_META_ENTRY_VISITOR_H_ diff --git a/src/MetaFileUtil.cc b/src/MetaFileUtil.cc new file mode 100644 index 00000000..bfc662b6 --- /dev/null +++ b/src/MetaFileUtil.cc @@ -0,0 +1,170 @@ +/* */ +#include "MetaFileUtil.h" +#include "File.h" +#include "DlAbortEx.h" +#include "message.h" +#include +#include + +MetaEntry* MetaFileUtil::parseMetaFile(string file) { + File f(file); + int len = f.size(); + char* buf = new char[len]; + FILE* fp = fopen(file.c_str(), "r+"); + if(fp == NULL) { + throw new DlAbortEx("cannot open metainfo file"); + } + if(fread(buf, len, 1, fp) != 1) { + fclose(fp); + throw new DlAbortEx("cannot read metainfo"); + } + fclose(fp); + MetaEntry* entry = bdecoding(buf, len); + delete [] buf; + return entry; +} + +MetaEntry* MetaFileUtil::bdecoding(const char* buf, int len) { + MetaEntry* entry = NULL; + try{ + const char* p = buf; + const char* end = buf+len; + entry = bdecodingR(&p, end); + return entry; + } catch(DlAbortEx* ex) { + if(entry != NULL) { + delete entry; + } + throw; + } +} + +MetaEntry* MetaFileUtil::bdecodingR(const char** pp, const char* end) { + if(*pp >= end) { + throw new DlAbortEx("mulformed metainfo"); + } + MetaEntry* e; + switch(**pp) { + case 'd': + (*pp)++; + e = parseDictionaryTree(pp, end); + break; + case 'l': + (*pp)++; + e = parseListTree(pp, end); + break; + case 'i': + (*pp)++; + e = decodeInt(pp, end); + break; + default: + e = decodeWord(pp, end); + } + return e; +} + +Dictionary* MetaFileUtil::parseDictionaryTree(const char** pp, const char* end) { + if(*pp >= end) { + throw new DlAbortEx("mulformed metainfo"); + } + Dictionary* dic = new Dictionary(); + while(1) { + if(**pp == 'e') { + (*pp)++; + break; + } + string name = decodeWordAsString(pp, end); + MetaEntry* e = bdecodingR(pp, end); + dic->put(name, e); + } + return dic; +} + +List* MetaFileUtil::parseListTree(const char** pp, const char* end) { + if(*pp >= end) { + throw new DlAbortEx("mulformed metainfo"); + } + List* lis = new List(); + while(1) { + if(**pp == 'e') { + (*pp)++; + break; + } + MetaEntry* e = bdecodingR(pp, end); + lis->add(e); + } + return lis; +} + +Data* MetaFileUtil::decodeInt(const char** pp, const char* end) { + if(*pp >= end) { + throw new DlAbortEx(EX_MULFORMED_META_INFO); + } + char* endTerm = (char*)memchr(*pp, 'e', end-*pp); + // TODO if endTerm is null + if(endTerm == NULL) { + throw new DlAbortEx(EX_MULFORMED_META_INFO); + } + int numSize = endTerm-*pp; + + Data* data = new Data(*pp, numSize, true); + *pp += numSize+1; + return data; +} + +Data* MetaFileUtil::decodeWord(const char** pp, const char* end) { + if(*pp >= end) { + throw new DlAbortEx("mulformed metainfo"); + } + char* delim = (char*)memchr(*pp, ':', end-*pp); + // TODO if delim is null + if(delim == *pp || delim == NULL) { + throw new DlAbortEx(EX_MULFORMED_META_INFO); + } + int numSize = delim-*pp; + char* temp = new char[numSize+1]; + memcpy(temp, *pp, numSize); + temp[numSize] = '\0'; + char* endptr; + int size = strtol(temp, &endptr, 10); + if(*endptr != '\0') { + delete [] temp; + throw new DlAbortEx(EX_MULFORMED_META_INFO); + } + delete [] temp; + + if(delim+1+size > end) { + throw new DlAbortEx(EX_MULFORMED_META_INFO); + } + + Data* data = new Data(delim+1, size); + *pp = delim+1+size; + return data; +} + +string MetaFileUtil::decodeWordAsString(const char** pp, const char* end) { + Data* data = decodeWord(pp, end); + string str = data->toString(); + delete data; + return str; +} diff --git a/src/MetaFileUtil.h b/src/MetaFileUtil.h new file mode 100644 index 00000000..ab123dde --- /dev/null +++ b/src/MetaFileUtil.h @@ -0,0 +1,50 @@ +/* */ +#ifndef _D_META_FILE_UTIL_H_ +#define _D_META_FILE_UTIL_H_ + +#include "MetaEntry.h" +#include "Dictionary.h" +#include "List.h" +#include "Data.h" +#include "common.h" +#include + +using namespace std; + +class MetaFileUtil { +private: + MetaFileUtil() {} + + static MetaEntry* bdecodingR(const char** pp, const char* end); + static Dictionary* parseDictionaryTree(const char** pp, const char* end); + static List* parseListTree(const char** pp, const char* end); + static Data* decodeWord(const char** pp, const char* end); + static Data* decodeInt(const char** pp, const char* end); + static string decodeWordAsString(const char** pp, const char* end); + +public: + static MetaEntry* parseMetaFile(string file); + static MetaEntry* bdecoding(const char* buf, int len); +}; + +#endif // _D_META_FILE_UTIL_H_ diff --git a/src/Peer.cc b/src/Peer.cc new file mode 100644 index 00000000..ece5c267 --- /dev/null +++ b/src/Peer.cc @@ -0,0 +1,48 @@ +/* */ +#include "Peer.h" + +Peer* Peer::nullPeer = new Peer("", 0, 0, 0); + +void Peer::updateBitfield(int index, int operation) { + if(operation == 1) { + bitfield->setBit(index); + } else if(operation == 0) { + bitfield->unsetBit(index); + } +} + +#define THRESHOLD 1024*1024*2 + +bool Peer::shouldChoke() const { + if(bitfield->countBlock()*0.8 < bitfield->countMissingBlock()) { + return false; + } + if(peerDownload < pieceLength*4 && peerUpload < pieceLength*4) { + return false; + } + if(amChocking) { + return !(peerDownload+pieceLength*4 < peerUpload); + } else { + return peerDownload >= peerUpload+pieceLength*4; + } +} diff --git a/src/Peer.h b/src/Peer.h new file mode 100644 index 00000000..ab5f62ca --- /dev/null +++ b/src/Peer.h @@ -0,0 +1,115 @@ +/* */ +#ifndef _D_PEER_H_ +#define _D_PEER_H_ + +#include "common.h" +#include "BitfieldMan.h" +#include +#include + +using namespace std; + +#define PEER_ID_LENGTH 20 + +class Peer { +public: + int entryId; + string ipaddr; + int port; + bool amChocking; + bool amInterested; + bool peerChoking; + bool peerInterested; + int tryCount; + int error; + int cuid; +private: + char peerId[PEER_ID_LENGTH]; + //unsigned char* bitfield; + BitfieldMan* bitfield; + //int bitfieldLength; + long long int peerUpload; + long long int peerDownload; + int pieceLength; + long long int totalLength; +public: + Peer(string ipaddr, int port, int pieceLength, long long int totalLength): + entryId(0), ipaddr(ipaddr), port(port), + amChocking(true), amInterested(false), + peerChoking(true), peerInterested(false), + tryCount(0), error(0), cuid(0), + bitfield(NULL),// bitfieldLength(0), + peerUpload(0), peerDownload(0), + pieceLength(pieceLength), totalLength(totalLength) { + this->bitfield = new BitfieldMan(pieceLength, totalLength); + } + + ~Peer() { + if(bitfield != NULL) { + delete /*[]*/ bitfield; + } + } + + void setPeerId(const char* peerId) { + memcpy(this->peerId, peerId, PEER_ID_LENGTH); + } + const char* getPeerId() const { return this->peerId; } + + void setBitfield(const unsigned char* bitfield, int bitfieldLength) { + this->bitfield->setBitfield(bitfield, bitfieldLength); + /* + if(this->bitfield != NULL) { + delete [] this->bitfield; + } + this->bitfieldLength = bitfieldLength; + this->bitfield = new unsigned char[this->bitfieldLength]; + memcpy(this->bitfield, bitfield, this->bitfieldLength); + */ + } + const unsigned char* getBitfield() const { return bitfield->getBitfield(); } + int getBitfieldLength() const { return bitfield->getBitfieldLength(); } + + /* + void initBitfield(int pieces); + */ + + /** + * operation = 1: set index-th bit 1 + * operation = 0: set index-th bit 0 + */ + void updateBitfield(int index, int operation); + + void addPeerUpload(int size) { peerUpload += size; } + void setPeerUpload(long long int size) { peerUpload = size; } + long long int getPeerUpload() const { return peerUpload; } + + void addPeerDownload(int size) { peerDownload += size; } + void setPeerDownload(long long int size) { peerDownload = size; } + long long int getPeerDownload() const { return peerDownload; } + + bool shouldChoke() const; + + static Peer* nullPeer; +}; + +#endif // _D_PEER_H_ diff --git a/src/PeerAbstractCommand.cc b/src/PeerAbstractCommand.cc new file mode 100644 index 00000000..6cbd615c --- /dev/null +++ b/src/PeerAbstractCommand.cc @@ -0,0 +1,181 @@ +/* */ +#include "PeerAbstractCommand.h" +#include "DlAbortEx.h" +#include "DlRetryEx.h" +#include +#include "Util.h" +#include "message.h" +#include "prefs.h" + +PeerAbstractCommand::PeerAbstractCommand(int cuid, Peer* peer, TorrentDownloadEngine* e, Socket* s): + Command(cuid), e(e), peer(peer), checkSocketIsReadable(false), checkSocketIsWritable(false) { + + if(s != NULL) { + socket = new Socket(*s); + setReadCheckSocket(socket); + } else { + socket = NULL; + } + this->checkPoint.tv_sec = 0; + this->checkPoint.tv_usec = 0; + + e->torrentMan->connections++; +} + +PeerAbstractCommand::~PeerAbstractCommand() { + setReadCheckSocket(NULL); + setWriteCheckSocket(NULL); + if(socket != NULL) { + delete(socket); + } + e->torrentMan->connections--; +} + +void PeerAbstractCommand::updateCheckPoint() { + gettimeofday(&checkPoint, NULL); +} + +bool PeerAbstractCommand::isTimeoutDetected() { + struct timeval now; + gettimeofday(&now, NULL); + if(checkPoint.tv_sec == 0 && checkPoint.tv_usec == 0) { + checkPoint = now; + return false; + } else { + long long int elapsed = Util::difftv(now, checkPoint); + if(elapsed >= e->option->getAsInt(PREF_TIMEOUT)*1000000) { + return true; + } else { + return false; + } + } +} + +bool PeerAbstractCommand::execute() { + try { + if(e->torrentMan->downloadComplete()) { + return true; + } + beforeSocketCheck(); + if(checkSocketIsReadable && !readCheckTarget->isReadable(0) + || checkSocketIsWritable && !writeCheckTarget->isWritable(0)) { + if(isTimeoutDetected()) { + // TODO + checkPoint.tv_sec = 0; + checkPoint.tv_usec = 0; + throw new DlRetryEx(EX_TIME_OUT); + } + e->commands.push(this); + return false; + } + updateCheckPoint(); + bool returnValue = executeInternal(); + //e->torrentMan->updatePeer(peer); + return returnValue; + } catch(Exception* err) { + e->logger->error(MSG_DOWNLOAD_ABORTED, err, cuid); + onAbort(err); + delete(err); + return prepareForNextPeer(0); + } catch(DlRetryEx* err) { + e->logger->error(MSG_RESTARTING_DOWNLOAD, err, cuid); + peer->tryCount++; + bool isAbort = e->option->getAsInt(PREF_MAX_TRIES) != 0 && + peer->tryCount >= e->option->getAsInt(PREF_MAX_TRIES); + int tryCount = peer->tryCount; + if(isAbort) { + onAbort(err); + } + delete(err); + if(isAbort) { + e->logger->error(MSG_MAX_TRY, cuid, tryCount); + return true; + } else { + return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT)); + } + } +} + +// TODO this method removed when PeerBalancerCommand is implemented +bool PeerAbstractCommand::prepareForNextPeer(int wait) { + return true; +} + +bool PeerAbstractCommand::prepareForRetry(int wait) { + return true; +} + +void PeerAbstractCommand::onAbort(Exception* ex) { + peer->error = 1; + peer->tryCount = 0; + peer->cuid = 0; + peer->amChocking = true; + peer->amInterested = false; + peer->peerChoking = true; + peer->peerInterested = false; + e->logger->debug("CUID#%d - peer %s:%d banned.", cuid, peer->ipaddr.c_str(), peer->port); +} + +void PeerAbstractCommand::setReadCheckSocket(Socket* socket) { + if(socket == NULL) { + if(checkSocketIsReadable) { + e->deleteSocketForReadCheck(readCheckTarget); + checkSocketIsReadable = false; + readCheckTarget = NULL; + } + } else { + if(checkSocketIsReadable) { + if(readCheckTarget != socket) { + e->deleteSocketForReadCheck(readCheckTarget); + e->addSocketForReadCheck(socket); + readCheckTarget = socket; + } + } else { + e->addSocketForReadCheck(socket); + checkSocketIsReadable = true; + readCheckTarget = socket; + } + } +} + +void PeerAbstractCommand::setWriteCheckSocket(Socket* socket) { + if(socket == NULL) { + if(checkSocketIsWritable) { + e->deleteSocketForWriteCheck(writeCheckTarget); + checkSocketIsWritable = false; + writeCheckTarget = NULL; + } + } else { + if(checkSocketIsWritable) { + if(writeCheckTarget != socket) { + e->deleteSocketForWriteCheck(writeCheckTarget); + e->addSocketForWriteCheck(socket); + writeCheckTarget = socket; + } + } else { + e->addSocketForWriteCheck(socket); + checkSocketIsWritable = true; + writeCheckTarget = socket; + } + } +} diff --git a/src/PeerAbstractCommand.h b/src/PeerAbstractCommand.h new file mode 100644 index 00000000..a6250a02 --- /dev/null +++ b/src/PeerAbstractCommand.h @@ -0,0 +1,58 @@ +/* */ +#ifndef _D_PEER_ABSTRACT_COMMAND_H_ +#define _D_PEER_ABSTRACT_COMMAND_H_ + +#include "Command.h" +#include "Request.h" +#include "TorrentDownloadEngine.h" +#include + +class PeerAbstractCommand : public Command { +private: + void updateCheckPoint(); + bool isTimeoutDetected(); + struct timeval checkPoint; +protected: + TorrentDownloadEngine* e; + Socket* socket; + Peer* peer; + + virtual bool prepareForNextPeer(int wait); + virtual bool prepareForRetry(int wait); + virtual void onAbort(Exception* ex); + virtual bool executeInternal() = 0; + virtual void beforeSocketCheck() {} + void setReadCheckSocket(Socket* socket); + void setWriteCheckSocket(Socket* socket); +private: + bool checkSocketIsReadable; + bool checkSocketIsWritable; + Socket* readCheckTarget; + Socket* writeCheckTarget; +public: + PeerAbstractCommand(int cuid, Peer* peer, TorrentDownloadEngine* e, Socket* s = NULL); + virtual ~PeerAbstractCommand(); + bool execute(); +}; + +#endif // _D_PEER_ABSTRACT_COMMAND_H_ diff --git a/src/PeerConnection.cc b/src/PeerConnection.cc new file mode 100644 index 00000000..af2dfb8b --- /dev/null +++ b/src/PeerConnection.cc @@ -0,0 +1,378 @@ +/* */ +#include "PeerConnection.h" +#include "message.h" +#include "DlAbortEx.h" +#include "PeerMessageUtil.h" +#include "Util.h" +#include + +PeerConnection::PeerConnection(int cuid, const Socket* socket, + const Option* op, const Logger* logger, + Peer* peer, TorrentMan* torrentMan) + :cuid(cuid), socket(socket), option(op), logger(logger), peer(peer), + torrentMan(torrentMan), + resbufLength(0), currentPayloadLength(0), lenbufLength(0) {} + +PeerConnection::~PeerConnection() {} + +void PeerConnection::sendHandshake() const { + /** + * pstrlen --- '19', 1byte + * pstr --- "BitTorrent protocol", 19bytes + * reserved --- \0 * 8, 8bytes + * info_hash --- info_hash, 20bytes + * peer_id --- peer_id, 20bytes + * total: 68bytes + */ + char msg[HANDSHAKE_MESSAGE_LENGTH]; + memset(msg, 0, sizeof(msg)); + msg[0] = 19; + memcpy(&msg[1], PSTR, strlen(PSTR)); + memcpy(&msg[28], torrentMan->getInfoHash(), 20); + memcpy(&msg[48], torrentMan->peerId.c_str(), 20); + writeOutgoingMessageLog("handshake"); + socket->writeData(msg, sizeof(msg)); +} + +void PeerConnection::sendKeepAlive() const { + /** + * len --- 0, 4bytes + * total: 4bytes + */ + char msg[4]; + memset(msg, 0, sizeof(msg)); + writeOutgoingMessageLog("keep-alive"); + socket->writeData(msg, sizeof(msg)); +} + +void PeerConnection::createNLengthMessage(char* msg, int msgLen, int payloadLen, int id) const { + assert(msgLen >= 5); + memset(msg, 0, msgLen); + setIntParam(msg, payloadLen); + msg[4] = (char)id; +} + +void PeerConnection::setIntParam(char* dest, int param) const { + int nParam = htonl(param); + memcpy(dest, &nParam, 4); +} + +void PeerConnection::writeOutgoingMessageLog(const char* msg) const { + logger->info(MSG_SEND_PEER_MESSAGE, cuid, peer->ipaddr.c_str(), peer->port, msg); +} + +void PeerConnection::writeOutgoingMessageLog(const char* msg, int index) const { + logger->info(MSG_SEND_PEER_MESSAGE_WITH_INDEX, cuid, peer->ipaddr.c_str(), peer->port, msg, index); +} + +void PeerConnection::writeOutgoingMessageLog(const char* msg, const unsigned char* bitfield, int bitfieldLength) const { + logger->info(MSG_SEND_PEER_MESSAGE_WITH_BITFIELD, cuid, peer->ipaddr.c_str(), peer->port, msg, Util::toHex(bitfield, bitfieldLength).c_str()); +} + +void PeerConnection::writeOutgoingMessageLog(const char* msg, int index, int begin, int length) const { + logger->info(MSG_SEND_PEER_MESSAGE_WITH_INDEX_BEGIN_LENGTH, cuid, peer->ipaddr.c_str(), peer->port, msg, index, begin, length); +} + +void PeerConnection::sendChoke() const { + /** + * len --- 1, 4bytes + * id --- 0, 1byte + * total: 5bytes + */ + char msg[5]; + createNLengthMessage(msg, sizeof(msg), 1, 0); + writeOutgoingMessageLog("choke"); + socket->writeData(msg, sizeof(msg)); +} + +void PeerConnection::sendUnchoke() const { + /** + * len --- 1, 4bytes + * id --- 1, 1byte + * total: 5bytes + */ + char msg[5]; + createNLengthMessage(msg, sizeof(msg), 1, 1); + writeOutgoingMessageLog("unchoke"); + socket->writeData(msg, sizeof(msg)); +} + +void PeerConnection::sendInterested() const { + /** + * len --- 1, 4bytes + * id --- 2, 1byte + * total: 5bytes + */ + char msg[5]; + createNLengthMessage(msg, sizeof(msg), 1, 2); + writeOutgoingMessageLog("interested"); + socket->writeData(msg, sizeof(msg)); +} + +void PeerConnection::sendNotInterested() const { + /** + * len --- 1, 4bytes + * id --- 3, 1byte + * total: 5bytes + */ + char msg[5]; + createNLengthMessage(msg, sizeof(msg), 1, 3); + writeOutgoingMessageLog("not interested"); + socket->writeData(msg, sizeof(msg)); +} + +void PeerConnection::sendHave(int index) const { + /** + * len --- 5, 4bytes + * id --- 4, 1byte + * piece index --- index, 4bytes + * total: 9bytes + */ + char msg[9]; + createNLengthMessage(msg, sizeof(msg), 5, 4); + setIntParam(&msg[5], index); + writeOutgoingMessageLog("have", index); + socket->writeData(msg, sizeof(msg)); +} + +void PeerConnection::sendBitfield() const { + int len = torrentMan->getBitfieldLength(); + const unsigned char* bitfield = torrentMan->getBitfield(); + /** + * len --- 1+len, 4bytes + * id --- 5, 1byte + * bitfield --- bitfield, len bytes + * total: 5+len bytes + */ + int msgLen = 5+len; + char* msg = new char[msgLen]; + try { + createNLengthMessage(msg, msgLen, 1+len, 5); + writeOutgoingMessageLog("bitfield", bitfield, len); + socket->writeData(msg, msgLen); + delete [] msg; + } catch(Exception* ex) { + delete [] msg; + throw; + } +} + +void PeerConnection::sendRequest(int index, int begin, int length) const { + /** + * len --- 13, 4bytes + * id --- 6, 1byte + * index --- index, 4bytes + * begin --- begin, 4bytes + * length --- length, 4bytes + * total: 17bytes + */ + char msg[17]; + createNLengthMessage(msg, sizeof(msg), 13, 6); + setIntParam(&msg[5], index); + setIntParam(&msg[9], begin); + setIntParam(&msg[13], length); + writeOutgoingMessageLog("request", index, begin, length); + socket->writeData(msg, sizeof(msg)); +} + +void PeerConnection::sendPiece(int index, int begin, int length) const { + /** + * len --- 9+length, 4bytes + * id --- 7, 1byte + * index --- index, 4bytes + * begin --- begin, 4bytes + * sub total: 13bytes + * additionally, + * block --- data, X bytes + */ + char msg[13]; + createNLengthMessage(msg, sizeof(msg), 9+length, 7); + setIntParam(&msg[5], index); + setIntParam(&msg[9], begin); + writeOutgoingMessageLog("piece", index, begin, length); + socket->writeData(msg, sizeof(msg)); + int BUF_SIZE = 4096; + char buf[BUF_SIZE]; + int iteration = length/BUF_SIZE; + long long int pieceOffset = ((long long int)index*torrentMan->pieceLength)+begin; + for(int i = 0; i < iteration; i++) { + if(torrentMan->diskWriter->readData(buf, BUF_SIZE, pieceOffset+i*BUF_SIZE) < BUF_SIZE) { + throw new DlAbortEx("piece reading failed."); + } + socket->writeData(buf, BUF_SIZE); + } + int rem = length%BUF_SIZE; + if(rem > 0) { + if(torrentMan->diskWriter->readData(buf, rem, pieceOffset+iteration*BUF_SIZE) < rem) { + throw new DlAbortEx("piece reading failed."); + } + socket->writeData(buf, rem); + } +} + +void PeerConnection::sendPieceHeader(int index, int begin, int length) const { + /** + * len --- 9+length, 4bytes + * id --- 7, 1byte + * index --- index, 4bytes + * begin --- begin, 4bytes + * sub total: 13bytes + * additionally, + * block --- data, X bytes + */ + char msg[13]; + createNLengthMessage(msg, sizeof(msg), 9+length, 7); + setIntParam(&msg[5], index); + setIntParam(&msg[9], begin); + writeOutgoingMessageLog("piece", index, begin, length); + socket->writeData(msg, sizeof(msg)); +} + +int PeerConnection::sendPieceData(long long int offset, int length) const { + int BUF_SIZE = 256; + char buf[BUF_SIZE]; + int iteration = length/BUF_SIZE; + int writtenLength = 0; + bool isWritable = true; + for(int i = 0; i < iteration; i++) { + isWritable = socket->isWritable(0); + if(!isWritable) { + return writtenLength; + } + if(torrentMan->diskWriter->readData(buf, BUF_SIZE, offset+i*BUF_SIZE) < BUF_SIZE) { + throw new DlAbortEx("piece reading failed."); + } + socket->writeData(buf, BUF_SIZE); + writtenLength += BUF_SIZE; + } + if(socket->isWritable(0)) { + int rem = length%BUF_SIZE; + if(rem > 0) { + if(torrentMan->diskWriter->readData(buf, rem, offset+iteration*BUF_SIZE) < rem) { + throw new DlAbortEx("piece reading failed."); + } + socket->writeData(buf, rem); + writtenLength += rem; + } + } + return writtenLength; +} + + +void PeerConnection::sendCancel(int index, int begin, int length) const { + /** + * len --- 13, 4bytes + * id --- 8, 1byte + * index --- index, 4bytes + * begin --- begin, 4bytes + * length -- length, 4bytes + * total: 17bytes + */ + char msg[17]; + createNLengthMessage(msg, sizeof(msg), 13, 8); + setIntParam(&msg[5], index); + setIntParam(&msg[9], begin); + setIntParam(&msg[13], length); + writeOutgoingMessageLog("cancel", index, begin, length); + socket->writeData(msg, sizeof(msg)); +} + +PeerMessage* PeerConnection::receiveMessage() { + if(!socket->isReadable(0)) { + return NULL; + } + if(resbufLength == 0 && lenbufLength != 4) { + // read payload size, 4-byte integer + int remain = 4-lenbufLength; + int temp = remain; + socket->readData(lenbuf+lenbufLength, temp); + if(temp == 0) { + // we got EOF + throw new DlAbortEx(EX_EOF_FROM_PEER); + } + if(remain != temp) { + // still 4-temp bytes to go + lenbufLength += temp; + return NULL; + } + //payloadLen = ntohl(nPayloadLen); + int payloadLength = ntohl(*((int*)lenbuf)); + if(payloadLength > MAX_PAYLOAD_LEN) { + throw new DlAbortEx("max payload length exceeded. length = %d", + payloadLength); + } + currentPayloadLength = payloadLength; + } + // we have currentPayloadLen-resbufLen bytes to read + int remaining = currentPayloadLength-resbufLength; + if(remaining > 0) { + socket->readData(resbuf+resbufLength, remaining); + if(remaining == 0) { + // we got EOF + throw new DlAbortEx(EX_EOF_FROM_PEER); + } + resbufLength += remaining; + if(currentPayloadLength != resbufLength) { + return NULL; + } + } + // we got whole payload. + resbufLength = 0; + lenbufLength = 0; + PeerMessage* peerMessage = PeerMessageUtil::createPeerMessage(resbuf, currentPayloadLength); + try { + PeerMessageUtil::checkIntegrity(peerMessage, torrentMan->pieceLength, + torrentMan->pieces, torrentMan->totalSize); + } catch(Exception* e) { + delete peerMessage; + throw; + } + return peerMessage; +} + +HandshakeMessage* PeerConnection::receiveHandshake() { + if(!socket->isReadable(0)) { + return NULL; + } + int remain = HANDSHAKE_MESSAGE_LENGTH-resbufLength; + int temp = remain; + socket->readData(resbuf+resbufLength, temp); + if(temp == 0) { + // we got EOF + throw new DlAbortEx(EX_EOF_FROM_PEER); + } + if(remain != temp) { + resbufLength += temp; + return NULL; + } + // we got whole handshake payload + resbufLength = 0; + HandshakeMessage* handshakeMessage = PeerMessageUtil::createHandshakeMessage(resbuf); + try { + PeerMessageUtil::checkHandshake(handshakeMessage, torrentMan->getInfoHash()); + } catch(Exception* e) { + delete handshakeMessage; + throw; + } + return handshakeMessage; +} diff --git a/src/PeerConnection.h b/src/PeerConnection.h new file mode 100644 index 00000000..9c8401e7 --- /dev/null +++ b/src/PeerConnection.h @@ -0,0 +1,82 @@ +/* */ +#ifndef _D_PEER_CONNECTION_H_ +#define _D_PEER_CONNECTION_H_ + +#include "Option.h" +#include "Socket.h" +#include "Logger.h" +#include "TorrentMan.h" +#include "PeerMessage.h" +#include "HandshakeMessage.h" + +// we assume maximum length of incoming message is "piece" message with 16KB +// data. Messages beyond that size are dropped. +#define MAX_PAYLOAD_LEN (9+16*1024) + +class PeerConnection { +private: + int cuid; + const Socket* socket; + const Option* option; + const Logger* logger; + Peer* peer; + TorrentMan* torrentMan; + + char resbuf[MAX_PAYLOAD_LEN]; + int resbufLength; + int currentPayloadLength; + char lenbuf[4]; + int lenbufLength; + + void createNLengthMessage(char* msg, int msgLen, int payloadLen, int id) const; + void setIntParam(char* dest, int param) const; + + void writeOutgoingMessageLog(const char* msg) const; + void writeOutgoingMessageLog(const char* msg, int index) const; + void writeOutgoingMessageLog(const char* msg, const unsigned char* bitfield, int bitfieldLength) const; + void writeOutgoingMessageLog(const char* msg, int index, int begin, int length) const; +public: + PeerConnection(int cuid, const Socket* socket, const Option* op, + const Logger* logger, Peer* peer, TorrentMan* torrenMan); + ~PeerConnection(); + + void sendHandshake() const; + void sendKeepAlive() const; + void sendChoke() const; + void sendUnchoke() const; + void sendInterested() const; + void sendNotInterested() const; + void sendHave(int index) const; + void sendBitfield() const; + void sendRequest(int index, int begin, int length) const; + void sendPiece(int index, int begin, int length) const; + void sendPieceHeader(int index, int begin, int length) const; + int sendPieceData(long long int offset, int length) const; + void sendCancel(int index, int begin, int length) const; + PeerMessage* receiveMessage(); + HandshakeMessage* receiveHandshake(); + + Peer* getPeer() const { return peer; } +}; + +#endif // _D_PEER_CONNECTION_H_ diff --git a/src/PeerInitiateConnectionCommand.cc b/src/PeerInitiateConnectionCommand.cc new file mode 100644 index 00000000..441d5e27 --- /dev/null +++ b/src/PeerInitiateConnectionCommand.cc @@ -0,0 +1,74 @@ +/* */ +#include "PeerInitiateConnectionCommand.h" +#include "PeerInteractionCommand.h" +#include "Util.h" +#include "DlAbortEx.h" +#include "message.h" +#include "prefs.h" + +PeerInitiateConnectionCommand::PeerInitiateConnectionCommand(int cuid, + Peer* peer, + TorrentDownloadEngine* e) + :PeerAbstractCommand(cuid, peer, e) {} + +PeerInitiateConnectionCommand::~PeerInitiateConnectionCommand() {} + +bool PeerInitiateConnectionCommand::executeInternal() { + socket = new Socket(); + // socket->establishConnection(...); + + Command* command; + e->logger->info(MSG_CONNECTING_TO_SERVER, cuid, peer->ipaddr.c_str(), + peer->port); + socket->establishConnection(peer->ipaddr, peer->port); + command = new PeerInteractionCommand(cuid, peer, e, socket, PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE); + + e->commands.push(command); + return true; +} + +// TODO this method removed when PeerBalancerCommand is implemented +bool PeerInitiateConnectionCommand::prepareForNextPeer(int wait) { + if(e->torrentMan->isPeerAvailable()) { + Peer* peer = e->torrentMan->getPeer(); + int newCuid = e->torrentMan->getNewCuid(); + peer->cuid = newCuid; + PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e); + e->commands.push(command); + } + return true; +} + +bool PeerInitiateConnectionCommand::prepareForRetry(int wait) { + PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(cuid, peer, e); + e->commands.push(command); + return true; +} + +bool PeerInitiateConnectionCommand::useProxy() { + return e->option->get(PREF_HTTP_PROXY_ENABLED) == V_TRUE; +} + +bool PeerInitiateConnectionCommand::useProxyTunnel() { + return e->option->get(PREF_HTTP_PROXY_METHOD) == V_TUNNEL; +} diff --git a/src/PeerInitiateConnectionCommand.h b/src/PeerInitiateConnectionCommand.h new file mode 100644 index 00000000..64c2a7d2 --- /dev/null +++ b/src/PeerInitiateConnectionCommand.h @@ -0,0 +1,40 @@ +/* */ +#ifndef _D_PEER_INITIATE_CONNECTION_H_ +#define _D_PEER_INITIATE_CONNECTION_H_ + +#include "PeerAbstractCommand.h" + +class PeerInitiateConnectionCommand : public PeerAbstractCommand { +private: + bool useProxy(); + bool useProxyTunnel(); +protected: + bool executeInternal(); + bool prepareForRetry(int wait); + bool prepareForNextPeer(int wait); +public: + PeerInitiateConnectionCommand(int cuid, Peer* peer, TorrentDownloadEngine* e); + ~PeerInitiateConnectionCommand(); +}; + +#endif // _D_PEER_INITIATE_CONNECTION_H_ diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc new file mode 100644 index 00000000..0d81fba7 --- /dev/null +++ b/src/PeerInteractionCommand.cc @@ -0,0 +1,477 @@ +/* */ +#include "PeerInteractionCommand.h" +#include "PeerInitiateConnectionCommand.h" +#include "PeerMessageUtil.h" +#include "DlAbortEx.h" +#include "Util.h" +#include "message.h" + +PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer, + TorrentDownloadEngine* e, + Socket* s, int sequence) + :PeerAbstractCommand(cuid, peer, e, s), sequence(sequence) { + if(sequence == INITIATOR_SEND_HANDSHAKE) { + setReadCheckSocket(NULL); + setWriteCheckSocket(socket); + } + peerConnection = new PeerConnection(cuid, socket, e->option, e->logger, + peer, e->torrentMan); + requestSlotMan = new RequestSlotMan(cuid, &pendingMessages, peerConnection, + e->torrentMan, e->logger); + piece = Piece::nullPiece; + keepAliveCheckPoint.tv_sec = 0; + keepAliveCheckPoint.tv_usec = 0; +} + +PeerInteractionCommand::~PeerInteractionCommand() { + delete peerConnection; + delete requestSlotMan; +} + +bool PeerInteractionCommand::executeInternal() { + if(sequence == INITIATOR_SEND_HANDSHAKE) { + socket->setBlockingMode(); + setReadCheckSocket(socket); + } + setWriteCheckSocket(NULL); + + switch(sequence) { + case INITIATOR_SEND_HANDSHAKE: + peerConnection->sendHandshake(); + sequence = INITIATOR_WAIT_HANDSHAKE; + break; + case INITIATOR_WAIT_HANDSHAKE: { + HandshakeMessage* handshakeMessage = peerConnection->receiveHandshake(); + if(handshakeMessage == NULL) { + break; + } + peer->setPeerId(handshakeMessage->peerId); + e->logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid, + peer->ipaddr.c_str(), peer->port, + handshakeMessage->toString().c_str()); + delete handshakeMessage; + if(e->torrentMan->getDownloadedSize() > 0) { + peerConnection->sendBitfield(); + } + sequence = WIRED; + break; + } + case RECEIVER_WAIT_HANDSHAKE: { + HandshakeMessage* handshakeMessage = peerConnection->receiveHandshake(); + if(handshakeMessage == NULL) { + break; + } + peer->setPeerId(handshakeMessage->peerId); + e->logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid, + peer->ipaddr.c_str(), peer->port, + handshakeMessage->toString().c_str()); + delete handshakeMessage; + peerConnection->sendHandshake(); + if(e->torrentMan->getDownloadedSize() > 0) { + peerConnection->sendBitfield(); + } + sequence = WIRED; + break; + } + case WIRED: + syncPiece(); + decideChoking(); + for(int i = 0; i < 10; i++) { + if(!socket->isReadable(0)) { + break; + } + receiveMessage(); + } + //detectTimeoutAndDuplicateBlock(); + requestSlotMan->deleteTimedoutRequestSlot(piece); + requestSlotMan->deleteCompletedRequestSlot(piece); + sendInterest(); + sendMessages(); + break; + } + if(pendingMessages.size() > 0) { + setWriteCheckSocket(socket); + } + e->commands.push(this); + return false; +} + +void PeerInteractionCommand::syncPiece() { + if(Piece::isNull(piece)) { + return; + } + e->torrentMan->syncPiece(piece); +} + +void PeerInteractionCommand::decideChoking() { + if(peer->shouldChoke()) { + if(!peer->amChocking) { + PendingMessage pendingMessage(PeerMessage::CHOKE, peerConnection); + pendingMessages.push_back(pendingMessage); + } + } else if(peer->amChocking && peer->peerInterested) { + PendingMessage pendingMessage(PeerMessage::UNCHOKE, peerConnection); + pendingMessages.push_back(pendingMessage); + } else if(!peer->peerInterested) { + PendingMessage pendingMessage(PeerMessage::CHOKE, peerConnection); + pendingMessages.push_back(pendingMessage); + } +} + +void PeerInteractionCommand::receiveMessage() { + PeerMessage* message = peerConnection->receiveMessage(); + if(message == NULL) { + return; + } + e->logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid, + peer->ipaddr.c_str(), peer->port, + message->toString().c_str()); + try { + switch(message->getId()) { + case PeerMessage::KEEP_ALIVE: + break; + case PeerMessage::CHOKE: + peer->peerChoking = true; + requestSlotMan->deleteAllRequestSlot(piece); + break; + case PeerMessage::UNCHOKE: + peer->peerChoking = false; + break; + case PeerMessage::INTERESTED: + peer->peerInterested = true; + break; + case PeerMessage::NOT_INTERESTED: + peer->peerInterested = false; + break; + case PeerMessage::HAVE: + peer->updateBitfield(message->getIndex(), 1); + break; + case PeerMessage::BITFIELD: + peer->setBitfield(message->getBitfield(), message->getBitfieldLength()); + break; + case PeerMessage::REQUEST: + if(e->torrentMan->hasPiece(message->getIndex())) { + PendingMessage pendingMessage + = PendingMessage::createPieceMessage(message->getIndex(), + message->getBegin(), + message->getLength(), + e->torrentMan->pieceLength, + peerConnection); + pendingMessages.push_back(pendingMessage); + e->torrentMan->addUploadedSize(message->getLength()); + e->torrentMan->addDeltaUpload(message->getLength()); + } + break; + case PeerMessage::CANCEL: + deletePendingMessage(message); + break; + case PeerMessage::PIECE: { + RequestSlot slot = requestSlotMan->getCorrespoindingRequestSlot(message); + peer->addPeerUpload(message->getBlockLength()); + if(!Piece::isNull(piece) && !RequestSlot::isNull(slot)) { + long long int offset = + ((long long int)message->getIndex())*e->torrentMan->pieceLength+message->getBegin(); + e->logger->debug("CUID#%d - write block length = %d, offset=%lld", + cuid, message->getBlockLength(), offset); + e->torrentMan->diskWriter->writeData(message->getBlock(), + message->getBlockLength(), + offset); + piece.completeBlock(slot.getBlockIndex()); + requestSlotMan->deleteRequestSlot(slot); + e->torrentMan->updatePiece(piece); + e->logger->debug("CUID#%d - setting piece bit index=%d", cuid, + slot.getBlockIndex()); + e->torrentMan->addDeltaDownload(message->getBlockLength()); + if(piece.pieceComplete()) { + if(checkPieceHash(piece)) { + onGotNewPiece(); + } else { + onGotWrongPiece(); + } + } + } + break; + } + } + delete message; + } catch(Exception* ex) { + delete message; + throw; + } +} + +void PeerInteractionCommand::deletePendingMessage(PeerMessage* cancelMessage) { + for(PendingMessages::iterator itr = pendingMessages.begin(); + itr != pendingMessages.end();) { + PendingMessage& pendingMessage = *itr; + if(pendingMessage.getPeerMessageId() == PeerMessage::PIECE && + pendingMessage.getIndex() == cancelMessage->getIndex() && + pendingMessage.getBegin() == cancelMessage->getBegin() && + pendingMessage.getLength() == cancelMessage->getLength() && + !pendingMessage.isInProgress()) { + e->logger->debug("CUID#%d - deleting pending piece message because cancel message received. index=%d, begin=%d, length=%d", + cuid, + pendingMessage.getIndex(), + pendingMessage.getBegin(), + pendingMessage.getLength()); + itr = pendingMessages.erase(itr); + } else { + itr++; + } + } +} + +void PeerInteractionCommand::onGotNewPiece() { + e->logger->info(MSG_GOT_NEW_PIECE, cuid, piece.getIndex()); + e->torrentMan->completePiece(piece); + e->torrentMan->advertisePiece(cuid, piece.getIndex()); + piece = Piece::nullPiece; +} + +void PeerInteractionCommand::onGotWrongPiece() { + e->logger->error(MSG_GOT_WRONG_PIECE, cuid, piece.getIndex()); + erasePieceOnDisk(piece); + piece.clearAllBlock(); + e->torrentMan->updatePiece(piece); +} + +/* +const RequestSlot& PeerInteractionCommand::getRequestSlot(int index, int begin, int length) const { + for(RequestSlots::const_iterator itr = requestSlots.begin(); itr != requestSlots.end(); itr++) { + const RequestSlot& slot = *itr; + if(slot.index == index && slot.begin == begin && slot.length == length) { + return slot; + } + } + return RequestSlot::nullSlot; +} +*/ +/* +bool PeerInteractionCommand::deleteRequestSlot(const RequestSlot& slot) { + for(RequestSlots::iterator itr = requestSlots.begin(); itr != requestSlots.end(); itr++) { + if(slot.index == itr->index && slot.begin == itr->begin && slot.length == itr->length) { + requestSlots.erase(itr); + return true; + } + } + return false; +} +*/ +/* +void PeerInteractionCommand::deleteAllRequestSlot() { + if(!Piece::isNull(piece)) { + for(RequestSlots::const_iterator itr = requestSlots.begin(); itr != requestSlots.end(); itr++) { + if(itr->index == piece.getIndex()) { + piece.cancelBlock(itr->blockIndex); + } + } + e->torrentMan->updatePiece(piece); + } + requestSlots.clear(); +} +*/ +// TODO this method removed when PeerBalancerCommand is implemented +bool PeerInteractionCommand::prepareForNextPeer(int wait) { + if(e->torrentMan->isPeerAvailable()) { + Peer* peer = e->torrentMan->getPeer(); + int newCuid = e->torrentMan->getNewCuid(); + peer->cuid = newCuid; + PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e); + e->commands.push(command); + } + return true; +} + +bool PeerInteractionCommand::prepareForRetry(int wait) { + e->commands.push(this); + return false; +} +/* +void PeerInteractionCommand::detectTimeoutAndDuplicateBlock() { + struct timeval now; + gettimeofday(&now, NULL); + for(RequestSlots::iterator itr = requestSlots.begin(); itr != requestSlots.end();) { + const RequestSlot& slot = *itr; + if(slot.isTimeout(120) || piece.hasBlock(slot.blockIndex)) { + e->logger->debug("CUID#%d - deleting requestslot blockIndex %d", cuid, slot.blockIndex); + if(slot.isTimeout(120)) { + e->logger->debug("CUID#%d - because of timeout", cuid); + } else { + e->logger->debug("CUID#%d - because of duplicate block", cuid); + } + piece.cancelBlock(slot.blockIndex); + e->torrentMan->updatePiece(piece); + // send cancel message + PendingMessage pendingMessage = + PendingMessage::createCancelMessage(piece.getIndex(), + slot.blockIndex*piece.getBlockLength(), + piece.getBlockLength(slot.blockIndex), + peerConnection); + pendingMessages.push_back(pendingMessage); + itr = requestSlots.erase(itr); + } else { + itr++; + } + } +} +*/ +Piece PeerInteractionCommand::getNewPieceAndSendInterest() { + Piece piece = e->torrentMan->getMissingPiece(peer->getBitfield(), + peer->getBitfieldLength()); + if(Piece::isNull(piece)) { + e->logger->debug("CUID#%d - try to send not-interested", cuid); + PendingMessage pendingMessage(PeerMessage::NOT_INTERESTED, peerConnection); + pendingMessages.push_back(pendingMessage); + } else { + e->logger->debug("CUID#%d - try to send interested", cuid); + PendingMessage pendingMessage(PeerMessage::INTERESTED, peerConnection); + pendingMessages.push_back(pendingMessage); + //piecefield = new BitfieldMan(16*1024, piece.length); + } + return piece; +} + +void PeerInteractionCommand::sendInterest() { + if(Piece::isNull(piece)) { + // retrive new piece from TorrentMan + piece = getNewPieceAndSendInterest(); + } else if(peer->peerChoking) { + // TODO separate method is better + requestSlotMan->deleteAllRequestSlot(piece); + e->torrentMan->cancelPiece(piece); + piece = Piece::nullPiece; + } else if(piece.pieceComplete()) { + piece = getNewPieceAndSendInterest(); + } +} + +void PeerInteractionCommand::createRequestPendingMessage(int blockIndex) { + PendingMessage pendingMessage = + PendingMessage::createRequestMessage(piece.getIndex(), + blockIndex*piece.getBlockLength(), + piece.getBlockLength(blockIndex), + peerConnection); + pendingMessages.push_back(pendingMessage); + RequestSlot requestSlot(piece.getIndex(), + blockIndex*piece.getBlockLength(), + piece.getBlockLength(blockIndex), + blockIndex); + requestSlotMan->addRequestSlot(requestSlot); +} + +void PeerInteractionCommand::sendMessages() { + if(!Piece::isNull(piece) && !peer->peerChoking) { + if(e->torrentMan->isEndGame()) { + vector missingBlockIndexes = piece.getAllMissingBlockIndexes(); + if(requestSlotMan->isEmpty()) { + for(vector::const_iterator itr = missingBlockIndexes.begin(); + itr != missingBlockIndexes.end(); itr++) { + createRequestPendingMessage(*itr); + } + } + } else { + for(int i = requestSlotMan->countRequestSlot(); i <= 5; i++) { + int blockIndex = piece.getMissingUnusedBlockIndex(); + if(blockIndex == -1) { + if(requestSlotMan->isEmpty()) { + piece = Piece::nullPiece; + } + break; + } + e->torrentMan->updatePiece(piece); + createRequestPendingMessage(blockIndex); + } + } + } + + for(PendingMessages::iterator itr = pendingMessages.begin(); itr != pendingMessages.end();) { + if(itr->processMessage()) { + itr = pendingMessages.erase(itr); + } else { + //setWriteCheckSocket(socket); + break; + } + } +} + +void PeerInteractionCommand::onAbort(Exception* ex) { + requestSlotMan->deleteAllRequestSlot(piece); + e->torrentMan->cancelPiece(piece); + PeerAbstractCommand::onAbort(ex); +} + +void PeerInteractionCommand::keepAlive() { + if(keepAliveCheckPoint.tv_sec == 0 && keepAliveCheckPoint.tv_usec == 0) { + gettimeofday(&keepAliveCheckPoint, NULL); + } else { + struct timeval now; + gettimeofday(&now, NULL); + if(Util::difftv(now, keepAliveCheckPoint) >= 120*1000000) { + if(pendingMessages.empty()) { + peerConnection->sendKeepAlive(); + } + keepAliveCheckPoint = now; + } + } +} + +void PeerInteractionCommand::beforeSocketCheck() { + if(sequence == WIRED) { + e->torrentMan->unadvertisePiece(cuid); + + vector indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid); + if(indexes.size() >= 20) { + PendingMessage pendingMessage(PeerMessage::BITFIELD, peerConnection); + pendingMessages.push_back(pendingMessage); + } else { + for(vector::iterator itr = indexes.begin(); itr != indexes.end(); itr++) { + PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection); + pendingMessages.push_back(pendingMessage); + } + } + if(indexes.size() == 0) { + keepAlive(); + } + } +} + +bool PeerInteractionCommand::checkPieceHash(const Piece& piece) { + long long int offset = ((long long int)piece.getIndex())*e->torrentMan->pieceLength; + return e->torrentMan->diskWriter->sha1Sum(offset, piece.getLength()) == + e->torrentMan->getPieceHash(piece.getIndex()); +} + +void PeerInteractionCommand::erasePieceOnDisk(const Piece& piece) { + int BUFSIZE = 4096; + char buf[BUFSIZE]; + memset(buf, 0, BUFSIZE); + long long int offset = ((long long int)piece.getIndex())*e->torrentMan->pieceLength; + for(int i = 0; i < piece.getLength()/BUFSIZE; i++) { + e->torrentMan->diskWriter->writeData(buf, BUFSIZE, offset); + offset += BUFSIZE; + } + int r = piece.getLength()%BUFSIZE; + if(r > 0) { + e->torrentMan->diskWriter->writeData(buf, r, offset); + } +} diff --git a/src/PeerInteractionCommand.h b/src/PeerInteractionCommand.h new file mode 100644 index 00000000..0bfe7e97 --- /dev/null +++ b/src/PeerInteractionCommand.h @@ -0,0 +1,76 @@ +/* */ +#ifndef _D_PEER_INTERACTION_COMMAND_H_ +#define _D_PEER_INTERACTION_COMMAND_H_ + +#include "PeerAbstractCommand.h" +#include "PeerConnection.h" +#include "PendingMessage.h" +#include "RequestSlotMan.h" +#include + +using namespace std; + +class PeerInteractionCommand : public PeerAbstractCommand { +private: + int sequence; + PeerConnection* peerConnection; + RequestSlotMan* requestSlotMan; + PendingMessages pendingMessages; + Piece piece; + struct timeval keepAliveCheckPoint; + void receiveMessage(); + void syncPiece(); + void detectTimeoutAndDuplicateBlock(); + void decideChoking(); + void sendInterest(); + void sendMessages(); + void createRequestPendingMessage(int blockIndex); + void deletePendingMessage(PeerMessage* cancelMessage); + const RequestSlot& getRequestSlot(int index, int begin, int length) const; + bool deleteRequestSlot(const RequestSlot& slot); + void deleteAllRequestSlot(); + bool checkPieceHash(const Piece& piece); + void erasePieceOnDisk(const Piece& piece); + void keepAlive(); + Piece getNewPieceAndSendInterest(); + void onGotNewPiece(); + void onGotWrongPiece(); +protected: + bool executeInternal(); + bool prepareForRetry(int wait); + bool prepareForNextPeer(int wait); + void onAbort(Exception* ex); + void beforeSocketCheck(); +public: + PeerInteractionCommand(int cuid, Peer* peer, TorrentDownloadEngine* e, Socket* s, int sequence); + ~PeerInteractionCommand(); + + enum Seq { + INITIATOR_SEND_HANDSHAKE, + INITIATOR_WAIT_HANDSHAKE, + RECEIVER_SEND_HANDSHAKE, + RECEIVER_WAIT_HANDSHAKE, + WIRED}; +}; + +#endif // _D_PEER_INTERACTION_COMMAND_H_ diff --git a/src/PeerListenCommand.cc b/src/PeerListenCommand.cc new file mode 100644 index 00000000..bf8efe67 --- /dev/null +++ b/src/PeerListenCommand.cc @@ -0,0 +1,91 @@ +/* */ +#include "PeerListenCommand.h" +#include "PeerInteractionCommand.h" + +PeerListenCommand::PeerListenCommand(int cuid, TorrentDownloadEngine* e) + :Command(cuid), e(e), socket(NULL) { +} + +PeerListenCommand::~PeerListenCommand() { + if(socket != NULL) { + delete socket; + } +} + +int PeerListenCommand::bindPort(int portRangeStart, int portRangeEnd) { + if(portRangeStart > portRangeEnd) { + return -1; + } + for(int port = portRangeStart; port <= portRangeEnd; port++) { + try { + socket = new Socket(); + socket->beginListen(port); + return port; + } catch(Exception* ex) { + e->logger->error("CUID#%d - an error occurred while binding port=%d", + cuid, port); + delete socket; + socket = NULL; + } + } + return -1; +} + +bool PeerListenCommand::execute() { + if(e->torrentMan->downloadComplete()) { + return true; + } + for(int i = 0; i < 3 && socket->isReadable(0); i++) { + Socket* peerSocket = NULL; + try { + peerSocket = socket->acceptConnection(); + if(e->torrentMan->connections < MAX_PEERS) { + pair peerInfo; + peerSocket->getPeerInfo(peerInfo); + Peer* peer = new Peer(peerInfo.first, peerInfo.second, + e->torrentMan->pieceLength, + e->torrentMan->totalSize); + if(e->torrentMan->addPeer(peer, true)) { + int newCuid = e->torrentMan->getNewCuid(); + peer->cuid = newCuid; + PeerInteractionCommand* command = + new PeerInteractionCommand(newCuid, peer, e, peerSocket, + PeerInteractionCommand::RECEIVER_WAIT_HANDSHAKE); + e->commands.push(command); + e->logger->debug("CUID#%d - incoming connection, adding new command CUID#%d", cuid, newCuid); + } else { + delete peer; + } + } + delete peerSocket; + } catch(Exception* ex) { + e->logger->error("CUID#%d - error in accepting connection", cuid, ex); + delete ex; + if(peerSocket != NULL) { + delete peerSocket; + } + } + } + e->commands.push(this); + return false; +} diff --git a/src/PeerListenCommand.h b/src/PeerListenCommand.h new file mode 100644 index 00000000..e2162234 --- /dev/null +++ b/src/PeerListenCommand.h @@ -0,0 +1,42 @@ +/* */ +#ifndef _D_PEER_LISTEN_COMMAND_H_ +#define _D_PEER_LISTEN_COMMAND_H_ + +#include "Command.h" +#include "TorrentDownloadEngine.h" + +class PeerListenCommand : public Command { +private: + TorrentDownloadEngine* e; + Socket* socket; + +public: + PeerListenCommand(int cuid, TorrentDownloadEngine* e); + ~PeerListenCommand(); + + bool execute(); + + int bindPort(int portRangeStart, int portRangeEnd); +}; + +#endif // _D_PEER_LISTEN_COMMAND_H_ diff --git a/src/PeerMessage.cc b/src/PeerMessage.cc new file mode 100644 index 00000000..ddaa3066 --- /dev/null +++ b/src/PeerMessage.cc @@ -0,0 +1,72 @@ +/* */ +#include "PeerMessage.h" +#include "Util.h" + +void PeerMessage::setBitfield(const unsigned char* bitfield, int bitfieldLength) { + if(this->bitfield != NULL) { + delete [] bitfield; + } + this->bitfieldLength = bitfieldLength; + this->bitfield = new unsigned char[this->bitfieldLength]; + memcpy(this->bitfield, bitfield, this->bitfieldLength); +} + +void PeerMessage::setBlock(const char* block, int blockLength) { + if(this->block != NULL) { + delete [] block; + } + this->blockLength = blockLength; + this->block = new char[this->blockLength]; + memcpy(this->block, block, this->blockLength); +} + +string PeerMessage::toString() const { + switch(id) { + case CHOKE: + return "choke"; + case UNCHOKE: + return "unchoke"; + case INTERESTED: + return "interested"; + case NOT_INTERESTED: + return "not interested"; + case HAVE: + return "have index="+Util::itos(index); + case BITFIELD: + return "bitfield "+Util::toHex(bitfield, bitfieldLength); + case REQUEST: + return "request index="+Util::itos(index)+", begin="+Util::itos(begin)+ + ", length="+Util::itos(length); + case PIECE: + return "piece index="+Util::itos(index)+", begin="+Util::itos(begin)+ + ", length="+Util::itos(blockLength); + case CANCEL: + return "calcel index="+Util::itos(index)+", begin="+Util::itos(begin)+ + ", length="+Util::itos(length); + case KEEP_ALIVE: + return "keep alive"; + default: + return "unknown"; + } +} + diff --git a/src/PeerMessage.h b/src/PeerMessage.h new file mode 100644 index 00000000..559a48a2 --- /dev/null +++ b/src/PeerMessage.h @@ -0,0 +1,83 @@ +/* */ +#ifndef _D_PEER_MESSAGE_H_ +#define _D_PEER_MESSAGE_H_ + +#include "common.h" +#include + +class PeerMessage { +private: + int id; + int index; + int begin; + int length; + unsigned char* bitfield; + int bitfieldLength; + char* block; + int blockLength; +public: + PeerMessage():bitfield(NULL), bitfieldLength(0), + block(NULL), blockLength(0) {} + ~PeerMessage() { + if(bitfield != NULL) { + delete [] bitfield; + } + if(block != NULL) { + delete [] block; + } + } + + void setBitfield(const unsigned char* bitfield, int bitfieldLength); + const unsigned char* getBitfield() const { return bitfield; } + + void setBlock(const char* block, int blockLength); + const char* getBlock() const { return block; } + + int getBitfieldLength() const { return bitfieldLength; } + int getBlockLength() const { return blockLength; } + + string toString() const; + + int getId() const { return id; } + void setId(int id) { this->id = id; } + int getIndex() const { return index; } + void setIndex(int index) { this->index = index; } + int getBegin() const { return begin; } + void setBegin(int begin) { this->begin = begin; } + int getLength() const { return length; } + void setLength(int length) { this->length = length; } + + enum ID { + CHOKE = 0, + UNCHOKE = 1, + INTERESTED = 2, + NOT_INTERESTED = 3, + HAVE = 4, + BITFIELD = 5, + REQUEST = 6, + PIECE = 7, + CANCEL = 8, + KEEP_ALIVE = 99}; +}; + +#endif // _D_PEER_MESSAGE_H_ diff --git a/src/PeerMessageUtil.cc b/src/PeerMessageUtil.cc new file mode 100644 index 00000000..4f0f67e0 --- /dev/null +++ b/src/PeerMessageUtil.cc @@ -0,0 +1,231 @@ +/* */ +#include "PeerMessageUtil.h" +#include "DlAbortEx.h" +#include "Util.h" +#include + +PeerMessage* PeerMessageUtil::createPeerMessage(const char* msg, int len) { + PeerMessage* peerMessage; + if(len == 0) { + // keep-alive + peerMessage = new PeerMessage(); + peerMessage->setId(PeerMessage::KEEP_ALIVE); + return peerMessage; + } + int id = getId(msg); + switch(id) { + case PeerMessage::CHOKE: + case PeerMessage::UNCHOKE: + case PeerMessage::INTERESTED: + case PeerMessage::NOT_INTERESTED: + peerMessage = createBasicMessage(id, msg, len); + break; + case PeerMessage::HAVE: + peerMessage = createHaveMessage(id, msg, len); + break; + case PeerMessage::BITFIELD: + peerMessage = createBitfieldMessage(id, msg, len); + break; + case PeerMessage::REQUEST: + case PeerMessage::CANCEL: + peerMessage = createRequestCancelMessage(id, msg, len); + break; + case PeerMessage::PIECE: + peerMessage = createPieceMessage(id, msg, len); + break; + default: + throw new DlAbortEx("invalid message id. id = %d", id); + } + return peerMessage; +} + +PeerMessage* PeerMessageUtil::createBasicMessage(int id, const char* msg, int len) { + if(len != 1) { + throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be %d", id, len, 1); + } + PeerMessage* peerMessage = new PeerMessage(); + peerMessage->setId(id); + return peerMessage; +} + +PeerMessage* PeerMessageUtil::createHaveMessage(int id, const char* msg, int len) { + if(len != 5) { + throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be %d", id, len, 5); + } + PeerMessage* peerMessage = new PeerMessage(); + peerMessage->setId(id); + peerMessage->setIndex(getIntParam(msg, 1)); + return peerMessage; +} + +PeerMessage* PeerMessageUtil::createBitfieldMessage(int id, const char* msg, int len) { + if(len <= 1) { + throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be greater than %d", id, len, 1); + } + PeerMessage* peerMessage = new PeerMessage(); + peerMessage->setId(id); + peerMessage->setBitfield((unsigned char*)msg+1, len-1); + return peerMessage; +} + +PeerMessage* PeerMessageUtil::createRequestCancelMessage(int id, const char* msg, int len) { + if(len != 13) { + throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be %d", id, len, 13); + } + PeerMessage* peerMessage = new PeerMessage(); + peerMessage->setId(id); + peerMessage->setIndex(getIntParam(msg, 1)); + peerMessage->setBegin(getIntParam(msg, 5)); + peerMessage->setLength(getIntParam(msg, 9)); + return peerMessage; +} + +PeerMessage* PeerMessageUtil::createPieceMessage(int id, const char* msg, int len) { + if(len <= 9) { + throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be greater than %d", id, len, 9); + } + PeerMessage* peerMessage = new PeerMessage(); + peerMessage->setId(id); + peerMessage->setIndex(getIntParam(msg, 1)); + peerMessage->setBegin(getIntParam(msg, 5)); + peerMessage->setBlock(msg+9, len-9); + return peerMessage; +} + +int PeerMessageUtil::getId(const char* msg) { + return (int)msg[0]; +} + +int PeerMessageUtil::getIntParam(const char* msg, int offset) { + int nParam; + memcpy(&nParam, msg+offset, 4); + return ntohl(nParam); +} + +void PeerMessageUtil::checkIndex(const PeerMessage* message, int pieces) { + if(!(0 <= message->getIndex() && message->getIndex() < pieces)) { + throw new DlAbortEx("invalid index = %d", message->getIndex()); + } +} + +void PeerMessageUtil::checkBegin(const PeerMessage* message, int pieceLength) { + if(!(0 <= message->getBegin() && message->getBegin() < pieceLength)) { + throw new DlAbortEx("invalid begin = %d", message->getBegin()); + } +} + +void PeerMessageUtil::checkPieceOffset(const PeerMessage* message, int pieceLength, int pieces, long long int totalSize) { + if(!(0 <= message->getBegin() && 0 < message->getLength())) { + throw new DlAbortEx("invalid offset, begin = %d, length = %d", message->getBegin(), message->getLength()); + } + int offset = message->getBegin()+message->getLength(); + int currentPieceLength; + if(message->getIndex()+1 == pieces) { + currentPieceLength = pieceLength-(pieces*pieceLength-totalSize); + } else { + currentPieceLength = pieceLength; + } + if(!(0 < offset && offset <= currentPieceLength)) { + throw new DlAbortEx("invalid offset, begin = %d, length = %d", message->getBegin(), message->getLength()); + } +} + +void PeerMessageUtil::checkLength(const PeerMessage* message) { + if(message->getLength() > 128*1024) { + throw new DlAbortEx("too large length %d > 128KB", message->getLength()); + } +} + +void PeerMessageUtil::checkBitfield(const PeerMessage* message, int pieces) { + if(!(message->getBitfieldLength() == BITFIELD_LEN_FROM_PIECES(pieces))) { + throw new DlAbortEx("invalid bitfield length = %d", message->getBitfieldLength()); + } + char lastbyte = message->getBitfield()[message->getBitfieldLength()-1]; + for(int i = 0; i < 8-pieces%8 && pieces%8 != 0; i++) { + if(!(((lastbyte >> i) & 1) == 0)) { + throw new DlAbortEx("invalid bitfield"); + } + } +} + +void PeerMessageUtil::checkIntegrity(const PeerMessage* message, int pieceLength, int pieces, long long int totalSize) { + // 0 <= index < pieces + // 0 <= begin < pieceLength + // 0 < begin+length <= pieceLength + // len of bitfield == pieces/8+(pieces%8 ? 1 : 0) + // for(int i = 0; i < 8-pieces%8; i++) { ((lastbyteofbitfield >> i) & 1) == 0 } + switch(message->getId()) { + case PeerMessage::KEEP_ALIVE: + case PeerMessage::CHOKE: + case PeerMessage::UNCHOKE: + case PeerMessage::INTERESTED: + case PeerMessage::NOT_INTERESTED: + break; + case PeerMessage::HAVE: + checkIndex(message, pieces); + break; + case PeerMessage::BITFIELD: + checkBitfield(message, pieces); + break; + case PeerMessage::REQUEST: + case PeerMessage::CANCEL: + checkIndex(message, pieces); + checkBegin(message, pieceLength); + checkLength(message); + checkPieceOffset(message, pieceLength, pieces, totalSize); + break; + case PeerMessage::PIECE: + checkIndex(message, pieces); + checkBegin(message, pieceLength); + break; + default: + throw new DlAbortEx("invalid message id. id = %d", message->getId()); + } +} + +HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg) { + HandshakeMessage* message = new HandshakeMessage(); + message->pstrlen = msg[0]; + char pstr[20]; + memcpy(pstr, &msg[1], sizeof(pstr)-1); + pstr[sizeof(pstr)-1] = '\0'; + message->pstr = pstr; + memcpy(message->infoHash, &msg[28], 20); + memcpy(message->peerId, &msg[48], 20); + return message; +} + +void PeerMessageUtil::checkHandshake(const HandshakeMessage* message, const unsigned char* infoHash) { + if(message->pstrlen != 19) { + throw new DlAbortEx("invalid handshake pstrlen = %d", (int)message->pstrlen); + } + if(message->pstr != PSTR) { + throw new DlAbortEx("invalid handshake pstr"); + } + string myInfoHash = Util::toHex(infoHash, 20); + string peerInfoHash = Util::toHex(message->infoHash, 20); + if(myInfoHash != peerInfoHash) { + throw new DlAbortEx("invalid handshake info hash: expected:%s, actual:%s", + myInfoHash.c_str(), peerInfoHash.c_str()); + } +} diff --git a/src/PeerMessageUtil.h b/src/PeerMessageUtil.h new file mode 100644 index 00000000..23e07358 --- /dev/null +++ b/src/PeerMessageUtil.h @@ -0,0 +1,51 @@ +/* */ +#ifndef _D_PEER_MESSAGE_UTIL_H_ +#define _D_PEER_MESSAGE_UTIL_H_ + +#include "PeerConnection.h" + +class PeerMessageUtil { +private: + PeerMessageUtil() {} + + static PeerMessage* createBasicMessage(int id, const char* msg, int len); + static PeerMessage* createHaveMessage(int id, const char* msg, int len); + static PeerMessage* createBitfieldMessage(int id, const char* msg, int len); + static PeerMessage* createRequestCancelMessage(int id, const char* msg, int len); + static PeerMessage* createPieceMessage(int id, const char* msg, int len); + static int getId(const char* msg); + static int getIntParam(const char* msg, int offset); + + static void checkIndex(const PeerMessage* message, int pieces); + static void checkBegin(const PeerMessage* message, int pieceLength); + static void checkLength(const PeerMessage* message); + static void checkPieceOffset(const PeerMessage* message, int pieceLength, int pieces, long long int totalSize); + static void checkBitfield(const PeerMessage* message, int pieces); +public: + static PeerMessage* createPeerMessage(const char* msg, int len); + static void checkIntegrity(const PeerMessage* message, int pieceLength, int pieces, long long int totalSize); + static HandshakeMessage* createHandshakeMessage(const char* msg); + static void checkHandshake(const HandshakeMessage* message, const unsigned char* infoHash); +}; + +#endif // _D_PEER_MESSAGE_UTIL_H_ diff --git a/src/PendingMessage.cc b/src/PendingMessage.cc new file mode 100644 index 00000000..27df5a99 --- /dev/null +++ b/src/PendingMessage.cc @@ -0,0 +1,115 @@ +/* */ +#include "PendingMessage.h" + +bool PendingMessage::processMessage() { + bool retval = true; + switch(peerMessageId) { + case PeerMessage::HAVE: + peerConnection->sendHave(index); + break; + case PeerMessage::BITFIELD: + peerConnection->sendBitfield(); + break; + case PeerMessage::UNCHOKE: + if(peerConnection->getPeer()->amChocking) { + peerConnection->sendUnchoke(); + peerConnection->getPeer()->amChocking = false; + } + break; + case PeerMessage::CHOKE: + if(!peerConnection->getPeer()->amChocking) { + peerConnection->sendChoke(); + peerConnection->getPeer()->amChocking = true; + } + break; + case PeerMessage::NOT_INTERESTED: + if(peerConnection->getPeer()->amInterested) { + peerConnection->sendNotInterested(); + peerConnection->getPeer()->amInterested = false; + } + break; + case PeerMessage::INTERESTED: + if(!peerConnection->getPeer()->amInterested) { + peerConnection->sendInterested(); + peerConnection->getPeer()->amInterested = true; + } + break; + case PeerMessage::PIECE: + if(!peerConnection->getPeer()->amChocking) { + if(!inProgress) { + peerConnection->sendPieceHeader(index, begin, length); + peerConnection->getPeer()->addPeerDownload(length); + } + int writtenLength = peerConnection->sendPieceData(pieceDataOffset, leftPieceDataLength); + if(writtenLength != leftPieceDataLength) { + inProgress = true; + leftPieceDataLength -= writtenLength; + pieceDataOffset += writtenLength; + retval = false; + } + } + break; + case PeerMessage::REQUEST: + peerConnection->sendRequest(index, begin, length); + break; + case PeerMessage::CANCEL: + peerConnection->sendCancel(index, begin, length); + break; + default: + break; + } + return retval; +} + +PendingMessage PendingMessage::createRequestMessage(int index, int begin, int length, PeerConnection* peerConnection) { + PendingMessage pendingMessage(PeerMessage::REQUEST, peerConnection); + pendingMessage.setIndex(index); + pendingMessage.setBegin(begin); + pendingMessage.setLength(length); + return pendingMessage; +} + +PendingMessage PendingMessage::createCancelMessage(int index, int begin, int length, PeerConnection* peerConnection) { + PendingMessage pendingMessage(PeerMessage::CANCEL, peerConnection); + pendingMessage.setIndex(index); + pendingMessage.setBegin(begin); + pendingMessage.setLength(length); + return pendingMessage; +} + +PendingMessage PendingMessage::createPieceMessage(int index, int begin, int length, int pieceLength, PeerConnection* peerConnection) { + PendingMessage pendingMessage(PeerMessage::PIECE, peerConnection); + pendingMessage.setIndex(index); + pendingMessage.setBegin(begin); + pendingMessage.setLength(length); + pendingMessage.setPieceDataOffset(((long long int)index)*pieceLength+begin); + pendingMessage.setLeftPieceDataLength(length); + return pendingMessage; +} + +PendingMessage PendingMessage::createHaveMessage(int index, PeerConnection* peerConnection) { + PendingMessage pendingMessage(PeerMessage::HAVE, peerConnection); + pendingMessage.setIndex(index); + return pendingMessage; +} + diff --git a/src/PendingMessage.h b/src/PendingMessage.h new file mode 100644 index 00000000..da877748 --- /dev/null +++ b/src/PendingMessage.h @@ -0,0 +1,71 @@ +/* */ +#ifndef _D_PENDING_MESSAGE_H_ +#define _D_PENDING_MESSAGE_H_ + +#include "common.h" +#include "PeerConnection.h" +#include + +class PendingMessage { +private: + int peerMessageId; + int index; + int begin; + int length; + long long int pieceDataOffset; + int leftPieceDataLength; + bool inProgress; + PeerConnection* peerConnection; +public: + PendingMessage(int peerMessageId, PeerConnection* peerConnection):peerMessageId(peerMessageId), inProgress(false), peerConnection(peerConnection) {} + ~PendingMessage() {} + + void setPeerMessageId(int peerMessageId) { this->peerMessageId = peerMessageId; } + int getPeerMessageId() const { return peerMessageId; } + + void setPieceDataOffset(long long int offset) { this->pieceDataOffset = offset; } + long long int getPieceDataOffset() const { return pieceDataOffset; } + + void setLeftPieceDataLength(int length) { this->leftPieceDataLength = length; } + int getLeftPieceDataLength() const { return leftPieceDataLength; } + + void setInProgress(bool inprogress) { this->inProgress = inProgress; } + bool isInProgress() const { return inProgress; } + + void setIndex(int index) { this->index = index; } + int getIndex() const { return index; } + void setBegin(int begin) { this->begin = begin; } + int getBegin() const { return begin; } + void setLength(int length) { this->length = length; } + int getLength() const { return length; } + bool processMessage(); + + static PendingMessage createRequestMessage(int index, int begin, int length, PeerConnection* peerConnection); + static PendingMessage createCancelMessage(int index, int begin, int length, PeerConnection* peerConnection); + static PendingMessage createPieceMessage(int index, int begin, int length, int pieceLength, PeerConnection* peerConnection); + static PendingMessage createHaveMessage(int index, PeerConnection* peerConnectioin); +}; + +typedef vector PendingMessages; + +#endif // _D_PENDING_MESSAGE_H_ diff --git a/src/Piece.cc b/src/Piece.cc new file mode 100644 index 00000000..b27cc621 --- /dev/null +++ b/src/Piece.cc @@ -0,0 +1,84 @@ +/* */ +#include "Piece.h" + +Piece Piece::nullPiece; + +Piece::Piece(const Piece& piece) { + index = piece.index; + length = piece.length; + if(piece.bitfield == NULL) { + bitfield = NULL; + } else { + bitfield = new BitfieldMan(*piece.bitfield); + } +} + +Piece& Piece::operator=(const Piece& piece) { + if(this != &piece) { + index = piece.index; + length = piece.length; + if(bitfield != NULL) { + delete bitfield; + } + if(piece.bitfield == NULL) { + bitfield = NULL; + } else { + bitfield = new BitfieldMan(*piece.bitfield); + } + } + return *this; +} + +void Piece::completeBlock(int blockIndex) { + bitfield->setBit(blockIndex); + bitfield->unsetUseBit(blockIndex); +} + +void Piece::clearAllBlock() { + bitfield->clearAllBit(); +} + +void Piece::setAllBlock() { + bitfield->setAllBit(); +} + +bool Piece::pieceComplete() const { + return bitfield->isAllBitSet(); +} + +void Piece::cancelBlock(int blockIndex) { + bitfield->unsetUseBit(blockIndex); +} + +int Piece::getMissingUnusedBlockIndex() const { + int blockIndex = bitfield->getFirstMissingUnusedIndex(); + if(blockIndex == -1) { + return blockIndex; + } + bitfield->setUseBit(blockIndex); + return blockIndex; +} + +vector Piece::getAllMissingBlockIndexes() const { + return bitfield->getAllMissingIndexes(); +} diff --git a/src/Piece.h b/src/Piece.h new file mode 100644 index 00000000..f12dcf15 --- /dev/null +++ b/src/Piece.h @@ -0,0 +1,81 @@ +/* */ +#ifndef _D_PIECE_H_ +#define _D_PIECE_H_ + +#include "BitfieldMan.h" +#include "common.h" + +#define BLOCK_LENGTH 16*1024 + +class Piece { +private: + int index; + int length; + BitfieldMan* bitfield; +public: + Piece():index(0), length(0), bitfield(NULL) {} + Piece(int index, int length):index(index), length(length) { + bitfield = new BitfieldMan(BLOCK_LENGTH, length); + } + Piece(const Piece& piece); + ~Piece() { + delete bitfield; + } + + Piece& operator=(const Piece& piece); + + int getMissingUnusedBlockIndex() const; + vector getAllMissingBlockIndexes() const; + void completeBlock(int blockIndex); + void cancelBlock(int blockIndex); + int countCompleteBlock() const { + return bitfield->countBlock()-bitfield->countMissingBlock(); + } + bool hasBlock(int blockIndex) const { + return bitfield->isBitSet(blockIndex); + } + + bool pieceComplete() const; + int countBlock() const { return bitfield->countBlock(); } + int getBlockLength(int index) const { + return bitfield->getBlockLength(index); + } + int getBlockLength() const { return bitfield->getBlockLength(); } + int getIndex() const { return index; } + void setIndex(int index) { this->index = index; } + int getLength() const { return length; } + void setLength(int index) { this->length = length; } + + const unsigned char* getBitfield() const { return bitfield->getBitfield(); } + void setBitfield(const unsigned char* bitfield, int len); + + void clearAllBlock(); + void setAllBlock(); + + static Piece nullPiece; + static bool isNull(const Piece& piece) { + return piece.index == 0 && piece.length == 0; + } +}; + +#endif // _D_PIECE_H_ diff --git a/src/PreAllocationDiskWriter.cc b/src/PreAllocationDiskWriter.cc index abf87777..9fef82f8 100644 --- a/src/PreAllocationDiskWriter.cc +++ b/src/PreAllocationDiskWriter.cc @@ -20,15 +20,16 @@ */ /* copyright --> */ #include "PreAllocationDiskWriter.h" +#include "DlAbortEx.h" #include #include #include #include #include #include -#include "DlAbortEx.h" -PreAllocationDiskWriter::PreAllocationDiskWriter(unsigned long int size):AbstractDiskWriter(),size(size) {} +PreAllocationDiskWriter::PreAllocationDiskWriter(long long int totalLength) + :AbstractDiskWriter(),totalLength(totalLength) {} PreAllocationDiskWriter::~PreAllocationDiskWriter() {} @@ -36,34 +37,32 @@ void PreAllocationDiskWriter::initAndOpenFile(string filename) { createFile(filename, O_DIRECT); int pageSize = getpagesize(); + int bufSize = pageSize*4; char* buf; - int size = pageSize*4; - int rt = posix_memalign((void**)&buf, pageSize, size); + int rt = posix_memalign((void**)&buf, pageSize, bufSize); if(rt != 0) { throw new DlAbortEx(strerror(rt)); } - memset(buf, 0, size); - int x = size/4096; - int r = size%4096; - for(int i = 0; i < x; i++) { - if(write(fd, buf, size) < 0) { - free(buf); - throw new DlAbortEx(strerror(errno)); + try { + memset(buf, 0, bufSize); + long long int x = totalLength/bufSize; + int r = totalLength%bufSize; + for(long long int i = 0; i < x; i++) { + if(write(fd, buf, bufSize) < 0) { + throw new DlAbortEx(strerror(errno)); + } } - } - free(buf); - closeFile(); - openExistingFile(filename); - char cbuf[4096]; - memset(cbuf, 0, sizeof(cbuf)); - if(write(fd, cbuf, r) < 0) { - throw new DlAbortEx(strerror(errno)); + closeFile(); + openExistingFile(filename); + if(r > 0) { + seek(totalLength-r); + if(write(fd, buf, r) < 0) { + throw new DlAbortEx(strerror(errno)); + } + } + free(buf); + } catch(Exception* ex) { + free(buf); + throw; } } - -void PreAllocationDiskWriter::writeData(const char* data, int len, unsigned long int offset) { - int x = lseek(fd, offset, SEEK_SET); - // TODO check the return value of write - writeDataInternal(data, len); -} - diff --git a/src/PreAllocationDiskWriter.h b/src/PreAllocationDiskWriter.h index eca8b996..c56cf717 100644 --- a/src/PreAllocationDiskWriter.h +++ b/src/PreAllocationDiskWriter.h @@ -26,14 +26,12 @@ class PreAllocationDiskWriter:public AbstractDiskWriter { private: - unsigned long int size; + long long int totalLength; public: - PreAllocationDiskWriter(unsigned long int size); + PreAllocationDiskWriter(long long int totalLength); ~PreAllocationDiskWriter(); void initAndOpenFile(string filename); - - void writeData(const char* data, int len, unsigned long int position); }; #endif // _D_PRE_ALLOCATION_DISK_WRITER_H_ diff --git a/src/Request.cc b/src/Request.cc index 9d183cd4..91bd6d12 100644 --- a/src/Request.cc +++ b/src/Request.cc @@ -22,7 +22,7 @@ #include "Request.h" #include "Util.h" -Request::Request():port(0), tryCount(0) { +Request::Request():port(0), tryCount(0), isTorrent(false) { defaultPorts["http"] = 80; #ifdef HAVE_LIBSSL // for SSL diff --git a/src/Request.h b/src/Request.h index 8d8676ef..9bd55948 100644 --- a/src/Request.h +++ b/src/Request.h @@ -56,10 +56,12 @@ private: string file; map defaultPorts; int tryCount; + int trackerEvent; bool parseUrl(string url); public: Segment seg; CookieBox* cookieBox; + bool isTorrent; public: Request(); virtual ~Request(); @@ -87,6 +89,17 @@ public: int getPort() const { return port; } string getDir() const { return dir; } string getFile() const { return file;} + + void setTrackerEvent(int event) { trackerEvent = event; } + int getTrackerEvent() const { return trackerEvent; } + + enum TRACKER_EVENT { + AUTO, + STARTED, + STOPPED, + COMPLETED + }; + }; #endif // _D_REQUEST_H_ diff --git a/src/RequestSlot.cc b/src/RequestSlot.cc new file mode 100644 index 00000000..3729f47d --- /dev/null +++ b/src/RequestSlot.cc @@ -0,0 +1,70 @@ +/* */ +#include "RequestSlot.h" +#include "Util.h" + +RequestSlot::RequestSlot(int index, int begin, int length, int blockIndex) + :index(index), begin(begin), length(length), blockIndex(blockIndex) { + setDispatchedTime(); +} + +RequestSlot::RequestSlot(const RequestSlot& requestSlot) { + copy(requestSlot); +} + +RequestSlot& RequestSlot::operator=(const RequestSlot& requestSlot) { + if(this != &requestSlot) { + copy(requestSlot); + } + return *this; +} + +void RequestSlot::copy(const RequestSlot& requestSlot) { + index = requestSlot.index; + begin = requestSlot.begin; + length = requestSlot.length; + blockIndex = requestSlot.blockIndex; + dispatchedTime = requestSlot.dispatchedTime; +} + +RequestSlot RequestSlot::nullSlot(0, 0, 0, 0); + +void RequestSlot::setDispatchedTime() { + gettimeofday(&dispatchedTime, NULL); +} + +bool RequestSlot::isTimeout(int timeoutSec) const { + struct timeval now; + gettimeofday(&now, NULL); + return Util::difftv(now, dispatchedTime) > timeoutSec*1000000; +} + +bool RequestSlot::isNull(const RequestSlot& requestSlot) { + return requestSlot.index == 0 && requestSlot.begin == 0&& + requestSlot.length == 0; +} + +bool RequestSlot::operator==(const RequestSlot& requestSlot) const { + return index == requestSlot.index && + begin == requestSlot.begin && + length == requestSlot.length; +} diff --git a/src/RequestSlot.h b/src/RequestSlot.h new file mode 100644 index 00000000..f4c36d9b --- /dev/null +++ b/src/RequestSlot.h @@ -0,0 +1,63 @@ +/* */ +#ifndef _D_REQUEST_SLOT_H_ +#define _D_REQUEST_SLOT_H_ + +#include "common.h" +#include + +class RequestSlot { +private: + struct timeval dispatchedTime; + int index; + int begin; + int length; + int blockIndex; + void copy(const RequestSlot& requestSlot); +public: + RequestSlot(int index, int begin, int legnth, int blockIndex); + RequestSlot(const RequestSlot& requestSlot); + ~RequestSlot() {} + + RequestSlot& operator=(const RequestSlot& requestSlot); + + void setDispatchedTime(); + + bool isTimeout(int timeoutSec) const; + + bool operator==(const RequestSlot& requestSlot) const; + + int getIndex() const { return index; } + void setIndex(int index) { this->index = index; } + int getBegin() const { return begin; } + void setBegin(int begin) { this->begin = begin; } + int getLength() const { return length; } + void setLength(int length) { this->length = length; } + int getBlockIndex() const { return blockIndex; } + void setBlockIndex(int blockIndex) { this->blockIndex = blockIndex; } + + static RequestSlot nullSlot; + + static bool isNull(const RequestSlot& requestSlot); +}; + +#endif // _D_REQUEST_SLOT_H_ diff --git a/src/RequestSlotMan.cc b/src/RequestSlotMan.cc new file mode 100644 index 00000000..378371a6 --- /dev/null +++ b/src/RequestSlotMan.cc @@ -0,0 +1,98 @@ +/* */ +#include "RequestSlotMan.h" + +void RequestSlotMan::addRequestSlot(const RequestSlot& requestSlot) { + requestSlots.push_back(requestSlot); +} + +void RequestSlotMan::deleteRequestSlot(const RequestSlot& requestSlot) { + for(RequestSlots::iterator itr = requestSlots.begin(); + itr != requestSlots.end(); itr++) { + if(*itr == requestSlot) { + requestSlots.erase(itr); + break; + } + } +} + +void RequestSlotMan::deleteAllRequestSlot(Piece& piece) { + if(!Piece::isNull(piece)) { + for(RequestSlots::const_iterator itr = requestSlots.begin(); + itr != requestSlots.end(); itr++) { + if(itr->getIndex() == piece.getIndex()) { + piece.cancelBlock(itr->getBlockIndex()); + } + } + torrentMan->updatePiece(piece); + } + requestSlots.clear(); +} + +void RequestSlotMan::deleteTimedoutRequestSlot(Piece& piece) { + for(RequestSlots::iterator itr = requestSlots.begin(); + itr != requestSlots.end();) { + if(itr->isTimeout(timeout)) { + logger->debug("CUID#%d - deleting requestslot blockIndex %d because of time out", cuid, + itr->getBlockIndex()); + if(!Piece::isNull(piece)) { + piece.cancelBlock(itr->getBlockIndex()); + } + itr = requestSlots.erase(itr); + } else { + itr++; + } + } + torrentMan->updatePiece(piece); +} + +void RequestSlotMan::deleteCompletedRequestSlot(const Piece& piece) { + for(RequestSlots::iterator itr = requestSlots.begin(); + itr != requestSlots.end();) { + if(Piece::isNull(piece) || piece.hasBlock(itr->getBlockIndex())) { + logger->debug("CUID#%d - deleting requestslot blockIndex %d because the block is already acquired.", cuid, + itr->getBlockIndex()); + PendingMessage pendingMessage = + PendingMessage::createCancelMessage(itr->getIndex(), + itr->getBegin(), + itr->getLength(), + peerConnection); + pendingMessages->push_back(pendingMessage); + itr = requestSlots.erase(itr); + } else { + itr++; + } + } +} + +RequestSlot RequestSlotMan::getCorrespoindingRequestSlot(const PeerMessage* pieceMessage) const { + for(RequestSlots::const_iterator itr = requestSlots.begin(); + itr != requestSlots.end(); itr++) { + const RequestSlot& slot = *itr; + if(slot.getIndex() == pieceMessage->getIndex() && + slot.getBegin() == pieceMessage->getBegin() && + slot.getLength() == pieceMessage->getBlockLength()) { + return slot; + } + } + return RequestSlot::nullSlot; +} diff --git a/src/RequestSlotMan.h b/src/RequestSlotMan.h new file mode 100644 index 00000000..f0c1f008 --- /dev/null +++ b/src/RequestSlotMan.h @@ -0,0 +1,72 @@ +/* */ +#ifndef _D_REQUEST_SLOT_MAN_H_ +#define _D_REQUEST_SLOT_MAN_H_ + +#include "RequestSlot.h" +#include "common.h" +#include "PeerMessage.h" +#include "Logger.h" +#include "PeerConnection.h" +#include "PendingMessage.h" +#include "TorrentMan.h" +#include + +#define DEFAULT_TIME_OUT 120 + +typedef vector RequestSlots; + +class RequestSlotMan { +private: + int cuid; + RequestSlots requestSlots; + int timeout; + PendingMessages* pendingMessages; + PeerConnection* peerConnection; + TorrentMan* torrentMan; + const Logger* logger; +public: + RequestSlotMan(int cuid, + PendingMessages* pendingMessages, + PeerConnection* peerConnection, + TorrentMan* torrentMan, + const Logger* logger):cuid(cuid), timeout(DEFAULT_TIME_OUT), + pendingMessages(pendingMessages), peerConnection(peerConnection), + torrentMan(torrentMan), logger(logger) {} + ~RequestSlotMan() {} + + void addRequestSlot(const RequestSlot& requestSlot); + void deleteRequestSlot(const RequestSlot& requestSlot); + void deleteAllRequestSlot(Piece& piece); + + void deleteTimedoutRequestSlot(Piece& piece); + void deleteCompletedRequestSlot(const Piece& piece); + + RequestSlot getCorrespoindingRequestSlot(const PeerMessage* pieceMessage) const; + bool isEmpty() { return requestSlots.empty(); } + int countRequestSlot() const { return requestSlots.size(); } + + void setTimeout(int timeout) { this->timeout = timeout; } + int getTimeout() const { return timeout; } +}; + +#endif // _D_REQUEST_SLOT_MAN_H_ diff --git a/src/ShaVisitor.cc b/src/ShaVisitor.cc new file mode 100644 index 00000000..0c6eef81 --- /dev/null +++ b/src/ShaVisitor.cc @@ -0,0 +1,82 @@ +/* */ +#include "ShaVisitor.h" +#include "Util.h" + +ShaVisitor::ShaVisitor() { + EVP_MD_CTX_init(&ctx); + EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL); +} + +ShaVisitor::~ShaVisitor() { + EVP_MD_CTX_cleanup(&ctx); +} + +void ShaVisitor::visit(const Data* d) { + if(d->isNumber()) { + EVP_DigestUpdate(&ctx, "i", 1); + } else { + string lenStr = Util::llitos(d->getLen()); + EVP_DigestUpdate(&ctx, lenStr.c_str(), lenStr.size()); + EVP_DigestUpdate(&ctx, ":", 1); + } + EVP_DigestUpdate(&ctx, d->getData(), d->getLen()); + if(d->isNumber()) { + EVP_DigestUpdate(&ctx, "e", 1); + } +} + +void ShaVisitor::visit(const Dictionary* d) { + EVP_DigestUpdate(&ctx, "d", 1); + const vector& v = d->getOrder(); + for(vector::const_iterator itr = v.begin(); itr != v.end(); itr++) { + string lenStr = Util::llitos(itr->size()); + EVP_DigestUpdate(&ctx, lenStr.c_str(), lenStr.size()); + EVP_DigestUpdate(&ctx, ":", 1); + EVP_DigestUpdate(&ctx, itr->c_str(), itr->size()); + const MetaEntry* e = d->get(*itr); + this->visit(e); + } + EVP_DigestUpdate(&ctx, "e", 1); +} + +void ShaVisitor::visit(const List* l) { + EVP_DigestUpdate(&ctx, "l", 1); + for(MetaList::const_iterator itr = l->getList().begin(); itr != l->getList().end(); itr++) { + this->visit(*itr); + } + EVP_DigestUpdate(&ctx, "e", 1); +} + +void ShaVisitor::visit(const MetaEntry* e) { + if(dynamic_cast(e) != NULL) { + visit((const Data*)e); + } else if(dynamic_cast(e) != NULL) { + visit((const Dictionary*)e); + } else if(dynamic_cast(e) != NULL) { + visit((const List*)e); + } +} + +void ShaVisitor::getHash(unsigned char* hashValue, int& len) { + EVP_DigestFinal_ex(&ctx, hashValue, (unsigned int*)&len); +} diff --git a/src/ShaVisitor.h b/src/ShaVisitor.h new file mode 100644 index 00000000..59b5e19a --- /dev/null +++ b/src/ShaVisitor.h @@ -0,0 +1,47 @@ +/* */ +#ifndef _D_SHA_VISITOR_H_ +#define _D_SHA_VISITOR_H_ + +#include "MetaEntryVisitor.h" +#include "Data.h" +#include "Dictionary.h" +#include "List.h" +#include "common.h" +#include + +class ShaVisitor : public MetaEntryVisitor { +private: + EVP_MD_CTX ctx; +public: + ShaVisitor(); + ~ShaVisitor(); + + void visit(const Data* d); + void visit(const Dictionary* d); + void visit(const List* l); + void visit(const MetaEntry* e); + + void getHash(unsigned char* md, int& s); +}; + +#endif // _D_SHA_VISITOR_H_ diff --git a/src/Socket.cc b/src/Socket.cc index f4e0862d..973aafe6 100644 --- a/src/Socket.cc +++ b/src/Socket.cc @@ -53,14 +53,18 @@ Socket& Socket::operator=(const Socket& s) { return *this; } -void Socket::beginListen() const { - core->beginListen(); +void Socket::beginListen(int port) const { + core->beginListen(port); } void Socket::getAddrInfo(pair& addrinfo) const { core->getAddrInfo(addrinfo); } +void Socket::getPeerInfo(pair& peerinfo) const { + core->getPeerInfo(peerinfo); +} + Socket* Socket::acceptConnection() const { return new Socket(core->acceptConnection()); } diff --git a/src/Socket.h b/src/Socket.h index d49ef953..d07a5eb9 100644 --- a/src/Socket.h +++ b/src/Socket.h @@ -51,13 +51,18 @@ public: /** * @see SocketCore::beginListen() */ - void beginListen() const; + void beginListen(int port = 0) const; /** * @see SocketCore::getAddrInfo() */ void getAddrInfo(pair& addrinfo) const; + /** + * @see SocketCore::getPeerInfo(); + */ + void getPeerInfo(pair& peerinfo) const; + /** * @see SocketCore::acceptConnection() */ diff --git a/src/SocketCore.cc b/src/SocketCore.cc index f4d02dce..83c2c95f 100644 --- a/src/SocketCore.cc +++ b/src/SocketCore.cc @@ -56,7 +56,7 @@ SocketCore::~SocketCore() { closeConnection(); } -void SocketCore::beginListen() { +void SocketCore::beginListen(int port) { closeConnection(); //sockfd = socket(AF_UNSPEC, SOCK_STREAM, PF_UNSPEC); sockfd = socket(AF_INET, SOCK_STREAM, 0); @@ -74,7 +74,7 @@ void SocketCore::beginListen() { memset((char*)&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = INADDR_ANY; - sockaddr.sin_port = htons(0); + sockaddr.sin_port = htons(port); if(bind(sockfd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == -1) { throw new DlAbortEx(strerror(errno)); @@ -93,6 +93,7 @@ SocketCore* SocketCore::acceptConnection() const { if((fd = accept(sockfd, (struct sockaddr*)&sockaddr, &len)) == -1) { throw new DlAbortEx(strerror(errno)); } + SocketCore* s = new SocketCore(fd); return s; } @@ -108,6 +109,17 @@ void SocketCore::getAddrInfo(pair& addrinfo) const { addrinfo.second = ntohs(listenaddr.sin_port); } +void SocketCore::getPeerInfo(pair& peerinfo) const { + struct sockaddr_in peerin; + memset(&peerin, 0, sizeof(peerin)); + int len = sizeof(peerin); + if(getpeername(sockfd, (struct sockaddr*)&peerin, (socklen_t*)&len) < 0) { + throw new DlAbortEx(strerror(errno)); + } + peerinfo.first = inet_ntoa(peerin.sin_addr); + peerinfo.second = ntohs(peerin.sin_port); +} + void SocketCore::establishConnection(string host, int port) { closeConnection(); sockfd = socket(AF_INET, SOCK_STREAM, 0); @@ -134,7 +146,6 @@ void SocketCore::establishConnection(string host, int port) { ai.ai_family = PF_INET; ai.ai_socktype = SOCK_STREAM; ai.ai_protocol = 0; - ai.ai_addr = (struct sockaddr*)&sockaddr; struct addrinfo* res; int ec; if((ec = getaddrinfo(host.c_str(), NULL, &ai, &res)) != 0) { @@ -227,8 +238,7 @@ bool SocketCore::isReadable(int timeout) const { } void SocketCore::writeData(const char* data, int len, int timeout) const { - if(!isWritable(timeout) || - !secure && send(sockfd, data, (size_t)len, 0) != len + if(!secure && send(sockfd, data, (size_t)len, 0) != len #ifdef HAVE_LIBSSL // for SSL // TODO handling len == 0 case required @@ -240,8 +250,7 @@ void SocketCore::writeData(const char* data, int len, int timeout) const { } void SocketCore::readData(char* data, int& len, int timeout) const { - if(!isReadable(timeout) || - !secure && (len = recv(sockfd, data, (size_t)len, 0)) < 0 + if(!secure && (len = recv(sockfd, data, (size_t)len, 0)) < 0 #ifdef HAVE_LIBSSL // for SSL // TODO handling len == 0 case required @@ -253,8 +262,7 @@ void SocketCore::readData(char* data, int& len, int timeout) const { } void SocketCore::peekData(char* data, int& len, int timeout) const { - if(!isReadable(timeout) || - !secure && (len = recv(sockfd, data, (size_t)len, MSG_PEEK)) < 0 + if(!secure && (len = recv(sockfd, data, (size_t)len, MSG_PEEK)) < 0 #ifdef HAVE_LIBSSL // for SSL // TODO handling len == 0 case required diff --git a/src/SocketCore.h b/src/SocketCore.h index 3c09da60..01ec3e85 100644 --- a/src/SocketCore.h +++ b/src/SocketCore.h @@ -54,14 +54,22 @@ public: /** * Creates a socket and listens form connection on it. + * @param port port to listen. If 0 is specified, os automaticaly + * choose avaiable port. */ - void beginListen(); + void beginListen(int port = 0); /** * Stores host address and port of this socket to addrinfo. * @param addrinfo placeholder to store host address and port. */ void getAddrInfo(pair& addrinfo) const; + + /** + * Stores peer's address and port to peerinfo. + * @param peerinfo placeholder to store peer's address and port. + */ + void getPeerInfo(pair& peerinfo) const; /** * Accepts incoming connection on this socket. @@ -118,7 +126,7 @@ public: * @param timeout the amount of time elapsed before isWritable() * are timed out. */ - void writeData(const char* data, int len, int timeout = 5) const; + void writeData(const char* data, int len, int timeout = 0) const; /** * Reads up to len bytes from this socket. @@ -134,7 +142,7 @@ public: * @param timeout the amount of time elapsed before isReadable() are timed * out. */ - void readData(char* data, int& len, int timeout = 5) const; + void readData(char* data, int& len, int timeout = 0) const; /** * Reads up to len bytes from this socket, but bytes are not removed from @@ -147,7 +155,7 @@ public: * @param timeout the amount of time elapsed before isReadable() are timed * out. */ - void peekData(char* data, int& len, int timeout = 5) const; + void peekData(char* data, int& len, int timeout = 0) const; /** * Makes this socket secure. diff --git a/src/TorrentAutoSaveCommand.cc b/src/TorrentAutoSaveCommand.cc new file mode 100644 index 00000000..994ee4af --- /dev/null +++ b/src/TorrentAutoSaveCommand.cc @@ -0,0 +1,37 @@ +/* */ +#include "TorrentAutoSaveCommand.h" +#include "SleepCommand.h" + +TorrentAutoSaveCommand::TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval):Command(cuid), e(e), interval(interval) {} + +TorrentAutoSaveCommand::~TorrentAutoSaveCommand() {} + +bool TorrentAutoSaveCommand::execute() { + if(e->torrentMan->downloadComplete()) { + return true; + } + e->torrentMan->save(); + SleepCommand* sleepCommand = new SleepCommand(cuid, e, this, interval); + e->commands.push(sleepCommand); + return false; +} diff --git a/src/TorrentAutoSaveCommand.h b/src/TorrentAutoSaveCommand.h new file mode 100644 index 00000000..562fdf0d --- /dev/null +++ b/src/TorrentAutoSaveCommand.h @@ -0,0 +1,40 @@ +/* */ +#ifndef _D_TORRENT_AUTO_SAVE_COMMAND_H_ +#define _D_TORRENT_AUTO_SAVE_COMMAND_H_ + +#include "Command.h" +#include "TorrentDownloadEngine.h" + +class TorrentAutoSaveCommand : public Command { +private: + int cuid; + TorrentDownloadEngine* e; + int interval; +public: + TorrentAutoSaveCommand(int cuid, TorrentDownloadEngine* e, int interval); + ~TorrentAutoSaveCommand(); + + bool execute(); +}; + +#endif // _D_TORRENT_AUTO_SAVE_COMMAND_H_ diff --git a/src/TorrentConsoleDownloadEngine.cc b/src/TorrentConsoleDownloadEngine.cc new file mode 100644 index 00000000..8a793e91 --- /dev/null +++ b/src/TorrentConsoleDownloadEngine.cc @@ -0,0 +1,132 @@ +/* */ +#include "TorrentConsoleDownloadEngine.h" +#include "Util.h" + +TorrentConsoleDownloadEngine::TorrentConsoleDownloadEngine() {} + +TorrentConsoleDownloadEngine::~TorrentConsoleDownloadEngine() {} + +void TorrentConsoleDownloadEngine::printStatistics() { + printf("\r "); + printf("\r"); + printf("%s/%sB %d%% DW:%.2f UP:%.2f(%s) %dpeers", + Util::llitos(torrentMan->getDownloadedSize(), true).c_str(), + Util::llitos(torrentMan->totalSize, true).c_str(), + (torrentMan->totalSize == 0 ? + 0 : (int)((torrentMan->getDownloadedSize()*100)/torrentMan->totalSize)), + downloadSpeed/1000.0, + uploadSpeed/1000.0, + Util::llitos(torrentMan->getUploadedSize(), true).c_str(), + torrentMan->connections); + fflush(stdout); +} + +void TorrentConsoleDownloadEngine::initStatistics() { + /* + gettimeofday(&cp, NULL); + */ + downloadSpeed = 0; + uploadSpeed = 0; + /* + sessionDownloadSize = 0; + sessionUploadSize = 0; + */ + lastElapsed = 0; + gettimeofday(&cp[0], NULL); + gettimeofday(&cp[1], NULL); + sessionDownloadSize[0] = 0; + sessionDownloadSize[1] = 0; + sessionUploadSize[0] = 0; + sessionUploadSize[1] = 0; + currentCp = 0; +} + +/* +int TorrentConsoleDownloadEngine::calculateSpeed(int deltaSize, long long int elapsed, int prevSpeed) { + int nowSpeed = (int)(deltaSize/(elapsed/1000000.0)); + return (nowSpeed+prevSpeed)/2; +} +*/ +int TorrentConsoleDownloadEngine::calculateSpeed(long long int sessionSize, long long int elapsed) { + int nowSpeed = (int)(sessionSize/(elapsed/1000000.0)); + return nowSpeed; +} + +void TorrentConsoleDownloadEngine::calculateStatistics() { + /* + struct timeval now; + gettimeofday(&now, NULL); + long long int elapsed = Util::difftv(now, cp); + sessionDownloadSize += torrentMan->getDeltaDownload(); + sessionUploadSize += torrentMan->getDeltaUpload(); + + downloadSpeed = calculateSpeed(sessionDownloadSize, elapsed); + uploadSpeed = calculateSpeed(sessionUploadSize, elapsed); + torrentMan->resetDeltaDownload(); + torrentMan->resetDeltaUpload(); + if(elapsed-lastElapsed >= 1000000) { + printStatistics(); + lastElapsed = elapsed; + } + */ + struct timeval now; + gettimeofday(&now, NULL); + long long int elapsed = Util::difftv(now, cp[currentCp]); + + sessionDownloadSize[0] += torrentMan->getDeltaDownload(); + sessionUploadSize[0] += torrentMan->getDeltaUpload(); + sessionDownloadSize[1] += torrentMan->getDeltaDownload(); + sessionUploadSize[1] += torrentMan->getDeltaUpload(); + + downloadSpeed = calculateSpeed(sessionDownloadSize[currentCp], elapsed); + uploadSpeed = calculateSpeed(sessionUploadSize[currentCp], elapsed); + + torrentMan->resetDeltaDownload(); + torrentMan->resetDeltaUpload(); + + if(elapsed-lastElapsed >= 1000000) { + printStatistics(); + lastElapsed = elapsed; + } + + if(elapsed > 15*1000000) { + sessionDownloadSize[currentCp] = 0; + sessionUploadSize[currentCp] = 0; + cp[currentCp] = now; + lastElapsed = 0; + currentCp = currentCp ? 0 : 1; + } + + /* + if(elapsed >= 1000000) { + downloadSpeed = calculateSpeed(torrentMan->getDeltaDownload(), + elapsed, downloadSpeed); + uploadSpeed = calculateSpeed(torrentMan->getDeltaUpload(), + elapsed, uploadSpeed); + torrentMan->resetDeltaDownload(); + torrentMan->resetDeltaUpload(); + cp = now; + printStatistics(); + } + */ +} diff --git a/src/TorrentConsoleDownloadEngine.h b/src/TorrentConsoleDownloadEngine.h new file mode 100644 index 00000000..da3a67b0 --- /dev/null +++ b/src/TorrentConsoleDownloadEngine.h @@ -0,0 +1,52 @@ +/* */ +#ifndef _D_TORRENT_CONSOLE_DOWNLOAD_ENGINE_H_ +#define _D_TORRENT_CONSOLE_DOWNLOAD_ENGINE_H_ + +#include "TorrentDownloadEngine.h" + +class TorrentConsoleDownloadEngine : public TorrentDownloadEngine { +private: + /* + struct timeval cp; + long long int sessionDownloadSize; + long long int sessionUploadSize; + */ + struct timeval cp[2]; + long long int sessionDownloadSize[2]; + long long int sessionUploadSize[2]; + int currentCp; + + int downloadSpeed; + int uploadSpeed; + long long int lastElapsed; + void printStatistics(); + int calculateSpeed(long long int sessionSize, long long int elapsed); +protected: + void initStatistics(); + void calculateStatistics(); +public: + TorrentConsoleDownloadEngine(); + ~TorrentConsoleDownloadEngine(); +}; + +#endif // _D_TORRENT_CONSOLE_DOWNLOAD_ENGINE_H_ diff --git a/src/TorrentDownloadEngine.cc b/src/TorrentDownloadEngine.cc new file mode 100644 index 00000000..17f2f301 --- /dev/null +++ b/src/TorrentDownloadEngine.cc @@ -0,0 +1,32 @@ +/* */ +#include "TorrentDownloadEngine.h" + +void TorrentDownloadEngine::onEndOfRun() { + torrentMan->diskWriter->closeFile(); + if(torrentMan->downloadComplete()) { + torrentMan->remove(); + torrentMan->fixFilename(); + } else { + torrentMan->save(); + } +} diff --git a/src/TorrentDownloadEngine.h b/src/TorrentDownloadEngine.h new file mode 100644 index 00000000..fca3daa5 --- /dev/null +++ b/src/TorrentDownloadEngine.h @@ -0,0 +1,38 @@ +/* */ +#ifndef _D_TORRENT_DOWNLOAD_ENGINE_H_ +#define _D_TORRENT_DOWNLOAD_ENGINE_H_ + +#include "DownloadEngine.h" +#include "TorrentMan.h" + +class TorrentDownloadEngine : public DownloadEngine { +protected: + void onEndOfRun(); +public: + TorrentDownloadEngine() {} + virtual ~TorrentDownloadEngine() {} + + TorrentMan* torrentMan; +}; + +#endif // _D_TORRENT_DOWNLOAD_ENGINE_H_ diff --git a/src/TorrentMan.cc b/src/TorrentMan.cc new file mode 100644 index 00000000..2bd95b5f --- /dev/null +++ b/src/TorrentMan.cc @@ -0,0 +1,505 @@ +/* */ +#include "TorrentMan.h" +#include "Dictionary.h" +#include "List.h" +#include "ShaVisitor.h" +#include "Util.h" +#include "MetaFileUtil.h" +#include "DlAbortEx.h" +#include "File.h" +#include "message.h" +#include "PreAllocationDiskWriter.h" +#include +#include +#include + +TorrentMan::TorrentMan():bitfield(NULL), + peerEntryIdCounter(0), cuidCounter(0), + downloadedSize(0), uploadedSize(0), + deltaDownload(0), deltaUpload(0), + multiFileTopDir(NULL), + interval(DEFAULT_ANNOUNCE_INTERVAL), + minInterval(DEFAULT_ANNOUNCE_MIN_INTERVAL), + complete(0), incomplete(0), + connections(0) {} + +TorrentMan::~TorrentMan() { + if(bitfield != NULL) { + delete bitfield; + } + if(multiFileTopDir != NULL) { + delete multiFileTopDir; + } + for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) { + delete *itr; + } +} + +// TODO do not use this method in application code +void TorrentMan::updatePeers(const Peers& peers) { + this->peers = peers; +} + +bool TorrentMan::addPeer(Peer* peer, bool duplicate) { + if(duplicate) { + for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) { + Peer* p = *itr; + if(p->ipaddr == peer->ipaddr && p->port == peer->port && p->error > 0) { + return false; + } + } + } else { + for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) { + Peer* p = *itr; + if(p->ipaddr == peer->ipaddr && p->port == peer->port) { + return false; + } + } + } + ++peerEntryIdCounter; + peer->entryId = peerEntryIdCounter; + peers.push_back(peer); + return true; +} + +/* +void TorrentMan::updatePeer(const Peer& peer) { + for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) { + Peer& p = *itr; + if(p.eid == peer.eid) { + p = peer; + break; + } + } +} +*/ + +bool TorrentMan::isPeerAvailable() const { + return getPeer() != Peer::nullPeer; +} + +int TorrentMan::deleteOldErrorPeers(int maxNum) { + int counter = 0; + for(Peers::iterator itr = peers.begin(); itr != peers.end();) { + Peer* p = *itr; + if(p->error != 0 && p->cuid == 0) { + delete p; + itr = peers.erase(itr); + counter++; + if(maxNum <= counter) { + break; + } + } else { + itr++; + } + } + return counter; +} + +Peer* TorrentMan::getPeer() const { + for(Peers::const_iterator itr = peers.begin(); itr != peers.end(); itr++) { + Peer* p = *itr; + if(p->cuid == 0 && p->error == 0) { + return p; + } + } + return Peer::nullPeer; +} + +bool TorrentMan::isEndGame() const { + return bitfield->countMissingBlock() <= END_GAME_PIECE_NUM; +} + +Piece TorrentMan::getMissingPiece(const unsigned char* peerBitfield, int length) { + int index = -1; + if(isEndGame()) { + index = bitfield->getMissingIndex(peerBitfield, length); + } else { + index = bitfield->getMissingUnusedIndex(peerBitfield, length); + } + if(index == -1) { + return Piece::nullPiece; + } + bitfield->setUseBit(index); + + Piece piece = findUsedPiece(index); + if(Piece::isNull(piece)) { + Piece piece(index, bitfield->getBlockLength(index)); + addUsedPiece(piece); + return piece; + } else { + return piece; + } +} + +int TorrentMan::deleteUsedPiecesByFillRate(int fillRate, int toDelete) { + int deleted = 0; + for(UsedPieces::iterator itr = usedPieces.begin(); + itr != usedPieces.end() && deleted < toDelete;) { + Piece& piece = *itr; + if(!bitfield->isUseBitSet(piece.getIndex()) && + piece.countCompleteBlock() <= piece.countBlock()*(fillRate/100.0)) { + logger->debug("deleting used piece index=%d, fillRate(%%)=%d<=%d", + piece.getIndex(), + (piece.countCompleteBlock()*100)/piece.countBlock(), + fillRate); + itr = usedPieces.erase(itr); + deleted++; + } else { + itr++; + } + } + return deleted; +} + +void TorrentMan::reduceUsedPieces(int max) { + int toDelete = usedPieces.size()-max; + if(toDelete <= 0) { + return; + } + int fillRate = 10; + while(fillRate < 50) { + int deleted = deleteUsedPiecesByFillRate(fillRate, toDelete); + if(deleted == 0) { + break; + } + toDelete -= deleted; + fillRate += 10; + } +} + +void TorrentMan::addUsedPiece(const Piece& piece) { + usedPieces.push_back(piece); +} + +Piece TorrentMan::findUsedPiece(int index) const { + for(UsedPieces::const_iterator itr = usedPieces.begin(); itr != usedPieces.end(); itr++) { + const Piece& piece = *itr; + if(piece.getIndex() == index) { + return piece; + } + } + return Piece::nullPiece; +} + +void TorrentMan::deleteUsedPiece(const Piece& piece) { + if(Piece::isNull(piece)) { + return; + } + for(UsedPieces::iterator itr = usedPieces.begin(); itr != usedPieces.end(); itr++) { + if(itr->getIndex() == piece.getIndex()) { + usedPieces.erase(itr); + break; + } + } +} + +void TorrentMan::completePiece(const Piece& piece) { + if(Piece::isNull(piece)) { + return; + } + bitfield->setBit(piece.getIndex()); + bitfield->unsetUseBit(piece.getIndex()); + addDownloadedSize(piece.getLength()); + deleteUsedPiece(piece); + if(!isEndGame()) { + reduceUsedPieces(100); + } +} + +void TorrentMan::cancelPiece(const Piece& piece) { + if(Piece::isNull(piece)) { + return; + } + bitfield->unsetUseBit(piece.getIndex()); + if(!isEndGame()) { + if(piece.countCompleteBlock() == 0) { + deleteUsedPiece(piece); + } + } +} + +void TorrentMan::updatePiece(const Piece& piece) { + if(Piece::isNull(piece)) { + return; + } + for(UsedPieces::iterator itr = usedPieces.begin(); itr != usedPieces.end(); itr++) { + if(itr->getIndex() == piece.getIndex()) { + *itr = piece; + break; + } + } +} + +void TorrentMan::syncPiece(Piece& piece) { + if(Piece::isNull(piece)) { + return; + } + for(UsedPieces::iterator itr = usedPieces.begin(); itr != usedPieces.end(); itr++) { + if(itr->getIndex() == piece.getIndex()) { + piece = *itr; + return; + } + } + // hasPiece(piece.getIndex()) is true, then set all bit of + // piece.bitfield to 1 + if(hasPiece(piece.getIndex())) { + piece.setAllBlock(); + } +} + +void TorrentMan::initBitfield() { + if(bitfield != NULL) { + delete bitfield; + } + bitfield = new BitfieldMan(pieceLength, totalSize); +} + +void TorrentMan::setBitfield(unsigned char* bitfield, int bitfieldLength) { + if(this->bitfield == NULL) { + initBitfield(); + } + this->bitfield->setBitfield(bitfield, bitfieldLength); +} + +bool TorrentMan::downloadComplete() const { + return bitfield->isAllBitSet(); +} + +void TorrentMan::setup(string metaInfoFile) { + peerId = "-A2****-"; + for(int i = 0; i < 12; i++) { + peerId += Util::itos((int)(((double)10)*random()/(RAND_MAX+1.0))); + } + + uploadedSize = 0; + downloadedSize = 0; + Dictionary* topDic = (Dictionary*)MetaFileUtil::parseMetaFile(metaInfoFile); + const Dictionary* infoDic = (const Dictionary*)topDic->get("info"); + ShaVisitor v; + infoDic->accept(&v); + unsigned char md[20]; + int len; + v.getHash(md, len); + setInfoHash(md); + + Data* topName = (Data*)infoDic->get("name"); + if(topName != NULL) { + name = topName->toString(); + } else { + char* basec = strdup(metaInfoFile.c_str()); + name = string(basename(basec)); + free(basec); + } + + List* files = (List*)infoDic->get("files"); + if(files == NULL) { + // single-file mode; + setFileMode(SINGLE); + Data* length = (Data*)infoDic->get("length"); + totalSize = length->toLLInt(); + } else { + long long int length = 0; + // multi-file mode + setFileMode(MULTI); + multiFileTopDir = new Directory(name); + const MetaList& metaList = files->getList(); + for(MetaList::const_iterator itr = metaList.begin(); itr != metaList.end(); + itr++) { + Dictionary* fileDic = (Dictionary*)(*itr); + Data* lengthData = (Data*)fileDic->get("length"); + //length += strtoll(data->toString().c_str(), NULL, 10); + length += lengthData->toLLInt(); + List* path = (List*)fileDic->get("path"); + const MetaList& paths = path->getList(); + Directory* parentDir = multiFileTopDir; + string filePath = name; + for(int i = 0; i < (int)paths.size()-1; i++) { + Data* subpath = (Data*)paths.at(i); + Directory* dir = new Directory(subpath->toString()); + parentDir->addFile(dir); + parentDir = dir; + filePath.append("/").append(subpath->toString()); + } + Data* lastpath = (Data*)paths.back(); + filePath.append("/").append(lastpath->toString()); + FileEntry fileEntry(filePath, lengthData->toLLInt()); + multiFileEntries.push_back(fileEntry); + } + totalSize = length; + } + announce = ((Data*)topDic->get("announce"))->toString(); + pieceLength = ((Data*)infoDic->get("piece length"))->toInt(); + pieces = totalSize/pieceLength+(totalSize%pieceLength ? 1 : 0); + + Data* piecesHashData = (Data*)infoDic->get("pieces"); + if(piecesHashData->getLen() != pieces*20) { + throw new DlAbortEx("the number of pieces is wrong."); + } + for(int index = 0; index < pieces; index++) { + string hex = Util::toHex((unsigned char*)&piecesHashData->getData()[index*20], 20); + pieceHashes.push_back(hex); + logger->debug("piece #%d, hash:%s", index, hex.c_str()); + } + + initBitfield(); + delete topDic; + + diskWriter = new PreAllocationDiskWriter(totalSize); + if(segmentFileExists()) { + load(); + diskWriter->openExistingFile(getTempFilePath()); + } else { + diskWriter->initAndOpenFile(getTempFilePath()); + } +} + +bool TorrentMan::hasPiece(int index) const { + return bitfield->isBitSet(index); +} + +string TorrentMan::getPieceHash(int index) const { + return pieceHashes.at(index); +} + +string TorrentMan::getFilePath() const { + return (storeDir == "" ? "." : storeDir)+"/"+name; +} + +string TorrentMan::getTempFilePath() const { + return getFilePath()+".a2tmp"; +} + +string TorrentMan::getSegmentFilePath() const { + return getFilePath()+".aria2"; +} + +bool TorrentMan::segmentFileExists() const { + string segFilename = getSegmentFilePath(); + File f(segFilename); + if(f.isFile()) { + logger->info(MSG_SEGMENT_FILE_EXISTS, segFilename.c_str()); + return true; + } else { + logger->info(MSG_SEGMENT_FILE_DOES_NOT_EXIST, segFilename.c_str()); + return false; + } +} + +FILE* TorrentMan::openSegFile(string segFilename, string mode) const { + FILE* segFile = fopen(segFilename.c_str(), mode.c_str()); + if(segFile == NULL) { + throw new DlAbortEx(strerror(errno)); + } + return segFile; +} + +void TorrentMan::load() { + string segFilename = getSegmentFilePath(); + logger->info(MSG_LOADING_SEGMENT_FILE, segFilename.c_str()); + FILE* segFile = openSegFile(segFilename, "r+"); + read(segFile); + fclose(segFile); + logger->info(MSG_LOADED_SEGMENT_FILE); +} + +void TorrentMan::read(FILE* file) { + assert(file != NULL); + unsigned char savedInfoHash[INFO_HASH_LENGTH]; + if(fread(savedInfoHash, INFO_HASH_LENGTH, 1, file) < 1) { + throw new DlAbortEx(strerror(errno)); + } + if(Util::toHex(savedInfoHash, INFO_HASH_LENGTH) != Util::toHex(infoHash, INFO_HASH_LENGTH)) { + throw new DlAbortEx("info hash mismatch"); + } + unsigned char* savedBitfield = new unsigned char[bitfield->getBitfieldLength()]; + try { + if(fread(savedBitfield, bitfield->getBitfieldLength(), 1, file) < 1) { + throw new DlAbortEx(strerror(errno)); + } + setBitfield(savedBitfield, bitfield->getBitfieldLength()); + if(fread(&downloadedSize, sizeof(downloadedSize), 1, file) < 1) { + throw new DlAbortEx(strerror(errno)); + } + if(fread(&uploadedSize, sizeof(uploadedSize), 1, file) < 1) { + throw new DlAbortEx(strerror(errno)); + } + delete savedBitfield; + } catch(Exception* ex) { + delete savedBitfield; + throw; + } +} + +void TorrentMan::save() const { + if(downloadedSize == 0) { + return; + } + string segFilename = getSegmentFilePath(); + logger->info(MSG_SAVING_SEGMENT_FILE, segFilename.c_str()); + FILE* file = openSegFile(segFilename, "w"); + if(fwrite(infoHash, INFO_HASH_LENGTH, 1, file) < 1) { + throw new DlAbortEx(strerror(errno)); + } + if(fwrite(bitfield->getBitfield(), bitfield->getBitfieldLength(), 1, file) < 1) { + throw new DlAbortEx(strerror(errno)); + } + if(fwrite(&downloadedSize, sizeof(downloadedSize), 1, file) < 1) { + throw new DlAbortEx(strerror(errno)); + } + if(fwrite(&uploadedSize, sizeof(uploadedSize), 1, file) < 1) { + throw new DlAbortEx(strerror(errno)); + } + fclose(file); + logger->info(MSG_SAVED_SEGMENT_FILE); +} + +void TorrentMan::remove() const { + if(segmentFileExists()) { + File f(getSegmentFilePath()); + f.remove(); + } +} + +void TorrentMan::fixFilename() const { + if(fileMode == SINGLE) { + renameSingleFile(); + } else { + splitMultiFile(); + } +} + +void TorrentMan::renameSingleFile() const { + rename(getTempFilePath().c_str(), getFilePath().c_str()); +} + +void TorrentMan::splitMultiFile() const { + multiFileTopDir->createDir((storeDir == "" ? "." : storeDir), true); + long long int offset = 0; + for(MultiFileEntries::const_iterator itr = multiFileEntries.begin(); + itr != multiFileEntries.end(); itr++) { + Util::rangedFileCopy(itr->path, getTempFilePath(), offset, itr->length); + offset += itr->length; + } + unlink(getTempFilePath().c_str()); +} diff --git a/src/TorrentMan.h b/src/TorrentMan.h new file mode 100644 index 00000000..3041f3f8 --- /dev/null +++ b/src/TorrentMan.h @@ -0,0 +1,217 @@ +/* */ +#ifndef _D_TORRENT_MAN_H_ +#define _D_TORRENT_MAN_H_ + +#include "Peer.h" +#include "common.h" +#include "Logger.h" +#include "BitfieldMan.h" +#include "DiskWriter.h" +#include "Piece.h" +#include "Directory.h" +#include +#include +#include + +using namespace std; + +#define DEFAULT_BLOCK_LEN 16*1024; +#define MAX_BLOCK_LEN 128*1024; + +#define INFO_HASH_LENGTH 20 + +#define IS_NULL_PIECE(X) (X.index == 0 && X.length == 0) + +#define DEFAULT_ANNOUNCE_INTERVAL 1800 +#define DEFAULT_ANNOUNCE_MIN_INTERVAL 120 +#define MAX_PEERS 55 +#define END_GAME_PIECE_NUM 20 + +class FileEntry { +public: + string path; + long long int length; + FileEntry(string path, long long int length):path(path), length(length) {} + ~FileEntry() {} +}; + +typedef vector Peers; +typedef multimap Haves; +typedef vector MultiFileEntries; +typedef vector UsedPieces; + +class TorrentMan { +private: + Peers peers; + BitfieldMan* bitfield; + unsigned char infoHash[INFO_HASH_LENGTH]; + vector pieceHashes; + int peerEntryIdCounter; + int cuidCounter; + long long int downloadedSize; + long long int uploadedSize; + int deltaDownload; + int deltaUpload; + int fileMode; + string storeDir; + int port; + Haves haves; + UsedPieces usedPieces; + Directory* multiFileTopDir; + MultiFileEntries multiFileEntries; + + FILE* openSegFile(string segFilename, string mode) const; + void read(FILE* file); + + Piece findUsedPiece(int index) const; + void addUsedPiece(const Piece& piece); + void deleteUsedPiece(const Piece& piece); + int deleteUsedPiecesByFillRate(int fillRate, int toDelete); + void reduceUsedPieces(int max); +public: + int pieceLength; + int pieces; + long long int totalSize; + string peerId; + string announce; + string trackerId; + string name; + int interval; + int minInterval; + int complete; + int incomplete; + int connections; +public: + TorrentMan(); + ~TorrentMan(); + + const Logger* logger; + DiskWriter* diskWriter; + + int getNewCuid() { return ++cuidCounter; } + + // TODO do not use this method + void updatePeers(const Peers& peers); + bool addPeer(Peer* peer, bool duplicate = false); + //void updatePeer(const Peer* peer); + const Peers& getPeers() const { return peers; } + Peer* getPeer() const; + bool isPeerAvailable() const; + int deleteOldErrorPeers(int maxNum); + + Piece getMissingPiece(const unsigned char* peerBitfield, int len); + void completePiece(const Piece& piece); + void cancelPiece(const Piece& piece); + void updatePiece(const Piece& piece); + void syncPiece(Piece& piece); + bool hasPiece(int index) const; + void initBitfield(); + bool isEndGame() const; + bool downloadComplete() const; + void setBitfield(unsigned char* bitfield, int len); + const unsigned char* getBitfield() const { + return bitfield->getBitfield(); + } + int getBitfieldLength() const { return bitfield->getBitfieldLength(); } + void setInfoHash(const unsigned char* infoHash) { + memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH); + } + const unsigned char* getInfoHash() const { + return infoHash; + } + + void setup(string metaInfoFile); + + string getPieceHash(int index) const; + + void advertisePiece(int cuid, int index) { + Haves::value_type vt(cuid, index); + haves.insert(vt); + } + + vector getAdvertisedPieceIndexes(int myCuid) const { + vector indexes; + for(Haves::const_iterator itr = haves.begin(); itr != haves.end(); itr++) { + const Haves::value_type& have = *itr; + if(have.first == myCuid) { + continue; + } + indexes.push_back(have.second); + } + return indexes; + } + + void unadvertisePiece(int cuid) { + haves.erase(cuid); + } + + void addDeltaDownload(int size) { deltaDownload += size; } + int getDeltaDownload() const { return deltaDownload; } + void resetDeltaDownload() { deltaDownload = 0; } + + void addDeltaUpload(int size) { deltaUpload += size; } + int getDeltaUpload() const { return deltaUpload; } + void resetDeltaUpload() { deltaUpload = 0; } + + void addDownloadedSize(int size) { downloadedSize += size; } + long long int getDownloadedSize() const { return downloadedSize; } + void setDownloadedSize(long long int size) { downloadedSize = size; } + + void addUploadedSize(int size) { uploadedSize += size; } + long long int getUploadedSize() const { return uploadedSize; } + void setUploadedSize(long long int size) { uploadedSize = size; } + + void setFileMode(int mode) { + fileMode = mode; + } + + int getFileMode() const { + return fileMode; + } + + string getStoreDir() const { return storeDir; } + void setStoreDir(string dir) { storeDir = dir; } + + string getFilePath() const; + string getTempFilePath() const; + string getSegmentFilePath() const; + + bool segmentFileExists() const; + void load(); + void save() const; + void remove() const; + + void renameSingleFile() const; + void splitMultiFile() const; + void fixFilename() const; + + void setPort(int port) { this->port = port; } + int getPort() const { return port; } + + enum FILE_MODE { + SINGLE, + MULTI + }; +}; + +#endif // _D_TORRENT_MAN_H_ diff --git a/src/TrackerDownloadCommand.cc b/src/TrackerDownloadCommand.cc new file mode 100644 index 00000000..85780f7e --- /dev/null +++ b/src/TrackerDownloadCommand.cc @@ -0,0 +1,99 @@ +/* */ +#include "TrackerDownloadCommand.h" +#include "TrackerUpdateCommand.h" +#include "ChunkedEncoding.h" +#include "DlRetryEx.h" +#include "message.h" +#include "MetaFileUtil.h" +#include "DlAbortEx.h" + +TrackerDownloadCommand::TrackerDownloadCommand(int cuid, Request* req, + TorrentDownloadEngine* e, + Socket* s) + :AbstractCommand(cuid, req, e, s), len(0) { + resSize = 256; + res = new char[resSize]; + ChunkedEncoding* ce = new ChunkedEncoding(); + transferEncodings["chunked"] = ce; +} + +TrackerDownloadCommand::~TrackerDownloadCommand() { + delete [] res; + for(map::iterator itr = transferEncodings.begin(); itr != transferEncodings.end(); itr++) { + delete((*itr).second); + } +} + +bool TrackerDownloadCommand::executeInternal(Segment seg) { + TransferEncoding* te = NULL; + if(transferEncoding.size()) { + te = getTransferEncoding(transferEncoding); + assert(te != NULL); + } + int bufSize = 4096; + char buf[bufSize]; + socket->readData(buf, bufSize); + if(te != NULL) { + int infbufSize = 4096; + char infbuf[infbufSize]; + te->inflate(infbuf, infbufSize, buf, bufSize); + if(len+infbufSize >= resSize) { + expandBuffer(len+infbufSize); + } + memcpy(res+len, infbuf, infbufSize); + len += infbufSize; + } else { + if(len+bufSize >= resSize) { + expandBuffer(len+bufSize); + } + memcpy(res+len, buf, bufSize); + len += bufSize; + } + if(e->segmentMan->totalSize != 0 && bufSize == 0) { + throw new DlRetryEx(EX_GOT_EOF); + } + if(te != NULL && te->finished() + || te == NULL && len == e->segmentMan->totalSize + || bufSize == 0) { + if(te != NULL) te->end(); + e->logger->info(MSG_DOWNLOAD_COMPLETED, cuid); + MetaEntry* entry = MetaFileUtil::bdecoding(res, len); + e->commands.push(new TrackerUpdateCommand(cuid, req, (TorrentDownloadEngine*)e, entry)); + return true; + } else { + e->commands.push(this); + return false; + } +} + +TransferEncoding* TrackerDownloadCommand::getTransferEncoding(string name) { + return transferEncodings[name]; +} + +void TrackerDownloadCommand::expandBuffer(int newSize) { + char* newbuf = new char[newSize]; + memcpy(newbuf, res, len); + delete [] res; + res = newbuf; + resSize = newSize; +} diff --git a/src/TrackerDownloadCommand.h b/src/TrackerDownloadCommand.h new file mode 100644 index 00000000..7fed8bf5 --- /dev/null +++ b/src/TrackerDownloadCommand.h @@ -0,0 +1,50 @@ +/* */ +#ifndef _D_TRACKER_DOWNLOAD_COMMAND_H_ +#define _D_TRACKER_DOWNLOAD_COMMAND_H_ + +#include "AbstractCommand.h" +#include "TorrentDownloadEngine.h" +#include "TransferEncoding.h" +#include "Segment.h" +#include + +class TrackerDownloadCommand : public AbstractCommand { +private: + char* res; + int resSize; + int len; + map transferEncodings; + void expandBuffer(int newSize); +protected: + bool executeInternal(Segment segment); +public: + TrackerDownloadCommand(int cuid, Request* req, TorrentDownloadEngine* e, Socket* s); + ~TrackerDownloadCommand(); + + TransferEncoding* getTransferEncoding(string transferEncoding); + + string transferEncoding; +}; + +#endif // _D_TRACKER_DOWNLOAD_COMMAND_H_ + diff --git a/src/TrackerInitCommand.cc b/src/TrackerInitCommand.cc new file mode 100644 index 00000000..66d01b3d --- /dev/null +++ b/src/TrackerInitCommand.cc @@ -0,0 +1,67 @@ +/* */ +#include "TrackerInitCommand.h" +#include "Request.h" +#include "InitiateConnectionCommandFactory.h" +#include "TorrentMan.h" +#include "Util.h" + +TrackerInitCommand::TrackerInitCommand(int cuid, Request* req, TorrentDownloadEngine* e):Command(cuid), req(req), e(e) {} + +TrackerInitCommand::~TrackerInitCommand() {} + +bool TrackerInitCommand::execute() { + if(e->torrentMan->downloadComplete()) { + req->setTrackerEvent(Request::COMPLETED); + } + string event; + switch(req->getTrackerEvent()) { + case Request::STARTED: + event = "started"; + break; + case Request::STOPPED: + event = "stopped"; + break; + case Request::COMPLETED: + event = "completed"; + break; + } + string url = e->torrentMan->announce+"?"+ + "info_hash="+Util::urlencode(e->torrentMan->getInfoHash(), 20)+"&"+ + "peer_id="+e->torrentMan->peerId+"&"+ + "port="+Util::itos(e->torrentMan->getPort())+"&"+ + "uploaded="+Util::llitos(e->torrentMan->getUploadedSize())+"&"+ + "downloaded="+Util::llitos(e->torrentMan->getDownloadedSize())+"&"+ + "left="+Util::llitos(e->torrentMan->totalSize-e->torrentMan->getDownloadedSize())+"&"+ + "compact=1"; + if(!event.empty()) { + url += string("&")+"event="+event; + } + if(!e->torrentMan->trackerId.empty()) { + url += string("&")+"trackerid="+e->torrentMan->trackerId; + } + req->setUrl(url); + Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e); + e->commands.push(command); + return true; +} + diff --git a/src/TrackerInitCommand.h b/src/TrackerInitCommand.h new file mode 100644 index 00000000..cf08c58e --- /dev/null +++ b/src/TrackerInitCommand.h @@ -0,0 +1,40 @@ +/* */ +#ifndef _D_TRACKER_INIT_COMMAND_H_ +#define _D_TRACKER_INIT_COMMAND_H_ + +#include "TorrentDownloadEngine.h" +#include "Request.h" +#include "Command.h" + +class TrackerInitCommand : public Command { +private: + Request* req; + TorrentDownloadEngine* e; +public: + TrackerInitCommand(int cuid, Request* req, TorrentDownloadEngine* e); + ~TrackerInitCommand(); + + bool execute(); +}; + +#endif // _D_TRACKER_INIT_COMMAND_H_ diff --git a/src/TrackerUpdateCommand.cc b/src/TrackerUpdateCommand.cc new file mode 100644 index 00000000..8ef3e0ae --- /dev/null +++ b/src/TrackerUpdateCommand.cc @@ -0,0 +1,126 @@ +/* */ +#include "TrackerUpdateCommand.h" +#include "TrackerInitCommand.h" +#include "PeerInitiateConnectionCommand.h" +#include "PeerListenCommand.h" +#include "SleepCommand.h" +#include "Dictionary.h" +#include "Data.h" +#include "DlAbortEx.h" +#include "message.h" +#include + +TrackerUpdateCommand::TrackerUpdateCommand(int cuid, Request* req, + TorrentDownloadEngine* e, + MetaEntry* trackerResponse) + :Command(cuid), req(req), e(e), trackerResponse(trackerResponse) {} + +TrackerUpdateCommand::~TrackerUpdateCommand() { + delete trackerResponse; +} + +bool TrackerUpdateCommand::execute() { + if(req->getTrackerEvent() == Request::COMPLETED) { + return true; + } + e->torrentMan->deleteOldErrorPeers(25); + + Dictionary* response = (Dictionary*)trackerResponse; + Data* failureReason = (Data*)response->get("failure reason"); + if(failureReason != NULL) { + throw new DlAbortEx("Tracker returned failure reason: %s", failureReason->toString().c_str()); + } + Data* warningMessage = (Data*)response->get("warning message"); + if(warningMessage != NULL) { + e->logger->info(MSG_TRACKER_WARNING_MESSAGE, cuid, warningMessage->toString().c_str()); + } + Data* trackerId = (Data*)response->get("tracker id"); + if(trackerId != NULL) { + e->torrentMan->trackerId = trackerId->toString(); + e->logger->debug("CUID#%d - Tracker ID:%s", cuid, e->torrentMan->trackerId.c_str()); + } + Data* interval = (Data*)response->get("interval"); + if(interval != NULL) { + e->torrentMan->interval = interval->toInt(); + e->logger->debug("CUID#%d - interval:%d", cuid, e->torrentMan->interval); + } + Data* minInterval = (Data*)response->get("min interval"); + if(minInterval != NULL) { + e->torrentMan->minInterval = minInterval->toInt(); + e->logger->debug("CUID#%d - min interval:%d", cuid, e->torrentMan->minInterval); + } + Data* complete = (Data*)response->get("complete"); + if(complete != NULL) { + e->torrentMan->complete = complete->toInt(); + e->logger->debug("CUID#%d - complete:%d", cuid, e->torrentMan->complete); + } + Data* incomplete = (Data*)response->get("incomplete"); + if(incomplete != NULL) { + e->torrentMan->incomplete = incomplete->toInt(); + e->logger->debug("CUID#%d - incomplete:%d", cuid, e->torrentMan->incomplete); + } + Data* peers = (Data*)response->get("peers"); + for(int i = 0; i < peers->getLen(); i += 6) { + unsigned int ipaddr1 = (unsigned char)*(peers->getData()+i); + unsigned int ipaddr2 = (unsigned char)*(peers->getData()+i+1); + unsigned int ipaddr3 = (unsigned char)*(peers->getData()+i+2); + unsigned int ipaddr4 = (unsigned char)*(peers->getData()+i+3); + //unsigned short int nPort = 0; + //memcpy(&nPort, peers->getData()+i+4, 2); + unsigned int port = ntohs(*(unsigned short int*)(peers->getData()+i+4)); + //unsigned int port = ntohs(nPort); + char ipaddr[16]; + + snprintf(ipaddr, sizeof(ipaddr), "%d.%d.%d.%d", + ipaddr1, ipaddr2, ipaddr3, ipaddr4); + Peer* peer = new Peer(ipaddr, port, e->torrentMan->pieceLength, + e->torrentMan->totalSize); + if(e->torrentMan->addPeer(peer)) { + e->logger->debug("CUID#%d - adding peer %s:%d", cuid, + peer->ipaddr.c_str(), peer->port); + } else { + delete peer; + } + } + /* + if(req->getTrackerEvent() == Request::STARTED) { + PeerListenCommand* command = new PeerListenCommand(e->torrentMan->getNewCuid(), e); + e->commands.push(command); + e->logger->debug("CUID#%d - adding listen command", cuid); + } + */ + while(e->torrentMan->isPeerAvailable() && + e->torrentMan->connections < MAX_PEERS) { + Peer* peer = e->torrentMan->getPeer(); + int newCuid = e->torrentMan->getNewCuid(); + peer->cuid = newCuid; + PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e); + e->commands.push(command); + e->logger->debug("CUID#%d - adding new command CUID#%d", cuid, newCuid); + } + req->setTrackerEvent(Request::AUTO); + TrackerInitCommand* command = new TrackerInitCommand(cuid, req, e); + SleepCommand* slpCommand = new SleepCommand(cuid, e, command, e->torrentMan->minInterval); + e->commands.push(slpCommand); + return true; +} diff --git a/src/TrackerUpdateCommand.h b/src/TrackerUpdateCommand.h new file mode 100644 index 00000000..7d68a222 --- /dev/null +++ b/src/TrackerUpdateCommand.h @@ -0,0 +1,42 @@ +/* */ +#ifndef _D_TRACKER_UPDATE_COMMAND_H_ +#define _D_TRACKER_UPDATE_COMMAND_H_ + +#include "Command.h" +#include "Request.h" +#include "TorrentDownloadEngine.h" +#include "MetaEntry.h" + +class TrackerUpdateCommand : public Command { +private: + Request* req; + TorrentDownloadEngine* e; + MetaEntry* trackerResponse; +public: + TrackerUpdateCommand(int cuid, Request* req, TorrentDownloadEngine* e, MetaEntry* trackerResponse); + ~TrackerUpdateCommand(); + + bool execute(); +}; + +#endif // _D_TRACKER_UPDATE_COMMAND_H_ diff --git a/src/Util.cc b/src/Util.cc index 5db1bcec..91c89532 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -20,6 +20,11 @@ */ /* copyright --> */ #include "Util.h" +#include "DlAbortEx.h" +#include +#include +#include +#include string Util::itos(int value, bool comma) { string str = llitos(value, comma); @@ -146,3 +151,70 @@ string Util::replace(string target, string oldstr, string newstr) { return result; } +string Util::urlencode(const unsigned char* target, int len) { + string dest; + for(int i = 0; i < len; i++) { + if(!('0' <= target[i] && target[i] <= '9' || + 'A' <= target[i] && target[i] <= 'Z' || + 'a' <= target[i] && target[i] <= 'z' || + '$' == target[i] || '-' == target[i] || + '_' == target[i] || '.' == target[i] || + '+' == target[i] || '!' == target[i] || + '*' == target[i] || '\'' == target[i] || + '(' == target[i] || ')' == target[i] || + ',' == target[i])) { + char temp[4]; + sprintf(temp, "%%%02x", target[i]); + temp[sizeof(temp)-1] = '\0'; + dest.append(temp); + } else { + dest += target[i]; + } + } + return dest; +} + +string Util::toHex(const unsigned char* src, int len) { + char* temp = new char[len*2+1]; + for(int i = 0; i < len; i++) { + sprintf(temp+i*2, "%02x", src[i]); + } + temp[len*2] = '\0'; + string hex = temp; + delete [] temp; + return hex; +} + +FILE* Util::openFile(string filename, string mode) { + FILE* file = fopen(filename.c_str(), mode.c_str()); + return file; +} + +void Util::rangedFileCopy(string dest, string src, long long int srcOffset, long long int length) { + int destFd; + if((destFd = open(dest.c_str(), O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR)) < 0) { + throw new DlAbortEx(strerror(errno)); + } + int srcFd; + if((srcFd = open(src.c_str(), O_RDONLY, S_IRUSR|S_IWUSR)) < 0) { + throw new DlAbortEx(strerror(errno)); + } + if(lseek(srcFd, srcOffset, SEEK_SET) != srcOffset) { + throw new DlAbortEx(strerror(errno)); + } + int BUF_SIZE = 16*1024; + char buf[BUF_SIZE]; + int x = length/BUF_SIZE+(length%BUF_SIZE ? 1 : 0); + for(int i = 0; i < x; i++) { + int readLength; + if((readLength = read(srcFd, buf, BUF_SIZE)) == -1) { + throw new DlAbortEx(strerror(errno)); + } + if(write(destFd, buf, readLength) == -1) { + throw new DlAbortEx(strerror(errno)); + } + } + close(srcFd); + close(destFd); +} + diff --git a/src/Util.h b/src/Util.h index a208e802..f8e50932 100644 --- a/src/Util.h +++ b/src/Util.h @@ -56,6 +56,15 @@ public: static bool endsWith(string target, string part); static string replace(string target, string oldstr, string newstr); + + static string urlencode(const unsigned char* target, int len); + + static string toHex(const unsigned char* src, int len); + + static FILE* openFile(string filename, string mode); + + static void rangedFileCopy(string destFile, string src, long long int srcOffset, long long int length); + }; #endif // _D_UTIL_H_ diff --git a/src/common.h b/src/common.h index 6b3672ad..1260edf5 100644 --- a/src/common.h +++ b/src/common.h @@ -41,6 +41,8 @@ #define USER_AGENT "aria2" +#define BITFIELD_LEN_FROM_PIECES(X) (X/8+(X%8? 1 : 0)) + using namespace std; #endif // _D_COMMON_H_ diff --git a/src/main.cc b/src/main.cc index c1b280d2..b7ed6347 100644 --- a/src/main.cc +++ b/src/main.cc @@ -21,7 +21,9 @@ /* copyright --> */ #include "HttpInitiateConnectionCommand.h" #include "ConsoleDownloadEngine.h" +#include "TorrentConsoleDownloadEngine.h" #include "SegmentMan.h" +#include "TorrentMan.h" #include "SplitSlowestSegmentSplitter.h" #include "SimpleLogger.h" #include "common.h" @@ -29,8 +31,13 @@ #include "Util.h" #include "InitiateConnectionCommandFactory.h" #include "prefs.h" +#include "TrackerInitCommand.h" +#include "PeerListenCommand.h" +#include "TorrentAutoSaveCommand.h" +#include "SleepCommand.h" #include #include +#include #include #include #include @@ -47,11 +54,20 @@ extern int optind, opterr, optopt; using namespace std; +void printDownloadCompeleteMessage(string filename) { + printf(_("\nThe download was complete. <%s>\n"), filename.c_str()); +} + +void printDownloadAbortMessage() { + printf(_("\nThe download was not complete because of errors. Check the log.\n")); +} + void clearRequest(Request* req) { delete(req); } DownloadEngine* e; +TorrentDownloadEngine* te; void handler(int signal) { cout << _("\nSIGINT signal received.") << endl; @@ -62,6 +78,22 @@ void handler(int signal) { exit(0); } +void torrentHandler(int signal) { + cout << _("\nSIGINT signal received.") << endl; + if(te->torrentMan->diskWriter != NULL) { + te->torrentMan->diskWriter->closeFile(); + } + if(te->torrentMan->downloadComplete()) { + te->torrentMan->remove(); + te->torrentMan->fixFilename(); + printDownloadCompeleteMessage(te->torrentMan->getFilePath()); + } else { + te->torrentMan->save(); + } + + exit(0); +} + void addCommand(int cuid, const char* url, string referer, vector requests) { Request* req = new Request(); req->setReferer(referer); @@ -146,6 +178,11 @@ void showUsage() { cout << _(" --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' or\n" " 'tunnel'.\n" " Default: tunnel") << endl; + cout << _(" --torrent-file=TORRENT_FILE The file path to .torrent file.") << endl; + cout << _(" --follow-torrent=true|false Setting this option to false prevents aria2 to\n" + " enter BitTorrent mode even if the filename of\n" + " downloaded file ends with .torrent.\n" + " Default: true") << endl; cout << _(" -v, --version Print the version number and exit.") << endl; cout << _(" -h, --help Print this message and exit.") << endl; cout << endl; @@ -162,6 +199,8 @@ void showUsage() { cout << " aria2c http://AAA.BBB.CCC/file.zip http://DDD.EEE.FFF/GGG/file.zip" << endl; cout << _(" You can mix up different protocols:") << endl; cout << " aria2c http://AAA.BBB.CCC/file.zip ftp://DDD.EEE.FFF/GGG/file.zip" << endl; + cout << _(" Download a torrent") << endl; + cout << " aria2c -o test.torret http://AAA.BBB.CCC/file.torrent" << endl; cout << endl; printf(_("Reports bugs to %s"), ""); cout << endl; @@ -181,6 +220,8 @@ int main(int argc, char* argv[]) { int split = 1; bool daemonMode = false; string referer; + string torrentFile; + bool followTorrent = true; int c; Option* op = new Option(); @@ -193,6 +234,7 @@ int main(int argc, char* argv[]) { op->put(PREF_FTP_PASSWD, "ARIA2USER@"); op->put(PREF_FTP_TYPE, V_BINARY); op->put(PREF_FTP_VIA_HTTP_PROXY, V_TUNNEL); + op->put(PREF_AUTO_SAVE_INTERVAL, "60"); while(1) { int optIndex = 0; @@ -220,6 +262,8 @@ int main(int argc, char* argv[]) { { "ftp-via-http-proxy", required_argument, &lopt, 12 }, { "min-segment-size", required_argument, &lopt, 13 }, { "http-proxy-method", required_argument, &lopt, 14 }, + { "torrent-file", required_argument, &lopt, 15 }, + { "follow-torrent", required_argument, &lopt, 16 }, { "version", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, { 0, 0, 0, 0 } @@ -332,6 +376,19 @@ int main(int argc, char* argv[]) { exit(1); } break; + case 15: + torrentFile = string(optarg); + break; + case 16: + if(string(optarg) == "on") { + followTorrent = true; + } else if(string(optarg) == "off") { + followTorrent = false; + } else { + cerr << _("follow-torrent must be either 'true' or 'false'.") << endl; + showUsage(); + exit(1); + } } break; } @@ -394,10 +451,12 @@ int main(int argc, char* argv[]) { exit(1); } } - if(optind == argc) { - cerr << _("specify at least one URL") << endl; - showUsage(); - exit(1); + if(torrentFile.empty()) { + if(optind == argc) { + cerr << _("specify at least one URL") << endl; + showUsage(); + exit(1); + } } if(daemonMode) { if(daemon(1, 1) < 0) { @@ -410,6 +469,7 @@ int main(int argc, char* argv[]) { SSL_load_error_strings(); SSL_library_init(); #endif // HAVE_LIBSSL + srandom(time(NULL)); SimpleLogger* logger; if(stdoutLog) { logger = new SimpleLogger(stdout); @@ -420,43 +480,120 @@ int main(int argc, char* argv[]) { } SegmentSplitter* splitter = new SplitSlowestSegmentSplitter(); splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE)); - splitter->logger = logger; - e = new ConsoleDownloadEngine(); - e->logger = logger; - e->option = op; - e->diskWriter = new DefaultDiskWriter(); - e->segmentMan = new SegmentMan(); - e->segmentMan->dir = dir; - e->segmentMan->ufilename = ufilename; - e->segmentMan->logger = logger; - e->segmentMan->option = op; - e->segmentMan->splitter = splitter; - vector requests; - for(int i = 1; optind+i-1 < argc; i++) { - for(int s = 1; s <= split; s++) { + + struct sigaction sigactIgn; + sigactIgn.sa_handler = SIG_IGN; + sigactIgn.sa_flags = 0; + sigemptyset(&sigactIgn.sa_mask); + sigaction(SIGPIPE, &sigactIgn, NULL); + + bool readyToTorrentMode = false; + string downloadedTorrentFile; + if(torrentFile.empty()) { + struct sigaction sigact; + sigact.sa_handler = handler; + sigact.sa_flags = 0; + sigemptyset(&sigact.sa_mask); + sigaction(SIGINT, &sigact, NULL); + + splitter->logger = logger; + e = new ConsoleDownloadEngine(); + e->logger = logger; + e->option = op; + e->diskWriter = new DefaultDiskWriter(); + e->segmentMan = new SegmentMan(); + e->segmentMan->dir = dir; + e->segmentMan->ufilename = ufilename; + e->segmentMan->logger = logger; + e->segmentMan->option = op; + e->segmentMan->splitter = splitter; + + vector requests; + for(int i = 1; optind+i-1 < argc; i++) { + for(int s = 1; s <= split; s++) { addCommand(split*(i-1)+s, argv[optind+i-1], referer, requests); + } + } + e->run(); + + if(e->segmentMan->finished()) { + printDownloadCompeleteMessage(e->segmentMan->getFilePath()); + if(Util::endsWith(e->segmentMan->getFilePath(), ".torrent")) { + downloadedTorrentFile = e->segmentMan->getFilePath(); + readyToTorrentMode = true; + } + } else { + printDownloadAbortMessage(); + } + + for_each(requests.begin(), requests.end(), clearRequest); + requests.clear(); + + delete(e->segmentMan); + delete(e->diskWriter); + delete(e); + } + if(!torrentFile.empty() || followTorrent && readyToTorrentMode) { + try { + op->put(PREF_MAX_TRIES, "0"); + struct sigaction sigact; + sigact.sa_handler = torrentHandler; + sigact.sa_flags = 0; + sigemptyset(&sigact.sa_mask); + sigaction(SIGINT, &sigact, NULL); + Request* req = new Request(); + req->isTorrent = true; + req->setTrackerEvent(Request::STARTED); + te = new TorrentConsoleDownloadEngine(); + te->logger = logger; + te->option = op; + te->diskWriter = new DefaultDiskWriter(); + te->segmentMan = new SegmentMan(); + te->segmentMan->logger = logger; + te->segmentMan->option = op; + te->segmentMan->splitter = splitter; + te->torrentMan = new TorrentMan(); + te->torrentMan->setStoreDir(dir); + te->torrentMan->logger = logger; + te->torrentMan->setup(torrentFile.empty() ? + downloadedTorrentFile : torrentFile); + + PeerListenCommand* listenCommand = + new PeerListenCommand(te->torrentMan->getNewCuid(), te); + int port = listenCommand->bindPort(6881, 6999); + if(port == -1) { + printf("an error occurred while binding port.\n"); + exit(1); + } + te->torrentMan->setPort(port); + te->commands.push(listenCommand); + te->commands.push(new TrackerInitCommand(te->torrentMan->getNewCuid(), + req, te)); + int autoSaveCommandCuid = te->torrentMan->getNewCuid(); + te->commands.push(new SleepCommand(autoSaveCommandCuid, te, + new TorrentAutoSaveCommand(autoSaveCommandCuid, te, op->getAsInt(PREF_AUTO_SAVE_INTERVAL)), + op->getAsInt(PREF_AUTO_SAVE_INTERVAL))); + te->run(); + + if(te->torrentMan->downloadComplete()) { + printDownloadCompeleteMessage(te->torrentMan->getFilePath()); + } else { + printDownloadAbortMessage(); + } + + delete(te->segmentMan); + delete(te->torrentMan); + delete(te); + } catch(Exception* ex) { + cerr << ex->getMsg() << endl; + delete ex; + exit(1); } } - struct sigaction sigact; - sigact.sa_handler = handler; - sigact.sa_flags = 0; - sigemptyset(&sigact.sa_mask); - sigaction(SIGINT, &sigact, NULL); - e->run(); - - if(e->segmentMan->finished()) { - printf(_("\nThe download was complete. <%s>\n"), e->segmentMan->getFilePath().c_str()); - } else { - printf(_("\nThe download was not complete because of errors. Check the log.\n")); - } - - for_each(requests.begin(), requests.end(), clearRequest); - requests.clear(); delete(logger); - delete(e->segmentMan); - delete(e->option); - delete(e->diskWriter); - delete(e); + delete(op); + delete(splitter); + return 0; } diff --git a/src/message.h b/src/message.h index 16596b0b..c38b2adc 100644 --- a/src/message.h +++ b/src/message.h @@ -35,6 +35,15 @@ #define MSG_RESTARTING_DOWNLOAD _("CUID#%d - Restarting the download.") #define MSG_MAX_TRY _("CUID#%d - %d times attempted, but no success. Download aborted.") #define MSG_UNREGISTER_CUID _("CUID#%d - Unregistering cuid from segmentManager.") +#define MSG_SEND_PEER_MESSAGE "CUID#%d - To: %s:%d %s" +#define MSG_SEND_PEER_MESSAGE_WITH_INDEX "CUID#%d - To: %s:%d %s index=%d" +#define MSG_SEND_PEER_MESSAGE_WITH_BITFIELD "CUID#%d - To: %s:%d %s %s" +#define MSG_SEND_PEER_MESSAGE_WITH_INDEX_BEGIN_LENGTH "CUID#%d - To: %s:%d %s index=%d, begin=%d, length=%d" +#define MSG_RECEIVE_PEER_MESSAGE "CUID#%d - From: %s:%d %s" +#define MSG_GOT_NEW_PIECE "CUID#%d - we got new piece. index=%d" +#define MSG_GOT_WRONG_PIECE "CUID#%d - we got wrong piece. index=%d" + +#define MSG_TRACKER_WARNING_MESSAGE "CUID#%d - Tracker returned warning message: %s" #define MSG_SEGMENT_FILE_EXISTS _("The segment file %s exists.") #define MSG_SEGMENT_FILE_DOES_NOT_EXIST _("The segment file %s does not exist.") @@ -59,5 +68,6 @@ #define EX_SSL_INIT_FAILURE _("SSL initialization failed.") #define EX_SIZE_MISMATCH _("Size mismatch %lld != %lld") #define EX_GOT_EOF _("Got EOF from the server.") - +#define EX_EOF_FROM_PEER "Got EOF from peer." +#define EX_MULFORMED_META_INFO "Mulformed meta info." #endif // _D_MESSAGE_H_ diff --git a/src/prefs.h b/src/prefs.h index 8127bb09..140661c9 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -41,6 +41,8 @@ #define PREF_MAX_TRIES "max_try" // values: 1*digit #define PREF_MIN_SEGMENT_SIZE "min_segment_size" +// values: 1*digit +#define PREF_AUTO_SAVE_INTERVAL "auto_save_interval" /** * FTP related preferences diff --git a/test/BitfieldManTest.cc b/test/BitfieldManTest.cc new file mode 100644 index 00000000..018b4e83 --- /dev/null +++ b/test/BitfieldManTest.cc @@ -0,0 +1,76 @@ +#include "BitfieldMan.h" +#include +#include + +using namespace std; + +class BitfieldManTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(BitfieldManTest); + CPPUNIT_TEST(testGetBlockSize); + CPPUNIT_TEST(testGetFirstMissingUnusedIndex); + CPPUNIT_TEST(testIsAllBitSet); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() { + } + + void testGetBlockSize(); + void testGetFirstMissingUnusedIndex(); + void testIsAllBitSet(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION( BitfieldManTest ); + +void BitfieldManTest::testGetBlockSize() { + BitfieldMan bt1(1024, 1024*10); + CPPUNIT_ASSERT_EQUAL(1024, bt1.getBlockSize(9)); + + BitfieldMan bt2(1024, 1024*10+1); + CPPUNIT_ASSERT_EQUAL(1024, bt2.getBlockSize(9)); + CPPUNIT_ASSERT_EQUAL(1, bt2.getBlockSize(10)); + CPPUNIT_ASSERT_EQUAL(0, bt2.getBlockSize(11)); +} + +void BitfieldManTest::testGetFirstMissingUnusedIndex() { + BitfieldMan bt1(1024, 1024*10); + unsigned char bitfield[2]; + memset(bitfield, 0xff, sizeof(bitfield)); + + CPPUNIT_ASSERT_EQUAL(0, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield))); + CPPUNIT_ASSERT(bt1.setUseBit(0)); + CPPUNIT_ASSERT_EQUAL(1, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield))); + CPPUNIT_ASSERT(bt1.unsetUseBit(0)); + CPPUNIT_ASSERT_EQUAL(0, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield))); + CPPUNIT_ASSERT(bt1.setBit(0)); + CPPUNIT_ASSERT_EQUAL(1, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield))); + + for(int i = 0; i < 8; i++) { + CPPUNIT_ASSERT(bt1.setBit(i)); + } + CPPUNIT_ASSERT_EQUAL(8, bt1.getFirstMissingUnusedIndex(bitfield, sizeof(bitfield))); + + CPPUNIT_ASSERT_EQUAL(8, bt1.getFirstMissingUnusedIndex()); + CPPUNIT_ASSERT(bt1.setUseBit(8)); + CPPUNIT_ASSERT_EQUAL(9, bt1.getFirstMissingUnusedIndex()); +} + +void BitfieldManTest::testIsAllBitSet() { + BitfieldMan bt1(1024, 1024*10); + CPPUNIT_ASSERT(!bt1.isAllBitSet()); + bt1.setBit(1); + CPPUNIT_ASSERT(!bt1.isAllBitSet()); + + for(int i = 0; i < 8; i++) { + CPPUNIT_ASSERT(bt1.setBit(i)); + } + CPPUNIT_ASSERT(!bt1.isAllBitSet()); + + for(int i = 0; i < bt1.getBlocks(); i++) { + CPPUNIT_ASSERT(bt1.setBit(i)); + } + CPPUNIT_ASSERT(bt1.isAllBitSet()); +} diff --git a/test/DataTest.cc b/test/DataTest.cc new file mode 100644 index 00000000..da678977 --- /dev/null +++ b/test/DataTest.cc @@ -0,0 +1,70 @@ +#include "Data.h" +#include +#include + +using namespace std; + +class DataTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(DataTest); + CPPUNIT_TEST(testToString); + CPPUNIT_TEST(testGetData); + CPPUNIT_TEST(testToInt); + CPPUNIT_TEST(testToLLInt); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() { + } + + void testToString(); + void testGetData(); + void testToInt(); + void testToLLInt(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION( DataTest ); + +void DataTest::testToString() { + Data data("aria2", 5); + CPPUNIT_ASSERT_EQUAL(string("aria2"), data.toString()); + + Data null(NULL, 0); + CPPUNIT_ASSERT_EQUAL(string(""), null.toString()); +} + +void DataTest::testGetData() { + Data data("aria2", 5); + int len; + CPPUNIT_ASSERT_EQUAL(0, memcmp("aria2", data.getData(), 5)); + CPPUNIT_ASSERT_EQUAL(5, data.getLen()); + + Data null(NULL, 0); + CPPUNIT_ASSERT_EQUAL((const char*)NULL, null.getData()); + CPPUNIT_ASSERT_EQUAL(0, null.getLen()); + +} + +void DataTest::testToInt() { + Data data("1000", 4); + CPPUNIT_ASSERT_EQUAL(1000, data.toInt()); + + Data null(NULL, 0); + CPPUNIT_ASSERT_EQUAL(0, null.toInt()); + + Data alpha("abc", 3); + CPPUNIT_ASSERT_EQUAL(0, alpha.toInt()); +} + +void DataTest::testToLLInt() { + Data data("1000", 4); + CPPUNIT_ASSERT_EQUAL(1000, (int)data.toLLInt()); + + Data null(NULL, 0); + CPPUNIT_ASSERT_EQUAL(0, (int)null.toLLInt()); + + Data alpha("abc", 3); + CPPUNIT_ASSERT_EQUAL(0, (int)alpha.toLLInt()); +} diff --git a/test/DefaultDiskWriterTest.cc b/test/DefaultDiskWriterTest.cc new file mode 100644 index 00000000..dc939918 --- /dev/null +++ b/test/DefaultDiskWriterTest.cc @@ -0,0 +1,35 @@ +#include "DefaultDiskWriter.h" +#include +#include + +using namespace std; + +class DefaultDiskWriterTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(DefaultDiskWriterTest); + CPPUNIT_TEST(testSha1Sum); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() { + } + + void testSha1Sum(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION( DefaultDiskWriterTest ); + +void DefaultDiskWriterTest::testSha1Sum() { + DefaultDiskWriter dw; + dw.openExistingFile("4096chunk.txt"); + + CPPUNIT_ASSERT_EQUAL(string("608cabc0f2fa18c260cafd974516865c772363d5"), + dw.sha1Sum(0, 4096)); + + CPPUNIT_ASSERT_EQUAL(string("7a4a9ae537ebbbb826b1060e704490ad0f365ead"), + dw.sha1Sum(5, 100)); + + dw.closeFile(); +} diff --git a/test/DictionaryTest.cc b/test/DictionaryTest.cc new file mode 100644 index 00000000..95c5b418 --- /dev/null +++ b/test/DictionaryTest.cc @@ -0,0 +1,35 @@ +#include "Dictionary.h" +#include "Data.h" +#include +#include + +using namespace std; + +class DictionaryTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(DictionaryTest); + CPPUNIT_TEST(testGet); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() { + } + + void testGet(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION( DictionaryTest ); + +void DictionaryTest::testGet() { + Dictionary d; + Data* data1 = new Data("aria2", 5); + d.put("app_name", data1); + Data* data2 = new Data("linux", 5); + d.put("platform", data2); + Data* dataGot = (Data*)d.get("app_name"); + CPPUNIT_ASSERT(dataGot != NULL); + CPPUNIT_ASSERT_EQUAL(string("aria2"), dataGot->toString()); +} + diff --git a/test/FileTest.cc b/test/FileTest.cc index 71576e2e..a31f824a 100644 --- a/test/FileTest.cc +++ b/test/FileTest.cc @@ -14,6 +14,7 @@ class FileTest:public CppUnit::TestFixture { CPPUNIT_TEST(testIsFile); CPPUNIT_TEST(testIsDir); CPPUNIT_TEST(testRemove); + CPPUNIT_TEST(testSize); CPPUNIT_TEST_SUITE_END(); private: @@ -25,6 +26,7 @@ public: void testIsFile(); void testIsDir(); void testRemove(); + void testSize(); }; @@ -86,3 +88,8 @@ void FileTest::testRemove() { // delete the directory again CPPUNIT_ASSERT(!d.remove()); } + +void FileTest::testSize() { + File f("4096chunk.txt"); + CPPUNIT_ASSERT_EQUAL(4096, (int)f.size()); +} diff --git a/test/ListTest.cc b/test/ListTest.cc new file mode 100644 index 00000000..8652c383 --- /dev/null +++ b/test/ListTest.cc @@ -0,0 +1,33 @@ +#include "List.h" +#include "Data.h" +#include +#include + +using namespace std; + +class ListTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(ListTest); + CPPUNIT_TEST(testAdd); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() { + } + + void testAdd(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION( ListTest ); + +void ListTest::testAdd() { + List l; + Data* data1 = new Data("usr", 3); + l.add(data1); + Data* data2 = new Data("local", 5); + l.add(data2); + CPPUNIT_ASSERT_EQUAL(2, (int)l.getList().size()); +} + diff --git a/test/Makefile.am b/test/Makefile.am index 72bbd507..60b7a83a 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -7,7 +7,16 @@ aria2c_SOURCES = AllTest.cc\ OptionTest.cc\ Base64Test.cc\ UtilTest.cc\ - CookieBoxTest.cc + CookieBoxTest.cc\ + DataTest.cc\ + DictionaryTest.cc\ + ListTest.cc\ + MetaFileUtilTest.cc\ + ShaVisitorTest.cc\ + TorrentManTest.cc\ + PeerMessageUtilTest.cc\ + BitfieldManTest.cc\ + DefaultDiskWriterTest.cc aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64 aria2c_LDFLAGS = ${CPPUNIT_LIBS} aria2c_LDADD = ../src/libaria2c.a \ No newline at end of file diff --git a/test/Makefile.in b/test/Makefile.in index 9b2cfe3b..25bebb08 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -59,7 +59,14 @@ am_aria2c_OBJECTS = aria2c-AllTest.$(OBJEXT) \ aria2c-RequestTest.$(OBJEXT) \ aria2c-ChunkedEncodingTest.$(OBJEXT) aria2c-FileTest.$(OBJEXT) \ aria2c-OptionTest.$(OBJEXT) aria2c-Base64Test.$(OBJEXT) \ - aria2c-UtilTest.$(OBJEXT) aria2c-CookieBoxTest.$(OBJEXT) + aria2c-UtilTest.$(OBJEXT) aria2c-CookieBoxTest.$(OBJEXT) \ + aria2c-DataTest.$(OBJEXT) aria2c-DictionaryTest.$(OBJEXT) \ + aria2c-ListTest.$(OBJEXT) aria2c-MetaFileUtilTest.$(OBJEXT) \ + aria2c-ShaVisitorTest.$(OBJEXT) \ + aria2c-TorrentManTest.$(OBJEXT) \ + aria2c-PeerMessageUtilTest.$(OBJEXT) \ + aria2c-BitfieldManTest.$(OBJEXT) \ + aria2c-DefaultDiskWriterTest.$(OBJEXT) aria2c_OBJECTS = $(am_aria2c_OBJECTS) aria2c_DEPENDENCIES = ../src/libaria2c.a DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) @@ -197,7 +204,16 @@ aria2c_SOURCES = AllTest.cc\ OptionTest.cc\ Base64Test.cc\ UtilTest.cc\ - CookieBoxTest.cc + CookieBoxTest.cc\ + DataTest.cc\ + DictionaryTest.cc\ + ListTest.cc\ + MetaFileUtilTest.cc\ + ShaVisitorTest.cc\ + TorrentManTest.cc\ + PeerMessageUtilTest.cc\ + BitfieldManTest.cc\ + DefaultDiskWriterTest.cc aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64 aria2c_LDFLAGS = ${CPPUNIT_LIBS} @@ -250,11 +266,20 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-AllTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-Base64Test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-BitfieldManTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-ChunkedEncodingTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-CookieBoxTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-DataTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-DefaultDiskWriterTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-DictionaryTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-FileTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-ListTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-MetaFileUtilTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-OptionTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-PeerMessageUtilTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-RequestTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-ShaVisitorTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-TorrentManTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aria2c-UtilTest.Po@am__quote@ .cc.o: @@ -382,6 +407,132 @@ aria2c-CookieBoxTest.obj: CookieBoxTest.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='CookieBoxTest.cc' object='aria2c-CookieBoxTest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-CookieBoxTest.obj `if test -f 'CookieBoxTest.cc'; then $(CYGPATH_W) 'CookieBoxTest.cc'; else $(CYGPATH_W) '$(srcdir)/CookieBoxTest.cc'; fi` + +aria2c-DataTest.o: DataTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-DataTest.o -MD -MP -MF "$(DEPDIR)/aria2c-DataTest.Tpo" -c -o aria2c-DataTest.o `test -f 'DataTest.cc' || echo '$(srcdir)/'`DataTest.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-DataTest.Tpo" "$(DEPDIR)/aria2c-DataTest.Po"; else rm -f "$(DEPDIR)/aria2c-DataTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DataTest.cc' object='aria2c-DataTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-DataTest.o `test -f 'DataTest.cc' || echo '$(srcdir)/'`DataTest.cc + +aria2c-DataTest.obj: DataTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-DataTest.obj -MD -MP -MF "$(DEPDIR)/aria2c-DataTest.Tpo" -c -o aria2c-DataTest.obj `if test -f 'DataTest.cc'; then $(CYGPATH_W) 'DataTest.cc'; else $(CYGPATH_W) '$(srcdir)/DataTest.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-DataTest.Tpo" "$(DEPDIR)/aria2c-DataTest.Po"; else rm -f "$(DEPDIR)/aria2c-DataTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DataTest.cc' object='aria2c-DataTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-DataTest.obj `if test -f 'DataTest.cc'; then $(CYGPATH_W) 'DataTest.cc'; else $(CYGPATH_W) '$(srcdir)/DataTest.cc'; fi` + +aria2c-DictionaryTest.o: DictionaryTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-DictionaryTest.o -MD -MP -MF "$(DEPDIR)/aria2c-DictionaryTest.Tpo" -c -o aria2c-DictionaryTest.o `test -f 'DictionaryTest.cc' || echo '$(srcdir)/'`DictionaryTest.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-DictionaryTest.Tpo" "$(DEPDIR)/aria2c-DictionaryTest.Po"; else rm -f "$(DEPDIR)/aria2c-DictionaryTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DictionaryTest.cc' object='aria2c-DictionaryTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-DictionaryTest.o `test -f 'DictionaryTest.cc' || echo '$(srcdir)/'`DictionaryTest.cc + +aria2c-DictionaryTest.obj: DictionaryTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-DictionaryTest.obj -MD -MP -MF "$(DEPDIR)/aria2c-DictionaryTest.Tpo" -c -o aria2c-DictionaryTest.obj `if test -f 'DictionaryTest.cc'; then $(CYGPATH_W) 'DictionaryTest.cc'; else $(CYGPATH_W) '$(srcdir)/DictionaryTest.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-DictionaryTest.Tpo" "$(DEPDIR)/aria2c-DictionaryTest.Po"; else rm -f "$(DEPDIR)/aria2c-DictionaryTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DictionaryTest.cc' object='aria2c-DictionaryTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-DictionaryTest.obj `if test -f 'DictionaryTest.cc'; then $(CYGPATH_W) 'DictionaryTest.cc'; else $(CYGPATH_W) '$(srcdir)/DictionaryTest.cc'; fi` + +aria2c-ListTest.o: ListTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-ListTest.o -MD -MP -MF "$(DEPDIR)/aria2c-ListTest.Tpo" -c -o aria2c-ListTest.o `test -f 'ListTest.cc' || echo '$(srcdir)/'`ListTest.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-ListTest.Tpo" "$(DEPDIR)/aria2c-ListTest.Po"; else rm -f "$(DEPDIR)/aria2c-ListTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ListTest.cc' object='aria2c-ListTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-ListTest.o `test -f 'ListTest.cc' || echo '$(srcdir)/'`ListTest.cc + +aria2c-ListTest.obj: ListTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-ListTest.obj -MD -MP -MF "$(DEPDIR)/aria2c-ListTest.Tpo" -c -o aria2c-ListTest.obj `if test -f 'ListTest.cc'; then $(CYGPATH_W) 'ListTest.cc'; else $(CYGPATH_W) '$(srcdir)/ListTest.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-ListTest.Tpo" "$(DEPDIR)/aria2c-ListTest.Po"; else rm -f "$(DEPDIR)/aria2c-ListTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ListTest.cc' object='aria2c-ListTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-ListTest.obj `if test -f 'ListTest.cc'; then $(CYGPATH_W) 'ListTest.cc'; else $(CYGPATH_W) '$(srcdir)/ListTest.cc'; fi` + +aria2c-MetaFileUtilTest.o: MetaFileUtilTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-MetaFileUtilTest.o -MD -MP -MF "$(DEPDIR)/aria2c-MetaFileUtilTest.Tpo" -c -o aria2c-MetaFileUtilTest.o `test -f 'MetaFileUtilTest.cc' || echo '$(srcdir)/'`MetaFileUtilTest.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-MetaFileUtilTest.Tpo" "$(DEPDIR)/aria2c-MetaFileUtilTest.Po"; else rm -f "$(DEPDIR)/aria2c-MetaFileUtilTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MetaFileUtilTest.cc' object='aria2c-MetaFileUtilTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-MetaFileUtilTest.o `test -f 'MetaFileUtilTest.cc' || echo '$(srcdir)/'`MetaFileUtilTest.cc + +aria2c-MetaFileUtilTest.obj: MetaFileUtilTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-MetaFileUtilTest.obj -MD -MP -MF "$(DEPDIR)/aria2c-MetaFileUtilTest.Tpo" -c -o aria2c-MetaFileUtilTest.obj `if test -f 'MetaFileUtilTest.cc'; then $(CYGPATH_W) 'MetaFileUtilTest.cc'; else $(CYGPATH_W) '$(srcdir)/MetaFileUtilTest.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-MetaFileUtilTest.Tpo" "$(DEPDIR)/aria2c-MetaFileUtilTest.Po"; else rm -f "$(DEPDIR)/aria2c-MetaFileUtilTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MetaFileUtilTest.cc' object='aria2c-MetaFileUtilTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-MetaFileUtilTest.obj `if test -f 'MetaFileUtilTest.cc'; then $(CYGPATH_W) 'MetaFileUtilTest.cc'; else $(CYGPATH_W) '$(srcdir)/MetaFileUtilTest.cc'; fi` + +aria2c-ShaVisitorTest.o: ShaVisitorTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-ShaVisitorTest.o -MD -MP -MF "$(DEPDIR)/aria2c-ShaVisitorTest.Tpo" -c -o aria2c-ShaVisitorTest.o `test -f 'ShaVisitorTest.cc' || echo '$(srcdir)/'`ShaVisitorTest.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-ShaVisitorTest.Tpo" "$(DEPDIR)/aria2c-ShaVisitorTest.Po"; else rm -f "$(DEPDIR)/aria2c-ShaVisitorTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ShaVisitorTest.cc' object='aria2c-ShaVisitorTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-ShaVisitorTest.o `test -f 'ShaVisitorTest.cc' || echo '$(srcdir)/'`ShaVisitorTest.cc + +aria2c-ShaVisitorTest.obj: ShaVisitorTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-ShaVisitorTest.obj -MD -MP -MF "$(DEPDIR)/aria2c-ShaVisitorTest.Tpo" -c -o aria2c-ShaVisitorTest.obj `if test -f 'ShaVisitorTest.cc'; then $(CYGPATH_W) 'ShaVisitorTest.cc'; else $(CYGPATH_W) '$(srcdir)/ShaVisitorTest.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-ShaVisitorTest.Tpo" "$(DEPDIR)/aria2c-ShaVisitorTest.Po"; else rm -f "$(DEPDIR)/aria2c-ShaVisitorTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ShaVisitorTest.cc' object='aria2c-ShaVisitorTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-ShaVisitorTest.obj `if test -f 'ShaVisitorTest.cc'; then $(CYGPATH_W) 'ShaVisitorTest.cc'; else $(CYGPATH_W) '$(srcdir)/ShaVisitorTest.cc'; fi` + +aria2c-TorrentManTest.o: TorrentManTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-TorrentManTest.o -MD -MP -MF "$(DEPDIR)/aria2c-TorrentManTest.Tpo" -c -o aria2c-TorrentManTest.o `test -f 'TorrentManTest.cc' || echo '$(srcdir)/'`TorrentManTest.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-TorrentManTest.Tpo" "$(DEPDIR)/aria2c-TorrentManTest.Po"; else rm -f "$(DEPDIR)/aria2c-TorrentManTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentManTest.cc' object='aria2c-TorrentManTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-TorrentManTest.o `test -f 'TorrentManTest.cc' || echo '$(srcdir)/'`TorrentManTest.cc + +aria2c-TorrentManTest.obj: TorrentManTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-TorrentManTest.obj -MD -MP -MF "$(DEPDIR)/aria2c-TorrentManTest.Tpo" -c -o aria2c-TorrentManTest.obj `if test -f 'TorrentManTest.cc'; then $(CYGPATH_W) 'TorrentManTest.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentManTest.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-TorrentManTest.Tpo" "$(DEPDIR)/aria2c-TorrentManTest.Po"; else rm -f "$(DEPDIR)/aria2c-TorrentManTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TorrentManTest.cc' object='aria2c-TorrentManTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-TorrentManTest.obj `if test -f 'TorrentManTest.cc'; then $(CYGPATH_W) 'TorrentManTest.cc'; else $(CYGPATH_W) '$(srcdir)/TorrentManTest.cc'; fi` + +aria2c-PeerMessageUtilTest.o: PeerMessageUtilTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-PeerMessageUtilTest.o -MD -MP -MF "$(DEPDIR)/aria2c-PeerMessageUtilTest.Tpo" -c -o aria2c-PeerMessageUtilTest.o `test -f 'PeerMessageUtilTest.cc' || echo '$(srcdir)/'`PeerMessageUtilTest.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-PeerMessageUtilTest.Tpo" "$(DEPDIR)/aria2c-PeerMessageUtilTest.Po"; else rm -f "$(DEPDIR)/aria2c-PeerMessageUtilTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerMessageUtilTest.cc' object='aria2c-PeerMessageUtilTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-PeerMessageUtilTest.o `test -f 'PeerMessageUtilTest.cc' || echo '$(srcdir)/'`PeerMessageUtilTest.cc + +aria2c-PeerMessageUtilTest.obj: PeerMessageUtilTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-PeerMessageUtilTest.obj -MD -MP -MF "$(DEPDIR)/aria2c-PeerMessageUtilTest.Tpo" -c -o aria2c-PeerMessageUtilTest.obj `if test -f 'PeerMessageUtilTest.cc'; then $(CYGPATH_W) 'PeerMessageUtilTest.cc'; else $(CYGPATH_W) '$(srcdir)/PeerMessageUtilTest.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-PeerMessageUtilTest.Tpo" "$(DEPDIR)/aria2c-PeerMessageUtilTest.Po"; else rm -f "$(DEPDIR)/aria2c-PeerMessageUtilTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PeerMessageUtilTest.cc' object='aria2c-PeerMessageUtilTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-PeerMessageUtilTest.obj `if test -f 'PeerMessageUtilTest.cc'; then $(CYGPATH_W) 'PeerMessageUtilTest.cc'; else $(CYGPATH_W) '$(srcdir)/PeerMessageUtilTest.cc'; fi` + +aria2c-BitfieldManTest.o: BitfieldManTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-BitfieldManTest.o -MD -MP -MF "$(DEPDIR)/aria2c-BitfieldManTest.Tpo" -c -o aria2c-BitfieldManTest.o `test -f 'BitfieldManTest.cc' || echo '$(srcdir)/'`BitfieldManTest.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-BitfieldManTest.Tpo" "$(DEPDIR)/aria2c-BitfieldManTest.Po"; else rm -f "$(DEPDIR)/aria2c-BitfieldManTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BitfieldManTest.cc' object='aria2c-BitfieldManTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-BitfieldManTest.o `test -f 'BitfieldManTest.cc' || echo '$(srcdir)/'`BitfieldManTest.cc + +aria2c-BitfieldManTest.obj: BitfieldManTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-BitfieldManTest.obj -MD -MP -MF "$(DEPDIR)/aria2c-BitfieldManTest.Tpo" -c -o aria2c-BitfieldManTest.obj `if test -f 'BitfieldManTest.cc'; then $(CYGPATH_W) 'BitfieldManTest.cc'; else $(CYGPATH_W) '$(srcdir)/BitfieldManTest.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-BitfieldManTest.Tpo" "$(DEPDIR)/aria2c-BitfieldManTest.Po"; else rm -f "$(DEPDIR)/aria2c-BitfieldManTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='BitfieldManTest.cc' object='aria2c-BitfieldManTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-BitfieldManTest.obj `if test -f 'BitfieldManTest.cc'; then $(CYGPATH_W) 'BitfieldManTest.cc'; else $(CYGPATH_W) '$(srcdir)/BitfieldManTest.cc'; fi` + +aria2c-DefaultDiskWriterTest.o: DefaultDiskWriterTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-DefaultDiskWriterTest.o -MD -MP -MF "$(DEPDIR)/aria2c-DefaultDiskWriterTest.Tpo" -c -o aria2c-DefaultDiskWriterTest.o `test -f 'DefaultDiskWriterTest.cc' || echo '$(srcdir)/'`DefaultDiskWriterTest.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-DefaultDiskWriterTest.Tpo" "$(DEPDIR)/aria2c-DefaultDiskWriterTest.Po"; else rm -f "$(DEPDIR)/aria2c-DefaultDiskWriterTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DefaultDiskWriterTest.cc' object='aria2c-DefaultDiskWriterTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-DefaultDiskWriterTest.o `test -f 'DefaultDiskWriterTest.cc' || echo '$(srcdir)/'`DefaultDiskWriterTest.cc + +aria2c-DefaultDiskWriterTest.obj: DefaultDiskWriterTest.cc +@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -MT aria2c-DefaultDiskWriterTest.obj -MD -MP -MF "$(DEPDIR)/aria2c-DefaultDiskWriterTest.Tpo" -c -o aria2c-DefaultDiskWriterTest.obj `if test -f 'DefaultDiskWriterTest.cc'; then $(CYGPATH_W) 'DefaultDiskWriterTest.cc'; else $(CYGPATH_W) '$(srcdir)/DefaultDiskWriterTest.cc'; fi`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/aria2c-DefaultDiskWriterTest.Tpo" "$(DEPDIR)/aria2c-DefaultDiskWriterTest.Po"; else rm -f "$(DEPDIR)/aria2c-DefaultDiskWriterTest.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DefaultDiskWriterTest.cc' object='aria2c-DefaultDiskWriterTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(aria2c_CXXFLAGS) $(CXXFLAGS) -c -o aria2c-DefaultDiskWriterTest.obj `if test -f 'DefaultDiskWriterTest.cc'; then $(CYGPATH_W) 'DefaultDiskWriterTest.cc'; else $(CYGPATH_W) '$(srcdir)/DefaultDiskWriterTest.cc'; fi` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) diff --git a/test/MetaFileUtilTest.cc b/test/MetaFileUtilTest.cc new file mode 100644 index 00000000..aa53aa74 --- /dev/null +++ b/test/MetaFileUtilTest.cc @@ -0,0 +1,77 @@ +#include "MetaFileUtil.h" +#include "Data.h" +#include "Dictionary.h" +#include "List.h" +#include "DlAbortEx.h" +#include +#include + +using namespace std; + +class MetaFileUtilTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(MetaFileUtilTest); + CPPUNIT_TEST(testParseMetaFile); + CPPUNIT_TEST(testBdecoding); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() { + } + + void testParseMetaFile(); + void testBdecoding(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION( MetaFileUtilTest ); + +void MetaFileUtilTest::testParseMetaFile() { + MetaEntry* entry = MetaFileUtil::parseMetaFile("test.torrent"); + Dictionary* d = dynamic_cast(entry); + CPPUNIT_ASSERT(d != NULL); +} + +void MetaFileUtilTest::testBdecoding() { + try { + char* str = "5:abcd"; + MetaEntry* entry = MetaFileUtil::bdecoding(str, strlen(str)); + CPPUNIT_FAIL("DlAbortEx exception must be throwed."); + } catch(DlAbortEx* ex) { + delete ex; + } catch(...) { + CPPUNIT_FAIL("DlAbortEx exception must be throwed."); + } + + try { + char* str = "i1234"; + MetaEntry* entry = MetaFileUtil::bdecoding(str, strlen(str)); + CPPUNIT_FAIL("DlAbortEx exception must be throwed."); + } catch(DlAbortEx* ex) { + delete ex; + } catch(...) { + CPPUNIT_FAIL("DlAbortEx exception must be throwed."); + } + + try { + char* str = "5abcd"; + MetaEntry* entry = MetaFileUtil::bdecoding(str, strlen(str)); + CPPUNIT_FAIL("DlAbortEx exception must be throwed."); + } catch(DlAbortEx* ex) { + delete ex; + } catch(...) { + CPPUNIT_FAIL("DlAbortEx exception must be throwed."); + } + + try { + char* str = "d"; + MetaEntry* entry = MetaFileUtil::bdecoding(str, strlen(str)); + CPPUNIT_FAIL("DlAbortEx exception must be throwed."); + } catch(DlAbortEx* ex) { + delete ex; + } catch(...) { + CPPUNIT_FAIL("DlAbortEx exception must be throwed."); + } +} + diff --git a/test/PeerMessageUtilTest.cc b/test/PeerMessageUtilTest.cc new file mode 100644 index 00000000..d58c3ecf --- /dev/null +++ b/test/PeerMessageUtilTest.cc @@ -0,0 +1,352 @@ +#include "PeerMessageUtil.h" +#include +#include +#include + +using namespace std; + +class PeerMessageUtilTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(PeerMessageUtilTest); + CPPUNIT_TEST(testCreatePeerMessageKeepAlive); + CPPUNIT_TEST(testCreatePeerMessageChoke); + CPPUNIT_TEST(testCreatePeerMessageUnchoke); + CPPUNIT_TEST(testCreatePeerMessageInterested); + CPPUNIT_TEST(testCreatePeerMessageNotInterested); + CPPUNIT_TEST(testCreatePeerMessageHave); + CPPUNIT_TEST(testCreatePeerMessageBitfield); + CPPUNIT_TEST(testCreatePeerMessageRequest); + CPPUNIT_TEST(testCreatePeerMessagePiece); + CPPUNIT_TEST(testCreatePeerMessageCancel); + CPPUNIT_TEST(testCheckIntegrityHave); + CPPUNIT_TEST(testCheckIntegrityBitfield); + CPPUNIT_TEST(testCheckIntegrityRequest); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() { + } + + void testCreatePeerMessageKeepAlive(); + void testCreatePeerMessageChoke(); + void testCreatePeerMessageUnchoke(); + void testCreatePeerMessageInterested(); + void testCreatePeerMessageNotInterested(); + void testCreatePeerMessageHave(); + void testCreatePeerMessageBitfield(); + void testCreatePeerMessageRequest(); + void testCreatePeerMessagePiece(); + void testCreatePeerMessageCancel(); + + void testCheckIntegrityHave(); + void testCheckIntegrityBitfield(); + void testCheckIntegrityRequest(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION( PeerMessageUtilTest ); + +void setIntParam(char* dest, int param) { + int nParam = htonl(param); + memcpy(dest, &nParam, 4); +} + +void createNLengthMessage(char* msg, int msgLen, int payloadLen, int id) { + memset(msg, 0, msgLen); + setIntParam(msg, payloadLen); + msg[4] = (char)id; +} + +void PeerMessageUtilTest::testCreatePeerMessageKeepAlive() { + char msg[4]; + memset(msg, 0, sizeof(msg)); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(NULL, 0); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::KEEP_ALIVE, pm->id); +} + +void PeerMessageUtilTest::testCreatePeerMessageChoke() { + char msg[5]; + createNLengthMessage(msg, sizeof(msg), 1, 0); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::CHOKE, pm->id); + + try { + char msg[6]; + createNLengthMessage(msg, sizeof(msg), 2, 0); + PeerMessageUtil::createPeerMessage(&msg[4], 2); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) { + } +} + +void PeerMessageUtilTest::testCreatePeerMessageUnchoke() { + char msg[5]; + createNLengthMessage(msg, sizeof(msg), 1, 1); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::UNCHOKE, pm->id); + + try { + char msg[6]; + createNLengthMessage(msg, sizeof(msg), 2, 1); + PeerMessageUtil::createPeerMessage(&msg[4], 2); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) { + } +} + +void PeerMessageUtilTest::testCreatePeerMessageInterested() { + char msg[5]; + createNLengthMessage(msg, sizeof(msg), 1, 2); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::INTERESTED, pm->id); + + try { + char msg[6]; + createNLengthMessage(msg, sizeof(msg), 2, 2); + PeerMessageUtil::createPeerMessage(&msg[4], 2); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) { + } +} + +void PeerMessageUtilTest::testCreatePeerMessageNotInterested() { + char msg[5]; + createNLengthMessage(msg, sizeof(msg), 1, 3); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::NOT_INTERESTED, pm->id); + + try { + char msg[6]; + createNLengthMessage(msg, sizeof(msg), 2, 3); + PeerMessageUtil::createPeerMessage(&msg[4], 2); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) { + } +} + +void PeerMessageUtilTest::testCreatePeerMessageHave() { + char msg[9]; + createNLengthMessage(msg, sizeof(msg), 5, 4); + setIntParam(&msg[5], 100); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 5); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::HAVE, pm->id); + CPPUNIT_ASSERT_EQUAL(100, pm->index); + + try { + char msg[8]; + createNLengthMessage(msg, sizeof(msg), 4, 4); + PeerMessageUtil::createPeerMessage(&msg[4], 4); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) {} + + try { + char msg[5]; + createNLengthMessage(msg, sizeof(msg), 1, 4); + PeerMessageUtil::createPeerMessage(&msg[4], 1); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) {} +} + +void PeerMessageUtilTest::testCreatePeerMessageBitfield() { + int msgLen = 5+2; + char* msg = new char[msgLen]; + createNLengthMessage(msg, msgLen, 3, 5); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 3); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::BITFIELD, pm->id); + CPPUNIT_ASSERT_EQUAL((unsigned char)0, pm->bitfield[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)0, pm->bitfield[1]); + CPPUNIT_ASSERT_EQUAL(2, pm->bitfieldLen); + + try { + int msgLen = 5; + char* msg = new char[msgLen]; + createNLengthMessage(msg, msgLen, 1, 5); + PeerMessageUtil::createPeerMessage(&msg[4], 1); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) {} +} + +void PeerMessageUtilTest::testCreatePeerMessageRequest() { + char msg[17]; + createNLengthMessage(msg, sizeof(msg), 13, 6); + setIntParam(&msg[5], 1); + setIntParam(&msg[9], 16*1024); + setIntParam(&msg[13], 16*1024-1); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 13); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::REQUEST, pm->id); + CPPUNIT_ASSERT_EQUAL(1, pm->index); + CPPUNIT_ASSERT_EQUAL(16*1024, pm->begin); + CPPUNIT_ASSERT_EQUAL(16*1024-1, pm->length); + + try { + char msg[13]; + createNLengthMessage(msg, sizeof(msg), 9, 6); + setIntParam(&msg[5], 1); + setIntParam(&msg[9], 16*1024); + PeerMessageUtil::createPeerMessage(&msg[4], 9); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) {} +} + +void PeerMessageUtilTest::testCreatePeerMessagePiece() { + char msg[23]; + createNLengthMessage(msg, sizeof(msg), 9+10, 7); + setIntParam(&msg[5], 1); + setIntParam(&msg[9], 16*1024); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 19); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::PIECE, pm->id); + CPPUNIT_ASSERT_EQUAL(1, pm->index); + CPPUNIT_ASSERT_EQUAL(16*1024, pm->begin); + CPPUNIT_ASSERT_EQUAL(10, pm->blockLen); + for(int i = 0; i < 10; i++) { + CPPUNIT_ASSERT_EQUAL((char)0, pm->block[i]); + } + + try { + char msg[13]; + createNLengthMessage(msg, sizeof(msg), 9, 7); + setIntParam(&msg[5], 1); + setIntParam(&msg[9], 16*1024); + PeerMessageUtil::createPeerMessage(&msg[4], 9); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) {} +} + +void PeerMessageUtilTest::testCreatePeerMessageCancel() { + char msg[17]; + createNLengthMessage(msg, sizeof(msg), 13, 8); + setIntParam(&msg[5], 1); + setIntParam(&msg[9], 16*1024); + setIntParam(&msg[13], 16*1024-1); + PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 13); + CPPUNIT_ASSERT_EQUAL((int)PeerMessage::CANCEL, pm->id); + CPPUNIT_ASSERT_EQUAL(1, pm->index); + CPPUNIT_ASSERT_EQUAL(16*1024, pm->begin); + CPPUNIT_ASSERT_EQUAL(16*1024-1, pm->length); + + try { + char msg[13]; + createNLengthMessage(msg, sizeof(msg), 9, 8); + setIntParam(&msg[5], 1); + setIntParam(&msg[9], 16*1024); + PeerMessageUtil::createPeerMessage(&msg[4], 9); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) {} +} + +void PeerMessageUtilTest::testCheckIntegrityHave() { + PeerMessage* pm = new PeerMessage(); + pm->id = PeerMessage::HAVE; + pm->index = 119; + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120); + } catch(Exception* ex) { + cerr << ex->getMsg() << endl; + CPPUNIT_FAIL(""); + } + + pm->index = 120; + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120); + CPPUNIT_FAIL("exception must be throwed."); + } catch(...) {} +} + + +void PeerMessageUtilTest::testCheckIntegrityBitfield() { + PeerMessage* pm = new PeerMessage(); + pm->id = PeerMessage::BITFIELD; + pm->bitfieldLen = 15; + pm->bitfield = new unsigned char[pm->bitfieldLen]; + memset(pm->bitfield, 1, pm->bitfieldLen); + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120); + } catch(Exception* ex) { + cerr << ex->getMsg() << endl; + CPPUNIT_FAIL(""); + } + + pm->bitfieldLen = 16; + pm->bitfield = new unsigned char[pm->bitfieldLen]; + memset(pm->bitfield, 1, pm->bitfieldLen); + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120); + CPPUNIT_FAIL("exception must be throwed."); + } catch(Exception* ex) { + } + + pm->bitfieldLen = 14; + pm->bitfield = new unsigned char[pm->bitfieldLen]; + memset(pm->bitfield, 1, pm->bitfieldLen); + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120); + CPPUNIT_FAIL("exception must be throwed."); + } catch(Exception* ex) { + } + + pm->bitfieldLen = 15; + pm->bitfield = new unsigned char[pm->bitfieldLen]; + memset(pm->bitfield, 1, pm->bitfieldLen); + pm->bitfield[pm->bitfieldLen-1] &= 0xfe; + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120); + } catch(Exception* ex) { + cerr << ex->getMsg() << endl; + CPPUNIT_FAIL(""); + } + + pm->bitfieldLen = 15; + pm->bitfield = new unsigned char[pm->bitfieldLen]; + memset(pm->bitfield, 1, pm->bitfieldLen); + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120); + CPPUNIT_FAIL("exception must be throwed."); + } catch(Exception* ex) { + } +} + +void PeerMessageUtilTest::testCheckIntegrityRequest() { + PeerMessage* pm = new PeerMessage(); + pm->id = PeerMessage::REQUEST; + pm->index = 119; + pm->begin = 0; + pm->length = 16*1024; + + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120); + } catch(Exception* ex) { + cerr << ex->getMsg() << endl; + CPPUNIT_FAIL(""); + } + + pm->begin = 256*1024; + pm->length = 16*1024; + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120); + CPPUNIT_FAIL("exception must be throwed."); + } catch(Exception* ex) {} + + pm->begin = 0; + pm->length = 256*1024+1; + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120); + CPPUNIT_FAIL("exception must be throwed."); + } catch(Exception* ex) {} + + pm->begin = 0; + pm->length = 256*1024; + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120); + } catch(Exception* ex) { + cerr << ex->getMsg() << endl; + CPPUNIT_FAIL(""); + } + + pm->begin = 0; + pm->length = 256*1024; + try { + PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120-1); + CPPUNIT_FAIL("exception must be throwed."); + } catch(Exception* ex) {} +} diff --git a/test/ShaVisitorTest.cc b/test/ShaVisitorTest.cc new file mode 100644 index 00000000..ce32b207 --- /dev/null +++ b/test/ShaVisitorTest.cc @@ -0,0 +1,60 @@ +#include "ShaVisitor.h" +#include "MetaFileUtil.h" +#include +#include + +using namespace std; + +class ShaVisitorTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(ShaVisitorTest); + CPPUNIT_TEST(testVisit); + CPPUNIT_TEST(testVisitCompound); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() { + } + + void testVisit(); + void testVisitCompound(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION( ShaVisitorTest ); + +string hexHash(unsigned char* md, int len) { + char* temp = new char[len*2+1]; + for(int i = 0; i < len; i++) { + sprintf(temp+i*2, "%02x", md[i]); + } + temp[len*2] = '\0'; + string h(temp); + delete [] temp; + return h; +} + +void ShaVisitorTest::testVisit() { + ShaVisitor v; + Data d("test", 4); + d.accept(&v); + unsigned char md[EVP_MAX_MD_SIZE]; + int len = 0; + v.getHash(md, len); + string hashHex = hexHash(md, len); + CPPUNIT_ASSERT_EQUAL(string("20482dadd856f5ac908848f731d9235d2891c41e"), + hashHex); +} + +void ShaVisitorTest::testVisitCompound() { + ShaVisitor v; + MetaEntry* e = MetaFileUtil::parseMetaFile("test.torrent"); + e->accept(&v); + unsigned char md[EVP_MAX_MD_SIZE]; + int len = 0; + v.getHash(md, len); + string hashHex = hexHash(md, len); + CPPUNIT_ASSERT_EQUAL(string("9d33ba293924df85f6067a81c65b484de04e8efd"), + hashHex); +} diff --git a/test/TorrentManTest.cc b/test/TorrentManTest.cc new file mode 100644 index 00000000..41419bf0 --- /dev/null +++ b/test/TorrentManTest.cc @@ -0,0 +1,188 @@ +#include "TorrentMan.h" +#include +#include + +using namespace std; + +class TorrentManTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(TorrentManTest); + CPPUNIT_TEST(testUpdatePeers); + //CPPUNIT_TEST(testUpdatePeer); + CPPUNIT_TEST(testGetPeer); + CPPUNIT_TEST(testGetMissingPiece); + CPPUNIT_TEST(testCancelPiece); + CPPUNIT_TEST(testAddPeer); + CPPUNIT_TEST_SUITE_END(); +private: + +public: + void setUp() { + } + + void testUpdatePeers(); + //void testUpdatePeer(); + void testGetPeer(); + void testGetMissingPiece(); + void testCancelPiece(); + void testAddPeer(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION( TorrentManTest ); + +Peers createPeers() { + Peers peers; + Peer* peer1 = new Peer("192.168.0.1", 6881); + peer1->entryId = 1; + Peer* peer2 = new Peer("192.168.0.2", 6881); + peer2->entryId = 2; + Peer* peer3 = new Peer("192.168.0.3", 6881); + peer3->entryId = 3; + peers.push_back(peer1); + peers.push_back(peer2); + peers.push_back(peer3); + return peers; +} + +void TorrentManTest::testUpdatePeers() { + TorrentMan tm; + Peers peers = createPeers(); + tm.updatePeers(peers); + const Peers& peersGot = tm.getPeers(); + Peers::const_iterator itr = peersGot.begin(); + CPPUNIT_ASSERT_EQUAL(string("192.168.0.1"), (*itr)->ipaddr); + itr++; + CPPUNIT_ASSERT_EQUAL(string("192.168.0.2"), (*itr)->ipaddr); + itr++; + CPPUNIT_ASSERT_EQUAL(string("192.168.0.3"), (*itr)->ipaddr); + itr++; +} + +/* +void TorrentManTest::testUpdatePeer() { + TorrentMan tm; + Peers peers = createPeers(); + tm.updatePeers(peers); + Peer* peer = tm.getPeer(1); + peer->amChocking = true; + peer->amInterested = true; + tm.updatePeer(peer); + + Peers::const_iterator itr = tm.getPeers().begin(); + CPPUNIT_ASSERT_EQUAL(3, (int)tm.getPeers().size()); + CPPUNIT_ASSERT_EQUAL(string("192.168.0.1"), itr->ipaddr); + CPPUNIT_ASSERT_EQUAL(true, itr->amChocking); + CPPUNIT_ASSERT_EQUAL(true, itr->amInterested); + CPPUNIT_ASSERT_EQUAL(1, itr->cuid); + itr++; + CPPUNIT_ASSERT_EQUAL(string("192.168.0.2"), itr->ipaddr); + CPPUNIT_ASSERT_EQUAL(false, itr->amChocking); + CPPUNIT_ASSERT_EQUAL(false, itr->amInterested); + CPPUNIT_ASSERT_EQUAL(0, itr->cuid); + itr++; + CPPUNIT_ASSERT_EQUAL(string("192.168.0.3"), itr->ipaddr); + CPPUNIT_ASSERT_EQUAL(false, itr->amChocking); + CPPUNIT_ASSERT_EQUAL(false, itr->amInterested); + CPPUNIT_ASSERT_EQUAL(0, itr->cuid); + itr++; +} +*/ + +void TorrentManTest::testGetPeer() { + TorrentMan tm; + Peers peers = createPeers(); + tm.updatePeers(peers); + CPPUNIT_ASSERT(tm.getPeer(1) != Peer::nullPeer); + CPPUNIT_ASSERT(tm.getPeer(2) != Peer::nullPeer); + CPPUNIT_ASSERT(tm.getPeer(3) != Peer::nullPeer); + CPPUNIT_ASSERT(tm.getPeer(4) == Peer::nullPeer); +} + +void TorrentManTest::testGetMissingPiece() { + TorrentMan tm; + tm.pieceLength = 512*1024; + tm.pieces = 10; + tm.totalSize = 5242870; + tm.initBitfield(); + + unsigned char peerBitfield[2] = { 0xff, 0xff }; + Piece piece1 = tm.getMissingPiece(peerBitfield, 2); + CPPUNIT_ASSERT_EQUAL(0, piece1.index); + CPPUNIT_ASSERT_EQUAL(512*1024, piece1.length); + + Piece piece2 = tm.getMissingPiece(peerBitfield, 2); + CPPUNIT_ASSERT_EQUAL(1, piece2.index); + CPPUNIT_ASSERT_EQUAL(512*1024, piece2.length); + + tm.completePiece(piece1); + + int len = tm.getBitfieldLength(); + const unsigned char* bitfield = tm.getBitfield(); + CPPUNIT_ASSERT_EQUAL(2, len); + CPPUNIT_ASSERT(bitfield[0]&(1 << 7)); + for(int i = 0; i < 7; i++) { + CPPUNIT_ASSERT(!(bitfield[0]&(1 << i))); + } + + tm.completePiece(piece2); + bitfield = tm.getBitfield(); + CPPUNIT_ASSERT_EQUAL(2, len); + CPPUNIT_ASSERT(bitfield[0]&(1 << 7)); + CPPUNIT_ASSERT(bitfield[0]&(1 << 6)); + for(int i = 0; i < 6; i++) { + CPPUNIT_ASSERT(!(bitfield[0]&(1 << i))); + } + + for(int i = 0; i < 8; i++) { + CPPUNIT_ASSERT(!IS_NULL_PIECE(tm.getMissingPiece(peerBitfield, 2))); + } + CPPUNIT_ASSERT(IS_NULL_PIECE(tm.getMissingPiece(peerBitfield, 2))); +} + +void TorrentManTest::testCancelPiece() { + TorrentMan tm; + tm.pieceLength = 512*1024; + tm.pieces = 10; + tm.totalSize = 5242870; + tm.initBitfield(); + + unsigned char peerBitfield[2] = { 0xff, 0xff }; + Piece piece = tm.getMissingPiece(peerBitfield, 2); + CPPUNIT_ASSERT_EQUAL(0, piece.index); + CPPUNIT_ASSERT_EQUAL(512*1024, piece.length); + + tm.cancelPiece(piece); + int len = tm.getBitfieldLength(); + const unsigned char* bitfield = tm.getBitfield(); + for(int i = 0; i < 8; i++) { + CPPUNIT_ASSERT(!(bitfield[0]&(1 << i))); + } +} + +void TorrentManTest::testAddPeer() { + TorrentMan tm; + Peers peers = createPeers(); + tm.updatePeers(peers); + + // try to add already added peer + Peer* dupPeer = new Peer("192.168.0.2", 6881); + CPPUNIT_ASSERT(!tm.addPeer(dupPeer)); + CPPUNIT_ASSERT_EQUAL(3, (int)tm.getPeers().size()); + + // duplicate flag on + CPPUNIT_ASSERT(tm.addPeer(dupPeer, true)); + CPPUNIT_ASSERT_EQUAL(4, (int)tm.getPeers().size()); + + // cannot add error peer even though duplicte flag turns on + dupPeer->error = 1; + Peer* dupPeer2 = new Peer("192.168.0.2", 6881); + CPPUNIT_ASSERT(!tm.addPeer(dupPeer2, true)); + CPPUNIT_ASSERT_EQUAL(4, (int)tm.getPeers().size()); + + // try to add new peer + Peer* newPeer = new Peer("10.1.0.1", 6881); + CPPUNIT_ASSERT(tm.addPeer(newPeer)); + CPPUNIT_ASSERT_EQUAL(5, (int)tm.getPeers().size()); + +} diff --git a/test/test.torrent b/test/test.torrent new file mode 100644 index 00000000..d7a4ecc1 --- /dev/null +++ b/test/test.torrent @@ -0,0 +1 @@ +d8:announce36:http://aria.rednoah.com/announce.php7:comment17:REDNOAH.COM RULES13:creation datei1123456789e4:infod5:filesld6:lengthi256000e4:pathl5:aria23:src6:aria2ceed6:lengthi128900e4:pathl19:aria2-0.2.2.tar.bz2eee4:name10:aria2-test12:piece lengthi128e6:pieces60:AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCee \ No newline at end of file