xref: /titanic_53/usr/src/cmd/sh/service.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
28*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.22.5.1 */
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*
34*7c478bd9Sstevel@tonic-gate  * UNIX shell
35*7c478bd9Sstevel@tonic-gate  */
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate #include	"defs.h"
38*7c478bd9Sstevel@tonic-gate #include	<errno.h>
39*7c478bd9Sstevel@tonic-gate #include	<fcntl.h>
40*7c478bd9Sstevel@tonic-gate #include	"sh_policy.h"
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate #define	ARGMK	01
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate static unsigned char	*execs();
45*7c478bd9Sstevel@tonic-gate static int	gsort();
46*7c478bd9Sstevel@tonic-gate static int	split();
47*7c478bd9Sstevel@tonic-gate extern const char	*sysmsg[];
48*7c478bd9Sstevel@tonic-gate extern short topfd;
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate /*
53*7c478bd9Sstevel@tonic-gate  * service routines for `execute'
54*7c478bd9Sstevel@tonic-gate  */
55*7c478bd9Sstevel@tonic-gate initio(iop, save)
56*7c478bd9Sstevel@tonic-gate 	struct ionod	*iop;
57*7c478bd9Sstevel@tonic-gate 	int		save;
58*7c478bd9Sstevel@tonic-gate {
59*7c478bd9Sstevel@tonic-gate 	register unsigned char	*ion;
60*7c478bd9Sstevel@tonic-gate 	register int	iof, fd;
61*7c478bd9Sstevel@tonic-gate 	int		ioufd;
62*7c478bd9Sstevel@tonic-gate 	short	lastfd;
63*7c478bd9Sstevel@tonic-gate 	int	newmode;
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate 	lastfd = topfd;
66*7c478bd9Sstevel@tonic-gate 	while (iop) {
67*7c478bd9Sstevel@tonic-gate 		iof = iop->iofile;
68*7c478bd9Sstevel@tonic-gate 		ion = mactrim(iop->ioname);
69*7c478bd9Sstevel@tonic-gate 		ioufd = iof & IOUFD;
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate 		if (*ion && (flags&noexec) == 0) {
72*7c478bd9Sstevel@tonic-gate 			if (save) {
73*7c478bd9Sstevel@tonic-gate 				fdmap[topfd].org_fd = ioufd;
74*7c478bd9Sstevel@tonic-gate 				fdmap[topfd++].dup_fd = savefd(ioufd);
75*7c478bd9Sstevel@tonic-gate 			}
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 			if (iof & IODOC) {
78*7c478bd9Sstevel@tonic-gate 				struct tempblk tb;
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate 				subst(chkopen(ion, 0), (fd = tmpfil(&tb)));
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate 				/*
83*7c478bd9Sstevel@tonic-gate 				 * pushed in tmpfil() --
84*7c478bd9Sstevel@tonic-gate 				 * bug fix for problem with
85*7c478bd9Sstevel@tonic-gate 				 * in-line scripts
86*7c478bd9Sstevel@tonic-gate 				 */
87*7c478bd9Sstevel@tonic-gate 				poptemp();
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 				fd = chkopen(tmpout, 0);
90*7c478bd9Sstevel@tonic-gate 				unlink((const char *)tmpout);
91*7c478bd9Sstevel@tonic-gate 			} else if (iof & IOMOV) {
92*7c478bd9Sstevel@tonic-gate 				if (eq(minus, ion)) {
93*7c478bd9Sstevel@tonic-gate 					fd = -1;
94*7c478bd9Sstevel@tonic-gate 					close(ioufd);
95*7c478bd9Sstevel@tonic-gate 				} else if ((fd = stoi(ion)) >= USERIO) {
96*7c478bd9Sstevel@tonic-gate 					failed(ion, badfile);
97*7c478bd9Sstevel@tonic-gate 				}
98*7c478bd9Sstevel@tonic-gate 				else
99*7c478bd9Sstevel@tonic-gate 					fd = dup(fd);
100*7c478bd9Sstevel@tonic-gate 			} else if (((iof & IOPUT) == 0) && ((iof & IORDW) == 0))
101*7c478bd9Sstevel@tonic-gate 				fd = chkopen(ion, 0);
102*7c478bd9Sstevel@tonic-gate 			else if (iof & IORDW) /* For <> */ {
103*7c478bd9Sstevel@tonic-gate 				newmode = O_RDWR|O_CREAT;
104*7c478bd9Sstevel@tonic-gate 				fd = chkopen(ion, newmode);
105*7c478bd9Sstevel@tonic-gate 			} else if (flags & rshflg) {
106*7c478bd9Sstevel@tonic-gate 				failed(ion, restricted);
107*7c478bd9Sstevel@tonic-gate 			} else if (iof & IOAPP &&
108*7c478bd9Sstevel@tonic-gate 			    (fd = open((char *)ion, 1)) >= 0) {
109*7c478bd9Sstevel@tonic-gate 				lseek(fd, (off_t)0, SEEK_END);
110*7c478bd9Sstevel@tonic-gate 			} else {
111*7c478bd9Sstevel@tonic-gate 				fd = create(ion);
112*7c478bd9Sstevel@tonic-gate 			}
113*7c478bd9Sstevel@tonic-gate 			if (fd >= 0)
114*7c478bd9Sstevel@tonic-gate 				renamef(fd, ioufd);
115*7c478bd9Sstevel@tonic-gate 		}
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate 		iop = iop->ionxt;
118*7c478bd9Sstevel@tonic-gate 	}
119*7c478bd9Sstevel@tonic-gate 	return (lastfd);
120*7c478bd9Sstevel@tonic-gate }
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate unsigned char *
123*7c478bd9Sstevel@tonic-gate simple(s)
124*7c478bd9Sstevel@tonic-gate unsigned char	*s;
125*7c478bd9Sstevel@tonic-gate {
126*7c478bd9Sstevel@tonic-gate 	unsigned char	*sname;
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 	sname = s;
129*7c478bd9Sstevel@tonic-gate 	while (1) {
130*7c478bd9Sstevel@tonic-gate 		if (any('/', sname))
131*7c478bd9Sstevel@tonic-gate 			while (*sname++ != '/')
132*7c478bd9Sstevel@tonic-gate 				;
133*7c478bd9Sstevel@tonic-gate 		else
134*7c478bd9Sstevel@tonic-gate 			return (sname);
135*7c478bd9Sstevel@tonic-gate 	}
136*7c478bd9Sstevel@tonic-gate }
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate unsigned char *
139*7c478bd9Sstevel@tonic-gate getpath(s)
140*7c478bd9Sstevel@tonic-gate 	unsigned char	*s;
141*7c478bd9Sstevel@tonic-gate {
142*7c478bd9Sstevel@tonic-gate 	register unsigned char	*path, *newpath;
143*7c478bd9Sstevel@tonic-gate 	register int pathlen;
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 	if (any('/', s))
146*7c478bd9Sstevel@tonic-gate 	{
147*7c478bd9Sstevel@tonic-gate 		if (flags & rshflg)
148*7c478bd9Sstevel@tonic-gate 			failed(s, restricted);
149*7c478bd9Sstevel@tonic-gate 		else
150*7c478bd9Sstevel@tonic-gate 			return ((unsigned char *)nullstr);
151*7c478bd9Sstevel@tonic-gate 	} else if ((path = pathnod.namval) == 0)
152*7c478bd9Sstevel@tonic-gate 		return ((unsigned char *)defpath);
153*7c478bd9Sstevel@tonic-gate 	else {
154*7c478bd9Sstevel@tonic-gate 		pathlen = length(path)-1;
155*7c478bd9Sstevel@tonic-gate 		/* Add extra ':' if PATH variable ends in ':' */
156*7c478bd9Sstevel@tonic-gate 		if (pathlen > 2 && path[pathlen - 1] == ':' &&
157*7c478bd9Sstevel@tonic-gate 				path[pathlen - 2] != ':') {
158*7c478bd9Sstevel@tonic-gate 			newpath = locstak();
159*7c478bd9Sstevel@tonic-gate 			(void) memcpystak(newpath, path, pathlen);
160*7c478bd9Sstevel@tonic-gate 			newpath[pathlen] = ':';
161*7c478bd9Sstevel@tonic-gate 			endstak(newpath + pathlen + 1);
162*7c478bd9Sstevel@tonic-gate 			return (newpath);
163*7c478bd9Sstevel@tonic-gate 		} else
164*7c478bd9Sstevel@tonic-gate 			return (cpystak(path));
165*7c478bd9Sstevel@tonic-gate 	}
166*7c478bd9Sstevel@tonic-gate }
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate pathopen(path, name)
169*7c478bd9Sstevel@tonic-gate register unsigned char *path, *name;
170*7c478bd9Sstevel@tonic-gate {
171*7c478bd9Sstevel@tonic-gate 	register int	f;
172*7c478bd9Sstevel@tonic-gate 
173*7c478bd9Sstevel@tonic-gate 	do
174*7c478bd9Sstevel@tonic-gate 	{
175*7c478bd9Sstevel@tonic-gate 		path = catpath(path, name);
176*7c478bd9Sstevel@tonic-gate 	} while ((f = open((char *)curstak(), 0)) < 0 && path);
177*7c478bd9Sstevel@tonic-gate 	return (f);
178*7c478bd9Sstevel@tonic-gate }
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate unsigned char *
181*7c478bd9Sstevel@tonic-gate catpath(path, name)
182*7c478bd9Sstevel@tonic-gate register unsigned char	*path;
183*7c478bd9Sstevel@tonic-gate unsigned char	*name;
184*7c478bd9Sstevel@tonic-gate {
185*7c478bd9Sstevel@tonic-gate 	/*
186*7c478bd9Sstevel@tonic-gate 	 * leaves result on top of stack
187*7c478bd9Sstevel@tonic-gate 	 */
188*7c478bd9Sstevel@tonic-gate 	register unsigned char	*scanp = path;
189*7c478bd9Sstevel@tonic-gate 	register unsigned char	*argp = locstak();
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate 	while (*scanp && *scanp != COLON)
192*7c478bd9Sstevel@tonic-gate 	{
193*7c478bd9Sstevel@tonic-gate 		if (argp >= brkend)
194*7c478bd9Sstevel@tonic-gate 			growstak(argp);
195*7c478bd9Sstevel@tonic-gate 		*argp++ = *scanp++;
196*7c478bd9Sstevel@tonic-gate 	}
197*7c478bd9Sstevel@tonic-gate 	if (scanp != path)
198*7c478bd9Sstevel@tonic-gate 	{
199*7c478bd9Sstevel@tonic-gate 		if (argp >= brkend)
200*7c478bd9Sstevel@tonic-gate 			growstak(argp);
201*7c478bd9Sstevel@tonic-gate 		*argp++ = '/';
202*7c478bd9Sstevel@tonic-gate 	}
203*7c478bd9Sstevel@tonic-gate 	if (*scanp == COLON)
204*7c478bd9Sstevel@tonic-gate 		scanp++;
205*7c478bd9Sstevel@tonic-gate 	path = (*scanp ? scanp : 0);
206*7c478bd9Sstevel@tonic-gate 	scanp = name;
207*7c478bd9Sstevel@tonic-gate 	do
208*7c478bd9Sstevel@tonic-gate 	{
209*7c478bd9Sstevel@tonic-gate 		if (argp >= brkend)
210*7c478bd9Sstevel@tonic-gate 			growstak(argp);
211*7c478bd9Sstevel@tonic-gate 	}
212*7c478bd9Sstevel@tonic-gate 	while (*argp++ = *scanp++);
213*7c478bd9Sstevel@tonic-gate 	return (path);
214*7c478bd9Sstevel@tonic-gate }
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate unsigned char *
217*7c478bd9Sstevel@tonic-gate nextpath(path)
218*7c478bd9Sstevel@tonic-gate 	register unsigned char	*path;
219*7c478bd9Sstevel@tonic-gate {
220*7c478bd9Sstevel@tonic-gate 	register unsigned char	*scanp = path;
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate 	while (*scanp && *scanp != COLON)
223*7c478bd9Sstevel@tonic-gate 		scanp++;
224*7c478bd9Sstevel@tonic-gate 
225*7c478bd9Sstevel@tonic-gate 	if (*scanp == COLON)
226*7c478bd9Sstevel@tonic-gate 		scanp++;
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 	return (*scanp ? scanp : 0);
229*7c478bd9Sstevel@tonic-gate }
230*7c478bd9Sstevel@tonic-gate 
231*7c478bd9Sstevel@tonic-gate static unsigned char	*xecmsg;
232*7c478bd9Sstevel@tonic-gate static unsigned char	**xecenv;
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate int
235*7c478bd9Sstevel@tonic-gate execa(at, pos)
236*7c478bd9Sstevel@tonic-gate     unsigned char *at[];
237*7c478bd9Sstevel@tonic-gate     short pos;
238*7c478bd9Sstevel@tonic-gate {
239*7c478bd9Sstevel@tonic-gate 	register unsigned char	*path;
240*7c478bd9Sstevel@tonic-gate 	register unsigned char	**t = at;
241*7c478bd9Sstevel@tonic-gate 	int		cnt;
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 	if ((flags & noexec) == 0)
244*7c478bd9Sstevel@tonic-gate 	{
245*7c478bd9Sstevel@tonic-gate 		xecmsg = (unsigned char *)notfound;
246*7c478bd9Sstevel@tonic-gate 		path = getpath(*t);
247*7c478bd9Sstevel@tonic-gate 		xecenv = local_setenv();
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate 		if (pos > 0)
250*7c478bd9Sstevel@tonic-gate 		{
251*7c478bd9Sstevel@tonic-gate 			cnt = 1;
252*7c478bd9Sstevel@tonic-gate 			while (cnt != pos)
253*7c478bd9Sstevel@tonic-gate 			{
254*7c478bd9Sstevel@tonic-gate 				++cnt;
255*7c478bd9Sstevel@tonic-gate 				path = nextpath(path);
256*7c478bd9Sstevel@tonic-gate 			}
257*7c478bd9Sstevel@tonic-gate 			execs(path, t);
258*7c478bd9Sstevel@tonic-gate 			path = getpath(*t);
259*7c478bd9Sstevel@tonic-gate 		}
260*7c478bd9Sstevel@tonic-gate 		while (path = execs(path, t))
261*7c478bd9Sstevel@tonic-gate 			;
262*7c478bd9Sstevel@tonic-gate 		failed(*t, xecmsg);
263*7c478bd9Sstevel@tonic-gate 	}
264*7c478bd9Sstevel@tonic-gate }
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate static unsigned char *
267*7c478bd9Sstevel@tonic-gate execs(ap, t)
268*7c478bd9Sstevel@tonic-gate unsigned char	*ap;
269*7c478bd9Sstevel@tonic-gate register unsigned char	*t[];
270*7c478bd9Sstevel@tonic-gate {
271*7c478bd9Sstevel@tonic-gate 	register int		pfstatus = NOATTRS;
272*7c478bd9Sstevel@tonic-gate 	register unsigned char	*p, *prefix;
273*7c478bd9Sstevel@tonic-gate 	unsigned char		*savptr;
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 	prefix = catpath(ap, t[0]);
276*7c478bd9Sstevel@tonic-gate 	trim(p = curstak());
277*7c478bd9Sstevel@tonic-gate 	sigchk();
278*7c478bd9Sstevel@tonic-gate 
279*7c478bd9Sstevel@tonic-gate 	if (flags & pfshflg) {
280*7c478bd9Sstevel@tonic-gate 		/*
281*7c478bd9Sstevel@tonic-gate 		 * Need to save the stack information, or the
282*7c478bd9Sstevel@tonic-gate 		 * first memory allocation in secpolicy_profile_lookup()
283*7c478bd9Sstevel@tonic-gate 		 * will clobber it.
284*7c478bd9Sstevel@tonic-gate 		 */
285*7c478bd9Sstevel@tonic-gate 		savptr = endstak(p + strlen((const char *)p) + 1);
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate 		pfstatus = secpolicy_pfexec((const char *)p,
288*7c478bd9Sstevel@tonic-gate 		    (char **)t, (const char **)xecenv);
289*7c478bd9Sstevel@tonic-gate 
290*7c478bd9Sstevel@tonic-gate 		if (pfstatus != NOATTRS) {
291*7c478bd9Sstevel@tonic-gate 			errno = pfstatus;
292*7c478bd9Sstevel@tonic-gate 		}
293*7c478bd9Sstevel@tonic-gate 
294*7c478bd9Sstevel@tonic-gate 		tdystak(savptr);
295*7c478bd9Sstevel@tonic-gate 	}
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate 	if (pfstatus == NOATTRS) {
298*7c478bd9Sstevel@tonic-gate 		execve((const char *)p, (char *const *)&t[0],
299*7c478bd9Sstevel@tonic-gate 		    (char *const *)xecenv);
300*7c478bd9Sstevel@tonic-gate 	}
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	switch (errno)
303*7c478bd9Sstevel@tonic-gate 	{
304*7c478bd9Sstevel@tonic-gate 	case ENOEXEC:		/* could be a shell script */
305*7c478bd9Sstevel@tonic-gate 		funcnt = 0;
306*7c478bd9Sstevel@tonic-gate 		flags = 0;
307*7c478bd9Sstevel@tonic-gate 		*flagadr = 0;
308*7c478bd9Sstevel@tonic-gate 		comdiv = 0;
309*7c478bd9Sstevel@tonic-gate 		ioset = 0;
310*7c478bd9Sstevel@tonic-gate 		clearup();	/* remove open files and for loop junk */
311*7c478bd9Sstevel@tonic-gate 		if (input)
312*7c478bd9Sstevel@tonic-gate 			close(input);
313*7c478bd9Sstevel@tonic-gate 		input = chkopen(p, 0);
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate #ifdef ACCT
316*7c478bd9Sstevel@tonic-gate 		preacct(p);	/* reset accounting */
317*7c478bd9Sstevel@tonic-gate #endif
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate 		/*
320*7c478bd9Sstevel@tonic-gate 		 * set up new args
321*7c478bd9Sstevel@tonic-gate 		 */
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 		setargs(t);
324*7c478bd9Sstevel@tonic-gate 		longjmp(subshell, 1);
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate 	case ENOMEM:
327*7c478bd9Sstevel@tonic-gate 		failed(p, toobig);
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate 	case E2BIG:
330*7c478bd9Sstevel@tonic-gate 		failed(p, arglist);
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate 	case ETXTBSY:
333*7c478bd9Sstevel@tonic-gate 		failed(p, txtbsy);
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate 	case ELIBACC:
336*7c478bd9Sstevel@tonic-gate 		failed(p, libacc);
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate 	case ELIBBAD:
339*7c478bd9Sstevel@tonic-gate 		failed(p, libbad);
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate 	case ELIBSCN:
342*7c478bd9Sstevel@tonic-gate 		failed(p, libscn);
343*7c478bd9Sstevel@tonic-gate 
344*7c478bd9Sstevel@tonic-gate 	case ELIBMAX:
345*7c478bd9Sstevel@tonic-gate 		failed(p, libmax);
346*7c478bd9Sstevel@tonic-gate 
347*7c478bd9Sstevel@tonic-gate 	default:
348*7c478bd9Sstevel@tonic-gate 		xecmsg = (unsigned char *)badexec;
349*7c478bd9Sstevel@tonic-gate 	case ENOENT:
350*7c478bd9Sstevel@tonic-gate 		return (prefix);
351*7c478bd9Sstevel@tonic-gate 	}
352*7c478bd9Sstevel@tonic-gate }
353*7c478bd9Sstevel@tonic-gate 
354*7c478bd9Sstevel@tonic-gate BOOL		nosubst;
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate trim(at)
357*7c478bd9Sstevel@tonic-gate unsigned char	*at;
358*7c478bd9Sstevel@tonic-gate {
359*7c478bd9Sstevel@tonic-gate 	register unsigned char	*last;
360*7c478bd9Sstevel@tonic-gate 	register unsigned char 	*current;
361*7c478bd9Sstevel@tonic-gate 	register unsigned char	c;
362*7c478bd9Sstevel@tonic-gate 	int	len;
363*7c478bd9Sstevel@tonic-gate 	wchar_t	wc;
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate 	nosubst = 0;
366*7c478bd9Sstevel@tonic-gate 	if (current = at)
367*7c478bd9Sstevel@tonic-gate 	{
368*7c478bd9Sstevel@tonic-gate 		last = at;
369*7c478bd9Sstevel@tonic-gate 		while (c = *current) {
370*7c478bd9Sstevel@tonic-gate 			if ((len = mbtowc(&wc, (char *)current,
371*7c478bd9Sstevel@tonic-gate 					MB_LEN_MAX)) <= 0) {
372*7c478bd9Sstevel@tonic-gate 				*last++ = c;
373*7c478bd9Sstevel@tonic-gate 				current++;
374*7c478bd9Sstevel@tonic-gate 				continue;
375*7c478bd9Sstevel@tonic-gate 			}
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate 			if (wc != '\\') {
378*7c478bd9Sstevel@tonic-gate 				memcpy(last, current, len);
379*7c478bd9Sstevel@tonic-gate 				last += len;
380*7c478bd9Sstevel@tonic-gate 				current += len;
381*7c478bd9Sstevel@tonic-gate 				continue;
382*7c478bd9Sstevel@tonic-gate 			}
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate 			/* remove \ and quoted nulls */
385*7c478bd9Sstevel@tonic-gate 			nosubst = 1;
386*7c478bd9Sstevel@tonic-gate 			current++;
387*7c478bd9Sstevel@tonic-gate 			if (c = *current) {
388*7c478bd9Sstevel@tonic-gate 				if ((len = mbtowc(&wc, (char *)current,
389*7c478bd9Sstevel@tonic-gate 						MB_LEN_MAX)) <= 0) {
390*7c478bd9Sstevel@tonic-gate 					*last++ = c;
391*7c478bd9Sstevel@tonic-gate 					current++;
392*7c478bd9Sstevel@tonic-gate 					continue;
393*7c478bd9Sstevel@tonic-gate 				}
394*7c478bd9Sstevel@tonic-gate 				memcpy(last, current, len);
395*7c478bd9Sstevel@tonic-gate 				last += len;
396*7c478bd9Sstevel@tonic-gate 				current += len;
397*7c478bd9Sstevel@tonic-gate 			} else
398*7c478bd9Sstevel@tonic-gate 				current++;
399*7c478bd9Sstevel@tonic-gate 		}
400*7c478bd9Sstevel@tonic-gate 
401*7c478bd9Sstevel@tonic-gate 		*last = 0;
402*7c478bd9Sstevel@tonic-gate 	}
403*7c478bd9Sstevel@tonic-gate }
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate /* Same as trim, but only removes backlashes before slashes */
406*7c478bd9Sstevel@tonic-gate trims(at)
407*7c478bd9Sstevel@tonic-gate unsigned char	*at;
408*7c478bd9Sstevel@tonic-gate {
409*7c478bd9Sstevel@tonic-gate 	register unsigned char	*last;
410*7c478bd9Sstevel@tonic-gate 	register unsigned char 	*current;
411*7c478bd9Sstevel@tonic-gate 	register unsigned char	c;
412*7c478bd9Sstevel@tonic-gate 	int	len;
413*7c478bd9Sstevel@tonic-gate 	wchar_t	wc;
414*7c478bd9Sstevel@tonic-gate 
415*7c478bd9Sstevel@tonic-gate 	if (current = at)
416*7c478bd9Sstevel@tonic-gate 	{
417*7c478bd9Sstevel@tonic-gate 		last = at;
418*7c478bd9Sstevel@tonic-gate 		while (c = *current) {
419*7c478bd9Sstevel@tonic-gate 			if ((len = mbtowc(&wc, (char *)current,
420*7c478bd9Sstevel@tonic-gate 					MB_LEN_MAX)) <= 0) {
421*7c478bd9Sstevel@tonic-gate 				*last++ = c;
422*7c478bd9Sstevel@tonic-gate 				current++;
423*7c478bd9Sstevel@tonic-gate 				continue;
424*7c478bd9Sstevel@tonic-gate 			}
425*7c478bd9Sstevel@tonic-gate 
426*7c478bd9Sstevel@tonic-gate 			if (wc != '\\') {
427*7c478bd9Sstevel@tonic-gate 				memcpy(last, current, len);
428*7c478bd9Sstevel@tonic-gate 				last += len; current += len;
429*7c478bd9Sstevel@tonic-gate 				continue;
430*7c478bd9Sstevel@tonic-gate 			}
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate 			/* remove \ and quoted nulls */
433*7c478bd9Sstevel@tonic-gate 			current++;
434*7c478bd9Sstevel@tonic-gate 			if (!(c = *current)) {
435*7c478bd9Sstevel@tonic-gate 				current++;
436*7c478bd9Sstevel@tonic-gate 				continue;
437*7c478bd9Sstevel@tonic-gate 			}
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate 			if (c == '/') {
440*7c478bd9Sstevel@tonic-gate 				*last++ = c;
441*7c478bd9Sstevel@tonic-gate 				current++;
442*7c478bd9Sstevel@tonic-gate 				continue;
443*7c478bd9Sstevel@tonic-gate 			}
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate 			*last++ = '\\';
446*7c478bd9Sstevel@tonic-gate 			if ((len = mbtowc(&wc, (char *)current,
447*7c478bd9Sstevel@tonic-gate 					MB_LEN_MAX)) <= 0) {
448*7c478bd9Sstevel@tonic-gate 				*last++ = c;
449*7c478bd9Sstevel@tonic-gate 				current++;
450*7c478bd9Sstevel@tonic-gate 				continue;
451*7c478bd9Sstevel@tonic-gate 			}
452*7c478bd9Sstevel@tonic-gate 			memcpy(last, current, len);
453*7c478bd9Sstevel@tonic-gate 			last += len; current += len;
454*7c478bd9Sstevel@tonic-gate 		}
455*7c478bd9Sstevel@tonic-gate 		*last = 0;
456*7c478bd9Sstevel@tonic-gate 	}
457*7c478bd9Sstevel@tonic-gate }
458*7c478bd9Sstevel@tonic-gate 
459*7c478bd9Sstevel@tonic-gate unsigned char *
460*7c478bd9Sstevel@tonic-gate mactrim(s)
461*7c478bd9Sstevel@tonic-gate unsigned char	*s;
462*7c478bd9Sstevel@tonic-gate {
463*7c478bd9Sstevel@tonic-gate 	register unsigned char	*t = macro(s);
464*7c478bd9Sstevel@tonic-gate 
465*7c478bd9Sstevel@tonic-gate 	trim(t);
466*7c478bd9Sstevel@tonic-gate 	return (t);
467*7c478bd9Sstevel@tonic-gate }
468*7c478bd9Sstevel@tonic-gate 
469*7c478bd9Sstevel@tonic-gate unsigned char **
470*7c478bd9Sstevel@tonic-gate scan(argn)
471*7c478bd9Sstevel@tonic-gate int	argn;
472*7c478bd9Sstevel@tonic-gate {
473*7c478bd9Sstevel@tonic-gate 	register struct argnod *argp =
474*7c478bd9Sstevel@tonic-gate 			(struct argnod *)(Rcheat(gchain) & ~ARGMK);
475*7c478bd9Sstevel@tonic-gate 	register unsigned char **comargn, **comargm;
476*7c478bd9Sstevel@tonic-gate 
477*7c478bd9Sstevel@tonic-gate 	comargn = (unsigned char **)getstak(BYTESPERWORD * argn + BYTESPERWORD);
478*7c478bd9Sstevel@tonic-gate 	comargm = comargn += argn;
479*7c478bd9Sstevel@tonic-gate 	*comargn = ENDARGS;
480*7c478bd9Sstevel@tonic-gate 	while (argp)
481*7c478bd9Sstevel@tonic-gate 	{
482*7c478bd9Sstevel@tonic-gate 		*--comargn = argp->argval;
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate 		trim(*comargn);
485*7c478bd9Sstevel@tonic-gate 		argp = argp->argnxt;
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate 		if (argp == 0 || Rcheat(argp) & ARGMK)
488*7c478bd9Sstevel@tonic-gate 		{
489*7c478bd9Sstevel@tonic-gate 			gsort(comargn, comargm);
490*7c478bd9Sstevel@tonic-gate 			comargm = comargn;
491*7c478bd9Sstevel@tonic-gate 		}
492*7c478bd9Sstevel@tonic-gate 		argp = (struct argnod *)(Rcheat(argp) & ~ARGMK);
493*7c478bd9Sstevel@tonic-gate 	}
494*7c478bd9Sstevel@tonic-gate 	return (comargn);
495*7c478bd9Sstevel@tonic-gate }
496*7c478bd9Sstevel@tonic-gate 
497*7c478bd9Sstevel@tonic-gate static int
498*7c478bd9Sstevel@tonic-gate gsort(from, to)
499*7c478bd9Sstevel@tonic-gate unsigned char	*from[], *to[];
500*7c478bd9Sstevel@tonic-gate {
501*7c478bd9Sstevel@tonic-gate 	int	k, m, n;
502*7c478bd9Sstevel@tonic-gate 	register int	i, j;
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 	if ((n = to - from) <= 1)
505*7c478bd9Sstevel@tonic-gate 		return;
506*7c478bd9Sstevel@tonic-gate 	for (j = 1; j <= n; j *= 2)
507*7c478bd9Sstevel@tonic-gate 		;
508*7c478bd9Sstevel@tonic-gate 	for (m = 2 * j - 1; m /= 2; )
509*7c478bd9Sstevel@tonic-gate 	{
510*7c478bd9Sstevel@tonic-gate 		k = n - m;
511*7c478bd9Sstevel@tonic-gate 		for (j = 0; j < k; j++)
512*7c478bd9Sstevel@tonic-gate 		{
513*7c478bd9Sstevel@tonic-gate 			for (i = j; i >= 0; i -= m)
514*7c478bd9Sstevel@tonic-gate 			{
515*7c478bd9Sstevel@tonic-gate 				register unsigned char **fromi;
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate 				fromi = &from[i];
518*7c478bd9Sstevel@tonic-gate 				if (cf(fromi[m], fromi[0]) > 0)
519*7c478bd9Sstevel@tonic-gate 				{
520*7c478bd9Sstevel@tonic-gate 					break;
521*7c478bd9Sstevel@tonic-gate 				}
522*7c478bd9Sstevel@tonic-gate 				else
523*7c478bd9Sstevel@tonic-gate 				{
524*7c478bd9Sstevel@tonic-gate 					unsigned char *s;
525*7c478bd9Sstevel@tonic-gate 
526*7c478bd9Sstevel@tonic-gate 					s = fromi[m];
527*7c478bd9Sstevel@tonic-gate 					fromi[m] = fromi[0];
528*7c478bd9Sstevel@tonic-gate 					fromi[0] = s;
529*7c478bd9Sstevel@tonic-gate 				}
530*7c478bd9Sstevel@tonic-gate 			}
531*7c478bd9Sstevel@tonic-gate 		}
532*7c478bd9Sstevel@tonic-gate 	}
533*7c478bd9Sstevel@tonic-gate }
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate /*
536*7c478bd9Sstevel@tonic-gate  * Argument list generation
537*7c478bd9Sstevel@tonic-gate  */
538*7c478bd9Sstevel@tonic-gate getarg(ac)
539*7c478bd9Sstevel@tonic-gate struct comnod	*ac;
540*7c478bd9Sstevel@tonic-gate {
541*7c478bd9Sstevel@tonic-gate 	register struct argnod	*argp;
542*7c478bd9Sstevel@tonic-gate 	register int		count = 0;
543*7c478bd9Sstevel@tonic-gate 	register struct comnod	*c;
544*7c478bd9Sstevel@tonic-gate 
545*7c478bd9Sstevel@tonic-gate 	if (c = ac)
546*7c478bd9Sstevel@tonic-gate 	{
547*7c478bd9Sstevel@tonic-gate 		argp = c->comarg;
548*7c478bd9Sstevel@tonic-gate 		while (argp)
549*7c478bd9Sstevel@tonic-gate 		{
550*7c478bd9Sstevel@tonic-gate 			count += split(macro(argp->argval), 1);
551*7c478bd9Sstevel@tonic-gate 			argp = argp->argnxt;
552*7c478bd9Sstevel@tonic-gate 		}
553*7c478bd9Sstevel@tonic-gate 	}
554*7c478bd9Sstevel@tonic-gate 	return (count);
555*7c478bd9Sstevel@tonic-gate }
556*7c478bd9Sstevel@tonic-gate 
557*7c478bd9Sstevel@tonic-gate static int
558*7c478bd9Sstevel@tonic-gate split(s)		/* blank interpretation routine */
559*7c478bd9Sstevel@tonic-gate unsigned char	*s;
560*7c478bd9Sstevel@tonic-gate {
561*7c478bd9Sstevel@tonic-gate 	register unsigned char	*argp;
562*7c478bd9Sstevel@tonic-gate 	register int	c;
563*7c478bd9Sstevel@tonic-gate 	int		count = 0;
564*7c478bd9Sstevel@tonic-gate 	for (;;)
565*7c478bd9Sstevel@tonic-gate 	{
566*7c478bd9Sstevel@tonic-gate 		register int length;
567*7c478bd9Sstevel@tonic-gate 		sigchk();
568*7c478bd9Sstevel@tonic-gate 		argp = locstak() + BYTESPERWORD;
569*7c478bd9Sstevel@tonic-gate 		while (c = *s) {
570*7c478bd9Sstevel@tonic-gate 			wchar_t wc;
571*7c478bd9Sstevel@tonic-gate 			if ((length = mbtowc(&wc, (char *)s,
572*7c478bd9Sstevel@tonic-gate 					MB_LEN_MAX)) <= 0) {
573*7c478bd9Sstevel@tonic-gate 				wc = (unsigned char)*s;
574*7c478bd9Sstevel@tonic-gate 				length = 1;
575*7c478bd9Sstevel@tonic-gate 			}
576*7c478bd9Sstevel@tonic-gate 
577*7c478bd9Sstevel@tonic-gate 			if (c == '\\') { /* skip over quoted characters */
578*7c478bd9Sstevel@tonic-gate 				if (argp >= brkend)
579*7c478bd9Sstevel@tonic-gate 					growstak(argp);
580*7c478bd9Sstevel@tonic-gate 				*argp++ = c;
581*7c478bd9Sstevel@tonic-gate 				s++;
582*7c478bd9Sstevel@tonic-gate 				/* get rest of multibyte character */
583*7c478bd9Sstevel@tonic-gate 				if ((length = mbtowc(&wc, (char *)s,
584*7c478bd9Sstevel@tonic-gate 						MB_LEN_MAX)) <= 0) {
585*7c478bd9Sstevel@tonic-gate 					wc = (unsigned char)*s;
586*7c478bd9Sstevel@tonic-gate 					length = 1;
587*7c478bd9Sstevel@tonic-gate 				}
588*7c478bd9Sstevel@tonic-gate 				if (argp >= brkend)
589*7c478bd9Sstevel@tonic-gate 					growstak(argp);
590*7c478bd9Sstevel@tonic-gate 				*argp++ = *s++;
591*7c478bd9Sstevel@tonic-gate 				while (--length > 0) {
592*7c478bd9Sstevel@tonic-gate 					if (argp >= brkend)
593*7c478bd9Sstevel@tonic-gate 						growstak(argp);
594*7c478bd9Sstevel@tonic-gate 					*argp++ = *s++;
595*7c478bd9Sstevel@tonic-gate 				}
596*7c478bd9Sstevel@tonic-gate 				continue;
597*7c478bd9Sstevel@tonic-gate 			}
598*7c478bd9Sstevel@tonic-gate 
599*7c478bd9Sstevel@tonic-gate 			if (anys(s, ifsnod.namval)) {
600*7c478bd9Sstevel@tonic-gate 				/* skip to next character position */
601*7c478bd9Sstevel@tonic-gate 				s += length;
602*7c478bd9Sstevel@tonic-gate 				break;
603*7c478bd9Sstevel@tonic-gate 			}
604*7c478bd9Sstevel@tonic-gate 
605*7c478bd9Sstevel@tonic-gate 			if (argp >= brkend)
606*7c478bd9Sstevel@tonic-gate 				growstak(argp);
607*7c478bd9Sstevel@tonic-gate 			*argp++ = c;
608*7c478bd9Sstevel@tonic-gate 			s++;
609*7c478bd9Sstevel@tonic-gate 			while (--length > 0) {
610*7c478bd9Sstevel@tonic-gate 				if (argp >= brkend)
611*7c478bd9Sstevel@tonic-gate 					growstak(argp);
612*7c478bd9Sstevel@tonic-gate 				*argp++ = *s++;
613*7c478bd9Sstevel@tonic-gate 			}
614*7c478bd9Sstevel@tonic-gate 		}
615*7c478bd9Sstevel@tonic-gate 		if (argp == staktop + BYTESPERWORD)
616*7c478bd9Sstevel@tonic-gate 		{
617*7c478bd9Sstevel@tonic-gate 			if (c)
618*7c478bd9Sstevel@tonic-gate 			{
619*7c478bd9Sstevel@tonic-gate 				continue;
620*7c478bd9Sstevel@tonic-gate 			}
621*7c478bd9Sstevel@tonic-gate 			else
622*7c478bd9Sstevel@tonic-gate 			{
623*7c478bd9Sstevel@tonic-gate 				return (count);
624*7c478bd9Sstevel@tonic-gate 			}
625*7c478bd9Sstevel@tonic-gate 		}
626*7c478bd9Sstevel@tonic-gate 		/*
627*7c478bd9Sstevel@tonic-gate 		 * file name generation
628*7c478bd9Sstevel@tonic-gate 		 */
629*7c478bd9Sstevel@tonic-gate 
630*7c478bd9Sstevel@tonic-gate 		argp = endstak(argp);
631*7c478bd9Sstevel@tonic-gate 		trims(((struct argnod *)argp)->argval);
632*7c478bd9Sstevel@tonic-gate 		if ((flags & nofngflg) == 0 &&
633*7c478bd9Sstevel@tonic-gate 			(c = expand(((struct argnod *)argp)->argval, 0)))
634*7c478bd9Sstevel@tonic-gate 			count += c;
635*7c478bd9Sstevel@tonic-gate 		else
636*7c478bd9Sstevel@tonic-gate 		{
637*7c478bd9Sstevel@tonic-gate 			makearg(argp);
638*7c478bd9Sstevel@tonic-gate 			count++;
639*7c478bd9Sstevel@tonic-gate 		}
640*7c478bd9Sstevel@tonic-gate 		gchain = (struct argnod *)((int)gchain | ARGMK);
641*7c478bd9Sstevel@tonic-gate 	}
642*7c478bd9Sstevel@tonic-gate }
643*7c478bd9Sstevel@tonic-gate 
644*7c478bd9Sstevel@tonic-gate #ifdef ACCT
645*7c478bd9Sstevel@tonic-gate #include	<sys/types.h>
646*7c478bd9Sstevel@tonic-gate #include	<sys/acct.h>
647*7c478bd9Sstevel@tonic-gate #include 	<sys/times.h>
648*7c478bd9Sstevel@tonic-gate 
649*7c478bd9Sstevel@tonic-gate struct acct sabuf;
650*7c478bd9Sstevel@tonic-gate struct tms buffer;
651*7c478bd9Sstevel@tonic-gate static clock_t before;
652*7c478bd9Sstevel@tonic-gate static int shaccton;	/* 0 implies do not write record on exit */
653*7c478bd9Sstevel@tonic-gate 			/* 1 implies write acct record on exit */
654*7c478bd9Sstevel@tonic-gate 
655*7c478bd9Sstevel@tonic-gate 
656*7c478bd9Sstevel@tonic-gate /*
657*7c478bd9Sstevel@tonic-gate  *	suspend accounting until turned on by preacct()
658*7c478bd9Sstevel@tonic-gate  */
659*7c478bd9Sstevel@tonic-gate 
660*7c478bd9Sstevel@tonic-gate suspacct()
661*7c478bd9Sstevel@tonic-gate {
662*7c478bd9Sstevel@tonic-gate 	shaccton = 0;
663*7c478bd9Sstevel@tonic-gate }
664*7c478bd9Sstevel@tonic-gate 
665*7c478bd9Sstevel@tonic-gate preacct(cmdadr)
666*7c478bd9Sstevel@tonic-gate 	unsigned char *cmdadr;
667*7c478bd9Sstevel@tonic-gate {
668*7c478bd9Sstevel@tonic-gate 	unsigned char *simple();
669*7c478bd9Sstevel@tonic-gate 
670*7c478bd9Sstevel@tonic-gate 	if (acctnod.namval && *acctnod.namval)
671*7c478bd9Sstevel@tonic-gate 	{
672*7c478bd9Sstevel@tonic-gate 		sabuf.ac_btime = time((time_t *)0);
673*7c478bd9Sstevel@tonic-gate 		before = times(&buffer);
674*7c478bd9Sstevel@tonic-gate 		sabuf.ac_uid = getuid();
675*7c478bd9Sstevel@tonic-gate 		sabuf.ac_gid = getgid();
676*7c478bd9Sstevel@tonic-gate 		movstrn(simple(cmdadr), sabuf.ac_comm, sizeof (sabuf.ac_comm));
677*7c478bd9Sstevel@tonic-gate 		shaccton = 1;
678*7c478bd9Sstevel@tonic-gate 	}
679*7c478bd9Sstevel@tonic-gate }
680*7c478bd9Sstevel@tonic-gate 
681*7c478bd9Sstevel@tonic-gate 
682*7c478bd9Sstevel@tonic-gate doacct()
683*7c478bd9Sstevel@tonic-gate {
684*7c478bd9Sstevel@tonic-gate 	int fd;
685*7c478bd9Sstevel@tonic-gate 	clock_t after;
686*7c478bd9Sstevel@tonic-gate 
687*7c478bd9Sstevel@tonic-gate 	if (shaccton) {
688*7c478bd9Sstevel@tonic-gate 		after = times(&buffer);
689*7c478bd9Sstevel@tonic-gate 		sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
690*7c478bd9Sstevel@tonic-gate 		sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
691*7c478bd9Sstevel@tonic-gate 		sabuf.ac_etime = compress(after - before);
692*7c478bd9Sstevel@tonic-gate 
693*7c478bd9Sstevel@tonic-gate 		if ((fd = open((char *)acctnod.namval,
694*7c478bd9Sstevel@tonic-gate 				O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1) {
695*7c478bd9Sstevel@tonic-gate 			write(fd, &sabuf, sizeof (sabuf));
696*7c478bd9Sstevel@tonic-gate 			close(fd);
697*7c478bd9Sstevel@tonic-gate 		}
698*7c478bd9Sstevel@tonic-gate 	}
699*7c478bd9Sstevel@tonic-gate }
700*7c478bd9Sstevel@tonic-gate 
701*7c478bd9Sstevel@tonic-gate /*
702*7c478bd9Sstevel@tonic-gate  *	Produce a pseudo-floating point representation
703*7c478bd9Sstevel@tonic-gate  *	with 3 bits base-8 exponent, 13 bits fraction
704*7c478bd9Sstevel@tonic-gate  */
705*7c478bd9Sstevel@tonic-gate 
706*7c478bd9Sstevel@tonic-gate compress(t)
707*7c478bd9Sstevel@tonic-gate 	register clock_t t;
708*7c478bd9Sstevel@tonic-gate {
709*7c478bd9Sstevel@tonic-gate 	register exp = 0;
710*7c478bd9Sstevel@tonic-gate 	register rund = 0;
711*7c478bd9Sstevel@tonic-gate 
712*7c478bd9Sstevel@tonic-gate 	while (t >= 8192)
713*7c478bd9Sstevel@tonic-gate 	{
714*7c478bd9Sstevel@tonic-gate 		exp++;
715*7c478bd9Sstevel@tonic-gate 		rund = t & 04;
716*7c478bd9Sstevel@tonic-gate 		t >>= 3;
717*7c478bd9Sstevel@tonic-gate 	}
718*7c478bd9Sstevel@tonic-gate 
719*7c478bd9Sstevel@tonic-gate 	if (rund)
720*7c478bd9Sstevel@tonic-gate 	{
721*7c478bd9Sstevel@tonic-gate 		t++;
722*7c478bd9Sstevel@tonic-gate 		if (t >= 8192)
723*7c478bd9Sstevel@tonic-gate 		{
724*7c478bd9Sstevel@tonic-gate 			t >>= 3;
725*7c478bd9Sstevel@tonic-gate 			exp++;
726*7c478bd9Sstevel@tonic-gate 		}
727*7c478bd9Sstevel@tonic-gate 	}
728*7c478bd9Sstevel@tonic-gate 	return ((exp << 13) + t);
729*7c478bd9Sstevel@tonic-gate }
730*7c478bd9Sstevel@tonic-gate #endif
731