273 lines
6.6 KiB
Diff
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 (;;)
|
||
{
|