// file : bbot/utility.txx -*- C++ -*- // license : MIT; see accompanying LICENSE file #include // cin #include #include #include #include namespace bbot { // run_*() // template process run_io_start (tracer& t, I&& in, O&& out, E&& err, const process_env& pe, A&&... args) { try { return butl::process_start_callback ( t, forward (in), forward (out), forward (err), pe, forward (args)...); } catch (const process_error& e) { fail << "unable to execute " << *pe.path << ": " << e << endf; } } template process_exit::code_type run_io_finish_exit (tracer&, process& pr, const P& p, bool fh) { try { pr.wait (); const process_exit& e (*pr.exit); if (!e.normal ()) fail (fh) << "process " << p << " " << e; return e.code (); } catch (const process_error& e) { fail (fh) << "unable to execute " << p << ": " << e << endf; } } template inline void run_io_finish (tracer& t, process& pr, const P& p, bool fh) { if (run_io_finish_exit (t, pr, p, fh) != 0) fail (fh) << "process " << p << " exited with non-zero code"; } template inline process_exit::code_type run_io_exit (tracer& t, I&& in, O&& out, E&& err, const P& p, A&&... args) { process pr (run_io_start (t, forward (in), forward (out), forward (err), p, forward (args)...)); return run_io_finish_exit (t, pr, p); } template inline void run_io (tracer& t, I&& in, O&& out, E&& err, const P& p, A&&... args) { process pr (run_io_start (t, forward (in), forward (out), forward (err), p, forward (args)...)); run_io_finish (t, pr, p); } // curl // template http_curl:: http_curl (tracer& t, I&& in, O&& out, method_type m, const string& url, A&&... options) : butl::curl (t, forward (in), forward (out), 2, // Diagnostics to stderr. m, url, "-A", BBOT_USER_AGENT, forward (options)...) { } template tftp_curl:: tftp_curl (tracer& t, I&& in, O&& out, method_type m, const string& url, A&&... options) : butl::curl (t, forward (in), forward (out), 2, // Diagnostics to stderr. m, url, forward (options)...) { } // *_manifest() // template T parse_manifest (const path& f, const char* what, bool fh, bool iu) { using namespace butl; try { if (f.string () == "-") return parse_manifest (std::cin, "", what, fh, iu); if (!file_exists (f)) fail (fh) << what << " manifest file " << f << " does not exist"; bool d (f.extension () == "lz4"); ifdstream ifs (f, (d ? fdopen_mode::binary : fdopen_mode::none), (d ? ifdstream::badbit : ifdstream::badbit | ifdstream::failbit)); ilz4stream izs; if (d) izs.open (ifs, true /* end */); return parse_manifest (d ? static_cast (izs) : static_cast (ifs), f.string (), what, fh, iu); } catch (const invalid_argument& e) // Invalid compressed content. { fail (fh) << "invalid " << what << " manifest " << f << ": " << e << endf; } catch (const system_error& e) // EACCES, etc. { fail (fh) << "unable to access " << what << " manifest " << f << ": " << e << endf; } } template T parse_manifest (istream& is, const string& name, const char* what, bool fh, bool iu) { using namespace butl; try { manifest_parser p (is, name); return T (p, iu); } catch (const manifest_parsing& e) { fail (fh) << "invalid " << what << " manifest: " << name << ':' << e.line << ':' << e.column << ": " << e.description << endf; } catch (const io_error& e) { fail (fh) << "unable to read " << what << " manifest " << name << ": " << e << endf; } } template void serialize_manifest (const T& m, const path& f, const char* what, bool ll) { using namespace std; using namespace butl; try { ofdstream ofs (f, fdopen_mode::binary); auto_rmfile arm (f); // Try to remove on failure ignoring errors. serialize_manifest (m, ofs, f.string (), what, true, ll); ofs.close (); arm.cancel (); } catch (const system_error& e) // EACCES, etc. { fail << "unable to access " << what << " manifest " << f << ": " << e; } } template void serialize_manifest (const T& m, ostream& os, const string& name, const char* what, bool fh, bool ll) { using namespace butl; try { manifest_serializer s (os, name, ll); m.serialize (s); return; } catch (const manifest_serialization& e) { fail (fh) << "invalid " << what << " manifest: " << e.description; } catch (const io_error& e) { fail (fh) << "unable to write to " << what << " manifest " << name << ": " << e; } } }