1
/* Copyright (c) 1993-2002
2
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4
* Copyright (c) 1987 Oliver Laumann
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2, or (at your option)
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program (see the file COPYING); if not, write to the
18
* Free Software Foundation, Inc.,
19
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21
****************************************************************
24
#include <sys/types.h>
25
#include <sys/stat.h> /* mkdir() declaration */
33
# include <sys/resource.h>
36
extern struct layer *flayer;
38
extern int eff_uid, real_uid;
39
extern int eff_gid, real_gid;
40
extern struct mline mline_old;
41
extern struct mchar mchar_blank;
42
extern unsigned char *null, *blank;
45
static int close_func __P((void *, int));
50
register const char *str;
54
if ((cp = malloc(strlen(str) + 1)) == NULL)
63
register const char *str;
68
if ((cp = malloc(n + 1)) == NULL)
72
bcopy((char *)str, cp, n);
78
/* cheap strstr replacement */
84
int npat = strlen(pat);
86
if (!strncmp(str, pat, npat))
97
extern char *sys_errlist[];
100
if (err > 0 && err < sys_nerr)
101
return sys_errlist[err];
102
sprintf(er, "Error %d", err);
116
if (n > flayer->l_width - 1)
117
n = flayer->l_width - 1;
118
l = (flayer->l_width - 1 - n) / 2;
119
LPutStr(flayer, str, n, &mchar_blank, l, y);
128
struct mchar mchar_dol;
130
mchar_dol = mchar_blank;
131
mchar_dol.image = '$';
135
if (n > flayer->l_width - 1)
136
n = flayer->l_width - 1;
137
LPutStr(flayer, str, n, &mchar_blank, 0, y);
139
LPutChar(flayer, &mchar_dol, n, y);
147
register char *p = s;
166
/* unixware has /dev/pts012 as synonym for /dev/pts/12 */
167
if (!strncmp(nam, "/dev/pts", 8) && nam[8] >= '0' && nam[8] <= '9')
170
sprintf(b, "pts/%d", atoi(nam + 8));
174
if (p = strstr(nam,"/dev/"))
179
if (strncmp(nam, "/dev/", 5) == 0)
191
sigret_t (*xsignal(sig, func))
198
sigret_t (*func) __P(SIGPROTOARG);
200
struct sigaction osa, sa;
201
sa.sa_handler = func;
202
(void)sigemptyset(&sa.sa_mask);
204
sa.sa_flags = (sig == SIGCHLD ? SA_RESTART : 0);
208
if (sigaction(sig, &sa, &osa))
209
return (sigret_t (*)__P(SIGPROTOARG))-1;
210
return osa.sa_handler;
216
* hpux has berkeley signal semantics if we use sigvector,
217
* but not, if we use signal, so we define our own signal() routine.
219
void (*xsignal(sig, func)) __P(SIGPROTOARG)
221
void (*func) __P(SIGPROTOARG);
223
struct sigvec osv, sv;
225
sv.sv_handler = func;
226
sv.sv_mask = sigmask(sig);
227
sv.sv_flags = SV_BSDSIG;
228
if (sigvector(sig, &sv, &osv) < 0)
229
return (void (*)__P(SIGPROTOARG))(BADSIG);
230
return osv.sv_handler;
246
if (seteuid(euid) == 0)
250
Panic(errno, "seteuid");
258
Panic(errno, "setegid");
261
#else /* HAVE_SETEUID */
262
# ifdef HAVE_SETREUID
273
if ((int)getuid() != euid)
275
if (setreuid(oeuid, euid))
276
Panic(errno, "setreuid");
288
if ((int)getgid() != egid)
290
if (setregid(oegid, egid))
291
Panic(errno, "setregid");
294
# endif /* HAVE_SETREUID */
295
#endif /* HAVE_SETEUID */
299
#ifdef NEED_OWN_BCOPY
302
register char *s1, *s2;
305
if (s1 < s2 && s2 < s1 + len)
316
#endif /* NEED_OWN_BCOPY */
323
bcopy((char *)blank, p, n);
333
(void) kill(pid, sig);
338
* Modern versions of Solaris include fdwalk(3c) which allows efficient
339
* implementation of closing open descriptors; this is helpful because
340
* the default file descriptor limit has risen to 65k.
343
close_func(cb_data, fd)
347
int except = *(int *)cb_data;
348
if (fd > 2 && fd != except)
354
closeallfiles(except)
357
(void)fdwalk(close_func, &except);
360
#else /* HAVE_FDWALK */
363
closeallfiles(except)
370
if ((getrlimit(RLIMIT_NOFILE, &rl) == 0) && rl.rlim_max != RLIM_INFINITY)
374
#if defined(SYSV) && defined(NOFILE) && !defined(ISC)
376
#else /* SYSV && !ISC */
378
#endif /* SYSV && !ISC */
384
#endif /* HAVE_FDWALK */
388
* Security - switch to real uid
393
static sigret_t (*Usersigcld)__P(SIGPROTOARG);
401
if (eff_uid == real_uid && eff_gid == real_gid)
403
Usersigcld = signal(SIGCHLD, SIG_DFL);
404
debug("UserContext: forking.\n");
405
switch (UserPID = fork())
411
signal(SIGHUP, SIG_DFL);
412
signal(SIGINT, SIG_IGN);
413
signal(SIGQUIT, SIG_DFL);
414
signal(SIGTERM, SIG_DFL);
416
signal(SIGTTIN, SIG_DFL);
417
signal(SIGTTOU, SIG_DFL);
437
if (eff_uid == real_uid && eff_gid == real_gid)
459
if (eff_uid == real_uid && eff_gid == real_gid)
463
while ((errno = 0, i = wait(&wstat)) != UserPID)
464
if (i < 0 && errno != EINTR)
466
(void) signal(SIGCHLD, Usersigcld);
469
return WEXITSTATUS(wstat);
481
if (link(old, new) < 0)
495
if (ch < ' ' || ch == 0x7f)
503
*p++ = (ch >> 6 & 7) + '0';
504
*p++ = (ch >> 3 & 7) + '0';
505
*p++ = (ch >> 0 & 7) + '0';
513
AddXChars(buf, len, str)
524
len -= 4; /* longest sequence produced by AddXChar() */
525
for (p = buf; p < buf + len && *str; str++)
530
p += AddXChar(p, *str);
539
opendebug(new, shout)
545
mode_t oumask = umask(0);
547
int oumask = umask(0);
552
(void) mkdir(DEBUGDIR, 0777);
553
sprintf(buf, shout ? "%s/SCREEN.%d" : "%s/screen.%d", DEBUGDIR, getpid());
554
if (!(dfp = fopen(buf, new ? "w" : "a")))
557
(void)chmod(buf, 0666);
560
debug("opendebug: done.\n");
571
t.tv_sec = (long) (msec / 1000);
572
t.tv_usec = (long) ((msec % 1000) * 1000);
573
select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
578
* This uses either setenv() or putenv(). If it is putenv() we cannot dare
579
* to free the buffer after putenv(), unless it it the one found in putenv.c
590
if ((buf = (char *)malloc((l = strlen(var)) +
591
strlen(value) + 2)) == NULL)
598
strcpy(buf + l + 1, value);
602
* we use our own putenv(), knowing that it does a malloc()
603
* the string space, we can free our buf now.
606
# else /* NEEDSETENV */
608
* For all sysv-ish systems that link a standard putenv()
609
* the string-space buf is added to the environment and must not
610
* be freed, or modified.
611
* We are sorry to say that memory is lost here, when setting
612
* the same variable again and again.
614
# endif /* NEEDSETENV */
615
#else /* USESETENV */
616
# if defined(linux) || defined(__convex__) || (BSD >= 199103)
617
setenv(var, value, 1);
620
# endif /* linux || convex || BSD >= 199103 */
621
#endif /* USESETENV */
626
* This is a replacement for the buggy _delay function from the termcap
627
* emulation of libcurses, which ignores ospeed.
632
int (*outc) __P((int));
636
static short osp2pad[] = {
637
0,2000,1333,909,743,666,500,333,166,83,55,41,20,10,5,2,1,1
640
if (ospeed <= 0 || ospeed >= (int)(sizeof(osp2pad)/sizeof(*osp2pad)))
642
pad =osp2pad[ospeed];
643
delay = (delay + pad / 2) / pad;
651
/* stupid stupid linux ncurses! It won't to padding with
652
* zeros but sleeps instead. This breaks CalcCost, of course.
653
* Also, the ncurses wait functions use a global variable
654
* to store the current outc function. Oh well...
657
int (*save_outc) __P((int));
662
xtputs(str, affcnt, outc)
665
int (*outc) __P((int));
667
extern int tputs __P((const char *, int, int (*)(int)));
669
tputs(str, affcnt, outc);
673
_nc_timed_wait(mode, ms, tlp)
676
_delay(ms * 10, save_outc);
682
#endif /* TERMINFO */
688
# define xva_arg(s, t, tn) (*(t *)(s += xsnoff(tn, 0, 0), s - xsnoff(tn, 0, 0)))
689
# define xva_list char *
697
return a ? (char *)&c - (char *)&b : (char *)&b - (char *)&a;
701
xsnprintf(s, n, fmt, p1, p2, p3, p4, p5, p6)
705
unsigned long p1, p2, p3, p4, p5, p6;
707
int xvsnprintf __P((char *, int, char *, xva_list));
708
return xvsnprintf(s, n, fmt, (char *)&fmt + xsnoff(1, 0, 0));
713
# define xva_arg(s, t, tn) va_arg(s, t)
714
# define xva_list va_list
719
#if !defined(USEVARARGS) || !defined(HAVE_VSNPRINTF)
722
xvsnprintf(s, n, fmt, stack)
730
char myf[10], buf[20];
736
while(arg || (sf = index(f, '%')) || (sf = f + strlen(f)))
745
i = argl > n - 1 ? n - 1 : argl;
764
while (((*f >= '0' && *f <='9') || *f == '#') && myfp - myf < 8)
779
i = xva_arg(stack, int, 0);
780
sprintf(buf, myf, i);
784
arg = xva_arg(stack, char *, 1);