Download | Plain Text | No Line Numbers


  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #include "global.h"
  8.  
  9. typedef enum
  10. {
  11. NONE,
  12. FIND,
  13. HIDE
  14. } stegit_mode_t;
  15.  
  16. static void sighandler(int signum)
  17. {
  18. #ifdef DEBUG
  19. (void) printf("signal %d received\n", signum);
  20. #endif
  21. error = 1;
  22. }
  23.  
  24. static void usage(void)
  25. {
  26. (void) fprintf(stderr, "Usage: %s -f | -h [-o <filename>]\n", me);
  27. (void) fprintf(stderr, " -f\t\t\tfind mode\n");
  28. (void) fprintf(stderr, " -h\t\t\thide mode\n");
  29. (void) fprintf(stderr, " [-o <filename>]\toutput filename\n");
  30. (void) exit(EXIT_FAILURE);
  31. }
  32.  
  33. static void hide(FILE *in, FILE *out)
  34. {
  35. int ch;
  36. char *word;
  37. int insertdot, wordcount = 0;
  38.  
  39. (void) srandom(time(NULL) * getpid());
  40. insertdot = 5 + (int)(11.0 * (random() / (RAND_MAX + 1.0)));
  41. while(!error && (ch = getc(in)) != EOF && ch != '\n')
  42. {
  43. if (ch < 0 || ch >= (sizeof(charmap) / sizeof(charmap[0])))
  44. continue;
  45.  
  46. word = charmap[ch];
  47. if (word == NULL)
  48. continue;
  49.  
  50. if (wordcount > 0 && putc(' ', out) == EOF)
  51. {
  52. (void) printferr("Error while writing to output");
  53. return;
  54. }
  55.  
  56. if (fputs(word, out) == EOF)
  57. {
  58. (void) printferr("Error while writing to output");
  59. return;
  60. }
  61.  
  62. ++wordcount;
  63.  
  64. if (insertdot <= wordcount)
  65. {
  66. if (putc('.', out) == EOF)
  67. {
  68. (void) printferr("Error while writing to output");
  69. return;
  70. }
  71. insertdot = wordcount + 5 + (int)(11.0 * (random() / (RAND_MAX + 1.0)));
  72. }
  73. }
  74.  
  75. if (!error && wordcount > 0 && putc('\n', out) == EOF)
  76. {
  77. (void) printferr("Error while writing to output");
  78. return;
  79. }
  80. }
  81.  
  82. static char lookup(char *str)
  83. {
  84. int i;
  85. char *str2;
  86.  
  87. for(i = 0; !error && i < sizeof(charmap) / sizeof(charmap[0]); ++i)
  88. {
  89. str2 = charmap[i];
  90. if (str2 == NULL)
  91. continue;
  92. if (strcmp(str2, str) == 0)
  93. return i;
  94. }
  95. return -1;
  96. }
  97.  
  98. static void find(FILE *in, FILE *out)
  99. {
  100. char buf[80]; /* increase that for more speed */
  101. size_t bufsize = sizeof(buf) / sizeof(buf[0]);
  102. size_t read, off = 0;
  103. char ch, *sep = " .\r\n", *word, *brkt;
  104. int wordcount = 0;
  105.  
  106. buf[0] = '\0';
  107. while(!error && !ferror(in))
  108. {
  109. off = strlen(buf);
  110. if (off >= bufsize - 1)
  111. {
  112. errno = 0;
  113. (void) printferr("Unable to read input words. buffer is too small.");
  114. return;
  115. }
  116.  
  117. read = fread(buf + off, sizeof(buf[0]), bufsize - off - 1, in);
  118. if (ferror(in))
  119. {
  120. (void) printferr("Error while reading from output");
  121. return;
  122. }
  123. buf[read + off] = '\0';
  124.  
  125. for(word = strtok_r(buf, sep, &brkt);
  126. !error && word;
  127. word = strtok_r(NULL, sep, &brkt))
  128. {
  129. ch = lookup(word);
  130. if (ch >= 0)
  131. {
  132. if (putc(ch, out) == EOF)
  133. {
  134. (void) printferr("Error while writing to output");
  135. return;
  136. }
  137.  
  138. ++wordcount;
  139. buf[0] = '\0';
  140. continue;
  141. }
  142.  
  143. if (brkt == NULL)
  144. (void) strcpy(buf, word);
  145. }
  146.  
  147. if (read < bufsize - off - 1 || read == 0)
  148. break;
  149. }
  150.  
  151. if (!error && wordcount && putc('\n', out) == EOF)
  152. {
  153. (void) printferr("Error while writing to output");
  154. return;
  155. }
  156. }
  157.  
  158. int main(int argc, char *argv[])
  159. {
  160. int opt;
  161. char *outfile = NULL;
  162. FILE *fp = NULL;
  163. struct sigaction new_action, old_action;
  164. stegit_mode_t mode = NONE;
  165.  
  166. me = argv[0];
  167.  
  168. /* install signal handler */
  169. new_action.sa_handler = sighandler;
  170. sigemptyset(&new_action.sa_mask);
  171. new_action.sa_flags = 0; /* to avoid restart of blocking syscalls */
  172. INSTALL_SIGNAL(SIGINT, new_action, old_action)
  173. INSTALL_SIGNAL(SIGQUIT, new_action, old_action)
  174. INSTALL_SIGNAL(SIGTERM, new_action, old_action)
  175.  
  176. while ((opt = getopt(argc, argv, "fho:")) != -1)
  177. {
  178. switch(opt)
  179. {
  180. case 'f':
  181. if (mode != NONE)
  182. (void) usage();
  183. mode = FIND;
  184. break;
  185. case 'h':
  186. if (mode != NONE)
  187. (void) usage();
  188. mode = HIDE;
  189. break;
  190. case 'o':
  191. outfile = optarg;
  192. break;
  193. default:
  194. (void) usage();
  195. break;
  196. }
  197. }
  198.  
  199. if (mode == NONE || (mode == FIND && outfile != NULL))
  200. (void) usage();
  201.  
  202. #ifdef DEBUG
  203. (void) printf("mode=%s outfile=%s\n", (mode == FIND) ? "FIND" : "HIDE", outfile);
  204. #endif
  205.  
  206. if (mode == HIDE)
  207. {
  208. if (!error && outfile != NULL && (fp = fopen(outfile, "w")) == NULL)
  209. (void) bailout("%s", outfile);
  210. if (!error)
  211. (void) hide(stdin, (fp != NULL) ? fp : stdout);
  212. }
  213. else
  214. {
  215. if (!error)
  216. (void) find(stdin, stdout);
  217. }
  218.  
  219. if (fp != NULL)
  220. (void) fclose(fp);
  221.  
  222. return (error) ? 1 : 0;
  223. }
  224.