/*
  ns.c
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/unistd.h>
#include "iiimcfint.h"
#include <EIMIL.h>

static IIIMF_status iiimcf_read_ns(IIIMCF_handle_rec *, int, int);
static IIIMF_status iiimcf_send_read_ns_reply(IIIMCF_handle_rec *, int, int, int, void *);

void
check_pathname(
    char *p
)   
{
    char *q;
    int index = 0;
    
    while (*p) {
	if ((q = (strstr(p, "../")))) {
	    index = p - q;
	    if (index < 0)
		index = -index;
	    strcpy(p+index, p+index+3);
	} else if ((q = (strstr(p, "//")))) {
	    index = p - q;
	    if (index < 0)
		index = -index;
	    strcpy(p+index, p+index+1);
	} else if ((q = (strstr(p, "./")))) {
	    index = p - q;
	    if (index < 0)
		index = -index;
	    strcpy(p+index, p+index+2);
	} else {
	    break ;
	}
    }
    return;
}

IIIMF_status
iiimcf_process_ns(
    IIIMCF_handle_rec *ph,
    IIIMP_message *pmes,
    int ic_id
)
{
    IIIMF_status st = IIIMF_STATUS_SUCCESS;
    int i, ns_count;

    IIIMP_im_read_ns_v *pimrn = &pmes->v.im_read_ns;

    ASSERT(pmes->opcode == IM_READ_NS);

    ns_count = ph->num_of_ns;

    if (!ns_count) {
	ph->pns = (IIIMCF_ns *) malloc(10 * sizeof(IIIMCF_ns));
    } else if (ns_count > 10) {
	ph->pns = (IIIMCF_ns *) realloc((IIIMCF_ns *)ph->pns, (ns_count + 1) * sizeof(IIIMCF_ns));
    }
    if (!ph->pns) return IIIMF_STATUS_MALLOC;

    if (ph->num_of_ns > 0) {
	for (i=0; i<ph->num_of_ns; i++) {
	    if (ph->pns[i].listener_id == pimrn->listener_id) {
		st = iiimcf_read_ns(ph, ic_id, i);
		return st;
	    }
	}
    } 

    ph->pns[ns_count].listener_id = pimrn->listener_id;

    ph->pns[ns_count].filename = (char *) malloc(pimrn->filename->len * sizeof(char));
    for(i=0; i<pimrn->filename->len; i++) {
	ph->pns[ns_count].filename[i] = pimrn->filename->ptr[i];
    }
    ph->pns[ns_count].filename[i] = '\0';
    st = iiimcf_read_ns(ph, ic_id, ns_count);
    return st;
}

static IIIMF_status
iiimcf_read_ns(
    IIIMCF_handle_rec *ph,
    int ic_id,
    int index
)
{
    IIIMF_status st = IIIMF_STATUS_SUCCESS;
    int fd;
    void *ptr;
    struct stat buf;
    char path[PATH_MAX];

    snprintf(path, sizeof(path), "%s/%s/%s","/export/home/sriram/", ".iiim/ns", ph->pns[index].filename);
    check_pathname(path);
    ph->pns[index].nsc_fp = fopen(path, "rw");
    if (!ph->pns[index].nsc_fp) {
	iiimcf_send_read_ns_reply(ph, ic_id, ph->pns[index].listener_id, 0, (char *)NULL);
	return IIIMF_STATUS_FAIL; 
    }
    fd = fileno((FILE *)ph->pns[index].nsc_fp);
    if (fstat(fd, &buf) < 0) {
	iiimcf_send_read_ns_reply(ph, ic_id, ph->pns[index].listener_id, 0, (char *)NULL);
	fclose(ph->pns[index].nsc_fp);
	return IIIMF_STATUS_FAIL; 
    }
    ptr = (char *) calloc(buf.st_size, sizeof(char));
    if ((fread(ptr, buf.st_size, 1, ph->pns[index].nsc_fp)) != 1) {
	iiimcf_send_read_ns_reply(ph, ic_id, ph->pns[index].listener_id, 0, (char *)NULL);
	fclose(ph->pns[index].nsc_fp);
	free(ptr);
	return IIIMF_STATUS_FAIL; 
    }
    st = iiimcf_send_read_ns_reply(ph, ic_id, ph->pns[index].listener_id, buf.st_size, ptr);
    fclose(ph->pns[index].nsc_fp);
    free(ptr);
    return st;
}

static IIIMF_status
iiimcf_send_read_ns_reply(
    IIIMCF_handle_rec *ph,
    int ic_id,
    int l_id,
    int size,
    void *object
)
{
    IIIMF_status st = IIIMF_STATUS_SUCCESS;
    IIIMP_message *preply;

    preply = iiimp_read_ns_reply_new(ph->data_s, ph->im_id, ic_id, l_id, size, object);
    st = iiimcf_send_message(ph, preply, 1);
    return st;
}

/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
