diff options
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 468 |
1 files changed, 468 insertions, 0 deletions
@@ -0,0 +1,468 @@ +/* Copyright (c) 1993 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + */ + +#include "rcs.h" +RCS_ID("$Id: misc.c,v 1.5 1994/05/31 12:32:19 mlschroe Exp $ FAU") + +#include <sys/types.h> +#include <signal.h> + +#include "config.h" +#include "screen.h" +#include "extern.h" + +#ifdef SVR4 +# include <sys/resource.h> +#endif + +extern struct display *display; +extern int eff_uid, real_uid; +extern int eff_gid, real_gid; +extern struct mline mline_old; +extern char *null, *blank; + +char * +SaveStr(str) +register const char *str; +{ + register char *cp; + + if ((cp = malloc(strlen(str) + 1)) == NULL) + Panic(0, strnomem); + else + strcpy(cp, str); + return cp; +} + +#ifndef HAVE_STRERROR +char * +strerror(err) +int err; +{ + extern int sys_nerr; + extern char *sys_errlist[]; + + static char er[20]; + if (err > 0 && err < sys_nerr) + return sys_errlist[err]; + sprintf(er, "Error %d", err); + return er; +} +#endif + +void +centerline(str) +char *str; +{ + int l, n; + + ASSERT(display); + n = strlen(str); + if (n > D_width - 1) + n = D_width - 1; + l = (D_width - 1 - n) / 2; + if (l > 0) + AddStrn("", l); + AddStrn(str, n); + AddStr("\r\n"); +} + +char * +Filename(s) +char *s; +{ + register char *p = s; + + if (p) + while (*p) + if (*p++ == '/') + s = p; + return s; +} + +char * +stripdev(nam) +char *nam; +{ +#ifdef apollo + char *p; + + if (nam == NULL) + return NULL; + if (p = strstr(nam,"/dev/")) + return p + 5; +#else /* apollo */ + if (nam == NULL) + return NULL; +# ifdef SVR4 + /* unixware has /dev/pts012 as synonym for /dev/pts/12 */ + if (!strncmp(nam, "/dev/pts", 8) && nam[8] >= '0' && nam[8] <= '9') + { + static char b[13]; + sprintf(b, "pts/%d", atoi(nam + 8)); + return b; + } +# endif /* SVR4 */ + if (strncmp(nam, "/dev/", 5) == 0) + return nam + 5; +#endif /* apollo */ + return nam; +} + + +/* + * Signal handling + */ + +#ifdef POSIX +sigret_t (*xsignal(sig, func)) __P(SIGPROTOARG) +int sig; +sigret_t (*func) __P(SIGPROTOARG); +{ + struct sigaction osa, sa; + sa.sa_handler = func; + (void)sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(sig, &sa, &osa)) + return (sigret_t (*)__P(SIGPROTOARG))-1; + return osa.sa_handler; +} + +#else +# ifdef hpux +/* + * hpux has berkeley signal semantics if we use sigvector, + * but not, if we use signal, so we define our own signal() routine. + */ +void (*xsignal(sig, func)) __P(SIGPROTOARG) +int sig; +void (*func) __P(SIGPROTOARG); +{ + struct sigvec osv, sv; + + sv.sv_handler = func; + sv.sv_mask = sigmask(sig); + sv.sv_flags = SV_BSDSIG; + if (sigvector(sig, &sv, &osv) < 0) + return (void (*)__P(SIGPROTOARG))(BADSIG); + return osv.sv_handler; +} +# endif /* hpux */ +#endif /* POSIX */ + + +/* + * uid/gid handling + */ + +#ifdef HAVE_SETEUID + +void +xseteuid(euid) +int euid; +{ + if (seteuid(euid) == 0) + return; + seteuid(0); + if (seteuid(euid)) + Panic(errno, "seteuid"); +} + +void +xsetegid(egid) +int egid; +{ + if (setegid(egid)) + Panic(errno, "setegid"); +} + +#else +# ifdef HAVE_SETREUID + +void +xseteuid(euid) +int euid; +{ + int oeuid; + + oeuid = geteuid(); + if (oeuid == euid) + return; + if (getuid() != euid) + oeuid = getuid(); + if (setreuid(oeuid, euid)) + Panic(errno, "setreuid"); +} + +void +xsetegid(egid) +int egid; +{ + int oegid; + + oegid = getegid(); + if (oegid == egid) + return; + if (getgid() != egid) + oegid = getgid(); + if (setregid(oegid, egid)) + Panic(errno, "setregid"); +} + +# endif +#endif + + + +#ifdef NEED_OWN_BCOPY +void +xbcopy(s1, s2, len) +register char *s1, *s2; +register int len; +{ + if (s1 < s2 && s2 < s1 + len) + { + s1 += len; + s2 += len; + while (len-- > 0) + *--s2 = *--s1; + } + else + while (len-- > 0) + *s2++ = *s1++; +} +#endif /* NEED_OWN_BCOPY */ + +void +bclear(p, n) +char *p; +int n; +{ + bcopy(blank, p, n); +} + + +void +Kill(pid, sig) +int pid, sig; +{ + if (pid < 2) + return; + (void) kill(pid, sig); +} + +void +closeallfiles(except) +int except; +{ + int f; +#ifdef SVR4 + struct rlimit rl; + + if ((getrlimit(RLIMIT_NOFILE, &rl) == 0) && rl.rlim_max != RLIM_INFINITY) + f = rl.rlim_max; + else +#endif /* SVR4 */ +#if defined(SYSV) && !defined(ISC) + f = NOFILE; +#else /* SYSV && !ISC */ + f = getdtablesize(); +#endif /* SYSV && !ISC */ + while (--f > 2) + if (f != except) + close(f); +} + + + +/* + * Security - switch to real uid + */ + +#ifndef USE_SETEUID +static int UserPID; +static sigret_t (*Usersigcld)__P(SIGPROTOARG); +#endif +static int UserSTAT; + +int +UserContext() +{ +#ifndef USE_SETEUID + if (eff_uid == real_uid && eff_gid == real_gid) + return 1; + Usersigcld = signal(SIGCHLD, SIG_DFL); + debug("UserContext: forking.\n"); + switch (UserPID = fork()) + { + case -1: + Msg(errno, "fork"); + return -1; + case 0: + signal(SIGHUP, SIG_DFL); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_DFL); + signal(SIGTERM, SIG_DFL); +# ifdef BSDJOBS + signal(SIGTTIN, SIG_DFL); + signal(SIGTTOU, SIG_DFL); +# endif + setuid(real_uid); + setgid(real_gid); + return 1; + default: + return 0; + } +#else + xseteuid(real_uid); + xsetegid(real_gid); + return 1; +#endif +} + +void +UserReturn(val) +int val; +{ +#ifndef USE_SETEUID + if (eff_uid == real_uid && eff_gid == real_gid) + UserSTAT = val; + else + _exit(val); +#else + xseteuid(eff_uid); + xsetegid(eff_gid); + UserSTAT = val; +#endif +} + +int +UserStatus() +{ +#ifndef USE_SETEUID + int i; +# ifdef BSDWAIT + union wait wstat; +# else + int wstat; +# endif + + if (eff_uid == real_uid && eff_gid == real_gid) + return UserSTAT; + if (UserPID < 0) + return -1; + while ((errno = 0, i = wait(&wstat)) != UserPID) + if (i < 0 && errno != EINTR) + break; + (void) signal(SIGCHLD, Usersigcld); + if (i == -1) + return -1; + return WEXITSTATUS(wstat); +#else + return UserSTAT; +#endif +} + +#ifdef NEED_RENAME +int +rename (old, new) +char *old; +char *new; +{ + if (link(old, new) < 0) + return -1; + return unlink(old); +} +#endif + + +int +AddXChar(buf, ch) +char *buf; +int ch; +{ + char *p = buf; + + if (ch < ' ' || ch == 0x7f) + { + *p++ = '^'; + *p++ = ch ^ 0x40; + } + else if (ch >= 0x80) + { + *p++ = '\\'; + *p++ = (ch >> 6 & 7) + '0'; + *p++ = (ch >> 3 & 7) + '0'; + *p++ = (ch >> 0 & 7) + '0'; + } + else + *p++ = ch; + return p - buf; +} + +int +AddXChars(buf, len, str) +char *buf, *str; +int len; +{ + char *p; + + len -= 4; /* longest sequence produced by AddXChar() */ + for (p = buf; p < buf + len && *str; str++) + { + if (*str == ' ') + *p++ = *str; + else + p += AddXChar(p, *str); + } + *p = 0; + return p - buf; +} + + +#ifdef TERMINFO +/* + * This is a replacement for the buggy _delay function from the termcap + * emulation of libcurses, which ignores ospeed. + */ +int +_delay(delay, outc) +register int delay; +int (*outc)(); +{ + int pad; + extern short ospeed; + static short osp2pad[] = { + 0,2000,1333,909,743,666,500,333,166,83,55,41,20,10,5,2,1,1 + }; + + if (ospeed <= 0 || ospeed >= sizeof(osp2pad)/sizeof(*osp2pad)) + return 0; + pad =osp2pad[ospeed]; + delay = (delay + pad / 2) / pad; + while (delay-- > 0) + (*outc)(0); + return 0; +} +#endif + |