TS-2977: rename traffic_manager Main.cc

Rename traffic_manager's Main.cc to traffic_manager.cc. Remove
Main.h, retaining just the 2 or 3 things from it that are used.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ab8c0cd2
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ab8c0cd2
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ab8c0cd2

Branch: refs/heads/master
Commit: ab8c0cd21a0ab6e832e969f006ace578661c4d47
Parents: ff716f2
Author: James Peach <jpe...@apache.org>
Authored: Thu Jul 31 14:20:39 2014 -0700
Committer: James Peach <jpe...@apache.org>
Committed: Fri Aug 1 19:55:45 2014 -0700

----------------------------------------------------------------------
 cmd/traffic_manager/AddConfigFilesHere.cc |    4 +-
 cmd/traffic_manager/Main.cc               | 1198 -----------------------
 cmd/traffic_manager/Main.h                |   53 --
 cmd/traffic_manager/Makefile.am           |    3 +-
 cmd/traffic_manager/StatType.h            |    1 -
 cmd/traffic_manager/traffic_manager.cc    | 1202 ++++++++++++++++++++++++
 6 files changed, 1206 insertions(+), 1255 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/AddConfigFilesHere.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/AddConfigFilesHere.cc 
b/cmd/traffic_manager/AddConfigFilesHere.cc
index cc6d169..bfed735 100644
--- a/cmd/traffic_manager/AddConfigFilesHere.cc
+++ b/cmd/traffic_manager/AddConfigFilesHere.cc
@@ -22,10 +22,12 @@
  */
 
 #include "ink_platform.h"
-#include "Main.h"
 #include "MgmtUtils.h"
 #include "ConfigParse.h"
 #include "Diags.h"
+#include "FileManager.h"
+
+extern FileManager *configFiles;
 
 /****************************************************************************
  *

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/Main.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Main.cc b/cmd/traffic_manager/Main.cc
deleted file mode 100644
index 8d80a24..0000000
--- a/cmd/traffic_manager/Main.cc
+++ /dev/null
@@ -1,1198 +0,0 @@
-/** @file
-
-  Entry point to the traffic manager.
-
-  @section license License
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
- */
-
-#include "libts.h"
-#include "ink_sys_control.h"
-
-#include "Main.h"
-#include "MgmtUtils.h"
-#include "WebMgmtUtils.h"
-#include "WebIntrMain.h"
-#include "WebOverview.h"
-#include "ClusterCom.h"
-#include "VMap.h"
-#include "FileManager.h"
-#include "I_Layout.h"
-#include "I_Version.h"
-#include "Diags.h"
-#include "DiagsConfig.h"
-#include "URL.h"
-#include "MIME.h"
-#include "HTTP.h"
-
-// Needs LibRecordsConfigInit()
-#include "RecordsConfig.h"
-
-#include "StatProcessor.h"
-#include "P_RecLocal.h"
-#include "P_RecCore.h"
-
-#if TS_USE_POSIX_CAP
-#include <sys/capability.h>
-#endif
-#include <grp.h>
-
-#define FD_THROTTLE_HEADROOM (128 + 64) // TODO: consolidate with 
THROTTLE_FD_HEADROOM
-#define DIAGS_LOG_FILENAME "manager.log"
-
-#if defined(freebsd)
-extern "C" int getpwnam_r(const char *name, struct passwd *result, char 
*buffer, size_t buflen, struct passwd **resptr);
-#endif
-
-static void extractConfigInfo(char *mgmt_path, const char *recs_conf, char 
*userName, int *fds_throttle);
-
-LocalManager *lmgmt = NULL;
-FileManager *configFiles;
-
-StatProcessor *statProcessor;   // Statistics Processors
-AppVersionInfo appVersionInfo;  // Build info for this application
-
-static inkcoreapi DiagsConfig *diagsConfig;
-static char debug_tags[1024] = "";
-static char action_tags[1024] = "";
-static bool proxy_on = true;
-
-char mgmt_path[PATH_NAME_MAX + 1];
-
-// By default, set the current directory as base
-static const char *recs_conf = "records.config";
-
-static int fds_limit;
-
-// TODO: Use positive instead negative selection
-//       Thsis should just be #if defined(solaris)
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-static void SignalHandler(int sig, siginfo_t * t, void *f);
-static void SignalAlrmHandler(int sig, siginfo_t * t, void *f);
-#else
-static void SignalHandler(int sig);
-static void SignalAlrmHandler(int sig);
-#endif
-
-static volatile int sigHupNotifier = 0;
-static volatile int sigUsr2Notifier = 0;
-static void SigChldHandler(int sig);
-
-static void
-check_lockfile()
-{
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  char lockfile[PATH_NAME_MAX];
-  int err;
-  pid_t holding_pid;
-
-  //////////////////////////////////////
-  // test for presence of server lock //
-  //////////////////////////////////////
-  Layout::relative_to(lockfile, sizeof(lockfile), rundir, SERVER_LOCK);
-  Lockfile server_lockfile(lockfile);
-  err = server_lockfile.Open(&holding_pid);
-  if (err == 1) {
-    server_lockfile.Close();    // no server running
-  } else {
-    char *reason = strerror(-err);
-    if (err == 0) {
-      // TODO: Add PID_FMT_T instead duplicating code just for printing
-#if defined(solaris)
-      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID 
%d\n", lockfile, (int)holding_pid);
-#else
-      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID 
%d\n", lockfile, holding_pid);
-#endif
-      mgmt_elog(stderr, 0, "FATAL: Lockfile '%s' says server already running 
as PID %d\n", lockfile, holding_pid);
-    } else {
-      fprintf(stderr, "FATAL: Can't open server lockfile '%s' (%s)\n", 
lockfile, (reason ? reason : "Unknown Reason"));
-      mgmt_elog(stderr, 0, "FATAL: Can't open server lockfile '%s' (%s)\n",
-                lockfile, (reason ? reason : "Unknown Reason"));
-    }
-    exit(1);
-  }
-
-  ///////////////////////////////////////////
-  // try to get the exclusive manager lock //
-  ///////////////////////////////////////////
-  Layout::relative_to(lockfile, sizeof(lockfile), rundir, MANAGER_LOCK);
-  Lockfile manager_lockfile(lockfile);
-  err = manager_lockfile.Get(&holding_pid);
-  if (err != 1) {
-    char *reason = strerror(-err);
-    fprintf(stderr, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
-    mgmt_elog(stderr, 0, "FATAL: Can't acquire manager lockfile '%s'", 
lockfile);
-    if (err == 0) {
-#if defined(solaris)
-      fprintf(stderr, " (Lock file held by process ID %d)\n", 
(int)holding_pid);
-#else
-      fprintf(stderr, " (Lock file held by process ID %d)\n", holding_pid);
-#endif
-      mgmt_elog(stderr, 0, " (Lock file held by process ID %d)\n", 
holding_pid);
-    } else if (reason) {
-      fprintf(stderr, " (%s)\n", reason);
-      mgmt_elog(stderr, 0, " (%s)\n", reason);
-    } else {
-      fprintf(stderr, "\n");
-    }
-    exit(1);
-
-    fprintf(stderr, "unable to acquire manager lock [%d]\n", -err);
-    exit(1);
-  }
-}
-
-static void
-initSignalHandlers()
-{
-  struct sigaction sigHandler, sigChldHandler, sigAlrmHandler;
-  sigset_t sigsToBlock;
-
-  // Set up the signal handler
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigHandler.sa_handler = NULL;
-  sigHandler.sa_sigaction = SignalHandler;
-#else
-  sigHandler.sa_handler = SignalHandler;
-#endif
-  sigemptyset(&sigHandler.sa_mask);
-
-  // We want the handler to remain in place on
-  //  SIGHUP to avoid any races with the signals
-  //  coming too quickly.  Also restart systems calls
-  //  after the signal since not all calls are wrapped
-  //  to check errno for EINTR
-  sigHandler.sa_flags = SA_RESTART;
-  sigaction(SIGHUP, &sigHandler, NULL);
-  sigaction(SIGUSR2, &sigHandler, NULL);
-
-  // Don't block the signal on entry to the signal
-  //   handler so we can reissue it and get a core
-  //   file in the appropriate circumstances
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigHandler.sa_flags = SA_RESETHAND | SA_SIGINFO;
-#else
-  sigHandler.sa_flags = SA_RESETHAND;
-#endif
-  sigaction(SIGINT, &sigHandler, NULL);
-  sigaction(SIGQUIT, &sigHandler, NULL);
-  sigaction(SIGILL, &sigHandler, NULL);
-  sigaction(SIGBUS, &sigHandler, NULL);
-  sigaction(SIGSEGV, &sigHandler, NULL);
-  sigaction(SIGTERM, &sigHandler, NULL);
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigAlrmHandler.sa_handler = NULL;
-  sigAlrmHandler.sa_sigaction = SignalAlrmHandler;
-#else
-  sigAlrmHandler.sa_handler = SignalAlrmHandler;
-#endif
-
-  sigemptyset(&sigAlrmHandler.sa_mask);
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigAlrmHandler.sa_flags = SA_SIGINFO;
-#else
-  sigAlrmHandler.sa_flags = 0;
-#endif
-  sigaction(SIGALRM, &sigAlrmHandler, NULL);
-
-  // Block the delivery of any signals we are not catching
-  //
-  //  except for SIGALARM since we use it
-  //    to break out of deadlock on semaphore
-  //    we share with the proxy
-  //
-  sigfillset(&sigsToBlock);
-  sigdelset(&sigsToBlock, SIGHUP);
-  sigdelset(&sigsToBlock, SIGUSR2);
-  sigdelset(&sigsToBlock, SIGINT);
-  sigdelset(&sigsToBlock, SIGQUIT);
-  sigdelset(&sigsToBlock, SIGILL);
-  sigdelset(&sigsToBlock, SIGABRT);
-  sigdelset(&sigsToBlock, SIGBUS);
-  sigdelset(&sigsToBlock, SIGSEGV);
-  sigdelset(&sigsToBlock, SIGTERM);
-  sigdelset(&sigsToBlock, SIGALRM);
-  ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
-
-  // Set up the SIGCHLD handler so we do not get into
-  //   a problem with Solaris 2.6 and strange waitpid()
-  //   behavior
-  sigChldHandler.sa_handler = SigChldHandler;
-  sigChldHandler.sa_flags = SA_RESTART;
-  sigemptyset(&sigChldHandler.sa_mask);
-  sigaction(SIGCHLD, &sigChldHandler, NULL);
-}
-
-#if defined(linux)
-#include <sys/prctl.h>
-#endif
-static int
-setup_coredump()
-{
-#if defined(linux)
-#ifndef PR_SET_DUMPABLE
-#define PR_SET_DUMPABLE 4       /* Ugly, but we cannot compile with 2.2.x 
otherwise.
-                                   Should be removed when we compile only on 
2.4.x */
-#endif
-  prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
-#endif  // linux check
-  return 0;
-}
-
-static void
-init_dirs()
-{
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-
-  if (access(Layout::get()->sysconfdir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() config dir '%s': %d, %s\n", 
Layout::get()->sysconfdir, errno, strerror(errno));
-    mgmt_elog(0, "please set the 'TS_ROOT' environment variable\n");
-    _exit(1);
-  }
-
-  if (access(rundir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() local state dir '%s': %d, %s\n", (const 
char *)rundir, errno, strerror(errno));
-    mgmt_elog(0, "please set 'proxy.config.local_state_dir'\n");
-    _exit(1);
-  }
-}
-
-static void
-chdir_root()
-{
-  const char * prefix = Layout::get()->prefix;
-
-  if (chdir(prefix) < 0) {
-    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", 
prefix, errno, strerror(errno));
-    mgmt_elog(0, " please set correct path in env variable TS_ROOT \n");
-    exit(1);
-  } else {
-    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix);
-  }
-}
-
-static void
-set_process_limits(int fds_throttle)
-{
-  struct rlimit lim;
-
-  // Set needed rlimits (root)
-  ink_max_out_rlimit(RLIMIT_NOFILE, true, false);
-  ink_max_out_rlimit(RLIMIT_STACK, true, true);
-  ink_max_out_rlimit(RLIMIT_DATA, true, true);
-  ink_max_out_rlimit(RLIMIT_FSIZE, true, false);
-#ifdef RLIMIT_RSS
-  ink_max_out_rlimit(RLIMIT_RSS, true, true);
-#endif
-
-#if defined(linux)
-  float file_max_pct = 0.9;
-  FILE *fd;
-
-  if ((fd = fopen("/proc/sys/fs/file-max","r"))) {
-    ATS_UNUSED_RETURN(fscanf(fd, "%lu", &lim.rlim_max));
-    fclose(fd);
-    REC_ReadConfigFloat(file_max_pct, "proxy.config.system.file_max_pct");
-    lim.rlim_cur = lim.rlim_max = static_cast<rlim_t>(lim.rlim_max * 
file_max_pct);
-    if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
-      fds_limit = (int) lim.rlim_cur;
-      syslog(LOG_NOTICE, "NOTE: 
RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, 
(int)lim.rlim_max);
-    } else {
-      syslog(LOG_NOTICE, "NOTE: Unable to set 
RLIMIT_NOFILE(%d):cur(%d),max(%d)", RLIMIT_NOFILE, (int)lim.rlim_cur, 
(int)lim.rlim_max);
-    }
-  } else {
-    syslog(LOG_NOTICE, "NOTE: Unable to open /proc/sys/fs/file-max");
-  }
-#endif // linux
-
-  if (!getrlimit(RLIMIT_NOFILE, &lim)) {
-    if (fds_throttle > (int) (lim.rlim_cur + FD_THROTTLE_HEADROOM)) {
-      lim.rlim_cur = (lim.rlim_max = (rlim_t) fds_throttle);
-      if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
-        fds_limit = (int) lim.rlim_cur;
-       syslog(LOG_NOTICE, "NOTE: 
RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, 
(int)lim.rlim_max);
-      }
-    }
-  }
-
-}
-
-#if TS_HAS_WCCP
-static void
-Errata_Logger(ts::Errata const& err) {
-  size_t n;
-  static size_t const SIZE = 4096;
-  char buff[SIZE];
-  if (err.size()) {
-    ts::Errata::Code code = err.top().getCode();
-    n = err.write(buff, SIZE, 1, 0, 2, "> ");
-    // strip trailing newlines.
-    while (n && (buff[n-1] == '\n' || buff[n-1] == '\r'))
-      buff[--n] = 0;
-    // log it.
-    if (code > 1) mgmt_elog(0, "[WCCP]%s", buff);
-    else if (code > 0) mgmt_log("[WCCP]%s", buff);
-    else Debug("WCCP", "%s", buff);
-  }
-}
-
-static void
-Init_Errata_Logging() {
-  ts::Errata::registerSink(&Errata_Logger);
-}
-#endif
-
-int
-main(int argc, char **argv)
-{
-  // Before accessing file system initialize Layout engine
-  Layout::create();
-  ink_strlcpy(mgmt_path, Layout::get()->sysconfdir, sizeof(mgmt_path));
-
-  // change the directory to the "root" directory
-  chdir_root();
-
-  // Line buffer standard output & standard error
-  int status;
-  status = setvbuf(stdout, NULL, _IOLBF, 0);
-  if (status != 0)
-    perror("WARNING: can't line buffer stdout");
-  status = setvbuf(stderr, NULL, _IOLBF, 0);
-  if (status != 0)
-    perror("WARNING: can't line buffer stderr");
-
-  bool found = false;
-  int just_started = 0;
-  int cluster_mcport = -1, cluster_rsport = -1;
-  // TODO: This seems completely incomplete, disabled for now
-  //  int dump_config = 0, dump_process = 0, dump_node = 0, dump_cluster = 0, 
dump_local = 0;
-  char* proxy_port = 0;
-  int proxy_backdoor = -1;
-  char *envVar = NULL, *group_addr = NULL, *tsArgs = NULL;
-  bool log_to_syslog = true;
-  char userToRunAs[80];
-  int  fds_throttle = -1;
-  time_t ticker;
-  ink_thread webThrId;
-
-  // Set up the application version info
-  appVersionInfo.setup(PACKAGE_NAME,"traffic_manager", PACKAGE_VERSION,
-                       __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
-  initSignalHandlers();
-
-  // Process Environment Variables
-  if ((envVar = getenv("MGMT_ACONF_PORT")) != NULL) {
-    aconf_port_arg = atoi(envVar);
-  }
-
-  if ((envVar = getenv("MGMT_CLUSTER_MC_PORT")) != NULL) {
-    cluster_mcport = atoi(envVar);
-  }
-
-  if ((envVar = getenv("MGMT_CLUSTER_RS_PORT")) != NULL) {
-    cluster_rsport = atoi(envVar);
-  }
-
-  if ((envVar = getenv("MGMT_GROUP_ADDR")) != NULL) {
-    group_addr = envVar;
-  }
-
-  for (int i = 1; i < argc; i++) {      /* Process command line args */
-
-    if (argv[i][0] == '-') {
-      if ((strcmp(argv[i], "-version") == 0) || (strcmp(argv[i], "-V") == 0)) {
-        fprintf(stderr, "%s\n", appVersionInfo.FullVersionInfoStr);
-        exit(0);
-      } else if (strcmp(argv[i], "-proxyOff") == 0) {
-        proxy_on = false;
-      } else if (strcmp(argv[i], "-nosyslog") == 0) {
-        log_to_syslog = false;
-      } else {
-        // The rest of the options require an argument in the form of -<Flag> 
<val>
-        if ((i + 1) < argc) {
-
-          if (strcmp(argv[i], "-aconfPort") == 0) {
-            ++i;
-            aconf_port_arg = atoi(argv[i]);
-          } else if (strcmp(argv[i], "-clusterMCPort") == 0) {
-            ++i;
-            cluster_mcport = atoi(argv[i]);
-          } else if (strcmp(argv[i], "-groupAddr") == 0) {
-            ++i;
-            group_addr = argv[i];
-          } else if (strcmp(argv[i], "-clusterRSPort") == 0) {
-            ++i;
-            cluster_rsport = atoi(argv[i]);
-#if TS_USE_DIAGS
-          } else if (strcmp(argv[i], "-debug") == 0) {
-            ++i;
-            ink_strlcpy(debug_tags, argv[i], sizeof(debug_tags));
-          } else if (strcmp(argv[i], "-action") == 0) {
-            ++i;
-            ink_strlcpy(action_tags, argv[i], sizeof(debug_tags));
-#endif
-          } else if (strcmp(argv[i], "-path") == 0) {
-            ++i;
-            //bugfixed by YTS Team, yamsat(id-59703)
-            if ((strlen(argv[i]) > PATH_NAME_MAX)) {
-              fprintf(stderr, "\n   Path exceeded the maximum allowed 
characters.\n");
-              exit(1);
-            }
-
-            ink_strlcpy(mgmt_path, argv[i], sizeof(mgmt_path));
-            /*
-               } else if(strcmp(argv[i], "-lmConf") == 0) {
-               ++i;
-               lm_conf = argv[i];
-             */
-          } else if (strcmp(argv[i], "-recordsConf") == 0) {
-            ++i;
-            recs_conf = argv[i];
-            // TODO: This seems completely incomplete, disabled for now
-#if 0
-          } else if (strcmp(argv[i], "-printRecords") == 0) {
-            ++i;
-            while (i < argc && argv[i][0] != '-') {
-              if (strcasecmp(argv[i], "config") == 0) {
-                dump_config = 1;
-              } else if (strcasecmp(argv[i], "process") == 0) {
-                dump_process = 1;
-              } else if (strcasecmp(argv[i], "node") == 0) {
-                dump_node = 1;
-              } else if (strcasecmp(argv[i], "cluster") == 0) {
-                dump_cluster = 1;
-              } else if (strcasecmp(argv[i], "local") == 0) {
-                dump_local = 1;
-              } else if (strcasecmp(argv[i], "all") == 0) {
-                dump_config = dump_node = dump_process = dump_cluster = 
dump_local = 1;
-              }
-              ++i;
-            }
-            --i;
-#endif
-          } else if (strcmp(argv[i], "-tsArgs") == 0) {
-            int size_of_args = 0, j = (++i);
-            while (j < argc) {
-              size_of_args += 1;
-              size_of_args += strlen((argv[j++]));
-            }
-            tsArgs = (char *)ats_malloc(size_of_args + 1);
-
-            j = 0;
-            while (i < argc) {
-              snprintf(&tsArgs[j], ((size_of_args + 1) - j), " %s", argv[i]);
-              j += strlen(argv[i]) + 1;
-              ++i;
-            }
-          } else if (strcmp(argv[i], "-proxyPort") == 0) {
-            ++i;
-            proxy_port = argv[i];
-          } else if (strcmp(argv[i], "-proxyBackDoor") == 0) {
-            ++i;
-            proxy_backdoor = atoi(argv[i]);
-          } else {
-            printUsage();
-          }
-        } else {
-          printUsage();
-        }
-      }
-    }
-  }
-
-  // Bootstrap with LOG_DAEMON until we've read our configuration
-  if (log_to_syslog) {
-    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, LOG_DAEMON);
-    mgmt_use_syslog();
-    syslog(LOG_NOTICE, "NOTE: --- Manager Starting ---");
-    syslog(LOG_NOTICE, "NOTE: Manager Version: %s", 
appVersionInfo.FullVersionInfoStr);
-  }
-
-  // Bootstrap the Diags facility so that we can use it while starting
-  //  up the manager
-  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, 
false);
-  diags = diagsConfig->diags;
-  diags->prefix_str = "Manager ";
-
-  RecLocalInit();
-  LibRecordsConfigInit();
-  RecordsConfigOverrideFromEnvironment();
-
-  init_dirs();// setup critical directories, needs LibRecords
-
-  // Get the config info we need while we are still root
-  extractConfigInfo(mgmt_path, recs_conf, userToRunAs, &fds_throttle);
-
-  set_process_limits(fds_throttle); // as root
-  runAsUser(userToRunAs);
-  setup_coredump();
-  check_lockfile();
-
-  url_init();
-  mime_init();
-  http_init();
-
-#if TS_HAS_WCCP
-  Init_Errata_Logging();
-#endif
-  ts_host_res_global_init();
-  ts_session_protocol_well_known_name_indices_init();
-  lmgmt = new LocalManager(proxy_on);
-  RecLocalInitMessage();
-  lmgmt->initAlarm();
-
-  if (diags) {
-    delete diagsConfig;
-    // diagsConfig->reconfigure_diags(); INKqa11968
-    /*
-       delete diags;
-       diags = new Diags(debug_tags,action_tags);
-     */
-  }
-  // INKqa11968: need to set up callbacks and diags data structures
-  // using configuration in records.config
-  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, 
true);
-  diags = diagsConfig->diags;
-  RecSetDiags(diags);
-  diags->prefix_str = "Manager ";
-
-  if (is_debug_tag_set("diags"))
-    diags->dump();
-  diags->cleanup_func = mgmt_cleanup;
-
-  // Setup the exported manager version records.
-  RecSetRecordString("proxy.node.version.manager.short", 
appVersionInfo.VersionStr);
-  RecSetRecordString("proxy.node.version.manager.long", 
appVersionInfo.FullVersionInfoStr);
-  RecSetRecordString("proxy.node.version.manager.build_number", 
appVersionInfo.BldNumStr);
-  RecSetRecordString("proxy.node.version.manager.build_time", 
appVersionInfo.BldTimeStr);
-  RecSetRecordString("proxy.node.version.manager.build_date", 
appVersionInfo.BldDateStr);
-  RecSetRecordString("proxy.node.version.manager.build_machine", 
appVersionInfo.BldMachineStr);
-  RecSetRecordString("proxy.node.version.manager.build_person", 
appVersionInfo.BldPersonStr);
-//    RecSetRecordString("proxy.node.version.manager.build_compile_flags",
-//                       appVersionInfo.BldCompileFlagsStr);
-
-  if (log_to_syslog) {
-    char sys_var[] = "proxy.config.syslog_facility";
-    char *facility_str = NULL;
-    int facility_int;
-    facility_str = REC_readString(sys_var, &found);
-    ink_assert(found);
-
-    if (!found) {
-      mgmt_elog(0, "Could not read %s.  Defaulting to DAEMON\n", sys_var);
-      facility_int = LOG_DAEMON;
-    } else {
-      facility_int = facility_string_to_int(facility_str);
-      ats_free(facility_str);
-      if (facility_int < 0) {
-        mgmt_elog(0, "Bad syslog facility specified.  Defaulting to DAEMON\n");
-        facility_int = LOG_DAEMON;
-      }
-    }
-
-    // NOTE: do NOT call closelog() here.  Solaris gets confused
-    //   and some how it hoses later calls to readdir_r.
-    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, 
facility_int);
-
-    lmgmt->syslog_facility = facility_int;
-  } else {
-    lmgmt->syslog_facility = -1;
-  }
-
-  // Find out our hostname so we can use it as part of the initialization
-  setHostnameVar();
-
-  // Create the data structure for overview page
-  //   Do this before the rest of the set up since it needs
-  //   to created to handle any alarms thrown by later
-  //   initialization
-  overviewGenerator = new overviewPage();
-
-  // Initialize the Config Object bindings before
-  //   starting any other threads
-  lmgmt->configFiles = configFiles = new FileManager();
-  initializeRegistry();
-  configFiles->registerCallback(fileUpdated);
-
-  // RecLocal's 'sync_thr' depends on 'configFiles', so we can't
-  // stat the 'sync_thr' until 'configFiles' has been initialized.
-  RecLocalStart(configFiles);
-
-  /* Update cmd line overrides/environmental overrides/etc */
-  if (tsArgs) {                 /* Passed command line args for proxy */
-    ats_free(lmgmt->proxy_options);
-    lmgmt->proxy_options = tsArgs;
-    mgmt_log(stderr, "[main] Traffic Server Args: '%s'\n", 
lmgmt->proxy_options);
-  }
-  if (proxy_port) {
-    HttpProxyPort::loadValue(lmgmt->m_proxy_ports, proxy_port);
-  }
-
-  if (proxy_backdoor != -1) {
-    RecSetRecordInt("proxy.config.process_manager.mgmt_port", proxy_backdoor);
-  }
-
-  if (cluster_rsport == -1) {
-    cluster_rsport = REC_readInteger("proxy.config.cluster.rsport", &found);
-    ink_assert(found);
-  }
-
-  if (cluster_mcport == -1) {
-    cluster_mcport = REC_readInteger("proxy.config.cluster.mcport", &found);
-    ink_assert(found);
-  }
-
-  if (!group_addr) {
-    group_addr = REC_readString("proxy.config.cluster.mc_group_addr", &found);
-    ink_assert(found);
-  }
-
-  in_addr_t min_ip = inet_network("224.0.0.255");
-  in_addr_t max_ip = inet_network("239.255.255.255");
-  in_addr_t group_addr_ip = inet_network(group_addr);
-
-  if (!(min_ip < group_addr_ip && group_addr_ip < max_ip)) {
-    mgmt_fatal(0, "[TrafficManager] Multi-Cast group addr '%s' is not in the 
permitted range of %s\n",
-               group_addr, "224.0.1.0 - 239.255.255.255");
-  }
-
-  /* TODO: Do we really need to init cluster communication? */
-  lmgmt->initCCom(appVersionInfo, configFiles, cluster_mcport, group_addr, 
cluster_rsport);       /* Setup cluster communication */
-
-  lmgmt->initMgmtProcessServer();       /* Setup p-to-p process server */
-
-  // Now that we know our cluster ip address, add the
-  //   UI record for this machine
-  overviewGenerator->addSelfRecord();
-
-  lmgmt->listenForProxy();
-
-  //
-  // As listenForProxy() may change/restore euid, we should put
-  // the creation of webIntr_main thread after it. So that we
-  // can keep a consistent euid when create mgmtapi/eventapi unix
-  // sockets in webIntr_main thread.
-  //
-  webThrId = ink_thread_create(webIntr_main, NULL);     /* Spin web agent 
thread */
-  Debug("lm", "Created Web Agent thread (%"  PRId64 ")", (int64_t)webThrId);
-
-  ticker = time(NULL);
-  mgmt_log("[TrafficManager] Setup complete\n");
-
-  statProcessor = new StatProcessor(configFiles);
-
-  for (;;) {
-    lmgmt->processEventQueue();
-    lmgmt->pollMgmtProcessServer();
-
-    // Check for a SIGHUP
-    if (sigHupNotifier != 0) {
-      mgmt_log(stderr, "[main] Reading Configuration Files due to SIGHUP\n");
-      configFiles->rereadConfig();
-      lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, "*");
-      sigHupNotifier = 0;
-      mgmt_log(stderr, "[main] Reading Configuration Files Reread\n");
-    }
-    // Check for SIGUSR2
-    if (sigUsr2Notifier != 0) {
-      ink_stack_trace_dump();
-      sigUsr2Notifier = 0;
-    }
-
-    lmgmt->ccom->generateClusterDelta();
-
-    if (lmgmt->run_proxy && lmgmt->processRunning()) {
-      lmgmt->ccom->sendSharedData();
-      lmgmt->virt_map->lt_runGambit();
-    } else {
-      if (!lmgmt->run_proxy) {  /* Down if we are not going to start another 
immed. */
-        /* Proxy is not up, so no addrs should be */
-        lmgmt->virt_map->downOurAddrs();
-      }
-
-      /* Proxy is not up, but we should still exchange config and alarm info */
-      lmgmt->ccom->sendSharedData(false);
-    }
-
-    lmgmt->ccom->checkPeers(&ticker);
-    overviewGenerator->checkForUpdates();
-
-    if (statProcessor) {
-      statProcessor->processStat();
-    }
-
-    if (lmgmt->mgmt_shutdown_outstanding == true) {
-      lmgmt->mgmtShutdown(true);
-      _exit(0);
-    }
-
-    if (lmgmt->run_proxy && !lmgmt->processRunning()) { /* Make sure we still 
have a proxy up */
-      if (lmgmt->startProxy())
-        just_started = 0;
-      else
-        just_started++;
-    } else {                    /* Give the proxy a chance to fire up */
-      just_started++;
-    }
-
-    /* This will catch the case were the proxy dies before it can connect to 
manager */
-    if (lmgmt->proxy_launch_outstanding && !lmgmt->processRunning() && 
just_started >= 120) {
-      just_started = 0;
-      lmgmt->proxy_launch_outstanding = false;
-      if (lmgmt->proxy_launch_pid != -1) {
-        int res;
-        kill(lmgmt->proxy_launch_pid, 9);
-        waitpid(lmgmt->proxy_launch_pid, &res, 0);
-        if (WIFSIGNALED(res)) {
-          int sig = WTERMSIG(res);
-#ifdef NEED_PSIGNAL
-          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d\n", sig);
-#else
-          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d: %s\n", sig, 
strsignal(sig));
-#endif /* NEED_PSIGNAL */
-        }
-      }
-      mgmt_log(stderr, "[main] Proxy launch failed, retrying...\n");
-    }
-
-  }
-
-  if (statProcessor) {
-    delete(statProcessor);
-  }
-
-#ifndef MGMT_SERVICE
-  return 0;
-#endif
-
-}                               /* End main */
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-static void
-SignalAlrmHandler(int /* sig ATS_UNUSED */, siginfo_t * t, void * /* c 
ATS_UNUSED */)
-#else
-static void
-SignalAlrmHandler(int /* sig ATS_UNUSED */)
-#endif
-{
-  /*
-     fprintf(stderr, "[TrafficManager] ==> SIGALRM received\n");
-     mgmt_elog(stderr, 0, "[TrafficManager] ==> SIGALRM received\n");
-   */
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  if (t) {
-    if (t->si_code <= 0) {
-#if defined(solaris)
-      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: 
%d\n", (int)t->si_pid, t->si_uid);
-#else
-      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: 
%d\n", t->si_pid, t->si_uid);
-#endif
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Alarm from pid: %d uid: 
%d\n", t->si_pid, t->si_uid);
-    } else {
-      fprintf(stderr, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", 
t->si_code);
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", 
t->si_code);
-    }
-  }
-#endif
-
-  return;
-}
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-static void
-SignalHandler(int sig, siginfo_t * t, void *c)
-#else
-static void
-SignalHandler(int sig)
-#endif
-{
-  static int clean = 0;
-  int status;
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  if (t) {
-    if (t->si_code <= 0) {
-#if defined(solaris)
-      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: 
%d\n", sig, (int)t->si_pid, t->si_uid);
-#else
-      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: 
%d\n", sig, t->si_pid, t->si_uid);
-#endif
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Sig %d from pid: %d uid: 
%d\n", sig, t->si_pid, t->si_uid);
-    } else {
-      fprintf(stderr, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, 
t->si_code);
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", 
sig, t->si_code);
-    }
-  }
-#endif
-
-  if (sig == SIGHUP) {
-    sigHupNotifier = 1;
-    return;
-  }
-
-  if (sig == SIGUSR2) {
-    sigUsr2Notifier = 1;
-    return;
-  }
-  fprintf(stderr, "[TrafficManager] ==> Cleaning up and reissuing signal 
#%d\n", sig);
-  mgmt_elog(stderr, 0, "[TrafficManager] ==> Cleaning up and reissuing signal 
#%d\n", sig);
-
-  if (lmgmt && !clean) {
-    clean = 1;
-    if (lmgmt->watched_process_pid != -1) {
-
-      if (sig == SIGTERM || sig == SIGINT) {
-        kill(lmgmt->watched_process_pid, sig);
-        waitpid(lmgmt->watched_process_pid, &status, 0);
-      }
-    }
-    lmgmt->mgmtCleanup();
-  }
-
-  switch (sig) {
-  case SIGQUIT:
-  case SIGILL:
-  case SIGTRAP:
-#if !defined(linux)
-  case SIGEMT:
-  case SIGSYS:
-#endif
-  case SIGFPE:
-  case SIGBUS:
-  case SIGSEGV:
-  case SIGXCPU:
-  case SIGXFSZ:
-    abort();
-  default:
-    fprintf(stderr, "[TrafficManager] ==> signal #%d\n", sig);
-    mgmt_elog(stderr, 0, "[TrafficManager] ==> signal #%d\n", sig);
-    _exit(sig);
-  }
-  fprintf(stderr, "[TrafficManager] ==> signal2 #%d\n", sig);
-  mgmt_elog(stderr, 0, "[TrafficManager] ==> signal2 #%d\n", sig);
-  _exit(sig);
-}                               /* End SignalHandler */
-
-// void SigChldHandler(int sig)
-//
-//   An empty handler needed so that we catch SIGCHLD
-//    With Solaris 2.6, ignoring sig child changes the behavior
-//    of waitpid() so that if there are no unwaited children,
-//    waitpid() blocks until all child are transformed into
-//    zombies which is bad for us
-//
-static void
-SigChldHandler(int /* sig ATS_UNUSED */)
-{
-}
-
-void
-printUsage()
-{
-  fprintf(stderr, 
"----------------------------------------------------------------------------\n");
-  fprintf(stderr, " Traffic Manager Usage: (all args are optional)\n");
-  fprintf(stderr, "\n");
-  fprintf(stderr, "   traffic_manager [options]\n");
-  fprintf(stderr, "     -proxyPort     <port>  Port to have proxy listen on, 
overrides records.config.\n");
-  /* Function is currently #ifdef'ed out so no reason to advertise
-     fprintf(stderr,
-     "     -proxyBackdoor <port>  Port to put proxy mgmt port on.\n");
-   */
-  /* Commented out because this option is used for debugging only.
-     fprintf(stderr,
-     "     -noProxy               Do not launch the proxy process.\n");
-   */
-  fprintf(stderr, "     -tsArgs        [...]   Args to proxy, everything till 
eol is passed.\n");
-  fprintf(stderr, "     -webPort       <port>  Port for web interface.\n");
-  /*
-     fprintf(stderr,
-     "     -graphPort     <port>  Port for dynamic graphs.\n");
-   */
-  fprintf(stderr, "     -clusterPort   <port>  Cluster Multicast port\n");
-  fprintf(stderr, "     -groupAddr     <addr>  Cluster Multicast group, 
example: \"225.0.0.37\".\n");
-  fprintf(stderr, "     -clusterRSPort <port>  Cluster Multicast port.\n");
-  fprintf(stderr, "     -path          <path>  Root path for config files.\n");
-  /*
-     fprintf(stderr,
-     "     -lmConf        <fname> Local Management config file.\n");
-   */
-  fprintf(stderr, "     -recordsConf   <fname> General config file.\n");
-  // TODO: This seems completely incomplete, disabled for now
-  // fprintf(stderr, "     -printRecords  [...]   Print flags, default all are 
off.\n");
-  fprintf(stderr, "     -debug         <tags>  Enable the given debug tags\n");
-  fprintf(stderr, "     -action        <tags>  Enable the given action 
tags.\n");
-  fprintf(stderr, "     -version or -V         Print version id and exit.\n");
-  fprintf(stderr, "\n");
-  fprintf(stderr, "   [...] can be one+ of: [config process node cluster local 
all]\n");
-  fprintf(stderr, 
"----------------------------------------------------------------------------\n");
-  exit(0);
-}                               /* End printUsage */
-
-void
-fileUpdated(char *fname, bool incVersion)
-{
-  if (strcmp(fname, "cluster.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cluster.cluster_configuration");
-
-  } else if (strcmp(fname, "remap.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.url_remap.filename");
-
-  } else if (strcmp(fname, "socks.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.socks.socks_config_file");
-
-  } else if (strcmp(fname, "records.config") == 0) {
-    lmgmt->signalFileChange("records.config", incVersion);
-
-  } else if (strcmp(fname, "cache.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cache.control.filename");
-
-  } else if (strcmp(fname, "parent.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.http.parent_proxy.file");
-
-  } else if (strcmp(fname, "ip_allow.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cache.ip_allow.filename");
-  } else if (strcmp(fname, "vaddrs.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] vaddrs.config updated\n");
-    lmgmt->virt_map->lt_readAListFile(fname);
-
-  } else if (strcmp(fname, "storage.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] storage.config changed, need restart 
auto-rebuild mode\n");
-
-  } else if (strcmp(fname, "proxy.pac") == 0) {
-    mgmt_log(stderr, "[fileUpdated] proxy.pac file has been modified\n");
-
-  } else if (strcmp(fname, "icp.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.icp.icp_configuration");
-
-  } else if (strcmp(fname, "update.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.update.update_configuration");
-
-  } else if (strcmp(fname, "volume.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] volume.config changed, need restart\n");
-
-  } else if (strcmp(fname, "hosting.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cache.hosting_filename");
-
-  } else if (strcmp(fname, "log_hosts.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.log.hosts_config_file");
-
-  } else if (strcmp(fname, "logs_xml.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.log.xml_config_file");
-
-  } else if (strcmp(fname, "splitdns.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.dns.splitdns.filename");
-
-  } else if (strcmp(fname, "plugin.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] plugin.config file has been modified\n");
-
-  } else if (strcmp(fname, "ssl_multicert.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.ssl.server.multicert.filename");
-
-  } else if (strcmp(fname, "proxy.config.body_factory.template_sets_dir") == 
0) {
-    lmgmt->signalFileChange("proxy.config.body_factory.template_sets_dir");
-
-  } else if (strcmp(fname, "stats.config.xml") == 0) {
-    if (statProcessor) {
-      statProcessor->rereadConfig(configFiles);
-    }
-    mgmt_log(stderr, "[fileUpdated] stats.config.xml file has been 
modified\n");
-  } else if (strcmp(fname, "congestion.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.http.congestion_control.filename");
-  } else if (strcmp(fname, "prefetch.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.prefetch.config_file");
-  } else {
-    mgmt_elog(stderr, 0, "[fileUpdated] Unknown config file updated '%s'\n", 
fname);
-
-  }
-  return;
-}                               /* End fileUpdate */
-
-#if TS_USE_POSIX_CAP
-/** Restore capabilities after user id change.
-    This manipulates LINUX capabilities so that this process
-    can perform certain privileged operations even if it is
-    no longer running as a privilege user.
-
-    @internal
-    I tried using
-    @code
-    prctl(PR_SET_KEEPCAPS, 1);
-    @endcode
-    but that had no effect even though the call reported success.
-    Only explicit capability manipulation was effective.
-
-    It does not appear to be necessary to set the capabilities on the
-    executable if originally run as root. That may be needed if
-    started as a user without that capability.
- */
-
-int
-restoreCapabilities() {
-  int zret = 0; // return value.
-  cap_t cap_set = cap_get_proc(); // current capabilities
-  // Make a list of the capabilities we want turned on.
-  cap_value_t cap_list[] = {
-    CAP_NET_ADMIN, ///< Set socket transparency.
-    CAP_NET_BIND_SERVICE, ///< Low port (e.g. 80) binding.
-    CAP_IPC_LOCK ///< Lock IPC objects.
-  };
-  static int const CAP_COUNT = sizeof(cap_list)/sizeof(*cap_list);
-
-  cap_set_flag(cap_set, CAP_EFFECTIVE, CAP_COUNT, cap_list, CAP_SET);
-  zret = cap_set_proc(cap_set);
-  cap_free(cap_set);
-  return zret;
-}
-#endif
-
-//  void runAsUser(...)
-//
-//  If we are root, switched to user to run as
-//    specified in records.config
-//
-//  If we are not root, do nothing
-//
-void
-runAsUser(char *userName)
-{
-  uid_t uid, euid;
-  struct passwd *result;
-  const int bufSize = 1024;
-  char buf[bufSize];
-
-  uid = getuid();
-  euid = geteuid();
-
-  if (uid == 0 || euid == 0) {
-
-    /* Figure out what user we should run as */
-
-    Debug("lm", "[runAsUser] Attempting to run as user '%s'\n", userName);
-
-    if (userName == NULL || userName[0] == '\0') {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: 
proxy.config.admin.user_id is not set\n");
-      _exit(1);
-    }
-
-    struct passwd passwdInfo;
-    struct passwd *ppasswd = NULL;
-    result = NULL;
-    int res;
-    if (*userName == '#') {
-      int uuid = atoi(userName + 1);
-      if (uuid == -1)
-        uuid = (int)uid;
-      res = getpwuid_r((uid_t)uuid, &passwdInfo, buf, bufSize, &ppasswd);
-    }
-    else {
-      res = getpwnam_r(&userName[0], &passwdInfo, buf, bufSize, &ppasswd);
-    }
-
-    if (!res && ppasswd) {
-      result = ppasswd;
-    }
-
-    if (result == NULL) {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to get info about 
user %s : %s\n", userName, strerror(errno));
-      _exit(1);
-    }
-
-    if (setegid(result->pw_gid) != 0 || seteuid(result->pw_uid) != 0) {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to switch to user 
%s : %s\n", userName, strerror(errno));
-      _exit(1);
-    }
-
-    uid = getuid();
-    euid = geteuid();
-
-    Debug("lm", "[runAsUser] Running with uid: '%d' euid: '%d'\n", uid, euid);
-
-    if (uid != result->pw_uid && euid != result->pw_uid) {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Failed to switch to user 
%s\n", userName);
-      _exit(1);
-    }
-
-    // setup supplementary groups if it is not set.
-    if (0 == getgroups(0, NULL)) {
-      initgroups(&userName[0],result->pw_gid);
-    }
-
-#if TS_USE_POSIX_CAP
-    if (0 != restoreCapabilities()) {
-      mgmt_elog(stderr, 0, "[runAsUser] Error: Failed to restore capabilities 
after switch to user %s.\n", userName);
-    }
-#endif
-
-  }
-}                               /* End runAsUser() */
-
-//  void extractConfigInfo(...)
-//
-//  We need to get certain records.config values while we are
-//   root.  We can not use LMRecords to get them because the constructor
-//   for LMRecords creates the mgmt DBM and we do not want that to
-//   be owned as root.  This function extracts that info from
-//   records.config
-//
-//
-void
-extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int 
*fds_throttle)
-{
-  char file[1024];
-  bool useridFound = false;
-  bool throttleFound = false;
-
-  /* Figure out what user we should run as */
-  if (mgmt_path && recs_conf) {
-    FILE *fin;
-    snprintf(file, sizeof(file), "%s/%s.shadow", mgmt_path, recs_conf);
-    if (!(fin = fopen(file, "r"))) {
-      ink_filepath_make(file, sizeof(file), mgmt_path, recs_conf);
-      if (!(fin = fopen(file, "r"))) {
-        mgmt_elog(stderr, errno, "[extractConfigInfo] Unable to open config 
file(%s)\n", file);
-        _exit(1);
-      }
-    }
-    // Get 'user id' and 'network connections throttle limit'
-    while (((!useridFound) || (!throttleFound)) && fgets(file, 1024, fin)) {
-      if (strstr(file, "CONFIG proxy.config.admin.user_id STRING")) {
-        //coverity[secure_coding]
-        if ((sscanf(file, "CONFIG proxy.config.admin.user_id STRING %1023s\n", 
userName) == 1) &&
-            strcmp(userName, "NULL") != 0) {
-          useridFound = true;
-        }
-      } else if (strstr(file, "CONFIG proxy.config.net.connections_throttle 
INT")) {
-        if ((sscanf(file, "CONFIG proxy.config.net.connections_throttle INT 
%d\n", fds_throttle) == 1)) {
-          throttleFound = true;
-        }
-      }
-
-    }
-    fclose(fin);
-  } else {
-    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: unable to access 
records file\n");
-    _exit(1);
-  }
-
-  if (useridFound == false) {
-    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: 
proxy.config.admin.user_id is not set\n");
-    _exit(1);
-  }
-
-}                               /* End extractConfigInfo() */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/Main.h
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Main.h b/cmd/traffic_manager/Main.h
deleted file mode 100644
index ec37226..0000000
--- a/cmd/traffic_manager/Main.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @section license License
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-#include "FileManager.h"
-#include "I_Version.h"
-
-// TODO: consolidate location of these defaults
-#define DEFAULT_ROOT_DIRECTORY            PREFIX
-#define DEFAULT_LOCAL_STATE_DIRECTORY     "var/trafficserver"
-#define DEFAULT_SYSTEM_CONFIG_DIRECTORY   "etc/trafficserver"
-#define DEFAULT_LOG_DIRECTORY             "var/log/trafficserver"
-
-void MgmtShutdown(int status);
-void fileUpdated(char *fname, bool incVersion);
-void runAsUser(char *userName);
-void printUsage(void);
-
-extern FileManager *configFiles;
-//extern overviewPage *overviewGenerator;
-extern AppVersionInfo appVersionInfo;
-
-// Global strings
-extern char mgmt_path[];
-
-// Global variable to replace ifdef MGMT_LAUNCH_PROXY so that
-// we can turn on/off proxy launch at runtime to facilitate
-// manager only testing.
-extern bool mgmt_launch_proxy;
-
-#endif /* _MAIN_H_ */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/Makefile.am
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Makefile.am b/cmd/traffic_manager/Makefile.am
index 6ba9bfd..97d6a41 100644
--- a/cmd/traffic_manager/Makefile.am
+++ b/cmd/traffic_manager/Makefile.am
@@ -34,8 +34,7 @@ AM_CPPFLAGS = \
 
 traffic_manager_SOURCES = \
   AddConfigFilesHere.cc \
-  Main.cc \
-  Main.h \
+  traffic_manager.cc \
   StatProcessor.cc \
   StatProcessor.h \
   StatType.cc \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/StatType.h
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/StatType.h b/cmd/traffic_manager/StatType.h
index 673e1e7..03e8f7a 100644
--- a/cmd/traffic_manager/StatType.h
+++ b/cmd/traffic_manager/StatType.h
@@ -34,7 +34,6 @@
 #define        _STATTYPE_H_
 
 #include "StatXML.h"
-#include "Main.h"               // Debug()
 #include "WebMgmtUtils.h"
 
 #define BYTES_TO_MBIT_SCALE (8/1000000.0)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/traffic_manager.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/traffic_manager.cc 
b/cmd/traffic_manager/traffic_manager.cc
new file mode 100644
index 0000000..a45e246
--- /dev/null
+++ b/cmd/traffic_manager/traffic_manager.cc
@@ -0,0 +1,1202 @@
+/** @file
+
+  Entry point to the traffic manager.
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "libts.h"
+#include "ink_sys_control.h"
+
+#include "MgmtUtils.h"
+#include "WebMgmtUtils.h"
+#include "WebIntrMain.h"
+#include "WebOverview.h"
+#include "ClusterCom.h"
+#include "VMap.h"
+#include "FileManager.h"
+#include "I_Layout.h"
+#include "I_Version.h"
+#include "Diags.h"
+#include "DiagsConfig.h"
+#include "URL.h"
+#include "MIME.h"
+#include "HTTP.h"
+
+// Needs LibRecordsConfigInit()
+#include "RecordsConfig.h"
+
+#include "StatProcessor.h"
+#include "P_RecLocal.h"
+#include "P_RecCore.h"
+
+#if TS_USE_POSIX_CAP
+#include <sys/capability.h>
+#endif
+#include <grp.h>
+
+#define FD_THROTTLE_HEADROOM (128 + 64) // TODO: consolidate with 
THROTTLE_FD_HEADROOM
+#define DIAGS_LOG_FILENAME "manager.log"
+
+// These globals are still referenced directly by management API.
+LocalManager *lmgmt = NULL;
+FileManager *configFiles;
+
+static void fileUpdated(char *fname, bool incVersion);
+static void runAsUser(char *userName);
+static void printUsage(void);
+
+#if defined(freebsd)
+extern "C" int getpwnam_r(const char *name, struct passwd *result, char 
*buffer, size_t buflen, struct passwd **resptr);
+#endif
+
+static void extractConfigInfo(char *mgmt_path, const char *recs_conf, char 
*userName, int *fds_throttle);
+
+static StatProcessor *statProcessor;   // Statistics Processors
+static AppVersionInfo appVersionInfo;  // Build info for this application
+
+static inkcoreapi DiagsConfig *diagsConfig;
+static char debug_tags[1024] = "";
+static char action_tags[1024] = "";
+static bool proxy_on = true;
+
+static char mgmt_path[PATH_NAME_MAX + 1];
+
+// By default, set the current directory as base
+static const char *recs_conf = "records.config";
+
+static int fds_limit;
+
+// TODO: Use positive instead negative selection
+//       Thsis should just be #if defined(solaris)
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+static void SignalHandler(int sig, siginfo_t * t, void *f);
+static void SignalAlrmHandler(int sig, siginfo_t * t, void *f);
+#else
+static void SignalHandler(int sig);
+static void SignalAlrmHandler(int sig);
+#endif
+
+static volatile int sigHupNotifier = 0;
+static volatile int sigUsr2Notifier = 0;
+static void SigChldHandler(int sig);
+
+static void
+check_lockfile()
+{
+  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+  char lockfile[PATH_NAME_MAX];
+  int err;
+  pid_t holding_pid;
+
+  //////////////////////////////////////
+  // test for presence of server lock //
+  //////////////////////////////////////
+  Layout::relative_to(lockfile, sizeof(lockfile), rundir, SERVER_LOCK);
+  Lockfile server_lockfile(lockfile);
+  err = server_lockfile.Open(&holding_pid);
+  if (err == 1) {
+    server_lockfile.Close();    // no server running
+  } else {
+    char *reason = strerror(-err);
+    if (err == 0) {
+      // TODO: Add PID_FMT_T instead duplicating code just for printing
+#if defined(solaris)
+      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID 
%d\n", lockfile, (int)holding_pid);
+#else
+      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID 
%d\n", lockfile, holding_pid);
+#endif
+      mgmt_elog(stderr, 0, "FATAL: Lockfile '%s' says server already running 
as PID %d\n", lockfile, holding_pid);
+    } else {
+      fprintf(stderr, "FATAL: Can't open server lockfile '%s' (%s)\n", 
lockfile, (reason ? reason : "Unknown Reason"));
+      mgmt_elog(stderr, 0, "FATAL: Can't open server lockfile '%s' (%s)\n",
+                lockfile, (reason ? reason : "Unknown Reason"));
+    }
+    exit(1);
+  }
+
+  ///////////////////////////////////////////
+  // try to get the exclusive manager lock //
+  ///////////////////////////////////////////
+  Layout::relative_to(lockfile, sizeof(lockfile), rundir, MANAGER_LOCK);
+  Lockfile manager_lockfile(lockfile);
+  err = manager_lockfile.Get(&holding_pid);
+  if (err != 1) {
+    char *reason = strerror(-err);
+    fprintf(stderr, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
+    mgmt_elog(stderr, 0, "FATAL: Can't acquire manager lockfile '%s'", 
lockfile);
+    if (err == 0) {
+#if defined(solaris)
+      fprintf(stderr, " (Lock file held by process ID %d)\n", 
(int)holding_pid);
+#else
+      fprintf(stderr, " (Lock file held by process ID %d)\n", holding_pid);
+#endif
+      mgmt_elog(stderr, 0, " (Lock file held by process ID %d)\n", 
holding_pid);
+    } else if (reason) {
+      fprintf(stderr, " (%s)\n", reason);
+      mgmt_elog(stderr, 0, " (%s)\n", reason);
+    } else {
+      fprintf(stderr, "\n");
+    }
+    exit(1);
+
+    fprintf(stderr, "unable to acquire manager lock [%d]\n", -err);
+    exit(1);
+  }
+}
+
+static void
+initSignalHandlers()
+{
+  struct sigaction sigHandler, sigChldHandler, sigAlrmHandler;
+  sigset_t sigsToBlock;
+
+  // Set up the signal handler
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigHandler.sa_handler = NULL;
+  sigHandler.sa_sigaction = SignalHandler;
+#else
+  sigHandler.sa_handler = SignalHandler;
+#endif
+  sigemptyset(&sigHandler.sa_mask);
+
+  // We want the handler to remain in place on
+  //  SIGHUP to avoid any races with the signals
+  //  coming too quickly.  Also restart systems calls
+  //  after the signal since not all calls are wrapped
+  //  to check errno for EINTR
+  sigHandler.sa_flags = SA_RESTART;
+  sigaction(SIGHUP, &sigHandler, NULL);
+  sigaction(SIGUSR2, &sigHandler, NULL);
+
+  // Don't block the signal on entry to the signal
+  //   handler so we can reissue it and get a core
+  //   file in the appropriate circumstances
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigHandler.sa_flags = SA_RESETHAND | SA_SIGINFO;
+#else
+  sigHandler.sa_flags = SA_RESETHAND;
+#endif
+  sigaction(SIGINT, &sigHandler, NULL);
+  sigaction(SIGQUIT, &sigHandler, NULL);
+  sigaction(SIGILL, &sigHandler, NULL);
+  sigaction(SIGBUS, &sigHandler, NULL);
+  sigaction(SIGSEGV, &sigHandler, NULL);
+  sigaction(SIGTERM, &sigHandler, NULL);
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigAlrmHandler.sa_handler = NULL;
+  sigAlrmHandler.sa_sigaction = SignalAlrmHandler;
+#else
+  sigAlrmHandler.sa_handler = SignalAlrmHandler;
+#endif
+
+  sigemptyset(&sigAlrmHandler.sa_mask);
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigAlrmHandler.sa_flags = SA_SIGINFO;
+#else
+  sigAlrmHandler.sa_flags = 0;
+#endif
+  sigaction(SIGALRM, &sigAlrmHandler, NULL);
+
+  // Block the delivery of any signals we are not catching
+  //
+  //  except for SIGALARM since we use it
+  //    to break out of deadlock on semaphore
+  //    we share with the proxy
+  //
+  sigfillset(&sigsToBlock);
+  sigdelset(&sigsToBlock, SIGHUP);
+  sigdelset(&sigsToBlock, SIGUSR2);
+  sigdelset(&sigsToBlock, SIGINT);
+  sigdelset(&sigsToBlock, SIGQUIT);
+  sigdelset(&sigsToBlock, SIGILL);
+  sigdelset(&sigsToBlock, SIGABRT);
+  sigdelset(&sigsToBlock, SIGBUS);
+  sigdelset(&sigsToBlock, SIGSEGV);
+  sigdelset(&sigsToBlock, SIGTERM);
+  sigdelset(&sigsToBlock, SIGALRM);
+  ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
+
+  // Set up the SIGCHLD handler so we do not get into
+  //   a problem with Solaris 2.6 and strange waitpid()
+  //   behavior
+  sigChldHandler.sa_handler = SigChldHandler;
+  sigChldHandler.sa_flags = SA_RESTART;
+  sigemptyset(&sigChldHandler.sa_mask);
+  sigaction(SIGCHLD, &sigChldHandler, NULL);
+}
+
+#if defined(linux)
+#include <sys/prctl.h>
+#endif
+static int
+setup_coredump()
+{
+#if defined(linux)
+#ifndef PR_SET_DUMPABLE
+#define PR_SET_DUMPABLE 4       /* Ugly, but we cannot compile with 2.2.x 
otherwise.
+                                   Should be removed when we compile only on 
2.4.x */
+#endif
+  prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+#endif  // linux check
+  return 0;
+}
+
+static void
+init_dirs()
+{
+  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+
+  if (access(Layout::get()->sysconfdir, R_OK) == -1) {
+    mgmt_elog(0, "unable to access() config dir '%s': %d, %s\n", 
Layout::get()->sysconfdir, errno, strerror(errno));
+    mgmt_elog(0, "please set the 'TS_ROOT' environment variable\n");
+    _exit(1);
+  }
+
+  if (access(rundir, R_OK) == -1) {
+    mgmt_elog(0, "unable to access() local state dir '%s': %d, %s\n", (const 
char *)rundir, errno, strerror(errno));
+    mgmt_elog(0, "please set 'proxy.config.local_state_dir'\n");
+    _exit(1);
+  }
+}
+
+static void
+chdir_root()
+{
+  const char * prefix = Layout::get()->prefix;
+
+  if (chdir(prefix) < 0) {
+    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", 
prefix, errno, strerror(errno));
+    mgmt_elog(0, " please set correct path in env variable TS_ROOT \n");
+    exit(1);
+  } else {
+    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix);
+  }
+}
+
+static void
+set_process_limits(int fds_throttle)
+{
+  struct rlimit lim;
+
+  // Set needed rlimits (root)
+  ink_max_out_rlimit(RLIMIT_NOFILE, true, false);
+  ink_max_out_rlimit(RLIMIT_STACK, true, true);
+  ink_max_out_rlimit(RLIMIT_DATA, true, true);
+  ink_max_out_rlimit(RLIMIT_FSIZE, true, false);
+#ifdef RLIMIT_RSS
+  ink_max_out_rlimit(RLIMIT_RSS, true, true);
+#endif
+
+#if defined(linux)
+  float file_max_pct = 0.9;
+  FILE *fd;
+
+  if ((fd = fopen("/proc/sys/fs/file-max","r"))) {
+    ATS_UNUSED_RETURN(fscanf(fd, "%lu", &lim.rlim_max));
+    fclose(fd);
+    REC_ReadConfigFloat(file_max_pct, "proxy.config.system.file_max_pct");
+    lim.rlim_cur = lim.rlim_max = static_cast<rlim_t>(lim.rlim_max * 
file_max_pct);
+    if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
+      fds_limit = (int) lim.rlim_cur;
+      syslog(LOG_NOTICE, "NOTE: 
RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, 
(int)lim.rlim_max);
+    } else {
+      syslog(LOG_NOTICE, "NOTE: Unable to set 
RLIMIT_NOFILE(%d):cur(%d),max(%d)", RLIMIT_NOFILE, (int)lim.rlim_cur, 
(int)lim.rlim_max);
+    }
+  } else {
+    syslog(LOG_NOTICE, "NOTE: Unable to open /proc/sys/fs/file-max");
+  }
+#endif // linux
+
+  if (!getrlimit(RLIMIT_NOFILE, &lim)) {
+    if (fds_throttle > (int) (lim.rlim_cur + FD_THROTTLE_HEADROOM)) {
+      lim.rlim_cur = (lim.rlim_max = (rlim_t) fds_throttle);
+      if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
+        fds_limit = (int) lim.rlim_cur;
+       syslog(LOG_NOTICE, "NOTE: 
RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, 
(int)lim.rlim_max);
+      }
+    }
+  }
+
+}
+
+#if TS_HAS_WCCP
+static void
+Errata_Logger(ts::Errata const& err) {
+  size_t n;
+  static size_t const SIZE = 4096;
+  char buff[SIZE];
+  if (err.size()) {
+    ts::Errata::Code code = err.top().getCode();
+    n = err.write(buff, SIZE, 1, 0, 2, "> ");
+    // strip trailing newlines.
+    while (n && (buff[n-1] == '\n' || buff[n-1] == '\r'))
+      buff[--n] = 0;
+    // log it.
+    if (code > 1) mgmt_elog(0, "[WCCP]%s", buff);
+    else if (code > 0) mgmt_log("[WCCP]%s", buff);
+    else Debug("WCCP", "%s", buff);
+  }
+}
+
+static void
+Init_Errata_Logging() {
+  ts::Errata::registerSink(&Errata_Logger);
+}
+#endif
+
+int
+main(int argc, char **argv)
+{
+  // Before accessing file system initialize Layout engine
+  Layout::create();
+  ink_strlcpy(mgmt_path, Layout::get()->sysconfdir, sizeof(mgmt_path));
+
+  // change the directory to the "root" directory
+  chdir_root();
+
+  // Line buffer standard output & standard error
+  int status;
+  status = setvbuf(stdout, NULL, _IOLBF, 0);
+  if (status != 0)
+    perror("WARNING: can't line buffer stdout");
+  status = setvbuf(stderr, NULL, _IOLBF, 0);
+  if (status != 0)
+    perror("WARNING: can't line buffer stderr");
+
+  bool found = false;
+  int just_started = 0;
+  int cluster_mcport = -1, cluster_rsport = -1;
+  // TODO: This seems completely incomplete, disabled for now
+  //  int dump_config = 0, dump_process = 0, dump_node = 0, dump_cluster = 0, 
dump_local = 0;
+  char* proxy_port = 0;
+  int proxy_backdoor = -1;
+  char *envVar = NULL, *group_addr = NULL, *tsArgs = NULL;
+  bool log_to_syslog = true;
+  char userToRunAs[80];
+  int  fds_throttle = -1;
+  time_t ticker;
+  ink_thread webThrId;
+
+  // Set up the application version info
+  appVersionInfo.setup(PACKAGE_NAME,"traffic_manager", PACKAGE_VERSION,
+                       __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
+  initSignalHandlers();
+
+  // Process Environment Variables
+  if ((envVar = getenv("MGMT_ACONF_PORT")) != NULL) {
+    aconf_port_arg = atoi(envVar);
+  }
+
+  if ((envVar = getenv("MGMT_CLUSTER_MC_PORT")) != NULL) {
+    cluster_mcport = atoi(envVar);
+  }
+
+  if ((envVar = getenv("MGMT_CLUSTER_RS_PORT")) != NULL) {
+    cluster_rsport = atoi(envVar);
+  }
+
+  if ((envVar = getenv("MGMT_GROUP_ADDR")) != NULL) {
+    group_addr = envVar;
+  }
+
+  for (int i = 1; i < argc; i++) {      /* Process command line args */
+
+    if (argv[i][0] == '-') {
+      if ((strcmp(argv[i], "-version") == 0) || (strcmp(argv[i], "-V") == 0)) {
+        fprintf(stderr, "%s\n", appVersionInfo.FullVersionInfoStr);
+        exit(0);
+      } else if (strcmp(argv[i], "-proxyOff") == 0) {
+        proxy_on = false;
+      } else if (strcmp(argv[i], "-nosyslog") == 0) {
+        log_to_syslog = false;
+      } else {
+        // The rest of the options require an argument in the form of -<Flag> 
<val>
+        if ((i + 1) < argc) {
+
+          if (strcmp(argv[i], "-aconfPort") == 0) {
+            ++i;
+            aconf_port_arg = atoi(argv[i]);
+          } else if (strcmp(argv[i], "-clusterMCPort") == 0) {
+            ++i;
+            cluster_mcport = atoi(argv[i]);
+          } else if (strcmp(argv[i], "-groupAddr") == 0) {
+            ++i;
+            group_addr = argv[i];
+          } else if (strcmp(argv[i], "-clusterRSPort") == 0) {
+            ++i;
+            cluster_rsport = atoi(argv[i]);
+#if TS_USE_DIAGS
+          } else if (strcmp(argv[i], "-debug") == 0) {
+            ++i;
+            ink_strlcpy(debug_tags, argv[i], sizeof(debug_tags));
+          } else if (strcmp(argv[i], "-action") == 0) {
+            ++i;
+            ink_strlcpy(action_tags, argv[i], sizeof(debug_tags));
+#endif
+          } else if (strcmp(argv[i], "-path") == 0) {
+            ++i;
+            //bugfixed by YTS Team, yamsat(id-59703)
+            if ((strlen(argv[i]) > PATH_NAME_MAX)) {
+              fprintf(stderr, "\n   Path exceeded the maximum allowed 
characters.\n");
+              exit(1);
+            }
+
+            ink_strlcpy(mgmt_path, argv[i], sizeof(mgmt_path));
+            /*
+               } else if(strcmp(argv[i], "-lmConf") == 0) {
+               ++i;
+               lm_conf = argv[i];
+             */
+          } else if (strcmp(argv[i], "-recordsConf") == 0) {
+            ++i;
+            recs_conf = argv[i];
+            // TODO: This seems completely incomplete, disabled for now
+#if 0
+          } else if (strcmp(argv[i], "-printRecords") == 0) {
+            ++i;
+            while (i < argc && argv[i][0] != '-') {
+              if (strcasecmp(argv[i], "config") == 0) {
+                dump_config = 1;
+              } else if (strcasecmp(argv[i], "process") == 0) {
+                dump_process = 1;
+              } else if (strcasecmp(argv[i], "node") == 0) {
+                dump_node = 1;
+              } else if (strcasecmp(argv[i], "cluster") == 0) {
+                dump_cluster = 1;
+              } else if (strcasecmp(argv[i], "local") == 0) {
+                dump_local = 1;
+              } else if (strcasecmp(argv[i], "all") == 0) {
+                dump_config = dump_node = dump_process = dump_cluster = 
dump_local = 1;
+              }
+              ++i;
+            }
+            --i;
+#endif
+          } else if (strcmp(argv[i], "-tsArgs") == 0) {
+            int size_of_args = 0, j = (++i);
+            while (j < argc) {
+              size_of_args += 1;
+              size_of_args += strlen((argv[j++]));
+            }
+            tsArgs = (char *)ats_malloc(size_of_args + 1);
+
+            j = 0;
+            while (i < argc) {
+              snprintf(&tsArgs[j], ((size_of_args + 1) - j), " %s", argv[i]);
+              j += strlen(argv[i]) + 1;
+              ++i;
+            }
+          } else if (strcmp(argv[i], "-proxyPort") == 0) {
+            ++i;
+            proxy_port = argv[i];
+          } else if (strcmp(argv[i], "-proxyBackDoor") == 0) {
+            ++i;
+            proxy_backdoor = atoi(argv[i]);
+          } else {
+            printUsage();
+          }
+        } else {
+          printUsage();
+        }
+      }
+    }
+  }
+
+  // Bootstrap with LOG_DAEMON until we've read our configuration
+  if (log_to_syslog) {
+    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, LOG_DAEMON);
+    mgmt_use_syslog();
+    syslog(LOG_NOTICE, "NOTE: --- Manager Starting ---");
+    syslog(LOG_NOTICE, "NOTE: Manager Version: %s", 
appVersionInfo.FullVersionInfoStr);
+  }
+
+  // Bootstrap the Diags facility so that we can use it while starting
+  //  up the manager
+  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, 
false);
+  diags = diagsConfig->diags;
+  diags->prefix_str = "Manager ";
+
+  RecLocalInit();
+  LibRecordsConfigInit();
+  RecordsConfigOverrideFromEnvironment();
+
+  init_dirs();// setup critical directories, needs LibRecords
+
+  // Get the config info we need while we are still root
+  extractConfigInfo(mgmt_path, recs_conf, userToRunAs, &fds_throttle);
+
+  set_process_limits(fds_throttle); // as root
+  runAsUser(userToRunAs);
+  setup_coredump();
+  check_lockfile();
+
+  url_init();
+  mime_init();
+  http_init();
+
+#if TS_HAS_WCCP
+  Init_Errata_Logging();
+#endif
+  ts_host_res_global_init();
+  ts_session_protocol_well_known_name_indices_init();
+  lmgmt = new LocalManager(proxy_on);
+  RecLocalInitMessage();
+  lmgmt->initAlarm();
+
+  if (diags) {
+    delete diagsConfig;
+    // diagsConfig->reconfigure_diags(); INKqa11968
+    /*
+       delete diags;
+       diags = new Diags(debug_tags,action_tags);
+     */
+  }
+  // INKqa11968: need to set up callbacks and diags data structures
+  // using configuration in records.config
+  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, 
true);
+  diags = diagsConfig->diags;
+  RecSetDiags(diags);
+  diags->prefix_str = "Manager ";
+
+  if (is_debug_tag_set("diags"))
+    diags->dump();
+  diags->cleanup_func = mgmt_cleanup;
+
+  // Setup the exported manager version records.
+  RecSetRecordString("proxy.node.version.manager.short", 
appVersionInfo.VersionStr);
+  RecSetRecordString("proxy.node.version.manager.long", 
appVersionInfo.FullVersionInfoStr);
+  RecSetRecordString("proxy.node.version.manager.build_number", 
appVersionInfo.BldNumStr);
+  RecSetRecordString("proxy.node.version.manager.build_time", 
appVersionInfo.BldTimeStr);
+  RecSetRecordString("proxy.node.version.manager.build_date", 
appVersionInfo.BldDateStr);
+  RecSetRecordString("proxy.node.version.manager.build_machine", 
appVersionInfo.BldMachineStr);
+  RecSetRecordString("proxy.node.version.manager.build_person", 
appVersionInfo.BldPersonStr);
+//    RecSetRecordString("proxy.node.version.manager.build_compile_flags",
+//                       appVersionInfo.BldCompileFlagsStr);
+
+  if (log_to_syslog) {
+    char sys_var[] = "proxy.config.syslog_facility";
+    char *facility_str = NULL;
+    int facility_int;
+    facility_str = REC_readString(sys_var, &found);
+    ink_assert(found);
+
+    if (!found) {
+      mgmt_elog(0, "Could not read %s.  Defaulting to DAEMON\n", sys_var);
+      facility_int = LOG_DAEMON;
+    } else {
+      facility_int = facility_string_to_int(facility_str);
+      ats_free(facility_str);
+      if (facility_int < 0) {
+        mgmt_elog(0, "Bad syslog facility specified.  Defaulting to DAEMON\n");
+        facility_int = LOG_DAEMON;
+      }
+    }
+
+    // NOTE: do NOT call closelog() here.  Solaris gets confused
+    //   and some how it hoses later calls to readdir_r.
+    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, 
facility_int);
+
+    lmgmt->syslog_facility = facility_int;
+  } else {
+    lmgmt->syslog_facility = -1;
+  }
+
+  // Find out our hostname so we can use it as part of the initialization
+  setHostnameVar();
+
+  // Create the data structure for overview page
+  //   Do this before the rest of the set up since it needs
+  //   to created to handle any alarms thrown by later
+  //   initialization
+  overviewGenerator = new overviewPage();
+
+  // Initialize the Config Object bindings before
+  //   starting any other threads
+  lmgmt->configFiles = configFiles = new FileManager();
+  initializeRegistry();
+  configFiles->registerCallback(fileUpdated);
+
+  // RecLocal's 'sync_thr' depends on 'configFiles', so we can't
+  // stat the 'sync_thr' until 'configFiles' has been initialized.
+  RecLocalStart(configFiles);
+
+  /* Update cmd line overrides/environmental overrides/etc */
+  if (tsArgs) {                 /* Passed command line args for proxy */
+    ats_free(lmgmt->proxy_options);
+    lmgmt->proxy_options = tsArgs;
+    mgmt_log(stderr, "[main] Traffic Server Args: '%s'\n", 
lmgmt->proxy_options);
+  }
+  if (proxy_port) {
+    HttpProxyPort::loadValue(lmgmt->m_proxy_ports, proxy_port);
+  }
+
+  if (proxy_backdoor != -1) {
+    RecSetRecordInt("proxy.config.process_manager.mgmt_port", proxy_backdoor);
+  }
+
+  if (cluster_rsport == -1) {
+    cluster_rsport = REC_readInteger("proxy.config.cluster.rsport", &found);
+    ink_assert(found);
+  }
+
+  if (cluster_mcport == -1) {
+    cluster_mcport = REC_readInteger("proxy.config.cluster.mcport", &found);
+    ink_assert(found);
+  }
+
+  if (!group_addr) {
+    group_addr = REC_readString("proxy.config.cluster.mc_group_addr", &found);
+    ink_assert(found);
+  }
+
+  in_addr_t min_ip = inet_network("224.0.0.255");
+  in_addr_t max_ip = inet_network("239.255.255.255");
+  in_addr_t group_addr_ip = inet_network(group_addr);
+
+  if (!(min_ip < group_addr_ip && group_addr_ip < max_ip)) {
+    mgmt_fatal(0, "[TrafficManager] Multi-Cast group addr '%s' is not in the 
permitted range of %s\n",
+               group_addr, "224.0.1.0 - 239.255.255.255");
+  }
+
+  /* TODO: Do we really need to init cluster communication? */
+  lmgmt->initCCom(appVersionInfo, configFiles, cluster_mcport, group_addr, 
cluster_rsport);       /* Setup cluster communication */
+
+  lmgmt->initMgmtProcessServer();       /* Setup p-to-p process server */
+
+  // Now that we know our cluster ip address, add the
+  //   UI record for this machine
+  overviewGenerator->addSelfRecord();
+
+  lmgmt->listenForProxy();
+
+  //
+  // As listenForProxy() may change/restore euid, we should put
+  // the creation of webIntr_main thread after it. So that we
+  // can keep a consistent euid when create mgmtapi/eventapi unix
+  // sockets in webIntr_main thread.
+  //
+  webThrId = ink_thread_create(webIntr_main, NULL);     /* Spin web agent 
thread */
+  Debug("lm", "Created Web Agent thread (%"  PRId64 ")", (int64_t)webThrId);
+
+  ticker = time(NULL);
+  mgmt_log("[TrafficManager] Setup complete\n");
+
+  statProcessor = new StatProcessor(configFiles);
+
+  for (;;) {
+    lmgmt->processEventQueue();
+    lmgmt->pollMgmtProcessServer();
+
+    // Check for a SIGHUP
+    if (sigHupNotifier != 0) {
+      mgmt_log(stderr, "[main] Reading Configuration Files due to SIGHUP\n");
+      configFiles->rereadConfig();
+      lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, "*");
+      sigHupNotifier = 0;
+      mgmt_log(stderr, "[main] Reading Configuration Files Reread\n");
+    }
+    // Check for SIGUSR2
+    if (sigUsr2Notifier != 0) {
+      ink_stack_trace_dump();
+      sigUsr2Notifier = 0;
+    }
+
+    lmgmt->ccom->generateClusterDelta();
+
+    if (lmgmt->run_proxy && lmgmt->processRunning()) {
+      lmgmt->ccom->sendSharedData();
+      lmgmt->virt_map->lt_runGambit();
+    } else {
+      if (!lmgmt->run_proxy) {  /* Down if we are not going to start another 
immed. */
+        /* Proxy is not up, so no addrs should be */
+        lmgmt->virt_map->downOurAddrs();
+      }
+
+      /* Proxy is not up, but we should still exchange config and alarm info */
+      lmgmt->ccom->sendSharedData(false);
+    }
+
+    lmgmt->ccom->checkPeers(&ticker);
+    overviewGenerator->checkForUpdates();
+
+    if (statProcessor) {
+      statProcessor->processStat();
+    }
+
+    if (lmgmt->mgmt_shutdown_outstanding == true) {
+      lmgmt->mgmtShutdown(true);
+      _exit(0);
+    }
+
+    if (lmgmt->run_proxy && !lmgmt->processRunning()) { /* Make sure we still 
have a proxy up */
+      if (lmgmt->startProxy())
+        just_started = 0;
+      else
+        just_started++;
+    } else {                    /* Give the proxy a chance to fire up */
+      just_started++;
+    }
+
+    /* This will catch the case were the proxy dies before it can connect to 
manager */
+    if (lmgmt->proxy_launch_outstanding && !lmgmt->processRunning() && 
just_started >= 120) {
+      just_started = 0;
+      lmgmt->proxy_launch_outstanding = false;
+      if (lmgmt->proxy_launch_pid != -1) {
+        int res;
+        kill(lmgmt->proxy_launch_pid, 9);
+        waitpid(lmgmt->proxy_launch_pid, &res, 0);
+        if (WIFSIGNALED(res)) {
+          int sig = WTERMSIG(res);
+#ifdef NEED_PSIGNAL
+          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d\n", sig);
+#else
+          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d: %s\n", sig, 
strsignal(sig));
+#endif /* NEED_PSIGNAL */
+        }
+      }
+      mgmt_log(stderr, "[main] Proxy launch failed, retrying...\n");
+    }
+
+  }
+
+  if (statProcessor) {
+    delete(statProcessor);
+  }
+
+#ifndef MGMT_SERVICE
+  return 0;
+#endif
+
+}                               /* End main */
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+static void
+SignalAlrmHandler(int /* sig ATS_UNUSED */, siginfo_t * t, void * /* c 
ATS_UNUSED */)
+#else
+static void
+SignalAlrmHandler(int /* sig ATS_UNUSED */)
+#endif
+{
+  /*
+     fprintf(stderr, "[TrafficManager] ==> SIGALRM received\n");
+     mgmt_elog(stderr, 0, "[TrafficManager] ==> SIGALRM received\n");
+   */
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  if (t) {
+    if (t->si_code <= 0) {
+#if defined(solaris)
+      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: 
%d\n", (int)t->si_pid, t->si_uid);
+#else
+      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: 
%d\n", t->si_pid, t->si_uid);
+#endif
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Alarm from pid: %d uid: 
%d\n", t->si_pid, t->si_uid);
+    } else {
+      fprintf(stderr, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", 
t->si_code);
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", 
t->si_code);
+    }
+  }
+#endif
+
+  return;
+}
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+static void
+SignalHandler(int sig, siginfo_t * t, void *c)
+#else
+static void
+SignalHandler(int sig)
+#endif
+{
+  static int clean = 0;
+  int status;
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  if (t) {
+    if (t->si_code <= 0) {
+#if defined(solaris)
+      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: 
%d\n", sig, (int)t->si_pid, t->si_uid);
+#else
+      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: 
%d\n", sig, t->si_pid, t->si_uid);
+#endif
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Sig %d from pid: %d uid: 
%d\n", sig, t->si_pid, t->si_uid);
+    } else {
+      fprintf(stderr, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, 
t->si_code);
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", 
sig, t->si_code);
+    }
+  }
+#endif
+
+  if (sig == SIGHUP) {
+    sigHupNotifier = 1;
+    return;
+  }
+
+  if (sig == SIGUSR2) {
+    sigUsr2Notifier = 1;
+    return;
+  }
+  fprintf(stderr, "[TrafficManager] ==> Cleaning up and reissuing signal 
#%d\n", sig);
+  mgmt_elog(stderr, 0, "[TrafficManager] ==> Cleaning up and reissuing signal 
#%d\n", sig);
+
+  if (lmgmt && !clean) {
+    clean = 1;
+    if (lmgmt->watched_process_pid != -1) {
+
+      if (sig == SIGTERM || sig == SIGINT) {
+        kill(lmgmt->watched_process_pid, sig);
+        waitpid(lmgmt->watched_process_pid, &status, 0);
+      }
+    }
+    lmgmt->mgmtCleanup();
+  }
+
+  switch (sig) {
+  case SIGQUIT:
+  case SIGILL:
+  case SIGTRAP:
+#if !defined(linux)
+  case SIGEMT:
+  case SIGSYS:
+#endif
+  case SIGFPE:
+  case SIGBUS:
+  case SIGSEGV:
+  case SIGXCPU:
+  case SIGXFSZ:
+    abort();
+  default:
+    fprintf(stderr, "[TrafficManager] ==> signal #%d\n", sig);
+    mgmt_elog(stderr, 0, "[TrafficManager] ==> signal #%d\n", sig);
+    _exit(sig);
+  }
+  fprintf(stderr, "[TrafficManager] ==> signal2 #%d\n", sig);
+  mgmt_elog(stderr, 0, "[TrafficManager] ==> signal2 #%d\n", sig);
+  _exit(sig);
+}                               /* End SignalHandler */
+
+// void SigChldHandler(int sig)
+//
+//   An empty handler needed so that we catch SIGCHLD
+//    With Solaris 2.6, ignoring sig child changes the behavior
+//    of waitpid() so that if there are no unwaited children,
+//    waitpid() blocks until all child are transformed into
+//    zombies which is bad for us
+//
+static void
+SigChldHandler(int /* sig ATS_UNUSED */)
+{
+}
+
+void
+printUsage()
+{
+  fprintf(stderr, 
"----------------------------------------------------------------------------\n");
+  fprintf(stderr, " Traffic Manager Usage: (all args are optional)\n");
+  fprintf(stderr, "\n");
+  fprintf(stderr, "   traffic_manager [options]\n");
+  fprintf(stderr, "     -proxyPort     <port>  Port to have proxy listen on, 
overrides records.config.\n");
+  /* Function is currently #ifdef'ed out so no reason to advertise
+     fprintf(stderr,
+     "     -proxyBackdoor <port>  Port to put proxy mgmt port on.\n");
+   */
+  /* Commented out because this option is used for debugging only.
+     fprintf(stderr,
+     "     -noProxy               Do not launch the proxy process.\n");
+   */
+  fprintf(stderr, "     -tsArgs        [...]   Args to proxy, everything till 
eol is passed.\n");
+  fprintf(stderr, "     -webPort       <port>  Port for web interface.\n");
+  /*
+     fprintf(stderr,
+     "     -graphPort     <port>  Port for dynamic graphs.\n");
+   */
+  fprintf(stderr, "     -clusterPort   <port>  Cluster Multicast port\n");
+  fprintf(stderr, "     -groupAddr     <addr>  Cluster Multicast group, 
example: \"225.0.0.37\".\n");
+  fprintf(stderr, "     -clusterRSPort <port>  Cluster Multicast port.\n");
+  fprintf(stderr, "     -path          <path>  Root path for config files.\n");
+  /*
+     fprintf(stderr,
+     "     -lmConf        <fname> Local Management config file.\n");
+   */
+  fprintf(stderr, "     -recordsConf   <fname> General config file.\n");
+  // TODO: This seems completely incomplete, disabled for now
+  // fprintf(stderr, "     -printRecords  [...]   Print flags, default all are 
off.\n");
+  fprintf(stderr, "     -debug         <tags>  Enable the given debug tags\n");
+  fprintf(stderr, "     -action        <tags>  Enable the given action 
tags.\n");
+  fprintf(stderr, "     -version or -V         Print version id and exit.\n");
+  fprintf(stderr, "\n");
+  fprintf(stderr, "   [...] can be one+ of: [config process node cluster local 
all]\n");
+  fprintf(stderr, 
"----------------------------------------------------------------------------\n");
+  exit(0);
+}                               /* End printUsage */
+
+void
+fileUpdated(char *fname, bool incVersion)
+{
+  if (strcmp(fname, "cluster.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cluster.cluster_configuration");
+
+  } else if (strcmp(fname, "remap.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.url_remap.filename");
+
+  } else if (strcmp(fname, "socks.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.socks.socks_config_file");
+
+  } else if (strcmp(fname, "records.config") == 0) {
+    lmgmt->signalFileChange("records.config", incVersion);
+
+  } else if (strcmp(fname, "cache.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cache.control.filename");
+
+  } else if (strcmp(fname, "parent.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.http.parent_proxy.file");
+
+  } else if (strcmp(fname, "ip_allow.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cache.ip_allow.filename");
+  } else if (strcmp(fname, "vaddrs.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] vaddrs.config updated\n");
+    lmgmt->virt_map->lt_readAListFile(fname);
+
+  } else if (strcmp(fname, "storage.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] storage.config changed, need restart 
auto-rebuild mode\n");
+
+  } else if (strcmp(fname, "proxy.pac") == 0) {
+    mgmt_log(stderr, "[fileUpdated] proxy.pac file has been modified\n");
+
+  } else if (strcmp(fname, "icp.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.icp.icp_configuration");
+
+  } else if (strcmp(fname, "update.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.update.update_configuration");
+
+  } else if (strcmp(fname, "volume.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] volume.config changed, need restart\n");
+
+  } else if (strcmp(fname, "hosting.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cache.hosting_filename");
+
+  } else if (strcmp(fname, "log_hosts.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.log.hosts_config_file");
+
+  } else if (strcmp(fname, "logs_xml.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.log.xml_config_file");
+
+  } else if (strcmp(fname, "splitdns.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.dns.splitdns.filename");
+
+  } else if (strcmp(fname, "plugin.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] plugin.config file has been modified\n");
+
+  } else if (strcmp(fname, "ssl_multicert.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.ssl.server.multicert.filename");
+
+  } else if (strcmp(fname, "proxy.config.body_factory.template_sets_dir") == 
0) {
+    lmgmt->signalFileChange("proxy.config.body_factory.template_sets_dir");
+
+  } else if (strcmp(fname, "stats.config.xml") == 0) {
+    if (statProcessor) {
+      statProcessor->rereadConfig(configFiles);
+    }
+    mgmt_log(stderr, "[fileUpdated] stats.config.xml file has been 
modified\n");
+  } else if (strcmp(fname, "congestion.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.http.congestion_control.filename");
+  } else if (strcmp(fname, "prefetch.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.prefetch.config_file");
+  } else {
+    mgmt_elog(stderr, 0, "[fileUpdated] Unknown config file updated '%s'\n", 
fname);
+
+  }
+  return;
+}                               /* End fileUpdate */
+
+#if TS_USE_POSIX_CAP
+/** Restore capabilities after user id change.
+    This manipulates LINUX capabilities so that this process
+    can perform certain privileged operations even if it is
+    no longer running as a privilege user.
+
+    @internal
+    I tried using
+    @code
+    prctl(PR_SET_KEEPCAPS, 1);
+    @endcode
+    but that had no effect even though the call reported success.
+    Only explicit capability manipulation was effective.
+
+    It does not appear to be necessary to set the capabilities on the
+    executable if originally run as root. That may be needed if
+    started as a user without that capability.
+ */
+
+int
+restoreCapabilities() {
+  int zret = 0; // return value.
+  cap_t cap_set = cap_get_proc(); // current capabilities
+  // Make a list of the capabilities we want turned on.
+  cap_value_t cap_list[] = {
+    CAP_NET_ADMIN, ///< Set socket transparency.
+    CAP_NET_BIND_SERVICE, ///< Low port (e.g. 80) binding.
+    CAP_IPC_LOCK ///< Lock IPC objects.
+  };
+  static int const CAP_COUNT = sizeof(cap_list)/sizeof(*cap_list);
+
+  cap_set_flag(cap_set, CAP_EFFECTIVE, CAP_COUNT, cap_list, CAP_SET);
+  zret = cap_set_proc(cap_set);
+  cap_free(cap_set);
+  return zret;
+}
+#endif
+
+//  void runAsUser(...)
+//
+//  If we are root, switched to user to run as
+//    specified in records.config
+//
+//  If we are not root, do nothing
+//
+void
+runAsUser(char *userName)
+{
+  uid_t uid, euid;
+  struct passwd *result;
+  const int bufSize = 1024;
+  char buf[bufSize];
+
+  uid = getuid();
+  euid = geteuid();
+
+  if (uid == 0 || euid == 0) {
+
+    /* Figure out what user we should run as */
+
+    Debug("lm", "[runAsUser] Attempting to run as user '%s'\n", userName);
+
+    if (userName == NULL || userName[0] == '\0') {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: 
proxy.config.admin.user_id is not set\n");
+      _exit(1);
+    }
+
+    struct passwd passwdInfo;
+    struct passwd *ppasswd = NULL;
+    result = NULL;
+    int res;
+    if (*userName == '#') {
+      int uuid = atoi(userName + 1);
+      if (uuid == -1)
+        uuid = (int)uid;
+      res = getpwuid_r((uid_t)uuid, &passwdInfo, buf, bufSize, &ppasswd);
+    }
+    else {
+      res = getpwnam_r(&userName[0], &passwdInfo, buf, bufSize, &ppasswd);
+    }
+
+    if (!res && ppasswd) {
+      result = ppasswd;
+    }
+
+    if (result == NULL) {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to get info about 
user %s : %s\n", userName, strerror(errno));
+      _exit(1);
+    }
+
+    if (setegid(result->pw_gid) != 0 || seteuid(result->pw_uid) != 0) {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to switch to user 
%s : %s\n", userName, strerror(errno));
+      _exit(1);
+    }
+
+    uid = getuid();
+    euid = geteuid();
+
+    Debug("lm", "[runAsUser] Running with uid: '%d' euid: '%d'\n", uid, euid);
+
+    if (uid != result->pw_uid && euid != result->pw_uid) {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Failed to switch to user 
%s\n", userName);
+      _exit(1);
+    }
+
+    // setup supplementary groups if it is not set.
+    if (0 == getgroups(0, NULL)) {
+      initgroups(&userName[0],result->pw_gid);
+    }
+
+#if TS_USE_POSIX_CAP
+    if (0 != restoreCapabilities()) {
+      mgmt_elog(stderr, 0, "[runAsUser] Error: Failed to restore capabilities 
after switch to user %s.\n", userName);
+    }
+#endif
+
+  }
+}                               /* End runAsUser() */
+
+//  void extractConfigInfo(...)
+//
+//  We need to get certain records.config values while we are
+//   root.  We can not use LMRecords to get them because the constructor
+//   for LMRecords creates the mgmt DBM and we do not want that to
+//   be owned as root.  This function extracts that info from
+//   records.config
+//
+//
+void
+extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int 
*fds_throttle)
+{
+  char file[1024];
+  bool useridFound = false;
+  bool throttleFound = false;
+
+  /* Figure out what user we should run as */
+  if (mgmt_path && recs_conf) {
+    FILE *fin;
+    snprintf(file, sizeof(file), "%s/%s.shadow", mgmt_path, recs_conf);
+    if (!(fin = fopen(file, "r"))) {
+      ink_filepath_make(file, sizeof(file), mgmt_path, recs_conf);
+      if (!(fin = fopen(file, "r"))) {
+        mgmt_elog(stderr, errno, "[extractConfigInfo] Unable to open config 
file(%s)\n", file);
+        _exit(1);
+      }
+    }
+    // Get 'user id' and 'network connections throttle limit'
+    while (((!useridFound) || (!throttleFound)) && fgets(file, 1024, fin)) {
+      if (strstr(file, "CONFIG proxy.config.admin.user_id STRING")) {
+        //coverity[secure_coding]
+        if ((sscanf(file, "CONFIG proxy.config.admin.user_id STRING %1023s\n", 
userName) == 1) &&
+            strcmp(userName, "NULL") != 0) {
+          useridFound = true;
+        }
+      } else if (strstr(file, "CONFIG proxy.config.net.connections_throttle 
INT")) {
+        if ((sscanf(file, "CONFIG proxy.config.net.connections_throttle INT 
%d\n", fds_throttle) == 1)) {
+          throttleFound = true;
+        }
+      }
+
+    }
+    fclose(fin);
+  } else {
+    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: unable to access 
records file\n");
+    _exit(1);
+  }
+
+  if (useridFound == false) {
+    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: 
proxy.config.admin.user_id is not set\n");
+    _exit(1);
+  }
+
+}                               /* End extractConfigInfo() */

Reply via email to