home *** CD-ROM | disk | FTP | other *** search
- // 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
-