Add boot count into motherboard eeprom and clear command

The bmc boot count which was previously stored into
the file /etc/conf/bios.cnt, is now stored into the
motherboard FRU eeprom/sys/bus/i2c/devices/4-0050/eeprom
starting from offset of 4 bytes from 0x1000.

The reading and writing to the FRU eeprom is handled
by using the helper functions.

Added the new IPMI clear command which sets the eeprom
to the default value of ff ff ff ff.

Use of 4 bytes from 0x1000 location to check
if the boot counter is at the max value or at the default
value which server as a header to the boot count.

All corner cases such as invalid command and invalid
command length have been added

Tested:
ipmitool raw 0x34 0x71 0x00 - read current boot count.
ipmitool raw 0x34 0x71 0x01 - increment the boot count by 1.
ipmitool raw 0x34 0x71 0x02 - set the boot_count to all ff which
is its default value of eeprom location where the boot count is
stored.
ipmitool raw 0x34 0x71 0x03 byte1 byte2 byte3 byte4 - set the
boot count to desired value provided by the request parameter.
Reboot,powercyle,flashing bmc - performed to see if the value
retains.

Signed-off-by: Avenash Asai Thambi <avenash.thambi@fii-usa.com>
Change-Id: I99dd5e6ba1d943e558e984d948bd63552cd5278f
diff --git a/src/file_handling.cpp b/src/file_handling.cpp
new file mode 100644
index 0000000..529e9f2
--- /dev/null
+++ b/src/file_handling.cpp
@@ -0,0 +1,59 @@
+#include <iostream>
+#include <fcntl.h>
+#include <unistd.h>
+
+using namespace std::string_literals;
+std::system_error errnoException(const std::string& message)
+{
+    return std::system_error(errno, std::generic_category(), message);
+}
+
+int sysopen(const std::string& path)
+{
+    int fd_ = open(path.c_str(), O_RDWR);
+    if (fd_ < 0)
+    {
+        throw errnoException("Error opening file "s + path);
+    }
+    return fd_;
+}
+
+void sysclose(int fd_)
+{
+    close(fd_);
+}
+
+void lseeker(int fd_, size_t offset)
+{
+    if (lseek(fd_, offset, SEEK_SET) < 0)
+    {
+        throw errnoException("Cannot lseek to pos "s + std::to_string(offset));
+    }
+}
+
+void readBin(int fd_, size_t offset, void *ptr, size_t size)
+{
+    lseeker(fd_, offset);
+    size_t ret = read(fd_, ptr, size);
+    if(ret < 0 )
+    {
+        throw errnoException("Error reading from file"s);
+    }
+}
+
+void writeBin(int fd_, size_t offset, void *ptr, size_t size)
+{
+    lseeker(fd_, offset);
+    ssize_t ret;
+    ret = write(fd_, ptr, size);
+    if (ret < 0)
+    {
+        throw errnoException("Error writing to file"s);
+    }
+    if (static_cast<size_t>(ret) != size)
+    {
+        throw std::runtime_error(
+                "Tried to send data size "s + std::to_string(size) +
+                " but could only send "s + std::to_string(ret));
+    }
+}