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 }