|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 17246 (0x435e) Types: TextFile Names: »dispatch.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/others/quipu/uips/fred/dispatch.c«
/* dispatch.c - fred dispatch */ #ifndef lint static char *rcsid = "$Header: /f/osi/others/quipu/uips/fred/RCS/dispatch.c,v 7.4 90/01/16 20:43:19 mrose Exp $"; #endif /* * $Header: /f/osi/others/quipu/uips/fred/RCS/dispatch.c,v 7.4 90/01/16 20:43:19 mrose Exp $ * * * $Log: dispatch.c,v $ * Revision 7.4 90/01/16 20:43:19 mrose * last check-out * * Revision 7.3 90/01/11 18:36:21 mrose * real-sync * * Revision 7.2 89/12/14 18:48:56 mrose * KIS project * * Revision 7.1 89/12/13 20:01:43 mrose * errfp * * Revision 7.0 89/11/23 22:08:52 mrose * Release 6.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> /* \f DATA */ int debug = 0; int fflag = 0; int kflag = 0; int mail = 0; int nametype = 1; int network = 0; int query = 1; int readonly = 0; int soundex = 0; int timelimit = 300; int verbose = 0; int watch = 0; int usetty = 1; int ifd = NOTOK; int ofd = NOTOK; int rcmode = 00; int runcom = 0; int runsys = 0; char *manager = "internal"; char *pager = "more"; char *mydn = NULLCP; char *myhome = NULLCP; char *myuser = NULLCP; FILE *stdfp = stdout; FILE *errfp = NULL; /* \f */ 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_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", NULL }; struct dispatch *getds (); /* \f 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; } } /* \f */ 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 (network) { for (ds = dispatches; ds -> ds_name; ds++) if (strcmp (ds -> ds_name, "whois") == 0) break; if (ds -> ds_name) 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; } } /* \f VARIABLES */ static char *bool[] = { "off", "on", NULL }; static char *names[] = { "fullname", "surname", 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 }; struct var *getvar (); static struct var vars[] = { "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, "query", &query, "confirm two-step operations", bool, NULLCP, NULLIFP, V_NULL, "soundex", &soundex, "use soundex for matching", bool, NULLCP, NULLIFP, V_NULL, "timelimit", &timelimit, "maximum time (in seconds) for matching", NULLVP, NULLCP, 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 (); /* \f */ 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; printf ("Variables:\n"); for (i = 0; i < lines; i++) for (j = 0; j < columns; j++) { v = vars + j * lines + i; printf ("%s", v -> v_name); if (v + lines >= u) { printf ("\n"); break; } for (w = strlen (v -> v_name); w < width; w = (w + 8) & ~7) (void) putchar ('\t'); } return OK; } if (strcmp (*vec, "-help") == 0) { fprintf (stdfp, "set [variable [value]]\n"); fprintf (stdfp, " with no arguments, lists variables which may be set\n"); fprintf (stdfp, " with one argument, lists the value of the named variable\n"); 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 (readonly && (v -> v_flags & V_RDONLY)) { advise (NULLCP, "variable is read-only"); return OK; } if (strcmp (*vec, "?") == 0) { if (v -> v_value && (cp = v -> v_dvalue)) { printf ("use %s of:", v -> v_mask ? "any" : "one"); for (i = 0; *cp; cp++) printf ("%s \"%s\"", i++ ? "," : "", *cp); if (v -> v_mask) printf (";\n\tor \"all\";\n\tor a hexadecimal number from 0 to 0x%x\n", (1 << (i - 1)) - 1); else printf (";\n\tor a number from 0 to %d\n", cp - v -> v_dvalue - 1); } else printf ("use any %s value\n", v -> v_value ? "integer" : "string"); 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; } if (v -> v_mask) { i = 0; for (; *vec; vec++) { if (!(cp = getval (*vec, v -> v_dvalue))) { advise (NULLCP, "bad value \"%s\"", *vec); return OK; } if ((j = cp - v -> v_dvalue) <= 0) continue; i |= 1 << (j - 1); } vflag = verbose; *v -> v_value = i; if (v -> v_hook) (*v -> v_hook) (v); if (vflag) printvar (v); return OK; } if (v -> v_dvalue && (cp = getval (*vec, v -> v_dvalue))) { vflag = verbose; *v -> v_value = cp - v -> v_dvalue; if (v -> v_hook) (*v -> v_hook) (v); if (vflag) printvar (v); } else if (!v -> v_dvalue) advise (NULLCP, "bad value \"%s\"", *vec); return OK; } /* \f */ static printvar (v) register struct var *v; { int i; char buffer[BUFSIZ]; if (runcom) return; printf ("%-*s = ", varwidth1, v -> v_name); if (v -> v_value) { i = *v -> v_value; if (v -> v_mask) { if (v -> v_dvalue) { if (i == 0) printf ("%-*s", varwidth2, v -> v_dvalue[i]); else { (void) strcpy (buffer, sprintb (i, v -> v_mask)); if (strlen (buffer) <= varwidth2) printf ("%-*s", varwidth2, buffer); else printf ("%s\n%*s", buffer, varwidth1 + varwidth2 + 3, ""); } } else printf ("0x%-*x", varwidth2 - 2, i); } else { if (v -> v_dvalue) printf ("%-*s", varwidth2, v -> v_dvalue[i]); else printf ("%-*d", varwidth2, i); } } else if (*v -> v_dvalue) { (void) sprintf (buffer, "\"%s\"", *v -> v_dvalue); printf ("%-*s", varwidth2, buffer); } printf (" - %s\n", v -> v_dname); } /* \f */ static char **getval (name, choices) register char *name; char **choices; { register int longest, nmatches; register char *p, *q, **cp, **fp; char buffer[BUFSIZ]; longest = nmatches = 0; for (cp = choices; p = *cp; cp++) { for (q = name; *q == *p++; q++) if (*q == NULL) return cp; if (*q == NULL) if (q - name > longest) { longest = q - name; nmatches = 1; fp = cp; } else if (q - name == longest) nmatches++; } switch (nmatches) { case 0: advise (NULLCP, "unknown value \"%s\"", name); return NULL; case 1: return fp; default: for (cp = choices, p = buffer; q = *cp; cp++) if (strncmp (q, name, longest) == 0) { (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q); p += strlen (p); } advise (NULLCP, "ambiguous value, it could be one of:%s", buffer); return NULL; } } /* \f */ static struct var *getvar (name) register char *name; { register int longest, nmatches; register char *p, *q; char buffer[BUFSIZ]; register struct var *v, *f; longest = nmatches = 0; for (v = vars; p = v -> v_name; v++) { for (q = name; *q == *p++; q++) if (*q == NULL) return v; if (*q == NULL) if (q - name > longest) { longest = q - name; nmatches = 1; f = v; } else if (q - name == longest) nmatches++; } switch (nmatches) { case 0: advise (NULLCP, "unknown variable \"%s\"", name); return NULL; case 1: return f; default: for (v = vars, p = buffer; q = v -> v_name; v++) if (strncmp (q, name, longest) == 0) { (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q); p += strlen (p); } advise (NULLCP, "ambiguous variable, it could be one of:%s", buffer); return NULL; } } /* \f HELP */ static int helpwidth; /* \f */ int f_help (vec) char **vec; { register int i, j, w; int columns, width, lines; register struct dispatch *ds, *es; if (network || vec == NULL) { register char **ap; for (ap = whois_help; *ap; ap++) fprintf (stdfp, "%s%s", *ap, EOLN); return OK; } for (es = dispatches; es -> ds_name; es++) continue; width = helpwidth; if (*++vec == NULL) { if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0) columns = 1; lines = ((es - dispatches) + columns - 1) / columns; printf ("Operations:\n"); for (i = 0; i < lines; i++) for (j = 0; j < columns; j++) { ds = dispatches + j * lines + i; printf ("%s", ds -> ds_name); if (ds + lines >= es) { printf ("\n"); break; } for (w = strlen (ds -> ds_name); w < width; w = (w + 8) & ~7) (void) putchar ('\t'); } printf ("\n"); return OK; } if (strcmp (*vec, "-help") == 0) { fprintf (stdfp, "help [commands ...]\n"); fprintf (stdfp, " with no arguments, lists operations which may be invoked\n"); fprintf (stdfp, " otherwise prints help for each operation given\n"); return OK; } for (; *vec; vec++) if (strcmp (*vec, "?") == 0) { for (ds = dispatches; ds -> ds_name; ds++) printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help); break; } else if (ds = getds (*vec)) printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help); return OK; } /* \f MISCELLANY */ rcinit () { register int w; register char **cp, *dp; char buffer[BUFSIZ]; register struct dispatch *ds; register struct var *v; if (fflag) return; if ((myhome = getenv ("HOME")) == NULL) myhome = "."; /* could do passwd search... */ if ((myuser = getenv ("USER")) == NULLCP) myuser = getenv ("LOGNAME"); if (dp = getenv ("QUIPURC")) (void) strcpy (buffer, dp); else (void) sprintf (buffer, "%s/.quipurc", myhome); snarf (buffer, "username:", &mydn); for (ds = dispatches, helpwidth = 0; ds -> ds_name; ds++) if ((w = strlen (ds -> ds_name)) > helpwidth) helpwidth = w; for (v = vars, varwidth1 = 0; v -> v_name; v++) { if ((w = strlen (v -> v_name)) > varwidth1) varwidth1 = w; if (v -> v_value) { if (cp = v -> v_dvalue) { if (v -> v_mask) { #ifdef notdef w = 1; while (*++cp) w <<= 1; w--; if ((w = strlen (sprintb (w, v -> v_mask))) > varwidth2) varwidth2 = w; #endif } else for (; *cp; cp++) if ((w = strlen (*cp)) > varwidth2) varwidth2 = w; } } else if (*v -> v_dvalue) { *v -> v_dvalue = strdup (*v -> v_dvalue); if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2) varwidth2 = w; } } } /* \f */ static snarf (file, name, variable) char *file, *name, **variable; { int i; register char *bp, *dp, *ep; char buffer[BUFSIZ]; FILE *fp; if (fp = fopen (file, "r")) { while (fgets (bp = buffer, sizeof buffer, fp)) { if (*bp == '#' || *bp == '\n') continue; if (bp = index (buffer, '\n')) *bp = NULL; if (lexnequ (buffer, name, strlen (name))) continue; bp = buffer + strlen (name); while (isspace (*bp)) bp++; if (*bp == '"') { if (*(dp = bp + strlen (bp) - 1) == '"') bp++, *dp = NULL; goto set_variable; } i = 0; for (dp = ep = bp; *dp; ) { if (isspace (*dp)) { *ep = ' '; while (isspace (*++dp)) i = 1; if (*dp) ep++; else break; } if (i == 1) *ep = *dp; dp++, ep++; } *ep = NULL; set_variable: ; if (*variable) free (*variable); *variable = strdup (bp); break; } (void) fclose (fp); } } /* \f */ rcfile (file, op, isystem) char *file; int op, isystem; { register char *cp; char buffer[BUFSIZ + 1], *vec[NVEC + 1]; register FILE *fp; struct stat st; if ((fp = fopen (file, "r")) == NULL) return; runcom = 1, runsys = isystem; if (fstat (fileno (fp), &st) == NOTOK) adios (file, "unable to fstat"); rcmode = st.st_mode & 0777; while (fgets (buffer, sizeof buffer, fp)) { if (*buffer == '#') continue; if (cp = index (buffer, '\n')) *cp = NULL; bzero ((char *) vec, sizeof vec); if (str2vec (buffer, vec) < 1) continue; if (fredloop (vec, NOTOK) != OK && op) { (void) f_quit (NULLVP); exit (1); } } runcom = 0; (void) fclose (fp); } /* \f */ #ifndef TIOCGWINSZ /* ARGSUSED */ #endif int ncols (fp) FILE *fp; { #ifdef TIOCGWINSZ int i; struct winsize ws; if (ioctl (fileno (fp), TIOCGWINSZ, (char *) &ws) != NOTOK && (i = ws.ws_col) > 0) return i; #endif return 80; }