3 * swift the multiparty transport protocol
5 * Created by Victor Grishchenko on 2/15/10.
6 * Copyright 2010 Delft University of Technology. All rights reserved.
14 using namespace swift;
16 #define quit(...) {fprintf(stderr,__VA_ARGS__); exit(1); }
17 SOCKET InstallHTTPGateway (Address addr);
20 int main (int argc, char** argv) {
22 static struct option long_options[] =
24 {"hash", required_argument, 0, 'h'},
25 {"file", required_argument, 0, 'f'},
26 {"daemon", no_argument, 0, 'd'},
27 {"listen", required_argument, 0, 'l'},
28 {"tracker", required_argument, 0, 't'},
29 {"debug", no_argument, 0, 'D'},
30 {"progress",no_argument, 0, 'p'},
31 {"http", optional_argument, 0, 'g'},
32 {"wait", optional_argument, 0, 'w'},
38 bool daemonize = false, report_progress = false;
47 while ( -1 != (c = getopt_long (argc, argv, ":h:f:dl:t:Dpg::w::", long_options, 0)) ) {
51 if (strlen(optarg)!=40)
52 quit("SHA1 hash must be 40 hex symbols\n");
53 root_hash = Sha1Hash(true,optarg); // FIXME ambiguity
54 if (root_hash==Sha1Hash::ZERO)
55 quit("SHA1 hash must be 40 hex symbols\n");
58 filename = strdup(optarg);
64 bindaddr = Address(optarg);
65 if (bindaddr==Address())
66 quit("address must be hostname:port, ip:port or just port\n");
67 wait_time = TINT_NEVER;
70 tracker = Address(optarg);
71 if (tracker==Address())
72 quit("address must be hostname:port, ip:port or just port\n");
76 Channel::debug_file = optarg ? fopen(optarg,"a") : stdout;
79 report_progress = true;
82 http_gw = optarg ? Address(optarg) : Address(Address::LOCALHOST,8080);
84 wait_time = TINT_NEVER; // seed
89 if (sscanf(optarg,"%lli%c",&wait_time,&unit)!=2)
90 quit("time format: 1234[umsMHD], e.g. 1M = one minute\n");
92 case 'D': wait_time *= 24;
93 case 'H': wait_time *= 60;
94 case 'M': wait_time *= 60;
95 case 's': wait_time *= 1000;
96 case 'm': wait_time *= 1000;
98 default: quit("time format: 1234[umsMHD], e.g. 1D = one day\n");
101 wait_time = TINT_NEVER;
105 } // arguments parsed
108 if (bindaddr!=Address()) { // seeding
109 if (Listen(bindaddr)<=0)
110 quit("cant listen to %s\n",bindaddr.str())
111 } else if (tracker!=Address() || http_gw!=Address()) { // leeching
112 for (int i=0; i<=10; i++) {
113 bindaddr = Address((uint32_t)INADDR_ANY,0);
114 if (Listen(bindaddr)>0)
117 quit("cant listen on %s\n",bindaddr.str());
121 if (tracker!=Address())
124 if (http_gw!=Address())
125 InstallHTTPGateway(http_gw);
127 if (root_hash!=Sha1Hash::ZERO && !filename)
128 filename = strdup(root_hash.hex().c_str());
132 file = Open(filename,root_hash);
134 quit("cannot open file %s",filename);
135 printf("Root hash: %s\n", RootMerkleHash(file).hex().c_str());
138 if (bindaddr==Address() && file==-1 && http_gw==Address()) {
139 fprintf(stderr,"Usage:\n");
140 fprintf(stderr," -h, --hash\troot Merkle hash for the transmission\n");
141 fprintf(stderr," -f, --file\tname of file to use (root hash by default)\n");
142 fprintf(stderr," -l, --listen\t[ip:|host:]port to listen to (default: random)\n");
143 fprintf(stderr," -t, --tracker\t[ip:|host:]port of the tracker (default: none)\n");
144 fprintf(stderr," -D, --debug\tfile name for debugging logs (default: stdout)\n");
145 fprintf(stderr," -p, --progress\treport transfer progress\n");
146 fprintf(stderr," -g, --http\t[ip:|host:]port to bind HTTP gateway to (default localhost:8080)\n");
147 fprintf(stderr," -w, --wait\tlimit running time, e.g. 1[DHMs] (default: infinite with -l, -g)\n");
151 tint start_time = NOW;
153 while ( (file>=0 && !IsComplete(file)) ||
154 (start_time+wait_time>NOW) ) {
155 swift::Loop(TINT_SEC);
156 if (report_progress && file>=0) {
158 "%s %lli of %lli (seq %lli) %lli dgram %lli bytes up, "\
159 "%lli dgram %lli bytes down\n",
160 IsComplete(file) ? "DONE" : "done",
161 Complete(file), Size(file), SeqComplete(file),
162 Datagram::dgrams_up, Datagram::bytes_up,
163 Datagram::dgrams_down, Datagram::bytes_down );
170 if (Channel::debug_file)
171 fclose(Channel::debug_file);