aboutsummaryrefslogtreecommitdiff
path: root/bpkg/pkg-verify.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-03-10 11:34:05 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-03-11 21:10:44 +0300
commitd452df33a8b702c9992da01e5963e4c4d89f0689 (patch)
tree6d3d06f94d76dd6191502fd64d89d5aef8bd78d7 /bpkg/pkg-verify.cxx
parent6d036eb95b33b9968e5e95e3e3e9b5a42ba99cc9 (diff)
Make rep_create to convert file-type manifest values to corresponding inline-type ones
Diffstat (limited to 'bpkg/pkg-verify.cxx')
-rw-r--r--bpkg/pkg-verify.cxx180
1 files changed, 78 insertions, 102 deletions
diff --git a/bpkg/pkg-verify.cxx b/bpkg/pkg-verify.cxx
index 292ea86..3c79cbd 100644
--- a/bpkg/pkg-verify.cxx
+++ b/bpkg/pkg-verify.cxx
@@ -11,6 +11,7 @@
#include <bpkg/manifest-parser>
+#include <bpkg/archive>
#include <bpkg/diagnostics>
using namespace std;
@@ -20,135 +21,110 @@ namespace bpkg
{
package_manifest
pkg_verify (const common_options& co, const path& af, bool iu, bool diag)
+ try
{
- // Figure out the package directory. Strip the top-level extension
- // and, as a special case, if the second-level extension is .tar,
- // strip that as well (e.g., .tar.bz2).
- //
- path pd (af.leaf ().base ());
- if (const char* e = pd.extension ())
- {
- if (e == string ("tar"))
- pd = pd.base ();
- }
-
- // Extract the manifest.
- //
+ dir_path pd (package_dir (af));
path mf (pd / path ("manifest"));
- cstrings args {co.tar ().string ().c_str ()};
-
- // Add extra options.
+ // If diag is false, we need to make tar not print any diagnostics.
+ // There doesn't seem to be an option to suppress this and the only
+ // way is to redirect STDERR to something like /dev/null. To keep
+ // things simple, we are going to redirect it to STDOUT, which we
+ // in turn redirect to a pipe and use to parse the manifest data.
+ // If things go badly for tar and it starts spitting errors instead
+ // of the manifest, the manifest parser will fail. But that's ok
+ // since we assume that the child error is always the reason for
+ // the manifest parsing failure.
//
- for (const string& o: co.tar_option ())
- args.push_back (o.c_str ());
+ process pr (start_extract (co, af, mf, diag));
- // -O/--to-stdout -- extract to STDOUT.
- //
- args.push_back ("-O");
-
- args.push_back ("-xf");
- args.push_back (af.string ().c_str ());
- args.push_back (mf.string ().c_str ());
- args.push_back (nullptr);
-
- if (verb >= 2)
- print_process (args);
+ ifdstream is (pr.in_ofd);
+ is.exceptions (ifdstream::badbit | ifdstream::failbit);
try
{
- // If diag is false, we need to make tar not print any diagnostics.
- // There doesn't seem to be an option to suppress this and the only
- // way is to redirect STDERR to something like /dev/null. To keep
- // things simple, we are going to redirect it to STDOUT, which we
- // in turn redirect to a pipe and use to parse the manifest data.
- // If things go badly for tar and it starts spitting errors instead
- // of the manifest, the manifest parser will fail. But that's ok
- // since we assume that the child error is always the reason for
- // the manifest parsing failure.
- //
- process pr (args.data (), 0, -1, (diag ? 2 : 1));
+ manifest_parser mp (is, mf.string ());
+ package_manifest m (mp, iu);
+ is.close ();
- try
+ if (pr.wait ())
{
- ifdstream is (pr.in_ofd);
- is.exceptions (ifdstream::badbit | ifdstream::failbit);
-
- manifest_parser mp (is, mf.string ());
- package_manifest m (mp, iu);
- is.close ();
+ // Verify package archive/directory is <name>-<version>.
+ //
+ dir_path ed (m.name + "-" + m.version.string ());
- if (pr.wait ())
- {
- // Verify package archive/directory is <name>-<version>.
- //
- path ed (m.name + "-" + m.version.string ());
-
- if (pd != ed)
- {
- if (diag)
- error << "package archive/directory name mismatch in " << af <<
- info << "extracted from archive '" << pd << "'" <<
- info << "expected from manifest '" << ed << "'";
-
- throw failed ();
- }
-
- return m;
- }
-
- // Child existed with an error, fall through.
- }
- // Ignore these exceptions if the child process exited with
- // an error status since that's the source of the failure.
- //
- catch (const manifest_parsing& e)
- {
- if (pr.wait ())
+ if (pd != ed)
{
if (diag)
- error (e.name, e.line, e.column) << e.description <<
- info << "package archive " << af;
+ error << "package archive/directory name mismatch in " << af <<
+ info << "extracted from archive '" << pd << "'" <<
+ info << "expected from manifest '" << ed << "'";
throw failed ();
}
- }
- catch (const ifdstream::failure&)
- {
- if (pr.wait ())
- {
- if (diag)
- error << "unable to extract " << mf << " from " << af;
- throw failed ();
- }
+ return m;
}
- // We should only get here if the child exited with an error
- // status.
+ // Child exited with an error, fall through.
+ }
+ // Ignore these exceptions if the child process exited with
+ // an error status since that's the source of the failure.
+ //
+ catch (const manifest_parsing& e)
+ {
+ // Before we used to just close the file descriptor to signal to the
+ // other end that we are not interested in the rest. But tar doesn't
+ // take this very well (SIGPIPE). So now we are going to skip until
+ // the end.
//
- assert (!pr.wait ());
+ if (!is.eof ())
+ is.ignore (numeric_limits<streamsize>::max ());
+ is.close ();
- // While it is reasonable to assuming the child process issued
- // diagnostics, tar, specifically, doesn't mention the archive
- // name.
- //
- if (diag)
- error << af << " does not appear to be a bpkg package";
+ if (pr.wait ())
+ {
+ if (diag)
+ error (e.name, e.line, e.column) << e.description <<
+ info << "package archive " << af;
- throw failed ();
+ throw failed ();
+ }
}
- catch (const process_error& e)
+ catch (const ifdstream::failure&)
{
- // Note: this is not an "invalid package" case, so no diag check.
- //
- error << "unable to execute " << args[0] << ": " << e.what ();
+ is.close ();
- if (e.child ())
- exit (1);
+ if (pr.wait ())
+ {
+ if (diag)
+ error << "unable to extract " << mf << " from " << af;
- throw failed ();
+ throw failed ();
+ }
}
+
+ // We should only get here if the child exited with an error
+ // status.
+ //
+ assert (!pr.wait ());
+
+ // While it is reasonable to assuming the child process issued
+ // diagnostics, tar, specifically, doesn't mention the archive
+ // name.
+ //
+ if (diag)
+ error << af << " does not appear to be a bpkg package";
+
+ throw failed ();
+ }
+ catch (const process_error& e)
+ {
+ // Note: this is not an "invalid package" case, so no diag check.
+ //
+ error << "unable to extract manifest file from " << af << ": "
+ << e.what ();
+ throw failed ();
}
package_manifest