int main(int argc, char **argv) {
  GError *error = NULL;
  GOptionContext *context = NULL;
  uid_t orig_uid = -1;
  gid_t orig_gid = -1;
  EscalateHelper *helper = NULL;
  int exit_code = 2;

  clearenv();
  umask(0077);

  context = g_option_context_new("- helper for pam_escalate.so");
  if (!g_option_context_parse(context, &argc, &argv, &error)) {
    goto done;
  }

  if (argc > 1) {
    g_set_error(&error, ESCALATE_HELPER_ERROR, ESCALATE_HELPER_ERROR_EXTRA_ARGS,
                "Non-flag arguments are not accepted");
    goto done;
  }

  orig_uid = getuid();
  orig_gid = getgid();

  if (orig_uid != geteuid()) {
    if (setuid(geteuid())) {
      g_error("setuid() failed: %s", g_strerror(errno));
    }
  }

  if (orig_gid != getegid()) {
    if (setgid(getegid())) {
      g_error("setgid() failed: %s", g_strerror(errno));
    }
  }

  helper = EscalateHelperNew(STDIN_FILENO, STDOUT_FILENO, orig_uid, orig_gid);

  if (!EscalateHelperHandleStart(helper, &error)) {
    goto done;
  }

  if (EscalateHelperDoAction(helper, &error)) {
    exit_code = 0;
  } else {
    exit_code = 1;
  }

done:
  if (error) {
    g_printerr("Caught error: %s\n", error->message);
    g_error_free(error);
  }
  EscalateHelperFree(helper);
  return exit_code;
}
static gpointer RunHelperThreadFunc(EscalateHelper *helper) {
  GError *error = NULL;

  if (!EscalateHelperHandleStart(helper, &error)) {
    g_print("EscalateHelperHandleStart failed: %s (%s, %d)", error->message,
              g_quark_to_string(error->domain), error->code);
    goto done;
  }

  if (!EscalateHelperDoAction(helper, &error)) {
    g_print("EscalateHelperDoAction failed: %s (%s, %d)", error->message,
              g_quark_to_string(error->domain), error->code);
    goto done;
  }

done:
  g_io_channel_shutdown(helper->reader, FALSE, NULL);
  g_io_channel_shutdown(helper->writer, FALSE, NULL);
  return NULL;
}