src/FileAttributeFinder.h
branchv_0
changeset 9 b4f29fb16159
parent 8 eb1ecb37c6b7
child 21 1252acdc5a5a
equal deleted inserted replaced
8:eb1ecb37c6b7 9:b4f29fb16159
    39 	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
    39 	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
    40 
    40 
    41 	string_t currentOwner;
    41 	string_t currentOwner;
    42 	string_t currentGroup;
    42 	string_t currentGroup;
    43 
    43 
    44 	string_t getType(const fs::path& file, bool x) {
    44 	string_t getType(const fs::path& file, bool workWithSymlinkItself) {
    45 		// TODO: Use whole words? (letters are compatible with find -type)
    45 		// TODO: Use whole words? (letters are compatible with find -type)
    46 		if (fs::is_symlink(file) && x) return L"l"; // symlinks are both symlinks and files/directories/etc.
    46 		if (fs::is_symlink(file) && workWithSymlinkItself) return L"l"; // symlinks are both symlinks and files/directories/etc.
    47 		else if (fs::is_regular_file(file)) return L"f";
    47 		else if (fs::is_regular_file(file)) return L"f";
    48 		else if (fs::is_directory(file)) return L"d";
    48 		else if (fs::is_directory(file)) return L"d";
    49 		else if (fs::is_fifo(file)) return L"p";
    49 		else if (fs::is_fifo(file)) return L"p";
    50 		else if (fs::is_socket(file)) return L"s";
    50 		else if (fs::is_socket(file)) return L"s";
    51 		else if (fs::is_block_file(file)) return L"b";
    51 		else if (fs::is_block_file(file)) return L"b";
    67 		struct passwd* pw = getpwuid(info.st_uid);
    67 		struct passwd* pw = getpwuid(info.st_uid);
    68 		struct group* gr = getgrgid(info.st_gid);
    68 		struct group* gr = getgrgid(info.st_gid);
    69 		owner = convertor.from_bytes(pw->pw_name);
    69 		owner = convertor.from_bytes(pw->pw_name);
    70 		group = convertor.from_bytes(gr->gr_name);
    70 		group = convertor.from_bytes(gr->gr_name);
    71 	}
    71 	}
       
    72 
       
    73 protected:
       
    74 
       
    75 	virtual void writeFieldOfExistingFile(RelationalWriter* writer, const RequestedField& field) override {
       
    76 		if (field.group == RequestedField::GROUP_FILE) {
       
    77 			for (string_t alias : field.getAliases()) {
       
    78 				if (field.name == FIELD_NAME) {
       
    79 					writer->writeAttribute(currentFile.filename().wstring());
       
    80 				} else if (field.name == FIELD_PATH_ORIGINAL) {
       
    81 					writer->writeAttribute(convertor.from_bytes(currentFileRaw));
       
    82 				} else if (field.name == FIELD_PATH_ABSOLUTE) {
       
    83 					writer->writeAttribute(fs::absolute(currentFile).wstring());
       
    84 				} else if (field.name == FIELD_PATH_CANONICAL) {
       
    85 					writer->writeAttribute(fs::canonical(currentFile).wstring());
       
    86 				} else if (field.name == FIELD_TYPE) {
       
    87 					writer->writeAttribute(getType(currentFile, true));
       
    88 				} else if (field.name == FIELD_SYMLINK_TARGET_TYPE) {
       
    89 					writer->writeAttribute(getType(currentFile, false));
       
    90 				} else if (field.name == FIELD_SYMLINK_TARGET) {
       
    91 					string_t symlinkTarget; // TODO: null value (when supported)
       
    92 					if (fs::is_symlink(currentFile)) {
       
    93 						try {
       
    94 							symlinkTarget = fs::read_symlink(currentFile).wstring();
       
    95 						} catch (...) {
       
    96 							// missing permissions, not readable → leave empty
       
    97 						}
       
    98 					}
       
    99 					writer->writeAttribute(symlinkTarget);
       
   100 				} else if (field.name == FIELD_SIZE) {
       
   101 					integer_t size = fs::is_regular_file(currentFile) ? fs::file_size(currentFile) : 0;
       
   102 					writer->writeAttribute(&size, typeid (size));
       
   103 				} else if (field.name == FIELD_OWNER) {
       
   104 					if (currentOwner.empty()) fetchOwner(currentFile, currentOwner, currentGroup);
       
   105 					writer->writeAttribute(currentOwner);
       
   106 				} else if (field.name == FIELD_GROUP) {
       
   107 					if (currentOwner.empty()) fetchOwner(currentFile, currentOwner, currentGroup);
       
   108 					writer->writeAttribute(currentGroup);
       
   109 				} else {
       
   110 					throw RelpipeWriterException(L"Unsupported field name in FileAttributeFinder: " + field.name);
       
   111 				}
       
   112 			}
       
   113 		}
       
   114 	}
       
   115 
    72 public:
   116 public:
    73 
   117 
    74 	static const string_t FIELD_PATH_ORIGINAL;
   118 	static const string_t FIELD_PATH_ORIGINAL;
    75 	static const string_t FIELD_NAME;
   119 	static const string_t FIELD_NAME;
    76 	static const string_t FIELD_SIZE;
   120 	static const string_t FIELD_SIZE;
    93 		} else {
   137 		} else {
    94 			return {};
   138 			return {};
    95 		}
   139 		}
    96 	}
   140 	}
    97 
   141 
       
   142 	void writeField(RelationalWriter* writer, const RequestedField& field) override {
       
   143 		if (currentFileExists
       
   144 				|| field.name == FIELD_PATH_ORIGINAL
       
   145 				|| (fs::is_symlink(currentFile) && (field.name == FIELD_SYMLINK_TARGET || field.name == FIELD_TYPE)))
       
   146 			writeFieldOfExistingFile(writer, field);
       
   147 		else
       
   148 			writeEmptyField(writer, field);
       
   149 	}
       
   150 
    98 	void endFile() override {
   151 	void endFile() override {
    99 		AttributeFinder::endFile();
   152 		AttributeFinder::endFile();
   100 		currentOwner.clear();
   153 		currentOwner.clear();
   101 		currentGroup.clear();
   154 		currentGroup.clear();
   102 	};
   155 	};
   103 
       
   104 	virtual void writeField(RelationalWriter* writer, const RequestedField& field) override {
       
   105 		if (field.group == RequestedField::GROUP_FILE) {
       
   106 			for (string_t alias : field.getAliases()) {
       
   107 				if (field.name == FIELD_NAME) {
       
   108 					writer->writeAttribute(currentFile.filename().wstring());
       
   109 				} else if (field.name == FIELD_PATH_ORIGINAL) {
       
   110 					writer->writeAttribute(convertor.from_bytes(currentFileRaw));
       
   111 				} else if (field.name == FIELD_PATH_ABSOLUTE) {
       
   112 					writer->writeAttribute(fs::absolute(currentFile).wstring());
       
   113 				} else if (field.name == FIELD_PATH_CANONICAL) {
       
   114 					writer->writeAttribute(fs::canonical(currentFile).wstring());
       
   115 				} else if (field.name == FIELD_TYPE) {
       
   116 					writer->writeAttribute(getType(currentFile, true));
       
   117 				} else if (field.name == FIELD_SYMLINK_TARGET_TYPE) {
       
   118 					writer->writeAttribute(getType(currentFile, false));
       
   119 				} else if (field.name == FIELD_SYMLINK_TARGET) {
       
   120 					writer->writeAttribute(fs::is_symlink(currentFile) ? fs::read_symlink(currentFile).wstring() : L""); // TODO: null value (when supported)
       
   121 				} else if (field.name == FIELD_SIZE) {
       
   122 					integer_t size = fs::is_regular_file(currentFile) ? fs::file_size(currentFile) : 0;
       
   123 					writer->writeAttribute(&size, typeid (size));
       
   124 				} else if (field.name == FIELD_OWNER) {
       
   125 					if (currentOwner.empty()) fetchOwner(currentFile, currentOwner, currentGroup);
       
   126 					writer->writeAttribute(currentOwner);
       
   127 				} else if (field.name == FIELD_GROUP) {
       
   128 					if (currentOwner.empty()) fetchOwner(currentFile, currentOwner, currentGroup);
       
   129 					writer->writeAttribute(currentGroup);
       
   130 				} else {
       
   131 					// TODO: should not happend; check supported attributes in toMetadata()?
       
   132 					writer->writeAttribute(L"");
       
   133 				}
       
   134 			}
       
   135 		}
       
   136 	}
       
   137 
   156 
   138 	virtual ~FileAttributeFinder() override {
   157 	virtual ~FileAttributeFinder() override {
   139 	}
   158 	}
   140 };
   159 };
   141 
   160