dispatch.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 945 行 · 第 1/2 页

C
945
字号
/* dispatch.c - fred dispatch */#ifndef	lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/quipu/uips/fred/RCS/dispatch.c,v 9.0 1992/06/16 12:44:30 isode Rel $";#endif/*  * $Header: /xtel/isode/isode/others/quipu/uips/fred/RCS/dispatch.c,v 9.0 1992/06/16 12:44:30 isode Rel $ * * * $Log: dispatch.c,v $ * Revision 9.0  1992/06/16  12:44:30  isode * Release 8.0 * *//* *				  NOTICE * *    Acquisition, use, and distribution of this module and related *    materials are subject to the restrictions of a license agreement. *    Consult the Preface in the User's Manual for the full terms of *    this agreement. * */#include <ctype.h>#include "fred.h"#ifdef	BSD42#include <sys/ioctl.h>#endif#include <sys/stat.h>#define	UFN_ALL		0x03#define	UFN_MASK	"\020\01approximate-matching\02full-wildcarding"/*    DATA */int	bflag = 1;int	boundP = 0;int	debug = 0;int	fflag = 0;int	kflag = 0;int	mail = 0;int	nametype = 2;int	network = 0;int	phone = 0;int	query = 1;int	readonly = 0;int	soundex = 0;int	timelimit = 300;int	ufn_options = UFN_ALL;int	verbose = 0;int	watch = 0;int	didbind = 0;int	dontpage = 0;int	rcmode = 00;int	runcom = 0;int	runsys = 0;char   *manager = "internal";char   *pager = "more";char   *server = "internal";char   *myarea = NULLCP;char   *mydn = NULLCP;char   *myhome = NULLCP;char   *myuser = NULLCP;extern char *isodeversion;FILE   *stdfp = stdout;FILE   *errfp = NULL;/*  */int	f_set (), f_help ();int	f_alias (), f_area (), f_dish (), f_edit (), f_manual (), f_report (),	f_thisis ();int	f_bind (), f_quit ();int	f_version (), f_whois ();static struct dispatch dispatches[] = {    "alias", f_alias, DS_SYOK,    "report on active aliases",    "area", f_area, DS_NULL,    "set default area for searches",    "dish", f_dish, DS_USER,    "talk directly to dish (experts only!)",        "edit", f_edit, DS_USER,    "edit entry in the white pages",        "help", f_help, DS_NULL,    "print help information",    "manual", f_manual, DS_NULL,    "print detailed documentation",    "quit", f_quit, DS_USER,    "terminate fred",    "report", f_report, DS_USER,    "send report to white pages manager",    "set", f_set, DS_SYOK,    "display or change variables",    "thisis", f_thisis, DS_USER,    "identify self to the white pages",    "whois", f_whois, DS_NULL,    "find something in the white pages",    "version", f_version, DS_NULL,    "identify the version of the system",    NULL};struct dispatch *getds ();static printvar ();static	snarf ();/*    DISPATCH */fredloop (vec, error)char  **vec;int	error;{    register struct dispatch *ds;    if ((ds = getds (strcmp (*vec, "?") ? *vec : "help")) == NULL)	return error;    if (network) {	if ((ds -> ds_flags & DS_USER)	        || ((ds -> ds_flags & DS_SYOK) && !runsys)) {	    advise (NULLCP, "unavailable operation \"%s\"", *vec);	    return error;	}    }    else	vec[0] = ds -> ds_name;    switch ((*ds -> ds_fnx) (vec)) {	case NOTOK:	    return error;	case OK:	default:	    return OK;        case DONE:	    return DONE;    }}/*  */static struct dispatch *getds (name)char   *name;{    register int    longest,                    nmatches;    register char  *p,                   *q;    char    buffer[BUFSIZ];    register struct dispatch   *ds,                               *fs;    longest = nmatches = 0;    for (ds = dispatches; p = ds -> ds_name; ds++) {	for (q = name; *q == *p++; q++)	    if (*q == NULL)		return ds;	if (*q == NULL)	    if (q - name > longest) {		longest = q - name;		nmatches = 1;		fs = ds;	    }	    else		if (q - name == longest)		    nmatches++;    }    switch (nmatches) {	case 0: 	    if (*(p = name) == '!')		p++;	    for (; *p; p++)		if (!isdigit (*p))		    break;	    if (!*p || network)		for (ds = dispatches; ds -> ds_name; ds++)		    if (strcmp (ds -> ds_name, "whois") == 0)			return ds;	    advise (NULLCP, "unknown operation \"%s\"", name);	    return NULL;	case 1: 	    return fs;	default: 	    for (ds = dispatches, p = buffer; q = ds -> ds_name; ds++)		if (strncmp (q, name, longest) == 0) {		    (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);		    p += strlen (p);		}	    advise (NULLCP, "ambiguous operation, it could be one of:%s",			buffer);	    return NULL;    }}/*    VARIABLES */static char *bool[] = {    "off", "on", NULL};static char *names[] = {    "fullname", "surname", "friendly", NULL};static char *ufnoptions[] = {    "none", "approx", "wild", NULL};struct var {    char   *v_name;    IP	    v_value;    char   *v_dname;    char  **v_dvalue;    char   *v_mask;    IFP	    v_hook;    int	    v_flags;#define	V_NULL		0x00#define	V_RDONLY	0x01#define	V_SERVER	0x02};struct var *getvar ();static struct var vars[] = {    "bell", &bflag, "ring bell at end of screen", bool,    	NULLCP, NULLIFP, V_NULL,    "debug", &debug, "debug FRED", bool,    	NULLCP, NULLIFP, V_NULL,    "manager", NULLIP, "mail-address of local white pages manager", &manager,	NULLCP, NULLIFP, V_RDONLY,    "namesearch", &nametype, "type of name used for matching", names,	NULLCP, NULLIFP, V_NULL,    "pager", NULLIP, "program to use for output pagination", &pager,	NULLCP, NULLIFP, V_RDONLY,    "phone", &phone, "display phone numbers in one-liner", bool,    	NULLCP, NULLIFP, V_NULL,    "query", &query, "confirm two-step operations", bool,    	NULLCP, NULLIFP, V_NULL,    "server", NULLIP, "IP-address of directory assistance server", &server,	NULLCP, NULLIFP, V_RDONLY | V_SERVER,    "soundex", &soundex, "use soundex for matching", bool,    	NULLCP, NULLIFP, V_NULL,    "timelimit", &timelimit, "maximum time (in seconds) for matching", NULLVP,	NULLCP, NULLIFP, V_NULL,    "ufn", &ufn_options, "UFN customization options", ufnoptions,	UFN_MASK, NULLIFP, V_NULL,    "verbose", &verbose, "verbose interaction", bool,    	NULLCP, NULLIFP, V_NULL,    "watch", &watch, "watch dialogue with dish", bool,    	NULLCP, NULLIFP, V_NULL,    NULL};static int varwidth1;static int varwidth2;char    **getval ();/*  */static int  f_set (vec)char  **vec;{    register int    i,		    j;    int     value,	    vflag;    register char **cp,		   *dp;    register struct var *v;    if (*++vec == NULL) {	register int    w;	int     columns,		width,		lines;	register struct var *u;	for (u = vars; u -> v_name; u++)	    continue;	width = varwidth1;	if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0)	    columns = 1;	lines = ((u - vars) + columns - 1) / columns;	(void) printf ("Variables:\n");	for (i = 0; i < lines; i++)	    for (j = 0; j < columns; j++) {		v = vars + j * lines + i;		(void) printf ("%s", v -> v_name);		if (v + lines >= u) {		    (void) printf ("\n");		    break;		}		for (w = strlen (v -> v_name); w < width; w = (w + 8) & ~7)		    (void) putchar ('\t');	    }/*	(void) printf ("\nversion: %s\n", isodeversion); */	return OK;    }    if (strcmp (*vec, "-help") == 0) {	(void) fprintf (stdfp, "set [variable [value]]\n");	(void) fprintf (stdfp,		 "    with no arguments, lists variables which may be set\n");	(void) fprintf (stdfp,		 "    with one argument, lists the value of the named variable\n");	(void) fprintf (stdfp,		 "    with two arguments, sets the given variable accordingly\n");	return OK;    }        if (strcmp (*vec, "?") == 0) {	for (v = vars; v -> v_name; v++)	    printvar (v);	return OK;    }    if ((v = getvar (*vec)) == NULL)	return OK;    if (*++vec == NULL) {	printvar (v);	return OK;    }    if (strcmp (*vec, "?") == 0) {	if (v -> v_value && (cp = v -> v_dvalue)) {	    (void) printf ("use %s of:", v -> v_mask ? "any" : "one");	    for (i = 0; *cp; cp++)		(void) printf ("%s \"%s\"", i++ ? "," : "", *cp);	    if (v -> v_mask)		(void) printf (";\n\tor  \"all\";\n\tor a hexadecimal number from 0 to 0x%x\n",		    (1 << (i - 1)) - 1);	    else		(void) printf (";\n\tor a number from 0 to %d\n",		    cp - v -> v_dvalue - 1);	}	else	    (void) printf ("use any %s value\n",		    v -> v_value ? "integer" : "string");	return OK;    }    if (!runsys && readonly && (v -> v_flags & V_RDONLY)) {	advise (NULLCP, "variable is read-only");	return OK;    }    if (boundP && (v -> v_flags & V_SERVER)) {	advise (NULLCP, "too late!");	return OK;    }    if (v -> v_value == NULLIP) {	register int    w;	if (*v -> v_dvalue)	    free (*v -> v_dvalue);	*v -> v_dvalue = strdup (*vec);	if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2)	    varwidth2 = w;	if (v -> v_hook)	    (*v -> v_hook) (v);	if (verbose)	    printvar (v);	return OK;    }    if (v -> v_mask) {	if (strcmp (dp = *vec, "all") == 0 && (cp = v -> v_dvalue)) {	    i = 1;	    while (*++cp)		i <<= 1;	    value = i - 1;	    j = 1;	}	else {	    if (strncmp (dp, "0x", 2) == 0)		dp += 2;	    for (j = sscanf (dp, "%x", &value); *dp; dp++)		if (!isxdigit (*dp)) {		    j = 0;		    break;		}	}    }    else	j = sscanf (*vec, "%d", &value);    if (j == 1) {	if (cp = v -> v_dvalue) {	    if (v -> v_mask) {		i = 1;		while (*++cp)		    i <<= 1;		if (value >= i)		    goto out_of_range;	    }	    else {		for (; *cp; cp++)		    continue;		if (value >= cp - v -> v_dvalue) {out_of_range: ;		    advise (NULLCP, "value out of range \"%s\"", *vec);		    return OK;		}	    }	}	vflag = verbose;	*v -> v_value = value;	if (v -> v_hook)	    (*v -> v_hook) (v);	if (vflag)	    printvar (v);	return OK;    }

⌨️ 快捷键说明

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