server/filters.c
/* Register and load a filter. */
Register and load a filter.
Register and load a filter .
struct backend *
filter_register (struct backend *next, size_t index, const char *filename,
                 void *dl, struct nbdkit_filter *(*filter_init) (void))
{
  struct backend_filter *f;
  const struct nbdkit_filter *filter;
  size_t i, len;
  f = calloc (1, sizeof *f);
  if (f == NULL) {
  out_of_memory:
    perror ("strdup");
    exit (EXIT_FAILURE);
  }
  f->backend = filter_functions;
  f->backend.next = next;
  f->backend.i = index;
  f->filename = strdup (filename);
  if (f->filename == NULL) goto out_of_memory;
  f->dl = dl;
  debug ("registering filter %s", f->filename);
  filter = filter_init ();
  if (!filter) {
    fprintf (stderr, "%s: %s: filter registration function failed\n",
             program_name, f->filename);
    exit (EXIT_FAILURE);
  }
  if (filter->_api_version != NBDKIT_FILTER_API_VERSION) {
    fprintf (stderr,
             "%s: %s: filter is incompatible with this version of nbdkit "
             "(_api_version = %d)\n",
             program_name, f->filename, filter->_api_version);
    exit (EXIT_FAILURE);
  }
  f->filter = *filter;
  if (f->filter.name == NULL) {
    fprintf (stderr, "%s: %s: filter must have a .name field\n",
             program_name, f->filename);
    exit (EXIT_FAILURE);
  }
  len = strlen (f->filter.name);
  if (len == 0) {
    fprintf (stderr, "%s: %s: filter.name field must not be empty\n",
             program_name, f->filename);
    exit (EXIT_FAILURE);
  }
  for (i = 0; i < len; ++i) {
    if (!((f->filter.name[i] >= '0' && f->filter.name[i] <= '9') ||
          (f->filter.name[i] >= 'a' && f->filter.name[i] <= 'z') ||
          (f->filter.name[i] >= 'A' && f->filter.name[i] <= 'Z'))) {
      fprintf (stderr,
               "%s: %s: filter.name ('%s') field "
               "must contain only ASCII alphanumeric characters\n",
               program_name, f->filename, f->filter.name);
      exit (EXIT_FAILURE);
    }
  }
  f->name = strdup (f->filter.name);
  if (f->name == NULL) {
    perror ("strdup");
    exit (EXIT_FAILURE);
  }
  debug ("registered filter %s (name %s)", f->filename, f->name);
  set_debug_flags (dl, f->name);
  debug ("%s: load", f->name);
  if (f->filter.load)
    f->filter.load ();
  return (struct backend *) f;
}
struct backend * filter_register ( struct backend * next , size_t index , const char * filename , void * dl , struct nbdkit_filter * ( * filter_init ) ( void ) ) { struct backend_filter * f ; const struct nbdkit_filter * filter ; size_t i , len ; f = calloc ( 1 , sizeof * f ) ; if ( f == NULL ) { out_of_memory : perror ( " " ) ; exit ( EXIT_FAILURE ) ; } f -> backend = filter_functions ; f -> backend . next = next ; f -> backend . i = index ; f -> filename = strdup ( filename ) ; if ( f -> filename == NULL ) goto out_of_memory ; f -> dl = dl ; debug ( " " , f -> filename ) ; filter = filter_init ( ) ; if ( ! filter ) { fprintf ( stderr , " \n " , program_name , f -> filename ) ; exit ( EXIT_FAILURE ) ; } if ( filter -> _api_version != NBDKIT_FILTER_API_VERSION ) { fprintf ( stderr , " " " \n " , program_name , f -> filename , filter -> _api_version ) ; exit ( EXIT_FAILURE ) ; } f -> filter = * filter ; if ( f -> filter . name == NULL ) { fprintf ( stderr , " \n " , program_name , f -> filename ) ; exit ( EXIT_FAILURE ) ; } len = strlen ( f -> filter . name ) ; if ( len == 0 ) { fprintf ( stderr , " \n " , program_name , f -> filename ) ; exit ( EXIT_FAILURE ) ; } for ( i = 0 ; i < len ; ++ i ) { if ( ! ( ( f -> filter . name [ i ] >= ' ' && f -> filter . name [ i ] <= ' ' ) || ( f -> filter . name [ i ] >= ' ' && f -> filter . name [ i ] <= ' ' ) || ( f -> filter . name [ i ] >= ' ' && f -> filter . name [ i ] <= ' ' ) ) ) { fprintf ( stderr , " " " \n " , program_name , f -> filename , f -> filter . name ) ; exit ( EXIT_FAILURE ) ; } } f -> name = strdup ( f -> filter . name ) ; if ( f -> name == NULL ) { perror ( " " ) ; exit ( EXIT_FAILURE ) ; } debug ( " " , f -> filename , f -> name ) ; set_debug_flags ( dl , f -> name ) ; debug ( " " , f -> name ) ; if ( f -> filter . load ) f -> filter . load ( ) ; return ( struct backend * ) f ; }
Register and load a filter.
Register and load a filter .
/* Call the initialization function which returns the address of the
   * filter's own 'struct nbdkit_filter'.
   */ /* We do not provide API or ABI guarantees for filters, other than
   * the ABI position of _api_version that will let us diagnose
   * mismatch when the API changes.
   */ /* Only filter.name is required. */ /* Copy the module's name into local storage, so that filter.name
   * survives past unload.
   */ /* Set debug flags before calling load. */ /* Call the on-load callback if it exists. */