"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 }