Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

Yep

By: a guest on May 6th, 2012  |  syntax: C  |  size: 27.55 KB  |  hits: 46  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /**
  2.  * @mainpage Yep Utility.
  3.  *
  4.  * Software for encryption/decryption of private text data.\n
  5.  * System requirements:
  6.  * - Compiler: cc/gcc
  7.  * - Compile options: -ansi -std=c99
  8.  *
  9.  * Contact: valsorym.e@gmail.com \n
  10.  * Copyright (c) 2012 valsorym. All rights reserved.
  11.  */
  12.  
  13. #include <math.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <stdarg.h>
  18. #include <termios.h>
  19. #include <sys/time.h>
  20. #include <unistd.h>
  21.  
  22. /* DEFINES */
  23. /*---------------------------------------------------------------------------*/
  24. /**
  25.  * @def ARGV_HELP
  26.  * @brief The list of arguments to display help information.
  27.  *
  28.  * @def ARGV_NEWPASS
  29.  * @brief The list of arguments to change the password on the specified file.
  30.  *
  31.  * @def ARGV_TEMPDIR
  32.  * @brief The list of arguments to specify a directory for storing
  33.  * temporary files.
  34.  *
  35.  * @def ARGV_HOOKWORD
  36.  * @brief The list of arguments to specify the protection word.
  37.  */
  38. #define ARGV_HELP     2, "-i", "-h"
  39. #define ARGV_NEWPASS  1, "-p"
  40. #define ARGV_TEMPDIR  1, "-d"
  41. #define ARGV_HOOKWORD 1, "-w"
  42.  
  43. /**
  44.  * @def DEFAULT_HOOKWORD
  45.  * @brief Protection word by default. Use if not specified arguments
  46.  * are \a ARGV_HOOKWORD.
  47.  *
  48.  * @def DEFAULT_TEMPDIR
  49.  * @brief Directory for storing temporary files by default. Use if not
  50.  * specified arguments are \a ARGV_TEMPDIR.
  51.  */
  52. #define DEFAULT_HOOKWORD  "howdy"
  53. #define DEFAULT_TEMPDIR   "/tmp/yep"
  54.  
  55. /**
  56.  * @def MAXLEN_BUF
  57.  * @brief The maximum length of text buffer. The buffer used to read lines
  58.  * from a file, encode/decode strings.
  59.  *
  60.  * @def MAXLEN_PATH
  61.  * @brief The maximum permissible length of the path to the file  including
  62.  * the file name.
  63.  *
  64.  * @def MAXLEN_SYSKEY
  65.  * @brief Maximum length of keywords: passwords, hookword.
  66.  *
  67.  * @def MAXLEN_TEMPNAME
  68.  * @brief The maximum permissible length of the temporary file name.
  69.  */
  70. #define MAXLEN_BUF      4096
  71. #define MAXLEN_PATH     255
  72. #define MAXLEN_SYSKEY   15
  73. #define MAXLEN_TEMPNAME 10
  74.  
  75. /* NEWTYPES */
  76. /*---------------------------------------------------------------------------*/
  77. /**
  78.  * @enum bool
  79.  * @brief Boolean data type. etc. \e c99 _Bool.
  80.  */
  81. typedef enum {
  82.     false=0,    /**< True value. */
  83.     true        /**< False value. */
  84. } bool;
  85.  
  86. /**
  87.  * @enum cmethod
  88.  * @brief Direction of encryption: encrypt, decrypt.
  89.  */
  90. typedef enum {
  91.     encode=1,   /**< Encrypt a file. */
  92.     decode=-1   /**< Decrypt a file. */
  93. } cmethod;
  94.  
  95. /**
  96.  * @enum cstatus
  97.  * @brief The status of the encrypting/decrypting the file.
  98.  */
  99. typedef enum {
  100.     no_err=0,     /**< Encryption/decryption is successful. */
  101.     err_hookword, /**< Decrypted file can not be obtained because of
  102.                    * not correct password/hookword. */
  103.     o_err_read,   /**< Can not open for reading the original file. */
  104.     t_err_read,   /**< Can not open for reading the temp file. */
  105.     o_err_write,  /**< Can not open for writing the original file. */
  106.     t_err_write,  /**< Can not open for writing the temp file. */
  107.     o_err_save,   /**< Can not save the original file.
  108.                    * Error function fclose(). */
  109.     t_err_save,   /**< Can not save the temp file.
  110.                    * Error function fclose(). */
  111.     o_err_create, /**< Can not create the original file.
  112.                    * Error function createyep(). */
  113.     t_err_create  /**< Can not create the temp file.
  114.                    * Error function createyep(). */
  115. } cstatus;
  116.  
  117. /**
  118.  * @enum maintype
  119.  * @brief The way to open the file.
  120.  */
  121. typedef enum {
  122.     editfile,   /**< The file is open to change/read. */
  123.     changepass  /**< The file is opened to change the password. */
  124. } maintype;
  125.  
  126. /* SYSTEM FUNCTIONS */
  127. /*---------------------------------------------------------------------------*/
  128. extern bool tsarg(const char *, int , ...);
  129. extern void errexit(const char *, ...);
  130. extern char *geths(char [], int );
  131. extern int intrand(int );
  132. extern char *strrand(char [], int );
  133. extern char csymbol(const char , int );
  134. extern bool cstr(char [], int , const char *, const char *, cmethod );
  135. extern bool createyep(const char *, const char *, const char *);
  136. extern cstatus decodingfile(const char *, const char *,
  137.     const char *, const char *);
  138. extern cstatus encodingfile(const char *, const char *,
  139.     const char *, const char *);
  140. extern int terminal(const char *, ...);
  141.  
  142. /* SCREEN FUNCTIONS */
  143. /*---------------------------------------------------------------------------*/
  144. extern void s_help(void);
  145. extern void s_main(const char *, const char *, const char *,
  146.     const char *, maintype );
  147.  
  148. /* VIRTUAL SCREEN FUNCTIONS */
  149. /*---------------------------------------------------------------------------*/
  150. extern void vs_newpass(char [], char [], const char *);
  151.  
  152. /* MAIN */
  153. /*---------------------------------------------------------------------------*/
  154. /**
  155.  * @brief Yep main function.
  156.  *
  157.  * @param argc Count of arguments passed.
  158.  * @param argv The list of arguments.
  159.  *
  160.  * @return Returns zero on success of the program.
  161.  */ //*
  162. int
  163. main(int argc, char **argv)
  164. {
  165.     // "editor" - text editor software.
  166.     // "tempdir" - store temporary files.
  167.     // "hookword" - indicator for file recovery.
  168.     char *editor = NULL,
  169.          *tempdir = NULL,
  170.          *hookword = NULL;
  171.  
  172.     // The program requires access to the UNIX shell.
  173.     if (!system(NULL))
  174.         errexit("The UNIX shell is not available.\n");
  175.  
  176.     // Must be at least one external argument.
  177.     if (argc < 2)
  178.         errexit("See the help page on the program.\n");
  179.  
  180.     // Read the arguments list.
  181.     for (int i = 1; i < argc; ++i)
  182.         if (tsarg(argv[i], ARGV_HELP))
  183.             // Show help screen.
  184.             s_help();
  185.         else if (tsarg(argv[i], ARGV_HOOKWORD)) {
  186.             // Read hookword.
  187.             if (++i < argc)
  188.                 hookword = argv[i];
  189.             else
  190.                 errexit("Hookword parameter is not specified.\n");
  191.         } else if (tsarg(argv[i], ARGV_TEMPDIR)) {
  192.             // Read tempdir.
  193.             if (++i < argc)
  194.                 tempdir = argv[i];
  195.             else
  196.                 errexit("Tempdir parameter is not specified.\n");
  197.         } else if (tsarg(argv[i], ARGV_NEWPASS)) {
  198.             // Set new password on file.
  199.             if (++i < argc) {
  200.                 if (!hookword)
  201.                     hookword = DEFAULT_HOOKWORD;
  202.  
  203.                 if (!tempdir)
  204.                     tempdir = DEFAULT_TEMPDIR;
  205.  
  206.                 s_main(hookword, editor, argv[i], tempdir, changepass);
  207.             } else
  208.                 errexit("Don't specify a file for change the password.\n");
  209.         } else {
  210.             // Get the editor and a filename.
  211.             editor = argv[i];
  212.             if (++i < argc) {
  213.                 if (i + 1 < argc)
  214.                     errexit("Too many arguments.\n");
  215.  
  216.                 if (!hookword)
  217.                     hookword = DEFAULT_HOOKWORD;
  218.  
  219.                 if (!tempdir)
  220.                     tempdir = DEFAULT_TEMPDIR;
  221.  
  222.                 s_main(hookword, editor, argv[i], tempdir, editfile);
  223.             } else
  224.                 errexit("The file is not specified.\n");
  225.         } // end if ().
  226.  
  227.     return 0;
  228. } // end main(). */
  229.  
  230. /* SYSTEM FUNCTIONS */
  231. /*---------------------------------------------------------------------------*/
  232. /**
  233.  * @brief To determine whether an \a arg list of available string
  234.  * arguments \a (...).
  235.  *
  236.  * @param arg Argument (string) for comparison.
  237.  * @param count Number of arguments in the list of comparisons.
  238.  * @param ... List of comparisons.
  239.  *
  240.  * @return
  241.  * - true - If the argument \a arg corresponds to at least one argument
  242.  * from the argument list.
  243.  * - false - If the argument \a arg does not correspond to any argument
  244.  * from the argument list.
  245.  */ //*
  246. bool
  247. tsarg(const char *arg, int count, ...)
  248. {
  249.     va_list ptr;
  250.     char *str = NULL;
  251.     bool result = false;
  252.  
  253.     // The argument list is empty.
  254.     if (count < 1)
  255.         return result;
  256.  
  257.     // Find the argument.
  258.     va_start(ptr, count);
  259.  
  260.     while ((str = va_arg(ptr, char *))
  261.             && !result && count-- > 0)
  262.         if (!strcmp(arg, str))
  263.             result = true;
  264.  
  265.     va_end(ptr);
  266.  
  267.     return result;
  268. } // end tsarg(). */
  269.  
  270. /**
  271.  * @brief  Exit on error.
  272.  *
  273.  * @detailed This function takes cover those arguments as printf() function
  274.  * from the C standard library.
  275.  *
  276.  * @param format Error message.
  277.  * @param ... The data formatting.
  278.  *
  279.  * @return  No data is returned.
  280.  */ //*
  281. void
  282. errexit(const char *format, ...)
  283. {
  284.     va_list ptr;
  285.     char buf[MAXLEN_BUF];
  286.  
  287.     // Format the error message.
  288.     va_start(ptr, format);
  289.     sprintf(buf, "*** Error: %s.", format);
  290.     vfprintf(stderr, buf, ptr);
  291.     va_end(ptr);
  292.  
  293.     exit(1);
  294. } // end errexit(). */
  295.  
  296. /**
  297.  * @brief Read from standard input hidden line.
  298.  *
  299.  * @param buf The buffer where written to a string from stdin.
  300.  * @param bufsize The size of the buffer.
  301.  *
  302.  * @return Returns a pointer to the line of input that is placed in the
  303.  * buffer \a buf.
  304.  */ //*
  305. char
  306. *geths(char buf[], int bufsize)
  307. {
  308.     struct termios term, oldterm;
  309.     int ch, i = 0, max = bufsize - 1;
  310.  
  311.     // Do not display the characters as you type.
  312.     tcgetattr(0, &term);
  313.     oldterm = term;
  314.     term.c_lflag &= ~ECHO;          // Does not display the characters.
  315.     term.c_lflag &= ~ICANON;        // Do not expect the press enter.
  316.     tcsetattr(0, TCSANOW, &term);
  317.  
  318.     // Read the hidden characters.
  319.     while ((ch = getchar()) != EOF && ch != '\n')
  320.         if (ch == 127 || ch == 8 || ch == '\b') {
  321.             if (i > 0) i--;
  322.         } else if (i < max)
  323.             buf[i++] = ch;
  324.  
  325.     buf[i++] = '\0';
  326.  
  327.     // Restore the old display options.
  328.     term = oldterm;
  329.     tcsetattr(0, TCSANOW, &term);
  330.  
  331.     return buf;
  332. } // end geths(). */
  333.  
  334. /**
  335.  * @brief  Generate random number.
  336.  *
  337.  * @param max The right border of the generated numbers.
  338.  *
  339.  * @return  The function returns a random number between \a 0 and \a max. When
  340.  * the function returns an error number \a -1.
  341.  *
  342.  * @see strrand().
  343.  */ //*
  344. int
  345. intrand(int max)
  346. {
  347.     struct timeval tp;
  348.     struct timezone tzp;
  349.     unsigned stime;
  350.  
  351.     // There is an extreme right edge.
  352.     max = abs(max);
  353.     if (max >= 32767)
  354.         return -1;
  355.  
  356.     // Random number depends on the microseconds.
  357.     if (gettimeofday(&tp, &tzp) == -1)
  358.         return -1;
  359.  
  360.     stime = (unsigned)tp.tv_usec;
  361.     srand(stime);
  362.  
  363.     // Return a random number in the range 0 ... max.
  364.     return abs(rand()%max);
  365. } // end intrand(). */
  366.  
  367. /**
  368.  * @brief Create a random string.
  369.  *
  370.  * @param buf A random sequence of characters will be written into this buffer.
  371.  * @param bufsize The size of the buffer.
  372.  *
  373.  * @return Returns a pointer to a random string that was placed in the
  374.  * buffer \a buf.
  375.  *
  376.  * @see intrand().
  377.  */ //*
  378. char
  379. *strrand(char buf[], int bufsize)
  380. {
  381.     char *alphabet = "QWERTYUIOPASDFGHJKLZXCVBNM"
  382.                      "qwertyuiopasdfghjklzxcvbnm"
  383.                      "1234567890";
  384.     int alphsize = strlen(alphabet);
  385.  
  386.     // The minimum buffer size - 1 bytes.
  387.     if (bufsize <= 0)
  388.         return NULL;
  389.  
  390.     // Generate random string.
  391.     for (int i=0; i<bufsize; ++i) {
  392.         int rn = intrand(alphsize);
  393.         if (rn >= 0 && rn < alphsize)
  394.             buf[i] = *(alphabet + rn);
  395.         else if (i > 0)
  396.             --i;
  397.     } // end for ().
  398.  
  399.     buf[bufsize-1] = '\0';
  400.  
  401.     return buf;
  402. } // end strrand(). */
  403.  
  404. /**
  405.  * @brief Encode a character offset.
  406.  *
  407.  * @param ch The symbol to encode.
  408.  * @param seek The shift to encode.
  409.  *
  410.  * @return Returns the encoded (If  \a seek variable  > = 0)/decoded (If
  411.  * \a seek variable <0) symbol. If symbol failed to encode/decode, returns the
  412.  * character \a ch variable .
  413.  *
  414.  * @see cstr().
  415.  */ //*
  416. char
  417. csymbol(const char ch, int seek)
  418. {
  419.     char result = ch;
  420.     char *alphabet = "QWERTYUIOPASDFGHJKLZXCVBNM"
  421.                      "qwertyuiopasdfghjklzxcvbnm"
  422.                      "1234567890 !@#$%^&*()_-+{}:";
  423.     int alphsize = strlen(alphabet);
  424.  
  425.     // Determine the symbol.
  426.     for (int i=0; i < alphsize; ++i)
  427.         if (ch == *(alphabet + i)) {
  428.             seek += i;
  429.  
  430.             while (seek >= alphsize)
  431.                 seek -= alphsize;
  432.                
  433.             while (seek < 0)
  434.                 seek += alphsize;
  435.  
  436.             if (seek >= 0 && seek < alphsize)
  437.                 result = *(alphabet + seek);
  438.  
  439.             break;
  440.         } // end if ().
  441.  
  442.     return result;
  443. } // end csymbol(). */
  444.  
  445. /**
  446.  * @brief Cryptography string.
  447.  *
  448.  * @param buf Encoded string is placed in the buffer.
  449.  * @param bufsize The size of the buffer.
  450.  * @param str The string to encode.
  451.  * @param pass Password to encrypt the string.
  452.  * @param method Method: encode/decode.
  453.  *
  454.  * @return
  455.  * - true - If the string \a str has been successfully encoded/decoded
  456.  *   and placed in buffer \a buf.
  457.  * - false - If you encode/decode the string is impossible.
  458.  *
  459.  * @see csymbol().
  460.  */ //*
  461. bool
  462. cstr(char buf[], int bufsize, const char *str, const char *pass,
  463.      cmethod method)
  464. {
  465.     int len = strlen(pass), seek=0;
  466.     bool result = true;
  467.  
  468.     // Determine the offset.
  469.     for (int i = 0; i < len; ++i)
  470.         seek = seek + ((int)(char)*(pass + i)) * i;
  471.  
  472.     // Can I put the original in the buffer?
  473.     // Determine the count of processed symbols.
  474.     len = strlen(str);
  475.     if (len > bufsize - 1)
  476.         result = false;
  477.  
  478.     // encode || decode str.
  479.     if (result) {
  480.         for (int i = 0; i < len; ++i)
  481.             buf[i] = csymbol((char)*(str+i), (seek + i) * method);
  482.         buf[len] = '\0';
  483.     } else
  484.         buf[0] = '\0';
  485.  
  486.     return result;
  487. } // end cstr(). */
  488.  
  489. /**
  490.  * @brief Creates an empty yep-file recording it encoded a keyword (hookword).
  491.  *
  492.  * @param hookword Word of the key.
  493.  * @param pass Password.
  494.  * @param file The file to be created.
  495.  *
  496.  * @return
  497.  * - true - If the file is successfully created.
  498.  * - false - An error occurred while creating the file.
  499.  */ //*
  500. bool
  501. createyep(const char *hookword, const char *pass,
  502.     const char *file)
  503. {
  504.     FILE *f_file;
  505.     char buf[MAXLEN_BUF];
  506.  
  507.     if (!(f_file = fopen(file, "w")))
  508.         return false;
  509.  
  510.     cstr(buf, MAXLEN_BUF, hookword, pass, encode);
  511.     strncat(buf, "\n", MAXLEN_BUF);
  512.     fputs(buf, f_file);
  513.  
  514.     if(fclose(f_file))
  515.         return false;
  516.  
  517.     return true;
  518. } // end createyep(). */
  519.  
  520. /**
  521.  * @brief Вуcode file.
  522.  *
  523.  * @param hookword Word of the key.
  524.  * @param pass Password.
  525.  * @param file File for decoding.
  526.  * @param tempfile The temporary file.
  527.  *
  528.  * @return
  529.  * - no_err - If the operation is executed without error.
  530.  * - o_err_read - Can not open file \a file for reading.
  531.  * - t_err_write - Can not open file \a tempfile for writing.
  532.  * - err_hookword - Wrong password or secret word.
  533.  * - o_err_save - Unable to save file \a file.
  534.  * - t_err_save - Unable to save file \a tempfile.
  535.  *
  536.  * @see encodingfile().
  537.  */ //*
  538. cstatus
  539. decodingfile(const char *hookword, const char *pass, const char *file,
  540.     const char *tempfile)
  541. {
  542.     FILE *f_file, *f_tempfile;
  543.     char buf[MAXLEN_BUF], str[MAXLEN_BUF];
  544.     bool hw_tested = false, result = no_err;
  545.  
  546.     if (!(f_file = fopen(file, "r")))
  547.         return o_err_read;
  548.  
  549.     if (!(f_tempfile = fopen(tempfile, "w"))) {
  550.         fclose(f_file);
  551.         return t_err_write;
  552.     } // end if ().
  553.  
  554.     // Encoding file.
  555.     while(!feof(f_file)) {
  556.         if (!hw_tested) {
  557.             // Read hookword.
  558.             hw_tested = true;
  559.  
  560.             if(fgets(buf, MAXLEN_BUF, f_file)) {
  561.                 buf[strlen(buf)-1] = '\0'; // Remove "\n" symbol.
  562.                 cstr(str, MAXLEN_BUF, buf, pass, decode);
  563.  
  564.                 if (strcmp(str, hookword)) {
  565.                     result = err_hookword;
  566.                     break;
  567.                 } // end if ().
  568.             } else {
  569.                 result = err_hookword;
  570.                 break;
  571.             }
  572.         } else {
  573.             // Read body.
  574.             buf[0] = '\0';
  575.             str[0] = '\0';
  576.             if(fgets(buf, MAXLEN_BUF, f_file)) {
  577.                 cstr(str, MAXLEN_BUF, buf, pass, decode);
  578.                 fputs(str, f_tempfile);
  579.             } // end if ().
  580.         } // end if ().
  581.     } // end while ().
  582.  
  583.     if(fclose(f_file)) {
  584.         fclose(f_tempfile);
  585.         return o_err_save;
  586.     } // end if ().
  587.  
  588.     if(fclose(f_tempfile))
  589.         return t_err_save;
  590.  
  591.     return result;
  592. } // end decodingfile(). */
  593.  
  594. /**
  595.  * @brief Encode file.
  596.  *
  597.  * @param hookword Word of the key.
  598.  * @param pass Password.
  599.  * @param file File for decoding.
  600.  * @param tempfile The temporary file.
  601.  *
  602.  * @return
  603.  * - no_err - If the operation is executed without error.
  604.  * - o_err_create - If the function createyep() caused the error,
  605.  *   etc. can not create file \a file.
  606.  * - o_err_write - Can not open file for writing \a file.
  607.  * - t_err_read - Can not open file for reading \a tempfile.
  608.  * - o_err_save - Unable to close file \a file.
  609.  * - t_err_save - Unable to close file \a tempfile.
  610.  *
  611.  * @see decodingfile().
  612.  */ //*
  613. cstatus
  614. encodingfile(const char *hookword, const char *pass, const char *file,
  615.     const char *tempfile)
  616. {
  617.     FILE *f_file, *f_tempfile;
  618.     char buf[MAXLEN_BUF], str[MAXLEN_BUF];
  619.     bool result = no_err;
  620.  
  621.     if (!createyep(hookword, pass, file))
  622.         return o_err_create;
  623.  
  624.     if (!(f_file = fopen(file, "a")))
  625.         return o_err_write;
  626.  
  627.     if (!(f_tempfile = fopen(tempfile, "r"))) {
  628.         fclose(f_file);
  629.         return t_err_read;
  630.     } // end if ().
  631.  
  632.     // Decoding file.
  633.     while(!feof(f_tempfile)) {
  634.         // Write body.
  635.         buf[0] = '\0';
  636.         str[0] = '\0';
  637.         if(fgets(buf, MAXLEN_BUF, f_tempfile)) {
  638.             cstr(str, MAXLEN_BUF, buf, pass, encode);
  639.             fputs(str, f_file);
  640.         }
  641.     } // end while ().
  642.  
  643.     if(fclose(f_file)) {
  644.         fclose(f_tempfile);
  645.         return o_err_save;
  646.     } // end if ();
  647.  
  648.     if(fclose(f_tempfile))
  649.         return t_err_save;
  650.  
  651.     return result;
  652. } // end encodingfile(). */
  653.  
  654. /**
  655.  * @brief Executing shell commands.
  656.  *
  657.  * @detailed This function takes cover those arguments as printf() function
  658.  * from the C standard library.
  659.  *
  660.  * @param format Command for the terminal.
  661.  * @param ... Formatting options.
  662.  *
  663.  * @return Returns integer - the result of a shell command.
  664.  */ //*
  665. int
  666. terminal(const char *format, ...)
  667. {
  668.     va_list ptr;
  669.     char buf[MAXLEN_BUF];
  670.  
  671.     va_start(ptr, format);
  672.     vsprintf(buf, format, ptr);
  673.     va_end(ptr);
  674.  
  675.     return system(buf);
  676. } // end terminal(). */
  677.  
  678. /* SCREEN FUNCTIONS */
  679. /*---------------------------------------------------------------------------*/
  680. /**
  681.  * @brief Show help page.
  682.  *
  683.  * @return No data is returned.
  684.  */ //*
  685. void
  686. s_help(void)
  687. {
  688.     printf("\nNAME\n"
  689.         "\tyep - encrypted text files.\n\n"
  690.         "SYNOPSIS\n"
  691.         "\tyep [-w hookword] [-d tempdir] editor file\n"
  692.         "\tyep [-h | -i]\n"
  693.         "\tyep [-w hookword] [-d tempdir] -p file\n\n"
  694.         "DESCRIPTION\n"
  695.         "\tyep program allows you to encrypt text files using the "
  696.         "public key.\n\n"
  697.         "OPTIONS\n"
  698.         "\t-w hookword\n"
  699.         "\t\tEstablishes additional protection for the word file. This \n"
  700.         "\t\tword should be that you could safely recover an encrypted \n"
  701.         "\t\tfile. If the word is not specified - the word will be used \n"
  702.         "\t\tby default.\n"
  703.         "\t-p file\n"
  704.         "\t\tThe flag allows you to change the previously set password,\n"
  705.         "\t\tand the protection word (hookword).\n"
  706.         "\t-d tempdir\n"
  707.         "\t\tSets the directory for storing temporary files.\n"
  708.         "\t-h, -i\n"
  709.         "\t\tDisplay help information about the program.\n"
  710.         "\teditor\n"
  711.         "\t\tSpecify a text editor synchronous: vi, vim, ee ... Use \n"
  712.         "\t\tasynchronous editors (geany &, emacs & ...) - is impossible.\n"
  713.         "\tfile\n"
  714.         "\t\tThe file to be encrypted / decrypted. If the file does not \n"
  715.         "\t\texist - it is created.\n\n"
  716.         "BUGS\n"
  717.         "\tEmail  bug  reports  to  iam@valsorym.com.  Be sure to include \n"
  718.         "\tthe word \"yep bugs\" somewhere in the \"Subject:\" field.\n");
  719.  
  720.     exit(0);
  721. } // end help(). */
  722.  
  723. /**
  724.  * @brief The main function of encoding, decoding, and change the
  725.  * password on file.
  726.  *
  727.  * @param hookword Secret word.
  728.  * @param editor Synchronous text editor.
  729.  * @param file File manipulation.
  730.  * @param tempdir The directory for storing temporary files.
  731.  * @param type The method of handling file: encoding/decoding or change
  732.  * your password.
  733.  *
  734.  * @return No data is returned.
  735.  */ //*
  736. void
  737. s_main(const char *hookword, const char *editor, const char *file,
  738.     const char *tempdir, maintype type)
  739. {
  740.     char newhookword[MAXLEN_SYSKEY],
  741.          passagain[MAXLEN_SYSKEY],
  742.          pass[MAXLEN_SYSKEY];
  743.     bool existfile = false,
  744.          existeditor = false;
  745.     char tempname[MAXLEN_TEMPNAME],
  746.          tempfile[MAXLEN_PATH];
  747.     int  len = 0;
  748.  
  749.     // Create a random filename for a temporary file.
  750.     do {
  751.         if (!strrand(tempname, MAXLEN_TEMPNAME))
  752.             errexit("Unable to create a temporary name.\n");
  753.         len = strlen(tempname);
  754.     } while (len < MAXLEN_TEMPNAME/2);
  755.  
  756.     if (strlen(tempdir) + MAXLEN_TEMPNAME > MAXLEN_PATH)
  757.         errexit("A very long name for a temporary file.\n");
  758.  
  759.     sprintf(tempfile, "%s/%s", tempdir, tempname);
  760.  
  761.     // Create a YEP temporary directory.
  762.     if (terminal("ls -l -d %s | grep ^d", tempdir))
  763.         if (terminal("mkdir -p %s", tempdir))
  764.             errexit("Can not create a directory for storing "
  765.                 "temporary files.\n");
  766.  
  767.     // Check for the file.
  768.     if (!(existfile = !terminal("ls -l -d %s | grep ^-", file)))
  769.         if (!terminal("ls -l -d %s | grep ^d", file)) {
  770.             // There exists a directory with that name: filename.
  771.             terminal("clear");
  772.             errexit("There exists a directory with that name: %s.\n", file);
  773.         } // end if ().
  774.  
  775.     // Checking the editor.
  776.     existeditor = !terminal("which %s", editor);
  777.     terminal("clear");
  778.  
  779.     // Create interface.
  780.     printf("This will open the file with the following parameters:\n");
  781.     printf("    Filename%s:\t%s\n", (existfile ? (char*)"" :
  782.         (char*)" (file not exist)"), file);
  783.  
  784.     if (type == editfile)
  785.         printf("    Editor%s:\t%s\n", (existeditor ? (char*)"" :
  786.             (char*)" (editor is not installed)"), editor);
  787.  
  788.     printf("    Hookword%s:\t%s\n\n", (!strcmp(DEFAULT_HOOKWORD, hookword) ?
  789.         (char*)" (default word protection)" : (char*)""), hookword);
  790.  
  791.     if (type == editfile) {
  792.         // Just open file.
  793.         if (!existeditor)
  794.             errexit("Editor is not installed: %s.\n", editor);
  795.     } else if (type == changepass) {
  796.         // Change password.
  797.         if (!existfile)
  798.             errexit("Сan not change the password on this file: %s.\n", file);
  799.     } else
  800.         // Bad type parameter.
  801.         errexit("Is not valid action.\n");
  802.     // end if ().
  803.  
  804.     // Read the password.
  805.     printf("\nTo exit, press Ctrl+C.\n");
  806.     while (true) {
  807.         printf("\nPassword: ");
  808.         geths(pass, MAXLEN_SYSKEY);
  809.  
  810.         if (!existfile) {
  811.             printf("\nEnter password again: ");
  812.             geths(passagain, MAXLEN_SYSKEY);
  813.  
  814.             if (strcmp(pass, passagain))
  815.                 printf("\nPasswords do not match. Please, enter again.\n");
  816.             else {
  817.                 // Need create file.
  818.                 if (!createyep(hookword, pass, file))
  819.                     errexit("The file can not be created: %s.\n", file);
  820.                 break;
  821.             }
  822.         } else
  823.             break;
  824.         // end if ().
  825.     } // end while ().
  826.     printf("\n");
  827.  
  828.     // Decoding.
  829.     switch ((int)decodingfile(hookword, pass, file, tempfile)) {
  830.         case (int)o_err_read:
  831.             errexit("Can not open file: %s.\n", file);
  832.             break;
  833.         case (int)t_err_write:
  834.             errexit("Unable to open temporary file for writing: %s.\n",
  835.                 tempfile);
  836.             break;
  837.         case (int)err_hookword:
  838.             errexit("Hookword was not recognized.\n");
  839.             break;
  840.         case (int)o_err_save:
  841.             errexit("Unable to close file: %s.\n", file);
  842.             break;
  843.         case (int)t_err_save:
  844.             errexit("Unable to close file: %s.\n", tempfile);
  845.             break;
  846.     } // end switch ().
  847.  
  848.     if (type == editfile) {
  849.         // Open editor.
  850.         if (terminal("%s %s", editor, tempfile))
  851.             errexit("Can not open file: %s.\n", tempfile);
  852.     } else if (type == changepass) {
  853.         // Change password.
  854.         sprintf(newhookword, "%s", hookword);
  855.         vs_newpass(newhookword, pass, file);
  856.         hookword = newhookword;
  857.     } // end if ().
  858.  
  859.     // Encoding again.
  860.     switch ((int)encodingfile(hookword, pass, file, tempfile)) {
  861.         case (int)o_err_create:
  862.             errexit("Can not create file: %s.\n", file);
  863.             break;
  864.         case (int)o_err_write:
  865.             errexit("Unable to write data to file: %s.\n", file);
  866.             break;
  867.         case (int)t_err_read:
  868.             errexit("Unable to read data from the temfile: %s.\n", tempfile);
  869.             break;
  870.         case (int)o_err_save:
  871.             errexit("Can not save the file: %s.\n", file);
  872.             break;
  873.         case (int)t_err_save:
  874.             errexit("Can not save the file: %s.\n", tempfile);
  875.             break;
  876.     } // end switch ().
  877.  
  878.     // Remove temp file.
  879.     if (terminal("rm -f %s", tempfile))
  880.         printf("\nThe temporary file was not deleted: %s.\n", tempfile);
  881.  
  882.     exit(0);
  883. } // end s_main(). */
  884.  
  885. /**
  886.  * @brief Function-interface to change password.
  887.  *
  888.  * @param hookword Buffer storage keyword.
  889.  * @param pass Buffer storage password.
  890.  * @param file The file to change the password.
  891.  *
  892.  * @return No data is returned.
  893.  */ //*
  894. void
  895. vs_newpass(char hookword[], char pass[], const char *file)
  896. {
  897.     char passagain[MAXLEN_SYSKEY],
  898.          cmd;
  899.  
  900.     // Go-go-go!!!
  901.     while (true) {
  902.         terminal("clear");
  903.         printf("You are trying to change the system "
  904.                "data to a file: %s.\n", file);
  905.         printf("Choose one of the actions:\n");
  906.         printf("    1. Change password (*******).\n");
  907.         printf("    2. Change hookword (%s).\n", hookword);
  908.         printf("    3. Save and exit.");
  909.         printf("\nTo exit, press Ctrl+C.\n");
  910.  
  911.         printf("\nYour choice: ");
  912.         scanf("%c", &cmd);
  913.         while (getchar() != '\n'); // Clear stdin buffer. Bad method. :(
  914.  
  915.         if (cmd == '1') {
  916.             // Change password.
  917.             while (true) {
  918.                 printf("\nEnter new password: ");
  919.                 geths(pass, MAXLEN_SYSKEY);
  920.  
  921.                 printf("\nEnter password again: ");
  922.                 geths(passagain, MAXLEN_SYSKEY);
  923.  
  924.                 if (strcmp(pass, passagain))
  925.                     printf("\nPasswords do not match. Please, enter again.\n");
  926.                 else
  927.                     break;
  928.             } // end while ().
  929.         } else if (cmd == '2') {
  930.             // Change hookword.
  931.             char hwformat[15];
  932.             sprintf(hwformat, "%%%ds", MAXLEN_SYSKEY-1);
  933.             printf("\nEnter new hookword: ");
  934.             scanf(hwformat, hookword);
  935.             while (getchar() != '\n'); // Clear stdin buffer. Bad method. :(
  936.         } else if (cmd == '3') {
  937.             // Save and exit;
  938.             terminal("clear");
  939.             printf("\nThe changes take effect.\n");
  940.             return;
  941.         } // end if ().
  942.     } // end while ().
  943.  
  944.     exit(0);
  945. } // end vs_newpass(). */
  946.  
  947. /* The End. */