diff --git a/acceptFactory.cc b/acceptFactory.cc index 741b6eb..e0047e0 100644 --- a/acceptFactory.cc +++ b/acceptFactory.cc @@ -354,7 +354,7 @@ void acceptItem::readFromFd(void) newFd = accept( _fd, &addr, &len ); if (newFd >= 0) { PRINTF("acceptItem: Accepted connection on handle %d\n", newFd); - AddConnection(clientFactory(newFd, _readonly)); + AddConnection(clientFactory(newFd, _readonly), true); } else { PRINTF("Accept error: %s\n", strerror(errno)); // on Cygwin got error EINVAL remakeConnection(); diff --git a/procServ.cc b/procServ.cc index a531d4c..3dc0fa5 100644 --- a/procServ.cc +++ b/procServ.cc @@ -25,6 +25,9 @@ #include #include #include +#include + +#include #ifdef __CYGWIN__ #include @@ -90,6 +93,8 @@ int logFileFD=-1; // FD for log file char *logPort; // address for logger connections int debugFD=-1; // FD for debug output +boost::circular_buffer logBuffer(0); + #define MAX_CONNECTIONS 64 // mLoop runs the program @@ -168,6 +173,7 @@ void printHelp() " -d --debug debug mode (keeps child in foreground)\n" " -e --exec specify child executable (default: arg0 of )\n" " -f --foreground keep child in foreground (interactive)\n" + " -H --history display the last n child messages for new connections\n" " -h --help print this message\n" " --holdoff set holdoff time [sec] between child restarts\n" " -i --ignore ignore all chars in (^ for ctrl)\n" @@ -229,7 +235,8 @@ int main(int argc,char * argv[]) {"exec", required_argument, 0, 'e'}, {"foreground", no_argument, 0, 'f'}, {"help", no_argument, 0, 'h'}, - {"holdoff", required_argument, 0, 'H'}, + {"history", required_argument, 0, 'H'}, + {"holdoff", required_argument, 0, 'O'}, {"ignore", required_argument, 0, 'i'}, {"info-file", required_argument, 0, 'I'}, {"killcmd", required_argument, 0, 'k'}, @@ -253,7 +260,7 @@ int main(int argc,char * argv[]) /* getopt_long stores the option index here. */ int option_index = 0; - c = getopt_long (argc, argv, "+c:de:fhi:I:k:l:L:n:p:P:qVwx:", + c = getopt_long (argc, argv, "+c:de:fhH:i:I:k:l:L:n:p:P:qVwx:", long_options, &option_index); /* Detect the end of the options. */ @@ -301,12 +308,17 @@ int main(int argc,char * argv[]) if (optarg) stampFormat = strdup(optarg); break; + + case 'H': // Size of history buffer + logBuffer.set_capacity( atoi( optarg ) ); + break; + case 'h': // Help printHelp(); exit(0); - case 'H': // Holdoff time + case 'O': // Holdoff time k = atoi( optarg ); if ( k >= 0 ) holdoffTime = k; break; @@ -504,7 +516,7 @@ int main(int argc,char * argv[]) { for(size_t i=0; iisProcess()) { + std::string s_message = ""; + if (stampLog) { + s_message += stamp; + s_message += " "; + } + s_message += message; + logBuffer.push_back(s_message); + } + // Log the traffic to file / stdout (debug) if (sender==NULL || sender->isProcess()) { @@ -697,6 +719,7 @@ void SendToAll(const char * message, for (i = 0; i < count; ++i) { if (!log_stamp_sent) { ignore_result( write(logFileFD, stamp, len) ); + ignore_result( write(logFileFD, " ", 1) ); log_stamp_sent = true; } if (message[i] == '\n') { @@ -725,6 +748,7 @@ void SendToAll(const char * message, p->Send(stamp, len, message, count); else p->Send(message, count); + } } p = p->next; @@ -781,7 +805,7 @@ void OnPollTimeout() } // Call this to add the item to the list of connections -void AddConnection(connectionItem * ci) +void AddConnection(connectionItem * ci, bool show_log) { PRINTF("Adding connection %p to list\n", ci); if (connectionItem::head ) @@ -794,8 +818,13 @@ void AddConnection(connectionItem * ci) ci->prev=NULL; connectionItem::head=ci; connectionNo++; -} + if (show_log) { + for (int i=0; i < logBuffer.size(); i++) { + ci->Send(logBuffer[i].c_str(), strlen(logBuffer[i].c_str())); + } + } +} void DeleteConnection(connectionItem *ci) { diff --git a/procServ.h b/procServ.h index 150ed5a..fe01481 100644 --- a/procServ.h +++ b/procServ.h @@ -77,7 +77,7 @@ void SendToAll(const char * message, const connectionItem * sender); // Call this to add the item to the list of connections -void AddConnection(connectionItem *); +void AddConnection(connectionItem *, bool show_log); void DeleteConnection(connectionItem *ci); // connectionItems are made in class factories so none of the diff --git a/procServ.spec b/procServ.spec index a68ebbc..37d7e71 100644 --- a/procServ.spec +++ b/procServ.spec @@ -10,7 +10,7 @@ Group: Applications/System URL: https://github.com/ralphlange/procServ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Source0: https://github.com/ralphlange/procServ/releases/download/V%{version}/procServ-%{version}.tar.gz -BuildRequires: libtelnet-devel +BuildRequires: libtelnet-devel boost-devel %description procServ is a wrapper that starts an arbitrary command as a child process in