Logo Search packages:      
Sourcecode: papaya version File versions  Download package

MudLog.cpp

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>



#ifdef WIN32

#include <direct.h>

#else

#include <unistd.h>

#endif


#include "MudLog.h"
#include "Win32PluginAPI.cpp"



static MudLog * ml;

#define MAJOR "1"
#define MINOR "1"

extern "C" G_MODULE_EXPORT char * plugin_query_name() {
  return "MudLog";
}

extern "C" G_MODULE_EXPORT char * plugin_query_description() {
  return _("Logs data from connections to separate files.");
}

extern "C" G_MODULE_EXPORT char * plugin_query_major() {
  return MAJOR;
}

extern "C" G_MODULE_EXPORT char * plugin_query_minor() {
  return MINOR;
}

extern "C" G_MODULE_EXPORT void plugin_init(plugin_address_table_t * pat) {
  plugin_address_table_init(pat);

  ml = new MudLog();
}

extern "C" G_MODULE_EXPORT void plugin_cleanup(void) {
  delete ml;
}

MudLog::MudLog() {
  version = 1.0;
  name = strdup("MudLog");

  char path[1024];


#ifdef WIN32

  snprintf(path, 1024, "%s/logs", get_prefix());

#else

  char * home = getenv("HOME");

  if (!home)

    snprintf(path, 1024, "logs");

  else

    snprintf(path, 1024, "%s/.papaya/logs", home);

#endif



#ifdef WIN32

  if (mkdir(path) == - 1) {

#else
  if (mkdir(path, 0700) == -1) {
#endif

      if (errno != EEXIST)
    perror("mkdir");
  }


  register_plugin(this, VERSION);

  plugin_handler_add_input_filter(get_plugin_handler(), this);
  plugin_handler_add_output_filter(get_plugin_handler(), this);

}

MudLog::~MudLog() {

  MudlogDataList::iterator i_next;
  for (MudlogDataList::iterator i = mudlogList.begin(); i != mudlogList.end(); i = i_next) {
    i_next = i;
    i_next++;

    fclose((*i)->fp);
    remove_data((*i));
    free((*i));
  }

  unregister_plugin(this);

}

void MudLog::input(Connection * c, char * in) {
  write(c, in, 1);
}


void MudLog::output(Connection * c, char * in) {
  write(c, in, 0);
}

void MudLog::write(Connection * conn, char * in, bool myInput) {

  struct mudlogData * data = find_data(conn);
  if (!data)
    data = createLogFile(conn);
    
  if (!data || !data->fp)
    return;
    
  if (myInput)
    fprintf(data->fp, "INPUT: %s\n", in);
  else
    fprintf(data->fp, "OUTPUT: %s\n", in);

  fflush(data->fp);

  return;
}

struct mudlogData * MudLog::createLogFile(Connection * c) {

  char buf[2048], time_buf[1024];
  char * home = getenv("HOME");
  time_t t;
  struct tm * tm_t;

  // Create the folder for the connection.  We always try to do this.
#ifdef WIN32
  snprintf(buf, 2048, "%s/logs/%s", get_prefix(), connection_get_name(c));
#else
  snprintf(buf, 2048, "%s/.papaya/logs/%s", home, connection_get_name(c));
#endif

#ifdef WIN32
  if (mkdir(buf) == - 1) {
#else
  if (mkdir(buf, 0700) == -1) {
#endif

      if (errno != EEXIST)
      perror("mkdir");
  }

  struct mudlogData * data = (struct mudlogData *)malloc(sizeof(struct mudlogData));

  // Figure out the timestamp for the log file.
  time(&t);
  tm_t = gmtime(&t);
  strftime(time_buf, 1024, "%d-%b-%Y-%H.%M.%S", tm_t);

#ifdef WIN32
  snprintf(buf, 2048, "%s/logs/%s/%s", get_prefix(), connection_get_name(c), time_buf);
#else
  snprintf(buf, 2048, "%s/.papaya/logs/%s/%s", home, connection_get_name(c), time_buf);
#endif

  // Open the file in append mode.
  data->fp = fopen(buf, "a");
  if (!data->fp) {
    perror("fopen");
    return NULL;
  }

  data->connection = c;
  add_data(data);
  return data;
}

void MudLog::closeLogFile(struct mudlogData * data) {
  fclose(data->fp);
  remove_data(data);
  free(data);
}

void MudLog::onEvent(Event * e, Connection * c) {
  
  if (event_get_type(e) == EvConnect) {
    createLogFile(c);
    return;
  }

  if (event_get_type(e) == EvDisconnect) {
    struct mudlogData * data = find_data(c);
    if (!data)
      return;

    closeLogFile(data);
    return;
  }

}

static int MudLogCmp(struct mudlogData * l1, struct mudlogData *l2) {
  return (l1 < l2);
}

void MudLog::remove_data(struct mudlogData * data) {
  MudlogDataList::iterator i = std::lower_bound(mudlogList.begin(),
                                               mudlogList.end(),
                                               data,
                                               MudLogCmp);
  if (i == mudlogList.end() || (*i) != data)
    return;

  mudlogList.erase(i);
}

struct mudlogData * MudLog::find_data(Connection * connection) {
  for (MudlogDataList::iterator i = mudlogList.begin(); i != mudlogList.end(); i++)
    if ((*i)->connection == connection)
      return (*i);
  return NULL;
}

void MudLog::add_data(struct mudlogData * data) {
    MudlogDataList::iterator i = std::lower_bound(mudlogList.begin(),
                                                 mudlogList.end(),
                                                 data,
                                                 MudLogCmp);
    
    mudlogList.insert(i, data);
}

Generated by  Doxygen 1.6.0   Back to index