| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -69,11 +69,45 @@ void Dotfile::add(const std::vector<std::string>& targets) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// Print root-owned targets and exit
 | 
					 | 
					 | 
					 | 
						sync( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							targets, homeTargets, systemTargets, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							[](std::string* paths, std::string homePath, size_t homeSize) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								paths[0] = homePath; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								paths[1] = homePath.substr(homeSize + 1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							}, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							[](std::string* paths, std::string systemPath) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								paths[0] = systemPath; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								paths[1] = systemPath.substr(1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							}); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					void Dotfile::list(const std::vector<std::string>& targets) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (s_workingDirectory.empty()) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							fprintf(stderr, "\033[31;1mDotfile:\033[0m working directory is unset\n"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (!std::filesystem::is_directory(s_workingDirectory)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							fprintf(stderr, "\033[31;1mDotfile:\033[0m working directory is not a directory\n"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						forEachDotfile(targets, [](std::filesystem::directory_entry path, size_t, size_t workingDirectory) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							printf("%s\n", path.path().c_str() + workingDirectory + 1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// -----------------------------------------
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					void Dotfile::sync(const std::vector<std::string>& files, const std::vector<size_t>& homeIndices, const std::vector<size_t>& systemIndices, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                   const std::function<void(std::string*, std::string, size_t)>& generateHomePaths, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                   const std::function<void(std::string*, std::string)>& generateSystemPaths) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						bool root = !geteuid() ? true : false; | 
					 | 
					 | 
					 | 
						bool root = !geteuid() ? true : false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (!systemTargets.empty() && !root) { | 
					 | 
					 | 
					 | 
						if (!systemIndices.empty() && !root) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							for (size_t i : systemTargets) { | 
					 | 
					 | 
					 | 
							for (size_t i : systemIndices) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								fprintf(stderr, "\033[31;1mDotfile:\033[0m you cannot copy system file '%s' unless you are root\n", targets.at(i).c_str()); | 
					 | 
					 | 
					 | 
								fprintf(stderr, "\033[31;1mDotfile:\033[0m you cannot copy system file '%s' unless you are root\n", files.at(i).c_str()); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -82,10 +116,6 @@ void Dotfile::add(const std::vector<std::string>& targets) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// the controlling terminal of the process
 | 
					 | 
					 | 
					 | 
						// the controlling terminal of the process
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						passwd* user = getpwnam(getlogin()); | 
					 | 
					 | 
					 | 
						passwd* user = getpwnam(getlogin()); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const auto copyOptions = std::filesystem::copy_options::overwrite_existing | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						                         | std::filesystem::copy_options::recursive | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						                         | std::filesystem::copy_options::copy_symlinks; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						auto printError = [](const std::filesystem::path& path, const std::error_code& error) -> void { | 
					 | 
					 | 
					 | 
						auto printError = [](const std::filesystem::path& path, const std::error_code& error) -> void { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// std::filesystem::copy doesnt respect 'overwrite_existing' for symlinks
 | 
					 | 
					 | 
					 | 
							// std::filesystem::copy doesnt respect 'overwrite_existing' for symlinks
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (error.value() && error.message() != "File exists") { | 
					 | 
					 | 
					 | 
							if (error.value() && error.message() != "File exists") { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -96,8 +126,12 @@ void Dotfile::add(const std::vector<std::string>& targets) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}; | 
					 | 
					 | 
					 | 
						}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						auto copyTarget = [&root, &user, &printError](const std::filesystem::path& from, | 
					 | 
					 | 
					 | 
						const auto copyOptions = std::filesystem::copy_options::overwrite_existing | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						                                              const std::filesystem::path& to, bool homePath) -> void { | 
					 | 
					 | 
					 | 
						                         | std::filesystem::copy_options::recursive | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						                         | std::filesystem::copy_options::copy_symlinks; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						auto copy = [&root, &user, &printError](const std::filesystem::path& from, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						                                        const std::filesystem::path& to, bool homePath) -> void { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (homePath && root) { | 
					 | 
					 | 
					 | 
							if (homePath && root) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								seteuid(user->pw_uid); | 
					 | 
					 | 
					 | 
								seteuid(user->pw_uid); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								setegid(user->pw_gid); | 
					 | 
					 | 
					 | 
								setegid(user->pw_gid); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -127,39 +161,19 @@ void Dotfile::add(const std::vector<std::string>& targets) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// /home/<user>/
 | 
					 | 
					 | 
					 | 
						// /home/<user>/
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						std::string home = "/home/" + std::string(user->pw_name); | 
					 | 
					 | 
					 | 
						std::string home = "/home/" + std::string(user->pw_name); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for (size_t index : homeTargets) { | 
					 | 
					 | 
					 | 
						for (size_t i : homeIndices) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							copyTarget(std::filesystem::path(targets.at(index)), | 
					 | 
					 | 
					 | 
							std::string paths[2]; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							           std::filesystem::path(targets.at(index).substr(home.size() + 1)), | 
					 | 
					 | 
					 | 
							generateHomePaths(paths, files.at(i), home.size()); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							           true); | 
					 | 
					 | 
					 | 
							copy(paths[0], paths[1], true); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// /
 | 
					 | 
					 | 
					 | 
						// /
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for (size_t index : systemTargets) { | 
					 | 
					 | 
					 | 
						for (size_t i : systemIndices) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							auto path = std::filesystem::path(targets.at(index)); | 
					 | 
					 | 
					 | 
							std::string paths[2]; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							copyTarget(path, | 
					 | 
					 | 
					 | 
							generateSystemPaths(paths, files.at(i)); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							           path.relative_path(), | 
					 | 
					 | 
					 | 
							copy(paths[0], paths[1], false); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							           false); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void Dotfile::list(const std::vector<std::string>& targets) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (s_workingDirectory.empty()) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							fprintf(stderr, "\033[31;1mDotfile:\033[0m working directory is unset\n"); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (!std::filesystem::is_directory(s_workingDirectory)) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							fprintf(stderr, "\033[31;1mDotfile:\033[0m working directory is not a directory\n"); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						forEachDotfile(targets, [](std::filesystem::directory_entry path, size_t, size_t workingDirectory) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("%s\n", path.path().c_str() + workingDirectory + 1); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// -----------------------------------------
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void Dotfile::forEachDotfile(const std::vector<std::string>& targets, const std::function<void(std::filesystem::directory_entry, size_t, size_t)>& callback) | 
					 | 
					 | 
					 | 
					void Dotfile::forEachDotfile(const std::vector<std::string>& targets, const std::function<void(std::filesystem::directory_entry, size_t, size_t)>& callback) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						size_t workingDirectory = s_workingDirectory.string().size(); | 
					 | 
					 | 
					 | 
						size_t workingDirectory = s_workingDirectory.string().size(); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |