16767bd61SMark Peek /* $Header: /src/pub/tcsh/tc.func.c,v 3.97 2001/08/28 23:13:44 christos Exp $ */ 2c80476e4SDavid E. O'Brien /* 3c80476e4SDavid E. O'Brien * tc.func.c: New tcsh builtins. 4c80476e4SDavid E. O'Brien */ 5c80476e4SDavid E. O'Brien /*- 6c80476e4SDavid E. O'Brien * Copyright (c) 1980, 1991 The Regents of the University of California. 7c80476e4SDavid E. O'Brien * All rights reserved. 8c80476e4SDavid E. O'Brien * 9c80476e4SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without 10c80476e4SDavid E. O'Brien * modification, are permitted provided that the following conditions 11c80476e4SDavid E. O'Brien * are met: 12c80476e4SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright 13c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer. 14c80476e4SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright 15c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the 16c80476e4SDavid E. O'Brien * documentation and/or other materials provided with the distribution. 17c80476e4SDavid E. O'Brien * 3. All advertising materials mentioning features or use of this software 18c80476e4SDavid E. O'Brien * must display the following acknowledgement: 19c80476e4SDavid E. O'Brien * This product includes software developed by the University of 20c80476e4SDavid E. O'Brien * California, Berkeley and its contributors. 21c80476e4SDavid E. O'Brien * 4. Neither the name of the University nor the names of its contributors 22c80476e4SDavid E. O'Brien * may be used to endorse or promote products derived from this software 23c80476e4SDavid E. O'Brien * without specific prior written permission. 24c80476e4SDavid E. O'Brien * 25c80476e4SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26c80476e4SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27c80476e4SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28c80476e4SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29c80476e4SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30c80476e4SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31c80476e4SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32c80476e4SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33c80476e4SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34c80476e4SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35c80476e4SDavid E. O'Brien * SUCH DAMAGE. 36c80476e4SDavid E. O'Brien */ 37c80476e4SDavid E. O'Brien #include "sh.h" 38c80476e4SDavid E. O'Brien 396767bd61SMark Peek RCSID("$Id: tc.func.c,v 3.97 2001/08/28 23:13:44 christos Exp $") 40c80476e4SDavid E. O'Brien 41c80476e4SDavid E. O'Brien #include "ed.h" 42c80476e4SDavid E. O'Brien #include "ed.defns.h" /* for the function names */ 43c80476e4SDavid E. O'Brien #include "tw.h" 44c80476e4SDavid E. O'Brien #include "tc.h" 453b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 46c80476e4SDavid E. O'Brien #include "nt.const.h" 473b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 48c80476e4SDavid E. O'Brien 49c80476e4SDavid E. O'Brien #ifdef AFS 50c80476e4SDavid E. O'Brien #define PASSMAX 16 51c80476e4SDavid E. O'Brien #include <afs/stds.h> 52c80476e4SDavid E. O'Brien #include <afs/kautils.h> 53c80476e4SDavid E. O'Brien long ka_UserAuthenticateGeneral(); 54c80476e4SDavid E. O'Brien #else 55c80476e4SDavid E. O'Brien #ifndef PASSMAX 56c80476e4SDavid E. O'Brien #define PASSMAX 8 57c80476e4SDavid E. O'Brien #endif 58c80476e4SDavid E. O'Brien #endif /* AFS */ 59c80476e4SDavid E. O'Brien 60c80476e4SDavid E. O'Brien #ifdef TESLA 61c80476e4SDavid E. O'Brien extern int do_logout; 62c80476e4SDavid E. O'Brien #endif /* TESLA */ 63c80476e4SDavid E. O'Brien extern time_t t_period; 64c80476e4SDavid E. O'Brien extern int just_signaled; 65c80476e4SDavid E. O'Brien static bool precmd_active = 0; 666767bd61SMark Peek static bool jobcmd_active = 0; /* GrP */ 67c80476e4SDavid E. O'Brien static bool postcmd_active = 0; 68c80476e4SDavid E. O'Brien static bool periodic_active = 0; 69c80476e4SDavid E. O'Brien static bool cwdcmd_active = 0; /* PWP: for cwd_cmd */ 70c80476e4SDavid E. O'Brien static bool beepcmd_active = 0; 71c80476e4SDavid E. O'Brien static signalfun_t alm_fun = NULL; 72c80476e4SDavid E. O'Brien 73c80476e4SDavid E. O'Brien static void auto_logout __P((int)); 74c80476e4SDavid E. O'Brien static char *xgetpass __P((char *)); 75c80476e4SDavid E. O'Brien static void auto_lock __P((int)); 76c80476e4SDavid E. O'Brien #ifdef BSDJOBS 77c80476e4SDavid E. O'Brien static void insert __P((struct wordent *, bool)); 78c80476e4SDavid E. O'Brien static void insert_we __P((struct wordent *, struct wordent *)); 79c80476e4SDavid E. O'Brien static int inlist __P((Char *, Char *)); 80c80476e4SDavid E. O'Brien #endif /* BSDJOBS */ 81c80476e4SDavid E. O'Brien struct tildecache; 82c80476e4SDavid E. O'Brien static int tildecompare __P((struct tildecache *, struct tildecache *)); 83c80476e4SDavid E. O'Brien static Char *gethomedir __P((Char *)); 84c80476e4SDavid E. O'Brien #ifdef REMOTEHOST 85c80476e4SDavid E. O'Brien static sigret_t palarm __P((int)); 86c80476e4SDavid E. O'Brien static void getremotehost __P((void)); 87c80476e4SDavid E. O'Brien #endif /* REMOTEHOST */ 88c80476e4SDavid E. O'Brien 89c80476e4SDavid E. O'Brien /* 90c80476e4SDavid E. O'Brien * Tops-C shell 91c80476e4SDavid E. O'Brien */ 92c80476e4SDavid E. O'Brien 93c80476e4SDavid E. O'Brien /* 94b2be84b1SDavid E. O'Brien * expand_lex: Take the given lex and put an expanded version of it in 95b2be84b1SDavid E. O'Brien * the string buf. First guy in lex list is ignored; last guy is ^J 96b2be84b1SDavid E. O'Brien * which we ignore. Only take lex'es from position 'from' to position 97b2be84b1SDavid E. O'Brien * 'to' inclusive 98b2be84b1SDavid E. O'Brien * 99b2be84b1SDavid E. O'Brien * Note: csh sometimes sets bit 8 in characters which causes all kinds 100b2be84b1SDavid E. O'Brien * of problems if we don't mask it here. Note: excl's in lexes have been 101b2be84b1SDavid E. O'Brien * un-back-slashed and must be re-back-slashed 102b2be84b1SDavid E. O'Brien * 103c80476e4SDavid E. O'Brien * (PWP: NOTE: this returns a pointer to the END of the string expanded 104c80476e4SDavid E. O'Brien * (in other words, where the NUL is).) 105c80476e4SDavid E. O'Brien */ 106c80476e4SDavid E. O'Brien /* PWP: this is a combination of the old sprlex() and the expand_lex from 107c80476e4SDavid E. O'Brien the magic-space stuff */ 108c80476e4SDavid E. O'Brien 109c80476e4SDavid E. O'Brien Char * 110c80476e4SDavid E. O'Brien expand_lex(buf, bufsiz, sp0, from, to) 111c80476e4SDavid E. O'Brien Char *buf; 112c80476e4SDavid E. O'Brien size_t bufsiz; 113c80476e4SDavid E. O'Brien struct wordent *sp0; 114c80476e4SDavid E. O'Brien int from, to; 115c80476e4SDavid E. O'Brien { 116c80476e4SDavid E. O'Brien register struct wordent *sp; 117c80476e4SDavid E. O'Brien register Char *s, *d, *e; 118c80476e4SDavid E. O'Brien register Char prev_c; 119c80476e4SDavid E. O'Brien register int i; 120c80476e4SDavid E. O'Brien 1213b6eaa7bSAndrey A. Chernov /* 1223b6eaa7bSAndrey A. Chernov * Make sure we have enough space to expand into. E.g. we may have 1233b6eaa7bSAndrey A. Chernov * "a|b" turn to "a | b" (from 3 to 5 characters) which is the worst 1243b6eaa7bSAndrey A. Chernov * case scenario (even "a>&! b" turns into "a > & ! b", i.e. 6 to 9 1253b6eaa7bSAndrey A. Chernov * characters -- am I missing any other cases?). 1263b6eaa7bSAndrey A. Chernov */ 1273b6eaa7bSAndrey A. Chernov bufsiz = bufsiz / 2; 1283b6eaa7bSAndrey A. Chernov 129c80476e4SDavid E. O'Brien buf[0] = '\0'; 130c80476e4SDavid E. O'Brien prev_c = '\0'; 131c80476e4SDavid E. O'Brien d = buf; 132c80476e4SDavid E. O'Brien e = &buf[bufsiz]; /* for bounds checking */ 133c80476e4SDavid E. O'Brien 134c80476e4SDavid E. O'Brien if (!sp0) 135c80476e4SDavid E. O'Brien return (buf); /* null lex */ 136c80476e4SDavid E. O'Brien if ((sp = sp0->next) == sp0) 137c80476e4SDavid E. O'Brien return (buf); /* nada */ 138c80476e4SDavid E. O'Brien if (sp == (sp0 = sp0->prev)) 139c80476e4SDavid E. O'Brien return (buf); /* nada */ 140c80476e4SDavid E. O'Brien 141c80476e4SDavid E. O'Brien for (i = 0; i < NCARGS; i++) { 142c80476e4SDavid E. O'Brien if ((i >= from) && (i <= to)) { /* if in range */ 143c80476e4SDavid E. O'Brien for (s = sp->word; *s && d < e; s++) { 144c80476e4SDavid E. O'Brien /* 145c80476e4SDavid E. O'Brien * bugfix by Michael Bloom: anything but the current history 146c80476e4SDavid E. O'Brien * character {(PWP) and backslash} seem to be dealt with 147c80476e4SDavid E. O'Brien * elsewhere. 148c80476e4SDavid E. O'Brien */ 149c80476e4SDavid E. O'Brien if ((*s & QUOTE) 150c80476e4SDavid E. O'Brien && (((*s & TRIM) == HIST) || 151c80476e4SDavid E. O'Brien (((*s & TRIM) == '\'') && (prev_c != '\\')) || 152c80476e4SDavid E. O'Brien (((*s & TRIM) == '\"') && (prev_c != '\\')) || 153c80476e4SDavid E. O'Brien (((*s & TRIM) == '\\') && (prev_c != '\\')))) { 154c80476e4SDavid E. O'Brien *d++ = '\\'; 155c80476e4SDavid E. O'Brien } 156c80476e4SDavid E. O'Brien if (d < e) 157c80476e4SDavid E. O'Brien *d++ = (*s & TRIM); 158c80476e4SDavid E. O'Brien prev_c = *s; 159c80476e4SDavid E. O'Brien } 160c80476e4SDavid E. O'Brien if (d < e) 161c80476e4SDavid E. O'Brien *d++ = ' '; 162c80476e4SDavid E. O'Brien } 163c80476e4SDavid E. O'Brien sp = sp->next; 164c80476e4SDavid E. O'Brien if (sp == sp0) 165c80476e4SDavid E. O'Brien break; 166c80476e4SDavid E. O'Brien } 167c80476e4SDavid E. O'Brien if (d > buf) 168c80476e4SDavid E. O'Brien d--; /* get rid of trailing space */ 169c80476e4SDavid E. O'Brien 170c80476e4SDavid E. O'Brien return (d); 171c80476e4SDavid E. O'Brien } 172c80476e4SDavid E. O'Brien 173c80476e4SDavid E. O'Brien Char * 174c80476e4SDavid E. O'Brien sprlex(buf, bufsiz, sp0) 175c80476e4SDavid E. O'Brien Char *buf; 176c80476e4SDavid E. O'Brien size_t bufsiz; 177c80476e4SDavid E. O'Brien struct wordent *sp0; 178c80476e4SDavid E. O'Brien { 179c80476e4SDavid E. O'Brien Char *cp; 180c80476e4SDavid E. O'Brien 181c80476e4SDavid E. O'Brien cp = expand_lex(buf, bufsiz, sp0, 0, NCARGS); 182c80476e4SDavid E. O'Brien *cp = '\0'; 183c80476e4SDavid E. O'Brien return (buf); 184c80476e4SDavid E. O'Brien } 185c80476e4SDavid E. O'Brien 186c80476e4SDavid E. O'Brien 187c80476e4SDavid E. O'Brien Char * 188c80476e4SDavid E. O'Brien Itoa(n, s, min_digits, attributes) 189c80476e4SDavid E. O'Brien int n; 190c80476e4SDavid E. O'Brien Char *s; 191c80476e4SDavid E. O'Brien int min_digits, attributes; 192c80476e4SDavid E. O'Brien { 193c80476e4SDavid E. O'Brien /* 194c80476e4SDavid E. O'Brien * The array size here is derived from 195c80476e4SDavid E. O'Brien * log8(UINT_MAX) 196c80476e4SDavid E. O'Brien * which is guaranteed to be enough for a decimal 197c80476e4SDavid E. O'Brien * representation. We add 1 because integer divide 198c80476e4SDavid E. O'Brien * rounds down. 199c80476e4SDavid E. O'Brien */ 200c80476e4SDavid E. O'Brien #ifndef CHAR_BIT 201c80476e4SDavid E. O'Brien # define CHAR_BIT 8 202c80476e4SDavid E. O'Brien #endif 203c80476e4SDavid E. O'Brien Char buf[CHAR_BIT * sizeof(int) / 3 + 1]; 204c80476e4SDavid E. O'Brien Char *p; 205c80476e4SDavid E. O'Brien unsigned int un; /* handle most negative # too */ 206c80476e4SDavid E. O'Brien int pad = (min_digits != 0); 207c80476e4SDavid E. O'Brien 208c80476e4SDavid E. O'Brien if (sizeof(buf) - 1 < min_digits) 209c80476e4SDavid E. O'Brien min_digits = sizeof(buf) - 1; 210c80476e4SDavid E. O'Brien 211c80476e4SDavid E. O'Brien un = n; 212c80476e4SDavid E. O'Brien if (n < 0) { 213c80476e4SDavid E. O'Brien un = -n; 214c80476e4SDavid E. O'Brien *s++ = '-'; 215c80476e4SDavid E. O'Brien } 216c80476e4SDavid E. O'Brien 217c80476e4SDavid E. O'Brien p = buf; 218c80476e4SDavid E. O'Brien do { 219c80476e4SDavid E. O'Brien *p++ = un % 10 + '0'; 220c80476e4SDavid E. O'Brien un /= 10; 221c80476e4SDavid E. O'Brien } while ((pad && --min_digits > 0) || un != 0); 222c80476e4SDavid E. O'Brien 223c80476e4SDavid E. O'Brien while (p > buf) 224c80476e4SDavid E. O'Brien *s++ = *--p | attributes; 225c80476e4SDavid E. O'Brien 226c80476e4SDavid E. O'Brien *s = '\0'; 227c80476e4SDavid E. O'Brien return s; 228c80476e4SDavid E. O'Brien } 229c80476e4SDavid E. O'Brien 230c80476e4SDavid E. O'Brien 231c80476e4SDavid E. O'Brien /*ARGSUSED*/ 232c80476e4SDavid E. O'Brien void 233c80476e4SDavid E. O'Brien dolist(v, c) 234c80476e4SDavid E. O'Brien register Char **v; 235c80476e4SDavid E. O'Brien struct command *c; 236c80476e4SDavid E. O'Brien { 237c80476e4SDavid E. O'Brien int i, k; 238c80476e4SDavid E. O'Brien struct stat st; 239c80476e4SDavid E. O'Brien #if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 240c80476e4SDavid E. O'Brien extern bool dspmbyte_ls; 241c80476e4SDavid E. O'Brien #endif 242c80476e4SDavid E. O'Brien #ifdef COLOR_LS_F 243c80476e4SDavid E. O'Brien extern bool color_context_ls; 244c80476e4SDavid E. O'Brien #endif /* COLOR_LS_F */ 245c80476e4SDavid E. O'Brien 246c80476e4SDavid E. O'Brien USE(c); 247c80476e4SDavid E. O'Brien if (*++v == NULL) { 248c80476e4SDavid E. O'Brien (void) t_search(STRNULL, NULL, LIST, 0, TW_ZERO, 0, STRNULL, 0); 249c80476e4SDavid E. O'Brien return; 250c80476e4SDavid E. O'Brien } 251c80476e4SDavid E. O'Brien gflag = 0; 252c80476e4SDavid E. O'Brien tglob(v); 253c80476e4SDavid E. O'Brien if (gflag) { 254c80476e4SDavid E. O'Brien v = globall(v); 255c80476e4SDavid E. O'Brien if (v == 0) 256c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_NOMATCH); 257c80476e4SDavid E. O'Brien } 258c80476e4SDavid E. O'Brien else 259c80476e4SDavid E. O'Brien v = gargv = saveblk(v); 260c80476e4SDavid E. O'Brien trim(v); 261c80476e4SDavid E. O'Brien for (k = 0; v[k] != NULL && v[k][0] != '-'; k++) 262c80476e4SDavid E. O'Brien continue; 263c80476e4SDavid E. O'Brien if (v[k]) { 264c80476e4SDavid E. O'Brien /* 265c80476e4SDavid E. O'Brien * We cannot process a flag therefore we let ls do it right. 266c80476e4SDavid E. O'Brien */ 267c80476e4SDavid E. O'Brien static Char STRls[] = {'l', 's', '\0'}; 268c80476e4SDavid E. O'Brien static Char STRmCF[] = {'-', 'C', 'F', '\0', '\0' }; 269c80476e4SDavid E. O'Brien Char *lspath; 270c80476e4SDavid E. O'Brien struct command *t; 271c80476e4SDavid E. O'Brien struct wordent cmd, *nextword, *lastword; 272c80476e4SDavid E. O'Brien Char *cp; 273c80476e4SDavid E. O'Brien struct varent *vp; 274c80476e4SDavid E. O'Brien 275c80476e4SDavid E. O'Brien #ifdef BSDSIGS 276c80476e4SDavid E. O'Brien sigmask_t omask = 0; 277c80476e4SDavid E. O'Brien 278c80476e4SDavid E. O'Brien if (setintr) 279c80476e4SDavid E. O'Brien omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT); 280c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 281c80476e4SDavid E. O'Brien (void) sighold(SIGINT); 282c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 283c80476e4SDavid E. O'Brien if (seterr) { 284c80476e4SDavid E. O'Brien xfree((ptr_t) seterr); 285c80476e4SDavid E. O'Brien seterr = NULL; 286c80476e4SDavid E. O'Brien } 287c80476e4SDavid E. O'Brien 288c80476e4SDavid E. O'Brien lspath = STRls; 289c80476e4SDavid E. O'Brien STRmCF[1] = 'C'; 290c80476e4SDavid E. O'Brien STRmCF[3] = '\0'; 291c80476e4SDavid E. O'Brien /* Look at listflags, to add -A to the flags, to get a path 292c80476e4SDavid E. O'Brien of ls if necessary */ 293c80476e4SDavid E. O'Brien if ((vp = adrof(STRlistflags)) != NULL && vp->vec[0] != STRNULL) { 294c80476e4SDavid E. O'Brien if (vp->vec[1] != NULL && vp->vec[1][0] != '\0') 295c80476e4SDavid E. O'Brien lspath = vp->vec[1]; 296c80476e4SDavid E. O'Brien for (cp = vp->vec[0]; *cp; cp++) 297c80476e4SDavid E. O'Brien switch (*cp) { 298c80476e4SDavid E. O'Brien case 'x': 299c80476e4SDavid E. O'Brien STRmCF[1] = 'x'; 300c80476e4SDavid E. O'Brien break; 301c80476e4SDavid E. O'Brien case 'a': 302c80476e4SDavid E. O'Brien STRmCF[3] = 'a'; 303c80476e4SDavid E. O'Brien break; 304c80476e4SDavid E. O'Brien case 'A': 305c80476e4SDavid E. O'Brien STRmCF[3] = 'A'; 306c80476e4SDavid E. O'Brien break; 307c80476e4SDavid E. O'Brien default: 308c80476e4SDavid E. O'Brien break; 309c80476e4SDavid E. O'Brien } 310c80476e4SDavid E. O'Brien } 311c80476e4SDavid E. O'Brien 312c80476e4SDavid E. O'Brien cmd.word = STRNULL; 313c80476e4SDavid E. O'Brien lastword = &cmd; 314c80476e4SDavid E. O'Brien nextword = (struct wordent *) xcalloc(1, sizeof cmd); 315c80476e4SDavid E. O'Brien nextword->word = Strsave(lspath); 316c80476e4SDavid E. O'Brien lastword->next = nextword; 317c80476e4SDavid E. O'Brien nextword->prev = lastword; 318c80476e4SDavid E. O'Brien lastword = nextword; 319c80476e4SDavid E. O'Brien nextword = (struct wordent *) xcalloc(1, sizeof cmd); 320c80476e4SDavid E. O'Brien nextword->word = Strsave(STRmCF); 321c80476e4SDavid E. O'Brien lastword->next = nextword; 322c80476e4SDavid E. O'Brien nextword->prev = lastword; 323c80476e4SDavid E. O'Brien #if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 324c80476e4SDavid E. O'Brien if (dspmbyte_ls) { 325c80476e4SDavid E. O'Brien lastword = nextword; 326c80476e4SDavid E. O'Brien nextword = (struct wordent *) xcalloc(1, sizeof cmd); 327c80476e4SDavid E. O'Brien nextword->word = Strsave(STRmmliteral); 328c80476e4SDavid E. O'Brien lastword->next = nextword; 329c80476e4SDavid E. O'Brien nextword->prev = lastword; 330c80476e4SDavid E. O'Brien } 331c80476e4SDavid E. O'Brien #endif 332c80476e4SDavid E. O'Brien #ifdef COLOR_LS_F 333c80476e4SDavid E. O'Brien if (color_context_ls) { 334c80476e4SDavid E. O'Brien lastword = nextword; 335c80476e4SDavid E. O'Brien nextword = (struct wordent *) xcalloc(1, sizeof cmd); 336c80476e4SDavid E. O'Brien nextword->word = Strsave(STRmmcolormauto); 337c80476e4SDavid E. O'Brien lastword->next = nextword; 338c80476e4SDavid E. O'Brien nextword->prev = lastword; 339c80476e4SDavid E. O'Brien } 340c80476e4SDavid E. O'Brien #endif /* COLOR_LS_F */ 341c80476e4SDavid E. O'Brien lastword = nextword; 342c80476e4SDavid E. O'Brien for (cp = *v; cp; cp = *++v) { 343c80476e4SDavid E. O'Brien nextword = (struct wordent *) xcalloc(1, sizeof cmd); 344c80476e4SDavid E. O'Brien nextword->word = Strsave(cp); 345c80476e4SDavid E. O'Brien lastword->next = nextword; 346c80476e4SDavid E. O'Brien nextword->prev = lastword; 347c80476e4SDavid E. O'Brien lastword = nextword; 348c80476e4SDavid E. O'Brien } 349c80476e4SDavid E. O'Brien lastword->next = &cmd; 350c80476e4SDavid E. O'Brien cmd.prev = lastword; 351c80476e4SDavid E. O'Brien 352c80476e4SDavid E. O'Brien /* build a syntax tree for the command. */ 353c80476e4SDavid E. O'Brien t = syntax(cmd.next, &cmd, 0); 354c80476e4SDavid E. O'Brien if (seterr) 355c80476e4SDavid E. O'Brien stderror(ERR_OLD); 356c80476e4SDavid E. O'Brien /* expand aliases like process() does */ 357c80476e4SDavid E. O'Brien /* alias(&cmd); */ 358c80476e4SDavid E. O'Brien /* execute the parse tree. */ 359c80476e4SDavid E. O'Brien execute(t, tpgrp > 0 ? tpgrp : -1, NULL, NULL); 360c80476e4SDavid E. O'Brien /* done. free the lex list and parse tree. */ 361c80476e4SDavid E. O'Brien freelex(&cmd), freesyn(t); 362c80476e4SDavid E. O'Brien if (setintr) 363c80476e4SDavid E. O'Brien #ifdef BSDSIGS 364c80476e4SDavid E. O'Brien (void) sigsetmask(omask); 365c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 366c80476e4SDavid E. O'Brien (void) sigrelse(SIGINT); 367c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 368c80476e4SDavid E. O'Brien } 369c80476e4SDavid E. O'Brien else { 370c80476e4SDavid E. O'Brien Char *dp, *tmp, buf[MAXPATHLEN]; 371c80476e4SDavid E. O'Brien 372c80476e4SDavid E. O'Brien for (k = 0, i = 0; v[k] != NULL; k++) { 373c80476e4SDavid E. O'Brien tmp = dnormalize(v[k], symlinks == SYM_IGNORE); 374c80476e4SDavid E. O'Brien dp = &tmp[Strlen(tmp) - 1]; 375c80476e4SDavid E. O'Brien if (*dp == '/' && dp != tmp) 376c80476e4SDavid E. O'Brien #ifdef apollo 377c80476e4SDavid E. O'Brien if (dp != &tmp[1]) 378c80476e4SDavid E. O'Brien #endif /* apollo */ 379c80476e4SDavid E. O'Brien *dp = '\0'; 380c80476e4SDavid E. O'Brien if (stat(short2str(tmp), &st) == -1) { 381c80476e4SDavid E. O'Brien if (k != i) { 382c80476e4SDavid E. O'Brien if (i != 0) 383c80476e4SDavid E. O'Brien xputchar('\n'); 384c80476e4SDavid E. O'Brien print_by_column(STRNULL, &v[i], k - i, FALSE); 385c80476e4SDavid E. O'Brien } 386c80476e4SDavid E. O'Brien xprintf("%S: %s.\n", tmp, strerror(errno)); 387c80476e4SDavid E. O'Brien i = k + 1; 388c80476e4SDavid E. O'Brien } 389c80476e4SDavid E. O'Brien else if (S_ISDIR(st.st_mode)) { 390c80476e4SDavid E. O'Brien Char *cp; 391c80476e4SDavid E. O'Brien 392c80476e4SDavid E. O'Brien if (k != i) { 393c80476e4SDavid E. O'Brien if (i != 0) 394c80476e4SDavid E. O'Brien xputchar('\n'); 395c80476e4SDavid E. O'Brien print_by_column(STRNULL, &v[i], k - i, FALSE); 396c80476e4SDavid E. O'Brien } 397c80476e4SDavid E. O'Brien if (k != 0 && v[1] != NULL) 398c80476e4SDavid E. O'Brien xputchar('\n'); 399c80476e4SDavid E. O'Brien xprintf("%S:\n", tmp); 400c80476e4SDavid E. O'Brien for (cp = tmp, dp = buf; *cp; *dp++ = (*cp++ | QUOTE)) 401c80476e4SDavid E. O'Brien continue; 402c80476e4SDavid E. O'Brien if ( 4033b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 404c80476e4SDavid E. O'Brien (dp[-1] != (Char) (':' | QUOTE)) && 4053b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 406c80476e4SDavid E. O'Brien (dp[-1] != (Char) ('/' | QUOTE))) 407c80476e4SDavid E. O'Brien *dp++ = '/'; 408c80476e4SDavid E. O'Brien else 409c80476e4SDavid E. O'Brien dp[-1] &= TRIM; 410c80476e4SDavid E. O'Brien *dp = '\0'; 411c80476e4SDavid E. O'Brien (void) t_search(buf, NULL, LIST, 0, TW_ZERO, 0, STRNULL, 0); 412c80476e4SDavid E. O'Brien i = k + 1; 413c80476e4SDavid E. O'Brien } 414c80476e4SDavid E. O'Brien xfree((ptr_t) tmp); 415c80476e4SDavid E. O'Brien } 416c80476e4SDavid E. O'Brien if (k != i) { 417c80476e4SDavid E. O'Brien if (i != 0) 418c80476e4SDavid E. O'Brien xputchar('\n'); 419c80476e4SDavid E. O'Brien print_by_column(STRNULL, &v[i], k - i, FALSE); 420c80476e4SDavid E. O'Brien } 421c80476e4SDavid E. O'Brien } 422c80476e4SDavid E. O'Brien 423c80476e4SDavid E. O'Brien if (gargv) { 424c80476e4SDavid E. O'Brien blkfree(gargv); 425c80476e4SDavid E. O'Brien gargv = 0; 426c80476e4SDavid E. O'Brien } 427c80476e4SDavid E. O'Brien } 428c80476e4SDavid E. O'Brien 429c80476e4SDavid E. O'Brien static char *defaulttell = "ALL"; 430c80476e4SDavid E. O'Brien extern bool GotTermCaps; 431c80476e4SDavid E. O'Brien 432c80476e4SDavid E. O'Brien /*ARGSUSED*/ 433c80476e4SDavid E. O'Brien void 434c80476e4SDavid E. O'Brien dotelltc(v, c) 435c80476e4SDavid E. O'Brien register Char **v; 436c80476e4SDavid E. O'Brien struct command *c; 437c80476e4SDavid E. O'Brien { 438c80476e4SDavid E. O'Brien USE(c); 439c80476e4SDavid E. O'Brien if (!GotTermCaps) 440c80476e4SDavid E. O'Brien GetTermCaps(); 441c80476e4SDavid E. O'Brien 442c80476e4SDavid E. O'Brien /* 443c80476e4SDavid E. O'Brien * Avoid a compiler bug on hpux 9.05 444c80476e4SDavid E. O'Brien * Writing the following as func(a ? b : c) breaks 445c80476e4SDavid E. O'Brien */ 446c80476e4SDavid E. O'Brien if (v[1]) 447c80476e4SDavid E. O'Brien TellTC(short2str(v[1])); 448c80476e4SDavid E. O'Brien else 449c80476e4SDavid E. O'Brien TellTC(defaulttell); 450c80476e4SDavid E. O'Brien } 451c80476e4SDavid E. O'Brien 452c80476e4SDavid E. O'Brien /*ARGSUSED*/ 453c80476e4SDavid E. O'Brien void 454c80476e4SDavid E. O'Brien doechotc(v, c) 455c80476e4SDavid E. O'Brien register Char **v; 456c80476e4SDavid E. O'Brien struct command *c; 457c80476e4SDavid E. O'Brien { 458c80476e4SDavid E. O'Brien if (!GotTermCaps) 459c80476e4SDavid E. O'Brien GetTermCaps(); 460c80476e4SDavid E. O'Brien EchoTC(++v); 461c80476e4SDavid E. O'Brien } 462c80476e4SDavid E. O'Brien 463c80476e4SDavid E. O'Brien /*ARGSUSED*/ 464c80476e4SDavid E. O'Brien void 465c80476e4SDavid E. O'Brien dosettc(v, c) 466c80476e4SDavid E. O'Brien Char **v; 467c80476e4SDavid E. O'Brien struct command *c; 468c80476e4SDavid E. O'Brien { 469c80476e4SDavid E. O'Brien char tv[2][BUFSIZE]; 470c80476e4SDavid E. O'Brien 471c80476e4SDavid E. O'Brien if (!GotTermCaps) 472c80476e4SDavid E. O'Brien GetTermCaps(); 473c80476e4SDavid E. O'Brien 474c80476e4SDavid E. O'Brien (void) strcpy(tv[0], short2str(v[1])); 475c80476e4SDavid E. O'Brien (void) strcpy(tv[1], short2str(v[2])); 476c80476e4SDavid E. O'Brien SetTC(tv[0], tv[1]); 477c80476e4SDavid E. O'Brien } 478c80476e4SDavid E. O'Brien 479c80476e4SDavid E. O'Brien /* The dowhich() is by: 480c80476e4SDavid E. O'Brien * Andreas Luik <luik@isaak.isa.de> 481c80476e4SDavid E. O'Brien * I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung 482c80476e4SDavid E. O'Brien * Azenberstr. 35 483c80476e4SDavid E. O'Brien * D-7000 Stuttgart 1 484c80476e4SDavid E. O'Brien * West-Germany 485c80476e4SDavid E. O'Brien * Thanks!! 486c80476e4SDavid E. O'Brien */ 487c80476e4SDavid E. O'Brien int 488c80476e4SDavid E. O'Brien cmd_expand(cmd, str) 489c80476e4SDavid E. O'Brien Char *cmd; 490c80476e4SDavid E. O'Brien Char *str; 491c80476e4SDavid E. O'Brien { 492c80476e4SDavid E. O'Brien struct wordent lexp[3]; 493c80476e4SDavid E. O'Brien struct varent *vp; 494c80476e4SDavid E. O'Brien int rv = TRUE; 495c80476e4SDavid E. O'Brien 496c80476e4SDavid E. O'Brien lexp[0].next = &lexp[1]; 497c80476e4SDavid E. O'Brien lexp[1].next = &lexp[2]; 498c80476e4SDavid E. O'Brien lexp[2].next = &lexp[0]; 499c80476e4SDavid E. O'Brien 500c80476e4SDavid E. O'Brien lexp[0].prev = &lexp[2]; 501c80476e4SDavid E. O'Brien lexp[1].prev = &lexp[0]; 502c80476e4SDavid E. O'Brien lexp[2].prev = &lexp[1]; 503c80476e4SDavid E. O'Brien 504c80476e4SDavid E. O'Brien lexp[0].word = STRNULL; 505c80476e4SDavid E. O'Brien lexp[2].word = STRret; 506c80476e4SDavid E. O'Brien 507c80476e4SDavid E. O'Brien if ((vp = adrof1(cmd, &aliases)) != NULL) { 508c80476e4SDavid E. O'Brien if (str == NULL) { 509c80476e4SDavid E. O'Brien xprintf(CGETS(22, 1, "%S: \t aliased to "), cmd); 510c80476e4SDavid E. O'Brien blkpr(vp->vec); 511c80476e4SDavid E. O'Brien xputchar('\n'); 512c80476e4SDavid E. O'Brien } 513c80476e4SDavid E. O'Brien else 514c80476e4SDavid E. O'Brien blkexpand(vp->vec, str); 515c80476e4SDavid E. O'Brien } 516c80476e4SDavid E. O'Brien else { 517c80476e4SDavid E. O'Brien lexp[1].word = cmd; 518c80476e4SDavid E. O'Brien rv = tellmewhat(lexp, str); 519c80476e4SDavid E. O'Brien } 520c80476e4SDavid E. O'Brien return rv; 521c80476e4SDavid E. O'Brien } 522c80476e4SDavid E. O'Brien 523c80476e4SDavid E. O'Brien 524c80476e4SDavid E. O'Brien /*ARGSUSED*/ 525c80476e4SDavid E. O'Brien void 526c80476e4SDavid E. O'Brien dowhich(v, c) 527c80476e4SDavid E. O'Brien register Char **v; 528c80476e4SDavid E. O'Brien struct command *c; 529c80476e4SDavid E. O'Brien { 530c80476e4SDavid E. O'Brien int rv = TRUE; 531c80476e4SDavid E. O'Brien USE(c); 532c80476e4SDavid E. O'Brien 533c80476e4SDavid E. O'Brien #ifdef notdef 534c80476e4SDavid E. O'Brien /* 535c80476e4SDavid E. O'Brien * We don't want to glob dowhich args because we lose quoteing 536c80476e4SDavid E. O'Brien * E.g. which \ls if ls is aliased will not work correctly if 537c80476e4SDavid E. O'Brien * we glob here. 538c80476e4SDavid E. O'Brien */ 539c80476e4SDavid E. O'Brien gflag = 0, tglob(v); 540c80476e4SDavid E. O'Brien if (gflag) { 541c80476e4SDavid E. O'Brien v = globall(v); 542c80476e4SDavid E. O'Brien if (v == 0) 543c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_NOMATCH); 544c80476e4SDavid E. O'Brien } 545c80476e4SDavid E. O'Brien else { 546c80476e4SDavid E. O'Brien v = gargv = saveblk(v); 547c80476e4SDavid E. O'Brien trim(v); 548c80476e4SDavid E. O'Brien } 549c80476e4SDavid E. O'Brien #endif 550c80476e4SDavid E. O'Brien 551c80476e4SDavid E. O'Brien while (*++v) 552c80476e4SDavid E. O'Brien rv &= cmd_expand(*v, NULL); 553c80476e4SDavid E. O'Brien 554c80476e4SDavid E. O'Brien if (!rv) 555c80476e4SDavid E. O'Brien set(STRstatus, Strsave(STR1), VAR_READWRITE); 556c80476e4SDavid E. O'Brien 557c80476e4SDavid E. O'Brien #ifdef notdef 558c80476e4SDavid E. O'Brien /* Again look at the comment above; since we don't glob, we don't free */ 559c80476e4SDavid E. O'Brien if (gargv) 560c80476e4SDavid E. O'Brien blkfree(gargv), gargv = 0; 561c80476e4SDavid E. O'Brien #endif 562c80476e4SDavid E. O'Brien } 563c80476e4SDavid E. O'Brien 564c80476e4SDavid E. O'Brien /* PWP: a hack to start up your stopped editor on a single keystroke */ 565c80476e4SDavid E. O'Brien /* jbs - fixed hack so it worked :-) 3/28/89 */ 566c80476e4SDavid E. O'Brien 567c80476e4SDavid E. O'Brien struct process * 568c80476e4SDavid E. O'Brien find_stop_ed() 569c80476e4SDavid E. O'Brien { 570c80476e4SDavid E. O'Brien register struct process *pp, *retp; 571c80476e4SDavid E. O'Brien register char *ep, *vp, *cp, *p; 572c80476e4SDavid E. O'Brien int epl, vpl, pstatus; 573c80476e4SDavid E. O'Brien 574c80476e4SDavid E. O'Brien if ((ep = getenv("EDITOR")) != NULL) { /* if we have a value */ 575c80476e4SDavid E. O'Brien if ((p = strrchr(ep, '/')) != NULL) /* if it has a path */ 576c80476e4SDavid E. O'Brien ep = p + 1; /* then we want only the last part */ 577c80476e4SDavid E. O'Brien } 578c80476e4SDavid E. O'Brien else 579c80476e4SDavid E. O'Brien ep = "ed"; 580c80476e4SDavid E. O'Brien 581c80476e4SDavid E. O'Brien if ((vp = getenv("VISUAL")) != NULL) { /* if we have a value */ 582c80476e4SDavid E. O'Brien if ((p = strrchr(vp, '/')) != NULL) /* and it has a path */ 583c80476e4SDavid E. O'Brien vp = p + 1; /* then we want only the last part */ 584c80476e4SDavid E. O'Brien } 585c80476e4SDavid E. O'Brien else 586c80476e4SDavid E. O'Brien vp = "vi"; 587c80476e4SDavid E. O'Brien 588c80476e4SDavid E. O'Brien for (vpl = 0; vp[vpl] && !Isspace(vp[vpl]); vpl++) 589c80476e4SDavid E. O'Brien continue; 590c80476e4SDavid E. O'Brien for (epl = 0; ep[epl] && !Isspace(ep[epl]); epl++) 591c80476e4SDavid E. O'Brien continue; 592c80476e4SDavid E. O'Brien 593c80476e4SDavid E. O'Brien if (pcurrent == NULL) /* see if we have any jobs */ 594c80476e4SDavid E. O'Brien return NULL; /* nope */ 595c80476e4SDavid E. O'Brien 596c80476e4SDavid E. O'Brien retp = NULL; 597c80476e4SDavid E. O'Brien for (pp = proclist.p_next; pp; pp = pp->p_next) 598c80476e4SDavid E. O'Brien if (pp->p_procid == pp->p_jobid) { 599c80476e4SDavid E. O'Brien 600c80476e4SDavid E. O'Brien /* 601c80476e4SDavid E. O'Brien * Only foreground an edit session if it is suspended. Some GUI 602c80476e4SDavid E. O'Brien * editors have may be happily running in a separate window, no 603c80476e4SDavid E. O'Brien * point in foregrounding these if they're already running - webb 604c80476e4SDavid E. O'Brien */ 605c80476e4SDavid E. O'Brien pstatus = (int) (pp->p_flags & PALLSTATES); 606c80476e4SDavid E. O'Brien if (pstatus != PINTERRUPTED && pstatus != PSTOPPED && 607c80476e4SDavid E. O'Brien pstatus != PSIGNALED) 608c80476e4SDavid E. O'Brien continue; 609c80476e4SDavid E. O'Brien 610c80476e4SDavid E. O'Brien p = short2str(pp->p_command); 611c80476e4SDavid E. O'Brien /* get the first word */ 612c80476e4SDavid E. O'Brien for (cp = p; *cp && !isspace((unsigned char) *cp); cp++) 613c80476e4SDavid E. O'Brien continue; 614c80476e4SDavid E. O'Brien *cp = '\0'; 615c80476e4SDavid E. O'Brien 616c80476e4SDavid E. O'Brien if ((cp = strrchr(p, '/')) != NULL) /* and it has a path */ 617c80476e4SDavid E. O'Brien cp = cp + 1; /* then we want only the last part */ 618c80476e4SDavid E. O'Brien else 619c80476e4SDavid E. O'Brien cp = p; /* else we get all of it */ 620c80476e4SDavid E. O'Brien 621c80476e4SDavid E. O'Brien /* if we find either in the current name, fg it */ 622c80476e4SDavid E. O'Brien if (strncmp(ep, cp, (size_t) epl) == 0 || 623c80476e4SDavid E. O'Brien strncmp(vp, cp, (size_t) vpl) == 0) { 624c80476e4SDavid E. O'Brien 625c80476e4SDavid E. O'Brien /* 626c80476e4SDavid E. O'Brien * If there is a choice, then choose the current process if 627c80476e4SDavid E. O'Brien * available, or the previous process otherwise, or else 628c80476e4SDavid E. O'Brien * anything will do - Robert Webb (robertw@mulga.cs.mu.oz.au). 629c80476e4SDavid E. O'Brien */ 630c80476e4SDavid E. O'Brien if (pp == pcurrent) 631c80476e4SDavid E. O'Brien return pp; 632c80476e4SDavid E. O'Brien else if (retp == NULL || pp == pprevious) 633c80476e4SDavid E. O'Brien retp = pp; 634c80476e4SDavid E. O'Brien } 635c80476e4SDavid E. O'Brien } 636c80476e4SDavid E. O'Brien 637c80476e4SDavid E. O'Brien return retp; /* Will be NULL if we didn't find a job */ 638c80476e4SDavid E. O'Brien } 639c80476e4SDavid E. O'Brien 640c80476e4SDavid E. O'Brien void 641c80476e4SDavid E. O'Brien fg_proc_entry(pp) 642c80476e4SDavid E. O'Brien register struct process *pp; 643c80476e4SDavid E. O'Brien { 644c80476e4SDavid E. O'Brien #ifdef BSDSIGS 645c80476e4SDavid E. O'Brien sigmask_t omask; 646c80476e4SDavid E. O'Brien #endif 647c80476e4SDavid E. O'Brien jmp_buf_t osetexit; 648c80476e4SDavid E. O'Brien bool ohaderr; 649c80476e4SDavid E. O'Brien Char oGettingInput; 650c80476e4SDavid E. O'Brien 651c80476e4SDavid E. O'Brien getexit(osetexit); 652c80476e4SDavid E. O'Brien 653c80476e4SDavid E. O'Brien #ifdef BSDSIGS 654c80476e4SDavid E. O'Brien omask = sigblock(sigmask(SIGINT)); 655c80476e4SDavid E. O'Brien #else 656c80476e4SDavid E. O'Brien (void) sighold(SIGINT); 657c80476e4SDavid E. O'Brien #endif 658c80476e4SDavid E. O'Brien oGettingInput = GettingInput; 659c80476e4SDavid E. O'Brien GettingInput = 0; 660c80476e4SDavid E. O'Brien 661c80476e4SDavid E. O'Brien ohaderr = haderr; /* we need to ignore setting of haderr due to 662c80476e4SDavid E. O'Brien * process getting stopped by a signal */ 663c80476e4SDavid E. O'Brien if (setexit() == 0) { /* come back here after pjwait */ 664c80476e4SDavid E. O'Brien pendjob(); 665c80476e4SDavid E. O'Brien (void) alarm(0); /* No autologout */ 666c80476e4SDavid E. O'Brien if (!pstart(pp, 1)) { 667c80476e4SDavid E. O'Brien pp->p_procid = 0; 668c80476e4SDavid E. O'Brien stderror(ERR_BADJOB, pp->p_command, strerror(errno)); 669c80476e4SDavid E. O'Brien } 670c80476e4SDavid E. O'Brien pjwait(pp); 671c80476e4SDavid E. O'Brien } 672c80476e4SDavid E. O'Brien setalarm(1); /* Autologout back on */ 673c80476e4SDavid E. O'Brien resexit(osetexit); 674c80476e4SDavid E. O'Brien haderr = ohaderr; 675c80476e4SDavid E. O'Brien GettingInput = oGettingInput; 676c80476e4SDavid E. O'Brien 677c80476e4SDavid E. O'Brien #ifdef BSDSIGS 678c80476e4SDavid E. O'Brien (void) sigsetmask(omask); 679c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 680c80476e4SDavid E. O'Brien (void) sigrelse(SIGINT); 681c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 682c80476e4SDavid E. O'Brien 683c80476e4SDavid E. O'Brien } 684c80476e4SDavid E. O'Brien 685c80476e4SDavid E. O'Brien static char * 686c80476e4SDavid E. O'Brien xgetpass(prm) 687c80476e4SDavid E. O'Brien char *prm; 688c80476e4SDavid E. O'Brien { 689c80476e4SDavid E. O'Brien static char pass[PASSMAX + 1]; 690c80476e4SDavid E. O'Brien int fd, i; 691c80476e4SDavid E. O'Brien signalfun_t sigint; 692c80476e4SDavid E. O'Brien 693c80476e4SDavid E. O'Brien sigint = (signalfun_t) sigset(SIGINT, SIG_IGN); 694c80476e4SDavid E. O'Brien (void) Rawmode(); /* Make sure, cause we want echo off */ 695c80476e4SDavid E. O'Brien if ((fd = open("/dev/tty", O_RDWR)) == -1) 696c80476e4SDavid E. O'Brien fd = SHIN; 697c80476e4SDavid E. O'Brien 698c80476e4SDavid E. O'Brien xprintf("%s", prm); flush(); 699c80476e4SDavid E. O'Brien for (i = 0;;) { 700c80476e4SDavid E. O'Brien if (read(fd, &pass[i], 1) < 1 || pass[i] == '\n') 701c80476e4SDavid E. O'Brien break; 702c80476e4SDavid E. O'Brien if (i < PASSMAX) 703c80476e4SDavid E. O'Brien i++; 704c80476e4SDavid E. O'Brien } 705c80476e4SDavid E. O'Brien 706c80476e4SDavid E. O'Brien pass[i] = '\0'; 707c80476e4SDavid E. O'Brien 708c80476e4SDavid E. O'Brien if (fd != SHIN) 709c80476e4SDavid E. O'Brien (void) close(fd); 710c80476e4SDavid E. O'Brien (void) sigset(SIGINT, sigint); 711c80476e4SDavid E. O'Brien 712c80476e4SDavid E. O'Brien return(pass); 713c80476e4SDavid E. O'Brien } 714c80476e4SDavid E. O'Brien 715c80476e4SDavid E. O'Brien /* 716c80476e4SDavid E. O'Brien * Ask the user for his login password to continue working 717c80476e4SDavid E. O'Brien * On systems that have a shadow password, this will only 718c80476e4SDavid E. O'Brien * work for root, but what can we do? 719c80476e4SDavid E. O'Brien * 720c80476e4SDavid E. O'Brien * If we fail to get the password, then we log the user out 721c80476e4SDavid E. O'Brien * immediately 722c80476e4SDavid E. O'Brien */ 723c80476e4SDavid E. O'Brien /*ARGSUSED*/ 724c80476e4SDavid E. O'Brien static void 725c80476e4SDavid E. O'Brien auto_lock(n) 726c80476e4SDavid E. O'Brien int n; 727c80476e4SDavid E. O'Brien { 728c80476e4SDavid E. O'Brien #ifndef NO_CRYPT 729c80476e4SDavid E. O'Brien 730c80476e4SDavid E. O'Brien int i; 731c80476e4SDavid E. O'Brien char *srpp = NULL; 732c80476e4SDavid E. O'Brien struct passwd *pw; 733c80476e4SDavid E. O'Brien #ifdef POSIX 734c80476e4SDavid E. O'Brien extern char *crypt __P((const char *, const char *)); 735c80476e4SDavid E. O'Brien #else 736c80476e4SDavid E. O'Brien extern char *crypt __P(()); 737c80476e4SDavid E. O'Brien #endif 738c80476e4SDavid E. O'Brien 739c80476e4SDavid E. O'Brien #undef XCRYPT 740c80476e4SDavid E. O'Brien 741c80476e4SDavid E. O'Brien #if defined(PW_AUTH) && !defined(XCRYPT) 742c80476e4SDavid E. O'Brien 743c80476e4SDavid E. O'Brien struct authorization *apw; 744c80476e4SDavid E. O'Brien extern char *crypt16 __P((const char *, const char *)); 745c80476e4SDavid E. O'Brien 746c80476e4SDavid E. O'Brien # define XCRYPT(a, b) crypt16(a, b) 747c80476e4SDavid E. O'Brien 748c80476e4SDavid E. O'Brien if ((pw = getpwuid(euid)) != NULL && /* effective user passwd */ 749c80476e4SDavid E. O'Brien (apw = getauthuid(euid)) != NULL) /* enhanced ultrix passwd */ 750c80476e4SDavid E. O'Brien srpp = apw->a_password; 751c80476e4SDavid E. O'Brien 752c80476e4SDavid E. O'Brien #endif /* PW_AUTH && !XCRYPT */ 753c80476e4SDavid E. O'Brien 754c80476e4SDavid E. O'Brien #if defined(PW_SHADOW) && !defined(XCRYPT) 755c80476e4SDavid E. O'Brien 756c80476e4SDavid E. O'Brien struct spwd *spw; 757c80476e4SDavid E. O'Brien 758c80476e4SDavid E. O'Brien # define XCRYPT(a, b) crypt(a, b) 759c80476e4SDavid E. O'Brien 760c80476e4SDavid E. O'Brien if ((pw = getpwuid(euid)) != NULL && /* effective user passwd */ 761c80476e4SDavid E. O'Brien (spw = getspnam(pw->pw_name)) != NULL) /* shadowed passwd */ 762c80476e4SDavid E. O'Brien srpp = spw->sp_pwdp; 763c80476e4SDavid E. O'Brien 764c80476e4SDavid E. O'Brien #endif /* PW_SHADOW && !XCRYPT */ 765c80476e4SDavid E. O'Brien 766c80476e4SDavid E. O'Brien #ifndef XCRYPT 767c80476e4SDavid E. O'Brien 768c80476e4SDavid E. O'Brien #define XCRYPT(a, b) crypt(a, b) 769c80476e4SDavid E. O'Brien 7703b6eaa7bSAndrey A. Chernov #if !defined(__MVS__) 771c80476e4SDavid E. O'Brien if ((pw = getpwuid(euid)) != NULL) /* effective user passwd */ 772c80476e4SDavid E. O'Brien srpp = pw->pw_passwd; 7733b6eaa7bSAndrey A. Chernov #endif /* !MVS */ 774c80476e4SDavid E. O'Brien 775c80476e4SDavid E. O'Brien #endif /* !XCRYPT */ 776c80476e4SDavid E. O'Brien 777c80476e4SDavid E. O'Brien if (srpp == NULL) { 778c80476e4SDavid E. O'Brien auto_logout(0); 779c80476e4SDavid E. O'Brien /*NOTREACHED*/ 780c80476e4SDavid E. O'Brien return; 781c80476e4SDavid E. O'Brien } 782c80476e4SDavid E. O'Brien 783c80476e4SDavid E. O'Brien setalarm(0); /* Not for locking any more */ 784c80476e4SDavid E. O'Brien #ifdef BSDSIGS 785c80476e4SDavid E. O'Brien (void) sigsetmask(sigblock(0) & ~(sigmask(SIGALRM))); 786c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 787c80476e4SDavid E. O'Brien (void) sigrelse(SIGALRM); 788c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 789c80476e4SDavid E. O'Brien xputchar('\n'); 790c80476e4SDavid E. O'Brien for (i = 0; i < 5; i++) { 791c80476e4SDavid E. O'Brien const char *crpp; 792c80476e4SDavid E. O'Brien char *pp; 793c80476e4SDavid E. O'Brien #ifdef AFS 794c80476e4SDavid E. O'Brien char *afsname; 795c80476e4SDavid E. O'Brien Char *safs; 796c80476e4SDavid E. O'Brien 797c80476e4SDavid E. O'Brien if ((safs = varval(STRafsuser)) != STRNULL) 798c80476e4SDavid E. O'Brien afsname = short2str(safs); 799c80476e4SDavid E. O'Brien else 800c80476e4SDavid E. O'Brien if ((afsname = getenv("AFSUSER")) == NULL) 801c80476e4SDavid E. O'Brien afsname = pw->pw_name; 802c80476e4SDavid E. O'Brien #endif 803c80476e4SDavid E. O'Brien pp = xgetpass("Password:"); 804c80476e4SDavid E. O'Brien 805c80476e4SDavid E. O'Brien crpp = XCRYPT(pp, srpp); 806c80476e4SDavid E. O'Brien if ((strcmp(crpp, srpp) == 0) 807c80476e4SDavid E. O'Brien #ifdef AFS 808c80476e4SDavid E. O'Brien || (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION, 809c80476e4SDavid E. O'Brien afsname, /* name */ 810c80476e4SDavid E. O'Brien NULL, /* instance */ 811c80476e4SDavid E. O'Brien NULL, /* realm */ 812c80476e4SDavid E. O'Brien pp, /* password */ 813c80476e4SDavid E. O'Brien 0, /* lifetime */ 814c80476e4SDavid E. O'Brien 0, 0, /* spare */ 815c80476e4SDavid E. O'Brien NULL) /* reason */ 816c80476e4SDavid E. O'Brien == 0) 817c80476e4SDavid E. O'Brien #endif /* AFS */ 818c80476e4SDavid E. O'Brien ) { 819c80476e4SDavid E. O'Brien (void) memset(pp, 0, PASSMAX); 820c80476e4SDavid E. O'Brien if (GettingInput && !just_signaled) { 821c80476e4SDavid E. O'Brien (void) Rawmode(); 822c80476e4SDavid E. O'Brien ClearLines(); 823c80476e4SDavid E. O'Brien ClearDisp(); 824c80476e4SDavid E. O'Brien Refresh(); 825c80476e4SDavid E. O'Brien } 826c80476e4SDavid E. O'Brien just_signaled = 0; 827c80476e4SDavid E. O'Brien return; 828c80476e4SDavid E. O'Brien } 829c80476e4SDavid E. O'Brien xprintf(CGETS(22, 2, "\nIncorrect passwd for %s\n"), pw->pw_name); 830c80476e4SDavid E. O'Brien } 831c80476e4SDavid E. O'Brien #endif /* NO_CRYPT */ 832c80476e4SDavid E. O'Brien auto_logout(0); 833c80476e4SDavid E. O'Brien USE(n); 834c80476e4SDavid E. O'Brien } 835c80476e4SDavid E. O'Brien 836c80476e4SDavid E. O'Brien 837c80476e4SDavid E. O'Brien static void 838c80476e4SDavid E. O'Brien auto_logout(n) 839c80476e4SDavid E. O'Brien int n; 840c80476e4SDavid E. O'Brien { 841c80476e4SDavid E. O'Brien USE(n); 842c80476e4SDavid E. O'Brien xprintf("auto-logout\n"); 843c80476e4SDavid E. O'Brien /* Don't leave the tty in raw mode */ 844c80476e4SDavid E. O'Brien if (editing) 845c80476e4SDavid E. O'Brien (void) Cookedmode(); 846c80476e4SDavid E. O'Brien (void) close(SHIN); 847c80476e4SDavid E. O'Brien set(STRlogout, Strsave(STRautomatic), VAR_READWRITE); 848c80476e4SDavid E. O'Brien child = 1; 849c80476e4SDavid E. O'Brien #ifdef TESLA 850c80476e4SDavid E. O'Brien do_logout = 1; 851c80476e4SDavid E. O'Brien #endif /* TESLA */ 852c80476e4SDavid E. O'Brien GettingInput = FALSE; /* make flush() work to write hist files. Huber*/ 853c80476e4SDavid E. O'Brien goodbye(NULL, NULL); 854c80476e4SDavid E. O'Brien } 855c80476e4SDavid E. O'Brien 856c80476e4SDavid E. O'Brien sigret_t 857c80476e4SDavid E. O'Brien /*ARGSUSED*/ 858c80476e4SDavid E. O'Brien alrmcatch(snum) 859c80476e4SDavid E. O'Brien int snum; 860c80476e4SDavid E. O'Brien { 861c80476e4SDavid E. O'Brien #ifdef UNRELSIGS 862c80476e4SDavid E. O'Brien if (snum) 863c80476e4SDavid E. O'Brien (void) sigset(SIGALRM, alrmcatch); 864c80476e4SDavid E. O'Brien #endif /* UNRELSIGS */ 865c80476e4SDavid E. O'Brien 866c80476e4SDavid E. O'Brien (*alm_fun)(0); 867c80476e4SDavid E. O'Brien 868c80476e4SDavid E. O'Brien setalarm(1); 869c80476e4SDavid E. O'Brien #ifndef SIGVOID 870c80476e4SDavid E. O'Brien return (snum); 871c80476e4SDavid E. O'Brien #endif /* !SIGVOID */ 872c80476e4SDavid E. O'Brien } 873c80476e4SDavid E. O'Brien 874c80476e4SDavid E. O'Brien /* 875c80476e4SDavid E. O'Brien * Karl Kleinpaste, 21oct1983. 876c80476e4SDavid E. O'Brien * Added precmd(), which checks for the alias 877c80476e4SDavid E. O'Brien * precmd in aliases. If it's there, the alias 878c80476e4SDavid E. O'Brien * is executed as a command. This is done 879c80476e4SDavid E. O'Brien * after mailchk() and just before print- 880c80476e4SDavid E. O'Brien * ing the prompt. Useful for things like printing 881c80476e4SDavid E. O'Brien * one's current directory just before each command. 882c80476e4SDavid E. O'Brien */ 883c80476e4SDavid E. O'Brien void 884c80476e4SDavid E. O'Brien precmd() 885c80476e4SDavid E. O'Brien { 886c80476e4SDavid E. O'Brien #ifdef BSDSIGS 887c80476e4SDavid E. O'Brien sigmask_t omask; 888c80476e4SDavid E. O'Brien 889c80476e4SDavid E. O'Brien omask = sigblock(sigmask(SIGINT)); 890c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 891c80476e4SDavid E. O'Brien (void) sighold(SIGINT); 892c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 893c80476e4SDavid E. O'Brien if (precmd_active) { /* an error must have been caught */ 894c80476e4SDavid E. O'Brien aliasrun(2, STRunalias, STRprecmd); 895c80476e4SDavid E. O'Brien xprintf(CGETS(22, 3, "Faulty alias 'precmd' removed.\n")); 896c80476e4SDavid E. O'Brien goto leave; 897c80476e4SDavid E. O'Brien } 898c80476e4SDavid E. O'Brien precmd_active = 1; 899c80476e4SDavid E. O'Brien if (!whyles && adrof1(STRprecmd, &aliases)) 900c80476e4SDavid E. O'Brien aliasrun(1, STRprecmd, NULL); 901c80476e4SDavid E. O'Brien leave: 902c80476e4SDavid E. O'Brien precmd_active = 0; 903c80476e4SDavid E. O'Brien #ifdef BSDSIGS 904c80476e4SDavid E. O'Brien (void) sigsetmask(omask); 905c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 906c80476e4SDavid E. O'Brien (void) sigrelse(SIGINT); 907c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 908c80476e4SDavid E. O'Brien } 909c80476e4SDavid E. O'Brien 910c80476e4SDavid E. O'Brien void 911c80476e4SDavid E. O'Brien postcmd() 912c80476e4SDavid E. O'Brien { 913c80476e4SDavid E. O'Brien #ifdef BSDSIGS 914c80476e4SDavid E. O'Brien sigmask_t omask; 915c80476e4SDavid E. O'Brien 916c80476e4SDavid E. O'Brien omask = sigblock(sigmask(SIGINT)); 917c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 918c80476e4SDavid E. O'Brien (void) sighold(SIGINT); 919c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 920c80476e4SDavid E. O'Brien if (postcmd_active) { /* an error must have been caught */ 921c80476e4SDavid E. O'Brien aliasrun(2, STRunalias, STRpostcmd); 922c80476e4SDavid E. O'Brien xprintf(CGETS(22, 3, "Faulty alias 'postcmd' removed.\n")); 923c80476e4SDavid E. O'Brien goto leave; 924c80476e4SDavid E. O'Brien } 925c80476e4SDavid E. O'Brien postcmd_active = 1; 926c80476e4SDavid E. O'Brien if (!whyles && adrof1(STRpostcmd, &aliases)) 927c80476e4SDavid E. O'Brien aliasrun(1, STRpostcmd, NULL); 928c80476e4SDavid E. O'Brien leave: 929c80476e4SDavid E. O'Brien postcmd_active = 0; 930c80476e4SDavid E. O'Brien #ifdef BSDSIGS 931c80476e4SDavid E. O'Brien (void) sigsetmask(omask); 932c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 933c80476e4SDavid E. O'Brien (void) sigrelse(SIGINT); 934c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 935c80476e4SDavid E. O'Brien } 936c80476e4SDavid E. O'Brien 937c80476e4SDavid E. O'Brien /* 938c80476e4SDavid E. O'Brien * Paul Placeway 11/24/87 Added cwd_cmd by hacking precmd() into 939c80476e4SDavid E. O'Brien * submission... Run every time $cwd is set (after it is set). Useful 940c80476e4SDavid E. O'Brien * for putting your machine and cwd (or anything else) in an xterm title 941c80476e4SDavid E. O'Brien * space. 942c80476e4SDavid E. O'Brien */ 943c80476e4SDavid E. O'Brien void 944c80476e4SDavid E. O'Brien cwd_cmd() 945c80476e4SDavid E. O'Brien { 946c80476e4SDavid E. O'Brien #ifdef BSDSIGS 947c80476e4SDavid E. O'Brien sigmask_t omask; 948c80476e4SDavid E. O'Brien 949c80476e4SDavid E. O'Brien omask = sigblock(sigmask(SIGINT)); 950c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 951c80476e4SDavid E. O'Brien (void) sighold(SIGINT); 952c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 953c80476e4SDavid E. O'Brien if (cwdcmd_active) { /* an error must have been caught */ 954c80476e4SDavid E. O'Brien aliasrun(2, STRunalias, STRcwdcmd); 955c80476e4SDavid E. O'Brien xprintf(CGETS(22, 4, "Faulty alias 'cwdcmd' removed.\n")); 956c80476e4SDavid E. O'Brien goto leave; 957c80476e4SDavid E. O'Brien } 958c80476e4SDavid E. O'Brien cwdcmd_active = 1; 959c80476e4SDavid E. O'Brien if (!whyles && adrof1(STRcwdcmd, &aliases)) 960c80476e4SDavid E. O'Brien aliasrun(1, STRcwdcmd, NULL); 961c80476e4SDavid E. O'Brien leave: 962c80476e4SDavid E. O'Brien cwdcmd_active = 0; 963c80476e4SDavid E. O'Brien #ifdef BSDSIGS 964c80476e4SDavid E. O'Brien (void) sigsetmask(omask); 965c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 966c80476e4SDavid E. O'Brien (void) sigrelse(SIGINT); 967c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 968c80476e4SDavid E. O'Brien } 969c80476e4SDavid E. O'Brien 970c80476e4SDavid E. O'Brien /* 971c80476e4SDavid E. O'Brien * Joachim Hoenig 07/16/91 Added beep_cmd, run every time tcsh wishes 972c80476e4SDavid E. O'Brien * to beep the terminal bell. Useful for playing nice sounds instead. 973c80476e4SDavid E. O'Brien */ 974c80476e4SDavid E. O'Brien void 975c80476e4SDavid E. O'Brien beep_cmd() 976c80476e4SDavid E. O'Brien { 977c80476e4SDavid E. O'Brien #ifdef BSDSIGS 978c80476e4SDavid E. O'Brien sigmask_t omask; 979c80476e4SDavid E. O'Brien 980c80476e4SDavid E. O'Brien omask = sigblock(sigmask(SIGINT)); 981c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 982c80476e4SDavid E. O'Brien (void) sighold(SIGINT); 983c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 984c80476e4SDavid E. O'Brien if (beepcmd_active) { /* an error must have been caught */ 985c80476e4SDavid E. O'Brien aliasrun(2, STRunalias, STRbeepcmd); 986c80476e4SDavid E. O'Brien xprintf(CGETS(22, 5, "Faulty alias 'beepcmd' removed.\n")); 987c80476e4SDavid E. O'Brien } 988c80476e4SDavid E. O'Brien else { 989c80476e4SDavid E. O'Brien beepcmd_active = 1; 990c80476e4SDavid E. O'Brien if (!whyles && adrof1(STRbeepcmd, &aliases)) 991c80476e4SDavid E. O'Brien aliasrun(1, STRbeepcmd, NULL); 992c80476e4SDavid E. O'Brien } 993c80476e4SDavid E. O'Brien beepcmd_active = 0; 994c80476e4SDavid E. O'Brien #ifdef BSDSIGS 995c80476e4SDavid E. O'Brien (void) sigsetmask(omask); 996c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 997c80476e4SDavid E. O'Brien (void) sigrelse(SIGINT); 998c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 999c80476e4SDavid E. O'Brien } 1000c80476e4SDavid E. O'Brien 1001c80476e4SDavid E. O'Brien 1002c80476e4SDavid E. O'Brien /* 1003c80476e4SDavid E. O'Brien * Karl Kleinpaste, 18 Jan 1984. 1004c80476e4SDavid E. O'Brien * Added period_cmd(), which executes the alias "periodic" every 1005c80476e4SDavid E. O'Brien * $tperiod minutes. Useful for occasional checking of msgs and such. 1006c80476e4SDavid E. O'Brien */ 1007c80476e4SDavid E. O'Brien void 1008c80476e4SDavid E. O'Brien period_cmd() 1009c80476e4SDavid E. O'Brien { 1010c80476e4SDavid E. O'Brien register Char *vp; 1011c80476e4SDavid E. O'Brien time_t t, interval; 1012c80476e4SDavid E. O'Brien #ifdef BSDSIGS 1013c80476e4SDavid E. O'Brien sigmask_t omask; 1014c80476e4SDavid E. O'Brien 1015c80476e4SDavid E. O'Brien omask = sigblock(sigmask(SIGINT)); 1016c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 1017c80476e4SDavid E. O'Brien (void) sighold(SIGINT); 1018c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 1019c80476e4SDavid E. O'Brien if (periodic_active) { /* an error must have been caught */ 1020c80476e4SDavid E. O'Brien aliasrun(2, STRunalias, STRperiodic); 1021c80476e4SDavid E. O'Brien xprintf(CGETS(22, 6, "Faulty alias 'periodic' removed.\n")); 1022c80476e4SDavid E. O'Brien goto leave; 1023c80476e4SDavid E. O'Brien } 1024c80476e4SDavid E. O'Brien periodic_active = 1; 1025c80476e4SDavid E. O'Brien if (!whyles && adrof1(STRperiodic, &aliases)) { 1026c80476e4SDavid E. O'Brien vp = varval(STRtperiod); 1027c80476e4SDavid E. O'Brien if (vp == STRNULL) { 1028c80476e4SDavid E. O'Brien aliasrun(1, STRperiodic, NULL); 1029c80476e4SDavid E. O'Brien goto leave; 1030c80476e4SDavid E. O'Brien } 1031c80476e4SDavid E. O'Brien interval = getn(vp); 1032c80476e4SDavid E. O'Brien (void) time(&t); 1033c80476e4SDavid E. O'Brien if (t - t_period >= interval * 60) { 1034c80476e4SDavid E. O'Brien t_period = t; 1035c80476e4SDavid E. O'Brien aliasrun(1, STRperiodic, NULL); 1036c80476e4SDavid E. O'Brien } 1037c80476e4SDavid E. O'Brien } 1038c80476e4SDavid E. O'Brien leave: 1039c80476e4SDavid E. O'Brien periodic_active = 0; 1040c80476e4SDavid E. O'Brien #ifdef BSDSIGS 1041c80476e4SDavid E. O'Brien (void) sigsetmask(omask); 1042c80476e4SDavid E. O'Brien #else /* !BSDSIGS */ 1043c80476e4SDavid E. O'Brien (void) sigrelse(SIGINT); 1044c80476e4SDavid E. O'Brien #endif /* BSDSIGS */ 1045c80476e4SDavid E. O'Brien } 1046c80476e4SDavid E. O'Brien 10476767bd61SMark Peek 10486767bd61SMark Peek /* 10496767bd61SMark Peek * GrP Greg Parker May 2001 10506767bd61SMark Peek * Added job_cmd(), which is run every time a job is started or 10516767bd61SMark Peek * foregrounded. The command is passed a single argument, the string 10526767bd61SMark Peek * used to start the job originally. With precmd, useful for setting 10536767bd61SMark Peek * xterm titles. 10546767bd61SMark Peek * Cloned from cwd_cmd(). 10556767bd61SMark Peek */ 10566767bd61SMark Peek void 10576767bd61SMark Peek job_cmd(args) 10586767bd61SMark Peek Char *args; 10596767bd61SMark Peek { 10606767bd61SMark Peek #ifdef BSDSIGS 10616767bd61SMark Peek sigmask_t omask; 10626767bd61SMark Peek 10636767bd61SMark Peek omask = sigblock(sigmask(SIGINT)); 10646767bd61SMark Peek #else /* !BSDSIGS */ 10656767bd61SMark Peek (void) sighold(SIGINT); 10666767bd61SMark Peek #endif /* BSDSIGS */ 10676767bd61SMark Peek if (jobcmd_active) { /* an error must have been caught */ 10686767bd61SMark Peek aliasrun(2, STRunalias, STRjobcmd); 10696767bd61SMark Peek xprintf(CGETS(22, 14, "Faulty alias 'jobcmd' removed.\n")); 10706767bd61SMark Peek goto leave; 10716767bd61SMark Peek } 10726767bd61SMark Peek jobcmd_active = 1; 10736767bd61SMark Peek if (!whyles && adrof1(STRjobcmd, &aliases)) 10746767bd61SMark Peek aliasrun(2, STRjobcmd, args); 10756767bd61SMark Peek leave: 10766767bd61SMark Peek jobcmd_active = 0; 10776767bd61SMark Peek #ifdef BSDSIGS 10786767bd61SMark Peek (void) sigsetmask(omask); 10796767bd61SMark Peek #else /* !BSDSIGS */ 10806767bd61SMark Peek (void) sigrelse(SIGINT); 10816767bd61SMark Peek #endif /* BSDSIGS */ 10826767bd61SMark Peek } 10836767bd61SMark Peek 10846767bd61SMark Peek 1085c80476e4SDavid E. O'Brien /* 1086c80476e4SDavid E. O'Brien * Karl Kleinpaste, 21oct1983. 1087c80476e4SDavid E. O'Brien * Set up a one-word alias command, for use for special things. 1088c80476e4SDavid E. O'Brien * This code is based on the mainline of process(). 1089c80476e4SDavid E. O'Brien */ 1090c80476e4SDavid E. O'Brien void 1091c80476e4SDavid E. O'Brien aliasrun(cnt, s1, s2) 1092c80476e4SDavid E. O'Brien int cnt; 1093c80476e4SDavid E. O'Brien Char *s1, *s2; 1094c80476e4SDavid E. O'Brien { 1095c80476e4SDavid E. O'Brien struct wordent w, *new1, *new2; /* for holding alias name */ 1096c80476e4SDavid E. O'Brien struct command *t = NULL; 1097c80476e4SDavid E. O'Brien jmp_buf_t osetexit; 1098c80476e4SDavid E. O'Brien int status; 1099c80476e4SDavid E. O'Brien 1100c80476e4SDavid E. O'Brien getexit(osetexit); 1101c80476e4SDavid E. O'Brien if (seterr) { 1102c80476e4SDavid E. O'Brien xfree((ptr_t) seterr); 1103c80476e4SDavid E. O'Brien seterr = NULL; /* don't repeatedly print err msg. */ 1104c80476e4SDavid E. O'Brien } 1105c80476e4SDavid E. O'Brien w.word = STRNULL; 1106c80476e4SDavid E. O'Brien new1 = (struct wordent *) xcalloc(1, sizeof w); 1107c80476e4SDavid E. O'Brien new1->word = Strsave(s1); 1108c80476e4SDavid E. O'Brien if (cnt == 1) { 1109c80476e4SDavid E. O'Brien /* build a lex list with one word. */ 1110c80476e4SDavid E. O'Brien w.next = w.prev = new1; 1111c80476e4SDavid E. O'Brien new1->next = new1->prev = &w; 1112c80476e4SDavid E. O'Brien } 1113c80476e4SDavid E. O'Brien else { 1114c80476e4SDavid E. O'Brien /* build a lex list with two words. */ 1115c80476e4SDavid E. O'Brien new2 = (struct wordent *) xcalloc(1, sizeof w); 1116c80476e4SDavid E. O'Brien new2->word = Strsave(s2); 1117c80476e4SDavid E. O'Brien w.next = new2->prev = new1; 1118c80476e4SDavid E. O'Brien new1->next = w.prev = new2; 1119c80476e4SDavid E. O'Brien new1->prev = new2->next = &w; 1120c80476e4SDavid E. O'Brien } 1121c80476e4SDavid E. O'Brien 1122c80476e4SDavid E. O'Brien /* Save the old status */ 1123c80476e4SDavid E. O'Brien status = getn(varval(STRstatus)); 1124c80476e4SDavid E. O'Brien 1125c80476e4SDavid E. O'Brien /* expand aliases like process() does. */ 1126c80476e4SDavid E. O'Brien alias(&w); 1127c80476e4SDavid E. O'Brien /* build a syntax tree for the command. */ 1128c80476e4SDavid E. O'Brien t = syntax(w.next, &w, 0); 1129c80476e4SDavid E. O'Brien if (seterr) 1130c80476e4SDavid E. O'Brien stderror(ERR_OLD); 1131c80476e4SDavid E. O'Brien 1132c80476e4SDavid E. O'Brien psavejob(); 1133c80476e4SDavid E. O'Brien 1134c80476e4SDavid E. O'Brien 1135c80476e4SDavid E. O'Brien /* catch any errors here */ 1136c80476e4SDavid E. O'Brien if (setexit() == 0) 1137c80476e4SDavid E. O'Brien /* execute the parse tree. */ 1138c80476e4SDavid E. O'Brien /* 1139c80476e4SDavid E. O'Brien * From: Michael Schroeder <mlschroe@immd4.informatik.uni-erlangen.de> 1140c80476e4SDavid E. O'Brien * was execute(t, tpgrp); 1141c80476e4SDavid E. O'Brien */ 1142c80476e4SDavid E. O'Brien execute(t, tpgrp > 0 ? tpgrp : -1, NULL, NULL); 1143c80476e4SDavid E. O'Brien /* done. free the lex list and parse tree. */ 1144c80476e4SDavid E. O'Brien freelex(&w), freesyn(t); 1145c80476e4SDavid E. O'Brien if (haderr) { 1146c80476e4SDavid E. O'Brien haderr = 0; 1147c80476e4SDavid E. O'Brien /* 1148c80476e4SDavid E. O'Brien * Either precmd, or cwdcmd, or periodic had an error. Call it again so 1149c80476e4SDavid E. O'Brien * that it is removed 1150c80476e4SDavid E. O'Brien */ 1151c80476e4SDavid E. O'Brien if (precmd_active) 1152c80476e4SDavid E. O'Brien precmd(); 1153c80476e4SDavid E. O'Brien if (postcmd_active) 1154c80476e4SDavid E. O'Brien postcmd(); 1155c80476e4SDavid E. O'Brien #ifdef notdef 1156c80476e4SDavid E. O'Brien /* 1157c80476e4SDavid E. O'Brien * XXX: On the other hand, just interrupting them causes an error too. 1158c80476e4SDavid E. O'Brien * So if we hit ^C in the middle of cwdcmd or periodic the alias gets 1159c80476e4SDavid E. O'Brien * removed. We don't want that. Note that we want to remove precmd 1160c80476e4SDavid E. O'Brien * though, cause that could lead into an infinite loop. This should be 1161c80476e4SDavid E. O'Brien * fixed correctly, but then haderr should give us the whole exit 1162c80476e4SDavid E. O'Brien * status not just true or false. 1163c80476e4SDavid E. O'Brien */ 1164c80476e4SDavid E. O'Brien else if (cwdcmd_active) 1165c80476e4SDavid E. O'Brien cwd_cmd(); 1166c80476e4SDavid E. O'Brien else if (beepcmd_active) 1167c80476e4SDavid E. O'Brien beep_cmd(); 1168c80476e4SDavid E. O'Brien else if (periodic_active) 1169c80476e4SDavid E. O'Brien period_cmd(); 1170c80476e4SDavid E. O'Brien #endif /* notdef */ 1171c80476e4SDavid E. O'Brien } 1172c80476e4SDavid E. O'Brien /* reset the error catcher to the old place */ 1173c80476e4SDavid E. O'Brien resexit(osetexit); 1174c80476e4SDavid E. O'Brien prestjob(); 1175c80476e4SDavid E. O'Brien pendjob(); 1176c80476e4SDavid E. O'Brien /* Restore status */ 1177c80476e4SDavid E. O'Brien set(STRstatus, putn(status), VAR_READWRITE); 1178c80476e4SDavid E. O'Brien } 1179c80476e4SDavid E. O'Brien 1180c80476e4SDavid E. O'Brien void 1181c80476e4SDavid E. O'Brien setalarm(lck) 1182c80476e4SDavid E. O'Brien int lck; 1183c80476e4SDavid E. O'Brien { 1184c80476e4SDavid E. O'Brien struct varent *vp; 1185c80476e4SDavid E. O'Brien Char *cp; 1186c80476e4SDavid E. O'Brien unsigned alrm_time = 0, logout_time, lock_time; 1187c80476e4SDavid E. O'Brien time_t cl, nl, sched_dif; 1188c80476e4SDavid E. O'Brien 1189c80476e4SDavid E. O'Brien if ((vp = adrof(STRautologout)) != NULL) { 1190c80476e4SDavid E. O'Brien if ((cp = vp->vec[0]) != 0) { 1191c80476e4SDavid E. O'Brien if ((logout_time = (unsigned) atoi(short2str(cp)) * 60) > 0) { 1192c80476e4SDavid E. O'Brien alrm_time = logout_time; 1193c80476e4SDavid E. O'Brien alm_fun = auto_logout; 1194c80476e4SDavid E. O'Brien } 1195c80476e4SDavid E. O'Brien } 1196c80476e4SDavid E. O'Brien if ((cp = vp->vec[1]) != 0) { 1197c80476e4SDavid E. O'Brien if ((lock_time = (unsigned) atoi(short2str(cp)) * 60) > 0) { 1198c80476e4SDavid E. O'Brien if (lck) { 1199c80476e4SDavid E. O'Brien if (alrm_time == 0 || lock_time < alrm_time) { 1200c80476e4SDavid E. O'Brien alrm_time = lock_time; 1201c80476e4SDavid E. O'Brien alm_fun = auto_lock; 1202c80476e4SDavid E. O'Brien } 1203c80476e4SDavid E. O'Brien } 1204c80476e4SDavid E. O'Brien else /* lock_time always < alrm_time */ 1205c80476e4SDavid E. O'Brien if (alrm_time) 1206c80476e4SDavid E. O'Brien alrm_time -= lock_time; 1207c80476e4SDavid E. O'Brien } 1208c80476e4SDavid E. O'Brien } 1209c80476e4SDavid E. O'Brien } 1210c80476e4SDavid E. O'Brien if ((nl = sched_next()) != -1) { 1211c80476e4SDavid E. O'Brien (void) time(&cl); 1212c80476e4SDavid E. O'Brien sched_dif = nl > cl ? nl - cl : 0; 1213c80476e4SDavid E. O'Brien if ((alrm_time == 0) || ((unsigned) sched_dif < alrm_time)) { 1214c80476e4SDavid E. O'Brien alrm_time = ((unsigned) sched_dif) + 1; 1215c80476e4SDavid E. O'Brien alm_fun = sched_run; 1216c80476e4SDavid E. O'Brien } 1217c80476e4SDavid E. O'Brien } 1218c80476e4SDavid E. O'Brien (void) alarm(alrm_time); /* Autologout ON */ 1219c80476e4SDavid E. O'Brien } 1220c80476e4SDavid E. O'Brien 1221c80476e4SDavid E. O'Brien #undef RMDEBUG /* For now... */ 1222c80476e4SDavid E. O'Brien 1223c80476e4SDavid E. O'Brien void 1224c80476e4SDavid E. O'Brien rmstar(cp) 1225c80476e4SDavid E. O'Brien struct wordent *cp; 1226c80476e4SDavid E. O'Brien { 1227c80476e4SDavid E. O'Brien struct wordent *we, *args; 1228c80476e4SDavid E. O'Brien register struct wordent *tmp, *del; 1229c80476e4SDavid E. O'Brien 1230c80476e4SDavid E. O'Brien #ifdef RMDEBUG 1231c80476e4SDavid E. O'Brien static Char STRrmdebug[] = {'r', 'm', 'd', 'e', 'b', 'u', 'g', '\0'}; 1232c80476e4SDavid E. O'Brien Char *tag; 1233c80476e4SDavid E. O'Brien #endif /* RMDEBUG */ 1234c80476e4SDavid E. O'Brien Char *charac; 1235c80476e4SDavid E. O'Brien char c; 1236c80476e4SDavid E. O'Brien int ask, doit, star = 0, silent = 0; 1237c80476e4SDavid E. O'Brien 1238c80476e4SDavid E. O'Brien if (!adrof(STRrmstar)) 1239c80476e4SDavid E. O'Brien return; 1240c80476e4SDavid E. O'Brien #ifdef RMDEBUG 1241c80476e4SDavid E. O'Brien tag = varval(STRrmdebug); 1242c80476e4SDavid E. O'Brien #endif /* RMDEBUG */ 1243c80476e4SDavid E. O'Brien we = cp->next; 1244c80476e4SDavid E. O'Brien while (*we->word == ';' && we != cp) 1245c80476e4SDavid E. O'Brien we = we->next; 1246c80476e4SDavid E. O'Brien while (we != cp) { 1247c80476e4SDavid E. O'Brien #ifdef RMDEBUG 1248c80476e4SDavid E. O'Brien if (*tag) 1249c80476e4SDavid E. O'Brien xprintf(CGETS(22, 7, "parsing command line\n")); 1250c80476e4SDavid E. O'Brien #endif /* RMDEBUG */ 1251c80476e4SDavid E. O'Brien if (!Strcmp(we->word, STRrm)) { 1252c80476e4SDavid E. O'Brien args = we->next; 1253c80476e4SDavid E. O'Brien ask = (*args->word != '-'); 1254c80476e4SDavid E. O'Brien while (*args->word == '-' && !silent) { /* check options */ 1255c80476e4SDavid E. O'Brien for (charac = (args->word + 1); *charac && !silent; charac++) 1256c80476e4SDavid E. O'Brien silent = (*charac == 'i' || *charac == 'f'); 1257c80476e4SDavid E. O'Brien args = args->next; 1258c80476e4SDavid E. O'Brien } 1259c80476e4SDavid E. O'Brien ask = (ask || (!ask && !silent)); 1260c80476e4SDavid E. O'Brien if (ask) { 1261c80476e4SDavid E. O'Brien for (; !star && *args->word != ';' 1262c80476e4SDavid E. O'Brien && args != cp; args = args->next) 1263c80476e4SDavid E. O'Brien if (!Strcmp(args->word, STRstar)) 1264c80476e4SDavid E. O'Brien star = 1; 1265c80476e4SDavid E. O'Brien if (ask && star) { 1266c80476e4SDavid E. O'Brien xprintf(CGETS(22, 8, 1267c80476e4SDavid E. O'Brien "Do you really want to delete all files? [n/y] ")); 1268c80476e4SDavid E. O'Brien flush(); 1269c80476e4SDavid E. O'Brien (void) force_read(SHIN, &c, 1); 1270c80476e4SDavid E. O'Brien /* 1271c80476e4SDavid E. O'Brien * Perhaps we should use the yesexpr from the 1272c80476e4SDavid E. O'Brien * actual locale 1273c80476e4SDavid E. O'Brien */ 1274c80476e4SDavid E. O'Brien doit = (strchr(CGETS(22, 14, "Yy"), c) != NULL); 1275c80476e4SDavid E. O'Brien while (c != '\n' && force_read(SHIN, &c, 1) == 1) 1276c80476e4SDavid E. O'Brien continue; 1277c80476e4SDavid E. O'Brien if (!doit) { 1278c80476e4SDavid E. O'Brien /* remove the command instead */ 1279c80476e4SDavid E. O'Brien #ifdef RMDEBUG 1280c80476e4SDavid E. O'Brien if (*tag) 1281c80476e4SDavid E. O'Brien xprintf(CGETS(22, 9, 1282c80476e4SDavid E. O'Brien "skipping deletion of files!\n")); 1283c80476e4SDavid E. O'Brien #endif /* RMDEBUG */ 1284c80476e4SDavid E. O'Brien for (tmp = we; 1285c80476e4SDavid E. O'Brien *tmp->word != '\n' && 1286c80476e4SDavid E. O'Brien *tmp->word != ';' && tmp != cp;) { 1287c80476e4SDavid E. O'Brien tmp->prev->next = tmp->next; 1288c80476e4SDavid E. O'Brien tmp->next->prev = tmp->prev; 1289c80476e4SDavid E. O'Brien xfree((ptr_t) tmp->word); 1290c80476e4SDavid E. O'Brien del = tmp; 1291c80476e4SDavid E. O'Brien tmp = tmp->next; 1292c80476e4SDavid E. O'Brien xfree((ptr_t) del); 1293c80476e4SDavid E. O'Brien } 1294c80476e4SDavid E. O'Brien if (*tmp->word == ';') { 1295c80476e4SDavid E. O'Brien tmp->prev->next = tmp->next; 1296c80476e4SDavid E. O'Brien tmp->next->prev = tmp->prev; 1297c80476e4SDavid E. O'Brien xfree((ptr_t) tmp->word); 1298c80476e4SDavid E. O'Brien del = tmp; 12996767bd61SMark Peek tmp = tmp->next; 1300c80476e4SDavid E. O'Brien xfree((ptr_t) del); 1301c80476e4SDavid E. O'Brien } 13026767bd61SMark Peek we = tmp; 13036767bd61SMark Peek continue; 1304c80476e4SDavid E. O'Brien } 1305c80476e4SDavid E. O'Brien } 1306c80476e4SDavid E. O'Brien } 1307c80476e4SDavid E. O'Brien } 1308c80476e4SDavid E. O'Brien for (we = we->next; 1309c80476e4SDavid E. O'Brien *we->word != ';' && we != cp; 1310c80476e4SDavid E. O'Brien we = we->next) 1311c80476e4SDavid E. O'Brien continue; 1312c80476e4SDavid E. O'Brien if (*we->word == ';') 1313c80476e4SDavid E. O'Brien we = we->next; 1314c80476e4SDavid E. O'Brien } 1315c80476e4SDavid E. O'Brien #ifdef RMDEBUG 1316c80476e4SDavid E. O'Brien if (*tag) { 1317c80476e4SDavid E. O'Brien xprintf(CGETS(22, 10, "command line now is:\n")); 1318c80476e4SDavid E. O'Brien for (we = cp->next; we != cp; we = we->next) 1319c80476e4SDavid E. O'Brien xprintf("%S ", we->word); 1320c80476e4SDavid E. O'Brien } 1321c80476e4SDavid E. O'Brien #endif /* RMDEBUG */ 1322c80476e4SDavid E. O'Brien return; 1323c80476e4SDavid E. O'Brien } 1324c80476e4SDavid E. O'Brien 1325c80476e4SDavid E. O'Brien #ifdef BSDJOBS 1326c80476e4SDavid E. O'Brien /* Check if command is in continue list 1327c80476e4SDavid E. O'Brien and do a "aliasing" if it exists as a job in background */ 1328c80476e4SDavid E. O'Brien 1329c80476e4SDavid E. O'Brien #undef CNDEBUG /* For now */ 1330c80476e4SDavid E. O'Brien void 1331c80476e4SDavid E. O'Brien continue_jobs(cp) 1332c80476e4SDavid E. O'Brien struct wordent *cp; 1333c80476e4SDavid E. O'Brien { 1334c80476e4SDavid E. O'Brien struct wordent *we; 1335c80476e4SDavid E. O'Brien register struct process *pp, *np; 1336c80476e4SDavid E. O'Brien Char *cmd, *continue_list, *continue_args_list; 1337c80476e4SDavid E. O'Brien 1338c80476e4SDavid E. O'Brien #ifdef CNDEBUG 1339c80476e4SDavid E. O'Brien Char *tag; 1340c80476e4SDavid E. O'Brien static Char STRcndebug[] = 1341c80476e4SDavid E. O'Brien {'c', 'n', 'd', 'e', 'b', 'u', 'g', '\0'}; 1342c80476e4SDavid E. O'Brien #endif /* CNDEBUG */ 1343c80476e4SDavid E. O'Brien bool in_cont_list, in_cont_arg_list; 1344c80476e4SDavid E. O'Brien 1345c80476e4SDavid E. O'Brien 1346c80476e4SDavid E. O'Brien #ifdef CNDEBUG 1347c80476e4SDavid E. O'Brien tag = varval(STRcndebug); 1348c80476e4SDavid E. O'Brien #endif /* CNDEBUG */ 1349c80476e4SDavid E. O'Brien continue_list = varval(STRcontinue); 1350c80476e4SDavid E. O'Brien continue_args_list = varval(STRcontinue_args); 1351c80476e4SDavid E. O'Brien if (*continue_list == '\0' && *continue_args_list == '\0') 1352c80476e4SDavid E. O'Brien return; 1353c80476e4SDavid E. O'Brien 1354c80476e4SDavid E. O'Brien we = cp->next; 1355c80476e4SDavid E. O'Brien while (*we->word == ';' && we != cp) 1356c80476e4SDavid E. O'Brien we = we->next; 1357c80476e4SDavid E. O'Brien while (we != cp) { 1358c80476e4SDavid E. O'Brien #ifdef CNDEBUG 1359c80476e4SDavid E. O'Brien if (*tag) 1360c80476e4SDavid E. O'Brien xprintf(CGETS(22, 11, "parsing command line\n")); 1361c80476e4SDavid E. O'Brien #endif /* CNDEBUG */ 1362c80476e4SDavid E. O'Brien cmd = we->word; 1363c80476e4SDavid E. O'Brien in_cont_list = inlist(continue_list, cmd); 1364c80476e4SDavid E. O'Brien in_cont_arg_list = inlist(continue_args_list, cmd); 1365c80476e4SDavid E. O'Brien if (in_cont_list || in_cont_arg_list) { 1366c80476e4SDavid E. O'Brien #ifdef CNDEBUG 1367c80476e4SDavid E. O'Brien if (*tag) 1368c80476e4SDavid E. O'Brien xprintf(CGETS(22, 12, "in one of the lists\n")); 1369c80476e4SDavid E. O'Brien #endif /* CNDEBUG */ 1370c80476e4SDavid E. O'Brien np = NULL; 1371c80476e4SDavid E. O'Brien for (pp = proclist.p_next; pp; pp = pp->p_next) { 1372c80476e4SDavid E. O'Brien if (prefix(cmd, pp->p_command)) { 1373c80476e4SDavid E. O'Brien if (pp->p_index) { 1374c80476e4SDavid E. O'Brien np = pp; 1375c80476e4SDavid E. O'Brien break; 1376c80476e4SDavid E. O'Brien } 1377c80476e4SDavid E. O'Brien } 1378c80476e4SDavid E. O'Brien } 1379c80476e4SDavid E. O'Brien if (np) { 1380c80476e4SDavid E. O'Brien insert(we, in_cont_arg_list); 1381c80476e4SDavid E. O'Brien } 1382c80476e4SDavid E. O'Brien } 1383c80476e4SDavid E. O'Brien for (we = we->next; 1384c80476e4SDavid E. O'Brien *we->word != ';' && we != cp; 1385c80476e4SDavid E. O'Brien we = we->next) 1386c80476e4SDavid E. O'Brien continue; 1387c80476e4SDavid E. O'Brien if (*we->word == ';') 1388c80476e4SDavid E. O'Brien we = we->next; 1389c80476e4SDavid E. O'Brien } 1390c80476e4SDavid E. O'Brien #ifdef CNDEBUG 1391c80476e4SDavid E. O'Brien if (*tag) { 1392c80476e4SDavid E. O'Brien xprintf(CGETS(22, 13, "command line now is:\n")); 1393c80476e4SDavid E. O'Brien for (we = cp->next; we != cp; we = we->next) 1394c80476e4SDavid E. O'Brien xprintf("%S ", we->word); 1395c80476e4SDavid E. O'Brien } 1396c80476e4SDavid E. O'Brien #endif /* CNDEBUG */ 1397c80476e4SDavid E. O'Brien return; 1398c80476e4SDavid E. O'Brien } 1399c80476e4SDavid E. O'Brien 1400c80476e4SDavid E. O'Brien /* The actual "aliasing" of for backgrounds() is done here 1401c80476e4SDavid E. O'Brien with the aid of insert_we(). */ 1402c80476e4SDavid E. O'Brien static void 1403c80476e4SDavid E. O'Brien insert(pl, file_args) 1404c80476e4SDavid E. O'Brien struct wordent *pl; 1405c80476e4SDavid E. O'Brien bool file_args; 1406c80476e4SDavid E. O'Brien { 1407c80476e4SDavid E. O'Brien struct wordent *now, *last; 1408c80476e4SDavid E. O'Brien Char *cmd, *bcmd, *cp1, *cp2; 1409c80476e4SDavid E. O'Brien int cmd_len; 1410c80476e4SDavid E. O'Brien Char *pause = STRunderpause; 1411c80476e4SDavid E. O'Brien int p_len = (int) Strlen(pause); 1412c80476e4SDavid E. O'Brien 1413c80476e4SDavid E. O'Brien cmd_len = (int) Strlen(pl->word); 1414c80476e4SDavid E. O'Brien cmd = (Char *) xcalloc(1, (size_t) ((cmd_len + 1) * sizeof(Char))); 1415c80476e4SDavid E. O'Brien (void) Strcpy(cmd, pl->word); 1416c80476e4SDavid E. O'Brien /* Do insertions at beginning, first replace command word */ 1417c80476e4SDavid E. O'Brien 1418c80476e4SDavid E. O'Brien if (file_args) { 1419c80476e4SDavid E. O'Brien now = pl; 1420c80476e4SDavid E. O'Brien xfree((ptr_t) now->word); 1421c80476e4SDavid E. O'Brien now->word = (Char *) xcalloc(1, (size_t) (5 * sizeof(Char))); 1422c80476e4SDavid E. O'Brien (void) Strcpy(now->word, STRecho); 1423c80476e4SDavid E. O'Brien 1424c80476e4SDavid E. O'Brien now = (struct wordent *) xcalloc(1, (size_t) sizeof(struct wordent)); 1425c80476e4SDavid E. O'Brien now->word = (Char *) xcalloc(1, (size_t) (6 * sizeof(Char))); 1426c80476e4SDavid E. O'Brien (void) Strcpy(now->word, STRbackqpwd); 1427c80476e4SDavid E. O'Brien insert_we(now, pl); 1428c80476e4SDavid E. O'Brien 1429c80476e4SDavid E. O'Brien for (last = now; *last->word != '\n' && *last->word != ';'; 1430c80476e4SDavid E. O'Brien last = last->next) 1431c80476e4SDavid E. O'Brien continue; 1432c80476e4SDavid E. O'Brien 1433c80476e4SDavid E. O'Brien now = (struct wordent *) xcalloc(1, (size_t) sizeof(struct wordent)); 1434c80476e4SDavid E. O'Brien now->word = (Char *) xcalloc(1, (size_t) (2 * sizeof(Char))); 1435c80476e4SDavid E. O'Brien (void) Strcpy(now->word, STRgt); 1436c80476e4SDavid E. O'Brien insert_we(now, last->prev); 1437c80476e4SDavid E. O'Brien 1438c80476e4SDavid E. O'Brien now = (struct wordent *) xcalloc(1, (size_t) sizeof(struct wordent)); 1439c80476e4SDavid E. O'Brien now->word = (Char *) xcalloc(1, (size_t) (2 * sizeof(Char))); 1440c80476e4SDavid E. O'Brien (void) Strcpy(now->word, STRbang); 1441c80476e4SDavid E. O'Brien insert_we(now, last->prev); 1442c80476e4SDavid E. O'Brien 1443c80476e4SDavid E. O'Brien now = (struct wordent *) xcalloc(1, (size_t) sizeof(struct wordent)); 1444c80476e4SDavid E. O'Brien now->word = (Char *) xcalloc(1, (size_t) cmd_len + p_len + 4); 1445c80476e4SDavid E. O'Brien cp1 = now->word; 1446c80476e4SDavid E. O'Brien cp2 = cmd; 1447c80476e4SDavid E. O'Brien *cp1++ = '~'; 1448c80476e4SDavid E. O'Brien *cp1++ = '/'; 1449c80476e4SDavid E. O'Brien *cp1++ = '.'; 1450c80476e4SDavid E. O'Brien while ((*cp1++ = *cp2++) != '\0') 1451c80476e4SDavid E. O'Brien continue; 1452c80476e4SDavid E. O'Brien cp1--; 1453c80476e4SDavid E. O'Brien cp2 = pause; 1454c80476e4SDavid E. O'Brien while ((*cp1++ = *cp2++) != '\0') 1455c80476e4SDavid E. O'Brien continue; 1456c80476e4SDavid E. O'Brien insert_we(now, last->prev); 1457c80476e4SDavid E. O'Brien 1458c80476e4SDavid E. O'Brien now = (struct wordent *) xcalloc(1, (size_t) sizeof(struct wordent)); 1459c80476e4SDavid E. O'Brien now->word = (Char *) xcalloc(1, (size_t) (2 * sizeof(Char))); 1460c80476e4SDavid E. O'Brien (void) Strcpy(now->word, STRsemi); 1461c80476e4SDavid E. O'Brien insert_we(now, last->prev); 1462c80476e4SDavid E. O'Brien bcmd = (Char *) xcalloc(1, (size_t) ((cmd_len + 2) * sizeof(Char))); 1463c80476e4SDavid E. O'Brien cp1 = bcmd; 1464c80476e4SDavid E. O'Brien cp2 = cmd; 1465c80476e4SDavid E. O'Brien *cp1++ = '%'; 1466c80476e4SDavid E. O'Brien while ((*cp1++ = *cp2++) != '\0') 1467c80476e4SDavid E. O'Brien continue; 1468c80476e4SDavid E. O'Brien now = (struct wordent *) xcalloc(1, (size_t) (sizeof(struct wordent))); 1469c80476e4SDavid E. O'Brien now->word = bcmd; 1470c80476e4SDavid E. O'Brien insert_we(now, last->prev); 1471c80476e4SDavid E. O'Brien } 1472c80476e4SDavid E. O'Brien else { 1473c80476e4SDavid E. O'Brien struct wordent *del; 1474c80476e4SDavid E. O'Brien 1475c80476e4SDavid E. O'Brien now = pl; 1476c80476e4SDavid E. O'Brien xfree((ptr_t) now->word); 1477c80476e4SDavid E. O'Brien now->word = (Char *) xcalloc(1, 1478c80476e4SDavid E. O'Brien (size_t) ((cmd_len + 2) * sizeof(Char))); 1479c80476e4SDavid E. O'Brien cp1 = now->word; 1480c80476e4SDavid E. O'Brien cp2 = cmd; 1481c80476e4SDavid E. O'Brien *cp1++ = '%'; 1482c80476e4SDavid E. O'Brien while ((*cp1++ = *cp2++) != '\0') 1483c80476e4SDavid E. O'Brien continue; 1484c80476e4SDavid E. O'Brien for (now = now->next; 1485c80476e4SDavid E. O'Brien *now->word != '\n' && *now->word != ';' && now != pl;) { 1486c80476e4SDavid E. O'Brien now->prev->next = now->next; 1487c80476e4SDavid E. O'Brien now->next->prev = now->prev; 1488c80476e4SDavid E. O'Brien xfree((ptr_t) now->word); 1489c80476e4SDavid E. O'Brien del = now; 1490c80476e4SDavid E. O'Brien now = now->next; 1491c80476e4SDavid E. O'Brien xfree((ptr_t) del); 1492c80476e4SDavid E. O'Brien } 1493c80476e4SDavid E. O'Brien } 1494c80476e4SDavid E. O'Brien } 1495c80476e4SDavid E. O'Brien 1496c80476e4SDavid E. O'Brien static void 1497c80476e4SDavid E. O'Brien insert_we(new, where) 1498c80476e4SDavid E. O'Brien struct wordent *new, *where; 1499c80476e4SDavid E. O'Brien { 1500c80476e4SDavid E. O'Brien 1501c80476e4SDavid E. O'Brien new->prev = where; 1502c80476e4SDavid E. O'Brien new->next = where->next; 1503c80476e4SDavid E. O'Brien where->next = new; 1504c80476e4SDavid E. O'Brien new->next->prev = new; 1505c80476e4SDavid E. O'Brien } 1506c80476e4SDavid E. O'Brien 1507c80476e4SDavid E. O'Brien static int 1508c80476e4SDavid E. O'Brien inlist(list, name) 1509c80476e4SDavid E. O'Brien Char *list, *name; 1510c80476e4SDavid E. O'Brien { 1511c80476e4SDavid E. O'Brien register Char *l, *n; 1512c80476e4SDavid E. O'Brien 1513c80476e4SDavid E. O'Brien l = list; 1514c80476e4SDavid E. O'Brien n = name; 1515c80476e4SDavid E. O'Brien 1516c80476e4SDavid E. O'Brien while (*l && *n) { 1517c80476e4SDavid E. O'Brien if (*l == *n) { 1518c80476e4SDavid E. O'Brien l++; 1519c80476e4SDavid E. O'Brien n++; 1520c80476e4SDavid E. O'Brien if (*n == '\0' && (*l == ' ' || *l == '\0')) 1521c80476e4SDavid E. O'Brien return (1); 1522c80476e4SDavid E. O'Brien else 1523c80476e4SDavid E. O'Brien continue; 1524c80476e4SDavid E. O'Brien } 1525c80476e4SDavid E. O'Brien else { 1526c80476e4SDavid E. O'Brien while (*l && *l != ' ') 1527c80476e4SDavid E. O'Brien l++; /* skip to blank */ 1528c80476e4SDavid E. O'Brien while (*l && *l == ' ') 1529c80476e4SDavid E. O'Brien l++; /* and find first nonblank character */ 1530c80476e4SDavid E. O'Brien n = name; 1531c80476e4SDavid E. O'Brien } 1532c80476e4SDavid E. O'Brien } 1533c80476e4SDavid E. O'Brien return (0); 1534c80476e4SDavid E. O'Brien } 1535c80476e4SDavid E. O'Brien 1536c80476e4SDavid E. O'Brien #endif /* BSDJOBS */ 1537c80476e4SDavid E. O'Brien 1538c80476e4SDavid E. O'Brien 1539c80476e4SDavid E. O'Brien /* 1540c80476e4SDavid E. O'Brien * Implement a small cache for tilde names. This is used primarily 1541c80476e4SDavid E. O'Brien * to expand tilde names to directories, but also 1542c80476e4SDavid E. O'Brien * we can find users from their home directories for the tilde 1543c80476e4SDavid E. O'Brien * prompt, on machines where yp lookup is slow this can be a big win... 1544c80476e4SDavid E. O'Brien * As with any cache this can run out of sync, rehash can sync it again. 1545c80476e4SDavid E. O'Brien */ 1546c80476e4SDavid E. O'Brien static struct tildecache { 1547c80476e4SDavid E. O'Brien Char *user; 1548c80476e4SDavid E. O'Brien Char *home; 1549c80476e4SDavid E. O'Brien int hlen; 1550c80476e4SDavid E. O'Brien } *tcache = NULL; 1551c80476e4SDavid E. O'Brien 1552c80476e4SDavid E. O'Brien #define TILINCR 10 1553c80476e4SDavid E. O'Brien int tlength = 0; 1554c80476e4SDavid E. O'Brien static int tsize = TILINCR; 1555c80476e4SDavid E. O'Brien 1556c80476e4SDavid E. O'Brien static int 1557c80476e4SDavid E. O'Brien tildecompare(p1, p2) 1558c80476e4SDavid E. O'Brien struct tildecache *p1, *p2; 1559c80476e4SDavid E. O'Brien { 1560c80476e4SDavid E. O'Brien return Strcmp(p1->user, p2->user); 1561c80476e4SDavid E. O'Brien } 1562c80476e4SDavid E. O'Brien 1563c80476e4SDavid E. O'Brien static Char * 1564c80476e4SDavid E. O'Brien gethomedir(us) 1565c80476e4SDavid E. O'Brien Char *us; 1566c80476e4SDavid E. O'Brien { 1567c80476e4SDavid E. O'Brien register struct passwd *pp; 1568c80476e4SDavid E. O'Brien #ifdef HESIOD 1569c80476e4SDavid E. O'Brien char **res, **res1, *cp; 1570c80476e4SDavid E. O'Brien Char *rp; 1571c80476e4SDavid E. O'Brien #endif /* HESIOD */ 1572c80476e4SDavid E. O'Brien 1573c80476e4SDavid E. O'Brien pp = getpwnam(short2str(us)); 1574c80476e4SDavid E. O'Brien #ifdef YPBUGS 1575c80476e4SDavid E. O'Brien fix_yp_bugs(); 1576c80476e4SDavid E. O'Brien #endif /* YPBUGS */ 15776767bd61SMark Peek if (pp != NULL) { 15786767bd61SMark Peek /* Don't return if root */ 15796767bd61SMark Peek if (pp->pw_dir[0] == '/' && pp->pw_dir[1] == '\0') 15806767bd61SMark Peek return NULL; 15816767bd61SMark Peek else 1582c80476e4SDavid E. O'Brien return Strsave(str2short(pp->pw_dir)); 15836767bd61SMark Peek } 1584c80476e4SDavid E. O'Brien #ifdef HESIOD 1585c80476e4SDavid E. O'Brien res = hes_resolve(short2str(us), "filsys"); 15866767bd61SMark Peek rp = NULL; 15876767bd61SMark Peek if (res != NULL) { 15886767bd61SMark Peek if ((*res) != NULL) { 1589c80476e4SDavid E. O'Brien /* 1590c80476e4SDavid E. O'Brien * Look at the first token to determine how to interpret 1591c80476e4SDavid E. O'Brien * the rest of it. 1592c80476e4SDavid E. O'Brien * Yes, strtok is evil (it's not thread-safe), but it's also 1593c80476e4SDavid E. O'Brien * easy to use. 1594c80476e4SDavid E. O'Brien */ 1595c80476e4SDavid E. O'Brien cp = strtok(*res, " "); 1596c80476e4SDavid E. O'Brien if (strcmp(cp, "AFS") == 0) { 1597c80476e4SDavid E. O'Brien /* next token is AFS pathname.. */ 1598c80476e4SDavid E. O'Brien cp = strtok(NULL, " "); 1599c80476e4SDavid E. O'Brien if (cp != NULL) 1600c80476e4SDavid E. O'Brien rp = Strsave(str2short(cp)); 1601c80476e4SDavid E. O'Brien } else if (strcmp(cp, "NFS") == 0) { 1602c80476e4SDavid E. O'Brien cp = NULL; 1603c80476e4SDavid E. O'Brien if ((strtok(NULL, " ")) && /* skip remote pathname */ 1604c80476e4SDavid E. O'Brien (strtok(NULL, " ")) && /* skip host */ 1605c80476e4SDavid E. O'Brien (strtok(NULL, " ")) && /* skip mode */ 1606c80476e4SDavid E. O'Brien (cp = strtok(NULL, " "))) { 1607c80476e4SDavid E. O'Brien rp = Strsave(str2short(cp)); 1608c80476e4SDavid E. O'Brien } 1609c80476e4SDavid E. O'Brien } 1610c80476e4SDavid E. O'Brien } 1611c80476e4SDavid E. O'Brien for (res1 = res; *res1; res1++) 1612c80476e4SDavid E. O'Brien free(*res1); 16136767bd61SMark Peek if (rp != NULL && rp[0] == '/' && rp[1] == '\0') { 16146767bd61SMark Peek xfree((ptr_t)rp); 16156767bd61SMark Peek rp = NULL; 16166767bd61SMark Peek } 1617c80476e4SDavid E. O'Brien return rp; 1618c80476e4SDavid E. O'Brien } 1619c80476e4SDavid E. O'Brien #endif /* HESIOD */ 1620c80476e4SDavid E. O'Brien return NULL; 1621c80476e4SDavid E. O'Brien } 1622c80476e4SDavid E. O'Brien 1623c80476e4SDavid E. O'Brien Char * 1624c80476e4SDavid E. O'Brien gettilde(us) 1625c80476e4SDavid E. O'Brien Char *us; 1626c80476e4SDavid E. O'Brien { 1627c80476e4SDavid E. O'Brien struct tildecache *bp1, *bp2, *bp; 1628c80476e4SDavid E. O'Brien Char *hd; 1629c80476e4SDavid E. O'Brien 1630c80476e4SDavid E. O'Brien /* Ignore NIS special names */ 1631c80476e4SDavid E. O'Brien if (*us == '+' || *us == '-') 1632c80476e4SDavid E. O'Brien return NULL; 1633c80476e4SDavid E. O'Brien 1634c80476e4SDavid E. O'Brien if (tcache == NULL) 1635c80476e4SDavid E. O'Brien tcache = (struct tildecache *) xmalloc((size_t) (TILINCR * 1636c80476e4SDavid E. O'Brien sizeof(struct tildecache))); 1637c80476e4SDavid E. O'Brien /* 1638c80476e4SDavid E. O'Brien * Binary search 1639c80476e4SDavid E. O'Brien */ 1640c80476e4SDavid E. O'Brien for (bp1 = tcache, bp2 = tcache + tlength; bp1 < bp2;) { 1641c80476e4SDavid E. O'Brien register int i; 1642c80476e4SDavid E. O'Brien 1643c80476e4SDavid E. O'Brien bp = bp1 + ((bp2 - bp1) >> 1); 1644c80476e4SDavid E. O'Brien if ((i = *us - *bp->user) == 0 && (i = Strcmp(us, bp->user)) == 0) 1645c80476e4SDavid E. O'Brien return (bp->home); 1646c80476e4SDavid E. O'Brien if (i < 0) 1647c80476e4SDavid E. O'Brien bp2 = bp; 1648c80476e4SDavid E. O'Brien else 1649c80476e4SDavid E. O'Brien bp1 = bp + 1; 1650c80476e4SDavid E. O'Brien } 1651c80476e4SDavid E. O'Brien /* 1652c80476e4SDavid E. O'Brien * Not in the cache, try to get it from the passwd file 1653c80476e4SDavid E. O'Brien */ 1654c80476e4SDavid E. O'Brien hd = gethomedir(us); 1655c80476e4SDavid E. O'Brien if (hd == NULL) 1656c80476e4SDavid E. O'Brien return NULL; 1657c80476e4SDavid E. O'Brien 1658c80476e4SDavid E. O'Brien /* 1659c80476e4SDavid E. O'Brien * Update the cache 1660c80476e4SDavid E. O'Brien */ 1661c80476e4SDavid E. O'Brien tcache[tlength].user = Strsave(us); 1662c80476e4SDavid E. O'Brien tcache[tlength].home = hd; 1663c80476e4SDavid E. O'Brien tcache[tlength++].hlen = (int) Strlen(hd); 1664c80476e4SDavid E. O'Brien 1665c80476e4SDavid E. O'Brien qsort((ptr_t) tcache, (size_t) tlength, sizeof(struct tildecache), 1666c80476e4SDavid E. O'Brien (int (*) __P((const void *, const void *))) tildecompare); 1667c80476e4SDavid E. O'Brien 1668c80476e4SDavid E. O'Brien if (tlength == tsize) { 1669c80476e4SDavid E. O'Brien tsize += TILINCR; 1670c80476e4SDavid E. O'Brien tcache = (struct tildecache *) xrealloc((ptr_t) tcache, 1671c80476e4SDavid E. O'Brien (size_t) (tsize * 1672c80476e4SDavid E. O'Brien sizeof(struct tildecache))); 1673c80476e4SDavid E. O'Brien } 1674c80476e4SDavid E. O'Brien return (hd); 1675c80476e4SDavid E. O'Brien } 1676c80476e4SDavid E. O'Brien 1677c80476e4SDavid E. O'Brien /* 1678c80476e4SDavid E. O'Brien * Return the username if the directory path passed contains a 1679c80476e4SDavid E. O'Brien * user's home directory in the tilde cache, otherwise return NULL 1680c80476e4SDavid E. O'Brien * hm points to the place where the path became different. 1681c80476e4SDavid E. O'Brien * Special case: Our own home directory. 1682c80476e4SDavid E. O'Brien * If we are passed a null pointer, then we flush the cache. 1683c80476e4SDavid E. O'Brien */ 1684c80476e4SDavid E. O'Brien Char * 1685c80476e4SDavid E. O'Brien getusername(hm) 1686c80476e4SDavid E. O'Brien Char **hm; 1687c80476e4SDavid E. O'Brien { 1688c80476e4SDavid E. O'Brien Char *h, *p; 1689c80476e4SDavid E. O'Brien int i, j; 1690c80476e4SDavid E. O'Brien 1691c80476e4SDavid E. O'Brien if (hm == NULL) { 1692c80476e4SDavid E. O'Brien for (i = 0; i < tlength; i++) { 1693c80476e4SDavid E. O'Brien xfree((ptr_t) tcache[i].home); 1694c80476e4SDavid E. O'Brien xfree((ptr_t) tcache[i].user); 1695c80476e4SDavid E. O'Brien } 1696c80476e4SDavid E. O'Brien xfree((ptr_t) tcache); 1697c80476e4SDavid E. O'Brien tlength = 0; 1698c80476e4SDavid E. O'Brien tsize = TILINCR; 1699c80476e4SDavid E. O'Brien tcache = NULL; 1700c80476e4SDavid E. O'Brien return NULL; 1701c80476e4SDavid E. O'Brien } 1702c80476e4SDavid E. O'Brien if (((h = varval(STRhome)) != STRNULL) && 1703c80476e4SDavid E. O'Brien (Strncmp(p = *hm, h, (size_t) (j = (int) Strlen(h))) == 0) && 1704c80476e4SDavid E. O'Brien (p[j] == '/' || p[j] == '\0')) { 1705c80476e4SDavid E. O'Brien *hm = &p[j]; 1706c80476e4SDavid E. O'Brien return STRNULL; 1707c80476e4SDavid E. O'Brien } 1708c80476e4SDavid E. O'Brien for (i = 0; i < tlength; i++) 1709c80476e4SDavid E. O'Brien if ((Strncmp(p = *hm, tcache[i].home, (size_t) 1710c80476e4SDavid E. O'Brien (j = tcache[i].hlen)) == 0) && (p[j] == '/' || p[j] == '\0')) { 1711c80476e4SDavid E. O'Brien *hm = &p[j]; 1712c80476e4SDavid E. O'Brien return tcache[i].user; 1713c80476e4SDavid E. O'Brien } 1714c80476e4SDavid E. O'Brien return NULL; 1715c80476e4SDavid E. O'Brien } 1716c80476e4SDavid E. O'Brien 1717c80476e4SDavid E. O'Brien #ifdef OBSOLETE 1718c80476e4SDavid E. O'Brien /* 1719c80476e4SDavid E. O'Brien * PWP: read a bunch of aliases out of a file QUICKLY. The format 1720c80476e4SDavid E. O'Brien * is almost the same as the result of saying "alias > FILE", except 1721c80476e4SDavid E. O'Brien * that saying "aliases > FILE" does not expand non-letters to printable 1722c80476e4SDavid E. O'Brien * sequences. 1723c80476e4SDavid E. O'Brien */ 1724c80476e4SDavid E. O'Brien /*ARGSUSED*/ 1725c80476e4SDavid E. O'Brien void 1726c80476e4SDavid E. O'Brien doaliases(v, c) 1727c80476e4SDavid E. O'Brien Char **v; 1728c80476e4SDavid E. O'Brien struct command *c; 1729c80476e4SDavid E. O'Brien { 1730c80476e4SDavid E. O'Brien jmp_buf_t oldexit; 1731c80476e4SDavid E. O'Brien Char **vec, *lp; 1732c80476e4SDavid E. O'Brien int fd; 1733c80476e4SDavid E. O'Brien Char buf[BUFSIZE], line[BUFSIZE]; 1734c80476e4SDavid E. O'Brien char tbuf[BUFSIZE + 1], *tmp; 1735c80476e4SDavid E. O'Brien extern bool output_raw; /* PWP: in sh.print.c */ 1736c80476e4SDavid E. O'Brien 1737c80476e4SDavid E. O'Brien USE(c); 1738c80476e4SDavid E. O'Brien v++; 1739c80476e4SDavid E. O'Brien if (*v == 0) { 1740c80476e4SDavid E. O'Brien output_raw = 1; 1741c80476e4SDavid E. O'Brien plist(&aliases, VAR_ALL); 1742c80476e4SDavid E. O'Brien output_raw = 0; 1743c80476e4SDavid E. O'Brien return; 1744c80476e4SDavid E. O'Brien } 1745c80476e4SDavid E. O'Brien 1746c80476e4SDavid E. O'Brien gflag = 0, tglob(v); 1747c80476e4SDavid E. O'Brien if (gflag) { 1748c80476e4SDavid E. O'Brien v = globall(v); 1749c80476e4SDavid E. O'Brien if (v == 0) 1750c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_NOMATCH); 1751c80476e4SDavid E. O'Brien } 1752c80476e4SDavid E. O'Brien else { 1753c80476e4SDavid E. O'Brien v = gargv = saveblk(v); 1754c80476e4SDavid E. O'Brien trim(v); 1755c80476e4SDavid E. O'Brien } 1756c80476e4SDavid E. O'Brien 1757c80476e4SDavid E. O'Brien if ((fd = open(tmp = short2str(*v), O_RDONLY)) < 0) 1758c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_SYSTEM, tmp, strerror(errno)); 1759c80476e4SDavid E. O'Brien 1760c80476e4SDavid E. O'Brien getexit(oldexit); 1761c80476e4SDavid E. O'Brien if (setexit() == 0) { 1762c80476e4SDavid E. O'Brien for (;;) { 1763c80476e4SDavid E. O'Brien Char *p = NULL; 1764c80476e4SDavid E. O'Brien int n = 0; 1765c80476e4SDavid E. O'Brien lp = line; 1766c80476e4SDavid E. O'Brien for (;;) { 1767c80476e4SDavid E. O'Brien if (n <= 0) { 1768c80476e4SDavid E. O'Brien int i; 1769c80476e4SDavid E. O'Brien 1770c80476e4SDavid E. O'Brien if ((n = read(fd, tbuf, BUFSIZE)) <= 0) { 1771c80476e4SDavid E. O'Brien #ifdef convex 1772c80476e4SDavid E. O'Brien stderror(ERR_SYSTEM, progname, strerror(errno)); 1773c80476e4SDavid E. O'Brien #endif /* convex */ 1774c80476e4SDavid E. O'Brien goto eof; 1775c80476e4SDavid E. O'Brien } 1776c80476e4SDavid E. O'Brien for (i = 0; i < n; i++) 1777c80476e4SDavid E. O'Brien buf[i] = (Char) tbuf[i]; 1778c80476e4SDavid E. O'Brien p = buf; 1779c80476e4SDavid E. O'Brien } 1780c80476e4SDavid E. O'Brien n--; 1781c80476e4SDavid E. O'Brien if ((*lp++ = *p++) == '\n') { 1782c80476e4SDavid E. O'Brien lp[-1] = '\0'; 1783c80476e4SDavid E. O'Brien break; 1784c80476e4SDavid E. O'Brien } 1785c80476e4SDavid E. O'Brien } 1786c80476e4SDavid E. O'Brien for (lp = line; *lp; lp++) { 1787c80476e4SDavid E. O'Brien if (isspc(*lp)) { 1788c80476e4SDavid E. O'Brien *lp++ = '\0'; 1789c80476e4SDavid E. O'Brien while (isspc(*lp)) 1790c80476e4SDavid E. O'Brien lp++; 1791c80476e4SDavid E. O'Brien vec = (Char **) xmalloc((size_t) 1792c80476e4SDavid E. O'Brien (2 * sizeof(Char **))); 1793c80476e4SDavid E. O'Brien vec[0] = Strsave(lp); 1794c80476e4SDavid E. O'Brien vec[1] = NULL; 1795c80476e4SDavid E. O'Brien setq(strip(line), vec, &aliases, VAR_READWRITE); 1796c80476e4SDavid E. O'Brien break; 1797c80476e4SDavid E. O'Brien } 1798c80476e4SDavid E. O'Brien } 1799c80476e4SDavid E. O'Brien } 1800c80476e4SDavid E. O'Brien } 1801c80476e4SDavid E. O'Brien 1802c80476e4SDavid E. O'Brien eof: 1803c80476e4SDavid E. O'Brien (void) close(fd); 1804c80476e4SDavid E. O'Brien tw_cmd_free(); 1805c80476e4SDavid E. O'Brien if (gargv) 1806c80476e4SDavid E. O'Brien blkfree(gargv), gargv = 0; 1807c80476e4SDavid E. O'Brien resexit(oldexit); 1808c80476e4SDavid E. O'Brien } 1809c80476e4SDavid E. O'Brien #endif /* OBSOLETE */ 1810c80476e4SDavid E. O'Brien 1811c80476e4SDavid E. O'Brien 1812c80476e4SDavid E. O'Brien /* 1813c80476e4SDavid E. O'Brien * set the shell-level var to 1 or apply change to it. 1814c80476e4SDavid E. O'Brien */ 1815c80476e4SDavid E. O'Brien void 1816c80476e4SDavid E. O'Brien shlvl(val) 1817c80476e4SDavid E. O'Brien int val; 1818c80476e4SDavid E. O'Brien { 1819c80476e4SDavid E. O'Brien char *cp; 1820c80476e4SDavid E. O'Brien 1821c80476e4SDavid E. O'Brien if ((cp = getenv("SHLVL")) != NULL) { 1822c80476e4SDavid E. O'Brien 1823c80476e4SDavid E. O'Brien if (loginsh) 1824c80476e4SDavid E. O'Brien val = 1; 1825c80476e4SDavid E. O'Brien else 1826c80476e4SDavid E. O'Brien val += atoi(cp); 1827c80476e4SDavid E. O'Brien 1828c80476e4SDavid E. O'Brien if (val <= 0) { 1829c80476e4SDavid E. O'Brien if (adrof(STRshlvl) != NULL) 1830c80476e4SDavid E. O'Brien unsetv(STRshlvl); 1831c80476e4SDavid E. O'Brien Unsetenv(STRKSHLVL); 1832c80476e4SDavid E. O'Brien } 1833c80476e4SDavid E. O'Brien else { 1834c80476e4SDavid E. O'Brien Char buff[BUFSIZE]; 1835c80476e4SDavid E. O'Brien 1836c80476e4SDavid E. O'Brien (void) Itoa(val, buff, 0, 0); 1837c80476e4SDavid E. O'Brien set(STRshlvl, Strsave(buff), VAR_READWRITE); 1838c80476e4SDavid E. O'Brien tsetenv(STRKSHLVL, buff); 1839c80476e4SDavid E. O'Brien } 1840c80476e4SDavid E. O'Brien } 1841c80476e4SDavid E. O'Brien else { 1842c80476e4SDavid E. O'Brien set(STRshlvl, SAVE("1"), VAR_READWRITE); 1843c80476e4SDavid E. O'Brien tsetenv(STRKSHLVL, str2short("1")); 1844c80476e4SDavid E. O'Brien } 1845c80476e4SDavid E. O'Brien } 1846c80476e4SDavid E. O'Brien 1847c80476e4SDavid E. O'Brien 1848c80476e4SDavid E. O'Brien /* fixio(): 1849c80476e4SDavid E. O'Brien * Try to recover from a read error 1850c80476e4SDavid E. O'Brien */ 1851c80476e4SDavid E. O'Brien int 1852c80476e4SDavid E. O'Brien fixio(fd, e) 1853c80476e4SDavid E. O'Brien int fd, e; 1854c80476e4SDavid E. O'Brien { 1855c80476e4SDavid E. O'Brien switch (e) { 1856c80476e4SDavid E. O'Brien case -1: /* Make sure that the code is reachable */ 1857c80476e4SDavid E. O'Brien 1858c80476e4SDavid E. O'Brien #ifdef EWOULDBLOCK 1859c80476e4SDavid E. O'Brien case EWOULDBLOCK: 1860c80476e4SDavid E. O'Brien # define FDRETRY 1861c80476e4SDavid E. O'Brien #endif /* EWOULDBLOCK */ 1862c80476e4SDavid E. O'Brien 1863c80476e4SDavid E. O'Brien #if defined(POSIX) && defined(EAGAIN) 1864c80476e4SDavid E. O'Brien # if !defined(EWOULDBLOCK) || EWOULDBLOCK != EAGAIN 1865c80476e4SDavid E. O'Brien case EAGAIN: 1866c80476e4SDavid E. O'Brien # define FDRETRY 1867c80476e4SDavid E. O'Brien # endif /* !EWOULDBLOCK || EWOULDBLOCK != EAGAIN */ 1868c80476e4SDavid E. O'Brien #endif /* POSIX && EAGAIN */ 1869c80476e4SDavid E. O'Brien 1870c80476e4SDavid E. O'Brien e = 0; 1871c80476e4SDavid E. O'Brien #ifdef FDRETRY 1872c80476e4SDavid E. O'Brien # ifdef F_SETFL 1873c80476e4SDavid E. O'Brien /* 1874c80476e4SDavid E. O'Brien * Great! we have on suns 3 flavors and 5 names... 1875c80476e4SDavid E. O'Brien * I hope that will cover everything. 1876c80476e4SDavid E. O'Brien * I added some more defines... many systems have different defines. 1877c80476e4SDavid E. O'Brien * Rather than dealing with getting the right includes, we'll just 1878c80476e4SDavid E. O'Brien * cover all the known possibilities here. -- sterling@netcom.com 1879c80476e4SDavid E. O'Brien */ 1880c80476e4SDavid E. O'Brien # ifndef O_NONBLOCK 1881c80476e4SDavid E. O'Brien # define O_NONBLOCK 0 1882c80476e4SDavid E. O'Brien # endif /* O_NONBLOCK */ 1883c80476e4SDavid E. O'Brien # ifndef O_NDELAY 1884c80476e4SDavid E. O'Brien # define O_NDELAY 0 1885c80476e4SDavid E. O'Brien # endif /* O_NDELAY */ 1886c80476e4SDavid E. O'Brien # ifndef FNBIO 1887c80476e4SDavid E. O'Brien # define FNBIO 0 1888c80476e4SDavid E. O'Brien # endif /* FNBIO */ 1889c80476e4SDavid E. O'Brien # ifndef _FNBIO 1890c80476e4SDavid E. O'Brien # define _FNBIO 0 1891c80476e4SDavid E. O'Brien # endif /* _FNBIO */ 1892c80476e4SDavid E. O'Brien # ifndef FNONBIO 1893c80476e4SDavid E. O'Brien # define FNONBIO 0 1894c80476e4SDavid E. O'Brien # endif /* FNONBIO */ 1895c80476e4SDavid E. O'Brien # ifndef FNONBLOCK 1896c80476e4SDavid E. O'Brien # define FNONBLOCK 0 1897c80476e4SDavid E. O'Brien # endif /* FNONBLOCK */ 1898c80476e4SDavid E. O'Brien # ifndef _FNONBLOCK 1899c80476e4SDavid E. O'Brien # define _FNONBLOCK 0 1900c80476e4SDavid E. O'Brien # endif /* _FNONBLOCK */ 1901c80476e4SDavid E. O'Brien # ifndef FNDELAY 1902c80476e4SDavid E. O'Brien # define FNDELAY 0 1903c80476e4SDavid E. O'Brien # endif /* FNDELAY */ 1904c80476e4SDavid E. O'Brien # ifndef _FNDELAY 1905c80476e4SDavid E. O'Brien # define _FNDELAY 0 1906c80476e4SDavid E. O'Brien # endif /* _FNDELAY */ 1907c80476e4SDavid E. O'Brien # ifndef FNDLEAY /* Some linux versions have this typo */ 1908c80476e4SDavid E. O'Brien # define FNDLEAY 0 1909c80476e4SDavid E. O'Brien # endif /* FNDLEAY */ 1910c80476e4SDavid E. O'Brien if ((e = fcntl(fd, F_GETFL, 0)) == -1) 1911c80476e4SDavid E. O'Brien return -1; 1912c80476e4SDavid E. O'Brien 1913c80476e4SDavid E. O'Brien e &= ~(O_NDELAY|O_NONBLOCK|FNBIO|_FNBIO|FNONBIO|FNONBLOCK|_FNONBLOCK| 1914c80476e4SDavid E. O'Brien FNDELAY|_FNDELAY|FNDLEAY); /* whew! */ 1915c80476e4SDavid E. O'Brien if (fcntl(fd, F_SETFL, e) == -1) 1916c80476e4SDavid E. O'Brien return -1; 1917c80476e4SDavid E. O'Brien else 1918c80476e4SDavid E. O'Brien e = 1; 1919c80476e4SDavid E. O'Brien # endif /* F_SETFL */ 1920c80476e4SDavid E. O'Brien 1921c80476e4SDavid E. O'Brien # ifdef FIONBIO 1922c80476e4SDavid E. O'Brien e = 0; 1923c80476e4SDavid E. O'Brien if (ioctl(fd, FIONBIO, (ioctl_t) &e) == -1) 1924c80476e4SDavid E. O'Brien return -1; 1925c80476e4SDavid E. O'Brien else 1926c80476e4SDavid E. O'Brien e = 1; 1927c80476e4SDavid E. O'Brien # endif /* FIONBIO */ 1928c80476e4SDavid E. O'Brien 1929c80476e4SDavid E. O'Brien #endif /* FDRETRY */ 1930c80476e4SDavid E. O'Brien return e ? 0 : -1; 1931c80476e4SDavid E. O'Brien 1932c80476e4SDavid E. O'Brien case EINTR: 1933c80476e4SDavid E. O'Brien return 0; 1934c80476e4SDavid E. O'Brien 1935c80476e4SDavid E. O'Brien default: 1936c80476e4SDavid E. O'Brien return -1; 1937c80476e4SDavid E. O'Brien } 1938c80476e4SDavid E. O'Brien } 1939c80476e4SDavid E. O'Brien 1940c80476e4SDavid E. O'Brien /* collate(): 1941c80476e4SDavid E. O'Brien * String collation 1942c80476e4SDavid E. O'Brien */ 1943c80476e4SDavid E. O'Brien int 1944c80476e4SDavid E. O'Brien collate(a, b) 1945c80476e4SDavid E. O'Brien const Char *a; 1946c80476e4SDavid E. O'Brien const Char *b; 1947c80476e4SDavid E. O'Brien { 1948c80476e4SDavid E. O'Brien int rv; 1949c80476e4SDavid E. O'Brien #ifdef SHORT_STRINGS 1950c80476e4SDavid E. O'Brien /* This strips the quote bit as a side effect */ 1951c80476e4SDavid E. O'Brien char *sa = strsave(short2str(a)); 1952c80476e4SDavid E. O'Brien char *sb = strsave(short2str(b)); 1953c80476e4SDavid E. O'Brien #else 1954c80476e4SDavid E. O'Brien char *sa = strip(strsave(a)); 1955c80476e4SDavid E. O'Brien char *sb = strip(strsave(b)); 1956c80476e4SDavid E. O'Brien #endif /* SHORT_STRINGS */ 1957c80476e4SDavid E. O'Brien 1958c80476e4SDavid E. O'Brien #if defined(NLS) && !defined(NOSTRCOLL) 1959c80476e4SDavid E. O'Brien errno = 0; /* strcoll sets errno, another brain-damage */ 1960c80476e4SDavid E. O'Brien 1961c80476e4SDavid E. O'Brien rv = strcoll(sa, sb); 1962c80476e4SDavid E. O'Brien 1963c80476e4SDavid E. O'Brien /* 1964c80476e4SDavid E. O'Brien * We should be checking for errno != 0, but some systems 1965c80476e4SDavid E. O'Brien * forget to reset errno to 0. So we only check for the 1966c80476e4SDavid E. O'Brien * only documented valid errno value for strcoll [EINVAL] 1967c80476e4SDavid E. O'Brien */ 1968c80476e4SDavid E. O'Brien if (errno == EINVAL) { 1969c80476e4SDavid E. O'Brien xfree((ptr_t) sa); 1970c80476e4SDavid E. O'Brien xfree((ptr_t) sb); 1971c80476e4SDavid E. O'Brien stderror(ERR_SYSTEM, "strcoll", strerror(errno)); 1972c80476e4SDavid E. O'Brien } 1973c80476e4SDavid E. O'Brien #else 1974c80476e4SDavid E. O'Brien rv = strcmp(sa, sb); 1975c80476e4SDavid E. O'Brien #endif /* NLS && !NOSTRCOLL */ 1976c80476e4SDavid E. O'Brien 1977c80476e4SDavid E. O'Brien xfree((ptr_t) sa); 1978c80476e4SDavid E. O'Brien xfree((ptr_t) sb); 1979c80476e4SDavid E. O'Brien 1980c80476e4SDavid E. O'Brien return rv; 1981c80476e4SDavid E. O'Brien } 1982c80476e4SDavid E. O'Brien 1983c80476e4SDavid E. O'Brien #ifdef HASHBANG 1984c80476e4SDavid E. O'Brien /* 1985c80476e4SDavid E. O'Brien * From: peter@zeus.dialix.oz.au (Peter Wemm) 1986c80476e4SDavid E. O'Brien * If exec() fails look first for a #! [word] [word] .... 1987c80476e4SDavid E. O'Brien * If it is, splice the header into the argument list and retry. 1988c80476e4SDavid E. O'Brien */ 1989c80476e4SDavid E. O'Brien #define HACKBUFSZ 1024 /* Max chars in #! vector */ 1990c80476e4SDavid E. O'Brien #define HACKVECSZ 128 /* Max words in #! vector */ 1991c80476e4SDavid E. O'Brien int 1992c80476e4SDavid E. O'Brien hashbang(fd, vp) 1993c80476e4SDavid E. O'Brien int fd; 1994c80476e4SDavid E. O'Brien Char ***vp; 1995c80476e4SDavid E. O'Brien { 1996c80476e4SDavid E. O'Brien unsigned char lbuf[HACKBUFSZ]; 1997c80476e4SDavid E. O'Brien char *sargv[HACKVECSZ]; 1998c80476e4SDavid E. O'Brien unsigned char *p, *ws; 1999c80476e4SDavid E. O'Brien int sargc = 0; 20003b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 2001c80476e4SDavid E. O'Brien int fw = 0; /* found at least one word */ 2002c80476e4SDavid E. O'Brien int first_word = 0; 20033b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 2004c80476e4SDavid E. O'Brien 2005c80476e4SDavid E. O'Brien if (read(fd, (char *) lbuf, HACKBUFSZ) <= 0) 2006c80476e4SDavid E. O'Brien return -1; 2007c80476e4SDavid E. O'Brien 2008c80476e4SDavid E. O'Brien ws = 0; /* word started = 0 */ 2009c80476e4SDavid E. O'Brien 2010c80476e4SDavid E. O'Brien for (p = lbuf; p < &lbuf[HACKBUFSZ]; ) 2011c80476e4SDavid E. O'Brien switch (*p) { 2012c80476e4SDavid E. O'Brien case ' ': 2013c80476e4SDavid E. O'Brien case '\t': 20143b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 2015c80476e4SDavid E. O'Brien case '\r': 20163b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 2017c80476e4SDavid E. O'Brien if (ws) { /* a blank after a word.. save it */ 2018c80476e4SDavid E. O'Brien *p = '\0'; 20193b6eaa7bSAndrey A. Chernov #ifndef WINNT_NATIVE 2020c80476e4SDavid E. O'Brien if (sargc < HACKVECSZ - 1) 2021c80476e4SDavid E. O'Brien sargv[sargc++] = ws; 2022c80476e4SDavid E. O'Brien ws = NULL; 20233b6eaa7bSAndrey A. Chernov #else /* WINNT_NATIVE */ 2024c80476e4SDavid E. O'Brien if (sargc < HACKVECSZ - 1) { 2025c80476e4SDavid E. O'Brien sargv[sargc] = first_word ? NULL: hb_subst(ws); 2026c80476e4SDavid E. O'Brien if (sargv[sargc] == NULL) 2027c80476e4SDavid E. O'Brien sargv[sargc] = ws; 2028c80476e4SDavid E. O'Brien sargc++; 2029c80476e4SDavid E. O'Brien } 2030c80476e4SDavid E. O'Brien ws = NULL; 2031c80476e4SDavid E. O'Brien fw = 1; 2032c80476e4SDavid E. O'Brien first_word = 1; 20333b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 2034c80476e4SDavid E. O'Brien } 2035c80476e4SDavid E. O'Brien p++; 2036c80476e4SDavid E. O'Brien continue; 2037c80476e4SDavid E. O'Brien 2038c80476e4SDavid E. O'Brien case '\0': /* Whoa!! what the hell happened */ 2039c80476e4SDavid E. O'Brien return -1; 2040c80476e4SDavid E. O'Brien 2041c80476e4SDavid E. O'Brien case '\n': /* The end of the line. */ 2042c80476e4SDavid E. O'Brien if ( 20433b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 2044c80476e4SDavid E. O'Brien fw || 20453b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 2046c80476e4SDavid E. O'Brien ws) { /* terminate the last word */ 2047c80476e4SDavid E. O'Brien *p = '\0'; 20483b6eaa7bSAndrey A. Chernov #ifndef WINNT_NATIVE 2049c80476e4SDavid E. O'Brien if (sargc < HACKVECSZ - 1) 2050c80476e4SDavid E. O'Brien sargv[sargc++] = ws; 20513b6eaa7bSAndrey A. Chernov #else /* WINNT_NATIVE */ 2052c80476e4SDavid E. O'Brien if (sargc < HACKVECSZ - 1) { /* deal with the 1-word case */ 2053c80476e4SDavid E. O'Brien sargv[sargc] = first_word? NULL : hb_subst(ws); 2054c80476e4SDavid E. O'Brien if (sargv[sargc] == NULL) 2055c80476e4SDavid E. O'Brien sargv[sargc] = ws; 2056c80476e4SDavid E. O'Brien sargc++; 2057c80476e4SDavid E. O'Brien } 20583b6eaa7bSAndrey A. Chernov #endif /* !WINNT_NATIVE */ 2059c80476e4SDavid E. O'Brien } 2060c80476e4SDavid E. O'Brien sargv[sargc] = NULL; 2061c80476e4SDavid E. O'Brien ws = NULL; 2062c80476e4SDavid E. O'Brien if (sargc > 0) { 2063c80476e4SDavid E. O'Brien *vp = blk2short(sargv); 2064c80476e4SDavid E. O'Brien return 0; 2065c80476e4SDavid E. O'Brien } 2066c80476e4SDavid E. O'Brien else 2067c80476e4SDavid E. O'Brien return -1; 2068c80476e4SDavid E. O'Brien 2069c80476e4SDavid E. O'Brien default: 2070c80476e4SDavid E. O'Brien if (!ws) /* Start a new word? */ 2071c80476e4SDavid E. O'Brien ws = p; 2072c80476e4SDavid E. O'Brien p++; 2073c80476e4SDavid E. O'Brien break; 2074c80476e4SDavid E. O'Brien } 2075c80476e4SDavid E. O'Brien return -1; 2076c80476e4SDavid E. O'Brien } 2077c80476e4SDavid E. O'Brien #endif /* HASHBANG */ 2078c80476e4SDavid E. O'Brien 2079c80476e4SDavid E. O'Brien #ifdef REMOTEHOST 2080c80476e4SDavid E. O'Brien 2081c80476e4SDavid E. O'Brien static sigret_t 2082c80476e4SDavid E. O'Brien palarm(snum) 2083c80476e4SDavid E. O'Brien int snum; 2084c80476e4SDavid E. O'Brien { 2085c80476e4SDavid E. O'Brien USE(snum); 2086c80476e4SDavid E. O'Brien #ifdef UNRELSIGS 2087c80476e4SDavid E. O'Brien if (snum) 2088c80476e4SDavid E. O'Brien (void) sigset(snum, SIG_IGN); 2089c80476e4SDavid E. O'Brien #endif /* UNRELSIGS */ 2090c80476e4SDavid E. O'Brien (void) alarm(0); 2091c80476e4SDavid E. O'Brien reset(); 2092c80476e4SDavid E. O'Brien 2093c80476e4SDavid E. O'Brien #ifndef SIGVOID 2094c80476e4SDavid E. O'Brien return (snum); 2095c80476e4SDavid E. O'Brien #endif 2096c80476e4SDavid E. O'Brien } 2097c80476e4SDavid E. O'Brien 2098c80476e4SDavid E. O'Brien 2099c80476e4SDavid E. O'Brien static void 2100c80476e4SDavid E. O'Brien getremotehost() 2101c80476e4SDavid E. O'Brien { 2102c80476e4SDavid E. O'Brien const char *host = NULL; 21033b6eaa7bSAndrey A. Chernov #ifdef INET6 21043b6eaa7bSAndrey A. Chernov struct sockaddr_storage saddr; 21053b6eaa7bSAndrey A. Chernov int len = sizeof(struct sockaddr_storage); 21063b6eaa7bSAndrey A. Chernov static char hbuf[NI_MAXHOST]; 21073b6eaa7bSAndrey A. Chernov #else 2108c80476e4SDavid E. O'Brien struct hostent* hp; 2109c80476e4SDavid E. O'Brien struct sockaddr_in saddr; 2110c80476e4SDavid E. O'Brien int len = sizeof(struct sockaddr_in); 21113b6eaa7bSAndrey A. Chernov #endif 2112c80476e4SDavid E. O'Brien #if defined(UTHOST) && !defined(HAVENOUTMP) 2113c80476e4SDavid E. O'Brien char *sptr = NULL; 2114c80476e4SDavid E. O'Brien #endif 2115c80476e4SDavid E. O'Brien 2116c80476e4SDavid E. O'Brien if (getpeername(SHIN, (struct sockaddr *) &saddr, &len) != -1) { 21173b6eaa7bSAndrey A. Chernov #ifdef INET6 21183b6eaa7bSAndrey A. Chernov #if 0 21193b6eaa7bSAndrey A. Chernov int flag = 0; 21203b6eaa7bSAndrey A. Chernov #else 21213b6eaa7bSAndrey A. Chernov int flag = NI_NUMERICHOST; 21223b6eaa7bSAndrey A. Chernov #endif 21233b6eaa7bSAndrey A. Chernov 21243b6eaa7bSAndrey A. Chernov #ifdef NI_WITHSCOPEID 21253b6eaa7bSAndrey A. Chernov flag |= NI_WITHSCOPEID; 21263b6eaa7bSAndrey A. Chernov #endif 21273b6eaa7bSAndrey A. Chernov getnameinfo((struct sockaddr *)&saddr, len, hbuf, sizeof(hbuf), 21283b6eaa7bSAndrey A. Chernov NULL, 0, flag); 21293b6eaa7bSAndrey A. Chernov host = hbuf; 21303b6eaa7bSAndrey A. Chernov #else 2131c80476e4SDavid E. O'Brien #if 0 2132c80476e4SDavid E. O'Brien if ((hp = gethostbyaddr((char *)&saddr.sin_addr, sizeof(struct in_addr), 2133c80476e4SDavid E. O'Brien AF_INET)) != NULL) 2134c80476e4SDavid E. O'Brien host = hp->h_name; 2135c80476e4SDavid E. O'Brien else 2136c80476e4SDavid E. O'Brien #endif 2137c80476e4SDavid E. O'Brien host = inet_ntoa(saddr.sin_addr); 21383b6eaa7bSAndrey A. Chernov #endif 2139c80476e4SDavid E. O'Brien } 2140c80476e4SDavid E. O'Brien #if defined(UTHOST) && !defined(HAVENOUTMP) 2141c80476e4SDavid E. O'Brien else { 2142c80476e4SDavid E. O'Brien char *ptr; 2143c80476e4SDavid E. O'Brien char *name = utmphost(); 2144c80476e4SDavid E. O'Brien /* Avoid empty names and local X displays */ 2145c80476e4SDavid E. O'Brien if (name != NULL && *name != '\0' && *name != ':') { 21463b6eaa7bSAndrey A. Chernov struct in_addr addr; 21473b6eaa7bSAndrey A. Chernov 2148c80476e4SDavid E. O'Brien /* Look for host:display.screen */ 21493b6eaa7bSAndrey A. Chernov /* 21503b6eaa7bSAndrey A. Chernov * There is conflict with IPv6 address and X DISPLAY. So, 21513b6eaa7bSAndrey A. Chernov * we assume there is no IPv6 address in utmp and don't 21523b6eaa7bSAndrey A. Chernov * touch here. 21533b6eaa7bSAndrey A. Chernov */ 2154c80476e4SDavid E. O'Brien if ((sptr = strchr(name, ':')) != NULL) 2155c80476e4SDavid E. O'Brien *sptr = '\0'; 21563b6eaa7bSAndrey A. Chernov /* Leave IPv4 address as is */ 21573b6eaa7bSAndrey A. Chernov /* 21583b6eaa7bSAndrey A. Chernov * we use inet_addr here, not inet_aton because many systems 21593b6eaa7bSAndrey A. Chernov * have not caught up yet. 21603b6eaa7bSAndrey A. Chernov */ 21613b6eaa7bSAndrey A. Chernov addr.s_addr = inet_addr(name); 21623b6eaa7bSAndrey A. Chernov if (addr.s_addr != (unsigned long)~0) 2163c80476e4SDavid E. O'Brien host = name; 2164c80476e4SDavid E. O'Brien else { 2165c80476e4SDavid E. O'Brien if (sptr != name) { 21663b6eaa7bSAndrey A. Chernov #ifdef INET6 21673b6eaa7bSAndrey A. Chernov char *s, *domain; 21683b6eaa7bSAndrey A. Chernov char dbuf[MAXHOSTNAMELEN], cbuf[MAXHOSTNAMELEN]; 21693b6eaa7bSAndrey A. Chernov struct addrinfo hints, *res = NULL; 21703b6eaa7bSAndrey A. Chernov 21713b6eaa7bSAndrey A. Chernov memset(&hints, 0, sizeof(hints)); 21723b6eaa7bSAndrey A. Chernov hints.ai_family = PF_UNSPEC; 21733b6eaa7bSAndrey A. Chernov hints.ai_socktype = SOCK_STREAM; 21743b6eaa7bSAndrey A. Chernov hints.ai_flags = AI_PASSIVE | AI_CANONNAME; 21753b6eaa7bSAndrey A. Chernov #if defined(UTHOST) && !defined(HAVENOUTMP) 21763b6eaa7bSAndrey A. Chernov if (strlen(name) < utmphostsize()) 21773b6eaa7bSAndrey A. Chernov #else 21783b6eaa7bSAndrey A. Chernov if (name != NULL) 21793b6eaa7bSAndrey A. Chernov #endif 21803b6eaa7bSAndrey A. Chernov { 21813b6eaa7bSAndrey A. Chernov if (getaddrinfo(name, NULL, &hints, &res) != 0) 21823b6eaa7bSAndrey A. Chernov res = NULL; 21833b6eaa7bSAndrey A. Chernov } else if (gethostname(dbuf, sizeof(dbuf) - 1) == 0 && 21843b6eaa7bSAndrey A. Chernov (domain = strchr(dbuf, '.')) != NULL) { 21853b6eaa7bSAndrey A. Chernov for (s = strchr(name, '.'); 21863b6eaa7bSAndrey A. Chernov s != NULL; s = strchr(s + 1, '.')) { 21873b6eaa7bSAndrey A. Chernov if (*(s + 1) != '\0' && 21883b6eaa7bSAndrey A. Chernov (ptr = strstr(domain, s)) != NULL) { 21893b6eaa7bSAndrey A. Chernov len = s - name; 21903b6eaa7bSAndrey A. Chernov if (len + strlen(ptr) >= sizeof(cbuf)) 21913b6eaa7bSAndrey A. Chernov break; 21923b6eaa7bSAndrey A. Chernov strncpy(cbuf, name, len); 21933b6eaa7bSAndrey A. Chernov strcpy(cbuf + len, ptr); 21943b6eaa7bSAndrey A. Chernov if (getaddrinfo(cbuf, NULL, &hints, &res) != 0) 21953b6eaa7bSAndrey A. Chernov res = NULL; 21963b6eaa7bSAndrey A. Chernov break; 21973b6eaa7bSAndrey A. Chernov } 21983b6eaa7bSAndrey A. Chernov } 21993b6eaa7bSAndrey A. Chernov } 22003b6eaa7bSAndrey A. Chernov if (res != NULL) { 22013b6eaa7bSAndrey A. Chernov if (res->ai_canonname != NULL) { 22023b6eaa7bSAndrey A. Chernov strncpy(hbuf, res->ai_canonname, sizeof(hbuf)); 22033b6eaa7bSAndrey A. Chernov host = hbuf; 22043b6eaa7bSAndrey A. Chernov } 22053b6eaa7bSAndrey A. Chernov freeaddrinfo(res); 22063b6eaa7bSAndrey A. Chernov } 22073b6eaa7bSAndrey A. Chernov #else 2208c80476e4SDavid E. O'Brien if ((hp = gethostbyname(name)) == NULL) { 2209c80476e4SDavid E. O'Brien /* Try again eliminating the trailing domain */ 2210c80476e4SDavid E. O'Brien if ((ptr = strchr(name, '.')) != NULL) { 2211c80476e4SDavid E. O'Brien *ptr = '\0'; 2212c80476e4SDavid E. O'Brien if ((hp = gethostbyname(name)) != NULL) 2213c80476e4SDavid E. O'Brien host = hp->h_name; 2214c80476e4SDavid E. O'Brien *ptr = '.'; 2215c80476e4SDavid E. O'Brien } 2216c80476e4SDavid E. O'Brien } 2217c80476e4SDavid E. O'Brien else 2218c80476e4SDavid E. O'Brien host = hp->h_name; 22193b6eaa7bSAndrey A. Chernov #endif 2220c80476e4SDavid E. O'Brien } 2221c80476e4SDavid E. O'Brien } 2222c80476e4SDavid E. O'Brien } 2223c80476e4SDavid E. O'Brien } 2224c80476e4SDavid E. O'Brien #endif 2225c80476e4SDavid E. O'Brien 2226c80476e4SDavid E. O'Brien if (host) 2227c80476e4SDavid E. O'Brien tsetenv(STRREMOTEHOST, str2short(host)); 2228c80476e4SDavid E. O'Brien 2229c80476e4SDavid E. O'Brien #if defined(UTHOST) && !defined(HAVENOUTMP) 2230c80476e4SDavid E. O'Brien if (sptr) 2231c80476e4SDavid E. O'Brien *sptr = ':'; 2232c80476e4SDavid E. O'Brien #endif 2233c80476e4SDavid E. O'Brien } 2234c80476e4SDavid E. O'Brien 2235c80476e4SDavid E. O'Brien 2236c80476e4SDavid E. O'Brien /* 2237c80476e4SDavid E. O'Brien * From: <lesv@ppvku.ericsson.se> (Lennart Svensson) 2238c80476e4SDavid E. O'Brien */ 2239c80476e4SDavid E. O'Brien void 2240c80476e4SDavid E. O'Brien remotehost() 2241c80476e4SDavid E. O'Brien { 2242c80476e4SDavid E. O'Brien /* Don't get stuck if the resolver does not work! */ 2243c80476e4SDavid E. O'Brien signalfun_t osig = sigset(SIGALRM, palarm); 2244c80476e4SDavid E. O'Brien 2245c80476e4SDavid E. O'Brien jmp_buf_t osetexit; 2246c80476e4SDavid E. O'Brien getexit(osetexit); 2247c80476e4SDavid E. O'Brien 2248c80476e4SDavid E. O'Brien (void) alarm(2); 2249c80476e4SDavid E. O'Brien 2250c80476e4SDavid E. O'Brien if (setexit() == 0) 2251c80476e4SDavid E. O'Brien getremotehost(); 2252c80476e4SDavid E. O'Brien 2253c80476e4SDavid E. O'Brien resexit(osetexit); 2254c80476e4SDavid E. O'Brien 2255c80476e4SDavid E. O'Brien (void) alarm(0); 2256c80476e4SDavid E. O'Brien (void) sigset(SIGALRM, osig); 2257c80476e4SDavid E. O'Brien 2258c80476e4SDavid E. O'Brien #ifdef YPBUGS 2259c80476e4SDavid E. O'Brien /* From: casper@fwi.uva.nl (Casper H.S. Dik), for Solaris 2.3 */ 2260c80476e4SDavid E. O'Brien fix_yp_bugs(); 2261c80476e4SDavid E. O'Brien #endif /* YPBUGS */ 2262c80476e4SDavid E. O'Brien 2263c80476e4SDavid E. O'Brien } 2264c80476e4SDavid E. O'Brien #endif /* REMOTEHOST */ 2265