Take input from file for write keyword
This commit adds code to read keyword’s value from the local file to
update keyword’s value. User can provide file path where the value
exists using --file option.
Output:
```
Write keyword using object path (both primary and backup path VPD gets updated)
Before update:
root@p10bmc:/tmp# ./vpd-tool -O /system/chassis/motherboard -R VSYS -K BR -r
{
"/system/chassis/motherboard": {
"BR": "S0"
}
}
root@p10bmc:/tmp# ./vpd-tool -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R VSYS -K BR -r -H
{
"/sys/bus/i2c/drivers/at24/8-0050/eeprom": {
"BR": "S0"
}
}
Input file (In ASCII format):
root@p10bmc:/tmp# cat input.txt
A2
Update keyword command:
root@p10bmc:/tmp# ./vpd-tool -O /system/chassis/motherboard -R VSYS -K BR -w --file input.txt
Data updated successfully
After update:
root@p10bmc:/tmp# ./vpd-tool -O /system/chassis/motherboard -R VSYS -K BR -r
{
"/system/chassis/motherboard": {
"BR": "A2"
}
}
root@p10bmc:/tmp# ./vpd-tool -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R VSYS -K BR -r -H
{
"/sys/bus/i2c/drivers/at24/8-0050/eeprom": {
"BR": "A2"
}
}
Write keyword using hardware path (updates only given hardware path):
Input file (In hexadecimal format):
root@p10bmc:/tmp# cat input.txt
0x5330
Update keyword command:
root@p10bmc:/tmp# ./vpd-tool -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R VSYS -K BR -w -H --file input.txt
Data updated successfully
After update:
root@p10bmc:/tmp# ./vpd-tool -O /system/chassis/motherboard -R VSYS -K BR -r
{
"/system/chassis/motherboard": {
"BR": "A2"
}
}
root@p10bmc:/tmp# ./vpd-tool -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R VSYS -K BR -r -H
{
"/sys/bus/i2c/drivers/at24/8-0050/eeprom": {
"BR": "S0"
}
}
```
Change-Id: I762dceae351ab2f9a1989b664a424cda4470dd1d
Signed-off-by: Anupama B R <anupama.b.r1@ibm.com>
diff --git a/vpd-tool/include/tool_utils.hpp b/vpd-tool/include/tool_utils.hpp
index e4b0a33..4306da5 100644
--- a/vpd-tool/include/tool_utils.hpp
+++ b/vpd-tool/include/tool_utils.hpp
@@ -767,5 +767,72 @@
}
};
+/**
+ * @brief API to read value from file.
+ *
+ * The API reads the file and returns the read value.
+ *
+ * @param[in] i_filePath - File path.
+ *
+ * @return - Data from file if any in string format, else empty string.
+ *
+ */
+inline std::string readValueFromFile(const std::string& i_filePath)
+{
+ std::string l_valueRead{};
+
+ std::error_code l_ec;
+ if (!std::filesystem::exists(i_filePath, l_ec))
+ {
+ std::string l_message{
+ "filesystem call exists failed for file [" + i_filePath + "]."};
+
+ if (l_ec)
+ {
+ l_message += " Error: " + l_ec.message();
+ }
+
+ std::cerr << l_message << std::endl;
+ return l_valueRead;
+ }
+
+ if (std::filesystem::is_empty(i_filePath, l_ec))
+ {
+ std::cerr << "File[" << i_filePath << "] is empty." << std::endl;
+ return l_valueRead;
+ }
+ else if (l_ec)
+ {
+ std::cerr << "is_empty file system call failed for file[" << i_filePath
+ << "] , error: " << l_ec.message() << std::endl;
+
+ return l_valueRead;
+ }
+
+ std::ifstream l_fileStream;
+ l_fileStream.exceptions(std::ifstream::badbit | std::ifstream::failbit);
+ try
+ {
+ l_fileStream.open(i_filePath, std::ifstream::in);
+
+ std::getline(l_fileStream, l_valueRead);
+
+ l_fileStream.close();
+ return l_valueRead;
+ }
+ catch (const std::ifstream::failure& l_ex)
+ {
+ if (l_fileStream.is_open())
+ {
+ l_fileStream.close();
+ }
+
+ std::cerr << "File read operation failed for path[" << i_filePath
+ << "], error: " << l_ex.what() << std::endl;
+ }
+
+ return l_valueRead;
+}
+
} // namespace utils
} // namespace vpd