示例#1
0
int load_plugin_cmd(struct katcp_dispatch *d, int argc)
{
  int i;
  int result;
  int n_cmds;
  char *name;
  char *error;
  void *module, *i_module;
  char *plugin_name, *i_plugin_name;
  char *plugin_vers, *i_plugin_vers;

  struct PLUGIN *plugin_info;
  struct PLUGIN *i_plugin_info;
  struct PLUGIN_CMD *plugin_cmds;

  int (* plugin_init)(struct katcp_dispatch *d, int argc);

  /* Get the filename of the plugin to load */
  name = arg_string_katcp(d, 1);
  if(name == NULL){
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "internal failure while acquiring parameters");
    return KATCP_RESULT_FAIL;
  }

  /* Load dynamic library */
  module = dlopen(name, RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND);
  if (!module) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "could not open shared object: %s", dlerror());
    return KATCP_RESULT_FAIL;
  }
 
  /* Get plugin info */
  plugin_info = dlsym(module, "KATCP_PLUGIN");
  error = dlerror();
  if (error) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "could not find symbol");
    dlclose(module); /* make sure to close on failure */
    return KATCP_RESULT_FAIL;
  }

  /* Get the plugin name */
  plugin_name = plugin_info->name;
  if (plugin_name == NULL) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "plugin name not set");
    dlclose(module); /* make sure to close on failure */
    return KATCP_RESULT_FAIL;
  }

  /* Get the plugin version */
  plugin_vers = plugin_info->version;
  if (plugin_vers == NULL) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "plugin version not set");
    dlclose(module); /* make sure to close on failure */
    return KATCP_RESULT_FAIL;
  }

  /* Check if we've already loaded this plugin */
  for (i=0; i<N_LOADED_PLUGINS; i++) {
    i_module = LOADED_PLUGINS[i];

    /* Get plugin info (no error checking needed)*/
    i_plugin_info = dlsym(i_module, "KATCP_PLUGIN");
    i_plugin_name = i_plugin_info->name;
    i_plugin_vers = i_plugin_info->version;

    if (strcmp(plugin_name, i_plugin_name) == 0) {
      log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "%s(%s) already loaded!", i_plugin_name, i_plugin_vers);
      dlclose(module); /* make sure to close on failure */
      return KATCP_RESULT_FAIL;
    }
  }

  /* Get the init if available */
  plugin_init = plugin_info->init;
  if (plugin_init == NULL) {
    log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "no plugin init function found");
  } else {
    /* Call init before loading commands */
    if (plugin_init(d, argc) != 0) {
      log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem while initializing");
      dlclose(module); /* make sure to close on failure */
      return KATCP_RESULT_FAIL;
    }
  }

  /* Get total commands available */
  n_cmds = plugin_info->n_cmds;
  if (n_cmds == 0) {
    log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "plugin says no commands available");
  }

  /* Get array of functions */
  plugin_cmds = plugin_info->cmd_array;
  if (plugin_cmds == NULL) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "no commands found");
  }

  /* Load commands into tcpborphserver */
  for (i=0; i<n_cmds; i++) {
    struct PLUGIN_CMD cmd = plugin_cmds[i];
    log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "found command: %s", cmd.name);
    result = register_flag_mode_katcp(d, cmd.name, cmd.desc, cmd.cmd, 0, TBS_MODE_RAW);
    if (result) {
      log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "error loading: ", cmd.name);
      dlclose(module); /* make sure to close on failure */
      return KATCP_RESULT_FAIL;
    }
  }

  /* Expand the plugins list */
  void **temp = realloc(LOADED_PLUGINS, (N_LOADED_PLUGINS+1) * sizeof(void *));
  if (temp == NULL) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem reallocing plugins list");
    dlclose(module); /* make sure to close on failure */
    return KATCP_RESULT_FAIL;
  }

  /* Add our module to new list */
  LOADED_PLUGINS = temp;
  LOADED_PLUGINS[N_LOADED_PLUGINS] = module;

  /* And finally increment the plugins counter */
  N_LOADED_PLUGINS++;

  return extra_response_katcp(d, KATCP_RESULT_OK, "%d commands loaded successfully", n_cmds);
}
示例#2
0
文件: upload.c 项目: gitj/katcp_devel
int upload_cmd(struct katcp_dispatch *d, int argc)
{
  struct katcp_dispatch *dl;
  struct katcp_job *j;
  struct katcp_url *url;
  struct tbs_port_data *pd;
  char *rtn;

  dl = template_shared_katcp(d);

  pd = create_port_data_tbs();
  if (pd == NULL){
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: couldn't create port data", __func__);
    return KATCP_RESULT_FAIL;
  }

#ifdef DEBUG
  fprintf(stderr, "%s: with %d args\n", __func__, argc);
#endif
 
  switch (argc){

    case 1:
      pd->t_port = 7146;

    case 2:
      rtn = arg_string_katcp(d, 1);

      if (rtn != NULL)
        pd->t_port = atoi(rtn);

      url = create_exec_kurl_katcp("upload");
      if (url == NULL){
        log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: could not create kurl", __func__);
        destroy_port_data_tbs(pd);
        return KATCP_RESULT_FAIL;
      }

      j = find_job_katcp(dl, url->u_str);
      if (j){
        log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: found job for %s", __func__, url->u_str);
        destroy_kurl_katcp(url);
        destroy_port_data_tbs(pd);
        return KATCP_RESULT_FAIL;
      }

      j = run_child_process_tbs(dl, url, &upload_tbs, pd, NULL);
      if (j == NULL){
        log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: run child process returned null for %s", __func__ , url->u_str);
        destroy_kurl_katcp(url);
        destroy_port_data_tbs(pd);
        return KATCP_RESULT_FAIL;
      }
      
      if (match_inform_job_katcp(dl, j, UPLOADCOMPLETE, &upload_complete_tbs, pd) < 0){
        log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: match inform for job %s failed", __func__, url->u_str);
        zap_job_katcp(dl,j);
        destroy_port_data_tbs(pd);
        return KATCP_RESULT_FAIL;
      }
      break; 
  }
  
  extra_response_katcp(d, KATCP_RESULT_OK, "%d", pd->t_port);

  return KATCP_RESULT_OWN;
}
示例#3
0
int unload_plugin_cmd(struct katcp_dispatch *d, int argc)
{
  int i, j, k;
  int past = 0;
  int found = 0;
  int result;
  int n_cmds;
  char *name;
  void *module;
  char *plugin_name;

  struct PLUGIN *plugin_info;
  struct PLUGIN_CMD *plugin_cmds;

  int (* plugin_uninit)(struct katcp_dispatch *d, int argc);

  /* Check if we haven't loaded any plugins */
  if (LOADED_PLUGINS == NULL) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "no plugins have been loaded");
    return KATCP_RESULT_FAIL;
  }

  /* Get the name of the plugin to unload */
  name = arg_string_katcp(d, 1);
  if(name == NULL){
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "internal failure while acquiring parameters");
    return KATCP_RESULT_FAIL;
  }

  for (i=0; i<N_LOADED_PLUGINS; i++) {
    module = LOADED_PLUGINS[i];

    /* Get plugin info (no error checking needed)*/
    plugin_info = dlsym(module, "KATCP_PLUGIN");
    plugin_name = plugin_info->name;

    if (strcmp(name, plugin_name) == 0) {
      /* Print info on each loaded module */
      log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "found plugin %s", plugin_name);
      found = 1;
      break;
    }
  }

  /* Get out if plugin hasn't been loaded */
  if (!found) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "plugin not found. cannot unload");
    return KATCP_RESULT_FAIL;
  }

  /* Get the uninit if available */
  plugin_uninit = plugin_info->uninit;
  if (plugin_uninit == NULL) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "no plugin uninit function found");
  } else {
    /* Call uninit before closing */
    if (plugin_uninit(d, argc) != 0) {
      log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem while uninitializing");
      return KATCP_RESULT_FAIL;
    }
  }

  /* Now deregister the katcp commands */
  n_cmds = plugin_info->n_cmds;
  plugin_cmds = plugin_info->cmd_array;
  for (j=0; j<n_cmds; j++) {
    struct PLUGIN_CMD cmd = plugin_cmds[j];
    result = deregister_command_katcp(d, cmd.name);
    if (result) {
      log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem deregistering: ", cmd.name);
      return KATCP_RESULT_FAIL;
    }
  }

  /* Now close the dynamic module */
  dlclose(module);

  /* Allocate new plugins list */
  void **temp = malloc((N_LOADED_PLUGINS-1) * sizeof(void *));
  if (temp == NULL) {
    log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem allocing plugins list");
    return KATCP_RESULT_FAIL;
  }

  /* Remove module from plugins list */
  for (k=0; k<N_LOADED_PLUGINS; k++) {
    if (k == i) {
      past = 1;
    } else {
      temp[k-past] = LOADED_PLUGINS[k];
    }
  }
  free(LOADED_PLUGINS);
  LOADED_PLUGINS = temp;

  /* And finally decrement the plugins counter */
  N_LOADED_PLUGINS--;

  return extra_response_katcp(d, KATCP_RESULT_OK, "%s plugin unloaded", name);
}