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