00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <eyedbconfig.h>
00025
00026 #include <stdlib.h>
00027 #include <fcntl.h>
00028 #include <signal.h>
00029 #include <sys/stat.h>
00030 #include <sys/mman.h>
00031 #include "SessionLog.h"
00032 #include <time.h>
00033 #include <eyedbsm/smd.h>
00034 #include <eyedblib/rpc_lib.h>
00035 #include <eyedblib/strutils.h>
00036 #include "comp_time.h"
00037 #include <lib/m_mem_p.h>
00038 #include <eyedbsm/eyedbsm_p.h>
00039
00040 #define MAXPORTS 8
00041 #define PORTLEN 127
00042 #define DATDIRLEN 511
00043 #define LOGDEVLEN 511
00044
00045 #define eyedbsm_mutexLock(X, Y) eyedbsm::mutexLock(X, Y)
00046 #define eyedbsm_mutexUnlock(X, Y) eyedbsm::mutexUnlock(X, Y)
00047
00048
00049
00050 namespace eyedb {
00051
00052 struct SessionHead {
00053 unsigned int magic;
00054 eyedbsm::MutexP mp;
00055 char version[32];
00056 int up;
00057 time_t start;
00058 char smdport[PORTLEN+1];
00059 int nports;
00060 char hosts[MAXPORTS][PORTLEN+1];
00061 char ports[MAXPORTS][PORTLEN+1];
00062 int uid;
00063 int pid;
00064 char datdir[DATDIRLEN+1];
00065 char logdev[LOGDEVLEN+1];
00066 int loglevel;
00067 int nconns;
00068 eyedbsm::XMOffset conn_first;
00069 };
00070
00071 #define MAXDBS 8
00072
00073 struct ClientInfo {
00074 time_t start;
00075 char hostname[64];
00076 char portname[64];
00077 char username[64];
00078 char progname[128];
00079 int n_dbs;
00080 struct {
00081 char dbname[32];
00082 char userauth[10];
00083 int flags;
00084 } dbs[MAXDBS];
00085 int prog_pid;
00086 int backend_pid;
00087 eyedbsm::XMOffset conn_prev, conn_next;
00088 };
00089
00090 SessionLog *SessionLog::sesslog;
00091
00092 #include <pwd.h>
00093
00094 static const char *
00095 getUserName(int uid)
00096 {
00097 struct passwd *p = getpwuid(uid);
00098 if (!p)
00099 return "<unknown>";
00100 return p->pw_name;
00101 }
00102
00103 #define SE_CONNLOG_MAGIC ((unsigned int)0x3f1920ab)
00104
00105 #define CONNLOG_SIZE (sizeof(SessionHead) + 128 * sizeof(ClientInfo))
00106
00107 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00108 Status
00109 SessionLog::init_sems()
00110 {
00111 vd = (void *)calloc(sizeof(eyedbsm::DbDescription), 1);
00112 int *semkeys = (int *)((eyedbsm::DbDescription *)vd)->semkeys;
00113 smdcli_conn_t *conn = smdcli_open(smd_get_port());
00114 if (!conn)
00115 return Exception::make(IDB_ERROR, "sessionlog: cannot connect to eyedbsmd ");
00116 smdcli_init_getsems(conn, ServerConfig::getSValue("default_dbm"), semkeys);
00117
00118 if (semkeys[0] <= 0)
00119 return Exception::make(IDB_ERROR, "sessionlog: cannot create semaphores ");
00120 return Success;
00121 }
00122 #endif
00123
00124 SessionLog::SessionLog(const SessionLog &sesslog)
00125 {
00126 init(sesslog.host, sesslog.port, sesslog.logdir, True);
00127 }
00128
00129 SessionLog::SessionLog(const char *host, const char *port,
00130 const char *logdir, Bool writing)
00131 {
00132 init(host, port, logdir, writing);
00133 }
00134
00135 void SessionLog::init(const char *host, const char *port, const char *logdir,
00136 Bool writing)
00137 {
00138 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00139 status = init_sems();
00140 if (status)
00141 return;
00142 #else
00143 vd = (void *)calloc(sizeof(eyedbsm::DbDescription), 1);
00144 #endif
00145 islocked = False;
00146 addr_connlog = 0;
00147 status = openRealize(host, port, logdir, False, writing);
00148 if (status)
00149 return;
00150
00151 sesslog = this;
00152 }
00153
00154
00155 SessionLog::SessionLog(const char *logdir, const char *version,
00156 int nports, const char *hosts[], const char *ports[],
00157 const char *datdir,
00158 const char *logdev, int loglevel)
00159 {
00160 int i;
00161
00162 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00163 status = init_sems();
00164 if (status)
00165 return;
00166 #else
00167 vd = (void *)calloc(sizeof(eyedbsm::DbDescription), 1);
00168 #endif
00169 islocked = False;
00170 addr_connlog = 0;
00171 status = openRealize(hosts[0], ports[0], logdir, True, True);
00172
00173 if (status)
00174 return;
00175
00176 file_cnt = nports;
00177 if (file_cnt > 1) {
00178 files = (char **)realloc(files, file_cnt * sizeof(char *));
00179
00180 for (i = 1; i < file_cnt; i++) {
00181 files[i] = makeFile(hosts[i], ports[i], logdir);
00182 symlink(files[0], files[i]);
00183 }
00184 }
00185
00186 sesslog = this;
00187
00188 memset(&connhead, sizeof(connhead), 0);
00189 connhead->magic = SE_CONNLOG_MAGIC;
00190 strcpy(connhead->version, version);
00191 time(&connhead->start);
00192 connhead->up = 1;
00193 strncpy(connhead->smdport, smd_get_port(), PORTLEN);
00194 connhead->smdport[PORTLEN] = 0;
00195 connhead->nports = nports;
00196 for (i = 0; i < nports; i++) {
00197 strncpy(connhead->hosts[i], hosts[i], PORTLEN);
00198 connhead->hosts[i][PORTLEN] = 0;
00199 strncpy(connhead->ports[i], ports[i], PORTLEN);
00200 connhead->ports[i][PORTLEN] = 0;
00201 }
00202
00203 strncpy(connhead->datdir, datdir, DATDIRLEN);
00204 connhead->datdir[DATDIRLEN] = 0;
00205 connhead->pid = rpc_getpid();
00206 connhead->uid = getuid();
00207
00208 if (logdev) {
00209 strncpy(connhead->logdev, logdev, LOGDEVLEN);
00210 connhead->logdev[LOGDEVLEN] = 0;
00211 }
00212
00213 connhead->loglevel = loglevel;
00214 connhead->conn_first = XM_NULLOFFSET;
00215 }
00216
00217 static char *truedir(const char *rs)
00218 {
00219 char *s, *os;
00220 s = strdup(rs);
00221
00222 os = s;
00223 if (!strchr(s, '.'))
00224 return s;
00225
00226 int sx_cnt = 0;
00227 int sx_alloc = 0;
00228 char **sx = 0;
00229 char *p;
00230 char *r = (char *)malloc(strlen(s)+1);
00231
00232 if (*s == '/')
00233 s++;
00234
00235 for (;;) {
00236 int stopafter = 0;
00237 if (!(p = strchr(s, '/'))) {
00238 p = s + strlen(s);
00239 stopafter = 1;
00240 }
00241
00242 char *q = (char *)malloc(p-s+1);
00243 strncpy(q, s, p-s);
00244 q[p-s] = 0;
00245 if (!strcmp(q, "..")) {
00246 sx_cnt--;
00247 free(sx[sx_cnt]);
00248 free(q);
00249 }
00250 else {
00251 if (sx_cnt >= sx_alloc) {
00252 sx_alloc++;
00253 sx = (char **)realloc(sx, sx_alloc*sizeof(char *));
00254 }
00255 sx[sx_cnt] = q;
00256 sx_cnt++;
00257 }
00258
00259 if (stopafter)
00260 break;
00261 s = p+1;
00262 }
00263
00264 *r = 0;
00265 for (int i = 0; i < sx_cnt; i++) {
00266 strcat(r, "/");
00267 strcat(r, sx[i]);
00268 free(sx[i]);
00269 }
00270
00271 free(sx);
00272 free(os);
00273 return r;
00274 }
00275
00276 char *
00277 SessionLog::makeFile(const char *_host, const char *_port, const char *_logdir)
00278 {
00279 static const char conn_prefix[] = ".eyedb_";
00280 static const char conn_suffix[] = ".con";
00281 char hostname[256];
00282 char *file;
00283
00284 if (!_logdir || !_port)
00285 return 0;
00286
00287 port = strdup(_port);
00288 host = strdup(_host);
00289
00290 char *port_file = truedir((std::string(host) + ":" + _port).c_str());
00291
00292 char *p = port_file;
00293 while (p = strchr(p, '/'))
00294 *p = '_';
00295
00296 logdir = strdup(_logdir ? _logdir : "/tmp");
00297
00298 gethostname(hostname, sizeof(hostname)-1);
00299
00300 file = (char *)malloc(strlen(logdir) +
00301 1 +
00302 strlen(conn_prefix) +
00303 strlen(port_file) +
00304 1 +
00305 strlen(hostname) +
00306 strlen(conn_suffix) +
00307 1);
00308
00309 sprintf(file, "%s/%s%s_%s%s", logdir, conn_prefix, port_file, hostname,
00310 conn_suffix);
00311
00312 return file;
00313 }
00314
00315 Status
00316 SessionLog::openRealize(const char *host, const char *port,
00317 const char *logdir, Bool create,
00318 Bool writing)
00319 {
00320 Error err = (create ? IDB_SESSION_LOG_CREATION_ERROR :
00321 IDB_SESSION_LOG_OPEN_ERROR);
00322 int fd;
00323 file_cnt = 1;
00324 files = (char **)malloc(file_cnt * sizeof(char *));
00325 files[0] = makeFile(host, port, logdir);
00326
00327
00328 writing = True;
00329
00330 xm_connlog = 0;
00331
00332 if (!files[0])
00333 return Exception::make(err, "eyedb environment error");
00334
00335 if (create)
00336 fd = open(files[0], O_CREAT | O_TRUNC | O_RDWR,
00337 0644 );
00338 else {
00339 if (access(files[0], F_OK) < 0)
00340 return Exception::make(IDB_CONNECTION_LOG_FILE_ERROR,
00341 "cannot access connection file '%s'",
00342 files[0]);
00343
00344 if (access(files[0], R_OK) < 0)
00345 return Exception::make(IDB_SESSION_LOG_OPEN_ERROR,
00346 "cannot open connection file '%s' "
00347 "for reading", files[0]);
00348
00349 if (writing) {
00350 if (access(files[0], W_OK) < 0)
00351 return Exception::make(IDB_SESSION_LOG_OPEN_ERROR,
00352 "cannot open connection file '%s' "
00353 "for writing", files[0]);
00354
00355 fd = open(files[0], O_RDWR);
00356 }
00357 else
00358 fd = open(files[0], O_RDONLY);
00359 }
00360
00361 if (fd < 0 && create)
00362 return Exception::make(err,
00363 "cannot %s connection file '%s'",
00364 (create ? "create" :
00365 "open"), files[0]);
00366 if (fd < 0)
00367 return Exception::make(IDB_SESSION_LOG_OPEN_ERROR,
00368 "cannot open connection file '%s'",
00369 files[0]);
00370
00371 if (create && ftruncate(fd, CONNLOG_SIZE) < 0) {
00372 close(fd);
00373 return Exception::make(err,
00374 "cannot create connection file '%s'", files[0]);
00375 }
00376
00377 unsigned int prot = PROT_READ;
00378 if (writing)
00379 prot |= PROT_WRITE;
00380 if (!(m_connlog = m_mmap(0, CONNLOG_SIZE, prot,
00381 MAP_SHARED, fd, 0, (char **)&addr_connlog,
00382 files[0], 0, 0))) {
00383 close(fd);
00384 return Exception::make(err,
00385 "cannot map connection file '%s' for size %d",
00386 files[0], CONNLOG_SIZE);
00387 }
00388
00389 if (!create) {
00390 struct stat st;
00391 if (fstat(fd, &st) < 0) {
00392 close(fd);
00393 return Exception::make(err, "cannot stat connection "
00394 "log file '%s'", files[0]);
00395 }
00396
00397 if (st.st_size < CONNLOG_SIZE && ftruncate(fd, CONNLOG_SIZE) < 0) {
00398 close(fd);
00399 return Exception::make(err,
00400 "cannot create connection "
00401 "log file '%s'", files[0]);
00402 }
00403 }
00404
00405 close(fd);
00406 m_lock(m_connlog);
00407
00408 connhead = (SessionHead *)addr_connlog;
00409
00410 if (create)
00411 xm_connlog = eyedbsm::XMCreate(addr_connlog + sizeof(SessionHead),
00412 CONNLOG_SIZE - sizeof(SessionHead), vd);
00413 else
00414 xm_connlog = eyedbsm::XMOpen(addr_connlog + sizeof(SessionHead), vd);
00415
00416 if (!xm_connlog)
00417 return Exception::make(err,
00418 "cannot map connection file '%s' for size %d",
00419 files[0], CONNLOG_SIZE);
00420 return Success;
00421 }
00422
00423 Status
00424 SessionLog::add(const char *hostname, const char *portname,
00425 const char *username,
00426 const char *progname, int pid,
00427 ClientSessionLog*& clientLog)
00428 {
00429 ClientInfo *conninfo =
00430 (ClientInfo *)XMAlloc(xm_connlog, sizeof(ClientInfo));
00431
00432 if (!conninfo)
00433 return Exception::make(IDB_SESSION_LOG_NO_SPACE_LEFT,
00434 "no space left on connection file");
00435
00436 memset(conninfo, 0, sizeof(*conninfo));
00437
00438 time(&conninfo->start);
00439 strncpy(conninfo->hostname, hostname, sizeof(conninfo->hostname)-1);
00440 strncpy(conninfo->portname, portname, sizeof(conninfo->portname)-1);
00441 strncpy(conninfo->username, username, sizeof(conninfo->username)-1);
00442 strncpy(conninfo->progname, progname, sizeof(conninfo->progname)-1);
00443
00444 conninfo->prog_pid = pid;
00445 conninfo->backend_pid = rpc_getpid();
00446
00447 #ifdef TRACE
00448 fprintf(stderr, "SessionLog %d tries to locked\n", rpc_getpid());
00449 #endif
00450 eyedbsm_mutexLock(xm_connlog->mp, 0);
00451 #ifdef TRACE
00452 fprintf(stderr, "SessionLog %d is locked\n", rpc_getpid());
00453 #endif
00454 islocked = True;
00455
00456 conninfo->conn_next = connhead->conn_first;
00457 conninfo->conn_prev = XM_NULLOFFSET;
00458
00459 if (connhead->conn_first) {
00460 ClientInfo *first = (ClientInfo *)
00461 XM_ADDR(xm_connlog, connhead->conn_first);
00462 first->conn_prev = XM_OFFSET(xm_connlog, conninfo);
00463 }
00464
00465 connhead->conn_first = XM_OFFSET(xm_connlog, conninfo);
00466 connhead->nconns++;
00467
00468 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00469 #ifdef TRACE
00470 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00471 #endif
00472 islocked = False;
00473
00474 clientLog = new ClientSessionLog(conninfo);
00475
00476 #ifdef TRACE
00477 fprintf(stderr, "log add (%s, %s, %s, %d, %d)\n",
00478 hostname, username, progname, pid, rpc_getpid());
00479 #endif
00480
00481 return Success;
00482 }
00483
00484 void
00485 SessionLog::suppress(ClientSessionLog *clientLog)
00486 {
00487 ClientInfo *conninfo = clientLog->getClientInfo();
00488
00489 #ifdef TRACE
00490 fprintf(stderr, "SessionLog %d tries to locked\n", rpc_getpid());
00491 #endif
00492 eyedbsm_mutexLock(xm_connlog->mp, 0);
00493 #ifdef TRACE
00494 fprintf(stderr, "SessionLog %d is locked\n", rpc_getpid());
00495 #endif
00496 islocked = True;
00497
00498 if (conninfo->conn_next)
00499 ((ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next))->conn_prev =
00500 conninfo->conn_prev;
00501
00502 if (conninfo->conn_prev)
00503 ((ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_prev))->conn_next =
00504 conninfo->conn_next;
00505 else
00506 connhead->conn_first = conninfo->conn_next;
00507
00508 #ifdef TRACE
00509 fprintf(stderr, "log suppress (%s, %s, %s, %d, %d)\n",
00510 conninfo->hostname, conninfo->username, conninfo->progname,
00511 conninfo->prog_pid, conninfo->backend_pid);
00512 #endif
00513
00514 connhead->nconns--;
00515 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00516 #ifdef TRACE
00517 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00518 #endif
00519 islocked = False;
00520
00521 XMFree(xm_connlog, conninfo);
00522 }
00523
00524 static Bool
00525 check_server(ClientInfo *conninfo)
00526 {
00527 #ifdef HAVE_SLASH_PROC
00528 if (access((std::string("/proc/") + str_convert((long)conninfo->backend_pid)).c_str(),
00529 F_OK) >= 0)
00530 return True;
00531 return False;
00532 #else
00533 return True;
00534 #endif
00535 }
00536
00537 int
00538 SessionLog::get_nb_clients()
00539 {
00540 ClientInfo *conninfo =
00541 (ClientInfo *)XM_ADDR(xm_connlog, connhead->conn_first);
00542
00543 int nb_clients = 0;
00544 for (int n = connhead->nconns-1; n >= 1; n--)
00545 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next);
00546
00547 while(conninfo) {
00548 if (check_server(conninfo))
00549 nb_clients++;
00550
00551 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_prev);
00552 }
00553
00554 return nb_clients;
00555 }
00556
00557 void SessionLog::display(FILE *fd, Bool nolock)
00558 {
00559 int n;
00560 ClientInfo *conninfo;
00561
00562 if (!connhead)
00563 {
00564 fprintf(fd, "EyeDB Server %s:%s is down\n", host, port);
00565 return;
00566 }
00567
00568 if (!nolock) {
00569 #ifdef TRACE
00570 fprintf(stderr, "SessionLog %d tries to locked\n", rpc_getpid());
00571 #endif
00572 eyedbsm_mutexLock(xm_connlog->mp, 0);
00573 #ifdef TRACE
00574 fprintf(stderr, "SessionLog %d is locked\n", rpc_getpid());
00575 #endif
00576 islocked = True;
00577 }
00578 else if (sesslog && sesslog->islocked) {
00579 #ifdef TRACE
00580 fprintf(stderr, "Warning SessionLog is locked by %d\n",
00581 sesslog->connhead->pid);
00582 #endif
00583 }
00584
00585 if (!connhead->up) {
00586 fprintf(fd, "EyeDB Server %s:%s is down from %s", host, port,
00587 ctime(&connhead->start));
00588 if (!nolock) {
00589 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00590 #ifdef TRACE
00591 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00592 #endif
00593 islocked = False;
00594 }
00595 return;
00596 }
00597
00598 fprintf(fd, "EyeDB Server running since %s\n",
00599 ctime(&connhead->start));
00600
00601 fprintf(fd, " Version V%s\n", connhead->version);
00602 fprintf(fd, " Date %s\n", getCompilationTime());
00603 fprintf(fd, " Architecture %s\n", Architecture::getArchitecture()->getArch());
00604 fprintf(fd, " Program Pid %d\n", connhead->pid);
00605 fprintf(fd, " Running Under %s\n\n", getUserName(connhead->uid));
00606
00607 #ifdef HAVE_EYEDBSMD
00608 fprintf(fd, " SMD Port %s\n", connhead->smdport);
00609 #endif
00610
00611 fprintf(fd, " Listening on ");
00612
00613 const char *indent;
00614 if (connhead->nports > 1) {
00615 indent = "\n ";
00616 }
00617 else
00618 indent = "";
00619
00620 for (n = 0; n < connhead->nports; n++) {
00621 fprintf(fd, "%s%s:%s", (n ? indent : ""), connhead->hosts[n],
00622 connhead->ports[n]);
00623 }
00624
00625 fprintf(fd, "\n Datafile Directory %s\n", connhead->datdir);
00626
00627 if (*connhead->logdev) {
00628 fprintf(fd, " Log Device '%s'\n", connhead->logdev);
00629 if (connhead->loglevel)
00630 fprintf(fd, " Log Level %d\n", connhead->loglevel);
00631 }
00632
00633 fprintf(fd, "\n");
00634
00635 int nb_clients = get_nb_clients();
00636 if (!nb_clients) {
00637 fprintf(fd, " No Clients connected.\n");
00638 if (!nolock) {
00639 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00640 #ifdef TRACE
00641 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00642 #endif
00643 islocked = False;
00644 }
00645 return;
00646 }
00647
00648 fprintf(fd, " %d Client%s connected\n\n",
00649 nb_clients, nb_clients > 1 ? "s" : "");
00650
00651 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, connhead->conn_first);
00652
00653 for (n = connhead->nconns-1; n >= 1; n--)
00654 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next);
00655
00656 for (n = 0; conninfo;
00657 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_prev)) {
00658
00659
00660 if (!check_server(conninfo))
00661 continue;
00662
00663 fprintf(fd, "%sClient #%d\n", (n ? "\n" : ""), n);
00664 fprintf(fd, " Connected on %s", ctime(&conninfo->start));
00665 if (*conninfo->hostname && *conninfo->portname)
00666 fprintf(fd, " Host:Port %s:%s\n", conninfo->hostname,
00667 conninfo->portname);
00668 if (*conninfo->username)
00669 fprintf(fd, " User Name %s\n", conninfo->username);
00670 if (*conninfo->progname)
00671 fprintf(fd, " Program Name %s\n", conninfo->progname);
00672 if (conninfo->prog_pid)
00673 fprintf(fd, " Client Pid %d\n", conninfo->prog_pid);
00674 if (conninfo->backend_pid)
00675 fprintf(fd, " EyeDB Server Pid %d\n", conninfo->backend_pid);
00676
00677 if (conninfo->n_dbs) {
00678 fprintf(fd, " Open Database%s ", conninfo->n_dbs > 1 ? "s" : "");
00679 for (int j = 0; j < conninfo->n_dbs; j++) {
00680 fprintf(fd, "%s'%s' [mode=%s]", (j?"\n ":""),
00681 conninfo->dbs[j].dbname,
00682 Database::getStringFlag((Database::OpenFlag)conninfo->dbs[j].flags));
00683 if (*conninfo->dbs[j].userauth)
00684 fprintf(fd, " [userauth=%s]", conninfo->dbs[j].userauth);
00685 }
00686 fprintf(fd, "\n");
00687 }
00688 else
00689 fprintf(fd, " No Opened Databases\n");
00690
00691 n++;
00692 }
00693
00694 if (!nolock) {
00695 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00696 #ifdef TRACE
00697 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00698 #endif
00699 islocked = False;
00700 }
00701 }
00702
00703 void SessionLog::remove()
00704 {
00705 connhead->up = 0;
00706 time(&connhead->start);
00707
00708 for (int i = 0; i < file_cnt; i++)
00709 unlink(files[i]);
00710 }
00711
00712 Bool SessionLog::isUp() const
00713 {
00714 return connhead && connhead->up ? True : False;
00715 }
00716
00717 Status
00718 SessionLog::stopServers(Bool force)
00719 {
00720 if (!connhead || !xm_connlog)
00721 return Exception::make("EyeDB Server %s:%s is down", host, port);
00722
00723 if (!connhead || !connhead->up)
00724 return Exception::make("EyeDB Server %s:%s is already down from %s",
00725 host, port, ctime(&connhead->start));
00726
00727 int nb_clients = get_nb_clients();
00728 if (nb_clients && !force) {
00729 return Exception::make
00730 (IDB_ERROR, "%d client%s %s connected.\n"
00731 "Use the `stop -f' option to force the servers to stop.",
00732 nb_clients,
00733 (nb_clients > 1 ? "s" : ""),
00734 (nb_clients > 1 ? "are" : "is"));
00735 }
00736
00737
00738
00739 ClientInfo *conninfo =
00740 (ClientInfo *)XM_ADDR(xm_connlog, connhead->conn_first);
00741
00742 while (conninfo) {
00743 if (check_server(conninfo)) {
00744 fprintf(stderr, "Killing Client Backend Pid %d\n",
00745 conninfo->backend_pid);
00746 kill(conninfo->backend_pid, SIGTERM);
00747 }
00748 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next);
00749 }
00750
00751 fprintf(stderr, "Killing EyeDB Server Pid %d\n", connhead->pid);
00752 kill(connhead->pid, SIGTERM);
00753
00754
00755 return Success;
00756 }
00757
00758 void
00759 SessionLog::release()
00760 {
00761
00762
00763
00764
00765 }
00766
00767 SessionLog::~SessionLog()
00768 {
00769 free(vd);
00770 }
00771
00772 ClientSessionLog::ClientSessionLog(ClientInfo *_clinfo)
00773 : clinfo(_clinfo)
00774 {
00775 }
00776
00777 void
00778 ClientSessionLog::addDatabase(const char *name, const char *userauth,
00779 int flags)
00780 {
00781 if (clinfo->n_dbs < MAXDBS) {
00782 if (!userauth)
00783 userauth = "";
00784
00785 strcpy(clinfo->dbs[clinfo->n_dbs].dbname, name);
00786 strcpy(clinfo->dbs[clinfo->n_dbs].userauth, userauth);
00787 clinfo->dbs[clinfo->n_dbs].flags = flags;
00788 clinfo->n_dbs++;
00789 }
00790 }
00791
00792 void
00793 ClientSessionLog::suppressDatabase(const char *name, const char *userauth,
00794 int flags)
00795 {
00796 if (!userauth)
00797 userauth = "";
00798
00799 for (int i = 0; i < clinfo->n_dbs; i++)
00800 if (!strcmp(clinfo->dbs[i].dbname, name) &&
00801 !strcmp(clinfo->dbs[i].userauth, userauth) &&
00802 clinfo->dbs[i].flags == flags) {
00803 for (int j = i; j < clinfo->n_dbs-1; j++) {
00804 strcpy(clinfo->dbs[j].dbname, clinfo->dbs[j+1].dbname);
00805 strcpy(clinfo->dbs[j].userauth, clinfo->dbs[j+1].userauth);
00806 clinfo->dbs[j].flags = clinfo->dbs[j+1].flags;
00807 }
00808
00809 clinfo->n_dbs--;
00810 return;
00811 }
00812 }
00813 }