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

📄 status.c++

📁 fax相关的东西
💻 C++
字号:
/*	$Id: Status.c++,v 1.7 2003/04/19 16:26:08 tim 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. *//* * Support related to server status. */#include "HylaFAXServer.h"#include "Sys.h"#include "config.h"#include <ctype.h>#include <sys/file.h>class ModemConfig : public FaxConfig {public:    enum {			// ClassModem::SpeakerVolume	OFF	= 0,		// nothing	QUIET	= 1,		// somewhere near a dull chirp	LOW	= 2,		// normally acceptable	MEDIUM	= 3,		// heard above a stereo	HIGH	= 4		// ear splitting    };    u_int	speakerVolume;		// volume control    u_int	tracingLevel;		// tracing level w/o session    u_int	logTracingLevel;	// tracing level during session    u_int	maxRecvPages;		// max pages to accept on receive    fxStr	localIdentifier;	// to use in place of FAXNumber    fxStr	FAXNumber;		// phone number    fxStr	modemName;		// canonical modem name    bool	isGettyRunning;		// true if faxgetty responds via FIFO    fxStr	status;			// from status file    ModemConfig(const char* name);    ~ModemConfig() {};    bool setConfigItem(const char* tag, const char* value);    void configError(const char* fmt, ...);    void configTrace(const char* fmt, ...);    void checkGetty(const char* fifoFile);};ModemConfig::ModemConfig(const char* name) : modemName(name){    HylaFAXServer::canonModem(modemName);    maxRecvPages = (u_int) -1;    tracingLevel = 0;    logTracingLevel = 0;    speakerVolume = QUIET;}void ModemConfig::configError(const char*, ...) {}void ModemConfig::configTrace(const char*, ...) {}voidModemConfig::checkGetty(const char* fifoFile){    int fifo;    Sys::close(fifo = Sys::open(fifoFile, O_WRONLY|O_NDELAY));    isGettyRunning = (fifo != -1);}boolModemConfig::setConfigItem(const char* tag, const char* value){    if (streq(tag, "faxnumber"))	FAXNumber = value;    else if (streq(tag, "localidentifier"))	localIdentifier = value;    else if (streq(tag, "speakervolume")) {	// XXX duplicates code elsewhere	if (strcasecmp(value, "off") == 0)	    speakerVolume = OFF;	else if (strcasecmp(value, "quiet") == 0)	    speakerVolume = QUIET;	else if (strcasecmp(value, "low") == 0)	    speakerVolume = LOW;	else if (strcasecmp(value, "medium") == 0)	    speakerVolume = MEDIUM;	else	    speakerVolume = HIGH;    } else if (streq(tag, "tracinglevel"))	tracingLevel = getNumber(value);    else if (streq(tag, "logtracinglevel"))	logTracingLevel = getNumber(value);    else if (streq(tag, "maxrecvpages"))	maxRecvPages = getNumber(value);    return (true);				// avoid complaints}voidHylaFAXServer::listStatus(FILE* fd, const SpoolDir& sd, DIR* dir){    /*     * Check scheduler status.     */    int fifo;    Sys::close(fifo = Sys::open("/" FAX_FIFO, O_WRONLY|O_NDELAY));    fprintf(fd, "HylaFAX scheduler on %s: %s\r\n"	, (const char*) hostname	, fifo != -1 ? "Running" : "Not running"    );    /*     * Cross-check entries in the status directory     * against the other files required for an operating     * modem.  There must be a configuration file and,     * if there is a faxgetty process running, there must     * be a FIFO special file in the root filesystem.     */    fxStr path(sd.pathname);    struct stat sb;    fxStr fifoPrefix("/" FAX_FIFO ".");    struct dirent* dp;    while ((dp = readdir(dir))) {	fxStr statusFile(path | dp->d_name);	if (!FileCache::update(statusFile, sb) || !S_ISREG(sb.st_mode))	    continue;	// verify there is a modem config file	fxStr configFile = fxStr::format("/" FAX_CONFIG ".%s", dp->d_name);	if (!FileCache::lookup(configFile, sb) || !S_ISREG(sb.st_mode))	    continue;	fxStr fifoFile(fifoPrefix | dp->d_name);	if (!FileCache::lookup(fifoFile, sb) || !S_ISFIFO(sb.st_mode))	    continue;	ModemConfig config(dp->d_name);	config.readConfig(configFile);			// read config file	config.checkGetty(fifoFile);			// check for faxgetty	getServerStatus(statusFile, config.status);	// XXX	Mprintf(fd, modemFormat, config);	fputs("\r\n", fd);    }}voidHylaFAXServer::listStatusFile(FILE* fd, const SpoolDir& dir,    const char* filename, const struct stat& sb){    listUnixFile(fd, dir, filename, sb);}voidHylaFAXServer::getServerStatus(const char* fileName, fxStr& status){    int fd = Sys::open(fileName, O_RDONLY);    if (fd > 0) {        struct stat sb;        (void) Sys::fstat(fd, sb);        status.resize((u_int) sb.st_size);        char* buff = new char[sb.st_size];        int n = Sys::read(fd, buff, (size_t) sb.st_size);        status = buff;        Sys::close(fd);        if (n > 0 && status[n-1] == '\n') n--;        if (n == 0) {            status = "No status (empty file)";        } else {            status.resize(n);        }        delete [] buff;    } else {        status = "No status (cannot open file)";    }}static const char mformat[] = {    'a',		// a    'b',		// b    'c',		// c    'd',		// d    'e',		// e    'f',		// f    'g',		// g    's',		// h (hostname)    'i',		// i    'j',		// j    'k',		// k    's',		// l (local identifier)    's',		// m (canonical modem name)    's',		// n (phone number)    'o',		// o    'p',		// p    'q',		// q    's',		// r (max recv pages)    's',		// s (status information)    's',		// t (server/session tracing level)    'x',		// u (server tracing level)    'c',		// v (speaker volume)    'w',		// w    'x',		// x    'y',		// y    'c'			// z (``*'' if faxgetty is running)};/* * Print a formatted string with fields filled in from * the specified modem state.  This functionality is * used to permit clients to get modem status listings * in preferred formats. */voidHylaFAXServer::Mprintf(FILE* fd, const char* fmt, const ModemConfig& config){    for (const char* cp = fmt; *cp; cp++) {	if (*cp == '%') {#define	MAXSPEC	20	    char fspec[MAXSPEC];	    char* fp = fspec;	    *fp++ = '%';	    char c = *++cp;	    if (c == '-')		*fp++ = c, c = *++cp;	    if (isdigit(c)) {		do {		    *fp++ = c;		} while (isdigit(c = *++cp) && fp < &fspec[MAXSPEC-3]);	    }	    if (c == '.') {		do {		    *fp++ = c;		} while (isdigit(c = *++cp) && fp < &fspec[MAXSPEC-2]);	    }	    if (!islower(c)) {		if (c == '%')		// %% -> %		    putc(c, fd);		else		    fprintf(fd, "%.*s%c", fp-fspec, fspec, c);		continue;	    }	    fp[0] = mformat[c-'a'];	// printf format string	    fp[1] = '\0';	    switch (c) {	    case 'h':		fprintf(fd, fspec, (const char*) hostname);		break;	    case 'l':		fprintf(fd, fspec, (const char*) config.localIdentifier);		break;	    case 'm':		fprintf(fd, fspec, (const char*) config.modemName);		break;	    case 'n':		fprintf(fd, fspec, (const char*) config.FAXNumber);		break;	    case 'r':        /*         * this is not used for some reason ie -1 represents infinite		* if (config.maxRecvPages == (u_int) -1) {		*    tmp = "INF";		* } else {		*    tmp = fxStr::format("%u", config.maxRecvPages);        * }        */		fprintf(fd, fspec, config.maxRecvPages);		break;	    case 's':		fprintf(fd, fspec, (const char*) config.status);		break;            case 't': {		            fxStr tmp = fxStr::format("%05x:%05x",                        config.tracingLevel&0xfffff,                        config.logTracingLevel&0xfffff);                    fprintf(fd, fspec, (const char*)tmp);                }		        break;	    case 'v':		fprintf(fd, fspec, " QLMH"[config.speakerVolume]);		break;	    case 'z':		fprintf(fd, fspec, config.isGettyRunning ? '*' : ' ');		break;	    }	} else	    putc(*cp, fd);    }}voidHylaFAXServer::nlstStatus(FILE* fd, const SpoolDir& sd, DIR* dir){    /*     * Cross-check entries in the status directory     * against the other files required for an operating     * modem.  There must be a configuration file and,     * if there is a faxgetty process running, there must     * be a FIFO special file in the root filesystem.     */    fxStr path(sd.pathname);    struct stat sb;    fxStr fifoPrefix("/" FAX_FIFO ".");    struct dirent* dp;    while ((dp = readdir(dir))) {	fxStr statusFile(path | dp->d_name);	if (!FileCache::update(statusFile, sb) || !S_ISREG(sb.st_mode))	    continue;	// verify there is a modem config file	fxStr configFile = fxStr::format("/" FAX_CONFIG ".%s", dp->d_name);	if (!FileCache::lookup(configFile, sb) || !S_ISREG(sb.st_mode))	    continue;	fxStr fifoFile(fifoPrefix | dp->d_name);	if (!FileCache::lookup(fifoFile, sb) || !S_ISFIFO(sb.st_mode))	    continue;	ModemConfig config(dp->d_name);	config.readConfig(configFile);			// read config file	config.checkGetty(fifoFile);			// check for faxgetty	getServerStatus(statusFile, config.status);	// XXX	Mprintf(fd, "%m\r\n", config);    }}

⌨️ 快捷键说明

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