diff --git a/acceptFactory.cc b/acceptFactory.cc index cfd1c85..7b7205b 100644 --- a/acceptFactory.cc +++ b/acceptFactory.cc @@ -392,7 +392,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 750a6c1..64abed8 100644 --- a/procServ.cc +++ b/procServ.cc @@ -29,6 +29,9 @@ #include #include #include +#include + +#include #ifdef __CYGWIN__ #include @@ -95,6 +98,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 @@ -174,6 +179,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" @@ -236,7 +242,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'}, @@ -261,7 +268,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:op:P:qVwx:", + c = getopt_long (argc, argv, "+c:de:fhH:i:I:k:l:L:n:op:P:qVwx:", long_options, &option_index); /* Detect the end of the options. */ @@ -309,12 +316,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; @@ -514,7 +526,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()) { @@ -730,6 +752,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') { @@ -758,6 +781,7 @@ void SendToAll(const char * message, p->Send(stamp, len, message, count); else p->Send(message, count); + } } p = p->next; @@ -815,7 +839,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 ) @@ -828,8 +852,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 0dcb381..2bba786 100644 --- a/procServ.h +++ b/procServ.h @@ -80,7 +80,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 826a85f..3f4cbb6 100644 --- a/procServ.spec +++ b/procServ.spec @@ -8,7 +8,7 @@ Release: 8%{?dist} License: GPLv3 URL: https://github.com/ralphlange/procServ Source0: https://github.com/ralphlange/procServ/releases/download/V%{version}/procServ-%{version}.tar.gz -BuildRequires: libtelnet-devel gcc-c++ +BuildRequires: libtelnet-devel gcc-c++ boost-devel %description procServ is a wrapper that starts an arbitrary command as a child process in