--- rxvt-unicode/src/main.C 2006/01/12 00:11:13 1.174 +++ rxvt-unicode/src/main.C 2006/01/20 10:27:08 1.191 @@ -48,27 +48,15 @@ # include #endif -#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(__CYGWIN32__) -static uid_t saved_euid; -static gid_t saved_egid; -#endif - -bool -rxvt_tainted () -{ -#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(__CYGWIN32__) - return getuid () != saved_euid || getgid () != saved_egid; -#else - return false; -#endif -} - vector rxvt_term::termlist; +// used to tell global functions which terminal instance is "active" +rxvt_t rxvt_current_term; + static char curlocale[128], savelocale[128]; bool -rxvt_set_locale (const char *locale) +rxvt_set_locale (const char *locale) NOTHROW { if (!locale || !strncmp (locale, curlocale, 128)) return false; @@ -79,14 +67,14 @@ } void -rxvt_push_locale (const char *locale) +rxvt_push_locale (const char *locale) NOTHROW { strcpy (savelocale, curlocale); rxvt_set_locale (locale); } void -rxvt_pop_locale () +rxvt_pop_locale () NOTHROW { rxvt_set_locale (savelocale); } @@ -163,9 +151,6 @@ #ifdef HAVE_SCROLLBARS scrollbar_ev (this, &rxvt_term::x_cb), #endif -#ifdef MENUBAR - menubar_ev (this, &rxvt_term::x_cb), -#endif #ifdef CURSOR_BLINK cursor_blink_ev (this, &rxvt_term::cursor_blink_cb), #endif @@ -189,6 +174,7 @@ #endif termwin_ev (this, &rxvt_term::x_cb), vt_ev (this, &rxvt_term::x_cb), + child_ev (this, &rxvt_term::child_cb), check_ev (this, &rxvt_term::check_cb), flush_ev (this, &rxvt_term::flush_cb), destroy_ev (this, &rxvt_term::destroy_cb), @@ -201,9 +187,6 @@ #ifdef KEYSYM_RESOURCE keyboard = new keyboard_manager; - - if (!keyboard) - rxvt_fatal ("out of memory, aborting.\n"); #endif } @@ -214,17 +197,11 @@ if (cmd_pid) kill (-cmd_pid, SIGHUP); -#ifdef UTMP_SUPPORT - privileged_utmp (RESTORE); -#endif - - pty.put (); + delete pty; pty = 0; } rxvt_term::~rxvt_term () { - HOOK_INVOKE ((this, HOOK_DESTROY, DT_END)); - termlist.erase (find (termlist.begin (), termlist.end(), this)); emergency_cleanup (); @@ -245,9 +222,6 @@ #ifdef USE_XIM im_destroy (); #endif -#ifdef MENUBAR - if (menubarGC) XFreeGC (disp, menubarGC); -#endif #ifdef XTERM_SCROLLBAR if (xscrollbarGC) XFreeGC (disp, xscrollbarGC); if (ShadowGC) XFreeGC (disp, ShadowGC); @@ -267,18 +241,13 @@ if (upArrowHi) XFreePixmap (disp, upArrowHi); if (downArrowHi) XFreePixmap (disp, downArrowHi); #endif -#if defined(MENUBAR) || defined(RXVT_SCROLLBAR) +#ifdef RXVT_SCROLLBAR if (topShadowGC) XFreeGC (disp, topShadowGC); if (botShadowGC) XFreeGC (disp, botShadowGC); if (scrollbarGC) XFreeGC (disp, scrollbarGC); #endif if (gc) XFreeGC (disp, gc); -#if defined(MENUBAR) && (MENUBAR_MAX > 1) - delete menuBar.drawable; - //if (menuBar.win) - // XDestroyWindow (disp, menuBar.win); -#endif delete drawable; // destroy all windows if (parent[0]) @@ -317,9 +286,12 @@ #endif } +// child has exited, usually destroys void -rxvt_term::child_exit () +rxvt_term::child_cb (child_watcher &w, int status) { + HOOK_INVOKE ((this, HOOK_CHILD_EXIT, DT_INT, status, DT_END)); + cmd_pid = 0; if (!OPTION (Opt_hold)) @@ -332,6 +304,9 @@ if (destroy_ev.active) return; + if (HOOK_INVOKE ((this, HOOK_DESTROY, DT_END))) + return; + #if ENABLE_OVERLAY scr_overlay_off (); #endif @@ -344,9 +319,6 @@ #if HAVE_SCROLLBARS scrollbar_ev.stop (display); #endif -#if MENUBAR - menubar_ev.stop (display); -#endif #if TRANSPARENT rootwin_ev.stop (display); #endif @@ -379,7 +351,7 @@ void rxvt_term::destroy_cb (time_watcher &w) { - SET_R (this); + make_current (); delete this; } @@ -480,33 +452,19 @@ rxvt_term::init (int argc, const char *const *argv) { SET_R (this); + set_locale (""); + set_environ (envv); // few things in X do not call setlocale :( - const char **cmd_argv; - - { - TEMP_ENV; // few things in X do not call setlocale :( - - set_locale (""); - - if (!init_vars ()) - return false; + if (!init_vars ()) + return false; - init_secondary (); + init_secondary (); - cmd_argv = init_resources (argc, argv); + const char **cmd_argv = init_resources (argc, argv); #ifdef KEYSYM_RESOURCE - keyboard->register_done (); -#endif - -#if MENUBAR_MAX - menubar_read (rs[Rs_menu]); -#endif -#ifdef HAVE_SCROLLBARS - if (OPTION (Opt_scrollBar)) - scrollBar.setIdle (); /* set existence for size calculations */ + keyboard->register_done (); #endif - } #if ENABLE_PERL if (!rs[Rs_perl_ext_1]) @@ -516,95 +474,66 @@ || (rs[Rs_perl_ext_2] && *rs[Rs_perl_ext_2]) || (rs[Rs_perl_eval] && *rs[Rs_perl_eval])) { -#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(__CYGWIN32__) - // ignore some perl-related arguments if some bozo installed us set[ug]id - if (rxvt_tainted ()) - { - if ((rs[Rs_perl_lib] && *rs[Rs_perl_lib]) - || (rs[Rs_perl_eval] && *rs[Rs_perl_eval])) - { - rxvt_warn ("running with elevated privileges: ignoring perl-lib and perl-eval.\n"); - rs[Rs_perl_lib] = 0; - rs[Rs_perl_eval] = 0; - } - } -#endif - rxvt_perl.init (); - setlocale (LC_CTYPE, curlocale); // perl destroys this info + rxvt_perl.init (this); HOOK_INVOKE ((this, HOOK_INIT, DT_END)); } #endif - { - TEMP_ENV; +#ifdef HAVE_SCROLLBARS + if (OPTION (Opt_scrollBar)) + scrollBar.setIdle (); /* set existence for size calculations */ +#endif - create_windows (argc, argv); + pty = rxvt_new_ptytty (); - dDisp; + create_windows (argc, argv); - init_xlocale (); + dDisp; + + init_xlocale (); - scr_reset (); // initialize screen + scr_reset (); // initialize screen #if 0 - XSynchronize (disp, True); + XSynchronize (disp, True); #endif #ifdef HAVE_SCROLLBARS - if (OPTION (Opt_scrollBar)) - resize_scrollbar (); /* create and map scrollbar */ -#endif -#if (MENUBAR_MAX) - if (menubar_visible ()) - XMapWindow (disp, menuBar.win); + if (OPTION (Opt_scrollBar)) + resize_scrollbar (); /* create and map scrollbar */ #endif #ifdef TRANSPARENT - if (OPTION (Opt_transparent)) - { - XSelectInput (disp, display->root, PropertyChangeMask); - check_our_parents (); - rootwin_ev.start (display, display->root); - } + if (OPTION (Opt_transparent)) + { + XSelectInput (disp, display->root, PropertyChangeMask); + check_our_parents (); + rootwin_ev.start (display, display->root); + } #endif - XMapWindow (disp, vt); - XMapWindow (disp, parent[0]); + set_colorfgbg (); - set_colorfgbg (); + init_command (cmd_argv); - init_command (cmd_argv); + free (cmd_argv); - free (cmd_argv); + if (pty->pty >= 0) + pty_ev.start (pty->pty, EVENT_READ); - if (pty.pty >= 0) - pty_ev.start (pty.pty, EVENT_READ); + check_ev.start (); - check_ev.start (); + HOOK_INVOKE ((this, HOOK_START, DT_END)); - HOOK_INVOKE ((this, HOOK_START, DT_END)); - } + XMapWindow (disp, vt); + XMapWindow (disp, parent[0]); return true; } static struct sig_handlers { - sig_watcher sw_chld, sw_term, sw_int; + sig_watcher sw_term, sw_int; - void sig_chld (sig_watcher &w) - { - // we are being called for every SIGCHLD, find the corresponding term - int pid; - - while ((pid = waitpid (-1, NULL, WNOHANG)) > 0) - for (rxvt_term **t = rxvt_term::termlist.begin (); t < rxvt_term::termlist.end (); t++) - if (pid == (*t)->cmd_pid) - { - (*t)->child_exit (); - break; - } - } - /* * Catch a fatal signal and tidy up before quitting */ @@ -620,30 +549,53 @@ } sig_handlers () - : sw_chld (this, &sig_handlers::sig_chld), - sw_term (this, &sig_handlers::sig_term), + : sw_term (this, &sig_handlers::sig_term), sw_int (this, &sig_handlers::sig_term) { } } sig_handlers; +char **rxvt_environ; // startup environment + void rxvt_init () { - /* - * Save and then give up any super-user privileges - * If we need privileges in any area then we must specifically request it. - * We should only need to be root in these cases: - * 1. write utmp entries on some systems - * 2. chown tty on some systems - */ - rxvt_privileges (SAVE); - rxvt_privileges (IGNORE); + uid_t uid = getuid (); + gid_t gid = getgid (); + + // before doing anything else, check for setuid/setgid operation, + // start the helper process and drop privileges + if (uid != geteuid () + || gid != getegid ()) + { +#if PTYTTY_HELPER + rxvt_ptytty_server (); +#else + rxvt_warn ("running setuid/setgid without pty helper compiled in, continuing unprivileged.\n"); +#endif + + // drop privileges +#if HAVE_SETRESUID + setresgid (gid, gid, gid); + setresuid (uid, uid, uid); +#elif HAVE_SETREUID + setregid (gid, gid); + setreuid (uid, uid); +#elif HAVE_SETUID + setgid (gid); + setuid (uid); +#endif + + if (uid != geteuid () + || gid != getegid ()) + rxvt_fatal ("unable to drop privileges, aborting.\n"); + } + + rxvt_environ = environ; signal (SIGHUP, SIG_IGN); signal (SIGPIPE, SIG_IGN); - sig_handlers.sw_chld.start (SIGCHLD); sig_handlers.sw_term.start (SIGTERM); sig_handlers.sw_int.start (SIGINT); @@ -682,7 +634,7 @@ return p; } -void * +void * rxvt_realloc (void *ptr, size_t size) { void *p = realloc (ptr, size); @@ -693,75 +645,6 @@ return p; } -/* ------------------------------------------------------------------------- * - * PRIVILEGED OPERATIONS * - * ------------------------------------------------------------------------- */ -/* take care of suid/sgid super-user (root) privileges */ -void -rxvt_privileges (rxvt_privaction action) -{ -#if ! defined(__CYGWIN32__) -# if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) - /* setreuid () is the poor man's setuid (), seteuid () */ -# define seteuid(a) setreuid(-1, (a)) -# define setegid(a) setregid(-1, (a)) -# define HAVE_SETEUID -# endif -# ifdef HAVE_SETEUID - switch (action) - { - case IGNORE: - /* - * change effective uid/gid - not real uid/gid - so we can switch - * back to root later, as required - */ - setegid (getgid ()); - seteuid (getuid ()); - break; - case SAVE: - saved_egid = getegid (); - saved_euid = geteuid (); - break; - case RESTORE: - setegid (saved_egid); - seteuid (saved_euid); - break; - } -# else - switch (action) - { - case IGNORE: - setgid (getgid ()); - setuid (getuid ()); - /* FALLTHROUGH */ - case SAVE: - /* FALLTHROUGH */ - case RESTORE: - break; - } -# endif -#endif -} - -#ifdef UTMP_SUPPORT -void -rxvt_term::privileged_utmp (rxvt_privaction action) -{ - if (OPTION (Opt_utmpInhibit) - || !pty.name || !*pty.name) - return; - - rxvt_privileges (RESTORE); - - if (action == SAVE) - makeutent (pty.name, rs[Rs_display_name]); - else - cleanutent (); - - rxvt_privileges (IGNORE); -} -#endif - /*----------------------------------------------------------------------*/ /* * window size/position calculcations for XSizeHint and other storage. @@ -771,7 +654,7 @@ rxvt_term::window_calc (unsigned int newwidth, unsigned int newheight) { short recalc_x, recalc_y; - int x, y, sb_w, mb_h, flags; + int x, y, sb_w, flags; unsigned int w, h; unsigned int max_width, max_height; dDisp; @@ -842,10 +725,10 @@ szHint.base_width = szHint.base_height = 2 * int_bwidth; - sb_w = mb_h = 0; + sb_w = 0; window_vt_x = window_vt_y = int_bwidth; - if (scrollbar_visible ()) + if (scrollBar.state) { sb_w = scrollbar_TotalWidth (); szHint.base_width += sb_w; @@ -853,13 +736,6 @@ window_vt_x += sb_w; } - if (menubar_visible ()) - { - mb_h = menuBar_TotalHeight (); - szHint.base_height += mb_h; - window_vt_y += mb_h; - } - szHint.width_inc = fwidth; szHint.height_inc = fheight; szHint.min_width = szHint.base_width + szHint.width_inc; @@ -887,7 +763,7 @@ szHint.height = szHint.base_height + height; } - if (scrollbar_visible () && OPTION (Opt_scrollBar_right)) + if (scrollBar.state && OPTION (Opt_scrollBar_right)) window_sb_x = szHint.width - sb_w; if (recalc_x) @@ -911,7 +787,7 @@ void rxvt_term::tt_winch () { - if (pty.pty < 0) + if (pty->pty < 0) return; struct winsize ws; @@ -920,7 +796,7 @@ ws.ws_row = nrow; ws.ws_xpixel = width; ws.ws_ypixel = height; - (void)ioctl (pty.pty, TIOCSWINSZ, &ws); + (void)ioctl (pty->pty, TIOCSWINSZ, &ws); #if 0 // TIOCSWINSZ⎈ is supposed to do this automatically and correctly @@ -1252,7 +1128,7 @@ if (fix_screen || newwidth != old_width || newheight != old_height) { - if (scrollbar_visible ()) + if (scrollBar.state) { XMoveResizeWindow (disp, scrollBar.win, window_sb_x, 0, @@ -1260,11 +1136,6 @@ resize_scrollbar (); } - if (menubar_visible ()) - XMoveResizeWindow (disp, menuBar.win, - window_vt_x, 0, - width, menuBar_TotalHeight ()); - XMoveResizeWindow (disp, vt, window_vt_x, window_vt_y, width, height); @@ -1458,7 +1329,7 @@ char **s; XIMStyles *xim_styles; - TEMP_ENV; + set_environ (envv); if (! ((p = XSetLocaleModifiers (modifiers)) && *p)) return false; @@ -1634,7 +1505,7 @@ char **s; char buf[IMBUFSIZ]; - SET_R (this); + make_current (); im_destroy (); @@ -1721,7 +1592,4 @@ } #endif /* USE_XIM */ -/*----------------------------------------------------------------------*/ -rxvt_t rxvt_current_term; - /*----------------------- end-of-file (C source) -----------------------*/