Exemple #1
0
static void printlim(enum limtype how, const struct rlimit *limit,
		     const struct limits *l)
{
	rlim_t val;

	val = limit->rlim_max;
	if (how & SOFT)
		val = limit->rlim_cur;

	if (val == RLIM_INFINITY)
		out1fmt("unlimited\n");
	else {
		val /= l->factor;
		out1fmt("%" PRIdMAX "\n", (intmax_t) val);
	}
}
/*
 *  The exp(1) builtin.
 */
int
letcmd(int argc, char **argv)
{
	const char *p;
	char *concat;
	char **ap;
	arith_t i;

	if (argc > 1) {
		p = argv[1];
		if (argc > 2) {
			/*
			 * Concatenate arguments.
			 */
			STARTSTACKSTR(concat);
			ap = argv + 2;
			for (;;) {
				while (*p)
					STPUTC(*p++, concat);
				if ((p = *ap++) == NULL)
					break;
				STPUTC(' ', concat);
			}
			STPUTC('\0', concat);
			p = grabstackstr(concat);
		}
	} else
		p = "";

	i = arith(p);

	out1fmt(ARITH_FORMAT_STR "\n", i);
	return !i;
}
Exemple #3
0
static void
printalias(const struct alias *a)
{
	out1fmt("%s=", a->name);
	out1qstr(a->val);
	out1c('\n');
}
Exemple #4
0
int
wordexpcmd(int argc, char **argv)
{
	size_t len;
	int i;

	out1fmt("%08x", argc - 1);
	for (i = 1, len = 0; i < argc; i++)
		len += strlen(argv[i]);
	out1fmt("%08x", (int)len);
	for (i = 1; i < argc; i++) {
		out1str(argv[i]);
		out1c('\0');
	}
        return (0);
}
Exemple #5
0
int
showvars(shinstance *psh, const char *name, int flag, int show_value)
{
    struct var **vpp;
    struct var *vp;
    const char *p;

    static struct var **list;	/* static in case we are interrupted */
    static int list_len;
    int count = 0;

    if (!list) {
        list_len = 32;
        list = ckmalloc(psh, list_len * sizeof(*list));
    }

    for (vpp = psh->vartab ; vpp < psh->vartab + VTABSIZE ; vpp++) {
        for (vp = *vpp ; vp ; vp = vp->next) {
            if (flag && !(vp->flags & flag))
                continue;
            if (vp->flags & VUNSET && !(show_value & 2))
                continue;
            if (count >= list_len) {
                list = ckrealloc(psh, list,
                                 (list_len << 1) * sizeof(*list));
                list_len <<= 1;
            }
            list[count++] = vp;
        }
    }

    qsort(list, count, sizeof(*list), sort_var);

    for (vpp = list; count--; vpp++) {
        vp = *vpp;
        if (name)
            out1fmt(psh, "%s ", name);
        for (p = vp->text ; *p != '=' ; p++)
            out1c(psh, *p);
        if (!(vp->flags & VUNSET) && show_value) {
            out1fmt(psh, "=");
            print_quoted(psh, ++p);
        }
        out1c(psh, '\n');
    }
    return 0;
}
Exemple #6
0
int
wordexpcmd(shinstance *psh, int argc, char **argv)
{
	size_t len;
	int i;

	out1fmt(psh, "%d", argc - 1);
	out1c(psh, '\0');
	for (i = 1, len = 0; i < argc; i++)
		len += strlen(argv[i]);
	out1fmt(psh, "%zd", len);
	out1c(psh, '\0');
	for (i = 1; i < argc; i++) {
		out1str(psh, argv[i]);
		out1c(psh, '\0');
	}
	return (0);
}
Exemple #7
0
int
trapcmd(int argc, char **argv)
{
    char *action;
    char **ap;
    int signo;

    nextopt(nullstr);
    ap = argptr;
    if (!*ap) {
        for (signo = 0 ; signo < NSIG ; signo++) {
            if (trap[signo] != NULL) {
                out1fmt(
                    "trap -- %s %s\n",
                    single_quote(trap[signo]),
                    signal_names[signo]
                );
            }
        }
        return 0;
    }
    if (!ap[1])
        action = NULL;
    else
        action = *ap++;
    while (*ap) {
        if ((signo = decode_signal(*ap, 0)) < 0) {
            outfmt(out2, "trap: %s: bad trap\n", *ap);
            return 1;
        }
        INTOFF;
        if (action) {
            if (action[0] == '-' && action[1] == '\0')
                action = NULL;
            else {
                if (*action)
                    trapcnt++;
                action = savestr(action);
            }
        }
        if (trap[signo]) {
            if (*trap[signo])
                trapcnt--;
            ckfree(trap[signo]);
        }
        trap[signo] = action;
        if (signo != 0)
            setsignal(signo);
        INTON;
        ap++;
    }
    return 0;
}
Exemple #8
0
int
bgcmd(int argc, char **argv)
{
	struct job *jp;
	int i;

	nextopt("");
	do {
		jp = getjob(*argptr, 0);
		if (jp->jobctl == 0)
			error("job not created under job control");
		set_curjob(jp, 1);
		out1fmt("[%ld] %s", (long)(jp - jobtab + 1), jp->ps[0].cmd);
		for (i = 1; i < jp->nprocs; i++)
			out1fmt(" | %s", jp->ps[i].cmd );
		out1c('\n');
		flushall();
		restartjob(jp);
	} while (*argptr && *++argptr);
	return 0;
}
Exemple #9
0
static void
printalias(const struct alias *a)
{
	char *p;

	out1fmt("%s=", a->name);
	/* Don't print the space added above. */
	p = a->val + strlen(a->val) - 1;
	*p = '\0';
	out1qstr(a->val);
	*p = ' ';
	out1c('\n');
}
Exemple #10
0
int
jobidcmd(int argc __unused, char **argv)
{
	struct job *jp;
	int i;

	jp = getjob(argv[1]);
	for (i = 0 ; i < jp->nprocs ; ) {
		out1fmt("%d", (int)jp->ps[i].pid);
		out1c(++i < jp->nprocs? ' ' : '\n');
	}
	return 0;
}
Exemple #11
0
int
pwd_main(int argc, char **argv)
{
	char *dir = getpwd();
	
	out1fmt(snlfmt, dir ? dir : "");
	if (dir != NULL)
	{
		free(dir);
	}

	return 0;
}
Exemple #12
0
/*
 * TODO - sort output
 */
int
aliascmd(int argc, char **argv)
{
	char *n, *v;
	int ret = 0;
	struct alias *ap;

	if (argc == 1) {
		int i;

		for (i = 0; i < ATABSIZE; i++)
			for (ap = atab[i]; ap; ap = ap->next) {
				if (*ap->name != '\0') {
					out1fmt("alias %s=", ap->name);
					print_quoted(ap->val);
					out1c('\n');
				}
			}
		return (0);
	}
	while ((n = *++argv) != NULL) {
		if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
			if ((ap = lookupalias(n, 0)) == NULL) {
				outfmt(out2, "alias: %s not found\n", n);
				ret = 1;
			} else {
				out1fmt("alias %s=", n);
				print_quoted(ap->val);
				out1c('\n');
			}
		} else {
			*v++ = '\0';
			setalias(n, v);
		}
	}

	return (ret);
}
Exemple #13
0
STATIC void
minus_o(char *name, int val)
{
	int doneset, i;

	if (name == NULL) {
		if (val) {
			/* "Pretty" output. */
			out1str("Current option settings\n");
			for (i = 0; i < NOPTS; i++)
				out1fmt("%-16s%s\n", optlist[i].name,
					optlist[i].val ? "on" : "off");
		} else {
			/* Output suitable for re-input to shell. */
			for (doneset = i = 0; i < NOPTS; i++)
				if (optlist[i].val) {
					if (!doneset) {
						out1str("set");
						doneset = 1;
					}
					out1fmt(" -o %s", optlist[i].name);
				}
			if (doneset)
				out1c('\n');
		}
	} else {
		for (i = 0; i < NOPTS; i++)
			if (equal(name, optlist[i].name)) {
				if (!val && privileged && equal(name, "privileged")) {
					(void) setuid(getuid());
					(void) setgid(getgid());
				}
				setoption(optlist[i].letter, val);
				return;
			}
		error("Illegal option -o %s", name);
	}
}
Exemple #14
0
/*
 * Print a list of valid signal names.
 */
static void
printsignals(void)
{
	int n, outlen;

	outlen = 0;
	for (n = 1; n < _NSIG; n++) {
		if (strsigname(n)) {
			out1fmt("%s", strsigname(n));
			outlen += strlen(strsigname(n));
		} else {
			out1fmt("%d", n);
			outlen += 3;	/* good enough */
		}
		++outlen;
		if (outlen > 70 || n == _NSIG - 1) {
			out1str("\n");
			outlen = 0;
		} else {
			out1c(' ');
		}
	}
}
Exemple #15
0
int
jobidcmd(int argc, char **argv)
{
	struct job *jp;
	int i;

	nextopt("");
	jp = getjob(*argptr, 0);
	for (i = 0 ; i < jp->nprocs ; ) {
		out1fmt("%ld", (long)jp->ps[i].pid);
		out1c(++i < jp->nprocs ? ' ' : '\n');
	}
	return 0;
}
Exemple #16
0
/*
 * Print a list of valid signal names.
 */
static void
printsignals(void)
{
	int n, outlen;

	outlen = 0;
	for (n = 1; n < sys_nsig; n++) {
		if (sys_signame[n]) {
			out1fmt("%s", sys_signame[n]);
			outlen += strlen(sys_signame[n]);
		} else {
			out1fmt("%d", n);
			outlen += 3;	/* good enough */
		}
		++outlen;
		if (outlen > 71 || n == sys_nsig - 1) {
			out1str("\n");
			outlen = 0;
		} else {
			out1c(' ');
		}
	}
}
Exemple #17
0
int
sqlCB(sqlite3_stmt * stmt)
{
	int		icol;
	const char     *colname;
	int		allcol;
	int		printheader = 0;
	char           *sqlcolnames = NULL;

	if (stmt == NULL)
		return 1;

	sqlcolnames = getenv("sqlcolnames");
	allcol = sqlite3_column_count(stmt);

	if ((printheader) && (sqlcolnames == NULL)) {
		for (icol = 0; icol < allcol; icol++) {
			colname = sqlite3_column_name(stmt, icol);
			if (icol != (allcol - 1))
				out1fmt("%s%s", colname, delim);
			else
				out1fmt("%s\n", colname);
		}
	}
	for (icol = 0; icol < allcol; icol++) {
		if (sqlcolnames)
			out1fmt("%s=\"%s\"\n", sqlite3_column_name(stmt, icol), sqlite3_column_text(stmt, icol));
		else {
			if (icol == (allcol - 1))
				out1fmt("%s\n", sqlite3_column_text(stmt, icol));
			else
				out1fmt("%s%s", sqlite3_column_text(stmt, icol), delim);
		}
	}

	return 0;
}
Exemple #18
0
/*
 * Print a list of valid signal names
 */
static void
printsignals(void)
{
	int n;

	out1str("EXIT ");

	for (n = 1; n < NSIG; n++) {
		out1fmt("%s", sys_signame[n]);
		if ((n == NSIG/2) ||  n == (NSIG - 1))
			out1str("\n");
		else
			out1c(' ');
	}
}
Exemple #19
0
void
print_quoted(shinstance *psh, const char *p)
{
    const char *q;

    if (strcspn(p, "|&;<>()$`\\\"' \t\n*?[]#~=%") == strlen(p)) {
        out1fmt(psh, "%s", p);
        return;
    }
    while (*p) {
        if (*p == '\'') {
            out1fmt(psh, "\\'");
            p++;
            continue;
        }
        q = strchr(p, '\'');
        if (!q) {
            out1fmt(psh, "'%s'", p );
            return;
        }
        out1fmt(psh, "'%.*s'", (int)(q - p), p );
        p = q;
    }
}
Exemple #20
0
int cbsdlua_loadcmd(int argc, char **argv) {
	int error;
//	lua_State *L = luaL_newstate();
//	luaL_openlibs(L);

	if (argc!=2) {
		out1fmt("Use: cbsdlua_load <path>\n");
		return 1;
	}

	lua_loadscript(L,argv[1]);

//	lua_close(L);

	return 0;
}
Exemple #21
0
/*
 * Print a list of valid signal names
 */
static void
printsignals(void)
{
	int n;

	out1str("EXIT ");
#ifndef HAVE_SYS_SIGNAME
	init_sys_signame();
#endif

	for (n = 1; n < NSIG; n++) {
		out1fmt("%s", sys_signame[n]);
		if ((n == NSIG/2) ||  n == (NSIG - 1))
			out1str("\n");
		else
			out1c(' ');
	}
}
Exemple #22
0
int
bgcmd(int argc, char **argv)
{
	struct job *jp;

	do {
		jp = getjob(*++argv);
		if (jp->jobctl == 0)
			error("job not created under job control");
		if (jp->state == JOBDONE)
			continue;
		restartjob(jp);
		jp->foreground = 0;
		out1fmt("[%td] ", jp - jobtab + 1);
		printjobcmd(jp);
	} while (--argc > 1);
	return 0;
}
Exemple #23
0
int
update_idlecmd(int argc, char **argv)
{
	char           *str = NULL;
	char		sql       [] = "UPDATE nodelist SET idle=datetime('now','localtime') WHERE nodename=''";

	if (argc != 2) {
		out1fmt("%d, usage: update_idle <nodename>\n", argc);
		return 0;
	}
	str = calloc(strlen(sql) + strlen(argv[1]) + 1, sizeof(char *));

	sprintf(str, "UPDATE nodelist SET idle=datetime('now','localtime') WHERE nodename='%s'", argv[1]);

	char           *a[] = {NULL, "nodes", str};
	sqlitecmd(3, a);

	free(str);

	return 0;
}
Exemple #24
0
int
ulimitcmd(int argc, char **argv)
{
	int	c;
	rlim_t val = 0;
	enum limtype how = SOFT | HARD;
	const struct limits	*l;
	int		set, all = 0;
	int		optc, what;
	struct rlimit	limit;

	what = 'f';
	while ((optc = nextopt("HSa"
#ifdef RLIMIT_CPU
			       "t"
#endif
#ifdef RLIMIT_FSIZE
			       "f"
#endif
#ifdef RLIMIT_DATA
			       "d"
#endif
#ifdef RLIMIT_STACK
			       "s"
#endif
#ifdef RLIMIT_CORE
			       "c"
#endif
#ifdef RLIMIT_RSS
			       "m"
#endif
#ifdef RLIMIT_MEMLOCK
			       "l"
#endif
#ifdef RLIMIT_NPROC
			       "p"
#endif
#ifdef RLIMIT_NOFILE
			       "n"
#endif
#ifdef RLIMIT_AS
			       "v"
#endif
#ifdef RLIMIT_LOCKS
			       "w"
#endif
	)) != '\0')
		switch (optc) {
		case 'H':
			how = HARD;
			break;
		case 'S':
			how = SOFT;
			break;
		case 'a':
			all = 1;
			break;
		default:
			what = optc;
		}

	for (l = limits; l->option != what; l++)
		;

	set = *argptr ? 1 : 0;
	if (set) {
		char *p = *argptr;

		if (all || argptr[1])
			sh_error("too many arguments");
		if (strcmp(p, "unlimited") == 0)
			val = RLIM_INFINITY;
		else {
			val = (rlim_t) 0;

			while ((c = *p++) >= '0' && c <= '9')
			{
				val = (val * 10) + (long)(c - '0');
				if (val < (rlim_t) 0)
					break;
			}
			if (c)
				sh_error("bad number");
			val *= l->factor;
		}
	}
	if (all) {
		for (l = limits; l->name; l++) {
			getrlimit(l->cmd, &limit);
			out1fmt("%-20s ", l->name);
			printlim(how, &limit, l);
		}
		return 0;
	}

	getrlimit(l->cmd, &limit);
	if (set) {
		if (how & HARD)
			limit.rlim_max = val;
		if (how & SOFT)
			limit.rlim_cur = val;
		if (setrlimit(l->cmd, &limit) < 0)
			sh_error("error setting limit (%s)", strerror(errno));
	} else {
		printlim(how, &limit, l);
	}
	return 0;
}
Exemple #25
0
int
umaskcmd(int argc, char **argv)
{
	char *ap;
	int mask;
	int i;
	int symbolic_mode = 0;

	while ((i = nextopt("S")) != '\0') {
		symbolic_mode = 1;
	}

	INTOFF;
	mask = umask(0);
	umask(mask);
	INTON;

	if ((ap = *argptr) == NULL) {
		if (symbolic_mode) {
			char buf[18];
			int j;

			mask = ~mask;
			ap = buf;
			for (i = 0; i < 3; i++) {
				*ap++ = "ugo"[i];
				*ap++ = '=';
				for (j = 0; j < 3; j++)
					if (mask & (1 << (8 - (3*i + j))))
						*ap++ = "rwx"[j];
				*ap++ = ',';
			}
			ap[-1] = '\0';
			out1fmt("%s\n", buf);
		} else {
			out1fmt("%.4o\n", mask);
		}
	} else {
		int new_mask;

		if (isdigit((unsigned char) *ap)) {
			new_mask = 0;
			do {
				if (*ap >= '8' || *ap < '0')
					sh_error(illnum, *argptr);
				new_mask = (new_mask << 3) + (*ap - '0');
			} while (*++ap != '\0');
		} else {
			int positions, new_val;
			char op;

			mask = ~mask;
			new_mask = mask;
			positions = 0;
			while (*ap) {
				while (*ap && strchr("augo", *ap))
					switch (*ap++) {
					case 'a': positions |= 0111; break;
					case 'u': positions |= 0100; break;
					case 'g': positions |= 0010; break;
					case 'o': positions |= 0001; break;
					}
				if (!positions)
					positions = 0111; /* default is a */
				if (!strchr("=+-", op = *ap))
					break;
				ap++;
				new_val = 0;
				while (*ap && strchr("rwxugoXs", *ap))
					switch (*ap++) {
					case 'r': new_val |= 04; break;
					case 'w': new_val |= 02; break;
					case 'x': new_val |= 01; break;
					case 'u': new_val |= mask >> 6;
						  break;
					case 'g': new_val |= mask >> 3;
						  break;
					case 'o': new_val |= mask >> 0;
						  break;
					case 'X': if (mask & 0111)
							new_val |= 01;
						  break;
					case 's': /* ignored */
						  break;
					}
				new_val = (new_val & 07) * positions;
				switch (op) {
				case '-':
					new_mask &= ~new_val;
					break;
				case '=':
					new_mask = new_val
					    | (new_mask & ~(positions * 07));
					break;
				case '+':
					new_mask |= new_val;
				}
				if (*ap == ',') {
					positions = 0;
					ap++;
				} else if (!strchr("=+-", *ap))
					break;
			}
			if (*ap) {
				sh_error("Illegal mode: %s", *argptr);
				return 1;
			}
			new_mask = ~new_mask;
		}
		umask(new_mask);
	}
	return 0;
}
Exemple #26
0
void
evaltree(union node *n, int flags)
{
	int do_etest;
	union node *next;
	struct stackmark smark;

	setstackmark(&smark);
	do_etest = 0;
	if (n == NULL) {
		TRACE(("evaltree(NULL) called\n"));
		exitstatus = 0;
		goto out;
	}
	do {
		next = NULL;
#ifndef NO_HISTORY
		displayhist = 1;	/* show history substitutions done with fc */
#endif
		TRACE(("evaltree(%p: %d) called\n", (void *)n, n->type));
		switch (n->type) {
		case NSEMI:
			evaltree(n->nbinary.ch1, flags & ~EV_EXIT);
			if (evalskip)
				goto out;
			next = n->nbinary.ch2;
			break;
		case NAND:
			evaltree(n->nbinary.ch1, EV_TESTED);
			if (evalskip || exitstatus != 0) {
				goto out;
			}
			next = n->nbinary.ch2;
			break;
		case NOR:
			evaltree(n->nbinary.ch1, EV_TESTED);
			if (evalskip || exitstatus == 0)
				goto out;
			next = n->nbinary.ch2;
			break;
		case NREDIR:
			evalredir(n, flags);
			break;
		case NSUBSHELL:
			evalsubshell(n, flags);
			do_etest = !(flags & EV_TESTED);
			break;
		case NBACKGND:
			evalsubshell(n, flags);
			break;
		case NIF: {
			evaltree(n->nif.test, EV_TESTED);
			if (evalskip)
				goto out;
			if (exitstatus == 0)
				next = n->nif.ifpart;
			else if (n->nif.elsepart)
				next = n->nif.elsepart;
			else
				exitstatus = 0;
			break;
		}
		case NWHILE:
		case NUNTIL:
			evalloop(n, flags & ~EV_EXIT);
			break;
		case NFOR:
			evalfor(n, flags & ~EV_EXIT);
			break;
		case NCASE:
			next = evalcase(n);
			break;
		case NCLIST:
			next = n->nclist.body;
			break;
		case NCLISTFALLTHRU:
			if (n->nclist.body) {
				evaltree(n->nclist.body, flags & ~EV_EXIT);
				if (evalskip)
					goto out;
			}
			next = n->nclist.next;
			break;
		case NDEFUN:
			defun(n->narg.text, n->narg.next);
			exitstatus = 0;
			break;
		case NNOT:
			evaltree(n->nnot.com, EV_TESTED);
			if (evalskip)
				goto out;
			exitstatus = !exitstatus;
			break;

		case NPIPE:
			evalpipe(n);
			do_etest = !(flags & EV_TESTED);
			break;
		case NCMD:
			evalcommand(n, flags, (struct backcmd *)NULL);
			do_etest = !(flags & EV_TESTED);
			break;
		default:
			out1fmt("Node type = %d\n", n->type);
			flushout(&output);
			break;
		}
		n = next;
		popstackmark(&smark);
		setstackmark(&smark);
	} while (n != NULL);
out:
	popstackmark(&smark);
	if (pendingsig)
		dotrap();
	if (eflag && exitstatus != 0 && do_etest)
		exitshell(exitstatus);
	if (flags & EV_EXIT)
		exraise(EXEXIT);
}
Exemple #27
0
int
trapcmd(int argc, char **argv)
{
	char *action;
	char **ap;
	int signo;

	if (argc <= 1) {
		for (signo = 0 ; signo <= NSIG ; signo++)
			if (trap[signo] != NULL) {
				out1fmt("trap -- ");
				print_quoted(trap[signo]);
				out1fmt(" %s\n",
				    (signo) ? sys_signame[signo] : "EXIT");
			}
		return 0;
	}
	ap = argv + 1;

	action = NULL;

	if (strcmp(*ap, "--") == 0)
		if (*++ap == NULL)
			return 0;

	if (signame_to_signum(*ap) == -1) {
		if ((*ap)[0] == '-') {
			if ((*ap)[1] == '\0')
				ap++;
			else if ((*ap)[1] == 'l' && (*ap)[2] == '\0') {
				printsignals();
				return 0;
			}
			else
				error("bad option %s\n", *ap);
		}
		else
			action = *ap++;
	}

	while (*ap) {
		if (is_number(*ap))
			signo = number(*ap);
		else
			signo = signame_to_signum(*ap);

		if (signo < 0 || signo > NSIG)
			error("%s: bad trap", *ap);

		INTOFF;
		if (action)
			action = savestr(action);

		if (trap[signo])
			ckfree(trap[signo]);

		trap[signo] = action;

		if (signo != 0)
			setsignal(signo, 0);
		INTON;
		ap++;
	}
	return 0;
}
Exemple #28
0
int
versioncmd(int argc, char **argv)
{
	out1fmt("%s\n",VERSION);
	return 0;
}
Exemple #29
0
/*
 *  This command is provided since POSIX decided to standardize
 *  the Korn shell fc command.  Oh well...
 */
int
histcmd(volatile int argc, char ** volatile argv)
{
	int ch;
	const char * volatile editor = NULL;
	HistEvent he;
	volatile int lflg = 0, nflg = 0, rflg = 0, sflg = 0;
	int i, retval;
	const char *firststr, *laststr;
	int first, last, direction;
	char * volatile pat = NULL, * volatile repl;	/* ksh "fc old=new" crap */
	static int active = 0;
	struct jmploc jmploc;
	struct jmploc *volatile savehandler;
	char editfile[MAXPATHLEN + 1];
	FILE * volatile efp;
#ifdef __GNUC__
	repl = NULL;	/* XXX gcc4 */
	efp = NULL;	/* XXX gcc4 */
#endif

	if (hist == NULL)
		error("history not active");

	if (argc == 1)
		error("missing history argument");

	optreset = 1; optind = 1; /* initialize getopt */
	while (not_fcnumber(argv[optind]) &&
	      (ch = getopt(argc, argv, ":e:lnrs")) != -1)
		switch ((char)ch) {
		case 'e':
			editor = optionarg;
			break;
		case 'l':
			lflg = 1;
			break;
		case 'n':
			nflg = 1;
			break;
		case 'r':
			rflg = 1;
			break;
		case 's':
			sflg = 1;
			break;
		case ':':
			error("option -%c expects argument", optopt);
			/* NOTREACHED */
		case '?':
		default:
			error("unknown option: -%c", optopt);
			/* NOTREACHED */
		}
	argc -= optind, argv += optind;

	/*
	 * If executing...
	 */
	if (lflg == 0 || editor || sflg) {
		lflg = 0;	/* ignore */
		editfile[0] = '\0';
		/*
		 * Catch interrupts to reset active counter and
		 * cleanup temp files.
		 */
		savehandler = handler;
		if (setjmp(jmploc.loc)) {
			active = 0;
			if (*editfile)
				unlink(editfile);
			handler = savehandler;
			longjmp(handler->loc, 1);
		}
		handler = &jmploc;
		if (++active > MAXHISTLOOPS) {
			active = 0;
			displayhist = 0;
			error("called recursively too many times");
		}
		/*
		 * Set editor.
		 */
		if (sflg == 0) {
			if (editor == NULL &&
			    (editor = bltinlookup("FCEDIT", 1)) == NULL &&
			    (editor = bltinlookup("EDITOR", 1)) == NULL)
				editor = DEFEDITOR;
			if (editor[0] == '-' && editor[1] == '\0') {
				sflg = 1;	/* no edit */
				editor = NULL;
			}
		}
	}

	/*
	 * If executing, parse [old=new] now
	 */
	if (lflg == 0 && argc > 0 &&
	     ((repl = strchr(argv[0], '=')) != NULL)) {
		pat = argv[0];
		*repl++ = '\0';
		argc--, argv++;
	}

	/*
	 * If -s is specified, accept only one operand
	 */
	if (sflg && argc >= 2)
		error("too many args");

	/*
	 * determine [first] and [last]
	 */
	switch (argc) {
	case 0:
		firststr = lflg ? "-16" : "-1";
		laststr = "-1";
		break;
	case 1:
		firststr = argv[0];
		laststr = lflg ? "-1" : argv[0];
		break;
	case 2:
		firststr = argv[0];
		laststr = argv[1];
		break;
	default:
		error("too many args");
		/* NOTREACHED */
	}
	/*
	 * Turn into event numbers.
	 */
	first = str_to_event(firststr, 0);
	last = str_to_event(laststr, 1);

	if (rflg) {
		i = last;
		last = first;
		first = i;
	}
	/*
	 * XXX - this should not depend on the event numbers
	 * always increasing.  Add sequence numbers or offset
	 * to the history element in next (diskbased) release.
	 */
	direction = first < last ? H_PREV : H_NEXT;

	/*
	 * If editing, grab a temp file.
	 */
	if (editor) {
		int fd;
		INTOFF;		/* easier */
		snprintf(editfile, sizeof(editfile), "%s_shXXXXXX", _PATH_TMP);
		if ((fd = mkstemp(editfile)) < 0)
			error("can't create temporary file %s", editfile);
		if ((efp = fdopen(fd, "w")) == NULL) {
			close(fd);
			error("can't allocate stdio buffer for temp");
		}
	}

	/*
	 * Loop through selected history events.  If listing or executing,
	 * do it now.  Otherwise, put into temp file and call the editor
	 * after.
	 *
	 * The history interface needs rethinking, as the following
	 * convolutions will demonstrate.
	 */
	history(hist, &he, H_FIRST);
	retval = history(hist, &he, H_NEXT_EVENT, first);
	for (;retval != -1; retval = history(hist, &he, direction)) {
		if (lflg) {
			if (!nflg)
				out1fmt("%5d ", he.num);
			out1str(he.str);
		} else {
			const char *s = pat ?
			   fc_replace(he.str, pat, repl) : he.str;

			if (sflg) {
				if (displayhist) {
					out2str(s);
				}

				evalstring(strcpy(stalloc(strlen(s) + 1), s), 0);
				if (displayhist && hist) {
					/*
					 *  XXX what about recursive and
					 *  relative histnums.
					 */
					history(hist, &he, H_ENTER, s);
				}

				break;
			} else
				fputs(s, efp);
		}
		/*
		 * At end?  (if we were to lose last, we'd sure be
		 * messed up).
		 */
		if (he.num == last)
			break;
	}
	if (editor) {
		char *editcmd;
		size_t cmdlen;

		fclose(efp);
		cmdlen = strlen(editor) + strlen(editfile) + 2;
		editcmd = stalloc(cmdlen);
		snprintf(editcmd, cmdlen, "%s %s", editor, editfile);
		evalstring(editcmd, 0);	/* XXX - should use no JC command */
		INTON;
		readcmdfile(editfile);	/* XXX - should read back - quick tst */
		unlink(editfile);
	}

	if (lflg == 0 && active > 0)
		--active;
	if (displayhist)
		displayhist = 0;
	return 0;
}
Exemple #30
0
int
aboutcmd(int argc, char **argv)
{
	out1fmt("CBSD Project. Version %s\n",VERSION);
	return 0;
}