home *** CD-ROM | disk | FTP | other *** search
/ The Elite Hackers Toolkit / TheEliteHackersToolkitVolume1_1998.rar / HACKERS.BIN / hackers / snow_tar.gz / snow.tar / snow / main.c < prev    next >
C/C++ Source or Header  |  1997-01-09  |  5KB  |  252 lines

  1. /*
  2.  * Command-line program for hiding and extracting messages within
  3.  * the whitespace of text files.
  4.  *
  5.  * Usage: snow [-C][-Q][-S][-p passwd][-l line-len] [-f file | -m message]
  6.  *                    [infile [outfile]]
  7.  *
  8.  *    -C : Use compression
  9.  *    -Q : Be quiet
  10.  *    -S : Calculate the space available in the file
  11.  *    -l : Maximum line length allowanble
  12.  *    -p : Specify the password to encrypt the message
  13.  *
  14.  *    -f : Insert the message contained in the file
  15.  *    -m : Insert the message given
  16.  *
  17.  * If the program is executed without either of the -f or -m options
  18.  * then the program will attempt to extract a concealed message.
  19.  * The output will go to outfile if specified, stdout otherwise.
  20.  *
  21.  * Written by Matthew Kwan - December 1996
  22.  */
  23.  
  24. #include "snow.h"
  25.  
  26.  
  27. /*
  28.  * Declaration of global variables.
  29.  */
  30.  
  31. BOOL    compress_flag = FALSE;
  32. BOOL    quiet_flag = FALSE;
  33. int    line_length = 80;
  34.  
  35.  
  36. /*
  37.  * Encode a single character.
  38.  */
  39.  
  40. static BOOL
  41. character_encode (
  42.     unsigned char    c,
  43.     FILE        *infile,
  44.     FILE        *outfile
  45. ) {
  46.     int        i;
  47.  
  48.     for (i=0; i<8; i++) {
  49.         int        bit = ((c & (128 >> i)) != 0) ? 1 : 0;
  50.  
  51.         if (!compress_bit (bit, infile, outfile))
  52.         return (FALSE);
  53.     }
  54.  
  55.     return (TRUE);
  56. }
  57.  
  58.  
  59. /*
  60.  * Encode a string of characters.
  61.  */
  62.  
  63. static BOOL
  64. message_string_encode (
  65.     const char    *msg,
  66.     FILE        *infile,
  67.     FILE        *outfile
  68. ) {
  69.     compress_init ();
  70.  
  71.     while (*msg != '\0') {
  72.         if (!character_encode (*msg, infile, outfile))
  73.         return (FALSE);
  74.         msg++;
  75.     }
  76.  
  77.     return (compress_flush (infile, outfile));
  78. }
  79.  
  80.  
  81. /*
  82.  * Encode the contents of a file.
  83.  */
  84.  
  85. static BOOL
  86. message_fp_encode (
  87.     FILE        *msg_fp,
  88.     FILE        *infile,
  89.     FILE        *outfile
  90. ) {
  91.     int        c;
  92.  
  93.     compress_init ();
  94.  
  95.     while ((c = fgetc (msg_fp)) != EOF)
  96.         if (!character_encode (c, infile, outfile))
  97.         return (FALSE);
  98.  
  99.     if (ferror (msg_fp) != 0) {
  100.         perror ("Message file");
  101.         return (FALSE);
  102.     }
  103.  
  104.     return (compress_flush (infile, outfile));
  105. }
  106.  
  107.  
  108. /*
  109.  * Program's starting point.
  110.  * Processes command-line args and starts things running.
  111.  */
  112.  
  113. void
  114. main (
  115.     int        argc,
  116.     char        *argv[]
  117. ) {
  118.     int        c;
  119.     int        optind;
  120.     BOOL        errflag = FALSE;
  121.     BOOL        space_flag = FALSE;
  122.     char        *passwd = NULL;
  123.     char        *message_string = NULL;
  124.     FILE        *message_fp = NULL;
  125.     FILE        *infile = stdin;
  126.     FILE        *outfile = stdout;
  127.  
  128.     optind = 1;
  129.     for (optind = 1; optind < argc && argv[optind][0] == '-'; optind++) {
  130.         char    c = argv[optind][1];
  131.         char    *optarg;
  132.  
  133.         switch (c) {
  134.         case 'C':
  135.             compress_flag = TRUE;
  136.             break;
  137.         case 'Q':
  138.             quiet_flag = TRUE;
  139.             break;
  140.         case 'S':
  141.             space_flag = TRUE;
  142.             break;
  143.         case 'f':
  144.             if (argv[optind][2] != '\0')
  145.             optarg = &argv[optind][2];
  146.             else if (++optind == argc) {
  147.             errflag = TRUE;
  148.             break;
  149.             } else
  150.             optarg = argv[optind];
  151.  
  152.             if ((message_fp = fopen (optarg, "r")) == NULL) {
  153.             perror (optarg);
  154.             errflag = TRUE;
  155.             }
  156.             break;
  157.         case 'l':
  158.             if (argv[optind][2] != '\0')
  159.             optarg = &argv[optind][2];
  160.             else if (++optind == argc) {
  161.             errflag = TRUE;
  162.             break;
  163.             } else
  164.             optarg = argv[optind];
  165.  
  166.             if (sscanf (optarg, "%d", &line_length) != 1
  167.                             || line_length < 8) {
  168.             fprintf (stderr, "Illegal line length value '%s'\n",
  169.                                 optarg);
  170.             errflag = TRUE;
  171.             }
  172.             break;
  173.         case 'm':
  174.             if (argv[optind][2] != '\0')
  175.             optarg = &argv[optind][2];
  176.             else if (++optind == argc) {
  177.             errflag = TRUE;
  178.             break;
  179.             } else
  180.             optarg = argv[optind];
  181.  
  182.             message_string = optarg;
  183.             break;
  184.         case 'p':
  185.             if (argv[optind][2] != '\0')
  186.             optarg = &argv[optind][2];
  187.             else if (++optind == argc) {
  188.             errflag = TRUE;
  189.             break;
  190.             } else
  191.             optarg = argv[optind];
  192.  
  193.             passwd = optarg;
  194.             break;
  195.         default:
  196.             errflag = TRUE;
  197.             break;
  198.         }
  199.     }
  200.  
  201.     if (message_string != NULL && message_fp != NULL) {
  202.         fprintf (stderr, "Cannot specify both message string and file\n");
  203.         errflag = TRUE;
  204.     }
  205.  
  206.     if (errflag) {
  207.         fprintf (stderr, "Usage: %s [-C][-Q][-S]", argv[0]);
  208.         fprintf (stderr, "[-p passwd][-l line-len]");
  209.         fprintf (stderr, " [-f file | -m message]\n");
  210.         fprintf (stderr, "\t\t\t\t\t[infile [outfile]]\n");
  211.         exit (1);
  212.     }
  213.  
  214.     if (passwd != NULL)
  215.         password_set (passwd);
  216.  
  217.     if (optind < argc) {
  218.         if ((infile = fopen (argv[optind], "r")) == NULL) {
  219.         perror (argv[optind]);
  220.         exit (1);
  221.         }
  222.     }
  223.  
  224.     if (optind + 1 < argc) {
  225.         if ((outfile = fopen (argv[optind + 1], "w")) == NULL) {
  226.         perror (argv[optind + 1]);
  227.         exit (1);
  228.         }
  229.     }
  230.  
  231.     if (space_flag) {
  232.         space_calculate (infile);
  233.     } else if (message_string != NULL) {
  234.         if (!message_string_encode (message_string, infile, outfile))
  235.         exit (1);
  236.     } else if (message_fp != NULL) {
  237.         if (!message_fp_encode (message_fp, infile, outfile))
  238.         exit (1);
  239.         fclose (message_fp);
  240.     } else {
  241.         if (!message_extract (infile, outfile))
  242.         exit (1);
  243.     }
  244.  
  245.     if (outfile != stdout)
  246.         fclose (outfile);
  247.     if (infile != stdout)
  248.         fclose (infile);
  249.  
  250.     exit (0);
  251. }
  252.