Exemplo n.º 1
0
struct temp *
maketemp(Area *ap, Temp_type type, struct temp **tlist)
{
	struct temp *tp;
	int len;
	int fd;
	char *path;
	const char *dir;

	dir = tmpdir ? tmpdir : "/tmp";
	/* The 20 + 20 is a paranoid worst case for pid/inc */
	len = strlen(dir) + 3 + 20 + 20 + 1;
	tp = alloc(sizeof(struct temp) + len, ap);
	tp->name = path = (char *) &tp[1];
	tp->shf = NULL;
	tp->type = type;
	shf_snprintf(path, len, "%s/shXXXXXXXX", dir);
	fd = mkstemp(path);
	if (fd >= 0)
		tp->shf = shf_fdopen(fd, SHF_WR, NULL);
	tp->pid = procpid;

	tp->next = *tlist;
	*tlist = tp;
	return tp;
}
Exemplo n.º 2
0
/* format a single select menu item */
static void
options_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg)
{
	const struct options_info *oi = (const struct options_info *)arg;

	shf_snprintf(buf, buflen, "%-*s %s",
	    oi->opt_width, OFN(oi->opts[i]),
	    Flag(oi->opts[i]) ? "on" : "off");
}
Exemplo n.º 3
0
/* format a single select menu item */
static void
select_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg)
{
	const struct select_menu_info *smi =
	    (const struct select_menu_info *)arg;

	shf_snprintf(buf, buflen, "%*u) %s",
	    smi->num_width, i + 1, smi->args[i]);
}
Exemplo n.º 4
0
Arquivo: misc.c Projeto: adtools/abcsh
/* format a single select menu item */
static char *
options_fmt_entry(void *arg, int i, char *buf, int buflen)
{
        struct options_info *oi = (struct options_info *) arg;

        shf_snprintf(buf, buflen, "%-*s %s",
                oi->opt_width, oi->opts[i].name,
                Flag(oi->opts[i].flag) ? "on" : "off");
        return buf;
}
Exemplo n.º 5
0
/* format a single select menu item */
static char *
options_fmt_entry(char *buf, int buflen, int i, const void *arg)
{
	const struct options_info *oi = (const struct options_info *)arg;

	shf_snprintf(buf, buflen, "%-*s %s",
	    oi->opt_width, options[oi->opts[i]].name,
	    Flag(oi->opts[i]) ? "on" : "off");
	return (buf);
}
Exemplo n.º 6
0
/*
 * Print job status in either short, medium or long format.
 *
 * If jobs are compiled in then this routine expects sigchld to be blocked.
 */
static void
j_print(Job *j, int how, struct shf *shf)
{
	Proc	*p;
	int	state;
	int	status;
	int	coredumped;
	char	jobchar = ' ';
	char	buf[64];
	const char *filler;
	int	output = 0;

	if (how == JP_PGRP) {
		/* POSIX doesn't say what to do it there is no process
		 * group leader (ie, !FMONITOR).  We arbitrarily return
		 * last pid (which is what $! returns).
		 */
		shf_fprintf(shf, "%d\n", j->pgrp ? j->pgrp :
		    (j->last_proc ? j->last_proc->pid : 0));
		return;
	}
	j->flags &= ~JF_CHANGED;
	filler = j->job > 10 ?  "\n       " : "\n      ";
	if (j == job_list)
		jobchar = '+';
	else if (j == job_list->next)
		jobchar = '-';

	for (p = j->proc_list; p != (Proc *) 0;) {
		coredumped = 0;
		switch (p->state) {
		case PRUNNING:
			strlcpy(buf, "Running", sizeof buf);
			break;
		case PSTOPPED:
			strlcpy(buf, sigtraps[WSTOPSIG(p->status)].mess,
			    sizeof buf);
			break;
		case PEXITED:
			if (how == JP_SHORT)
				buf[0] = '\0';
			else if (WEXITSTATUS(p->status) == 0)
				strlcpy(buf, "Done", sizeof buf);
			else
				shf_snprintf(buf, sizeof(buf), "Done (%d)",
				    WEXITSTATUS(p->status));
			break;
		case PSIGNALLED:
			if (WCOREDUMP(p->status))
				coredumped = 1;
			/* kludge for not reporting `normal termination signals'
			 * (ie, SIGINT, SIGPIPE)
			 */
			if (how == JP_SHORT && !coredumped &&
			    (WTERMSIG(p->status) == SIGINT ||
			    WTERMSIG(p->status) == SIGPIPE)) {
				buf[0] = '\0';
			} else
				strlcpy(buf, sigtraps[WTERMSIG(p->status)].mess,
				    sizeof buf);
			break;
		}

		if (how != JP_SHORT) {
			if (p == j->proc_list)
				shf_fprintf(shf, "[%d] %c ", j->job, jobchar);
			else
				shf_fprintf(shf, "%s", filler);
		}

		if (how == JP_LONG)
			shf_fprintf(shf, "%5d ", p->pid);

		if (how == JP_SHORT) {
			if (buf[0]) {
				output = 1;
				shf_fprintf(shf, "%s%s ",
				    buf, coredumped ? " (core dumped)" : null);
			}
		} else {
			output = 1;
			shf_fprintf(shf, "%-20s %s%s%s", buf, p->command,
			    p->next ? "|" : null,
			    coredumped ? " (core dumped)" : null);
		}

		state = p->state;
		status = p->status;
		p = p->next;
		while (p && p->state == state && p->status == status) {
			if (how == JP_LONG)
				shf_fprintf(shf, "%s%5d %-20s %s%s", filler, p->pid,
				    space, p->command, p->next ? "|" : null);
			else if (how == JP_MEDIUM)
				shf_fprintf(shf, " %s%s", p->command,
				    p->next ? "|" : null);
			p = p->next;
		}
	}
	if (output)
		shf_fprintf(shf, newline);
}
Exemplo n.º 7
0
static char *
formatstr(struct tbl *vp, const char *s)
{
	int olen, nlen;
	char *p, *q;
	size_t psiz;

	olen = (int)utf_mbswidth(s);

	if (vp->flag & (RJUST|LJUST)) {
		if (!vp->u2.field)
			/* default field width */
			vp->u2.field = olen;
		nlen = vp->u2.field;
	} else
		nlen = olen;

	p = alloc((psiz = nlen * /* MB_LEN_MAX */ 3 + 1), ATEMP);
	if (vp->flag & (RJUST|LJUST)) {
		int slen = olen, i = 0;

		if (vp->flag & RJUST) {
			const char *qq = s;
			int n = 0;

			while (i < slen)
				i += utf_widthadj(qq, &qq);
			/* strip trailing spaces (AT&T uses qq[-1] == ' ') */
			while (qq > s && ksh_isspace(qq[-1])) {
				--qq;
				--slen;
			}
			if (vp->flag & ZEROFIL && vp->flag & INTEGER) {
				if (!s[0] || !s[1])
					goto uhm_no;
				if (s[1] == '#')
					n = 2;
				else if (s[2] == '#')
					n = 3;
 uhm_no:
				if (vp->u2.field <= n)
					n = 0;
			}
			if (n) {
				memcpy(p, s, n);
				s += n;
			}
			while (slen > vp->u2.field)
				slen -= utf_widthadj(s, &s);
			if (vp->u2.field - slen)
				memset(p + n, (vp->flag & ZEROFIL) ? '0' : ' ',
				    vp->u2.field - slen);
			slen -= n;
			shf_snprintf(p + vp->u2.field - slen,
			    psiz - (vp->u2.field - slen),
			    "%.*s", slen, s);
		} else {
			/* strip leading spaces/zeros */
			while (ksh_isspace(*s))
				s++;
			if (vp->flag & ZEROFIL)
				while (*s == '0')
					s++;
			shf_snprintf(p, nlen + 1, "%-*.*s",
				vp->u2.field, vp->u2.field, s);
		}
	} else
		memcpy(p, s, strlen(s) + 1);

	if (vp->flag & UCASEV_AL) {
		for (q = p; *q; q++)
			*q = ksh_toupper(*q);
	} else if (vp->flag & LCASEV) {
		for (q = p; *q; q++)
			*q = ksh_tolower(*q);
	}

	return (p);
}
Exemplo n.º 8
0
static void
getspec(struct tbl *vp)
{
	mksh_ari_u num;
	int st;
	struct timeval tv;

	switch ((st = special(vp->name))) {
	case V_COLUMNS:
	case V_LINES:
		/*
		 * Do NOT export COLUMNS/LINES. Many applications
		 * check COLUMNS/LINES before checking ws.ws_col/row,
		 * so if the app is started with C/L in the environ
		 * and the window is then resized, the app won't
		 * see the change cause the environ doesn't change.
		 */
		if (got_winch)
			change_winsz();
		break;
	}
	switch (st) {
	case V_BASHPID:
		num.u = (mksh_uari_t)procpid;
		break;
	case V_COLUMNS:
		num.i = x_cols;
		break;
	case V_HISTSIZE:
		num.i = histsize;
		break;
	case V_LINENO:
		num.u = (mksh_uari_t)current_lineno + user_lineno;
		break;
	case V_LINES:
		num.i = x_lins;
		break;
	case V_EPOCHREALTIME: {
		/* 10(%u) + 1(.) + 6 + NUL */
		char buf[18];

		vp->flag &= ~SPECIAL;
		mksh_TIME(tv);
		shf_snprintf(buf, sizeof(buf), "%u.%06u",
		    (unsigned)tv.tv_sec, (unsigned)tv.tv_usec);
		setstr(vp, buf, KSH_RETURN_ERROR | 0x4);
		vp->flag |= SPECIAL;
		return;
	}
	case V_OPTIND:
		num.i = user_opt.uoptind;
		break;
	case V_RANDOM:
		num.i = rndget();
		break;
	case V_SECONDS:
		/*
		 * On start up the value of SECONDS is used before
		 * it has been set - don't do anything in this case
		 * (see initcoms[] in main.c).
		 */
		if (vp->flag & ISSET) {
			mksh_TIME(tv);
			num.i = tv.tv_sec - seconds;
		} else
			return;
		break;
	default:
		/* do nothing, do not touch vp at all */
		return;
	}
	vp->flag &= ~SPECIAL;
	setint_n(vp, num.i, 0);
	vp->flag |= SPECIAL;
}
Exemplo n.º 9
0
static int
dopprompt(const char *sp, int ntruncate, const char **spp, int doprint)
{
	char strbuf[1024], tmpbuf[1024], *p, *str, nbuf[32], delimiter = '\0';
	int len, c, n, totlen = 0, indelimit = 0, counting = 1, delimitthis;
	const char *cp = sp;
	struct tm *tm;
	time_t t;

	if (*cp && cp[1] == '\r') {
		delimiter = *cp;
		cp += 2;
	}

	while (*cp != 0) {
		delimitthis = 0;
		if (indelimit && *cp != delimiter)
			;
		else if (*cp == '\n' || *cp == '\r') {
			totlen = 0;
			sp = cp + 1;
		} else if (*cp == '\t') {
			if (counting)
				totlen = (totlen | 7) + 1;
		} else if (*cp == delimiter) {
			indelimit = !indelimit;
			delimitthis = 1;
		}

		if (*cp == '\\') {
			cp++;
			if (!*cp)
				break;
			if (Flag(FSH))
				snprintf(strbuf, sizeof strbuf, "\\%c", *cp);
			else switch (*cp) {
			case 'a':	/* '\' 'a' bell */
				strbuf[0] = '\007';
				strbuf[1] = '\0';
				break;
			case 'd':	/* '\' 'd' Dow Mon DD */
				time(&t);
				tm = localtime(&t);
				strftime(strbuf, sizeof strbuf, "%a %b %d", tm);
				break;
			case 'D': /* '\' 'D' '{' strftime format '}' */
				p = strchr(cp + 2, '}');
				if (cp[1] != '{' || p == NULL) {
					snprintf(strbuf, sizeof strbuf,
					    "\\%c", *cp);
					break;
				}
				strlcpy(tmpbuf, cp + 2, sizeof tmpbuf);
				p = strchr(tmpbuf, '}');
				if (p)
					*p = '\0';
				time(&t);
				tm = localtime(&t);
				strftime(strbuf, sizeof strbuf, tmpbuf, tm);
				cp = strchr(cp + 2, '}');
				break;
			case 'e':	/* '\' 'e' escape */
				strbuf[0] = '\033';
				strbuf[1] = '\0';
				break;
			case 'h':	/* '\' 'h' shortened hostname */
				gethostname(strbuf, sizeof strbuf);
				p = strchr(strbuf, '.');
				if (p)
					*p = '\0';
				break;
			case 'H':	/* '\' 'H' full hostname */
				gethostname(strbuf, sizeof strbuf);
				break;
			case 'j':	/* '\' 'j' number of jobs */
				snprintf(strbuf, sizeof strbuf, "%d",
				    j_njobs());
				break;
			case 'l':	/* '\' 'l' basename of tty */
				p = ttyname(0);
				if (p)
					p = basename(p);
				if (p)
					strlcpy(strbuf, p, sizeof strbuf);
				break;
			case 'n':	/* '\' 'n' newline */
				strbuf[0] = '\n';
				strbuf[1] = '\0';
				totlen = 0;	/* reset for prompt re-print */
				sp = cp + 1;
				break;
			case 'r':	/* '\' 'r' return */
				strbuf[0] = '\r';
				strbuf[1] = '\0';
				totlen = 0;	/* reset for prompt re-print */
				sp = cp + 1;
				break;
			case 's':	/* '\' 's' basename $0 */
				strlcpy(strbuf, kshname, sizeof strbuf);
				break;
			case 't':	/* '\' 't' 24 hour HH:MM:SS */
				time(&t);
				tm = localtime(&t);
				strftime(strbuf, sizeof strbuf, "%T", tm);
				break;
			case 'T':	/* '\' 'T' 12 hour HH:MM:SS */
				time(&t);
				tm = localtime(&t);
				strftime(strbuf, sizeof strbuf, "%l:%M:%S", tm);
				break;
			case '@':	/* '\' '@' 12 hour am/pm format */
				time(&t);
				tm = localtime(&t);
				strftime(strbuf, sizeof strbuf, "%r", tm);
				break;
			case 'A':	/* '\' 'A' 24 hour HH:MM */
				time(&t);
				tm = localtime(&t);
				strftime(strbuf, sizeof strbuf, "%R", tm);
				break;
			case 'u':	/* '\' 'u' username */
				p = getlogin();
				if (p)
					strlcpy(strbuf, p, sizeof strbuf);
				else
					strbuf[0] = '\0';
				break;
			case 'v':	/* '\' 'v' version (short) */
				p = strchr(ksh_version, ' ');
				if (p)
					p = strchr(p + 1, ' ');
				if (p) {
					p++;
					strlcpy(strbuf, p, sizeof strbuf);
					p = strchr(strbuf, ' ');
					if (p)
						*p = '\0';
				}
				break;
			case 'V':	/* '\' 'V' version (long) */
				strlcpy(strbuf, ksh_version, sizeof strbuf);
				break;
			case 'w':	/* '\' 'w' cwd */
				p = str_val(global("PWD"));
				n = strlen(str_val(global("HOME")));
				if (strcmp(p, "/") == 0) {
					strlcpy(strbuf, p, sizeof strbuf);
				} else if (strcmp(p, str_val(global("HOME"))) == 0) {
					strbuf[0] = '~';
					strbuf[1] = '\0';
				} else if (strncmp(p, str_val(global("HOME")), n)
				    == 0 && p[n] == '/') {
					snprintf(strbuf, sizeof strbuf, "~/%s",
					    str_val(global("PWD")) + n + 1);
				} else
					strlcpy(strbuf, p, sizeof strbuf);
				break;
			case 'W':	/* '\' 'W' basename(cwd) */
				p = str_val(global("PWD"));
				strlcpy(strbuf, basename(p), sizeof strbuf);
				break;
			case '!':	/* '\' '!' history line number XXX busted */
				snprintf(strbuf, sizeof strbuf, "%d",
				    source->line + 1);
				break;
			case '#':	/* '\' '#' command line number XXX busted */
				snprintf(strbuf, sizeof strbuf, "%d",
				    source->line + 1);
				break;
			case '$':	/* '\' '$' $ or # XXX busted */
				strbuf[0] = ksheuid ? '$' : '#';
				strbuf[1] = '\0';
				break;
			case '0':	/* '\' '#' '#' ' #' octal numeric handling */
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
				if ((cp[1] > '7' || cp[1] < '0') ||
				    (cp[2] > '7' || cp[2] < '0')) {
					snprintf(strbuf, sizeof strbuf,
					    "\\%c", *cp);
					break;
				}
				n = cp[0] * 8 * 8 + cp[1] * 8 + cp[2];
				snprintf(strbuf, sizeof strbuf, "%c", n);
				cp += 2;
				break;
			case '\\':	/* '\' '\' */
				strbuf[0] = '\\';
				strbuf[1] = '\0';
				break;
			case '[': /* '\' '[' .... stop counting */
				strbuf[0] = '\0';
				counting = 0;
				break;
			case ']': /* '\' ']' restart counting */
				strbuf[0] = '\0';
				counting = 1;
				break;

			default:
				snprintf(strbuf, sizeof strbuf, "\\%c", *cp);
				break;
			}
			cp++;

			str = strbuf;
			len = strlen(str);
			if (ntruncate) {
				if (ntruncate >= len) {
					ntruncate -= len;
					continue;
				}
				str += ntruncate;
				len -= ntruncate;
				ntruncate = 0;
			}
			if (doprint)
				shf_write(str, len, shl_out);
			if (counting && !indelimit && !delimitthis)
				totlen += len;
			continue;
		} else if (*cp != '!')
			c = *cp++;
		else if (*++cp == '!')
			c = *cp++;
		else {
			char *p;

			shf_snprintf(p = nbuf, sizeof(nbuf), "%d",
			    source->line + 1);
			len = strlen(nbuf);
			if (ntruncate) {
				if (ntruncate >= len) {
					ntruncate -= len;
					continue;
				}
				p += ntruncate;
				len -= ntruncate;
				ntruncate = 0;
			}
			if (doprint)
				shf_write(p, len, shl_out);
			if (counting && !indelimit && !delimitthis)
				totlen += len;
			continue;
		}
		if (ntruncate)
			--ntruncate;
		else if (doprint) {
			shf_putc(c, shl_out);
		}
		if (counting && !indelimit && !delimitthis)
			totlen++;
	}
	if (doprint)
		shf_flush(shl_out);
	if (spp)
		*spp = sp;
	return (totlen);
}
Exemplo n.º 10
0
Arquivo: var.c Projeto: tomgrean/mksh
/* search for variable; if not found, return NULL or create globally */
struct tbl *
isglobal(const char *n, bool docreate)
{
	struct tbl *vp;
	union mksh_cchack vname;
	struct block *l = e->loc;
	int c;
	bool array;
	uint32_t h, val;

	/*
	 * check to see if this is an array;
	 * dereference namerefs; must come first
	 */
	vn = array_index_calc(n, &array, &val);
	h = hash(vn);
	c = (unsigned char)vn[0];
	if (!ctype(c, C_ALPHX)) {
		if (array)
			errorf(Tbadsubst);
		vp = vtemp;
		vp->flag = DEFINED;
		vp->type = 0;
		vp->areap = ATEMP;
		if (ctype(c, C_DIGIT)) {
			if (getn(vn, &c)) {
				/* main.c:main_init() says 12 */
				shf_snprintf(vp->name, 12, Tf_d, c);
				if (c <= l->argc) {
					/* setstr can't fail here */
					setstr(vp, l->argv[c],
					    KSH_RETURN_ERROR);
				}
			} else
				vp->name[0] = '\0';
			vp->flag |= RDONLY;
			goto out;
		}
		vp->name[0] = c;
		vp->name[1] = '\0';
		vp->flag |= RDONLY;
		if (vn[1] != '\0')
			goto out;
		vp->flag |= ISSET|INTEGER;
		switch (c) {
		case '$':
			vp->val.i = kshpid;
			break;
		case '!':
			/* if no job, expand to nothing */
			if ((vp->val.i = j_async()) == 0)
				vp->flag &= ~(ISSET|INTEGER);
			break;
		case '?':
			vp->val.i = exstat & 0xFF;
			break;
		case '#':
			vp->val.i = l->argc;
			break;
		case '-':
			vp->flag &= ~INTEGER;
			vp->val.s = getoptions();
			break;
		default:
			vp->flag &= ~(ISSET|INTEGER);
		}
		goto out;
	}
	l = varsearch(e->loc, &vp, vn, h);
	if (vp == NULL && docreate)
		vp = ktenter(&l->vars, vn, h);
	else
		docreate = false;
	if (vp != NULL) {
		if (array)
			vp = arraysearch(vp, val);
		if (docreate) {
			vp->flag |= DEFINED;
			if (special(vn))
				vp->flag |= SPECIAL;
		}
	}
 out:
	last_lookup_was_array = array;
	if (vn != n)
		afree(vname.rw, ATEMP);
	return (vp);
}