Ejemplo n.º 1
0
Archivo: glom.c Proyecto: muennich/rc3
extern void assign(List *s1, List *s2, bool stack) {
	List *val = s2;
	if (s1 == NULL)
		rc_error("null variable name");
	if (s1->n != NULL)
		rc_error("multi-word variable name");
	if (*s1->w == '\0')
		rc_error("zero-length variable name");
	if (a2u(s1->w) != -1)
		rc_error("numeric variable name");
	if (strchr(s1->w, '=') != NULL)
		rc_error("'=' in variable name");
	if (*s1->w == '*' && s1->w[1] == '\0')
		val = append(varlookup("0"), s2); /* preserve $0 when * is assigned explicitly */
	if (s2 != NULL || stack) {
		if (dashex)
			prettyprint_var(2, s1->w, val);
		varassign(s1->w, val, stack);
		alias(s1->w, varlookup(s1->w), stack);
	} else {
		if (dashex)
			prettyprint_var(2, s1->w, NULL);
		varrm(s1->w, stack);
	}
}
Ejemplo n.º 2
0
static void b_shift(char **av) {
	int shift = (av[1] == NULL ? 1 : a2u(av[1]));
	List *s, *dollarzero;
	if (av[1] != NULL && av[2] != NULL) {
		arg_count("shift");
		return;
	}
	if (shift < 0) {
		badnum(av[1]);
		return;
	}
	s = varlookup("*")->n;
	dollarzero = varlookup("0");
	while (s != NULL && shift != 0) {
		s = s->n;
		--shift;
	}
	if (s == NULL && shift != 0) {
		fprint(2, "cannot shift\n");
		set(FALSE);
	} else {
		varassign("*", append(dollarzero, s), FALSE);
		set(TRUE);
	}
}
Ejemplo n.º 3
0
static void b_cd(char **av) {
	if (*++av == NULL) {
		List *s2 = varlookup("home");
		*av = (s2 == NULL) ? "/" : s2->w;
	} else if (av[1] != NULL) {
		arg_count("cd");
		return;
	}
	if (isabsolute(*av) || streq(*av, ".") || streq(*av, "..")) { /* absolute pathname? */
		if (chdir(*av) < 0) {
			set(FALSE);
			uerror(*av);
		} else {
			update_cwd_var();
			set(TRUE);
		}
	} else {
		char *path = NULL;
		size_t pathlen = 0;
		List nil;
		List *s = varlookup("cdpath");
		if (s == NULL) {
			s = &nil;
			nil.w = "";
			nil.n = NULL;
		}
		do {
			if (s != &nil && *s->w != '\0') {
				const size_t t = strlen(*av) + strlen(s->w) + 2;
				if (t > pathlen)
					path = nnew_arr(char, pathlen = t);
				strcpy(path, s->w);
				if (!streq(s->w, "/")) /* "//" is special to POSIX */
					strcat(path, "/");
				strcat(path, *av);
			} else {
				pathlen = 0;
				path = *av;
			}
			if (chdir(path) >= 0) {
				update_cwd_var();
				set(TRUE);
				if (interactive && *s->w != '\0' && !streq(s->w, "."))
					fprint(1, "%s\n", path);
				return;
			}
			s = s->n;
		} while (s != NULL);
		fprint(2, "couldn't cd to %s\n", *av);
		set(FALSE);
	}
Ejemplo n.º 4
0
/* pathsearch -- evaluate fn %pathsearch + some argument */
extern List *pathsearch(Term *term) {
	List *search, *list;
	search = varlookup("fn-%pathsearch", NULL);
	if (search == NULL)
		fail("es:pathsearch", "%E: fn %%pathsearch undefined", term);
	list = mklist(term, NULL);
	return eval(append(search, list), NULL, 0);
}
Ejemplo n.º 5
0
EPNODE *
dlookup(			/* look up a definition */
	char  *name
)
{
    VARDEF  *vp;
    
    if ((vp = varlookup(name)) == NULL)
	return(NULL);
    return(vp->def);
}
Ejemplo n.º 6
0
extern char *which(char *name, bool verbose) {
	static char *test = NULL;
	static size_t testlen = 0;
	List *path;
	int len;
	if (name == NULL)	/* no filename? can happen with "> foo" as a command */
		return NULL;
	if (!initialized) {
		initialized = TRUE;
		uid = geteuid();
		gid = getegid();
#if HAVE_GETGROUPS
#if HAVE_POSIX_GETGROUPS
		ngroups = getgroups(0, (GETGROUPS_T *)0);
		if (ngroups < 0) {
			uerror("getgroups");
			rc_exit(1);
		}
#else
		ngroups = NGROUPS;
#endif
		if (ngroups) {	
			gidset = ealloc(ngroups * sizeof(GETGROUPS_T));
			getgroups(ngroups, gidset);
		}
#endif
	}
	if (isabsolute(name)) /* absolute pathname? */
		return rc_access(name, verbose) ? name : NULL;
	len = strlen(name);
	for (path = varlookup("path"); path != NULL; path = path->n) {
		size_t need = strlen(path->w) + len + 2; /* one for null terminator, one for the '/' */
		if (testlen < need) {
			efree(test);
			test = ealloc(testlen = need);
		}
		if (*path->w == '\0') {
			strcpy(test, name);
		} else {
			strcpy(test, path->w);
			if (!streq(test, "/")) /* "//" is special to POSIX */
				strcat(test, "/");
			strcat(test, name);
		}
		if (rc_access(test, FALSE))
			return test;
	}
	if (verbose) {
		char *n = protect(name);
		fprint(2, RC "cannot find `%s'\n", n);
		efree(n);
	}
	return NULL;
}
Ejemplo n.º 7
0
Archivo: utils.c Proyecto: muennich/rc3
extern void applylocale() {
	char *lvar[3] = { "LC_ALL", "LC_CTYPE", "LANG" };
	size_t i;
	for (i = 0; i < arraysize(lvar); i++) {
		List *loc = varlookup(lvar[i]);
		if (loc) {
			setlocale(LC_CTYPE, loc->w);
			break;
		}
	}
}
Ejemplo n.º 8
0
Archivo: glob.c Proyecto: muennich/rc3
static List *expandtilde(List *s) {
    List *top, *r, *var;
    char *home;
    size_t i, j, hsize, psize;
    bool tilde;
    for (r = s, tilde = FALSE; r != NULL; r = r->n)
        if (r->m != NULL && r->m[0] && r->w[0] == '~')
            tilde = TRUE;
    if (!tilde)
        return s;
    for (top = NULL; s != NULL; s = s->n) {
        if (top == NULL)
            top = r = nnew(List);
        else
            r = r->n = nnew(List);
        r->w = s->w;
        r->m = s->m;
        if (s->m == NULL || !s->m[0] || s->w[0] != '~')
            continue;
        for (i = 1; s->w[i] != '/' && s->w[i] != '\0'; i++);
        home = NULL;
        if (i == 1) {
            if ((var = varlookup("HOME")) != NULL)
                home = var->w;
        } else {
            char c = s->w[i];
            struct passwd *pw;
            s->w[i] = '\0';
            if ((pw = getpwnam(s->w + 1)) != NULL)
                home = pw->pw_dir;
            s->w[i] = c;
        }
        if (home == NULL || (hsize = strlen(home)) == 0)
            continue;
        psize = strlen(s->w + i) + 1;
        r->w = nalloc(psize + hsize);
        memcpy(r->w, home, hsize);
        memcpy(r->w + hsize, s->w + i, psize);
        for (j = i; s->w[j] != '\0'; j++)
            if (s->m[j])
                break;
        if (s->w[j] != '\0') {
            r->m = nalloc(psize + hsize);
            memset(r->m, 0, hsize);
            memcpy(r->m + hsize, s->m + i, psize);
        } else
            r->m = NULL;
    }
    r->n = NULL;
    return top;
}
Ejemplo n.º 9
0
EPNODE *
dpop(			/* pop a definition */
	char  *name
)
{
    VARDEF  *vp;
    EPNODE  *dp;
    
    if ((vp = varlookup(name)) == NULL || vp->def == NULL)
	return(NULL);
    dp = vp->def;
    vp->def = dp->sibling;
    varfree(vp);
    return(dp);
}
Ejemplo n.º 10
0
static noreturn failexec(char *file, List *args) {
	List *fn;
	assert(gcisblocked());
	fn = varlookup("fn-%exec-failure", NULL);
	if (fn != NULL) {
		int olderror = errno;
		Ref(List *, list, append(fn, mklist(mkstr(file), args)));
		RefAdd(file);
		gcenable();
		RefRemove(file);
		eval(list, NULL, 0);
		RefEnd(list);
		errno = olderror;
	}
	eprint("%s: %s\n", file, esstrerror(errno));
	exit(1);
}
Ejemplo n.º 11
0
void
getstatement(void)			/* get next statement */
{
    EPNODE  *ep;
    char  *qname;
    VARDEF  *vdef;

    if (nextc == ';') {		/* empty statement */
	scan();
	return;
    }
    if (esupport&E_OUTCHAN &&
		nextc == '$') {		/* channel assignment */
	ep = getchan();
	addchan(ep);
    } else {				/* ordinary definition */
	ep = getdefn();
	qname = qualname(dname(ep), 0);
	if (esupport&E_REDEFW && (vdef = varlookup(qname)) != NULL) {
	    if (vdef->def != NULL && epcmp(ep, vdef->def)) {
		wputs(qname);
		if (vdef->def->type == ':')
		    wputs(": redefined constant expression\n");
		else
		    wputs(": redefined\n");
	    } else if (ep->v.kid->type == FUNC && vdef->lib != NULL) {
		wputs(qname);
		wputs(": definition hides library function\n");
	    }
	}
	if (ep->type == ':')
	    dremove(qname);
	else
	    dclear(qname);
	dpush(qname, ep);
    }
    if (nextc != EOF) {
	if (nextc != ';')
	    syntax("';' expected");
	scan();
    }
}
Ejemplo n.º 12
0
/* varlookup -- lookup a variable in the current context */
extern List *varlookup(const char *name, Binding *bp) {
	Var *var;

	if (iscounting(name)) {
		Term *term = nth(varlookup("*", bp), strtol(name, NULL, 10));
		if (term == NULL)
			return NULL;
		return mklist(term, NULL);
	}

	validatevar(name);
	for (; bp != NULL; bp = bp->next)
		if (streq(name, bp->name))
			return bp->defn;

	var = dictget(vars, name);
	if (var == NULL)
		return NULL;
	return var->defn;
}
Ejemplo n.º 13
0
VARDEF *
varinsert(			/* get a link to a variable */
	char  *name
)
{
    VARDEF  *vp;
    int	 hv;
    
    if ((vp = varlookup(name)) != NULL) {
	vp->nlinks++;
	return(vp);
    }
    vp = (VARDEF *)emalloc(sizeof(VARDEF));
    vp->lib = liblookup(name);
    if (vp->lib == NULL)		/* if name not in library */
	name = qualname(name, 0);	/* use fully qualified version */
    hv = hash(name);
    vp->name = savestr(name);
    vp->nlinks = 1;
    vp->def = NULL;
    vp->next = hashtbl[hv];
    hashtbl[hv] = vp;
    return(vp);
}
Ejemplo n.º 14
0
/* expandhome -- do tilde expansion by calling fn %home */
static char *expandhome(char *s, StrList *qp) {
	int c;
	size_t slash;
	List *fn = varlookup("fn-%home", NULL);

	assert(*s == '~');
	assert(qp->str == UNQUOTED || *qp->str == 'r');

	if (fn == NULL)
		return s;

	for (slash = 1; (c = s[slash]) != '/' && c != '\0'; slash++)
		;

	Ref(char *, string, s);
	Ref(StrList *, quote, qp);
	Ref(List *, list, NULL);
	RefAdd(fn);
	if (slash > 1)
		list = mklist(mkstr(gcndup(s + 1, slash - 1)), NULL);
	RefRemove(fn);

	list = eval(append(fn, list), NULL, 0);

	if (list != NULL) {
		if (list->next != NULL)
			fail("es:expandhome", "%%home returned more than one value");
		Ref(char *, home, getstr(list->term));
		if (c == '\0') {
			string = home;
			quote->str = QUOTED;
		} else {
			char *q;
			size_t pathlen = strlen(string);
			size_t homelen = strlen(home);
			size_t len = pathlen - slash + homelen;
			s = gcalloc(len + 1, &StringTag);
			memcpy(s, home, homelen);
			memcpy(&s[homelen], &string[slash], pathlen - slash);
			s[len] = '\0';
			string = s;
			q = quote->str;
			if (q == UNQUOTED) {
				q = gcalloc(len + 1, &StringTag);
				memset(q, 'q', homelen);
				memset(&q[homelen], 'r', pathlen - slash);
				q[len] = '\0';
			} else if (strchr(q, 'r') == NULL)
				q = QUOTED;
			else {
				q = gcalloc(len + 1, &StringTag);
				memset(q, 'q', homelen);
				memcpy(&q[homelen], &quote->str[slash], pathlen - slash);
				q[len] = '\0';
			}
			quote->str = q;
		}
		RefEnd(home);
	}
	RefEnd2(list, quote);
	RefReturn(string);
}
Ejemplo n.º 15
0
extern int main(int argc, char *argv[], char *envp[]) {
	char *dashsee[2], *dollarzero, *null[1];
	int c;
	initprint();
	dashsee[0] = dashsee[1] = NULL;
	dollarzero = argv[0];
	rc_pid = getpid();
	dashell = (*argv[0] == '-'); /* Unix tradition */
	while ((c = rc_getopt(argc, argv, "c:deiIlnopsvx")) != -1)
		switch (c) {
		case 'c':
			dashsee[0] = rc_optarg;
			goto quitopts;
		case 'd':
			dashdee = TRUE;
			break;
		case 'e':
			dashee = TRUE;
			break;
		case 'I':
			dashEYE = TRUE;
			interactive = FALSE;
			break;
		case 'i':
			dasheye = interactive = TRUE;
			break;
		case 'l':
			dashell = TRUE;
			break;
		case 'n':
			dashen = TRUE;
			break;
		case 'o':
			dashoh = TRUE;
			break;
		case 'p':
			dashpee = TRUE;
			break;
		case 's':
			dashess = TRUE;
			break;
		case 'v':
			dashvee = TRUE;
			break;
		case 'x':
			dashex = TRUE;
			break;
		case '?':
			exit(1);
		}
quitopts:
	argv += rc_optind;
	/* use isatty() iff neither -i nor -I is set, and iff the input is not from a script or -c flags */
	if (!dasheye && !dashEYE && dashsee[0] == NULL && (dashess || *argv == NULL))
		interactive = isatty(0);
	if (!dashoh) {
		checkfd(0, rFrom);
		checkfd(1, rCreate);
		checkfd(2, rCreate);
	}
	initsignal();
	inithash();
	initparse();
	assigndefault("ifs", " ", "\t", "\n", (void *)0);
#ifdef DEFAULTPATH
	assigndefault("path", DEFAULTPATH, (void *)0);
#endif
	assigndefault("pid", nprint("%d", rc_pid), (void *)0);
	assigndefault("prompt", "; ", "", (void *)0);
	assigndefault("version", VERSION, "$Release: @(#)" PACKAGE " " VERSION " " RELDATE " $", (void *)0);
	initenv(envp);
	initinput();
	null[0] = NULL;
	starassign(dollarzero, null, FALSE); /* assign $0 to $* */
	inithandler();

	if (dashell) {
		char *rcrc;
		int fd;

		rcrc = concat(varlookup("home"), word("/.rcrc", NULL))->w;
		fd = rc_open(rcrc, rFrom);
		if (fd == -1) {
			if (errno != ENOENT)
				uerror(rcrc);
		} else {
			bool push_interactive;

			pushfd(fd);
			push_interactive = interactive;
			interactive = FALSE;
			doit(TRUE);
			interactive = push_interactive;
			close(fd);
		}
	}

	if (dashsee[0] != NULL || dashess) {	/* input from  -c or -s? */
		if (*argv != NULL)
			starassign(dollarzero, argv, FALSE);
		if (dashess)
			pushfd(0);
		else
			pushstring(dashsee, TRUE);
	} else if (*argv != NULL) {	/* else from a file? */
		b_dot(--argv);
		rc_exit(getstatus());
	} else {			/* else stdin */
		pushfd(0);
	}
	dasheye = FALSE;
	doit(TRUE);
	rc_exit(getstatus());
	return 0; /* Never really reached. */
}
Ejemplo n.º 16
0
static void b_whatis(char **av) {
	bool ess, eff, vee, pee, bee;
	bool f, found;
	int i, ac, c;
	List *s;
	Node *n;
	char *e;
	for (rc_optind = ac = 0; av[ac] != NULL; ac++)
		; /* count the arguments for getopt */
	ess = eff = vee = pee = bee = FALSE;
	while ((c = rc_getopt(ac, av, "sfvpb")) != -1)
		switch (c) {
		default: set(FALSE); return;
		case 's': ess = TRUE; break;
		case 'f': eff = TRUE; break;
		case 'v': vee = TRUE; break;
		case 'p': pee = TRUE; break;
		case 'b': bee = TRUE; break;
		}
	av += rc_optind;
	if (*av == NULL) {
		if (vee|eff)
			whatare_all_vars(eff, vee);
		if (ess)
			whatare_all_signals();
		if (bee)
			for (i = 0; i < arraysize(builtins); i++)
				fprint(1, "builtin %s\n", builtins[i].name);
		if (pee)
			fprint(2, "whatis -p: must specify argument\n");
		if (show(FALSE)) /* no options? */
			whatare_all_vars(TRUE, TRUE);
		set(TRUE);
		return;
	}
	found = TRUE;
	for (i = 0; av[i] != NULL; i++) {
		f = FALSE;
		errno = ENOENT;
		if (show(vee) && (s = varlookup(av[i])) != NULL) {
			f = TRUE;
			prettyprint_var(1, av[i], s);
		}
		if (((show(ess)&&issig(av[i])) || show(eff)) && (n = fnlookup(av[i])) != NULL) {
			f = TRUE;
			prettyprint_fn(1, av[i], n);
		} else if (show(bee) && isbuiltin(av[i]) != NULL) {
			f = TRUE;
			fprint(1, "builtin %s\n", av[i]);
		} else if (show(pee) && (e = which(av[i], FALSE)) != NULL) {
			f = TRUE;
			fprint(1, "%S\n", e);
		}
		if (!f) {
			found = FALSE;
			if (errno != ENOENT)
				uerror(av[i]);
			else
				fprint(2, "%s not found\n", av[i]);
		}
	}
	set(found);
}
Ejemplo n.º 17
0
Archivo: glom.c Proyecto: muennich/rc3
extern List *glom(Node *n) {
	List *v, *head, *tail;
	Node *words;
	if (n == NULL)
		return NULL;
	switch (n->type) {
	case nArgs:
	case nLappend:
		words = n->u[0].p;
		tail = NULL;
		while (words != NULL && (words->type == nArgs || words->type == nLappend)) {
			if (words->u[1].p != NULL && words->u[1].p->type != nWord)
				break;
			head = glom(words->u[1].p);
			if (head != NULL) {
				head->n = tail;
				tail = head;
			}
			words = words->u[0].p;
		}
		v = append(glom(words), tail); /* force left to right evaluation */
		return append(v, glom(n->u[1].p));
	case nBackq:
		return backq(n->u[0].p, n->u[1].p);
	case nConcat:
		head = glom(n->u[0].p); /* force left-to-right evaluation */
		return concat(head, glom(n->u[1].p));
	case nDup:
	case nRedir:
		qredir(n);
		return NULL;
	case nWord:
		return word(n->u[0].s, n->u[1].s);
	case nNmpipe:
		return mkcmdarg(n);
	default:
		/*
		   The next four operations depend on the left-child of glom
		   to be a variable name. Therefore the variable is looked up
		   here.
		*/
		if ((v = glom(n->u[0].p)) == NULL)
			rc_error("null variable name");
		if (v->n != NULL)
			rc_error("multi-word variable name");
		if (*v->w == '\0')
			rc_error("zero-length variable name");
		v = (*v->w == '*' && v->w[1] == '\0') ? varlookup(v->w)->n : varlookup(v->w);
		switch (n->type) {
		default:
			panic("unexpected node in glom");
			exit(1);
			/* NOTREACHED */
		case nCount:
			return count(v);
		case nFlat:
			return flatten(v);
		case nVar:
			return v;
		case nVarsub:
			return varsub(v, glom(n->u[1].p));
		}
	}
}