guncat-1.01.02/CLASSES0000644000175000017500000000204312605005772013143 0ustar frankfrank# This file contains the names of all subdirectories containing sources to # compile. Each directory should be specified on a line of its own. Initial # blanks are ok. Compilation is 1-level deep. # If a parser or scanner is used, (see icmconfig's USE_PARSER and USE_SCANNER # defines) then those directories are automatically included (although they # could be included here as well) # Lines starting with # or with // are ignored, as are empty lines. # sources in the current (i.e., this) directory are also compiled. # If a class Y depends on class X as in: # class Y: public X # or: # class Y # { # X d_y; # }; # then specify the dependency here using the form # y x # where x and y are the directories holding the resp. class sources. Multiple # dependencies are OK. Then, when altering X's data organization, do 'touch # x/a', followed by 'icmbuild program': x's sources as well as the sources in # directories (in)directly depending on x (e.g., y) are then automatically # recompiled by icmbuild. guncat decryptor guncat-1.01.02/INSTALL0000644000175000017500000000750412605005772013163 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.01.02/INSTALL.im0000644000175000017500000000356512605005772013572 0ustar frankfrank // The name of the program and the support directories as installed by // the 'build install' command. Normally there is no reason for changing // this #define #define PROGRAM "guncat" // The CXX, CXXFLAGS, and LDFLAGS #defines are overruled by identically // named environment variables: // the compiler to use. #define CXX "g++" // the compiler options to use. #define CXXFLAGS "--std=c++14 -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" // COMPONENTS TO INSTALL // ===================== // For an operational non-Debian installation, you probably must be // `root'. // If necessary, adapt DOC, HDR, LIB and MAN (below) to your situation. // The provided locations are used by Debian Linux. // With 'build install' you can dynamically specify a location to prepend // to the locations configured here, and select which components you want // to install // 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.01.02/README0000644000175000017500000000124712605005772013010 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.01.02/VERSION0000644000175000017500000000015312633025413013166 0ustar frankfrank#define AUTHOR "Frank B. Brokken (f.b.brokken@rug.nl)" #define VERSION "1.01.02" #define YEARS "2014-2015" guncat-1.01.02/VERSION.h0000644000175000017500000000010412605005772013415 0ustar frankfrank#include "VERSION" SUBST(_CurVers_)(VERSION) SUBST(_CurYrs_)(YEARS) guncat-1.01.02/build0000755000175000017500000000765512626361067013173 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/github" 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 == "github") github(); 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" " github - prepare github's gh-pages update\n" " (internal use only)\n" "\n" ); exit(0); } guncat-1.01.02/changelog0000644000175000017500000000314712633025520013775 0ustar frankfrankguncat (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.01.02/decryptor/0000755000175000017500000000000012626356373014150 5ustar frankfrankguncat-1.01.02/decryptor/echo.cc0000644000175000017500000000054612605005772015371 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.01.02/decryptor/destructor.cc0000644000175000017500000000040412605005772016642 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.01.02/decryptor/decryptor.ih0000644000175000017500000000053612605005772016500 0ustar frankfrank#include "decryptor.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace FBB; guncat-1.01.02/decryptor/insertgpgsection.cc0000644000175000017500000000074512605005772020043 0ustar frankfrank#include "decryptor.ih" int Decryptor::insertPGPsection(Process &gpg, string const &pgpHeader, istream &in) { gpg.start(); gpg << pgpHeader << '\n'; string line; do { getline(in, line); gpg << line << '\n'; } while (line.find("-----END PGP MESSAGE-----") != 0); gpg.close(); int ret = gpg.waitForChild(); (d_msgName == "-" ? cerr : d_msg) << gpg.childErrStream().rdbuf(); return ret; } guncat-1.01.02/decryptor/getpassphrase.cc0000644000175000017500000000070512605005772017321 0ustar frankfrank#include "decryptor.ih" void Decryptor::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.01.02/decryptor/decryptor1.cc0000644000175000017500000000214112605005772016540 0ustar frankfrank#include "decryptor.ih" Decryptor::Decryptor() : d_arg(Arg::instance()), d_gpgOptions(" ") { if (not d_arg.option(&d_gpg, "gpg")) // override default gpg location d_gpg = "/usr/bin/gpg"; if (not d_arg.option(&d_msgName, 'm')) // get the name of the message d_msgName = "/dev/null"; // stream if (not d_arg.option('t')) // by default --no-tty is used d_gpgOptions += " --no-tty"; if (not d_arg.option('l')) // by default missing keys are d_gpgOptions += " --no-auto-key-locate"; // searched for setVerbosity(); // set GPG's verbosity setRemainingOptions(); if (not d_arg.option(0, "gpg-no-batch")) d_gpgOptions += " --batch"; d_gpgOptions += " --decrypt"; if (d_arg.option(0, "show-gpg")) { cout << d_gpg; if (not d_passphrase.empty()) cout << " --passphrase-fd "; cout << d_gpgOptions << '\n'; throw 0; } if (d_msgName != "-") Exception::open(d_msg, d_msgName); } guncat-1.01.02/decryptor/decryptor.h0000644000175000017500000000176712605005772016336 0ustar frankfrank#ifndef INCLUDED_DECRYPTOR_ #define INCLUDED_DECRYPTOR_ #include #include struct termios; namespace FBB { class Arg; class Process; class Pipe; } class Decryptor { FBB::Arg &d_arg; std::string d_gpg; std::string d_gpgOptions; std::string d_passphrase; std::string d_msgName; std::ofstream d_msg; public: Decryptor(); ~Decryptor(); // line must contain the // BEGIN PGP MESSAGE header void handleGPG(std::istream &in, std::string const &pgpHeader); private: int echo(struct termios *ttySaved, bool reset = false) const; void getPassphrase(); void setVerbosity(); void setRemainingOptions(); std::string pipePassphrase(FBB::Pipe &pipe); int insertPGPsection(FBB::Process &gpg, std::string const &pgpHeader, std::istream &in); }; #endif guncat-1.01.02/decryptor/setverbosity.cc0000644000175000017500000000112612605005772017210 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.01.02/decryptor/handlegpg.cc0000644000175000017500000000211512605005772016376 0ustar frankfrank#include "decryptor.ih" void Decryptor::handleGPG(istream &in, string const &pgpHeader) { off_t offset = in.tellg(); for (size_t attempt = 1; ; ++attempt) { if (d_passphrase.empty() && d_arg.option('p')) getPassphrase(); Pipe pipe; Process gpg(Process::CIN | Process::CERR, d_gpg + pipePassphrase(pipe) + d_gpgOptions); // exitValue 2 means: incorrect passphrase if (insertPGPsection(gpg, pgpHeader, in) != 2) return; if (not in.seekg(offset, ios::beg)) throw Exception() << "File cannot be repositioned " "following incorrect passphrase\n"; if (attempt == 3) throw Exception() << "Quitting after three attempts to enter a " "correct passphrase\n"; if (d_arg.option('p')) { cerr << "Passphrase incorrect. Try again...\n"; d_passphrase.clear(); } } } guncat-1.01.02/decryptor/pipepassphrase.cc0000644000175000017500000000044512605005772017500 0ustar frankfrank#include "decryptor.ih" string Decryptor::pipePassphrase(Pipe &pipe) { string ret; if (not d_passphrase.empty()) { ret = " --passphrase-fd " + to_string(pipe.readFd()); OFdStream pwd(pipe.writeFd()); pwd << d_passphrase << endl; } return ret; } guncat-1.01.02/decryptor/setremainingoptions.cc0000644000175000017500000000064412605005772020553 0ustar frankfrank#include "decryptor.ih" void Decryptor::setRemainingOptions() { 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.01.02/documentation/0000755000175000017500000000000012605005772014775 5ustar frankfrankguncat-1.01.02/documentation/man/0000755000175000017500000000000012605005772015550 5ustar frankfrankguncat-1.01.02/documentation/man/guncat.yo0000644000175000017500000001303712605005772017406 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 like 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 will then forward the passphrase to g(), or g() will itself ask for the required passphrase. When providing an incorrect passphrase to u() two additional attempts to provide the correct passphrase are granted. 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 usage info (option tt(--help)), u()'s version number (option tt(--version)), or the configured g() call (option tt(--show-gpg)) is requested. manpagesection(INPUT FILE(S)) When no file arguments are provided (or when - is provided) the standard input stream is processed. Note that when the standard input stream is specified and option tt(--passphrase) is specified the standard input stream's first line is used as g()'s passphrase. 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() 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() should write its messages. Specify - to write the messages to the standard error stream. By default messages are suppressed. it() loption(gpg-no-batch)nl() Option tt(--batch) is omitted when calling g(). 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. it() loption(help) (soption(h))nl() Basic usage information is written to the standard output stream. it() loption(locate-keys) soption(l)nl() Locate missing public keys at the configured key server(s) (by default missing keys are not searched for). it() loption(passphrase) soption(p)nl() The passphrase is read as the first line from the standard input stream (without being echoed); otherwise the passphrase is handled by g() itself (e.g., using bf(gpg-agent)(1)). it() loption(show-gpg)nl() Show the gpg command that would be used, and quit, returning 0. it() loption(tty-OK) soption(t)nl() Option tt(--no-tty) is omitted when calling g(). 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(gpg-agent)(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.github.io/guncat/) manpagesection(ORGANIZATION) Center for Information Technology, University of Groningen. manpageauthor() Frank B. Brokken (bf(f.b.brokken@rug.nl)). guncat-1.01.02/guncat/0000755000175000017500000000000012626356373013416 5ustar frankfrankguncat-1.01.02/guncat/processfilearguments.cc0000644000175000017500000000051412605005772020160 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 { ifstream in; Exception::open(in, d_arg[idx]); process(in); } } } guncat-1.01.02/guncat/guncat1.cc0000644000175000017500000000013612605005772015256 0ustar frankfrank#include "guncat.ih" Guncat::Guncat() : d_arg(Arg::instance()) { wmsg.reset(cerr); } guncat-1.01.02/guncat/guncat.ih0000644000175000017500000000026412605005772015212 0ustar frankfrank#include "guncat.h" #include #include #include #include #include using namespace std; using namespace FBB; guncat-1.01.02/guncat/guncat.h0000644000175000017500000000100412605005772015032 0ustar frankfrank#ifndef INCLUDED_GUNCAT_ #define INCLUDED_GUNCAT_ #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; public: Guncat(); void arguments(); private: void process(std::istream &in); void processCin(); void processFileArguments(); }; #endif guncat-1.01.02/guncat/process.cc0000644000175000017500000000042412605005772015372 0ustar frankfrank#include "guncat.ih" void Guncat::process(istream &in) { string line; while (getline(in, line)) { if (line.find("-----BEGIN PGP MESSAGE-----") == 0) d_decryptor.handleGPG(in, line); else cout << line << endl; } } guncat-1.01.02/guncat/processcin.cc0000644000175000017500000000060112605005772016061 0ustar frankfrank#include "guncat.ih" void Guncat::processCin() { 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.01.02/guncat/arguments.cc0000644000175000017500000000056112605005772015723 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() { if (d_arg.nArgs() == 0) process(cin); else processFileArguments(); } guncat-1.01.02/icmake/0000755000175000017500000000000012633025021013343 5ustar frankfrankguncat-1.01.02/icmake/setopt0000644000175000017500000000034112605005772014614 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.01.02/icmake/loginstall0000644000175000017500000000156512626356317015466 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.01.02/icmake/logzip0000644000175000017500000000165612626356320014615 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.01.02/icmake/clean0000644000175000017500000000043612605005772014365 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.01.02/icmake/logfile0000644000175000017500000000025712605005772014725 0ustar frankfrankvoid logFile(string srcdir, string src, string destdir, string dest) { chdir(g_cwd); md(destdir); run("cp " + srcdir + "/" + src + " " + destdir + "/" + dest); } guncat-1.01.02/icmake/findall0000644000175000017500000000107412626356313014716 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.01.02/icmake/manpage0000644000175000017500000000057512605005772014717 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.01.02/icmake/cuteoln0000644000175000017500000000023312605005772014747 0ustar frankfrankstring cutEoln(string text) { int len; len = strlen(text) - 1; if (text[len] == "\n") text = substr(text, 0, len); return text; } guncat-1.01.02/icmake/uninstall0000644000175000017500000000045612605005772015316 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.01.02/icmake/pathfile0000644000175000017500000000055212605005772015076 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.01.02/icmake/github0000644000175000017500000000022112605005772014555 0ustar frankfrankvoid github() { run("cp -r release.yo tmp/manhtml/guncat.1.html ../../wip"); run("cp changelog ../../wip/changelog.txt"); exit(0); } guncat-1.01.02/icmake/md0000644000175000017500000000074012605005772013701 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.01.02/icmake/log0000755000175000017500000000063212605005772014065 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.01.02/icmake/remove0000755000175000017500000000117012605005772014577 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.01.02/icmake/precompileheaders0000644000175000017500000000133612626356321017000 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.01.02/icmake/special0000644000175000017500000000042112605005772014715 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.01.02/icmake/run0000644000175000017500000000015112605005772014101 0ustar frankfrankvoid run(string cmd) { if (g_echo == OFF) cmd += "> /dev/null 2>&1"; system(0, cmd); } guncat-1.01.02/icmake/install0000644000175000017500000000332412605005772014750 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.01.02/icmake/adddir0000644000175000017500000000112512626356312014530 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.01.02/icmake/backtick0000644000175000017500000000016012605005772015050 0ustar frankfranklist backtick(string arg) { list ret; echo(OFF); ret = `arg`; echo(g_echo); return ret; } guncat-1.01.02/icmconf0000644000175000017500000000135712633027376013500 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 PARSER_DIR "" #define PARSFLAGS "" #define PARSGEN "" #define PARSOUT "" #define PARSSPEC "" //#define REFRESH #define SCANNER_DIR "" #define SCANFLAGS "" #define SCANGEN "" #define SCANOUT "" #define SCANSPEC "" #define SHAREDREQ "" #define SOURCES "*.cc" #define TMP_DIR "tmp" //#define USE_ALL "a" #define USE_ECHO ON #define USE_VERSION #define DEFCOM "program" guncat-1.01.02/main.cc0000644000175000017500000000210712605005772013357 0ustar frankfrank#include "main.ih" namespace { Arg::LongOption longOptions[] = { Arg::LongOption("gpg", Arg::Required), Arg::LongOption("passphrase", 'p'), Arg::LongOption("gpg-no-batch", Arg::None), Arg::LongOption("gpg-msg", 'm'), Arg::LongOption("gpg-option", Arg::Required), Arg::LongOption("help", 'h'), Arg::LongOption("locate-keys", 'l'), Arg::LongOption("show-gpg", Arg::None), 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:hlptv", 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.01.02/main.ih0000644000175000017500000000050012605005772013365 0ustar frankfrank#include #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.01.02/required0000644000175000017500000000071112633025477013673 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.01.02/usage.cc0000644000175000017500000000500212605005772013534 0ustar frankfrank// usage.cc #include "main.ih" void usage(std::string const &progname) { cout << "\n" << progname << " by " << Icmbuild::author << "\n" << progname << " V" << Icmbuild::version << " " << Icmbuild::years << "\n" "\n" "Usage: " << progname << " [options] [file(s)]\n" "Where:\n" " [options] - optional arguments (short options between parentheses):\n" " --gpg : path to the gpg program (default: /usr/bin/gpg)\n" " --gpg-msg (-m) path: specify - to write gpg's messages to " "stderr,\n" " otherwise write messages to `path' (by default " "messages\n" " are suppressed)\n" " --gpg-no-batch: do not use gpg's --batch option (by default " "--batch\n" " is used)\n" " --gpg-option \"spec\": gpg option `spec' is passed to gpg child " "processes\n" " --help (-h): provide this help\n" " --locate-keys (-l): locate missing public keys at the " "configured key\n" " server(s) (by default missing keys are not searched " "for)\n" " --passphrase (-p): the passphrase is read as the first line from " "stdin,\n" " (without being echoed); otherwise the passphrase is\n" " handled by gpg itself (e.g., using gpg-agent)\n" " --show-gpg: show the gpg command that would be used, and quit.\n" " --tty-OK (-t): by default gpg's option --no-tty is used.\n" " --verbose [0-2]: gpg's verbosity level (by default: gpg's " "--quiet\n" " option is used)\n" " --version (-v) - show version information and terminate\n" "\n" " [file(s)] - file(s) to process. If not specified or if specified " "as\n" " - (also within a sequence of file names) the standard " "input\n" " is read.\n" "\n"; } guncat-1.01.02/version.cc0000644000175000017500000000056312626356330014126 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; }