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 >
C/C++ Source or Header  |  1995-12-05  |  9KB  |  355 lines

  1. //    PGPJNDOS.C
  2. //    Run a DOS executable for PGPJN by John Navas.
  3. //    Copyright (c) 1995, John Navas, All Rights Reserved.
  4. //
  5. //    The author grants explicit permission for this source code to be
  6. //    used or modified as required, subject only to the conditions that
  7. //    the copyright notices above are preserved; that this source code
  8. //    not be used in any product distributed in competition with this
  9. //  product; that by using this code you agree that the code is
  10. //    provided without warranty of any kind, either explicit or implied,
  11. //    and you use it at your own risk.
  12. //
  13. //    COMMAND LINE ARGUMENTS:
  14. //    A file that resides in the TEMP directory, which has the following lines:
  15. //        1.    Pathname of DOS program to execute (PGP)
  16. //        2.    First part of DOS program arguments (PGP options)
  17. //        3.    Pathname of redirected input
  18. //        4.    Pathname of redirected output (appended)
  19. //        5.    Recipient name
  20. //        7.    stderr redirection (optional)
  21. //    An optional Key (pass word/phrase)
  22. //
  23. //    Returns a non-zero PGP return code in the temporary control file
  24.  
  25. #include <conio.h>
  26. #include <fcntl.h>
  27. #include <io.h>
  28. #include <process.h>
  29. #include <stdarg.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <sys\stat.h>
  34.  
  35. ///////////////////////////////////////////////////////////////////////////////
  36.  
  37. char* TEMP;                                // TEMP directory
  38. char tempfile[_MAX_PATH];                // pathname of temporary file
  39. // temp file values have space to read \n
  40. char PGPpath[_MAX_PATH + 1];            // PGP pathname
  41. char PGPargs[128 + 1];                    // PGP args
  42. char inputfile[_MAX_PATH + 1];            // PGP input
  43. char outputfile[_MAX_PATH + 1];            // PGP output
  44. char recipient[128 + 1];                // PGP recipient
  45. char fstderr[_MAX_PATH + 1];            // stderr redirection (optional)
  46.  
  47. ///////////////////////////////////////////////////////////////////////////////
  48. // PRINTF FOR UNBUFFERED I/O
  49.  
  50. int
  51. uprintf(
  52. int file,
  53. const char* format,
  54. ...
  55. )
  56. {
  57.     char buf[256];
  58.     int len;
  59.     va_list arg;
  60.     
  61.     va_start(arg, format);
  62.     len = _vsnprintf(buf, sizeof(buf), format, arg);
  63.     va_end(arg);
  64.     
  65.     return _write(file, buf, len);
  66. }
  67.  
  68. ///////////////////////////////////////////////////////////////////////////////
  69. // UNBUFFERED PERROR() EQUIVALENT
  70.  
  71. #define myperror(string)    uprintf(_fileno(stderr), "%s\a", _strerror(string))
  72.  
  73. ///////////////////////////////////////////////////////////////////////////////
  74. // BINARY UNBUFFERED GETS/FGETS
  75.  
  76. char*                                    // string, or NULL if eof-of-file or error
  77. ugets(
  78. char* string,                            // destination string
  79. int size,                                // maximum size
  80. int file                                // file handle
  81. )
  82. {
  83.     // try to fill input buffer
  84.     int ret = _read(file, string, size - 1);
  85.  
  86.     // error or end-of-file    
  87.     if (ret <= 0) {
  88.         *string = '\0';
  89.         string = NULL;
  90.     }
  91.     // process line as string
  92.     else {
  93.         char* p;
  94.         
  95.         string[ret] = '\0';                // make sure string is delimited
  96.  
  97.         // get rid of \r\n
  98.         p = strchr(string, '\n');        // string up to end of line
  99.         if (p) {                        // if e-o-l found
  100.             if (p > string && '\r' == p[-1])
  101.                 p[-1] = '\0';            // zap the \r too
  102.             else
  103.                 p[0] = '\0';            // zap only the \n
  104.             ++p;                        // consume the [\r]\n
  105.         }
  106.         else
  107.             p = string + ret;            // string too long
  108.  
  109.         _lseek(file, (p - string) - ret, SEEK_CUR);    // seek to next line
  110.     }
  111.  
  112.     return string;
  113. }
  114.  
  115. ///////////////////////////////////////////////////////////////////////////////
  116. // ADD FILENAME TO AN EXISTING PATH
  117.  
  118. static
  119. char*                                    // complete pathname
  120. AddFileName(
  121. char* path,                                // directory path
  122. const char* file                        // filename to add
  123. )
  124. {
  125.     char drive[_MAX_DRIVE];
  126.     char dir[_MAX_DIR];
  127.     char fname[_MAX_FNAME];
  128.     char ext[_MAX_EXT];
  129.  
  130.     _splitpath(path, drive, dir, fname, ext);    // check dir
  131.  
  132.     if (*fname) {                        // logic was fooled, thinks dir is file
  133.         strcat(dir, fname);                // fixup path
  134.         strcat(dir, ext);
  135.     }
  136.  
  137.     _splitpath(file, NULL, NULL, fname, ext);    // get real file
  138.  
  139.     _makepath(path, drive, dir, fname, ext);    // make pathname
  140.  
  141.     return path;
  142. }
  143.  
  144. ///////////////////////////////////////////////////////////////////////////////
  145. // ERASE A FILE FOR SECURITY
  146.  
  147. void
  148. EraseFile(
  149. const char* tempfile,
  150. unsigned int times
  151. )
  152. {
  153.     char buf[BUFSIZ];
  154.  
  155.     memset(buf, 0, sizeof(buf));
  156.  
  157.     for (; times > 0; --times) {
  158.         int fil = _open(tempfile, _O_BINARY | _O_WRONLY);
  159.         long len;
  160.  
  161.         if (fil < 0)
  162.             return;
  163.         for (len = _filelength(fil); len >= BUFSIZ; len -= BUFSIZ)
  164.             _write(fil, buf, BUFSIZ);
  165.         if (len)
  166.             _write(fil, buf, (unsigned int) len);
  167.         _commit(fil);
  168.         _close(fil);
  169.     }
  170. }
  171.  
  172. ///////////////////////////////////////////////////////////////////////////////
  173.  
  174. int
  175. main(int ac, char** av)
  176. {
  177.     int ret;                            // return code
  178.     int fin, fout, ferr;                // working files
  179.     int sstdin, sstdout, sstderr;        // save std file handles here
  180.  
  181. #ifdef _DEBUG
  182.     {
  183.         int n;
  184.         
  185.         uprintf(_fileno(stderr), "ARGS:");
  186.         for (n = 1; n < ac; ++n)
  187.             uprintf(_fileno(stderr), " '%s'", av[n]);
  188.         uprintf(_fileno(stderr), "\n");
  189.     }
  190. #endif // _DEBUG
  191.  
  192.     // usage if no args
  193.     if (ac < 2) {
  194.         uprintf(_fileno(stderr), "usage: <fileinTEMPdir> [<passphrase>]\n\a");
  195.         return 64;
  196.     }
  197.  
  198.     // get and check TEMP environment variable
  199.     TEMP = getenv("TEMP");
  200.     if (! TEMP) {
  201.         TEMP = getenv("TMP");
  202.         if (! TEMP) {
  203.             uprintf(_fileno(stderr), "TEMP environment variable not set!\n\a");
  204.             return 65;
  205.         }
  206.     }
  207.  
  208.     // check temp file
  209.     strcpy(tempfile, TEMP);
  210.     AddFileName(tempfile, av[1]);
  211.     strupr(tempfile);
  212.     if (_access(tempfile, 06)) {
  213.         myperror(tempfile);
  214.         return 66;
  215.     }
  216.  
  217.     // get temp file data
  218.     fin = _open(tempfile, _O_RDONLY | _O_BINARY);
  219.     if (fin < 0) {
  220.         myperror(tempfile);
  221.         return 67;
  222.     }
  223.     ugets(PGPpath, sizeof(PGPpath), fin);        // PGP pathname
  224.     ugets(PGPargs, sizeof(PGPargs), fin);        // PGP options
  225.     ugets(inputfile, sizeof(inputfile), fin);    // PGP input file
  226.     ugets(outputfile, sizeof(outputfile), fin);    // PGP output file
  227.     ugets(recipient, sizeof(recipient), fin);    // PGP recipient
  228.     ugets(fstderr, sizeof(fstderr), fin);        // stderr redirection (optional)
  229.     _close(fin);
  230.     
  231.     // erase temporary file for security
  232.     EraseFile(tempfile, 1);                        // not critical
  233.  
  234.     // check to make sure PGPpath is valid
  235.     if (_access(PGPpath, 04)) {
  236.         myperror(PGPpath);
  237.         return 68;
  238.     }
  239.  
  240.     // redirect PGP input
  241.     if (*inputfile) {
  242.         fin = _open(inputfile, _O_RDONLY | _O_TEXT);
  243.         sstdin = _dup(_fileno(stdin));            // save existing file
  244.         if (fin < 0 || sstdin < 0) {
  245.             myperror(inputfile);
  246.             return 69;
  247.         }
  248.         ret = _dup2(fin, _fileno(stdin));        // redirection
  249.         _close(fin);
  250.         if (ret < 0) {
  251.             myperror(inputfile);
  252.             return 70;
  253.         }
  254.     }
  255.  
  256.     // redirect PGP output (append)
  257.     if (*outputfile) {
  258.         fout = _open(outputfile, _O_APPEND | _O_CREAT | _O_TEXT | _O_WRONLY,
  259.             _S_IREAD | _S_IWRITE);
  260.         sstdout = _dup(_fileno(stdout));        // save existing file
  261.         if (fout < 0 || sstdout < 0) {
  262.             myperror(outputfile);
  263.             return 71;
  264.         }
  265.         ret = _dup2(fout, _fileno(stdout));        // redirection
  266.         _close(fout);
  267.         if (ret < 0) {
  268.             myperror(outputfile);
  269.             return 72;
  270.         }
  271.         _lseek(_fileno(stdout), 0, SEEK_END);    // position at end
  272.     }
  273.  
  274.     // redirect PGP stderr (append)
  275.     if (*fstderr) {
  276.         ferr = _open(fstderr, _O_APPEND | _O_CREAT | _O_TEXT | _O_WRONLY,
  277.             _S_IREAD | _S_IWRITE);
  278.         sstderr = _dup(_fileno(stderr));        // save existing file
  279.         if (ferr < 0 || sstderr < 0) {
  280.             myperror(fstderr);
  281.             return 73;
  282.         }
  283.         ret = _dup2(ferr, _fileno(stderr));        // redirection
  284.         _close(ferr);
  285.         if (ret < 0) {
  286.             myperror(fstderr);
  287.             return 74;
  288.         }
  289.         _lseek(_fileno(stderr), 0, SEEK_END);    // position at end
  290.     }
  291.  
  292.     // ensure some TZ environment is set    
  293.     if (! getenv("TZ"))
  294.         _putenv("TZ=PST8PDT");            // default
  295.         
  296.     // put key (pass phrase) in environment if it is present
  297.     if (ac >= 3) {
  298.         char buf[128];
  299.         
  300.         _snprintf(buf, sizeof(buf), "PGPPASS=%s", av[2]);
  301.         buf[sizeof(buf)-1] = '\0';
  302.         _putenv(buf);
  303. #ifdef _DEBUG
  304.         uprintf(_fileno(stderr), "'%s'\n", buf);
  305. #endif // _DEBUG
  306.     }
  307.         
  308.     // spawn PGP
  309.     {
  310.         char buf[256];
  311.  
  312.         // build args
  313.         strcpy(buf, PGPargs);            // PGP options
  314.         if (*recipient) {                // recipient
  315.             strcat(buf, " ");
  316.             strcat(buf, recipient);
  317.         }
  318.         ret = _spawnl(_P_WAIT, PGPpath, "PGP", buf, NULL);
  319.     }
  320.     
  321.     // remove redirection and close save files
  322.     _dup2(sstdin, _fileno(stdin));
  323.     _close(sstdin);
  324.     _dup2(sstdout, _fileno(stdout));
  325.     _close(sstdout);
  326.     _dup2(sstderr, _fileno(stderr));
  327.     _close(sstderr);
  328.  
  329.     // see if any spawn errors
  330.     if (ret < 0)
  331.         myperror("spawn");
  332.     if (ret) {
  333.         // if there was a PGP error, pass the return code back
  334.         char buf[16];
  335.         
  336.         fout = _open(tempfile, _O_CREAT | _O_TEXT | _O_TRUNC | _O_WRONLY);
  337.         _itoa(ret, buf, 10);
  338.         _write(fout, buf, strlen(buf));
  339.         _close(fout);
  340.     }
  341.     else
  342.         // if no PGP error, delete the temp file
  343.         if (remove(tempfile))
  344.             myperror("tempfile");
  345.  
  346. #ifdef _DEBUG
  347.     uprintf(_fileno(stderr), "\npress any key to continue...");
  348.     getch();
  349. #endif // _DEBUG
  350.  
  351.     return ret;
  352. }
  353.  
  354. //    PGPJNDOS.C
  355.