⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatcontroller.cpp

📁 一个UNIX/LINUX下的基于内容的过滤服务器源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    timeval t;  // timeval struct    t.tv_sec = timeout;    t.tv_usec = 0;    if (selectEINTR(fd + 1, NULL, &fdSet, NULL, &t) < 1) {        return false;  // on timeout or error    }    return true;}int FatController::getLineFromFD(int fd, char* buff, int size, int timeout) {    if (!checkForInput(fd, timeout)) {        return -1;    }    char b[1];    int rc = -1; // only set to prevent compiler warnings    int i = 0;    b[0] = 0;    while(i < (size - 1)) {        while (true) {            if (!checkForInput(fd, 12)) {                break;            }            rc = recv(fd, b, 1, 0);            if (rc < 0) {                if (errno == EINTR && !reloadconfig) {                    continue;                }            }            break;        }        if (rc < 0) {            return -1; // error        }        if (rc == 0) {  // eof, other end closed so            b[0] = '\n'; // force it to return what read        }        buff[i] = b[0];        i++;        if (b[0] == '\n') {            buff[i - 1] = '\0';            break;        }    }    buff[i] = '\0';    return i;}bool FatController::checkForInput(int fd, int timeout) {    fd_set fdSet;    FD_ZERO(&fdSet);  // clear the set    FD_SET(fd, &fdSet);  // add fd to the set    if (timeout > 0) {        timeval t;  // timeval struct        t.tv_sec = timeout;        t.tv_usec = 0;        if (selectEINTR(fd + 1, &fdSet, NULL, NULL, &t) < 1) {            return false;        }    }    if (selectEINTR(fd + 1, &fdSet, NULL, NULL, NULL) < 1) {        return false;    }    return true; // Innnppppuuuuttt!!!! </#5>}int FatController::selectEINTR(int numfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout) {    int rc;    while (true) {  // using the while as a restart point with continue        rc = select(numfds, readfds, writefds, exceptfds, timeout);        if (rc < 0) {            if (errno == EINTR && !reloadconfig) {                continue;  // was interupted by a signal so restart            }        }        break;  // end the while    }    return rc;  // return status}void FatController::mopUpAfterKids() {    pid_t pid;    int stat_val;    while(true) {        pid = waitpid(-1, &stat_val, WNOHANG);        if (pid < 1) {            break;        }        if (WIFEXITED(stat_val) ) {  // exited normally            deleteChild((int)pid, WEXITSTATUS(stat_val));        }        else {            deleteChild((int)pid, -1);        }    }}int FatController::logListener(std::string log_location, int logconerror) {    #ifdef DGDEBUG        std::cout << "log listener started" << std::endl;    #endif    if (!dropPrivCompletely()) {        return 1; //error    }    UDSocket ipcpeersock;  // the socket which will contain the ipc connection    ipcpeersock.close(); // don't need default fd as will be accept()ing    int rc, ipcsockfd;    char* logline = new char[8192];    ofstream logfile(log_location.c_str(), ios::app);    if (logfile.fail()) {        syslog(LOG_ERR, "%s","Error opening/creating log file.");        #ifdef DGDEBUG            std::cout << "Error opening/creating log file: " << log_location << std::endl;        #endif        return 1;  // return with error    }    ipcsockfd = ipcsock.getFD();    fd_set fdSet;  // our set of fds (only 1) that select monitors for us    fd_set fdcpy;  // select modifes the set so we need to use a copy    FD_ZERO(&fdSet);  // clear the set    FD_SET(ipcsockfd, &fdSet);  // add ipcsock to the set    while (true) {  // loop, essentially, for ever        fdcpy = fdSet;  // take a copy        rc = select(ipcsockfd + 1, &fdcpy, NULL, NULL, NULL);  // block                                                  // until something happens        if (rc < 0) {  // was an error            if (errno == EINTR) {                continue;  // was interupted by a signal so restart            }            if (logconerror == 1) {                syslog(LOG_ERR, "%s","ipc rc<0. (Ignorable)");            }            continue;        }        if (rc < 1) {            if (logconerror == 1) {                syslog(LOG_ERR, "%s","ipc rc<0. (Ignorable)");            }            continue;        }        if (FD_ISSET(ipcsockfd, &fdcpy)) {            #ifdef DGDEBUG                std::cout << "received a log request" << std::endl;            #endif            ipcpeersock = ipcsock.accept();            if (ipcpeersock.getFD() < 0) {                ipcpeersock.close();                if (logconerror == 1) {                    syslog(LOG_ERR, "%s","Error accepting ipc. (Ignorable)");                }                continue; // if the fd of the new socket < 0 there was error                          // but we ignore it as its not a problem            }            try {                rc = ipcpeersock.getline(logline, 8192, 3);  // throws on err            } catch (exception& e) {                ipcpeersock.close();                if (logconerror == 1) {                    syslog(LOG_ERR, "%s","Error reading ipc. (Ignorable)");                }                continue;            }            logfile << logline << std::endl;  // append the line            #ifdef DGDEBUG                std::cout << logline << std::endl;            #endif            ipcpeersock.close();  // close the connection            #ifdef DGDEBUG                std::cout << "logged" << std::endl;            #endif            continue;  // go back to listening        }        // should never get here        syslog(LOG_ERR, "%s","Something wicked has ipc happened");    }    delete[] logline;    logfile.close();  // close the file and    ipcsock.close();  // be nice and neat    return 1; // It is only possible to reach here with an error}extern "C" {  // The kernel knows nothing of objects so              // we have to have a lump of c    void sig_term(int signo) {        sig_term_killall = true;        ttg = true;  // its time to go    }    void sig_termsafe(int signo) {        ttg = true;  // its time to go    }    void sig_hup(int signo) {        reloadconfig = true;        #ifdef DGDEBUG            std::cout << "HUP received." << std::endl;        #endif    }    void sig_usr1(int signo) {        gentlereload = true;        #ifdef DGDEBUG            std::cout << "USR1 received." << std::endl;        #endif    }}int FatController::urlListListener(int logconerror) {    #ifdef DGDEBUG            std::cout << "url listener started" << std::endl;    #endif    if (!dropPrivCompletely()) {        return 1; //error    }    UDSocket ipcpeersock;  // the socket which will contain the ipc connection    ipcpeersock.close(); // don't need default fd as will be accept()ing    int rc, ipcsockfd;    char* logline = new char[32000];    String reply;    DynamicURLList urllist;    #ifdef DGDEBUG            std::cout << "setting url list size-age:" << o.url_cache_number << "-" << o.url_cache_age << std::endl;    #endif    urllist.setListSize(o.url_cache_number, o.url_cache_age);    ipcsockfd = urllistsock.getFD();    #ifdef DGDEBUG            std::cout << "url ipcsockfd:" << ipcsockfd << std::endl;    #endif    fd_set fdSet;  // our set of fds (only 1) that select monitors for us    fd_set fdcpy;  // select modifes the set so we need to use a copy    FD_ZERO(&fdSet);  // clear the set    FD_SET(ipcsockfd, &fdSet);  // add ipcsock to the set    #ifdef DGDEBUG            std::cout << "url listener entering select()" << std::endl;    #endif    while (true) {  // loop, essentially, for ever        fdcpy = fdSet;  // take a copy        rc = select(ipcsockfd + 1, &fdcpy, NULL, NULL, NULL);  // block                                                  // until something happens        #ifdef DGDEBUG            std::cout << "url listener select returned" << std::endl;        #endif        if (rc < 0) {  // was an error            if (errno == EINTR) {                continue;  // was interupted by a signal so restart            }            if (logconerror == 1) {                syslog(LOG_ERR, "%s","url ipc rc<0. (Ignorable)");            }            continue;        }        if (FD_ISSET(ipcsockfd, &fdcpy)) {            #ifdef DGDEBUG                std::cout << "received an url request" << std::endl;            #endif            ipcpeersock = urllistsock.accept();            if (ipcpeersock.getFD() < 0) {                ipcpeersock.close();                if (logconerror == 1) {                    #ifdef DGDEBUG                        std::cout << "Error accepting url ipc. (Ignorable)" << std::endl;                    #endif                    syslog(LOG_ERR, "%s","Error accepting url ipc. (Ignorable)");                }                continue; // if the fd of the new socket < 0 there was error                          // but we ignore it as its not a problem            }            try {                rc = ipcpeersock.getline(logline, 32000, 3);  // throws on err            } catch (exception& e) {                ipcpeersock.close();  // close the connection                if (logconerror == 1) {                    #ifdef DGDEBUG                        std::cout << "Error reading ip ipc. (Ignorable)" << std::endl;                        std::cerr << e.what() << std::endl;                    #endif                    syslog(LOG_ERR, "%s","Error reading ip ipc. (Ignorable)");                    syslog(LOG_ERR, "%s", e.what());                }                continue;            }            if (logline[0] == 'F' && logline[1] == ' ') {                ipcpeersock.close();  // close the connection                urllist.flush();                #ifdef DGDEBUG                    std::cout << "url FLUSH request" << std::endl;                #endif                continue;            }            if (logline[0] == 'A' && logline[1] == ' ') {                ipcpeersock.close();  // close the connection                urllist.addEntry(logline + 2);                #ifdef DGDEBUG                    std::cout << "url add request:" << logline << std::endl;                #endif                continue;            }            #ifdef DGDEBUG                std::cout << "url search request:" << logline << std::endl;            #endif            if (urllist.inURLList(logline)) {                reply = "Y\n";            }            else {                reply = "N\n";            }            try {                ipcpeersock.writeString(reply.toCharArray());            } catch (exception& e) {                ipcpeersock.close();  // close the connection                if (logconerror == 1) {                    syslog(LOG_ERR, "%s","Error writing url ipc. (Ignorable)");                    syslog(LOG_ERR, "%s", e.what());                }                continue;            }            ipcpeersock.close();  // close the connection            #ifdef DGDEBUG                std::cout << "url list reply:" << reply << std::endl;            #endif            continue;  // go back to listening        }   }    delete[] logline;    urllistsock.close();  // be nice and neat    return 1; // It is only possible to reach here with an error}bool FatController::dropPrivCompletely() {    // This is done to solve the problem where the total processes for the    // uid rather than euid is taken for RLIMIT_NPROC and so can't fork()    // as many as expected.    // It is also more secure.    //    // Suggested fix by Lawrence Manning Tue 25th February 2003    //    int rc = seteuid(o.root_user);  // need to be root again to drop properly    if (rc == -1) {        syslog(LOG_ERR, "%s","Unable to seteuid(suid)");        #ifdef DGDEBUG            std::cout << strerror(errno) << std::endl;        #endif        return false;  // setuid failed for some reason so exit with error    }    rc = setuid(o.proxy_user);    if (rc == -1) {        syslog(LOG_ERR, "%s","Unable to setuid()");        return false;  // setuid failed for some reason so exit with error    }    return true;}void FatController::flushURLCache() {    if (o.url_cache_number < 1) {        return;  // no cache running to flush    }    UDSocket fipcsock;    if (fipcsock.getFD() < 0) {        syslog(LOG_ERR, "%s","Error creating ipc socket to url cache for flush");        return;    }    if (fipcsock.connect((char*) o.urlipc_filename.c_str()) < 0) {  // conn to dedicated url cach proc        syslog(LOG_ERR, "%s","Error connecting via ipc to url cache for flush");        #ifdef DGDEBUG            std::cout << "Error connecting via ipc to url cache for flush" << std::endl;        #endif        return;    }    String request = "F \n";    try {        fipcsock.writeString(request.toCharArray());  // throws on err    }    catch (exception& e) {        #ifdef DGDEBUG            std::cerr << "Exception flushing url cache" << std::endl;            std::cerr << e.what() << std::endl;        #endif        syslog(LOG_ERR, "%s","Exception flushing url cache");        syslog(LOG_ERR, "%s", e.what());    }    fipcsock.close();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -