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 */
617 setenv(var
, value
, 1);
620 # endif /* HAVE_SETENV_3 */
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);