Esempio n. 1
0
File: ctrls.c Progetto: OPSF/uClinux
static pr_ctrls_t *ctrls_prepare(ctrls_action_t *act) {
  pr_ctrls_t *ctrl = NULL;

  /* Sanity check */
  if (!act)
    return NULL;

  pr_block_ctrls();

  /* Get a blank ctrl object */
  ctrl = ctrls_new();

  /* Fill in the fields from the action object. */
  ctrl->ctrls_id = act->id;
  ctrl->ctrls_module = act->module;
  ctrl->ctrls_action = act->action;
  ctrl->ctrls_desc = act->desc;
  ctrl->ctrls_cb = act->action_cb;
  ctrl->ctrls_flags = act->flags;

  /* Add this to the "in use" list */
  ctrl->ctrls_next = ctrls_active_list;
  ctrls_active_list = ctrl;

  pr_unblock_ctrls();
  return ctrl;
}
Esempio n. 2
0
int pr_ctrls_register(const module *mod, const char *action,
    const char *desc, int (*cb)(pr_ctrls_t *, int, char **)) {
  ctrls_action_t *act = NULL, *acti = NULL;
  int act_id = -1;

  /* sanity checks */
  if (!action || !desc || !cb) {
    errno = EINVAL;
    return -1;
  }

  pr_trace_msg("ctrls", 3,
    "module '%s' registering handler for ctrl action '%s' (at %p)",
    mod ? mod->name : "(none)", action, cb);

  /* Block ctrls while we're doing this */
  pr_block_ctrls();

  /* Get a ctrl action object */
  act = ctrls_action_new();

  /* Randomly generate a unique random ID for this object */
  while (TRUE) {
    unsigned char have_id = FALSE;
    act_id = rand();

    /* Check the list for this ID */
    for (acti = ctrls_action_list; acti; acti = acti->next) {
      if (acti->id == act_id) {
        have_id = TRUE;
        break;
      }
    }

    if (!have_id)
      break;
  }

  act->next = NULL;
  act->id = act_id;
  act->action = pstrdup(ctrls_pool, action);
  act->desc = desc;
  act->module = mod;
  act->action_cb = cb;

  /* Add this to the list of "registered" actions */

  if (ctrls_action_list) {
    act->next = ctrls_action_list;
    ctrls_action_list->prev = act;
  }
  
  ctrls_action_list = act;

  pr_unblock_ctrls();

  return act_id;
}
Esempio n. 3
0
File: ctrls.c Progetto: OPSF/uClinux
int pr_ctrls_unregister(module *mod, const char *action) {
  ctrls_action_t *act = NULL;
  unsigned char have_action = FALSE;

  /* sanity checks */
  if (!action) {
    errno = EINVAL;
    return -1;
  }

  /* Make sure that ctrls are blocked while we're doing this */
  pr_block_ctrls();

  for (act = ctrls_action_list; act; act = act->next) {
    if (strcmp(act->action, action) == 0 &&
        (act->module == mod || mod == ANY_MODULE || mod == NULL)) {
      have_action = TRUE;

      /* Remove this object from the list of registered actions */
      if (act->prev)
        act->prev->next = act->next;

      else
        ctrls_action_list = act->next;

      if (act->next)
        act->next->prev = act->prev;

      /* Destroy this action. */
      destroy_pool(act->pool); 
    }
  }
  
  pr_unblock_ctrls();

  if (!have_action) {
    errno = ENOENT;
    return -1;
  }

  return 0;
}
Esempio n. 4
0
int pr_ctrls_unregister(module *mod, const char *action) {
  ctrls_action_t *act = NULL;
  unsigned char have_action = FALSE;

  /* Make sure that ctrls are blocked while we're doing this */
  pr_block_ctrls();

  for (act = ctrls_action_list; act; act = act->next) {
    if ((action == NULL || strcmp(act->action, action) == 0) &&
        (act->module == mod || mod == ANY_MODULE || mod == NULL)) {
      have_action = TRUE;

      /* Remove this object from the list of registered actions */
      if (act->prev) {
        act->prev->next = act->next;

      } else {
        ctrls_action_list = act->next;
      }

      if (act->next) {
        act->next->prev = act->prev;
      }

      pr_trace_msg("ctrls", 3,
        "module '%s' unregistering handler for ctrl action '%s'",
        mod ? mod->name : "(none)", act->action);

      /* Destroy this action. */
      destroy_pool(act->pool); 
    }
  }
  
  pr_unblock_ctrls();

  if (!have_action) {
    errno = ENOENT;
    return -1;
  }

  return 0;
}
Esempio n. 5
0
File: ctrls.c Progetto: OPSF/uClinux
static void ctrls_free(pr_ctrls_t *ctrl) {

  /* Make sure that ctrls are blocked while we're doing this */
  pr_block_ctrls();

  /* Remove this object from the active list */
  if (ctrl->ctrls_prev)
    ctrl->ctrls_prev->ctrls_next = ctrl->ctrls_next;

  else
    ctrls_active_list = ctrl->ctrls_next;

  if (ctrl->ctrls_next)
    ctrl->ctrls_next->ctrls_prev = ctrl->ctrls_prev;

  /* Clear its fields, and add it to the free list */
  ctrl->ctrls_next = NULL;
  ctrl->ctrls_prev = NULL;
  ctrl->ctrls_id = 0;
  ctrl->ctrls_module = NULL;
  ctrl->ctrls_action = NULL;
  ctrl->ctrls_cb = NULL;
  ctrl->ctrls_cb_retval = 1;
  ctrl->ctrls_flags = 0;

  if (ctrl->ctrls_tmp_pool) {
    destroy_pool(ctrl->ctrls_tmp_pool);
    ctrl->ctrls_tmp_pool = NULL;
  }

  ctrl->ctrls_cb_args = NULL;
  ctrl->ctrls_cb_resps = NULL;
  ctrl->ctrls_data = NULL;

  ctrl->ctrls_next = ctrls_free_list;
  ctrls_free_list = ctrl;

  pr_unblock_ctrls();
  return;
}
Esempio n. 6
0
File: ctrls.c Progetto: OPSF/uClinux
int pr_run_ctrls(module *mod, const char *action) {
  pr_ctrls_t *ctrl = NULL;

  /* Are ctrls blocked? */
  if (ctrls_blocked) {
    errno = EPERM;
    return -1;
  }

  for (ctrl = ctrls_active_list; ctrl; ctrl = ctrl->ctrls_next) {

    /* Be watchful of the various client-side flags.  Note: if
     * ctrl->ctrls_cl is ever NULL, it means there's a bug in the code.
     */
    if (ctrl->ctrls_cl->cl_flags != PR_CTRLS_CL_HAVEREQ)
      continue;

    /* Has this control been disabled? */
    if (ctrl->ctrls_flags & PR_CTRLS_ACT_DISABLED)
      continue;

    /* Is it time to trigger this ctrl? */
    if (!(ctrl->ctrls_flags & PR_CTRLS_REQUESTED))
      continue;

    if (ctrl->ctrls_when > time(NULL)) {
      ctrl->ctrls_flags |= PR_CTRLS_PENDING;
      pr_ctrls_add_response(ctrl, "request pending");
      continue;
    }

    if (action &&
        strcmp(ctrl->ctrls_action, action) == 0) {
      pr_log_debug(DEBUG7, "calling '%s' control handler", ctrl->ctrls_action);

      /* Invoke the callback, if the ctrl's action matches.  Unblock
       * ctrls before invoking the callback, then re-block them after the
       * callback returns.  This will allow the action handlers to use some
       * of the Controls API functions correctly.
       */
      pr_unblock_ctrls();
      ctrl->ctrls_cb_retval = ctrl->ctrls_cb(ctrl,
        (ctrl->ctrls_cb_args ? ctrl->ctrls_cb_args->nelts : 0),
        (ctrl->ctrls_cb_args ? (char **) ctrl->ctrls_cb_args->elts : NULL));
      pr_block_ctrls();

      if (ctrl->ctrls_cb_retval < 1) {
        ctrl->ctrls_flags &= ~PR_CTRLS_REQUESTED;
        ctrl->ctrls_flags &= ~PR_CTRLS_PENDING;
        ctrl->ctrls_flags |= PR_CTRLS_HANDLED;
      }

    } else if (!action) {
      pr_log_debug(DEBUG5, "calling '%s' control handler", ctrl->ctrls_action);

      /* If no action was given, invoke every callback */
      pr_unblock_ctrls();
      ctrl->ctrls_cb_retval = ctrl->ctrls_cb(ctrl,
        (ctrl->ctrls_cb_args ? ctrl->ctrls_cb_args->nelts : 0),
        (ctrl->ctrls_cb_args ? (char **) ctrl->ctrls_cb_args->elts : NULL));
      pr_block_ctrls();

      if (ctrl->ctrls_cb_retval < 1) {
        ctrl->ctrls_flags &= ~PR_CTRLS_REQUESTED;
        ctrl->ctrls_flags &= ~PR_CTRLS_PENDING;
        ctrl->ctrls_flags |= PR_CTRLS_HANDLED;
      }
    }
  }

  return 0;
}