/* * Define a variable from a command line argument. */ void define(char *name) { char *cp, *s; struct namelist *nl; struct namelist *value; value = NULL; if (debug) printf("define(%s)\n", name); cp = index(name, '='); if (cp == NULL) value = NULL; else if (cp[1] == '\0') { *cp = '\0'; value = NULL; } else if (cp[1] != '(') { *cp++ = '\0'; value = makenl(cp); } else { nl = NULL; *cp++ = '\0'; do cp++; while (*cp == ' ' || *cp == '\t'); for (s = cp; ; s++) { switch (*s) { case ')': *s = '\0'; case '\0': break; case ' ': case '\t': *s++ = '\0'; while (*s == ' ' || *s == '\t') s++; if (*s == ')') *s = '\0'; break; default: continue; } if (nl == NULL) value = nl = makenl(cp); else { nl->n_next = makenl(cp); nl = nl->n_next; } if (*s == '\0') break; cp = s; } } lookup(name, REPLACE, value); }
/* * Take a list of names and expand any macros, etc. * wh = E_VARS if expanding variables. * wh = E_SHELL if expanding shell characters. * wh = E_TILDE if expanding `~'. * or any of these or'ed together. * * Major portions of this were snarfed from csh/sh.glob.c. */ struct namelist * expand(struct namelist *list, int wh) { struct namelist *nl, *prev; int n; char pathbuf[BUFSIZ]; char *argvbuf[GAVSIZ]; if (debug) { printf("expand(%p, %d)\nlist = ", list, wh); prnames(list); } if (wh == 0) { char *cp; for (nl = list; nl != NULL; nl = nl->n_next) for (cp = nl->n_name; *cp; cp++) *cp = *cp & TRIM; return(list); } which = wh; path = tpathp = pathp = pathbuf; *pathp = '\0'; lastpathp = &path[sizeof pathbuf - 2]; tilde = ""; eargc = 0; eargv = sortbase = argvbuf; *eargv = NULL; nleft = NCARGS - 4; /* * Walk the name list and expand names into eargv[]; */ for (nl = list; nl != NULL; nl = nl->n_next) expstr(nl->n_name); /* * Take expanded list of names from eargv[] and build a new list. */ list = prev = NULL; for (n = 0; n < eargc; n++) { nl = makenl(NULL); nl->n_name = eargv[n]; if (prev == NULL) list = prev = nl; else { prev->n_next = nl; prev = nl; } } if (debug) { printf("expanded list = "); prnames(list); } return(list); }
/* * rcp like interface for distributing files. */ static void docmdargs(int nargs, char **args) { struct namelist *nl, *prev; char *cp; struct namelist *files, *hosts; struct subcmd *cmds; char *dest; static struct namelist tnl = { NULL, NULL }; int i; files = NULL; if (nargs < 2) usage(); prev = NULL; for (i = 0; i < nargs - 1; i++) { nl = makenl(args[i]); if (prev == NULL) files = prev = nl; else { prev->n_next = nl; prev = nl; } } cp = args[i]; if ((dest = index(cp, ':')) != NULL) *dest++ = '\0'; tnl.n_name = cp; hosts = expand(&tnl, E_ALL); if (nerrs) exit(1); if (dest == NULL || *dest == '\0') cmds = NULL; else { cmds = makesubcmd(INSTALL); cmds->sc_options = options; cmds->sc_name = dest; } if (debug) { printf("docmdargs()\nfiles = "); prnames(files); printf("hosts = "); prnames(hosts); } insert(NULL, files, hosts, cmds); docmds(NULL, 0, NULL); }