Implementation of the LogViewer entity in the Secure Logger example

log_viewer.c

#include <time.h>

#include "secure_logger_common.h"

/* Reader interfaces description. */

#include <secure_logger/Read.idl.h>

#include <secure_logger/GetLastIndex.idl.h>

/**

* START_INDEX is the index of a message in the log file starting from

* which the entire log will be displayed.

*/

#define START_INDEX 0

#define READ_DELAY_SEC 10

#define READ_DELAY_NANOSEC 0

const struct timespec ReadDelay = {

.tv_sec = READ_DELAY_SEC,

.tv_nsec = READ_DELAY_NANOSEC

};

static const char EntityName[] = "LogViewer";

typedef struct {

struct Read_proxy *proxy;

struct GetLastIndex_proxy *getProxy;

Read_ReadFromLog_req *req;

Read_ReadFromLog_res *res;

struct nk_arena *reqArena;

struct nk_arena *resArena;

GetLastIndex_GetLogLastIndex_req *reqGet;

GetLastIndex_GetLogLastIndex_res *resGet;

struct nk_arena *reqArenaGet;

struct nk_arena *resArenaGet;

} TransportDescriptor;

#define DESCR_INIT( \

proxyIn, \

getProxyIn, \

reqIn, \

resIn, \

reqArenaIn, \

resArenaIn, \

reqGetIn, \

resGetIn, \

reqArenaGetIn, \

resArenaGetIn) \

{ \

.proxy = proxyIn, \

.getProxy = getProxyIn, \

.req = reqIn, \

.res = resIn, \

.reqArena = reqArenaIn, \

.resArena = resArenaIn, \

.reqGet = reqGetIn, \

.resGet = resGetIn, \

.reqArenaGet = reqArenaGetIn, \

.resArenaGet = resArenaGetIn \

}

static void DoLogRequest(

TransportDescriptor *desc, unsigned *messageCount, unsigned *startIndex)

{

nk_req_reset(desc->req);

nk_arena_reset(desc->resArena);

desc->req->logReq.startIndex = *startIndex;

if (GetLastIndex_GetLogLastIndex(

&desc->getProxy->base,

desc->reqGet,

desc->reqArenaGet,

desc->resGet,

desc->resArenaGet) != NK_EOK)

{

fprintf(

stderr,

"[%s]: Error: can`t get last index of message in log!\n",

EntityName);

return;

}

/**

* If START_INDEX is lower than the index of the last message in the log,

* nothing will be displayed.

*/

if (desc->resGet->logLastIndex < START_INDEX)

{

return;

}

desc->req->logReq.endIndex = desc->resGet->logLastIndex;

*messageCount = desc->resGet->logLastIndex - START_INDEX + 1;

*startIndex = desc->req->logReq.endIndex + 1;

if (Read_ReadFromLog(

&desc->proxy->base,

desc->req,

desc->reqArena,

desc->res,

desc->resArena) == NK_EOK)

{

fprintf(stderr, "[%s]: Read from log:\n", EntityName);

nk_uint32_t msgNum = 0;

nk_uint32_t msgLen = 0;

nk_ptr_t *messages = nk_arena_get(

nk_ptr_t, desc->resArena, &desc->res->logRes, &msgNum);

for(int i = 0; i < msgNum; i++)

{

nk_char_t *str = nk_arena_get(

nk_char_t, desc->resArena, &messages[i], &msgLen);

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

}

}

}

int main(int argc, char **argv)

{

unsigned messageCounter = 0;

NkKosTransport transport;

struct Read_proxy proxy;

struct GetLastIndex_proxy getProxy;

unsigned startIndex = START_INDEX;

setvbuf(stderr, NULL, _IOLBF, 0);

/**

* Gets the client IPC handle for the connection named

* "reader_connection".

*/

Handle handle = ServiceLocatorConnect("reader_connection");

if (handle == INVALID_HANDLE)

{

fprintf(

stderr,

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

EntityName);

return EXIT_FAILURE;

}

/* Initializes IPC transport for the connection with the Reader entity. */

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

/* Gets the runtime implementation ID (RIID) of the interface secure_logger.Logger.read. */

nk_iid_t riid = ServiceLocatorGetRiid(

handle, "secure_logger.Reader.read");

if (riid == INVALID_RIID)

{

fprintf(

stderr,

"[%s]: Error: can`t get runtime implementation ID (RIID) of "

"interface secure_logger.Logger.read!\n",

EntityName);

return EXIT_FAILURE;

}

/**

* Initializes the proxy object. Every method of the proxy object will be

* implemented as a request to the server.

*/

Read_proxy_init(&proxy, &transport.base, riid);

/* Structures of the request and response. */

Read_ReadFromLog_req req;

Read_ReadFromLog_res res;

char resBuffer[Read_ReadFromLog_res_arena_size];

struct nk_arena resArena = NK_ARENA_INITIALIZER(

resBuffer, resBuffer + sizeof(resBuffer));

/* Gets the runtime implementation ID (RIID) of the interface secure_logger.Logger.getLastIndex. */

nk_iid_t riidGet = ServiceLocatorGetRiid(

handle, "secure_logger.Reader.getLastIndex");

if (riidGet == INVALID_RIID)

{

fprintf(

stderr,

"[%s]: Error: can`t get runtime implementation ID (RIID) of "

"interface secure_logger.Logger.getLastIndex!\n",

EntityName);

return EXIT_FAILURE;

}

GetLastIndex_proxy_init(&getProxy, &transport.base, riidGet);

/* Structures of the request and response. */

GetLastIndex_GetLogLastIndex_req reqGet;

GetLastIndex_GetLogLastIndex_res resGet;

TransportDescriptor desc = DESCR_INIT(

&proxy,

&getProxy,

&req,

&res,

RTL_NULL,

&resArena,

&reqGet,

&resGet,

RTL_NULL,

RTL_NULL);

/**

* The LogViewer entity must not be able to write to the log. The code below

* will not get the handle of "logger_connection".

*/

if (ServiceLocatorConnect("logger_connection") == INVALID_HANDLE)

{

fprintf(

stderr,

"[%s]: Expected behavior: can not open connection with Logger\n",

EntityName);

}

else

{

fprintf(stderr,

"[%s]: Error: something goes wrong! Somebody could get access"

" to write in log file!\n",

EntityName);

}

do

{

nanosleep(&ReadDelay, NULL);

DoLogRequest(&desc, &messageCounter, &startIndex);

}

while (messageCounter != MAX_MESSAGE_COUNT - START_INDEX);

fprintf(stderr, "[%s]: Stop read from log.\n", EntityName);

return EXIT_SUCCESS;

}

Page top