void Component::handleStanza(Stanza *stanza) { if(strcmp(stanza->name(), "message") == 0) { if(message_handler) { message_handler->handleMessage(stanza); } else { std::cerr << " [JCE] Got a message, but have no handler for it.\n"; } } if(strcmp(stanza->name(), "presence") == 0) { if(presence_handler) { presence_handler->handlePresence(stanza); } else { std::cerr << " [JCE] Got a presence, but have no handler for it.\n"; } } if(strcmp(stanza->name(), "stream:error") == 0) { if(stream_error_handler) { stream_error_handler->handleStreamError(); } else { std::cerr << " [JCE] Got a stream error, but have no handler for it.\n"; } } if(strcmp(stanza->name(), "handshake") == 0) { if(auth_success_handler) { auth_success_handler->handleHandshake(); } else { std::cerr << " [JCE] Got a successful handshake, but have no handler for it.\n"; } } if(strcmp(stanza->name(), "iq") == 0) { XmlTag *query = stanza->query(); if(query) { const char *query_xmlns = query->getAttribute("xmlns"); } } delete stanza; }
int main(int argc, const char **argv) { // Конфигурация ConfigFile *config = new ConfigFile(PATH_CONFIG); // открыть лог файлы до смены пользователя open_access_log(PATH_ACCESS_LOG); open_error_log(PATH_ERROR_LOG); FILE *fpid = fopen(PATH_PID, "w"); // установить лимиты до смены пользователя if ( getuid() == 0 ) { struct rlimit rl; rl.rlim_cur = config->filesLimit(); rl.rlim_max = config->filesLimit(); if ( setrlimit(RLIMIT_NOFILE, &rl) == -1 ) { fprintf(stderr, "setrlimit fault: %s\n", strerror(errno)); } } else { struct rlimit rl; if ( getrlimit(RLIMIT_NOFILE, &rl) == -1 ) { fprintf(stderr, "getrlimit fault: %s\n", strerror(errno)); } else { rl.rlim_cur = config->filesLimit(); if ( config->filesLimit() > rl.rlim_max ) { fprintf(stderr, "only root can increase over hard limit (RLIMIT_NOFILE)\ntry to increase up to hard limit (%lu)\n", rl.rlim_max); rl.rlim_cur = rl.rlim_max; } if ( setrlimit(RLIMIT_NOFILE, &rl) == -1 ) { fprintf(stderr, "setrlimit fault: %s\n", strerror(errno)); } } } // если запущены под root, то сменить пользователя if ( getuid() == 0 ) { fprintf(stdout, "Trying to switch to user: "******"\n"); struct passwd *pw = getpwnam(config->user()); if(pw) { if(setgid(pw->pw_gid) != 0) fprintf(stderr, "Failed to setgid!\n"); if(setuid(pw->pw_uid) != 0 ) fprintf(stderr, "Failed to setuid!\n"); } else { fprintf(stderr, "user %s not found\n", config->user()); } } if ( argc > 1 && strcmp(argv[1], "-d") == 0 ) { printf("try fork\n"); pid_t parpid; if((parpid = fork()) < 0) { mawarError("Failed to fork!", 99); } else if(parpid != 0) { exit(0); // успешно создан дочерний процесс, основной можно завершить } setsid(); } // после форка записать pid if ( fpid ) { fprintf(fpid, "%d", getpid()); fclose(fpid); fpid = 0; } // демон управляющий воркерами вводом-выводом struct rlimit rl; if ( getrlimit(RLIMIT_NOFILE, &rl) == -1 ) { fprintf(stderr, "getrlimit fault: %s\n", strerror(errno)); return 1; } printf("files limit: %lu\n", rl.rlim_cur); NetDaemon daemon(rl.rlim_cur, config->getOutputBuffers()); // устанавливаем скорректированное число воркеров daemon.setWorkerCount(config->workers() - 1); // XMPP-сервер server = new XMPPServer(&daemon); server->config = config; // подключемся к c2s-порту из конфига server->bind(config->c2s()); // не более 10 ожидающих соединений server->listen(10); // добавляем виртуальные хосты printf("[main] loading virtual hosts\n"); for(XmlTag *vhost = config->firstHost(); vhost; vhost = config->nextHost(vhost)) { printf("[main] load vhost: %s\n", vhost->getAttribute("name").c_str()); server->addHost(vhost->getAttribute("name"), vhost); } printf("[main] virtual hosts loaded\n"); // асинхронный резолвер nanosoft::ptr<AsyncDNS> dns = new AsyncDNS(&daemon); daemon.addObject(dns); server->adns = dns; // добавляем сервер в демона daemon.addObject(server); int port = config->xep0114(); if ( port > 0 ) { nanosoft::ptr<XEP0114Listener> xep0114 = new XEP0114Listener(server.getObject()); xep0114->bind(port); xep0114->listen(10); daemon.addObject(xep0114); } port = config->s2s(); if ( port > 0 ) { server->s2s = new S2SListener(server.getObject()); server->s2s->bind(port); server->s2s->listen(10); daemon.addObject(server->s2s); } string path = config->status(); if ( path != "" ) { nanosoft::ptr<ServerStatus> status = new ServerStatus(server.getObject()); status->bind(path.c_str()); status->listen(1); daemon.addObject(status); } // консоль управления сервером //MyConsole console(&daemon, 0); //daemon.addObject(&console); struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = on_signal; sigaction(SIGTERM, &sa, 0); sigaction(SIGHUP, &sa, 0); sigaction(SIGINT, &sa, 0); // запускаем демона fprintf(stderr, "[main] run daemon\n"); daemon.run(); fprintf(stderr, "[main] daemon exited\n"); cleanup(); return 0; }