Implementation of the Reader entity in the Secure Logger example

reader.c

#include "secure_logger_common_secure.h"

#include "secure_logger/Reader.edl.h"

#include <rtl/string.h>

#include <rtl/stdio.h>

static const char EntityName[] = "Reader";

static int FastForwardLogToStartIndex(

const FILE *fd,

const unsigned startIndex,

char *buffer,

unsigned *curIndex)

{

if (fd == RTL_NULL)

{

fprintf(

stderr,

"[%s]: Error: file descriptor is null!\n",

EntityName);

return EXIT_FAILURE;

}

if (buffer == RTL_NULL)

{

fprintf(

stderr,

"[%s]: Error: buffer pointer is null!\n",

EntityName);

return EXIT_FAILURE;

}

if (curIndex == RTL_NULL)

{

fprintf(

stderr,

"[%s]: Error: current index pointer is null!\n",

EntityName);

return EXIT_FAILURE;

}

while (*curIndex != startIndex)

{

if (feof(fd) || !fgets(buffer, Read_ReadFromLog_res_logRes_elem_size, fd))

{

return EXIT_FAILURE;

}

(*curIndex)++;

}

return EXIT_SUCCESS;

}

/* Implementation of the Read method. */

static nk_err_t ReadImpl(

struct Read *self,

const Read_ReadFromLog_req *req,

const struct nk_arena* reqArena,

Read_ReadFromLog_res* res,

struct nk_arena* resArena)

{

FILE *fd = RTL_NULL;

int msgCount = req->logReq.endIndex - req->logReq.startIndex + 1;

nk_ptr_t *paths = RTL_NULL;

unsigned counter = 0;

unsigned curIndex = 0;

char buffer[Read_ReadFromLog_res_logRes_size];

if (msgCount < 0)

{

fprintf(

stderr,

"[%s]: Error: wrong message range to read!\n",

EntityName);

return NK_EINVAL;

}

if (msgCount > Read_ReadFromLog_res_logRes_size)

{

fprintf(

stderr,

"[%s]: Error: message count is bigger than expected!\n",

EntityName);

return NK_EINVAL;

}

if ((fd = fopen(logPath, "r")) == RTL_NULL)

{

fprintf(stderr, "[%s]: Error: can`t open log file!\n", EntityName);

return NK_EOK;

}

setvbuf(fd, NULL, _IOLBF, 0);

if (FastForwardLogToStartIndex(

fd, req->logReq.startIndex, buffer, &curIndex))

{

fclose(fd);

return NK_EOK;

}

paths = nk_arena_alloc(nk_ptr_t, resArena, &res->logRes, msgCount);

if (paths == RTL_NULL)

{

fprintf(

stderr,

"[%s]: Error: can`t allocate memory in arena!\n",

EntityName);

fclose(fd);

return NK_ENOMEM;

}

while (fgets(buffer, Read_ReadFromLog_res_logRes_elem_size, fd))

{

unsigned stringLength = rtl_strnlen(

buffer, Read_ReadFromLog_res_logRes_size);

int penultStringIndex = stringLength - 1;

if (penultStringIndex < 0)

{

fprintf(

stderr,

"[%s]: Error: index of penult character is negative!\n",

EntityName);

fclose(fd);

return NK_EINVAL;

}

if (buffer[penultStringIndex] == '\n')

{

buffer[penultStringIndex] = '\0';

nk_char_t *str = nk_arena_alloc(

nk_char_t,

resArena,

&paths[counter],

stringLength + 1);

if (str == RTL_NULL)

{

fprintf(

stderr,

"[%s]: Error: can`t allocate memory in arena!\n",

EntityName);

fclose(fd);

return NK_ENOMEM;

}

rtl_snprintf(str, (stringLength + 1), "%s", buffer);

}

if (curIndex == req->logReq.endIndex)

{

break;

}

curIndex++;

counter++;

}

fclose(fd);

return NK_EOK;

}

/* Implementation of the GetLastIndex method. */

static nk_err_t GetLastIndexImpl(

struct GetLastIndex *self,

const GetLastIndex_GetLogLastIndex_req *req,

const struct nk_arena* reqArena,

GetLastIndex_GetLogLastIndex_res* res,

struct nk_arena* resArena)

{

FILE *fd = RTL_NULL;

if ((fd = fopen(logPath, "r")))

{

setvbuf(fd, NULL, _IOLBF, 0);

unsigned counter = 0;

char buffer[Read_ReadFromLog_res_logRes_elem_size];

fgets(buffer, Read_ReadFromLog_res_logRes_elem_size, fd);

while (fgets(buffer, Read_ReadFromLog_res_logRes_elem_size, fd))

{

if (buffer[rtl_strlen(buffer) - 1] == '\n')

{

counter++;

}

else

{

break;

}

}

res->logLastIndex = counter;

fclose(fd);

}

else

{

fprintf(stderr, "[%s]: Error: can`t open log file!\n", EntityName);

}

return NK_EOK;

}

static struct Read *CreateIReadImpl()

{

/* Structure with implementation of Read interface methods. */

static const struct Read_ops Ops =

{

.ReadFromLog = ReadImpl

};

static Read obj =

{

.ops = &Ops

};

return &obj;

}

static struct GetLastIndex *CreateIGetLastIndexImpl()

{

/* Structure with implementation of GetLastIndex interface methods. */

static const struct GetLastIndex_ops Ops =

{

.GetLogLastIndex = GetLastIndexImpl

};

static GetLastIndex obj =

{

.ops = &Ops

};

return &obj;

}

/* Entry point in the Reader entity. */

int main(int argc, const char *argv[])

{

ServiceId iid;

NkKosTransport transport;

/**

* Gets the server IPC handle for the connection named

* "reader_connection".

*/

Handle handleClients = ServiceLocatorRegister(

"reader_connection", NULL, 0, &iid);

if (handleClients == INVALID_HANDLE)

{

fprintf(

stderr,

"[%s]: Error: can`t establish static IPC connection!\n",

EntityName);

return EXIT_FAILURE;

}

/* Initializes transport to clients. */

NkKosTransport_Init(&transport, handleClients, NK_NULL, 0);

/* Prepares the response structures:fixed part. */

Reader_entity_req req;

/* Prepares response structures:fixed part and arena. */

Reader_entity_res res;

char resBuffer[Reader_entity_res_arena_size];

struct nk_arena resArena = NK_ARENA_INITIALIZER(

resBuffer, resBuffer + sizeof(resBuffer));

/* Initializes the Reader entity dispatcher. */

Reader_entity entity;

Reader_entity_init(

&entity, CreateIReadImpl(), CreateIGetLastIndexImpl());

/* Main cycle: requests execution. */

while (true)

{

/* Reset buffers with request and response. */

nk_req_reset(&req);

nk_arena_reset(&resArena);

if (nk_transport_recv(&transport.base, &req.base_, RTL_NULL) == NK_EOK)

{

Reader_entity_dispatch(

&entity, &req.base_, RTL_NULL, &res.base_, &resArena);

}

else

{

fprintf(stderr, "[%s]: nk_transport_recv error\n", EntityName);

}

if (nk_transport_reply(

&transport.base, &res.base_, &resArena) != NK_EOK)

{

fprintf(stderr, "[%s]: nk_transport_reply error\n", EntityName);

}

}

return EXIT_SUCCESS;

}

Page top