libmp3splt
src/plugins.c
Go to the documentation of this file.
00001 /**********************************************************
00002  *
00003  * libmp3splt -- library based on mp3splt,
00004  *               for mp3/ogg splitting without decoding
00005  *
00006  * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net>
00007  * Copyright (c) 2005-2011 Alexandru Munteanu - io_fx@yahoo.fr
00008  *
00009  * http://mp3splt.sourceforge.net
00010  *
00011  *********************************************************/
00012 
00013 /**********************************************************
00014  *
00015  * This program is free software; you can redistribute it and/or
00016  * modify it under the terms of the GNU General Public License
00017  * as published by the Free Software Foundation; either version 2
00018  * of the License, or (at your option) any later version.
00019  *
00020  * This program is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  *
00025  * You should have received a copy of the GNU General Public License
00026  * along with this program; if not, write to the Free Software
00027  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00028  * 02111-1307,
00029  * USA.
00030  *
00031  *********************************************************/
00032 
00037 #include <string.h>
00038 #include <dirent.h>
00039 #include <errno.h>
00040 
00041 #include <ltdl.h>
00042 
00043 #ifdef __WIN32__
00044 #include <direct.h>
00045 #endif
00046 
00047 #include "splt.h"
00048 #include "plugins.h"
00049 
00050 int splt_p_append_plugin_scan_dir(splt_state *state, const char *dir)
00051 {
00052   if (dir == NULL)
00053   {
00054     return SPLT_OK;
00055   }
00056 
00057   splt_plugins *pl = state->plug;
00058 
00059   if (pl->plugins_scan_dirs == NULL)
00060   {
00061     pl->plugins_scan_dirs = malloc(sizeof(char *));
00062   }
00063   else
00064   {
00065     pl->plugins_scan_dirs = realloc(pl->plugins_scan_dirs,
00066         sizeof(char *) * (pl->number_of_dirs_to_scan + 1));
00067   }
00068   if (pl->plugins_scan_dirs == NULL)
00069   {
00070     return SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00071   }
00072 
00073   size_t dir_size = strlen(dir) + 1;
00074 
00075   pl->plugins_scan_dirs[pl->number_of_dirs_to_scan] = malloc(sizeof(char) * dir_size);
00076   if (pl->plugins_scan_dirs[pl->number_of_dirs_to_scan] == NULL)
00077   {
00078     return SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00079   }
00080 
00081   snprintf(pl->plugins_scan_dirs[pl->number_of_dirs_to_scan], dir_size, "%s", dir);
00082   pl->number_of_dirs_to_scan++;
00083 
00084   return SPLT_OK;
00085 }
00086 
00087 //function to filter the plugin files
00088 static int splt_p_filter_plugin_files(const struct dirent *de)
00089 {
00090   char *file = (char *) de->d_name;
00091   const char *p_end = NULL;
00092   const char *p_start = NULL;
00093   if (file)
00094   {
00095     if (strlen(file) >= 8)
00096     {
00097       //if the name starts with splt_and contains .so or .sl or .dll or .dylib
00098       if (strncmp(file,"libsplt_",8) == 0)
00099       {
00100         splt_d_print_debug(NULL, "Looking at the file _%s_\n", file);
00101 
00102         p_start = strchr(file,'.');
00103 
00104 #ifndef __WIN32__
00105         //gnu/linux .so.0
00106         p_end = strstr(file, ".so");
00107         if (p_end != NULL && (p_start == p_end) && (*(p_end+3) == '\0'))
00108         {
00109           return 1;
00110         }
00111 #endif
00112 
00113         p_end = strrchr(file,'.');
00114         if ((p_end != NULL) && (p_start == p_end))
00115         {
00116           //windows .dll
00117 #ifdef __WIN32__
00118           if (strcmp(p_end,".dll") == 0)
00119           {
00120             return 1;
00121           }
00122 #else
00123           //bsd .sl & darwin .dylib
00124           if ((strcmp(p_end,".sl") == 0) || (strcmp(p_end,".dylib") == 0))
00125           {
00126             return 1;
00127           }
00128 #endif
00129         }
00130       }
00131     }
00132   }
00133 
00134   return 0;
00135 }
00136 
00137 static int splt_p_alloc_init_new_plugin(splt_plugins *pl)
00138 {
00139   int return_value = SPLT_OK;
00140 
00141   if (pl->data == NULL)
00142   {
00143     pl->data = malloc(sizeof(splt_plugin_data) * (pl->number_of_plugins_found+1));
00144     if (pl->data == NULL)
00145     {
00146       return_value = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00147       return return_value;
00148     }
00149   }
00150   else
00151   {
00152     pl->data = realloc(pl->data,sizeof(splt_plugin_data) *
00153         (pl->number_of_plugins_found+1));
00154     if (pl->data == NULL)
00155     {
00156       return_value = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00157       return return_value;
00158     }
00159   }
00160 
00161   pl->data[pl->number_of_plugins_found].func = NULL;
00162   pl->data[pl->number_of_plugins_found].plugin_handle = NULL;
00163   pl->data[pl->number_of_plugins_found].info.version = 0;
00164   pl->data[pl->number_of_plugins_found].info.name = NULL;
00165   pl->data[pl->number_of_plugins_found].info.extension = NULL;
00166   pl->data[pl->number_of_plugins_found].info.upper_extension = NULL;
00167   pl->data[pl->number_of_plugins_found].plugin_filename = NULL;
00168 
00169   return return_value;
00170 }
00171 
00176 static int splt_p_scan_dir_for_plugins(splt_state *state, splt_plugins *pl, const char *directory)
00177 {
00178   int return_value = SPLT_OK;
00179 
00180   struct dirent **files = NULL;
00181 
00182   int number_of_files = 0;
00183   errno = 0;
00184   number_of_files = scandir(directory, &files, splt_p_filter_plugin_files, alphasort);
00185   int directory_len = strlen(directory);
00186   int new_number_of_files = number_of_files;
00187 
00188   if (number_of_files == -1)
00189   {
00190     if (errno == ENOMEM)
00191     {
00192       return SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00193     }
00194   }
00195   else if (new_number_of_files >= 0)
00196   {
00197     char *fname = NULL;
00198 
00199     //for all the filtered found plugins,
00200     //copy their name
00201     while (new_number_of_files--)
00202     {
00203       fname = files[new_number_of_files]->d_name;
00204       int fname_len = strlen(fname);
00205 
00206       //get the full directory + filename
00207       int dir_and_fname_len = fname_len + directory_len + 3;
00208       char *dir_and_fname = malloc(sizeof(char) * dir_and_fname_len);
00209       if (dir_and_fname == NULL)
00210       {
00211         return_value = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00212         goto end;
00213       }
00214       snprintf(dir_and_fname, dir_and_fname_len - 1, "%s%c%s",directory,SPLT_DIRCHAR,fname);
00215 
00216       //check if we already have a plugin with the same file
00217       int we_already_have_this_plugin_file = SPLT_FALSE;
00218       int i = 0;
00219       int err = SPLT_OK;
00220       for (i = 0;i < pl->number_of_plugins_found;i++)
00221       {
00222         if (splt_check_is_the_same_file(state, dir_and_fname, pl->data[i].plugin_filename, &err))
00223         {
00224           we_already_have_this_plugin_file = SPLT_TRUE;
00225           break;
00226         }
00227 
00228         if (err != SPLT_OK)
00229         {
00230           return_value = err;
00231           goto end;
00232         }
00233       }
00234 
00235       //if we don't have a plugin from the same file, add this new plugin
00236       if (! we_already_have_this_plugin_file)
00237       {
00238         int alloc_err = splt_p_alloc_init_new_plugin(pl);
00239         if (alloc_err < 0)
00240         {
00241           return_value = alloc_err;
00242           goto end;
00243         }
00244 
00245         pl->data[pl->number_of_plugins_found].func = malloc(sizeof(splt_plugin_func));
00246         if (pl->data[pl->number_of_plugins_found].func == NULL)
00247         {
00248           return_value = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00249           goto end;
00250         }
00251         memset(pl->data[pl->number_of_plugins_found].func,0,sizeof(splt_plugin_func));
00252 
00253         pl->data[pl->number_of_plugins_found].plugin_filename = malloc(sizeof(char) *
00254             dir_and_fname_len);
00255         if (pl->data[pl->number_of_plugins_found].plugin_filename == NULL)
00256         {
00257           return_value = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00258           goto end;
00259         }
00260 
00261         //set the plugin path
00262         snprintf(pl->data[pl->number_of_plugins_found].plugin_filename,
00263             dir_and_fname_len - 1,"%s%c%s",directory,SPLT_DIRCHAR,fname);
00264 
00265         pl->number_of_plugins_found++;
00266       }
00267 
00268       //free some memory
00269       if (dir_and_fname)
00270       {
00271         free(dir_and_fname);
00272         dir_and_fname = NULL;
00273       }
00274     }
00275 
00276 end:
00277     ;
00278 
00279     if (files)
00280     {
00281       //free memory
00282       while (number_of_files--)
00283       {
00284         if (files[number_of_files])
00285         {
00286           free(files[number_of_files]);
00287           files[number_of_files] = NULL;
00288         }
00289       }
00290       free(files);
00291       files = NULL;
00292     }
00293   }
00294 
00295   return return_value;
00296 }
00297 
00298 //finds the plugins
00299 //-returns SPLT_OK if no error and SPLT_ERROR_CANNOT_FIND_PLUGINS if
00300 //no plugin was found
00301 static int splt_p_find_plugins(splt_state *state)
00302 {
00303   int return_value = SPLT_OK;
00304 
00305   splt_plugins *pl = state->plug;
00306 
00307   //for each scan directory, look for the files starting with 'splt' and
00308   //ending with '.so' on unix-like and '.dll' on windows
00309   int i = 0;
00310 
00311   char current_dir[3] = { '\0' };
00312   snprintf(current_dir,3,".%c",SPLT_DIRCHAR);
00313 
00314   for (i = 0;i < pl->number_of_dirs_to_scan;i++)
00315   {
00316     if (pl->plugins_scan_dirs[i] != NULL)
00317     {
00318       splt_d_print_debug(state,"Scanning plugins in the directory _%s_\n",
00319           pl->plugins_scan_dirs[i]);
00320 
00321       //don't check if directory exists if the directory is ./ on unix-like
00322       //OSes or .\\ on windows
00323       if (((strlen(pl->plugins_scan_dirs[i]) >= 2) &&
00324             strncmp(pl->plugins_scan_dirs[i], current_dir,2) == 0) ||
00325           splt_io_check_if_directory(pl->plugins_scan_dirs[i]))
00326       {
00327         return_value = splt_p_scan_dir_for_plugins(state, pl, pl->plugins_scan_dirs[i]);
00328         if (return_value != SPLT_OK)
00329         {
00330           return return_value;
00331         }
00332       }
00333     }
00334   }
00335 
00336   return return_value;
00337 }
00338 
00340 static void splt_p_free_plugin_data_info(splt_plugin_data *pl_data)
00341 {
00342   if (pl_data->info.name)
00343   {
00344     free(pl_data->info.name);
00345     pl_data->info.name = NULL;
00346   }
00347   if (pl_data->info.extension)
00348   {
00349     free(pl_data->info.extension);
00350     pl_data->info.extension = NULL;
00351   }
00352   if (pl_data->info.upper_extension)
00353   {
00354     free(pl_data->info.upper_extension);
00355     pl_data->info.upper_extension = NULL;
00356   }
00357 }
00358 
00359 static void splt_p_free_plugin_data(splt_plugin_data *pl_data)
00360 {
00361   splt_p_free_plugin_data_info(pl_data);
00362   if (pl_data->plugin_filename)
00363   {
00364     free(pl_data->plugin_filename);
00365     pl_data->plugin_filename = NULL;
00366   }
00367   if (pl_data->plugin_handle)
00368   {
00369     lt_dlclose(pl_data->plugin_handle);
00370     pl_data->plugin_handle = NULL;
00371   }
00372   if (pl_data->func)
00373   {
00374     free(pl_data->func);
00375     pl_data->func = NULL;
00376   }
00377 }
00378 
00379 int splt_p_move_replace_plugin_data(splt_state *state, int old, int new)
00380 {
00381   splt_plugins *pl = state->plug;
00382 
00383   splt_p_free_plugin_data(&pl->data[new]);
00384 
00385   pl->data[new].func = malloc(sizeof(splt_plugin_func));
00386   if (pl->data[new].func == NULL)
00387   {
00388     return SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00389   }
00390   memset(pl->data[new].func,0,sizeof(splt_plugin_func));
00391 
00392   int plugin_fname_len = strlen(pl->data[old].plugin_filename) + 1;
00393   pl->data[new].plugin_filename = malloc(sizeof(char) * plugin_fname_len);
00394   if (pl->data[new].plugin_filename == NULL)
00395   {
00396     return SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00397   }
00398   snprintf(pl->data[new].plugin_filename, plugin_fname_len, "%s",
00399       pl->data[old].plugin_filename);
00400 
00401   splt_p_free_plugin_data(&pl->data[old]);
00402 
00403   return SPLT_OK;
00404 }
00405 
00406 //shifts all the elements to the left, starting at element index+1
00407 static int splt_p_shift_left_plugins_data(splt_state *state, int index)
00408 {
00409   int i = 0;
00410   splt_plugins *pl = state->plug;
00411 
00412   for (i = index+1;i < pl->number_of_plugins_found;i++)
00413   {
00414     int err = splt_p_move_replace_plugin_data(state, i, i - 1);
00415     if (err != SPLT_OK)
00416     {
00417       return err;
00418     }
00419   }
00420 
00421   return SPLT_OK;
00422 }
00423 
00424 //function that gets information of each plugin
00425 static int splt_p_open_get_valid_plugins(splt_state *state)
00426 {
00427   splt_plugins *pl = state->plug;
00428 
00429   int *plugin_index_to_remove = NULL;
00430   int number_of_plugins_to_remove = 0;
00431 
00432   int error = SPLT_OK;
00433 
00434   int i = 0;
00435   for (i = 0;i < pl->number_of_plugins_found;i++)
00436   {
00437     splt_d_print_debug(state,"\nTrying to open the plugin _%s_ ...\n",
00438         pl->data[i].plugin_filename);
00439 
00440     //ltdl currently does not supports windows unicode path/filename
00441     pl->data[i].plugin_handle = lt_dlopen(pl->data[i].plugin_filename);
00442     //error
00443     if (! pl->data[i].plugin_handle)
00444     {
00445       splt_d_print_debug(state,"Error loading the plugin _%s_\n", pl->data[i].plugin_filename);
00446       splt_d_print_debug(state," - error message from libltdl: _%s_\n", lt_dlerror());
00447 
00448       //keep the index of this failed plugin in order to remove it
00449       //afterwards
00450       if (! plugin_index_to_remove)
00451       {
00452         plugin_index_to_remove = malloc(sizeof(int));
00453       }
00454       else
00455       {
00456         plugin_index_to_remove = realloc(plugin_index_to_remove, sizeof(int) * (number_of_plugins_to_remove + 1));
00457       }
00458       plugin_index_to_remove[number_of_plugins_to_remove] = i;
00459       number_of_plugins_to_remove++;
00460     }
00461     else
00462     {
00463       splt_d_print_debug(state," - success !\n");
00464 
00465       pl->data[i].func->set_plugin_info =
00466         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_set_plugin_info");
00467       if (pl->data[i].func->set_plugin_info != NULL)
00468       {
00469         pl->data[i].func->set_plugin_info(&pl->data[i].info,&error);
00470       }
00471 
00472       //look if we already have a plugin with the same name
00473       int j = 0;
00474       splt_p_set_current_plugin(state, i);
00475       const char *current_plugin_name = splt_p_get_name(state, &error);
00476       for (j = 0;j < i;j++)
00477       {
00478         if (pl->data[j].plugin_handle)
00479         {
00480           splt_p_set_current_plugin(state, j);
00481           const char *plugin_name = splt_p_get_name(state, &error);
00482           //if we do have one with the same name,
00483           if (strcmp(plugin_name,current_plugin_name) == 0)
00484           {
00485             //keep unique index to remove afterwards
00486             int unique = SPLT_TRUE;
00487             int k = 0;
00488             for (k = 0;k < number_of_plugins_to_remove;k++)
00489             {
00490               if (i == plugin_index_to_remove[k])
00491               {
00492                 unique = SPLT_FALSE;
00493                 break;
00494               }
00495             }
00496             if (unique)
00497             {
00498               if (! plugin_index_to_remove)
00499               {
00500                 plugin_index_to_remove = malloc(sizeof(int));
00501               }
00502               else
00503               {
00504                 plugin_index_to_remove = realloc(plugin_index_to_remove,
00505                     sizeof(int) * (number_of_plugins_to_remove + 1));
00506               }
00507               plugin_index_to_remove[number_of_plugins_to_remove] = i;
00508               number_of_plugins_to_remove++;
00509             }
00510           }
00511         }
00512       }
00513     }
00514   }
00515 
00516   //remove the plugins that failed to open
00517   //-some plugins fail to open twice (on Windows for example)
00518   int left_shift = 0;
00519   //we shift to the left the plugin data in order to replace the bad
00520   //plugins with the others
00521   for (i = 0;i < number_of_plugins_to_remove;i++) 
00522   {
00523     int index_to_remove = plugin_index_to_remove[i] - left_shift;
00524 
00525     splt_d_print_debug(state,"Removing the plugin _%s_ at index %d\n",
00526         pl->data[index_to_remove].plugin_filename, index_to_remove);
00527 
00528     error = splt_p_shift_left_plugins_data(state, index_to_remove);
00529     if (error < SPLT_OK) { break; }
00530 
00531     pl->number_of_plugins_found--;
00532     left_shift++;
00533   }
00534 
00535   //free the plugin index to remove
00536   if (plugin_index_to_remove)
00537   {
00538     free(plugin_index_to_remove);
00539     plugin_index_to_remove = NULL;
00540   }
00541   number_of_plugins_to_remove = 0;
00542 
00543   return error;
00544 }
00545 
00546 //main plugin function which finds the plugins and gets out the plugin data
00547 //-returns possible error
00548 //-for the moment should only be called once
00549 int splt_p_find_get_plugins_data(splt_state *state)
00550 {
00551   int return_value = SPLT_OK;
00552 
00553   splt_d_print_debug(state,"\nSearching for plugins ...\n");
00554 
00555   //find the plugins
00556   return_value = splt_p_find_plugins(state);
00557 
00558   if (return_value != SPLT_OK)
00559   {
00560     return return_value;
00561   }
00562   else
00563   {
00564     //open the plugins
00565     return_value = splt_p_open_get_valid_plugins(state);
00566   }
00567 
00568   if (return_value >= 0)
00569   {
00570     splt_plugins *pl = state->plug;
00571     splt_d_print_debug(state,"\nNumber of plugins found: _%d_\n",pl->number_of_plugins_found);
00572     int i = 0;
00573     int err = 0;
00574     for (i = 0;i < pl->number_of_plugins_found;i++)
00575     {
00576       pl->data[i].plugin_handle = lt_dlopen(pl->data[i].plugin_filename);
00577 
00578       pl->data[i].func->check_plugin_is_for_file =
00579         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_check_plugin_is_for_file");
00580       pl->data[i].func->search_syncerrors =
00581         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_search_syncerrors");
00582       pl->data[i].func->dewrap =
00583         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_dewrap");
00584       pl->data[i].func->simple_split =
00585         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_simple_split");
00586       pl->data[i].func->split =
00587         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_split");
00588       pl->data[i].func->init =
00589         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_init");
00590       pl->data[i].func->end =
00591         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_end");
00592       pl->data[i].func->scan_silence =
00593         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_scan_silence");
00594       pl->data[i].func->set_original_tags =
00595         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_set_original_tags");
00596       pl->data[i].func->set_plugin_info =
00597         lt_dlsym(pl->data[i].plugin_handle, "splt_pl_set_plugin_info");
00598       if (pl->data[i].func->set_plugin_info != NULL)
00599       {
00600         splt_p_free_plugin_data_info(&pl->data[i]);
00601         pl->data[i].func->set_plugin_info(&pl->data[i].info,&err);
00602       }
00603 
00604       splt_p_set_current_plugin(state, i);
00605       if (pl->data[i].plugin_filename != NULL)
00606       {
00607         splt_d_print_debug(state,"plugin filename = _%s_\n", pl->data[i].plugin_filename);
00608       }
00609 
00610       const char *temp = splt_p_get_name(state, &err);
00611       splt_d_print_debug(state,"plugin name = _%s_\n", temp);
00612 
00613       float version = splt_p_get_version(state, &err);
00614       splt_d_print_debug(state,"plugin version = _%lf_\n", version);
00615 
00616       temp = splt_p_get_extension(state,&err);
00617       splt_d_print_debug(state,"extension = _%s_\n\n", temp);
00618     }
00619   }
00620   splt_p_set_current_plugin(state, -1);
00621 
00622   return return_value;
00623 }
00624 
00625 /* plugin info wrappers */
00626 
00627 float splt_p_get_version(splt_state *state, int *error)
00628 {
00629   splt_plugins *pl = state->plug;
00630   int current_plugin = splt_p_get_current_plugin(state);
00631   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00632   {
00633     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00634     return 0;
00635   }
00636   else
00637   {
00638     return pl->data[current_plugin].info.version;
00639   }
00640 }
00641 
00642 const char *splt_p_get_name(splt_state *state, int *error)
00643 {
00644   splt_plugins *pl = state->plug;
00645   int current_plugin = splt_p_get_current_plugin(state);
00646   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00647   {
00648     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00649     return NULL;
00650   }
00651   else
00652   {
00653     return pl->data[current_plugin].info.name;
00654   }
00655 }
00656 
00657 const char *splt_p_get_extension(splt_state *state, int *error)
00658 {
00659   splt_plugins *pl = state->plug;
00660   int current_plugin = splt_p_get_current_plugin(state);
00661   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00662   {
00663     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00664     return NULL;
00665   }
00666   else
00667   {
00668     return pl->data[current_plugin].info.extension;
00669   }
00670 }
00671 
00672 const char *splt_p_get_upper_extension(splt_state *state, int *error)
00673 {
00674   splt_plugins *pl = state->plug;
00675   int current_plugin = splt_p_get_current_plugin(state);
00676   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00677   {
00678     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00679     return NULL;
00680   }
00681   else
00682   {
00683     return pl->data[current_plugin].info.upper_extension;
00684   }
00685 }
00686 
00687 /* plugin function wrappers */
00688 
00689 int splt_p_check_plugin_is_for_file(splt_state *state, int *error)
00690 {
00691   splt_plugins *pl = state->plug;
00692   int current_plugin = splt_p_get_current_plugin(state);
00693   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00694   {
00695     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00696     return SPLT_FALSE;
00697   }
00698   else
00699   {
00700     if (pl->data[current_plugin].func->check_plugin_is_for_file != NULL)
00701     {
00702       return pl->data[current_plugin].func->check_plugin_is_for_file(state, error);
00703     }
00704     else
00705     {
00706       *error = SPLT_PLUGIN_ERROR_UNSUPPORTED_FEATURE;
00707       return SPLT_FALSE;
00708     }
00709   }
00710 }
00711 
00712 void splt_p_search_syncerrors(splt_state *state, int *error)
00713 {
00714   splt_plugins *pl = state->plug;
00715   int current_plugin = splt_p_get_current_plugin(state);
00716   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00717   {
00718     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00719     return;
00720   }
00721   else
00722   {
00723     if (pl->data[current_plugin].func->search_syncerrors != NULL)
00724     {
00725       splt_se_serrors_free(state);
00726       pl->data[current_plugin].func->search_syncerrors(state, error);
00727     }
00728     else
00729     {
00730       *error = SPLT_PLUGIN_ERROR_UNSUPPORTED_FEATURE;
00731     }
00732   }
00733 }
00734 
00735 void splt_p_dewrap(splt_state *state, int listonly, const char *dir, int *error)
00736 {
00737   splt_plugins *pl = state->plug;
00738   int current_plugin = splt_p_get_current_plugin(state);
00739   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00740   {
00741     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00742     return;
00743   }
00744   else
00745   {
00746     if (pl->data[current_plugin].func->dewrap != NULL)
00747     {
00748       pl->data[current_plugin].func->dewrap(state, listonly, dir, error);
00749     }
00750     else
00751     {
00752       *error = SPLT_PLUGIN_ERROR_UNSUPPORTED_FEATURE;
00753     }
00754   }
00755 }
00756 
00757 double splt_p_split(splt_state *state, const char *final_fname, double begin_point,
00758     double end_point, int *error, int save_end_point)
00759 {
00760   splt_plugins *pl = state->plug;
00761   int current_plugin = splt_p_get_current_plugin(state);
00762   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00763   {
00764     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00765     return end_point;
00766   }
00767   else
00768   {
00769     int err = SPLT_OK;
00770 
00771     splt_d_print_debug(state, "split creating directories of final fname ... _%s_\n", final_fname);
00772 
00773     splt_io_create_output_dirs_if_necessary(state, final_fname, &err);
00774     if (err < 0) { *error = err; return end_point; }
00775 
00776     if (pl->data[current_plugin].func->split != NULL)
00777     {
00778       double new_end_point = pl->data[current_plugin].func->split(state, final_fname,
00779           begin_point, end_point, error, save_end_point);
00780 
00781       splt_d_print_debug(state, "New end point after split = _%lf_\n", new_end_point);
00782 
00783       return new_end_point;
00784     }
00785     else
00786     {
00787       *error = SPLT_PLUGIN_ERROR_UNSUPPORTED_FEATURE;
00788     }
00789   }
00790 
00791   return end_point;
00792 }
00793 
00794 void splt_p_init(splt_state *state, int *error)
00795 {
00796   splt_plugins *pl = state->plug;
00797   int current_plugin = splt_p_get_current_plugin(state);
00798   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00799   {
00800     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00801     return;
00802   }
00803   else
00804   {
00805     if (pl->data[current_plugin].func->init != NULL)
00806     {
00807       pl->data[current_plugin].func->init(state, error);
00808     }
00809     else
00810     {
00811       *error = SPLT_PLUGIN_ERROR_UNSUPPORTED_FEATURE;
00812     }
00813   }
00814 }
00815 
00816 void splt_p_end(splt_state *state, int *error)
00817 {
00818   splt_plugins *pl = state->plug;
00819   int current_plugin = splt_p_get_current_plugin(state);
00820   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00821   {
00822     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00823     return;
00824   }
00825   else
00826   {
00827     if (pl->data[current_plugin].func->end != NULL)
00828     {
00829       pl->data[current_plugin].func->end(state, error);
00830     }
00831     else
00832     {
00833       *error = SPLT_PLUGIN_ERROR_UNSUPPORTED_FEATURE;
00834     }
00835   }
00836 }
00837 
00838 int splt_p_simple_split(splt_state *state, const char *output_fname, off_t begin,
00839     off_t end)
00840 {
00841   splt_plugins *pl = state->plug;
00842   int current_plugin = splt_p_get_current_plugin(state);
00843   int error = SPLT_OK;
00844   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00845   {
00846     error = SPLT_ERROR_NO_PLUGIN_FOUND;
00847     return error;
00848   }
00849   else
00850   {
00851     if (pl->data[current_plugin].func->simple_split != NULL)
00852     {
00853       error = pl->data[current_plugin].func->simple_split(state, output_fname, begin, end);
00854     }
00855     else
00856     {
00857       error = SPLT_PLUGIN_ERROR_UNSUPPORTED_FEATURE;
00858     }
00859   }
00860 
00861   return error;
00862 }
00863 
00864 int splt_p_scan_silence(splt_state *state, int *error)
00865 {
00866   splt_plugins *pl = state->plug;
00867   int current_plugin = splt_p_get_current_plugin(state);
00868   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00869   {
00870     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00871     return 0;
00872   }
00873   else
00874   {
00875     if (pl->data[current_plugin].func->scan_silence != NULL)
00876     {
00877       return pl->data[current_plugin].func->scan_silence(state, error);
00878     }
00879     else
00880     {
00881       *error = SPLT_PLUGIN_ERROR_UNSUPPORTED_FEATURE;
00882     }
00883   }
00884 
00885   return 0;
00886 }
00887 
00888 void splt_p_set_original_tags(splt_state *state, int *error)
00889 {
00890   splt_plugins *pl = state->plug;
00891   int current_plugin = splt_p_get_current_plugin(state);
00892   if ((current_plugin < 0) || (current_plugin >= pl->number_of_plugins_found))
00893   {
00894     *error = SPLT_ERROR_NO_PLUGIN_FOUND;
00895     return;
00896   }
00897   else
00898   {
00899     if (pl->data[current_plugin].func->set_original_tags != NULL)
00900     {
00901       pl->data[current_plugin].func->set_original_tags(state, error);
00902     }
00903   }
00904 }
00905 
00906 static int splt_p_set_default_plugins_scan_dirs(splt_state *state)
00907 {
00908   int err = SPLT_OK;
00909   char *dir = NULL;
00910 
00911 #ifndef __WIN32__
00912   err = splt_p_append_plugin_scan_dir(state, SPLT_PLUGINS_DIR);
00913   if (err < 0) { return err; }
00914 #endif
00915 
00916   err = splt_su_append_str(&dir, getenv("HOME"), SPLT_DIRSTR, ".libmp3splt", NULL);
00917   if (err < 0) { goto end; }
00918   err = splt_p_append_plugin_scan_dir(state, dir);
00919   free(dir);
00920   dir = NULL;
00921 
00922   err = splt_su_append_str(&dir, ".", SPLT_DIRSTR, NULL);
00923   if (err < 0) { goto end; }
00924   err = splt_p_append_plugin_scan_dir(state, dir);
00925 
00926 end:
00927   if (dir)
00928   {
00929     free(dir);
00930     dir = NULL;
00931   }
00932 
00933   return err;
00934 }
00935 
00936 int splt_p_set_default_values(splt_state *state)
00937 {
00938   state->plug->plugins_scan_dirs = NULL;
00939   state->plug->number_of_plugins_found = 0;
00940   state->plug->data = NULL;
00941   state->plug->number_of_dirs_to_scan = 0;
00942 
00943   return splt_p_set_default_plugins_scan_dirs(state);
00944 }
00945 
00946 void splt_p_free_plugins(splt_state *state)
00947 {
00948   splt_plugins *pl = state->plug;
00949   int i = 0;
00950 
00951   if (pl->plugins_scan_dirs)
00952   {
00953     for (i = 0;i < pl->number_of_dirs_to_scan;i++)
00954     {
00955       if (pl->plugins_scan_dirs[i])
00956       {
00957         free(pl->plugins_scan_dirs[i]);
00958         pl->plugins_scan_dirs[i] = NULL;
00959       }
00960     }
00961     free(pl->plugins_scan_dirs);
00962     pl->plugins_scan_dirs = NULL;
00963     pl->number_of_dirs_to_scan = 0;
00964   }
00965   if (pl->data)
00966   {
00967     for (i = 0;i < pl->number_of_plugins_found;i++)
00968     {
00969       splt_p_free_plugin_data(&pl->data[i]);
00970     }
00971     free(pl->data);
00972     pl->data = NULL;
00973     pl->number_of_plugins_found = 0;
00974   }
00975 }
00976 
00977 void splt_p_set_current_plugin(splt_state *state, int current_plugin)
00978 {
00979   //-1 means no plugin
00980   if (current_plugin >= -1)
00981   {
00982     state->current_plugin = current_plugin;
00983   }
00984   else
00985   {
00986     splt_e_error(SPLT_IERROR_INT,__func__, current_plugin, NULL);
00987   }
00988 }
00989 
00990 int splt_p_get_current_plugin(splt_state *state)
00991 {
00992   return state->current_plugin;
00993 }
00994 
00995 int splt_p_file_is_supported_by_plugins(splt_state *state, const char *fname)
00996 {
00997   splt_plugins *pl = state->plug;
00998 
00999   int fname_length = strlen(fname);
01000   if (fname_length > 3)
01001   {
01002     char *ptr_to_compare = strrchr(fname, '.');
01003     if (ptr_to_compare)
01004     {
01005       int i = 0;
01006       for (i = 0;i < pl->number_of_plugins_found;i++)
01007       {
01008         char *pl_extension = pl->data[i].info.extension;
01009         char *pl_upper_extension = pl->data[i].info.upper_extension;
01010 
01011         if ((strcmp(ptr_to_compare, pl_extension) == 0) ||
01012             (strcmp(ptr_to_compare, pl_upper_extension) == 0))
01013         {
01014           return SPLT_TRUE;
01015         }
01016       }
01017     }
01018   }
01019 
01020   return SPLT_FALSE;
01021 }
01022