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

📄 hylafaxserver.c++

📁 fax相关的东西
💻 C++
📖 第 1 页 / 共 2 页
字号:
/*	$Id: HylaFAXServer.c++,v 1.21 2006/06/12 18:28:54 aidan Exp $ *//* * Copyright (c) 1995-1996 Sam Leffler * Copyright (c) 1995-1996 Silicon Graphics, Inc. * HylaFAX is a trademark of Silicon Graphics * * Permission to use, copy, modify, distribute, and sell this software and  * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. *  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   *  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  * OF THIS SOFTWARE. */#include "port.h"#include "Sys.h"#include "config.h"#include "tiffio.h"#include "HylaFAXServer.h"#include "Dispatcher.h"#include "StackBuffer.h"#include "Sequence.h"#include <ctype.h>#include <sys/file.h>#include <pwd.h>#include <limits.h>#include <grp.h>#include <unistd.h>#include <stdlib.h>const char* HylaFAXServer::version = HYLAFAX_VERSION;/* * NB: The remainder of the instance state is * initialized in initServer which is expected to * be called before any other operation is done * (through open).  This is required because some * initialization work is done by virtual methods * that cannot be invoked from the constructor. */HylaFAXServer::HylaFAXServer()    : defJob(""){    state = 0;    xferfaxlog = -1;    loginAttempts = 0;		// NB: not reset by REIN command    adminAttempts = 0;		// NB: not reset by REIN command    idcache = NULL;#ifdef HAVE_PAM	pamh = NULL;	pam_chrooted = false;#endif    data = -1;			// current data connection (socket)    pdata = -1;			// passive mode data connect (socket)    faxqFd = -1;    clientFd = -1;    char buff[64];    (void) gethostname(buff, sizeof(buff));    hostname = buff;    hostaddr = "unknown";	// derived classes should fill-in    lastModTime = 0;		// shutdown file mod time    discTime = 0;		// shutdown forced disconnect time    denyTime = 0;		// shutdown service denial time    /*     * Calculate the time differential between the local timezone     * and GMT for adjusting client-specified time values that are     * given in GMT.     *     * We want the actual offset of the local now from UTC,      * This means we have to "force" daylight savings off, otherwise     * the offset we get back is of the real timezone (the time     * functions automatically compensate if DST is set).     *     * Because we take the actual offset instead of a real timezone,     * we force the TZ a format CUT<offset> instead of an actual     * timezone like EST<offset>EDT, or PST<offset>PDT.  This means     * we no longer have to rely on the system being able to do the     * DST offset.     */    time_t now = Sys::now();    struct tm gmt = *gmtime(&now);    struct tm tm = *localtime(&now);    tm.tm_isdst = 0;    gmtoff = mktime(&gmt) - mktime(&tm);#if HAS_TM_ZONE    /*     * BSD/OS doesn't support the global timezone     * information so setup substitutes here.     */    tzname[0] = tm.tm_zone;    tzname[1] = NULL;#endif    /*     * Some versions of  glibc (like RHEL4) will revert to UTC in     * the chroot if it can't find the zoneinfo file and no TZ is     * set in the environment.     * We'll set the TZ to our crafted TZ to make sure that we     * have the right offset even if no timezone DST info is     * available in the chroot.     */    fxStr tz = fxStr::format("CUT%d:%02d",    		(gmtoff / 3600), ((gmtoff / 60) % 60));    setenv("TZ", tz, 0);    cachedTIFF = NULL;}HylaFAXServer::~HylaFAXServer(){    dologout(0);}/* * Initialize the state of the server.  Note that this * is used to implement the REIN command and for that * it doesn't work entirely because state set from the * configuration files is not accessible after a login * because the sever does a chroot to the top of the * spooling area.  The only way to make this work is * to keep all the configuration files in the spooling * area which is not folks want when things are shared * through NFS (i.e. server binaries and config files * are NFS-mounted by the spooling area is private). */voidHylaFAXServer::initServer(void){    end_login();		// reset user-related state    /*     * Default state:     *   o send long replies     *   o use GMT for time values     *   o auto-detect whether filesystem has BSD or SysV     *     semantics for setting the GID on created files     */    state = S_LREPLIES|S_USEGMT|S_CHECKGID;    restart_point = 0;		// data-transfer-related state    mode = MODE_S;    form = FORM_PS;    type = TYPE_A;    stru = STRU_F;    initDefaultJob();		// reset default job state    curJob = &defJob;    if (data != -1)		// data transfer-related state	Sys::close(data), data = -1;    if (pdata != -1)	Sys::close(pdata), pdata = -1;    if (trigSpec != "") {	fxStr emsg;	cancelTrigger(emsg);    }    // XXX FIFO state    pushedToken = T_NIL;    recvCC = 0;			// no data present in buffer    recvNext = 0;    consecutiveBadCmds = 0;    resetConfig();    readConfig(FAX_SYSCONF);    readConfig(FAX_LIBDATA "/hfaxd.conf");}static voidtiffErrorHandler(const char* module, const char* fmt0, va_list ap){    fxStr fmt = (module != 0) ?        fxStr::format("%s: Warning, %s.", module, fmt0)        : fxStr::format("Warning, %s.", fmt0);    vlogError(fmt, ap);}static voidtiffWarningHandler(const char* module, const char* fmt0, va_list ap){    fxStr fmt = (module != 0) ?        fxStr::format("%s: Warning, %s.", module, fmt0)        : fxStr::format("Warning, %s.", fmt0);    vlogWarning(fmt, ap);}voidHylaFAXServer::open(void){    initServer();		// complete state initialization    fxStr emsg;    if (!initClientFIFO(emsg)) {        logInfo("connection refused (%s) from %s [%s]",	    (const char*) emsg,	    (const char*) remotehost, (const char*) remoteaddr);	reply(420, "%s server cannot initialize: %s",	    (const char*) hostname, (const char*) emsg);	dologout(-1);    }    ctrlFlags = fcntl(STDIN_FILENO, F_GETFL);	// for parser    if (isShutdown(true))	reply(220, "%s HylaFAX server shut down; available only for admin use.",	    (const char*) hostname);    else	reply(220, "%s server (%s) ready.", (const char*) hostname, version);    if (TRACE(TIFF)) {	TIFFSetErrorHandler(tiffErrorHandler);	TIFFSetWarningHandler(tiffWarningHandler);    } else {	TIFFSetErrorHandler(NULL);	TIFFSetWarningHandler(NULL);    }}voidHylaFAXServer::close(){    dologout(-1);}voidHylaFAXServer::setupPermissions(void){    uid_t euid = geteuid();    struct passwd* pwd = getpwnam(FAX_USER);    if (!pwd)	logError("No fax user \"%s\" defined on your system!\n"	    "This software is not installed properly!", FAX_USER);    else if (euid == 0) {	if (initgroups(pwd->pw_name, pwd->pw_gid) != 0)	    logError("Can not setup permissions (supplementary groups): %m");	if (setegid(pwd->pw_gid) < 0)	    logError("Can not setup permissions (gid): %m");	else if (seteuid(pwd->pw_uid) < 0)	    logError("Can not setup permissions (uid): %m");	else {	    faxuid = pwd->pw_gid;	    endpwent();	    return;	}    } else {	faxuid = pwd->pw_gid;	uid_t faxuid = pwd->pw_uid;	setpwent();	pwd = getpwuid(euid);	if (!pwd)	    logError("Can not figure out the identity of uid %u", euid);	else if (pwd->pw_uid != faxuid)	    logError("Configuration error; "		"the fax server must run as the fax user \"%s\".", FAX_USER);	else {	    endpwent();	    return;	}    }    exit(-1);}/* * Close all open descriptors and unlink any * Dispatcher i/o handlers. */voidHylaFAXServer::closeAllBut(int fd){    Dispatcher& disp = Dispatcher::instance();    for (int f = Sys::getOpenMax()-1; f >= 0; f--)	if (f != fd) {	    IOHandler* h = disp.handler(f, Dispatcher::ReadMask);	    if (h)		disp.unlink(f);	    Sys::close(f);	}}/* * Unlink all dispatcher i/o handlers and close * their file descriptor. */voidHylaFAXServer::closeAllDispatched(){    Dispatcher& disp = Dispatcher::instance();    for (int f = Sys::getOpenMax()-1; f >= 0; f--)    {	IOHandler* h = disp.handler(f, Dispatcher::ReadMask);	if (h)	{	    disp.unlink(f);	    Sys::close(f);	}    }}const char*HylaFAXServer::fixPathname(const char* file){    return (!IS(LOGGEDIN) && file[0] == '/' ? file+1 : file);}boolHylaFAXServer::readShutdownFile(void){    bool ok = false;    FILE* fd = fopen(fixPathname(shutdownFile), "r");    if (fd != NULL) {	struct tm tm;	int deny, disc;	memset(&tm, 0, sizeof (tm));	int n = fscanf(fd, "%d %d %d %d %d %d %d\n",	    &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,	    &deny, &disc);	if (n == 7) {	    tm.tm_year -= 1900;	    tm.tm_isdst = -1;	    time_t shut = mktime(&tm);	    if (shut != (time_t) -1) {		denyTime = shut - 3600 * (deny / 100) + 60 * (deny % 100);		discTime = shut - 3600 * (disc / 100) + 60 * (disc % 100);

⌨️ 快捷键说明

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