159243Sobrien/*
259243Sobrien * tc.os.c: OS Dependent builtin functions
359243Sobrien */
459243Sobrien/*-
559243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California.
659243Sobrien * All rights reserved.
759243Sobrien *
859243Sobrien * Redistribution and use in source and binary forms, with or without
959243Sobrien * modification, are permitted provided that the following conditions
1059243Sobrien * are met:
1159243Sobrien * 1. Redistributions of source code must retain the above copyright
1259243Sobrien *    notice, this list of conditions and the following disclaimer.
1359243Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1459243Sobrien *    notice, this list of conditions and the following disclaimer in the
1559243Sobrien *    documentation and/or other materials provided with the distribution.
16100616Smp * 3. Neither the name of the University nor the names of its contributors
1759243Sobrien *    may be used to endorse or promote products derived from this software
1859243Sobrien *    without specific prior written permission.
1959243Sobrien *
2059243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2159243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2259243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2359243Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2459243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2559243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2659243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2759243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2859243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2959243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3059243Sobrien * SUCH DAMAGE.
3159243Sobrien */
3259243Sobrien#include "sh.h"
3359243Sobrien#include "tw.h"
3459243Sobrien#include "ed.h"
3559243Sobrien#include "ed.defns.h"		/* for the function names */
3659243Sobrien#include "sh.decls.h"
3759243Sobrien
3859243Sobrien#ifdef _UWIN
3959243Sobrien#define TIOCGPGRP TIOCGETPGRP
4059243Sobrien#define TIOCSPGRP TIOCSETPGRP
4159243Sobrien#endif
4259243Sobrien
4359243Sobrien/***
4459243Sobrien *** MACH
4559243Sobrien ***/
4659243Sobrien
4759243Sobrien#ifdef MACH
4859243Sobrien/* dosetpath -- setpath built-in command
4959243Sobrien *
5059243Sobrien **********************************************************************
5159243Sobrien * HISTORY
5259243Sobrien * 08-May-88  Richard Draves (rpd) at Carnegie-Mellon University
5359243Sobrien *	Major changes to remove artificial limits on sizes and numbers
5459243Sobrien *	of paths.
5559243Sobrien *
5659243Sobrien **********************************************************************
5759243Sobrien */
5859243Sobrien
5959243Sobrien#ifdef MACH
6059243Sobrienstatic Char STRCPATH[] = {'C', 'P', 'A', 'T', 'H', '\0'};
6159243Sobrienstatic Char STRLPATH[] = {'L', 'P', 'A', 'T', 'H', '\0'};
6259243Sobrienstatic Char STRMPATH[] = {'M', 'P', 'A', 'T', 'H', '\0'};
6359243Sobrien# if EPATH
6459243Sobrienstatic Char STREPATH[] = {'E', 'P', 'A', 'T', 'H', '\0'};
6559243Sobrien# endif
6659243Sobrien#endif /* MACH */
6759243Sobrienstatic Char *syspaths[] = {STRKPATH, STRCPATH, STRLPATH, STRMPATH,
6859243Sobrien
6959243Sobrien#if EPATH
7059243Sobrien	STREPATH,
7159243Sobrien#endif
7259243Sobrien	 0};
7359243Sobrien#define LOCALSYSPATH	"/usr/local"
7459243Sobrien
7559243Sobrien/*ARGSUSED*/
7659243Sobrienvoid
77167465Smpdosetpath(Char **arglist, struct command *c)
7859243Sobrien{
7959243Sobrien    extern char *getenv();
8059243Sobrien    Char  **pathvars, **cmdargs;
8159243Sobrien    char  **spaths, **cpaths, **cmds;
8259243Sobrien    char   *tcp;
8359243Sobrien    unsigned int npaths, ncmds;
8459243Sobrien    int     i, sysflag;
8559243Sobrien
86167465Smp    pintr_disabled++;
87167465Smp    cleanup_push(&pintr_disabled, disabled_cleanup);
8859243Sobrien
8959243Sobrien    /*
9059243Sobrien     * setpath(3) uses stdio and we want 0, 1, 2 to work...
9159243Sobrien     */
9259243Sobrien    if (!didfds) {
9359243Sobrien	(void) dcopy(SHIN, 0);
9459243Sobrien	(void) dcopy(SHOUT, 1);
9559243Sobrien	(void) dcopy(SHDIAG, 2);
9659243Sobrien	didfds = 1;
9759243Sobrien    }
9859243Sobrien
9959243Sobrien    for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++);
10059243Sobrien    npaths = i - 1;
10159243Sobrien
10259243Sobrien    cmdargs = &arglist[i];
10359243Sobrien    for (; arglist[i]; i++);
10459243Sobrien    ncmds = i - npaths - 1;
10559243Sobrien
10659243Sobrien    if (npaths) {
10759243Sobrien	sysflag = 0;
10859243Sobrien	pathvars = &arglist[1];
10959243Sobrien    }
11059243Sobrien    else {
11159243Sobrien	sysflag = 1;
11259243Sobrien	npaths = (sizeof syspaths / sizeof *syspaths) - 1;
11359243Sobrien	pathvars = syspaths;
11459243Sobrien    }
11559243Sobrien
11659243Sobrien    /* note that npaths != 0 */
11759243Sobrien
118167465Smp    spaths = xmalloc(npaths * sizeof *spaths);
119167465Smp    setzero(spaths, npaths * sizeof *spaths);
120167465Smp    cpaths = xmalloc((npaths + 1) * sizeof *cpaths);
121167465Smp    setzero(cpaths, (npaths + 1) * sizeof *cpaths);
122167465Smp    cmds = xmalloc((ncmds + 1) * sizeof *cmds);
123167465Smp    setzero(cmds, (ncmds + 1) * sizeof *cmds);
12459243Sobrien    for (i = 0; i < npaths; i++) {
12559243Sobrien	char   *val = getenv(short2str(pathvars[i]));
12659243Sobrien
12759243Sobrien	if (val == NULL)
12859243Sobrien	    val = "";
12959243Sobrien
130167465Smp	spaths[i] = xmalloc((Strlen(pathvars[i]) + strlen(val) + 2) *
131167465Smp			    sizeof **spaths);
13259243Sobrien	(void) strcpy(spaths[i], short2str(pathvars[i]));
13359243Sobrien	(void) strcat(spaths[i], "=");
13459243Sobrien	(void) strcat(spaths[i], val);
13559243Sobrien	cpaths[i] = spaths[i];
13659243Sobrien    }
13759243Sobrien
13859243Sobrien    for (i = 0; i < ncmds; i++) {
139167465Smp	Char   *val = globone(cmdargs[i], G_ERROR);/*FIXRESET*/
14059243Sobrien
14159243Sobrien	if (val == NULL)
14259243Sobrien	    goto abortpath;
143167465Smp	cmds[i] = strsave(short2str(val));
14459243Sobrien    }
14559243Sobrien
14659243Sobrien
14759243Sobrien    if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) {
14859243Sobrienabortpath:
14959243Sobrien	if (spaths) {
15059243Sobrien	    for (i = 0; i < npaths; i++)
151167465Smp		xfree(spaths[i]);
152167465Smp	    xfree(spaths);
15359243Sobrien	}
154167465Smp	xfree(cpaths);
15559243Sobrien	if (cmds) {
15659243Sobrien	    for (i = 0; i < ncmds; i++)
157167465Smp		xfree(cmds[i]);
158167465Smp	    xfree(cmds);
15959243Sobrien	}
16059243Sobrien
161167465Smp	cleanup_until(&pintr_disabled);
16259243Sobrien	donefds();
16359243Sobrien	return;
16459243Sobrien    }
16559243Sobrien
16659243Sobrien    for (i = 0; i < npaths; i++) {
16759243Sobrien	Char	*val, *name;
16859243Sobrien
16959243Sobrien	name = str2short(cpaths[i]);
17059243Sobrien	for (val = str2short(cpaths[i]); val && *val && *val != '='; val++);
17159243Sobrien	if (val && *val == '=') {
17259243Sobrien	    *val++ = '\0';
17359243Sobrien
174167465Smp	    tsetenv(name, val);/*FIXRESET*/
17559243Sobrien	    if (Strcmp(name, STRKPATH) == 0) {
176167465Smp		importpath(val);/*FIXRESET*/
17759243Sobrien		if (havhash)
178167465Smp		    dohash(NULL, NULL);/*FIXRESET*/
17959243Sobrien	    }
18059243Sobrien	    *--val = '=';
18159243Sobrien	}
18259243Sobrien    }
183167465Smp    cleanup_until(&pintr_disabled);
18459243Sobrien    donefds();
18559243Sobrien}
18659243Sobrien#endif /* MACH */
18759243Sobrien
18859243Sobrien/***
18959243Sobrien *** AIX
19059243Sobrien ***/
19159243Sobrien#ifdef TCF
19259243Sobrien/* ARGSUSED */
19359243Sobrienvoid
194167465Smpdogetxvers(Char **v, struct command *c)
19559243Sobrien{
19659243Sobrien    char    xvers[MAXPATHLEN];
19759243Sobrien
19859243Sobrien    if (getxvers(xvers, MAXPATHLEN) == -1)
19959243Sobrien	stderror(ERR_SYSTEM, "getxvers", strerror(errno));
20059243Sobrien    xprintf("%s\n", xvers);
20159243Sobrien    flush();
20259243Sobrien}
20359243Sobrien
20459243Sobrien/*ARGSUSED*/
20559243Sobrienvoid
206167465Smpdosetxvers(Char **v, struct command *c)
20759243Sobrien{
20859243Sobrien    char   *xvers;
20959243Sobrien
21059243Sobrien    ++v;
21159243Sobrien    if (!*v || *v[0] == '\0')
21259243Sobrien	xvers = "";
21359243Sobrien    else
21459243Sobrien	xvers = short2str(*v);
21559243Sobrien    if (setxvers(xvers) == -1)
21659243Sobrien	stderror(ERR_SYSTEM, "setxvers", strerror(errno));
21759243Sobrien}
21859243Sobrien
21959243Sobrien#include <sf.h>
22059243Sobrien#ifdef _AIXPS2
22159243Sobrien# define XC_PDP11	0x01
22259243Sobrien# define XC_23		0x02
22359243Sobrien# define XC_Z8K		0x03
22459243Sobrien# define XC_8086	0x04
22559243Sobrien# define XC_68K		0x05
22659243Sobrien# define XC_Z80		0x06
22759243Sobrien# define XC_VAX		0x07
22859243Sobrien# define XC_16032	0x08
22959243Sobrien# define XC_286		0x09
23059243Sobrien# define XC_386		0x0a
23159243Sobrien# define XC_S370	0x0b
23259243Sobrien#else
23359243Sobrien# include <sys/x.out.h>
23459243Sobrien#endif /* _AIXPS2 */
23559243Sobrien
23659243Sobrienstatic struct xc_cpu_t {
23759243Sobrien    short   xc_id;
23859243Sobrien    char   *xc_name;
23959243Sobrien}       xcpu[] =
24059243Sobrien{
24159243Sobrien    { XC_PDP11,	"pdp11"   },
24259243Sobrien    { XC_23,	"i370"    },
24359243Sobrien    { XC_Z8K,	"z8000"   },
24459243Sobrien    { XC_8086,	"i86"	  },
24559243Sobrien    { XC_68K,	"mc68000" },
24659243Sobrien    { XC_Z80,	"x80"	  },
24759243Sobrien    { XC_VAX,	"vax"	  },
24859243Sobrien    { XC_16032,	"ns16032" },
24959243Sobrien    { XC_286,	"i286"	  },
25059243Sobrien    { XC_386,	"i386"	  },
25159243Sobrien    { XC_S370,	"xa370"	  },
25259243Sobrien    { 0,	NULL      }
25359243Sobrien};
25459243Sobrien
25559243Sobrien/*
25659243Sobrien * our local hack table, stolen from x.out.h
25759243Sobrien */
25859243Sobrienstatic char *
259167465Smpgetxcode(short xcid)
26059243Sobrien{
26159243Sobrien    int     i;
26259243Sobrien
26359243Sobrien    for (i = 0; xcpu[i].xc_name != NULL; i++)
26459243Sobrien	if (xcpu[i].xc_id == xcid)
26559243Sobrien	    return (xcpu[i].xc_name);
26659243Sobrien    return (NULL);
26759243Sobrien}
26859243Sobrien
26959243Sobrienstatic short
270167465Smpgetxid(char *xcname)
27159243Sobrien{
27259243Sobrien    int     i;
27359243Sobrien
27459243Sobrien    for (i = 0; xcpu[i].xc_name != NULL; i++)
27559243Sobrien	if (strcmp(xcpu[i].xc_name, xcname) == 0)
27659243Sobrien	    return (xcpu[i].xc_id);
27759243Sobrien    return ((short) -1);
27859243Sobrien}
27959243Sobrien
28059243Sobrien
28159243Sobrien/*ARGSUSED*/
28259243Sobrienvoid
283167465Smpdogetspath(Char **v, struct command *c)
28459243Sobrien{
28559243Sobrien    int     i, j;
28659243Sobrien    sitepath_t p[MAXSITE];
28759243Sobrien    struct sf *st;
28859243Sobrien    static char *local = "LOCAL ";
28959243Sobrien
29059243Sobrien    if ((j = getspath(p, MAXSITE)) == -1)
29159243Sobrien	stderror(ERR_SYSTEM, "getspath", strerror(errno));
29259243Sobrien    for (i = 0; i < j && (p[i] & SPATH_CPU) != NOSITE; i++) {
29359243Sobrien	if (p[i] & SPATH_CPU) {
29459243Sobrien	    if ((p[i] & SPATH_MASK) == NULLSITE)
29559243Sobrien		xprintf(local);
29659243Sobrien	    else if ((st = sfxcode((short) (p[i] & SPATH_MASK))) != NULL)
29759243Sobrien		xprintf("%s ", st->sf_ctype);
29859243Sobrien	    else {
29959243Sobrien		char   *xc = getxcode(p[i] & SPATH_MASK);
30059243Sobrien
30159243Sobrien		if (xc != NULL)
30259243Sobrien		    xprintf("%s ", xc);
30359243Sobrien		else
30459243Sobrien		    xprintf("*cpu %d* ", (int) (p[i] & SPATH_MASK));
30559243Sobrien		/*
30659243Sobrien		 * BUG in the aix code... needs that cause if
30759243Sobrien		 * sfxcode fails once it fails for ever
30859243Sobrien		 */
30959243Sobrien		endsf();
31059243Sobrien	    }
31159243Sobrien	}
31259243Sobrien	else {
31359243Sobrien	    if (p[i] == NULLSITE)
31459243Sobrien		xprintf(local);
31559243Sobrien	    else if ((st = sfnum(p[i])) != NULL)
31659243Sobrien		xprintf("%s ", st->sf_sname);
31759243Sobrien	    else
31859243Sobrien		xprintf("*site %d* ", (int) (p[i] & SPATH_MASK));
31959243Sobrien	}
32059243Sobrien    }
32159243Sobrien    xputchar('\n');
32259243Sobrien    flush();
32359243Sobrien}
32459243Sobrien
32559243Sobrien/*ARGSUSED*/
32659243Sobrienvoid
327167465Smpdosetspath(Char **v, struct command *c)
32859243Sobrien{
32959243Sobrien    int     i;
33059243Sobrien    short   j;
33159243Sobrien    char   *s;
33259243Sobrien    sitepath_t p[MAXSITE];
33359243Sobrien    struct sf *st;
33459243Sobrien
33559243Sobrien    /*
33659243Sobrien     * sfname() on AIX G9.9 at least, mallocs too pointers p, q
33759243Sobrien     * then does the equivalent of while (*p++ == *q++) continue;
33859243Sobrien     * and then tries to free(p,q) them! Congrats to the wizard who
33959243Sobrien     * wrote that one. I bet he tested it really well too.
34059243Sobrien     * Sooo, we set dont_free :-)
34159243Sobrien     */
34259243Sobrien    dont_free = 1;
34359243Sobrien    for (i = 0, v++; *v && *v[0] != '\0'; v++, i++) {
34459243Sobrien	s = short2str(*v);
345145479Smp	if (isdigit(*s))
34659243Sobrien	    p[i] = atoi(s);
34759243Sobrien	else if (strcmp(s, "LOCAL") == 0)
34859243Sobrien	    p[i] = NULLSITE;
34959243Sobrien	else if ((st = sfctype(s)) != NULL)
35059243Sobrien	    p[i] = SPATH_CPU | st->sf_ccode;
35159243Sobrien	else if ((j = getxid(s)) != -1)
35259243Sobrien	    p[i] = SPATH_CPU | j;
35359243Sobrien	else if ((st = sfname(s)) != NULL)
35459243Sobrien	    p[i] = st->sf_id;
35559243Sobrien	else {
35659243Sobrien	    setname(s);
35759243Sobrien	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 1, "Bad cpu/site name"));
35859243Sobrien	}
35959243Sobrien	if (i == MAXSITE - 1)
36059243Sobrien	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 2, "Site path too long"));
36159243Sobrien    }
36259243Sobrien    if (setspath(p, i) == -1)
36359243Sobrien	stderror(ERR_SYSTEM, "setspath", strerror(errno));
36459243Sobrien    dont_free = 0;
36559243Sobrien}
36659243Sobrien
36759243Sobrien/* sitename():
36859243Sobrien *	Return the site name where the process is running
36959243Sobrien */
37059243Sobrienchar   *
371167465Smpsitename(pid_t pid)
37259243Sobrien{
37359243Sobrien    siteno_t ss;
37459243Sobrien    struct sf *st;
37559243Sobrien
37659243Sobrien    if ((ss = site(pid)) == -1 || (st = sfnum(ss)) == NULL)
37759243Sobrien	return CGETS(23, 3, "unknown");
37859243Sobrien    else
37959243Sobrien	return st->sf_sname;
38059243Sobrien}
38159243Sobrien
38259243Sobrienstatic int
383167465Smpmigratepid(pit_t pid, siteno_t new_site)
38459243Sobrien{
38559243Sobrien    struct sf *st;
38659243Sobrien    int     need_local;
38759243Sobrien
38859243Sobrien    need_local = (pid == 0) || (pid == getpid());
38959243Sobrien
390167465Smp    if (kill3(pid, SIGMIGRATE, new_site) < 0) {
39159243Sobrien	xprintf("%d: %s\n", pid, strerror(errno));
39259243Sobrien	return (-1);
39359243Sobrien    }
39459243Sobrien
39559243Sobrien    if (need_local) {
39659243Sobrien	if ((new_site = site(0)) == -1) {
39759243Sobrien	    xprintf(CGETS(23, 4, "site: %s\n"), strerror(errno));
39859243Sobrien	    return (-1);
39959243Sobrien	}
40059243Sobrien	if ((st = sfnum(new_site)) == NULL) {
40159243Sobrien	    xprintf(CGETS(23, 5, "%d: Site not found\n"), new_site);
40259243Sobrien	    return (-1);
40359243Sobrien	}
40459243Sobrien	if (setlocal(st->sf_local, strlen(st->sf_local)) == -1) {
40559243Sobrien	    xprintf(CGETS(23, 6, "setlocal: %s: %s\n"),
40659243Sobrien			  st->sf_local, strerror(errno));
40759243Sobrien	    return (-1);
40859243Sobrien	}
40959243Sobrien    }
41059243Sobrien    return (0);
41159243Sobrien}
41259243Sobrien
41359243Sobrien/*ARGSUSED*/
41459243Sobrienvoid
415167465Smpdomigrate(Char **v, struct command *c)
41659243Sobrien{
41759243Sobrien    struct sf *st;
41859243Sobrien    char   *s;
41959243Sobrien    Char   *cp;
42059243Sobrien    struct process *pp;
42159243Sobrien    int    err1 = 0;
42259243Sobrien    int    pid = 0;
42359243Sobrien    siteno_t new_site = 0;
42459243Sobrien
425167465Smp    pchild_disabled++;
426167465Smp    cleanup_push(&pchild_disabled, disabled_cleanup);
427167465Smp    if (setintr) {
428167465Smp	pintr_disabled++;
429167465Smp	cleanup_push(&pintr_disabled, disabled_cleanup);
430167465Smp    }
43159243Sobrien
43259243Sobrien    ++v;
43359243Sobrien    if (*v[0] == '-') {
43459243Sobrien	/*
43559243Sobrien	 * Do the -site.
43659243Sobrien	 */
43759243Sobrien	s = short2str(&v[0][1]);
43859243Sobrien	/*
43959243Sobrien	 * see comment in setspath()
44059243Sobrien	 */
44159243Sobrien	dont_free = 1;
44259243Sobrien	if ((st = sfname(s)) == NULL) {
443167465Smp	    dont_free = 0;
44459243Sobrien	    setname(s);
44559243Sobrien	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 7, "Site not found"));
44659243Sobrien	}
44759243Sobrien	dont_free = 0;
44859243Sobrien	new_site = st->sf_id;
44959243Sobrien	++v;
45059243Sobrien    }
45159243Sobrien
45259243Sobrien    if (!*v || *v[0] == '\0') {
45359243Sobrien	if (migratepid(0, new_site) == -1)
45459243Sobrien	    err1++;
45559243Sobrien    }
45659243Sobrien    else {
457167465Smp	Char **globbed;
45859243Sobrien
459167465Smp	v = glob_all_or_error(v);
460167465Smp	globbed = v;
461167465Smp	cleanup_push(globbed, blk_cleanup);
462167465Smp
46359243Sobrien	while (v && (cp = *v)) {
46459243Sobrien	    if (*cp == '%') {
46559243Sobrien		pp = pfind(cp);
466167465Smp		if (kill3(- pp->p_jobid, SIGMIGRATE, new_site) < 0) {
46759243Sobrien		    xprintf("%S: %s\n", cp, strerror(errno));
46859243Sobrien		    err1++;
46959243Sobrien		}
47059243Sobrien	    }
47159243Sobrien	    else if (!(Isdigit(*cp) || *cp == '-'))
47259243Sobrien		stderror(ERR_NAME | ERR_JOBARGS);
47359243Sobrien	    else {
47459243Sobrien		pid = atoi(short2str(cp));
47559243Sobrien		if (migratepid(pid, new_site) == -1)
47659243Sobrien		    err1++;
47759243Sobrien	    }
47859243Sobrien	    v++;
47959243Sobrien	}
480167465Smp	cleanup_until(globbed);
48159243Sobrien    }
48259243Sobrien
48359243Sobriendone:
484167465Smp    cleanup_until(&pchild_disabled);
48559243Sobrien    if (err1)
48659243Sobrien	stderror(ERR_SILENT);
48759243Sobrien}
48859243Sobrien
48959243Sobrien#endif /* TCF */
49059243Sobrien
49159243Sobrien/***
49259243Sobrien *** CRAY ddmode <velo@sesun3.epfl.ch> (Martin Ouwehand EPFL-SIC/SE)
49359243Sobrien ***/
49459243Sobrien#if defined(_CRAY) && !defined(_CRAYMPP)
49559243Sobrienvoid
496167465Smpdodmmode(Char **v, struct command *c)
49759243Sobrien{
49859243Sobrien    Char *cp = v[1];
49959243Sobrien
50059243Sobrien    USE(c);
50159243Sobrien
50259243Sobrien    if ( !cp ) {
50359243Sobrien	int mode;
50459243Sobrien
50559243Sobrien	mode = dmmode(0);
50659243Sobrien	dmmode(mode);
50759243Sobrien	xprintf("%d\n",mode);
50859243Sobrien    }
50959243Sobrien    else {
51059243Sobrien	if (cp[1] != '\0')
511167465Smp	    stderror(ERR_NAME | ERR_STRING,
51259243Sobrien		     CGETS(23, 30, "Too many arguments"));
51359243Sobrien	else
51459243Sobrien	    switch(*cp) {
51559243Sobrien	    case '0':
51659243Sobrien		dmmode(0);
51759243Sobrien		break;
51859243Sobrien	    case '1':
51959243Sobrien		dmmode(1);
52059243Sobrien		break;
52159243Sobrien	    default:
522167465Smp		stderror(ERR_NAME | ERR_STRING,
52359243Sobrien			 CGETS(23, 31, "Invalid argument"));
52459243Sobrien	    }
52559243Sobrien    }
52659243Sobrien}
52759243Sobrien#endif /* _CRAY && !_CRAYMPP */
52859243Sobrien
52959243Sobrien
53059243Sobrien/***
53159243Sobrien *** CONVEX Warps.
53259243Sobrien ***/
53359243Sobrien
53459243Sobrien#ifdef WARP
53559243Sobrien/*
53659243Sobrien * handle the funky warping of symlinks
53759243Sobrien */
53859243Sobrien#include <warpdb.h>
53959243Sobrien#include <sys/warp.h>
54059243Sobrien
54159243Sobrienstatic jmp_buf sigsys_buf;
54259243Sobrien
543167465Smpstatic void
544167465Smpcatch_sigsys(void)
54559243Sobrien{
546167465Smp    sigset_t set;
547167465Smp    sigemptyset(&set, SIGSYS);
548167465Smp    (void)sigprocmask(SIG_UNBLOCK, &set, NULL);
54959243Sobrien    longjmp(sigsys_buf, 1);
55059243Sobrien}
55159243Sobrien
55259243Sobrien
55359243Sobrien/*ARGSUSED*/
55459243Sobrienvoid
555167465Smpdowarp(Char **v, struct command *c)
55659243Sobrien{
55759243Sobrien    int     warp, oldwarp;
55859243Sobrien    struct warpent *we;
559167465Smp    volatile struct sigaction old_sigsys_handler;
56059243Sobrien    char   *newwarp;
56159243Sobrien
56259243Sobrien    if (setjmp(sigsys_buf)) {
563167465Smp	sigaction(SIGSYS, &old_sigsys_handler, NULL);
564167465Smp	stderror(ERR_NAME | ERR_STRING,
56559243Sobrien		 CGETS(23, 8, "You're trapped in a universe you never made"));
56659243Sobrien	return;
56759243Sobrien    }
568167465Smp    sigaction(SIGSYS, NULL, &old_sigsys_handler);
569167465Smp    signal(SIGSYS, catch_sigsys);
57059243Sobrien
57159243Sobrien    warp = getwarp();
57259243Sobrien
57359243Sobrien    v++;
57459243Sobrien    if (*v == 0) {		/* display warp value */
57559243Sobrien	if (warp < 0)
57659243Sobrien	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 9, "Getwarp failed"));
57759243Sobrien	we = getwarpbyvalue(warp);
57859243Sobrien	if (we)
57959243Sobrien	    printf("%s\n", we->w_name);
58059243Sobrien	else
58159243Sobrien	    printf("%d\n", warp);
58259243Sobrien    }
58359243Sobrien    else {			/* set warp value */
58459243Sobrien	oldwarp = warp;
58559243Sobrien	newwarp = short2str(*v);
58659243Sobrien	if (Isdigit(*v[0]))
58759243Sobrien	    warp = atoi(newwarp);
58859243Sobrien	else {
58959243Sobrien	    we = getwarpbyname(newwarp);
59059243Sobrien	    if (we)
59159243Sobrien		warp = we->w_value;
59259243Sobrien	    else
59359243Sobrien		warp = -1;
59459243Sobrien	}
59559243Sobrien	if ((warp < 0) || (warp >= WARP_MAXLINK))
59659243Sobrien	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 10, "Invalid warp"));
59759243Sobrien	if ((setwarp(warp) < 0) || (getwarp() != warp)) {
59859243Sobrien	    (void) setwarp(oldwarp);
59959243Sobrien	    stderror(ERR_NAME | ERR_STRING, CGETS(23, 11, "Setwarp failed"));
60059243Sobrien	}
60159243Sobrien    }
602167465Smp    sigaction(SIGSYS, &old_sigsys_handler, NULL);
60359243Sobrien}
60459243Sobrien#endif /* WARP */
60559243Sobrien
60659243Sobrien/***
60759243Sobrien *** Masscomp or HCX
60859243Sobrien ***/
60959243Sobrien/* Added, DAS DEC-90. */
61059243Sobrien#if defined(masscomp) || defined(_CX_UX)
611167465Smpstatic void
612167465Smpsetuniverse_cleanup(void *xbuf)
613167465Smp{
614167465Smp    char *buf;
615167465Smp
616167465Smp    buf = xbuf;
617167465Smp    setuniverse(buf);
618167465Smp}
619167465Smp
62059243Sobrien/*ARGSUSED*/
62159243Sobrienvoid
622167465Smpdouniverse(Char **v, struct command *c)
62359243Sobrien{
624145479Smp    Char *cp = v[1];
625145479Smp    Char *cp2;		/* dunno how many elements v comes in with */
62659243Sobrien    char    ubuf[100];
62759243Sobrien
62859243Sobrien    if (cp == 0) {
62959243Sobrien	(void) getuniverse(ubuf);
63059243Sobrien	xprintf("%s\n", ubuf);
63159243Sobrien    }
63259243Sobrien    else {
63359243Sobrien	cp2 = v[2];
63459243Sobrien	if (cp2 == 0) {
63559243Sobrien	    if (*cp == '\0' || setuniverse(short2str(cp)) != 0)
63659243Sobrien		stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe"));
63759243Sobrien	    }
63859243Sobrien	else {
63959243Sobrien	    (void) getuniverse(ubuf);
64059243Sobrien	    if (*cp == '\0' || setuniverse(short2str(cp)) != 0)
641167465Smp		stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe"));
642167465Smp	    cleanup_push(ubuf, setuniverse_cleanup);
643167465Smp	    if (setintr) {
644167465Smp		pintr_disabled++;
645167465Smp		cleanup_push(&pintr_disabled, disabled_cleanup);
646167465Smp	    }
64759243Sobrien	    lshift(v, 2);
64859243Sobrien	    if (setintr)
649167465Smp		cleanup_until(&pintr_disabled);
65059243Sobrien	    reexecute(c);
651167465Smp	    cleanup_until(ubuf);
65259243Sobrien	}
65359243Sobrien    }
65459243Sobrien}
65559243Sobrien#endif /* masscomp || _CX_UX */
65659243Sobrien
657131962Smp/***
658131962Smp *** BS2000/OSD POSIX (Fujitsu Siemens Computers)
659131962Smp ***/
660131962Smp#if defined(_OSD_POSIX)
661131962Smpstatic int
662131962Smpbs2upcase(char *str)
663131962Smp{
664131962Smp    enum { outside = ' ', singlequote='\'', doublequote='"'} string = outside;
665131962Smp
666131962Smp    char *white;
667131962Smp
668131962Smp    for (white = str + strlen(str) - 1; isspace(*white) && white > str; --white)
669131962Smp        *white = '\0';
670131962Smp
671131962Smp    for (; *str != '\0'; ++str)
672131962Smp    {
673131962Smp        if (string == outside)
674131962Smp        {
675131962Smp            *str = toupper (*str);
676131962Smp        }
677131962Smp        if (*str == '\'')
678131962Smp        {
679131962Smp            if (string == outside)
680131962Smp                string = singlequote;
681131962Smp            else if (string != doublequote)
682131962Smp                string = outside;
683131962Smp        }
684131962Smp        else if (*str == '"')
685131962Smp        {
686131962Smp            if (string == outside)
687131962Smp                string = doublequote;
688131962Smp            else if (string != singlequote)
689131962Smp                string = outside;
690131962Smp        }
691131962Smp    }
692131962Smp    if (string != outside)
693131962Smp    {
694131962Smp        stderror(ERR_NAME | ERR_UNMATCHED, (Char) string);
695131962Smp        return 1;
696131962Smp    }
697131962Smp    return 0;
698131962Smp}
699131962Smpstatic int
700131962Smpbs2cmdlist(char *str)
701131962Smp{
702131962Smp    char *str_beg = NULL;
703131962Smp    int ret = 0;
704131962Smp
705131962Smp    enum { outside = ' ', singlequote='\'', doublequote='"'} string = outside;
706131962Smp
707131962Smp    while (*str != '\0')
708131962Smp    {
709131962Smp        while (isspace(*str))
710131962Smp            ++str;
711131962Smp
712131962Smp        if (*str == '\0')
713131962Smp            break;
714131962Smp
715131962Smp        str_beg = str;
716131962Smp
717131962Smp        for (; *str != '\0'; ++str)
718131962Smp        {
719131962Smp            if (string == outside && *str == ';') /* End of command */
720131962Smp            {
721131962Smp                *str++ = '\0';
722131962Smp                break;    /* continue with next command */
723131962Smp            }
724131962Smp            if (*str == '\'')
725131962Smp            {
726131962Smp                if (string == outside)
727131962Smp                    string = singlequote;
728131962Smp                else if (string != doublequote)
729131962Smp                    string = outside;
730131962Smp            }
731131962Smp            else if (*str == '"')
732131962Smp            {
733131962Smp                if (string == outside)
734131962Smp                    string = doublequote;
735131962Smp                else if (string != singlequote)
736131962Smp                    string = outside;
737131962Smp            }
738131962Smp        }
739131962Smp        if (strlen(str_beg) != 0)
740131962Smp        {
741131962Smp            ret = bs2system(str_beg);
742131962Smp	    flush();
743131962Smp            if (ret != 0 /*&& !option.err_ignore*/)
744131962Smp                break; /* do not continue after errors */
745131962Smp        }
746131962Smp    }
747131962Smp
748131962Smp    if (string != outside)
749131962Smp    {
750131962Smp        stderror(ERR_NAME | ERR_UNMATCHED, (Char) string);
751131962Smp        return -1;
752131962Smp    }
753131962Smp
754131962Smp    return ret;
755131962Smp}
756131962Smp/*ARGSUSED*/
757131962Smpvoid
758167465Smpdobs2cmd(Char **v, struct command *c)
759131962Smp{
760167465Smp    Char *cp, **globbed;
761145479Smp    int  i = 0, len = 0;
762131962Smp    char *cmd = NULL;
763131962Smp    int     pvec[2];
764131962Smp    struct command faket;
765131962Smp    Char   *fakecom[2];
766131962Smp    char    tibuf[BUFSIZE];
767167465Smp    int     icnt, old_pintr_disabled;
768131962Smp    static const Char STRbs2cmd[] = { 'b','s','2','c','m','d','\0' };
769131962Smp
770167465Smp    v++;
771131962Smp    if (setintr)
772167465Smp	pintr_push_enable(&old_pintr_disabled);
773167465Smp    v = glob_all_or_error(v);
774167465Smp    if (setintr)
775167465Smp	cleanup_until(&old_pintr_disabled);
776167465Smp    globbed = v;
777167465Smp    cleanup_push(globbed, blk_cleanup);
778131962Smp
779131962Smp    /* First round: count the string lengths */
780131962Smp    for (i=0; v[i]; ++i) {
781167465Smp	len += Strlen(v[i]) + (v[i+1] != NULL);
782131962Smp    }
783131962Smp
784167465Smp    cmd = xmalloc(len+1); /* 1 for the final '\0' *//* FIXME: memory leak? */
785131962Smp
786131962Smp    /* 2nd round: fill cmd buffer */
787131962Smp    i = 0;
788131962Smp    while ((cp = *v++) != 0) {
789145479Smp	int c;
790131962Smp	while (c = *cp++)
791131962Smp	    cmd[i++] = (char)c;
792131962Smp        if (*v)
793131962Smp	    cmd[i++] = ' ';
794131962Smp    }
795131962Smp    cmd[i] = '\0';
796131962Smp
797131962Smp    /* Make upper case */
798131962Smp    bs2upcase(cmd);
799131962Smp
800131962Smp    faket.t_dtyp = NODE_COMMAND;
801131962Smp    faket.t_dflg = F_BACKQ|F_STDERR;
802131962Smp    faket.t_dlef = 0;
803131962Smp    faket.t_drit = 0;
804131962Smp    faket.t_dspr = 0;
805131962Smp    faket.t_dcom = fakecom;
806167465Smp    fakecom[0] = (Char *)STRbs2cmd;
807131962Smp    fakecom[1] = 0;
808131962Smp
809131962Smp    mypipe(pvec);
810167465Smp    cleanup_push(&pvec[0], open_cleanup);
811167465Smp    cleanup_push(&pvec[1], open_cleanup);
812131962Smp    if (pfork(&faket, -1) == 0) {
813167465Smp	sigset_t set;
814131962Smp        /* child */
815167465Smp        xclose(pvec[0]);
816131962Smp        (void) dmove(pvec[1], 1);
817131962Smp        (void) dmove(SHDIAG,  2);
818131962Smp        initdesc();
819167465Smp	sigemptyset(&set);
820167465Smp	sigaddset(&set, SIGINT);
821167465Smp	(void)sigprocmask(SIG_UNBLOCK, &set, NULL);
822131962Smp#ifdef SIGTSTP
823167465Smp        signal(SIGTSTP, SIG_IGN);
824131962Smp#endif
825131962Smp#ifdef SIGTTIN
826167465Smp        signal(SIGTTIN, SIG_IGN);
827131962Smp#endif
828131962Smp#ifdef SIGTTOU
829167465Smp        signal(SIGTTOU, SIG_IGN);
830131962Smp#endif
831131962Smp        xexit(bs2cmdlist(cmd));
832131962Smp    }
833167465Smp    cleanup_until(&pvec[1]);
834131962Smp    for(;;) {
835167465Smp	int old_pintr_disabled;
836167465Smp
837167465Smp	if (setintr)
838167465Smp	    pintr_push_enable(&old_pintr_disabled);
839167465Smp	icnt = xread(pvec[0], tibuf, sizeof(tibuf));
840167465Smp	if (setintr)
841167465Smp	    cleanup_until(&old_pintr_disabled);
842131962Smp        if (icnt <= 0)
843131962Smp            break;
844131962Smp        for (i = 0; i < icnt; i++)
845131962Smp            xputchar((unsigned char) tibuf[i]);
846131962Smp    }
847167465Smp    cleanup_until(&pvec[0]);
848131962Smp    pwait();
849131962Smp
850131962Smp    flush();
851131962Smp
852167465Smp    cleanup_until(globbed);
853131962Smp}
854131962Smp#endif /* _OSD_POSIX */
855131962Smp
85659243Sobrien#if defined(_CX_UX)
857167465Smpstatic void
858167465Smpsetuniverse_cleanup(void *xbuf)
859167465Smp{
860167465Smp    char *buf;
861167465Smp
862167465Smp    buf = xbuf;
863167465Smp    setuniverse(buf);
864167465Smp}
865167465Smp
86659243Sobrien/*ARGSUSED*/
86759243Sobrienvoid
868167465Smpdoatt(Char **v, struct command *c)
86959243Sobrien{
870145479Smp    Char *cp = v[1];
87159243Sobrien    char    ubuf[100];
87259243Sobrien
87359243Sobrien    if (cp == 0)
87459243Sobrien	(void) setuniverse("att");
87559243Sobrien    else {
87659243Sobrien	(void) getuniverse(ubuf);
87759243Sobrien	(void) setuniverse("att");
878167465Smp	cleanup_push(ubuf, setuniverse_cleanup);
879167465Smp	if (setintr) {
880167465Smp	    pintr_disabled++;
881167465Smp	    cleanup_push(&pintr_disabled, disabled_cleanup);
882167465Smp	}
88359243Sobrien	lshift(v, 1);
88459243Sobrien	if (setintr)
885167465Smp	    cleanup_until(&pintr_disabled);
88659243Sobrien	reexecute(c);
887167465Smp	cleanup_until(ubuf);
88859243Sobrien    }
88959243Sobrien}
89059243Sobrien
89159243Sobrien/*ARGSUSED*/
89259243Sobrienvoid
893167465Smpdoucb(Char **v, struct command *c)
89459243Sobrien{
895145479Smp    Char *cp = v[1];
89659243Sobrien    char    ubuf[100];
89759243Sobrien
89859243Sobrien    if (cp == 0)
89959243Sobrien	(void) setuniverse("ucb");
90059243Sobrien    else {
90159243Sobrien	(void) getuniverse(ubuf);
90259243Sobrien	(void) setuniverse("ucb");
903167465Smp	cleanup_push(ubuf, setuniverse_cleanup);
904167465Smp	if (setintr) {
905167465Smp	    pintr_disabled++;
906167465Smp	    cleanup_push(&pintr_disabled, disabled_cleanup);
907167465Smp	}
90859243Sobrien	lshift(v, 1);
90959243Sobrien	if (setintr)
910167465Smp	    cleanup_until(&pintr_disabled);
91159243Sobrien	reexecute(c);
912167465Smp	cleanup_until(ubuf);
91359243Sobrien    }
91459243Sobrien}
91559243Sobrien#endif /* _CX_UX */
91659243Sobrien
91759243Sobrien#ifdef _SEQUENT_
91859243Sobrien/*
91959243Sobrien * Compute the difference in process stats.
92059243Sobrien */
92159243Sobrienvoid
922167465Smppr_stat_sub(struct process_stats *p2, struct process_stats *p1,
923167465Smp	    struct process_stats *pr)
92459243Sobrien{
92559243Sobrien    pr->ps_utime.tv_sec = p2->ps_utime.tv_sec - p1->ps_utime.tv_sec;
92659243Sobrien    pr->ps_utime.tv_usec = p2->ps_utime.tv_usec - p1->ps_utime.tv_usec;
92759243Sobrien    if (pr->ps_utime.tv_usec < 0) {
92859243Sobrien	pr->ps_utime.tv_sec -= 1;
92959243Sobrien	pr->ps_utime.tv_usec += 1000000;
93059243Sobrien    }
93159243Sobrien    pr->ps_stime.tv_sec = p2->ps_stime.tv_sec - p1->ps_stime.tv_sec;
93259243Sobrien    pr->ps_stime.tv_usec = p2->ps_stime.tv_usec - p1->ps_stime.tv_usec;
93359243Sobrien    if (pr->ps_stime.tv_usec < 0) {
93459243Sobrien	pr->ps_stime.tv_sec -= 1;
93559243Sobrien	pr->ps_stime.tv_usec += 1000000;
93659243Sobrien    }
93759243Sobrien
93859243Sobrien    pr->ps_maxrss = p2->ps_maxrss - p1->ps_maxrss;
93959243Sobrien    pr->ps_pagein = p2->ps_pagein - p1->ps_pagein;
94059243Sobrien    pr->ps_reclaim = p2->ps_reclaim - p1->ps_reclaim;
94159243Sobrien    pr->ps_zerofill = p2->ps_zerofill - p1->ps_zerofill;
94259243Sobrien    pr->ps_pffincr = p2->ps_pffincr - p1->ps_pffincr;
94359243Sobrien    pr->ps_pffdecr = p2->ps_pffdecr - p1->ps_pffdecr;
94459243Sobrien    pr->ps_swap = p2->ps_swap - p1->ps_swap;
94559243Sobrien    pr->ps_syscall = p2->ps_syscall - p1->ps_syscall;
94659243Sobrien    pr->ps_volcsw = p2->ps_volcsw - p1->ps_volcsw;
94759243Sobrien    pr->ps_involcsw = p2->ps_involcsw - p1->ps_involcsw;
94859243Sobrien    pr->ps_signal = p2->ps_signal - p1->ps_signal;
94959243Sobrien    pr->ps_lread = p2->ps_lread - p1->ps_lread;
95059243Sobrien    pr->ps_lwrite = p2->ps_lwrite - p1->ps_lwrite;
95159243Sobrien    pr->ps_bread = p2->ps_bread - p1->ps_bread;
95259243Sobrien    pr->ps_bwrite = p2->ps_bwrite - p1->ps_bwrite;
95359243Sobrien    pr->ps_phread = p2->ps_phread - p1->ps_phread;
95459243Sobrien    pr->ps_phwrite = p2->ps_phwrite - p1->ps_phwrite;
95559243Sobrien}
95659243Sobrien
95759243Sobrien#endif /* _SEQUENT_ */
95859243Sobrien
95959243Sobrien
960145479Smp#ifndef HAVE_MEMSET
96159243Sobrien/* This is a replacement for a missing memset function */
962167465Smpvoid *xmemset(void *loc, int value, size_t len)
96359243Sobrien{
964167465Smp    char *ptr = loc;
965167465Smp
96659243Sobrien    while (len--)
96759243Sobrien	*ptr++ = value;
96859243Sobrien    return loc;
96959243Sobrien}
970145479Smp#endif /* !HAVE_MEMSET */
97159243Sobrien
97259243Sobrien
973145479Smp#ifndef HAVE_MEMMOVE
97459243Sobrien/* memmove():
97559243Sobrien * 	This is the ANSI form of bcopy() with the arguments backwards...
97659243Sobrien *	Unlike memcpy(), it handles overlaps between source and
97759243Sobrien *	destination memory
97859243Sobrien */
979167465Smpvoid *
980167465Smpxmemmove(void *vdst, const void *vsrc, size_t len)
98159243Sobrien{
982167465Smp    const char *src = vsrc;
983167465Smp    char *dst = vdst;
98459243Sobrien
98559243Sobrien    if (src == dst)
98659243Sobrien	return vdst;
98759243Sobrien
98859243Sobrien    if (src > dst) {
98959243Sobrien	while (len--)
99059243Sobrien	    *dst++ = *src++;
99159243Sobrien    }
99259243Sobrien    else {
99359243Sobrien	src += len;
99459243Sobrien	dst += len;
99559243Sobrien	while (len--)
99659243Sobrien	    *--dst = *--src;
99759243Sobrien    }
99859243Sobrien    return vdst;
99959243Sobrien}
1000145479Smp#endif /* HAVE_MEMMOVE */
100159243Sobrien
100259243Sobrien
100369408Sache#ifndef WINNT_NATIVE
1004145479Smp#ifdef NEEDtcgetpgrp
1005167465Smppid_t
1006167465Smpxtcgetpgrp(int fd)
100759243Sobrien{
100859243Sobrien    int     pgrp;
100959243Sobrien
101059243Sobrien    /* ioctl will handle setting errno correctly. */
101159243Sobrien    if (ioctl(fd, TIOCGPGRP, (ioctl_t) & pgrp) < 0)
101259243Sobrien	return (-1);
101359243Sobrien    return (pgrp);
101459243Sobrien}
101559243Sobrien
101659243Sobrien/*
101759243Sobrien * XXX: tcsetpgrp is not a macro any more cause on some systems,
101859243Sobrien * pid_t is a short, but the ioctl() takes a pointer to int (pyr)
101959243Sobrien * Thanks to Simon Day (simon@pharaoh.cyborg.bt.co.uk) for pointing
102059243Sobrien * this out.
102159243Sobrien */
102259243Sobrienint
1023167465Smpxtcsetpgrp(int fd, int pgrp)
102459243Sobrien{
102559243Sobrien    return ioctl(fd, TIOCSPGRP, (ioctl_t) &pgrp);
102659243Sobrien}
102759243Sobrien
1028145479Smp#endif	/* NEEDtcgetpgrp */
102969408Sache#endif /* WINNT_NATIVE */
103059243Sobrien
103159243Sobrien
103259243Sobrien#ifdef YPBUGS
103359243Sobrienvoid
1034167465Smpfix_yp_bugs(void)
103559243Sobrien{
103659243Sobrien    char   *mydomain;
103759243Sobrien
1038167465Smp    extern int yp_get_default_domain (char **);
103959243Sobrien    /*
104059243Sobrien     * PWP: The previous version assumed that yp domain was the same as the
104159243Sobrien     * internet name domain.  This isn't allways true. (Thanks to Mat Landau
104259243Sobrien     * <mlandau@bbn.com> for the original version of this.)
104359243Sobrien     */
104459243Sobrien    if (yp_get_default_domain(&mydomain) == 0) {	/* if we got a name */
1045167465Smp	extern void yp_unbind (const char *);
104659243Sobrien
104759243Sobrien	yp_unbind(mydomain);
104859243Sobrien    }
104959243Sobrien}
105059243Sobrien
105159243Sobrien#endif /* YPBUGS */
105259243Sobrien
105359243Sobrien#ifdef STRCOLLBUG
105459243Sobrienvoid
1055167465Smpfix_strcoll_bug(void)
105659243Sobrien{
1057167465Smp#if defined(NLS) && defined(HAVE_STRCOLL)
105859243Sobrien    /*
105959243Sobrien     * SunOS4 checks the file descriptor from openlocale() for <= 0
106059243Sobrien     * instead of == -1. Someone should tell sun that file descriptor 0
106159243Sobrien     * is valid! Our portable hack: open one so we call it with 0 used...
106259243Sobrien     * We have to call this routine every time the locale changes...
106359243Sobrien     *
106459243Sobrien     * Of course it also tries to free the constant locale "C" it initially
106559243Sobrien     * had allocated, with the sequence
106659243Sobrien     * > setenv LANG "fr"
106759243Sobrien     * > ls^D
106859243Sobrien     * > unsetenv LANG
106959243Sobrien     * But we are smarter than that and just print a warning message.
107059243Sobrien     */
107159243Sobrien    int fd = -1;
107259243Sobrien    static char *root = "/";
107359243Sobrien
107459243Sobrien    if (!didfds)
1075167465Smp	fd = xopen(root, O_RDONLY|O_LARGEFILE);
107659243Sobrien
107759243Sobrien    (void) strcoll(root, root);
107859243Sobrien
107959243Sobrien    if (fd != -1)
1080167465Smp	xclose(fd);
108159243Sobrien#endif
108259243Sobrien}
108359243Sobrien#endif /* STRCOLLBUG */
108459243Sobrien
108559243Sobrien
108659243Sobrien#ifdef OREO
108759243Sobrien#include <compat.h>
108859243Sobrien#endif /* OREO */
108959243Sobrien
109059243Sobrienvoid
1091167465Smposinit(void)
109259243Sobrien{
109359243Sobrien#ifdef OREO
109459243Sobrien    set42sig();
109559243Sobrien    setcompat(getcompat() & ~COMPAT_EXEC);
1096167465Smp    signal(SIGIO, SIG_IGN);		/* ignore SIGIO */
109759243Sobrien#endif /* OREO */
109859243Sobrien
109959243Sobrien#ifdef aiws
110059243Sobrien    {
110159243Sobrien	struct sigstack inst;
1102167465Smp	inst.ss_sp = xmalloc(4192) + 4192;
110359243Sobrien	inst.ss_onstack = 0;
110459243Sobrien	sigstack(&inst, NULL);
110559243Sobrien    }
110659243Sobrien#endif /* aiws */
110759243Sobrien
110859243Sobrien#ifdef apollo
110959243Sobrien    (void) isapad();
111059243Sobrien#endif
111159243Sobrien
111259243Sobrien#ifdef _SX
111359243Sobrien    /*
111459243Sobrien     * kill(SIGCONT) problems, don't know what this syscall does
111559243Sobrien     * [schott@rzg.mpg.de]
111659243Sobrien     */
111759243Sobrien    syscall(151, getpid(), getpid());
111859243Sobrien#endif /* _SX */
111959243Sobrien}
112059243Sobrien
1121145479Smp#ifndef HAVE_STRERROR
1122167465Smpextern int sys_nerr;
1123167465Smpextern char *sys_errlist[];
112459243Sobrienchar *
1125167465Smpxstrerror(int i)
112659243Sobrien{
112759243Sobrien    if (i >= 0 && i < sys_nerr) {
112859243Sobrien	return sys_errlist[i];
112959243Sobrien    } else {
1130167465Smp	static char *errbuf; /* = NULL; */
1131167465Smp
1132167465Smp	xfree(errbuf);
1133167465Smp	errbuf = xasprintf(CGETS(23, 13, "Unknown Error: %d"), i);
113459243Sobrien	return errbuf;
113559243Sobrien    }
113659243Sobrien}
1137145479Smp#endif /* !HAVE_STRERROR */
113859243Sobrien
1139145479Smp#ifndef HAVE_GETHOSTNAME
114069408Sache# if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE)
114159243Sobrien#  include <sys/utsname.h>
114269408Sache# endif /* !_MINIX && !__EMX__ && !WINNT_NATIVE */
114359243Sobrien
114459243Sobrienint
1145167465Smpxgethostname(char *name, int namlen)
114659243Sobrien{
114769408Sache# if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE)
114859243Sobrien    int     i, retval;
114959243Sobrien    struct utsname uts;
115059243Sobrien
115159243Sobrien    retval = uname(&uts);
115259243Sobrien
115359243Sobrien#  ifdef DEBUG
115459243Sobrien    xprintf(CGETS(23, 14, "sysname:  %s\n"), uts.sysname);
115559243Sobrien    xprintf(CGETS(23, 15, "nodename: %s\n"), uts.nodename);
115659243Sobrien    xprintf(CGETS(23, 16, "release:  %s\n"), uts.release);
115759243Sobrien    xprintf(CGETS(23, 17, "version:  %s\n"), uts.version);
115859243Sobrien    xprintf(CGETS(23, 18, "machine:  %s\n"), uts.machine);
115959243Sobrien#  endif /* DEBUG */
116059243Sobrien    i = strlen(uts.nodename) + 1;
116159243Sobrien    (void) strncpy(name, uts.nodename, i < namlen ? i : namlen);
116259243Sobrien
116359243Sobrien    return retval;
116459243Sobrien# else /* !_MINIX && !__EMX__ */
116559243Sobrien    if (namlen > 0) {
116659243Sobrien#  ifdef __EMX__
116759243Sobrien	(void) strncpy(name, "OS/2", namlen);
116859243Sobrien#  else /* _MINIX */
116959243Sobrien	(void) strncpy(name, "minix", namlen);
117059243Sobrien#  endif /* __EMX__ */
117159243Sobrien	name[namlen-1] = '\0';
117259243Sobrien    }
117359243Sobrien    return(0);
117459243Sobrien#endif /* _MINIX && !__EMX__ */
117559243Sobrien} /* end xgethostname */
1176145479Smp#endif /* !HAVE_GETHOSTNAME */
117759243Sobrien
1178145479Smp#ifndef HAVE_NICE
117959243Sobrien# if defined(_MINIX) && defined(NICE)
118059243Sobrien#  undef _POSIX_SOURCE	/* redefined in <lib.h> */
118159243Sobrien#  undef _MINIX		/* redefined in <lib.h> */
118259243Sobrien#  undef HZ		/* redefined in <minix/const.h> */
118359243Sobrien#  include <lib.h>
118459243Sobrien# endif /* _MINIX && NICE */
118559243Sobrienint
1186167465Smpxnice(int incr)
118759243Sobrien{
118859243Sobrien#if defined(_MINIX) && defined(NICE)
118959243Sobrien    return callm1(MM, NICE, incr, 0, 0, NIL_PTR, NIL_PTR, NIL_PTR);
119059243Sobrien#else
119159243Sobrien    return /* incr ? 0 : */ 0;
119259243Sobrien#endif /* _MINIX && NICE */
119359243Sobrien} /* end xnice */
1194145479Smp#endif /* !HAVE_NICE */
119559243Sobrien
1196145479Smp#ifndef HAVE_GETCWD
1197167465Smpstatic char *strnrcpy (char *, char *, size_t);
119859243Sobrien
119959243Sobrien/* xgetcwd():
120059243Sobrien *	Return the pathname of the current directory, or return
120159243Sobrien *	an error message in pathname.
120259243Sobrien */
120359243Sobrien
120459243Sobrien# ifdef hp9000s500
120559243Sobrien/*
120659243Sobrien *  From: Bernd Mohr <mohr@faui77.informatik.uni-erlangen.de>
120759243Sobrien *  I also ported the tcsh to the HP9000 Series 500. This computer
120859243Sobrien *  is a little bit different than the other HP 9000 computer. It has
120959243Sobrien *  a HP Chip instead of a Motorola CPU and it is no "real" UNIX. It runs
121059243Sobrien *  HP-UX which is emulated in top of a HP operating system. So, the last
121159243Sobrien *  supported version of HP-UX is 5.2 on the HP9000s500. This has two
121259243Sobrien *  consequences: it supports no job control and it has a filesystem
121359243Sobrien *  without "." and ".." !!!
121459243Sobrien */
121559243Sobrienchar *
1216167465Smpxgetcwd(char *pathname, size_t pathlen)
121759243Sobrien{
1218167465Smp    char pathbuf[MAXPATHLEN];	/* temporary pathname buffer */
121959243Sobrien    char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
122059243Sobrien    dev_t rdev;			/* root device number */
122159243Sobrien    DIR *dirp = NULL;		/* directory stream */
122259243Sobrien    ino_t rino;			/* root inode number */
122359243Sobrien    off_t rsize;		/* root size */
122459243Sobrien    struct direct *dir;		/* directory entry struct */
122559243Sobrien    struct stat d, dd;		/* file status struct */
122659243Sobrien    int serrno;
122759243Sobrien
122859243Sobrien    *pnptr = '\0';
122959243Sobrien    (void) stat("/.", &d);
123059243Sobrien    rdev = d.st_dev;
123159243Sobrien    rino = d.st_ino;
123259243Sobrien    rsize = d.st_size;
123359243Sobrien    for (;;) {
123459243Sobrien	if (stat(".", &d) == -1) {
123559243Sobrien	    (void) xsnprintf(pathname, pathlen, CGETS(23, 24,
123659243Sobrien		"getcwd: Cannot stat \".\" (%s)"), strerror(errno));
123759243Sobrien	    goto fail;
123859243Sobrien	}
123959243Sobrien	if (d.st_ino == rino && d.st_dev == rdev && d.st_size == rsize)
124059243Sobrien	    break;		/* reached root directory */
124159243Sobrien	if ((dirp = opendir("..")) == NULL) {
124259243Sobrien	    (void) xsnprintf(pathname, pathlen, CGETS(23, 19,
124359243Sobrien		"getcwd: Cannot open \"..\" (%s)"), strerror(errno));
124459243Sobrien	    goto fail;
124559243Sobrien	}
124659243Sobrien	if (chdir("..") == -1) {
124759243Sobrien	    (void) xsnprintf(pathname, pathlen, CGETS(23, 20,
124859243Sobrien		"getcwd: Cannot chdir to \"..\" (%s)"), strerror(errno));
124959243Sobrien	    goto fail;
125059243Sobrien	}
125159243Sobrien	do {
125259243Sobrien	    if ((dir = readdir(dirp)) == NULL) {
125359243Sobrien		(void) xsnprintf(pathname, pathlen,
125459243Sobrien		    CGETS(23, 21, "getcwd: Read error in \"..\" (%s)"),
125559243Sobrien		    strerror(errno));
125659243Sobrien		goto fail;
125759243Sobrien	    }
125859243Sobrien	    if (stat(dir->d_name, &dd) == -1) {
125959243Sobrien		(void) xsnprintf(pathname, pathlen,
126059243Sobrien		    CGETS(23, 25, "getcwd: Cannot stat directory \"%s\" (%s)"),
126159243Sobrien		    dir->d_name, strerror(errno));
126259243Sobrien		goto fail;
126359243Sobrien	    }
126459243Sobrien	} while (dd.st_ino  != d.st_ino  ||
126559243Sobrien		 dd.st_dev  != d.st_dev  ||
126659243Sobrien		 dd.st_size != d.st_size);
1267167465Smp	closedir(dirp);
126859243Sobrien	dirp = NULL;
126959243Sobrien	pnptr = strnrcpy(dirp->d_name, pnptr, pnptr - pathbuf);
127059243Sobrien	pnptr = strnrcpy("/", pnptr, pnptr - pathbuf);
127159243Sobrien    }
127259243Sobrien
127359243Sobrien    if (*pnptr == '\0')		/* current dir == root dir */
127459243Sobrien	(void) strncpy(pathname, "/", pathlen);
127559243Sobrien    else {
127659243Sobrien	(void) strncpy(pathname, pnptr, pathlen);
127759243Sobrien	pathname[pathlen - 1] = '\0';
127859243Sobrien	if (chdir(pnptr) == -1) {
127959243Sobrien	    (void) xsnprintf(pathname, MAXPATHLEN, CGETS(23, 22,
128059243Sobrien		    "getcwd: Cannot change back to \".\" (%s)"),
128159243Sobrien		    strerror(errno));
128259243Sobrien	    return NULL;
128359243Sobrien	}
128459243Sobrien    }
128559243Sobrien    return pathname;
128659243Sobrien
128759243Sobrienfail:
128859243Sobrien    serrno = errno;
128959243Sobrien    (void) chdir(strnrcpy(".", pnptr, pnptr - pathbuf));
129059243Sobrien    errno = serrno;
129159243Sobrien    return NULL;
129259243Sobrien}
129359243Sobrien
129459243Sobrien# else /* ! hp9000s500 */
129559243Sobrien
129659243Sobrien
129759243Sobrienchar *
1298167465Smpxgetcwd(char *pathname, size_t pathlen)
129959243Sobrien{
130059243Sobrien    DIR    *dp;
130159243Sobrien    struct dirent *d;
130259243Sobrien
130359243Sobrien    struct stat st_root, st_cur, st_next, st_dotdot;
130459243Sobrien    char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
130559243Sobrien    char   *pathptr, *nextpathptr, *cur_name_add;
130659243Sobrien    int	   save_errno = 0;
130759243Sobrien
130859243Sobrien    /* find the inode of root */
130959243Sobrien    if (stat("/", &st_root) == -1) {
131059243Sobrien	(void) xsnprintf(pathname, pathlen, CGETS(23, 23,
131159243Sobrien			"getcwd: Cannot stat \"/\" (%s)"),
131259243Sobrien			strerror(errno));
131359243Sobrien	return NULL;
131459243Sobrien    }
131559243Sobrien    pathbuf[MAXPATHLEN - 1] = '\0';
131659243Sobrien    pathptr = &pathbuf[MAXPATHLEN - 1];
131759243Sobrien    nextpathbuf[MAXPATHLEN - 1] = '\0';
131859243Sobrien    cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
131959243Sobrien
132059243Sobrien    /* find the inode of the current directory */
132159243Sobrien    if (lstat(".", &st_cur) == -1) {
132259243Sobrien	(void) xsnprintf(pathname, pathlen, CGETS(23, 24,
132359243Sobrien			 "getcwd: Cannot stat \".\" (%s)"),
132459243Sobrien			 strerror(errno));
132559243Sobrien	return NULL;
132659243Sobrien    }
132759243Sobrien    nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf);
132859243Sobrien
132959243Sobrien    /* Descend to root */
133059243Sobrien    for (;;) {
133159243Sobrien
133259243Sobrien	/* look if we found root yet */
133359243Sobrien	if (st_cur.st_ino == st_root.st_ino &&
133459243Sobrien	    DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
133559243Sobrien	    (void) strncpy(pathname, *pathptr != '/' ? "/" : pathptr, pathlen);
133659243Sobrien	    pathname[pathlen - 1] = '\0';
133759243Sobrien	    return pathname;
133859243Sobrien	}
133959243Sobrien
134059243Sobrien	/* open the parent directory */
134159243Sobrien	if (stat(nextpathptr, &st_dotdot) == -1) {
134259243Sobrien	    (void) xsnprintf(pathname, pathlen, CGETS(23, 25,
134359243Sobrien			     "getcwd: Cannot stat directory \"%s\" (%s)"),
134459243Sobrien			     nextpathptr, strerror(errno));
134559243Sobrien	    return NULL;
134659243Sobrien	}
134759243Sobrien	if ((dp = opendir(nextpathptr)) == NULL) {
134859243Sobrien	    (void) xsnprintf(pathname, pathlen, CGETS(23, 26,
134959243Sobrien			     "getcwd: Cannot open directory \"%s\" (%s)"),
135059243Sobrien			     nextpathptr, strerror(errno));
135159243Sobrien	    return NULL;
135259243Sobrien	}
135359243Sobrien
135459243Sobrien	/* look in the parent for the entry with the same inode */
135559243Sobrien	if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
135659243Sobrien	    /* Parent has same device. No need to stat every member */
135759243Sobrien	    for (d = readdir(dp); d != NULL; d = readdir(dp)) {
135859243Sobrien#ifdef __clipper__
1359145479Smp		if (((unsigned long)d->d_ino & 0xffff) == st_cur.st_ino)
136059243Sobrien		    break;
136159243Sobrien#else
1362145479Smp		if (d->d_ino == st_cur.st_ino)
136359243Sobrien		    break;
136459243Sobrien#endif
136559243Sobrien	    }
136659243Sobrien	}
136759243Sobrien	else {
136859243Sobrien	    /*
136959243Sobrien	     * Parent has a different device. This is a mount point so we
137059243Sobrien	     * need to stat every member
137159243Sobrien	     */
137259243Sobrien	    for (d = readdir(dp); d != NULL; d = readdir(dp)) {
137359243Sobrien		if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
137459243Sobrien		    continue;
137559243Sobrien		(void)strncpy(cur_name_add, d->d_name,
137659243Sobrien		    (size_t) (&nextpathbuf[sizeof(nextpathbuf) - 1] - cur_name_add));
137759243Sobrien		if (lstat(nextpathptr, &st_next) == -1) {
137859243Sobrien		    /*
137959243Sobrien		     * We might not be able to stat() some path components
138059243Sobrien		     * if we are using afs, but this is not an error as
138159243Sobrien		     * long as we find the one we need; we also save the
138259243Sobrien		     * first error to report it if we don't finally succeed.
138359243Sobrien		     */
138459243Sobrien		    if (save_errno == 0)
138559243Sobrien			save_errno = errno;
138659243Sobrien		    continue;
138759243Sobrien		}
138859243Sobrien		/* check if we found it yet */
138959243Sobrien		if (st_next.st_ino == st_cur.st_ino &&
139059243Sobrien		    DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
139159243Sobrien		    break;
139259243Sobrien	    }
139359243Sobrien	}
139459243Sobrien	if (d == NULL) {
139559243Sobrien	    (void) xsnprintf(pathname, pathlen, CGETS(23, 27,
139659243Sobrien			     "getcwd: Cannot find \".\" in \"..\" (%s)"),
139759243Sobrien			     strerror(save_errno ? save_errno : ENOENT));
1398167465Smp	    closedir(dp);
139959243Sobrien	    return NULL;
140059243Sobrien	}
140159243Sobrien	else
140259243Sobrien	    save_errno = 0;
140359243Sobrien	st_cur = st_dotdot;
140459243Sobrien	pathptr = strnrcpy(pathptr, d->d_name, pathptr - pathbuf);
140559243Sobrien	pathptr = strnrcpy(pathptr, "/", pathptr - pathbuf);
140659243Sobrien	nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf);
140759243Sobrien	*cur_name_add = '\0';
1408167465Smp	closedir(dp);
140959243Sobrien    }
141059243Sobrien} /* end getcwd */
141159243Sobrien# endif /* hp9000s500 */
141259243Sobrien
141359243Sobrien/* strnrcpy():
141459243Sobrien *	Like strncpy, going backwards and returning the new pointer
141559243Sobrien */
141659243Sobrienstatic char *
1417167465Smpstrnrcpy(char *ptr, char *str, size_t siz)
141859243Sobrien{
1419145479Smp    int len = strlen(str);
142059243Sobrien    if (siz == 0)
142159243Sobrien	return ptr;
142259243Sobrien
142359243Sobrien    while (len && siz--)
142459243Sobrien	*--ptr = str[--len];
142559243Sobrien
142659243Sobrien    return (ptr);
142759243Sobrien} /* end strnrcpy */
1428145479Smp#endif /* !HAVE_GETCWD */
142959243Sobrien
143059243Sobrien#ifdef apollo
143159243Sobrien/***
143259243Sobrien *** Domain/OS
143359243Sobrien ***/
143459243Sobrien#include <apollo/base.h>
143559243Sobrien#include <apollo/loader.h>
143659243Sobrien#include <apollo/error.h>
143759243Sobrien
143859243Sobrien
143959243Sobrienstatic char *
1440167465Smpapperr(status_$t *st)
144159243Sobrien{
1442167465Smp    static char *buf; /* = NULL */
144359243Sobrien    short e_subl, e_modl, e_codel;
144459243Sobrien    error_$string_t e_sub, e_mod, e_code;
144559243Sobrien
144659243Sobrien    error_$get_text(*st, e_sub, &e_subl, e_mod, &e_modl, e_code, &e_codel);
144759243Sobrien    e_sub[e_subl] = '\0';
144859243Sobrien    e_code[e_codel] = '\0';
144959243Sobrien    e_mod[e_modl] = '\0';
1450167465Smp    xfree(buf);
1451167465Smp    buf = xasprintf("%s (%s/%s)", e_code, e_sub, e_mod);
145259243Sobrien
145359243Sobrien    return(buf);
145459243Sobrien}
145559243Sobrien
145659243Sobrienstatic int
1457167465Smpllib(Char *s)
145859243Sobrien{
145959243Sobrien    short len = Strlen(s);
146059243Sobrien    status_$t st;
146159243Sobrien    char *t;
146259243Sobrien
146359243Sobrien    loader_$inlib(t = short2str(s), len, &st);
146459243Sobrien    if (st.all != status_$ok)
146559243Sobrien	stderror(ERR_SYSTEM, t, apperr(&st));
146659243Sobrien}
146759243Sobrien
146859243Sobrien/*ARGSUSED*/
146959243Sobrienvoid
1470167465Smpdoinlib(Char **v, struct command *c)
147159243Sobrien{
1472167465Smp    Char **globbed;
1473167465Smp
147459243Sobrien    setname(short2str(*v++));
1475167465Smp    v = glob_all_or_error(v);
1476167465Smp    globbed = v;
1477167465Smp    cleanup_push(globbed, blk_cleanup);
147859243Sobrien
147959243Sobrien    while (v && *v)
148059243Sobrien	llib(*v++);
1481167465Smp    cleanup_until(globbed);
148259243Sobrien}
148359243Sobrien
148459243Sobrienint
1485167465Smpgetv(Char *v)
148659243Sobrien{
148759243Sobrien    if (eq(v, STRbsd43))
148859243Sobrien	return(1);
148959243Sobrien    else if (eq(v, STRsys53))
149059243Sobrien	return(0);
149159243Sobrien    else
149259243Sobrien	stderror(ERR_NAME | ERR_SYSTEM, short2str(v),
149359243Sobrien		 CGETS(23, 28, "Invalid system type"));
149459243Sobrien    /*NOTREACHED*/
149559243Sobrien    return(0);
149659243Sobrien}
149759243Sobrien
149859243Sobrien/*ARGSUSED*/
149959243Sobrienvoid
1500167465Smpdover(Char **v, struct command *c)
150159243Sobrien{
150259243Sobrien    Char *p;
150359243Sobrien
150459243Sobrien    setname(short2str(*v++));
150559243Sobrien    if (!*v) {
150659243Sobrien	if (!(p = tgetenv(STRSYSTYPE)))
150759243Sobrien	    stderror(ERR_NAME | ERR_STRING,
150859243Sobrien		     CGETS(23, 29, "System type is not set"));
150959243Sobrien	xprintf("%S\n", p);
151059243Sobrien    }
151159243Sobrien    else {
151259243Sobrien	tsetenv(STRSYSTYPE, getv(*v) ? STRbsd43 : STRsys53);
151359243Sobrien	dohash(NULL, NULL);
151459243Sobrien    }
151559243Sobrien}
151659243Sobrien
151759243Sobrien/*
151859243Sobrien * Many thanks to rees@citi.umich.edu (Jim Rees) and
151959243Sobrien *                mathys@ssdt-tempe.sps.mot.com (Yves Mathys)
152059243Sobrien * For figuring out how to do this... I could have never done
152159243Sobrien * it without their help.
152259243Sobrien */
152359243Sobrientypedef short enum {
152459243Sobrien	name_$wdir_type,
152559243Sobrien	name_$ndir_type,
152659243Sobrien	name_$node_dir_type,
152759243Sobrien} name_$dir_type_t;
152859243Sobrien
152959243Sobrien/*ARGSUSED*/
153059243Sobrienvoid
1531167465Smpdorootnode(Char **v, struct command *c)
153259243Sobrien{
153359243Sobrien    name_$dir_type_t dirtype = name_$node_dir_type;
153459243Sobrien    uid_$t uid;
153559243Sobrien    status_$t st;
153659243Sobrien    char *name;
153759243Sobrien    short namelen;
153859243Sobrien
153959243Sobrien    setname(short2str(*v++));
154059243Sobrien
154159243Sobrien    name = short2str(*v);
154259243Sobrien    namelen = strlen(name);
154359243Sobrien
154459243Sobrien    name_$resolve(name, &namelen, &uid, &st);
154559243Sobrien    if (st.all != status_$ok)
154659243Sobrien	stderror(ERR_SYSTEM, name, apperr(&st));
154759243Sobrien    namelen = 0;
154859243Sobrien    name_$set_diru(&uid, "", &namelen, &dirtype, &st);
154959243Sobrien    if (st.all != status_$ok)
155059243Sobrien	stderror(ERR_SYSTEM, name, apperr(&st));
155159243Sobrien    dohash(NULL, NULL);
155259243Sobrien}
155359243Sobrien
155459243Sobrienint
1555167465Smpisapad(void)
155659243Sobrien{
155759243Sobrien    static int res = -1;
155859243Sobrien    static status_$t st;
155959243Sobrien
156059243Sobrien    if (res == -1) {
156159243Sobrien	int strm;
156259243Sobrien	if (isatty(0))
156359243Sobrien	    strm = 0;
156459243Sobrien	if (isatty(1))
156559243Sobrien	    strm = 1;
156659243Sobrien	if (isatty(2))
156759243Sobrien	    strm = 2;
156859243Sobrien	else {
156959243Sobrien	    res = 0;
157059243Sobrien	    st.all = status_$ok;
157159243Sobrien	    return(res);
157259243Sobrien	}
157359243Sobrien	res = stream_$isavt(&strm, &st);
157459243Sobrien	res = res ? 1 : 0;
157559243Sobrien    }
157659243Sobrien    else {
157759243Sobrien	if (st.all != status_$ok)
157859243Sobrien	    stderror(ERR_SYSTEM, "stream_$isavt", apperr(&st));
157959243Sobrien    }
158059243Sobrien    return(res);
158159243Sobrien}
158259243Sobrien#endif
1583231990Smp
1584231990Smp#if defined(__CYGWIN__) && !defined(NO_CRYPT)
1585231990Smp#undef CHAR		/* Collides with Win32 API */
1586231990Smp#define WIN32_LEAN_AND_MEAN
1587231990Smp#include <windows.h>
1588231990Smp#include <sys/cygwin.h>
1589231990Smpchar *
1590231990Smpcygwin_xcrypt(struct passwd *pw, const char *password, const char *expected_pwd)
1591231990Smp{
1592231990Smp    static char invalid_password[] = "\377";
1593231990Smp    HANDLE token = cygwin_logon_user(pw, password);
1594231990Smp    if (token == INVALID_HANDLE_VALUE)
1595231990Smp	return invalid_password;
1596231990Smp    CloseHandle(token);
1597231990Smp    return (char *) expected_pwd;
1598231990Smp}
1599231990Smp#endif /* __CYGWIN__ && !NO_CRYPT */
1600