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 #if TIME_WITH_SYS_TIME
00027 #include <sys/time.h>
00028 #include <time.h>
00029 #else
00030 #if HAVE_SYS_TIME_H
00031 #include <sys/time.h>
00032 #else
00033 #include <time.h>
00034 #endif
00035 #endif
00036
00037 #include <sys/types.h>
00038 #include <sys/socket.h>
00039 #include <sys/uio.h>
00040 #include <sys/un.h>
00041 #include <netdb.h>
00042 #include <netinet/in.h>
00043 #include <unistd.h>
00044 #include <sys/wait.h>
00045 #include <sys/types.h>
00046 #include <sys/select.h>
00047 #include <signal.h>
00048 #include <unistd.h>
00049 #include <fcntl.h>
00050 #include <sys/stat.h>
00051 #include <errno.h>
00052
00053
00054 #include <eyedblib/rpc_lib.h>
00055 #include <eyedblib/stdlist.h>
00056 #include <eyedblib/semlib.h>
00057 #include <eyedblib/filelib.h>
00058 #include <eyedblib/filelib.h>
00059 #include <eyedbsm/smd.h>
00060 #include <eyedblib/log.h>
00061 #include <kern_p.h>
00062
00063 #define USE_INODE
00064
00065 using namespace eyedbsm;
00066
00067 static int smd_refcnt;
00068
00069
00070 static void clean_exit(int from);
00071
00072 class Reference {
00073
00074 protected:
00075 Reference() {
00076 refcnt = 1;
00077 }
00078
00079 void incrRefCount() {
00080 refcnt++;
00081 }
00082
00083 int decrRefCount() {
00084 return --refcnt;
00085 }
00086
00087 public:
00088 int getRefCount() const {
00089 return refcnt;
00090 }
00091
00092 private:
00093 int refcnt;
00094 };
00095
00096 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00097 class Semaphore : public Reference {
00098 int key;
00099 int excl;
00100 static std::list<Semaphore *> sem_list;
00101
00102 Semaphore(int _key, int _excl) : Reference() {
00103 key = _key;
00104 excl = _excl;
00105 #ifdef TRACE
00106 fprintf(stderr, "eyedbsmd: creating semaphore ");
00107 trace();
00108 fprintf(stderr, "\n");
00109 #endif
00110 sem_list.push_back(this);
00111 }
00112
00113 public:
00114 int isExcl() const {
00115 return excl;
00116 }
00117
00118 int getKey() const {
00119 return key;
00120 }
00121
00122 void release() {
00123 #ifdef TRACE
00124 fprintf(stderr, "eyedbsmd: releasing semaphore 0x%08x [refcnt:%d]\n", key, getRefCount());
00125 #endif
00126 if (!decrRefCount()) {
00127 bool r = std_list_erase(sem_list, this);
00128 if (!r)
00129 std::cerr << "Warning: semaphore::release " << key << "not found\n";
00130 delete this;
00131 }
00132 }
00133
00134 ~Semaphore() {
00135 #ifdef TRACE
00136 fprintf(stderr, "eyedbsmd: deleting key 0x%08x\n", key);
00137 #endif
00138 ut_sem_rm(ut_sem_open(key));
00139 }
00140
00141 void trace() {
00142 fprintf(stderr, "eyedbsmd: key 0x%08x [%s]", key, (excl ? "excl" : "shared"));
00143 }
00144
00145 static Semaphore *find(int excl) {
00146 int key;
00147 Semaphore *sem;
00148
00149 if (ut_sem_find(&key, excl) >= 0)
00150 return new Semaphore(key, excl);
00151
00152 std::list<Semaphore *>::const_iterator begin = sem_list.begin();
00153 std::list<Semaphore *>::const_iterator end = sem_list.end();
00154
00155 while (begin != end ) {
00156 Semaphore *sem = *begin;
00157 if (!sem->isExcl()) {
00158 sem->incrRefCount();
00159 return sem;
00160 }
00161 ++begin;
00162 }
00163
00164 #ifdef TRACE
00165 fprintf(stderr, "eyedbsmd: cannot find any semaphore\n");
00166 #endif
00167 return 0;
00168 }
00169
00170 static void traceList() {
00171 std::list<Semaphore *>::const_iterator begin = sem_list.begin();
00172 std::list<Semaphore *>::const_iterator end = sem_list.end();
00173
00174 while (begin != end ) {
00175 Semaphore *sem = *begin;
00176 sem->trace();
00177 ++begin;
00178 }
00179 }
00180 };
00181 #endif
00182
00183 class DbFile : public Reference {
00184 #ifdef USE_INODE
00185 ino_t ino;
00186 dev_t dev;
00187 char *dbfile;
00188 #else
00189 char *dbfile;
00190 #endif
00191
00192 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00193 Semaphore *sm[ESM_NSEMS];
00194 #endif
00195 static std::list<DbFile *> dbfile_list;
00196
00197 DbFile(const char *_dbfile) : Reference() {
00198 #ifdef USE_INODE
00199 struct stat st;
00200 if (stat(_dbfile, &st) >= 0) {
00201 ino = st.st_ino;
00202 dev = st.st_dev;
00203 }
00204 else {
00205 #ifdef TRACE
00206 fprintf(stderr, "eyedbsmd: cannot stat file %s\n", _dbfile);
00207 #endif
00208 ino = 0;
00209 dev = 0;
00210 }
00211
00212 dbfile = strdup(_dbfile);
00213 #else
00214 dbfile = strdup(_dbfile);
00215 #endif
00216
00217 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00218 sm[0] = Semaphore::find(1);
00219 sm[1] = Semaphore::find(0);
00220 #endif
00221 dbfile_list.push_back(this);
00222 #ifdef TRACE
00223 fprintf(stderr, "eyedbsmd: creating dbfile ");
00224 trace();
00225 fprintf(stderr, "\n");
00226 #endif
00227 }
00228
00229 ~DbFile() {
00230 free(dbfile);
00231 #ifdef TRACE
00232 fprintf(stderr, "eyedbsmd: deleting dbfile %s\n", getDbfile());
00233 #endif
00234 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00235 for (int i = 0; i < ESM_NSEMS; i++)
00236 if (sm[i]) sm[i]->release();
00237 #endif
00238 }
00239
00240 public:
00241
00242 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00243 int getSemaphores(int sx[]) const {
00244 for (int i = 0; i < ESM_NSEMS; i++)
00245 sx[i] = (sm[i] ? sm[i]->getKey() : 0);
00246
00247 return 0;
00248 }
00249 #endif
00250
00251 #if 0
00252 const char *getDbfile() const {
00253 static std::string st_dbfile;
00254 char buf[64];
00255 sprintf(buf, "dev=%d,ino=%d", dev, ino);
00256 st_dbfile = buf;
00257 return st_dbfile.c_str();
00258 }
00259 #else
00260 const char *getDbfile() const {
00261 return dbfile;
00262 }
00263 #endif
00264
00265 void release() {
00266 #ifdef TRACE
00267 fprintf(stderr, "eyedbsmd: releasing dbfile %s [refcnt:%d]\n", getDbfile(), getRefCount());
00268 #endif
00269 if (!decrRefCount()) {
00270 bool r = std_list_erase(dbfile_list, this);
00271 #ifdef TRACE
00272 if (!r)
00273 std::cerr << "Warning: DbFile::release " << getDbfile() << "not found\n";
00274 #endif
00275 delete this;
00276 }
00277 }
00278
00279 static DbFile *find(const char *dbfile, int get_sems, int &found) {
00280 std::list<DbFile *>::const_iterator begin = dbfile_list.begin();
00281 std::list<DbFile *>::const_iterator end = dbfile_list.end();
00282 DbFile *dbf;
00283
00284 #ifdef USE_INODE
00285 struct stat st;
00286 ino_t ino;
00287 dev_t dev;
00288
00289 if (stat(dbfile, &st) >= 0) {
00290 ino = st.st_ino;
00291 dev = st.st_dev;
00292 }
00293 else {
00294 ino = 0;
00295 dev = 0;
00296 }
00297
00298 while (begin != end) {
00299 dbf = *begin;
00300 if (ino && dev) {
00301 if (dbf->ino == ino && dbf->dev == dev) {
00302 if (get_sems)
00303 dbf->incrRefCount();
00304 found = 1;
00305 return dbf;
00306 }
00307 }
00308 else {
00309 if (!strcmp(dbf->dbfile, dbfile)) {
00310 if (get_sems)
00311 dbf->incrRefCount();
00312 found = 1;
00313 return dbf;
00314 }
00315 }
00316 ++begin;
00317 }
00318 #else
00319 while (begin != end) {
00320 dbf = *begin;
00321 if (!strcmp(dbf->dbfile, dbfile)) {
00322 if (get_sems)
00323 dbf->incrRefCount();
00324 found = 1;
00325 return dbf;
00326 }
00327 ++begin;
00328 }
00329 #endif
00330
00331 found = 0;
00332 if (get_sems) {
00333 dbf = new DbFile(dbfile);
00334
00335 Status s = dbCleanup(dbfile);
00336 if (s && s->err != CANNOT_LOCK_SHMFILE)
00337 statusPrint(s, "eyedbsmd");
00338 #ifdef TRACE
00339 if (s)
00340 statusPrint(s, "eyedbsmd");
00341 #endif
00342 return dbf;
00343 }
00344 return 0;
00345 }
00346
00347 void trace() {
00348 fprintf(stderr, "eyedbsmd: %s, ", getDbfile());
00349 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00350 for (int i = 0; i < ESM_NSEMS; i++) {
00351 if (i) fprintf(stderr, ", ");
00352 if (!sm[i]) fprintf(stderr, "*");
00353 else sm[i]->trace();
00354 }
00355 #endif
00356 }
00357
00358 static void traceList() {
00359 std::list<DbFile *>::const_iterator begin = dbfile_list.begin();
00360 std::list<DbFile *>::const_iterator end = dbfile_list.end();
00361 DbFile *dbf;
00362
00363 while (begin != end) {
00364 dbf = *begin;
00365 dbf->trace();
00366 fprintf(stderr, "\n");
00367 ++begin;
00368 }
00369 }
00370 };
00371
00372 class Client {
00373 int fd;
00374 static std::list<Client *> client_list;
00375 std::list<DbFile *> dbfile_list;
00376
00377 public:
00378 Client(int _fd) {
00379 fd = _fd;
00380 #ifdef TRACE
00381 fprintf(stderr, "eyedbsmd: creating client %d\n", fd);
00382 #endif
00383 client_list.push_back(this);
00384 }
00385
00386 void addDbFile(DbFile *dbf) {
00387 dbfile_list.push_back(dbf);
00388
00389 #ifdef TRACE
00390 if (dbf)
00391 fprintf(stderr, "eyedbsmd: adding dbfile %s to client %d [refcnt:%d]\n", dbf->getDbfile(), fd,
00392 dbf->getRefCount());
00393 else
00394 fprintf(stderr, "eyedbsmd: adding null dbfile\n");
00395 #endif
00396 }
00397
00398 void rmDbFile(DbFile *dbf) {
00399 #ifdef TRACE
00400 if (dbf)
00401 fprintf(stderr, "eyedbsmd: removing dbfile %s from client %d\n", dbf->getDbfile(), fd);
00402 else
00403 fprintf(stderr, "eyedbsmd: removing null dbfile\n");
00404 #endif
00405 std::list<DbFile *>::iterator db_begin = dbfile_list.begin();
00406 std::list<DbFile *>::iterator db_end = dbfile_list.end();
00407 while (db_begin != db_end) {
00408 DbFile *xdbf = *db_begin;
00409 if (xdbf == dbf) {
00410 dbf->release();
00411 bool r = std_list_erase(dbfile_list, dbf);
00412 #ifdef TRACE
00413 if (!r)
00414 std::cerr << "Warning: rmDbFile not found\n";
00415 #endif
00416 return;
00417 }
00418 ++db_begin;
00419 }
00420
00421 #ifdef TRACE
00422 fprintf(stderr, "eyedbsmd: dbfile %s not found in client %d\n", dbf->getDbfile(), fd);
00423 #endif
00424 }
00425
00426 ~Client() {
00427 #ifdef TRACE
00428 fprintf(stderr, "eyedbsmd: releasing client %d\n", fd);
00429 #endif
00430 std::list<DbFile *>::iterator db_begin = dbfile_list.begin();
00431 std::list<DbFile *>::iterator db_end = dbfile_list.end();
00432 while (db_begin != db_end) {
00433 DbFile *dbf = *db_begin;
00434 dbf->release();
00435 ++db_begin;
00436 }
00437 bool r = std_list_erase(client_list, this);
00438 #ifdef TRACE
00439 if (!r)
00440 std::cerr << "Warning: Client not found\n";
00441 #endif
00442 }
00443
00444 static void clean_all() {
00445 std::list<Client *>::iterator cl_begin = client_list.begin();
00446 std::list<Client *>::iterator cl_end = client_list.end();
00447
00448 while (cl_begin != cl_end) {
00449 Client *client = *cl_begin;
00450 std::list<DbFile *>::iterator db_begin = client->dbfile_list.begin();
00451 std::list<DbFile *>::iterator db_end = client->dbfile_list.end();
00452 while (db_begin != db_end) {
00453 DbFile *dbf = *db_begin;
00454 dbf->release();
00455 ++db_begin;
00456 }
00457 ++cl_begin;
00458 }
00459 }
00460
00461 static Client *find(int fd) {
00462 std::list<Client *>::iterator begin = client_list.begin();
00463 std::list<Client *>::iterator end = client_list.end();
00464 while (begin != end) {
00465 Client *client = *begin;
00466 if (client->fd == fd)
00467 return client;
00468 ++begin;
00469 }
00470
00471 return 0;
00472 }
00473 };
00474
00475 std::list<DbFile *> DbFile::dbfile_list;
00476
00477 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00478 std::list<Semaphore *> Semaphore::sem_list;
00479 #endif
00480
00481 std::list<Client *> Client::client_list;
00482
00483 static void
00484 unit_test()
00485 {
00486 DbFile *dbf1, *dbf2, *dbf3;
00487 int found;
00488 dbf1 = DbFile::find("foo.dbs", 1, found);
00489 dbf2 = DbFile::find("goo.dbs", 1, found);
00490 dbf3 = DbFile::find("foo.dbs", 1, found);
00491
00492 DbFile::traceList();
00493
00494 fprintf(stderr, "continue> ");
00495 getchar();
00496
00497 dbf1->release();
00498 dbf2->release();
00499 dbf3->release();
00500 }
00501
00502 static struct sockaddr_un sock_un_name;
00503
00504 static int
00505 port_open(const char *port)
00506 {
00507 int sockun_fd;
00508 int v = 1;
00509
00510 rpc_checkAFUnixPort(port);
00511
00512 if ((sockun_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00513 fprintf(stderr, "eyedbsmd: unable to create unix socket port `%d'\n", port);
00514 return -1;
00515 }
00516
00517 if (setsockopt(sockun_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&v, sizeof(v)) <
00518 0) {
00519 fprintf(stderr, "eyedbsmd: setsockopt reuseaddr\n");
00520 return -1;
00521 }
00522
00523 sock_un_name.sun_family = AF_UNIX;
00524 strcpy(sock_un_name.sun_path, port);
00525
00526 if (bind(sockun_fd, (struct sockaddr *)&sock_un_name,
00527 sizeof(sock_un_name)) < 0 ) {
00528 fprintf(stderr, "eyedbsmd: bind: failing on port %s (%s)\n", port,
00529 strerror(errno));
00530 fprintf(stderr, "\nPerharps another eyedbsmd is running on port:\n%s\n",
00531 port);
00532 fprintf(stderr, "\nIf no, unlink this port as follows:\n");
00533 fprintf(stderr, "rm -f %s\n", port);
00534 fprintf(stderr, "and relaunch the server.\n");
00535 return -1;
00536 }
00537
00538 chmod(port, 0777);
00539 if (sockun_fd >= 0 && listen(sockun_fd, 2) < 0 ) {
00540 fprintf(stderr, "eyedbsmd: listen: failing on port %s (%s)\n", port,
00541 strerror(errno));
00542 return -1;
00543 }
00544
00545 return sockun_fd;
00546 }
00547
00548 static void
00549 clear_client(fd_set &fds, int fd, int &max_fd)
00550 {
00551 Client *client = Client::find(fd);
00552 delete client;
00553 FD_CLR(fd, &fds);
00554 close(fd);
00555 if (max_fd == fd)
00556 --max_fd;
00557 }
00558
00559 static const char *
00560 string_message(int msg)
00561 {
00562 if (msg == SMD_INIT)
00563 return "SMD_INIT";
00564
00565 if (msg == SMD_INIT_GETSEMS)
00566 return "SMD_INIT_GETSEMS";
00567
00568 if (msg == SMD_RELEASE)
00569 return "SMD_RELEASE";
00570
00571 if (msg == SMD_STATUS)
00572 return "SMD_STATUS";
00573
00574 if (msg == SMD_DECL)
00575 return "SMD_DECL";
00576
00577 if (msg == SMD_UNDECL)
00578 return "SMD_UNDECL";
00579
00580 if (msg == SMD_STOP)
00581 return "SMD_STOP";
00582
00583 return "UNKNOWN";
00584 }
00585
00586 static int
00587 manage_message(int fd)
00588 {
00589 int msg;
00590 Client *client = Client::find(fd);
00591 if (!client)
00592 return 0;
00593
00594 if (rpc_socketRead(fd, &msg, sizeof(msg)) != sizeof(msg))
00595 return 0;
00596
00597
00598
00599
00600
00601
00602
00603
00604 if (msg == SMD_INIT || msg == SMD_INIT_GETSEMS || msg == SMD_RELEASE) {
00605 int len;
00606 if (rpc_socketRead(fd, &len, sizeof(len)) != sizeof(len))
00607 return 0;
00608
00609 char *dbfile = new char[len];
00610 if (rpc_socketRead(fd, dbfile, len) != len)
00611 return 0;
00612
00613 int found;
00614 DbFile *dbf = DbFile::find(dbfile, (msg == SMD_INIT_GETSEMS ||
00615 msg == SMD_INIT), found);
00616 delete [] dbfile;
00617
00618 if (msg == SMD_INIT_GETSEMS) {
00619 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00620 client->addDbFile(dbf);
00621
00622 int sm[ESM_NSEMS];
00623 dbf->getSemaphores(sm);
00624
00625 if (rpc_socketWrite(fd, sm, sizeof(int)*ESM_NSEMS) !=
00626 sizeof(int)*ESM_NSEMS)
00627 return 0;
00628 #else
00629 assert(0);
00630 #endif
00631 }
00632 else if (msg == SMD_INIT) {
00633 client->addDbFile(dbf);
00634 if (rpc_socketWrite(fd, &msg, sizeof(msg)) != sizeof(msg))
00635 return 0;
00636 }
00637 else
00638 client->rmDbFile(dbf);
00639 }
00640 else if (msg == SMD_STATUS) {
00641 fprintf(stderr, "eyedbsmd: Reference Count: %d\n", smd_refcnt);
00642 DbFile::traceList();
00643 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00644 Semaphore::traceList();
00645 #endif
00646 }
00647 else if (msg == SMD_DECL)
00648 smd_refcnt++;
00649 else if (msg == SMD_UNDECL) {
00650 if (smd_refcnt > 0)
00651 --smd_refcnt;
00652 }
00653 else if (msg == SMD_STOP) {
00654 #ifdef TRACE
00655 fprintf(stderr, "eyedbsmd: smd_refcnt %d\n", smd_refcnt);
00656 #endif
00657 Client::clean_all();
00658 clean_exit(1);
00659 exit(0);
00660 }
00661 else {
00662 fprintf(stderr, "eyedbsmd: unknown message %x\n", msg);
00663 return 0;
00664 }
00665
00666 return 1;
00667 }
00668
00669 static void
00670 net_main_loop(int sock_fd)
00671 {
00672 fd_set fds;
00673 int max_fd = sock_fd, fd;
00674
00675 FD_ZERO(&fds);
00676 FD_SET(sock_fd, &fds);
00677
00678 for (;;) {
00679 #ifdef TRACE
00680 fprintf(stderr, "eyedbsmd: \nwaiting on socket %d, maxfd %d\n", sock_fd, max_fd);
00681 #endif
00682 fd_set fdt = fds;
00683 if (select (max_fd+1, &fdt, 0, 0, 0) < 0) {
00684 perror("select");
00685 continue;
00686 }
00687
00688 for (fd = 0; fd <= max_fd; fd++)
00689 if (FD_ISSET(fd, &fdt)) {
00690 if (fd == sock_fd) {
00691 struct sockaddr *sock_addr;
00692 #if defined(ORIGIN) || defined(ALPHA)
00693 int length;
00694 #else
00695 socklen_t length;
00696 #endif
00697 int input_fd;
00698
00699 sock_addr = (struct sockaddr *)&sock_un_name;
00700 length = sizeof(sock_un_name);
00701
00702 if ((input_fd = accept(fd, sock_addr, &length)) < 0) {
00703 perror("accept");
00704 continue;
00705 }
00706
00707 new Client(input_fd);
00708 FD_SET(input_fd, &fds);
00709 if (input_fd > max_fd)
00710 max_fd = input_fd;
00711 }
00712 else if (!manage_message(fd)) {
00713 clear_client(fds, fd, max_fd);
00714 continue;
00715 }
00716 }
00717 }
00718 }
00719
00720 static const char *port;
00721
00722 static void
00723 clean_exit(int from)
00724 {
00725 #ifdef TRACE
00726 fprintf(stderr, "eyedbsmd: clean_exit(%d)\n", from);
00727 #endif
00728 unlink(port);
00729 }
00730
00731 static void
00732 signal_handler(int sig)
00733 {
00734 #ifdef TRACE
00735 fprintf(stderr, "eyedbsmd: receive signal #%d\n", sig);
00736 #endif
00737 sleep(1000);
00738 clean_exit(2);
00739 exit(sig);
00740 }
00741
00742 static int
00743 notice(int status)
00744 {
00745 const char *s;
00746 if (s = getenv("EYEDBPFD")) {
00747 int pfd = atoi(s);
00748 if (pfd > 0) {
00749 write(pfd, &status, sizeof(status));
00750 close(pfd);
00751 }
00752 }
00753
00754 return status;
00755 }
00756
00757 static void
00758 init()
00759 {
00760 signal(SIGHUP, SIG_IGN);
00761 signal(SIGINT, SIG_IGN);
00762
00763 signal(SIGQUIT, signal_handler);
00764 signal(SIGSEGV, signal_handler);
00765 signal(SIGBUS, signal_handler);
00766 signal(SIGABRT, signal_handler);
00767 }
00768
00769 static int
00770 usage(const char *prog) {
00771 fprintf(stderr, "usage: %s [-p PORT|--port=PORT] [--status] [--stop]\n", prog);
00772 return notice(1);
00773 }
00774
00775 int
00776 main(int argc, char *argv[])
00777 {
00778 enum Action {
00779 Daemon = 1,
00780 Status,
00781 Stop
00782 } action;
00783
00784 action = Daemon;
00785
00786 static const char port_opt[] = "--port=";
00787 unsigned int port_len = strlen(port_opt);
00788
00789 for (int n = 1; n < argc; n++) {
00790 const char *s = argv[n];
00791 if (*s == '-') {
00792 if (!strcmp(s, "-p")) {
00793 if (n == argc-1)
00794 return usage(argv[0]);
00795 smd_set_port(argv[++n]);
00796 }
00797 else if (!strncmp(s, port_opt, port_len)) {
00798 smd_set_port(&argv[n][port_len]);
00799 }
00800 else if (!strcmp(s, "--status")) {
00801 action = Status;
00802 }
00803 else if (!strcmp(s, "--stop")) {
00804 action = Stop;
00805 }
00806 else
00807 return usage(argv[0]);
00808 }
00809 else
00810 return usage(argv[0]);
00811 }
00812
00813 if (action != Daemon) {
00814 smdcli_conn_t *conn = smdcli_open(smd_get_port());
00815
00816 if (!conn)
00817 return 1;
00818
00819 if (action == Stop)
00820 return smdcli_stop(conn);
00821
00822 return smdcli_status(conn);
00823 }
00824
00825 const char *logmask = getenv("IDB_LOG_MASK");
00826 if (logmask) {
00827 utlogInit(argv[0], "stderr");
00828 sscanf(logmask, "%llx", &eyedblib::log_mask);
00829 }
00830
00831 port = smd_get_port();
00832
00833 eyedbsm::init();
00834 ::init();
00835
00836 int sock_fd = port_open(port);
00837 if (sock_fd < 0)
00838 return notice(1);
00839
00840 smd_refcnt = 1;
00841 (void)notice(0);
00842
00843 #ifndef TRACE
00844 close(0);
00845 close(1);
00846 close(2);
00847 #endif
00848 net_main_loop(sock_fd);
00849
00850 clean_exit(3);
00851 return notice(0);
00852 }