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