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 + -
显示快捷键?