Files
MSYS2-packages/inetutils/09-inetd.patch
T
2014-12-12 14:42:56 +03:00

273 lines
6.6 KiB
Diff

diff -Naur inetutils-1.9.2-orig/src/inetd.c inetutils-1.9.2/src/inetd.c
--- inetutils-1.9.2-orig/src/inetd.c 2013-12-23 14:57:54.000000000 +0300
+++ inetutils-1.9.2/src/inetd.c 2014-12-12 11:55:11.402400000 +0300
@@ -138,6 +138,13 @@
#include "version-etc.h"
#include "unused-parameter.h"
+#ifdef __CYGWIN__
+#include <windows.h>
+#include <exceptions.h>
+#include <sys/cygwin.h>
+#endif /* __CYGWIN__ */
+
+
#ifndef EAI_ADDRFAMILY
# define EAI_ADDRFAMILY 1
#endif
@@ -151,7 +158,14 @@
#endif
#define SIGBLOCK (sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM))
+enum {
+ NO_DAEMON = 0,
+ UNIX_DAEMON
+};
+
bool debug = false;
+static int daemonize = UNIX_DAEMON;
+
int nsock, maxsock;
fd_set allsock;
int options;
@@ -196,6 +210,13 @@
{"resolve", OPT_RESOLVE, NULL, 0,
"resolve IP addresses when setting environment variables "
"(see --environment)", GRP+1},
+#ifdef __CYGWIN__
+ {0,0,0,0,"Cygwin-specific options:",GRP+2},
+ {"no-daemonize", 'D', NULL, 0,
+ "Do not run as a daemon", GRP+2},
+ {"traditional-daemon", 'T', NULL, 0,
+ "This option is present for backwards compatibility.", GRP+2},
+#endif /* __CYGWIN__ */
#undef GRP
{NULL, 0, NULL, 0, NULL, 0}
};
@@ -237,6 +258,16 @@
resolve_option = true;
break;
+#ifdef __CYGWIN__
+ case 'D': /* don't become a daemon */
+ daemonize = NO_DAEMON;
+ break;
+
+ case 'T': /* act like a normal unix daemon */
+ daemonize = UNIX_DAEMON;
+ break;
+#endif /* __CYGWIN__ */
+
default:
return ARGP_ERR_UNKNOWN;
}
@@ -412,6 +443,44 @@
#endif
}
+#ifdef __CYGWIN__
+void
+hide_console ()
+{
+ HMODULE lib;
+ HWND WINAPI (*GetConsoleWindow) (void) = NULL;
+ HWND console = NULL;
+
+ AllocConsole ();
+ if (lib = LoadLibrary ("kernel32.dll"))
+ GetConsoleWindow = (HWND WINAPI (*) (void))
+ GetProcAddress (lib, "GetConsoleWindow");
+
+ if (GetConsoleWindow)
+ /* If GetConsoleWindow exists (W2K and newer), use it. */
+ console = GetConsoleWindow ();
+ if (!console)
+ {
+ /* Get console window handle as described in KB article Q124103 */
+ char title[32];
+ snprintf (title, 32, "inetd.%d", getpid ());
+ SetConsoleTitle (title);
+ Sleep (40);
+ console = FindWindow (NULL, title);
+ if (console)
+ {
+ char ctitle[256];
+ if (!GetWindowText (console, ctitle, 256) || strcmp (title, ctitle))
+ console = NULL;
+ }
+ }
+ if (console)
+ ShowWindow (console, SW_HIDE);
+}
+#endif /* __CYGWIN__ */
+
+
+
void
run_service (int ctrl, struct servtab *sep)
{
@@ -431,6 +500,10 @@
close (ctrl);
dup2 (0, 1);
dup2 (0, 2);
+#ifdef __CYGWIN__
+ if (strcmp (sep->se_user, "root"))
+ {
+#endif
pwd = getpwnam (sep->se_user);
if (pwd == NULL)
{
@@ -452,14 +525,21 @@
_exit (EXIT_FAILURE);
}
}
+#ifdef __CYGWIN__
+ }
+ else
+ {
+ pwd = getpwuid (getuid ());
+ }
+#endif
if (pwd->pw_uid)
{
if (grp && grp->gr_gid)
{
if (setgid (grp->gr_gid) < 0)
{
- syslog (LOG_ERR, "%s: can't set gid %d: %m",
- sep->se_service, grp->gr_gid);
+ syslog (LOG_ERR, "%s: can't set gid %d uid(%d): %m",
+ sep->se_service, pwd->pw_gid, pwd->pw_uid);
_exit (EXIT_FAILURE);
}
}
@@ -1278,6 +1358,10 @@
}
while ((sep = getconfigent (fconfig, file, &line)))
{
+#ifdef __CYGWIN__
+ if (strcmp (sep->se_user, "root"))
+ {
+#endif
pwd = getpwnam (sep->se_user);
if (pwd == NULL)
{
@@ -1285,6 +1369,9 @@
sep->se_service, sep->se_proto, sep->se_user);
continue;
}
+#ifdef __CYGWIN__
+ }
+#endif
if (sep->se_group && *sep->se_group)
{
grp = getgrnam (sep->se_group);
@@ -1497,10 +1584,48 @@
}
else
snprintf (buf, sizeof buf, "-%s", a);
- strncpy (cp, buf, LastArg - cp);
- cp += strlen (cp);
- while (cp < LastArg)
- *cp++ = ' ';
+
+ /* the non-portable code in the #else block relies on
+ the system allocating all of the strings in argv[]
+ contiguously. On cygwin this is not necessarily so,
+ and to assume otherwise will lead to segfaults.
+ The downside here is we get supposed ps entries for
+ internal services like:
+ '-echo' instead of '-echo [remoteIP]' (okay?)
+ '-char' instead of '-chargen [remoteIP]' (awful)
+ '-disc' instead of '-discard [remoteIP]' (awful)
+ because the original argv[0] might be 'inetd' unless
+ it was specifically invoked with a full path. However,
+ this is mostly moot:
+ (1) cygwin's ps uses its own internal version of the
+ exe name (or GetModuleName) and then calls
+ cygwin_conv_xxx() for display.
+ (2) procps DOES use the modified argv[0] value
+ */
+ {
+#ifdef __CYGWIN__
+ char* LastNullChar = cp + strlen(cp);
+ char** scan;
+#else
+ char* LastNullChar = LastArg;
+#endif
+
+ strncpy (cp, buf, LastNullChar - cp);
+ cp += strlen (cp);
+ while (cp < LastNullChar)
+ *cp++ = ' ';
+
+#ifdef __CYGWIN__
+ /* individually blank out the rest of the args */
+ for (scan = Argv + 1; *scan != NULL; scan++)
+ {
+ char* nullChar = *scan + strlen(*scan);
+ cp = *scan;
+ while (cp < nullChar)
+ *cp++ = ' ';
+ }
+#endif
+ }
}
/*
@@ -1939,6 +2064,16 @@
envp++;
LastArg = envp[-1] + strlen (envp[-1]);
+#ifdef __CYGWIN__
+ /* on cygwin, open the log early -- because even
+ help and cmdline processing messages go directly
+ to syslog. This is because inetd is often run
+ under the SYSTEM account (which is not quite like
+ the *nix 'root')
+ */
+ openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
+#endif
+
/* Parse command line */
iu_argp_init ("inetd", program_authors);
argp_parse (&argp, argc, argv, 0, &index, NULL);
@@ -1962,7 +2097,7 @@
config_files[1] = newstr (PATH_INETDDIR);
}
- if (!debug)
+ if ((debug == 0) && daemonize)
{
if (daemon (0, 0) < 0)
{
@@ -1971,6 +2106,12 @@
exit (EXIT_FAILURE);
};
}
+#ifndef __CYGWIN__
+ exception_list except_list;
+ cygwin_internal (CW_INIT_EXCEPTIONS, &except_list);
+ hide_console ();
+#endif /* __CYGWIN__ */
+
openlog ("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
@@ -1995,6 +2136,7 @@
signal_set_handler (SIGCHLD, reapchild);
signal_set_handler (SIGPIPE, SIG_IGN);
+#ifndef __CYGWIN__
{
/* space for daemons to overwrite environment for ps */
#define DUMMYSIZE 100
@@ -2004,6 +2146,7 @@
dummy[DUMMYSIZE - 1] = '\0';
setenv ("inetd_dummy", dummy, 1);
}
+#endif /* __CYGWIN__ */
for (;;)
{