Ejemplo n.º 1
0
static char*
temp(char* buf, int* fdp)
{
	char*	s;
	char*	d;
	int	n;
	size_t	len;

	len = strlen(buf);
	if (s = strrchr(buf, '/'))
	{
		*s++ = 0;
		d = buf;
	}
	else
	{
		s = buf;
		d = "";
	}
	if ((n = strlen(s)) < 6 || strcmp(s + n - 6, "XXXXXX"))
		*buf = 0;
	else
	{
		*(s + n - 6) = 0;
		if (!pathtemp(buf, len, d, s, fdp))
			*buf = 0;
	}
	return buf;
}
Ejemplo n.º 2
0
extern char*
tmpnam(char* s)
{
	static char	buf[L_tmpnam];

	return pathtemp(s ? s : buf, L_tmpnam, NiL, "tn", NiL);
}
Ejemplo n.º 3
0
int
b_mktemp(int argc, char** argv, Shbltin_t* context)
{
	mode_t		mode = 0;
	mode_t		mask;
	int		fd;
	int		i;
	int		quiet = 0;
	int		unsafe = 0;
	int*		fdp = &fd;
	char*		dir = "";
	char*		pfx;
	char*		t;
	char		path[PATH_MAX];

	cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
	for (;;)
	{
		switch (optget(argv, usage))
		{
		case 'd':
			fdp = 0;
			continue;
		case 'm':
			mode = strperm(pfx = opt_info.arg, &opt_info.arg, S_IRWXU);
			if (*opt_info.arg)
				error(ERROR_exit(0), "%s: invalid mode", pfx);
			continue;
		case 'p':
			if ((t = getenv("TMPDIR")) && *t)
				dir = 0;
			else
				dir = opt_info.arg;
			continue;
		case 'q':
			quiet = 1;
			continue;
		case 't':
			dir = 0;
			continue;
		case 'u':
			unsafe = 1;
			fdp = 0;
			continue;
		case 'R':
			if (!pathtemp(NiL, 0, opt_info.arg, "/seed", NiL))
				error(2, "%s: regression test initializtion failed", opt_info.arg);
			continue;
		case ':':
			error(2, "%s", opt_info.arg);
			break;
		case '?':
			error(ERROR_usage(2), "%s", opt_info.arg);
			break;
		}
		break;
	}
	argv += opt_info.index;
	if (error_info.errors || (pfx = *argv++) && *argv)
		error(ERROR_usage(2), "%s", optusage(NiL));
	mask = umask(0);
	if (!mode)
		mode = (fdp ? (S_IRUSR|S_IWUSR) : S_IRWXU) & ~mask;
	umask(~mode & (S_IRWXU|S_IRWXG|S_IRWXO));
	if (!pfx)
	{
		pfx = "tmp_";
		if (dir && !*dir)
			dir = 0;
	}
	if (t = strrchr(pfx, '/'))
	{
		i = ++t - pfx;
		dir = fmtbuf(i);
		memcpy(dir, pfx, i);
		dir[i] = 0;
		pfx = t;
	}
	for (;;)
	{
		if (!pathtemp(path, sizeof(path), dir, pfx, fdp))
		{
			if (quiet)
				error_info.errors++;
			else
				error(ERROR_SYSTEM|2, "cannot create temporary path");
			break;
		}
		if (fdp || unsafe || !mkdir(path, mode))
		{
			if (fdp)
				close(*fdp);
			sfputr(sfstdout, path, '\n');
			break;
		}
		if (sh_checksig(context))
		{
			error_info.errors++;
			break;
		}
	}
	umask(mask);
	return error_info.errors != 0;
}
Ejemplo n.º 4
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("!");
	}
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
static void
execute(register Joblist_t* job)
{
	register List_t*	p;
	char*			s;
	char*			t;
	int			flags;
	Rule_t*			r;
	Var_t*			v;
	Sfio_t*			tmp;
	Sfio_t*			att;
	Sfio_t*			sp;

	att = sfstropen();
	tmp = sfstropen();
	restore(job, tmp, att);
	job->status = RUNNING;
	job->target->mark &= ~M_waiting;
	if (state.targetcontext || state.maxview && !state.fsview && *job->target->name != '/' && (!(job->target->dynamic & D_regular) || job->target->view))
		commit(job, job->target->name);
	if ((state.mam.dynamic || state.mam.regress) && state.user && !(job->target->property & (P_after|P_before|P_dontcare|P_make|P_state|P_virtual)))
		sfprintf(state.mam.out, "%sinit %s %s\n", state.mam.label, mamname(job->target), timefmt(NiL, CURTIME));
	t = sfstruse(tmp);
	if (!(job->flags & CO_ALWAYS))
	{
		if (state.touch)
		{
			if (state.virtualdot)
			{
				state.virtualdot = 0;
				lockstate(1);
			}
			if (!(job->target->property & (P_attribute|P_virtual)))
			{
				acceptrule(job->target);
				if ((job->target->property & (P_joint|P_target)) == (P_joint|P_target))
					for (p = job->target->prereqs->rule->prereqs; p; p = p->next)
						if (p->rule != job->target)
							acceptrule(p->rule);
			}
		}
		else if (*t && (!state.silent || state.mam.regress))
			dumpaction(state.mam.out ? state.mam.out : sfstdout, NiL, t, NiL);
		done(job, 0, NiL);
	}
	else
	{
		if (state.virtualdot && !notfile(job->target))
		{
			state.virtualdot = 0;
			lockstate(1);
		}
		if (!state.coshell)
		{
			sp = sfstropen();
			sfprintf(sp, "label=%s", idname);
			expand(sp, " $(" CO_ENV_OPTIONS ")");
			flags = CO_ANY;
			if (state.cross)
				flags |= CO_CROSS;
			if (state.serialize && state.jobs > 1)
				flags |= CO_SERIALIZE;
			if (!(state.coshell = coopen(getval(CO_ENV_SHELL, VAL_PRIMARY), flags, sfstruse(sp))))
				error(ERROR_SYSTEM|3, "coshell open error");
			sfstrclose(sp);
		}
		if (p = internal.exports->prereqs)
		{
			Sfio_t*	exp;

			exp = sfstropen();
			do
			{
				if (v = getvar(p->rule->name))
				{
					expand(exp, v->value);
					coexport(state.coshell, p->rule->name, sfstruse(exp));
				}
				else if (s = strchr(p->rule->name, '='))
				{
					*s = 0;
					expand(exp, s + 1);
					coexport(state.coshell, p->rule->name, sfstruse(exp));
					*s = '=';
				}
			} while (p = p->next);
			sfstrclose(exp);
#if 0
			freelist(internal.exports->prereqs);
#endif
			internal.exports->prereqs = 0;
		}
		if (job->flags & CO_DATAFILE)
		{
			static char*	dot;
			static char*	tmp;

			if (job->target->property & P_read)
			{
				if (!dot)
					dot = pathtemp(NiL, 0, null, idname, NiL);
				state.tmpfile = dot;
			}
			else
			{
				if (!tmp)
					tmp = pathtemp(NiL, 0, NiL, idname, NiL);
				state.tmpfile = tmp;
			}
		}
#if !_HUH_1992_02_29 /* i386 and ftx m68k dump without this statement -- help */
		message((-99, "execute: %s: t=0x%08x &t=0x%08x", job->target->name, t, &t));
#endif
		if (state.mam.out)
			dumpaction(state.mam.out, MAMNAME(job->target), t, NiL);
		if (r = getrule(external.makerun))
			maketop(r, P_dontcare|P_foreground, NiL);
		if (!(job->cojob = coexec(state.coshell, t, job->flags, state.tmpfile, NiL, sfstruse(att))))
			error(3, "%s: cannot send action to coshell", job->target->name);
		job->cojob->local = (void*)job;

		/*
		 * grab semaphores
		 */

		if (job->target->dynamic & D_hassemaphore)
		{
			job->flags |= CO_SEMAPHORES;
			for (p = job->prereqs; p; p = p->next)
				if (p->rule->semaphore && --p->rule->semaphore == 1)
					p->rule->status = MAKING;
		}

		/*
		 * check status and sync
		 */

		if (job->target->dynamic & D_hasafter)
			save(job);
		if (job->flags & (CO_DATAFILE|CO_FOREGROUND))
		{
			complete(job->target, NiL, NiL, 0);
			if (job->target->property & (P_functional|P_read))
			{
				if (sp = sfopen(NiL, state.tmpfile, "r"))
				{
					remove(state.tmpfile);
					if (job->target->property & P_read)
						parse(sp, NiL, job->target->name, NiL);
					else
					{
						char*	e;

						sfmove(sp, tmp, SF_UNBOUND, -1);
						t = sfstrbase(tmp);
						e = sfstrseek(tmp, 0, SEEK_CUR);
						while (e > t && *(e - 1) == '\n')
							e--;
						sfstrseek(tmp, e - t, SEEK_SET);
						setvar(job->target->name, sfstruse(tmp), 0);
					}
					sfclose(sp);
				}
				else
					error(2, "%s: cannot read temporary data output file %s", job->target->name, state.tmpfile);
				state.tmpfile = 0;
			}
		}
	}
	sfstrclose(att);
	sfstrclose(tmp);
}
Ejemplo n.º 7
0
static void*
aso_init_fcntl(void* data, const char* details)
{
	APL_t*		apl = (APL_t*)data;
	char*		path;
	char*		opt;
	size_t		size;
	size_t		references;
	int		n;
	int		fd;
	int		drop;
	int		perm;
	struct flock	lock;
	char		buf[PATH_MAX];
	char		tmp[64];

	if (apl)
	{
		lock.l_type = F_WRLCK;
		lock.l_whence = SEEK_SET;
		lock.l_start = apl->size;
		lock.l_len = sizeof(references);
		if (fcntl(apl->fd, F_SETLKW, &lock) >= 0)
		{
			if (lseek(apl->fd, apl->size, SEEK_SET) != apl->size)
				references = 0;
			else if (read(apl->fd, &references, sizeof(references)) != sizeof(references))
				references = 0;
			else if (references > 0)
			{
				references--;
				if (lseek(apl->fd, apl->size, SEEK_SET) != apl->size)
					references = 0;
				else if (write(apl->fd, &references, sizeof(references)) != sizeof(references))
					references = 0;
			}
			lock.l_type = F_UNLCK;
			fcntl(apl->fd, F_SETLK, &lock);
			if (!references)
				remove(apl->path);
		}
		close(apl->fd);
		free(apl);
		return 0;
	}
	fd = -1;
	perm = S_IRUSR|S_IWUSR;
	drop = 0;
	size = 32 * 1024 - sizeof(references);
	if (path = (char*)details)
		while (opt = strchr(path, ','))
		{
			if (strneq(path, "perm=", 5))
			{
				if ((n = opt - (path + 5)) >= sizeof(tmp))
					n = sizeof(tmp) - 1;
				memcpy(tmp, path + 5, n);
				tmp[n] = 0;
				perm = strperm(tmp, NiL, perm);
			}
			else if (strneq(path, "size=", 5))
			{
				size = strtoul(path + 5, NiL, 0);
				if (size <= sizeof(references))
					goto bad;
				size -= sizeof(references);
			}
			path = opt + 1;
		}
	if (!path || !*path)
	{
		if (!(path = pathtemp(buf, sizeof(buf), NiL, "aso", &fd)))
			return 0;
		drop = 1;
	}
	if (!(apl = newof(0, APL_t, 1, strlen(path))))
		goto bad;
	if (fd >= 0 || (fd = open(path, O_RDWR)) < 0 && (fd = open(path, O_CREAT|O_RDWR, perm)) >= 0)
	{
		if (lseek(fd, size, SEEK_SET) != size)
			goto bad;
		references = 1;
		if (write(fd, &references, sizeof(references)) != sizeof(references))
			goto bad;
	}
	else
	{
		if ((size = lseek(fd, 0, SEEK_END)) <= sizeof(references))
			goto bad;
		size -= sizeof(references);
		lock.l_type = F_WRLCK;
		lock.l_whence = SEEK_SET;
		lock.l_start = 0;
		lock.l_len = sizeof(references);
		if (fcntl(fd, F_SETLKW, &lock) < 0)
			goto bad;
		if (lseek(fd, size, SEEK_SET) != size)
			goto bad;
		if (read(fd, &references, sizeof(references)) != sizeof(references))
			goto bad;
		references++;
		if (lseek(fd, size, SEEK_SET) != size)
			goto bad;
		if (write(fd, &references, sizeof(references)) != sizeof(references))
			goto bad;
		lock.l_type = F_UNLCK;
		fcntl(fd, F_SETLK, &lock);
	}
	apl->fd = fd;
	apl->size = size;
	strcpy(apl->path, path);
	return apl;
 bad:
	if (apl)
		free(apl);
	if (fd >= 0)
		close(fd);
	if (drop)
		remove(path);
	return 0;
}