Esempio n. 1
0
/**
 * Forks the current process in the context of the LDM.  Does whatever's
 * necessary before and after the fork to ensure correct behavior.  Terminates
 * the child process if the fork() was successful but an error occurs.
 *
 * @retval -1  Failure. "log_add()" called.
 * @retval  0  Success. The calling process is the child.
 * @return              PID of child process. The calling process is the parent.
 */
pid_t ldmfork(void)
{
    pid_t       pid;

    if (reg_close()) {
        pid = -1;
    }
    else {
        pid = fork();

        if (0 == pid) {
            log_clear(); // So child process starts with no queued messages
            /* Child process */
        }
        else if (-1 == pid) {
            /* System error */
            log_syserr("Couldn't fork a child process");
        }
    }

    return pid;
}
Esempio n. 2
0
File: ldmd.c Progetto: dgaer/LDM
/*
 * Called at exit.
 * This callback routine registered by atexit().
 */
static void cleanup(
        void)
{
    const char* const pqfname = getQueuePath();

    unotice("Exiting");

    lcf_savePreviousProdInfo();

    free_remote_clss();

    /*
     * Ensure release of COMINGSOON-reserved space in product-queue.
     */
    clr_pip_5();
    down6_destroy();

    /*
     * Close product-queue.
     */
    if (pq) {
        (void) pq_close(pq);
        pq = NULL;
    }

    /*
     * Ensure that this process has no entry in the upstream LDM database and
     * that the database is closed.
     */
    (void) uldb_remove(getpid());
    (void) uldb_close();
    log_clear();

    if (getpid() == getpgrp()) {
        /*
         * This process is the process group leader (i.e., the top-level
         * LDM server).
         */
        if (portIsMapped) {
            int vers;

            /*
             * Superuser privileges might be required to unmap the
             * port on which the LDM is listening.
             */
            rootpriv();

            for (vers = MIN_LDM_VERSION; vers <= MAX_LDM_VERSION; vers++) {
                if (!pmap_unset(LDMPROG, vers))
                    uerror("pmap_unset(LDMPROG %lu, LDMVERS %lu) "
                            "failed", LDMPROG, vers);
                else
                    portIsMapped = 0;
            }

            unpriv();
        }

        /*
         * Terminate all child processes.
         */
        {
            /*
             * Ignore the signal I'm about to send my process group.
             */
            struct sigaction sigact;

            (void) sigemptyset(&sigact.sa_mask);
            sigact.sa_flags = 0;
            sigact.sa_handler = SIG_IGN;
            (void) sigaction(SIGTERM, &sigact, NULL );
        }

        /*
         * Signal my process group.
         */
        unotice("Terminating process group");
        (void) kill(0, SIGTERM);

        while (reap(-1, 0) > 0)
            ; /*empty*/

        /*
         * Delete the upstream LDM database.
         */
        (void) uldb_delete(NULL);

#if WANT_MULTICAST
        /*
         * Destroy the multicast LDM sender map.
         */
        msm_destroy();
#endif
    }

    /*
     * Free access-control-list resources.
     */
    lcf_free();

    /*
     * Close registry.
     */
    if (reg_close())
        log_log(LOG_ERR);

    /*
     * Terminate logging.
     */
    (void) closeulog();
}
Esempio n. 3
0
int
main (int argc, char **argv)
{
  BOOL ret;
  HKEY hkey, skey;
  WCHAR keyname[256], stdname[256], std2name[256], country[10], *spc;
  GEOID geo;
  int opt, idx, gotit = -1;

  setlocale (LC_ALL, "");
  while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
    switch (opt)
      {
      case 'h':
	usage (stdout);
	return 0;
      case 'V':
	print_version ();
	return 0;
      default:
	fprintf (stderr, "Try `%s --help' for more information.\n",
		 program_invocation_short_name);
	return 1;
      }
  if (optind < argc)
    {
	usage (stderr);
	return 1;
    }

  /* First fetch current timezone information from registry. */
  hkey = reg_open (HKEY_LOCAL_MACHINE, REG_TZINFO, "timezone information");
  if (!hkey)
    return 1;
  /* Vista introduced the TimeZoneKeyName value, which simplifies the
     job a lot. */
  if (!reg_query (hkey, L"TimeZoneKeyName", keyname, sizeof keyname, NULL))
    {
      /* Pre-Vista we have a lot more to do.  First fetch the name of the
	 Standard (non-DST) timezone.  If we can't get that, give up. */
      if (!reg_query (hkey, L"StandardName", stdname, sizeof stdname,
		      "timezone information"))
	{
	  reg_close (hkey);
	  return 1;
	}
      reg_close (hkey);
      /* Now open the timezone database registry key.  Every subkey is a
         timezone.  The key name is what we're after, but to find the right
	 one, we have to compare the name of the previously fetched
	 "StandardName" with the "Std" value in the timezone info... */
      hkey = reg_open (HKEY_LOCAL_MACHINE, REG_TZDB, "timezone database");
      if (!hkey)
	return 1;
      for (idx = 0; reg_enum (hkey, idx, keyname, sizeof keyname); ++idx)
	{
	  skey = reg_open (hkey, keyname, NULL);
	  if (skey)
	    {
	      /* ...however, on MUI-enabled machines, the names are not stored
		 directly in the above StandardName, rather it is a resource
		 pointer into tzres.dll.  This is stored in MUI_Std.
		 Fortunately it's easy to recognize this situation: If
		 StandardName starts with @, it's a resource pointer, otherwise
		 it's the cleartext value. */
	      ret = reg_query (skey, stdname[0] == L'@' ? L"MUI_Std" : L"Std",
			       std2name, sizeof std2name, NULL);
	      reg_close (skey);
	      if (ret && !wcscmp (stdname, std2name))
		break;
	    }
	}
    }
  reg_close (hkey);

  /* We fetch the current Geo-location of the user and convert it to an
     ISO 3166-1 compatible nation code. */
  *country = L'\0';
  geo = GetUserGeoID (GEOCLASS_NATION);
  if (geo != GEOID_NOT_AVAILABLE)
    GetGeoInfoW (geo, GEO_ISO2, country, sizeof country, 0);
  /* If, for some reason, the Geo-location isn't available, we use the locale
     setting instead. */
  if (!*country)
    GetLocaleInfoW (LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME,
		    country, sizeof country);

  /* Now iterate over the mapping table and find the right entry. */
  for (idx = 0; idx < TZMAP_SIZE; ++idx)
    {
      if (!wcscmp (keyname, tzmap[idx].win_tzkey))
	{
	  if (gotit < 0)
	    gotit = idx;
	  if (!wcscmp (country, tzmap[idx].country))
	    break;
	}
      else if (gotit >= 0)
	{
	  idx = gotit;
	  break;
	}
    }
  if (idx >= TZMAP_SIZE)
    {
      if (gotit < 0)
	{
	  fprintf (stderr,
		   "%s: can't find matching POSIX timezone for "
		   "Windows timezone \"%ls\"\n",
		   program_invocation_short_name, keyname);
	  return 1;
	}
      idx = gotit;
    }
  /* Got one.  Print it.
     Note: The tzmap array is in the R/O data section on x86_64.  Don't
           try to overwrite the space, as the code did originally. */
  spc = wcschr (tzmap[idx].posix_tzid, L' ');
  if (!spc)
    spc = wcschr (tzmap[idx].posix_tzid, L'\0');
  printf ("%.*ls\n", (int) (spc - tzmap[idx].posix_tzid), tzmap[idx].posix_tzid);
  return 0;
}