Commit a6169800 authored by Brendan C's avatar Brendan C Committed by Nick Mathewson
Browse files

Fix bug 3842: add a GETINFO signal/names

Also refactor SIGNAL so that it and signal/names use the same table.

(commit message by nickm)
parent 12298901
Loading
Loading
Loading
Loading
+44 −19
Original line number Diff line number Diff line
@@ -1244,6 +1244,27 @@ handle_control_saveconf(control_connection_t *conn, uint32_t len,
  return 0;
}

struct signal_t {
  int sig;
  const char *signal_name;
};

static const struct signal_t signal_table[] = {
  { SIGHUP, "RELOAD" },
  { SIGHUP, "HUP" },
  { SIGINT, "SHUTDOWN" },
  { SIGUSR1, "DUMP" },
  { SIGUSR1, "USR1" },
  { SIGUSR2, "DEBUG" },
  { SIGUSR2, "USR2" },
  { SIGTERM, "HALT" },
  { SIGTERM, "TERM" },
  { SIGTERM, "INT" },
  { SIGNEWNYM, "NEWNYM" },
  { SIGCLEARDNSCACHE, "CLEARDNSCACHE"},
  { 0, NULL },
};

/** Called when we get a SIGNAL command. React to the provided signal, and
 * report success or failure. (If the signal results in a shutdown, success
 * may not be reported.) */
@@ -1251,7 +1272,8 @@ static int
handle_control_signal(control_connection_t *conn, uint32_t len,
                      const char *body)
{
  int sig;
  int sig = -1;
  int i;
  int n = 0;
  char *s;

@@ -1260,25 +1282,17 @@ handle_control_signal(control_connection_t *conn, uint32_t len,
  while (body[n] && ! TOR_ISSPACE(body[n]))
    ++n;
  s = tor_strndup(body, n);
  if (!strcasecmp(s, "RELOAD") || !strcasecmp(s, "HUP"))
    sig = SIGHUP;
  else if (!strcasecmp(s, "SHUTDOWN") || !strcasecmp(s, "INT"))
    sig = SIGINT;
  else if (!strcasecmp(s, "DUMP") || !strcasecmp(s, "USR1"))
    sig = SIGUSR1;
  else if (!strcasecmp(s, "DEBUG") || !strcasecmp(s, "USR2"))
    sig = SIGUSR2;
  else if (!strcasecmp(s, "HALT") || !strcasecmp(s, "TERM"))
    sig = SIGTERM;
  else if (!strcasecmp(s, "NEWNYM"))
    sig = SIGNEWNYM;
  else if (!strcasecmp(s, "CLEARDNSCACHE"))
    sig = SIGCLEARDNSCACHE;
  else {

  for (i = 0; signal_table[i].signal_name != NULL; ++i) {
    if (!strcasecmp(s, signal_table[i].signal_name)) {
      sig = signal_table[i].sig;
      break;
    }
  }

  if (sig < 0)
    connection_printf_to_buf(conn, "552 Unrecognized signal code \"%s\"\r\n",
                             s);
    sig = -1;
  }
  tor_free(s);
  if (sig < 0)
    return 0;
@@ -1432,6 +1446,16 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
    *answer = smartlist_join_strings(event_names, " ", 0, NULL);

    smartlist_free(event_names);
  } else if (!strcmp(question, "signal/names")) {
    smartlist_t *signal_names = smartlist_new();
    int j;
    for (j = 0; signal_table[j].signal_name != NULL; ++j) {
      smartlist_add(signal_names, (char*)signal_table[j].signal_name);
    }

    *answer = smartlist_join_strings(signal_names, " ", 0, NULL);

    smartlist_free(signal_names);
  } else if (!strcmp(question, "features/names")) {
    *answer = tor_strdup("VERBOSE_NAMES EXTENDED_EVENTS");
  } else if (!strcmp(question, "address")) {
@@ -2130,6 +2154,7 @@ static const getinfo_item_t getinfo_items[] = {
       "List of GETINFO options, types, and documentation."),
  ITEM("events/names", misc,
       "Events that the controller can ask for with SETEVENTS."),
  ITEM("signal/names", misc, "Signal names recognized by the SIGNAL command"),
  ITEM("features/names", misc, "What arguments can USEFEATURE take?"),
  PREFIX("desc/id/", dir, "Router descriptors by ID."),
  PREFIX("desc/name/", dir, "Router descriptors by nickname."),