1 module gccbuild.download; 2 3 import scriptlike, gccbuild, std.digest.md; 4 5 void downloadSources() 6 { 7 8 startSection("Fetching source files"); 9 10 foreach (name, component; build.configuredComponents) 11 { 12 downloadComponent(name, component); 13 } 14 15 if (build.glibcPorts) 16 downloadComponent("glibc_ports", build.glibcPorts); 17 18 endSection(); 19 } 20 21 void downloadComponent(string name, Component component) 22 { 23 auto dlPath = component.localFile; 24 if (dlPath.exists && !forceDownload) 25 { 26 writeBulletPoint("Found " ~ component.file ~ " (cached)"); 27 if (verifyCachedSources) 28 enforceChecksum(dlPath, component.md5); 29 30 endBulletPoint(); 31 } 32 else 33 { 34 string forced = dlPath.exists ? " (forced)" : ""; 35 writeBulletPoint("Downloading " ~ component.file ~ forced ~ "..."); 36 tryMkdirRecurse(dlPath.dirName); 37 tryRemove(dlPath); 38 39 string[] urls = map!(a => component.suburl.empty ? a ~ component.file : a ~ component 40 .suburl)(mirrors[name]).array; 41 if (!component.url.empty) 42 urls = [component.url] ~ urls; 43 44 foreach (url; urls) 45 { 46 try 47 { 48 runCollectLog(mixin(interp!"wget ${url} -O ${dlPath}")); 49 break; 50 } 51 catch (Exception e) 52 { 53 tryRemove(dlPath); 54 } 55 } 56 57 failEnforcec(dlPath.exists, "Failed to find a working mirror for ", component.file); 58 enforceChecksum(dlPath, component.md5); 59 endBulletPoint(); 60 } 61 } 62 63 void enforceChecksum(Path file, string sum) 64 { 65 if (!verifyFile(file, sum)) 66 failc("Invalid MD5 of ", file); 67 } 68 69 bool verifyFile(Path file, string sum) 70 { 71 auto md5 = File(file.toString()).byChunk(4096).md5Of().toHexString!(LetterCase.lower); 72 if (sicmp(md5, sum) == 0) 73 { 74 yapFunc("md5(", file, ")=", md5, " == ", sum, " => OK"); 75 return true; 76 } 77 78 yapFunc("md5(", file, ")=", md5, " == ", sum, " => FAIL"); 79 return false; 80 }