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

📄 parser.c++

📁 fax相关的东西
💻 C++
📖 第 1 页 / 共 4 页
字号:
/*	$Id: Parser.c++,v 1.11 2005/05/09 14:57:44 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. *//* * HylaFAX Client-Server Protocol Parser. */#include "port.h"#include "config.h"#include "Sys.h"#include "Socket.h"#include "HylaFAXServer.h"#include "Dispatcher.h"#include <ctype.h>#define	N(a)	(sizeof (a) / sizeof (a[0]))/* * Standard protocol commands. */static const tab cmdtab[] = {{ "ABOR",         T_ABOR,	false, true, "[modem] (abort operation)" },{ "ACCT",         T_ACCT,	false,false, "(specify account)" },{ "ADMIN",        T_ADMIN,	 true, true, "password" },{ "ALLO",         T_ALLO,	false,false, "(allocate disk space)" },{ "ANSWER",       T_ANSWER,	 true, true, "modem [DATA|VOICE|FAX]" },{ "APPE",         T_APPE,	 true, true, "file-name" },{ "CWD",          T_CWD,	 true, true, "[directory-name]" },{ "CDUP",         T_CDUP,	 true, true, "(change directory up one level)"},{ "CHMOD",        T_CHMOD,	 true, true, "file-name mode" },{ "CHOWN",        T_CHOWN,	 true, true, "file-name user" },{ "DELE",         T_DELE,	 true, true, "file-name" },{ "DISABLE",      T_DISABLE,	 true, true, "modem [reason]" },{ "ENABLE",       T_ENABLE,	 true, true, "modem" },{ "HELP",         T_HELP,	false, true, "[<string>]" },{ "FILEFMT",      T_FILEFMT,	 true, true, "[format-string]" },{ "FORM",         T_FORM,	 true, true, "format-type" },{ "IDLE",         T_IDLE,	 true, true, "[max-idle-timeout]" },{ "JDELE",        T_JDELE,	 true, true, "[job-id]" },{ "JINTR",        T_JINTR,	 true, true, "[job-id]" },{ "JKILL",        T_JKILL,	 true, true, "[job-id]" },{ "JNEW",         T_JNEW,	 true, true, "" },{ "JOB",          T_JOB,	 true, true, "[job-id]" },{ "JOBFMT",       T_JOBFMT,	 true, true, "[format-string]" },{ "JPARM",        T_JPARM,	 true, true, "[parm-name [parm-value]]" },{ "JREST",        T_JREST,	 true, true, "(reset current job state)" },{ "JSUBM",        T_JSUB,	 true, true, "[job-id]" },{ "JSUSP",        T_JSUSP,	 true, true, "[job-id]" },{ "JWAIT",        T_JWAIT,	 true, true, "[job-id]" },{ "JGDELE",       T_JGDELE,	 true,false, "[jobgroup-id]" },{ "JGINTR",       T_JGINTR,	 true,false, "[jobgroup-id]" },{ "JGKILL",       T_JGKILL,	 true,false, "[jobgroup-id]" },{ "JGNEW",        T_JGNEW,	 true, true, "" },{ "JGPARM",       T_JGPARM,	 true,false, "parm-name [parm-value]" },{ "JGREST",       T_JGREST,	 true,false, "(reset current job group state)"},{ "JGRP",         T_JGRP,	 true,false, "[jobgroup-id]" },{ "JGSUBM",       T_JGSUB,	 true,false, "[jobgroup-id]" },{ "JGSUSP",       T_JGSUSP,	 true,false, "[jobgroup-id]" },{ "JGWAIT",       T_JGWAIT,	 true,false, "[jobgroup-id]" },{ "LIST",         T_LIST,	 true, true, "[path-name]" },{ "MDTM",         T_MDTM,	 true, true, "path-name" },{ "MODE",         T_MODE,	false, true, "(specify transfer mode)" },{ "MDMFMT",       T_MODEMFMT,	 true, true, "[format-string]" },{ "NLST",         T_NLST,	 true, true, "[path-name]" },{ "NOOP",         T_NOOP,	false, true, "" },{ "PASS",         T_PASS,	false, true, "password" },{ "PASV",         T_PASV,	 true, true, "(set server in passive mode)" },{ "PORT",         T_PORT,	 true, true, "a0,a1,a2,a3,p0,p1" },{ "PWD",          T_PWD,	 true, true, "(print working directory)" },{ "QUIT",         T_QUIT,	false, true, "(terminate service)", },{ "RCVFMT",       T_RCVFMT,	 true, true, "[format-string]" },{ "REIN",         T_REIN,	false, true, "(reinitialize server state)" },{ "REST",         T_REST,	 true, true, "restart-marker" },{ "RETP",         T_RETP,	 true, true, "file-name" },{ "RETR",         T_RETR,	 true, true, "file-name" },{ "RNFR",         T_RNFR,	 true,false, "file-name" },{ "RNTO",         T_RNTO,	 true,false, "file-name" },{ "SHUT",         T_SHUT,	 true, true, "NOW|HHSS|YYYYMMDDHHSS [reason]" },{ "SITE",         T_SITE,	 true, true, "site-cmd [arguments]" },{ "SIZE",         T_SIZE,	 true, true, "path-name" },{ "STAT",         T_STAT,	false, true, "[path-name]" },{ "STOR",         T_STOR,	 true, true, "file-name" },{ "STOT",         T_STOT,	 true, true, "(store unique temporary)" },{ "STOU",         T_STOU,	 true, true, "(store unique)" },{ "STRU",         T_STRU,	false, true, "file-structure" },{ "SYST",         T_SYST,	 true, true, "(return system type)" },{ "TZONE",        T_TZONE,	 true, true, "[GMT|LOCAL]" },{ "TYPE",         T_TYPE,	false, true, "transfer-type" },{ "USER",         T_USER,	false, true, "username" },{ "VRFY",         T_VRFY,	false, true, "dialstring" },};/* * Job parameter commands/keys. */static const tab parmtab[] = {{ "ACCTINFO",     T_ACCTINFO,	  false,false, "[<string>]" },{ "BEGBR",        T_BEGBR,	  false, true, "[ANY|bit-rate]" },{ "BEGST",        T_BEGST,	  false, true, "[ANY|scanline-time]" },{ "CHOPTHRESHOLD",T_CHOPTHRESH,	  false, true, "[inches]" },{ "CLIENT",       T_CLIENT,	  false, true, "[<string>]" },{ "COMMENTS",     T_COMMENTS,	  false, true, "[<string>]" },{ "COMMID",       T_COMMID,	  false, true, "(communication identifier)" },{ "COVER",        T_COVER,	  false, true, "path-name" },{ "DATAFORMAT",   T_DATAFORMAT,	  false, true, "[ANY|G31D|G32D|G4]" },{ "DIALSTRING",   T_DIALSTRING,	  false, true, "[<string>]" },{ "DOCUMENT",     T_DOCUMENT,	  false, true, "path-name" },{ "DONEOP",       T_DONEOP,	  false, true, "[<string>]" },{ "EXTERNAL",     T_EXTERNAL,	  false, true, "[<string>]" },{ "FAXNUMBER",    T_FAXNUMBER,	  false, true, "[<string>]" },{ "FROMCOMPANY",  T_FROM_COMPANY, false, true, "[<string>]" },{ "FROMLOCATION", T_FROM_LOCATION,false, true, "[<string>]" },{ "FROMUSER",     T_FROM_USER,	  false, true, "[<string>]" },{ "FROMVOICE",    T_FROM_VOICE,	  false, true, "[<string>]" },{ "GROUPID",      T_GROUPID,	  false, true, "(job group identifier)" },{ "HRES",         T_HRES,	  false,false, "[dots-per-inch]" },{ "JOBID",        T_JOBID,	  false, true, "(job identifier)" },{ "JOBINFO",      T_JOBINFO,	  false, true, "[<string>]" },{ "JOBTYPE",      T_JOBTYPE,	  false, true, "(job type)" },{ "LASTTIME",     T_LASTTIME,	  false, true, "[DDHHSS]" },{ "MAXDIALS",     T_MAXDIALS,	  false, true, "[<number>]" },{ "MAXPAGES",     T_MAXPAGES,	  false, true, "[<number>]" },{ "MAXTRIES",     T_MAXTRIES,	  false, true, "[<number>]" },{ "MINBR",        T_MINBR,	  false, true, "[ANY|bit-rate]" },{ "MODEM",        T_MODEM,	  false, true, "[device|class]" },{ "NDIALS",       T_NDIALS,	  false, true, "[<number>]" },{ "NOTIFY",       T_NOTIFY,	  false, true, "[NONE|DONE|REQUEUE|DONE+REQUEUE]" },{ "NOTIFYADDR",   T_NOTIFYADDR,	  false, true, "[email-address]" },{ "NPAGES",       T_NPAGES,	  false, true, "[<number>]" },{ "NTRIES",       T_NTRIES,	  false, true, "[<number>]" },{ "OWNER",        T_OWNER,	  false, true, "[<name>|<number>]" },{ "PAGECHOP",     T_PAGECHOP,	  false, true, "[DEFAULT|NONE|ALL|LAST]" },{ "PAGELENGTH",   T_PAGELENGTH,	  false, true, "[millimeters]" },{ "PAGEWIDTH",    T_PAGEWIDTH,	  false, true, "[millimeters]" },{ "PASSWD",       T_PASSWD,	  false, true, "[<string>]" },{ "POLL",         T_POLL,	  false, true, "selector [passwd]" },{ "REGARDING",    T_REGARDING,	  false, true, "[<string>]" },{ "RETRYTIME",    T_RETRYTIME,	  false, true, "[HHSS]" },{ "SCHEDPRI",     T_SCHEDPRI,	  false, true, "[<number>]" },{ "SENDTIME",     T_SENDTIME,	  false, true, "[NOW|YYYYMMDDHHSS]" },{ "STATE",        T_STATE,	  false, true, "(job state)" },{ "STATUS",       T_STATUS,       false, true, "[<string>" },{ "SUBADDR",      T_SUBADDR,	  false, true, "[<string>]" },{ "TAGLINE",      T_TAGLINE,	  false, true, "[<string>]" },{ "TOCOMPANY",    T_TO_COMPANY,	  false, true, "[<string>]" },{ "TOLOCATION",   T_TO_LOCATION,  false, true, "[<string>]" },{ "TOTDIALS",     T_TOTDIALS,	  false, true, "[<number>]" },{ "TOTPAGES",     T_TOTPAGES,	  false, true, "[<number>]" },{ "TOTTRIES",     T_TOTTRIES,	  false, true, "[<number>]" },{ "TOUSER",       T_TO_USER,	  false, true, "[<string>]" },{ "TOVOICE",      T_TO_VOICE,	  false, true, "[<string>]" },{ "TSI",          T_TSI,	  false, true, "[<string>]" },{ "USECONTCOVER", T_USE_CONTCOVER,false, true, "[YES|NO]" },{ "USEXVRES",     T_USE_XVRES,	  false, true, "[YES|NO]" },{ "USEECM",       T_USE_ECM,	  false, true, "[YES|NO]" },{ "USETAGLINE",   T_USE_TAGLINE,  false, true, "[YES|NO]" },{ "USRKEY",       T_USRKEY,	  false, true, "[<string>]" },{ "VRES",         T_VRES,	  false, true, "[lines-per-inch]" },{ "HELP",         T_HELP,	  false, true, "[<string>]" },};/* * Site-specific commands. */static const tab sitetab[] = {{ "ADDMODEM",     T_ADDMODEM,	  false,false, "modem [speed]"},{ "ADDUSER",      T_ADDUSER,	  false, true, "user-spec [passwd [adminwd]]"},{ "CONFIG",       T_CONFIG,	  false, true, "[parm-name [parm-value]]" },{ "DELMODEM",     T_DELMODEM,	  false,false, "modem" },{ "DELUSER",      T_DELUSER,	  false, true, "user-spec" },{ "TRIGGER",	  T_TRIGGER,	  false, true, "spec" },{ "HELP",         T_HELP,	  false, true, "[<string>]" },};static const tab*lookup(const tab* p, u_int n, const char* cmd){    while (n != 0) {        if (strcmp(cmd, p->name) == 0)            return (p);	p++, n--;    }    return (NULL);}static const char*tokenName(const tab* p, u_int n, Token t){    while (n != 0) {	if (p->token == t)	    return (p->name);	p++, n--;    }    return ("???");}const char*HylaFAXServer::cmdToken(Token t){    return tokenName(cmdtab, N(cmdtab), t);}const char*HylaFAXServer::siteToken(Token t){    return tokenName(sitetab, N(sitetab), t);}const char*HylaFAXServer::parmToken(Token t){    return tokenName(parmtab, N(parmtab), t);}u_intHylaFAXServer::twodigits(const char* cp, u_int range){    return ((cp[0]-'0')*10 + (cp[1]-'0')) % range;}u_intHylaFAXServer::fourdigits(const char* cp){    return (cp[0]-'0')*1000 +	   (cp[1]-'0')*100 +	   (cp[2]-'0')*10 +	   (cp[3]-'0');}inline boolisLoginToken(Token t){    return (t == T_USER || t == T_PASS || t == T_ADMIN);}/* * Parse and process command input received on the * control channel.  This method is invoked whenever * data is present on the control channel.  We read * everything and parse (and execute) as much as possible * but do not block waiting for more data except when * a partial line of input is received.  This is done * to ensure other processing will be handled in a * timely fashion (e.g. processing of messages from * the scheduler received via the FIFO). */intHylaFAXServer::parse(){    if (IS(WAITDATA)) {			// recursive invocation	state &= ~S_WAITDATA;	return (0);    }					// stop control channel idle timeout    Dispatcher::instance().stopTimer(this);    pushToken(T_NIL);			// reset state    for (;;) {	/*	 * Fetch the next complete line of input received on the	 * control channel.  This call will fail when no more data	 * is *currently* waiting on the control channel.  Note	 * that this does not mean the connection has dropped; just	 * that data is not available at this instant.  Note also	 * that if a partial line of input is received a complete	 * line will be waited for (see below).	 */	if (!getCmdLine(cbuf, sizeof (cbuf)))	    break;	/*	 * Parse the line of input read above.	 */	if (getToken(T_STRING, "command token")) {	    tokenBody.raisecase();	    const tab* p = lookup(cmdtab, N(cmdtab), tokenBody);	    if (p == NULL)		reply(500, "%s: Command not recognized.",		    (const char*) tokenBody);	    else if (!p->implemented)		reply(502, "%s: Command not implemented.", p->name);	    /*	     * If the user is not privileged, then check for	     * the service being shutdown if the command is	     * not part of the login procedure (USER-PASS-ADMIN).	     * This permits administrators to gain access to	     * a system that is shutdown.  Other users will get	     * dropped if they type something else.	     */ 	    else if (!IS(PRIVILEGED) && !isLoginToken(p->token) &&	      isShutdown(!IS(LOGGEDIN))) {		reply(221, "Server shutting down.  Goodbye.");		dologout(0);		// XXX	    /*	     * If command requires client to be logged in check	     * for this.  Note that some commands have variants	     * that do not require the client be logged in--these	     * cannot check here and must do it specially below.	     */	    } else if (p->checklogin && !checklogin(p->token))		;	    /*	     * Command is valid, implemented, and the server	     * is available to service it.  If the syntax is	     * correct then reset the number of consecutive	     * bad commands.  Note that since part of the syntax	     * checking is login validation this logic will also	     * catch people typing syntacitcally valid but	     * unacceptable commands just to remain connected.	     */	    else if (cmd(p->token)) {		if (p->token != T_REST)		    restart_point = 0;		consecutiveBadCmds = 0;		continue;	    }	}	/*	 * If too many consecutive bad commands have been	 * received disconnect.  This is to safeguard against	 * a client that spews trash down the control connection.	 */	if (++consecutiveBadCmds >= maxConsecutiveBadCmds) {	    /*	     * Check for shutdown so that any shutdown message	     * will get prepended to client reply.	     */	    (void) isShutdown(!IS(LOGGEDIN));	    reply(221, "Server shutting down.  Goodbye.");	    dologout(0);	}    }    Dispatcher::instance().startTimer(idleTimeout, 0, this);    return (0);}/* * Protocol command (one line). */boolHylaFAXServer::cmd(Token t){    fxStr s;    long n;    switch (t) {    case T_USER:			// user name	if (string_param(s, "user name")) {	    logcmd(t, "%s", (const char*) s);	    userCmd(s);	    return (true);	}	break;    case T_PASS:			// user password	if (string_param(s, "password")) {	    logcmd(t, "<password>");	    passCmd(s);	    return (true);	}	break;    case T_ADMIN:			// administrator password	if (opt_CRLF())	    s = "";	else if (!string_param(s, "password"))	    break;	logcmd(t, "<password>");	adminCmd(s);	return (true);    case T_REIN:			// reinitialize server	logcmd(t);	if (IS(LOGGEDIN))	    (void) chdir("/");		// return to top of spooling area	initServer();	reply(220, "%s server (%s) ready.", (const char*) hostname, version);	break;    case T_REST:			// restart data transfer	if (number_param(n)) {	    logcmd(t, "%lu", n);	    restart_point = n;	    reply(350, "Data transfer will restart at %lu, "		"send transfer command", n);	    return (true);	}	break;    case T_SYST:			// system identification	if (CRLF()) {	    logcmd(t);	    // this is what we *emulate*	    reply(215, "%s", (const char*) systemType);	    return (true);	}	break;    case T_PORT:			// port for data transfer	if (SPACE() && hostPort() && CRLF()) {	    portCmd();	    return (true);	}	break;    case T_PASV:			// enable passive mode	if (CRLF()) {	    logcmd(t);	    passiveCmd();	    return (true);	}	break;    case T_FORM:			// document format	if (string_param(s, "document format")) {	    logcmd(t, "%s", (const char*) s);	    formCmd(s);	    return (true);	}	break;    case T_MODE:			// data transfer mode	if (string_param(s, "transfer mode")) {	    logcmd(t, "%s", (const char*) s);	    modeCmd(s);	    return (true);	}	break;    case T_STRU:			// data transfer file structure	if (string_param(s, "file structure")) {	    logcmd(t, "%s", (const char*) s);	    struCmd(s);	    return (true);	}	break;

⌨️ 快捷键说明

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