This is the mail archive of the cygwin-apps@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

patch to add --dep to cygrunsrv


The attached patch adds a --dep option to cygrunsrv allowing the user to
name other services that the service depends on.  The NT service manager
will attempt to start those other services first.  For example, the
PostgreSQL service depends in ipc-daemon running first.

-- 
Fred Yankowski           fred@OntoSys.com      tel: +1.630.879.1312
Principal Consultant     www.OntoSys.com       fax: +1.630.879.1370
OntoSys, Inc             38W242 Deerpath Rd, Batavia, IL 60510, USA
Index: cygrunsrv.cc
===================================================================
RCS file: /home/cvs/cvsroot/src/cygrunsrv/cygrunsrv.cc,v
retrieving revision 1.3
diff -u -p -r1.3 cygrunsrv.cc
--- cygrunsrv.cc	2001/05/21 11:47:32	1.3
+++ cygrunsrv.cc	2001/05/21 17:25:25
@@ -58,12 +58,13 @@ struct option longopts[] = {
   { "passwd", required_argument, NULL, 'w' },
   { "type", required_argument, NULL, 't' },
   { "termsig", required_argument, NULL, 's' },
+  { "dep", required_argument, NULL, 'y' },
   { "help", no_argument, NULL, 'h' },
   { "version", no_argument, NULL, 'v' },
   { 0, no_argument, NULL, 0 }
 };
 
-char *opts = "I:R:S:E:p:a:e:d:u:w:t:s:hv";
+char *opts = "I:R:S:E:p:a:e:d:u:w:t:s:y:hv";
 
 char *appname;
 char *svcname;
@@ -300,6 +301,23 @@ add_env_var (char *envstr, env_t *&env)
   			    " environment variables allowed");
 }
 
+int
+add_dep(char *service_name, char **&deps)
+{
+  if (!service_name)
+    return error(InstallErr, "NULL dependency name not allowed");
+  if (!deps && !(deps = (char **) calloc(MAX_DEPS + 1, sizeof(char *))))
+    return error(InstallErr, "Out of memory");
+  for (int i = 0; i <= MAX_DEPS; ++i)
+    if (! deps[i])
+      {
+	if (! (deps[i] = strdup(service_name)))
+	  return error(InstallErr, "Out of memory");
+	return 0;
+      }
+  return error(InstallErr, "Only " MAX_DEPS_STR " dependency values allowed");
+}
+
 /* The strings `path' and `args' are evaluated to an arglist which
    can be used as `argv' argument to execv. It's splitted at the
    spaces. One level of " or ' quotes are supported as well. */
@@ -347,7 +365,7 @@ eval_arglist (const char *path, char *ar
 /* Installs cygrunsrv as service `name' with display name `disp'. */
 int
 install_service (const char *name, const char *disp, type_t type,
-		 char *user, char *pass)
+		 char *user, char *pass, char **deps)
 {
   char mypath[MAX_PATH];
   SC_HANDLE sm = (SC_HANDLE) 0;
@@ -355,6 +373,7 @@ install_service (const char *name, const
   SC_LOCK sl = (SC_LOCK) 0;
   char userbuf[INTERNET_MAX_HOST_NAME_LENGTH + UNLEN + 2];
   char *username = NULL;
+  char *dependencies = NULL;
   char *err_func;
   DWORD err = 0;
 
@@ -376,6 +395,29 @@ install_service (const char *name, const
       SetLastError (ERROR_SERVICE_EXISTS);
       err_out (OpenService);
     }
+  /* Set optional dependencies. */
+  if (deps)
+    {
+      int concat_length = 0;
+      for (int i = 0; i < MAX_DEPS && deps[i]; i++)
+	concat_length += (strlen(deps[i]) + 1);
+      concat_length++;
+      if (! (dependencies = (char *) malloc(concat_length)))
+	{
+	  SetLastError(ERROR_OUTOFMEMORY);
+	  err_out(malloc);
+	}
+      char *p = dependencies;
+      for (int i = 0; i < MAX_DEPS && deps[i]; i++)
+	{
+	  strcpy(p, deps[i]);
+	  p += (strlen(deps[i]) + 1);
+	}
+      *p = '\0';
+      /* dependencies now holds the concatenation of all the
+         dependent service names, each terminated by a null and the
+         whole thing terminated by a final null. */
+    }
   /* Check username. */
   if (user)
     {
@@ -434,7 +476,8 @@ install_service (const char *name, const
 			    SERVICE_WIN32_OWN_PROCESS,
 			    type == Auto ? SERVICE_AUTO_START
 			    		 : SERVICE_DEMAND_START,
-			    SERVICE_ERROR_NORMAL, mypath, NULL, NULL, NULL,
+			    SERVICE_ERROR_NORMAL, mypath, NULL, NULL,
+			    dependencies,
 			    username, username ? pass ?: "" : NULL)))
     err_out (CreateService);
 
@@ -879,6 +922,7 @@ main (int argc, char **argv)
   char *in_user = NULL;
   char *in_pass = NULL;
   int in_termsig = 0;
+  char **in_deps = 0;
 
   appname = argv[0];
 
@@ -992,6 +1036,12 @@ main (int argc, char **argv)
 	  return error (OnlyOnePass);
 	in_pass = optarg;
 	break;
+      case 'y':
+	if (action != Install)
+	  return error (DepNotAllowed);
+	if (add_dep(optarg, in_deps))
+	  return 1;
+	break;
       case 'h':
 	return usage ();
       case 'v':
@@ -1014,7 +1064,7 @@ main (int argc, char **argv)
         in_type = Auto;
       if (!is_executable (in_path))
         return error (InvalidPath);
-      if (ret = install_service (in_name, in_disp, in_type, in_user, in_pass))
+      if (ret = install_service (in_name, in_disp, in_type, in_user, in_pass, in_deps))
         return ret;
       if (ret = install_registry_keys (in_name, in_path, in_args, in_env, in_termsig))
         remove_service (in_name);
Index: cygrunsrv.h
===================================================================
RCS file: /home/cvs/cvsroot/src/cygrunsrv/cygrunsrv.h,v
retrieving revision 1.3
diff -u -p -r1.3 cygrunsrv.h
--- cygrunsrv.h	2001/05/21 11:47:32	1.3
+++ cygrunsrv.h	2001/05/21 17:25:25
@@ -31,6 +31,9 @@
 #define MAX_ENV		255
 #define MAX_ENV_STR	"255"
 
+#define MAX_DEPS	16
+#define MAX_DEPS_STR	"16"
+
 extern char *appname;
 extern char *svcname;
 
Index: utils.cc
===================================================================
RCS file: /home/cvs/cvsroot/src/cygrunsrv/utils.cc,v
retrieving revision 1.2
diff -u -p -r1.2 utils.cc
--- utils.cc	2001/05/18 21:15:57	1.2
+++ utils.cc	2001/05/21 17:25:25
@@ -50,6 +50,7 @@ char *reason_list[] = {
   "--termsig is only allowed with --install",
   "Only one --termsig is allowed",
   "Invalid signal; must be number or name like INT, QUIT, TERM, etc.",
+  "--dep is only allowed with --install",
   "Trailing commandline arguments not allowed",
   "You must specify one of the `-IRSE' options",
   "Error installing a service",
@@ -140,6 +141,10 @@ usage ()
   uprint ("                            when service is stopped.  <signal> can be a number");
   uprint ("                            or a signal name such as HUP, INT, QUIT, etc.");
   uprint ("                            Default is TERM.");
+  uprint ("  -y, --dep <svc_name2>     Optional name of service that must be started");
+  uprint ("                            before this new service.  The --dep option may");
+  uprint ("                            up to " MAX_DEPS_STR " times, listing another dependent");
+  uprint ("                            service each time.");
   uprint ("\nInformative output:");
   uprint ("  -h, --help                print this help, then exit.");
   uprint ("  -v, --version             print cygrunsrv program version number, then exit.");
Index: utils.h
===================================================================
RCS file: /home/cvs/cvsroot/src/cygrunsrv/utils.h,v
retrieving revision 1.2
diff -u -p -r1.2 utils.h
--- utils.h	2001/05/18 21:15:57	1.2
+++ utils.h	2001/05/21 17:25:25
@@ -43,6 +43,7 @@ enum reason_t {
   SigNotAllowed,
   OnlyOneSig,
   InvalidSig,
+  DepNotAllowed,
   TrailingArgs,
   StartAsSvcErr,
   InstallErr,
2001-05-21  Fred Yankowski  <fred@ontosys.com>

	* utils.cc (reason_list): Add error strings for --dep errors.
	(usage): Add help text for --dep.
	* utils.h (reason_t): Add codes for --dep errors.
	* cygrunsrv.h (MAX_DEPS): Number of --dep values allowed.
	(MAX_DEPS_STR): String value of MAX_DEPS.
	* cygrunsrv.cc (install_service): Create service with optional
	dependencies.
	(add_dep): New function to save --dep command-line value.
	(main): Handle --dep option.
	(longopts): Add '--dep' option.
	(opts): Add 'y' option.

2001-05-21  Corinna Vinschen <corinna@vinschen.de>

	* cygrunsrv.cc (install_registry_keys): Create environment strings in
	subkey "Environment" now.
	(get_reg_entries): Read environment strings from subkey "Environment"
	now.
	(add_env_var): Drop test for illegal environment string names
	"AppPath" and "AppArgs".
	* cygrunsrv.h (PARAM_ENVIRON): New registry name for environment
	string subkey.

2001-05-18  Fred Yankowski  <fred@ontosys.com>

	* utils.cc (usage): Add help for --termsig option.
	(reason_list):  Add error strings for wrong --termsig usage.
	* cygrunsrv.cc (get_reg_entries): Get --termsig value from registry.
	(service_main): Set up global termsig value.
	(terminate_child): Send termsig signal to server process.
	(termsig):  Create new global variable to hold --termsig value.
	(install_registry_keys): Save --termsig value.
	(longopts): Add '--termsig' option.
	(opts): Add 's' option.
	(main): Handle '--termsig' option.
	* cygrunsrv.h (PARAM_TERMSIG): New registry name for --termsig value.
	* utils.h (reason_t): Add codes for '--termsig' errors.

2001-05-11  Corinna Vinschen <corinna@vinschen.de>

	* utils.cc: New file. Move several functions from cygrunsrv.cc to here.
	* utils.h: Ditto.
	(reason_t): Add error codes for wrong --type usage.
	* utils.cc (winerror): New function providing strerror functionality for
	Win32 errors.
	(reason_list): Add error strings for wrong --type usage.
	(error): Add windows error message text to error output.
	(syslog_starterr): New function.
	* cygrunsrv.cc (longopts): Add `--type' option.
	(opts): Add `t' option.
	(type_t): New type.
	(usage): Add help for `--type' option.
	(install_service): Add parameter for service start type.
	(service_main): Use syslog_starterr function.
	(main): Add handling for `--type' option.
	* Bump version to 0.92.

2001-05-10  Corinna Vinschen <corinna@vinschen.de>

	* (get_reg_entries): Fix memory usage.
	* (install_service): Add interactive password request if password
	is omitted.
	* Control access to SERVICE_STATUS by using a critical section.
	Move access functions to new file crit.cc. Declare access functions
	in crit.h.
	* Bump version to 0.91.

2001-05-09  Corinna Vinschen <corinna@vinschen.de>

	* Initial version 0.9.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]