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
00231 if (*s == '/')
00232 s++;
00233
00234 for (;;) {
00235 int stopafter = 0;
00236 if (!(p = strchr(s, '/'))) {
00237 p = s + strlen(s);
00238 stopafter = 1;
00239 }
00240
00241 char *q = (char *)malloc(p-s+1);
00242 strncpy(q, s, p-s);
00243 q[p-s] = 0;
00244 if (!strcmp(q, "..")) {
00245 sx_cnt--;
00246 free(sx[sx_cnt]);
00247 free(q);
00248 }
00249 else {
00250 if (sx_cnt >= sx_alloc) {
00251 sx_alloc++;
00252 sx = (char **)realloc(sx, sx_alloc*sizeof(char *));
00253 }
00254 sx[sx_cnt] = q;
00255 sx_cnt++;
00256 }
00257
00258 if (stopafter)
00259 break;
00260 s = p+1;
00261 }
00262
00263 #if 1
00264 std::string str;
00265 for (int i = 0; i < sx_cnt; i++) {
00266 str += "/";
00267 str += sx[i];
00268 free(sx[i]);
00269 }
00270 char* r = strdup(str.c_str());
00271 #else
00272 char *r = (char *)malloc(strlen(s)+1);
00273 *r = 0;
00274 for (int i = 0; i < sx_cnt; i++) {
00275 strcat(r, "/");
00276 strcat(r, sx[i]);
00277 free(sx[i]);
00278 }
00279 #endif
00280
00281 free(sx);
00282 free(os);
00283 return r;
00284 }
00285
00286 char *
00287 SessionLog::makeFile(const char *_host, const char *_port, const char *_logdir)
00288 {
00289 static const char conn_prefix[] = ".eyedb_";
00290 static const char conn_suffix[] = ".con";
00291 char hostname[256] = {0};
00292 char *file;
00293
00294 if (!_logdir || !_port)
00295 return 0;
00296
00297 port = strdup(_port);
00298 host = strdup(_host);
00299
00300
00301 std::string host_port = std::string(host) + ":" + _port;
00302 char *port_file = truedir(host_port.c_str());
00303
00304 char *p = port_file;
00305 while (p = strchr(p, '/'))
00306 *p = '_';
00307
00308 logdir = strdup(_logdir ? _logdir : "/tmp");
00309
00310 gethostname(hostname, sizeof(hostname)-1);
00311
00312 file = (char *)malloc(strlen(logdir) +
00313 1 +
00314 strlen(conn_prefix) +
00315 strlen(port_file) +
00316 1 +
00317 strlen(hostname) +
00318 strlen(conn_suffix) +
00319 1);
00320
00321 sprintf(file, "%s/%s%s_%s%s", logdir, conn_prefix, port_file, hostname,
00322 conn_suffix);
00323
00324 return file;
00325 }
00326
00327 Status
00328 SessionLog::openRealize(const char *host, const char *port,
00329 const char *logdir, Bool create,
00330 Bool writing)
00331 {
00332 Error err = (create ? IDB_SESSION_LOG_CREATION_ERROR :
00333 IDB_SESSION_LOG_OPEN_ERROR);
00334 int fd;
00335 file_cnt = 1;
00336 files = (char **)malloc(file_cnt * sizeof(char *));
00337 files[0] = makeFile(host, port, logdir);
00338
00339
00340 writing = True;
00341
00342 xm_connlog = 0;
00343
00344 if (!files[0])
00345 return Exception::make(err, "eyedb environment error");
00346
00347 if (create)
00348 fd = open(files[0], O_CREAT | O_TRUNC | O_RDWR,
00349 0644 );
00350 else {
00351 if (access(files[0], F_OK) < 0)
00352 return Exception::make(IDB_CONNECTION_LOG_FILE_ERROR,
00353 "cannot access connection file '%s'",
00354 files[0]);
00355
00356 if (access(files[0], R_OK) < 0)
00357 return Exception::make(IDB_SESSION_LOG_OPEN_ERROR,
00358 "cannot open connection file '%s' "
00359 "for reading", files[0]);
00360
00361 if (writing) {
00362 if (access(files[0], W_OK) < 0)
00363 return Exception::make(IDB_SESSION_LOG_OPEN_ERROR,
00364 "cannot open connection file '%s' "
00365 "for writing", files[0]);
00366
00367 fd = open(files[0], O_RDWR);
00368 }
00369 else
00370 fd = open(files[0], O_RDONLY);
00371 }
00372
00373 if (fd < 0 && create)
00374 return Exception::make(err,
00375 "cannot %s connection file '%s'",
00376 (create ? "create" :
00377 "open"), files[0]);
00378 if (fd < 0)
00379 return Exception::make(IDB_SESSION_LOG_OPEN_ERROR,
00380 "cannot open connection file '%s'",
00381 files[0]);
00382
00383 if (create && ftruncate(fd, CONNLOG_SIZE) < 0) {
00384 close(fd);
00385 return Exception::make(err,
00386 "cannot create connection file '%s'", files[0]);
00387 }
00388
00389 unsigned int prot = PROT_READ;
00390 if (writing)
00391 prot |= PROT_WRITE;
00392 if (!(m_connlog = m_mmap(0, CONNLOG_SIZE, prot,
00393 MAP_SHARED, fd, 0, (char **)&addr_connlog,
00394 files[0], 0, 0))) {
00395 close(fd);
00396 return Exception::make(err,
00397 "cannot map connection file '%s' for size %d",
00398 files[0], CONNLOG_SIZE);
00399 }
00400
00401 if (!create) {
00402 struct stat st;
00403 if (fstat(fd, &st) < 0) {
00404 close(fd);
00405 return Exception::make(err, "cannot stat connection "
00406 "log file '%s'", files[0]);
00407 }
00408
00409 if (st.st_size < CONNLOG_SIZE && ftruncate(fd, CONNLOG_SIZE) < 0) {
00410 close(fd);
00411 return Exception::make(err,
00412 "cannot create connection "
00413 "log file '%s'", files[0]);
00414 }
00415 }
00416
00417 close(fd);
00418 m_lock(m_connlog);
00419
00420 connhead = (SessionHead *)addr_connlog;
00421
00422 if (create)
00423 xm_connlog = eyedbsm::XMCreate(addr_connlog + sizeof(SessionHead),
00424 CONNLOG_SIZE - sizeof(SessionHead), vd);
00425 else
00426 xm_connlog = eyedbsm::XMOpen(addr_connlog + sizeof(SessionHead), vd);
00427
00428 if (!xm_connlog)
00429 return Exception::make(err,
00430 "cannot map connection file '%s' for size %d",
00431 files[0], CONNLOG_SIZE);
00432 return Success;
00433 }
00434
00435 Status
00436 SessionLog::add(const char *hostname, const char *portname,
00437 const char *username,
00438 const char *progname, int pid,
00439 ClientSessionLog*& clientLog)
00440 {
00441 ClientInfo *conninfo =
00442 (ClientInfo *)XMAlloc(xm_connlog, sizeof(ClientInfo));
00443
00444 if (!conninfo)
00445 return Exception::make(IDB_SESSION_LOG_NO_SPACE_LEFT,
00446 "no space left on connection file");
00447
00448 memset(conninfo, 0, sizeof(*conninfo));
00449
00450 time(&conninfo->start);
00451 strncpy(conninfo->hostname, hostname, sizeof(conninfo->hostname)-1);
00452 strncpy(conninfo->portname, portname, sizeof(conninfo->portname)-1);
00453 strncpy(conninfo->username, username, sizeof(conninfo->username)-1);
00454 strncpy(conninfo->progname, progname, sizeof(conninfo->progname)-1);
00455
00456 conninfo->prog_pid = pid;
00457 conninfo->backend_pid = rpc_getpid();
00458
00459 #ifdef TRACE
00460 fprintf(stderr, "SessionLog %d tries to locked\n", rpc_getpid());
00461 #endif
00462 eyedbsm_mutexLock(xm_connlog->mp, 0);
00463 #ifdef TRACE
00464 fprintf(stderr, "SessionLog %d is locked\n", rpc_getpid());
00465 #endif
00466 islocked = True;
00467
00468 conninfo->conn_next = connhead->conn_first;
00469 conninfo->conn_prev = XM_NULLOFFSET;
00470
00471 if (connhead->conn_first) {
00472 ClientInfo *first = (ClientInfo *)
00473 XM_ADDR(xm_connlog, connhead->conn_first);
00474 first->conn_prev = XM_OFFSET(xm_connlog, conninfo);
00475 }
00476
00477 connhead->conn_first = XM_OFFSET(xm_connlog, conninfo);
00478 connhead->nconns++;
00479
00480 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00481 #ifdef TRACE
00482 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00483 #endif
00484 islocked = False;
00485
00486 clientLog = new ClientSessionLog(conninfo);
00487
00488 #ifdef TRACE
00489 fprintf(stderr, "log add (%s, %s, %s, %d, %d)\n",
00490 hostname, username, progname, pid, rpc_getpid());
00491 #endif
00492
00493 return Success;
00494 }
00495
00496 void
00497 SessionLog::suppress(ClientSessionLog *clientLog)
00498 {
00499 ClientInfo *conninfo = clientLog->getClientInfo();
00500
00501 #ifdef TRACE
00502 fprintf(stderr, "SessionLog %d tries to locked\n", rpc_getpid());
00503 #endif
00504 eyedbsm_mutexLock(xm_connlog->mp, 0);
00505 #ifdef TRACE
00506 fprintf(stderr, "SessionLog %d is locked\n", rpc_getpid());
00507 #endif
00508 islocked = True;
00509
00510 if (conninfo->conn_next)
00511 ((ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next))->conn_prev =
00512 conninfo->conn_prev;
00513
00514 if (conninfo->conn_prev)
00515 ((ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_prev))->conn_next =
00516 conninfo->conn_next;
00517 else
00518 connhead->conn_first = conninfo->conn_next;
00519
00520 #ifdef TRACE
00521 fprintf(stderr, "log suppress (%s, %s, %s, %d, %d)\n",
00522 conninfo->hostname, conninfo->username, conninfo->progname,
00523 conninfo->prog_pid, conninfo->backend_pid);
00524 #endif
00525
00526 connhead->nconns--;
00527 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00528 #ifdef TRACE
00529 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00530 #endif
00531 islocked = False;
00532
00533 XMFree(xm_connlog, conninfo);
00534 }
00535
00536 static Bool
00537 check_server(ClientInfo *conninfo)
00538 {
00539 #ifdef HAVE_SLASH_PROC
00540 if (access((std::string("/proc/") + str_convert((long)conninfo->backend_pid)).c_str(),
00541 F_OK) >= 0)
00542 return True;
00543 return False;
00544 #else
00545 return True;
00546 #endif
00547 }
00548
00549 int
00550 SessionLog::get_nb_clients()
00551 {
00552 ClientInfo *conninfo =
00553 (ClientInfo *)XM_ADDR(xm_connlog, connhead->conn_first);
00554
00555 int nb_clients = 0;
00556 for (int n = connhead->nconns-1; n >= 1; n--)
00557 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next);
00558
00559 while(conninfo) {
00560 if (check_server(conninfo))
00561 nb_clients++;
00562
00563 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_prev);
00564 }
00565
00566 return nb_clients;
00567 }
00568
00569 void SessionLog::display(FILE *fd, Bool nolock)
00570 {
00571 int n;
00572 ClientInfo *conninfo;
00573
00574 if (!connhead)
00575 {
00576 fprintf(fd, "EyeDB Server %s:%s is down\n", host, port);
00577 return;
00578 }
00579
00580 if (!nolock) {
00581 #ifdef TRACE
00582 fprintf(stderr, "SessionLog %d tries to locked\n", rpc_getpid());
00583 #endif
00584 eyedbsm_mutexLock(xm_connlog->mp, 0);
00585 #ifdef TRACE
00586 fprintf(stderr, "SessionLog %d is locked\n", rpc_getpid());
00587 #endif
00588 islocked = True;
00589 }
00590 else if (sesslog && sesslog->islocked) {
00591 #ifdef TRACE
00592 fprintf(stderr, "Warning SessionLog is locked by %d\n",
00593 sesslog->connhead->pid);
00594 #endif
00595 }
00596
00597 if (!connhead->up) {
00598 fprintf(fd, "EyeDB Server %s:%s is down from %s", host, port,
00599 ctime(&connhead->start));
00600 if (!nolock) {
00601 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00602 #ifdef TRACE
00603 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00604 #endif
00605 islocked = False;
00606 }
00607 return;
00608 }
00609
00610 fprintf(fd, "EyeDB Server running since %s\n",
00611 ctime(&connhead->start));
00612
00613 fprintf(fd, " Version V%s\n", connhead->version);
00614 fprintf(fd, " Date %s\n", getCompilationTime());
00615 fprintf(fd, " Architecture %s\n", Architecture::getArchitecture()->getArch());
00616 fprintf(fd, " Program Pid %d\n", connhead->pid);
00617 fprintf(fd, " Running Under %s\n\n", getUserName(connhead->uid));
00618
00619 #ifdef HAVE_EYEDBSMD
00620 fprintf(fd, " SMD Port %s\n", connhead->smdport);
00621 #endif
00622
00623 fprintf(fd, " Listening on ");
00624
00625 const char *indent;
00626 if (connhead->nports > 1) {
00627 indent = "\n ";
00628 }
00629 else
00630 indent = "";
00631
00632 for (n = 0; n < connhead->nports; n++) {
00633 fprintf(fd, "%s%s:%s", (n ? indent : ""), connhead->hosts[n],
00634 connhead->ports[n]);
00635 }
00636
00637 fprintf(fd, "\n Datafile Directory %s\n", connhead->datdir);
00638
00639 if (*connhead->logdev) {
00640 fprintf(fd, " Log Device '%s'\n", connhead->logdev);
00641 if (connhead->loglevel)
00642 fprintf(fd, " Log Level %d\n", connhead->loglevel);
00643 }
00644
00645 fprintf(fd, "\n");
00646
00647 int nb_clients = get_nb_clients();
00648 if (!nb_clients) {
00649 fprintf(fd, " No Clients connected.\n");
00650 if (!nolock) {
00651 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00652 #ifdef TRACE
00653 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00654 #endif
00655 islocked = False;
00656 }
00657 return;
00658 }
00659
00660 fprintf(fd, " %d Client%s connected\n\n",
00661 nb_clients, nb_clients > 1 ? "s" : "");
00662
00663 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, connhead->conn_first);
00664
00665 for (n = connhead->nconns-1; n >= 1; n--)
00666 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next);
00667
00668 for (n = 0; conninfo;
00669 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_prev)) {
00670
00671
00672 if (!check_server(conninfo))
00673 continue;
00674
00675 fprintf(fd, "%sClient #%d\n", (n ? "\n" : ""), n);
00676 fprintf(fd, " Connected on %s", ctime(&conninfo->start));
00677 if (*conninfo->hostname && *conninfo->portname)
00678 fprintf(fd, " Host:Port %s:%s\n", conninfo->hostname,
00679 conninfo->portname);
00680 if (*conninfo->username)
00681 fprintf(fd, " User Name %s\n", conninfo->username);
00682 if (*conninfo->progname)
00683 fprintf(fd, " Program Name %s\n", conninfo->progname);
00684 if (conninfo->prog_pid)
00685 fprintf(fd, " Client Pid %d\n", conninfo->prog_pid);
00686 if (conninfo->backend_pid)
00687 fprintf(fd, " EyeDB Server Pid %d\n", conninfo->backend_pid);
00688
00689 if (conninfo->n_dbs) {
00690 fprintf(fd, " Open Database%s ", conninfo->n_dbs > 1 ? "s" : "");
00691 for (int j = 0; j < conninfo->n_dbs; j++) {
00692 fprintf(fd, "%s'%s' [mode=%s]", (j?"\n ":""),
00693 conninfo->dbs[j].dbname,
00694 Database::getStringFlag((Database::OpenFlag)conninfo->dbs[j].flags));
00695 if (*conninfo->dbs[j].userauth)
00696 fprintf(fd, " [userauth=%s]", conninfo->dbs[j].userauth);
00697 }
00698 fprintf(fd, "\n");
00699 }
00700 else
00701 fprintf(fd, " No Opened Databases\n");
00702
00703 n++;
00704 }
00705
00706 if (!nolock) {
00707 eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00708 #ifdef TRACE
00709 fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00710 #endif
00711 islocked = False;
00712 }
00713 }
00714
00715 void SessionLog::remove()
00716 {
00717 connhead->up = 0;
00718 time(&connhead->start);
00719
00720 for (int i = 0; i < file_cnt; i++)
00721 unlink(files[i]);
00722 }
00723
00724 Bool SessionLog::isUp() const
00725 {
00726 return connhead && connhead->up ? True : False;
00727 }
00728
00729 Status
00730 SessionLog::stopServers(Bool force)
00731 {
00732 if (!connhead || !xm_connlog)
00733 return Exception::make("EyeDB Server %s:%s is down", host, port);
00734
00735 if (!connhead || !connhead->up)
00736 return Exception::make("EyeDB Server %s:%s is already down from %s",
00737 host, port, ctime(&connhead->start));
00738
00739 int nb_clients = get_nb_clients();
00740 if (nb_clients && !force) {
00741 return Exception::make
00742 (IDB_ERROR, "%d client%s %s connected.\n"
00743 "Use the `stop -f' option to force the servers to stop.",
00744 nb_clients,
00745 (nb_clients > 1 ? "s" : ""),
00746 (nb_clients > 1 ? "are" : "is"));
00747 }
00748
00749
00750
00751 ClientInfo *conninfo =
00752 (ClientInfo *)XM_ADDR(xm_connlog, connhead->conn_first);
00753
00754 while (conninfo) {
00755 if (check_server(conninfo)) {
00756 fprintf(stderr, "Killing Client Backend Pid %d\n",
00757 conninfo->backend_pid);
00758 kill(conninfo->backend_pid, SIGTERM);
00759 }
00760 conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next);
00761 }
00762
00763 fprintf(stderr, "Killing EyeDB Server Pid %d\n", connhead->pid);
00764 kill(connhead->pid, SIGTERM);
00765
00766
00767 return Success;
00768 }
00769
00770 void
00771 SessionLog::release()
00772 {
00773
00774
00775
00776
00777 }
00778
00779 SessionLog::~SessionLog()
00780 {
00781 free(vd);
00782 }
00783
00784 ClientSessionLog::ClientSessionLog(ClientInfo *_clinfo)
00785 : clinfo(_clinfo)
00786 {
00787 }
00788
00789 void
00790 ClientSessionLog::addDatabase(const char *name, const char *userauth,
00791 int flags)
00792 {
00793 if (clinfo->n_dbs < MAXDBS) {
00794 if (!userauth)
00795 userauth = "";
00796
00797 strcpy(clinfo->dbs[clinfo->n_dbs].dbname, name);
00798 strcpy(clinfo->dbs[clinfo->n_dbs].userauth, userauth);
00799 clinfo->dbs[clinfo->n_dbs].flags = flags;
00800 clinfo->n_dbs++;
00801 }
00802 }
00803
00804 void
00805 ClientSessionLog::suppressDatabase(const char *name, const char *userauth,
00806 int flags)
00807 {
00808 if (!userauth)
00809 userauth = "";
00810
00811 for (int i = 0; i < clinfo->n_dbs; i++)
00812 if (!strcmp(clinfo->dbs[i].dbname, name) &&
00813 !strcmp(clinfo->dbs[i].userauth, userauth) &&
00814 clinfo->dbs[i].flags == flags) {
00815 for (int j = i; j < clinfo->n_dbs-1; j++) {
00816 strcpy(clinfo->dbs[j].dbname, clinfo->dbs[j+1].dbname);
00817 strcpy(clinfo->dbs[j].userauth, clinfo->dbs[j+1].userauth);
00818 clinfo->dbs[j].flags = clinfo->dbs[j+1].flags;
00819 }
00820
00821 clinfo->n_dbs--;
00822 return;
00823 }
00824 }
00825 }