summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2005-06-19 11:44:14 +0000
committerdeva <deva>2005-06-19 11:44:14 +0000
commit52fd913be8b044f1d064973c53b4467e5bd153fe (patch)
tree807ac3d85c9af0fe81bd88c22f6fe32c3c7af25b
parent60053525996c751ea9cdeddebbea8fa98e0c23a3 (diff)
Cleaned up a log of logging.
Fixed server queue (shouldn't happen). Added user and group lookup.
-rw-r--r--ChangeLog11
-rw-r--r--TODO2
-rw-r--r--configure.in2
-rw-r--r--etc/miav.conf4
-rw-r--r--src/daemon.cc44
-rw-r--r--src/daemon.h2
-rw-r--r--src/file.cc7
-rw-r--r--src/mainwindow.cc9
-rw-r--r--src/miav.cc16
-rw-r--r--src/miav_daemon.cc59
-rw-r--r--src/mov_encoder.cc74
-rw-r--r--src/server.cc116
-rw-r--r--src/server_status.cc33
-rw-r--r--src/server_status.h14
-rw-r--r--src/socket.cc12
-rw-r--r--src/socket.h6
16 files changed, 185 insertions, 226 deletions
diff --git a/ChangeLog b/ChangeLog
index 22d50f2..5dd344f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,17 @@
Changelog for MIaV
=======================================
+Juni 19 2005 - MIaV version 0.2.6
+---------------------------------------
+New Features:
+ - Added a lot of info, warning, and error message code.
+Bug Fixes:
+ - Fixed huge memory consumption when 'address in use' error on
+ server.
+ - Fixed server code which built up a framequeue serverside (I thought
+ I already fixed that in last release!)
+
+=======================================
Juni 16 2005 - MIaV version 0.2.5
---------------------------------------
New Features:
diff --git a/TODO b/TODO
index 0674af0..141a468 100644
--- a/TODO
+++ b/TODO
@@ -17,8 +17,6 @@ http://encyclopedia.laborlawtalk.com/YUV_4:2:0
open64 ?
Split files at some given (in config file) point?
-getpwent
-getgrent
==========================================================================
diff --git a/configure.in b/configure.in
index 543b991..cf3ca88 100644
--- a/configure.in
+++ b/configure.in
@@ -1,6 +1,6 @@
# Filename: configure.in
AC_INIT(src/miav.cc)
-AM_INIT_AUTOMAKE( miav, 0.2.5 )
+AM_INIT_AUTOMAKE( miav, 0.2.6 )
AC_PROG_CXX
diff --git a/etc/miav.conf b/etc/miav.conf
index 39bf4f6..05f865e 100644
--- a/etc/miav.conf
+++ b/etc/miav.conf
@@ -28,8 +28,8 @@ server_addr = "192.168.0.10"
server_port = 18120
# Run the server as the following user:
-server_uid = 500
-server_gid = 100
+server_user = "miav"
+server_group = "miav"
# Where to store the files recieved by the server
server_root = "/home/miav/miav_files"
diff --git a/src/daemon.cc b/src/daemon.cc
index 678a8c9..6e46bd5 100644
--- a/src/daemon.cc
+++ b/src/daemon.cc
@@ -31,17 +31,47 @@
#include <signal.h>
#include <stdio.h>
+// For getgrent and getgrent
+#include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
+
+// For strcmp
+#include <string.h>
+
Daemon::Daemon()
{}
Daemon::~Daemon()
{}
-int Daemon::run(uid_t uid, gid_t gid)
+int Daemon::run(const char *user, const char* group)
{
int f;
int fd;
+ // Fetch user id
+ int uid = -1;
+ struct passwd *p = getpwent();
+ while(p) {
+ if(strcmp(p->pw_name, user) == 0) uid = p->pw_uid;
+ p = getpwent();
+ }
+ if(uid == -1) {
+ fprintf(stderr, "Could not find user \"%s\" in /etc/passwd file.\n", user);
+ }
+
+ // Fetch group id
+ int gid = -1;
+ struct group *g = getgrent();
+ while(g) {
+ if(strcmp(g->gr_name, group) == 0) gid = g->gr_gid;
+ g = getgrent();
+ }
+ if(gid == -1) {
+ fprintf(stderr, "Could not find group \"%s\" in /etc/group file.\n", group);
+ }
+
chdir("/");
umask(0);
@@ -52,14 +82,18 @@ int Daemon::run(uid_t uid, gid_t gid)
return 1;
case 0: // Forked child
+ // Switch to given group
if(setgid(gid) != 0) {
- fprintf(stderr, "Failed to change to gid %d, quitting.\n", gid);
- return 1;
+ fprintf(stderr, "Failed to change to group \"%s\" (gid: %d), quitting.\n", group, gid);
+ perror("");
+ fprintf(stderr, "Runnning daemon as current group\n");
}
+ // Switch to given user
if(setuid(uid) != 0) {
- fprintf(stderr, "Failed to change to uid %d, quitting.\n", uid);
- return 1;
+ fprintf(stderr, "Failed to change to user \"%s\" (uid: %d), quitting.\n", user, uid);
+ perror("");
+ fprintf(stderr, "Runnning daemon as current user\n");
}
// Redirect stdin, stdout and stderr to /dev/null
diff --git a/src/daemon.h b/src/daemon.h
index 0859034..1bd663e 100644
--- a/src/daemon.h
+++ b/src/daemon.h
@@ -36,7 +36,7 @@ public:
/**
* Use NOBODY_GROUP and NOBODY_USER if no privileges are needed to run.
*/
- int run(uid_t uid, gid_t gid);
+ int run(const char* user, const char* group);
private:
virtual int daemon_main() = 0;
diff --git a/src/file.cc b/src/file.cc
index 2224178..2ba20bb 100644
--- a/src/file.cc
+++ b/src/file.cc
@@ -31,6 +31,11 @@
/*
* $Log$
+ * Revision 1.5 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.4 2005/06/14 18:58:35 deva
* *** empty log message ***
*
@@ -126,7 +131,7 @@ int File::Open()
seqnum ++;
- info->info("Outout file: %s", fname);
+ info->info("Output file: %s", fname);
return 0;
}
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index 0b1343e..3b8ca74 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
@@ -31,6 +31,11 @@
/*
* $Log$
+ * Revision 1.34 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.33 2005/06/16 21:28:57 deva
* Rewrote thread object
* Fixed bug in mov_encoder (pushed read_sem too many times, whihc lead to
@@ -345,11 +350,11 @@ void MainWindow::taskbar_update()
s = time.tv_sec - starttime.tv_sec;
h = s / (60 * 60);
- s -= h * (60 *60);
+ s -= h * (60 * 60);
m = s / 60;
s -= m * 60;
} else {
- if((camera->getQueueLength() > 0) && (watchdog % 50 == 0))
+ if((camera->getQueueLength() > 0) && (watchdog % 300 == 0))
info->log("Queue length: %d (passive)", camera->getQueueLength());
gettimeofday(&starttime, NULL);
}
diff --git a/src/miav.cc b/src/miav.cc
index 0f2feb3..9dc3552 100644
--- a/src/miav.cc
+++ b/src/miav.cc
@@ -31,6 +31,11 @@
/*
* $Log$
+ * Revision 1.15 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.14 2005/06/14 12:29:40 deva
* Incorporated the use of the Info object everywhere... also using the log functionality.
*
@@ -72,7 +77,6 @@
#include "miav.h"
#endif /* USE_GUI */
-
#include "miav_daemon.h"
#include "miav_config.h"
@@ -128,11 +132,11 @@ int server(int argc, char *argv[])
MiavDaemon daemon;
MiavConfig cfg(ETC"/miav.conf", NULL);
-
- int uid = cfg.readInt("server_uid");
- int gid = cfg.readInt("server_gid");
-
- return daemon.run(uid, gid);
+
+ string *user = cfg.readString("server_user");
+ string *group = cfg.readString("server_group");
+
+ return daemon.run(user->c_str(), group->c_str());
}
#include "debug.h"
diff --git a/src/miav_daemon.cc b/src/miav_daemon.cc
index 520a2fb..b164e92 100644
--- a/src/miav_daemon.cc
+++ b/src/miav_daemon.cc
@@ -31,6 +31,11 @@
/*
* $Log$
+ * Revision 1.5 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.4 2005/06/16 21:28:57 deva
* Rewrote thread object
* Fixed bug in mov_encoder (pushed read_sem too many times, whihc lead to
@@ -78,26 +83,50 @@ int MiavDaemon::daemon_main()
info.info("Listening on port %d", port);
Socket *socket = new Socket(port, &info);
+ if(socket->hasError()) {
+ info.error("Listening socket has errors, quitting.");
+ delete socket;
+ return 1;
+ }
+
while(1) {
Socket *csocket = new Socket(socket->slisten());
- if(csocket->isConnected()) {
- childpid = fork();
+
+ if(socket->hasError()) {
+ info.error("Server socket has errors, quitting.");
+ delete csocket;
+ break;
+ }
+
+ if(csocket->hasError()) {
+ info.error("Child socket has errors, quitting.");
+ delete csocket;
+ break;
+ }
+
+ if(!csocket->isConnected()) {
+ info.error("Child socket is not connected, quitting.");
+ delete csocket;
+ break;
+ }
+
+ childpid = fork();
+
+ switch(childpid) {
+ case -1: // fork() returns -1 on failure
+ info.log("Fork error: %s", strerror(errno));
+ exit(1);
+ case 0: // fork() returns 0 to the child process
+ delete socket; // Close listen socket.
+ newConnection(csocket, &info);
+ delete csocket; // Close communication socket.
+ exit(0);
- switch(childpid) {
- case -1: // fork() returns -1 on failure
- info.log("Fork error: %s", strerror(errno));
- exit(1);
- case 0: // fork() returns 0 to the child process
- delete socket; // Close listen socket.
- newConnection(csocket, &info);
- delete csocket; // Close communication socket.
- exit(0);
-
- default: // fork() returns new pid to the parent process
- break;
- }
+ default: // fork() returns new pid to the parent process
+ break;
}
}
+
delete socket;
return 0;
}
diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc
index 908e857..b31e1c9 100644
--- a/src/mov_encoder.cc
+++ b/src/mov_encoder.cc
@@ -39,6 +39,11 @@
/*
* $Log$
+ * Revision 1.31 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.30 2005/06/16 21:28:57 deva
* Rewrote thread object
* Fixed bug in mov_encoder (pushed read_sem too many times, whihc lead to
@@ -379,7 +384,7 @@ void MovEncoder::encode_audio(Frame *dvframe)
// this runs in a thread
void MovEncoder::thread_main()
{
- info->info("MovEncoder::run");
+ info->info("MovEncoder thread is running.");
FrameVector *item;
Frame *in_frame;
@@ -408,78 +413,17 @@ void MovEncoder::thread_main()
outputqueue->push(out_frame);
pthread_mutex_unlock(output_mutex);
// Unlock output mutex
-
- // Kick frame writer
- sem_post(output_sem);
}
delete item;
- // Kick reader
- sem_post(read_sem);
- }
- }
-
- info->info("MovEncoder::stop");
-}
-
-/*
-void MovEncoder::thread_main()
-{
- info->info("MovEncoder::run");
-
- FrameVector *item;
- Frame *in_frame;
- Frame *out_frame;
-
- while(running) {
- sem_wait(input_sem);
-
- // Lock inout mutex
- pthread_mutex_lock(input_mutex);
- if(inputqueue->size() == 0) {
- info->warn("Empty queue in MovEncoder (This should not happen).");
- pthread_mutex_unlock(input_mutex);
- // Kick reader
- sem_post(read_sem);
- continue;
- }
- item = inputqueue->front();
- inputqueue->pop();
- pthread_mutex_unlock(input_mutex);
- // Unlock input mutex
+ // Kick frame writer
+ sem_post(output_sem);
- if(!item) {
- info->warn("Empty block detected (This should not happen).");
// Kick reader
sem_post(read_sem);
- continue;
}
-
- for(unsigned int cnt = 0; cnt < item->size(); cnt++) {
- in_frame = item->at(cnt);
- out_frame = encode(in_frame);
- out_frame->number = in_frame->number;
-
- delete in_frame;
-
- // Lock output mutex
- pthread_mutex_lock(output_mutex);
- outputqueue->push(out_frame);
- pthread_mutex_unlock(output_mutex);
- // Unlock output mutex
-
- // Kick frame writer
- sem_post(output_sem);
- }
-
- delete item;
-
- // Kick reader
- sem_post(read_sem);
}
- info->info("MovEncoder::stop");
+ info->info("MovEncoder thread has stopped.");
}
-
- */
diff --git a/src/server.cc b/src/server.cc
index fad79ae..e6a6ff7 100644
--- a/src/server.cc
+++ b/src/server.cc
@@ -31,6 +31,11 @@
/*
* $Log$
+ * Revision 1.24 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.23 2005/06/14 18:58:35 deva
* *** empty log message ***
*
@@ -198,125 +203,18 @@ void saveFrameAsImage(char* cpr, Frame *f)
fprintf(stderr, "Success - using filename: [%s.jpg]\n", fname); fflush(stderr);
imgenc.encode(f, fname, 100); // Quality is between 0...100, where 100 is best.
}
-/*
-struct tm
-{
- int tm_sec; // Seconds. [0-60] (1 leap second)
- int tm_min; // Minutes. [0-59]
- int tm_hour; // Hours. [0-23]
- int tm_mday; // Day. [1-31]
- int tm_mon; // Month. [0-11]
- int tm_year; // Year - 1900.
- int tm_wday; // Day of week. [0-6]
- int tm_yday; // Days in year.[0-365]
- int tm_isdst; // DST. [-1/0/1]
-};
-*/
-
-MovEncoderThread *newMovEncoder(char* cpr)
-{
- /*
- MovEncoderThread *enc;
- struct tm *ltime;
- time_t t = time(NULL);
- FILE *fp;
- int cnt = 0;
- char fname[256];
- char birthmonth[3];
- char date[9];
-
- string *root = config->readString("server_root");
-
- // Test for server root writeability
- sprintf(fname, "%s/miavtemp.tmp%d", (char*)root->c_str(), rand());
- fp = fopen(fname, "w");
- if(!fp) {
- int r = rand();
- fprintf(stderr, "MIaV does not have write access to the server root [%s]\n", root->c_str());
- fprintf(stderr, "Redirecting output to [/tmp/miav-%d.mpg]\n", r);
- sprintf(fname, "/tmp/miav-%d", r);
- enc = new MovEncoderThread(fname);
- return enc;
- }
- fclose(fp);
- unlink(fname);
-
- // Check for cpr length correctness
- if(strlen(cpr) != 11) {
- int r = rand();
- fprintf(stderr, "Illigal CPR, it must have length 11, it had lentgh %d\n", strlen(cpr));
- fprintf(stderr, "Redirecting output to [/tmp/miav-%d.mpg]\n", r);
- sprintf(fname, "/tmp/miav-%d", r);
- enc = new MovEncoderThread(fname);
- return enc;
- }
-
- // Copy the bytes representing the birth month from the cpr
- // [dd][mm][yy]-[nn][nn]
- strncpy(birthmonth, &cpr[2], 2);
- birthmonth[2] = 0;
-
- // Create folder named birthmonth in server root
- sprintf(fname, "%s/%s", root->c_str(), birthmonth);
- if(!mkdir(fname, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH) == -1 && errno != EEXIST) {
- int r = rand();
- fprintf(stderr, "Not possible to create subfolder %s\n", fname);
- fprintf(stderr, "Redirecting output to [/tmp/miav-%d.mpg]\n", r);
- sprintf(fname, "/tmp/miav-%d", r);
- enc = new MovEncoderThread(fname);
- return enc;
- }
-
- // Create folder named cpr in serverroot/birthmonth
- sprintf(fname, "%s/%s/%s", root->c_str(), birthmonth, cpr);
- if(!mkdir(fname, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH) == -1 && errno != EEXIST) {
- int r = rand();
- fprintf(stderr, "Not possible to create subfolder %s\n", fname);
- fprintf(stderr, "Redirecting output to [/tmp/miav-%d.mpg]\n", r);
- sprintf(fname, "/tmp/miav-%d", r);
- enc = new MovEncoderThread(fname);
- return enc;
- }
-
- // Create date (today) in [yyyy][mm][dd]
- ltime = localtime(&t);
- sprintf(date, "%.4d%.2d%.2d",
- ltime->tm_year + 1900,
- ltime->tm_mon,
- ltime->tm_mday);
-
- // Create filename: [serverroot]/[birthmonth]/[cpr]/[cpr]-[date]-[cnt].mpg
- sprintf(fname, "%s/%s/%s/%s-%s-%.3d.mpg", root->c_str(), birthmonth, cpr, cpr, date, cnt);
-
- // test filename-[cnt] for existamce cnt++ until not existing.
- fp = fopen(fname, "r");
- while(fp) {
- fclose(fp);
- cnt++;
- sprintf(fname, "%s/%s/%s/%s-%s-%.3d.mpg", root->c_str(), birthmonth, cpr, cpr, date, cnt);
- fp = fopen(fname, "r");
- }
- sprintf(fname, "%s/%s/%s/%s-%s-%.3d", root->c_str(), birthmonth, cpr, cpr, date, cnt);
-
- fprintf(stderr, "Success - using filename: [%s.mpg]\n", fname); fflush(stderr);
- enc = new MovEncoderThread(fname);
- return enc;
-*/
- return NULL;
-}
void newConnection(Socket *socket, Info *info)
{
char cpr[256];
bool hasCpr = false;
- ServerStatus status;
+ ServerStatus status(info);
n_savestate savestate = LATER;
n_header h;
Frame *frame;
Frame *freeze_frame = NULL;
MovEncoderThread *enc = NULL;
- // unsigned char dvbuf[DVPACKAGE_SIZE];
frame = new Frame(NULL, DVPACKAGE_SIZE);
@@ -324,7 +222,9 @@ void newConnection(Socket *socket, Info *info)
Network network = Network(socket, info);
while(int ret = network.recvPackage(&h, frame->data, frame->size)) {
+
status.checkPoint();
+
if(ret == -1) {
info->error("A network error ocurred, terminating session");
break;
diff --git a/src/server_status.cc b/src/server_status.cc
index 23c6c3d..e65cef2 100644
--- a/src/server_status.cc
+++ b/src/server_status.cc
@@ -31,6 +31,11 @@
/*
* $Log$
+ * Revision 1.9 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.8 2005/05/22 15:49:22 deva
* Added multithreaded encoding support.
*
@@ -38,16 +43,13 @@
* Fixed file rights (All read on files and directories, and all execute on directories).
*
* Revision 1.6 2005/05/16 16:00:57 deva
- *
* Lots of stuff!
*
* Revision 1.5 2005/05/16 13:25:52 deva
- *
* Moved video setting to configuration file.
* Fine tuned setting for 2.4ghz server
*
* Revision 1.4 2005/05/09 16:40:20 deva
- *
* Added optimize yuv conversion code
*
* Revision 1.3 2005/05/03 08:31:59 deva
@@ -62,16 +64,19 @@
#include <stdio.h>
-#define UPD 25
-ServerStatus::ServerStatus()
+ServerStatus::ServerStatus(Info *i)
{
+ info = i;
+
gettimeofday(&oldtime, NULL);
for(int cnt = 0; cnt < BUFFERSIZE; cnt++) {
- frametime[cnt] = 41660 * UPD;
+ frametime[cnt] = 41660;
}
gettimeofday(&time, NULL);
+
+ frame = 0;
}
ServerStatus::~ServerStatus()
@@ -80,11 +85,6 @@ ServerStatus::~ServerStatus()
void ServerStatus::checkPoint()
{
- return;
-
- static int frame = 0;
- frame++;
- if(frame % UPD != 0) return;
for(int cnt = BUFFERSIZE - 1; cnt > 0; cnt--) {
frametime[cnt] = frametime[cnt-1];
}
@@ -95,11 +95,14 @@ void ServerStatus::checkPoint()
gettimeofday(&time, NULL);
- double total = 0.0;
- for(int cnt = 0; cnt < BUFFERSIZE; cnt++) {
- total += (double)frametime[cnt];
+ frame++;
+ if(frame % UPD == 0) {
+ double total = 0.0;
+ for(int cnt = 0; cnt < BUFFERSIZE; cnt++) {
+ total += (double)frametime[cnt];
+ }
+ info->info("Status - fps: %f", 1000000.0 / (total / (double)BUFFERSIZE));
}
- fprintf(stderr, "[ms: %d, fps: %f]\n", frametime[0] / UPD, (1000000.0 / (total / (double)BUFFERSIZE)) * UPD );
}
diff --git a/src/server_status.h b/src/server_status.h
index 84f7273..58de61c 100644
--- a/src/server_status.h
+++ b/src/server_status.h
@@ -31,6 +31,11 @@
/*
* $Log$
+ * Revision 1.4 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.3 2005/05/03 08:31:59 deva
* Removed the error object, and replaced it with a more generic info object.
*
@@ -43,18 +48,23 @@
#ifndef __MIAV_SERVER_STATUS_H__
#define __MIAV_SERVER_STATUS_H__
+#include "info.h"
+
#include <sys/time.h>
-#define BUFFERSIZE 25
+#define BUFFERSIZE 100
+#define UPD 1500
class ServerStatus {
public:
- ServerStatus();
+ ServerStatus(Info *info);
~ServerStatus();
void checkPoint();
private:
+ int frame;
+ Info *info;
unsigned int frametime[BUFFERSIZE];
struct timeval time;
struct timeval oldtime;
diff --git a/src/socket.cc b/src/socket.cc
index c5a2575..91b8e34 100644
--- a/src/socket.cc
+++ b/src/socket.cc
@@ -31,6 +31,11 @@
/*
* $Log$
+ * Revision 1.7 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.6 2005/06/02 15:03:23 deva
*
* Fixed crash in network.cc if socket not connected.
@@ -79,7 +84,7 @@ Socket::Socket(u_short port, Info *ginfo)
socketaddr.sin_family = AF_INET; // Use "internet protocol" IP
socketaddr.sin_port = htons(port); // connect to that port
socketaddr.sin_addr.s_addr = INADDR_ANY;
- // INADDR_ANY puts your IP address automatically
+ // INADDR_ANY puts your IP address automatically
}
@@ -165,3 +170,8 @@ bool Socket::isConnected()
{
return connected;
}
+
+bool Socket::hasError()
+{
+ return err != 0;
+}
diff --git a/src/socket.h b/src/socket.h
index 3f95e69..41ada6d 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -31,6 +31,11 @@
/*
* $Log$
+ * Revision 1.6 2005/06/19 11:44:14 deva
+ * Cleaned up a log of logging.
+ * Fixed server queue (shouldn't happen).
+ * Added user and group lookup.
+ *
* Revision 1.5 2005/05/03 17:13:25 deva
* Fixed some missong Info object references.
*
@@ -65,6 +70,7 @@ public:
Socket slisten();
int sconnect(char *ip);
bool isConnected();
+ bool hasError();
struct sockaddr_in socketaddr;
int ssocket;