raw
v_mod6_genesis          1 #!/usr/bin/perl
v_mod6_genesis 2
v_mod6_99993 3 # (C) 2014 - 2018 The Bitcoin Foundation. You do not have, nor can you ever
v_mod6_genesis 4 # acquire the right to use, copy or distribute this software ; Should you use
v_mod6_genesis 5 # this software for any purpose, or copy and distribute it to anyone or in any
v_mod6_genesis 6 # manner, you are breaking the laws of whatever soi-disant jurisdiction, and
v_mod6_genesis 7 # you promise to continue doing so for the indefinite future. In any case,
v_mod6_genesis 8 # please always : read and understand any software ; verify any PGP signatures
v_mod6_genesis 9 # that you use - for any purpose.
v_mod6_genesis 10
v_keccak_vtools 11 # modified by Diana Coman to use vtools with keccak hashes (vpatch and ksum)
v_keccak_vtools 12 # version no changed to 99992
v_keccak_vtools 13
v_mod6_genesis 14 use strict;
v_mod6_genesis 15
v_keccak_vtools 16 my $version = "99992 K ";
v_mod6_genesis 17
v_mod6_99993 18 my $tdir = "";
v_mod6_genesis 19
v_mod6_genesis 20 my $graph;
v_mod6_genesis 21 my %wot = ();
v_mod6_genesis 22 my %map = ();
v_mod6_genesis 23 my %tmp_map = ();
v_mod6_genesis 24 my %banners = ();
v_mod6_99993 25 my %ante_map = ();
v_mod6_genesis 26 my %desc_map = ();
v_mod6_genesis 27 my %vp_map = ();
v_mod6_genesis 28
v_mod6_genesis 29 my ($pdir, $sdir, $wdir) = "";
v_mod6_genesis 30 my (@pfiles, @sfiles, @wfiles) = ();
v_mod6_genesis 31
v_keccak_vtools 32 my @dep_bins = ("cat", "echo", "gpg", "ls", "mkdir", "vpatch", "pwd",
v_keccak_vtools 33 "rm", "ksum", "sort", "wget", "which", "mktemp");
v_mod6_99993 34
v_mod6_99993 35 sub check_required_bins {
v_mod6_99993 36 my (@bins) = @_;
v_mod6_99993 37
v_mod6_99993 38 foreach my $bin (@bins) {
v_mod6_99993 39 my $res = `command -v $bin >&1`; chomp($res);
v_mod6_99993 40 death("Dependent program not found! : $bin\n") if $res eq "";
v_mod6_99993 41 }
v_mod6_genesis 42 }
v_mod6_genesis 43
v_mod6_genesis 44 sub get_pwd {
v_mod6_genesis 45 my $pwd = `pwd`; chomp($pwd);
v_mod6_genesis 46 return $pwd;
v_mod6_genesis 47 }
v_mod6_genesis 48
v_mod6_genesis 49 sub set_files {
v_mod6_genesis 50 my ($dir) = @_;
v_mod6_genesis 51 if(!-d $dir) {
v_mod6_genesis 52 my $msg = "$dir directory does not exist.\n" .
v_mod6_genesis 53 "See 'init' or 'sync' commands in 'help'.\n";
v_mod6_genesis 54 death($msg);
v_mod6_genesis 55 }
v_mod6_genesis 56 my @a = `ls $dir | sort`;
v_mod6_genesis 57 return wash(@a);
v_mod6_genesis 58 }
v_mod6_genesis 59
v_mod6_genesis 60 sub wash { my (@a)=@_; my @b; foreach(@a) {chomp($_); push @b, $_;} return @b; }
v_mod6_genesis 61
v_mod6_genesis 62 sub init {
v_mod6_genesis 63 my ($URL, $pd, $sd) = @_;
v_mod6_genesis 64
v_mod6_genesis 65 if($URL && $pd && $sd) {
v_mod6_genesis 66 if(!-d $pd) { `mkdir -p $pd`; sync_all_vpatches($URL, $pd); }
v_mod6_genesis 67 else { print "$pd dir exists! Skipping initial Vpatch sync\n"; }
v_mod6_genesis 68 if(!-d $sd) { `mkdir -p $sd`; sync_seals($URL, $sd); }
v_mod6_genesis 69 else { print "$sd dir exists! Skipping initial Seal sync\n"; }
v_mod6_genesis 70 }
v_mod6_genesis 71 }
v_mod6_genesis 72
v_mod6_genesis 73 sub build_wot {
v_mod6_genesis 74 my $uid, my $banner, my $keyid, my $fp;
v_mod6_genesis 75 foreach my $pubkey (@wfiles) {
v_mod6_genesis 76 my $import = "gpg --homedir $tdir --logger-fd 1 --keyid-format=long " .
v_mod6_genesis 77 "--import $wdir/$pubkey 2> /dev/null";
v_mod6_genesis 78 my $res = `$import`;
v_mod6_genesis 79 $uid = $1 if $pubkey =~ /(.*)\.asc/; chomp($uid);
v_mod6_genesis 80 $banner = $1 if $res =~ /\"(.*)\"/; chomp($banner);
v_mod6_genesis 81 $keyid = $1 if $res =~ /key (.*)\:/; chomp($keyid);
v_mod6_genesis 82 my $res_fp = `gpg --homedir $tdir --logger-fd 1 --fingerprint $keyid`;
v_mod6_genesis 83 $fp = $1 if $res_fp =~ /Key fingerprint = (.*)/; $fp =~ s/\s+//g;
v_mod6_genesis 84 $wot{$uid} = { fp => $fp, banner => $banner };
v_mod6_genesis 85 }
v_mod6_genesis 86 }
v_mod6_genesis 87
v_mod6_genesis 88 sub validate_seals {
v_mod6_genesis 89 my $seal_key, my $seal_signatory, my $uid, my $fp, my $patch, my %sig;
v_mod6_genesis 90 foreach my $patch (@pfiles) {
v_mod6_genesis 91 foreach my $seal (@sfiles) {
v_mod6_genesis 92 $seal_key = $1 if $seal =~ /^(.*)\..*\..*$/;
v_mod6_genesis 93 $seal_signatory = $1 if $seal =~ /^.*\.(.*)\..*$/;
v_mod6_genesis 94 if($patch =~ /^$seal_key$/) {
v_mod6_genesis 95 if(exists $wot{$seal_signatory}) {
v_mod6_genesis 96 if(not exists $banners{$patch} && $patch ne "") {
v_mod6_genesis 97 $banners{$patch} = $patch;
v_mod6_genesis 98 %sig = ();
v_mod6_genesis 99 }
v_mod6_genesis 100 my $verify = "gpg --homedir $tdir --logger-fd 1 --verify $sdir/$seal " .
v_mod6_genesis 101 "$pdir/$patch";
v_mod6_genesis 102 my @res = `$verify`;
v_mod6_genesis 103 foreach my $r (@res) {
v_mod6_genesis 104 $fp = $1 if $r =~ /Primary key fingerprint: (.*)/; $fp =~ s/\s+//g;
v_mod6_genesis 105 foreach my $uidkey (sort keys %wot) {
v_mod6_genesis 106 if($wot{$uidkey}{fp} eq $fp) {
v_mod6_genesis 107 $uid = $uidkey;
v_mod6_genesis 108 last;
v_mod6_genesis 109 }
v_mod6_genesis 110 }
v_mod6_genesis 111 }
v_mod6_genesis 112 my $verified = "";
v_mod6_genesis 113 foreach my $r (@res) {
v_mod6_genesis 114 if($r =~ /Good signature/ && $uid ne "") {
v_mod6_genesis 115 $sig{$wot{$uid}{fp}} = $uid;
v_mod6_genesis 116 $banners{$patch} = {%sig};
v_mod6_genesis 117 $verified = "true";
v_mod6_genesis 118 last;
v_mod6_genesis 119 }
v_mod6_genesis 120 }
v_mod6_genesis 121 if($verified ne "true") {
v_mod6_genesis 122 my $border = "-----------------------------------------" .
v_mod6_genesis 123 "-----------------------------------------";
v_mod6_genesis 124 print "$border\n";
v_mod6_genesis 125 print "WARNING: $seal is an INVALID seal for $patch!\n";
v_mod6_genesis 126 my $msg = "Check that this user is in your WoT.\n" .
v_mod6_genesis 127 "Otherwise remove the invalid seal from your SEALS directory.";
v_mod6_genesis 128 print "$msg\n";
v_mod6_genesis 129 print "$border\n";
v_mod6_genesis 130 death();
v_mod6_genesis 131 }
v_mod6_genesis 132 $verified = "";
v_mod6_genesis 133 }
v_mod6_genesis 134 }
v_mod6_genesis 135 }
v_mod6_genesis 136 }
v_mod6_genesis 137 }
v_mod6_genesis 138
v_mod6_genesis 139 sub build_map {
v_mod6_genesis 140 my %vpdata;
v_mod6_genesis 141 @pfiles = ();
v_mod6_genesis 142 foreach my $vpatch (keys %banners) {
v_mod6_genesis 143 push @pfiles, $vpatch;
v_mod6_genesis 144 }
v_mod6_genesis 145 foreach my $pfile (@pfiles) {
v_mod6_genesis 146 $map{$pfile} = $pfile;
v_mod6_genesis 147 my @patch = `cat $pdir/$pfile`;
v_mod6_genesis 148 my $src_file = "", my $ante_hash = "", my $desc_hash = "";
v_mod6_genesis 149 foreach my $p (@patch) {
v_mod6_genesis 150 $src_file = $1, $ante_hash = $2 if $p =~ /^--- (.*) (.*)/;
v_mod6_genesis 151 $desc_hash = $1 if $p =~ /^\+\+\+ .* (.*)/;
v_mod6_genesis 152 if($src_file && $ante_hash && $desc_hash) {
v_mod6_genesis 153 death("$pfile is an invalid vpatch!\n") if $ante_hash eq $desc_hash;
v_mod6_genesis 154 $vpdata{$src_file} = { a => $ante_hash, b => $desc_hash };
v_mod6_genesis 155 $map{$pfile} = {%vpdata};
v_mod6_genesis 156 $src_file = "", $ante_hash = "", $desc_hash = "";
v_mod6_genesis 157 }
v_mod6_genesis 158 }
v_mod6_genesis 159 death("Error! $pfile is an invalid vpatch file.\n") if !%vpdata;
v_mod6_genesis 160 %vpdata = ();
v_mod6_genesis 161 }
v_mod6_genesis 162 return %map;
v_mod6_genesis 163 }
v_mod6_genesis 164
v_mod6_genesis 165 sub roots {
v_mod6_genesis 166 my @roots = ();
v_mod6_genesis 167 my $is_root = "false";
v_mod6_genesis 168 foreach my $vpatch (keys %map) {
v_mod6_genesis 169 my %ante = antecedents($vpatch);
v_mod6_genesis 170 if(!%ante) {
v_mod6_genesis 171 foreach my $src_file_name (keys %{$map{$vpatch}}) {
v_mod6_genesis 172 if($map{$vpatch}{$src_file_name}->{a} eq "false") {
v_mod6_genesis 173 $is_root = "true";
v_mod6_genesis 174 next;
v_mod6_genesis 175 } else {
v_mod6_genesis 176 $is_root = "false";
v_mod6_genesis 177 last;
v_mod6_genesis 178 }
v_mod6_genesis 179 }
v_mod6_genesis 180 push @roots, $vpatch if $is_root eq "true";
v_mod6_genesis 181 }
v_mod6_genesis 182 }
v_mod6_genesis 183 return @roots;
v_mod6_genesis 184 }
v_mod6_genesis 185
v_mod6_genesis 186 sub leafs {
v_mod6_genesis 187 my @leafs;
v_mod6_genesis 188 foreach my $vpatch (keys %map) {
v_mod6_genesis 189 my %desc = descendants($vpatch);
v_mod6_genesis 190 push @leafs, $vpatch if !%desc;
v_mod6_genesis 191 }
v_mod6_genesis 192 return @leafs;
v_mod6_genesis 193 }
v_mod6_genesis 194
v_mod6_genesis 195 sub traverse_desc {
v_mod6_genesis 196 my (%st) = @_;
v_mod6_genesis 197 my %desc;
v_mod6_genesis 198 foreach my $k (keys %map) {
v_mod6_genesis 199 my @tmp = ();
v_mod6_genesis 200 foreach my $src_file_name (keys %{$map{$k}}) {
v_mod6_genesis 201 my $src_file = $map{$k}{$src_file_name};
v_mod6_genesis 202 foreach my $sf_name (keys %st) {
v_mod6_genesis 203 my $sf = $st{$sf_name};
v_mod6_genesis 204 if($src_file_name eq $sf_name &&
v_mod6_genesis 205 $src_file->{a} eq $sf->{b} &&
v_mod6_genesis 206 $src_file->{a} ne "false") {
v_mod6_genesis 207 push @tmp, $sf_name;
v_mod6_genesis 208 $desc{$k} = [@tmp];
v_mod6_genesis 209 }
v_mod6_genesis 210 }
v_mod6_genesis 211 }
v_mod6_genesis 212 }
v_mod6_genesis 213 return %desc;
v_mod6_genesis 214 }
v_mod6_genesis 215
v_mod6_genesis 216 sub traverse_ante {
v_mod6_genesis 217 my (%st) = @_;
v_mod6_genesis 218 my %ante;
v_mod6_genesis 219 foreach my $k (keys %map) {
v_mod6_genesis 220 my @tmp = ();
v_mod6_genesis 221 foreach my $src_file_name (keys %{$map{$k}}) {
v_mod6_genesis 222 my $src_file = $map{$k}{$src_file_name};
v_mod6_genesis 223 foreach my $sf_name (keys %st) {
v_mod6_genesis 224 my $sf = $st{$sf_name};
v_mod6_genesis 225 if($src_file_name eq $sf_name &&
v_mod6_genesis 226 $src_file->{b} eq $sf->{a} &&
v_mod6_genesis 227 $src_file->{b} ne "false") {
v_mod6_genesis 228 push @tmp, $sf_name;
v_mod6_genesis 229 $ante{$k} = [@tmp];
v_mod6_genesis 230 }
v_mod6_genesis 231 }
v_mod6_genesis 232 }
v_mod6_genesis 233 }
v_mod6_genesis 234 return %ante;
v_mod6_genesis 235 }
v_mod6_genesis 236
v_mod6_genesis 237 sub search_map {
v_mod6_genesis 238 my ($search_key) = @_;
v_mod6_genesis 239 if(exists $map{$search_key}) {
v_mod6_genesis 240 return %{$map{$search_key}};
v_mod6_genesis 241 } else {
v_mod6_genesis 242 death("Error! Could not find vpatch \"$search_key\" in $pdir\n");
v_mod6_genesis 243 }
v_mod6_genesis 244 }
v_mod6_genesis 245
v_mod6_genesis 246 sub antecedents {
v_mod6_genesis 247 my ($vpatch) = @_;
v_mod6_genesis 248 return traverse_ante(search_map($vpatch));
v_mod6_genesis 249 }
v_mod6_genesis 250
v_mod6_genesis 251 sub descendants {
v_mod6_genesis 252 my ($vpatch) = @_;
v_mod6_genesis 253 return traverse_desc(search_map($vpatch));
v_mod6_genesis 254 }
v_mod6_genesis 255
v_mod6_genesis 256 sub get_signatories {
v_mod6_genesis 257 my ($vpatch) = @_;
v_mod6_genesis 258 my @sigs;
v_mod6_genesis 259 foreach my $k (keys %banners) {
v_mod6_genesis 260 foreach my $fp (keys %{$banners{$k}}) {
v_mod6_genesis 261 my $uid = $banners{$k}{$fp};
v_mod6_genesis 262 push @sigs, $uid if $vpatch eq $k;
v_mod6_genesis 263 }
v_mod6_genesis 264 }
v_mod6_genesis 265 push @sigs, "WILD" if !@sigs;
v_mod6_genesis 266 return "(" . join(', ', sort @sigs) . ")";
v_mod6_genesis 267 }
v_mod6_genesis 268
v_mod6_genesis 269 sub build_flow {
v_mod6_genesis 270 my @flow = ();
v_mod6_genesis 271 my @roots = roots();
v_mod6_genesis 272 %tmp_map = %map;
v_mod6_genesis 273 foreach my $root (@roots) {
v_mod6_genesis 274 my %desc = descendants($root);
v_mod6_genesis 275 if(%desc) {
v_mod6_genesis 276 $desc_map{$root} = [keys %desc];
v_mod6_genesis 277 get_all_descendant_nodes(sort keys %desc);
v_mod6_genesis 278 verify_ante($root);
v_mod6_genesis 279 } else {
v_mod6_genesis 280 $desc_map{$root} = [];
v_mod6_genesis 281 }
v_mod6_genesis 282 }
v_mod6_genesis 283 @flow = toposort(%desc_map);
v_mod6_genesis 284 %map = scrub_map(@flow);
v_mod6_99993 285 return reverse @flow;
v_mod6_99993 286 }
v_mod6_99993 287
v_mod6_99993 288 sub calc_press_path {
v_mod6_99993 289 my ($head) = @_;
v_mod6_99993 290 traverse_press_path($head);
v_mod6_99993 291 return toposort(%ante_map);
v_mod6_99993 292 }
v_mod6_99993 293
v_mod6_99993 294 sub traverse_press_path {
v_mod6_99993 295 my ($vp) = @_;
v_mod6_99993 296
v_mod6_99993 297 my %ante = antecedents($vp);
v_mod6_99993 298
v_mod6_99993 299 if(%ante) {
v_mod6_99993 300 $ante_map{$vp} = [keys %ante];
v_mod6_99993 301 foreach my $a (keys %ante) {
v_mod6_99993 302 traverse_press_path($a);
v_mod6_99993 303 }
v_mod6_99993 304 } else {
v_mod6_99993 305 $ante_map{$vp} = [];
v_mod6_99993 306 }
v_mod6_genesis 307 }
v_mod6_genesis 308
v_mod6_genesis 309 sub scrub_map {
v_mod6_genesis 310 my (@flow) = @_;
v_mod6_genesis 311 foreach my $k (keys %tmp_map) {
v_mod6_genesis 312 if(!grep {/$k/} @flow) { delete $tmp_map{$k} if exists $tmp_map{$k}; }
v_mod6_genesis 313 }
v_mod6_genesis 314 return %tmp_map;
v_mod6_genesis 315 }
v_mod6_genesis 316
v_mod6_genesis 317 sub verify_ante {
v_mod6_genesis 318 my (@vpatch) = @_;
v_mod6_genesis 319 my %desc = ();
v_mod6_genesis 320 foreach my $vp (@vpatch) {
v_mod6_genesis 321 %desc = descendants($vp);
v_mod6_genesis 322 if(%desc) {
v_mod6_genesis 323 foreach my $a (sort keys %desc) {
v_mod6_genesis 324 check_ante($a);
v_mod6_genesis 325 }
v_mod6_genesis 326 }
v_mod6_genesis 327 }
v_mod6_genesis 328 if(%desc) {
v_mod6_genesis 329 verify_ante(sort keys %desc);
v_mod6_genesis 330 }
v_mod6_genesis 331 }
v_mod6_genesis 332
v_mod6_genesis 333 sub check_ante {
v_mod6_genesis 334 my ($vp) = @_;
v_mod6_genesis 335 my @curr_node_edge_hashes = ();
v_mod6_genesis 336 my @verified_hashes = ();
v_mod6_genesis 337 my %ante = antecedents($vp);
v_mod6_genesis 338 foreach my $curr_node_edge (keys %{$tmp_map{$vp}}) {
v_mod6_genesis 339 if($tmp_map{$vp}{$curr_node_edge}->{a} ne "false") {
v_mod6_genesis 340 push @curr_node_edge_hashes, $tmp_map{$vp}{$curr_node_edge}->{a};
v_mod6_genesis 341 }
v_mod6_genesis 342 foreach my $ante_node (keys %ante) {
v_mod6_genesis 343 foreach my $ante_node_edge (keys %{$tmp_map{$ante_node}}) {
v_mod6_genesis 344 next if $curr_node_edge ne $ante_node_edge;
v_mod6_genesis 345 if($tmp_map{$vp}{$curr_node_edge}->{a} eq
v_mod6_genesis 346 $tmp_map{$ante_node}{$ante_node_edge}->{b}) {
v_mod6_genesis 347 push @verified_hashes, $tmp_map{$vp}{$curr_node_edge}->{a};
v_mod6_genesis 348 }
v_mod6_genesis 349 }
v_mod6_genesis 350 }
v_mod6_genesis 351 }
v_mod6_genesis 352 if(@curr_node_edge_hashes != @verified_hashes) {
v_mod6_genesis 353 remove_desc($vp);
v_mod6_genesis 354 }
v_mod6_genesis 355 }
v_mod6_genesis 356
v_mod6_genesis 357 sub remove_desc {
v_mod6_genesis 358 my (@vp) = @_;
v_mod6_genesis 359 my %desc = ();
v_mod6_genesis 360 foreach my $v (@vp) {
v_mod6_genesis 361 delete $desc_map{$v} if exists $desc_map{$v};
v_mod6_genesis 362 delete $tmp_map{$v} if exists $tmp_map{$v};
v_mod6_genesis 363 my %desc = descendants($v);
v_mod6_genesis 364 next if !%desc;
v_mod6_genesis 365 foreach my $d (keys %desc) {
v_mod6_genesis 366 foreach my $dkeys (keys %desc_map) {
v_mod6_genesis 367 my @tmp = @{$desc_map{$dkeys}};
v_mod6_genesis 368 if(@tmp) {
v_mod6_genesis 369 my $offset = 0;
v_mod6_genesis 370 foreach my $t (@tmp) {
v_mod6_genesis 371 if($t eq $d) {
v_mod6_genesis 372 splice @tmp, $offset, 1;
v_mod6_genesis 373 }
v_mod6_genesis 374 $offset++;
v_mod6_genesis 375 }
v_mod6_genesis 376 $desc_map{$dkeys} = [@tmp];
v_mod6_genesis 377 }
v_mod6_genesis 378 }
v_mod6_genesis 379 }
v_mod6_genesis 380 remove_desc(sort keys %desc) if %desc;
v_mod6_genesis 381 }
v_mod6_genesis 382 }
v_mod6_genesis 383
v_mod6_genesis 384 sub get_all_descendant_nodes {
v_mod6_genesis 385 my (@vpatch) = @_;
v_mod6_genesis 386 my %desc = ();
v_mod6_genesis 387 foreach my $vp (@vpatch) {
v_mod6_genesis 388 %desc = descendants($vp);
v_mod6_genesis 389 if(keys %desc) {
v_mod6_genesis 390 my @dkeys = keys %desc;
v_mod6_genesis 391 $desc_map{$vp} = [@dkeys];
v_mod6_genesis 392 get_all_descendant_nodes(sort @dkeys);
v_mod6_genesis 393 }
v_mod6_genesis 394 if(!%desc) {
v_mod6_genesis 395 $desc_map{$vp} = [];
v_mod6_genesis 396 }
v_mod6_genesis 397 }
v_mod6_genesis 398 return %desc_map;
v_mod6_genesis 399 }
v_mod6_genesis 400
v_mod6_genesis 401 sub toposort {
v_mod6_genesis 402 my (%unsorted) = @_;
v_mod6_genesis 403 my $acyclic = "", my $flag = "f", my @flow = ();
v_mod6_genesis 404 while(%unsorted) {
v_mod6_genesis 405 $acyclic = "false";
v_mod6_genesis 406 foreach my $node (sort keys %unsorted) {
v_mod6_genesis 407 my @edges = @{$unsorted{$node}};
v_mod6_genesis 408 foreach my $edge (@edges) {
v_mod6_genesis 409 $flag = "t" and last if exists $unsorted{$edge};
v_mod6_genesis 410 }
v_mod6_genesis 411 if($flag ne "t") {
v_mod6_genesis 412 $acyclic = "true";
v_mod6_genesis 413 delete $unsorted{$node};
v_mod6_genesis 414 push @flow, $node;
v_mod6_genesis 415 }
v_mod6_genesis 416 $flag = "";
v_mod6_genesis 417 }
v_mod6_genesis 418 if(!$acyclic eq "true") {
v_mod6_genesis 419 death("Cyclic Graph!\n");
v_mod6_genesis 420 }
v_mod6_genesis 421 }
v_mod6_99993 422 return @flow;
v_mod6_genesis 423 }
v_mod6_genesis 424
v_mod6_genesis 425 sub press_vpatches {
v_mod6_genesis 426 my ($p, @flow) = @_;
v_mod6_genesis 427 my @press = @{$p};
v_mod6_genesis 428 my $v = 1 and shift @press if $press[0] =~ /^v$|^verbose$/i;
v_mod6_genesis 429 death("HEAD: $press[1] not found in flow\n") if !grep /^$press[1]$/, @flow;
v_mod6_99993 430 my @pp = calc_press_path($press[1]);
v_mod6_99993 431 death("Directory $press[0] already exists! Halting press.\n") if -d $press[0];
v_mod6_genesis 432 `mkdir -p $press[0]`;
v_mod6_99993 433 foreach my $vp (@pp) {
v_mod6_genesis 434 if($v) {
v_keccak_vtools 435 my @out = `cd $press[0] && vpatch < $pdir/$vp 2>&1`;
v_mod6_genesis 436 print "$vp\n";
v_mod6_genesis 437 foreach my $o (@out) { print " $o"; }
v_mod6_genesis 438 } else {
v_keccak_vtools 439 `cd $press[0] && vpatch < $pdir/$vp`;
v_mod6_genesis 440 }
v_mod6_genesis 441 %vp_map = ();
v_mod6_genesis 442 verify_pressed($press[0], add_pressed($vp));
v_mod6_genesis 443 last if $vp eq $press[1];
v_mod6_genesis 444 }
v_mod6_genesis 445 }
v_mod6_genesis 446
v_mod6_genesis 447 sub add_pressed {
v_mod6_genesis 448 my ($vpatch) = @_;
v_mod6_genesis 449 $vp_map{$vpatch} = $map{$vpatch};
v_mod6_genesis 450 return %vp_map;
v_mod6_genesis 451 }
v_mod6_genesis 452
v_mod6_genesis 453 sub get_filepath {
v_mod6_genesis 454 my ($fp) = @_;
v_mod6_genesis 455 $fp =~ /^[a|b]\/(.*)$/;
v_mod6_genesis 456 return $1;
v_mod6_genesis 457 }
v_mod6_genesis 458
v_mod6_genesis 459 sub verify_pressed {
v_mod6_genesis 460 my ($press_dir, %vp_map) = @_;
v_mod6_genesis 461 foreach my $vp (keys %vp_map) {
v_mod6_genesis 462 foreach my $src_file_name (keys %{$vp_map{$vp}}) {
v_mod6_genesis 463 my $file_hash = $vp_map{$vp}{$src_file_name}{b};
v_mod6_genesis 464 if($file_hash ne "false") {
v_mod6_genesis 465 my $fp = $press_dir . "/" . get_filepath($src_file_name);
v_keccak_vtools 466 my $hashed = `ksum $fp`;
v_mod6_genesis 467 $hashed =~ /^(.*) .*$/;
v_mod6_genesis 468 my $pressed_hash = $1;
v_mod6_genesis 469 if($file_hash ne $pressed_hash) {
v_mod6_genesis 470 print " File: $fp\n" .
v_mod6_genesis 471 "Expected: $file_hash\n" .
v_mod6_genesis 472 " Actual: $pressed_hash\n";
v_mod6_genesis 473 death("Pressed file hash did not match expected!\n");
v_mod6_genesis 474 }
v_mod6_genesis 475 }
v_mod6_genesis 476 }
v_mod6_genesis 477 }
v_mod6_genesis 478 }
v_mod6_genesis 479
v_mod6_genesis 480 sub sync_seals {
v_mod6_genesis 481 my ($URL, $out) = @_;
v_mod6_genesis 482 if(!-d $out) { `mkdir -p $out`; }
v_mod6_genesis 483 my $wget = "wget -q -r -nd -N --no-parent " .
v_mod6_genesis 484 "--reject \"index.html*\" $URL/v/seals/ -P $out";
v_mod6_genesis 485 `$wget`;
v_mod6_genesis 486 print "Seal sync complete to \"$out\"\n";
v_mod6_genesis 487 }
v_mod6_genesis 488
v_mod6_genesis 489 sub sync_vpatches {
v_mod6_genesis 490 my ($URL, $out, @sync) = @_;
v_mod6_genesis 491 my $wget = "";
v_mod6_genesis 492 if(!-d $out) { `mkdir -p $out`; }
v_mod6_genesis 493 foreach my $vpatch (@sync) {
v_mod6_genesis 494 $wget = "wget -q -r -nd -N --no-parent " .
v_mod6_genesis 495 "--reject \"index.html*\" $URL/v/patches/$vpatch -P $out";
v_mod6_genesis 496 `$wget`;
v_mod6_genesis 497 print "$vpatch sync complete to \"$out\"\n";
v_mod6_genesis 498 }
v_mod6_genesis 499 }
v_mod6_genesis 500
v_mod6_genesis 501 sub sync_all_vpatches {
v_mod6_genesis 502 my ($URL, $out) = @_;
v_mod6_genesis 503 if(!-d $out) { `mkdir -p $out`; }
v_mod6_genesis 504 my $wget = "wget -q -r -nd -N --no-parent " .
v_mod6_genesis 505 "--reject \"index.html*\" $URL/v/patches/ -P $out";
v_mod6_genesis 506 `$wget`;
v_mod6_genesis 507 print "Full vpatch sync complete to \"$out\"\n";
v_mod6_genesis 508 }
v_mod6_genesis 509
v_mod6_genesis 510 sub sync_everything {
v_mod6_genesis 511 my ($URL, $pd, $sd) = @_;
v_mod6_genesis 512 sync_all_vpatches($URL, $pd);
v_mod6_genesis 513 sync_seals($URL, $sd);
v_mod6_genesis 514 }
v_mod6_genesis 515
v_mod6_genesis 516 sub build_desc_full_graph {
v_mod6_genesis 517 $graph->set_attributes("graph",
v_mod6_genesis 518 {
v_mod6_genesis 519 font => "monospace",
v_mod6_genesis 520 label => "..::[ The Bitcoin Foundation: Vpatch Graph ]::.."
v_mod6_genesis 521 });
v_mod6_genesis 522 $graph->set_attributes("node",
v_mod6_genesis 523 {
v_mod6_genesis 524 linkbase => "http://thebitcoin.foundation/v/patches/",
v_mod6_genesis 525 autolink => "name",
v_mod6_genesis 526 color => "blue"
v_mod6_genesis 527 });
v_mod6_genesis 528 my @roots = roots();
v_mod6_genesis 529 foreach my $root (@roots) {
v_mod6_genesis 530 my $node = $graph->add_node($root);
v_mod6_genesis 531 $node->set_attribute("title", "Signed By: " . get_signatories($root));
v_mod6_genesis 532 my %desc = descendants($root);
v_mod6_genesis 533 my @dkeys = keys %desc;
v_mod6_genesis 534 add_desc_edges($root, @dkeys);
v_mod6_genesis 535 my @sn = $graph->source_nodes();
v_mod6_genesis 536 add_desc_src_files($sn[0]);
v_mod6_genesis 537 }
v_mod6_genesis 538 }
v_mod6_genesis 539
v_mod6_genesis 540 sub add_desc_edges {
v_mod6_genesis 541 my ($origin, @vpatch) = @_;
v_mod6_genesis 542 my %desc = ();
v_mod6_genesis 543 foreach my $vp (@vpatch) {
v_mod6_genesis 544 %desc = descendants($vp);
v_mod6_genesis 545 my $node = $graph->add_node($vp);
v_mod6_genesis 546 my $sigs = get_signatories($vp);
v_mod6_genesis 547 $node->set_attribute("title", "Signed By: $sigs");
v_mod6_genesis 548 $graph->add_edge_once($origin, $vp);
v_mod6_genesis 549 if(keys %desc) {
v_mod6_genesis 550 my @dkeys = sort keys %desc;
v_mod6_genesis 551 add_desc_edges($vp, @dkeys);
v_mod6_genesis 552 }
v_mod6_genesis 553 }
v_mod6_genesis 554 }
v_mod6_genesis 555
v_mod6_genesis 556 sub add_desc_src_files {
v_mod6_genesis 557 my ($node) = @_;
v_mod6_genesis 558 if($node != "") {
v_mod6_genesis 559 my %desc = descendants($node->name());
v_mod6_genesis 560 my @suc = $node->successors();
v_mod6_genesis 561 foreach my $s (@suc) {
v_mod6_genesis 562 my $name = $s->name();
v_mod6_genesis 563 my @edges = $node->edges_to($s);
v_mod6_genesis 564 foreach my $e (@edges) {
v_mod6_genesis 565 $e->set_attribute("title", "[ " .
v_mod6_genesis 566 join('; ', sort @{$desc{$name}}) . " ]");
v_mod6_genesis 567 add_desc_src_files($s);
v_mod6_genesis 568 }
v_mod6_genesis 569 }
v_mod6_genesis 570 }
v_mod6_genesis 571 }
v_mod6_genesis 572
v_mod6_genesis 573 sub rank_leafs_gviz {
v_mod6_genesis 574 build_desc_full_graph();
v_mod6_genesis 575 my $gviz = $graph->as_graphviz();
v_mod6_genesis 576 my @leafs = leafs();
v_mod6_genesis 577 $gviz =~ s/GRAPH_0/VPATCH_GRAPH/;
v_mod6_genesis 578 $gviz =~ s/rankdir=LR/rankdir=BT,ranksep=1.00,nodesep=.50/;
v_mod6_genesis 579 $gviz =~ s/}$//;
v_mod6_genesis 580 $gviz .= " { rank=same; ";
v_mod6_genesis 581 foreach my $l (@leafs) {
v_mod6_genesis 582 $gviz .= "\"$l\" ";
v_mod6_genesis 583 }
v_mod6_genesis 584 $gviz .= "}\n}";
v_mod6_genesis 585 return $gviz;
v_mod6_genesis 586 }
v_mod6_genesis 587
v_mod6_genesis 588 sub make_tmpdir {
v_mod6_99993 589 if(-d "/tmp") { $tdir = `mktemp -d`; } else { $tdir = `mktemp -d -p .`; }
v_mod6_99993 590 chomp($tdir);
v_mod6_99993 591 death("Failed to create tempdir!\n") if $tdir eq "";
v_mod6_genesis 592 }
v_mod6_genesis 593
v_mod6_genesis 594 sub death {
v_mod6_genesis 595 my ($msg) = @_;
v_mod6_genesis 596 remove_tmpdir($tdir);
v_mod6_genesis 597 die "$msg";
v_mod6_genesis 598 }
v_mod6_genesis 599
v_mod6_genesis 600 sub remove_tmpdir {
v_mod6_genesis 601 my ($dir) = @_;
v_mod6_genesis 602 `rm -rf $dir` if -d $dir;
v_mod6_genesis 603 }
v_mod6_genesis 604
v_mod6_genesis 605 sub print_graph {
v_mod6_genesis 606 my ($graph, @gv) = @_;
v_mod6_genesis 607 if(!@gv) {
v_mod6_genesis 608 print "$graph\n";
v_mod6_genesis 609 } elsif($#gv eq 1) {
v_mod6_genesis 610 open FH, ">$gv[0]"; print FH "$graph\n";
v_mod6_genesis 611 close FH;
v_mod6_genesis 612 print "Printed Graphviz dot file to $gv[0]\n";
v_mod6_genesis 613 my @which = `which dot`; chomp($which[0]);
v_mod6_genesis 614 if($which[0] =~ /dot/) {
v_mod6_genesis 615 `$which[0] -Tsvg $gv[0] > $gv[1]`;
v_mod6_genesis 616 } else {
v_mod6_genesis 617 print "`dot` binary not found, check if 'graphviz' is installed\n";
v_mod6_genesis 618 }
v_mod6_genesis 619 print "Executed `dot` and built svg html output file: $gv[1]\n";
v_mod6_genesis 620 } else {
v_mod6_genesis 621 open FH, ">$gv[0]"; print FH "$graph\n";
v_mod6_genesis 622 close FH;
v_mod6_genesis 623 print "Printed Graphviz dot file to $gv[0]\n";
v_mod6_genesis 624 }
v_mod6_genesis 625 }
v_mod6_genesis 626
v_mod6_genesis 627 sub get_mirrors {
v_mod6_genesis 628 my ($out) = @_;
v_mod6_genesis 629 my @mirror_sigs = ();
v_mod6_genesis 630 if(!-d $out) { `mkdir -p $out`; }
v_mod6_genesis 631 my $wget = "wget -q -r -nd -N --no-parent " .
v_mod6_genesis 632 "--reject \"index.html*\" -A 'mirrors.*' " .
v_mod6_genesis 633 "http://thebitcoin.foundation/v/ -P $out";
v_mod6_genesis 634 `$wget`;
v_mod6_genesis 635
v_mod6_genesis 636 my @sigs = `ls $out | sort`;
v_mod6_genesis 637 @sigs = wash(@sigs);
v_mod6_genesis 638 foreach my $sig (@sigs) {
v_mod6_genesis 639 my $who = $1 if $sig =~ /.*\..*\.(.*)\..*/;
v_mod6_genesis 640 my $verify = "gpg --homedir $tdir --logger-fd 1 --verify $out/$sig " .
v_mod6_genesis 641 "$out/mirrors.txt";
v_mod6_genesis 642 my @res = `$verify`;
v_mod6_genesis 643 foreach my $r (@res) {
v_mod6_genesis 644 if($r =~ /Good signature/) {
v_mod6_genesis 645 push @mirror_sigs, $who;
v_mod6_genesis 646 next;
v_mod6_genesis 647 }
v_mod6_genesis 648 }
v_mod6_genesis 649 }
v_mod6_genesis 650 return @mirror_sigs;
v_mod6_genesis 651 }
v_mod6_genesis 652
v_mod6_genesis 653 sub print_mirrors {
v_mod6_genesis 654 my ($out) = @_;
v_mod6_genesis 655 my @mirror_sigs = get_mirrors($out);
v_mod6_genesis 656
v_mod6_genesis 657 if(-d $out) {
v_mod6_genesis 658 my @mirrors = `cat $out/mirrors.txt`;
v_mod6_genesis 659 print "Mirrors signed by (" . join(', ', sort @mirror_sigs) . "):\n";
v_mod6_genesis 660 foreach(@mirrors) { chomp($_); print "$_\n"; }
v_mod6_genesis 661 }
v_mod6_genesis 662 }
v_mod6_genesis 663
v_mod6_genesis 664 sub print_roots {
v_mod6_genesis 665 my @r = roots();
v_mod6_genesis 666 foreach(@r) {
v_mod6_genesis 667 print "Root: $_ " . get_signatories($_) . "\n";
v_mod6_genesis 668 }
v_mod6_genesis 669 }
v_mod6_genesis 670
v_mod6_genesis 671 sub print_leafs {
v_mod6_genesis 672 my @l = leafs();
v_mod6_genesis 673 foreach(@l) {
v_mod6_genesis 674 print "Leaf: $_ " . get_signatories($_) . "\n";
v_mod6_genesis 675 }
v_mod6_genesis 676 }
v_mod6_genesis 677
v_mod6_genesis 678 sub print_wot {
v_mod6_genesis 679 my ($finger) = @_;
v_mod6_genesis 680 if(%wot) {
v_mod6_genesis 681 foreach my $uid (sort keys %wot) {
v_mod6_genesis 682 if(!$finger) {
v_mod6_genesis 683 print "$uid:$wot{$uid}{fp}:$wot{$uid}{banner}\n";
v_mod6_genesis 684 } else {
v_mod6_genesis 685 print "$uid-" . substr($wot{$uid}{fp}, -16) .
v_mod6_genesis 686 ":$wot{$uid}{fp}:$wot{$uid}{banner}\n";
v_mod6_genesis 687 }
v_mod6_genesis 688 }
v_mod6_genesis 689 }
v_mod6_genesis 690 }
v_mod6_genesis 691
v_mod6_genesis 692 sub print_antecedents {
v_mod6_genesis 693 my ($vpatch) = @_;
v_mod6_genesis 694 my %ante = antecedents($vpatch);
v_mod6_genesis 695 my $sigs;
v_mod6_genesis 696 foreach my $a (sort keys %ante) {
v_mod6_genesis 697 $sigs = get_signatories($a);
v_mod6_genesis 698 print "Antecedent: $a $sigs [ " . join('; ', sort @{$ante{$a}}) . " ]\n";
v_mod6_genesis 699 }
v_mod6_genesis 700 }
v_mod6_genesis 701
v_mod6_genesis 702 sub print_descendants {
v_mod6_genesis 703 my ($vpatch) = @_;
v_mod6_genesis 704 my %desc = descendants($vpatch);
v_mod6_genesis 705 my $sigs;
v_mod6_genesis 706 foreach my $d (sort keys %desc) {
v_mod6_genesis 707 $sigs = get_signatories($d);
v_mod6_genesis 708 print "Descendant: $d $sigs [ " . join('; ', sort @{$desc{$d}}) . " ]\n";
v_mod6_genesis 709 }
v_mod6_genesis 710 }
v_mod6_genesis 711
v_mod6_genesis 712 sub print_origin {
v_mod6_genesis 713 my ($hash) = @_;
v_mod6_genesis 714 my $found = "f";
v_mod6_genesis 715 foreach my $k (keys %map) {
v_mod6_genesis 716 foreach my $sf (keys %{$map{$k}}) {
v_mod6_genesis 717 if($map{$k}{$sf}{b} eq $hash) {
v_mod6_genesis 718 $found = "t";
v_mod6_genesis 719 print "Origin: $k " . get_signatories($k) . "\n";
v_mod6_genesis 720 }
v_mod6_genesis 721 }
v_mod6_genesis 722 }
v_mod6_genesis 723 print "No Origin Found by Hash: $hash\n" if $found ne "t";
v_mod6_genesis 724 }
v_mod6_genesis 725
v_mod6_genesis 726 sub print_flow {
v_mod6_genesis 727 my (@flow) = @_;
v_mod6_genesis 728 foreach(@flow) { print "$_ " . get_signatories($_) . "\n"; }
v_mod6_genesis 729 }
v_mod6_genesis 730
v_mod6_99993 731 sub print_press_path {
v_mod6_99993 732 my ($head) = @_;
v_mod6_99993 733 my @pp = calc_press_path($head);
v_mod6_99993 734 foreach(@pp) { print "$_ " . get_signatories($_) . "\n"; }
v_mod6_99993 735 }
v_mod6_99993 736
v_mod6_genesis 737 sub get_version {
v_mod6_genesis 738 my $version_text = << "END_VERSION_TEXT";
v_mod6_genesis 739 ################################################################################
v_mod6_genesis 740 # ..::[ The Bitcoin Foundation: V ]::.. #
v_mod6_genesis 741 # #
v_mod6_genesis 742 # Version: $version #
v_mod6_genesis 743 # Author: mod6 #
v_mod6_genesis 744 # Fingerprint: 0x027A8D7C0FB8A16643720F40721705A8B71EADAF #
v_mod6_genesis 745 # #
v_mod6_genesis 746 ################################################################################
v_mod6_genesis 747 END_VERSION_TEXT
v_mod6_genesis 748 return $version_text;
v_mod6_genesis 749 }
v_mod6_genesis 750
v_mod6_genesis 751 sub short_help {
v_mod6_genesis 752 my ($flag) = @_;
v_mod6_genesis 753 my $short_help = << "END_SHORT_HELP";
v_mod6_genesis 754 ################################################################################
v_mod6_genesis 755 # ..::[ The Bitcoin Foundation: V ]::.. #
v_mod6_genesis 756 # #
v_mod6_genesis 757 # Version: $version #
v_mod6_genesis 758 # Author: mod6 #
v_mod6_genesis 759 # Fingerprint: 0x027A8D7C0FB8A16643720F40721705A8B71EADAF #
v_mod6_genesis 760 # #
v_mod6_genesis 761 # Usage: v.pl #
v_mod6_genesis 762 # (m | mirrors) (<output_dir>) #
v_mod6_genesis 763 # (i | init) (mirror_url) [(<pdir> <sdir>)] #
v_mod6_genesis 764 # (wd | wotdir) (<wotdir>) #
v_mod6_genesis 765 # (pd | patchdir) (<patchdir>) #
v_mod6_genesis 766 # (sd | sealdir) (<sealdir>) #
v_mod6_genesis 767 # (w | wot) [ finger ] #
v_mod6_genesis 768 # (r | roots) #
v_mod6_genesis 769 # (l | leafs) #
v_mod6_genesis 770 # (f | flow) #
v_mod6_genesis 771 # (p | press) (<press_dir> <head>) #
v_mod6_99993 772 # (pp | press-path) (<head>) #
v_mod6_genesis 773 # (ss | sync-seals) (<mirror_url> <sdir>) #
v_mod6_genesis 774 # (sv | sync-vpatches) (<mirror_url> <pdir> <vpatches>... ) #
v_mod6_genesis 775 # (sa | sync-all-vpatches) (<mirror_url> <pdir>) #
v_mod6_genesis 776 # (se | sync-everything) (<mirror_url> <pdir> <sdir>) #
v_mod6_genesis 777 # (a | ante | antecedents) (<vpatch>) #
v_mod6_genesis 778 # (d | desc | descendants) (<vpatch>) #
v_keccak_vtools 779 # (o | origin) (<keccak_hash>) #
v_mod6_genesis 780 # (g | graph) (<output_dotfile> [<output_svg_html_file>]) #
v_mod6_genesis 781 # (v | version) #
v_mod6_99993 782 # (h | help) #
v_mod6_genesis 783 # #
v_mod6_genesis 784 END_SHORT_HELP
v_mod6_genesis 785 my $l = "########################################" .
v_mod6_genesis 786 "########################################\n";
v_mod6_genesis 787 if($flag) { $short_help .= $l; }
v_mod6_genesis 788 return $short_help;
v_mod6_genesis 789 }
v_mod6_genesis 790
v_mod6_genesis 791 sub long_help {
v_mod6_genesis 792 print short_help();
v_mod6_genesis 793 my $long_help = << "END_LONG_HELP";
v_mod6_genesis 794 # Commands: #
v_mod6_genesis 795 # m, mirrors (<output_dir>) #
v_mod6_genesis 796 # Will attempt to retrieve, cryptographically verify and print entries #
v_mod6_99993 797 # in this list for usage in other commands. Mirrors command may only #
v_mod6_99993 798 # be invoked by itself. [See: sync-seals, sync-vpatches, #
v_mod6_99993 799 # sync-everything] #
v_mod6_genesis 800 # #
v_mod6_genesis 801 # i, init (<mirror_url>) [(<pdir> <sdir>)] #
v_mod6_genesis 802 # init should be run as the first command executed with V. init only #
v_mod6_genesis 803 # requires one option: <mirror_url>. The <pdir> and <sdir> options are #
v_mod6_genesis 804 # optional. Use these if you want to override the default Vpatches and #
v_mod6_genesis 805 # Seals directories in that exact order. #
v_mod6_genesis 806 # #
v_mod6_genesis 807 # Defaults: "~/.wot", "patches" (in present working directory) and #
v_mod6_genesis 808 # "~/.seals" will be used as defaults. WoTs pubkeys can not be sync'd #
v_mod6_genesis 809 # these need to be placed in the WoT directory manually. #
v_mod6_genesis 810 # #
v_mod6_genesis 811 # Set <mirror_url> to one of the signed URLs in the PGP signed mirrors #
v_mod6_genesis 812 # list at: http://thebitcoin.foundation/v/mirrors.txt #
v_mod6_genesis 813 # #
v_mod6_genesis 814 # wd, wotdir (<wotdir>) #
v_mod6_genesis 815 # Given the required option <wotdir>, overrides the default wotdir #
v_mod6_genesis 816 # ( .wot in the current working directory ) containing PGP public keys. #
v_mod6_genesis 817 # #
v_mod6_genesis 818 # pd, patchdir (<patchdir>) #
v_mod6_genesis 819 # Given required option of <patchdir>, overrides the default #
v_mod6_genesis 820 # patchdir ( ./patches ) containing vpatch files. #
v_mod6_genesis 821 # #
v_mod6_genesis 822 # sd, sealdir (<sealdir>) #
v_mod6_genesis 823 # Given required option of <sealdir>, overrides the default sealdir #
v_mod6_genesis 824 # ( .seals in the current working directory ) containing PGP detached #
v_mod6_genesis 825 # signatures of vpatch files. #
v_mod6_genesis 826 # #
v_mod6_genesis 827 # w, wot [ finger ] #
v_mod6_genesis 828 # Loads PGP public keys from wotdir and prints the WoT to stdout #
v_mod6_genesis 829 # #
v_mod6_genesis 830 # r, roots #
v_mod6_genesis 831 # Finds the root vpatches (which have no antecedents) and prints them #
v_mod6_genesis 832 # to stdout. #
v_mod6_genesis 833 # #
v_mod6_genesis 834 # l, leafs #
v_mod6_genesis 835 # Finds the leaf vpatches (which have no descendants) and prints them #
v_mod6_genesis 836 # to stdout. #
v_mod6_genesis 837 # #
v_mod6_genesis 838 # f, flow #
v_mod6_genesis 839 # Prints the topological flow of vpatches based on precedence. #
v_mod6_genesis 840 # #
v_mod6_genesis 841 # p, press (<press_dir> <head>) #
v_mod6_genesis 842 # Given required options <press_dir> output directory and <vpatch> #
v_mod6_genesis 843 # press will apply vpatches in topologicial order up through the #
v_mod6_genesis 844 # supplied (head) vpatch. Will print patching output if 'verbose' flag #
v_mod6_genesis 845 # is supplied immediately after ( p | press ) option. #
v_mod6_genesis 846 # See: ( f | flow ) to view the topological ordering. #
v_mod6_genesis 847 # #
v_mod6_99993 848 # pp, press-path (<head>) #
v_mod6_99993 849 # Print the actual path to be pressed, given a <head> found in the #
v_mod6_99993 850 # flow. #
v_mod6_99993 851 # #
v_mod6_genesis 852 # ss, sync-seals (<mirror_url> <sdir>) #
v_mod6_genesis 853 # Given required options of <mirror_url> and output directory <sdir> #
v_mod6_genesis 854 # will pull all of the available seal files from the given mirror into #
v_mod6_genesis 855 # output directory. #
v_mod6_genesis 856 # #
v_mod6_genesis 857 # sv, sync-vpatches (<mirror_url> <pdir> <vpatch>... ) #
v_mod6_genesis 858 # Given required options of <mirror_url> and output directory <pdir> #
v_mod6_genesis 859 # will pull the requested vpatch(s) from the given mirror into output #
v_mod6_genesis 860 # directory. #
v_mod6_genesis 861 # #
v_mod6_genesis 862 # sa, sync-all-vpatches (<mirror_url> <pdir>) #
v_mod6_genesis 863 # Given required options of <mirror_url> and output directory <pdir> #
v_mod6_genesis 864 # will pull all available vpatches from the given mirror into output #
v_mod6_genesis 865 # directory. #
v_mod6_genesis 866 # #
v_mod6_genesis 867 # se, sync-everything (<mirror_url> <pdir> <sdir>) #
v_mod6_genesis 868 # Given required options of <mirror_url>, <pdir>, and <sdir>; #
v_mod6_genesis 869 # sync-everything will pull all of the available seals and vpatches #
v_mod6_genesis 870 # available at the given mirror. #
v_mod6_genesis 871 # #
v_mod6_genesis 872 # a, ante, antecedents (<vpatch>) #
v_mod6_genesis 873 # Finds the antecedents of a given vpatch and prints the results to #
v_mod6_genesis 874 # stdout #
v_mod6_genesis 875 # #
v_mod6_genesis 876 # d, desc, descendants (<vpatch>) #
v_mod6_genesis 877 # Finds the descendants of a given vpatch and prints the results to #
v_mod6_genesis 878 # stdout #
v_mod6_genesis 879 # #
v_keccak_vtools 880 # o, origin (<keccak_hash>) #
v_mod6_genesis 881 # Returns the vpatch and signatories where the given hash originated in #
v_mod6_genesis 882 # the source tree. #
v_mod6_genesis 883 # #
v_mod6_genesis 884 # g, graph (<output_dotfile> [<output_svg_html_file>]) #
v_mod6_genesis 885 # Builds a complete directed GraphViz graph of all vpatches from a #
v_mod6_genesis 886 # topological flow and prints the Dot language output to file. If the #
v_mod6_genesis 887 # output_svg_html_file argument is supplied the V will attempt to parse #
v_mod6_genesis 888 # the output_dotfile into an html file; Requires having separately #
v_mod6_genesis 889 # installed 'graphviz' ahead of time. #
v_mod6_genesis 890 # #
v_mod6_genesis 891 # v, version #
v_mod6_genesis 892 # Prints the version message. #
v_mod6_genesis 893 # #
v_mod6_99993 894 # h, help #
v_mod6_genesis 895 # Prints this full help message. #
v_mod6_genesis 896 # #
v_mod6_genesis 897 ################################################################################
v_mod6_genesis 898 END_LONG_HELP
v_mod6_genesis 899 return $long_help;
v_mod6_genesis 900 }
v_mod6_genesis 901
v_mod6_genesis 902 sub main {
v_mod6_99993 903 check_required_bins(@dep_bins);
v_mod6_99993 904
v_mod6_genesis 905 my $cmd;
v_mod6_genesis 906 if(@ARGV > 0) { $cmd = shift @ARGV; }
v_mod6_genesis 907 else { print "Unknown or missing option!\n"; print short_help("t"); return; }
v_mod6_genesis 908
v_mod6_genesis 909 my $pwd = get_pwd();
v_mod6_genesis 910 $wdir = "$pwd/.wot";
v_mod6_genesis 911 $pdir = "$pwd/patches";
v_mod6_genesis 912 $sdir = "$pwd/.seals";
v_mod6_genesis 913
v_mod6_genesis 914 if(($cmd =~ /^m$|^mirrors$/i ||
v_mod6_genesis 915 $cmd =~ /^i$|^init$/i ||
v_mod6_genesis 916 $cmd =~ /^wd$|^wotdir$/i ||
v_mod6_genesis 917 $cmd =~ /^pd$|^patchdir$/i ||
v_mod6_genesis 918 $cmd =~ /^sd$|^sealdir$/i ||
v_mod6_genesis 919 $cmd =~ /^p$|^press$/i ||
v_mod6_genesis 920 $cmd =~ /^ss$|^sync-seals$/i ||
v_mod6_genesis 921 $cmd =~ /^sv$|^sync-vpatches$/i ||
v_mod6_genesis 922 $cmd =~ /^sa$|^sync-all-vpatches$/i ||
v_mod6_genesis 923 $cmd =~ /^sa$|^sync-all-vpatches$/i ||
v_mod6_genesis 924 $cmd =~ /^se$|^sync-everything$/i ||
v_mod6_genesis 925 $cmd =~ /^a$|^ante$|^antecedents$/i ||
v_mod6_genesis 926 $cmd =~ /^d$|^desc$|^descendants$/i ||
v_mod6_genesis 927 $cmd =~ /^o$|^origin$/i ||
v_mod6_genesis 928 $cmd =~ /^g$|^graph$/i) && !@ARGV) {
v_mod6_genesis 929 print "Option \"$cmd\" requires arguments!\n";
v_mod6_genesis 930 print short_help("t"); return;
v_mod6_genesis 931 }
v_mod6_genesis 932
v_mod6_genesis 933 my @tmp = ();
v_mod6_genesis 934 while(@ARGV > 0) {
v_mod6_genesis 935 if($ARGV[0] =~ /^wd$|^wotdir$/) {
v_mod6_genesis 936 shift @ARGV; $wdir = shift @ARGV; next;
v_mod6_genesis 937 } elsif($ARGV[0] =~ /^pd$|^patchdir$/) {
v_mod6_genesis 938 shift @ARGV; $pdir = shift @ARGV; next;
v_mod6_genesis 939 } elsif($ARGV[0] =~ /^sd$|^sealdir$/) {
v_mod6_genesis 940 shift @ARGV; $sdir = shift @ARGV; next;
v_mod6_genesis 941 } else {
v_mod6_genesis 942 push @tmp, shift @ARGV;
v_mod6_genesis 943 }
v_mod6_genesis 944 }
v_mod6_genesis 945 @ARGV = @tmp;
v_mod6_genesis 946
v_mod6_genesis 947 @wfiles = set_files($wdir);
v_mod6_genesis 948 build_wot();
v_mod6_genesis 949
v_mod6_99993 950 if($cmd =~ /^h$|^help$/) { print long_help(); return; }
v_mod6_genesis 951 if($cmd =~ /^i$|^init$/) {
v_mod6_genesis 952 if(@ARGV == 1) {
v_mod6_genesis 953 init(@ARGV, $pdir, $sdir); return;
v_mod6_genesis 954 } elsif(@ARGV == 3) {
v_mod6_genesis 955 $sdir = pop @ARGV; $pdir = pop @ARGV;
v_mod6_genesis 956 init(@ARGV, $pdir, $sdir); return;
v_mod6_genesis 957 } else {
v_mod6_genesis 958 print "Incorrect number of arguments passed to init!\n";
v_mod6_genesis 959 print short_help("t"); return;
v_mod6_genesis 960 }
v_mod6_genesis 961 }
v_mod6_genesis 962
v_mod6_genesis 963 if($cmd =~ /^m$|^mirrors$/) { print_mirrors(@ARGV); return; }
v_mod6_genesis 964 if($cmd =~ /^w$|^wot$/) { print_wot(@ARGV); return; }
v_mod6_genesis 965 if($cmd =~ /^v$|^version$/) { print get_version(); return; }
v_mod6_genesis 966
v_mod6_genesis 967 @pfiles = set_files($pdir);
v_mod6_genesis 968 @sfiles = set_files($sdir);
v_mod6_genesis 969
v_mod6_genesis 970 validate_seals();
v_mod6_genesis 971 build_map();
v_mod6_genesis 972 my @flow = build_flow();
v_mod6_genesis 973
v_mod6_genesis 974 if ($cmd =~ /^r$|^roots$/) { print_roots(); }
v_mod6_genesis 975 elsif($cmd =~ /^l$|^leafs$/) { print_leafs(); }
v_mod6_genesis 976 elsif($cmd =~ /^f$|^flow$/) { print_flow(@flow); }
v_mod6_99993 977 elsif($cmd =~ /^pp$|^press-path$/) { print_press_path(@ARGV); }
v_mod6_genesis 978 elsif($cmd =~ /^p$|^press$/) {
v_mod6_genesis 979 if(@ARGV < 2) {
v_mod6_genesis 980 print "$cmd requires two arguments: (<press_dir> <head>)\n\n";
v_mod6_genesis 981 print short_help("t"); }
v_mod6_genesis 982 else { press_vpatches(\@ARGV, @flow); } }
v_mod6_genesis 983 elsif($cmd =~ /^ss$|^sync-seals$/) {
v_mod6_genesis 984 if(@ARGV < 2) {
v_mod6_genesis 985 print "$cmd requires two arguments: (<mirror_url> <sdir>)\n\n";
v_mod6_genesis 986 print short_help("t"); }
v_mod6_genesis 987 else { sync_seals(@ARGV); } }
v_mod6_genesis 988 elsif($cmd =~ /^sv$|^sync-vpatches$/) {
v_mod6_genesis 989 if(@ARGV < 3) {
v_mod6_genesis 990 print "$cmd requires three arguments: " .
v_mod6_genesis 991 "(<mirror_url> <pdir> <vpatch>... )\n\n"; print short_help("t"); }
v_mod6_genesis 992 else { sync_vpatches(@ARGV); } }
v_mod6_genesis 993 elsif($cmd =~ /^sa$|^sync-all-vpatches$/) {
v_mod6_genesis 994 if(@ARGV < 2) {
v_mod6_genesis 995 print "$cmd requires two arguments: " .
v_mod6_genesis 996 "(<mirror_url> <pdir>)\n\n"; print short_help("t"); }
v_mod6_genesis 997 else { sync_all_vpatches(@ARGV); } }
v_mod6_genesis 998 elsif($cmd =~ /^se$|^sync-everything$/) {
v_mod6_genesis 999 if(@ARGV < 3) {
v_mod6_genesis 1000 print "$cmd requires three arguments: " .
v_mod6_genesis 1001 "(<mirror_url> <pdir> <sdir>)\n\n"; print short_help("t"); }
v_mod6_genesis 1002 else { sync_everything(@ARGV); } }
v_mod6_genesis 1003 elsif($cmd =~ /^a$|^ante$|^antecedents$/) { print_antecedents(@ARGV); }
v_mod6_genesis 1004 elsif($cmd =~ /^d$|^desc$|^descendants$/) { print_descendants(@ARGV); }
v_mod6_genesis 1005 elsif($cmd =~ /^o$|^origin$/) { print_origin(@ARGV); }
v_mod6_genesis 1006 elsif($cmd =~ /^g$|^graph$/) {
v_mod6_genesis 1007 my $mod = "Graph::Easy";
v_mod6_genesis 1008 (my $req = $mod . ".pm") =~ s{::}{/}g;
v_mod6_genesis 1009 require $req;
v_mod6_genesis 1010 $graph = $mod->new();
v_mod6_genesis 1011 print_graph(rank_leafs_gviz(), @ARGV); }
v_mod6_genesis 1012 else { print "Unknown option: \"$cmd\"\n"; print short_help("t"); }
v_mod6_genesis 1013 }
v_mod6_genesis 1014
v_mod6_99993 1015 make_tmpdir();
v_mod6_genesis 1016 main();
v_mod6_genesis 1017 remove_tmpdir($tdir);