--- rxvt-unicode/src/init.C 2007/09/12 21:06:08 1.212 +++ rxvt-unicode/src/init.C 2007/10/28 11:25:04 1.220 @@ -7,6 +7,9 @@ * - original version * Copyright (c) 1994 Robert Nation * - extensive modifications + * Copyright (c) 1996 Chuck Blake + * Copyright (c) 1997 mj olesen + * Copyright (c) 1997,1998 Oezguer Kesim * Copyright (c) 1998-2001 Geoff Wing * - extensive modifications * Copyright (c) 1999 D J Hawkey Jr @@ -40,6 +43,107 @@ #include +#ifdef HAVE_XSETLOCALE +# define X_LOCALE +# include +#else +# ifdef HAVE_SETLOCALE +# include +# endif +#endif + +#ifdef HAVE_NL_LANGINFO +# include +#endif + +#ifdef DISPLAY_IS_IP +/* On Solaris link with -lsocket and -lnsl */ +#include +#include + +/* these next two are probably only on Sun (not Solaris) */ +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#ifdef HAVE_SYS_BYTEORDER_H +#include +#endif + +#include +#include +#include +#include + +static char * +rxvt_network_display (const char *display) +{ + char buffer[1024], *rval = NULL; + struct ifconf ifc; + struct ifreq *ifr; + int i, skfd; + + if (display[0] != ':' && strncmp (display, "unix:", 5)) + return (char *) display; /* nothing to do */ + + ifc.ifc_len = sizeof (buffer); /* Get names of all ifaces */ + ifc.ifc_buf = buffer; + + if ((skfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) + { + perror ("socket"); + return NULL; + } + + if (ioctl (skfd, SIOCGIFCONF, &ifc) < 0) + { + perror ("SIOCGIFCONF"); + close (skfd); + return NULL; + } + + for (i = 0, ifr = ifc.ifc_req; + i < (ifc.ifc_len / sizeof (struct ifreq)); + i++, ifr++) + { + struct ifreq ifr2; + + strcpy (ifr2.ifr_name, ifr->ifr_name); + + if (ioctl (skfd, SIOCGIFADDR, &ifr2) >= 0) + { + unsigned long addr; + struct sockaddr_in *p_addr; + + p_addr = (struct sockaddr_in *) &ifr2.ifr_addr; + addr = htonl ((unsigned long)p_addr->sin_addr.s_addr); + + /* + * not "0.0.0.0" or "127.0.0.1" - so format the address + */ + if (addr && addr != 0x7F000001) + { + char *colon = strchr (display, ':'); + + if (colon == NULL) + colon = ":0.0"; + + rval = rxvt_malloc (strlen (colon) + 16); + sprintf (rval, "%d.%d.%d.%d%s", + (int) ((addr >> 030) & 0xFF), + (int) ((addr >> 020) & 0xFF), + (int) ((addr >> 010) & 0xFF), + (int) (addr & 0xFF), colon); + break; + } + } + } + + close (skfd); + + return rval; +} +#endif + const char *const def_colorName[] = { COLOR_FOREGROUND, @@ -230,7 +334,7 @@ /* TODO: BOO HISS */ dup2 (STDERR_FILENO, STDIN_FILENO); } - else if (i > STDIN_FILENO) + else if (i != STDIN_FILENO) { dup2 (i, STDIN_FILENO); close (i); @@ -264,15 +368,10 @@ if (!strcmp (argv[r_argc], "-e")) break; - r_argv = (const char **)rxvt_malloc (sizeof (char *) * (r_argc + 1)); - - for (i = 0; i < r_argc; i++) - r_argv[i] = (const char *)argv[i]; - - r_argv[i] = NULL; - if (r_argc == argc) cmd_argv = NULL; + else if (!argv[r_argc + 1]) + rxvt_fatal ("option '-e' requires an argument, aborting.\n"); else { cmd_argv = (const char **)rxvt_malloc (sizeof (char *) * (argc - r_argc)); @@ -283,6 +382,13 @@ cmd_argv[i] = NULL; } + r_argv = (const char **)rxvt_malloc (sizeof (char *) * (r_argc + 1)); + + for (i = 0; i < r_argc; i++) + r_argv[i] = (const char *)argv[i]; + + r_argv[i] = NULL; + rs[Rs_name] = rxvt_basename (argv[0]); /* @@ -295,7 +401,10 @@ get_options (r_argc, r_argv); if (!(display = displays.get (rs[Rs_display_name]))) - rxvt_fatal ("can't open display %s, aborting.\n", rs[Rs_display_name]); + { + free (r_argv); + rxvt_fatal ("can't open display %s, aborting.\n", rs[Rs_display_name]); + } // using a local pointer decreases code size a lot xa = display->xa; @@ -550,7 +659,7 @@ } - this->locale = rxvt_strdup (this->locale); + this->locale = strdup (this->locale); SET_LOCALE (this->locale); mbstate.reset (); #endif @@ -1346,7 +1455,7 @@ sigprocmask (SIG_SETMASK, &ss, 0); /* command interpreter path */ - if (argv != NULL) + if (argv) { # ifdef DEBUG_CMD int i; @@ -1376,7 +1485,7 @@ argv0 = login; } - execlp (shell, argv0, NULL); + execlp (shell, argv0, (char *)0); /* no error message: STDERR is closed! */ }