guncat-1.02.00/build0000755000175000017500000000765613312732316013163 0ustar frankfrank#!/usr/bin/icmake -qt/tmp/guncat #define LOGENV "GUNCAT" #include "icmconf" list g_log; string g_logPath = getenv(LOGENV)[1], g_logMark, // unique-marker for g_log entries g_cwd = chdir(""); // initial working directory, ends in / int g_echo = ON; // MODIFIED, existing variable int g_installing; // set to 1 by install. int g_lognr; // unique-marker number counter for g_log entries #include "icmake/setopt" #include "icmake/cuteoln" #include "icmake/backtick" #include "icmake/run" #include "icmake/md" #include "icmake/findall" #include "icmake/loginstall" #include "icmake/logzip" #include "icmake/logfile" #include "icmake/uninstall" #include "icmake/pathfile" #include "icmake/precompileheaders" #include "icmake/special" #include "icmake/clean" #include "icmake/manpage" #include "icmake/install" #include "icmake/gitlab" void main(int argc, list argv) { string option; string strip; int idx; for (idx = listlen(argv); idx--; ) { if (argv[idx] == "-q") { g_echo = OFF; argv -= (list)"-q"; } else if (argv[idx] == "-P") { g_gch = 0; argv -= (list)"-P"; } } echo(g_echo); option = argv[1]; if (option == "clean") clean(0); if (option == "distclean") clean(1); if (option == "install") install(argv[2], argv[3]); if (option == "uninstall") uninstall(argv[2]); if (option != "") special(); if (option == "gitlab") gitlab(); if (option == "man") manpage(); if (option == "library") { precompileHeaders(); system("icmbuild library"); exit(0); } if (argv[2] == "strip") strip = "strip"; if (option == "program") { precompileHeaders(); system("icmbuild program " + strip); exit(0); } if (option == "xref") { precompileHeaders(); system("icmbuild program " + strip); run("oxref -fxs tmp/lib" LIBRARY ".a > " PROGRAM ".xref"); exit(0); } printf("Usage: build [-q -P] what\n" "Where\n" " [-q]: run quietly, do not show executed commands\n" " [-P]: do not use precompiled headers\n" "`what' is one of:\n" " clean - clean up remnants of previous " "compilations\n" " distclean - clean + fully remove tmp/\n" " library - build " PROGRAM "'s library\n" " man - build the man-page (requires " "Yodl)\n" " program [strip] - build " PROGRAM " (optionally " "strip the\n" " executable)\n" " xref [strip] - same a `program', also builds " "xref file\n" " using oxref\n" " install selection [base] - to install the software in the \n" " locations defined in the INSTALL.im file,\n" " optionally below base\n" " selection can be\n" " x, to install all components,\n" " or a combination of:\n" " b (binary program),\n" " d (documentation),\n" " m (man-pages)\n" " uninstall logfile - remove files and empty directories listed\n" " in the file 'logfile'\n" " gitlab - prepare gitlab's web-pages update\n" " (internal use only)\n" "\n" ); exit(0); } guncat-1.02.00/changelog0000644000175000017500000000467213372046525014011 0ustar frankfrankguncat (1.02.00) * New options: errors-OK, time-limit; disused options: gpg-no-batch, locate-keys * Refined the Decryptor's handlePGP / insertPGPsection implementations * The passphrase is requested at the start of the program to avoid interference with output to the std. output stream * Updated options passed to gpg to gpg version 2.1, see the description of the --passphrase-fd option in the gpg(1) manual page. * Using compilation option --std=c++2a * Updated usage and man-page -- Frank B. Brokken Sun, 11 Nov 2018 16:03:27 +0100 guncat (1.01.03) * Migrated from Github to Gitlab. * Updated the C++ standard to use to c++17. * Added header-precompilation to icmconf. * Removed comment from CLASSES -- Frank B. Brokken Thu, 21 Jun 2018 19:18:26 +0530 guncat (1.01.02) * Updated the build script to icmake 8.00.04. -- Frank B. Brokken Sat, 12 Dec 2015 15:12:24 +0100 guncat (1.01.01) * Kevin Brodsky observed that the installation scripts used 'chdir' rather than 'cd'. Fixed in this release. * Kevin Brodsky also observed that the combined size of all precompiled headers might exceed some disks capacities. The option -P was added to the ./build script to prevent the use of precompiled headers. -- Frank B. Brokken Mon, 05 Oct 2015 21:25:25 +0200 guncat (1.01.00) * Update to version 1.00.00 after being operational for over one year without issues. * Added 'build uninstall'. * Updated 'INSTALL' * Guncat depends on libbobcat >= 4.00.00 (see 'required') * Standardized the (de)installation procedures -- Frank B. Brokken Sun, 04 Oct 2015 10:32:32 +0200 guncat (0.92.00) * The GPG passphrase is now requested only once. It is only requested again if a provided passphrase was incorrect. -- Frank B. Brokken Tue, 27 May 2014 15:57:34 +0200 guncat (0.91.00) * The GPG passphrase is read from /dev/tty, and not from the std. input stream (cin) anymore -- Frank B. Brokken Sun, 04 May 2014 10:55:53 +0200 guncat (0.90.00) * Initial completion of the program and man-page. -- Frank B. Brokken Sat, 03 May 2014 11:48:43 +0200 guncat (0.00.00) * Preparing the sourceforge archive, and finalizing release 0.00.00 -- Frank B. Brokken Wed, 30 Apr 2014 15:10:18 +0200 guncat-1.02.00/CLASSES0000644000175000017500000000003713372042752013144 0ustar frankfrankguncat decryptor gpipe globals guncat-1.02.00/decryptor/0000755000175000017500000000000013372055735014144 5ustar frankfrankguncat-1.02.00/decryptor/getpassphrase.cc0000644000175000017500000000077013372042752017323 0ustar frankfrank#include "decryptor.ih" void Decryptor::getPassphrase() { if (not d_passphrase.empty()) return; struct termios ttySaved; int fd = echo(&ttySaved); // switch off echoing, fd to /dev/tty cerr << "Enter passphrase: "; IFdStream in(fd); // get the passphrase from /dev/tty getline(in, d_passphrase); cerr << '\n'; // echo the Enter following the passphrase echo(&ttySaved, true); // restore the echoing state } guncat-1.02.00/decryptor/decryptor.ih0000644000175000017500000000070713372046525016502 0ustar frankfrank#include "decryptor.h" #include #define XERR std::cerr << __FILE__": " #include #include #include #include #include #include #include #include #include #include #include #include "../gpipe/gpipe.h" #include "../globals/globals.h" using namespace std; using namespace FBB; guncat-1.02.00/decryptor/passphrasefd.cc0000644000175000017500000000052313372042752017131 0ustar frankfrank#include "decryptor.ih" string Decryptor::passphraseFd(Pipe &pipe) const { string ret; if (not d_passphrase.empty()) { ret = " --pinentry-mode loopback --passphrase-fd " + to_string(pipe.readFd()); OFdStream pwd(pipe.writeFd()); pwd << d_passphrase << endl; } return ret; } guncat-1.02.00/decryptor/retrypassphrase.cc0000644000175000017500000000131113372046525017703 0ustar frankfrank#include "decryptor.ih" bool Decryptor::retryPassphrase(PwdInfo &pwdInfo) { if (not d_firstSection) return false; if (d_optionP) throw Exception{} << "Incorrect passphrase on 1st line of input"; if (pwdInfo.retry == 3) throw Exception{} << "Quitting after three passphrase attempts\n"; cerr << "Incorrect passphrase. Try again...\n"; d_passphrase.clear(); getPassphrase(); if (not pwdInfo.in->seekg(pwdInfo.offset)) throw Exception{} << "Cannot reset " << g_filename << " to the PGP section at line " << pwdInfo.lineNr; ++pwdInfo.retry; return true; } guncat-1.02.00/decryptor/handlegpg.cc0000644000175000017500000000160413372055573016405 0ustar frankfrank#include "decryptor.ih" void Decryptor::handleGPG(istream &in, string const &pgpHeader) { PwdInfo pwdInfo{ &in, in.tellg(), g_lineNr, 1 }; while (true) { GPipe pipe; Process gpg(Process::CIN | Process::CERR, d_gpg + passphraseFd(pipe) + d_gpgOptions); if (d_timeLimit != 0) gpg.setTimeLimit(d_timeLimit); switch (insertPGPsection(gpg, pgpHeader, in)) { case 2: // incorrect passphrase if (retryPassphrase(pwdInfo)) continue; [[fallthrough]]; default: // some error... gpgError(gpg); [[fallthrough]]; case 0: // no errors d_firstSection = false; return; // this section is now completed } } } guncat-1.02.00/decryptor/showgpg.cc0000644000175000017500000000026513372042752016127 0ustar frankfrank#include "decryptor.ih" void Decryptor::showGPG() const { cout << d_gpg << " --pinentry-mode loopback --passphrase-fd " << d_gpgOptions << '\n'; throw 0; } guncat-1.02.00/decryptor/setpassphrase.cc0000644000175000017500000000026113372042752017332 0ustar frankfrank#include "decryptor.ih" void Decryptor::setPassphrase(std::string &passphrase) { d_passphrase = std::move(passphrase); d_optionP = not d_passphrase.empty(); } guncat-1.02.00/decryptor/gpgerror.cc0000644000175000017500000000054713372046525016305 0ustar frankfrank#include "decryptor.ih" void Decryptor::gpgError(Process &gpg) { ostringstream out; out << gpg.childErrStream().rdbuf(); if (d_msg) *d_msg << out.str() << endl; if (not d_errorsOK) throw Exception{} << fileInfo() << ":\n" << out.str() << "\n" "Terminating " << d_arg.basename(); } guncat-1.02.00/decryptor/decryptor.h0000644000175000017500000000325713372046525016334 0ustar frankfrank#ifndef INCLUDED_DECRYPTOR_ #define INCLUDED_DECRYPTOR_ #include #include struct termios; namespace FBB { class Arg; class Process; class Pipe; } class Decryptor { struct PwdInfo { std::istream *in; off_t offset; size_t lineNr; size_t retry; }; FBB::Arg &d_arg; size_t d_timeLimit = 0; bool d_firstSection = true; // pwd only requested 3x at the 1st section bool d_optionP = false; bool d_errorsOK; std::string d_gpg; std::string d_gpgOptions; std::string d_passphrase; std::ofstream d_fmsg; std::ostream *d_msg = 0; public: Decryptor(); ~Decryptor(); // set by Guncat on -p void setPassphrase(std::string &passphrase); void getPassphrase(); // line must contain the // BEGIN PGP MESSAGE header void handleGPG(std::istream &in, std::string const &pgpHeader); void showGPG() const; // throws 0, called from // Guncat() private: int echo(struct termios *ttySaved, bool reset = false) const; void setVerbosity(); void addGPGoptions(); // add --gpg-option values std::string passphraseFd(FBB::Pipe &pipe) const; int insertPGPsection(FBB::Process &gpg, std::string const &pgpHeader, std::istream &in); bool retryPassphrase(PwdInfo &pwdInfo); void gpgError(FBB::Process &gpg); }; #endif guncat-1.02.00/decryptor/echo.cc0000644000175000017500000000054613312732316015365 0ustar frankfrank#include "decryptor.ih" int Decryptor::echo(struct termios *ttySaved, bool reset) const { int fd = open("/dev/tty", O_RDONLY); struct termios tty; tcgetattr(fd, &tty); if (reset) tty = *ttySaved; else { *ttySaved = tty; tty.c_lflag &= ~ECHO; } tcsetattr(fd, TCSANOW, &tty); return fd; } guncat-1.02.00/decryptor/decryptor1.cc0000644000175000017500000000224013372046525016542 0ustar frankfrank#include "decryptor.ih" Decryptor::Decryptor() : d_arg(Arg::instance()), d_errorsOK(d_arg.option(0, "errors-OK")), d_gpgOptions(" --no-auto-key-locate --decrypt --batch") { if (not d_arg.option(&d_gpg, "gpg")) // override default gpg location d_gpg = "/usr/bin/gpg"; string value; if (d_arg.option(&value, 'm')) // get the name of the msg. file { if (value == "-") d_msg = &cerr; // write to cerr else { Exception::open(d_fmsg, value); // or open a file d_msg = &d_fmsg; } } if (not d_arg.option('t')) // by default --no-tty is used d_gpgOptions += " --no-tty"; value.clear(); if (d_arg.option(&value, 'T')) d_timeLimit = stoul(value); // set the gpg time-limit setVerbosity(); // set GPG's verbosity addGPGoptions(); // add gpg-option values if (d_arg.option('l')) wmsg << "Option --locate-keys is disused\n"; if (d_arg.option(0, "gpg-no-batch")) wmsg << "Option --gpg-no-batch is disused\n"; } guncat-1.02.00/decryptor/destructor.cc0000644000175000017500000000040413312732316016636 0ustar frankfrank#include "decryptor.ih" Decryptor::~Decryptor() { // interactive passphrase, and passphrase // was provided if (d_arg.option('p') && not d_passphrase.empty()) cerr << '\n'; } guncat-1.02.00/decryptor/setverbosity.cc0000644000175000017500000000112613371765511017214 0ustar frankfrank#include "decryptor.ih" void Decryptor::setVerbosity() { string verbosity; if (not d_arg.option(&verbosity, "verbose")) d_gpgOptions += " --quiet"; else { switch (verbosity[0]) { case '0': d_gpgOptions += " --no-verbose"; return; case '2': d_gpgOptions += " -verbose"; // FALLING THRU case '1': d_gpgOptions += " -verbose"; return; default: throw Exception() << "--verbose needs 0, 1 or 2"; } } } guncat-1.02.00/decryptor/addgpgoptions.cc0000644000175000017500000000063613372042752017315 0ustar frankfrank#include "decryptor.ih" void Decryptor::addGPGoptions() { string option; if (size_t nOptions = d_arg.option(&option, "gpg-option")) { d_gpgOptions += ' '; d_gpgOptions += option; for (size_t idx = 1; idx != nOptions; ++idx) { d_arg.option(idx, &option, "gpg-option"); d_gpgOptions += ' '; d_gpgOptions += option; } } } guncat-1.02.00/decryptor/insertgpgsection.cc0000644000175000017500000000072513372055425020042 0ustar frankfrank#include "decryptor.ih" int Decryptor::insertPGPsection(Process &gpg, string const &pgpHeader, istream &in) { gpg.start(); if (d_msg) *d_msg << fileInfo() << ": PGP HEADER" << endl; gpg << pgpHeader << '\n'; string line; do { nextline(in, line); gpg << line << '\n'; } while (line.find("-----END PGP MESSAGE-----") != 0); gpg.close(); return gpg.waitForChild(); } guncat-1.02.00/decryptor/driver/0000755000175000017500000000000013372046525015434 5ustar frankfrankguncat-1.02.00/decryptor/driver/getpassphrase.cc0000644000175000017500000000066513372046525020623 0ustar frankfrank#include "main.ih" void getPassphrase() { struct termios ttySaved; int fd = echo(&ttySaved); // switch off echoing, fd to /dev/tty cerr << "Enter passphrase: "; IFdStream in(fd); // get the passphrase from /dev/tty getline(in, d_passphrase); cerr << '\n'; // echo the Enter following the passphrase echo(&ttySaved, true); // restore the echoing state } guncat-1.02.00/decryptor/driver/pipepassphrase.cc0000644000175000017500000000041113372046525020766 0ustar frankfrank#include "main.ih" string pipePassphrase(Pipe &pipe) { string ret{ " --batch --pinentry-mode loopback --passphrase-fd " + to_string(pipe.readFd()) }; OFdStream pwd(pipe.writeFd()); pwd << d_passphrase << endl; return ret; } guncat-1.02.00/decryptor/driver/icmconf0000644000175000017500000000124713372046525017001 0ustar frankfrank#define CLS //#define LIBRARY "modules" #define MAIN "main.cc" #define SOURCES "*.cc" #define OBJ_EXT ".o" #define TMP_DIR "tmp" //#define USE_ALL "a" #define USE_ECHO ON //#define CXX "clang++" #define CXX "g++" #define CXXFLAGS " --std=c++2a -Wall -O2 -pthread" \ " -fdiagnostics-color=never " #define IH ".ih" //#define PRECOMP "-x c++-header" #define REFRESH #define LDFLAGS "-s" #define ADD_LIBRARIES "bobcat" #define ADD_LIBRARY_PATHS "" #define DEFCOM "program" guncat-1.02.00/decryptor/driver/main.cc0000644000175000017500000000406013372046525016667 0ustar frankfrank#include "main.ih" namespace { void collect(ostream *outStream, streambuf *rdbuf) { *outStream << rdbuf << flush; } } string d_passphrase; int main(int argc, char **argv) try { if (argc == 1) throw Exception{} << "1st argument must be an encrypted file"; ifstream encrypted{ argv[1] }; ofstream out{ argv[1] + ".dec"s }; size_t count = 0; string line; while (getline(encrypted, line)) { if (line.find("-----BEGIN PGP MESSAGE-----") != 0) { out << line << '\n'; continue; } if (d_passphrase.empty()) { getPassphrase(); // cout << d_passphrase << '\n'; } Pipe pipe; string passPhraseFdOption = pipePassphrase(pipe); cout << ++count << ' ' << passPhraseFdOption << ", read fd = " << pipe.readFd() << '\n'; // IFdStream in{ pipe.readFd() }; // cout << in.rdbuf() << '\n'; string pgpCommand{ "/usr/bin/gpg --no-tty --no-auto-key-locate " + passPhraseFdOption + // " --verbose " " --decrypt " }; // cout << "PGP command: " << pgpCommand << '\n'; Process gpg{ Process::ALL, pgpCommand }; gpg.setTimeLimit(5); gpg.start(); thread outThread(collect, &out, gpg.childOutStream().rdbuf()); gpg << line << endl; do { getline(encrypted, line); gpg << line << endl; } while (line.find("-----END PGP MESSAGE-----") != 0); gpg.close(); outThread.join(); cout << "waiting..." << endl; int ret = gpg.waitForChild(); cout << "done: " << ret << endl; if (ret != 0) { cerr << gpg.childErrStream().rdbuf() << '\n'; return ret; } close(pipe.readFd()); close(pipe.writeFd()); } } catch (exception const &exc) { cerr << exc.what() << '\n'; return 1; } catch (...) { cerr << "unaccounted exception\n"; return 1; } guncat-1.02.00/decryptor/driver/echo.cc0000644000175000017500000000064713372046525016670 0ustar frankfrank#include "main.ih" int echo(struct termios *ttySaved, bool reset) { int fd = open("/dev/tty", O_RDONLY); if (fd == -1) throw Exception{} << "can't open /dev/tty: " << errnodescr; struct termios tty; tcgetattr(fd, &tty); if (reset) tty = *ttySaved; else { *ttySaved = tty; tty.c_lflag &= ~ECHO; } tcsetattr(fd, TCSANOW, &tty); return fd; } guncat-1.02.00/decryptor/driver/main.ih0000644000175000017500000000074413372046525016707 0ustar frankfrank#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace FBB; extern string d_passphrase; int echo(struct termios *ttySaved, bool reset = false); void getPassphrase(); string pipePassphrase(Pipe &pipe); guncat-1.02.00/documentation/0000755000175000017500000000000013312732316014771 5ustar frankfrankguncat-1.02.00/documentation/man/0000755000175000017500000000000013372046525015552 5ustar frankfrankguncat-1.02.00/documentation/man/guncat.yo0000644000175000017500000001476513372046525017421 0ustar frankfrankgagmacrowarning(server FILE) includefile(../../release.yo) htmlbodyopt(text)(#27408B) htmlbodyopt(bgcolor)(#FFFAF0) gagmacrowarning(guncat) mailto(f.b.brokken@rug.nl) DEFINEMACRO(lsoption)(3)(\ bf(--ARG1)=tt(ARG3) (bf(-ARG2))\ ) DEFINEMACRO(laoption)(2)(\ bf(--ARG1)=tt(ARG2)\ ) DEFINEMACRO(loption)(1)(\ bf(--ARG1)\ ) DEFINEMACRO(soption)(1)(\ bf(-ARG1)\ ) DEFINEMACRO(u)(0)(bf(guncat)) DEFINEMACRO(U)(0)(bf(Guncat)) DEFINEMACRO(g)(0)(bf(gpg)) manpage(guncat)(1)(_CurYrs_)(guncat__CurVers_.tar.gz) (guncat - unencrypting file concatenation) manpagename(guncat)(catenates files, unencrypting pgp encrypted sections) manpagesynopsis() bf(guncat) [OPTIONS] tt([file(s)]) nl() [OPTIONS] - cf. section bf(OPTIONS)nl() [file+nop()(s)] - optional files to process (cf. section bf(INPUT FILE(S)))nl() manpagedescription() U() was designed to tackle a problem encountered with (partically) PGP encrypted files (which may be encountered in, e.g., mailboxes). Tools to process text-files (like bf(grep)(1), or bf(less)(1)) may be used to process those files, but standard tools like bf(cat)(1) leave PGP encrypted sections within such files as-is. As a consequence, browsing the `real' contents (i.e., clear-text sections and the unencrypted contents of PGP encrypted sections) of those files is difficult. U() acts comparably to bf(cat), but unencrypts encrypted sections encountered in the files processed by u(), copying the unencrypted information to u()'s standard output stream, which may thereupon be processed by other tools. PGP/GPG encrypted sections are surrounded by verb( -----BEGIN PGP MESSAGE----- ) and verb( -----END PGP MESSAGE----- ) markers. Whenever u() encounters such sections they will be processed by g()(1). bf(Gpg) needs a passphrase to unencrypt such sections. The required passphrase may be provided to u(), which then forwards the passphrase to g(). When providing an incorrect passphrase to u() two additional attempts to provide the correct passphrase are provided. If the third attempt also fails, u() terminates. Furthermore, when an incorrect passphrase is provided, the currently processed file must be reset to the beginning of the encrypted section. This implies that the processed file must be em(seekable). If the file does not support seeking operations then u() also terminates. manpagesection(RETURN VALUE) U() returns 0 to the operating system unless an error occurs (0 is also returned when the option tt(--show-gpg)) is specified. manpagesection(INPUT FILE(S)) When no file arguments are provided (or when - is provided) the standard input stream is processed. When option tt(--passphrase) is specified the first line of the first file that is processed is read as the passphrase to use. When a thus specified passphrase is incorrect, u() terminates. Any other argument is considered a file (path specifications are allowed) to be processed in sequence by u(). If an argument does not refer to a readable file, u() terminates with an error message. manpageoptions() Where available, single letter options are listed between parentheses following their associated long-option variants. Single letter options require arguments if their associated long options require arguments as well. itemization( it() loption(errors-OK)nl() When specifying the option tt(--errors-OK) the input file(s) continue to be processed even if g() returns a non-zero exit value. it() laoption(gpg)(path)nl() Path to the g() program (default: tt(/usr/bin/gpg)) it() lsoption(gpg-msg)(m)(path)nl() Path to where g() and u() should write messages. Specify - to write the messages to the standard error stream. By default messages are suppressed. it() loption(gpg-no-batch)nl() Starting with u() version 1.02.00 this option is not used anymore. It will be removed in a future vestion. it() lsoption(gpg-option)(m)(option)nl() Add tt(option) to g()'s call. If the option contains blanks, surround tt(option) by single or double quotes. Option tt(gpg-option) may repeatedly be specified. it() loption(help) (soption(h))nl() Basic usage information is written to the standard output stream. it() loption(locate-keys) soption(l)nl() Starting with g() version 1.02.00 this option is not used anymore. It will be removed in a future vestion. it() loption(passphrase) soption(p)nl() By default the passphrase is read by u() after prompting the user to enter the passphrase. The passphrase is not echoed. If input redirection is used or if input files are specified option tt(--passphrase) can be specified to read the passphrase from the first line of the first input stream that is read by u(). In that case the input stream's first line is (of course) not written to the output stream. When the tt(--passphrase) option is specified and the provided password is incorrect, u() terminates. it() loption(show-gpg)nl() Show the gpg command that would be used, and quit, returning 0. it() lsoption(time-limit)(T)(seconds)nl() Option tt(--time-limit) is used to specify the max. time in seconds that g() is allowed to run while decrypting a single encrypted section. By default no time limit is used. This option is useful when the file to process might contain errors in encrypted sections (like a missing tt(END PGP MESSAGE) line). it() loption(tty-OK) soption(t)nl() Option tt(--no-tty) is not specified when calling g(). By default it is specified. it() laoption(verbose)([0-2])nl() Specifies g()'s verbosity level. When calling g(), by default tt(--quiet) is specified; with tt(--verbose 0) g()'s option tt(--no-verbose) is specified; otherwise tt(--verbose) is specified once or twice. it() loption(version) (soption(v))nl() U()'s version number is written to the standard output stream. ) manpageseealso() bf(cat)(1), bf(gpg)(1), bf(grep)(1), bf(less)(1). manpagebugs() None reported manpagesection(COPYRIGHT) This is free software, distributed under the terms of the `GNU General Public License'. Copyright remains with the author. U() is available at tt(https://fbb-git.gitlab.io/guncat/) manpagesection(ORGANIZATION) Center for Information Technology, University of Groningen. manpageauthor() Frank B. Brokken (bf(f.b.brokken@rug.nl)). guncat-1.02.00/globals/0000755000175000017500000000000013372055735013554 5ustar frankfrankguncat-1.02.00/globals/data.cc0000644000175000017500000000007413372042752014770 0ustar frankfrank#include "globals.ih" size_t g_lineNr; string g_filename; guncat-1.02.00/globals/nextline.cc0000644000175000017500000000020713372042752015703 0ustar frankfrank#include "globals.ih" istream &nextline(istream &in, string &line) { if (getline(in, line)) ++g_lineNr; return in; } guncat-1.02.00/globals/globals.ih0000644000175000017500000000022113372046525015511 0ustar frankfrank#include "globals.h" //#include //#define XERR std::cerr << __FILE__": " #include #include using namespace std; guncat-1.02.00/globals/fileinfo.cc0000644000175000017500000000020313372042752015644 0ustar frankfrank#include "globals.ih" #include string fileInfo() { return "In " + g_filename + ", line " + to_string(g_lineNr); } guncat-1.02.00/globals/globals.h0000644000175000017500000000034113372042752015341 0ustar frankfrank#ifndef INCLUDED_GLOBALS_H_ #define INCLUDED_GLOBALS_H_ #include extern size_t g_lineNr; extern std::string g_filename; std::string fileInfo(); std::istream &nextline(std::istream &in, std::string &line); #endif guncat-1.02.00/gpipe/0000755000175000017500000000000013372055735013235 5ustar frankfrankguncat-1.02.00/gpipe/gpipe.h0000644000175000017500000000027413372042752014510 0ustar frankfrank#ifndef INCLUDED_GPIPE_ #define INCLUDED_GPIPE_ #include class GPipe: public FBB::Pipe { public: ~GPipe(); // closes the pipes }; #endif guncat-1.02.00/gpipe/gpipe.ih0000644000175000017500000000015113372042752014653 0ustar frankfrank#include "gpipe.h" //#include //#define XERR std::cerr << __FILE__": " #include guncat-1.02.00/gpipe/destructor.cc0000644000175000017500000000012413372042752015732 0ustar frankfrank#include "gpipe.ih" GPipe::~GPipe() { close(readFd()); close(writeFd()); } guncat-1.02.00/guncat/0000755000175000017500000000000013372055735013412 5ustar frankfrankguncat-1.02.00/guncat/processcin.cc0000644000175000017500000000063313372042752016066 0ustar frankfrank#include "guncat.ih" void Guncat::processCin() { g_filename = "stdin"; switch (d_processedCin) { case FIRST: process(cin); d_processedCin = DONE; break; case DONE: wmsg << "Multiple stdin (`-') specifications are ignored" << endl; d_processedCin = WARNED; break; case WARNED: break; } } guncat-1.02.00/guncat/getpassphrase.cc0000644000175000017500000000032713372042752016567 0ustar frankfrank#include "guncat.ih" void Guncat::getPassphrase(istream &in) { if (not nextline(in, d_passphrase)) throw Exception{} << fileInfo() << ": no line"; d_getPassphrase = &Guncat::nop; ++g_lineNr; } guncat-1.02.00/guncat/arguments.cc0000644000175000017500000000071313372043234015716 0ustar frankfrank#include "guncat.ih" // `Guncat' all files specified as the program's arguments in turn. // if no arguments are provided, process stdin // The constructor has initialized a Decryptor object, which has read the // first stdin line as the passphrase. void Guncat::arguments() { d_decryptor.setPassphrase(d_passphrase); if (d_arg.nArgs() != 0) processFileArguments(); else { g_filename = "stdin"; process(cin); } } guncat-1.02.00/guncat/guncat.ih0000644000175000017500000000037513372042752015215 0ustar frankfrank#include "guncat.h" #include #define XERR std::cerr << __FILE__": " #include #include #include #include #include "../globals/globals.h" using namespace std; using namespace FBB; guncat-1.02.00/guncat/guncat.h0000644000175000017500000000166413372046624015050 0ustar frankfrank#ifndef INCLUDED_GUNCAT_ #define INCLUDED_GUNCAT_ #include #include #include "../decryptor/decryptor.h" namespace FBB { class Arg; } class Guncat { enum CinSpec { FIRST, DONE, WARNED }; CinSpec d_processedCin = FIRST; FBB::Arg &d_arg; Decryptor d_decryptor; // sets the passphrase at -p // from the 1st line of the 1st // input stream void (Guncat::*d_getPassphrase)(std::istream &in); std::string d_passphrase; public: Guncat(); void arguments(); private: void process(std::istream &in); void processCin(); void processFileArguments(); void getPassphrase(std::istream &in); void nop(std::istream &in); // no pwd retrieval: no-op. }; #endif guncat-1.02.00/guncat/nop.cc0000644000175000017500000000011013372042752014500 0ustar frankfrank#include "guncat.ih" void Guncat::nop([[maybe_unused]] istream &in) {} guncat-1.02.00/guncat/process.cc0000644000175000017500000000062713372044330015371 0ustar frankfrank#include "guncat.ih" void Guncat::process(istream &in) { string line; g_lineNr = 0; (this->*d_getPassphrase)(in); // called once, then resets to nop() d_decryptor.getPassphrase(); while (nextline(in, line)) { if (line.find("-----BEGIN PGP MESSAGE-----") == 0) d_decryptor.handleGPG(in, line); else cout << line << endl; } } guncat-1.02.00/guncat/processfilearguments.cc0000644000175000017500000000056113372042752020162 0ustar frankfrank#include "guncat.ih" void Guncat::processFileArguments() { for (size_t idx = 0, end = d_arg.nArgs(); idx != end; ++idx) { if (string(d_arg[idx]) == "-") processCin(); else { g_filename = d_arg[idx]; ifstream in; Exception::open(in, g_filename); process(in); } } } guncat-1.02.00/guncat/guncat1.cc0000644000175000017500000000054213372046624015261 0ustar frankfrank#include "guncat.ih" Guncat::Guncat() : d_arg(Arg::instance()), d_getPassphrase(d_arg.option('p') ? &Guncat::getPassphrase : &Guncat::nop) { wmsg.reset(cerr); // warnings to cerr if (d_arg.option(0, "show-gpg")) d_decryptor.showGPG(); // ends the program with return value 0. } guncat-1.02.00/icmake/0000755000175000017500000000000013312732316013351 5ustar frankfrankguncat-1.02.00/icmake/setopt0000644000175000017500000000034113312732316014610 0ustar frankfrankstring setOpt(string install_im, string envvar) { list optvar; string ret; optvar = getenv(envvar); if (optvar[0] == "1") ret = optvar[1]; else ret = install_im; return ret; } guncat-1.02.00/icmake/manpage0000644000175000017500000000057513312732316014713 0ustar frankfrank#define MANPAGE "../../tmp/man/" ${PROGRAM} ".1" void manpage() { md("tmp/man tmp/manhtml"); chdir("documentation/man"); if (PROGRAM ".yo" younger MANPAGE || "release.yo" younger MANPAGE) { run("yodl2man -o " MANPAGE " " PROGRAM); run("yodl2html -o ../../tmp/manhtml/" PROGRAM ".1.html " PROGRAM); chdir("../.."); } exit(0); } guncat-1.02.00/icmake/findall0000644000175000017500000000107413312732316014707 0ustar frankfrank// assuming we're in g_cwd, all entries of type 'type' matching source/pattern // are returned w/o final \n list findAll(string type, string source, string pattern) { string cmd; list entries; list ret; int idx; chdir(source); cmd = "find ./ -mindepth 1 -maxdepth 1 -type " + type; if (pattern != "") pattern = "-name '" + pattern + "'"; entries = backtick(cmd + " " + pattern + " -printf \"%f\\n\""); for (idx = listlen(entries); idx--; ) ret += (list)cutEoln(entries[idx]); chdir(g_cwd); return ret; } guncat-1.02.00/icmake/log0000755000175000017500000000063213312732316014061 0ustar frankfrank#!/bin/bash find tmp/install -type f -exec md5sum "{}" \; | sed 's|tmp/install|'$1'|' > $2 find tmp/install -type l -exec printf "link %s\n" "{}" \; | sed 's|tmp/install|'$1'|' >> $2 find tmp/install -type d -exec printf "dir %s\n" "{}" \; | sed 's|tmp/install|'$1'|' >> $2 guncat-1.02.00/icmake/adddir0000644000175000017500000000112513312732316014522 0ustar frankfranklist addDir(list dir, string entry) { list ret; int idx; int keep = 1; string elem; for (idx = listlen(dir); idx--; ) { elem = dir[idx]; if (strfind(entry, elem) != -1) // entry contains dir, ignore dir ret += (list)entry; else if (strfind(elem, entry) != -1) // dir contains entry { ret += (list)elem; keep = 0; } else // new unique entry, keep dir[idx] ret += (list)elem; } if (keep) ret += (list)entry; return ret; } guncat-1.02.00/icmake/pathfile0000644000175000017500000000055213312732316015072 0ustar frankfranklist path_file(string path) { list ret; int len; int idx; for (len = strlen(path), idx = len; idx--; ) { if (path[idx] == "/") { ret = (list)substr(path, 0, idx) + (list)substr(path, idx + 1, len); return ret; } } ret = (list)"" + (list)path; return ret; } guncat-1.02.00/icmake/clean0000644000175000017500000000043613312732316014361 0ustar frankfrankvoid clean(int dist) { run("rm -rf " "build-stamp configure-stamp " "options/SKEL " "tmp/*.o tmp/*-stamp " + "o */o release.yo tmp/lib*.a " ); if (dist) run("rm -rf tmp *.ih.gch */*.ih.gch"); exit(0); } guncat-1.02.00/icmake/uninstall0000644000175000017500000000045613312732316015312 0ustar frankfrankvoid uninstall(string logfile) { int idx; list entry; string dir; list line; if (!exists(logfile)) { printf("installation log file " + logfile + " not found\n"); exit(0); } run("icmake/remove " + logfile + " " + (string)g_echo); exit(0); } guncat-1.02.00/icmake/cuteoln0000644000175000017500000000023313312732316014743 0ustar frankfrankstring cutEoln(string text) { int len; len = strlen(text) - 1; if (text[len] == "\n") text = substr(text, 0, len); return text; } guncat-1.02.00/icmake/run0000644000175000017500000000015113312732316014075 0ustar frankfrankvoid run(string cmd) { if (g_echo == OFF) cmd += "> /dev/null 2>&1"; system(0, cmd); } guncat-1.02.00/icmake/md0000644000175000017500000000074013312732316013675 0ustar frankfrank// md: target should be a series of blank-delimited directories to be created // If an element is a whildcard, the directory will always be created, // using mkdir -p. // // uses: run() void md(string target) { int idx; list paths; string dir; if (!exists(target)) run("mkdir -p " + target); else if (((int)stat(target)[0] & S_IFDIR) == 0) { printf(target + " exists, but is not a directory\n"); exit(1); } } guncat-1.02.00/icmake/gitlab0000644000175000017500000000022113312732316014531 0ustar frankfrankvoid gitlab() { run("cp -r release.yo tmp/manhtml/guncat.1.html ../../wip"); run("cp changelog ../../wip/changelog.txt"); exit(0); } guncat-1.02.00/icmake/remove0000755000175000017500000000117013312732316014573 0ustar frankfrank#!/bin/bash g_echo=$2 rm_f() { [ $g_echo -ne 0 ] && echo rm $1 rm -f $1 } rm_dir() { [ $g_echo -ne 0 ] && echo rmdir $1 rmdir --ignore-fail-on-non-empty -p $1 } IFS=" " for line in `cat $1` do field1=`echo $line | awk '{printf $1}'` field2=`echo $line | awk '{printf $2}'` if [ $field1 == "link" ] ; then rm_f $field2 elif [ $field1 == "dir" ] ; then rm_dir $field2 elif [ -e "$field2" ] ; then if [ "$field1" != "`md5sum $field2 | awk '{printf $1}'`" ] ; then echo $field2 changed, not removed else rm_f $field2 fi fi done rm_f $1 guncat-1.02.00/icmake/precompileheaders0000644000175000017500000000133613312732316016772 0ustar frankfrankstring g_compiler; int g_gch = 1; void _precompile(string class) { string classIH; classIH = class + ".ih"; if (classIH younger class + ".ih.gch") run(g_compiler + " -x c++-header " + classIH); } void precompileHeaders() { int idx; list classes; string class; if (!g_gch) return; classes = makelist(O_SUBDIR, "*"); g_compiler = setOpt(CXX, "CXX") + " " + setOpt(CXXFLAGS, "CXXFLAGS") + " "; _precompile("main"); // precompile the main program .ih file for (idx = listlen(classes); idx--; ) { class = classes[idx]; chdir(class); _precompile(class); chdir(g_cwd); } } guncat-1.02.00/icmake/backtick0000644000175000017500000000016013312732316015044 0ustar frankfranklist backtick(string arg) { list ret; echo(OFF); ret = `arg`; echo(g_echo); return ret; } guncat-1.02.00/icmake/install0000644000175000017500000000332413312732316014744 0ustar frankfrank void install(string request, string dest) { string target; int components = 0; list pathsplit; string base; base = "tmp/install/"; md(base); if (request == "x") components = 63; else { if (strfind(request, "b") != -1) components |= 2; if (strfind(request, "d") != -1) components |= 4; if (strfind(request, "m") != -1) components |= 8; } if (components & 2) { target = base + BINARY; pathsplit = path_file(target); printf(" installing the executable `", target, "'\n"); logFile("tmp/bin", "binary", pathsplit[0], pathsplit[1]); } if (components & (4 | 8)) { target = base + DOC "/"; if (components & 4) { printf(" installing the README and changelog files at `", target, "\n"); logZip("", "changelog README", target ); } if (components & 8) { printf(" installing the html-manual pages at `", target, "\n"); logInstall("tmp/manhtml", "", target); } } if (components & 8) { target = base + MAN "/"; printf(" installing the manual page below `", target, "'\n"); logZip("tmp/man", "guncat.1", target); } chdir(g_cwd); if (dest == "") dest = "/"; else md(dest); dest = cutEoln(backtick("realpath " + dest)[0]); if (g_logPath != "") backtick("icmake/log " + dest + " " + g_logPath); run("tar cf - -Ctmp/install . | tar xf - -C" + dest); printf("\n Installation completed\n"); exit(0); } guncat-1.02.00/icmake/logfile0000644000175000017500000000025713312732316014721 0ustar frankfrankvoid logFile(string srcdir, string src, string destdir, string dest) { chdir(g_cwd); md(destdir); run("cp " + srcdir + "/" + src + " " + destdir + "/" + dest); } guncat-1.02.00/icmake/loginstall0000644000175000017500000000156513312732316015453 0ustar frankfrank// source and dest, absolute or reachable from g_cwd, should exist. // files and links in source matching dest (if empty: all) are copied to dest // and are logged in g_log // Before they are logged, dest is created void logInstall(string src, string pattern, string dest) { list entries; int idx; chdir(g_cwd); md(dest); src += "/"; dest += "/"; if (listlen(makelist(O_DIR, src)) == 0) { printf("Warning: ", src, " not found: can't install ", src, pattern, " at ", dest, "\n"); return; } entries = findAll("f", src, pattern); for (idx = listlen(entries); idx--; ) run("cp " + src + entries[idx] + " " + dest); chdir(g_cwd); entries = findAll("l", src, pattern); for (idx = listlen(entries); idx--; ) run("cp " CPOPTS " " + src + entries[idx] + " " + dest); } guncat-1.02.00/icmake/special0000644000175000017500000000042113312732316014711 0ustar frankfrankvoid special() { if (! exists("release.yo") || "VERSION" newer "release.yo") { system("touch version.cc"); run("gcc -E VERSION.h | grep -v '#' | sed 's/\\\"//g' > " "release.yo"); } } guncat-1.02.00/icmake/logzip0000644000175000017500000000165613312732316014610 0ustar frankfrank// names may be a series of files in src, not a wildcard. // if it's empty then all files in src are used. // the files are gzipped and logged in dest. // src and dest do not have to end in / void logZip(string src, string names, string dest) { list files; int idx; string file; chdir(g_cwd); md(dest); dest += "/"; if (src != "") { if (listlen(makelist(O_DIR, src)) == 0) { printf("Warning: ", src, " not found: can't install ", src, names, " at ", dest, "\n"); return; } chdir(src); } if (names == "") files = makelist("*"); else files = strtok(names, " "); for (idx = listlen(files); idx--; ) { file = files[idx]; run("gzip -n -9 < " + file + " > " + file + ".gz"); } run("tar cf - *.gz | (cd " + g_cwd + "; cd " + dest + "; tar xf -)"); run("rm *.gz"); } guncat-1.02.00/icmconf0000644000175000017500000000100513367564761013476 0ustar frankfrank#include "INSTALL.im" #define ADD_LIBRARIES "bobcat" #define ADD_LIBRARY_PATHS "" #define LIBRARY "modules" #define MAIN "main.cc" #define OBJ_EXT ".o" //#define REFRESH #define SHAREDREQ "" #define SOURCES "*.cc" #define TMP_DIR "tmp" //#define USE_ALL "a" #define IH ".ih" #define PRECOMP "-x c++-header" #define USE_ECHO ON #define USE_VERSION #define DEFCOM "program" guncat-1.02.00/INSTALL0000644000175000017500000000750413312732316013157 0ustar frankfrankTo install guncat by hand instead of using a binary distribution perform the following steps: 0. guncat and its construction depends, in addition to the normally standard available system software on specific software and versions which is documented in the file `required'. (If you compile the bobcat library yourself, note that guncat does not use the SSL, Milter and Xpointer classes; they may --as far as guncat is concerned-- be left out of the library by running './build light') 1. It is expected you use icmake for the package construction. For this a top-level script (build) and support scripts in the ./icmake/ directory are available. By default, the 'build' script echoes the commands it executes to the standard output stream. By specifying the option -q (e.g., ./build -q ...) this is prevented, significantly reducing the output generated by 'build'. 2. Inspect the values of the variables in the file INSTALL.im Modify these when necessary. 3. Run ./build program [strip] to compile guncat. The argument `strip' is optional and strips symbolic information from the final executable. 4. If you installed Yodl then you can create the documentation: ./build man builds the man-page. 5. Before installing the components of guncat, consider defining the environment variable GUNCAT, defining its value as the (preferably absolute) filename of a file on which installed files and directories are logged. Defining the GUNCAT environment variable as ~/.guncat usually works well. 6. Run (probably as root) ./build install 'what' 'base' to install. Here, 'what' specifies what you want to install. Specify: x, to install all components, or specify a combination of: b (binary program), d (standard documentation), m (man-pages) E.g., use ./build install bm 'base' if you only want to be able to run guncat, and want its man-page to be installed below 'base'. ./build install's last argument 'base' is optional: the base directory below which the requested files are installed. This base directory is prepended to the paths #defined in the INSTALL.im file. If 'base' is not specified, then INSTALL.im's #defined paths are used as-is. When requesting non-existing elements (e.g., './build install x' was requested, but the man-pages weren't constructed) then these non-existing elements are silently ignored by the installation process. If the environment variable GUNCAT was defined when issuing the `./build install ...' command then a log of all installed files is written to the file indicated by the GUNCAT environment variable (see also the next item). Defining the GUNCAT environment variable as ~/.guncat usually works well. 7. Uninstalling previously installed components of guncat is easy if the environment variable GUNCAT was defined before issuing the `./build install ...' command. In that case, run the command ./build uninstall logfile where 'logfile' is the file that was written by ./build install. Modified files and non-empty directories are not removed, but the logfile itself is removed following the uninstallation. 8. Following the installation nothing in the directory tree which contains this file (i.e., INSTALL) is required for the proper functioning of guncat, so consider removing it. If you only want to remove left-over files from the build-process, just run ./build distclean guncat-1.02.00/INSTALL.im0000644000175000017500000000216713372046624013571 0ustar frankfrank#define PROGRAM "guncat" #define CXX "g++" // the compiler options to use. #define CXXFLAGS "--std=c++2a -Wall -O2 -fdiagnostics-color=never" // flags passed to the linker #define LDFLAGS "" // The following /bin/cp option is used to keep, rather than follow // symbolic references. If your installation doesn't support these flags, // then change them into available ones. // -P, --no-dereference // never follow symbolic links in SOURCE // --preserve[=ATTR_LIST] // preserve the specified attributes (default: // mode,ownership,timestamps), if possible additional // attributes: context, links, all // -d same as --no-dereference --preserve=links #define CPOPTS "-d" // ONLY USE ABSOLUTE DIRECTORY NAMES: // the final program #define BINARY "/usr/bin/"${PROGRAM} // the directory where the standard documentation is stored #define DOC "/usr/share/doc/"${PROGRAM} // the directory whre the manual page is stored #define MAN "/usr/share/man/man1" guncat-1.02.00/main.cc0000644000175000017500000000227513372043037013362 0ustar frankfrank#include "main.ih" namespace { Arg::LongOption longOptions[] = { Arg::LongOption("errors-OK", Arg::None), Arg::LongOption("gpg", Arg::Required), Arg::LongOption("gpg-msg", 'm'), Arg::LongOption("gpg-no-batch", Arg::None), // deprecated Arg::LongOption("gpg-option", Arg::Required), Arg::LongOption("help", 'h'), Arg::LongOption("locate-keys", 'l'), Arg::LongOption("passphrase", 'p'), Arg::LongOption("show-gpg", Arg::None), Arg::LongOption("time-limit", 'T'), Arg::LongOption("tty-OK", 't'), Arg::LongOption("verbose", Arg::Required), Arg::LongOption("version", 'v'), }; auto longEnd = longOptions + sizeof(longOptions) / sizeof(longOptions[0]); } int main(int argc, char **argv) try { Arg &arg = Arg::initialize("m:hlptT:v", longOptions, longEnd, argc, argv); arg.versionHelp(usage, version, 0); Guncat guncat; guncat.arguments(); } catch (int x) { return 0; } catch (exception const &exc) { cerr << exc.what() << '\n'; return 1; } catch (...) { cerr << "Unexpected exception\n"; return 1; } guncat-1.02.00/main.ih0000644000175000017500000000055113372042752013373 0ustar frankfrank#include #define XERR std::cerr << __FILE__": " #include #include #include #include "guncat/guncat.h" namespace Icmbuild { extern char version[]; extern char years[]; extern char author[]; }; using namespace std; using namespace FBB; using namespace Icmbuild; void usage(string const &progname); guncat-1.02.00/README0000644000175000017500000000124713312732316013004 0ustar frankfrankGuncat was designed to tackle a problem encountered with (partically) PGP encrypted files (as encountered, e.g., in mailboxes): the encrypted sections of such files are relatively difficult to browse through. Guncat acts like unix's cat command, but handles (partially) encrypted sections of processed files. Sections of guncat's input files which are surrounded by -----BEGIN PGP MESSAGE----- and -----END PGP MESSAGE----- markers are decrypted before being concatenated to the std. output stream. Guncat's output (i.e., the standard output stream) may subsequently be processed by other programs, like grep or less. April 2014 Frank B. Brokken (f.b.brokken@rug.nl) guncat-1.02.00/required0000644000175000017500000000071113312732316013662 0ustar frankfrankThis file lists non-standard software only. Thus, standard utilities like cp, mv, sed, etc, etc, are not explicitly mentioned. Neither is the gcc compiler explicitly mentioned, but a fairly recent one is assumed. Required software for building Guncat ------------------------------------- libbobcat-dev (>= 4.01.02), To use the provided build-script: icmake (>= 8.00.04) To construct the manual and map-page: yodl (>= 3.06.0) guncat-1.02.00/usage.cc0000644000175000017500000000353213372042752013542 0ustar frankfrank// usage.cc #include "main.ih" namespace { char const info[] = R"R([options] [file(s)] Where: [options] - optional arguments (short options between parentheses): --errors-OK: processing continues even if gpg returns a non-zero exit value --gpg : path to the gpg program (default: /usr/bin/gpg) --gpg-msg (-m) path: specify - to write gpg's messages to stderr, otherwise write messages to `path' (by default messages are suppressed) --gpg-option "spec": gpg option `spec' is passed to gpg child processes --help (-h): provide this help --passphrase (-p): the passphrase is read as the first line from stdin, (without being echoed); otherwise the passphrase is handled by gpg itself (e.g., using gpg-agent) --show-gpg: show the gpg command that would be used, and quit. --time-limit (-T) : maximum allowed time in seconds for decrypting an encrypted section (by default: no time limit is used) --tty-OK (-t): by default gpg's option --no-tty is used. --verbose [0-2]: gpg's verbosity level (by default: gpg's --quiet option is used) --version (-v) - show version information and terminate [file(s)] - file(s) to process. If not specified or if specified as - (also within a sequence of file names) the standard input stream is read. The processed information is written to the standard output stream. )R"; } void usage(std::string const &progname) { cout << "\n" << progname << " by " << Icmbuild::author << "\n" << progname << " V" << Icmbuild::version << " " << Icmbuild::years << "\n" "\n" "Usage: " << progname << info; } guncat-1.02.00/VERSION0000644000175000017500000000015313372011760013166 0ustar frankfrank#define AUTHOR "Frank B. Brokken (f.b.brokken@rug.nl)" #define VERSION "1.02.00" #define YEARS "2014-2018" guncat-1.02.00/version.cc0000644000175000017500000000056313372055250014121 0ustar frankfrank// version.cc #include "main.ih" #include "icmconf" #ifdef USE_VERSION #include "VERSION" #endif #ifndef AUTHOR #define AUTHOR "" #endif #ifndef VERSION #define VERSION "0.00.00" #endif #ifndef YEARS #define YEARS "2012" #endif namespace Icmbuild { char version[] = VERSION; char years[] = YEARS; char author[] = AUTHOR; } guncat-1.02.00/VERSION.h0000644000175000017500000000010413367564761013432 0ustar frankfrank#include "VERSION" SUBST(_CurVers_)(VERSION) SUBST(_CurYrs_)(YEARS)