/* System Recovery - By Patrick Lambert <drow@wildstar.net>
 * This program is under the GPL license.
*/

#include "sr.h"
#define VERSION "1.01"

int usage()
{
 fprintf(stderr, "Syntax:\n");
 fprintf(stderr, "sr <command>\n\n");
 fprintf(stderr, " * Database making: -d\n");
 fprintf(stderr, "    This will make the file sr.db with information about your system's files. It should be moved to a secure location, like a floppy disk.\n");
 fprintf(stderr, " * System verification: -v <database file>\n");
 fprintf(stderr, "    This will verify the current system from <database file>.\n");
 fprintf(stderr, " * System recovery: -r <path>\n");
 fprintf(stderr, "    This will automatically replace all your system files with the versions from <path>, which must have the same hierarchy and can be an NFS mounted root from a similar system (must be running the same OS).\n");
}

char *lindex(char *input_string, int word_number)
{
 char *tokens[1024];
 static char tmpstring[1024];
 int i;
 strncpy(tmpstring,input_string,1024);
 (char *)tokens[i=0] = (char *)strtok(tmpstring, " ");
 while (((char *)tokens[++i] = (char *)strtok(NULL, " ")));
 tokens[i] = NULL;
 return(tokens[word_number]);
}

int make()
{
 fd = fopen("sr.db", "w");
 sprintf(temp, "SYSTEM-RECOVERY %ld :\n", time(NULL));
 fputs(temp, fd);
 for(i=0;files[i]!=NULL;i++)
 {
  printf("Adding %s...", files[i]);
  fd2 = fopen(files[i], "r");
  if(fd2==NULL)
  {
   printf("can't access file\n");
  }
  else
  {
   fstat(fileno(fd2), &stat_buf);
   sprintf(temp, "%s %ld %ld %d %d %ld %ld %ld 1\n", files[i], stat_buf.st_size, stat_buf.st_mode, stat_buf.st_uid, stat_buf.st_gid, stat_buf.st_mtime, stat_buf.st_ctime, stat_buf.st_atime);
   fputs(temp, fd);
   fclose(fd2);
   printf("ok\n");
  }
 }
 fclose(fd);
}

int verify(char *file)
{
 fd = fopen(file, "r");
 if(fd==NULL)
 {
  fprintf(stderr, "Can't open file.\n");
  exit(1);
 }
 fgets(temp,255,fd);
 printf("File time stamp: %ld\n", atol(lindex(temp,1)));
 while(fgets(temp,255,fd)!=NULL)
 {
  printf("Checking %s...", lindex(temp,0));
  fd2 = fopen(lindex(temp,0), "r");
  if(fd2==NULL)
  {
   printf("WARNING: Can't access file!\n");
  }
  else
  {
   fstat(fileno(fd2), &stat_buf);
   if(stat_buf.st_size != atol(lindex(temp,1)))
   printf("WARNING: Size changed from %ld to %ld ",atol(lindex(temp,1)),stat_buf.st_size);
   if(stat_buf.st_mode != atol(lindex(temp,2)))
   printf("WARNING: Mode changed from %ld to %ld ",atol(lindex(temp,2)),stat_buf.st_mode);
   if(stat_buf.st_uid != atol(lindex(temp,3)))
   printf("WARNING: Owner changed from %ld to %ld ",atol(lindex(temp,3)),stat_buf.st_uid);
   if(stat_buf.st_gid != atol(lindex(temp,4)))
   printf("WARNING: Group changed from %ld to %ld ",atol(lindex(temp,4)),stat_buf.st_gid);
   if(stat_buf.st_mtime != atol(lindex(temp,5)))
   printf("WARNING: Last modified time changed from %ld to %ld ",atol(lindex(temp,5)),stat_buf.st_mtime);
   if(stat_buf.st_ctime != atol(lindex(temp,6)))
   printf("WARNING: Last change time changed from %ld to %ld ",atol(lindex(temp,6)),stat_buf.st_ctime);  
   printf("\n");
   fclose(fd2);
  }
 }
 fclose(fd);
}

int recovery(char *path)
{
 printf("WARNING!!! This will replace all files listed in the database file for the ones in %s! You should use the -v option and replace them manually. Press ENTER to continue anyways, or CTRL+C to cancel.", path);
 gets(temp);
 fd = fopen("sr.db", "r");
 if(fd==NULL)
 {
  fprintf(stderr, "Can't open sr.db\n");
  exit(1);
 }
 fgets(temp,255,fd);
 while(fgets(temp,255,fd)!=NULL)
 {
  sprintf(temp2, "cp %s%s %s", path, lindex(temp,0), lindex(temp,0));
  system(temp2);
 }
 fclose(fd);
}

main(int argc, char *argv[])
{
 printf("System Recovery v%s by Patrick Lambert <drow@wildstar.net>\n",VERSION);
 if(argc==1)
 {
  usage();
  exit(0);
 }
 if(!strcasecmp(argv[1],"-d")) make();
 else if(!strcasecmp(argv[1],"-v"))
 {
  if(argv[2]==NULL)
  {
   fprintf(stderr, "No filename specified.\n");
   exit(1);
  }
  verify(argv[2]);
 }
 else if(!strcasecmp(argv[1],"-r"))
 {
  if(argv[2]==NULL)
  {
   fprintf(stderr, "No path specified.\n");
   exit(1); 
  }
  recovery(argv[2]);
 }
 else
 {
 fprintf(stderr, "Unknown command.\n");
 exit(1);
 }
 exit(0);
}
