"Fossies" - the Fresh Open Source Software Archive 
Member "giis_4.6.2/src/get_it_i_say.c" (6 Nov 2012, 21082 Bytes) of package /linux/misc/old/giis_4.6.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*
2 * /giis/get_it_i_say.c-Here we try to recover deleted files
3 *
4 * Copyright (C) 2005,2006,2007,2008,2009,2010,2011,2012 Lakshmipathi.G <lakshmipathi.g@giis.co.in>.
5 * This file may be redistributed under the terms of the GNU Public License.
6 *
7 */
8
9
10 #include "giis.h"
11
12 /*
13 * get_it() This is will scan through the file entries with the help of verfiy_inode()
14 * Mofication for giis2:
15 * Keep track of s_offy and d_offy.
16 */
17
18 int get_it ()
19 {
20 int i, fd, no = 0;
21 static int search_uid;
22 search_uid = 0;
23 //Added for giis4.0
24 char extension[10];
25 int glength = 0, ulength = 0, pos, count, typefound;
26
27 if (use_uid == 2)
28 {
29 i = force_giis ();
30 if (i == -1)
31 {
32 perror ("");
33 printf ("Error Number:%d", errno);
34 return -1;
35 }
36 return 1;
37 }
38
39 if (use_uid == 1)
40 {
41 printf ("\n Enter the User Name....");
42 scanf ("%s", user);
43 pwfile = getpwnam (user);
44 if (pwfile == NULL)
45 {
46 printf ("\nPlease Enter Correct user name ");
47 return 1;
48 }
49 use_uid = pwfile->pw_uid;
50 printf ("\nSearching For %s files with uid=%d", pwfile->pw_name, use_uid);
51 search_uid = 1; /* Search for specific users */
52 }
53 /* Get by File format */
54 if (use_uid == 3)
55 {
56 printf ("\n Enter any file type:(txt,doc,mp3,c,cpp,dat--etc) :");
57 scanf ("%s", extension);
58 search_format = 1;
59 }
60
61
62 /* Reset offset of two files */
63
64 d_offy = 0;
65 s_offy = 0;
66
67
68 fd = open (FILE_INFO_FILE, 2);
69 if (fd == -1)
70 {
71 perror ("open");
72 return -1;
73 }
74
75 i = read (fd, giis_f.buffer, GIIS_FSIZE);
76 if (i == -1)
77 {
78 perror ("");
79 printf ("Error Number:%d", errno);
80 return -1;
81 }
82 while (i > 0)
83 {
84 /* Search for given file formats only */
85 if (search_format == 1)
86 {
87 glength = 0;
88 ulength = 0;
89 glength = strlen (giis_f.info.name);
90 ulength = strlen (extension);
91 ulength++; //get dot part too .txt /.cpp
92 pos = glength - ulength;
93 if (giis_f.info.name[pos] == '.')
94 {
95 pos++;
96 count = 0;
97 typefound = 1;
98 for (; pos < glength; pos++, count++)
99 {
100 if (giis_f.info.name[pos] != extension[count])
101 {
102 typefound = 0;
103 pos = glength;
104 }
105 }
106 if (typefound)
107 {
108
109 i = verify_inode (giis_f.info.inode_number);
110 if (i == -1)
111 {
112 perror ("");
113 printf ("Error Number:%d", errno);
114 return -1;
115 }
116 }
117 else
118 i = 0;
119 }
120 }
121
122 /* Specific user is set and this is his entry then verfify else skip.
123 If use_uid not set search for all files ignore uid */
124 if (search_uid)
125 {
126
127 if (giis_f.info.owner == use_uid)
128 {
129 i = verify_inode (giis_f.info.inode_number);
130 if (i == -1)
131 {
132 perror ("");
133 printf ("Error Number:%d", errno);
134 return -1;
135 }
136 }
137 else
138 i = 0;
139 }
140 if ((search_format != 1) && (!search_uid))
141 {
142 i = verify_inode (giis_f.info.inode_number);
143 if (i == -1)
144 {
145 perror ("");
146 printf ("Error Number:%d", errno);
147 return -1;
148 }
149 }
150 /* Update s_offy and d_offy here */
151
152 if (giis_f.info.is_offset)
153 s_offy += giis_f.info.is_offset;
154
155
156 if (giis_f.info.id_offset)
157 d_offy += giis_f.info.id_offset;
158
159
160 if (i == 1)
161 {
162
163 get_it_i_say ();
164
165 /* Finally update this entry in file_info_file() */
166
167 giis_f.info.search_flag = 1; /* Recovered or failed */
168 lseek (fd, -GIIS_FSIZE, 1);
169 i = write (fd, giis_f.buffer, GIIS_FSIZE);
170 if (i != GIIS_FSIZE)
171 {
172 perror ("write");
173 return -1;
174 }
175 no = 1;
176 }
177 i = read (fd, giis_f.buffer, GIIS_FSIZE);
178 if (i == -1)
179 {
180 perror ("");
181 printf ("Error Number:%d", errno);
182 return -1;
183 }
184 }
185 if (no == 1)
186 {
187 printf ("\n\n giis process Completed...");
188 printf ("\n\t Recovered files : /usr/share/giis/got_it");
189 printf ("\n\t Unrecovered files : /usr/share/giis/unrecovered");
190 }
191 else
192 printf ("\n\n\t\tNothing Recovered...");
193 close (fd);
194 return 1;
195 }
196
197 /*
198 * verify_inode() - This is a helper file to get_it_i_say() this one verifies inode
199 * is deleted or is being in use.
200 */
201
202 int verify_inode (unsigned long inode)
203 {
204 int i;
205 /* For time based recovery - giis4.4*/
206 time_t rawtime;
207 struct tm *mytm;
208
209 fs.inode_number = inode;
210
211 i = find_inode_offset ();
212 if (i == -1)
213 {
214 perror ("");
215 printf ("Error Number:%d", errno);
216 return -1;
217 }
218 i = read_inode ();
219 if (i == -1)
220 {
221 perror ("");
222 printf ("Error Number:%d", errno);
223 return -1;
224 }
225 if (iin.in.i_links_count == 0)
226 {
227
228 deleted_inode_offset = fs.inode_offset;
229
230 /* Check whether it's time-based recovery - if so process it.*/
231 if(date_mode !=-1){
232 time(&rawtime);
233 mytm=localtime(&rawtime);
234 mytm->tm_mon=month-1;
235 mytm->tm_mday=day;
236 mytm->tm_year=year-1900;
237
238 mytm->tm_sec=0;
239 mytm->tm_min=0;
240 mytm->tm_hour=0;
241 result = mktime(mytm);
242
243 //Deleted on
244 if(date_mode ==0){
245 if ((iin.in.i_dtime >= result) && (iin.in.i_dtime<= (result+86400)))
246 return 1;
247 else
248 return 0;
249 }
250
251 //Deleted before
252 if(date_mode ==2){
253 if (iin.in.i_dtime<result)
254 return 1;
255 else
256 return 0;
257 }
258
259 //Deleted after
260
261 if(date_mode==1){
262 if (iin.in.i_dtime > (result+86400))
263 return 1;
264 else
265 return 0;
266 }
267
268 //Deleted between
269 if(date_mode==3){
270 //set to-date
271 time(&rawtime);
272 mytm=localtime(&rawtime);
273 mytm->tm_mon=month1-1;
274 mytm->tm_mday=day1;
275 mytm->tm_year=year1-1900;
276
277 mytm->tm_sec=0;
278 mytm->tm_min=0;
279 mytm->tm_hour=0;
280 result1 = mktime(mytm);
281
282 if ((iin.in.i_dtime > result) && (iin.in.i_dtime < (result1+86400)))
283 return 1;
284 else
285 return 0;
286 }
287 }
288 return 1; // for get all files
289 }
290 else
291 return 0;
292
293 }
294
295 /*
296 * get_it_i_say()-This will try to retrieve the deleted file.
297 * Mofication for giis2:
298 * New Access methods for the following flags,
299 * sfragment_flag=0 files not uses single indirect at all.
300 * sfragment_flag=1 file uses single indirect but it's already in sequence.
301 * sfragment_flag=2 file uses single indirect with SIND FILE .
302 *
303 * dfragment_flag=0 files not uses double indirect at all.
304 * dfragment_flag=1 file uses double indirect but it's already in sequence.
305 * dfragment_flag=2 file uses double indirect with DIND FILE .
306 *
307 */
308
309 int get_it_i_say ()
310 {
311 int i, fp, fdes, fd, num, hole, eof, count, tfp;
312 unsigned long indirect_block, iblock[1024];
313 char name[75] = "/usr/share/giis/got_it/";
314 char over[75] = "/usr/share/giis/unrecovered/";
315 extern char rere_filenames[200][150];
316 extern int rere_count;
317 extern unsigned long rere_inodes[1024];
318
319
320 /* just always create a new file */
321 strcat (name, giis_f.info.name);
322
323 fp = open (name, 0);
324 if (fp != -1)
325 {
326 /*Already retrieved */
327 close (fp);
328 return 1;
329 }
330
331
332 fp = open (name, O_CREAT | O_RDWR | O_TRUNC,S_IRWXU |S_IRWXG |S_IRWXO );
333 if (fp == -1)
334 {
335 printf ("\nFile Not found %s", name);
336 close (fp);
337 return -1;
338 }
339
340 //Store file names to temp. variable for rere
341 if((rere==1)&&(rere_count<200)){
342 strcpy(rere_filenames[rere_count],giis_f.info.name);
343 rere_inodes[rere_count]=fs.inode_number;
344 rere_count++;
345 }
346
347
348 fd = open (device_name, 0);
349 if (fd == -1)
350 {
351 perror ("");
352 printf ("Error Number:%d", errno);
353 return -1;
354 }
355 eof = 1;
356 fileoverwritten = 0;
357 size = giis_f.info.file_size; /* Decrement afer every read to denote EOF */
358 err_size = 0; /* Increment after read for Error check */
359 gd = 0; /* used in get_data_from_block */
360 /* giis 4.4 - Set owner & permission mode */
361 chmod(name,iin.in.i_mode);
362 chown(name,iin.in.i_uid,iin.in.i_gid);
363
364 for (i = 0; (i <= 14) && eof; i++)
365 {
366
367
368 /*Don't use fragment_flag Here */
369
370 if (i < 12 && giis_f.info.data_block[i] != 0)
371 { /* Direct blocks */
372 eof = get_data_from_block (fp, fd, giis_f.info.data_block[i]);
373 /* If Data Overwritten then Quit */
374 if (fileoverwritten == 444)
375 {
376 close (fp);
377 i = unlink (name);
378 strcat (over, giis_f.info.name);
379 tfp = open (over, O_CREAT | O_RDWR | O_TRUNC);
380 if (tfp == -1)
381 {
382 printf ("\nFile Not found %s", over);
383 return -1;
384 }
385 close (tfp);
386 close (fd);
387 return 1;
388 }
389 if (eof == 0)
390 {
391 close (fp);
392 close (fd);
393 return 1;
394 }
395
396 continue;
397 }
398
399
400 /* part 1: Access single indirect blocks */
401
402 if (i == 12 && giis_f.info.data_block[12] != 0)
403 {
404
405 indirect_block = giis_f.info.data_block[12];
406
407 /* sfragment_flag=1 just read by incrementing number */
408
409
410 if (giis_f.info.sfragment_flag == 1)
411 {
412
413 for (count = 0; count < 1024; count++)
414 { /* Sequence */
415 indirect_block++;
416 eof = get_data_from_block (fp, fd, indirect_block);
417
418
419 if (eof == 0)
420 {
421 close (fp);
422 close (fd);
423 return 1;
424 }
425 }
426 }
427
428 /* sfragment_flag=2 read from sind_info_file */
429
430
431
432 if (giis_f.info.sfragment_flag == 2)
433 { /* holes here n there */
434 num = 0;
435
436 fdes = open (SIND_INFO_FILE, 0);
437 if (fdes == -1)
438 {
439 perror ("open");
440 printf ("\nError No : %d", errno);
441 }
442
443 lseek (fdes, (s_offy - giis_f.info.is_offset) * sizeof (unsigned long), 0);
444 read (fdes, iblock, giis_f.info.is_offset * sizeof (unsigned long));
445 if (i == -1)
446 {
447 perror ("");
448 printf ("Error Number:%d", errno);
449 return -1;
450 }
451 hole = iblock[num];
452
453 for (count = 0; count < 1024; count++)
454 {
455
456 if (indirect_block == hole)
457 {
458 indirect_block = iblock[num + 1];
459 num += 2;
460 hole = iblock[num];
461 }
462 else
463 indirect_block++;
464
465 eof = get_data_from_block (fp, fd, indirect_block);
466 if (eof == 0)
467 {
468 close (fp);
469 close (fd);
470 return 1;
471 }
472 }
473 }
474 continue;
475 }
476
477 /* part 2: Access double indirect blocks */
478
479 if (i == 13 && giis_f.info.data_block[13] != 0)
480 {
481
482
483 indirect_block = giis_f.info.data_block[13];
484 indirect_block++;
485
486 /* dfragment_flag=1 just read by incrementing number */
487
488 if (giis_f.info.dfragment_flag == 1)
489 {
490 while (eof)
491 { /* Sequence */
492 indirect_block++;
493 eof = get_data_from_block (fp, fd, indirect_block);
494 if (eof == 0)
495 {
496 close (fp);
497 close (fd);
498 return 1;
499 }
500 }
501
502 }
503
504 /* dfragment_flag=2 read from file_info_file */
505
506 if (giis_f.info.dfragment_flag == 2)
507 { /* holes here n there */
508 num = 0;
509 fdes = open (DIND_INFO_FILE, 0);
510 if (fdes == -1)
511 {
512 perror ("open");
513 printf ("\nError No : %d", errno);
514 }
515
516 lseek (fdes, (d_offy - giis_f.info.id_offset) * sizeof (unsigned long), 0);
517 read (fdes, iblock, giis_f.info.id_offset * sizeof (unsigned long));
518 if (i == -1)
519 {
520 perror ("");
521 printf ("Error Number:%d", errno);
522 return -1;
523 }
524 hole = iblock[num];
525 count = 0;
526 /* 4 holes occur first say at [13] itself */
527 if (hole == (indirect_block - 1))
528 indirect_block = hole;
529
530 /*
531 For files more than 8.04 MB we need count to keep trace of
532 when to double jump from position 1022 to next.
533 It's has taken few hours for me to find solution why the above if block doesn't reset count.The answer is,
534 In situations like we have a hole at indirect_block+1 and count=1023
535 doesn't enter above block then count goes to beyond 1024 so in the
536 following iterations too we can't reset count so we have...
537 */
538
539 while (eof)
540 {
541 if (indirect_block == hole)
542 {
543 indirect_block = iblock[num + 1];
544 num += 2;
545 hole = iblock[num];
546 if (count == 1024)
547 count = 0;
548 }
549 else
550 indirect_block++;
551
552 if (count == 1024)
553 {
554 indirect_block++;
555 count = 0;
556 }
557
558
559 eof = get_data_from_block (fp, fd, indirect_block);
560 if (eof == 0)
561 {
562 close (fp);
563 close (fd);
564 return 1;
565 }
566 count++;
567
568
569 }
570 }
571 }
572
573
574 }
575 close (fd);
576 close (fp);
577 return 1;
578 }
579
580 /*
581 * get_data_from_block() is a helper function to above procedure it computes the content
582 * offset of given block number and access that data.
583 * Modification for giis2:
584 * Check introduced with help of last_data_block.
585 */
586
587 int get_data_from_block (int fp, int fd, unsigned long data_block)
588 {
589 int i = 0;
590 unsigned long device_block_number;
591 /*
592 static int lg;
593 char *disp1="\ngiis.........Smile or Sad face?";
594 char *disp2=" ";
595 char disp3[]="|\\-/|\\-/";
596 char disp4[]=" :-";
597 char disp5[]=")(";
598 */
599
600
601
602 /* just for fun */
603
604 /* Some graphics output commented because it's affects speedy recovery
605 Removing following comments is not a risky opertions at all. */
606
607 /* system("clear");
608 write(0,disp1,strlen(disp1));
609 write(0,disp2,strlen(disp2));
610 write(0,&disp3[lg],1);
611 write(0,disp4,strlen(disp4));
612 write(0,&disp5[lg%2],1);
613 lg++;
614 if(lg==strlen(disp3))
615 lg=0;
616 */
617
618 fs.block_number = data_block; /* blocks */
619
620 if (fs.block_number != 0)
621 {
622
623 /*
624 First thought some big file are unable to recover since they might be using
625 fragment blocks.So i let go.Just in final hours i found something you can
626 call its as a bug but for me it's big breakthough.
627
628 Here we just can't go and get blocks sometimes blocks might be scattered around
629 the disk.So make sure that you access data from all groups.
630 So Always keep a close eye on block number and it's Group Descriptor
631
632 */
633
634 if (gd == 0)
635 i = eye_on_gd ();
636 if (i == -1)
637 {
638 printf ("\n\tAbnormal : Group Descriptor not found ");
639 return 0;
640 }
641
642 /* Calling eye_on_gd() affect performance so call when it's needed absoultely */
643
644 if (fs.block_number > (fs.block_bitmap + fs.blocks_per_group) ||
645 fs.block_number < (fs.block_bitmap))
646 i = eye_on_gd ();
647 if (i == -1)
648 {
649 printf ("\n\tAbnormal : Group Descriptor not found %lu", fs.block_number);
650 return 0;
651 }
652
653 device_block_number =
654 ((fs.block_number - 1) % fs.blocks_per_group) +
655 fs.group_number * fs.blocks_per_group;
656 device_block_number += fs.first_data_block;
657 fs.content_offset =
658 (unsigned long long) device_block_number *(unsigned long long) fs.block_size;
659 fs.content_offset += fs.block_size;
660 //set devicefile to appropriate address
661 lseek64 (fd, fs.content_offset, 0);
662
663 read_show_file (fd, fp);
664
665 if (fileoverwritten == 444)
666 { //Check for fileoverwritten ???
667 return 0;
668 }
669
670 if (size == 0 || fs.block_number == giis_f.info.last_data_block)
671 {
672
673
674 if ((size == 0) && (fs.block_number == giis_f.info.last_data_block)
675 && (err_size == giis_f.info.file_size))
676 {
677 return 0; /* fine */
678 }
679
680 else
681 {
682 printf ("\n\n\tWarning : %s size differs\n\t", giis_f.info.name);
683 printf ("Actual Size(Approx):%lu MB", ((giis_f.info.file_size / 1024) / 1024));
684 printf ("\n\tRecovered Only(Approx):%lu MB ", ((err_size / 1024) / 1024));
685 return 0;
686 }
687 }
688 return 444; /*... nothing special. my lucky number */
689
690 }
691
692 return JSJ_NO_RETURN;
693 }
694
695
696
697 /*
698 * force_giis : Tries to recover the requested file.
699 * giis4.1:
700 * concept of version is implemented.
701 */
702
703
704 int force_giis ()
705 {
706 int fp, i, exists;
707 repeat = 0; /* If exists == repeat latest version of a file */
708
709
710
711 printf ("\n ->Get Latest Version or First Version of Deleted File ??");
712 printf ("\n\tPress 0: Get Latest Version (Recommended)\n\tPress 1: First Version ");
713 printf ("\n\t Enter your choice :");
714 scanf ("%d", &get_version);
715 if (get_version != 0 && get_version != 1)
716 {
717 get_version = 0; //default version is latest .
718 }
719
720 printf ("\nForcing giis-Warning:Recovered file may be a corrupted one.");
721 printf ("\nWitch/Which File ? : Enter Filename \t :");
722 scanf ("%s", search_file);
723
724 fp = open (FILE_INFO_FILE, 0);
725 if (fp == -1)
726 {
727 perror ("open");
728 return -1;
729 }
730
731 i = read (fp, giis_f.buffer, GIIS_FSIZE);
732 s_offy = d_offy = 0;
733
734 while (i > 0)
735 {
736
737 /* update s_offy & d_offy */
738
739 if (giis_f.info.is_offset)
740 s_offy += giis_f.info.is_offset;
741
742 if (giis_f.info.id_offset)
743 d_offy += giis_f.info.id_offset;
744
745
746 if (strcmp (search_file, giis_f.info.name) == 0)
747 {
748 /* Check how many entries are available in giis system file */
749 exists = file_repeated (giis_f.info.name);
750
751 repeat++; /* We created version. 'repeat' of this file */
752 /* Get Lastest Version */
753 if (get_version == 0)
754 {
755 if (repeat == exists)
756 {
757 /* Fetch the last updated version of deleted file */
758 get_it_i_say (); /*Never mind about others go and get */
759 close (fp);
760 printf ("\n\n\tRecovered :/usr/share/giis/got_it");
761 printf ("\n\tUnrecovered Files :/usr/share/giis/unrecovered");
762 return 1;
763 }
764 }
765 if (get_version == 1)
766 { /*Get First version */
767 get_it_i_say (); /*Never mind about others go and get */
768 close (fp);
769 printf ("\n\n\tRecovered :/usr/share/giis/got_it");
770 printf ("\n\tUnrecovered Files :/usr/share/giis/unrecovered");
771 return 1;
772 }
773
774 }
775
776 i = read (fp, giis_f.buffer, GIIS_FSIZE);
777 if (i == -1)
778 {
779 perror ("");
780 printf ("Error Number:%d", errno);
781 return -1;
782 }
783 }
784 printf ("\n\t%s File not found", search_file);
785 close (fp);
786 return 1;
787 }
788
789 /*
790 * recover_restore : Tries to recover the requested file and copies recovered files to it's original
791 * directories and creates symbolic link under /giis/got_it . If unable to find original parent path,
792 * files will be placed under /giis/got_it.
793 */
794
795
796 int recover_restore ()
797 {
798 int i=0,j=0,retval=0,total=0,fp;
799 extern union u_s_rere_info giis_r;
800 char homepath[250]="/usr/share/giis/got_it/";
801 char *disp1="Recovered File Name \t\t Restore Directory\n";
802 char *disp2=" \t\t\t";
803 char *disp3="\n";
804 if(rere_count==0) //Nothing is recovered
805 return 1;
806
807
808 /* Load inodes and files into global structure.*/
809 total=display_deleted_files();
810
811
812 /* File which contains details about where the files are restored back to */
813
814 fp = open (GIIS_RERE_FILE, 2);
815 if (fp == -1)
816 {
817 perror ("open:");
818 printf ("\nError No:%d", errno);
819 close (fp);
820 return -1;
821 }
822 write(fp,disp1,strlen(disp1));
823
824 /* Restore */
825 for(i=0;i<rere_count;i++){
826
827 for(j=0;j<total;j++){
828 if(rere_inodes[i]==giis_r.info.list_of_deleted_inodes[j]){
829
830 strcat(strcat(giis_r.info.list_of_restorepaths[j],"/"),rere_filenames[i]);
831 memset(homepath,'\0',250);
832 strcat(homepath,"/usr/share/giis/got_it/");
833
834 retval=link(strcat(homepath,rere_filenames[i]),giis_r.info.list_of_restorepaths[j]);
835 if(retval<0){
836 //printf("\nretval=%d",retval);
837 //perror("");
838 }else{
839 /* Store file and restore paths */
840 write(fp,rere_filenames[i],strlen(rere_filenames[i]));
841 write(fp,disp2,strlen(disp2));
842 write(fp,giis_r.info.list_of_restorepaths[j],strlen(giis_r.info.list_of_restorepaths[j]));
843 write(fp,disp3,strlen(disp3));
844 }
845
846 }
847
848 }
849 }
850 printf("\n See /usr/share/giis/restore_details.txt for Successfully restored files\n");
851 close(fp);
852 printf ("\n\n\tCheck /usr/share/giis/got_it For all Recovered Files.\n");
853 return 1;
854
855 }