Dynamically load SetDefaultDllDirectories()
[cygwin-setup.git] / package_source.cc
blob2b5909bf5cd70f088d4304b91a3772b29eb60d62
1 /*
2 * Copyright (c) 2001, Robert Collins.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
12 * Written by Robert Collins <rbtcollins@hotmail.com>
16 /* this is the parent class for all package source (not source code - installation
17 * source as in http/ftp/disk file) operations.
20 #include "package_source.h"
21 #include "sha2.h"
22 #include "csu_util/MD5Sum.h"
23 #include "LogFile.h"
24 #include "threebar.h"
25 #include "Exception.h"
26 #include "filemanip.h"
27 #include "io_stream.h"
28 #include "resource.h"
30 extern ThreeBarProgressPage Progress;
32 site::site (const std::string& newkey) : key(newkey)
36 void
37 packagesource::set_canonical (char const *fn)
39 canonical = fn;
40 size_t found = canonical.find_last_of ("/");
41 shortname = canonical.substr (found + 1);
44 void
45 packagesource::set_cached (const std::string& fp)
47 cached = fp;
50 void
51 packagesource::check_size_and_cache (const std::string fullname)
53 DWORD fnsize = get_file_size (fullname);
54 if (fnsize != size)
56 Log (LOG_BABBLE) << "INVALID PACKAGE: " << fullname
57 << " - Size mismatch: Ini-file: " << size
58 << " != On-disk: " << fnsize << endLog;
59 throw new Exception (TOSTRING(__LINE__) " " __FILE__,
60 "Size mismatch for " + fullname,
61 APPERR_CORRUPT_PACKAGE);
63 cached = fullname;
64 validated = false;
67 void
68 packagesource::check_hash ()
70 if (validated || cached.empty ())
71 return;
73 if (sha512_isSet)
75 check_sha512 (cached);
76 validated = true;
78 else if (md5.isSet())
80 check_md5 (cached);
81 validated = true;
83 else
84 Log (LOG_BABBLE) << "No checksum recorded for " << cached
85 << ", cannot determine integrity of package!"
86 << endLog;
89 static char *
90 sha512_str (const unsigned char *in, char *buf)
92 char *bp = buf;
93 for (int i = 0; i < SHA512_DIGEST_LENGTH; ++i)
94 bp += sprintf (bp, "%02x", in[i]);
95 *bp = '\0';
96 return buf;
99 void
100 packagesource::check_sha512 (const std::string fullname) const
102 io_stream *thefile = io_stream::open (fullname, "rb", 0);
103 if (!thefile)
104 throw new Exception (TOSTRING (__LINE__) " " __FILE__,
105 std::string ("IO Error opening ") + fullname,
106 APPERR_IO_ERROR);
107 SHA2_CTX ctx;
108 unsigned char sha512result[SHA512_DIGEST_LENGTH];
109 char ini_sum[SHA512_DIGEST_STRING_LENGTH],
110 disk_sum[SHA512_DIGEST_STRING_LENGTH];
112 SHA512Init (&ctx);
114 Log (LOG_BABBLE) << "Checking SHA512 for " << fullname << endLog;
116 std::wstring fmt = LoadStringW(IDS_PROGRESS_CHECKING_HASH);
117 std::wstring s = format(fmt, "SHA512", shortname.c_str());
118 Progress.SetText1 (s.c_str());
119 Progress.SetText4 (IDS_PROGRESS_PROGRESS);
120 Progress.SetBar1 (0);
122 unsigned char buffer[64 * 1024];
123 ssize_t count;
124 while ((count = thefile->read (buffer, sizeof (buffer))) > 0)
126 SHA512Update (&ctx, buffer, count);
127 Progress.SetBar1 (thefile->tell (), thefile->get_size ());
129 delete thefile;
130 if (count < 0)
131 throw new Exception (TOSTRING(__LINE__) " " __FILE__,
132 "IO Error reading " + fullname,
133 APPERR_IO_ERROR);
135 SHA512Final (sha512result, &ctx);
137 if (memcmp (sha512sum, sha512result, sizeof sha512result))
139 Log (LOG_BABBLE) << "INVALID PACKAGE: " << fullname
140 << " - SHA512 mismatch: Ini-file: "
141 << sha512_str (sha512sum, ini_sum)
142 << " != On-disk: "
143 << sha512_str (sha512result, disk_sum)
144 << endLog;
145 throw new Exception (TOSTRING(__LINE__) " " __FILE__,
146 "SHA512 failure for " + fullname,
147 APPERR_CORRUPT_PACKAGE);
150 Log (LOG_BABBLE) << "SHA512 verified OK: " << fullname << " "
151 << sha512_str (sha512sum, ini_sum) << endLog;
154 void
155 packagesource::check_md5 (const std::string fullname) const
157 io_stream *thefile = io_stream::open (fullname, "rb", 0);
158 if (!thefile)
159 throw new Exception (TOSTRING (__LINE__) " " __FILE__,
160 std::string ("IO Error opening ") + fullname,
161 APPERR_IO_ERROR);
162 MD5Sum tempMD5;
163 tempMD5.begin ();
165 Log (LOG_BABBLE) << "Checking MD5 for " << fullname << endLog;
167 std::wstring fmt = LoadStringW(IDS_PROGRESS_CHECKING_HASH);
168 std::wstring s = format(fmt, "MD5", shortname);
169 Progress.SetText1 (s.c_str());
170 Progress.SetText4 (IDS_PROGRESS_PROGRESS);
171 Progress.SetBar1 (0);
173 unsigned char buffer[64 * 1024];
174 ssize_t count;
175 while ((count = thefile->read (buffer, sizeof (buffer))) > 0)
177 tempMD5.append (buffer, count);
178 Progress.SetBar1 (thefile->tell (), thefile->get_size ());
180 delete thefile;
181 if (count < 0)
182 throw new Exception (TOSTRING(__LINE__) " " __FILE__,
183 "IO Error reading " + fullname,
184 APPERR_IO_ERROR);
186 tempMD5.finish ();
188 if (md5 != tempMD5)
190 Log (LOG_BABBLE) << "INVALID PACKAGE: " << fullname
191 << " - MD5 mismatch: Ini-file: " << md5.str()
192 << " != On-disk: " << tempMD5.str() << endLog;
193 throw new Exception (TOSTRING(__LINE__) " " __FILE__,
194 "MD5 failure for " + fullname,
195 APPERR_CORRUPT_PACKAGE);
198 Log (LOG_BABBLE) << "MD5 verified OK: " << fullname << " "
199 << md5.str() << endLog;