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

copyover.cpp

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#include <pthread.h>
#else
#include <windows.h>

#include <process.h>
#endif
#include <signal.h>

#include "Connection.h"
#include "mudclient.h"
#include "MUDSelector.h"
#include "BaseWindow.h"

#include "CommandInterpreter.h"
#include "Prefs.h"

extern CommandInterpreter * commandInterpreter;
extern MUDSelector * mud_selector;
extern BaseWindow * mainWindow;

static bool in_crashover = false;

void crashover(int i) {

  printf (_("Papaya has crashed and will now attempt to restart."));
  printf(CRLF);
  in_crashover = true;
  copyover();
  printf (_("Papaya was unable to recover from the crash.  You will need to restart it manually."));
  printf(CRLF);
}

int read_socket_timeout(gpointer);

void copyover() {

  FILE * fp;
  char * args[4];

  // Disable the signal handler.
  signal(SIGSEGV, SIG_DFL);

  Connection * tmp;

  // Send the compression off command to each compressed MUD.
  for (tmp = first_connection; tmp; tmp = tmp->getNext()) {
    if (tmp->getSocket()->compression()) {
      commandInterpreter->interpret(tmp, tmp->queryPreferences()->getPreference("CompressionOffCommand"));
      tmp->getSocket()->write("   \n\r");
    }
  }

  // Sleep for a second to give MUDs a chance to process command and turn
  // off compression.
#ifdef WIN32
  Sleep(1000);
#else
  sleep(1);
#endif



  if (!in_crashover) {
    // Check for input on all connections and process as per normal.
    for (tmp = first_connection; tmp; tmp = tmp->getNext()) {
      read_socket_timeout((gpointer)tmp);
    }

    while (gtk_events_pending())
      gtk_main_iteration();
  }    

  fp = openFile(".mudclient-copyover", NULL, "wb");
  if (!fp) {
    g_print(_("Can't copyover.  Manually restart the client.\n"));
    return;
  }

  /**
   * Need the following information about each connection:
   *
   *   o host
   *   o port
   *   o name
   *
   * We don't need to know if we're connected or not, since we're going
   * to drop any inprogress connections.
   */

  Connection * tmp_next;
  for (tmp = first_connection; tmp; tmp = tmp_next) {
    tmp_next = tmp->getNext();

    fprintf(fp, "%d %s %d %d %d %s\n", tmp->getSocket()->fd, tmp->getHost(), tmp->getPort(), tmp->getSocket()->compression(), tmp->getSocket()->getCookie(), tmp->getMUD()->getName());
    // fprintf(fp, "%d %s %d %s\n", tmp->getSocket()->fd, tmp->getHost(), tmp->getPort(), tmp->getName());
  }

  fclose(fp);

  // This should (ungracefully) kill all the other threads.
#ifndef WIN32
  // pthread_exit kills the current thread. (doh)
  //  pthread_exit(&retval);
#endif

  /* Now exec the new binary. */
  char buf[1024];
#ifdef WIN32
  snprintf(buf, 1024, "%s\\bin\\papaya.exe", getPrefix());
#else
  snprintf(buf, 1024, "%s/bin/papaya", getPrefix());
#endif

  args[0] = strdup(buf);
  args[1] = strdup("copyover");
  args[2] = strdup("--disable-crash-dialog");
  args[3] = NULL;

  execvp(buf, args);

  perror("copyover");
  exit(1);
}

void copyover_recover() {

  /**
   * By this point we should have the entire app up, and about to enter
   * gtk_main.
   */

  FILE * fp = NULL;
  char host[1024];
  char name[1024];
  int desc, port;
  int compress;
  int cookie;

  in_crashover = false;

  fp = openFile(".mudclient-copyover", NULL, "rb");
  if (!fp) {
    printf(_("Can't recover client's previous state."));
    printf(CRLF);
    return;
  }

  while (1) {
    if (fscanf(fp, "%d %s %d %d %d %[^\n]\n", &desc, host, &port, &compress, &cookie, name) != 6) {
      fclose(fp);
      return;
    }

    MUD * m = mud_selector->findMUD(name);
    Connection * c;
    if (!m) {
      m = new MUD;
      m->setHostname(host);
      m->setPort(port);
      m->setName(name);
    }

    c = new Connection(desc, m, compress, cookie);
    mainWindow->addConnection(c);
    c->getVT()->use();
    c->getVT()->focus();
  }

  fclose(fp);

}

Generated by  Doxygen 1.6.0   Back to index