]> git.sesse.net Git - freerainbowtables/blob - Server Applications/rtperfecter0.0/RTRead.cpp
initial
[freerainbowtables] / Server Applications / rtperfecter0.0 / RTRead.cpp
1 /*
2         Copyright (C) 2008 Steve Thomas <SMT837784@yahoo.com>
3
4         This file is part of RT Perfecter v0.0.
5
6         RT Perfecter v0.0 is free software: you can redistribute it and/or modify
7         it under the terms of the GNU General Public License as published by
8         the Free Software Foundation, either version 3 of the License, or
9         (at your option) any later version.
10
11         RT Perfecter v0.0 is distributed in the hope that it will be useful,
12         but WITHOUT ANY WARRANTY; without even the implied warranty of
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14         GNU General Public License for more details.
15
16         You should have received a copy of the GNU General Public License
17         along with RT Perfecter v0.0.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <time.h>
23 #include <ctime>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include "RTRead.h"
27
28 #ifdef HAVE_DIRENT_H
29         #include <dirent.h>
30 #else
31         // I know Microsoft's compiler, .Net 2005 or older, does not come with this file.
32         // You can use this if you don't have dirent.h: http://www.cs.fiu.edu/~weiss/cop4338_spr06/dirent.h
33         // Umm I'm not sure if the license on that file, which appears to be public domain, conflicts with GPL v3.
34         // So only use that if you need it and the licenses don't conflict.
35         #include "dirent.h"
36 #endif
37
38 #ifdef _WIN32
39         #include <conio.h>
40         #define DIRECTORY_SEPERATOR '\\'
41 #else
42         #include <fcntl.h>
43         #define DIRECTORY_SEPERATOR '/'
44 #endif
45
46 #ifndef NAME_MAX
47         #define NAME_MAX 256
48 #endif
49
50 #include "RTRead.h"
51
52 RTRead::RTRead(char *dir, uint64 maxIndex, int verbose)
53 {
54         int dirLen = strlen(dir), dirFileLen;
55         char *file = new char[dirLen + NAME_MAX + 2];
56         DIR *pDir;
57         struct dirent *pDirFile;
58         FileList *head = NULL, *current = NULL, *temp = new FileList;
59
60         // Init
61         m_verbose = verbose;
62         m_maxIndex = maxIndex;
63         m_chainsRead = 0;
64         m_chains = 0;
65         m_pqSize = 0;
66         m_pq = NULL;
67         temp->next = NULL;
68         strncpy(file, dir, dirLen);
69         if (dir[dirLen - 1] != DIRECTORY_SEPERATOR)
70         {
71                 file[dirLen] = DIRECTORY_SEPERATOR;
72                 dirLen++;
73         }
74
75         // Open directory
76         pDir = opendir(dir);
77         if (pDir == NULL)
78         {
79                 printf("Error #%u: Opening directory '%s'\n", errno, dir);
80                 exit(errno);
81         }
82
83         // Get files
84         for (pDirFile = readdir(pDir); pDirFile != NULL; pDirFile = readdir(pDir))
85         {
86                 dirFileLen = strlen(pDirFile->d_name);
87                 if (pDirFile->d_name[0] != '.' && dirFileLen > 3 &&
88                     pDirFile->d_name[dirFileLen - 3] == '.' &&
89                    (pDirFile->d_name[dirFileLen - 2] == 'r' || pDirFile->d_name[dirFileLen - 2] == 'R') &&
90                    (pDirFile->d_name[dirFileLen - 1] == 't' || pDirFile->d_name[dirFileLen - 1] == 'T'))
91                 {
92                         strcpy(file + dirLen, pDirFile->d_name);
93                         if (getInfo(file, dirLen + dirFileLen, temp) == 0)
94                         {
95                                 m_chains += temp->chains;
96                                 m_pqSize++;
97                                 if (head == NULL)
98                                 {
99                                         head = temp;
100                                         current = temp;
101                                 }
102                                 else
103                                 {
104                                         current->next = temp;
105                                         current = temp;
106                                 }
107                                 temp = new FileList;
108                                 temp->next = NULL;
109                         }
110                         else
111                         {
112                                 printf("Continue? (y/n): ");
113                                 int ch = 0;
114                                 while (ch != EOF && ch != 'y' && ch != 'Y' && ch != 'n' && ch != 'N')
115                                 {
116                                         ch = getchar();
117                                 }
118                                 if (ch != 'y' && ch != 'Y')
119                                 {
120                                         while (head != NULL)
121                                         {
122                                                 current = head;
123                                                 head = head->next;
124                                                 fclose(current->pFile);
125                                                 delete [] current->name;
126                                                 delete current;
127                                         }
128                                         delete [] file;
129                                         delete temp;
130                                         closedir(pDir);
131                                         exit(1);
132                                 }
133                         }
134                 }
135         }
136         delete [] file;
137         delete temp;
138         closedir(pDir);
139         if (head == NULL)
140         {
141                 printf("Error no '*.rt' input files found in directory '%s'.\n", dir);
142                 exit(1);
143         }
144
145         // Push file list into priority queue
146         PriorityQueueNode tmpNode;
147         unsigned int i = 0, node, par;
148
149         m_pq = new PriorityQueueNode[m_pqSize];
150         while (head != NULL)
151         {
152                 if (readGoodChain(head->pFile, &(m_pq[i].chain)) == 0)
153                 {
154                         // Init priority queue node
155                         m_pq[i].pFile = head->pFile;
156                         m_pq[i].fName = head->name;
157
158                         // Insert into priority queue
159                         if (i != 0)
160                         {
161                                 node = i;
162                                 par = (node - 1) >> 1;
163                                 if (m_pq[par].chain.endpt > m_pq[node].chain.endpt)
164                                 {
165                                         tmpNode = m_pq[node];
166                                         do
167                                         {
168                                                 m_pq[node] = m_pq[par];
169                                                 node = par;
170                                                 if (par == 0)
171                                                 {
172                                                         break;
173                                                 }
174                                                 par = (node - 1) >> 1;
175                                         } while (m_pq[par].chain.endpt > tmpNode.chain.endpt);
176                                 }
177                                 if (i != node)
178                                 {
179                                         m_pq[node] = tmpNode;
180                                 }
181                         }
182                         i++;
183                 }
184                 else
185                 {
186                         m_pqSize--;
187                         printf("File had no valid chains '%s'\n", head->name);
188                         delete [] head->name;
189                 }
190
191                 // Delete file list node
192                 current = head;
193                 head = head->next;
194                 delete current;
195         }
196
197         printf("Starting with %u files.\n", m_pqSize);
198         m_startTime = clock();
199 }
200
201 RTRead::~RTRead()
202 {
203         if (m_pq != NULL)
204         {
205                 for (unsigned int i = 0; i < m_pqSize; i++)
206                 {
207                         if (m_pq[i].pFile != NULL)
208                         {
209                                 fclose(m_pq[i].pFile);
210                         }
211                         if (m_pq[i].fName != NULL)
212                         {
213                                 delete [] m_pq[i].fName;
214                         }
215                 }
216                 delete [] m_pq;
217         }
218 }
219
220 int RTRead::readChain(RTChain *chain)
221 {
222         PriorityQueueNode tmp;
223         unsigned int child, node;
224
225         if (m_pq == NULL)
226         {
227                 return 1;
228         }
229         *chain = m_pq[0].chain;
230         bool remove = (readGoodChain(m_pq[0].pFile, &(m_pq[0].chain)) != 0);
231
232         if (remove)
233         {
234                 if (m_verbose)
235                 {
236                         printf("Finished with file '%s'\n", m_pq[0].fName);
237                 }
238                 delete [] m_pq[0].fName;
239
240                 // Remove node from queue
241                 m_pqSize--;
242                 if (m_pqSize == 2)
243                 {
244                         if (m_pq[1].chain.endpt < m_pq[2].chain.endpt)
245                         {
246                                 m_pq[0] = m_pq[1];
247                                 m_pq[1] = m_pq[2];
248                         }
249                         else
250                         {
251                                 m_pq[0] = m_pq[2];
252                         }
253                         m_pq[2].fName = NULL;
254                         m_pq[2].pFile = NULL;
255                 }
256                 else if (m_pqSize == 1)
257                 {
258                         m_pq[0] = m_pq[1];
259                         m_pq[1].fName = NULL;
260                         m_pq[1].pFile = NULL;
261                 }
262                 else if (m_pqSize == 0)
263                 {
264                         delete [] m_pq;
265                         m_pq = NULL;
266                 }
267         }
268         if (m_pqSize > 2)
269         {
270                 if (remove)
271                 {
272                         tmp = m_pq[m_pqSize];
273                         m_pq[m_pqSize].fName = NULL;
274                         m_pq[m_pqSize].pFile = NULL;
275                 }
276                 else
277                 {                       
278                         tmp = m_pq[0];
279                 }
280                 // Move tmp node to proper posistion in queue
281                 node = 0;
282                 child = 1;
283                 if (m_pq[1].chain.endpt > m_pq[2].chain.endpt)
284                 {
285                         child = 2;
286                 }
287                 while (tmp.chain.endpt > m_pq[child].chain.endpt)
288                 {
289                         m_pq[node] = m_pq[child];
290                         node = child;
291                         // child = left node
292                         child = (node << 1) + 1;
293                         if (child >= m_pqSize)
294                         {
295                                 break;
296                         }
297                         if (child + 1 < m_pqSize && m_pq[child].chain.endpt > m_pq[child + 1].chain.endpt)
298                         {
299                                 // child = right node
300                                 child++;
301                         }
302                 }
303                 if (node != 0 || remove)
304                 {
305                         m_pq[node] = tmp;
306                 }
307         }
308         else if (m_pqSize == 2 && !remove)
309         {
310                 if (m_pq[0].chain.endpt > m_pq[1].chain.endpt)
311                 {
312                         tmp = m_pq[1];
313                         m_pq[1] = m_pq[0];
314                         m_pq[0] = tmp;
315                 }
316         }
317         return 0;
318 }
319
320 int RTRead::readGoodChain(FILE *pFile, RTChain *chain)
321 {
322         size_t ret;
323
324         if (pFile == NULL)
325         {
326                 return 1;
327         }
328         do
329         {
330                 ret = fread((void*)chain, 16, 1, pFile);
331                 if(ret == 1) ret = fread((void*)&chain->checkpoint, 2, 1, pFile);
332                 if (ret != 1)
333                 {
334                         if (ferror(pFile) != 0)
335                         {
336                                 printf("Error reading file.\n");
337                                 printf("Continue? (y/n): ");
338                                 int ch = 0;
339                                 while (ch != EOF && ch != 'y' && ch != 'Y' && ch != 'n' && ch != 'N')
340                                 {
341                                         ch = getchar();
342                                 }
343                                 if (ch != 'y' && ch != 'Y')
344                                 {
345                                         exit(1);
346                                 }
347                                 clearerr(pFile);
348                         }
349                         else if (feof(pFile) != 0)
350                         {
351                                 fclose(pFile);
352                                 return 1;
353                         }
354                 }
355                 else
356                 {
357                         m_chainsRead++;
358                 }
359         } while (ret != 1 || chain->startpt > m_maxIndex || chain->endpt > m_maxIndex);
360         return 0;
361 }
362
363 void RTRead::printStatus()
364 {
365         double percent = ((double) m_chainsRead / (double) m_chains) * 100.0;
366         double timeElapsed = (clock() - m_startTime) / (double)CLOCKS_PER_SEC;
367
368         printf("\n*** Status ***\n");
369 #ifdef _WIN32
370         printf("  Chains Read:   %I64u\n", m_chainsRead);
371         printf("  Total Chains:  %I64u\n", m_chains);
372 #else
373         printf("  Chains Read:   %llu\n", m_chainsRead);
374         printf("  Total Chains:  %llu\n", m_chains);
375 #endif
376         printf("  Files Open:    %u\n", m_pqSize);
377         printf("  Percent:       %0.1f\n", percent);
378         printf("  Time Elapsed:  %0.0f sec\n", timeElapsed);
379         printf("  Time Left:     %0.0f sec\n\n", timeElapsed / (percent / 100.0) - timeElapsed);
380 }
381
382 int RTRead::getInfo(char *file, int len, FileList *ret)
383 {
384         FILE *pFile;
385         unsigned int size;
386
387         if (m_verbose)
388         {
389                 printf("Opening file '%s'\n", file);
390         }
391         pFile = fopen(file, "rb");
392         if (pFile == NULL)
393         {
394                 perror(file);
395                 return 1;
396         }
397
398         // Get file size
399         fseek(pFile, 0, SEEK_END);
400         size = ftell(pFile);
401         if (size & 15 != 0)
402         {
403                 fclose(pFile);
404                 printf("Error file size of '%s' is not a multible of 16 bytes.\n", file);
405                 return 1;
406         }
407         fseek(pFile, 0, SEEK_SET);
408         ret->chains = size >> 4;
409         ret->pFile = pFile;
410
411         ret->name = new char[len + 1];
412         strncpy(ret->name, file, len);
413         ret->name[len] = '\0';
414         return 0;
415 }
416