Exemple #1
0
static void
commit(Joblist_t* job, register char* s)
{
	register char*		t;
	register char*		v;
	register Rule_t*	r;
	Stat_t			st;

	if (t = strrchr(s, '/'))
	{
		*t = 0;
		if (r = bindfile(NiL, s, 0))
		{
			if (!r->view)
			{
				*t = '/';
				return;
			}
			if (*(v = r->name) != '/')
			{
				sfprintf(internal.nam, "%s/%s", state.view[r->view].root, v);
				v = sfstruse(internal.nam);
			}
			if (stat(v, &st))
				r = 0;
		}
		if (r || state.targetcontext && (!r || !r->time) && (st.st_mode = (S_IRWXU|S_IRWXG|S_IRWXO)) && tmxsetmtime(&st, state.start))
		{
			/*
			 * why not mkdir -p here?
			 */

			commit(job, s);
			if (((job->flags & CO_ALWAYS) || state.exec && state.touch) && (mkdir(s, st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) || stat(s, &st)))
				error(1, "%s: cannot create target directory %s", job->target->name, s);
			if (state.mam.out)
			{
				Sfio_t*	tmp = sfstropen();

				sfprintf(tmp, "mkdir %s", s);
				dumpaction(state.mam.out, MAMNAME(job->target), sfstruse(tmp), NiL);
				sfstrclose(tmp);
			}
			r = makerule(s);
			if (r->dynamic & D_alias)
				oldname(r);
			r->view = 0;
			r->time = tmxgetmtime(&st);
			if (r->dynamic & D_scanned)
				unbind(NiL, (char*)r, NiL);
		}
		*t = '/';
	}
}
Exemple #2
0
static int arraysort(const char *s1, const char *s2)
{
	struct Sort *sp = Sp;
	Shell_t	*shp = sp->shp;
	int r=0, cur=sp->cur;
	Namval_t *np1, *np2;
	Namfun_t	fun;
	char		*cp;
	memset(&fun,0,sizeof(Namfun_t));
	if(!(np1 = ((struct Node*)s1)->nodes[sp->cur]))
	{
		sfprintf(shp->strbuf,"%s[%i].%s%c",sp->name,((struct Node*)s1)->index,sp->keys[sp->cur],0);
		cp = sfstruse(shp->strbuf);
		np1 = nv_create(cp,sp->root,NV_VARNAME|NV_NOFAIL|NV_NOADD|NV_NOSCOPE,&fun);
		((struct Node*)s1)->nodes[sp->cur] = np1;
	}
	if(!(np2 = ((struct Node*)s2)->nodes[sp->cur]))
	{
		sfprintf( shp->strbuf,"%s[%i].%s%c",sp->name,((struct Node*)s2)->index,sp->keys[sp->cur],0);
		cp = sfstruse(shp->strbuf);
		np2 = nv_create(cp,sp->root,NV_VARNAME|NV_NOFAIL|NV_NOADD|NV_NOSCOPE,&fun);
		((struct Node*)s2)->nodes[sp->cur] = np2;
	}
	if(sp->flags[sp->cur]&SORT_numeric)
	{
		Sfdouble_t d1 = np1?nv_getnum(np1):0;
		Sfdouble_t d2 = np2?nv_getnum(np2):0;
		if(d2<d1)
			r = 1;
		else if(d2>d1)
			r = -1;
	}
	else if(np1 && np2)
	{
		char *sp1 = nv_getval(np1);
		char *sp2 = nv_getval(np2);
		r = strcoll(sp1,sp2);
		
	}
	else if(np1)
		r = 1;
	else if(np2)
		r = -1;
	if(sp->flags[sp->cur]&SORT_reverse)
		r = -r;
	if(r==0 && sp->keys[++sp->cur])
		r = arraysort(s1,s2);
	sp->cur = cur;
	return(r);
}
Exemple #3
0
Time_t
tmxduration(const char* s, char** e)
{
	Time_t		ns;
	Time_t		ts;
	Time_t		now;
	char*		last;
	char*		t;
	char*		x;
	Sfio_t*		f;
	int		i;

	now = TMX_NOW;
	while (isspace(*s))
		s++;
	if (*s == 'P' || *s == 'p')
		ns = tmxdate(s, &last, now) - now;
	else
	{
		ns = strtod(s, &last) * TMX_RESOLUTION;
		if (*last && (f = sfstropen()))
		{
			sfprintf(f, "exact %s", s);
			t = sfstruse(f);
			ts = tmxdate(t, &x, now);
			if ((i = x - t - 6) > (last - s))
			{
				last = (char*)s + i;
				ns = ts - now;
			}
			else
			{
				sfprintf(f, "p%s", s);
				t = sfstruse(f);
				ts = tmxdate(t, &x, now);
				if ((i = x - t - 1) > (last - s))
				{
					last = (char*)s + i;
					ns = ts - now;
				}
			}
			sfstrclose(f);
		}
	}
	if (e)
		*e = last;
	return ns;
}
Exemple #4
0
void
exerror(const char* format, ...)
{
	Sfio_t*	sp;

	if (expr.program->disc->errorf && !expr.program->errors && (sp = sfstropen()))
	{
		va_list	ap;
		char*	s;
		char	buf[64];

		expr.program->errors = 1;
		excontext(expr.program, buf, sizeof(buf));
		sfputr(sp, buf, -1);
		va_start(ap, format);
		sfvprintf(sp, format, ap);
		va_end(ap);
		if (!(s = sfstruse(sp)))
			s = "out of space";
		(*expr.program->disc->errorf)(expr.program, expr.program->disc, (expr.program->disc->flags & EX_FATAL) ? 3 : 2, "%s", s);
		sfclose(sp);
	}
	else if (expr.program->disc->flags & EX_FATAL)
		exit(1);
}
Exemple #5
0
static void
splice(void)
{
	char*	s;
	int	n;

	if (ed.spend) {
		if (!ed.spl && !(ed.spl = sfstropen()))
			error(ERROR_SYSTEM|3, "cannot initialize splice buffer");
		sfwrite(ed.spl, ed.spbeg, ed.spend - ed.spbeg);
		ed.spend = 0;
		sfputc(ed.spl, '\n');
		while (s = sfgetr(sfstdin, '\n', 1)) {
			if ((n = sfvalue(sfstdin) - 1) > 0 && s[n - 1] == '\r')
				n--;
			if (n > 0 && s[n - 1] == '\\') {
				sfwrite(ed.spl, s, n - 1);
				sfputc(ed.spl, '\n');
			}
			else {
				sfwrite(ed.spl, s, n);
				break;
			}
		}
		if (!(s = sfstruse(ed.spl)))
			error(ERROR_SYSTEM|3, "out of space");
		ed.input = s + (ed.input - ed.spbeg);
	}
}
Exemple #6
0
static char*
getrec(register Sfio_t* sp, register int delimiter, register int flags)
{
	register int	c;
	register char*	glob;

	sfstrseek(sp, 0, SEEK_SET);
	glob = ed.global;
	while ((c = getchr()) != delimiter) {
		if (c == '\n') {
			ed.peekc = c;
			break;
		}
		if (c == EOF) {
			if (glob)
				ed.peekc = (flags & REC_LINE) ? 0 : c;
			else if (delimiter != '\n' || (flags & (REC_LINE|REC_SPLICE)))
				error(2, "unexpected EOF");
			else if (flags & REC_TEXT)
				return 0;
			break;
		}
		if (c == '\\' && ((c = getchr()) != delimiter || (flags & REC_SPLICE) && c != '\n') && c && !(flags & REC_IGNORE))
			sfputc(sp, '\\');
		if (!c)
			error(1, "null character ignored");
		else if (!(flags & REC_IGNORE))
			sfputc(sp, c);
	}
	if (flags & REC_TERMINATE)
		sfputc(sp, c);
	if (!(glob = sfstruse(sp)))
		error(ERROR_SYSTEM|3, "out of space");
	return glob;
}
Exemple #7
0
char*
exstash(Sfio_t* sp, Vmalloc_t* vp)
{
	char*	s;

	return ((s = sfstruse(sp)) && (!vp || (s = vmstrdup(vp, s)))) ? s : exnospace();
}
Exemple #8
0
static int
post(Css_t* css, Cssdisc_t* disc, Connection_t* from, register Connection_t* to, int channel, const char* format, ...)
{
	State_t*		state = (State_t*)disc;
	char*			s;
	ssize_t			n;
	Sfulong_t		m;
	va_list			ap;

	sfprintf(state->tmp, "%d", channel);
	if (from)
		sfprintf(state->tmp, ".%d", from->fp->fd);
	sfputc(state->tmp, ' ');
	va_start(ap, format);
	sfvprintf(state->tmp, format, ap);
	va_end(ap);
	sfputc(state->tmp, '\n');
	n = sfstrtell(state->tmp);
	if (!(s = sfstruse(state->tmp)))
		error(ERROR_SYSTEM|3, "out of space");
	m = CHAN_MASK(channel);
	state->logged = 0;
	if (!to)
	{
		for (to = state->all; to; to = to->next)
			if ((to->mask & m) && to != from)
				note(css, to, state->log, s, n, 0, disc);
	}
	else if (to->mask & m)
		note(css, to, state->log, s, n, 0, disc);
	return 0;
}
Exemple #9
0
static int
intercept(Sfio_t* sp, int level, int flags)
{
	register Rule_t*	r;
	char*			m;
	char*			s;
	char*			t;
	char*			e;
	int			n;
	int			i;
	Sfio_t*			tmp;

	NoP(sp);
	NoP(flags);
	if ((state.mam.level = level) > 0 && !state.hold && (r = internal.error) && (r->property & (P_functional|P_target)) == (P_functional|P_target) && !state.compileonly && !state.interrupt && (m = stakptr(0)) && (n = staktell()) > 0)
	{
		/*
		 * make the error trap
		 */

		state.hold = m;
		while (*m && *m != ':')
			m++;
		while (isspace(*++m));
		n -= m - state.hold;
		tmp = sfstropen();
		sfprintf(tmp, "%d %-.*s", level, n, m);
		s = sfstruse(tmp);

		/*
		 * return [ level | - ] [ message ]
		 * level is new level or - to retain old
		 * omitted message means it has been printed
		 */

		if (t = call(r, s))
		{
			i = strtol(t, &e, 0);
			if (e > t)
			{
				t = e;
				level = i;
			}
			else if (*t == '-')
				t++;
			while (isspace(*t))
				t++;
		}
		if (!t || !*t)
		{
			level |= ERROR_OUTPUT;
			message((-1, "suppressed %s message: `%-.*s'", level == 1 ? "warning" : "error", n, m));
		}
		sfstrclose(tmp);
		state.hold = 0;
	}
	return level;
}
Exemple #10
0
char*
costash(Sfio_t* sp)
{
	char*			s;

	if (!(s = sfstruse(sp)))
		errormsg(state.lib, ERROR_LIBRARY|2, "out of space");
	return s;
}
Exemple #11
0
/* toUpper:
 * Convert characters to uppercase
 */
char *toUpper(Expr_t * pgm, char *s, Sfio_t* tmps)
{
    int c;

    while ((c = *s++))
	sfputc (tmps, toupper (c));

    return exstring(pgm, sfstruse(tmps));
}
Exemple #12
0
char*
_re_putc(int c)
{
	static Sfio_t*	sp;

	if (!sp && !(sp = sfstropen()))
		return 0;
	if (!c)
		return sfstruse(sp);
	sfputc(sp, c);
	return 0;
}
Exemple #13
0
static int read_tree(Namval_t* np, Sfio_t *iop, int n, Namfun_t *dp)
{
	Sfio_t	*sp;
	char	*cp;
	int	c;
	if(n>=0)
		return(-1);
	while((c = sfgetc(iop)) &&  isblank(c));
	sfungetc(iop,c);
	sfprintf(sh.strbuf,"%s=%c",nv_name(np),0);
	cp = sfstruse(sh.strbuf);
	sp = sfopen((Sfio_t*)0,cp,"s");
	sfstack(iop,sp);
	c=sh_eval(iop,SH_READEVAL);
	return(c);
}
Exemple #14
0
static void
join(void)
{
	register Line_t*	a1;
	char*			s;

	nonzero();
	sfstrseek(ed.buffer.work, 0, SEEK_SET);
	for (a1 = ed.addr1; a1 <= ed.addr2;)
		sfputr(ed.buffer.work, lineget((a1++)->offset), -1);
	a1 = ed.dot = ed.addr1;
	if (!(s = sfstruse(ed.buffer.work)))
		error(ERROR_SYSTEM|3, "out of space");
	replace(a1, s);
	if (a1 < ed.addr2)
		rdelete(a1 + 1, ed.addr2);
}
Exemple #15
0
int
vasprintf(char** s, const char* fmt, va_list args)
{
	Sfio_t*	f;
	int	v;

	if (f = sfstropen())
	{
		v = sfvprintf(f, fmt, args);
		if (!(*s = strdup(sfstruse(f))))
			v = -1;
		sfstrclose(f);
	}
	else
	{
		*s = 0;
		v = -1;
	}
	return v;
}
Exemple #16
0
/*
 * Read single line from stream.
 * Return "" on EOF.
 */
char *readLine(Expr_t * ex, int fd)
{
    Sfio_t *sp;
    int c;
    Sfio_t *tmps;
    char *line;

    if (fd < 0 || fd >= elementsof(ex->file) || !((sp = ex->file[fd]))) {
	exerror("readL: %d: invalid descriptor", fd);
	return "";
    }
    tmps = sfstropen();
    while (((c = sfgetc(sp)) > 0) && (c != '\n'))
	sfputc(tmps, c);
    if (c == '\n')
	sfputc(tmps, c);
    line = exstring(ex, sfstruse(tmps));
    sfclose(tmps);
    return line;
}
Exemple #17
0
static void
exfile(void)
{
	if (sfclose(ed.iop))
		error(ERROR_SYSTEM|1, "io error");
	ed.iop = 0;
	if (ed.verbose) {
		if (ed.help) {
			sfprintf(ed.msg, "\"%s\" %lu line%s, %lu character%s", error_info.file, ed.lines, plural(ed.lines), ed.bytes, plural(ed.bytes));
			if (ed.warn_null) {
				sfprintf(ed.msg, ", %lu null%s", ed.warn_null, plural(ed.warn_null));
				ed.warn_null = 0;
			}
			if (ed.warn_newline) {
				sfprintf(ed.msg, ", newline appended");
				ed.warn_newline = 0;
			}
			sfputc(ed.msg, '\n');
		}
		else
			sfprintf(ed.msg, "%d\n", ed.bytes);
	}
	if (ed.warn_null || ed.warn_newline) {
		char*	sep = "";

		sfstrseek(ed.buffer.line, 0, SEEK_SET);
		if (ed.warn_null) {
			sfprintf(ed.buffer.line, "%d null character%s ignored", ed.warn_null, plural(ed.warn_null));
			ed.warn_null = 0;
			sep = ", ";
		}
		if (ed.warn_newline) {
			sfprintf(ed.buffer.line, "%snewline appended to last line", sep);
			ed.warn_newline = 0;
		}
		if (!(sep = sfstruse(ed.buffer.line)))
			error(ERROR_SYSTEM|3, "out of space");
		error(1, "%s", sep);
	}
	error_info.file = 0;
}
Exemple #18
0
void exwarn(const char *format, ...)
{
    Sfio_t *sp;

    if (expr.program->disc->errorf && (sp = sfstropen())) {
	va_list ap;
	char *s;
	char buf[64];

	excontext(expr.program, buf, sizeof(buf));
	sfputr(sp, buf, -1);
	sfputr(sp, "\n -- ", -1);
	va_start(ap, format);
	sfvprintf(sp, format, ap);
	va_end(ap);
	s = sfstruse(sp);
	(*expr.program->disc->errorf) (expr.program, expr.program->disc,
				       ERROR_WARNING, "%s", s);
	sfclose(sp);
    }
}
Exemple #19
0
static void
handle(void)
{
	register int	c;
	char*		s;
	char*		b;
	mode_t		mask;

	if (ed.caught == SIGINT) {
		ed.caught = 0;
		ed.lastc = '\n';
		sfputc(ed.msg, '\n');
		error(2, "interrupt");
	}
	for (c = 0; c < elementsof(signals); c++)
		signal(signals[c], SIG_IGN);
	if (ed.dol > ed.zero) {
		ed.addr1 = ed.zero + 1;
		ed.addr2 = ed.dol;
		mask = umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
		b = "ed.hup";
		if (!(ed.iop = sfopen(NiL, b, "w")) && !ed.restricted && (s = getenv("HOME"))) {
			sfstrseek(ed.buffer.line, 0, SEEK_SET);
			sfprintf(ed.buffer.line, "%s/%s", s, b);
			if (!(b = sfstruse(ed.buffer.line)))
				error(ERROR_SYSTEM|3, "out of space");
			ed.iop = sfopen(NiL, b, "w");
		}
		umask(mask);
		if (!ed.iop)
			error(ERROR_SYSTEM|1, "%s: cannot save changes", b);
		else {
			error_info.file = b;
			putfile();
		}
	}
	ed.modified = 0;
	quit(0);
}
Exemple #20
0
void
ppbuiltin(void)
{
	register int		c;
	register char*		p;
	register char*		a;

	int			n;
	int			op;
	char*			token;
	char*			t;
	long			number;
	long			onumber;
	struct ppinstk*		in;
	struct pplist*		list;
	struct ppsymbol*	sym;
	Sfio_t*			sp;

	number = pp.state;
	pp.state |= DISABLE|FILEPOP|NOSPACE;
	token = pp.token;
	p = pp.token = pp.tmpbuf;
	*(a = pp.args) = 0;
	if ((c = pplex()) != T_ID)
	{
		error(2, "%s: #(<identifier>...) expected", p);
		*p = 0;
	}
	switch (op = (int)hashget(pp.strtab, p))
	{
	case V_DEFAULT:
		n = 0;
		p = pp.token = pp.valbuf;
		if ((c = pplex()) == ',')
		{
			op = -1;
			c = pplex();
		}
		pp.state &= ~NOSPACE;
		for (;;)
		{
			if (!c)
			{
				error(2, "%s in #(...) argument", pptokchr(c));
				break;
			}
			if (c == '(') n++;
			else if (c == ')' && !n--) break;
			else if (c == ',' && !n && op > 0) op = 0;
			if (op) pp.token = pp.toknxt;
			c = pplex();
		}
		*pp.token = 0;
		pp.token = token;
		pp.state = number;
		break;
	case V_EMPTY:
		p = pp.valbuf;
		if ((c = pplex()) == ')') *p = '1';
		else
		{
			*p = '0';
			n = 0;
			for (;;)
			{
				if (!c)
				{
					error(2, "%s in #(...) argument", pptokchr(c));
					break;
				}
				if (c == '(') n++;
				else if (c == ')' && !n--) break;
				c = pplex();
			}
		}
		*(p + 1) = 0;
		pp.token = token;
		pp.state = number;
		break;
	case V_ITERATE:
		n = 0;
		pp.token = pp.valbuf;
		if ((c = pplex()) != T_ID || !(sym = ppsymref(pp.symtab, pp.token)) || !sym->macro || sym->macro->arity != 1 || (c = pplex()) != ',')
		{
			error(2, "#(%s <macro(x)>, ...) expected", p);
			for (;;)
			{
				if (!c)
				{
					error(2, "%s in #(...) argument", pptokchr(c));
					break;
				}
				if (c == '(') n++;
				else if (c == ')' && !n--) break;
				c = pplex();
			}
			*pp.valbuf = 0;
		}
		else while (c != ')')
		{
			p = pp.token;
			if (pp.token > pp.valbuf) *pp.token++ = ' ';
			STRCOPY(pp.token, sym->name, a);
			*pp.token++ = '(';
			if (!c || !(c = pplex()))
			{
				pp.token = p;
				error(2, "%s in #(...) argument", pptokchr(c));
				break;
			}
			pp.state &= ~NOSPACE;
			while (c)
			{
				if (c == '(') n++;
				else if (c == ')' && !n--) break;
				else if (c == ',' && !n) break;
				pp.token = pp.toknxt;
				c = pplex();
			}
			*pp.token++ = ')';
			pp.state |= NOSPACE;
		}
		p = pp.valbuf;
		pp.token = token;
		pp.state = number;
		break;
	default:
		pp.token = token;
		while (c != ')')
		{
			if (!c)
			{
				error(2, "%s in #(...) argument", pptokchr(c));
				break;
			}
			if ((c = pplex()) == T_ID && !*a)
				strcpy(a, pp.token);
		}
		pp.state = number;
		switch (op)
		{
		case V_ARGC:
			c = -1;
			for (in = pp.in; in; in = in->prev)
				if ((in->type == IN_MACRO || in->type == IN_MULTILINE) && (in->symbol->flags & SYM_FUNCTION))
				{
					c = *((unsigned char*)(pp.macp->arg[0] - 2));
					break;
				}
			sfsprintf(p = pp.valbuf, MAXTOKEN, "%d", c);
			break;
		case V_BASE:
			p = (a = strrchr(error_info.file, '/')) ? a + 1 : error_info.file;
			break;
		case V_DATE:
			if (!(p = pp.date))
			{
				time_t	tm;

				time(&tm);
				a = p = ctime(&tm) + 4;
				*(p + 20) = 0;
				for (p += 7; *p = *(p + 9); p++);
				pp.date = p = strdup(a);
			}
			break;
		case V_FILE:
			p = error_info.file;
			break;
		case V_LINE:
			sfsprintf(p = pp.valbuf, MAXTOKEN, "%d", error_info.line);
			break;
		case V_PATH:
			p = pp.path;
			break;
		case V_SOURCE:
			p = error_info.file;
			for (in = pp.in; in->prev; in = in->prev)
				if (in->prev->type == IN_FILE && in->file)
					p = in->file;
			break;
		case V_STDC:
			p = pp.valbuf;
			p[0] = ((pp.state & (COMPATIBILITY|TRANSITION)) || (pp.mode & (HOSTED|HOSTEDTRANSITION)) == (HOSTED|HOSTEDTRANSITION)) ? '0' : '1';
			p[1] = 0;
			break;
		case V_TIME:
			if (!(p = pp.time))
			{
				time_t	tm;

				time(&tm);
				p = ctime(&tm) + 11;
				*(p + 8) = 0;
				pp.time = p = strdup(p);
			}
			break;
		case V_VERSION:
			p = (char*)pp.version;
			break;
		case V_DIRECTIVE:
			pp.state |= NEWLINE;
			pp.mode |= RELAX;
			strcpy(p = pp.valbuf, "#");
			break;
		case V_GETENV:
			if (!(p = getenv(a))) p = "";
			break;
		case V_GETMAC:
			p = (sym = pprefmac(a, REF_NORMAL)) ? sym->macro->value : "";
			break;
		case V_GETOPT:
			sfsprintf(p = pp.valbuf, MAXTOKEN, "%ld", ppoption(a));
			break;
		case V_GETPRD:
			p = (list = (struct pplist*)hashget(pp.prdtab, a)) ? list->value : "";
			break;
		case V__PRAGMA:
			if ((c = pplex()) == '(')
			{
				number = pp.state;
				pp.state |= NOSPACE|STRIP;
				c = pplex();
				pp.state = number;
				if (c == T_STRING || c == T_WSTRING)
				{
					if (!(sp = sfstropen()))
						error(3, "temporary buffer allocation error");
					sfprintf(sp, "#%s %s\n", dirname(PRAGMA), pp.token);
					a = sfstruse(sp);
					if ((c = pplex()) == ')')
					{
						pp.state |= NEWLINE;
						PUSH_BUFFER(p, a, 1);
					}
					sfstrclose(sp);
				}
			}
			if (c != ')')
				error(2, "%s: (\"...\") expected", p);
			return;
		case V_FUNCTION:

#define BACK(a,p)	((a>p)?*--a:(number++?0:((p=pp.outbuf+PPBUFSIZ),(a=pp.outbuf+2*PPBUFSIZ),*--a)))
#define PEEK(a,p)	((a>p)?*(a-1):(number?0:*(pp.outbuf+2*PPBUFSIZ-1)))

			number = pp.outbuf != pp.outb;
			a = pp.outp;
			p = pp.outb;
			op = 0;
			while (c = BACK(a, p))
			{
				if (c == '"' || c == '\'')
				{
					op = 0;
					while ((n = BACK(a, p)) && n != c || PEEK(a, p) == '\\');
				}
				else if (c == '\n')
				{
					token = a;
					while (c = BACK(a, p))
						if (c == '\n')
						{
							a = token;
							break;
						}
						else if (c == '#' && PEEK(a, p) == '\n')
							break;
				}
				else if (c == ' ')
					/*ignore*/;
				else if (c == '{') /* '}' */
					op = 1;
				else if (op == 1)
				{
					if (c == ')')
					{
						op = 2;
						n = 1;
					}
					else
						op = 0;
				}
				else if (op == 2)
				{
					if (c == ')')
						n++;
					else if (c == '(' && !--n)
						op = 3;
				}
				else if (op == 3)
				{
					if (ppisidig(c))
					{
						for (t = p, token = a, onumber = number; ppisidig(PEEK(a, p)) && a >= p; BACK(a, p));
						p = pp.valbuf + 1;
						if (a > token)
						{
							for (; a < pp.outbuf+2*PPBUFSIZ; *p++ = *a++);
							a = pp.outbuf;
						}
						for (; a <= token; *p++ = *a++);
						*p = 0;
						p = pp.valbuf + 1;
						if (streq(p, "for") || streq(p, "if") || streq(p, "switch") || streq(p, "while"))
						{
							op = 0;
							p = t;
							number = onumber;
							continue;
						}
					}
					else
						op = 0;
					break;
				}
			}
			if (op == 3)
				p = strncpy(pp.funbuf, p, sizeof(pp.funbuf) - 1);
			else if (*pp.funbuf)
				p = pp.funbuf;
			else
				p = "__FUNCTION__";
			break;
		default:
			if (pp.builtin && (a = (*pp.builtin)(pp.valbuf, p, a)))
				p = a;
			break;
		}
		break;
	}
	if (strchr(p, MARK))
	{
		a = pp.tmpbuf;
		strcpy(a, p);
		c = p != pp.valbuf;
		p = pp.valbuf + c;
		for (;;)
		{
			if (p < pp.valbuf + MAXTOKEN - 2)
				switch (*p++ = *a++)
				{
				case 0:
					break;
				case MARK:
					*p++ = MARK;
					/*FALLTHROUGH*/
				default:
					continue;
				}
			break;
		}
		p = pp.valbuf + c;
	}
	if (p == pp.valbuf)
		PUSH_STRING(p);
	else
	{
		if (p == pp.valbuf + 1)
			*pp.valbuf = '"';
		else
		{
			if (strlen(p) > MAXTOKEN - 2)
				error(1, "%-.16s: builtin value truncated", p);
			sfsprintf(pp.valbuf, MAXTOKEN, "\"%-.*s", MAXTOKEN - 2, p);
		}
		PUSH_QUOTE(pp.valbuf, 1);
	}
}
Exemple #21
0
int
extoken_fn(register Expr_t* ex)
{
	register int	c;
	register char*	s;
	register int	q;
	char*		e;

	if (ex->eof || ex->errors)
		return 0;
 again:
	for (;;) switch (c = lex(ex))
	{
	case 0:
		goto eof;
	case '/':
		switch (q = lex(ex))
		{
		case '*':
			for (;;) switch (lex(ex))
			{
			case '\n':
				BUMP (error_info.line);
				continue;
			case '*':
				switch (lex(ex))
				{
				case 0:
					goto eof;
				case '\n':
					BUMP (error_info.line);
					break;
				case '*':
					exunlex(ex, '*');
					break;
				case '/':
					goto again;
				}
				break;
			}
			break;
		case '/':
			while ((c = lex(ex)) != '\n')
				if (!c)
					goto eof;
			break;
		default:
			goto opeq;
		}
		/*FALLTHROUGH*/
	case '\n':
		BUMP (error_info.line);
		/*FALLTHROUGH*/
	case ' ':
	case '\t':
		break;
	case '(':
	case '{':
	case '[':
		ex->input->nesting++;
		return exlval.op = c;
	case ')':
	case '}':
	case ']':
		ex->input->nesting--;
		return exlval.op = c;
	case '+':
	case '-':
		if ((q = lex(ex)) == c)
			return exlval.op = c == '+' ? INC : DEC;
		goto opeq;
	case '*':
	case '%':
	case '^':
		q = lex(ex);
	opeq:
		exlval.op = c;
		if (q == '=')
			c = '=';
		else if (q == '%' && c == '%')
		{
			if (ex->input->fp)
				ex->more = (const char*)ex->input->fp;
			else ex->more = ex->input->sp;
			goto eof;
		}
		else exunlex(ex, q);
		return c;
	case '&':
	case '|':
		if ((q = lex(ex)) == '=')
		{
			exlval.op = c;
			return '=';
		}
		if (q == c)
			c = c == '&' ? AND : OR;
		else exunlex(ex, q);
		return exlval.op = c;
	case '<':
	case '>':
		if ((q = lex(ex)) == c)
		{
			exlval.op = c = c == '<' ? LS : RS;
			if ((q = lex(ex)) == '=')
				c = '=';
			else exunlex(ex, q);
			return c;
		}
		goto relational;
	case '=':
	case '!':
		q = lex(ex);
	relational:
		if (q == '=') switch (c)
		{
		case '<':
			c = LE;
			break;
		case '>':
			c = GE;
			break;
		case '=':
			c = EQ;
			break;
		case '!':
			c = NE;
			break;
		}
		else exunlex(ex, q);
		return exlval.op = c;
	case '#':
		if (!ex->linewrap && !(ex->disc->flags & EX_PURE))
		{
			s = ex->linep - 1;
			while (s > ex->line && isspace(*(s - 1)))
				s--;
			if (s == ex->line)
			{
				switch (extoken_fn(ex))
				{
				case DYNAMIC:
				case ID:
				case NAME:
					s = exlval.id->name;
					break;
				default:
					s = "";
					break;
				}
				if (streq(s, "include"))
				{
					if (extoken_fn(ex) != STRING)
						exerror("#%s: string argument expected", s);
					else if (!expush(ex, exlval.string, 1, NiL, NiL))
					{
						setcontext(ex);
						goto again;
					}
				}
				else exerror("unknown directive");
			}
		}
		return exlval.op = c;
	case '\'':
	case '"':
		q = c;
		sfstrset(ex->tmp, 0);
		ex->input->nesting++;
		while ((c = lex(ex)) != q)
		{
			if (c == '\\')
			{
				sfputc(ex->tmp, c);
				c = lex(ex);
			}
			if (!c)
			{
				exerror("unterminated %c string", q);
				goto eof;
			}
			if (c == '\n')
			{
				BUMP (error_info.line);
			}
			sfputc(ex->tmp, c);
		}
		ex->input->nesting--;
		s = sfstruse(ex->tmp);
		if (q == '"' || (ex->disc->flags & EX_CHARSTRING))
		{
			if (!(exlval.string = vmstrdup(ex->vm, s)))
				goto eof;
			stresc(exlval.string);
			return STRING;
		}
		exlval.integer = chrtoi(s);
		return INTEGER;
	case '.':
		if (isdigit(c = lex(ex)))
		{
			sfstrset(ex->tmp, 0);
			sfputc(ex->tmp, '0');
			sfputc(ex->tmp, '.');
			goto floating;
		}
		exunlex(ex, c);
		return exlval.op = '.';
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
		sfstrset(ex->tmp, 0);
		sfputc(ex->tmp, c);
		q = INTEGER;
		if ((c = lex(ex)) == 'x' || c == 'X')
		{
			sfputc(ex->tmp, c);
			for (;;)
			{
				switch (c = lex(ex))
				{
				case '0': case '1': case '2': case '3': case '4':
				case '5': case '6': case '7': case '8': case '9':
				case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 
				case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 
					sfputc(ex->tmp, c);
					continue;
				}
				break;
			}
		}
		else
		{
			while (isdigit(c))
			{
				sfputc(ex->tmp, c);
				c = lex(ex);
			}
			if (c == '#')
			{
				sfputc(ex->tmp, c);
				/* s = sfstruse(ex->tmp); */
				/* b = strtol(s, NiL, 10); */
				do
				{
					sfputc(ex->tmp, c);
				} while (isalnum(c = lex(ex)));
			}
			else
			{
				if (c == '.')
				{
				floating:
					q = FLOATING;
					sfputc(ex->tmp, c);
					while (isdigit(c = lex(ex)))
						sfputc(ex->tmp, c);
				}
				if (c == 'e' || c == 'E')
				{
					q = FLOATING;
					sfputc(ex->tmp, c);
					if ((c = lex(ex)) == '-' || c == '+')
					{
						sfputc(ex->tmp, c);
						c = lex(ex);
					}
					while (isdigit(c))
					{
						sfputc(ex->tmp, c);
						c = lex(ex);
					}
				}
			}
		}
		s = sfstruse(ex->tmp);
		if (q == FLOATING)
			exlval.floating = strtod(s, &e);
		else
		{
			if (c == 'u' || c == 'U')
			{
				q = UNSIGNED;
				c = lex(ex);
				exlval.integer = strToL(s, &e);
			}
			else
				exlval.integer = strToL(s, &e);
			if (*e)
			{
				*--e = 1;
				exlval.integer *= strton(e, &e, NiL, 0);
			}
		}
		exunlex(ex, c);
		if (*e || isalpha(c) || c == '_' || c == '$')
		{
			exerror("%s: invalid numeric constant", s);
			goto eof;
		}
		return q;
	default:
		if (isalpha(c) || c == '_' || c == '$')
		{
			sfstrset(ex->tmp, 0);
			sfputc(ex->tmp, c);
			while (isalnum(c = lex(ex)) || c == '_' || c == '$')
				sfputc(ex->tmp, c);
			exunlex(ex, c);
			s = sfstruse(ex->tmp);
			if (!(exlval.id = (Exid_t*)dtmatch(ex->symbols, s)))
			{
				if (!(exlval.id = newof(0, Exid_t, 1, strlen(s) - EX_NAMELEN + 1)))
				{
					exerror("out of space");
					goto eof;
				}
				strcpy(exlval.id->name, s);
				exlval.id->lex = NAME;
				dtinsert((ex->formals || !ex->symbols->view) ? ex->symbols : ex->symbols->view, exlval.id);
			}

			/*
			 * lexical analyzer state controlled by the grammar
			 */

			switch (exlval.id->lex)
			{
			case DECLARE:
				if (exlval.id->index == CHAR)
				{
					/*
					 * `char*' === `string'
					 * the * must immediately follow char
					 */

					if (c == '*')
					{
						lex(ex);
						exlval.id = id_string;
					}
				}
				break;
			case NAME:
				/*
				 * action labels are disambiguated from ?:
				 * through the expr.nolabel grammar hook
				 * the : must immediately follow labels
				 */

				if (c == ':' && !expr.nolabel)
					return LABEL;
				break;
			case PRAGMA:
				/*
				 * user specific statement stripped and
				 * passed as string
				 */

				{
					int	b;
					int	n;
					int	pc = 0;
					int	po;
					int	t;

					/*UNDENT...*/
	sfstrset(ex->tmp, 0);
	b = 1;
	n = 0;
	po = 0;
	t = 0;
	for (c = t = lex(ex);; c = lex(ex))
	{
		switch (c)
		{
		case 0:
			goto eof;
		case '/':
			switch (q = lex(ex))
			{
			case '*':
				for (;;)
				{
					switch (lex(ex))
					{
					case '\n':
						BUMP (error_info.line);
						continue;
					case '*':
						switch (lex(ex))
						{
						case 0:
							goto eof;
						case '\n':
							BUMP (error_info.line);
							continue;
						case '*':
							exunlex(ex, '*');
							continue;
						case '/':
							break;
						default:
							continue;
						}
						break;
					}
					if (!b++)
						goto eof;
					sfputc(ex->tmp, ' ');
					break;
				}
				break;
			case '/':
				while ((c = lex(ex)) != '\n')
					if (!c)
						goto eof;
				BUMP (error_info.line);
				b = 1;
				sfputc(ex->tmp, '\n');
				break;
			default:
				b = 0;
				sfputc(ex->tmp, c);
				sfputc(ex->tmp, q);
				break;
			}
			continue;
		case '\n':
			BUMP (error_info.line);
			b = 1;
			sfputc(ex->tmp, '\n');
			continue;
		case ' ':
		case '\t':
			if (!b++)
				goto eof;
			sfputc(ex->tmp, ' ');
			continue;
		case '(':
		case '{':
		case '[':
			b = 0;
			if (!po)
			{
				switch (po = c)
				{
				case '(':
					pc = ')';
					break;
				case '{':
					pc = '}';
					break;
				case '[':
					pc = ']';
					break;
				}
				n++;
			}
			else if (c == po)
				n++;
			sfputc(ex->tmp, c);
			continue;
		case ')':
		case '}':
		case ']':
			b = 0;
			if (!po)
			{
				exunlex(ex, c);
				break;
			}
			sfputc(ex->tmp, c);
			if (c == pc && --n <= 0)
			{
				if (t == po)
					break;
				po = 0;
			}
			continue;
		case ';':
			b = 0;
			if (!n)
				break;
			sfputc(ex->tmp, c);
			continue;
		case '\'':
		case '"':
			b = 0;
			sfputc(ex->tmp, c);
			ex->input->nesting++;
			q = c;
			while ((c = lex(ex)) != q)
			{
				if (c == '\\')
				{
					sfputc(ex->tmp, c);
					c = lex(ex);
				}
				if (!c)
				{
					exerror("unterminated %c string", q);
					goto eof;
				}
				if (c == '\n')
				{
					BUMP (error_info.line);
				}
				sfputc(ex->tmp, c);
			}
			ex->input->nesting--;
			continue;
		default:
			b = 0;
			sfputc(ex->tmp, c);
			continue;
		}
		break;
	}
	(*ex->disc->reff)(ex, NiL, exlval.id, NiL, sfstruse(ex->tmp), 0, ex->disc);

					/*..INDENT*/
				}
				goto again;
			}
			return exlval.id->lex;
		}
		return exlval.op = c;
	}
 eof:
	ex->eof = 1;
	return exlval.op = ';';
}
Exemple #22
0
static int
actionf(register Css_t* css, register Cssfd_t* fp, Cssdisc_t* disc)
{
	register State_t*	state = (State_t*)disc;
	register Connection_t*	con;
	register char*		s;
	register char*		t;
	int			n;
	int			i;

	switch (fp->status)
	{
	case CS_POLL_CLOSE:
		if (con = (Connection_t*)fp->data)
		{
			if (con->service)
				error(ERROR_SYSTEM|3, "service termination exit");
			free(con);
		}
		return 0;
	case CS_POLL_READ:
		con = (Connection_t*)fp->data;
		if ((n = csread(css->state, fp->fd, buf, sizeof(buf) - 1, CS_LINE)) <= 0)
		{
			if (con->service)
				error(ERROR_SYSTEM|3, "service termination exit");
			return -1;
		}
		buf[n] = 0;
		for (s = buf; isspace(*s); s++);
		if (con->service)
		{
			for (i = 0; isdigit(*s); i = i * 10 + *s++ - '0');
			for (; isspace(*s); s++);
			if (*s && cssfd(css, i, 0))
			{
				n -= s - buf;
				if (cswrite(css->state, i, s, n) != n)
					cssfd(css, i, CS_POLL_CLOSE);
			}
		}
		else if (*s == '!')
		{
			if ((n -= ++s - buf) > 0 && cswrite(css->state, state->proc->wfd, s, n) != n)
				return -1;
		}
		else
		{
			for (t = s; *t && !isspace(*t); t++);
			for (; isspace(*t); t++);
			if (*s == 'Q' && !*t)
			{
				if (con->id.uid == geteuid())
					error(3, "service quit exit");
			}
			else
			{
				n = sfprintf(state->tmp, "%-.*s%d %s", t - s, s, fp->fd, t);
				if (!(s = sfstruse(state->tmp)))
					return -1;
				if (cswrite(css->state, state->proc->wfd, s, n) != n)
					return -1;
			}
		}
		return 1;
	}
	return 0;
}
Exemple #23
0
static void
shell(void)
{
	register char*	s;
	register char*	f = 0;
	register int	c;

	if (ed.given)
		squeeze(ed.dol > ed.zero);
	s = getrec(ed.buffer.line, '\n', 0);
	if (s[0] == '!' && !s[1]) {
		if (!*sfstrbase(ed.buffer.shell))
			error(2, "no saved shell command");
		f = sfstrbase(ed.buffer.file);
	}
	else if (!s[0])
		error(2, "empty shell command");
	else
		SWP(ed.buffer.shell, ed.buffer.line);
	s = sfstrbase(ed.buffer.shell);
	sfstrseek(ed.buffer.line, 0, SEEK_SET);
	sfputc(ed.buffer.line, '!');
	while (c = *s++) {
		if (c == '\\') {
			if (*s != '%')
				sfputc(ed.buffer.line, c);
			sfputc(ed.buffer.line, *s++);
		}
		else if (c == '%')
			sfputr(ed.buffer.line, f = sfstrbase(ed.buffer.file), -1);
		else
			sfputc(ed.buffer.line, c);
	}
	if (ed.given) {
		if (!ed.tmpfile && !(ed.tmpfile = pathtemp(NiL, 0, NiL, error_info.id, NiL)))
			error(ERROR_SYSTEM|2, "cannot generate temp file name");
		if (!(ed.iop = sfopen(NiL, ed.tmpfile, "w")))
			error(ERROR_SYSTEM|2, "%s: cannot create temp file", ed.tmpfile);
		error_info.file = ed.tmpfile;
		if (ed.dol > ed.zero)
			putfile();
		exfile();
		ed.bytes = 0;
		ed.lines = 0;
		sfprintf(ed.buffer.line, " < %s", ed.tmpfile);
		if (!(s = sfstruse(ed.buffer.line)))
			error(ERROR_SYSTEM|3, "out of space");
		if (!(ed.iop = sfpopen(NiL, s + 1, "r")))
			error(ERROR_SYSTEM|2, "%s: cannot execute shell command", s);
		error_info.file = s;
		rdelete(ed.addr1, ed.addr2);
		append(getfile, ed.dot, NiL);
		exfile();
		remove(ed.tmpfile);
	}
	else {
		if (!(s = sfstruse(ed.buffer.line)))
			error(ERROR_SYSTEM|3, "out of space");
		s++;
		if (f)
			putrec(s);
		if (!(ed.iop = sfpopen(NiL, s, "")))
			error(ERROR_SYSTEM|2, "%s: cannot execute shell command", s);
		if (sfclose(ed.iop)) {
			ed.iop = 0;
			error(ERROR_SYSTEM|2, "%s: shell command exit error", s);
		}
		if (ed.verbose)
			putrec("!");
	}
}
Exemple #24
0
void
filein(register Archive_t* ap, register File_t* f)
{
	register off_t	c;
	register int	n;
	register char*	s;
	int		dfd;
	int		wfd;
	long		checksum;
	Filter_t*	fp;
	Proc_t*		pp;
	Tv_t		t1;
	Tv_t		t2;
	struct stat	st;

	if (f->skip)
		goto skip;
	else if (state.list)
	{
		if (fp = filter(ap, f))
		{
			for (n = 0; s = fp->argv[n]; n++)
			{
				while (*s)
					if (*s++ == '%' && *s == '(')
						break;
				if (*s)
				{
					s = fp->argv[n];
					listprintf(state.tmp.str, ap, f, s);
					if (!(fp->argv[n] = sfstruse(state.tmp.str)))
						nospace();
					break;
				}
			}
			pp = procopen(*fp->argv, fp->argv, NiL, NiL, PROC_WRITE);
			if (s)
				fp->argv[n] = s;
			if (!pp)
			{
				error(2, "%s: %s: cannot execute filter %s", ap->name, f->path, *fp->argv);
				goto skip;
			}
			if (!ap->format->getdata || !(*ap->format->getdata)(&state, ap, f, pp->wfd))
			{
				checksum = 0;
				for (c = f->st->st_size; c > 0; c -= n)
				{
					n = (c > state.buffersize) ? state.buffersize : c;
					if (!(s = bget(ap, n, NiL)))
					{
						error(ERROR_SYSTEM|2, "%s: read error", f->name);
						break;
					}
					if (write(pp->wfd, s, n) != n)
					{
						error(ERROR_SYSTEM|2, "%s: write error", f->name);
						break;
					}
					if (ap->format->checksum)
						checksum = (*ap->format->checksum)(&state, ap, f, s, n, checksum);
				}
			}
			if (ap->format->checksum && checksum != f->checksum)
				error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum);
			/*
			 * explicitly ignore exit status
			 */

			procclose(pp);
			return;
		}
		listentry(f);
		goto skip;
	}
	else switch (f->delta.op)
	{
	case DELTA_create:
		if (f->delta.base)
			error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__);
		if (ap->delta->format->flags & PSEUDO)
			goto regular;
		if ((wfd = openout(ap, f)) < 0)
			goto skip;
		else
			paxdelta(NiL, ap, f, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, f->st->st_size, 0);
		break;
	case DELTA_update:
		if (!f->delta.base || (unsigned long)f->delta.base->mtime.tv_sec >= (unsigned long)f->st->st_mtime)
			error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__);
		c = f->st->st_size;
		if ((wfd = openout(ap, f)) < 0)
			goto skip;
		if (state.ordered)
		{
			if (!f->delta.base->uncompressed)
				paxdelta(NiL, ap, f, DELTA_SRC|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
			else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0))
				paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
		}
		else if (!f->delta.base->uncompressed)
			paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
		else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0))
			paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
		break;
	case DELTA_verify:
		if (!f->delta.base || f->delta.base->mtime.tv_sec != f->st->st_mtime)
			error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__);
		if ((*state.statf)(f->name, &st))
			error(2, "%s: not copied from base archive", f->name);
		else if (st.st_size != f->delta.base->size || state.modtime && tvcmp(tvmtime(&t1, &st), tvmtime(&t2, f->st)))
			error(1, "%s: changed from base archive", f->name);
		break;
	case DELTA_delete:
		if (!f->delta.base)
			error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__);
		/*FALLTHROUGH*/
	default:
	regular:
		wfd = openout(ap, f);
		if (wfd >= 0)
		{
			holeinit(wfd);
			if (!ap->format->getdata || !(*ap->format->getdata)(&state, ap, f, wfd))
			{
				checksum = 0;
				for (c = f->st->st_size; c > 0; c -= n)
				{
					n = (c > state.buffersize) ? state.buffersize : c;
					if (!(s = bget(ap, n, NiL)))
					{
						error(ERROR_SYSTEM|2, "%s: read error", f->name);
						break;
					}
					if (holewrite(wfd, s, n) != n)
					{
						error(ERROR_SYSTEM|2, "%s: write error", f->name);
						break;
					}
					if (ap->format->checksum)
						checksum = (*ap->format->checksum)(&state, ap, f, s, n, checksum);
				}
			}
			holedone(wfd);
			closeout(ap, f, wfd);
			setfile(ap, f);
			if (ap->format->checksum && checksum != f->checksum)
				error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum);
		}
		else if (ap->format->getdata)
			(*ap->format->getdata)(&state, ap, f, wfd);
		else
		{
			if (wfd < -1)
				listentry(f);
			goto skip;
		}
		break;
	}
	listentry(f);
	return;
 skip:
	fileskip(ap, f);
}
Exemple #25
0
int
main(int argc, char** argv)
{
	register Mc_t*	mc;
	register char*	s;
	register char*	t;
	register int	c;
	register int	q;
	register int	i;
	int		num;
	char*		b;
	char*		e;
	char*		catfile;
	char*		msgfile;
	Sfio_t*		sp;
	Sfio_t*		mp;
	Sfio_t*		tp;
	Xl_t*		px;
	Xl_t*		bp;

	Xl_t*		xp = 0;
	int		format = 0;
	int		list = 0;
	int		set = 0;

	NoP(argc);
	error_info.id = "msggen";
	for (;;)
	{
		switch (optget(argv, usage))
		{
		case 'f':
			format = list = 1;
			continue;
		case 'l':
			list = 1;
			continue;
		case 's':
			set = 1;
			continue;
		case '?':
			error(ERROR_USAGE|4, "%s", opt_info.arg);
			continue;
		case ':':
			error(2, "%s", opt_info.arg);
			continue;
		}
		break;
	}
	argv += opt_info.index;
	if (error_info.errors || !(catfile = *argv++))
		error(ERROR_USAGE|4, "%s", optusage(NiL));

	/*
	 * set and list only need catfile
	 */

	if (set)
	{
		sfprintf(sfstdout, "%d\n", mcindex(catfile, NiL, NiL, NiL));
		return error_info.errors != 0;
	}
	else if (list)
	{
		if (!(sp = sfopen(NiL, catfile, "r")))
			error(ERROR_SYSTEM|3, "%s: cannot read catalog", catfile);
		if (!(mc = mcopen(sp)))
			error(ERROR_SYSTEM|3, "%s: catalog content error", catfile);
		sfclose(sp);
		if (format)
		{
			for (set = 1; set <= mc->num; set++)
				if (mc->set[set].num)
				{
					sfprintf(sfstdout, "$set %d\n", set);
					for (num = 1; num <= mc->set[set].num; num++)
						if (s = mc->set[set].msg[num])
							sfprintf(sfstdout, "%d \"%s\"\n", num, fmtfmt(s));
				}
		}
		else
		{
			if (*mc->translation)
			{
				ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$translation ");
				sfprintf(sfstdout, "%s", mc->translation);
				ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "\n");
			}
			ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$quote \"\n");
			for (set = 1; set <= mc->num; set++)
				if (mc->set[set].num)
				{
					ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$set %d\n", set);
					for (num = 1; num <= mc->set[set].num; num++)
						if (s = mc->set[set].msg[num])
						{
							ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "%d \"", num);
							while (c = *s++)
							{
								/*INDENT...*/

			switch (c)
			{
			case 0x22: /* " */
			case 0x5C: /* \ */
				sfputc(sfstdout, 0x5C);
				break;
			case 0x07: /* \a */
				c = 0x61;
				sfputc(sfstdout, 0x5C);
				break;
			case 0x08: /* \b */
				c = 0x62;
				sfputc(sfstdout, 0x5C);
				break;
			case 0x0A: /* \n */
				c = 0x6E;
				sfputc(sfstdout, 0x5C);
				break;
			case 0x0B: /* \v */
				c = 0x76;
				sfputc(sfstdout, 0x5C);
				break;
			case 0x0C: /* \f */
				c = 0x66;
				sfputc(sfstdout, 0x5C);
				break;
			case 0x0D: /* \r */
				c = 0x72;
				sfputc(sfstdout, 0x5C);
				break;
			}

								/*...UNDENT*/
								sfputc(sfstdout, c);
							}
							ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "\"\n");
						}
				}
		}
		mcclose(mc);
		return error_info.errors != 0;
	}
	else if (!(msgfile = *argv++) || *argv)
		error(3, "exactly one message file must be specified");

	/*
	 * open the files and handles
	 */

	if (!(tp = sfstropen()))
		error(ERROR_SYSTEM|3, "out of space [string stream]");
	if (!(mp = sfopen(NiL, msgfile, "r")))
		error(ERROR_SYSTEM|3, "%s: cannot read message file", msgfile);
	sp = sfopen(NiL, catfile, "r");
	if (!(mc = mcopen(sp)))
		error(ERROR_SYSTEM|3, "%s: catalog content error", catfile);
	if (sp)
		sfclose(sp);
	xp = translation(xp, mc->translation);

	/*
	 * read the message file
	 */

	q = 0;
	set = 1;
	error_info.file = msgfile;
	while (s = sfgetr(mp, '\n', 1))
	{
		error_info.line++;
		if (!*s)
			continue;
		if (*s == '$')
		{
			if (!*++s || isspace(*s))
				continue;
			for (t = s; *s && !isspace(*s); s++);
			if (*s)
				*s++ = 0;
			if (streq(t, "delset"))
			{
				while (isspace(*s))
					s++;
				num = (int)strtol(s, NiL, 0);
				if (num < mc->num && mc->set[num].num)
					for (i = 1; i <= mc->set[num].num; i++)
						mcput(mc, num, i, NiL);
			}
			else if (streq(t, "quote"))
				q = *s ? *s : 0;
			else if (streq(t, "set"))
			{
				while (isspace(*s))
					s++;
				num = (int)strtol(s, &e, 0);
				if (e != s)
					set = num;
				else
					error(2, "set number expected");
			}
			else if (streq(t, "translation"))
				xp = translation(xp, s);
		}
		else
		{
			t = s + sfvalue(mp);
			num = (int)strtol(s, &e, 0);
			if (e != s)
			{
				s = e;
				if (!*s)
				{
					if (mcput(mc, set, num, NiL))
						error(2, "(%d,%d): cannot delete message", set, num);
				}
				else if (isspace(*s++))
				{
					if (t > (s + 1) && *(t -= 2) == '\\')
					{
						sfwrite(tp, s, t - s);
						while (s = sfgetr(mp, '\n', 0))
						{
							error_info.line++;
							t = s + sfvalue(mp);
							if (t <= (s + 1) || *(t -= 2) != '\\')
								break;
							sfwrite(tp, s, t - s);
						}
						if (!(s = sfstruse(tp)))
							error(ERROR_SYSTEM|3, "out of space");
					}
					if (q)
					{
						if (*s++ != q)
						{
							error(2, "(%d,%d): %c quote expected", set, num, q);
							continue;
						}
						b = t = s;
						while (c = *s++)
						{
							if (c == '\\')
							{
								c = chresc(s - 1, &e);
								s = e;
								if (c)
									*t++ = c;
								else
									error(1, "nul character ignored");
							}
							else if (c == q)
								break;
							else
								*t++ = c;
						}
						if (*s)
						{
							error(2, "(%d,%d): characters after quote not expected", set, num);
							continue;
						}
						*t = 0;
						s = b;
					}
					if (mcput(mc, set, num, s))
						error(2, "(%d,%d): cannot add message", set, num);
				}
				else
					error(2, "message text expected");
			}
			else
				error(2, "message number expected");
		}
	}
	error_info.file = 0;
	error_info.line = 0;

	/*
	 * fix up the translation record
	 */

	if (xp)
	{
		t = "";
		for (;;)
		{
			for (bp = 0, px = xp; px; px = px->next)
				if (px->date && (!bp || strcoll(bp->date, px->date) < 0))
					bp = px;
			if (!bp)
				break;
			sfprintf(tp, "%s%s %s", t, bp->name, bp->date);
			t = ", ";
			bp->date = 0;
		}
		if (!(mc->translation = sfstruse(tp)))
			error(ERROR_SYSTEM|3, "out of space");
	}

	/*
	 * dump the catalog to a local temporary
	 * rename if no errors
	 */

	if (!(s = pathtemp(NiL, 0, "", error_info.id, NiL)) || !(sp = sfopen(NiL, s, "w")))
		error(ERROR_SYSTEM|3, "%s: cannot write catalog file", catfile);
	if (mcdump(mc, sp) || mcclose(mc) || sfclose(sp))
	{
		remove(s);
		error(ERROR_SYSTEM|3, "%s: temporary catalog file write error", s);
	}
	remove(catfile);
	if (rename(s, catfile))
		error(ERROR_SYSTEM|3, "%s: cannot rename from temporary catalog file %s", catfile, s);
	return error_info.errors != 0;
}
Exemple #26
0
int
csclient(Cs_t* cs, int fd, const char* service, const char* prompt, char** argv, unsigned int flags)
{
	register int	i;
	char*		s;
	Sfio_t*		tmp;
	int		done;
	int		promptlen;
	int		timeout;
	ssize_t		n;
	int		sdf[2];
	Cspoll_t	fds[2];
	char		buf[8 * 1024];

	if (fd < 0 && (fd = csopen(cs, service, CS_OPEN_TEST)) < 0)
	{
		if (errno == ENOENT)
			error(3, "%s: server not running", service);
		else
			error(ERROR_SYSTEM|3, "%s: cannot open connect stream", service);
	}
#if _hdr_termios
	if (flags & CS_CLIENT_RAW)
	{
		tcgetattr(0, &state.old_term);
		atexit(restore);
		state.new_term = state.old_term;
		state.new_term.c_iflag &= ~(BRKINT|IGNPAR|PARMRK|INLCR|IGNCR|ICRNL);
		state.new_term.c_lflag &= ~(ECHO|ECHOK|ICANON|ISIG);
		state.new_term.c_cc[VTIME] = 0;
		state.new_term.c_cc[VMIN] = 1;
		tcsetattr(0, TCSANOW, &state.new_term);
	}
#endif
	sdf[0] = fd;
	sdf[1] = 1;
	if (argv && *argv)
	{
		fds[0].fd = 1;
		fds[0].events = CS_POLL_WRITE;
	}
	else
	{
		argv = 0;
		fds[0].fd = 0;
		fds[0].events = CS_POLL_READ;
	}
	fds[1].fd = fd;
	fds[1].events = CS_POLL_READ;
	done = 0;
	if (promptlen = (!argv && prompt && isatty(fds[0].fd) && isatty(1)) ? strlen(prompt) : 0)
		write(1, prompt, promptlen);
	timeout = CS_NEVER;
	tmp = 0;
	while (cspoll(cs, fds, elementsof(fds), timeout) > 0)
		for (i = 0; i < elementsof(fds); i++)
			if (fds[i].status & (CS_POLL_READ|CS_POLL_WRITE))
			{
				if (!i && argv)
				{
					if (!*argv)
					{
						argv = 0;
						fds[0].fd = 0;
						if (flags & CS_CLIENT_ARGV)
						{
							if (done++)
								return 0;
							timeout = 500;
						}
						fds[0].events = CS_POLL_READ;
						continue;
					}
					if (!tmp && !(tmp = sfstropen()))
						error(ERROR_SYSTEM|3, "out of space");
					for (;;)
					{
						s = *argv++;
						if ((flags & CS_CLIENT_SEP) && *s == ':' && !*(s + 1))
							break;
						if (sfstrtell(tmp))
							sfputc(tmp, ' ');
						sfprintf(tmp, "%s", s);
						if (!(flags & CS_CLIENT_SEP) || !*argv)
							break;
					}
					sfputc(tmp, '\n');
					n = sfstrtell(tmp);
					s = sfstruse(tmp);
				}
				else if ((n = read(fds[i].fd, s = buf, sizeof(buf) - 1)) < 0)
					error(ERROR_SYSTEM|3, "/dev/fd/%d: read error", fds[i].fd);
				if (!n)
				{
					if (done++)
						return 0;
					if (!i)
						write(sdf[i], "quit\n", 5);
					continue;
				}
				if (!i)
				{
#if _hdr_termios
					register char*	u;
					register int	m;

					s[n] = 0;
					if ((u = strchr(s, 035)))
					{
						if ((m = u - s) > 0 && write(sdf[i], s, m) != m)
							error(ERROR_SYSTEM|3, "/dev/fd/%d: write error", sdf[i]);
						tcsetattr(0, TCSANOW, &state.old_term);
						if (promptlen)
							write(1, prompt, promptlen);
						if ((n = read(fds[i].fd, s = buf, sizeof(buf) - 1)) <= 0)
						{
							write(1, "\n", 1);
							return 0;
						}
						buf[n - 1] = 0;
						if (*u == 'q' || *u == 'Q')
							return 0;
						tcsetattr(0, TCSANOW, &state.new_term);
						if (*u)
							error(1, "%s: unknown command", u);
						continue;
					}
#endif
				}
				if (write(sdf[i], s, n) != n)
					error(ERROR_SYSTEM|3, "/dev/fd/%d: write error", sdf[i]);
				if (sdf[i] == 1 && promptlen)
					write(1, prompt, promptlen);
			}
	return error_info.errors != 0;
}
Exemple #27
0
int
pzheadwrite(Pz_t* pz, Sfio_t* op)
{
	register size_t	i;
	register size_t	m;
	register size_t	n;
	register char*	s;

	if (pz->flags & PZ_HEAD)
		return 0;
	pz->oop = op;
	if (!(pz->flags & PZ_NOGZIP))
		sfdcgzip(op, 0);
	if (pz->flags & PZ_NOPZIP)
		return 0;
	sfputc(op, PZ_MAGIC_1);
	sfputc(op, PZ_MAGIC_2);
	if (sfsync(op))
		return -1;
	sfputc(op, pz->major = PZ_MAJOR);
	sfputc(op, pz->minor = PZ_MINOR);
	sfputu(op, pz->win);
	if (pz->disc->comment)
	{
		sfputc(op, PZ_HDR_comment);
		m = strlen(pz->disc->comment) + 1;
		sfputu(op, m);
		sfwrite(op, pz->disc->comment, m);
	}
	if (pz->det && (m = sfstrtell(pz->det)))
	{
		sfputc(op, PZ_HDR_options);
		if (!(s = sfstruse(pz->det)))
		{
			if (pz->disc->errorf)
				(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "out of space");
			return -1;
		}
		m++;
		sfputu(op, m);
		sfwrite(op, s, m);
	}
	if (i = pz->prefix.count)
	{
		sfputc(op, PZ_HDR_prefix);
		if (pz->prefix.terminator >= 0)
		{
			m = 0;
			while (i-- > 0)
			{
				if (!(s = sfgetr(pz->io, pz->prefix.terminator, 0)))
				{
					if (pz->disc->errorf)
						(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix record%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
					return -1;
				}
				m += n = sfvalue(pz->io);
				sfwrite(pz->tmp, s, n);
			}
			s = sfstrseek(pz->tmp, 0, SEEK_SET);
		}
		else
		{
			m = i;
			if (!(s = (char*)sfreserve(pz->io, m, 0)))
			{
				if (pz->disc->errorf)
					(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix byte%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
				return -1;
			}
		}
		sfputu(op, m);
		sfwrite(op, s, m);
	}
	pz->flags |= PZ_HEAD;
	return pzpartwrite(pz, op);
}
Exemple #28
0
int
main(int argc, char** argv)
{
	char*	s;

	NoP(argc);
	if (s = strrchr(*argv, '/')) s++;
	else s = *argv;
	ed.restricted = streq(s, "red");
	error_info.id = s;
	error_info.write = helpwrite;
	init();
	for (;;)
	{
		for (;;) {
			switch (optget(argv, usage)) {

			case 'O':
				ed.reflags |= REG_LENIENT;
				continue;

			case 'S':
				ed.reflags &= ~REG_LENIENT;
				continue;

			case 'h':
				ed.help = 1;
				continue;

			case 'o':
				ed.msg = sfstderr;
				sfstrseek(ed.buffer.file, 0, SEEK_SET);
				sfputr(ed.buffer.file, "/dev/stdout", 0);
				continue;

			case 'p':
				sfstrseek(ed.buffer.prompt, 0, SEEK_SET);
				sfputr(ed.buffer.prompt, opt_info.arg, 0);
				ed.prompt = 1;
				continue;

			case 'q':
				signal(SIGQUIT, SIG_DFL);
				ed.verbose = 1;
				continue;

			case 's':
				ed.verbose = 0;
				continue;

			case '?':
				ed.help++;
				error(ERROR_USAGE|4, "%s", opt_info.arg);
				ed.help--;
				break;

			case ':':
				ed.help++;
				error(2, "%s", opt_info.arg);
				ed.help--;
				continue;

			}
			break;
		}
		if (!*(argv += opt_info.index) || **argv != '-' || *(*argv + 1))
			break;
		ed.verbose = 0;
	}
	if (*argv) {
		if (*(argv + 1))
			error(ERROR_USAGE|4, "%s", optusage(NiL));
		sfprintf(ed.buffer.global, "e %s", *argv);
		if (!(ed.global = sfstruse(ed.buffer.global)))
			error(ERROR_SYSTEM|3, "out of space");
	}
	edit();
	sfdcslow(sfstdin);
	setjmp(ed.again);
	commands();
	quit(0);
	exit(0);
}
Exemple #29
0
void
copy(register Archive_t* ap, register int (*copyfile)(Ftw_t*))
{
	register char*	s;
	register char*	t;
	register char*	v;
	register int	c;
	unsigned long	flags;
	char*		mode;
	char*		mtime;

	if (ap)
	{
		deltabase(ap);
		if (ap->delta && ap->delta->format != ap->expected && ap->expected)
			error(3, "%s: archive format %s does not match requested format %s", ap->name, ap->delta->format->name, ap->expected->name);
		if (state.append || state.update)
		{
			ap->format = ap->delta->format;
			if (!(ap->format->flags & APPEND))
				error(3, "%s: archive format %s does support append/update", ap->name, ap->format->name);
			if (state.update)
				ap->update = ap->delta->tab;
			ap->delta = 0;
			ap->parent = 0;
			ap->volume--;
		}
		putprologue(ap, state.append || state.update);
	}
	if (state.files)
		ftwalk((char*)state.files, copyfile, state.ftwflags|FTW_MULTIPLE, state.exact ? (Ftw_cmp_t)0 : cmpftw);
	else
	{
		sfopen(sfstdin, NiL, "rt");
		sfset(sfstdin, SF_SHARE, 0);
		mode = state.mode;
		mtime = state.mtime;
		for (;;)
		{
			if (s = state.peekfile)
			{
				state.peekfile = 0;
				c = state.peeklen;
			}
			else if (!(s = sfgetr(sfstdin, '\n', 1)))
				break;
			else
				c = sfvalue(sfstdin) - 1;
			sfwrite(state.tmp.lst, s, c);
			if (!(s = sfstruse(state.tmp.lst)))
				nospace();
			flags = state.ftwflags;
			if (state.filter.line)
			{
				if (!(c = *s++))
					continue;
				state.filter.options = s;
				if (!(s = skip(s, c)))
					continue;
				*s++ = 0;
				state.filter.command = s;
				if (!(s = skip(s, c)))
					continue;
				*s++ = 0;
				state.filter.path = s;
				if (!(s = skip(s, c)))
					state.filter.name = state.filter.path;
				else
				{
					*s++ = 0;
					state.filter.name = s;
					if (s = skip(s, c))
						*s = 0;
				}
				s = state.filter.options;
				for (;;)
				{
					if (t = strchr(s, ','))
						*t = 0;
					if (v = strchr(s, '='))
					{
						*v++ = 0;
						c = strtol(v, NiL, 0);
					}
					else
						c = 1;
					if (s[0] == 'n' && s[1] == 'o')
					{
						s += 2;
						c = !c;
					}
					if (streq(s, "logical") || streq(s, "physical"))
					{
						if (s[0] == 'p')
							c = !c;
						if (c)
							flags &= ~(FTW_META|FTW_PHYSICAL);
						else
						{
							flags &= ~(FTW_META);
							flags |= FTW_PHYSICAL;
						}
					}
					else if (streq(s, "mode"))
						state.mode = v;
					else if (streq(s, "mtime"))
						state.mtime = v;
					if (!t)
						break;
					s = t + 1;
				}
				s = state.filter.path;
				state.filter.line = *state.filter.name ? 2 : 1;
			}
			c = *s ? ftwalk(s, copyfile, flags, NiL) : 0;
			state.mode = mode;
			state.mtime = mtime;
			if (c)
			{
				error(2, "%s: not completely copied", s);
				break;
			}
		}
	}
	if (ap)
	{
		deltadelete(ap);
		putepilogue(ap);
	}
}
Exemple #30
0
int
b_mime(int argc, char** argv, Shbltin_t* context)
{
	Mime_t*		mp;
	char*		s;
	Sfio_t*		sp;
	int		silent;
	Mimedisc_t	disc;

	cmdinit(argc, argv, context, ERROR_CATALOG, 0);
	silent = 0;
	for (;;)
	{
		switch (optget(argv, usage))
		{
		case 0:
			break;
		case 's':
			silent = 1;
			continue;
		case ':':
			error(2, "%s", opt_info.arg);
			continue;
		case '?':
			error(ERROR_usage(2), "%s", opt_info.arg);
			continue;
		}
		break;
	}
	argc -= opt_info.index;
	argv += opt_info.index;
	if (error_info.errors || argc > 1 && argc < 3)
		error(ERROR_usage(2), "%s", optusage(NiL));
	disc.version = MIME_VERSION;
	disc.flags = 0;
	disc.errorf = errorf;
	if (!(mp = mimeopen(&disc)))
		error(ERROR_exit(1), "mime library error");
	if (mimeload(mp, NiL, 0))
	{
		mimeclose(mp);
		error(ERROR_exit(1), "mime load error");
	}
	if (argc <= 1)
		mimelist(mp, sfstdout, argv[0]);
	else if (!(sp = sfstropen()))
		error(ERROR_exit(1), "out of space");
	else
	{
		for (argc = 3; s = argv[argc]; argc++)
			sfputr(sp, s, ';');
		if (!(s = sfstruse(sp)))
			error(ERROR_exit(1), "out of space");
		if (!(s = mimeview(mp, argv[0], argv[1], argv[2], s)))
		{
			if (silent)
				exit(1);
			error(ERROR_exit(1), "no %s view for mime type %s", argv[0], argv[2]);
		}
		else
			sfputr(sfstdout, s, '\n');
		sfclose(sp);
	}
	mimeclose(mp);
	return 0;
}