1 /*
2  *cryptoslam: A tool for decoding cryptograms
3  *
4  *Copyright (C) 1997,2000,2003 Brian Enigma
5  *                             enigma@netninja.com
6  *                             http://sourceforge.net/projects/cryptoslam/
7  *
8  *   This program is free software; you can redistribute it and/or
9  *   modify it under the terms of the GNU General Public License as
10  *   published by the Free Software Foundation; either version 2 of
11  *   the License, or (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or EXISTANCE OF KITTEN.  See the GNU General
16  *   Public License for more details.
17  *
18  *   http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21 
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <curses.h>
25 #include <string.h>
26 #include "cryptogram.h"
27 
28 #define MENUBAR " S:SetChar U:UnSetChar R:ResetChars F:File T:Tools Q:Quit "
29 #define FILEMENU " L:Load T:saveText B:saveBinary S:SaveKeys K:LoadKeys N:New C:Cancel "
30 #define TOOLSMENU " R:RandomCypher 3:ROT13 T:Transform G:Generate C:Cancel "
31 
drawScreen(WINDOW * menu,WINDOW * message,WINDOW * alphabet,Cryptogram * cr)32 void drawScreen(WINDOW *menu,
33                 WINDOW *message,
34                 WINDOW *alphabet,
35                 Cryptogram *cr)
36 {
37     // Print the menu...
38     wclear(menu);
39     wcolor_set(menu, 1, NULL);
40     wattron(menu, WA_REVERSE);
41     mvwprintw(menu, 0, 0, "%s", MENUBAR);
42     wattroff(menu, WA_REVERSE);
43     wmove(menu, 0, strlen(MENUBAR));
44 
45     // Print the alphabet...
46     cr->paintAlphabet(alphabet);
47 
48     // Paint the message...
49     cr->paintMessage(message);
50 
51     wrefresh(menu);
52     wrefresh(message);
53     wrefresh(alphabet);
54 }
55 
fileMenu(WINDOW * menu,Cryptogram * cr)56 void fileMenu(WINDOW *menu, Cryptogram *cr)
57 {
58     char filename[255];
59     char key;
60     char *editor = NULL;
61     char command[1024] = "";
62     while (1)
63     {
64         wclear(menu);
65         wcolor_set(menu, 1, NULL);
66         wattron(menu, WA_REVERSE);
67         mvwprintw(menu, 0, 0, "%s", FILEMENU);
68         wattroff(menu, WA_REVERSE);
69         wmove(menu, 0, strlen(FILEMENU));
70         wrefresh(menu);
71 
72         noecho();
73         key = getch();
74         echo();
75         switch(key)
76         {
77             case 'L':
78             case 'l':
79                 wclear(menu);
80                 mvwprintw(menu, 0, 0, "File to open? ");
81                 wrefresh(menu);
82                 wgetnstr(menu, filename, 255);
83                 filename[254] = 0;
84                 cr->loadFile(filename);
85                 cr->calcPlaintext();
86                 return;
87             case 'T':
88             case 't':
89                 wclear(menu);
90                 mvwprintw(menu, 0, 0, "Text file to save? ");
91                 wrefresh(menu);
92                 wgetnstr(menu, filename, 255);
93                 filename[254] = 0;
94                 cr->saveFileText(filename);
95                 cr->calcPlaintext();
96                 return;
97             case 'B':
98             case 'b':
99                 wclear(menu);
100                 mvwprintw(menu, 0, 0, "Binary file to save? ");
101                 wrefresh(menu);
102                 wgetnstr(menu, filename, 255);
103                 filename[254] = 0;
104                 cr->saveFileBinary(filename);
105                 cr->calcPlaintext();
106                 return;
107             case 'N':
108             case 'n':
109                 wclear(menu);
110                 mvwprintw(menu, 0, 0, "File to create? ");
111                 wrefresh(menu);
112                 wgetnstr(menu, filename, 255);
113                 filename[254] = 0;
114                 editor = getenv("VISUAL");
115                 if (!editor)
116                     editor = getenv("EDITOR");
117                 if (!editor)
118                     return;
119                 strncpy(command, editor, 512);
120                 strcat(command, " ");
121                 strcat(command, filename);
122                 system(command);
123                 cr->loadFile(filename);
124                 cr->calcPlaintext();
125                 return;
126             case 'S':
127             case 's':
128                 wclear(menu);
129                 mvwprintw(menu, 0, 0, "File to save keys to? ");
130                 wrefresh(menu);
131                 wgetnstr(menu, filename, 255);
132                 filename[254] = 0;
133                 cr->saveKeys(filename);
134                 return;
135             case 'K':
136             case 'k':
137                 wclear(menu);
138                 mvwprintw(menu, 0, 0, "File to load keys from? ");
139                 wrefresh(menu);
140                 wgetnstr(menu, filename, 255);
141                 filename[254] = 0;
142                 cr->loadKeys(filename);
143                 return;
144             case 'C':
145             case 'c':
146                 return;
147         }
148     }
149 }
150 
toolsMenu(WINDOW * menu,WINDOW * message,WINDOW * alphabet,Cryptogram * cr)151 void toolsMenu(WINDOW *menu, WINDOW *message, WINDOW *alphabet, Cryptogram *cr)
152 {
153     char filename[255];
154     char key;
155     char *editor = NULL;
156     char command[1024] = "";
157 
158     wclear(message);
159     cr->paintStats(message);
160     wrefresh(message);
161     while (1)
162     {
163         wclear(menu);
164         wcolor_set(menu, 1, NULL);
165         wattron(menu, WA_REVERSE);
166         mvwprintw(menu, 0, 0, "%s", TOOLSMENU);
167         wattroff(menu, WA_REVERSE);
168         wmove(menu, 0, strlen(TOOLSMENU));
169         wrefresh(menu);
170 
171         noecho();
172         key = getch();
173         echo();
174         switch(key)
175         {
176             case 'R':
177             case 'r':
178                 cr->randomizeKeys();
179                 cr->calcPlaintext();
180                 return;
181             case 'T':
182             case 't':
183                 wclear(menu);
184                 wcolor_set(menu, 1, NULL);
185                 mvwprintw(menu, 0, 0, "Please wait, randomizing...");
186                 wmove(menu, 0, 27);
187                 wrefresh(menu);
188                 cr->randomizeMessage();
189                 cr->calcPlaintext();
190                 return;
191             case 'G':
192             case 'g':
193                 wclear(menu);
194                 wcolor_set(menu, 1, NULL);
195                 mvwprintw(menu, 0, 0, "Please wait, generating...");
196                 wmove(menu, 0, 27);
197                 wrefresh(menu);
198                 cr->newRandomMessage();
199                 cr->calcPlaintext();
200                 return;
201             case '3':
202                 for (int i=0; i < 26; i++)
203                     cr->set(i + 'A', ((i+13)%26) + 'A');
204                 cr->calcPlaintext();
205                 return;
206             case 'C':
207             case 'c':
208                 return;
209         }
210     }
211 }
212 
handleKey(char key,WINDOW * menu,WINDOW * message,WINDOW * alphabet,Cryptogram * cr)213 void handleKey(char key,
214                WINDOW *menu,
215                WINDOW *message,
216                WINDOW *alphabet,
217                Cryptogram *cr)
218 {
219     char key1, key2;
220     switch(key)
221     {
222         case 's':
223         case 'S':
224             wclear(menu);
225             mvwprintw(menu, 0, 0, "Cyphertext letter to set? ");
226             wrefresh(menu);
227             key1 = getch();
228             wclear(menu);
229             mvwprintw(menu, 0, 0, "Set letter \"%c\" to which plaintext letter (spacebar to unset)? ",
230                       key1);
231             wrefresh(menu);
232             key2 = getch();
233             cr->set(key1, key2);
234             cr->calcPlaintext();
235             break;
236         case 'u':
237         case 'U':
238             wclear(menu);
239             mvwprintw(menu, 0, 0, "Cyphertext letter to unset? ");
240             wrefresh(menu);
241             key1 = getch();
242             cr->unset(key1);
243             cr->calcPlaintext();
244             break;
245         case 'r':
246         case 'R':
247             for (char c = 'A'; c <= 'Z'; c++)
248                 cr->unset(c);
249             cr->calcPlaintext();
250             break;
251         case 't':
252         case 'T':
253             toolsMenu(menu, message, alphabet, cr);
254             break;
255         case 'f':
256         case 'F':
257             fileMenu(menu, cr);
258             break;
259     }
260 }
261 
mainLoop(Cryptogram * cr)262 void mainLoop(Cryptogram *cr)
263 {
264     WINDOW *main = initscr();
265     WINDOW *menu = subwin(main, 1, COLS, 0, 0);
266     WINDOW *message = subwin(main, LINES-4, COLS, 1, 0);
267     WINDOW *alphabet = subwin(main, 3, COLS, LINES-3, 0);
268     start_color();
269     init_pair(1, COLOR_GREEN, COLOR_BLACK);
270     init_pair(2, COLOR_BLUE, COLOR_BLACK);
271     init_pair(3, COLOR_WHITE, COLOR_BLACK);
272     char opt;
273     while (1)
274     {
275         drawScreen(menu, message, alphabet, cr);
276         wmove(main, 0, strlen(MENUBAR));
277         wrefresh(main);
278         noecho();
279         opt = getch();
280         echo();
281         if ( (opt=='q') || (opt=='Q') )
282             break;
283         handleKey(opt, menu, message, alphabet, cr);
284     }
285     endwin();
286 }
287 
main(int argc,char * argv[])288 int main(int argc, char *argv[])
289 {
290     Cryptogram cr;
291     if (argc==2)
292         cr.loadFile(argv[1]);
293     mainLoop(&cr);
294 }
295