Beispiel #1
0
const char* WStatus::GetLogFileName(int nDaysAgo) const {
  DCHECK_GE(nDaysAgo, 0);
  switch (nDaysAgo) {
  case 0:
  {
    static char s[81]; // logname
    std::string todays_log = GetSysopLogFileName(daten_to_date(time(nullptr)));
    strcpy(s, todays_log.c_str());
    return s;
  }
  case 1:
    return m_pStatusRecord->log1;
  case 2:
    return m_pStatusRecord->log2;
  default:
    return m_pStatusRecord->log1;
  }
}
Beispiel #2
0
void catsl() {
  char szInstanceBaseName[MAX_PATH];
  char szInstanceLogFileName[MAX_PATH];

  GetTemporaryInstanceLogFileName(szInstanceBaseName);
  sprintf(szInstanceLogFileName, "%s%s", syscfg.gfilesdir, szInstanceBaseName);

  if (WFile::Exists(szInstanceLogFileName)) {
    char szLogFileBaseName[MAX_PATH];

    GetSysopLogFileName(date(), szLogFileBaseName);
    WFile wholeLogFile(syscfg.gfilesdir, szLogFileBaseName);

    char* pLogBuffer = static_cast<char *>(BbsAllocA(CAT_BUFSIZE));
    if (pLogBuffer) {
      if (wholeLogFile.Open(WFile::modeReadWrite | WFile::modeBinary | WFile::modeCreateFile, WFile::shareUnknown,
                            WFile::permReadWrite)) {
        wholeLogFile.Seek(0, WFile::seekBegin);
        wholeLogFile.Seek(0, WFile::seekEnd);

        WFile instLogFile(szInstanceLogFileName);
        if (instLogFile.Open(WFile::modeReadOnly | WFile::modeBinary)) {
          int nNumRead = 0;
          do {
            nNumRead = instLogFile.Read(pLogBuffer, CAT_BUFSIZE);
            if (nNumRead > 0) {
              wholeLogFile.Write(pLogBuffer, nNumRead);
            }
          } while (nNumRead == CAT_BUFSIZE);

          instLogFile.Close();
          instLogFile.Delete();
        }
        wholeLogFile.Close();
      }
      free(pLogBuffer);
    }
  }
}
Beispiel #3
0
bool WStatus::NewDay() {
  m_pStatusRecord->callstoday = 0;
  m_pStatusRecord->msgposttoday = 0;
  m_pStatusRecord->localposts = 0;
  m_pStatusRecord->emailtoday = 0;
  m_pStatusRecord->fbacktoday = 0;
  m_pStatusRecord->uptoday = 0;
  m_pStatusRecord->activetoday = 0;
  m_pStatusRecord->days++;

  // Need to verify the dates aren't trashed otherwise we can crash here.
  ValidateAndFixDates();

  strcpy(m_pStatusRecord->date3, m_pStatusRecord->date2);
  strcpy(m_pStatusRecord->date2, m_pStatusRecord->date1);
  const string d = daten_to_date(time(nullptr));
  strcpy(m_pStatusRecord->date1, d.c_str());
  strcpy(m_pStatusRecord->log2, m_pStatusRecord->log1);

  const string log = GetSysopLogFileName(GetLastDate(1));
  strcpy(m_pStatusRecord->log1, log.c_str());
  return true;
}
Beispiel #4
0
namespace wfc {

namespace {
static CursesWindow* CreateBoxedWindow(const std::string& title, int nlines, int ncols, int y, int x) {
  unique_ptr<CursesWindow> window(new CursesWindow(out->window(), out->color_scheme(), nlines, ncols, y, x));
  window->SetColor(SchemeId::WINDOW_BOX);
  window->Box(0, 0);
  window->SetTitle(title);
  window->SetColor(SchemeId::WINDOW_TEXT);
  return window.release();
}
}

auto noop = [](){};

static void wfc_command(int instance_location_id, std::function<void()> f, 
    std::function<void()> f2 = noop, std::function<void()> f3 = noop, std::function<void()> f4 = noop) {
  session()->reset_local_io(new CursesLocalIO(out->window()->GetMaxY()));

  wfc_cls();
  write_inst(instance_location_id, 0, INST_FLAGS_NONE);
  f();
  f2();
  f3();
  f4();
  write_inst(INST_LOC_WFC, 0, INST_FLAGS_NONE);
}

auto send_email_f = []() {
  session()->usernum = 1;
  bout << "|#1Send Email:";
  send_email();
  session()->WriteCurrentUser(1);
};

auto view_sysop_log_f = []() {
  unique_ptr<WStatus> pStatus(session()->status_manager()->GetStatus());
  const string sysop_log_file = GetSysopLogFileName(date());
  print_local_file(sysop_log_file);
};

auto view_yesterday_sysop_log_f = []() {
  unique_ptr<WStatus> pStatus(session()->status_manager()->GetStatus());
  print_local_file(pStatus->GetLogFileName(1));
};

auto read_mail_f = []() {
  session()->usernum = 1;
  readmail(0);
  session()->WriteCurrentUser(1);
};

auto getkey_f = []() { getkey(); };

ControlCenter::ControlCenter() {
  const string title = StringPrintf("WWIV %s%s Server.", wwiv_version, beta_version);
  CursesIO::Init(title);
  // take ownership of out.
  out_scope_.reset(out);
  session()->SetWfcStatus(0);
}

ControlCenter::~ControlCenter() {}

static void DrawCommands(CursesWindow* commands) {
  commands->SetColor(SchemeId::WINDOW_TEXT);
  commands->PutsXY(1, 1, "[B]oardEdit [C]hainEdit");
  commands->PutsXY(1, 2, "[D]irEdit [E]mail [G]-FileEdit");
  commands->PutsXY(1, 3, "[I]nit Voting Data  [J] ConfEdit");
  commands->PutsXY(1, 4, "Sysop[L]og  Read [M]ail  [N]etLog");
  commands->PutsXY(1, 5, "[P]ending Net Data [/] Net Callout");
  commands->PutsXY(1, 6, "[R]ead all email [S]ystem Status");
  commands->PutsXY(1, 7, "[U]serEdit [Y]-Log [Z]-Log");
}

static void DrawStatus(CursesWindow* statusWindow) {
  statusWindow->SetColor(SchemeId::WINDOW_TEXT);
  statusWindow->PutsXY(2, 1, "Today:");
  statusWindow->PutsXY(2, 2, "Calls: XXXXX Minutes: XXXXX");
  statusWindow->PutsXY(2, 3, "M: XXX L: XXX E: XXX F: XXX FW: XXX");
  statusWindow->PutsXY(2, 4, "Totals:");
  statusWindow->PutsXY(2, 5, "Users: XXXXX Calls: XXXXX");
  statusWindow->PutsXY(2, 6, "Last User:"******"XXXXXXXXXXXXXXXXXXXXXXXXXX");
}

static string GetLastUserName(int inst_num) {
  instancerec ir;
  get_inst_info(inst_num, &ir);

  if (ir.flags & INST_FLAGS_ONLINE) {
    return session()->names()->UserName(ir.user);
  } else {
    return "Nobody";
  }

}

static void UpdateStatus(CursesWindow* statusWindow) {
  statusWindow->SetColor(SchemeId::WINDOW_DATA);
  std::unique_ptr<WStatus> pStatus(session()->status_manager()->GetStatus());

  statusWindow->PrintfXY(9, 2, "%-5d", pStatus->GetNumCallsToday());
  statusWindow->PrintfXY(24, 2, "%-5d", pStatus->GetMinutesActiveToday());

  statusWindow->PrintfXY(5, 3, "%-3u", pStatus->GetNumMessagesPostedToday());
  statusWindow->PrintfXY(12, 3, "%-3u", pStatus->GetNumLocalPosts());
  statusWindow->PrintfXY(19, 3, "%-3u", pStatus->GetNumEmailSentToday());
  statusWindow->PrintfXY(26, 3, "%-3u", pStatus->GetNumFeedbackSentToday());

  fwaiting = session()->user()->GetNumMailWaiting();
  statusWindow->PrintfXY(34, 3, "%-3d", fwaiting);

  statusWindow->PrintfXY(9, 5, "%-5d", pStatus->GetNumUsers());
  statusWindow->PrintfXY(22, 5, "%-6lu", pStatus->GetCallerNumber());

  // TODO(rushfan): Need to know the last used node number
  // then call GetLastUserName.
  //  statusWindow->PutsXY(2, 7, "XXXXXXXXXXXXXXXXXXXXXXXXXX");
}

static void CleanNetIfNeeded() {
  static int mult_time = 0;
  if (session()->IsCleanNetNeeded() || std::abs(timer1() - mult_time) > 1000L) {
    cleanup_net();
    mult_time = timer1();
  }
}

static void RunEventsIfNeeded() {
  unique_ptr<WStatus> pStatus(session()->status_manager()->GetStatus());
  if (!IsEquals(date(), pStatus->GetLastDate())) {
    if ((session()->GetBeginDayNodeNumber() == 0) 
        || (session()->instance_number() == session()->GetBeginDayNodeNumber())) {
      cleanup_events();
      beginday(true);
    }
  }

  if (!do_event) {
    check_event();
  }

  while (do_event) {
    run_event(do_event - 1);
    check_event();
  }

  session()->SetCurrentSpeed("KB");
  static time_t last_time_c = 0;
  time_t lCurrentTime = time(nullptr);
  if ((((rand() % 8000) == 0) || (lCurrentTime - last_time_c > 1200)) && net_sysnum) {
    lCurrentTime = last_time_c;
    attempt_callout();
  }
}

void ControlCenter::Initialize() {
  // Initialization steps that have to happen before we
  // have a functional WFC system. This also supposes that
  // session()->InitializeBBS has been called.
  out->Cls(ACS_CKBOARD);
  const int logs_y_padding = 1;
  const int logs_start = 11;
  const int logs_length = out->window()->GetMaxY() - logs_start - logs_y_padding;
  log_.reset(new WfcLog(logs_length - 2));
  commands_.reset(CreateBoxedWindow("Commands", 9, 38, 1, 1));
  status_.reset(CreateBoxedWindow("Status", 9, 39, 1, 40));
  logs_.reset(CreateBoxedWindow("Logs", logs_length, 78, 11, 1));

  DrawCommands(commands_.get());
  DrawStatus(status_.get());
  vector<HelpItem> help_items0 = { { "?", "All Commands" },};
  vector<HelpItem> help_items1 = { {"Q", "Quit" } };
  out->footer()->ShowHelpItems(0, help_items0);
  out->footer()->ShowHelpItems(1, help_items1);

  session()->ReadCurrentUser(1);
  read_qscn(1, qsc, false);
  session()->ResetEffectiveSl();
  session()->usernum = 1;

  fwaiting = session()->user()->GetNumMailWaiting();
  session()->SetWfcStatus(1);
}

void ControlCenter::Run() {
  Initialize();
  bool need_refresh = false;
  for (bool done = false; !done;) {
    if (need_refresh) {
      // refresh the window since we call endwin before invoking bbs code.
      RefreshAll();
      need_refresh = false;
    }

    wtimeout(commands_->window(), 500);
    int key = commands_->GetChar();
    if (key == ERR) {
      // we have a timeout. process other events
      need_refresh = false;
      UpdateLog();
      UpdateStatus(status_.get());
      CleanNetIfNeeded();
      RunEventsIfNeeded();
      continue;
    }
    need_refresh = true;
    session()->SetWfcStatus(2);
    // Call endwin since we'll be out of curses IO
    endwin();
    switch (toupper(key)) {
    case 'B': wfc_command(INST_LOC_BOARDEDIT, boardedit, cleanup_net); log_->Put("Ran BoardEdit"); break;
    case 'C': wfc_command(INST_LOC_CHAINEDIT, chainedit); log_->Put("Ran ChainEdit"); break;
    case 'D': wfc_command(INST_LOC_DIREDIT, dlboardedit); log_->Put("Ran DirEdit"); break;
    case 'E': wfc_command(INST_LOC_EMAIL, send_email_f, cleanup_net); break;
    case 'G': wfc_command(INST_LOC_GFILEEDIT, gfileedit); break;
    case 'H': wfc_command(INST_LOC_EVENTEDIT, eventedit); break;
    case 'I': wfc_command(INST_LOC_VOTEEDIT, ivotes); break;
    case 'J': wfc_command(INST_LOC_CONFEDIT, edit_confs); break;
    case 'L': wfc_command(INST_LOC_WFC, view_sysop_log_f); break;
    case 'M': wfc_command(INST_LOC_EMAIL, read_mail_f, cleanup_net); break;
    case 'N': wfc_command(INST_LOC_WFC, []() { print_local_file("net.log"); }); break;
    case 'P': wfc_command(INST_LOC_WFC, print_pending_list); break;
    case 'R': wfc_command(INST_LOC_MAILR, mailr); break;
    case 'S': wfc_command(INST_LOC_WFC, prstatus, getkey_f); break;
    case 'U': wfc_command(INST_LOC_UEDIT, []() { uedit(1, UEDIT_NONE); } ); break;
    case 'Y': wfc_command(INST_LOC_WFC, view_yesterday_sysop_log_f); break;
    case 'Z': wfc_command(INST_LOC_WFC, zlog, getkey_f); break;
    case 'Q': done=true; break;
    // ansicallout doesn't work due to arrow keys and other drawing problems with it under curses.
    // case '/': wfc_command(INST_LOC_NET, []() { force_callout(0); }); log_->Put("Ran Network Callout"); break;
    case ' ': log_->Put("Not Implemented Yet"); break; 
    }
    TouchAll();
  }
}

void ControlCenter::TouchAll() {
  out->window()->TouchWin();
  commands_->TouchWin();
  status_->TouchWin();
  logs_->TouchWin();
}

void ControlCenter::RefreshAll() {
  out->window()->Refresh();
  commands_->Refresh();
  status_->Refresh();
  logs_->Refresh();
  UpdateStatus(status_.get());
}

void ControlCenter::UpdateLog() {
  if (!log_->dirty()) {
    return;
  }

  vector<string> lines;
  if (!log_->Get(lines)) {
    return;
  }

  int start = 1;
  const int width = logs_->GetMaxX() - 4;
  for (const auto& line : lines) {
    logs_->PutsXY(1, start, line);
    logs_->PutsXY(1 + line.size(), start, string(width - line.size(), ' '));
    start++;
  }
}

}