home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC-Online 1998 February
/
PCOnline_02_1998.iso
/
filesbbs
/
win3x
/
pgpjn.exe
/
JNSOURCE.ZIP
/
PGPJNDOS.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-05
|
9KB
|
355 lines
// PGPJNDOS.C
// Run a DOS executable for PGPJN by John Navas.
// Copyright (c) 1995, John Navas, All Rights Reserved.
//
// The author grants explicit permission for this source code to be
// used or modified as required, subject only to the conditions that
// the copyright notices above are preserved; that this source code
// not be used in any product distributed in competition with this
// product; that by using this code you agree that the code is
// provided without warranty of any kind, either explicit or implied,
// and you use it at your own risk.
//
// COMMAND LINE ARGUMENTS:
// A file that resides in the TEMP directory, which has the following lines:
// 1. Pathname of DOS program to execute (PGP)
// 2. First part of DOS program arguments (PGP options)
// 3. Pathname of redirected input
// 4. Pathname of redirected output (appended)
// 5. Recipient name
// 7. stderr redirection (optional)
// An optional Key (pass word/phrase)
//
// Returns a non-zero PGP return code in the temporary control file
#include <conio.h>
#include <fcntl.h>
#include <io.h>
#include <process.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys\stat.h>
///////////////////////////////////////////////////////////////////////////////
char* TEMP; // TEMP directory
char tempfile[_MAX_PATH]; // pathname of temporary file
// temp file values have space to read \n
char PGPpath[_MAX_PATH + 1]; // PGP pathname
char PGPargs[128 + 1]; // PGP args
char inputfile[_MAX_PATH + 1]; // PGP input
char outputfile[_MAX_PATH + 1]; // PGP output
char recipient[128 + 1]; // PGP recipient
char fstderr[_MAX_PATH + 1]; // stderr redirection (optional)
///////////////////////////////////////////////////////////////////////////////
// PRINTF FOR UNBUFFERED I/O
int
uprintf(
int file,
const char* format,
...
)
{
char buf[256];
int len;
va_list arg;
va_start(arg, format);
len = _vsnprintf(buf, sizeof(buf), format, arg);
va_end(arg);
return _write(file, buf, len);
}
///////////////////////////////////////////////////////////////////////////////
// UNBUFFERED PERROR() EQUIVALENT
#define myperror(string) uprintf(_fileno(stderr), "%s\a", _strerror(string))
///////////////////////////////////////////////////////////////////////////////
// BINARY UNBUFFERED GETS/FGETS
char* // string, or NULL if eof-of-file or error
ugets(
char* string, // destination string
int size, // maximum size
int file // file handle
)
{
// try to fill input buffer
int ret = _read(file, string, size - 1);
// error or end-of-file
if (ret <= 0) {
*string = '\0';
string = NULL;
}
// process line as string
else {
char* p;
string[ret] = '\0'; // make sure string is delimited
// get rid of \r\n
p = strchr(string, '\n'); // string up to end of line
if (p) { // if e-o-l found
if (p > string && '\r' == p[-1])
p[-1] = '\0'; // zap the \r too
else
p[0] = '\0'; // zap only the \n
++p; // consume the [\r]\n
}
else
p = string + ret; // string too long
_lseek(file, (p - string) - ret, SEEK_CUR); // seek to next line
}
return string;
}
///////////////////////////////////////////////////////////////////////////////
// ADD FILENAME TO AN EXISTING PATH
static
char* // complete pathname
AddFileName(
char* path, // directory path
const char* file // filename to add
)
{
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath(path, drive, dir, fname, ext); // check dir
if (*fname) { // logic was fooled, thinks dir is file
strcat(dir, fname); // fixup path
strcat(dir, ext);
}
_splitpath(file, NULL, NULL, fname, ext); // get real file
_makepath(path, drive, dir, fname, ext); // make pathname
return path;
}
///////////////////////////////////////////////////////////////////////////////
// ERASE A FILE FOR SECURITY
void
EraseFile(
const char* tempfile,
unsigned int times
)
{
char buf[BUFSIZ];
memset(buf, 0, sizeof(buf));
for (; times > 0; --times) {
int fil = _open(tempfile, _O_BINARY | _O_WRONLY);
long len;
if (fil < 0)
return;
for (len = _filelength(fil); len >= BUFSIZ; len -= BUFSIZ)
_write(fil, buf, BUFSIZ);
if (len)
_write(fil, buf, (unsigned int) len);
_commit(fil);
_close(fil);
}
}
///////////////////////////////////////////////////////////////////////////////
int
main(int ac, char** av)
{
int ret; // return code
int fin, fout, ferr; // working files
int sstdin, sstdout, sstderr; // save std file handles here
#ifdef _DEBUG
{
int n;
uprintf(_fileno(stderr), "ARGS:");
for (n = 1; n < ac; ++n)
uprintf(_fileno(stderr), " '%s'", av[n]);
uprintf(_fileno(stderr), "\n");
}
#endif // _DEBUG
// usage if no args
if (ac < 2) {
uprintf(_fileno(stderr), "usage: <fileinTEMPdir> [<passphrase>]\n\a");
return 64;
}
// get and check TEMP environment variable
TEMP = getenv("TEMP");
if (! TEMP) {
TEMP = getenv("TMP");
if (! TEMP) {
uprintf(_fileno(stderr), "TEMP environment variable not set!\n\a");
return 65;
}
}
// check temp file
strcpy(tempfile, TEMP);
AddFileName(tempfile, av[1]);
strupr(tempfile);
if (_access(tempfile, 06)) {
myperror(tempfile);
return 66;
}
// get temp file data
fin = _open(tempfile, _O_RDONLY | _O_BINARY);
if (fin < 0) {
myperror(tempfile);
return 67;
}
ugets(PGPpath, sizeof(PGPpath), fin); // PGP pathname
ugets(PGPargs, sizeof(PGPargs), fin); // PGP options
ugets(inputfile, sizeof(inputfile), fin); // PGP input file
ugets(outputfile, sizeof(outputfile), fin); // PGP output file
ugets(recipient, sizeof(recipient), fin); // PGP recipient
ugets(fstderr, sizeof(fstderr), fin); // stderr redirection (optional)
_close(fin);
// erase temporary file for security
EraseFile(tempfile, 1); // not critical
// check to make sure PGPpath is valid
if (_access(PGPpath, 04)) {
myperror(PGPpath);
return 68;
}
// redirect PGP input
if (*inputfile) {
fin = _open(inputfile, _O_RDONLY | _O_TEXT);
sstdin = _dup(_fileno(stdin)); // save existing file
if (fin < 0 || sstdin < 0) {
myperror(inputfile);
return 69;
}
ret = _dup2(fin, _fileno(stdin)); // redirection
_close(fin);
if (ret < 0) {
myperror(inputfile);
return 70;
}
}
// redirect PGP output (append)
if (*outputfile) {
fout = _open(outputfile, _O_APPEND | _O_CREAT | _O_TEXT | _O_WRONLY,
_S_IREAD | _S_IWRITE);
sstdout = _dup(_fileno(stdout)); // save existing file
if (fout < 0 || sstdout < 0) {
myperror(outputfile);
return 71;
}
ret = _dup2(fout, _fileno(stdout)); // redirection
_close(fout);
if (ret < 0) {
myperror(outputfile);
return 72;
}
_lseek(_fileno(stdout), 0, SEEK_END); // position at end
}
// redirect PGP stderr (append)
if (*fstderr) {
ferr = _open(fstderr, _O_APPEND | _O_CREAT | _O_TEXT | _O_WRONLY,
_S_IREAD | _S_IWRITE);
sstderr = _dup(_fileno(stderr)); // save existing file
if (ferr < 0 || sstderr < 0) {
myperror(fstderr);
return 73;
}
ret = _dup2(ferr, _fileno(stderr)); // redirection
_close(ferr);
if (ret < 0) {
myperror(fstderr);
return 74;
}
_lseek(_fileno(stderr), 0, SEEK_END); // position at end
}
// ensure some TZ environment is set
if (! getenv("TZ"))
_putenv("TZ=PST8PDT"); // default
// put key (pass phrase) in environment if it is present
if (ac >= 3) {
char buf[128];
_snprintf(buf, sizeof(buf), "PGPPASS=%s", av[2]);
buf[sizeof(buf)-1] = '\0';
_putenv(buf);
#ifdef _DEBUG
uprintf(_fileno(stderr), "'%s'\n", buf);
#endif // _DEBUG
}
// spawn PGP
{
char buf[256];
// build args
strcpy(buf, PGPargs); // PGP options
if (*recipient) { // recipient
strcat(buf, " ");
strcat(buf, recipient);
}
ret = _spawnl(_P_WAIT, PGPpath, "PGP", buf, NULL);
}
// remove redirection and close save files
_dup2(sstdin, _fileno(stdin));
_close(sstdin);
_dup2(sstdout, _fileno(stdout));
_close(sstdout);
_dup2(sstderr, _fileno(stderr));
_close(sstderr);
// see if any spawn errors
if (ret < 0)
myperror("spawn");
if (ret) {
// if there was a PGP error, pass the return code back
char buf[16];
fout = _open(tempfile, _O_CREAT | _O_TEXT | _O_TRUNC | _O_WRONLY);
_itoa(ret, buf, 10);
_write(fout, buf, strlen(buf));
_close(fout);
}
else
// if no PGP error, delete the temp file
if (remove(tempfile))
myperror("tempfile");
#ifdef _DEBUG
uprintf(_fileno(stderr), "\npress any key to continue...");
getch();
#endif // _DEBUG
return ret;
}
// PGPJNDOS.C