Advertisement
iwishiknew

Selective Data Backup

Jan 11th, 2013
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 39.56 KB | None | 0 0
  1. Total number of coded lines: 1384
  2.  
  3. /*This source code is compatible with my Source Code Collector Program, which can automatically parse and separate this text file into all of the header/cpp files necessary to create and compile the project.  The program can be found at:
  4. http://sourceforge.net/projects/selectivedataba/files/Source%20Code%20Text%20Collector.exe/download
  5. */
  6.  
  7.  
  8. /*Meant to be an alternative to the native Windows Image backup, the Selective Data Backup program was created because (as I descovered the hard way) windows image can not be used to restore a hard drive if that hard drive is not the same size as the hard drive the image was created by.  So, say your 300Gb hard drive fails.  You decide that 'hey, while we're at it, why not get a bigger drive?', so you get a 500Gb drive.  The windows backup you created of your 300Gb hard drive will only work with another 300Gb hard drive, so now you have a 500Gb hard drive, with no data...  This program allows you to save your all-too-important documents, programs, etc... without any limitation.*/
  9.  
  10.  
  11. \\backup_session.cpp begin==================================================================
  12.  
  13. #include <iostream>
  14. #include <fstream>
  15. #include <string>
  16. #include <vector>
  17. #include <boost/filesystem.hpp>
  18. #include "common.h"
  19. #include "fsys.h"
  20. #include "datastruct.h"
  21. #include <math.h>
  22. #include <windows.h>
  23.  
  24. using namespace std;
  25.  
  26. void clean_target(string target = "")
  27. {
  28.     if(folder_empty(target) == true)
  29.     {
  30.         return;
  31.     }
  32.     boost::filesystem::path p;
  33.     p = target;
  34.     vector<boost::filesystem::directory_entry> directories;
  35.     copy(boost::filesystem::directory_iterator(p), boost::filesystem::directory_iterator(), back_inserter(directories));
  36.     for(unsigned int x = 0; x < directories.size(); x++)
  37.     {
  38.         boost::filesystem::remove_all(directories[x].path());
  39.     }
  40.     p.clear();
  41.     directories.clear();
  42. }
  43.  
  44. boost::filesystem::path file_directory(string d = "")
  45. {
  46.     while(d[(d.size() - 1)] != '\\')
  47.     {
  48.         d.resize(d.size() - 1);
  49.     }
  50.     if(d[(d.size() - 1)] == '\\')
  51.     {
  52.         d.resize(d.size() - 1);
  53.     }
  54.     boost::filesystem::path p;
  55.     p.clear();
  56.     p = d;
  57.     return p;
  58. }
  59.  
  60. void copy_special_file(boost::filesystem::path pfrom, boost::filesystem::path pto)
  61. {
  62.     boost::filesystem::path ptodirectory;
  63.     ptodirectory = (pto.string() + file_directory(pfrom.string()).relative_path().string());
  64.     boost::filesystem::create_directories(ptodirectory);
  65.     ptodirectory.clear();
  66.     ptodirectory = (pto.string() + pfrom.relative_path().string());
  67.     boost::filesystem::copy_file(pfrom, ptodirectory);
  68. }
  69.  
  70. void copy_filesystem(boost::filesystem::path pfrom, boost::filesystem::path pto)
  71. {
  72.     vector<boost::filesystem::directory_entry> directories;
  73.     boost::filesystem::path ext_pto;
  74.     if(is_folder(pfrom.string()) == true)
  75.     {
  76.         copy(boost::filesystem::recursive_directory_iterator(pfrom), boost::filesystem::recursive_directory_iterator(), back_inserter(directories));
  77.         for(unsigned int x = 0; x < directories.size(); x++)
  78.         {
  79.             if(is_folder(directories[x].path().string()) == true)
  80.             {
  81.                 ext_pto.clear();
  82.                 ext_pto = (pto.string() + directories[x].path().relative_path().string());
  83.                 boost::filesystem::create_directories(ext_pto);
  84.             }
  85.         }
  86.     }
  87. }
  88.  
  89. void copy_data(boost::filesystem::path pfrom, boost::filesystem::path pto, int perc = -1)
  90. {
  91.     int pcomplete = -1;
  92.     vector<boost::filesystem::directory_entry> directories;
  93.     boost::filesystem::path file;
  94.     copy(boost::filesystem::recursive_directory_iterator(pfrom), boost::filesystem::recursive_directory_iterator(), back_inserter(directories));
  95.     for(unsigned int x = 0; x < directories.size(); x++)
  96.     {
  97.         if(is_file(directories[x].path().string()) == true)
  98.         {
  99.             file.clear();
  100.             file = (file.string() + pto.string() + directories[x].path().relative_path().string());
  101.             if(percent_complete(x, signed(directories.size())) != pcomplete)
  102.             {
  103.                 pcomplete = percent_complete(x, signed(directories.size()));
  104.                 cls();
  105.                 cout<< "Backup is "<< perc<< "\% complete..."<< endl<< endl;
  106.                 cout<< "Backing up \""<< pfrom.string()<< "\""<< endl;
  107.                 cout<< pcomplete<< "\%"<< endl;
  108.             }
  109.             boost::filesystem::copy_file(directories[x].path(), file);
  110.         }
  111.     }
  112.     directories.clear();
  113. }
  114.  
  115. void copy_files(string target = "", vector<string> files = vector<string>())
  116. {
  117.     boost::filesystem::path pfrom, pto;
  118.     vector<boost::filesystem::path> filesp;
  119.     for(unsigned int x = 0; x < files.size(); x++) //convert to paths
  120.     {
  121.         filesp.push_back(files[x]);
  122.     }
  123.     cls();
  124.     for(unsigned int x = 0; x < filesp.size(); x++)
  125.     {
  126.         if(boost::filesystem::is_regular_file(filesp[x]) == true)
  127.         {
  128.             pto.clear();
  129.             pfrom.clear();
  130.             pto = (pto.string() + target + "\\");
  131.             pfrom = files[x];
  132.             copy_special_file(pfrom, pto);
  133.             continue;
  134.         }
  135.         if(boost::filesystem::is_directory(filesp[x]) == true)
  136.         {
  137.             cls();
  138.             cout<< "Backing up \""<< filesp[x]<< "\"..."<< endl;
  139.             pto.clear();
  140.             pto = (pto.string() + target + "\\" + filesp[x].relative_path().string()); //path: C:\Targetdir\relative path of our directory
  141.             pfrom.clear();
  142.             pfrom = filesp[x];
  143.             boost::filesystem::create_directories(pto);
  144.             pto.clear();
  145.             pto = (pto.string() + target + "\\");
  146.             copy_filesystem(pfrom, pto);
  147.             copy_data(pfrom, pto, percent_complete(x, signed(filesp.size())));
  148.         }
  149.     }
  150. }
  151.  
  152. bool are_you_sure()
  153. {
  154.     char ch;
  155.     int x = 0;
  156.     while(x == 0)
  157.     {
  158.         cls();
  159.         cout<< "Are you sure you want to perform a backup?"<< endl;
  160.         cout<< "Y/N";
  161.         ch = gkey();
  162.         if(ch == 'y')
  163.         {
  164.             return true;
  165.         }
  166.         if(ch == 'n')
  167.         {
  168.             return false;
  169.         }
  170.     }
  171.     return false;
  172. }
  173.  
  174. void after_action(string action = "nothing")
  175. {
  176.     if(action == "sleep")
  177.     {
  178.         system("rundll32 PowrProf.dll SetSuspendState 0 1 0");
  179.         return;
  180.     }
  181.     if(action == "beep")
  182.     {
  183.         Beep(2000, 500);
  184.         Beep(1500, 1000);
  185.         Beep(1900, 500);
  186.         return;
  187.     }
  188.     if(action == "nothing")
  189.     {
  190.         return;
  191.     }
  192. }
  193.  
  194. int start_backup()
  195. {
  196.     if(are_you_sure() == false)
  197.     {
  198.         return 0;
  199.     }
  200.     check_subdirectory_inclusion();
  201.     cls();
  202.     cout<< "Checking data..."<< endl;
  203.     if(!there_are_directories_to_back_up())
  204.     {
  205.         cls();
  206.         cout<< "You have not listed any valid directories to back up."<< endl;
  207.         wait();
  208.         return 0;
  209.     }
  210.     vector<string> options;
  211.     options = get_options();
  212.     if(!is_folder(options[0]))
  213.     {
  214.         cls();
  215.         cout<< "Invalid target directory!"<< endl;
  216.         wait();
  217.         return 0;
  218.     }
  219.     string target;
  220.     target = options[0]; //for easy reading
  221.     cout<< "Validating target directory..."<< endl;
  222.     if(is_part_of_backup(target) == true)
  223.     {
  224.         cls();
  225.         cout<< "FATAL ERROR: target == boost::filesystem::recursive_directory_iterator(p) \n Please check that your target is not part of your backup."<< endl;
  226.         wait();
  227.         return 0;
  228.     }
  229.     vector<string> files;
  230.     vector<boost::filesystem::directory_entry> directories;
  231.     files = get_file("dirbacklist.dat");
  232.     cout<< "Cleaning target directory..."<< endl;
  233.     if(is_folder(target) == true)
  234.     {
  235.         clean_target(target);
  236.         if(!folder_empty(target)) //a folder with contents might cause conflictions
  237.         {
  238.             cls();
  239.             cout<< "Error: ARBORTING BACKUP"<< endl;
  240.             exit(1);
  241.         }
  242.     }
  243.     cout<< "Starting backup..."<< endl;
  244.     copy_files(target, files);
  245.     after_action(options[1]);
  246.     cls();
  247.     cout<< "Backup to \""<< target<< "\" is complete."<< endl;
  248.     wait();
  249.     return 0;
  250. }
  251.  
  252.  
  253. \\backup_session.cpp END==================================================================
  254.  
  255. \\common.cpp begin==================================================================
  256.  
  257. #include <iostream>
  258. #include <conio.h>
  259. #include <windows.h>
  260. #include <string>
  261. #include <fstream>
  262. #include <math.h>
  263. #include "common.h"
  264. #include "fsys.h"
  265.  
  266. using namespace std;
  267.  
  268. void cls()
  269. {
  270.     system("CLS");
  271. }
  272.  
  273. void cl()
  274. {
  275.     Sleep(10);
  276.     while(_kbhit()) _getch();
  277. }
  278.  
  279. void wait()
  280. {
  281.     cout<< endl<< endl<< endl<< endl;
  282.     cout<< "Press any key to continue..."<< endl;
  283.     cl();
  284.     while(!_kbhit())
  285.     {
  286.         continue;
  287.     }
  288.     cl();
  289. }
  290.  
  291. char gkey()
  292. {
  293.     char ch;
  294.     cl();
  295.     ch = _getch();
  296.     return ch;
  297. }
  298.  
  299. int conv_str(string s)
  300. {
  301.     ifstream in;
  302.     ofstream out;
  303.     int x = 0;
  304.     out.open("temp.dat", ios::out);
  305.     while((is_file("temp.dat", true) == true) && (!out.is_open()))
  306.     {
  307.         continue;
  308.     }
  309.     out<< s;
  310.     out.close();
  311.     in.open("temp.dat", ios::in);
  312.     while((is_file("temp.dat", true) == true) && (!in.is_open()))
  313.     {
  314.         continue;
  315.     }
  316.     in>> x;
  317.     in.close();
  318.     out.clear();
  319.     in.clear();
  320.     remove("temp.dat");
  321.     return x;
  322. }
  323.  
  324. string conv_int(int x)
  325. {
  326.     ifstream in;
  327.     ofstream out;
  328.     string s;
  329.     s.clear();
  330.     out.open("temp.dat", ios::out);
  331.     while((is_file("temp.dat", true) == true) && (!out.is_open()))
  332.     {
  333.         continue;
  334.     }
  335.     out<< x;
  336.     out.close();
  337.     in.open("temp.dat", ios::in);
  338.     while((is_file("temp.dat", true) == true) && (!in.is_open()))
  339.     {
  340.         continue;
  341.     }
  342.     getline(in, s);
  343.     in.close();
  344.     remove("temp.dat");
  345.     in.clear();
  346.     out.clear();
  347.     return s;
  348. }
  349.  
  350. int percent_complete(int x, int max)
  351. {
  352.     float p = 0;
  353.     p = (float(x) / float(max));
  354.     p = (p * 100);
  355.     return floor(p);
  356. }
  357.  
  358.  
  359. \\common.cpp END==================================================================
  360.  
  361. \\common.h begin==================================================================
  362.  
  363. #ifndef COMMON_H_INCLUDED
  364. #define COMMON_H_INCLUDED
  365. using namespace std;
  366.  
  367. void cls();
  368. void cl();
  369. void wait();
  370. char gkey();
  371. int conv_str(string s = "");
  372. string conv_int(int x = 0);
  373. int percent_complete(int x = 0, int max = 0);
  374.  
  375. #endif // COMMON_H_INCLUDED
  376.  
  377.  
  378. \\common.h END==================================================================
  379.  
  380. \\datastruct.cpp begin==================================================================
  381.  
  382. #include <iostream>
  383. #include <fstream>
  384. #include <vector>
  385. #include <string>
  386. #include "datastruct.h"
  387. #include "common.h"
  388. #include "fsys.h"
  389.  
  390. using namespace std;
  391.  
  392. /**
  393. Data structure:
  394.  
  395. directiories:
  396.  
  397. file: dirbacklist.dat
  398.  
  399. just listed.  We can iterate all sub-directories upon the initiation of
  400. our backup.  this will also allow the user some freedom in changing his/her filesystem
  401. without worrying about this program.
  402. */
  403.  
  404. vector<string> get_file(string f)
  405. {
  406.     vector<string> file;
  407.     if(data_there(f) == false)
  408.     {
  409.         return file;
  410.     }
  411.     ifstream in;
  412.     string line;
  413.     in.open(f.c_str(), ios::in);
  414.     while(in.good())
  415.     {
  416.         getline(in, line);
  417.         file.push_back(line);
  418.     }
  419.     in.close();
  420.     return file;
  421. }
  422.  
  423. vector<string> get_options()
  424. {
  425.     vector<string> options;
  426.     if(data_there("optsback.dat") == false)
  427.     {
  428.         options.clear();
  429.         options.push_back("");
  430.         options.push_back("do nothing");
  431.         return options;
  432.     }
  433.     ifstream in;
  434.     string line;
  435.     in.open("optsback.dat", ios::in);
  436.     while(in.good())
  437.     {
  438.         getline(in, line);
  439.         if(line == "x")
  440.         {
  441.             line = "";
  442.         }
  443.         options.push_back(line);
  444.     }
  445.     in.close();
  446.     return options;
  447. }
  448.  
  449. void save_directories(vector<string> directories)
  450. {
  451.     ofstream out;
  452.     out.open("dirbacklist.dat", ios::out);
  453.     if(directories.size() > 0)
  454.     {
  455.         for(unsigned int x = 0; x < directories.size(); x++)
  456.         {
  457.             out<< directories[x];
  458.             if(x < (directories.size() - 1))
  459.             {
  460.                 out<< endl;
  461.             }
  462.         }
  463.     }
  464.     out.close();
  465. }
  466.  
  467. void save_options(vector<string> options)
  468. {
  469.     ofstream out;
  470.     out.open("optsback.dat", ios::out);
  471.     for(unsigned int x = 0; x < options.size(); x++)
  472.     {
  473.         out<< options[x];
  474.         if(x < (options.size() - 1))
  475.         {
  476.             out<< endl;
  477.         }
  478.     }
  479.     out.close();
  480. }
  481.  
  482. //checks if the target directory is part of the list of directories it will back up
  483. bool target_isnt_part_of_backup(string target)
  484. {
  485.     vector<string> directories;
  486.     directories = get_file("dirbacklist.dat");
  487.     for(unsigned int x = 0; x < directories.size(); x++)
  488.     {
  489.         if(target == directories[x])
  490.         {
  491.             directories.clear();
  492.             return false;
  493.         }
  494.     }
  495.     directories.clear();
  496.     return true;
  497. }
  498.  
  499. bool there_are_directories_to_back_up()
  500. {
  501.     remove_extinct_directories();
  502.     vector<string> f;
  503.     f = get_file("dirbacklist.dat");
  504.     if(f.size() > 0)
  505.     {
  506.         f.clear();
  507.         return true;
  508.     }
  509.     return false;
  510. }
  511.  
  512.  
  513. \\datastruct.cpp END==================================================================
  514.  
  515. \\datastruct.h begin==================================================================
  516.  
  517. #ifndef DATASTRUCT_H_INCLUDED
  518. #define DATASTRUCT_H_INCLUDED
  519. #include <string>
  520. #include <vector>
  521. using namespace std;
  522.  
  523. vector<string> get_file(string f = "");
  524. vector<string> get_options();
  525. void save_directories(vector<string> directories = vector<string>());
  526. void save_options(vector<string> options = vector<string>());
  527. bool target_isnt_part_of_backup(string target = "");
  528. bool there_are_directories_to_back_up();
  529.  
  530. #endif // DATASTRUCT_H_INCLUDED
  531.  
  532.  
  533. \\datastruct.h END==================================================================
  534.  
  535. \\dataunits.cpp begin==================================================================
  536.  
  537. #include <iostream>
  538. #include <string>
  539. #include <math.h>
  540. #include "dataunits.h"
  541.  
  542. #include "common.h"
  543.  
  544. using namespace std;
  545.  
  546. /**First off, this file is special:
  547. it conatins ONLY functions for converting
  548. units of data storage.  lets keep it that way.*/
  549.  
  550. /*
  551. Detirmines what unit to use to measure the data size.
  552. return values:
  553. none = no data type, no data
  554. byte, megabyte, kilobyte, and gigabyte*/
  555.  
  556. double round_to_tenths(double x)
  557. {
  558.     float newf = 0;
  559.     newf = (x * 100);
  560.     newf = int(newf);
  561.     newf = (newf / 100);
  562.     return newf;
  563. }
  564.  
  565. string choose_unit(double s)
  566. {
  567.     if(s == 0)
  568.     {
  569.         return "none";
  570.     }
  571.     if(s < 1024)
  572.     {
  573.         return "b";
  574.     }
  575.     if((s >= 1024) && (s < 1048576))
  576.     {
  577.         return "Kb";
  578.     }
  579.     if((s >= 1048576) && (s < 1073741824))
  580.     {
  581.         return "MB";
  582.     }
  583.     if(s >= 1073741824)
  584.     {
  585.         return "Gb";
  586.     }
  587.     return "unknown";
  588. }
  589.  
  590. double convert_size(double size, string& unit)
  591. {
  592.     if(size == 0)
  593.     {
  594.         unit = "b";
  595.         return 0;
  596.     }
  597.     float news = 0;
  598.     unit = choose_unit(size);
  599.     if(unit == "unknown")
  600.     {
  601.         news = float(size);
  602.         return news;
  603.     }
  604.     if(unit == "b")
  605.     {
  606.         news = float(size);
  607.         return round_to_tenths(news);
  608.     }
  609.     if(unit == "Kb")
  610.     {
  611.         news = (float(size) / 1024);
  612.         return round_to_tenths(news);
  613.     }
  614.     if(unit == "MB")
  615.     {
  616.         news = (float(size) / 1048576);
  617.         return round_to_tenths(news);
  618.     }
  619.     if(unit == "Gb")
  620.     {
  621.         news = (float(size) / 1073741824);
  622.         return round_to_tenths(news);
  623.     }
  624.     unit = "b";
  625.     return 0;
  626. }
  627.  
  628.  
  629.  
  630. \\dataunits.cpp END==================================================================
  631.  
  632. \\dataunits.h begin==================================================================
  633.  
  634. #ifndef DATAUNITS_H_INCLUDED
  635. #define DATAUNITS_H_INCLUDED
  636. using namespace std;
  637.  
  638. static string default_s2 = string();
  639.  
  640. string choose_unit(double s = 0);
  641. double convert_size(double size = 0, string& unit = default_s2);
  642. double round_to_tenths(double x = 0);
  643.  
  644. #endif // DATAUNITS_H_INCLUDED
  645.  
  646.  
  647. \\dataunits.h END==================================================================
  648.  
  649. \\fsys.cpp begin==================================================================
  650.  
  651. #include <iostream>
  652. #include <fstream>
  653. #include <string>
  654. #include <vector>
  655. #include <boost/filesystem.hpp>
  656. #include "fsys.h"
  657. #include "datastruct.h"
  658. #include "dataunits.h"
  659. #include "common.h"
  660.  
  661. using namespace std;
  662.  
  663. /*Here we have all of our filesystem functions.  That
  664. is to say most of the functions in this program that
  665. perform fileoperations are included in this file.*/
  666.  
  667. /**This also include file/folder confirmation
  668. so that our buackup session doesnt try to copy
  669. non-existent files/folders.*/
  670.  
  671. //does that file exist?
  672. //this_directory can be specified so that we dont have to use entire paths
  673. bool is_file(string f, bool this_directory)
  674. {
  675.     boost::filesystem::path p;
  676.     p = f;
  677.     if(this_directory == false)
  678.     {
  679.         if(boost::filesystem::is_regular_file(p) == true)
  680.         {
  681.             p.clear();
  682.             return true;
  683.         }
  684.         return false;
  685.     }
  686.     if(this_directory == true)
  687.     {
  688.         p = (boost::filesystem::current_path().string() + "\\" + p.string());
  689.         if(boost::filesystem::is_regular_file(p) == true)
  690.         {
  691.             return true;
  692.         }
  693.         return false;
  694.     }
  695.     return false;
  696. }
  697.  
  698. //does that folder exist?
  699. bool is_folder(string d)
  700. {
  701.     boost::filesystem::path p;
  702.     p = d;
  703.     if(boost::filesystem::is_directory(p) == true)
  704.     {
  705.         p.clear();
  706.         return true;
  707.     }
  708.     p.clear();
  709.     return false;
  710. }
  711.  
  712. bool data_there(string f)
  713. {
  714.     string line;
  715.     ifstream in;
  716.     int number_of_lines = 0;
  717.     if(is_file(f) == true)
  718.     {
  719.         in.open(f.c_str(), ios::in);
  720.         while(in.good())
  721.         {
  722.             getline(in, line);
  723.             if(line.size() > 0)
  724.             {
  725.                 number_of_lines++;
  726.             }
  727.         }
  728.         in.close();
  729.         line.clear();
  730.         in.clear();
  731.         if(number_of_lines > 0)
  732.         {
  733.             return true;
  734.         }
  735.     }
  736.     return false;
  737. }
  738.  
  739. //lists the contents of a folder.  all subdiurectories, files, and sub-sub-directories...
  740. //d = directory of folder, size = size of its contents in bytes
  741. void list_folder_contents(string d, vector<string>& contents, double& s)
  742. {
  743.     contents.clear();
  744.     s = 0;
  745.     if(!is_folder(d))
  746.     {
  747.         return;
  748.     }
  749.     vector<boost::filesystem::directory_entry> directories;
  750.     boost::filesystem::path p;
  751.     p = d;
  752.     //we get a list of all the files/folders
  753.     copy(boost::filesystem::recursive_directory_iterator(p), boost::filesystem::recursive_directory_iterator(), back_inserter(directories));
  754.     //now we will calculate the size of this directory...
  755.     s = 0;
  756.     for(unsigned int x = 0; x < directories.size(); x++)
  757.     {
  758.         if(is_file(directories[x].path().string()) == true)
  759.         {
  760.             s = (s + file_size(directories[x].path()));
  761.         }
  762.         contents.push_back(directories[x].path().string());
  763.     }
  764.     directories.clear();
  765.     p.clear();
  766. }
  767.  
  768. //converts a plain text file to binary.  this appears as single-lined in notepad.exe
  769. void conv_tobin(string f)
  770. {
  771.     ifstream in;
  772.     ofstream out;
  773.     vector<string> file;
  774.     string line;
  775.     if(is_file(f) == true)
  776.     {
  777.         in.open(f.c_str(), ios::in);
  778.         while(in.good())
  779.         {
  780.             getline(in, line);
  781.             file.push_back(line);
  782.         }
  783.         in.close();
  784.         out.open(f.c_str(), ios::binary);
  785.         for(unsigned int x = 0; x < file.size(); x++)
  786.         {
  787.             out<< file[x];
  788.             if(x < (file.size() - 1))
  789.             {
  790.                 out<< endl;
  791.             }
  792.         }
  793.         out.close();
  794.         file.clear();
  795.         in.clear();
  796.         out.clear();
  797.         line.clear();
  798.     }
  799. }
  800.  
  801. //converts a file to text format.  this appears in lines in notepad.exe
  802. void conv_totext(string f)
  803. {
  804.     ofstream out;
  805.     ifstream in;
  806.     string line;
  807.     vector<string> file;
  808.     if(is_file(f) == true)
  809.     {
  810.         in.open(f.c_str(), ios::binary);
  811.         while(in.good())
  812.         {
  813.             getline(in, line);
  814.             file.push_back(line);
  815.         }
  816.         in.close();
  817.         out.open(f.c_str(), ios::out);
  818.         for(unsigned int x = 0; x < file.size(); x++)
  819.         {
  820.             out<< file[x];
  821.             if(x < (file.size() - 1))
  822.             {
  823.                 out<< endl;
  824.             }
  825.         }
  826.         out.close();
  827.         file.clear();
  828.         in.clear();
  829.         out.clear();
  830.         line.clear();
  831.     }
  832. }
  833.  
  834. /*This function makes sure all of the
  835. directories in the directories folder exist.
  836. It will remove any directories that dont
  837. exist.*/
  838. void remove_extinct_directories()
  839. {
  840.     if((is_file("dirbacklist.dat", true) == false) || (data_there("dirbacklist.dat") == false))
  841.     {
  842.         return;
  843.     }
  844.     ifstream in;
  845.     vector<string> directories, existing;
  846.     ofstream out;
  847.     string line;
  848.     in.open("dirbacklist.dat", ios::in);
  849.     while(in.good())
  850.     {
  851.         getline(in, line);
  852.         directories.push_back(line);
  853.     }
  854.     in.close();
  855.     for(unsigned int x = 0; x < directories.size(); x++) //go through the list of directories and filter out non-existing ones
  856.     {
  857.         if((is_file(directories[x]) == true) || (is_folder(directories[x]) == true))
  858.         {
  859.             existing.push_back(directories[x]);
  860.         }
  861.     }
  862.     //write it back to the file.
  863.     out.open("dirbacklist.dat", ios::out);
  864.     for(unsigned int x = 0; x < existing.size(); x++)
  865.     {
  866.         out<< existing[x];
  867.         if(x < (existing.size() - 1))
  868.         {
  869.             out<< endl;
  870.         }
  871.     }
  872.     out.close();
  873.     existing.clear();
  874.     directories.clear();
  875.     in.clear();
  876.     out.clear();
  877.     line.clear();
  878. }
  879.  
  880. double backup_size(string& unit_type)
  881. {
  882.     cls();
  883.     cout<< "Please wait..."<< endl;
  884.     vector<string> directories, contents;
  885.     directories = get_file("dirbacklist.dat");
  886.     boost::filesystem::path p;
  887.     double s = 0, total = 0, per = 0, total_final = 0;
  888.     for(unsigned int x = 0; x < directories.size(); x++)
  889.     {
  890.         if(per != percent_complete(x, directories.size()))
  891.         {
  892.             per = percent_complete(x, signed(directories.size()));
  893.             cls();
  894.             cout<< per<< "\%"<< endl;
  895.         }
  896.         if(is_folder(directories[x]) == true)
  897.         {
  898.             list_folder_contents(directories[x], contents, s);
  899.             total = (total + s);
  900.             continue;
  901.         }
  902.         if(is_file(directories[x]) == true)
  903.         {
  904.             p = directories[x];
  905.             s = boost::filesystem::file_size(p);
  906.             total = (total + s);
  907.             continue;
  908.         }
  909.     }
  910.     total_final = float(total);
  911.     total_final = convert_size(total, unit_type);
  912.     return total_final;
  913. }
  914.  
  915. /*Checks a directory's contents.  Returns true if
  916. it is empty, and false if it doesnt exist, or contains
  917. data.*/
  918. bool folder_empty(string f)
  919. {
  920.     boost::filesystem::path p;
  921.     p = f;
  922.     vector<boost::filesystem::directory_entry> directories;
  923.     if(boost::filesystem::is_regular_file(p) == true)
  924.     {
  925.         return false;
  926.     }
  927.     if(boost::filesystem::is_directory(p) == false)
  928.     {
  929.         return false;
  930.     }
  931.     copy(boost::filesystem::directory_iterator(p), boost::filesystem::directory_iterator(), back_inserter(directories));
  932.     if(directories.size() > 0)
  933.     {
  934.         directories.clear();
  935.         return false;
  936.     }
  937.     return true;
  938. }
  939.  
  940. //this is necessary to avoid a fatal runtime error.....
  941. bool is_part_of_backup(string directory)
  942. {
  943.     vector<boost::filesystem::directory_entry> dirs;
  944.     vector<string> files;
  945.     int matches = 0;
  946.     boost::filesystem::path p;
  947.     files = get_file("dirbacklist.dat");
  948.     for(unsigned int x = 0; x < files.size(); x++)
  949.     {
  950.         p = files[x];
  951.         if(boost::filesystem::is_regular_file(p) == true)
  952.         {
  953.             continue;
  954.         }
  955.         copy(boost::filesystem::recursive_directory_iterator(p), boost::filesystem::recursive_directory_iterator(), back_inserter(dirs));
  956.         for(unsigned int y = 0; y < dirs.size(); y++)
  957.         {
  958.             if(dirs[x].path().string() == directory)
  959.             {
  960.                 matches++;
  961.             }
  962.         }
  963.     }
  964.     if(matches > 0)
  965.     {
  966.         return true;
  967.     }
  968.     return false;
  969. }
  970.  
  971. bool sd_included_in_backup(boost::filesystem::path p, vector<string> file)
  972. {
  973.     for(unsigned int x = 0; x < file.size(); x++)
  974.     {
  975.         if(p.string() == file[x])
  976.         {
  977.             return true;
  978.         }
  979.     }
  980.     return false;
  981. }
  982.  
  983. void remove_directory_from_list(boost::filesystem::path p)
  984. {
  985.     vector<string> file, newfile;
  986.     file = get_file("dirbacklist.dat");
  987.     ofstream out;
  988.     newfile.clear();
  989.     for(unsigned int x = 0; x < file.size(); x++)
  990.     {
  991.         if(file[x] != p.string())
  992.         {
  993.             newfile.push_back(file[x]);
  994.         }
  995.     }
  996.     out.open("dirbacklist.dat", ios::out);
  997.     for(unsigned int x = 0; x < newfile.size(); x++)
  998.     {
  999.         out<< newfile[x];
  1000.         if(x < (newfile.size() - 1))
  1001.         {
  1002.             out<< endl;
  1003.         }
  1004.     }
  1005.     out.close();
  1006.     newfile.clear();
  1007.     file.clear();
  1008. }
  1009.  
  1010. /*Checks to see if the user included subdirectories
  1011. of those directories he did include.*/
  1012. void check_subdirectory_inclusion()
  1013. {
  1014.     vector<boost::filesystem::directory_entry> directories;
  1015.     vector<string> file;
  1016.     file = get_file("dirbacklist.dat");
  1017.     boost::filesystem::path p;
  1018.     for(unsigned int x = 0; x < file.size(); x++)
  1019.     {
  1020.         cls();
  1021.         cout<< "I am removeing from your list directories that are subdirectories of directories you already included."<< endl<< endl;
  1022.         cout<< "Removing sub-directory inclusions..."<< endl;
  1023.         cout<< percent_complete(x, signed(file.size()))<< " \%"<< endl;
  1024.         p.clear();
  1025.         p = file[x];
  1026.         if(is_folder(p.string()) == true)
  1027.         {
  1028.             copy(boost::filesystem::recursive_directory_iterator(p), boost::filesystem::recursive_directory_iterator(), back_inserter(directories));
  1029.             for(unsigned int y = 0; y < directories.size(); y++)
  1030.             {
  1031.                 if(sd_included_in_backup(directories[y].path(), file) == true)
  1032.                 {
  1033.                     remove_directory_from_list(directories[y].path());
  1034.                 }
  1035.             }
  1036.         }
  1037.         /*we dont need to do this for any of the files, because we go
  1038.         through the entire list in sd_included_in_backup(), so if it
  1039.         finds a file, it will be removed.*/
  1040.     }
  1041.     directories.clear();
  1042.     file.clear();
  1043. }
  1044.  
  1045.  
  1046. \\fsys.cpp END==================================================================
  1047.  
  1048. \\fsys.h begin==================================================================
  1049.  
  1050. #ifndef FSYS_H_INCLUDED
  1051. #define FSYS_H_INCLUDED
  1052. #include <string>
  1053. #include <vector>
  1054. #include <boost/filesystem.hpp>
  1055.  
  1056. using namespace std;
  1057.  
  1058. static vector<string> default_vs;
  1059. static string default_s = string();
  1060. static double default_d = double();
  1061.  
  1062. bool is_file(string f = "", bool this_directory = false);
  1063. bool is_folder(string d = "");
  1064. void list_folder_contents(string d = "", vector<string>& contents = default_vs, double& s = default_d);
  1065. void conv_tobin(string f = "");
  1066. void conv_totext(string f = "");
  1067. bool data_there(string f = "");
  1068. void remove_extinct_directories();
  1069. double backup_size(string& unit_type = default_s);
  1070. bool folder_empty(string f = "");
  1071. bool is_part_of_backup(string directory = "");
  1072. bool sd_included_in_backup(boost::filesystem::path p, vector<string> file = vector<string>());
  1073. void check_subdirectory_inclusion();
  1074.  
  1075. #endif // FSYS_H_INCLUDED
  1076.  
  1077.  
  1078. \\fsys.h END==================================================================
  1079.  
  1080. \\link.h begin==================================================================
  1081.  
  1082. #ifndef LINK_H_INCLUDED
  1083. #define LINK_H_INCLUDED
  1084.  
  1085. void options_menu();
  1086. int start_backup();
  1087.  
  1088. #endif // LINK_H_INCLUDED
  1089.  
  1090.  
  1091. \\link.h END==================================================================
  1092.  
  1093. \\main.cpp begin==================================================================
  1094.  
  1095. #include <iostream>
  1096. #include "datastruct.h"
  1097. #include "common.h"
  1098. #include "link.h"
  1099. #include "fsys.h"
  1100.  
  1101. using namespace std;
  1102.  
  1103. /**
  1104. In-Dev notes:
  1105.  
  1106. Menu layout:
  1107.  
  1108. Main menu options-
  1109. start backup (must add directories)
  1110.     -y/n prompt
  1111.     -displays amount of data being backed up and a percent complete
  1112. Options-
  1113.      -Add/remove directories
  1114.           - Directory options:
  1115.                  - edit directory
  1116.                  - remove directory from list
  1117.      - add/edit target directory
  1118.      - Do somthing when backup is complete:
  1119.          - put computer to sleep
  1120.          - beep
  1121.          - nothing
  1122. */
  1123.  
  1124. int main()
  1125. {
  1126.     int x = 0;
  1127.     char ch;
  1128.     while(x == 0)
  1129.     {
  1130.         remove_extinct_directories(); //making sure we do not have non-existent file/folders listed
  1131.         cls();
  1132.         cout<< "             Main menu"<< endl<< endl<< endl;
  1133.         cout<< "1 -  Start Backup"<< endl;
  1134.         cout<< "2 -  Options"<< endl;
  1135.         cout<< "3/[ESCAPE] -  Exit Program"<< endl;
  1136.         ch = gkey();
  1137.         if(ch == '1')
  1138.         {
  1139.             start_backup();
  1140.             continue;
  1141.         }
  1142.         if(ch == '2')
  1143.         {
  1144.             options_menu();
  1145.             continue;
  1146.         }
  1147.         if((ch == '3') || (ch == 0x1b))
  1148.         {
  1149.             return 0;
  1150.         }
  1151.     }
  1152.     return 0;
  1153. }
  1154.  
  1155.  
  1156. \\main.cpp END==================================================================
  1157.  
  1158. \\options_menu.cpp begin==================================================================
  1159.  
  1160. #include <iostream>
  1161. #include <string>
  1162. #include <vector>
  1163. #include "fsys.h"
  1164. #include "common.h"
  1165. #include "datastruct.h"
  1166.  
  1167. using namespace std;
  1168.  
  1169. static vector<string> default_vs2;
  1170.  
  1171. /*Options menu
  1172.  
  1173. file: optsback.dat
  1174.  
  1175. directories file: dirbacklist.dat
  1176.  
  1177. data structure:
  1178.  
  1179. 0  target directory
  1180. 1  what to do after backup completed
  1181. */
  1182.  
  1183. void remove_directory(vector<string>& directories = default_vs2, int line = -1)
  1184. {
  1185.     if(line < 0)
  1186.     {
  1187.         return;
  1188.     }
  1189.     vector<string> temp;
  1190.     //copy to temp
  1191.     for(unsigned int x = 0; x < directories.size(); x++)
  1192.     {
  1193.         temp.push_back(directories[x]);
  1194.     }
  1195.     directories.clear();
  1196.     //copy all but that line back to the origional vector
  1197.     for(int x = 0; unsigned(x) < temp.size(); x++)
  1198.     {
  1199.         if(x != line)
  1200.         {
  1201.             directories.push_back(temp[x]);
  1202.         }
  1203.     }
  1204.     //clear the temp vector
  1205.     temp.clear();
  1206. }
  1207.  
  1208. bool is_duplicate_directory(vector<string> directories = vector<string>(), string dir = "")
  1209. {
  1210.     int dups = 0;
  1211.     for(unsigned int x = 0; x < directories.size(); x++)
  1212.     {
  1213.         if(directories[x] == dir)
  1214.         {
  1215.             dups++;
  1216.         }
  1217.     }
  1218.     if(dups > 0)
  1219.     {
  1220.         return true;
  1221.     }
  1222.     return false;
  1223. }
  1224.  
  1225. void modify_directory(vector<string>& directories = default_vs2, int dir = 0)
  1226. {
  1227.     int x = 0;
  1228.     string renam = "";
  1229.     char ch;
  1230.     while(x == 0)
  1231.     {
  1232.         cls();
  1233.         cout<< "         Modify \""<< directories[dir]<< "\":"<< endl<< endl<< endl;
  1234.         cout<< " 1 -  Re-Name"<< endl;
  1235.         cout<< " 2 -  Delete"<< endl;
  1236.         cout<< " [BACK] -  Back to directory list"<< endl;
  1237.         ch = gkey();
  1238.         if(ch == '1')
  1239.         {
  1240.             renam = "";
  1241.             while(renam == "")
  1242.             {
  1243.                 cls();
  1244.                 cout<< "Rename \""<< directories[dir]<< "\":";
  1245.                 getline(cin, renam);
  1246.                 if(renam.size() == 1)
  1247.                 {
  1248.                     if(tolower(renam[0]) == 'x')
  1249.                     {
  1250.                         renam = directories[dir];
  1251.                         break;
  1252.                     }
  1253.                 }
  1254.                 if((is_duplicate_directory(directories, renam) == true) && (renam != directories[dir]))
  1255.                 {
  1256.                     cls();
  1257.                     cout<< "I already have that directory listed.  You do noty need to add it again."<< endl;
  1258.                     wait();
  1259.                     renam.clear();
  1260.                     renam = "";
  1261.                     continue;
  1262.                 }
  1263.                 if((is_file(renam) == false) && (is_folder(renam) == false))
  1264.                 {
  1265.                     cls();
  1266.                     cout<< "That is not a valid path!"<< endl;
  1267.                     wait();
  1268.                     renam = "";
  1269.                 }
  1270.             }
  1271.             directories[dir] = renam;
  1272.             save_directories(directories);
  1273.             continue;
  1274.         }
  1275.         if(ch == '2')
  1276.         {
  1277.             remove_directory(directories, dir);
  1278.             save_directories(directories);
  1279.             return;
  1280.         }
  1281.         if(ch == 0x08)
  1282.         {
  1283.             save_directories(directories);
  1284.             return;
  1285.         }
  1286.     }
  1287. }
  1288.  
  1289. void add_directory(vector<string>& directories = default_vs2)
  1290. {
  1291.     string directory_name = "";
  1292.     while(directory_name == "")
  1293.     {
  1294.         cls();
  1295.         cout<< "Enter 'x' to cancel."<< endl<< endl;
  1296.         cout<< "Enter a path: ";
  1297.         getline(cin, directory_name);
  1298.         if(directory_name.size() == 1)
  1299.         {
  1300.             if(tolower(directory_name[0]) == 'x')
  1301.             {
  1302.                 return;
  1303.             }
  1304.         }
  1305.         if((is_file(directory_name) == false) && (is_folder(directory_name) == false))
  1306.         {
  1307.             cls();
  1308.             cout<< "That path is invalid!"<< endl;
  1309.             wait();
  1310.             directory_name.clear();
  1311.             directory_name = "";
  1312.         }
  1313.         if(is_duplicate_directory(directories, directory_name) == true)
  1314.         {
  1315.             cls();
  1316.             cout<< "I already have that directory listed.  You do noty need to add it again."<< endl;
  1317.             wait();
  1318.             directory_name.clear();
  1319.             directory_name = "";
  1320.         }
  1321.     }
  1322.     directories.push_back(directory_name);
  1323.     save_directories(directories);
  1324. }
  1325.  
  1326. void edit_directory_list()
  1327. {
  1328.     vector<string> directories;
  1329.     int x = 0, choice;
  1330.     string choice_s;
  1331.     while(x == 0)
  1332.     {
  1333.         directories.clear();
  1334.         directories = get_file("dirbacklist.dat");
  1335.         cls();
  1336.         cout<< "             Directories:"<< endl<< endl<< endl;
  1337.         if(directories.size() > 0)
  1338.         {
  1339.             for(unsigned int x = 0; x < directories.size(); x++)
  1340.             {
  1341.                 cout<< (x + 1)<< " -  "<< directories[x]<< endl;
  1342.             }
  1343.         }
  1344.         cout<< endl<< endl;
  1345.         cout<< "*************************************"<< endl;
  1346.         cout<< "'a' -  Add a new directory"<< endl;
  1347.         cout<< "'q' -  Back"<< endl;
  1348.         cout<< endl<< "*************************************"<< endl;
  1349.         choice_s.clear();
  1350.         choice = 0;
  1351.         while((choice < 1) || (unsigned(choice) > directories.size()))
  1352.         {
  1353.             choice_s.clear();
  1354.             cin.sync();
  1355.             getline(cin, choice_s);
  1356.             if(choice_s.size() > 0)
  1357.             {
  1358.                 if(tolower(choice_s[0]) == 'a')
  1359.                 {
  1360.                     choice = -1;
  1361.                     break;
  1362.                 }
  1363.                 if(tolower(choice_s[0] == 'q'))
  1364.                 {
  1365.                     save_directories(directories);
  1366.                     return;
  1367.                 }
  1368.             }
  1369.             choice = conv_str(choice_s);
  1370.         }
  1371.         if(choice == -1)
  1372.         {
  1373.             add_directory(directories);
  1374.             continue;
  1375.         }
  1376.         choice--;
  1377.         modify_directory(directories, choice);
  1378.     }
  1379. }
  1380.  
  1381. void edit_target_directory(vector<string>& options = default_vs2)
  1382. {
  1383.     vector<string> directories;
  1384.     directories = get_file("dirbacklist.dat");
  1385.     string edit = "";
  1386.     while(edit == "")
  1387.     {
  1388.         cls();
  1389.         cout<< "Press 'x' to cancel."<< endl<< endl;
  1390.         if(options[0].size() > 0)
  1391.         {
  1392.             cout<< "Current target: \""<< options[0]<< "\""<< endl;
  1393.         }
  1394.         cout<< endl<< endl<< endl<< endl;
  1395.         cout<< "Enter the new target directory: ";
  1396.         getline(cin, edit);
  1397.         if(edit.size() == 1)
  1398.         {
  1399.             if(tolower(edit[0]) == 'x')
  1400.             {
  1401.                 return;
  1402.             }
  1403.         }
  1404.         if(folder_empty(edit) == false)
  1405.         {
  1406.             if(is_folder(edit) == true)
  1407.             {
  1408.                 cls();
  1409.                 cout<< "It is recommended that you name an empty folder, as your target's contents will be completely erased."<< endl;
  1410.                 edit = "";
  1411.                 wait();
  1412.                 continue;
  1413.             }
  1414.         }
  1415.         if(target_isnt_part_of_backup(edit) == false)
  1416.         {
  1417.             cls();
  1418.             cout<< "You can not copy a folder to itself!!  This path is part of your backup, and cannot be the target directory."<< endl;
  1419.             wait();
  1420.             edit = "";
  1421.             continue;
  1422.         }
  1423.         if(is_duplicate_directory(directories, edit) == false)
  1424.         {
  1425.             if(is_folder(edit) == true)
  1426.             {
  1427.                 options[0] = edit;
  1428.                 save_options(options);
  1429.                 return;
  1430.             }
  1431.             cls();
  1432.             cout<< "You can not name a file as your target!"<< endl;
  1433.             wait();
  1434.             edit = "";
  1435.             continue;
  1436.         }
  1437.         edit = "";
  1438.     }
  1439. }
  1440.  
  1441. void toggle_end(vector<string>& options = default_vs2)
  1442. {
  1443.     vector<string> toggles;
  1444.     toggles.push_back("sleep");
  1445.     toggles.push_back("beep");
  1446.     toggles.push_back("nothing");
  1447.     int id = 2;
  1448.     for(unsigned int x = 0; x < toggles.size(); x++)
  1449.     {
  1450.         if(options[1] == toggles[x])
  1451.         {
  1452.             id = x;
  1453.             break;
  1454.         }
  1455.     }
  1456.     id++;
  1457.     if(id > 2)
  1458.     {
  1459.         id = (id - 3);
  1460.     }
  1461.     options[1] = toggles[id];
  1462.     save_options(options);
  1463.     toggles.clear();
  1464. }
  1465.  
  1466. void options_menu()
  1467. {
  1468.     vector<string> options;
  1469.     int x = 0;
  1470.     string unit = "";
  1471.     double backup = 0;
  1472.     char ch;
  1473.     while(x == 0)
  1474.     {
  1475.         remove_extinct_directories();
  1476.         options.clear();
  1477.         options = get_options();
  1478.         cls();
  1479.         cout<< "              Options"<< endl;
  1480.         cout<< endl<< endl<< endl;
  1481.         cout<< " 1 -  Add/Remove directories"<< endl;
  1482.         cout<< " 2 -  Add/Edit the Target Directory"<< endl;
  1483.         cout<< " 3 -  End of backup option:  "<< options[1]<< endl;
  1484.         cout<< " 4 -  Calculate the Size of the backup"<< endl;
  1485.         cout<< " 5 -  Remove sub-directory inclusions"<< endl;
  1486.         cout<< " [BACK] -  Back to main menu"<< endl;
  1487.         ch = gkey();
  1488.         if(ch == '1')
  1489.         {
  1490.             edit_directory_list();
  1491.             continue;
  1492.         }
  1493.         if(ch == '2')
  1494.         {
  1495.             edit_target_directory(options);
  1496.             continue;
  1497.         }
  1498.         if(ch == '3')
  1499.         {
  1500.             toggle_end(options);
  1501.             continue;
  1502.         }
  1503.         if(ch == '4')
  1504.         {
  1505.             cls();
  1506.             backup = backup_size(unit);
  1507.             cls();
  1508.             cout<< "Size of backup: "<< backup<< " "<< unit<< "."<< endl;
  1509.             wait();
  1510.             cls();
  1511.             continue;
  1512.         }
  1513.         if(ch == '5')
  1514.         {
  1515.             check_subdirectory_inclusion();
  1516.             continue;
  1517.         }
  1518.         if(ch == 0x08)
  1519.         {
  1520.             save_options(options);
  1521.             return;
  1522.         }
  1523.     }
  1524. }
  1525.  
  1526.  
  1527. \\options_menu.cpp END==================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement