diff options
author | Loïc Collignon <loic.collignon@iot.bzh> | 2017-07-11 06:36:33 +0200 |
---|---|---|
committer | Loïc Collignon <loic.collignon@iot.bzh> | 2017-07-11 06:36:33 +0200 |
commit | 0455a7401f9f0f9bfad82c5ddf04f7dd70b0b852 (patch) | |
tree | 819bc150cb62c8eb344656086bbb52892f5288b8 /idkey | |
parent | 66b90d26cfd555b2aa5fef67d31e539a70256719 (diff) |
first somewhat working version.
Change-Id: I3101dc6b8add87eccac3bbf177b1320137f72463
Signed-off-by: Loïc Collignon <loic.collignon@iot.bzh>
Diffstat (limited to 'idkey')
-rw-r--r-- | idkey/CMakeLists.txt | 6 | ||||
-rw-r--r-- | idkey/main.c | 127 |
2 files changed, 133 insertions, 0 deletions
diff --git a/idkey/CMakeLists.txt b/idkey/CMakeLists.txt new file mode 100644 index 0000000..dc1f8cb --- /dev/null +++ b/idkey/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.3) +project(idkey) +add_executable(idkey main.c) +install(TARGETS idkey + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib) diff --git a/idkey/main.c b/idkey/main.c new file mode 100644 index 0000000..16b2232 --- /dev/null +++ b/idkey/main.c @@ -0,0 +1,127 @@ +#include <fcntl.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define EXIT_SUCCESS 0 +#define EXIT_CMDLINE 1 +#define EXIT_FILEOPEN 2 +#define EXIT_FILEREAD 3 +#define EXIT_FILEWRITE 4 +#define EXIT_INVALID 5 +#define EXIT_ALLOC 6 + +#define BLOCK_SIZE 4096 + +/// @brief Header of the datas. +typedef struct header_ +{ + char mn[4]; + size_t size; +} header; + +/// @brief Check if the @c v is a valid magick number. +/// @param[in] v magick number. +/// @return 1 if valid, zero otherwise. +int is_valid_nm(const char* v) +{ + return v && v[0] == 'I' && v[1] == 'D' && v[2] == 'K' && v[3] == 'Y'; +} + +/// @brief Close the file descriptor if valid then print a formatted error message then return the specified code. +/// @param[in] fd File descriptor to close. +/// @param[in] code The exit code to return. +/// @param[in] format The message to print. +/// @param[in] ... Values for formatting. +/// @return The exit code provided by @c code. +int close_and_fail(int fd, int code, const char* format, ...) +{ + va_list arglist; + fprintf(stderr, "Error: "); + va_start(arglist, format); + vfprintf(stderr, format, arglist); + va_end(arglist); + fprintf(stderr, "\n"); + return code; +} + +/// @brief Read the device @c devname and print it's data to stdout. +/// @param[in] devname Device's name. +/// @return Exit code, zero if success. +int read_device(const char* devname) +{ + int fd = open(devname, O_RDONLY); + if (fd == -1) return close_and_fail(fd, EXIT_FILEOPEN, "Failed to open '%s'!", devname); + + header h; + ssize_t sz = read(fd, &h, sizeof(header)); + if (sz != sizeof(header)) return close_and_fail(fd, EXIT_FILEREAD, "Failed to read the header!"); + if (!is_valid_nm(h.mn)) return close_and_fail(fd, EXIT_INVALID, "Not a valid identity key!"); + + while(h.size) + { + char datas[BLOCK_SIZE + 1]; + memset(datas, BLOCK_SIZE +1, 0); + size_t count = BLOCK_SIZE > h.size ? h.size : BLOCK_SIZE; + + sz = read(fd, datas, count); + + if (sz != count) close_and_fail(fd, EXIT_FILEREAD, "Failed to read a data block!"); + h.size = (h.size - count); + + printf(datas); + } + printf("\n"); + close(fd); + return EXIT_SUCCESS; +} + +/// @brief Write the specified data to the specified device. +/// @param[in] devname Name of the device. +/// @param[in] datas Datas to write. +/// @return Exit code, zero if success, non-zero otherwise. +int write_device(const char* devname, const char* datas) +{ + header h = { + .mn = {'I', 'D', 'K', 'Y'}, + .size = strlen(datas) + }; + if (h.size < 1) return close_and_fail(-1, EXIT_CMDLINE, "No data to write!"); + + int fd = open(devname, O_WRONLY); + if (fd == -1) return close_and_fail(fd, EXIT_FILEOPEN, "Failed to open device '%s'!", devname); + if (write(fd, &h, sizeof(header)) != sizeof(header)) return close_and_fail(fd, EXIT_FILEWRITE, "Failed to write the header!"); + if (write(fd, datas, h.size) != h.size) return close_and_fail(fd, EXIT_FILEWRITE, "Failed to write datas!"); + + close(fd); + return EXIT_SUCCESS; +} + +/// @brief Entry point. +/// @param[in] argc Number of arguments in @c argv. +/// @param[in] argv Arguments array. +/// @return Exit code, zero if success, non-zero otherwise. +int main(int argc, char** argv) +{ + switch(argc) + { + case 0: + case 1: + fprintf(stderr, "ERROR: too few arguments!\n"); + return EXIT_CMDLINE; + + case 2: // Read the device + return read_device(argv[1]); + + case 3: // Write the device + return write_device(argv[1], argv[2]); + + default: + fprintf(stderr, "ERROR: too many arguments!\n"); + return EXIT_CMDLINE; + } +} + |