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 (;;)
|
|
{
|