xref: /freebsd/contrib/tcsh/tc.os.c (revision 6560ac57ce879857203bc456cdc3849808dc0700)
1c80476e4SDavid E. O'Brien /*
2c80476e4SDavid E. O'Brien  * tc.os.c: OS Dependent builtin functions
3c80476e4SDavid E. O'Brien  */
4c80476e4SDavid E. O'Brien /*-
5c80476e4SDavid E. O'Brien  * Copyright (c) 1980, 1991 The Regents of the University of California.
6c80476e4SDavid E. O'Brien  * All rights reserved.
7c80476e4SDavid E. O'Brien  *
8c80476e4SDavid E. O'Brien  * Redistribution and use in source and binary forms, with or without
9c80476e4SDavid E. O'Brien  * modification, are permitted provided that the following conditions
10c80476e4SDavid E. O'Brien  * are met:
11c80476e4SDavid E. O'Brien  * 1. Redistributions of source code must retain the above copyright
12c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer.
13c80476e4SDavid E. O'Brien  * 2. Redistributions in binary form must reproduce the above copyright
14c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer in the
15c80476e4SDavid E. O'Brien  *    documentation and/or other materials provided with the distribution.
1629301572SMark Peek  * 3. Neither the name of the University nor the names of its contributors
17c80476e4SDavid E. O'Brien  *    may be used to endorse or promote products derived from this software
18c80476e4SDavid E. O'Brien  *    without specific prior written permission.
19c80476e4SDavid E. O'Brien  *
20c80476e4SDavid E. O'Brien  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21c80476e4SDavid E. O'Brien  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c80476e4SDavid E. O'Brien  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c80476e4SDavid E. O'Brien  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24c80476e4SDavid E. O'Brien  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c80476e4SDavid E. O'Brien  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c80476e4SDavid E. O'Brien  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c80476e4SDavid E. O'Brien  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c80476e4SDavid E. O'Brien  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c80476e4SDavid E. O'Brien  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c80476e4SDavid E. O'Brien  * SUCH DAMAGE.
31c80476e4SDavid E. O'Brien  */
32c80476e4SDavid E. O'Brien #include "sh.h"
33c80476e4SDavid E. O'Brien #include "tw.h"
34c80476e4SDavid E. O'Brien #include "ed.h"
35c80476e4SDavid E. O'Brien #include "ed.defns.h"		/* for the function names */
36c80476e4SDavid E. O'Brien #include "sh.decls.h"
37c80476e4SDavid E. O'Brien 
38c80476e4SDavid E. O'Brien #ifdef _UWIN
39c80476e4SDavid E. O'Brien #define TIOCGPGRP TIOCGETPGRP
40c80476e4SDavid E. O'Brien #define TIOCSPGRP TIOCSETPGRP
41c80476e4SDavid E. O'Brien #endif
42c80476e4SDavid E. O'Brien 
43c80476e4SDavid E. O'Brien /***
44c80476e4SDavid E. O'Brien  *** MACH
45c80476e4SDavid E. O'Brien  ***/
46c80476e4SDavid E. O'Brien 
47c80476e4SDavid E. O'Brien #ifdef MACH
48c80476e4SDavid E. O'Brien /* dosetpath -- setpath built-in command
49c80476e4SDavid E. O'Brien  *
50c80476e4SDavid E. O'Brien  **********************************************************************
51c80476e4SDavid E. O'Brien  * HISTORY
52c80476e4SDavid E. O'Brien  * 08-May-88  Richard Draves (rpd) at Carnegie-Mellon University
53c80476e4SDavid E. O'Brien  *	Major changes to remove artificial limits on sizes and numbers
54c80476e4SDavid E. O'Brien  *	of paths.
55c80476e4SDavid E. O'Brien  *
56c80476e4SDavid E. O'Brien  **********************************************************************
57c80476e4SDavid E. O'Brien  */
58c80476e4SDavid E. O'Brien 
59c80476e4SDavid E. O'Brien #ifdef MACH
60c80476e4SDavid E. O'Brien static Char STRCPATH[] = {'C', 'P', 'A', 'T', 'H', '\0'};
61c80476e4SDavid E. O'Brien static Char STRLPATH[] = {'L', 'P', 'A', 'T', 'H', '\0'};
62c80476e4SDavid E. O'Brien static Char STRMPATH[] = {'M', 'P', 'A', 'T', 'H', '\0'};
63c80476e4SDavid E. O'Brien # if EPATH
64c80476e4SDavid E. O'Brien static Char STREPATH[] = {'E', 'P', 'A', 'T', 'H', '\0'};
65c80476e4SDavid E. O'Brien # endif
66c80476e4SDavid E. O'Brien #endif /* MACH */
67c80476e4SDavid E. O'Brien static Char *syspaths[] = {STRKPATH, STRCPATH, STRLPATH, STRMPATH,
68c80476e4SDavid E. O'Brien 
69c80476e4SDavid E. O'Brien #if EPATH
70c80476e4SDavid E. O'Brien 	STREPATH,
71c80476e4SDavid E. O'Brien #endif
72c80476e4SDavid E. O'Brien 	 0};
73c80476e4SDavid E. O'Brien #define LOCALSYSPATH	"/usr/local"
74c80476e4SDavid E. O'Brien 
75c80476e4SDavid E. O'Brien /*ARGSUSED*/
76c80476e4SDavid E. O'Brien void
dosetpath(Char ** arglist,struct command * c)7745e5710bSMark Peek dosetpath(Char **arglist, struct command *c)
78c80476e4SDavid E. O'Brien {
79c80476e4SDavid E. O'Brien     extern char *getenv();
80c80476e4SDavid E. O'Brien     Char  **pathvars, **cmdargs;
81c80476e4SDavid E. O'Brien     char  **spaths, **cpaths, **cmds;
82c80476e4SDavid E. O'Brien     char   *tcp;
83c80476e4SDavid E. O'Brien     unsigned int npaths, ncmds;
84c80476e4SDavid E. O'Brien     int     i, sysflag;
85c80476e4SDavid E. O'Brien 
8645e5710bSMark Peek     pintr_disabled++;
8745e5710bSMark Peek     cleanup_push(&pintr_disabled, disabled_cleanup);
88c80476e4SDavid E. O'Brien 
89c80476e4SDavid E. O'Brien     /*
90c80476e4SDavid E. O'Brien      * setpath(3) uses stdio and we want 0, 1, 2 to work...
91c80476e4SDavid E. O'Brien      */
92c80476e4SDavid E. O'Brien     if (!didfds) {
93c80476e4SDavid E. O'Brien 	(void) dcopy(SHIN, 0);
94c80476e4SDavid E. O'Brien 	(void) dcopy(SHOUT, 1);
95c80476e4SDavid E. O'Brien 	(void) dcopy(SHDIAG, 2);
96c80476e4SDavid E. O'Brien 	didfds = 1;
97c80476e4SDavid E. O'Brien     }
98c80476e4SDavid E. O'Brien 
99c80476e4SDavid E. O'Brien     for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++);
100c80476e4SDavid E. O'Brien     npaths = i - 1;
101c80476e4SDavid E. O'Brien 
102c80476e4SDavid E. O'Brien     cmdargs = &arglist[i];
103c80476e4SDavid E. O'Brien     for (; arglist[i]; i++);
104c80476e4SDavid E. O'Brien     ncmds = i - npaths - 1;
105c80476e4SDavid E. O'Brien 
106c80476e4SDavid E. O'Brien     if (npaths) {
107c80476e4SDavid E. O'Brien 	sysflag = 0;
108c80476e4SDavid E. O'Brien 	pathvars = &arglist[1];
109c80476e4SDavid E. O'Brien     }
110c80476e4SDavid E. O'Brien     else {
111c80476e4SDavid E. O'Brien 	sysflag = 1;
112c80476e4SDavid E. O'Brien 	npaths = (sizeof syspaths / sizeof *syspaths) - 1;
113c80476e4SDavid E. O'Brien 	pathvars = syspaths;
114c80476e4SDavid E. O'Brien     }
115c80476e4SDavid E. O'Brien 
116c80476e4SDavid E. O'Brien     /* note that npaths != 0 */
117c80476e4SDavid E. O'Brien 
11845e5710bSMark Peek     spaths = xmalloc(npaths * sizeof *spaths);
11945e5710bSMark Peek     setzero(spaths, npaths * sizeof *spaths);
12045e5710bSMark Peek     cpaths = xmalloc((npaths + 1) * sizeof *cpaths);
12145e5710bSMark Peek     setzero(cpaths, (npaths + 1) * sizeof *cpaths);
12245e5710bSMark Peek     cmds = xmalloc((ncmds + 1) * sizeof *cmds);
12345e5710bSMark Peek     setzero(cmds, (ncmds + 1) * sizeof *cmds);
124c80476e4SDavid E. O'Brien     for (i = 0; i < npaths; i++) {
125c80476e4SDavid E. O'Brien 	char   *val = getenv(short2str(pathvars[i]));
126c80476e4SDavid E. O'Brien 
127c80476e4SDavid E. O'Brien 	if (val == NULL)
128c80476e4SDavid E. O'Brien 	    val = "";
129c80476e4SDavid E. O'Brien 
13045e5710bSMark Peek 	spaths[i] = xmalloc((Strlen(pathvars[i]) + strlen(val) + 2) *
13145e5710bSMark Peek 			    sizeof **spaths);
132c80476e4SDavid E. O'Brien 	(void) strcpy(spaths[i], short2str(pathvars[i]));
133c80476e4SDavid E. O'Brien 	(void) strcat(spaths[i], "=");
134c80476e4SDavid E. O'Brien 	(void) strcat(spaths[i], val);
135c80476e4SDavid E. O'Brien 	cpaths[i] = spaths[i];
136c80476e4SDavid E. O'Brien     }
137c80476e4SDavid E. O'Brien 
138c80476e4SDavid E. O'Brien     for (i = 0; i < ncmds; i++) {
13945e5710bSMark Peek 	Char   *val = globone(cmdargs[i], G_ERROR);/*FIXRESET*/
140c80476e4SDavid E. O'Brien 
141c80476e4SDavid E. O'Brien 	if (val == NULL)
142c80476e4SDavid E. O'Brien 	    goto abortpath;
14345e5710bSMark Peek 	cmds[i] = strsave(short2str(val));
144c80476e4SDavid E. O'Brien     }
145c80476e4SDavid E. O'Brien 
146c80476e4SDavid E. O'Brien 
147c80476e4SDavid E. O'Brien     if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) {
148c80476e4SDavid E. O'Brien abortpath:
149c80476e4SDavid E. O'Brien 	if (spaths) {
150c80476e4SDavid E. O'Brien 	    for (i = 0; i < npaths; i++)
15145e5710bSMark Peek 		xfree(spaths[i]);
15245e5710bSMark Peek 	    xfree(spaths);
153c80476e4SDavid E. O'Brien 	}
15445e5710bSMark Peek 	xfree(cpaths);
155c80476e4SDavid E. O'Brien 	if (cmds) {
156c80476e4SDavid E. O'Brien 	    for (i = 0; i < ncmds; i++)
15745e5710bSMark Peek 		xfree(cmds[i]);
15845e5710bSMark Peek 	    xfree(cmds);
159c80476e4SDavid E. O'Brien 	}
160c80476e4SDavid E. O'Brien 
16145e5710bSMark Peek 	cleanup_until(&pintr_disabled);
162c80476e4SDavid E. O'Brien 	donefds();
163c80476e4SDavid E. O'Brien 	return;
164c80476e4SDavid E. O'Brien     }
165c80476e4SDavid E. O'Brien 
166c80476e4SDavid E. O'Brien     for (i = 0; i < npaths; i++) {
167c80476e4SDavid E. O'Brien 	Char	*val, *name;
168c80476e4SDavid E. O'Brien 
169c80476e4SDavid E. O'Brien 	name = str2short(cpaths[i]);
170c80476e4SDavid E. O'Brien 	for (val = str2short(cpaths[i]); val && *val && *val != '='; val++);
171c80476e4SDavid E. O'Brien 	if (val && *val == '=') {
172c80476e4SDavid E. O'Brien 	    *val++ = '\0';
173c80476e4SDavid E. O'Brien 
17445e5710bSMark Peek 	    tsetenv(name, val);/*FIXRESET*/
175c80476e4SDavid E. O'Brien 	    if (Strcmp(name, STRKPATH) == 0) {
17645e5710bSMark Peek 		importpath(val);/*FIXRESET*/
177c80476e4SDavid E. O'Brien 		if (havhash)
17845e5710bSMark Peek 		    dohash(NULL, NULL);/*FIXRESET*/
179c80476e4SDavid E. O'Brien 	    }
180c80476e4SDavid E. O'Brien 	    *--val = '=';
181c80476e4SDavid E. O'Brien 	}
182c80476e4SDavid E. O'Brien     }
18345e5710bSMark Peek     cleanup_until(&pintr_disabled);
184c80476e4SDavid E. O'Brien     donefds();
185c80476e4SDavid E. O'Brien }
186c80476e4SDavid E. O'Brien #endif /* MACH */
187c80476e4SDavid E. O'Brien 
188c80476e4SDavid E. O'Brien /***
189c80476e4SDavid E. O'Brien  *** AIX
190c80476e4SDavid E. O'Brien  ***/
191c80476e4SDavid E. O'Brien #ifdef TCF
192c80476e4SDavid E. O'Brien /* ARGSUSED */
193c80476e4SDavid E. O'Brien void
dogetxvers(Char ** v,struct command * c)19445e5710bSMark Peek dogetxvers(Char **v, struct command *c)
195c80476e4SDavid E. O'Brien {
196c80476e4SDavid E. O'Brien     char    xvers[MAXPATHLEN];
197c80476e4SDavid E. O'Brien 
198c80476e4SDavid E. O'Brien     if (getxvers(xvers, MAXPATHLEN) == -1)
199c80476e4SDavid E. O'Brien 	stderror(ERR_SYSTEM, "getxvers", strerror(errno));
200c80476e4SDavid E. O'Brien     xprintf("%s\n", xvers);
201c80476e4SDavid E. O'Brien     flush();
202c80476e4SDavid E. O'Brien }
203c80476e4SDavid E. O'Brien 
204c80476e4SDavid E. O'Brien /*ARGSUSED*/
205c80476e4SDavid E. O'Brien void
dosetxvers(Char ** v,struct command * c)20645e5710bSMark Peek dosetxvers(Char **v, struct command *c)
207c80476e4SDavid E. O'Brien {
208c80476e4SDavid E. O'Brien     char   *xvers;
209c80476e4SDavid E. O'Brien 
210c80476e4SDavid E. O'Brien     ++v;
211c80476e4SDavid E. O'Brien     if (!*v || *v[0] == '\0')
212c80476e4SDavid E. O'Brien 	xvers = "";
213c80476e4SDavid E. O'Brien     else
214c80476e4SDavid E. O'Brien 	xvers = short2str(*v);
215c80476e4SDavid E. O'Brien     if (setxvers(xvers) == -1)
216c80476e4SDavid E. O'Brien 	stderror(ERR_SYSTEM, "setxvers", strerror(errno));
217c80476e4SDavid E. O'Brien }
218c80476e4SDavid E. O'Brien 
219c80476e4SDavid E. O'Brien #include <sf.h>
220c80476e4SDavid E. O'Brien #ifdef _AIXPS2
221c80476e4SDavid E. O'Brien # define XC_PDP11	0x01
222c80476e4SDavid E. O'Brien # define XC_23		0x02
223c80476e4SDavid E. O'Brien # define XC_Z8K		0x03
224c80476e4SDavid E. O'Brien # define XC_8086	0x04
225c80476e4SDavid E. O'Brien # define XC_68K		0x05
226c80476e4SDavid E. O'Brien # define XC_Z80		0x06
227c80476e4SDavid E. O'Brien # define XC_VAX		0x07
228c80476e4SDavid E. O'Brien # define XC_16032	0x08
229c80476e4SDavid E. O'Brien # define XC_286		0x09
230c80476e4SDavid E. O'Brien # define XC_386		0x0a
231c80476e4SDavid E. O'Brien # define XC_S370	0x0b
232c80476e4SDavid E. O'Brien #else
233c80476e4SDavid E. O'Brien # include <sys/x.out.h>
234c80476e4SDavid E. O'Brien #endif /* _AIXPS2 */
235c80476e4SDavid E. O'Brien 
236c80476e4SDavid E. O'Brien static struct xc_cpu_t {
237c80476e4SDavid E. O'Brien     short   xc_id;
238c80476e4SDavid E. O'Brien     char   *xc_name;
239c80476e4SDavid E. O'Brien }       xcpu[] =
240c80476e4SDavid E. O'Brien {
241c80476e4SDavid E. O'Brien     { XC_PDP11,	"pdp11"   },
242c80476e4SDavid E. O'Brien     { XC_23,	"i370"    },
243c80476e4SDavid E. O'Brien     { XC_Z8K,	"z8000"   },
244c80476e4SDavid E. O'Brien     { XC_8086,	"i86"	  },
245c80476e4SDavid E. O'Brien     { XC_68K,	"mc68000" },
246c80476e4SDavid E. O'Brien     { XC_Z80,	"x80"	  },
247c80476e4SDavid E. O'Brien     { XC_VAX,	"vax"	  },
248c80476e4SDavid E. O'Brien     { XC_16032,	"ns16032" },
249c80476e4SDavid E. O'Brien     { XC_286,	"i286"	  },
250c80476e4SDavid E. O'Brien     { XC_386,	"i386"	  },
251c80476e4SDavid E. O'Brien     { XC_S370,	"xa370"	  },
252c80476e4SDavid E. O'Brien     { 0,	NULL      }
253c80476e4SDavid E. O'Brien };
254c80476e4SDavid E. O'Brien 
255c80476e4SDavid E. O'Brien /*
256c80476e4SDavid E. O'Brien  * our local hack table, stolen from x.out.h
257c80476e4SDavid E. O'Brien  */
258c80476e4SDavid E. O'Brien static char *
getxcode(short xcid)25945e5710bSMark Peek getxcode(short xcid)
260c80476e4SDavid E. O'Brien {
261c80476e4SDavid E. O'Brien     int     i;
262c80476e4SDavid E. O'Brien 
263c80476e4SDavid E. O'Brien     for (i = 0; xcpu[i].xc_name != NULL; i++)
264c80476e4SDavid E. O'Brien 	if (xcpu[i].xc_id == xcid)
265c80476e4SDavid E. O'Brien 	    return (xcpu[i].xc_name);
266c80476e4SDavid E. O'Brien     return (NULL);
267c80476e4SDavid E. O'Brien }
268c80476e4SDavid E. O'Brien 
269c80476e4SDavid E. O'Brien static short
getxid(char * xcname)27045e5710bSMark Peek getxid(char *xcname)
271c80476e4SDavid E. O'Brien {
272c80476e4SDavid E. O'Brien     int     i;
273c80476e4SDavid E. O'Brien 
274c80476e4SDavid E. O'Brien     for (i = 0; xcpu[i].xc_name != NULL; i++)
275c80476e4SDavid E. O'Brien 	if (strcmp(xcpu[i].xc_name, xcname) == 0)
276c80476e4SDavid E. O'Brien 	    return (xcpu[i].xc_id);
277c80476e4SDavid E. O'Brien     return ((short) -1);
278c80476e4SDavid E. O'Brien }
279c80476e4SDavid E. O'Brien 
280c80476e4SDavid E. O'Brien 
281c80476e4SDavid E. O'Brien /*ARGSUSED*/
282c80476e4SDavid E. O'Brien void
dogetspath(Char ** v,struct command * c)28345e5710bSMark Peek dogetspath(Char **v, struct command *c)
284c80476e4SDavid E. O'Brien {
285c80476e4SDavid E. O'Brien     int     i, j;
286c80476e4SDavid E. O'Brien     sitepath_t p[MAXSITE];
287c80476e4SDavid E. O'Brien     struct sf *st;
288c80476e4SDavid E. O'Brien     static char *local = "LOCAL ";
289c80476e4SDavid E. O'Brien 
290c80476e4SDavid E. O'Brien     if ((j = getspath(p, MAXSITE)) == -1)
291c80476e4SDavid E. O'Brien 	stderror(ERR_SYSTEM, "getspath", strerror(errno));
292c80476e4SDavid E. O'Brien     for (i = 0; i < j && (p[i] & SPATH_CPU) != NOSITE; i++) {
293c80476e4SDavid E. O'Brien 	if (p[i] & SPATH_CPU) {
294c80476e4SDavid E. O'Brien 	    if ((p[i] & SPATH_MASK) == NULLSITE)
295c80476e4SDavid E. O'Brien 		xprintf(local);
296c80476e4SDavid E. O'Brien 	    else if ((st = sfxcode((short) (p[i] & SPATH_MASK))) != NULL)
297c80476e4SDavid E. O'Brien 		xprintf("%s ", st->sf_ctype);
298c80476e4SDavid E. O'Brien 	    else {
299c80476e4SDavid E. O'Brien 		char   *xc = getxcode(p[i] & SPATH_MASK);
300c80476e4SDavid E. O'Brien 
301c80476e4SDavid E. O'Brien 		if (xc != NULL)
302c80476e4SDavid E. O'Brien 		    xprintf("%s ", xc);
303c80476e4SDavid E. O'Brien 		else
304c80476e4SDavid E. O'Brien 		    xprintf("*cpu %d* ", (int) (p[i] & SPATH_MASK));
305c80476e4SDavid E. O'Brien 		/*
306c80476e4SDavid E. O'Brien 		 * BUG in the aix code... needs that cause if
307c80476e4SDavid E. O'Brien 		 * sfxcode fails once it fails for ever
308c80476e4SDavid E. O'Brien 		 */
309c80476e4SDavid E. O'Brien 		endsf();
310c80476e4SDavid E. O'Brien 	    }
311c80476e4SDavid E. O'Brien 	}
312c80476e4SDavid E. O'Brien 	else {
313c80476e4SDavid E. O'Brien 	    if (p[i] == NULLSITE)
314c80476e4SDavid E. O'Brien 		xprintf(local);
315c80476e4SDavid E. O'Brien 	    else if ((st = sfnum(p[i])) != NULL)
316c80476e4SDavid E. O'Brien 		xprintf("%s ", st->sf_sname);
317c80476e4SDavid E. O'Brien 	    else
318c80476e4SDavid E. O'Brien 		xprintf("*site %d* ", (int) (p[i] & SPATH_MASK));
319c80476e4SDavid E. O'Brien 	}
320c80476e4SDavid E. O'Brien     }
321c80476e4SDavid E. O'Brien     xputchar('\n');
322c80476e4SDavid E. O'Brien     flush();
323c80476e4SDavid E. O'Brien }
324c80476e4SDavid E. O'Brien 
325c80476e4SDavid E. O'Brien /*ARGSUSED*/
326c80476e4SDavid E. O'Brien void
dosetspath(Char ** v,struct command * c)32745e5710bSMark Peek dosetspath(Char **v, struct command *c)
328c80476e4SDavid E. O'Brien {
329c80476e4SDavid E. O'Brien     int     i;
330c80476e4SDavid E. O'Brien     short   j;
331c80476e4SDavid E. O'Brien     char   *s;
332c80476e4SDavid E. O'Brien     sitepath_t p[MAXSITE];
333c80476e4SDavid E. O'Brien     struct sf *st;
334c80476e4SDavid E. O'Brien 
335c80476e4SDavid E. O'Brien     /*
336c80476e4SDavid E. O'Brien      * sfname() on AIX G9.9 at least, mallocs too pointers p, q
337c80476e4SDavid E. O'Brien      * then does the equivalent of while (*p++ == *q++) continue;
338c80476e4SDavid E. O'Brien      * and then tries to free(p,q) them! Congrats to the wizard who
339c80476e4SDavid E. O'Brien      * wrote that one. I bet he tested it really well too.
340c80476e4SDavid E. O'Brien      * Sooo, we set dont_free :-)
341c80476e4SDavid E. O'Brien      */
342c80476e4SDavid E. O'Brien     dont_free = 1;
343c80476e4SDavid E. O'Brien     for (i = 0, v++; *v && *v[0] != '\0'; v++, i++) {
344c80476e4SDavid E. O'Brien 	s = short2str(*v);
34523338178SMark Peek 	if (isdigit(*s))
346c80476e4SDavid E. O'Brien 	    p[i] = atoi(s);
347c80476e4SDavid E. O'Brien 	else if (strcmp(s, "LOCAL") == 0)
348c80476e4SDavid E. O'Brien 	    p[i] = NULLSITE;
349c80476e4SDavid E. O'Brien 	else if ((st = sfctype(s)) != NULL)
350c80476e4SDavid E. O'Brien 	    p[i] = SPATH_CPU | st->sf_ccode;
351c80476e4SDavid E. O'Brien 	else if ((j = getxid(s)) != -1)
352c80476e4SDavid E. O'Brien 	    p[i] = SPATH_CPU | j;
353c80476e4SDavid E. O'Brien 	else if ((st = sfname(s)) != NULL)
354c80476e4SDavid E. O'Brien 	    p[i] = st->sf_id;
355c80476e4SDavid E. O'Brien 	else {
356c80476e4SDavid E. O'Brien 	    setname(s);
357c80476e4SDavid E. O'Brien 	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 1, "Bad cpu/site name"));
358c80476e4SDavid E. O'Brien 	}
359c80476e4SDavid E. O'Brien 	if (i == MAXSITE - 1)
360c80476e4SDavid E. O'Brien 	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 2, "Site path too long"));
361c80476e4SDavid E. O'Brien     }
362c80476e4SDavid E. O'Brien     if (setspath(p, i) == -1)
363c80476e4SDavid E. O'Brien 	stderror(ERR_SYSTEM, "setspath", strerror(errno));
364c80476e4SDavid E. O'Brien     dont_free = 0;
365c80476e4SDavid E. O'Brien }
366c80476e4SDavid E. O'Brien 
367c80476e4SDavid E. O'Brien /* sitename():
368c80476e4SDavid E. O'Brien  *	Return the site name where the process is running
369c80476e4SDavid E. O'Brien  */
370c80476e4SDavid E. O'Brien char   *
sitename(pid_t pid)37145e5710bSMark Peek sitename(pid_t pid)
372c80476e4SDavid E. O'Brien {
373c80476e4SDavid E. O'Brien     siteno_t ss;
374c80476e4SDavid E. O'Brien     struct sf *st;
375c80476e4SDavid E. O'Brien 
376c80476e4SDavid E. O'Brien     if ((ss = site(pid)) == -1 || (st = sfnum(ss)) == NULL)
377c80476e4SDavid E. O'Brien 	return CGETS(23, 3, "unknown");
378c80476e4SDavid E. O'Brien     else
379c80476e4SDavid E. O'Brien 	return st->sf_sname;
380c80476e4SDavid E. O'Brien }
381c80476e4SDavid E. O'Brien 
382c80476e4SDavid E. O'Brien static int
migratepid(pit_t pid,siteno_t new_site)38345e5710bSMark Peek migratepid(pit_t pid, siteno_t new_site)
384c80476e4SDavid E. O'Brien {
385c80476e4SDavid E. O'Brien     struct sf *st;
386c80476e4SDavid E. O'Brien     int     need_local;
387c80476e4SDavid E. O'Brien 
388c80476e4SDavid E. O'Brien     need_local = (pid == 0) || (pid == getpid());
389c80476e4SDavid E. O'Brien 
39045e5710bSMark Peek     if (kill3(pid, SIGMIGRATE, new_site) < 0) {
391c80476e4SDavid E. O'Brien 	xprintf("%d: %s\n", pid, strerror(errno));
392c80476e4SDavid E. O'Brien 	return (-1);
393c80476e4SDavid E. O'Brien     }
394c80476e4SDavid E. O'Brien 
395c80476e4SDavid E. O'Brien     if (need_local) {
396c80476e4SDavid E. O'Brien 	if ((new_site = site(0)) == -1) {
397c80476e4SDavid E. O'Brien 	    xprintf(CGETS(23, 4, "site: %s\n"), strerror(errno));
398c80476e4SDavid E. O'Brien 	    return (-1);
399c80476e4SDavid E. O'Brien 	}
400c80476e4SDavid E. O'Brien 	if ((st = sfnum(new_site)) == NULL) {
401c80476e4SDavid E. O'Brien 	    xprintf(CGETS(23, 5, "%d: Site not found\n"), new_site);
402c80476e4SDavid E. O'Brien 	    return (-1);
403c80476e4SDavid E. O'Brien 	}
404c80476e4SDavid E. O'Brien 	if (setlocal(st->sf_local, strlen(st->sf_local)) == -1) {
405c80476e4SDavid E. O'Brien 	    xprintf(CGETS(23, 6, "setlocal: %s: %s\n"),
406c80476e4SDavid E. O'Brien 			  st->sf_local, strerror(errno));
407c80476e4SDavid E. O'Brien 	    return (-1);
408c80476e4SDavid E. O'Brien 	}
409c80476e4SDavid E. O'Brien     }
410c80476e4SDavid E. O'Brien     return (0);
411c80476e4SDavid E. O'Brien }
412c80476e4SDavid E. O'Brien 
413c80476e4SDavid E. O'Brien /*ARGSUSED*/
414c80476e4SDavid E. O'Brien void
domigrate(Char ** v,struct command * c)41545e5710bSMark Peek domigrate(Char **v, struct command *c)
416c80476e4SDavid E. O'Brien {
417c80476e4SDavid E. O'Brien     struct sf *st;
418c80476e4SDavid E. O'Brien     char   *s;
419c80476e4SDavid E. O'Brien     Char   *cp;
420c80476e4SDavid E. O'Brien     struct process *pp;
421c80476e4SDavid E. O'Brien     int    err1 = 0;
422c80476e4SDavid E. O'Brien     int    pid = 0;
423c80476e4SDavid E. O'Brien     siteno_t new_site = 0;
424c80476e4SDavid E. O'Brien 
42545e5710bSMark Peek     pchild_disabled++;
42645e5710bSMark Peek     cleanup_push(&pchild_disabled, disabled_cleanup);
42745e5710bSMark Peek     if (setintr) {
42845e5710bSMark Peek 	pintr_disabled++;
42945e5710bSMark Peek 	cleanup_push(&pintr_disabled, disabled_cleanup);
43045e5710bSMark Peek     }
431c80476e4SDavid E. O'Brien 
432c80476e4SDavid E. O'Brien     ++v;
433c80476e4SDavid E. O'Brien     if (*v[0] == '-') {
434c80476e4SDavid E. O'Brien 	/*
435c80476e4SDavid E. O'Brien 	 * Do the -site.
436c80476e4SDavid E. O'Brien 	 */
437c80476e4SDavid E. O'Brien 	s = short2str(&v[0][1]);
438c80476e4SDavid E. O'Brien 	/*
439c80476e4SDavid E. O'Brien 	 * see comment in setspath()
440c80476e4SDavid E. O'Brien 	 */
441c80476e4SDavid E. O'Brien 	dont_free = 1;
442c80476e4SDavid E. O'Brien 	if ((st = sfname(s)) == NULL) {
44345e5710bSMark Peek 	    dont_free = 0;
444c80476e4SDavid E. O'Brien 	    setname(s);
445c80476e4SDavid E. O'Brien 	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 7, "Site not found"));
446c80476e4SDavid E. O'Brien 	}
447c80476e4SDavid E. O'Brien 	dont_free = 0;
448c80476e4SDavid E. O'Brien 	new_site = st->sf_id;
449c80476e4SDavid E. O'Brien 	++v;
450c80476e4SDavid E. O'Brien     }
451c80476e4SDavid E. O'Brien 
452c80476e4SDavid E. O'Brien     if (!*v || *v[0] == '\0') {
453c80476e4SDavid E. O'Brien 	if (migratepid(0, new_site) == -1)
454c80476e4SDavid E. O'Brien 	    err1++;
455c80476e4SDavid E. O'Brien     }
456c80476e4SDavid E. O'Brien     else {
45745e5710bSMark Peek 	Char **globbed;
45845e5710bSMark Peek 
45945e5710bSMark Peek 	v = glob_all_or_error(v);
46045e5710bSMark Peek 	globbed = v;
46145e5710bSMark Peek 	cleanup_push(globbed, blk_cleanup);
462c80476e4SDavid E. O'Brien 
463c80476e4SDavid E. O'Brien 	while (v && (cp = *v)) {
464c80476e4SDavid E. O'Brien 	    if (*cp == '%') {
465c80476e4SDavid E. O'Brien 		pp = pfind(cp);
46645e5710bSMark Peek 		if (kill3(- pp->p_jobid, SIGMIGRATE, new_site) < 0) {
467c80476e4SDavid E. O'Brien 		    xprintf("%S: %s\n", cp, strerror(errno));
468c80476e4SDavid E. O'Brien 		    err1++;
469c80476e4SDavid E. O'Brien 		}
470c80476e4SDavid E. O'Brien 	    }
471c80476e4SDavid E. O'Brien 	    else if (!(Isdigit(*cp) || *cp == '-'))
472c80476e4SDavid E. O'Brien 		stderror(ERR_NAME | ERR_JOBARGS);
473c80476e4SDavid E. O'Brien 	    else {
474c80476e4SDavid E. O'Brien 		pid = atoi(short2str(cp));
475c80476e4SDavid E. O'Brien 		if (migratepid(pid, new_site) == -1)
476c80476e4SDavid E. O'Brien 		    err1++;
477c80476e4SDavid E. O'Brien 	    }
478c80476e4SDavid E. O'Brien 	    v++;
479c80476e4SDavid E. O'Brien 	}
48045e5710bSMark Peek 	cleanup_until(globbed);
481c80476e4SDavid E. O'Brien     }
482c80476e4SDavid E. O'Brien 
483c80476e4SDavid E. O'Brien done:
48445e5710bSMark Peek     cleanup_until(&pchild_disabled);
485c80476e4SDavid E. O'Brien     if (err1)
486c80476e4SDavid E. O'Brien 	stderror(ERR_SILENT);
487c80476e4SDavid E. O'Brien }
488c80476e4SDavid E. O'Brien 
489c80476e4SDavid E. O'Brien #endif /* TCF */
490c80476e4SDavid E. O'Brien 
491c80476e4SDavid E. O'Brien /***
492c80476e4SDavid E. O'Brien  *** CRAY ddmode <velo@sesun3.epfl.ch> (Martin Ouwehand EPFL-SIC/SE)
493c80476e4SDavid E. O'Brien  ***/
494c80476e4SDavid E. O'Brien #if defined(_CRAY) && !defined(_CRAYMPP)
495c80476e4SDavid E. O'Brien void
dodmmode(Char ** v,struct command * c)49645e5710bSMark Peek dodmmode(Char **v, struct command *c)
497c80476e4SDavid E. O'Brien {
498c80476e4SDavid E. O'Brien     Char *cp = v[1];
499c80476e4SDavid E. O'Brien 
500c80476e4SDavid E. O'Brien     USE(c);
501c80476e4SDavid E. O'Brien 
502c80476e4SDavid E. O'Brien     if ( !cp ) {
503c80476e4SDavid E. O'Brien 	int mode;
504c80476e4SDavid E. O'Brien 
505c80476e4SDavid E. O'Brien 	mode = dmmode(0);
506c80476e4SDavid E. O'Brien 	dmmode(mode);
507c80476e4SDavid E. O'Brien 	xprintf("%d\n",mode);
508c80476e4SDavid E. O'Brien     }
509c80476e4SDavid E. O'Brien     else {
510c80476e4SDavid E. O'Brien 	if (cp[1] != '\0')
511c80476e4SDavid E. O'Brien 	    stderror(ERR_NAME | ERR_STRING,
512c80476e4SDavid E. O'Brien 		     CGETS(23, 30, "Too many arguments"));
513c80476e4SDavid E. O'Brien 	else
514c80476e4SDavid E. O'Brien 	    switch(*cp) {
515c80476e4SDavid E. O'Brien 	    case '0':
516c80476e4SDavid E. O'Brien 		dmmode(0);
517c80476e4SDavid E. O'Brien 		break;
518c80476e4SDavid E. O'Brien 	    case '1':
519c80476e4SDavid E. O'Brien 		dmmode(1);
520c80476e4SDavid E. O'Brien 		break;
521c80476e4SDavid E. O'Brien 	    default:
522c80476e4SDavid E. O'Brien 		stderror(ERR_NAME | ERR_STRING,
523c80476e4SDavid E. O'Brien 			 CGETS(23, 31, "Invalid argument"));
524c80476e4SDavid E. O'Brien 	    }
525c80476e4SDavid E. O'Brien     }
526c80476e4SDavid E. O'Brien }
527c80476e4SDavid E. O'Brien #endif /* _CRAY && !_CRAYMPP */
528c80476e4SDavid E. O'Brien 
529c80476e4SDavid E. O'Brien 
530c80476e4SDavid E. O'Brien /***
531c80476e4SDavid E. O'Brien  *** CONVEX Warps.
532c80476e4SDavid E. O'Brien  ***/
533c80476e4SDavid E. O'Brien 
534c80476e4SDavid E. O'Brien #ifdef WARP
535c80476e4SDavid E. O'Brien /*
536c80476e4SDavid E. O'Brien  * handle the funky warping of symlinks
537c80476e4SDavid E. O'Brien  */
538c80476e4SDavid E. O'Brien #include <warpdb.h>
539c80476e4SDavid E. O'Brien #include <sys/warp.h>
540c80476e4SDavid E. O'Brien 
541c80476e4SDavid E. O'Brien static jmp_buf sigsys_buf;
542c80476e4SDavid E. O'Brien 
54345e5710bSMark Peek static void
catch_sigsys(void)54445e5710bSMark Peek catch_sigsys(void)
545c80476e4SDavid E. O'Brien {
54645e5710bSMark Peek     sigset_t set;
54745e5710bSMark Peek     sigemptyset(&set, SIGSYS);
54845e5710bSMark Peek     (void)sigprocmask(SIG_UNBLOCK, &set, NULL);
549c80476e4SDavid E. O'Brien     longjmp(sigsys_buf, 1);
550c80476e4SDavid E. O'Brien }
551c80476e4SDavid E. O'Brien 
552c80476e4SDavid E. O'Brien 
553c80476e4SDavid E. O'Brien /*ARGSUSED*/
554c80476e4SDavid E. O'Brien void
dowarp(Char ** v,struct command * c)55545e5710bSMark Peek dowarp(Char **v, struct command *c)
556c80476e4SDavid E. O'Brien {
557c80476e4SDavid E. O'Brien     int     warp, oldwarp;
558c80476e4SDavid E. O'Brien     struct warpent *we;
55945e5710bSMark Peek     volatile struct sigaction old_sigsys_handler;
560c80476e4SDavid E. O'Brien     char   *newwarp;
561c80476e4SDavid E. O'Brien 
562c80476e4SDavid E. O'Brien     if (setjmp(sigsys_buf)) {
56345e5710bSMark Peek 	sigaction(SIGSYS, &old_sigsys_handler, NULL);
564c80476e4SDavid E. O'Brien 	stderror(ERR_NAME | ERR_STRING,
565c80476e4SDavid E. O'Brien 		 CGETS(23, 8, "You're trapped in a universe you never made"));
566c80476e4SDavid E. O'Brien 	return;
567c80476e4SDavid E. O'Brien     }
56845e5710bSMark Peek     sigaction(SIGSYS, NULL, &old_sigsys_handler);
56945e5710bSMark Peek     signal(SIGSYS, catch_sigsys);
570c80476e4SDavid E. O'Brien 
571c80476e4SDavid E. O'Brien     warp = getwarp();
572c80476e4SDavid E. O'Brien 
573c80476e4SDavid E. O'Brien     v++;
574c80476e4SDavid E. O'Brien     if (*v == 0) {		/* display warp value */
575c80476e4SDavid E. O'Brien 	if (warp < 0)
576c80476e4SDavid E. O'Brien 	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 9, "Getwarp failed"));
577c80476e4SDavid E. O'Brien 	we = getwarpbyvalue(warp);
578c80476e4SDavid E. O'Brien 	if (we)
579c80476e4SDavid E. O'Brien 	    printf("%s\n", we->w_name);
580c80476e4SDavid E. O'Brien 	else
581c80476e4SDavid E. O'Brien 	    printf("%d\n", warp);
582c80476e4SDavid E. O'Brien     }
583c80476e4SDavid E. O'Brien     else {			/* set warp value */
584c80476e4SDavid E. O'Brien 	oldwarp = warp;
585c80476e4SDavid E. O'Brien 	newwarp = short2str(*v);
586c80476e4SDavid E. O'Brien 	if (Isdigit(*v[0]))
587c80476e4SDavid E. O'Brien 	    warp = atoi(newwarp);
588c80476e4SDavid E. O'Brien 	else {
589c80476e4SDavid E. O'Brien 	    we = getwarpbyname(newwarp);
590c80476e4SDavid E. O'Brien 	    if (we)
591c80476e4SDavid E. O'Brien 		warp = we->w_value;
592c80476e4SDavid E. O'Brien 	    else
593c80476e4SDavid E. O'Brien 		warp = -1;
594c80476e4SDavid E. O'Brien 	}
595c80476e4SDavid E. O'Brien 	if ((warp < 0) || (warp >= WARP_MAXLINK))
596c80476e4SDavid E. O'Brien 	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 10, "Invalid warp"));
597c80476e4SDavid E. O'Brien 	if ((setwarp(warp) < 0) || (getwarp() != warp)) {
598c80476e4SDavid E. O'Brien 	    (void) setwarp(oldwarp);
599c80476e4SDavid E. O'Brien 	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 11, "Setwarp failed"));
600c80476e4SDavid E. O'Brien 	}
601c80476e4SDavid E. O'Brien     }
60245e5710bSMark Peek     sigaction(SIGSYS, &old_sigsys_handler, NULL);
603c80476e4SDavid E. O'Brien }
604c80476e4SDavid E. O'Brien #endif /* WARP */
605c80476e4SDavid E. O'Brien 
606c80476e4SDavid E. O'Brien /***
607c80476e4SDavid E. O'Brien  *** Masscomp or HCX
608c80476e4SDavid E. O'Brien  ***/
609c80476e4SDavid E. O'Brien /* Added, DAS DEC-90. */
610c80476e4SDavid E. O'Brien #if defined(masscomp) || defined(_CX_UX)
61145e5710bSMark Peek static void
setuniverse_cleanup(void * xbuf)61245e5710bSMark Peek setuniverse_cleanup(void *xbuf)
61345e5710bSMark Peek {
61445e5710bSMark Peek     char *buf;
61545e5710bSMark Peek 
61645e5710bSMark Peek     buf = xbuf;
61745e5710bSMark Peek     setuniverse(buf);
61845e5710bSMark Peek }
61945e5710bSMark Peek 
620c80476e4SDavid E. O'Brien /*ARGSUSED*/
621c80476e4SDavid E. O'Brien void
douniverse(Char ** v,struct command * c)62245e5710bSMark Peek douniverse(Char **v, struct command *c)
623c80476e4SDavid E. O'Brien {
62423338178SMark Peek     Char *cp = v[1];
62523338178SMark Peek     Char *cp2;		/* dunno how many elements v comes in with */
626c80476e4SDavid E. O'Brien     char    ubuf[100];
627c80476e4SDavid E. O'Brien 
628c80476e4SDavid E. O'Brien     if (cp == 0) {
629c80476e4SDavid E. O'Brien 	(void) getuniverse(ubuf);
630c80476e4SDavid E. O'Brien 	xprintf("%s\n", ubuf);
631c80476e4SDavid E. O'Brien     }
632c80476e4SDavid E. O'Brien     else {
633c80476e4SDavid E. O'Brien 	cp2 = v[2];
634c80476e4SDavid E. O'Brien 	if (cp2 == 0) {
635c80476e4SDavid E. O'Brien 	    if (*cp == '\0' || setuniverse(short2str(cp)) != 0)
636c80476e4SDavid E. O'Brien 		stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe"));
637c80476e4SDavid E. O'Brien 	    }
638c80476e4SDavid E. O'Brien 	else {
639c80476e4SDavid E. O'Brien 	    (void) getuniverse(ubuf);
640c80476e4SDavid E. O'Brien 	    if (*cp == '\0' || setuniverse(short2str(cp)) != 0)
641c80476e4SDavid E. O'Brien 		stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe"));
64245e5710bSMark Peek 	    cleanup_push(ubuf, setuniverse_cleanup);
64345e5710bSMark Peek 	    if (setintr) {
64445e5710bSMark Peek 		pintr_disabled++;
64545e5710bSMark Peek 		cleanup_push(&pintr_disabled, disabled_cleanup);
64645e5710bSMark Peek 	    }
647c80476e4SDavid E. O'Brien 	    lshift(v, 2);
648c80476e4SDavid E. O'Brien 	    if (setintr)
64945e5710bSMark Peek 		cleanup_until(&pintr_disabled);
650c80476e4SDavid E. O'Brien 	    reexecute(c);
65145e5710bSMark Peek 	    cleanup_until(ubuf);
652c80476e4SDavid E. O'Brien 	}
653c80476e4SDavid E. O'Brien     }
654c80476e4SDavid E. O'Brien }
655c80476e4SDavid E. O'Brien #endif /* masscomp || _CX_UX */
656c80476e4SDavid E. O'Brien 
657b2d5d167SMark Peek /***
658b2d5d167SMark Peek  *** BS2000/OSD POSIX (Fujitsu Siemens Computers)
659b2d5d167SMark Peek  ***/
660b2d5d167SMark Peek #if defined(_OSD_POSIX)
661b2d5d167SMark Peek static int
bs2upcase(char * str)662b2d5d167SMark Peek bs2upcase(char *str)
663b2d5d167SMark Peek {
664b2d5d167SMark Peek     enum { outside = ' ', singlequote='\'', doublequote='"'} string = outside;
665b2d5d167SMark Peek 
666b2d5d167SMark Peek     char *white;
667b2d5d167SMark Peek 
668b2d5d167SMark Peek     for (white = str + strlen(str) - 1; isspace(*white) && white > str; --white)
669b2d5d167SMark Peek         *white = '\0';
670b2d5d167SMark Peek 
671b2d5d167SMark Peek     for (; *str != '\0'; ++str)
672b2d5d167SMark Peek     {
673b2d5d167SMark Peek         if (string == outside)
674b2d5d167SMark Peek         {
675b2d5d167SMark Peek             *str = toupper (*str);
676b2d5d167SMark Peek         }
677b2d5d167SMark Peek         if (*str == '\'')
678b2d5d167SMark Peek         {
679b2d5d167SMark Peek             if (string == outside)
680b2d5d167SMark Peek                 string = singlequote;
681b2d5d167SMark Peek             else if (string != doublequote)
682b2d5d167SMark Peek                 string = outside;
683b2d5d167SMark Peek         }
684b2d5d167SMark Peek         else if (*str == '"')
685b2d5d167SMark Peek         {
686b2d5d167SMark Peek             if (string == outside)
687b2d5d167SMark Peek                 string = doublequote;
688b2d5d167SMark Peek             else if (string != singlequote)
689b2d5d167SMark Peek                 string = outside;
690b2d5d167SMark Peek         }
691b2d5d167SMark Peek     }
692b2d5d167SMark Peek     if (string != outside)
693b2d5d167SMark Peek     {
694b2d5d167SMark Peek         stderror(ERR_NAME | ERR_UNMATCHED, (Char) string);
695b2d5d167SMark Peek         return 1;
696b2d5d167SMark Peek     }
697b2d5d167SMark Peek     return 0;
698b2d5d167SMark Peek }
699b2d5d167SMark Peek static int
bs2cmdlist(char * str)700b2d5d167SMark Peek bs2cmdlist(char *str)
701b2d5d167SMark Peek {
702b2d5d167SMark Peek     char *str_beg = NULL;
703b2d5d167SMark Peek     int ret = 0;
704b2d5d167SMark Peek 
705b2d5d167SMark Peek     enum { outside = ' ', singlequote='\'', doublequote='"'} string = outside;
706b2d5d167SMark Peek 
707b2d5d167SMark Peek     while (*str != '\0')
708b2d5d167SMark Peek     {
709b2d5d167SMark Peek         while (isspace(*str))
710b2d5d167SMark Peek             ++str;
711b2d5d167SMark Peek 
712b2d5d167SMark Peek         if (*str == '\0')
713b2d5d167SMark Peek             break;
714b2d5d167SMark Peek 
715b2d5d167SMark Peek         str_beg = str;
716b2d5d167SMark Peek 
717b2d5d167SMark Peek         for (; *str != '\0'; ++str)
718b2d5d167SMark Peek         {
719b2d5d167SMark Peek             if (string == outside && *str == ';') /* End of command */
720b2d5d167SMark Peek             {
721b2d5d167SMark Peek                 *str++ = '\0';
722b2d5d167SMark Peek                 break;    /* continue with next command */
723b2d5d167SMark Peek             }
724b2d5d167SMark Peek             if (*str == '\'')
725b2d5d167SMark Peek             {
726b2d5d167SMark Peek                 if (string == outside)
727b2d5d167SMark Peek                     string = singlequote;
728b2d5d167SMark Peek                 else if (string != doublequote)
729b2d5d167SMark Peek                     string = outside;
730b2d5d167SMark Peek             }
731b2d5d167SMark Peek             else if (*str == '"')
732b2d5d167SMark Peek             {
733b2d5d167SMark Peek                 if (string == outside)
734b2d5d167SMark Peek                     string = doublequote;
735b2d5d167SMark Peek                 else if (string != singlequote)
736b2d5d167SMark Peek                     string = outside;
737b2d5d167SMark Peek             }
738b2d5d167SMark Peek         }
739b2d5d167SMark Peek         if (strlen(str_beg) != 0)
740b2d5d167SMark Peek         {
741b2d5d167SMark Peek             ret = bs2system(str_beg);
742b2d5d167SMark Peek 	    flush();
743b2d5d167SMark Peek             if (ret != 0 /*&& !option.err_ignore*/)
744b2d5d167SMark Peek                 break; /* do not continue after errors */
745b2d5d167SMark Peek         }
746b2d5d167SMark Peek     }
747b2d5d167SMark Peek 
748b2d5d167SMark Peek     if (string != outside)
749b2d5d167SMark Peek     {
750b2d5d167SMark Peek         stderror(ERR_NAME | ERR_UNMATCHED, (Char) string);
751b2d5d167SMark Peek         return -1;
752b2d5d167SMark Peek     }
753b2d5d167SMark Peek 
754b2d5d167SMark Peek     return ret;
755b2d5d167SMark Peek }
756b2d5d167SMark Peek /*ARGSUSED*/
757b2d5d167SMark Peek void
dobs2cmd(Char ** v,struct command * c)75845e5710bSMark Peek dobs2cmd(Char **v, struct command *c)
759b2d5d167SMark Peek {
76045e5710bSMark Peek     Char *cp, **globbed;
76123338178SMark Peek     int  i = 0, len = 0;
762b2d5d167SMark Peek     char *cmd = NULL;
763b2d5d167SMark Peek     int     pvec[2];
764b2d5d167SMark Peek     struct command faket;
765b2d5d167SMark Peek     Char   *fakecom[2];
766b2d5d167SMark Peek     char    tibuf[BUFSIZE];
76745e5710bSMark Peek     int     icnt, old_pintr_disabled;
768b2d5d167SMark Peek     static const Char STRbs2cmd[] = { 'b','s','2','c','m','d','\0' };
769b2d5d167SMark Peek 
770b2d5d167SMark Peek     v++;
77145e5710bSMark Peek     if (setintr)
77245e5710bSMark Peek 	pintr_push_enable(&old_pintr_disabled);
77345e5710bSMark Peek     v = glob_all_or_error(v);
77445e5710bSMark Peek     if (setintr)
77545e5710bSMark Peek 	cleanup_until(&old_pintr_disabled);
77645e5710bSMark Peek     globbed = v;
77745e5710bSMark Peek     cleanup_push(globbed, blk_cleanup);
778b2d5d167SMark Peek 
779b2d5d167SMark Peek     /* First round: count the string lengths */
780b2d5d167SMark Peek     for (i=0; v[i]; ++i) {
78145e5710bSMark Peek 	len += Strlen(v[i]) + (v[i+1] != NULL);
782b2d5d167SMark Peek     }
783b2d5d167SMark Peek 
78445e5710bSMark Peek     cmd = xmalloc(len+1); /* 1 for the final '\0' *//* FIXME: memory leak? */
785b2d5d167SMark Peek 
786b2d5d167SMark Peek     /* 2nd round: fill cmd buffer */
787b2d5d167SMark Peek     i = 0;
788b2d5d167SMark Peek     while ((cp = *v++) != 0) {
78923338178SMark Peek 	int c;
790b2d5d167SMark Peek 	while (c = *cp++)
791b2d5d167SMark Peek 	    cmd[i++] = (char)c;
792b2d5d167SMark Peek         if (*v)
793b2d5d167SMark Peek 	    cmd[i++] = ' ';
794b2d5d167SMark Peek     }
795b2d5d167SMark Peek     cmd[i] = '\0';
796b2d5d167SMark Peek 
797b2d5d167SMark Peek     /* Make upper case */
798b2d5d167SMark Peek     bs2upcase(cmd);
799b2d5d167SMark Peek 
800b2d5d167SMark Peek     faket.t_dtyp = NODE_COMMAND;
801b2d5d167SMark Peek     faket.t_dflg = F_BACKQ|F_STDERR;
802b2d5d167SMark Peek     faket.t_dlef = 0;
803b2d5d167SMark Peek     faket.t_drit = 0;
804b2d5d167SMark Peek     faket.t_dspr = 0;
805b2d5d167SMark Peek     faket.t_dcom = fakecom;
80645e5710bSMark Peek     fakecom[0] = (Char *)STRbs2cmd;
807b2d5d167SMark Peek     fakecom[1] = 0;
808b2d5d167SMark Peek 
809b2d5d167SMark Peek     mypipe(pvec);
81045e5710bSMark Peek     cleanup_push(&pvec[0], open_cleanup);
81145e5710bSMark Peek     cleanup_push(&pvec[1], open_cleanup);
812b2d5d167SMark Peek     if (pfork(&faket, -1) == 0) {
81345e5710bSMark Peek 	sigset_t set;
814b2d5d167SMark Peek         /* child */
81545e5710bSMark Peek         xclose(pvec[0]);
816b2d5d167SMark Peek         (void) dmove(pvec[1], 1);
817b2d5d167SMark Peek         (void) dmove(SHDIAG,  2);
818b2d5d167SMark Peek         initdesc();
81945e5710bSMark Peek 	sigemptyset(&set);
82045e5710bSMark Peek 	sigaddset(&set, SIGINT);
82145e5710bSMark Peek 	(void)sigprocmask(SIG_UNBLOCK, &set, NULL);
822b2d5d167SMark Peek #ifdef SIGTSTP
82345e5710bSMark Peek         signal(SIGTSTP, SIG_IGN);
824b2d5d167SMark Peek #endif
825b2d5d167SMark Peek #ifdef SIGTTIN
82645e5710bSMark Peek         signal(SIGTTIN, SIG_IGN);
827b2d5d167SMark Peek #endif
828b2d5d167SMark Peek #ifdef SIGTTOU
82945e5710bSMark Peek         signal(SIGTTOU, SIG_IGN);
830b2d5d167SMark Peek #endif
831b2d5d167SMark Peek         xexit(bs2cmdlist(cmd));
832b2d5d167SMark Peek     }
83345e5710bSMark Peek     cleanup_until(&pvec[1]);
834b2d5d167SMark Peek     for (;;) {
83545e5710bSMark Peek 	int old_pintr_disabled;
83645e5710bSMark Peek 
83745e5710bSMark Peek 	if (setintr)
83845e5710bSMark Peek 	    pintr_push_enable(&old_pintr_disabled);
83945e5710bSMark Peek 	icnt = xread(pvec[0], tibuf, sizeof(tibuf));
84045e5710bSMark Peek 	if (setintr)
84145e5710bSMark Peek 	    cleanup_until(&old_pintr_disabled);
842b2d5d167SMark Peek         if (icnt <= 0)
843b2d5d167SMark Peek             break;
844b2d5d167SMark Peek         for (i = 0; i < icnt; i++)
845b2d5d167SMark Peek             xputchar((unsigned char) tibuf[i]);
846b2d5d167SMark Peek     }
84745e5710bSMark Peek     cleanup_until(&pvec[0]);
848b2d5d167SMark Peek     pwait();
849b2d5d167SMark Peek 
850b2d5d167SMark Peek     flush();
851b2d5d167SMark Peek 
85245e5710bSMark Peek     cleanup_until(globbed);
853b2d5d167SMark Peek }
854b2d5d167SMark Peek #endif /* _OSD_POSIX */
855b2d5d167SMark Peek 
856c80476e4SDavid E. O'Brien #if defined(_CX_UX)
85745e5710bSMark Peek static void
setuniverse_cleanup(void * xbuf)85845e5710bSMark Peek setuniverse_cleanup(void *xbuf)
85945e5710bSMark Peek {
86045e5710bSMark Peek     char *buf;
86145e5710bSMark Peek 
86245e5710bSMark Peek     buf = xbuf;
86345e5710bSMark Peek     setuniverse(buf);
86445e5710bSMark Peek }
86545e5710bSMark Peek 
866c80476e4SDavid E. O'Brien /*ARGSUSED*/
867c80476e4SDavid E. O'Brien void
doatt(Char ** v,struct command * c)86845e5710bSMark Peek doatt(Char **v, struct command *c)
869c80476e4SDavid E. O'Brien {
87023338178SMark Peek     Char *cp = v[1];
871c80476e4SDavid E. O'Brien     char    ubuf[100];
872c80476e4SDavid E. O'Brien 
873c80476e4SDavid E. O'Brien     if (cp == 0)
874c80476e4SDavid E. O'Brien 	(void) setuniverse("att");
875c80476e4SDavid E. O'Brien     else {
876c80476e4SDavid E. O'Brien 	(void) getuniverse(ubuf);
877c80476e4SDavid E. O'Brien 	(void) setuniverse("att");
87845e5710bSMark Peek 	cleanup_push(ubuf, setuniverse_cleanup);
87945e5710bSMark Peek 	if (setintr) {
88045e5710bSMark Peek 	    pintr_disabled++;
88145e5710bSMark Peek 	    cleanup_push(&pintr_disabled, disabled_cleanup);
88245e5710bSMark Peek 	}
883c80476e4SDavid E. O'Brien 	lshift(v, 1);
884c80476e4SDavid E. O'Brien 	if (setintr)
88545e5710bSMark Peek 	    cleanup_until(&pintr_disabled);
886c80476e4SDavid E. O'Brien 	reexecute(c);
88745e5710bSMark Peek 	cleanup_until(ubuf);
888c80476e4SDavid E. O'Brien     }
889c80476e4SDavid E. O'Brien }
890c80476e4SDavid E. O'Brien 
891c80476e4SDavid E. O'Brien /*ARGSUSED*/
892c80476e4SDavid E. O'Brien void
doucb(Char ** v,struct command * c)89345e5710bSMark Peek doucb(Char **v, struct command *c)
894c80476e4SDavid E. O'Brien {
89523338178SMark Peek     Char *cp = v[1];
896c80476e4SDavid E. O'Brien     char    ubuf[100];
897c80476e4SDavid E. O'Brien 
898c80476e4SDavid E. O'Brien     if (cp == 0)
899c80476e4SDavid E. O'Brien 	(void) setuniverse("ucb");
900c80476e4SDavid E. O'Brien     else {
901c80476e4SDavid E. O'Brien 	(void) getuniverse(ubuf);
902c80476e4SDavid E. O'Brien 	(void) setuniverse("ucb");
90345e5710bSMark Peek 	cleanup_push(ubuf, setuniverse_cleanup);
90445e5710bSMark Peek 	if (setintr) {
90545e5710bSMark Peek 	    pintr_disabled++;
90645e5710bSMark Peek 	    cleanup_push(&pintr_disabled, disabled_cleanup);
90745e5710bSMark Peek 	}
908c80476e4SDavid E. O'Brien 	lshift(v, 1);
909c80476e4SDavid E. O'Brien 	if (setintr)
91045e5710bSMark Peek 	    cleanup_until(&pintr_disabled);
911c80476e4SDavid E. O'Brien 	reexecute(c);
91245e5710bSMark Peek 	cleanup_until(ubuf);
913c80476e4SDavid E. O'Brien     }
914c80476e4SDavid E. O'Brien }
915c80476e4SDavid E. O'Brien #endif /* _CX_UX */
916c80476e4SDavid E. O'Brien 
917c80476e4SDavid E. O'Brien #ifdef _SEQUENT_
918c80476e4SDavid E. O'Brien /*
919c80476e4SDavid E. O'Brien  * Compute the difference in process stats.
920c80476e4SDavid E. O'Brien  */
921c80476e4SDavid E. O'Brien void
pr_stat_sub(struct process_stats * p2,struct process_stats * p1,struct process_stats * pr)92245e5710bSMark Peek pr_stat_sub(struct process_stats *p2, struct process_stats *p1,
92345e5710bSMark Peek 	    struct process_stats *pr)
924c80476e4SDavid E. O'Brien {
925c80476e4SDavid E. O'Brien     pr->ps_utime.tv_sec = p2->ps_utime.tv_sec - p1->ps_utime.tv_sec;
926c80476e4SDavid E. O'Brien     pr->ps_utime.tv_usec = p2->ps_utime.tv_usec - p1->ps_utime.tv_usec;
927c80476e4SDavid E. O'Brien     if (pr->ps_utime.tv_usec < 0) {
928c80476e4SDavid E. O'Brien 	pr->ps_utime.tv_sec -= 1;
929c80476e4SDavid E. O'Brien 	pr->ps_utime.tv_usec += 1000000;
930c80476e4SDavid E. O'Brien     }
931c80476e4SDavid E. O'Brien     pr->ps_stime.tv_sec = p2->ps_stime.tv_sec - p1->ps_stime.tv_sec;
932c80476e4SDavid E. O'Brien     pr->ps_stime.tv_usec = p2->ps_stime.tv_usec - p1->ps_stime.tv_usec;
933c80476e4SDavid E. O'Brien     if (pr->ps_stime.tv_usec < 0) {
934c80476e4SDavid E. O'Brien 	pr->ps_stime.tv_sec -= 1;
935c80476e4SDavid E. O'Brien 	pr->ps_stime.tv_usec += 1000000;
936c80476e4SDavid E. O'Brien     }
937c80476e4SDavid E. O'Brien 
938c80476e4SDavid E. O'Brien     pr->ps_maxrss = p2->ps_maxrss - p1->ps_maxrss;
939c80476e4SDavid E. O'Brien     pr->ps_pagein = p2->ps_pagein - p1->ps_pagein;
940c80476e4SDavid E. O'Brien     pr->ps_reclaim = p2->ps_reclaim - p1->ps_reclaim;
941c80476e4SDavid E. O'Brien     pr->ps_zerofill = p2->ps_zerofill - p1->ps_zerofill;
942c80476e4SDavid E. O'Brien     pr->ps_pffincr = p2->ps_pffincr - p1->ps_pffincr;
943c80476e4SDavid E. O'Brien     pr->ps_pffdecr = p2->ps_pffdecr - p1->ps_pffdecr;
944c80476e4SDavid E. O'Brien     pr->ps_swap = p2->ps_swap - p1->ps_swap;
945c80476e4SDavid E. O'Brien     pr->ps_syscall = p2->ps_syscall - p1->ps_syscall;
946c80476e4SDavid E. O'Brien     pr->ps_volcsw = p2->ps_volcsw - p1->ps_volcsw;
947c80476e4SDavid E. O'Brien     pr->ps_involcsw = p2->ps_involcsw - p1->ps_involcsw;
948c80476e4SDavid E. O'Brien     pr->ps_signal = p2->ps_signal - p1->ps_signal;
949c80476e4SDavid E. O'Brien     pr->ps_lread = p2->ps_lread - p1->ps_lread;
950c80476e4SDavid E. O'Brien     pr->ps_lwrite = p2->ps_lwrite - p1->ps_lwrite;
951c80476e4SDavid E. O'Brien     pr->ps_bread = p2->ps_bread - p1->ps_bread;
952c80476e4SDavid E. O'Brien     pr->ps_bwrite = p2->ps_bwrite - p1->ps_bwrite;
953c80476e4SDavid E. O'Brien     pr->ps_phread = p2->ps_phread - p1->ps_phread;
954c80476e4SDavid E. O'Brien     pr->ps_phwrite = p2->ps_phwrite - p1->ps_phwrite;
955c80476e4SDavid E. O'Brien }
956c80476e4SDavid E. O'Brien 
957c80476e4SDavid E. O'Brien #endif /* _SEQUENT_ */
958c80476e4SDavid E. O'Brien 
959c80476e4SDavid E. O'Brien 
96023338178SMark Peek #ifndef HAVE_MEMSET
961c80476e4SDavid E. O'Brien /* This is a replacement for a missing memset function */
xmemset(void * loc,int value,size_t len)96245e5710bSMark Peek void *xmemset(void *loc, int value, size_t len)
963c80476e4SDavid E. O'Brien {
96445e5710bSMark Peek     char *ptr = loc;
965c80476e4SDavid E. O'Brien 
966c80476e4SDavid E. O'Brien     while (len--)
967c80476e4SDavid E. O'Brien 	*ptr++ = value;
968c80476e4SDavid E. O'Brien     return loc;
969c80476e4SDavid E. O'Brien }
97023338178SMark Peek #endif /* !HAVE_MEMSET */
971c80476e4SDavid E. O'Brien 
972c80476e4SDavid E. O'Brien 
97323338178SMark Peek #ifndef HAVE_MEMMOVE
974c80476e4SDavid E. O'Brien /* memmove():
975c80476e4SDavid E. O'Brien  * 	This is the ANSI form of bcopy() with the arguments backwards...
976c80476e4SDavid E. O'Brien  *	Unlike memcpy(), it handles overlaps between source and
977c80476e4SDavid E. O'Brien  *	destination memory
978c80476e4SDavid E. O'Brien  */
97945e5710bSMark Peek void *
xmemmove(void * vdst,const void * vsrc,size_t len)98045e5710bSMark Peek xmemmove(void *vdst, const void *vsrc, size_t len)
981c80476e4SDavid E. O'Brien {
98245e5710bSMark Peek     const char *src = vsrc;
98345e5710bSMark Peek     char *dst = vdst;
984c80476e4SDavid E. O'Brien 
985c80476e4SDavid E. O'Brien     if (src == dst)
986c80476e4SDavid E. O'Brien 	return vdst;
987c80476e4SDavid E. O'Brien 
988c80476e4SDavid E. O'Brien     if (src > dst) {
989c80476e4SDavid E. O'Brien 	while (len--)
990c80476e4SDavid E. O'Brien 	    *dst++ = *src++;
991c80476e4SDavid E. O'Brien     }
992c80476e4SDavid E. O'Brien     else {
993c80476e4SDavid E. O'Brien 	src += len;
994c80476e4SDavid E. O'Brien 	dst += len;
995c80476e4SDavid E. O'Brien 	while (len--)
996c80476e4SDavid E. O'Brien 	    *--dst = *--src;
997c80476e4SDavid E. O'Brien     }
998c80476e4SDavid E. O'Brien     return vdst;
999c80476e4SDavid E. O'Brien }
100023338178SMark Peek #endif /* HAVE_MEMMOVE */
1001c80476e4SDavid E. O'Brien 
1002c80476e4SDavid E. O'Brien 
10033b6eaa7bSAndrey A. Chernov #ifndef WINNT_NATIVE
100423338178SMark Peek #ifdef NEEDtcgetpgrp
100545e5710bSMark Peek pid_t
xtcgetpgrp(int fd)100645e5710bSMark Peek xtcgetpgrp(int fd)
1007c80476e4SDavid E. O'Brien {
1008c80476e4SDavid E. O'Brien     int     pgrp;
1009c80476e4SDavid E. O'Brien 
1010c80476e4SDavid E. O'Brien     /* ioctl will handle setting errno correctly. */
1011c80476e4SDavid E. O'Brien     if (ioctl(fd, TIOCGPGRP, (ioctl_t) & pgrp) < 0)
1012c80476e4SDavid E. O'Brien 	return (-1);
1013c80476e4SDavid E. O'Brien     return (pgrp);
1014c80476e4SDavid E. O'Brien }
1015c80476e4SDavid E. O'Brien 
1016c80476e4SDavid E. O'Brien /*
1017c80476e4SDavid E. O'Brien  * XXX: tcsetpgrp is not a macro any more cause on some systems,
1018c80476e4SDavid E. O'Brien  * pid_t is a short, but the ioctl() takes a pointer to int (pyr)
1019c80476e4SDavid E. O'Brien  * Thanks to Simon Day (simon@pharaoh.cyborg.bt.co.uk) for pointing
1020c80476e4SDavid E. O'Brien  * this out.
1021c80476e4SDavid E. O'Brien  */
1022c80476e4SDavid E. O'Brien int
xtcsetpgrp(int fd,int pgrp)102345e5710bSMark Peek xtcsetpgrp(int fd, int pgrp)
1024c80476e4SDavid E. O'Brien {
1025c80476e4SDavid E. O'Brien     return ioctl(fd, TIOCSPGRP, (ioctl_t) &pgrp);
1026c80476e4SDavid E. O'Brien }
1027c80476e4SDavid E. O'Brien 
102823338178SMark Peek #endif	/* NEEDtcgetpgrp */
10293b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */
1030c80476e4SDavid E. O'Brien 
1031c80476e4SDavid E. O'Brien 
1032c80476e4SDavid E. O'Brien #ifdef YPBUGS
1033c80476e4SDavid E. O'Brien void
fix_yp_bugs(void)103445e5710bSMark Peek fix_yp_bugs(void)
1035c80476e4SDavid E. O'Brien {
1036c80476e4SDavid E. O'Brien     char   *mydomain;
1037c80476e4SDavid E. O'Brien 
103845e5710bSMark Peek     extern int yp_get_default_domain (char **);
1039c80476e4SDavid E. O'Brien     /*
1040c80476e4SDavid E. O'Brien      * PWP: The previous version assumed that yp domain was the same as the
1041c80476e4SDavid E. O'Brien      * internet name domain.  This isn't allways true. (Thanks to Mat Landau
1042c80476e4SDavid E. O'Brien      * <mlandau@bbn.com> for the original version of this.)
1043c80476e4SDavid E. O'Brien      */
1044c80476e4SDavid E. O'Brien     if (yp_get_default_domain(&mydomain) == 0) {	/* if we got a name */
104545e5710bSMark Peek 	extern void yp_unbind (const char *);
1046c80476e4SDavid E. O'Brien 
1047c80476e4SDavid E. O'Brien 	yp_unbind(mydomain);
1048c80476e4SDavid E. O'Brien     }
1049c80476e4SDavid E. O'Brien }
1050c80476e4SDavid E. O'Brien 
1051c80476e4SDavid E. O'Brien #endif /* YPBUGS */
1052c80476e4SDavid E. O'Brien 
1053c80476e4SDavid E. O'Brien #ifdef STRCOLLBUG
1054c80476e4SDavid E. O'Brien void
fix_strcoll_bug(void)105545e5710bSMark Peek fix_strcoll_bug(void)
1056c80476e4SDavid E. O'Brien {
105745e5710bSMark Peek #if defined(NLS) && defined(HAVE_STRCOLL)
1058c80476e4SDavid E. O'Brien     /*
1059c80476e4SDavid E. O'Brien      * SunOS4 checks the file descriptor from openlocale() for <= 0
1060c80476e4SDavid E. O'Brien      * instead of == -1. Someone should tell sun that file descriptor 0
1061c80476e4SDavid E. O'Brien      * is valid! Our portable hack: open one so we call it with 0 used...
1062c80476e4SDavid E. O'Brien      * We have to call this routine every time the locale changes...
1063c80476e4SDavid E. O'Brien      *
1064c80476e4SDavid E. O'Brien      * Of course it also tries to free the constant locale "C" it initially
1065c80476e4SDavid E. O'Brien      * had allocated, with the sequence
1066c80476e4SDavid E. O'Brien      * > setenv LANG "fr"
1067c80476e4SDavid E. O'Brien      * > ls^D
1068c80476e4SDavid E. O'Brien      * > unsetenv LANG
1069c80476e4SDavid E. O'Brien      * But we are smarter than that and just print a warning message.
1070c80476e4SDavid E. O'Brien      */
1071c80476e4SDavid E. O'Brien     int fd = -1;
1072c80476e4SDavid E. O'Brien     static char *root = "/";
1073c80476e4SDavid E. O'Brien 
1074c80476e4SDavid E. O'Brien     if (!didfds)
107545e5710bSMark Peek 	fd = xopen(root, O_RDONLY|O_LARGEFILE);
1076c80476e4SDavid E. O'Brien 
1077c80476e4SDavid E. O'Brien     (void) strcoll(root, root);
1078c80476e4SDavid E. O'Brien 
1079c80476e4SDavid E. O'Brien     if (fd != -1)
108045e5710bSMark Peek 	xclose(fd);
1081c80476e4SDavid E. O'Brien #endif
1082c80476e4SDavid E. O'Brien }
1083c80476e4SDavid E. O'Brien #endif /* STRCOLLBUG */
1084c80476e4SDavid E. O'Brien 
1085c80476e4SDavid E. O'Brien 
1086c80476e4SDavid E. O'Brien #ifdef OREO
1087c80476e4SDavid E. O'Brien #include <compat.h>
1088c80476e4SDavid E. O'Brien #endif /* OREO */
1089c80476e4SDavid E. O'Brien 
1090c80476e4SDavid E. O'Brien void
osinit(void)109145e5710bSMark Peek osinit(void)
1092c80476e4SDavid E. O'Brien {
1093c80476e4SDavid E. O'Brien #ifdef OREO
1094c80476e4SDavid E. O'Brien     set42sig();
1095c80476e4SDavid E. O'Brien     setcompat(getcompat() & ~COMPAT_EXEC);
109645e5710bSMark Peek     signal(SIGIO, SIG_IGN);		/* ignore SIGIO */
1097c80476e4SDavid E. O'Brien #endif /* OREO */
1098c80476e4SDavid E. O'Brien 
1099c80476e4SDavid E. O'Brien #ifdef aiws
1100c80476e4SDavid E. O'Brien     {
1101c80476e4SDavid E. O'Brien 	struct sigstack inst;
110245e5710bSMark Peek 	inst.ss_sp = xmalloc(4192) + 4192;
1103c80476e4SDavid E. O'Brien 	inst.ss_onstack = 0;
1104c80476e4SDavid E. O'Brien 	sigstack(&inst, NULL);
1105c80476e4SDavid E. O'Brien     }
1106c80476e4SDavid E. O'Brien #endif /* aiws */
1107c80476e4SDavid E. O'Brien 
1108c80476e4SDavid E. O'Brien #ifdef apollo
1109c80476e4SDavid E. O'Brien     (void) isapad();
1110c80476e4SDavid E. O'Brien #endif
1111c80476e4SDavid E. O'Brien 
1112c80476e4SDavid E. O'Brien #ifdef _SX
1113c80476e4SDavid E. O'Brien     /*
1114c80476e4SDavid E. O'Brien      * kill(SIGCONT) problems, don't know what this syscall does
1115c80476e4SDavid E. O'Brien      * [schott@rzg.mpg.de]
1116c80476e4SDavid E. O'Brien      */
1117c80476e4SDavid E. O'Brien     syscall(151, getpid(), getpid());
1118c80476e4SDavid E. O'Brien #endif /* _SX */
1119c80476e4SDavid E. O'Brien }
1120c80476e4SDavid E. O'Brien 
112123338178SMark Peek #ifndef HAVE_STRERROR
112245e5710bSMark Peek extern int sys_nerr;
112345e5710bSMark Peek extern char *sys_errlist[];
1124c80476e4SDavid E. O'Brien char *
xstrerror(int i)112545e5710bSMark Peek xstrerror(int i)
1126c80476e4SDavid E. O'Brien {
1127c80476e4SDavid E. O'Brien     if (i >= 0 && i < sys_nerr) {
1128c80476e4SDavid E. O'Brien 	return sys_errlist[i];
1129c80476e4SDavid E. O'Brien     } else {
113045e5710bSMark Peek 	static char *errbuf; /* = NULL; */
113145e5710bSMark Peek 
113245e5710bSMark Peek 	xfree(errbuf);
113345e5710bSMark Peek 	errbuf = xasprintf(CGETS(23, 13, "Unknown Error: %d"), i);
1134c80476e4SDavid E. O'Brien 	return errbuf;
1135c80476e4SDavid E. O'Brien     }
1136c80476e4SDavid E. O'Brien }
113723338178SMark Peek #endif /* !HAVE_STRERROR */
1138c80476e4SDavid E. O'Brien 
113923338178SMark Peek #ifndef HAVE_GETHOSTNAME
11403b6eaa7bSAndrey A. Chernov # if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE)
1141c80476e4SDavid E. O'Brien #  include <sys/utsname.h>
11423b6eaa7bSAndrey A. Chernov # endif /* !_MINIX && !__EMX__ && !WINNT_NATIVE */
1143c80476e4SDavid E. O'Brien 
1144c80476e4SDavid E. O'Brien int
xgethostname(char * name,int namlen)114545e5710bSMark Peek xgethostname(char *name, int namlen)
1146c80476e4SDavid E. O'Brien {
11473b6eaa7bSAndrey A. Chernov # if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE)
1148c80476e4SDavid E. O'Brien     int     i, retval;
1149c80476e4SDavid E. O'Brien     struct utsname uts;
1150c80476e4SDavid E. O'Brien 
1151c80476e4SDavid E. O'Brien     retval = uname(&uts);
1152c80476e4SDavid E. O'Brien 
1153c80476e4SDavid E. O'Brien #  ifdef DEBUG
1154c80476e4SDavid E. O'Brien     xprintf(CGETS(23, 14, "sysname:  %s\n"), uts.sysname);
1155c80476e4SDavid E. O'Brien     xprintf(CGETS(23, 15, "nodename: %s\n"), uts.nodename);
1156c80476e4SDavid E. O'Brien     xprintf(CGETS(23, 16, "release:  %s\n"), uts.release);
1157c80476e4SDavid E. O'Brien     xprintf(CGETS(23, 17, "version:  %s\n"), uts.version);
1158c80476e4SDavid E. O'Brien     xprintf(CGETS(23, 18, "machine:  %s\n"), uts.machine);
1159c80476e4SDavid E. O'Brien #  endif /* DEBUG */
1160c80476e4SDavid E. O'Brien     i = strlen(uts.nodename) + 1;
1161c80476e4SDavid E. O'Brien     (void) strncpy(name, uts.nodename, i < namlen ? i : namlen);
1162c80476e4SDavid E. O'Brien 
1163c80476e4SDavid E. O'Brien     return retval;
1164c80476e4SDavid E. O'Brien # else /* !_MINIX && !__EMX__ */
1165c80476e4SDavid E. O'Brien     if (namlen > 0) {
1166c80476e4SDavid E. O'Brien #  ifdef __EMX__
1167c80476e4SDavid E. O'Brien 	(void) strncpy(name, "OS/2", namlen);
1168c80476e4SDavid E. O'Brien #  else /* _MINIX */
1169c80476e4SDavid E. O'Brien 	(void) strncpy(name, "minix", namlen);
1170c80476e4SDavid E. O'Brien #  endif /* __EMX__ */
1171c80476e4SDavid E. O'Brien 	name[namlen-1] = '\0';
1172c80476e4SDavid E. O'Brien     }
1173c80476e4SDavid E. O'Brien     return(0);
1174c80476e4SDavid E. O'Brien #endif /* _MINIX && !__EMX__ */
1175c80476e4SDavid E. O'Brien } /* end xgethostname */
117623338178SMark Peek #endif /* !HAVE_GETHOSTNAME */
1177c80476e4SDavid E. O'Brien 
117823338178SMark Peek #ifndef HAVE_NICE
1179c80476e4SDavid E. O'Brien # if defined(_MINIX) && defined(NICE)
1180c80476e4SDavid E. O'Brien #  undef _POSIX_SOURCE	/* redefined in <lib.h> */
1181c80476e4SDavid E. O'Brien #  undef _MINIX		/* redefined in <lib.h> */
1182c80476e4SDavid E. O'Brien #  undef HZ		/* redefined in <minix/const.h> */
1183c80476e4SDavid E. O'Brien #  include <lib.h>
1184c80476e4SDavid E. O'Brien # endif /* _MINIX && NICE */
1185c80476e4SDavid E. O'Brien int
xnice(int incr)118645e5710bSMark Peek xnice(int incr)
1187c80476e4SDavid E. O'Brien {
1188c80476e4SDavid E. O'Brien #if defined(_MINIX) && defined(NICE)
1189c80476e4SDavid E. O'Brien     return callm1(MM, NICE, incr, 0, 0, NIL_PTR, NIL_PTR, NIL_PTR);
1190c80476e4SDavid E. O'Brien #else
1191c80476e4SDavid E. O'Brien     return /* incr ? 0 : */ 0;
1192c80476e4SDavid E. O'Brien #endif /* _MINIX && NICE */
1193c80476e4SDavid E. O'Brien } /* end xnice */
119423338178SMark Peek #endif /* !HAVE_NICE */
1195c80476e4SDavid E. O'Brien 
119623338178SMark Peek #ifndef HAVE_GETCWD
119745e5710bSMark Peek static char *strnrcpy (char *, char *, size_t);
1198c80476e4SDavid E. O'Brien 
1199c80476e4SDavid E. O'Brien /* xgetcwd():
1200c80476e4SDavid E. O'Brien  *	Return the pathname of the current directory, or return
1201c80476e4SDavid E. O'Brien  *	an error message in pathname.
1202c80476e4SDavid E. O'Brien  */
1203c80476e4SDavid E. O'Brien 
1204c80476e4SDavid E. O'Brien # ifdef hp9000s500
1205c80476e4SDavid E. O'Brien /*
1206c80476e4SDavid E. O'Brien  *  From: Bernd Mohr <mohr@faui77.informatik.uni-erlangen.de>
1207c80476e4SDavid E. O'Brien  *  I also ported the tcsh to the HP9000 Series 500. This computer
1208c80476e4SDavid E. O'Brien  *  is a little bit different than the other HP 9000 computer. It has
1209c80476e4SDavid E. O'Brien  *  a HP Chip instead of a Motorola CPU and it is no "real" UNIX. It runs
1210c80476e4SDavid E. O'Brien  *  HP-UX which is emulated in top of a HP operating system. So, the last
1211c80476e4SDavid E. O'Brien  *  supported version of HP-UX is 5.2 on the HP9000s500. This has two
1212c80476e4SDavid E. O'Brien  *  consequences: it supports no job control and it has a filesystem
1213c80476e4SDavid E. O'Brien  *  without "." and ".." !!!
1214c80476e4SDavid E. O'Brien  */
1215c80476e4SDavid E. O'Brien char *
xgetcwd(char * pathname,size_t pathlen)121645e5710bSMark Peek xgetcwd(char *pathname, size_t pathlen)
1217c80476e4SDavid E. O'Brien {
121845e5710bSMark Peek     char pathbuf[MAXPATHLEN];	/* temporary pathname buffer */
1219c80476e4SDavid E. O'Brien     char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
1220c80476e4SDavid E. O'Brien     dev_t rdev;			/* root device number */
1221c80476e4SDavid E. O'Brien     DIR *dirp = NULL;		/* directory stream */
1222c80476e4SDavid E. O'Brien     ino_t rino;			/* root inode number */
1223c80476e4SDavid E. O'Brien     off_t rsize;		/* root size */
1224c80476e4SDavid E. O'Brien     struct direct *dir;		/* directory entry struct */
1225c80476e4SDavid E. O'Brien     struct stat d, dd;		/* file status struct */
1226c80476e4SDavid E. O'Brien     int serrno;
1227c80476e4SDavid E. O'Brien 
1228c80476e4SDavid E. O'Brien     *pnptr = '\0';
1229c80476e4SDavid E. O'Brien     (void) stat("/.", &d);
1230c80476e4SDavid E. O'Brien     rdev = d.st_dev;
1231c80476e4SDavid E. O'Brien     rino = d.st_ino;
1232c80476e4SDavid E. O'Brien     rsize = d.st_size;
1233c80476e4SDavid E. O'Brien     for (;;) {
1234c80476e4SDavid E. O'Brien 	if (stat(".", &d) == -1) {
1235c80476e4SDavid E. O'Brien 	    (void) xsnprintf(pathname, pathlen, CGETS(23, 24,
1236c80476e4SDavid E. O'Brien 		"getcwd: Cannot stat \".\" (%s)"), strerror(errno));
1237c80476e4SDavid E. O'Brien 	    goto fail;
1238c80476e4SDavid E. O'Brien 	}
1239c80476e4SDavid E. O'Brien 	if (d.st_ino == rino && d.st_dev == rdev && d.st_size == rsize)
1240c80476e4SDavid E. O'Brien 	    break;		/* reached root directory */
1241c80476e4SDavid E. O'Brien 	if ((dirp = opendir("..")) == NULL) {
1242c80476e4SDavid E. O'Brien 	    (void) xsnprintf(pathname, pathlen, CGETS(23, 19,
1243c80476e4SDavid E. O'Brien 		"getcwd: Cannot open \"..\" (%s)"), strerror(errno));
1244c80476e4SDavid E. O'Brien 	    goto fail;
1245c80476e4SDavid E. O'Brien 	}
1246c80476e4SDavid E. O'Brien 	if (chdir("..") == -1) {
1247c80476e4SDavid E. O'Brien 	    (void) xsnprintf(pathname, pathlen, CGETS(23, 20,
1248c80476e4SDavid E. O'Brien 		"getcwd: Cannot chdir to \"..\" (%s)"), strerror(errno));
1249c80476e4SDavid E. O'Brien 	    goto fail;
1250c80476e4SDavid E. O'Brien 	}
1251c80476e4SDavid E. O'Brien 	do {
1252c80476e4SDavid E. O'Brien 	    if ((dir = readdir(dirp)) == NULL) {
1253c80476e4SDavid E. O'Brien 		(void) xsnprintf(pathname, pathlen,
1254c80476e4SDavid E. O'Brien 		    CGETS(23, 21, "getcwd: Read error in \"..\" (%s)"),
1255c80476e4SDavid E. O'Brien 		    strerror(errno));
1256c80476e4SDavid E. O'Brien 		goto fail;
1257c80476e4SDavid E. O'Brien 	    }
1258c80476e4SDavid E. O'Brien 	    if (stat(dir->d_name, &dd) == -1) {
1259c80476e4SDavid E. O'Brien 		(void) xsnprintf(pathname, pathlen,
1260c80476e4SDavid E. O'Brien 		    CGETS(23, 25, "getcwd: Cannot stat directory \"%s\" (%s)"),
1261c80476e4SDavid E. O'Brien 		    dir->d_name, strerror(errno));
1262c80476e4SDavid E. O'Brien 		goto fail;
1263c80476e4SDavid E. O'Brien 	    }
1264c80476e4SDavid E. O'Brien 	} while (dd.st_ino  != d.st_ino  ||
1265c80476e4SDavid E. O'Brien 		 dd.st_dev  != d.st_dev  ||
1266c80476e4SDavid E. O'Brien 		 dd.st_size != d.st_size);
126745e5710bSMark Peek 	closedir(dirp);
1268c80476e4SDavid E. O'Brien 	dirp = NULL;
1269c80476e4SDavid E. O'Brien 	pnptr = strnrcpy(dirp->d_name, pnptr, pnptr - pathbuf);
1270c80476e4SDavid E. O'Brien 	pnptr = strnrcpy("/", pnptr, pnptr - pathbuf);
1271c80476e4SDavid E. O'Brien     }
1272c80476e4SDavid E. O'Brien 
1273c80476e4SDavid E. O'Brien     if (*pnptr == '\0')		/* current dir == root dir */
1274c80476e4SDavid E. O'Brien 	(void) strncpy(pathname, "/", pathlen);
1275c80476e4SDavid E. O'Brien     else {
1276c80476e4SDavid E. O'Brien 	(void) strncpy(pathname, pnptr, pathlen);
1277c80476e4SDavid E. O'Brien 	pathname[pathlen - 1] = '\0';
1278c80476e4SDavid E. O'Brien 	if (chdir(pnptr) == -1) {
1279c80476e4SDavid E. O'Brien 	    (void) xsnprintf(pathname, MAXPATHLEN, CGETS(23, 22,
1280c80476e4SDavid E. O'Brien 		    "getcwd: Cannot change back to \".\" (%s)"),
1281c80476e4SDavid E. O'Brien 		    strerror(errno));
1282c80476e4SDavid E. O'Brien 	    return NULL;
1283c80476e4SDavid E. O'Brien 	}
1284c80476e4SDavid E. O'Brien     }
1285c80476e4SDavid E. O'Brien     return pathname;
1286c80476e4SDavid E. O'Brien 
1287c80476e4SDavid E. O'Brien fail:
1288c80476e4SDavid E. O'Brien     serrno = errno;
1289c80476e4SDavid E. O'Brien     (void) chdir(strnrcpy(".", pnptr, pnptr - pathbuf));
1290c80476e4SDavid E. O'Brien     errno = serrno;
1291c80476e4SDavid E. O'Brien     return NULL;
1292c80476e4SDavid E. O'Brien }
1293c80476e4SDavid E. O'Brien 
1294c80476e4SDavid E. O'Brien # else /* ! hp9000s500 */
1295c80476e4SDavid E. O'Brien 
1296c80476e4SDavid E. O'Brien 
1297c80476e4SDavid E. O'Brien char *
xgetcwd(char * pathname,size_t pathlen)129845e5710bSMark Peek xgetcwd(char *pathname, size_t pathlen)
1299c80476e4SDavid E. O'Brien {
1300c80476e4SDavid E. O'Brien     DIR    *dp;
1301c80476e4SDavid E. O'Brien     struct dirent *d;
1302c80476e4SDavid E. O'Brien 
1303c80476e4SDavid E. O'Brien     struct stat st_root, st_cur, st_next, st_dotdot;
1304c80476e4SDavid E. O'Brien     char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
1305c80476e4SDavid E. O'Brien     char   *pathptr, *nextpathptr, *cur_name_add;
1306c80476e4SDavid E. O'Brien     int	   save_errno = 0;
1307c80476e4SDavid E. O'Brien 
1308c80476e4SDavid E. O'Brien     /* find the inode of root */
1309c80476e4SDavid E. O'Brien     if (stat("/", &st_root) == -1) {
1310c80476e4SDavid E. O'Brien 	(void) xsnprintf(pathname, pathlen, CGETS(23, 23,
1311c80476e4SDavid E. O'Brien 			"getcwd: Cannot stat \"/\" (%s)"),
1312c80476e4SDavid E. O'Brien 			strerror(errno));
1313c80476e4SDavid E. O'Brien 	return NULL;
1314c80476e4SDavid E. O'Brien     }
1315c80476e4SDavid E. O'Brien     pathbuf[MAXPATHLEN - 1] = '\0';
1316c80476e4SDavid E. O'Brien     pathptr = &pathbuf[MAXPATHLEN - 1];
1317c80476e4SDavid E. O'Brien     nextpathbuf[MAXPATHLEN - 1] = '\0';
1318c80476e4SDavid E. O'Brien     cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
1319c80476e4SDavid E. O'Brien 
1320c80476e4SDavid E. O'Brien     /* find the inode of the current directory */
1321c80476e4SDavid E. O'Brien     if (lstat(".", &st_cur) == -1) {
1322c80476e4SDavid E. O'Brien 	(void) xsnprintf(pathname, pathlen, CGETS(23, 24,
1323c80476e4SDavid E. O'Brien 			 "getcwd: Cannot stat \".\" (%s)"),
1324c80476e4SDavid E. O'Brien 			 strerror(errno));
1325c80476e4SDavid E. O'Brien 	return NULL;
1326c80476e4SDavid E. O'Brien     }
1327c80476e4SDavid E. O'Brien     nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf);
1328c80476e4SDavid E. O'Brien 
1329c80476e4SDavid E. O'Brien     /* Descend to root */
1330c80476e4SDavid E. O'Brien     for (;;) {
1331c80476e4SDavid E. O'Brien 
1332c80476e4SDavid E. O'Brien 	/* look if we found root yet */
1333c80476e4SDavid E. O'Brien 	if (st_cur.st_ino == st_root.st_ino &&
1334c80476e4SDavid E. O'Brien 	    DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
1335c80476e4SDavid E. O'Brien 	    (void) strncpy(pathname, *pathptr != '/' ? "/" : pathptr, pathlen);
1336c80476e4SDavid E. O'Brien 	    pathname[pathlen - 1] = '\0';
1337c80476e4SDavid E. O'Brien 	    return pathname;
1338c80476e4SDavid E. O'Brien 	}
1339c80476e4SDavid E. O'Brien 
1340c80476e4SDavid E. O'Brien 	/* open the parent directory */
1341c80476e4SDavid E. O'Brien 	if (stat(nextpathptr, &st_dotdot) == -1) {
1342c80476e4SDavid E. O'Brien 	    (void) xsnprintf(pathname, pathlen, CGETS(23, 25,
1343c80476e4SDavid E. O'Brien 			     "getcwd: Cannot stat directory \"%s\" (%s)"),
1344c80476e4SDavid E. O'Brien 			     nextpathptr, strerror(errno));
1345c80476e4SDavid E. O'Brien 	    return NULL;
1346c80476e4SDavid E. O'Brien 	}
1347c80476e4SDavid E. O'Brien 	if ((dp = opendir(nextpathptr)) == NULL) {
1348c80476e4SDavid E. O'Brien 	    (void) xsnprintf(pathname, pathlen, CGETS(23, 26,
1349c80476e4SDavid E. O'Brien 			     "getcwd: Cannot open directory \"%s\" (%s)"),
1350c80476e4SDavid E. O'Brien 			     nextpathptr, strerror(errno));
1351c80476e4SDavid E. O'Brien 	    return NULL;
1352c80476e4SDavid E. O'Brien 	}
1353c80476e4SDavid E. O'Brien 
1354c80476e4SDavid E. O'Brien 	/* look in the parent for the entry with the same inode */
1355c80476e4SDavid E. O'Brien 	if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
1356c80476e4SDavid E. O'Brien 	    /* Parent has same device. No need to stat every member */
1357c80476e4SDavid E. O'Brien 	    for (d = readdir(dp); d != NULL; d = readdir(dp)) {
1358c80476e4SDavid E. O'Brien #ifdef __clipper__
135923338178SMark Peek 		if (((unsigned long)d->d_ino & 0xffff) == st_cur.st_ino)
1360c80476e4SDavid E. O'Brien 		    break;
1361c80476e4SDavid E. O'Brien #else
136223338178SMark Peek 		if (d->d_ino == st_cur.st_ino)
1363c80476e4SDavid E. O'Brien 		    break;
1364c80476e4SDavid E. O'Brien #endif
1365c80476e4SDavid E. O'Brien 	    }
1366c80476e4SDavid E. O'Brien 	}
1367c80476e4SDavid E. O'Brien 	else {
1368c80476e4SDavid E. O'Brien 	    /*
1369c80476e4SDavid E. O'Brien 	     * Parent has a different device. This is a mount point so we
1370c80476e4SDavid E. O'Brien 	     * need to stat every member
1371c80476e4SDavid E. O'Brien 	     */
1372c80476e4SDavid E. O'Brien 	    for (d = readdir(dp); d != NULL; d = readdir(dp)) {
1373c80476e4SDavid E. O'Brien 		if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
1374c80476e4SDavid E. O'Brien 		    continue;
1375c80476e4SDavid E. O'Brien 		(void)strncpy(cur_name_add, d->d_name,
1376c80476e4SDavid E. O'Brien 		    (size_t) (&nextpathbuf[sizeof(nextpathbuf) - 1] - cur_name_add));
1377c80476e4SDavid E. O'Brien 		if (lstat(nextpathptr, &st_next) == -1) {
1378c80476e4SDavid E. O'Brien 		    /*
1379c80476e4SDavid E. O'Brien 		     * We might not be able to stat() some path components
1380c80476e4SDavid E. O'Brien 		     * if we are using afs, but this is not an error as
1381c80476e4SDavid E. O'Brien 		     * long as we find the one we need; we also save the
1382c80476e4SDavid E. O'Brien 		     * first error to report it if we don't finally succeed.
1383c80476e4SDavid E. O'Brien 		     */
1384c80476e4SDavid E. O'Brien 		    if (save_errno == 0)
1385c80476e4SDavid E. O'Brien 			save_errno = errno;
1386c80476e4SDavid E. O'Brien 		    continue;
1387c80476e4SDavid E. O'Brien 		}
1388c80476e4SDavid E. O'Brien 		/* check if we found it yet */
1389c80476e4SDavid E. O'Brien 		if (st_next.st_ino == st_cur.st_ino &&
1390c80476e4SDavid E. O'Brien 		    DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
1391c80476e4SDavid E. O'Brien 		    break;
1392c80476e4SDavid E. O'Brien 	    }
1393c80476e4SDavid E. O'Brien 	}
1394c80476e4SDavid E. O'Brien 	if (d == NULL) {
1395c80476e4SDavid E. O'Brien 	    (void) xsnprintf(pathname, pathlen, CGETS(23, 27,
1396c80476e4SDavid E. O'Brien 			     "getcwd: Cannot find \".\" in \"..\" (%s)"),
1397c80476e4SDavid E. O'Brien 			     strerror(save_errno ? save_errno : ENOENT));
139845e5710bSMark Peek 	    closedir(dp);
1399c80476e4SDavid E. O'Brien 	    return NULL;
1400c80476e4SDavid E. O'Brien 	}
1401c80476e4SDavid E. O'Brien 	else
1402c80476e4SDavid E. O'Brien 	    save_errno = 0;
1403c80476e4SDavid E. O'Brien 	st_cur = st_dotdot;
1404c80476e4SDavid E. O'Brien 	pathptr = strnrcpy(pathptr, d->d_name, pathptr - pathbuf);
1405c80476e4SDavid E. O'Brien 	pathptr = strnrcpy(pathptr, "/", pathptr - pathbuf);
1406c80476e4SDavid E. O'Brien 	nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf);
1407c80476e4SDavid E. O'Brien 	*cur_name_add = '\0';
140845e5710bSMark Peek 	closedir(dp);
1409c80476e4SDavid E. O'Brien     }
1410c80476e4SDavid E. O'Brien } /* end getcwd */
1411c80476e4SDavid E. O'Brien # endif /* hp9000s500 */
1412c80476e4SDavid E. O'Brien 
1413c80476e4SDavid E. O'Brien /* strnrcpy():
1414c80476e4SDavid E. O'Brien  *	Like strncpy, going backwards and returning the new pointer
1415c80476e4SDavid E. O'Brien  */
1416c80476e4SDavid E. O'Brien static char *
strnrcpy(char * ptr,char * str,size_t siz)141745e5710bSMark Peek strnrcpy(char *ptr, char *str, size_t siz)
1418c80476e4SDavid E. O'Brien {
141923338178SMark Peek     int len = strlen(str);
1420c80476e4SDavid E. O'Brien     if (siz == 0)
1421c80476e4SDavid E. O'Brien 	return ptr;
1422c80476e4SDavid E. O'Brien 
1423c80476e4SDavid E. O'Brien     while (len && siz--)
1424c80476e4SDavid E. O'Brien 	*--ptr = str[--len];
1425c80476e4SDavid E. O'Brien 
1426c80476e4SDavid E. O'Brien     return (ptr);
1427c80476e4SDavid E. O'Brien } /* end strnrcpy */
142823338178SMark Peek #endif /* !HAVE_GETCWD */
1429c80476e4SDavid E. O'Brien 
1430c80476e4SDavid E. O'Brien #ifdef apollo
1431c80476e4SDavid E. O'Brien /***
1432c80476e4SDavid E. O'Brien  *** Domain/OS
1433c80476e4SDavid E. O'Brien  ***/
1434c80476e4SDavid E. O'Brien #include <apollo/base.h>
1435c80476e4SDavid E. O'Brien #include <apollo/loader.h>
1436c80476e4SDavid E. O'Brien #include <apollo/error.h>
1437c80476e4SDavid E. O'Brien 
1438c80476e4SDavid E. O'Brien 
1439c80476e4SDavid E. O'Brien static char *
apperr(status_$t * st)144045e5710bSMark Peek apperr(status_$t *st)
1441c80476e4SDavid E. O'Brien {
144245e5710bSMark Peek     static char *buf; /* = NULL */
1443c80476e4SDavid E. O'Brien     short e_subl, e_modl, e_codel;
1444c80476e4SDavid E. O'Brien     error_$string_t e_sub, e_mod, e_code;
1445c80476e4SDavid E. O'Brien 
1446c80476e4SDavid E. O'Brien     error_$get_text(*st, e_sub, &e_subl, e_mod, &e_modl, e_code, &e_codel);
1447c80476e4SDavid E. O'Brien     e_sub[e_subl] = '\0';
1448c80476e4SDavid E. O'Brien     e_code[e_codel] = '\0';
1449c80476e4SDavid E. O'Brien     e_mod[e_modl] = '\0';
145045e5710bSMark Peek     xfree(buf);
145145e5710bSMark Peek     buf = xasprintf("%s (%s/%s)", e_code, e_sub, e_mod);
1452c80476e4SDavid E. O'Brien 
1453c80476e4SDavid E. O'Brien     return(buf);
1454c80476e4SDavid E. O'Brien }
1455c80476e4SDavid E. O'Brien 
1456c80476e4SDavid E. O'Brien static int
llib(Char * s)145745e5710bSMark Peek llib(Char *s)
1458c80476e4SDavid E. O'Brien {
1459c80476e4SDavid E. O'Brien     short len = Strlen(s);
1460c80476e4SDavid E. O'Brien     status_$t st;
1461c80476e4SDavid E. O'Brien     char *t;
1462c80476e4SDavid E. O'Brien 
1463c80476e4SDavid E. O'Brien     loader_$inlib(t = short2str(s), len, &st);
1464c80476e4SDavid E. O'Brien     if (st.all != status_$ok)
1465c80476e4SDavid E. O'Brien 	stderror(ERR_SYSTEM, t, apperr(&st));
1466c80476e4SDavid E. O'Brien }
1467c80476e4SDavid E. O'Brien 
1468c80476e4SDavid E. O'Brien /*ARGSUSED*/
1469c80476e4SDavid E. O'Brien void
doinlib(Char ** v,struct command * c)147045e5710bSMark Peek doinlib(Char **v, struct command *c)
1471c80476e4SDavid E. O'Brien {
147245e5710bSMark Peek     Char **globbed;
147345e5710bSMark Peek 
1474c80476e4SDavid E. O'Brien     setname(short2str(*v++));
147545e5710bSMark Peek     v = glob_all_or_error(v);
147645e5710bSMark Peek     globbed = v;
147745e5710bSMark Peek     cleanup_push(globbed, blk_cleanup);
1478c80476e4SDavid E. O'Brien 
1479c80476e4SDavid E. O'Brien     while (v && *v)
1480c80476e4SDavid E. O'Brien 	llib(*v++);
148145e5710bSMark Peek     cleanup_until(globbed);
1482c80476e4SDavid E. O'Brien }
1483c80476e4SDavid E. O'Brien 
1484c80476e4SDavid E. O'Brien int
getv(Char * v)148545e5710bSMark Peek getv(Char *v)
1486c80476e4SDavid E. O'Brien {
1487c80476e4SDavid E. O'Brien     if (eq(v, STRbsd43))
1488c80476e4SDavid E. O'Brien 	return(1);
1489c80476e4SDavid E. O'Brien     else if (eq(v, STRsys53))
1490c80476e4SDavid E. O'Brien 	return(0);
1491c80476e4SDavid E. O'Brien     else
1492c80476e4SDavid E. O'Brien 	stderror(ERR_NAME | ERR_SYSTEM, short2str(v),
1493c80476e4SDavid E. O'Brien 		 CGETS(23, 28, "Invalid system type"));
1494c80476e4SDavid E. O'Brien     /*NOTREACHED*/
1495c80476e4SDavid E. O'Brien     return(0);
1496c80476e4SDavid E. O'Brien }
1497c80476e4SDavid E. O'Brien 
1498c80476e4SDavid E. O'Brien /*ARGSUSED*/
1499c80476e4SDavid E. O'Brien void
dover(Char ** v,struct command * c)150045e5710bSMark Peek dover(Char **v, struct command *c)
1501c80476e4SDavid E. O'Brien {
1502c80476e4SDavid E. O'Brien     Char *p;
1503c80476e4SDavid E. O'Brien 
1504c80476e4SDavid E. O'Brien     setname(short2str(*v++));
1505c80476e4SDavid E. O'Brien     if (!*v) {
1506c80476e4SDavid E. O'Brien 	if (!(p = tgetenv(STRSYSTYPE)))
1507c80476e4SDavid E. O'Brien 	    stderror(ERR_NAME | ERR_STRING,
1508c80476e4SDavid E. O'Brien 		     CGETS(23, 29, "System type is not set"));
1509c80476e4SDavid E. O'Brien 	xprintf("%S\n", p);
1510c80476e4SDavid E. O'Brien     }
1511c80476e4SDavid E. O'Brien     else {
1512c80476e4SDavid E. O'Brien 	tsetenv(STRSYSTYPE, getv(*v) ? STRbsd43 : STRsys53);
1513c80476e4SDavid E. O'Brien 	dohash(NULL, NULL);
1514c80476e4SDavid E. O'Brien     }
1515c80476e4SDavid E. O'Brien }
1516c80476e4SDavid E. O'Brien 
1517c80476e4SDavid E. O'Brien /*
1518c80476e4SDavid E. O'Brien  * Many thanks to rees@citi.umich.edu (Jim Rees) and
1519c80476e4SDavid E. O'Brien  *                mathys@ssdt-tempe.sps.mot.com (Yves Mathys)
1520c80476e4SDavid E. O'Brien  * For figuring out how to do this... I could have never done
1521c80476e4SDavid E. O'Brien  * it without their help.
1522c80476e4SDavid E. O'Brien  */
1523c80476e4SDavid E. O'Brien typedef short enum {
1524c80476e4SDavid E. O'Brien 	name_$wdir_type,
1525c80476e4SDavid E. O'Brien 	name_$ndir_type,
1526c80476e4SDavid E. O'Brien 	name_$node_dir_type,
1527c80476e4SDavid E. O'Brien } name_$dir_type_t;
1528c80476e4SDavid E. O'Brien 
1529c80476e4SDavid E. O'Brien /*ARGSUSED*/
1530c80476e4SDavid E. O'Brien void
dorootnode(Char ** v,struct command * c)153145e5710bSMark Peek dorootnode(Char **v, struct command *c)
1532c80476e4SDavid E. O'Brien {
1533c80476e4SDavid E. O'Brien     name_$dir_type_t dirtype = name_$node_dir_type;
1534c80476e4SDavid E. O'Brien     uid_$t uid;
1535c80476e4SDavid E. O'Brien     status_$t st;
1536c80476e4SDavid E. O'Brien     char *name;
1537c80476e4SDavid E. O'Brien     short namelen;
1538c80476e4SDavid E. O'Brien 
1539c80476e4SDavid E. O'Brien     setname(short2str(*v++));
1540c80476e4SDavid E. O'Brien 
1541c80476e4SDavid E. O'Brien     name = short2str(*v);
1542c80476e4SDavid E. O'Brien     namelen = strlen(name);
1543c80476e4SDavid E. O'Brien 
1544c80476e4SDavid E. O'Brien     name_$resolve(name, &namelen, &uid, &st);
1545c80476e4SDavid E. O'Brien     if (st.all != status_$ok)
1546c80476e4SDavid E. O'Brien 	stderror(ERR_SYSTEM, name, apperr(&st));
1547c80476e4SDavid E. O'Brien     namelen = 0;
1548c80476e4SDavid E. O'Brien     name_$set_diru(&uid, "", &namelen, &dirtype, &st);
1549c80476e4SDavid E. O'Brien     if (st.all != status_$ok)
1550c80476e4SDavid E. O'Brien 	stderror(ERR_SYSTEM, name, apperr(&st));
1551c80476e4SDavid E. O'Brien     dohash(NULL, NULL);
1552c80476e4SDavid E. O'Brien }
1553c80476e4SDavid E. O'Brien 
1554c80476e4SDavid E. O'Brien int
isapad(void)155545e5710bSMark Peek isapad(void)
1556c80476e4SDavid E. O'Brien {
1557c80476e4SDavid E. O'Brien     static int res = -1;
1558c80476e4SDavid E. O'Brien     static status_$t st;
1559c80476e4SDavid E. O'Brien 
1560c80476e4SDavid E. O'Brien     if (res == -1) {
1561c80476e4SDavid E. O'Brien 	int strm;
1562c80476e4SDavid E. O'Brien 	if (isatty(0))
1563c80476e4SDavid E. O'Brien 	    strm = 0;
1564c80476e4SDavid E. O'Brien 	if (isatty(1))
1565c80476e4SDavid E. O'Brien 	    strm = 1;
1566c80476e4SDavid E. O'Brien 	if (isatty(2))
1567c80476e4SDavid E. O'Brien 	    strm = 2;
1568c80476e4SDavid E. O'Brien 	else {
1569c80476e4SDavid E. O'Brien 	    res = 0;
1570c80476e4SDavid E. O'Brien 	    st.all = status_$ok;
1571c80476e4SDavid E. O'Brien 	    return(res);
1572c80476e4SDavid E. O'Brien 	}
1573c80476e4SDavid E. O'Brien 	res = stream_$isavt(&strm, &st);
1574c80476e4SDavid E. O'Brien 	res = res ? 1 : 0;
1575c80476e4SDavid E. O'Brien     }
1576c80476e4SDavid E. O'Brien     else {
1577c80476e4SDavid E. O'Brien 	if (st.all != status_$ok)
1578c80476e4SDavid E. O'Brien 	    stderror(ERR_SYSTEM, "stream_$isavt", apperr(&st));
1579c80476e4SDavid E. O'Brien     }
1580c80476e4SDavid E. O'Brien     return(res);
1581c80476e4SDavid E. O'Brien }
1582c80476e4SDavid E. O'Brien #endif
1583*9ccc37e3SMark Peek 
1584*9ccc37e3SMark Peek #if defined(__CYGWIN__) && !defined(NO_CRYPT)
1585*9ccc37e3SMark Peek #undef CHAR		/* Collides with Win32 API */
1586*9ccc37e3SMark Peek #define WIN32_LEAN_AND_MEAN
1587*9ccc37e3SMark Peek #include <windows.h>
1588*9ccc37e3SMark Peek #include <sys/cygwin.h>
1589*9ccc37e3SMark Peek char *
cygwin_xcrypt(struct passwd * pw,const char * password,const char * expected_pwd)1590*9ccc37e3SMark Peek cygwin_xcrypt(struct passwd *pw, const char *password, const char *expected_pwd)
1591*9ccc37e3SMark Peek {
1592*9ccc37e3SMark Peek     static char invalid_password[] = "\377";
1593*9ccc37e3SMark Peek     HANDLE token = cygwin_logon_user(pw, password);
1594*9ccc37e3SMark Peek     if (token == INVALID_HANDLE_VALUE)
1595*9ccc37e3SMark Peek 	return invalid_password;
1596*9ccc37e3SMark Peek     CloseHandle(token);
1597*9ccc37e3SMark Peek     return (char *) expected_pwd;
1598*9ccc37e3SMark Peek }
1599*9ccc37e3SMark Peek #endif /* __CYGWIN__ && !NO_CRYPT */
1600