summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c468
1 files changed, 468 insertions, 0 deletions
diff --git a/misc.c b/misc.c
new file mode 100644
index 0000000..0adfe19
--- /dev/null
+++ b/misc.c
@@ -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
+