1
/* $Id: er_plugin.c,v 1.97 2010/05/19 08:20:52 kbanse Exp $
3
* This file is part of the ESO Common Pipeline Library
4
* Copyright (C) 2001-2009 European Southern Observatory
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
* $Date: 2010/05/19 08:20:52 $
25
* $Name: esorex-3_9_0 $
40
#include <sys/types.h>
52
#include "er_stringarray.h"
53
#include "er_fileutils.h"
54
#include "er_paramutils.h"
55
#include "er_params.h"
56
#include "er_plugin.h"
57
#include "er_pluginlist.h"
59
#include "er_stringutils.h"
61
static char trace_msg[80];
62
static cpl_frameset *holdme;
69
#define Xspace(x) (x == ' ') || (x == '\t') || (x == '\n')
70
#define Xnospace(x) (x != ' ') && (x != '\t') && (x != '\n')
74
* @defgroup esorex_plugin_process EsoRex Plugin Processing Functions
76
* EsoRex Plugin Processing Functions
85
/**********************************************************************/
87
* @brief Sets the message severity level for the terminal
88
* @param param_list A list of the command line parameters
89
* @param flag = 1, get level for logging
90
* = 2, get level for terminal messages
92
* This function takes the list of all the command line parameters, and
93
* checks for the existence of one to set the terminal message reporting
94
* level. If it exists, the log-level is set to the requested value.
97
/**********************************************************************/
99
cpl_msg_severity message_severity (cpl_parameterlist *param_list, int flag)
102
const char *msg_level_value = NULL;
110
if (param_list == NULL) return (CPL_MSG_OFF);
114
p = cpl_parameterlist_find (param_list, PACKAGE_RESOURCE ".log-level");
116
p = cpl_parameterlist_find (param_list, PACKAGE_RESOURCE ".msg-level");
118
msg_level_value = cpl_parameter_get_string (p);
119
ForceNull(msg_level_value)
121
if (msg_level_value != NULL)
123
if (strcmp (msg_level_value, "debug") == 0)
124
return CPL_MSG_DEBUG;
126
else if (strcmp (msg_level_value, "info") == 0)
129
else if (strcmp (msg_level_value, "warning") == 0)
130
return CPL_MSG_WARNING;
132
else if (strcmp (msg_level_value, "error") == 0)
133
return CPL_MSG_ERROR;
135
else if (strcmp (msg_level_value, "off") == 0)
143
(void) strcpy(tmp,"logfile");
145
(void) strcpy(tmp,"terminal");
147
(er_func, "%s messaging level '%s' is not recognized", tmp,msg_level_value);
151
return (CPL_MSG_OFF);
153
} /* End of message_severity() */
158
int add_size(const char *path, double *fsz)
163
if (stat(path,&buf) == -1) /* get file structure info */
168
*fsz += (double) buf.st_size; /* add current files size in bytes */
171
printf("file: %s has size %d bytes => total size = %13.6g\n",path,buf.st_size,*fsz);
177
int mysscanf (char *myline, char *path, char * tag,char * group)
194
for (iout=1; iout <4; iout++)
196
while(1) /* find blank space */
201
(void) strcpy(mpt[iout-1],&myline[keep]);
204
if (Xspace(cc)) break;
208
(void) strcpy(mpt[iout-1],&myline[keep]);
210
if (iout == 3) return iout; /* not more than 3 items... */
212
while(1) /* find non-space char */
215
if (cc == '\0') return iout;
216
if (Xnospace(cc)) break;
227
/**********************************************************************/
230
* Create a new frame set from a @em set @em of @em frames file.
232
* @param name Input file path.
233
* @param set Frame set to be updated with the contents of @em name.
235
* @return Pointer to the newly created frame set if @em set was @c NULL,
236
* or the updated set @em set. In case an error occurred the return value
239
* The function reads the given input file @em filename and either,
240
* if @c NULL is passed for @em set, creates a new frame set from its
241
* contents, or updates @em set, if @em set points to an already existing
245
* The current format of the @em set @em of @em frames file is as follows:
246
* - One frame description per line.
247
* - Each frame description consists of an absolute file path followed
248
* by the frame tag and, optionally, the group the frame belongs to.
249
* - Currently the only defined group tags are RAW, CALIB and PRODUCT.
250
* - The individual fields are separated by whitespace.
251
* - Blank lines are ignored.
252
* - Lines that begin with a hash (#) are treated as comment lines.
254
/**********************************************************************/
256
cpl_frameset *er_frameset_load
257
(const char *name, cpl_frameset * set, int flag_check_sof_exist)
261
char *line, *path, *group, *tag, *xpath;
265
int line_number = 0, created = 0;
266
int ii, mlen, n, no_comnt;
268
int load_sucesfull = 1;
270
cpl_frame *frame = NULL;
272
cpl_msg_severity msg_level;
281
cpl_msg_error (er_func, "No SOF name provided, when one was expected.");
285
if (!(fp = fopen (name, "r")))
287
cpl_msg_error (er_func, "Unable to open SOF file '%s'", name);
291
/* If set was NULL, create a new frame set that we can fill. */
295
set = cpl_frameset_new ();
300
(void) sprintf(trace_msg,"new frameset created for SOF %48.48s",name);
306
line = (char *) cpl_calloc((size_t) SIZE_C, (size_t) 1);
307
path = (char *) cpl_calloc((size_t) SIZE_C, (size_t) 1);
308
xpath = (char *) cpl_calloc((size_t) SIZE_C, (size_t) 1);
309
group = (char *) cpl_calloc((size_t) SIZE_C, (size_t) 1);
310
tag = (char *) cpl_calloc((size_t) SIZE_C, (size_t) 1);
312
msg_level = cpl_msg_get_level(); /* get the message level */
315
/* Loop over all the lines in the set-of-frames file */
317
while( fgets (line, (SIZE_C-1), fp))
320
no_comnt = 0; /* check for comments + empty records */
321
line[SIZE_C-1] = '\0';
322
mlen = (int)strlen(line);
324
/* printf("line no. %d has length %d\n",line_number,mlen); */
326
for (ii=0; ii<mlen; ii++)
329
if (Xnospace(cc)) /* look for 1st non-blank char */
331
if (cc != '#') no_comnt = 1; /* # indicates comment line */
338
n = mysscanf (&line[ii], xpath, tag, group); /* split up line */
342
printf("mysscanf returns %d\n",n);
343
printf("path: %s\ntag: %s, group: %s\n",xpath,tag,group);
348
if (xpath[0] == '$') /* check for env. variables */
354
wer = wordexp(xpath,&wresult,0); /* expand the $VAR/file */
357
wp = *wresult.we_wordv; /* use 1st and only result word */
359
(void) strcpy(path,wp);
367
(void) snprintf(estr,(size_t)238,"Expansion of %s failed...",xpath);
368
cpl_msg_error (er_func, estr);
374
(void) strcpy(path,xpath);
377
if (!(fileutils_file_exists (path))) /* Ensure that the path exists */
378
{ /* Invalid file name? */
380
/* allow a single FITS file instead of SOF */
382
if (strncmp(path,"SIMPLE",6) == 0)
383
{ /* it's a single FITS file */
384
n = (int) strlen(name);
388
(void) strncpy(path,name,(size_t)n);
390
cpl_msg_warning (er_func, "FITS file name truncated to %d chars", n);
394
(void) strcpy(path,name);
396
(void) strcpy(tag,"COMMAND_LINE");
397
n = -1; /* to remember that later on */
399
else /* Yes, bad filename */
401
if (flag_check_sof_exist)
403
cpl_msg_error (er_func,
404
"The input data file '%s', specified on line %d of the SOF "
405
"file, '%s', does not exist...", path, line_number, name);
410
cpl_msg_debug (er_func,
411
"The input data file '%s', specified on line %d of the SOF "
412
"file, '%s', does not exist...", path, line_number, name);
417
frame = cpl_frame_new (); /* allocate a new frame */
418
cpl_frame_set_filename (frame, path); /* and provide the filename */
420
if (n == 1) /* no tag in SOF line */
421
cpl_frame_set_tag (frame, "");
423
cpl_frame_set_tag (frame, tag);
425
/* Set the group component of the frame (or set a default) */
426
if (n > 2) /* so, omitted for single FITS file */
430
if (!strcmp (group, CPL_FRAME_GROUP_RAW_ID))
431
grp = CPL_FRAME_GROUP_RAW;
434
if (!strcmp (group, CPL_FRAME_GROUP_CALIB_ID))
435
grp = CPL_FRAME_GROUP_CALIB;
438
if (!strcmp (group, CPL_FRAME_GROUP_PRODUCT_ID))
439
grp = CPL_FRAME_GROUP_PRODUCT;
441
grp = CPL_FRAME_GROUP_NONE;
445
cpl_frame_set_group (frame, grp);
448
cpl_frameset_insert (set, frame);
449
if (n == -1) goto dealloc; /* was single FITS file */
453
{ /* Invalid frame description. */
454
if (msg_level == CPL_MSG_DEBUG)
456
cpl_msg_debug (er_func,
457
"Invalid frame description '%s', specified on line %d of the SOF "
458
"file, '%s'.", path, line_number, name);
463
} /* End of while() */
466
dealloc: /* Deallocate resources */
479
ii = cpl_frameset_get_size(set);
480
(void) sprintf(trace_msg,"size of frameset = %d",ii);
484
frame = cpl_frameset_get_first(set);
485
while (frame != NULL)
487
gp = cpl_frame_get_filename(frame);
488
tp = cpl_frame_get_tag(frame);
489
(void) sprintf(trace_msg,"name: %60.60s, %s",gp,tp);
492
frame = cpl_frameset_get_next(set);
497
/* Check if the loading was sucesfully */
501
cpl_frameset_delete(set);
505
/* Return the pointer to the frameset */
508
} /* End of er_frameset_load() */
513
/**********************************************************************/
515
* @brief Process the Plugin
517
* @param frameset Set of frames to be moved
518
* @param output_prefix Character string with the prefix to be used
522
* This function updates the DATAMD5 keyword for any product already created
523
* in the case a recipe returned an error status (failed)
526
/**********************************************************************/
528
int upda_products (cpl_frameset * frameset)
539
reto = cpl_dfs_update_product_header(frameset);
540
if (reto != CPL_ERROR_NONE)
542
cpl_msg_error (er_func, "could not update the product header...");
552
/**********************************************************************/
554
* @brief Process the Plugin
556
* @param plugin_name Name of Plugin to process
557
* @param frameset Set of frames to be moved
558
* @param output_directory Character string with the output directory
559
* @param output_prefix Character string with the prefix to be used
560
* @param flag_noprefix Boolean indicating if prefix/number system
561
* should be ignored, in which case the recipe
562
* output filenames are used.
563
* @param flag_readonly Boolean indicating whether or not output files
564
* should be set to oct(444) for Paranal.
566
* @returns 0 if successfull, !=0 otherwise
568
* This function moves the products from the temporary working
569
* directory, as used by the recipe, to the output directory requested
572
* This function also sets the PIPEFILE keyword in the FITS header if
573
* appropriate. If this cannot be done, or the FITS card has
574
* insufficient size to then a warning is printed.
576
/**********************************************************************/
578
/* int move_products (char * plugin_name, */
579
int move_products (cpl_frameset * frameset,
580
char * output_directory,
581
char * output_prefix,
582
char * link_directory,
583
int flag_noprefix, int flag_nolink, int flag_readonly)
586
cpl_frame *frame = NULL; /* The current frame being processed */
588
int filenum = 0; /* Number of the output product */
591
const char *input_name = NULL; /* Name of the input file */
592
const char *output_dir = NULL; /* Name of the output directory */
593
const char *link_dir = NULL; /* Name of the symbolic link dir. */
596
char *output_name = NULL; /* Name of the output file */
597
char *suffix = NULL; /* The file suffix */
598
char current_dir[FILEMAX]; /* Name of current (work) directory */
606
output_name = (char *) cpl_malloc((size_t) SIZE_A);
608
current_dir[0] = '\0';
611
/* Start by getting the "cleaned" output directory name */
614
er_fileutils_dot_replace (er_fileutils_tilde_replace (output_directory));
615
link_dir = er_fileutils_tilde_replace (link_directory);
617
if (link_dir == NULL)
619
cpl_msg_warning (er_func, "missing directory for symbolic link ignored...");
622
/* Determine the name of the current directory */
624
(void) getcwd (current_dir, (size_t) FILEMAX);
628
(void) sprintf(trace_msg, "output_directory = %s>",output_directory);
630
(void) sprintf(trace_msg, "output_dir = %s>",output_dir);
632
(void) sprintf(trace_msg, "current_dir = %s>",current_dir);
634
(void) sprintf(trace_msg, "link_dir = %s>",link_dir);
638
ii = upda_products(frameset); /* MD5 errors ignored at the moment... */
642
/* Loop through the frameset */
644
move_err = 0; /* init possible error from moving files */
645
frame = cpl_frameset_get_first (frameset);
646
while (frame != NULL)
648
if (cpl_frame_get_group (frame) == CPL_FRAME_GROUP_PRODUCT)
651
/* Get the filename as specified by the frame */
652
input_name = cpl_frame_get_filename (frame);
654
/* Temporarily remove the suffix (find the first '.' and replace it) */
655
suffix = strrchr (input_name, '.');
656
if (suffix) *suffix = '\0';
658
/* Generate the output filename (keep original if this is suppressed) */
659
if (flag_noprefix != 0)
661
(void) strcpy (output_name, input_name);
665
(void) sprintf (output_name, "%s_%04d", output_prefix, filenum);
668
/* Now restore the suffix (note difference between suffix and *suffix) */
669
if (suffix) *suffix = '.';
670
if (suffix) (void) strcat (output_name, suffix);
672
/* Check if any move-command is required */
674
cpp = cpl_frame_get_filename (frame);
677
cpl_msg_error (er_func, "cpl_frame_get_filename failed");
679
goto report_products;
682
if (((strcmp (current_dir, output_dir) == 0) ||
683
(strcmp (".", output_directory) == 0)) && /* same dir */
684
(strcmp (cpp, output_name) == 0)) /* same file */
686
/* No move. Report that the product has been created */
687
cpl_msg_info (er_func, "Created product %s (in place)", output_name);
691
{ /* Create the full path */
696
(void) sprintf(trace_msg, "input name = %s>",cpp);
698
(void) sprintf(trace_msg, "output_name = %s>",output_name);
702
if (output_name[0] == '\0')
703
(void) strcpy(tmp,"dummy_output");
705
(void) strcpy(tmp,output_name);
707
(void) strcpy (output_name, output_dir);
708
ii = (int) strlen(output_name) - 1;
709
if (output_name[ii] != '/') output_name[++ii] = '/';
710
(void) strcpy (&output_name[ii+1],tmp);
714
(void) sprintf(trace_msg, "input = %s",cpp);
716
(void) sprintf(trace_msg, "final output_name = %s",output_name);
721
rename() has problems:
722
a) it happily overwrites read-only files...
723
b) it does not work across different partitions (that's documented)
724
so we cannot simply do:
726
ret_val = rename (cpp, output_name);
729
ii = fileutils_move (cpp, output_name);
731
{ /* also that failed - so, no way... */
733
{ /* different name, but same inode ... */
734
cpl_msg_info (er_func, "Created product %s (in place)", output_name);
738
cpl_msg_error (er_func, "Unable to move product file to final "
739
"output location (%s)", output_name);
741
(void) sprintf(trace_msg, "fileutils_move returned: %d",ii);
743
goto report_products;
748
/* Update the name in the sof */
749
cpl_frame_set_filename(frame, output_name);
751
cpl_msg_info (er_func, "Created product %s", output_name);
755
/* If required, generate the symbolic links for the archive system */
756
if (flag_nolink == 0)
758
if (er_fileutils_link (link_dir, output_name) != EXIT_SUCCESS)
760
cpl_msg_error (er_func,
761
"Unable to create symbolic link for %s in "
762
"directory %s", output_name, link_dir);
764
goto report_products;
768
/* If required, lock the file permissions to read-only */
769
if (flag_readonly != 0) chmod (output_name, 0444);
771
filenum++; /* Increment the product number */
774
/* Get the next frame in the list */
776
frame = cpl_frameset_get_next (frameset);
777
} /* End of (while) loop through all frames in frameset */
780
/* Report how many products were created (getting the plural right!) */
783
cpl_msg_info (er_func, "%d product%s created", filenum, (filenum == 1) ? "" : "s");
784
cpl_free (output_name); /* free the allocated memory */
792
/**********************************************************************/
794
* @brief Process the Plugin
796
* @param caller_parameters Caller parameters
797
* @param plugin_name Name of Plugin to process
798
* @param sof_filename_list List of strings with SOF filenames
799
* @param argc Count of remaining arguments from cmdl
800
* @param argv Handle to remaining arguments from cmdl
802
* @returns 0 if successfull, !=0 otherwise
804
* Processes a Plugin.
808
/**********************************************************************/
810
int plugin_process_plugin (cpl_parameterlist * caller_parameters,
812
er_stringarray_t * sof_filename_list,
813
int argc, char * argv[])
816
const char *val_output_mask,
820
*val_output_dir, *cpp;
821
const char *val_string_tmp = NULL;
824
const char *val_paf_config;
826
char **val_recipe_dirs = NULL,
827
*log_file_name_full = NULL;
830
*plugin_conf_file_global=NULL,
831
*plugin_conf_file_local=NULL,
832
library_path[MAXSTRLENCONF];
834
char *val_create = NULL, *help_str = NULL;
836
int e_code = 0, e_code2 = 0, i = 0, ii = 0;
839
int flag_time_plugin = 0,
840
flag_plugin_found = 0,
843
flag_create_config = 0,
847
f_val_unload_plugin = 1, /* default is TRUE */
851
double plugin_time_start=0.0, plugin_time_end=0.0;
853
cpl_msg_severity msg_level = CPL_MSG_ERROR,
854
msg_sev_logfile, msg_sev_terminal;
855
cpl_parameter *p = NULL;
856
cpl_plugin *tplugin = NULL;
857
lt_dlhandle module = NULL;
858
cpl_plugin_func plugin_func_init = NULL,
859
plugin_func_exec = NULL,
860
plugin_func_deinit = NULL;
861
cpl_recipe *trecipe = NULL;
862
cpl_recipe2 *t2recipe = NULL;
864
cpl_error_code log_err;
866
er_stringarray_t *list_of_pllib_names = NULL;
874
library_path[0] = '\0';
876
/* check, if we want to take times */
877
p = cpl_parameterlist_find (caller_parameters, PACKAGE_RESOURCE ".time");
878
flag_time_plugin = cpl_parameter_get_bool (p);
879
if (flag_time_plugin != 0) /* --time option */
881
plugin_time_start = cpl_test_get_walltime();
884
msg_sev_logfile = message_severity (caller_parameters,1);
885
msg_sev_terminal = message_severity (caller_parameters,2);
887
p = cpl_parameterlist_find (caller_parameters, PACKAGE_RESOURCE ".log-dir");
888
val_log_dir = cpl_parameter_get_string (p);
889
ForceNull(val_log_dir)
891
p = cpl_parameterlist_find (caller_parameters, PACKAGE_RESOURCE ".log-file");
892
val_log_file = cpl_parameter_get_string (p);
893
ForceNull(val_log_file)
895
fileutils_create_fqfname ((char *) val_log_dir, (char *) val_log_file);
898
/* CPL messaging should already be active, but reset the defaults */
900
cpl_msg_set_domain (PACKAGE);
901
cpl_msg_set_time_off ();
902
cpl_msg_set_domain_on ();
903
cpl_msg_set_component_off ();
904
log_err = cpl_msg_set_log_level (msg_sev_logfile);
905
if (log_err != CPL_ERROR_NONE)
907
(void) printf ("WARNING : EsoRex is unable to establish the message log "
908
"(Error = %d)\n", log_err);
909
(void) printf (" (Check write permission for temporary files.)\n");
912
/* always save used library versions in logfile (only) */
914
cpl_msg_set_level (CPL_MSG_OFF);
915
cdescr = cpl_get_description(CPL_DESCRIPTION_DEFAULT);
917
(void) cpl_msg_info(er_func,"Libraries used: %s\n",cdescr);
918
cpl_msg_set_level (msg_sev_terminal);
921
/* look for recipe directory */
923
p = cpl_parameterlist_find (caller_parameters, PACKAGE_RESOURCE ".recipe-dir");
924
val_string_tmp = cpl_parameter_get_string (p);
925
ForceNull(val_string_tmp)
926
if (val_string_tmp != NULL)
927
val_recipe_dirs = cx_strsplit (val_string_tmp, ":", -1);
931
(void) sprintf(trace_msg,"plugin_process_plugin: recipe-dir = %s",val_string_tmp);
940
(void) sprintf(trace_msg,"plugin_name = %s]",plugin_name);
944
if ((plugin_name[0] == ' ') || (plugin_name[0] == '\0'))
949
if ((val_recipe_dirs != NULL) && (sz > 0))
951
list_of_pllib_names = er_pluginlist_create_list (val_recipe_dirs);
953
sz = er_pluginlist_get_libpath (list_of_pllib_names, plugin_name, library_path);
956
tplugin = er_pluginlist_get_plugin (library_path, plugin_name, &module);
959
flag_plugin_found = 1;
963
cpl_msg_error (er_func, "Unable to find recipe '%s'."
964
" Check that the recipe is in the path specified by the"
965
" '--recipe-dir' option.", plugin_name);
966
e_code = CPL_ERROR_INCOMPATIBLE_INPUT;
967
goto cleanup; /* we cannot do anything */
971
/* ------------------------------------- */
972
/* here we process the plugin (if found) */
973
/* ------------------------------------- */
978
printf("none = %d, recipe = %d, recipe_v2 = %d\n",CPL_PLUGIN_TYPE_NONE,CPL_PLUGIN_TYPE_RECIPE,CPL_PLUGIN_TYPE_RECIPE_V2);
982
uil = cpl_plugin_get_type(tplugin);
984
/* initialize the plugin/recipe structure: trecipe->parameters is handled by plugin */
988
n = sizeof (cpl_recipe);
989
trecipe = (cpl_recipe *) cpl_calloc (1,(size_t) n);
993
n = sizeof (cpl_recipe2);
994
t2recipe = (cpl_recipe2 *) cpl_calloc (1,(size_t) n);
995
trecipe = &t2recipe->base;
1000
("trying to support version 2 recipes ...\nplugin type: %d, size of recipe = %d\n",
1004
trecipe->frames = cpl_frameset_new ();
1007
if (flag_plugin_found != 0) /* = TRUE */
1009
cpl_plugin_copy ((cpl_plugin *) & trecipe->interface, tplugin);
1012
/* Run Plugin Initialization... */
1014
plugin_func_init = cpl_plugin_get_init ((cpl_plugin *) trecipe);
1015
if (plugin_func_init != NULL)
1017
cpl_msg_set_domain (cpl_plugin_get_name ((cpl_plugin *) trecipe));
1018
e_code = plugin_func_init ((cpl_plugin *) trecipe);
1019
cpl_msg_set_domain (PACKAGE);
1022
cpl_msg_error (er_func, "Init of recipe failed...");
1027
/* loop through all parameters in the list */
1029
p = cpl_parameterlist_get_first (trecipe->parameters);
1032
char recip_def[] = "recipe default";
1036
er_manage_sources(1,cpl_parameter_get_name(p),&myptr);
1038
/* Get the next parameter in the list */
1039
p = cpl_parameterlist_get_next (trecipe->parameters);
1043
cpp = cpl_plugin_get_name ((cpl_plugin *) trecipe);
1045
#ifdef USE_GLOBAL_PLUGIN_RC /* Parse any global plugin configuration file */
1047
cptr = getenv ("HOME");
1051
n = (int) strlen(cptr);
1052
if (cpp != NULL) n += (int)strlen(cpp);
1054
n = n + ((int)strlen(cpp)) +
1055
((int) strlen(GLOBAL_RC_DIR)) + ((int) strlen(GLOBAL_RC_EXTENSION));
1056
n += 4; /* for the additionial const chars */
1058
plugin_conf_file_global = (char *) cpl_malloc((size_t) n);
1059
if ( plugin_conf_file_global == NULL)
1061
cpl_msg_error (er_func,
1062
"Could not allocate %d bytes for plugin_conf_file_global",n);
1063
e_code = CPL_ERROR_ILLEGAL_OUTPUT;
1069
(void) strcpy(plugin_conf_file_global, "/");
1072
(void) strcpy(plugin_conf_file_global,cptr);
1073
(void) strcat(plugin_conf_file_global, "/");
1075
(void) strcat(plugin_conf_file_global, GLOBAL_RC_DIR);
1076
(void) strcat(plugin_conf_file_global, "/");
1077
if (cpp != NULL) (void) strcat(plugin_conf_file_global, cpp);
1078
(void) strcat(plugin_conf_file_global, GLOBAL_RC_EXTENSION);
1082
if (fileutils_file_exists(plugin_conf_file_global) != 0)
1084
e_code = params_parse_config_file (trecipe->parameters,
1085
plugin_conf_file_global);
1086
if (e_code != 0) goto plugin_deinit;
1091
#ifdef USE_LOCAL_PLUGIN_RC /* Parse any local plugin configuration file */
1094
n = (int)strlen(cpp);
1097
n = n + ((int) strlen(LOCAL_RC_PATH)) + ((int) strlen(GLOBAL_RC_EXTENSION));
1098
n += 4; /* for the additionial const chars */
1100
plugin_conf_file_local = (char *) cpl_malloc((size_t) n);
1101
if ( plugin_conf_file_local == NULL)
1103
cpl_msg_error (er_func,
1104
"Could not allocate %d bytes for plugin_conf_file_local",n);
1105
e_code = CPL_ERROR_ILLEGAL_OUTPUT;
1109
void) strcpy(plugin_conf_file_local,LOCAL_RC_PATH);
1110
(void) strcat(plugin_conf_file_local, "/");
1111
if (cpp != NULL) (void) strcat(plugin_conf_file_local, cpp);
1112
(void) strcat(plugin_conf_file_local, GLOBAL_RC_EXTENSION);
1116
if (fileutils_file_exists(plugin_conf_file_local) != 0)
1118
e_code = params_parse_config_file (trecipe->parameters,
1119
plugin_conf_file_local);
1120
if (e_code != 0) goto plugin_deinit;
1125
/* Parse any specifically specified plugin configuration file */
1128
p = cpl_parameterlist_find (caller_parameters,
1129
PACKAGE_RESOURCE ".recipe-config");
1130
val_string_tmp = cpl_parameter_get_string (p);
1132
if ((val_string_tmp != (char *) 0) && (strlen (val_string_tmp) > 0))
1133
e_code = params_parse_config_file (trecipe->parameters, val_string_tmp);
1139
char *str_tmp = NULL;
1141
e_code = params_parse_config_commandline
1142
(trecipe->parameters, plugin_name,
1143
sof_filename_list, argc, argv, 0);
1144
if (e_code != 0) goto plugin_deinit;
1146
params_parse_config_postprocess (trecipe->parameters);
1147
ii = er_stringarray_size(sof_filename_list);
1149
for (i=0; i<ii; i++)
1151
int flag_check_sof_exist;
1152
/* Get the check input files parameter */
1153
p = cpl_parameterlist_find (caller_parameters,
1154
PACKAGE_RESOURCE ".check-sof-exist");
1155
flag_check_sof_exist = cpl_parameter_get_bool (p);
1157
str_tmp = er_stringarray_get (sof_filename_list, i);
1158
if (er_frameset_load (str_tmp, trecipe->frames, flag_check_sof_exist) == NULL)
1160
cpl_msg_error (er_func, "Problem occurred loading frameset "
1161
"from the SOF file '%s'.\n"
1162
"If you want to ignore errors of missing files in "
1163
"the sof, set '--check-sof-exist=false'.", str_tmp);
1165
e_code = CPL_ERROR_FILE_NOT_FOUND;
1170
/* Check if we want to create the plugin (recipe) configuration file */
1172
p = cpl_parameterlist_find (caller_parameters, PACKAGE_RESOURCE ".create-config");
1173
if (cpl_parameter_get_default_flag (p))
1175
val_create = cpl_parameter_get_string (p);
1176
ForceNull(val_create)
1177
if (val_create != NULL) /* --create-config=bla.bla found */
1178
{ /* handle FALSE and TRUE from boolean history of this param */
1179
if (strcmp(val_create,"TRUE") == 0)
1181
flag_create_config = 1;
1183
else if (strcmp(val_create,"FALSE") != 0)
1185
flag_create_config = 11; /* indicates filename is given */
1188
else /* --create-config is interpreted as ...=TRUE */
1190
flag_create_config = 1;
1193
if (flag_create_config == 11)
1195
er_help_create_config (flag_create_config,val_create, caller_parameters, trecipe->parameters);
1198
else if (flag_create_config == 1)
1200
er_help_create_config (flag_create_config, plugin_name, caller_parameters, trecipe->parameters);
1204
/* Check if we want to display the plugin help */
1206
p = cpl_parameterlist_find (caller_parameters, PACKAGE_RESOURCE ".man-page");
1207
flag_man_page = cpl_parameter_get_bool (p);
1208
if (flag_man_page != 0)
1210
er_help_manpage (trecipe);
1214
/* Check if we want to display the plugin help */
1216
p = cpl_parameterlist_find (caller_parameters, PACKAGE_RESOURCE ".help");
1217
flag_help = cpl_parameter_get_bool (p);
1223
help_str = (char *) cpl_malloc((size_t) h_size);
1224
if (help_str == NULL)
1226
cpl_msg_error (er_func, "Could not allocate %d bytes for help_str",h_size);
1227
e_code = CPL_ERROR_ILLEGAL_OUTPUT;
1232
(void) strcpy (help_str, "Recipe: ");
1234
cpp = cpl_plugin_get_name ((cpl_plugin *) trecipe);
1235
n = (int) strlen(cpp);
1237
if (countr > h_size)
1238
{ /* allocate more space */
1239
h_size = countr + 120;
1240
er_enlarge(er_func,&help_str,h_size);
1242
(void) strcat (help_str, cpp);
1243
(void) strcat (help_str, " -- ");
1245
cpp = cpl_plugin_get_synopsis ((cpl_plugin *) trecipe);
1246
n = (int) strlen(cpp) + countr;
1248
{ /* allocate more space */
1250
er_enlarge(er_func,&help_str,h_size);
1252
(void) strcat (help_str, cpp);
1253
printf ("%s\n\n", er_strutils_split (help_str, 2, er_strutils_termwidth ()));
1255
msg_level = cpl_msg_get_level(); /* test, if we are in debug mode */
1256
if (msg_level == CPL_MSG_DEBUG)
1258
(void) strcpy (help_str, "Library: ");
1259
countr = 12; /* length of above */
1260
n = countr + (int) strlen(library_path);
1262
{ /* allocate more space */
1264
er_enlarge(er_func,&help_str,h_size);
1267
(void) strcat (help_str, library_path);
1268
printf ("%s\n\n", er_strutils_split (help_str, 2, er_strutils_termwidth ()));
1271
/* Display the actual help for the plugin */
1273
er_help_display (plugin_name, trecipe->parameters);
1275
/* Explain why the esorex help doesn't appear */
1277
(void) strcpy (tmp_buf,"For help on the options of " PACKAGE
1278
" itself, please use the command '" PACKAGE " --help' "
1279
"(that is, without specifying any recipe name). "
1280
"For more information about the recipe, one can also use "
1281
"the command '" PACKAGE " --man-page ");
1282
countr = (int) strlen(tmp_buf);
1284
cpp = cpl_plugin_get_name ((cpl_plugin *) trecipe);
1285
n = (int) strlen(cpp) + countr + 4;
1290
er_enlarge("plugin_process_plugin",&help_str,h_size);
1293
(void) strcpy (help_str, tmp_buf);
1294
(void) strcat (help_str, cpp);
1295
(void) strcat (help_str, "'.");
1297
("%s\n", er_strutils_split (help_str, 0, er_strutils_termwidth ()));
1299
goto plugin_deinit; /* avoid plugin execution */
1302
/* Check if we want to display the plugin parameters */
1304
p = cpl_parameterlist_find (caller_parameters,PACKAGE_RESOURCE ".params");
1305
flag_params = cpl_parameter_get_bool (p);
1306
if (flag_params != 0)
1308
if (er_paramutils_print_list(trecipe->parameters,"Recipe Parameters") != 0)
1310
cpl_msg_error (er_func,"Unable to print the recipe parameter list\n");
1311
e_code = CPL_ERROR_INCOMPATIBLE_INPUT;
1314
goto plugin_deinit; /* avoid plugin execution */
1317
/* Check if we don't want to cleanup after processing (for debugging) */
1319
p = cpl_parameterlist_find (caller_parameters,PACKAGE_RESOURCE ".unload-plugin");
1320
f_val_unload_plugin = cpl_parameter_get_bool (p);
1321
/* printf("f_val_unload_plugin = %d\n",f_val_unload_plugin); */
1325
* Run Plugin Execute - if all went well until here...
1330
plugin_func_exec = cpl_plugin_get_exec ((cpl_plugin *) trecipe);
1332
if (plugin_func_exec != NULL)
1333
{ /* We have a pointer, so run the plugin */
1334
const char *recipe_name;
1336
recipe_name = cpl_plugin_get_name ((cpl_plugin *) trecipe);
1337
cpl_msg_set_domain (recipe_name);
1338
e_code = plugin_func_exec ((cpl_plugin *) trecipe);
1339
cpl_msg_set_domain (PACKAGE);
1342
cpl_msg_error (er_func,"Execution of recipe '%s' failed, status = %d",
1343
recipe_name,e_code);
1346
else /* NULL-pointer, so we simply set an error */
1347
e_code = CPL_ERROR_INCOMPATIBLE_INPUT;
1350
if (e_code == 0) /* successful execution of recipe */
1352
p = cpl_parameterlist_find (caller_parameters,
1353
PACKAGE_RESOURCE ".output-dir");
1354
val_output_dir = cpl_parameter_get_string (p);
1355
ForceNull(val_output_dir)
1357
p = cpl_parameterlist_find (caller_parameters,
1358
PACKAGE_RESOURCE ".link-dir");
1359
val_link_dir = cpl_parameter_get_string (p);
1360
ForceNull(val_link_dir)
1362
p = cpl_parameterlist_find (caller_parameters,
1363
PACKAGE_RESOURCE ".output-prefix");
1364
val_output_mask = cpl_parameter_get_string (p);
1365
ForceNull(val_output_mask)
1367
p = cpl_parameterlist_find (caller_parameters,
1368
PACKAGE_RESOURCE ".output-readonly");
1369
flag_readonly = cpl_parameter_get_bool (p);
1371
p = cpl_parameterlist_find (caller_parameters,
1372
PACKAGE_RESOURCE ".suppress-prefix");
1373
flag_noprefix = cpl_parameter_get_bool (p);
1375
p = cpl_parameterlist_find (caller_parameters,
1376
PACKAGE_RESOURCE ".suppress-link");
1377
flag_nolink = cpl_parameter_get_bool (p);
1379
/* Move all product files to output directory */
1381
e_code = move_products (trecipe->frames, (char *)val_output_dir,
1382
(char *)val_output_mask,
1383
(char *)val_link_dir, flag_noprefix, flag_nolink, flag_readonly);
1385
if (e_code != 0) cpl_msg_error (er_func,
1386
"An error occurred while trying to move the output products");
1389
else /* recipe failed, only get correct MD5 sum */
1390
{ /* for all product files created anyway */
1391
if (e_code != -99999) ii = upda_products (trecipe->frames);
1394
/* Run PAF creation */
1395
p = cpl_parameterlist_find (caller_parameters,
1396
PACKAGE_RESOURCE ".paf-config");
1397
val_paf_config = cpl_parameter_get_string (p);
1398
ForceNull(val_paf_config)
1399
if(val_paf_config != NULL)
1401
if (e_code == 0) /* successful execution of recipe and product move*/
1403
e_code = er_create_recipe_pafs(trecipe->frames,
1404
trecipe->interface.name,
1408
cpl_msg_error (er_func,"Cannot create paf files, status = %d",
1414
cpl_msg_warning (er_func,"Writing of paf files omitted"
1415
" due to previous errors");
1420
/* Run Plugin Deinitialisation... */
1423
if (f_val_unload_plugin == 0) /* we want to keep all memory */
1425
cpl_msg_info(er_func,
1426
"The plugin info will not be removed after execution!");
1427
goto final_end; /* as it is for debugging! */
1430
plugin_func_deinit = cpl_plugin_get_deinit ((cpl_plugin *) trecipe);
1432
if (plugin_func_deinit != NULL)
1434
cpl_msg_set_domain (cpl_plugin_get_name ((cpl_plugin *) trecipe));
1435
e_code2 = plugin_func_deinit ((cpl_plugin *) trecipe);
1436
cpl_msg_set_domain (PACKAGE);
1441
/* For now deinitialization is empty */
1444
/* If out main err.code is "OKAY", then use the deinit one, */
1445
/* (otherwise, preserve the original error). */
1447
if (e_code == 0) e_code = e_code2;
1451
if ((flag_time_plugin != 0) && (flag_plugin_found != 0))
1454
int infile_count = 0;
1455
cpl_frame *frame = NULL;
1456
const char *input_name = NULL;
1458
plugin_time_end = cpl_test_get_walltime();
1459
if (plugin_time_end > plugin_time_start)
1461
plugin_time_end -= plugin_time_start; /* reuse for time difference */
1465
plugin_time_end = -1.0;
1468
/* loop again over frameset - now, all tags should be set by the recipe */
1470
frame = cpl_frameset_get_first (holdme);
1471
while (frame != NULL)
1473
if (cpl_frame_get_group (frame) == CPL_FRAME_GROUP_RAW)
1474
{ /* Get the filename as specified by the frame */
1475
input_name = cpl_frame_get_filename (frame);
1476
if (add_size (input_name,&fsz) != 0) /* accumulate size (in bytes) of raw input frames */
1478
cpl_msg_warning("could not get size of %s\n",input_name);
1485
frame = cpl_frameset_get_next (holdme);
1488
if ((plugin_time_end > 0.0) && (fsz > 0.0))
1490
cpl_msg_info (er_func, "Recipe operation(s) took %14.3g seconds to complete.",
1496
cpl_msg_info (er_func, "No timing function [gettimeofday()] available...\n");
1503
if (infile_count > 1)
1504
cpl_msg_info (er_func, "Total size of %d raw input frames = %8.2f MB\n",infile_count,fsz);
1506
cpl_msg_info (er_func, "Size of single raw input frame = %8.2f MB\n",fsz);
1508
if (plugin_time_end > 0.0)
1510
fsz /= plugin_time_end;
1511
cpl_msg_info (er_func, "=> processing rate of %8.2f MB/sec \n",fsz);
1517
cpl_msg_info (er_func, "No size information obtained for raw input frames(s)...\n");
1522
/* Terminate CPL messaging */
1525
/* currently cpl_msg_stop_log () always returns CPL_ERROR_NONE ... 080613 */
1526
if (cpl_msg_stop_log () != CPL_ERROR_NONE)
1527
cpl_msg_error (er_func, "An error was encountered while closing the logfile");
1529
if (flag_plugin_found != 0)
1530
{ /* Move log file... */
1531
char tmpbuf[FILEMAX+12];
1533
(void) getcwd (tmpbuf, (size_t) FILEMAX);
1534
(void) strcat (tmpbuf, "/.logfile");
1536
if (fileutils_file_is_there(tmpbuf) != 0)
1537
{ /* .logfile exists ... */
1538
char dstbuf[FILEMAX+2];
1540
(void) strcpy (dstbuf, val_log_dir);
1541
(void) strcat (dstbuf, "/");
1542
(void) strcat (dstbuf, val_log_file);
1543
n = fileutils_copy(tmpbuf,dstbuf); /* copy .logfile to "real" log file */
1546
(void) printf("we could not copy .logfile to %s (err-code = %d)\n",
1551
if (n == 0) (void) unlink(tmpbuf); /* get rid of .logfile */
1556
cpl_msg_set_component_off ();
1557
cpl_msg_set_time_off ();
1558
cpl_msg_set_domain_off ();
1561
/* free memory again */
1563
if (help_str != NULL) cpl_free (help_str);
1565
if (log_file_name_full != NULL) cpl_free (log_file_name_full);
1566
if (plugin_conf_file_global != NULL) cpl_free (plugin_conf_file_global);
1567
if (plugin_conf_file_local != NULL) cpl_free (plugin_conf_file_local);
1569
if (val_recipe_dirs != NULL) cx_strfreev (val_recipe_dirs);
1570
if (list_of_pllib_names != NULL) er_stringarray_delete (list_of_pllib_names);
1572
if (tplugin != NULL) cpl_plugin_delete (tplugin);
1576
if (module != NULL) lt_dlclose (module);
1579
if (t2recipe != NULL)
1580
{ /* we have a version 2 recipe! */
1581
cpl_frameset_delete (trecipe->frames);
1582
cpl_plugin_delete ((cpl_plugin *) t2recipe);
1584
else if (trecipe != NULL)
1585
{ /* trecipe->parameters handled by plugin */
1586
cpl_frameset_delete (trecipe->frames);
1587
cpl_plugin_delete ((cpl_plugin *) trecipe);
1591
if (e_code == -99999) e_code = 0;
1593
} /* End of plugin_process_plugin() */
1599
/**********************************************************************/
1601
* @brief Enlarge memory buffer
1602
* @param func name of caller
1603
* @param mem_pntr addr. of pointer to allocated memory buffer
1604
* @param mem_size new (increased) size for memory buffer
1606
* @returns 0 if successfull, !=0 otherwise
1608
* This function frees the currently allocated space and uses the pointer
1609
* 'mem_pntr' to point to newly allocated memory
1611
/**********************************************************************/
1613
void er_enlarge (const char *fn, char **pptr, int msize)
1619
ptr = (void *) *pptr; /* get address to free */
1621
newptr = cpl_realloc(ptr,(size_t) msize);
1622
if (newptr == NULL) /* couldn't get the memory... */
1624
cpl_msg_error (fn, "Could not allocate %d bytes - fatal error", msize);
1625
exit (EXIT_FAILURE);
1628
*pptr = (char *) newptr;