diff --git a/Changelog.txt b/Changelog.txt
index 264d7fc9..475fbc54 100644
--- a/Changelog.txt
+++ b/Changelog.txt
@@ -2,6 +2,13 @@ This is log of changes in the DABC project.
It is the best (and sometimes the only) place to find information
about current functionality of the framework.
+06.05.2024
+1. First implementation of runtime plugin for ELDER analysis framework (by Michael Reese). Requires external elder installation.
+ May read data directly from MBS via stream server socket, or from list mode data files using the olmd plugin. [JAM]
+2. Added new plugin OLMD for reading original formatted lmd files. In contrast to the mbs plugin, it will use internally the full MBS event api libraries,
+ like in Go4 framework. This allows to handle all lmd files that were written by MBS DAQ. [JAM]
+
+
20.12.2023
1. Fix mbs stream server transport. Command like `socat /dev/null TCP:localhost:6002` can harm server.
It establish connection and then immediately close socket. In some situations server transport get
diff --git a/cmake/modules/DabcBuildOptions.cmake b/cmake/modules/DabcBuildOptions.cmake
index 81fe711a..f3b09df2 100644
--- a/cmake/modules/DabcBuildOptions.cmake
+++ b/cmake/modules/DabcBuildOptions.cmake
@@ -79,12 +79,14 @@ dabc_build_option(mbs ON "Enable MBS plugin")
dabc_build_option(rfio ON "Enable RFIO plugin")
dabc_build_option(saft OFF "Enable SAFT plugin")
dabc_build_option(stream ON "Enable Stream plugin")
+dabc_build_option(elder ON "Enable ELDER plugin")
dabc_build_option(user ON "Enable USER plugin")
dabc_build_option(verbs ON "Enable VERBS plugin")
dabc_build_option(root ON "Enable ROOT plugin")
dabc_build_option(dogma ON "Enable DOGMA plugin")
dabc_build_option(dofi ON "Enable DOFI plugin")
dabc_build_option(mbsroot ON "Enable MBS-ROOT plugin")
+dabc_build_option(olmd ON "Enable Original LMD plugin")
# --- The 'all' option switches ON major options ------------------------------
if(all)
@@ -101,12 +103,14 @@ if(all)
set(rfio_defvalue ON)
set(saft_defvalue ON)
set(stream_defvalue ON)
+ set(elder_defvalue ON)
set(user_defvalue ON)
set(verbs_defvalue ON)
set(root_defvalue ON)
set(dogma_defvalue ON)
set(dofi_defvalue ON)
set(mbsroot_defvalue ON)
+ set(olmd_defvalue ON)
endif()
# --- The 'all' option switches ON major options ------------------------------
@@ -124,12 +128,14 @@ if(minimal)
set(rfio_defvalue ON)
set(saft_defvalue OFF)
set(stream_defvalue OFF)
+ set(elder_defvalue OFF)
set(user_defvalue OFF)
set(verbs_defvalue OFF)
set(root_defvalue OFF)
set(dogma_defvalue OFF)
set(dofi_defvalue OFF)
set(mbsroot_defvalue OFF)
+ set(olmd_defvalue ON)
endif()
# --- Define at moment the options with the selected default values -----------
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index a4ff7974..36078fee 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -31,6 +31,11 @@ if(stream)
add_subdirectory(stream)
endif()
+
+if(elder)
+ add_subdirectory(elder)
+endif()
+
if(aqua)
add_subdirectory(aqua)
endif()
@@ -71,4 +76,8 @@ if(saft)
add_subdirectory(saft)
endif()
+if(olmd)
+ add_subdirectory(olmd)
+endif()
+
add_subdirectory(user)
diff --git a/plugins/elder/CMakeLists.txt b/plugins/elder/CMakeLists.txt
new file mode 100644
index 00000000..9002aaad
--- /dev/null
+++ b/plugins/elder/CMakeLists.txt
@@ -0,0 +1,19 @@
+find_package(ELDER)
+
+if(ELDER_FOUND)
+ dabc_link_library(
+ DabcElder
+ SOURCES src/RunModule.cxx src/Factory.cxx src/VisConDabc.cxx
+ HEADERS elderdabc/RunModule.h elderdabc/VisConDabc.h elderdabc/Factory.h
+ INCDIR elderdabc
+ LIBRARIES dabc::DabcBase dabc::DabcMbs ${ELDER_LIBRARY} ${ELDER-STD_LIBRARY} ${ELDER-GSI_LIBRARY} ${ELDER-EEL_LIBRARY}
+ INCLUDES ${ELDER_INCLUDE_DIR}
+ )
+
+ dabc_install_plugin_data(
+ DabcElder
+ DIRECTORIES icons app
+ DESTINATION ${DABC_INSTALL_PLUGINDIR}/elder
+ )
+
+endif()
diff --git a/plugins/elder/app/Elder.xml b/plugins/elder/app/Elder.xml
new file mode 100644
index 00000000..425cc8ec
--- /dev/null
+++ b/plugins/elder/app/Elder.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/elder/app/lycca.config b/plugins/elder/app/lycca.config
new file mode 100644
index 00000000..17734ca3
--- /dev/null
+++ b/plugins/elder/app/lycca.config
@@ -0,0 +1,251 @@
+using std
+using gsi_gs
+#using geant4
+
+processor trigger std.single
+ value <- event.trigger
+ histogram value 16,0,16
+end
+
+crate LyccaWallCrate1
+ procid 70
+ triggers all
+ module adc01 gsi_gs.CAENv785
+ module adc02 gsi_gs.CAENv785
+ module adc05 gsi_gs.CAENv785
+ module adc06 gsi_gs.CAENv785
+ module adc07 gsi_gs.CAENv785
+ module adc08 gsi_gs.CAENv785
+ module adc11 gsi_gs.CAENv785
+ module adc12 gsi_gs.CAENv785
+ module mhtdc gsi_gs.CAENv767
+ hitpattern
+end
+
+crate LyccaWallCrate2
+ procid 80
+ triggers all
+ module adc13 gsi_gs.CAENv785
+ module adc14 gsi_gs.CAENv785
+ module adc17 gsi_gs.CAENv785
+ module adc18 gsi_gs.CAENv785
+ module adc19 gsi_gs.CAENv785
+ module adc20 gsi_gs.CAENv785
+ module adc23 gsi_gs.CAENv785
+ module adc24 gsi_gs.CAENv785
+ module mhtdc gsi_gs.CAENv767
+ hitpattern
+end
+#crate LyccaWallCsICrate
+# procid 85
+# triggers all
+# module adc0 gsi_gs.MADC32
+# module adc1 gsi_gs.MADC32
+# module adc2 gsi_gs.MADC32
+# module adc3 gsi_gs.MADC32
+# module adc4 gsi_gs.MADC32
+# module adc5 gsi_gs.MADC32
+# module tdc0 gsi_gs.CAENv775
+# module tdc1 gsi_gs.CAENv775
+# module mhtdc gsi_gs.CAENv767
+# hitpattern
+#end
+crate LyccaTargetTofCrate
+ procid 90
+ triggers all
+ module adc0 gsi_gs.CAENv785
+ module adc1 gsi_gs.CAENv785
+ module tdc gsi_gs.CAENv775
+ module mhtdc0 gsi_gs.CAENv1290TMM
+ module mhtdc1 gsi_gs.CAENv1290TMM
+ module mhtdc2 gsi_gs.CAENv1290TMM
+ hitpattern
+ display
+end
+
+crate FrsCrate
+ procid 10
+ module header std.single32bit
+ module hp gsi_gs.FRShp
+ module tdc0 gsi_gs.CAENv775frs
+ module tdc1 gsi_gs.CAENv775frs
+ module adc0 gsi_gs.CAENv785frs
+ module qdc1 gsi_gs.CAENv792frs
+ #print
+ display
+ for $i in 0
+ hitpattern
+ end
+end
+
+processor Frs/Scintillators/dEnergySc21 std.pair
+ first <- FrsCrate.qdc1[16]
+ second <- FrsCrate.qdc1[17]
+ display first:second
+ display first
+ display second
+end
+
+
+alias $NUM_CHANNELS = 20
+crate SIS3302
+ procid 120
+ triggers all
+ for $i in [0:{$NUM_CHANNELS-1}]
+ module header_$i_0 std.single32bit
+ module header_$i_1 std.single32bit
+ module header_$i_2 std.single32bit
+ module header_$i_3 std.single32bit
+ module header_$i_4 std.single32bit
+ module trace_$i std.multiple32bit(200)
+ end
+ for $j in [0:10]
+ #blub
+ end
+ #hitpattern
+end
+
+processor SIS3302/traces std.array adhoc
+ parameter index_range = $NUM_CHANNELS
+ for $i in [0:{$NUM_CHANNELS-1}]
+ entry[$i] <- SIS3302.trace_$i[0]
+ end
+ waveform entry
+end
+
+for $h in [0:4]
+ processor SIS3302/header_$h/channels std.array adhoc
+ parameter index_range = $NUM_CHANNELS
+ for $i in [0:{$NUM_CHANNELS-1}]
+ entry[$i] <- SIS3302.header_$i_$h[0]
+ end
+ histogram entry 3000,0,500000
+ end
+ processor SIS3302/header_$h/channel_sum std.array adhoc
+ parameter index_range = 1
+ for $i in [0:{$NUM_CHANNELS-1}]
+ entry[0] <- SIS3302.header_$i_$h[0]
+ end
+ histogram sum 3000,0,5000000
+ end
+end
+
+
+#processor simulation/EventGenerator geant4.PlungerSimulator
+# histogram decay_E 4096,0,4096
+# histogram decay_beta
+#end
+#processor simulation/Geant4Detector geant4.DetectorGeant4
+# gamma_pos_x[0] <- simulation/EventGenerator.decay_x[0]
+# gamma_pos_y[0] <- simulation/EventGenerator.decay_y[0]
+# gamma_pos_z[0] <- simulation/EventGenerator.decay_z[0]
+# gamma_dir_x[0] <- simulation/EventGenerator.decay_rx[0]
+# gamma_dir_y[0] <- simulation/EventGenerator.decay_ry[0]
+# gamma_dir_z[0] <- simulation/EventGenerator.decay_rz[0]
+# gamma_T[0] <- simulation/EventGenerator.decay_t[0]
+# gamma_E[0] <- simulation/EventGenerator.decay_E[0]
+#
+# histogram detected_E:::detected_E 2048,0,1024:2048,0,1024
+# histogram detected_E 2048,0,4096
+#end
+
+#processor simulation/GeGe std.array_pair adhoc
+# parameter index_range_first = 14
+# parameter index_range_second = 14
+# first[0:13] <- simulation/Geant4Detector.detected_E[0:13]
+# second[0:13] <- simulation/Geant4Detector.detected_E[0:13]
+# histogram first:::second 2048,0,1024:2048,0,1024
+#end
+#processor simulation/LaBrLaBr std.array_pair adhoc
+# parameter index_range_first = 6
+# parameter index_range_second = 6
+# first[0:5] <- simulation/Geant4Detector.detected_E[14:19]
+# second[0:5] <- simulation/Geant4Detector.detected_E[14:19]
+# histogram first:::second 512,0,1024:512,0,1024
+#end
+
+for $direction in x y
+ processor generator/gauss_$direction std.rand_gaussian adhoc
+ parameter mean = 0
+ parameter sigma = 1
+ histogram value 100
+ end
+end
+processor generator/gauss_xy std.pair
+ first <- generator/gauss_x.value
+ second <- generator/gauss_y.value
+ histogram first:second 500,-10,10:500,-10,10
+end
+processor dsssd/pAmplitude_pOverflow std.pair
+ for $i in [0:31]
+ first <- LyccaTargetTofCrate.adc0[$i].amplitude
+ second <- LyccaTargetTofCrate.adc0[$i].overflow
+ end
+ histogram first:second 200,0,5000:200,0,5000
+end
+processor dsssd/pn_amplitude std.pair
+ for $i in [0:31]
+ first <- LyccaTargetTofCrate.adc0[$i].amplitude
+ second <- LyccaTargetTofCrate.adc1[$i].amplitude
+ end
+ histogram first:second 1000:1000
+end
+processor dsssd/p_n_overflow std.array
+ parameter index_range = 2
+ for $i in [0:31]
+ entry[0] <- LyccaTargetTofCrate.adc0[$i].overflow
+ entry[1] <- LyccaTargetTofCrate.adc1[$i].overflow
+ end
+ histogram entry
+end
+processor dsssd/p_n_underthreshold std.array
+ parameter index_range = 2
+ for $i in [0:31]
+ entry[0] <- LyccaTargetTofCrate.adc0[$i].underthreshold
+ entry[1] <- LyccaTargetTofCrate.adc1[$i].underthreshold
+ end
+ histogram entry
+end
+
+
+for $i in [10:67]
+ processor generator/rand_$i std.rand_uniform adhoc
+ parameter left = 50
+ parameter right = 100
+ histogram value in rand
+ end
+end
+
+alias $N = 9
+processor trace std.array adhoc
+ parameter index_range = $N
+ for $i in [0:{$N-1}]
+ for $j in [0:49]
+ entry[$i] <- generator/rand_{10+$i+$j}.value
+ end
+ end
+ histogram entry
+ waveform entry
+ picture entry 10:5
+end
+
+processor EventRate std.pair
+ first <- event.number
+ second <- event.time
+ ratemeter first:second 0.1,200
+end
+
+processor conditions/poly std.condition_window2d
+ x <- generator/rand_10.value
+ y <- generator/rand_11.value
+ histogram x:y | xy_window
+end
+
+processor gated/test std.pair
+ first <- generator/rand_10.value
+ second <- generator/rand_11.value
+ condition <- conditions/poly.inside
+ histogram valid_first:valid_second
+end
+
+
diff --git a/plugins/elder/app/twinpeaks.config b/plugins/elder/app/twinpeaks.config
new file mode 100644
index 00000000..399b8380
--- /dev/null
+++ b/plugins/elder/app/twinpeaks.config
@@ -0,0 +1,60 @@
+using std
+using eel
+#using ttree
+
+crate kinpex1
+ procid 100
+ types 10
+ subtypes 1
+ controls 9
+
+ #module wr1 std.single32bit
+ #module wr2 std.single32bit
+ #module wr3 std.single32bit
+ #module wr4 std.single32bit
+ #module wr5 std.single32bit
+
+ module tamex1 eel.TAMEX
+
+ hitpattern
+end
+
+for $edge in leading trailing
+ processor cal/tamex_$edge eel.TAMEXcal
+ parameter do_calibration = 0
+ fine[0:31] <- kinpex1.tamex1[0:31].$edge_fine
+ coarse[0:31] <- kinpex1.tamex1[0:31].$edge_coarse
+ epoch_cnt[0:31] <- kinpex1.tamex1[0:31].$edge_epoch_cnt
+ histogram fine 1000,0,1000
+ # histogram smooth_fine_ps:::smooth_fine_ps 300,0,5000:300,0,5000
+ histogram fine_ps:::fine_ps 300,0,5000:300,0,5000
+ end
+end
+
+processor anl/twinpeaks eel.TwinPeaks
+ leading_epoch[0:31] <- cal/tamex_leading.epoch[0:31]
+ leading_time[0:31] <- cal/tamex_leading.smooth_time_ps[0:31]
+ leading_stddev[0:31] <- cal/tamex_leading.sdev_ps[0:31]
+
+ trailing_epoch[0:31] <- cal/tamex_trailing.epoch[0:31]
+#channel_idx >= 32
+
+ trailing_time[0:31] <- cal/tamex_trailing.smooth_time_ps[0:31]
+ trailing_stddev[0:31] <- cal/tamex_trailing.sdev_ps[0:31]
+
+ histogram fastToT 1000,0,3000000
+ histogram linearToT 1000,0,3000000
+ histogram fast_missing_edge_cases 4,1,5
+ histogram linear_missing_edge_cases 4,1,5
+end
+
+processor event_rate std.pair
+ first <- event.number
+ second <- event.time
+ ratemeter first:second
+end
+
+
+# processor my_tree/fine[32] ttree.DoubleArrayStatic
+# value[0:31] <- cal/tamex_leading.smooth_fine_ps[0:31]
+# end
diff --git a/plugins/elder/elderdabc/Factory.h b/plugins/elder/elderdabc/Factory.h
new file mode 100644
index 00000000..3052f74f
--- /dev/null
+++ b/plugins/elder/elderdabc/Factory.h
@@ -0,0 +1,40 @@
+// $Id$
+
+/************************************************************
+ * The Data Acquisition Backbone Core (DABC) *
+ ************************************************************
+ * Copyright (C) 2009 - *
+ * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
+ * Planckstr. 1, 64291 Darmstadt, Germany *
+ * Contact: http://dabc.gsi.de *
+ ************************************************************
+ * This software can be used under the GPL license *
+ * agreements as stated in LICENSE.txt file *
+ * which is part of the distribution. *
+ ************************************************************/
+
+#ifndef ELDERDABC_Factory
+#define ELDERDABC_Factory
+
+#ifndef DABC_Factory
+#include "dabc/Factory.h"
+#endif
+
+/** \brief Support for stream framework in DABC */
+
+namespace elderdabc {
+
+ /** \brief %Factory for ELDER DABC classes */
+
+ class Factory : public dabc::Factory {
+ public:
+ Factory(const std::string &name) : dabc::Factory(name) {}
+
+ dabc::Module *CreateModule(const std::string &classname, const std::string &modulename, dabc::Command cmd) override;
+
+
+ };
+
+}
+
+#endif
diff --git a/plugins/elder/elderdabc/RunModule.h b/plugins/elder/elderdabc/RunModule.h
new file mode 100644
index 00000000..1fc6487a
--- /dev/null
+++ b/plugins/elder/elderdabc/RunModule.h
@@ -0,0 +1,94 @@
+// $Id$
+
+/************************************************************
+ * The Data Acquisition Backbone Core (DABC) *
+ ************************************************************
+ * Copyright (C) 2009 - *
+ * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
+ * Planckstr. 1, 64291 Darmstadt, Germany *
+ * Contact: http://dabc.gsi.de *
+ ************************************************************
+ * This software can be used under the GPL license *
+ * agreements as stated in LICENSE.txt file *
+ * which is part of the distribution. *
+ ************************************************************/
+
+#ifndef ELDER_RunModule
+#define ELDER_RunModule
+
+#ifndef DABC_ModuleAsync
+#include "dabc/ModuleAsync.h"
+#endif
+
+#include "dabc/timing.h"
+
+namespace mbs {class ReadIterator;}
+
+ namespace elderpt { namespace control { class Controller; class Event;} }
+
+
+namespace elderdabc {
+
+ class VisConDabc;
+
+
+ /** \brief Runs code of elder framework
+ *
+ * Module used to run code, available in elder framework
+ */
+
+ class RunModule : public dabc::ModuleAsync {
+
+ protected:
+ //int fParallel{0}; /// how many parallel processes to start
+ //void *fInitFunc{nullptr}; /// init function
+ //int fStopMode{0}; /// for central module waiting that others finish
+
+
+ elderdabc::VisConDabc* fViscon; // visualization interface
+ ::elderpt::control::Controller* fAnalysis; //handle to elder analysis framework
+ ::elderpt::control::Event* fEvent; // the current event to be processed
+ std::string fElderConfigFile; //!
+
+#include "dabc/Hierarchy.h"
+#include "dabc/Command.h"
+#include "dabc/Worker.h"
+
+#include
+#include
+
+namespace elderdabc {
+
+
+ typedef double* H1handle;
+ typedef double* H2handle;
+ typedef void* C1handle;
+
+
+class VisConDabc : public ::elderpt::viscon::Interface
+{
+
+
+
+ private:
+
+ std::vector fvHistograms1d; // keep pointers to 1d histograms in hierarchy. index in vector used as handle for elder
+ std::vector fvHistograms2d; // keep pointers to 2d histograms in hierarchy. index in vector used as handle for elder
+
+ // TODO: condition painter in dabc?
+// std::vector conditions1d_;
+// std::vector conditions2d_;
+// std::vector conditions2d_poly_;
+
+ protected:
+
+ dabc::Hierarchy fTop;
+ //bool fWorkingFlag{false};
+
+ dabc::LocalWorkerRef fStore;
+ std::string fStoreInfo; /// &points,
+ elderpt::viscon::Interface::Histogram1DHandle h);
+
+ void cond2d_get(::elderpt::viscon::Interface::Condition2DHandle h, std::vector &points) override;
+
+
+
+
+
+ // JAM from stream: redefine only make procedure, fill and clear should work
+// base::H1handle MakeH1(const char* name, const char* title, int nbins, double left, double right, const char* xtitle = nullptr) override;
+//
+// base::H2handle MakeH2(const char* name, const char* title, int nbins1, double left1, double right1, int nbins2, double left2, double right2, const char* options = nullptr) override;
+//
+// void SetH1Title(base::H1handle h1, const char* title) override;
+// void TagH1Time(base::H1handle h1) override;
+//
+// void SetH2Title(base::H2handle h2, const char* title) override;
+// void TagH2Time(base::H2handle h2) override;
+//
+// void ClearAllHistograms() override;
+
+ void SetSortedOrder(bool on = true) { fSortOrder = on; }
+ bool IsSortedOrder() { return fSortOrder; }
+
+ void AddRunLog(const char *msg);// override;
+ void AddErrLog(const char *msg);// override;
+// bool DoLog() override { return true; }
+
+ // void PrintLog(const char *msg);// override;
+
+// bool CallFunc(const char* funcname, void* arg) override;
+//
+// bool CreateStore(const char* storename) override;
+// bool CloseStore() override;
+//
+// bool CreateBranch(const char* name, const char* class_name, void** obj) override;
+// bool CreateBranch(const char* name, void* member, const char* kind) override;
+//
+// bool StoreEvent() override;
+
+ bool ExecuteHCommand(dabc::Command cmd);
+
+ bool SaveAllHistograms() { return SaveAllHistograms(fTop); }
+
+ std::string GetStoreInfo() const { return fStoreInfo; }
+ };
+
+}
+
+#endif
diff --git a/plugins/elder/icons/clear.png b/plugins/elder/icons/clear.png
new file mode 100644
index 00000000..b90786bf
Binary files /dev/null and b/plugins/elder/icons/clear.png differ
diff --git a/plugins/elder/icons/icons.dfPackage b/plugins/elder/icons/icons.dfPackage
new file mode 100644
index 00000000..6072cdf6
--- /dev/null
+++ b/plugins/elder/icons/icons.dfPackage
@@ -0,0 +1,22 @@
+package id8mmsgqls8x24lols8x82vy;
+
+/**
+@version 2.0
+@physicalPackage
+@__modelType diagram
+*/
+class diagram {
+}/**
+@__tags
+@shapeType ClassDiagram
+*/
+class __tags {
+}/**
+@__options
+*/
+class __options {
+}/**
+@__positions
+*/
+class __positions {
+}
\ No newline at end of file
diff --git a/plugins/elder/icons/save.png b/plugins/elder/icons/save.png
new file mode 100644
index 00000000..ecd033d5
Binary files /dev/null and b/plugins/elder/icons/save.png differ
diff --git a/plugins/elder/icons/start.png b/plugins/elder/icons/start.png
new file mode 100644
index 00000000..e8b55dbf
Binary files /dev/null and b/plugins/elder/icons/start.png differ
diff --git a/plugins/elder/icons/stop.png b/plugins/elder/icons/stop.png
new file mode 100644
index 00000000..1965a41c
Binary files /dev/null and b/plugins/elder/icons/stop.png differ
diff --git a/plugins/elder/src/Factory.cxx b/plugins/elder/src/Factory.cxx
new file mode 100644
index 00000000..55bba739
--- /dev/null
+++ b/plugins/elder/src/Factory.cxx
@@ -0,0 +1,37 @@
+// $Id$
+
+/************************************************************
+ * The Data Acquisition Backbone Core (DABC) *
+ ************************************************************
+ * Copyright (C) 2009 - *
+ * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
+ * Planckstr. 1, 64291 Darmstadt, Germany *
+ * Contact: http://dabc.gsi.de *
+ ************************************************************
+ * This software can be used under the GPL license *
+ * agreements as stated in LICENSE.txt file *
+ * which is part of the distribution. *
+ ************************************************************/
+
+#include "elderdabc/Factory.h"
+
+#include "dabc/Url.h"
+#include "dabc/Port.h"
+#include "dabc/Manager.h"
+
+#include "elderdabc/RunModule.h"
+
+dabc::FactoryPlugin elderdabcfactory(new elderdabc::Factory("elder"));
+
+dabc::Module* elderdabc::Factory::CreateModule(const std::string &classname, const std::string &modulename, dabc::Command cmd)
+{
+ if (classname == "elderdabc::RunModule")
+ return new elderdabc::RunModule(modulename, cmd);
+
+
+
+ return dabc::Factory::CreateModule(classname, modulename, cmd);
+}
+
+
+
diff --git a/plugins/elder/src/RunModule.cxx b/plugins/elder/src/RunModule.cxx
new file mode 100644
index 00000000..58146db9
--- /dev/null
+++ b/plugins/elder/src/RunModule.cxx
@@ -0,0 +1,373 @@
+// $Id$
+
+/************************************************************
+ * The Data Acquisition Backbone Core (DABC) *
+ ************************************************************
+ * Copyright (C) 2009 - *
+ * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
+ * Planckstr. 1, 64291 Darmstadt, Germany *
+ * Contact: http://dabc.gsi.de *
+ ************************************************************
+ * This software can be used under the GPL license *
+ * agreements as stated in LICENSE.txt file *
+ * which is part of the distribution. *
+ ************************************************************/
+
+#include "elderdabc/RunModule.h"
+#include "elderdabc/VisConDabc.h"
+
+#include "dabc/Manager.h"
+#include "dabc/Factory.h"
+#include "dabc/Iterator.h"
+#include "dabc/Buffer.h"
+#include "dabc/Publisher.h"
+#include "dabc/Url.h"
+#include "dabc/BinaryFile.h"
+
+#include "mbs/Iterator.h"
+
+#include
+#include
+
+
+
+#include
+
+
+// ==================================================================================
+
+elderdabc::RunModule::RunModule(const std::string &name, dabc::Command cmd) :
+ dabc::ModuleAsync(name, cmd),
+ fViscon(nullptr),
+ fAnalysis(nullptr),
+ fElderConfigFile(),
+ fAsf(),
+ fTotalSize(0),
+ fTotalEvnts(0),
+ fTotalOutEvnts(0)// ,
+ //fDefaultFill(5)
+{
+ EnsurePorts(1, 0);
+ // we need one input and no outputs
+
+ //fDefaultFill = Cfg("FillColor", cmd).AsInt(3);
+
+ fElderConfigFile = Cfg("ElderConfig", cmd).AsStr("./analysis");
+
+
+ fWorkerHierarchy.Create("Worker");
+
+ CreateTimer("Update", 1.);
+
+ //fWorkerHierarchy.CreateHChild("Status").SetField("_hidden", "true");
+ //fWorkerHierarchy.SetField("_player", "DABC.ElderControl");
+
+
+ fAsf = Cfg("AutosaveFile",cmd).AsStr();
+ // do not autosave is specified, module will not stop when data source disappears
+ if (fAsf.empty())SetAutoStop(false);
+
+
+
+
+
+ // JAM24: keep these commands for future usage?
+ dabc::CommandDefinition cmddef = fWorkerHierarchy.CreateHChild("Control/StartRootFile");
+ cmddef.SetField(dabc::prop_kind, "DABC.Command");
+ // cmddef.SetField(dabc::prop_auth, true); // require authentication
+ cmddef.AddArg("fname", "string", true, "file.root");
+ cmddef.AddArg("kind", "int", false, "2");
+ cmddef.AddArg("maxsize", "int", false, "1900");
+
+ cmddef = fWorkerHierarchy.CreateHChild("Control/StopRootFile");
+ cmddef.SetField(dabc::prop_kind, "DABC.Command");
+ // cmddef.SetField(dabc::prop_auth, true); // require authentication
+
+ fViscon = new VisConDabc();
+ fViscon->SetTop(fWorkerHierarchy, true);
+ fAnalysis = new ::elderpt::control::Controller(fElderConfigFile, fViscon);
+
+
+ if (fAnalysis->errors() == 0)
+ {
+ fAnalysis->create_histograms(*fViscon);
+ }
+ else
+ {
+ EOUT("There were %d errors while parsing file %s ! \n", fAnalysis->errors(),fElderConfigFile.c_str());
+ //exit(); TODO proper error handling in dabc
+ }
+
+ fEvent=new ::elderpt::control::Event();
+
+ //Publish(fWorkerHierarchy, dabc::format("$CONTEXT$/%s", GetName()));
+
+ //fWorkerHierarchy.CreateHChild("Status").SetField("_hidden", "true");
+ CreatePar("Events").SetRatemeter(false, 3.).SetUnits("Ev");
+ CreatePar("DataRate").SetRatemeter(false, 3.).SetUnits("MB");
+
+ PublishPars(dabc::format("$CONTEXT$/%s", GetName())); // will also publish rest of hierarchy...
+ //Publish(fWorkerHierarchy, dabc::format("$CONTEXT$/%s", GetName()));
+
+ double interval = Cfg("AutosaveInterval", cmd).AsDouble(0);
+ if (interval > 1) CreateTimer("AutoSave", interval);
+}
+
+elderdabc::RunModule::~RunModule()
+{
+ if(fEvent) delete fEvent;
+ if (fAnalysis) {
+ delete fAnalysis;
+ fAnalysis = nullptr;
+ }
+ if (fViscon) {
+ delete fViscon;
+ fViscon = nullptr;
+ }
+// printf("elderdabc::RunModule dtor ended \n");
+}
+
+
+
+void elderdabc::RunModule::OnThreadAssigned()
+{
+ dabc::ModuleAsync::OnThreadAssigned();
+
+ // JAM24: optionally do something for the parallel setup here, like in stream...
+
+ DOUT0("!!!! Assigned to thread %s !!!!!", thread().GetName());
+}
+
+
+
+int elderdabc::RunModule::ExecuteCommand(dabc::Command cmd)
+{
+ if (fViscon && fViscon->ExecuteHCommand(cmd)) {
+ //if (fProcMgr->IsWorking()) ActivateInput(); // when working set, just ensure that module reads input
+ return dabc::cmd_true;
+ }
+
+ if (cmd.IsName(dabc::CmdHierarchyExec::CmdName())) {
+ std::string cmdpath = cmd.GetStr("Item");
+ DOUT0("Execute command %s", cmdpath.c_str());
+
+ if (cmdpath == "Control/StartRootFile") {
+
+// std::string fname = cmd.GetStr("fname","file.root");
+// int kind = cmd.GetInt("kind", 2);
+// int maxsize = cmd.GetInt("maxsize", 1900);
+// fname += dabc::format("?maxsize=%d", maxsize);
+// if (fViscon)
+// if (fViscon->CreateStore(fname.c_str())) {
+// // only in triggered mode storing is allowed
+// fViscon->SetStoreKind(kind);
+// fViscon->UserPreLoop(nullptr, true);
+//
+// }
+ DOUT0("Command StartRootFile is not yet implemented.");
+ return dabc::cmd_true;
+
+ } else
+ if (cmdpath == "Control/StopRootFile") {
+ //if (fViscon) fViscon->CloseStore();
+ DOUT0("Command StopRootFile is not yet implemented.");
+
+
+ return dabc::cmd_true;
+
+ } else
+ if (cmdpath == "Control/Start") {
+ DOUT0("Command Control/Start");
+ fViscon->AddRunLog("Executing Application Start command...");
+ return dabc::ModuleAsync::ExecuteCommand(dabc::Command("DoStart")); //dabc::Application::stcmdDoStart()
+ //return dabc::cmd_true;
+ } else
+ if (cmdpath == "Control/Stop") {
+ DOUT0("Command Control/Stop");
+ fViscon->AddRunLog("Executing Application Stop command...");
+ return dabc::ModuleAsync::ExecuteCommand(dabc::Command("DoStop")); //dabc::Application::stcmdDoStop()
+ // return dabc::cmd_true;
+
+
+ } else
+ return dabc::cmd_false;
+ }
+
+
+ if (cmd.IsName("GetHierarchy")) {
+ cmd.SetRef("hierarchy", fWorkerHierarchy);
+ return dabc::cmd_true;
+ }
+
+ return dabc::ModuleAsync::ExecuteCommand(cmd);
+}
+
+void elderdabc::RunModule::BeforeModuleStart()
+{
+ DOUT0("START ELDER MODULE %s inp %s", GetName(), DBOOL(IsInputConnected(0)));
+
+ //if (fProcMgr) fProcMgr->UserPreLoop();
+}
+
+void elderdabc::RunModule::SaveHierarchy(dabc::Buffer buf)
+{
+ if (buf.GetTotalSize() == 0) return;
+
+ DOUT0("store hierarchy size %d in temporary h.bin file", buf.GetTotalSize());
+ {
+ dabc::BinaryFile f;
+ std::system("rm -f h.bin");
+ if (f.OpenWriting("h.bin")) {
+ if (f.WriteBufHeader(buf.GetTotalSize(), buf.GetTypeId()))
+ for (unsigned n=0;nUserPostLoop();
+
+ // DOUT0("!!!! thread on start %s !!!!!", thread().GetName());
+
+ DOUT0("STOP ELDER MODULE %s data %lu evnts %lu outevents %lu %s", GetName(), fTotalSize, fTotalEvnts, fTotalOutEvnts, (fTotalEvnts == fTotalOutEvnts ? "ok" : "MISSMATCH"));
+
+ if (fAsf.length() > 0) {
+ SaveHierarchy(fWorkerHierarchy.SaveToBuffer());
+ }
+ DestroyPar("Events");
+}
+
+bool elderdabc::RunModule::ProcessNextEvent(mbs::ReadIterator& iter)
+{
+ if (!fAnalysis)
+ return false;
+ DOUT5("elderdabc::RunModule::ProcessNextEvent() for event %lu", fTotalEvnts);
+ fTotalEvnts++;
+ Par("Events").SetValue(1);
+// first get event header
+ struct timeval tv;
+ gettimeofday(&tv,0);
+ static uint64_t first_timestamp_ = tv.tv_sec*1000 + tv.tv_usec/1000;
+ uint64_t now = (tv.tv_sec*1000 + tv.tv_usec/1000);
+ uint64_t timestamp = now-first_timestamp_;
+
+ int time = timestamp/1000;
+ int msec = timestamp%1000;
+ // TODO: access to mbs buffer header time?
+
+ mbs::EventHeader* head=iter.evnt();
+
+ // convert the MBS event structure into a elder Event class
+// elderpt::control::Event event(head->EventNumber(),
+// head->Type(),
+// head->TriggerNumber(),
+// time,
+// msec,
+// timestamp);
+ fEvent->clear();
+ fEvent->set_number(head->EventNumber());
+ fEvent->set_type(head->Type());
+ fEvent->set_trigger(head->TriggerNumber());
+ fEvent->set_time(time);
+ fEvent->set_msec(msec);
+ fEvent->set_timestamp(timestamp);
+
+ while (iter.NextSubEvent())
+ {
+ // scan subevent here
+ // loop over subevents and convert them into Elder-PT format
+ mbs::SubeventHeader* subhead = iter.subevnt();
+ fEvent->push_back(::elderpt::control::Subevent(subhead->ProcId(),
+ subhead->Type(),
+ subhead->SubType(),
+ subhead->Control(),
+ subhead->Subcrate(),
+ iter.rawdatasize()/sizeof(uint32_t), //subevt->GetIntLen(),
+ reinterpret_cast(iter.rawdata())
+ ));
+ }
+
+ fAnalysis->unpack(*fViscon , *fEvent);
+ fAnalysis->process(*fViscon);
+
+ return true;
+}
+
+
+bool elderdabc::RunModule::ProcessNextBuffer()
+{
+
+ //printf("elderdabc::RunModule enters ProcessNextBuffer... fAnalysis=0x%x\n",fAnalysis);
+ if (!fAnalysis) return false;
+ dabc::Buffer buf = Recv();
+ //printf("elderdabc::RunModule::ProcessNextBuffer after rcv =0x%x\n",fAnalysis);
+ Par("DataRate").SetValue(buf.GetTotalSize()/1024./1024.);
+ fTotalSize += buf.GetTotalSize();
+ DOUT5("elderdabc::RunModule::ProcessNextBuffer() has total size %lu", fTotalSize);
+
+ if (buf.GetTypeId() == mbs::mbt_MbsEvents) {
+ DOUT5("elderdabc::RunModule::RunModule::ProcessNextBuffer() sees MBS type id %d", buf.GetTypeId());
+ mbs::ReadIterator iter(buf);
+ while (iter.NextEvent()) {
+ ProcessNextEvent(iter);
+ }
+ }
+ else if(buf.GetTypeId() == dabc::mbt_EOF) {
+ DOUT0("elderdabc::RunModule::RunModule::ProcessNextBuffer() sees end of all files.");
+ //Stop();
+ return false;
+ }
+ else {
+ EOUT("elderdabc::RunModule::ProcessNextBuffer() sees OTHER type id %d", buf.GetTypeId());
+ return false;
+ }
+
+ return true;
+}
+
+
+
+bool elderdabc::RunModule::ProcessRecv(unsigned)
+{
+ DOUT5("elderdabc::RunModule::ProcessRecv() entering...");
+ return ProcessNextBuffer();
+}
+
+void elderdabc::RunModule::ProcessTimerEvent(unsigned timer)
+{
+ if (TimerName(timer) == "AutoSave") {
+ if (fAsf.length() > 0) {
+ // overwrite single autosave file
+ SaveHierarchy(fWorkerHierarchy.SaveToBuffer());
+ }
+ else
+ {
+ // dump histograms into file with timestamp
+ if (fViscon) fViscon->SaveAllHistograms();
+ }
+ return;
+ }
+
+
+
+ // rest is for update timer JAM
+// dabc::Hierarchy folder = fWorkerHierarchy.FindChild("Status");
+// folder.SetField("EventsRate", Par("Events").GetField("value").AsDouble());
+// folder.SetField("EventsCount", (int64_t) fTotalEvnts);
+ //folder.SetField("StoreInfo", fProcMgr->GetStoreInfo());
+
+}
+
diff --git a/plugins/elder/src/VisConDabc.cxx b/plugins/elder/src/VisConDabc.cxx
new file mode 100644
index 00000000..75d3ff1d
--- /dev/null
+++ b/plugins/elder/src/VisConDabc.cxx
@@ -0,0 +1,843 @@
+// $Id$
+
+/************************************************************
+ * The Data Acquisition Backbone Core (DABC) *
+ ************************************************************
+ * Copyright (C) 2009 - *
+ * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
+ * Planckstr. 1, 64291 Darmstadt, Germany *
+ * Contact: http://dabc.gsi.de *
+ ************************************************************
+ * This software can be used under the GPL license *
+ * agreements as stated in LICENSE.txt file *
+ * which is part of the distribution. *
+ ************************************************************/
+
+#include "elderdabc/VisConDabc.h"
+
+#include "dabc/Buffer.h"
+#include "dabc/Iterator.h"
+#include "dabc/Factory.h"
+#include "dabc/Manager.h"
+#include "dabc/BinaryFile.h"
+#include "dabc/timing.h"
+
+#include
+#include
+
+elderdabc::VisConDabc::VisConDabc() :
+ elderpt::viscon::Interface(),
+ fTop(),
+ //fWorkingFlag(true),
+ fStore(),
+ fStoreInfo("no store created"),
+ fSortOrder(true),
+ fDefaultFill(3)
+{
+ fvHistograms1d.clear();
+ fvHistograms2d.clear();
+
+}
+
+
+elderdabc::VisConDabc::~VisConDabc()
+{
+}
+
+void elderdabc::VisConDabc::SetTop(dabc::Hierarchy& top, bool withcmds)
+{
+ fTop = top;
+ //fTop=top.CreateHChild("Viscon");later
+
+ if (!withcmds) return;
+
+ dabc::Hierarchy h = fTop.CreateHChild("Control/Clear");
+ h.SetField("_kind","Command");
+ h.SetField("_title", "Clear all histograms in the server");
+ h.SetField("_icon", "dabcsys/plugins/elder/icons/clear.png");
+ h.SetField("_fastcmd", "true");
+ h.SetField("_numargs", "0");
+
+ h = fTop.CreateHChild("Control/Save");
+ h.SetField("_kind","Command");
+ h.SetField("_title", "Save all histograms in the dabc.root file");
+ h.SetField("_icon", "dabcsys/plugins/elder/icons/save.png");
+ h.SetField("_fastcmd", "true");
+ h.SetField("_numargs", "0");
+
+ h = fTop.CreateHChild("Control/Start");
+ h.SetField("_kind","Command");
+ h.SetField("_title", "Start processing of data");
+ h.SetField("_icon", "dabcsys/plugins/elder/icons/start.png");
+ h.SetField("_fastcmd", "true");
+ h.SetField("_numargs", "0");
+
+ h = fTop.CreateHChild("Control/Stop");
+ h.SetField("_kind","Command");
+ h.SetField("_title", "Stop processing of data");
+ h.SetField("_icon", "dabcsys/plugins/elder/icons/stop.png");
+ h.SetField("_fastcmd", "true");
+ h.SetField("_numargs", "0");
+
+
+ h = fTop.CreateHChild("Control/RunLog");
+ h.SetField(dabc::prop_kind, "log");
+ h.EnableHistory(1000);
+
+ h = fTop.CreateHChild("Control/ErrLog");
+ h.SetField(dabc::prop_kind, "log");
+ h.EnableHistory(1000);
+}
+
+
+void elderdabc::VisConDabc::AddRunLog(const char *msg)
+{
+ dabc::Hierarchy h = fTop.GetHChild("Control/RunLog");
+ h.SetField("value", msg);
+ h.MarkChangedItems();
+ DOUT1("AddRunLog: %s",msg);
+}
+
+void elderdabc::VisConDabc::AddErrLog(const char *msg)
+{
+ dabc::Hierarchy h = fTop.GetHChild("Control/ErrLog");
+ h.SetField("value", msg);
+ h.MarkChangedItems();
+ DOUT1("AddErrLog: %s",msg);
+}
+
+//void elderdabc::VisConDabc::PrintLog(const char *msg)
+//{
+// //if (fDebug >= 0)
+// DOUT0(msg);
+//}
+
+////////////// TODO: implement elder viscon methods below
+
+
+::elderpt::viscon::Interface::Histogram1DHandle elderdabc::VisConDabc::hist1d_create(const char *name,
+ const char *title,
+ const char *, //axis,
+ int n_bins,
+ double left,
+ double right)
+{
+ double* hist= MakeH1(name, title, n_bins, left, right);
+ fvHistograms1d.push_back(hist);
+ return fvHistograms1d.size()-1;
+
+return 0;
+}
+
+void elderdabc::VisConDabc::hist1d_fill(
+ ::elderpt::viscon::Interface::Histogram1DHandle h, double value)
+{
+ if (h < 0 || (size_t) h > fvHistograms1d.size()) return; // error handling required when handle out of bounds?
+ elderdabc::H1handle hist = fvHistograms1d[h];
+ FillH1(hist, value, 1);
+}
+
+void elderdabc::VisConDabc::hist1d_set_bin(
+ ::elderpt::viscon::Interface::Histogram1DHandle h, int bin, double value)
+{
+
+ if (h < 0 || (size_t) h > fvHistograms1d.size()) return; // error handling required when handle out of bounds?
+ elderdabc::H1handle hist = fvHistograms1d[h]; // TODO: error handling when out of bounds?
+ SetH1Content(hist, bin, value);
+}
+
+::elderpt::viscon::Interface::Histogram2DHandle elderdabc::VisConDabc::hist2d_create(const char *name,
+ const char *title,
+ const char *, //axis1,
+ int n_bins1,
+ double left1,
+ double right1,
+ const char *, //axis2,
+ int n_bins2,
+ double left2,
+ double right2)
+{
+ double* hist= MakeH2(name, title, n_bins1, left1, right1, n_bins2, left2, right2);
+ fvHistograms2d.push_back(hist);
+ return fvHistograms2d.size()-1;
+}
+
+void elderdabc::VisConDabc::hist2d_fill(::elderpt::viscon::Interface::Histogram2DHandle h, double value1, double value2)
+{
+ if (h < 0 || (size_t) h > fvHistograms2d.size()) return; // error handling required when handle out of bounds?
+ elderdabc::H2handle hist = fvHistograms2d[h];
+ FillH2(hist, value1, value2, 1);
+}
+
+void elderdabc::VisConDabc::hist2d_set_bin(::elderpt::viscon::Interface::Histogram2DHandle h, int xbin, int ybin, double value)
+{
+ if (h < 0 || (size_t) h > fvHistograms2d.size()) return; // error handling required when handle out of bounds?
+ elderdabc::H2handle hist = fvHistograms2d[h];
+ SetH2Content(hist, xbin, ybin, value);
+}
+
+ //! @brief Implements the Go4-way of creating a 1d window condition
+ //! @param name the name of the condition
+ //! @param left left limit of the window
+ //! @param right right limit of the window
+ //! @param h a handle to a histogram that should be linked to that condition
+::elderpt::viscon::Interface::Condition1DHandle elderdabc::VisConDabc::cond1d_create(
+ const char* ,//name,
+ double, // left,
+ double, // right,
+ int //h
+ )
+{
+ // TODO
+ return ::elderpt::viscon::Interface::INVALID_HANDLE;
+//
+ //const char *histogram_name = "";
+// if (h >= 0)
+// {
+// histogram_name = histograms1d_[h]->GetName();
+// }
+// TGo4WinCond* condition = creator_.MakeWinCond(name, left, right, histogram_name);
+// conditions1d_.push_back(condition);
+// return conditions1d_.size()-1;
+ }
+//! @brief Implements the Go4-way of creating a 1d window condition
+ //! @param h ???
+ //! @param left left limit of the window
+ //! @param right right limit of the window
+ //! @warning Documented by Pico, h needs documentation
+void elderdabc::VisConDabc::cond1d_get(::elderpt::viscon::Interface::Condition1DHandle h, double &left, double &right)
+ {
+ if (h == ::elderpt::viscon::Interface::INVALID_HANDLE)
+ return;
+
+// int dim;
+// //PK double x1,y1,x2,y2; //x1 and y1 are not used anywhere
+// double x2,y2;
+// conditions1d_[h]->GetValues(dim,left,right,x2,y2);
+ }
+ //! @brief Implements the Go4-way of creating a 1d window condition
+ //! @param name the name of the condition
+ //! @param points ???
+ //! @param h a handle to a histogram that should be linked to that condition
+ //! @warning Documented by Pico, points needs documentation
+::elderpt::viscon::Interface::Condition2DHandle elderdabc::VisConDabc::cond2d_create(const char *name,
+ const std::vector &points,
+ int h)
+ {
+
+
+ int size = points.size();
+ if (size < 4)
+ return ::elderpt::viscon::Interface::INVALID_HANDLE;
+ if (size%2 != 0)
+ return ::elderpt::viscon::Interface::INVALID_HANDLE;
+
+ // TODO:::
+
+
+// const char *histogram_name = "";
+// if (h >= 0)
+// {
+// histogram_name = histograms2d_[h]->GetName();
+// }
+//
+// if (size == 4) // create 2d window condition
+// {
+// TGo4WinCond* condition = creator_.MakeWinCond(name, points[0],points[1], points[2],points[3], histogram_name);
+// conditions2d_.push_back(condition);
+// return conditions2d_.size()-1;
+// }
+// else // create 2d polygon condition
+// {
+// static double points_array[100][2] = {{0,},};
+// for (int i = 0; i < size/2; ++i)
+// {
+// points_array[i][0] = points[2*i];
+// points_array[i][1] = points[2*i+1];
+// }
+// TGo4PolyCond * condition = creator_.MakePolyCond(name, size/2, points_array, histogram_name);
+// condition->GetCut(false)->SetMarkerStyle(kCircle);
+// conditions2d_poly_.push_back(condition);
+// return conditions2d_poly_.size()-1;
+// }
+ return ::elderpt::viscon::Interface::INVALID_HANDLE;
+ }
+
+ void elderdabc::VisConDabc::cond2d_get(::elderpt::viscon::Interface::Condition2DHandle h, std::vector &points)
+ {
+ if (h == ::elderpt::viscon::Interface::INVALID_HANDLE)
+ return;
+
+ if (points.size() < 4)
+ return;
+
+ if (points.size() == 4)
+ {
+ int dim;
+ //conditions2d_[h]->GetValues(dim,points[0],points[1],points[2],points[3]);
+ }
+ else
+ {
+// TCutG *cut = conditions2d_poly_[h]->GetCut(0);
+// uint n_points = cut->GetN();
+// double *x_coords = cut->GetX();
+// double *y_coords = cut->GetY();
+//
+// if (points.size() < 2*n_points-2)
+// points.resize(2*n_points-2);
+//
+// for (uint i = 0; i < points.size()/2; ++i)
+// {
+// points[2*i ] = x_coords[i];
+// points[2*i+1] = y_coords[i];
+ }
+ }
+
+
+
+
+
+
+
+//////////////////////////////////////////// JAM below old from stream interface
+elderdabc::H1handle elderdabc::VisConDabc::MakeH1(const char* name, const char* title, int nbins, double left, double right, const char* options)
+{
+// if (IsBlockHistCreation()) {
+// DOUT0("Block H1 creation %s due to multithreading", name);
+// return nullptr;
+// }
+
+ std::string xtitle, ytitle, xlbls, fillcolor, drawopt, hmin, hmax;
+ bool reuse = false, clear_protect = false;
+
+ while (options) {
+ const char* separ = strchr(options,';');
+ std::string part = options;
+ if (separ) {
+ part.resize(separ-options);
+ options = separ+1;
+ } else {
+ options = nullptr;
+ }
+
+ if (part.find("xbin:") == 0) { xlbls = part; xlbls.erase(0, 5); } else
+ if (part.find("fill:") == 0) { fillcolor = part; fillcolor.erase(0,5); } else
+ if (part.find("opt:") == 0) { drawopt = part; drawopt.erase(0,4); } else
+ if (part.find("hmin:") == 0) { hmin = part; hmin.erase(0,5); } else
+ if (part.find("hmax:") == 0) { hmax = part; hmax.erase(0,5); } else
+ if (part.find("kind:") == 0) { } else
+ if (part.find("reuse") == 0) { reuse = true; } else
+ if (part.find("clear_protect") == 0) { clear_protect = true; } else
+ if (xtitle.empty()) xtitle = part; else ytitle = part;
+ }
+
+ dabc::LockGuard lock(fTop.GetHMutex());
+
+ dabc::Hierarchy h = fTop.GetHChild(name);
+ if (!h.null() && reuse && h.GetFieldPtr("bins"))
+ return (elderdabc::H1handle) h.GetFieldPtr("bins")->GetDoubleArr();
+
+ if (!h) {
+ std::string sname = name;
+ auto pos = sname.find_last_of("/");
+ if ((pos != std::string::npos) && fSortOrder)
+ h = fTop.CreateHChild(sname.substr(0,pos).c_str(), false, true).CreateHChild(sname.substr(pos+1).c_str());
+ else
+ h = fTop.CreateHChild(name);
+ }
+ if (!h) return nullptr;
+
+ h.SetField("_kind","ROOT.TH1D");
+ h.SetField("_title", title);
+ h.SetField("_dabc_hist", true); // indicate for browser that it is DABC histogram
+ h.SetField("_make_request", "DABC.ReqH"); // provide proper request
+ h.SetField("_after_request", "DABC.ConvertH"); // convert object into ROOT histogram
+ h.SetField("nbins", nbins);
+ h.SetField("left", left);
+ h.SetField("right", right);
+ if (!xtitle.empty()) h.SetField("xtitle", xtitle);
+ if (!ytitle.empty()) h.SetField("ytitle", ytitle);
+ if (xlbls.length()>0) h.SetField("xlabels", xlbls);
+ h.SetField("fillcolor", fillcolor.empty() ? fDefaultFill : std::stoi(fillcolor));
+ if (drawopt.length() > 0) h.SetField("drawopt", drawopt);
+ if (!hmin.empty()) h.SetField("hmin", std::stof(hmin));
+ if (!hmax.empty()) h.SetField("hmax", std::stof(hmax));
+ if (clear_protect) h.SetField("_no_reset", "true");
+
+ std::vector bins;
+ bins.resize(nbins+5, 0.);
+ bins[0] = nbins;
+ bins[1] = left;
+ bins[2] = right;
+ h.SetField("bins", bins);
+
+ fTop.MarkChangedItems();
+
+ return (elderdabc::H1handle) h.GetFieldPtr("bins")->GetDoubleArr();
+}
+
+elderdabc::H2handle elderdabc::VisConDabc::MakeH2(const char* name, const char* title, int nbins1, double left1, double right1, int nbins2, double left2, double right2, const char* options)
+{
+// if (IsBlockHistCreation()) {
+// DOUT0("Block H2 creation %s due to multithreading", name);
+// return nullptr;
+// }
+
+ std::string xtitle, ytitle, xlbls, ylbls, fillcolor, drawopt, hmin, hmax, h2poly;
+ bool reuse = false, clear_protect = false;
+
+ while (options != nullptr) {
+ const char* separ = strchr(options,';');
+ std::string part = options;
+ if (separ) {
+ part.resize(separ-options);
+ options = separ+1;
+ } else {
+ options = nullptr;
+ }
+
+ if (part.find("xbin:") == 0) { xlbls = part; xlbls.erase(0, 5); } else
+ if (part.find("ybin:") == 0) { ylbls = part; ylbls.erase(0, 5); } else
+ if (part.find("fill:") == 0) { fillcolor = part; fillcolor.erase(0,5); } else
+ if (part.find("opt:") == 0) { drawopt = part; drawopt.erase(0,4); } else
+ if (part.find("hmin:") == 0) { hmin = part; hmin.erase(0,5); } else
+ if (part.find("hmax:") == 0) { hmax = part; hmax.erase(0,5); } else
+ if (part.find("kind:") == 0) { } else
+ if (part.find("h2poly:") == 0) { h2poly = part; h2poly.erase(0,7); } else
+ if (part.find("reuse") == 0) { reuse = true; } else
+ if (part.find("clear_protect") == 0) { clear_protect = true; } else
+ if (xtitle.empty()) xtitle = part; else ytitle = part;
+ }
+
+ dabc::LockGuard lock(fTop.GetHMutex());
+
+ dabc::Hierarchy h = fTop.GetHChild(name);
+ if (!h.null() && reuse && h.GetFieldPtr("bins"))
+ return (elderdabc::H2handle) h.GetFieldPtr("bins")->GetDoubleArr();
+
+ if (!h) {
+ std::string sname = name;
+ auto pos = sname.find_last_of("/");
+ if ((pos != std::string::npos) && fSortOrder)
+ h = fTop.CreateHChild(sname.substr(0,pos).c_str(), false, true).CreateHChild(sname.substr(pos+1).c_str());
+ else
+ h = fTop.CreateHChild(name);
+ }
+ if (!h) return nullptr;
+
+ h.SetField("_kind", h2poly.empty() ? "ROOT.TH2D" : "ROOT.TH2Poly");
+ h.SetField("_title", title);
+ h.SetField("_dabc_hist", true); // indicate for browser that it is DABC histogram
+ h.SetField("_make_request", "DABC.ReqH"); // provide proper request
+ h.SetField("_after_request", "DABC.ConvertH"); // convert object into ROOT histogram
+ h.SetField("nbins1", nbins1);
+ h.SetField("left1", left1);
+ h.SetField("right1", right1);
+ h.SetField("nbins2", nbins2);
+ h.SetField("left2", left2);
+ h.SetField("right2", right2);
+ if (!xtitle.empty()) h.SetField("xtitle", xtitle);
+ if (!ytitle.empty()) h.SetField("ytitle", ytitle);
+ if (xlbls.length() > 0) h.SetField("xlabels", xlbls);
+ if (ylbls.length() > 0) h.SetField("ylabels", ylbls);
+ if (!fillcolor.empty()) h.SetField("fillcolor", std::stoi(fillcolor));
+ h.SetField("drawopt", drawopt.empty() ? std::string("colz") : drawopt);
+ if (!hmin.empty()) h.SetField("hmin", std::stof(hmin));
+ if (!hmax.empty()) h.SetField("hmax", std::stof(hmax));
+ if (!h2poly.empty()) h.SetField("h2poly", h2poly);
+ if (clear_protect) h.SetField("_no_reset", "true");
+
+ std::vector bins;
+ bins.resize(6+(nbins1+2)*(nbins2+2), 0.);
+ bins[0] = nbins1;
+ bins[1] = left1;
+ bins[2] = right1;
+ bins[3] = nbins2;
+ bins[4] = left2;
+ bins[5] = right2;
+ h.SetField("bins", bins);
+
+ fTop.MarkChangedItems();
+
+ return (elderdabc::H2handle) h.GetFieldPtr("bins")->GetDoubleArr();
+}
+
+////////// from stream ProcMgr/Processor code
+
+void elderdabc::VisConDabc::FillH1(elderdabc::H1handle h1, double x, double weight)
+{
+ // taken from stream framework, double array is treated like in ROOT histograms (overflow, underflow bins etc.)
+ double* arr = (double*) h1;
+ int nbin = (int) arr[0];
+ int bin = (int) (nbin * (x - arr[1]) / (arr[2] - arr[1]));
+ if (bin<0) arr[3]+=weight; else
+ if (bin>=nbin) arr[4+nbin]+=weight; else arr[4+bin]+=weight;
+}
+
+
+
+double elderdabc::VisConDabc::GetH1Content(elderdabc::H1handle h1, int bin)
+{
+ // taken from stream framework, double array is treated like in ROOT histograms (overflow, underflow bins etc.)
+ double* arr = (double*) h1;
+ int nbin = (int) arr[0];
+ if (bin<0) return arr[3];
+ if (bin>=nbin) return arr[4+nbin];
+ return arr[4+bin];
+}
+
+
+void elderdabc::VisConDabc::SetH1Content(elderdabc::H1handle h1, int bin, double v)
+{
+ // taken from stream framework, double array is treated like in ROOT histograms (overflow, underflow bins etc.)
+ double* arr = (double*) h1;
+ int nbin = (int) arr[0];
+ if (bin<0) arr[3] = v;
+ else if (bin>=nbin) arr[4+nbin] = v;
+ else arr[4+bin] = v;
+}
+
+
+
+
+void elderdabc::VisConDabc::FillH2(elderdabc::H2handle h2, double x, double y, double weight)
+{
+ // taken from stream framework, double array is treated like in ROOT histograms (overflow, underflow bins etc.)
+ double* arr = (double*) h2;
+
+ int nbin1 = (int) arr[0];
+ int nbin2 = (int) arr[3];
+
+ int bin1 = (int) (nbin1 * (x - arr[1]) / (arr[2] - arr[1]));
+ int bin2 = (int) (nbin2 * (y - arr[4]) / (arr[5] - arr[4]));
+
+ if (bin1<0) bin1 = -1; else if (bin1>nbin1) bin1 = nbin1;
+ if (bin2<0) bin2 = -1; else if (bin2>nbin2) bin2 = nbin2;
+
+ arr[6 + (bin1+1) + (bin2+1)*(nbin1+2)] += weight;
+}
+
+double elderdabc::VisConDabc::GetH2Content(H2handle h2, int bin1, int bin2)
+{
+ // taken from stream framework, double array is treated like in ROOT histograms (overflow, underflow bins etc.)
+ double* arr = (double*) h2;
+
+ int nbin1 = (int) arr[0];
+ int nbin2 = (int) arr[3];
+
+ if (bin1<0) bin1 = -1; else if (bin1>nbin1) bin1 = nbin1;
+ if (bin2<0) bin2 = -1; else if (bin2>nbin2) bin2 = nbin2;
+
+ return arr[6 + (bin1+1) + (bin2+1)*(nbin1+2)];
+}
+
+
+void elderdabc::VisConDabc::SetH2Content(H2handle h2, int bin1, int bin2, double v)
+{
+ // taken from stream framework, double array is treated like in ROOT histograms (overflow, underflow bins etc.)
+ double* arr = (double*) h2;
+
+ int nbin1 = (int) arr[0];
+ int nbin2 = (int) arr[3];
+
+ if (bin1<0) bin1 = -1; else if (bin1>nbin1) bin1 = nbin1;
+ if (bin2<0) bin2 = -1; else if (bin2>nbin2) bin2 = nbin2;
+
+ arr[6 + (bin1+1) + (bin2+1)*(nbin1+2)] = v;
+}
+
+
+
+dabc::Hierarchy elderdabc::VisConDabc::FindHistogram(double *handle)
+{
+// if (IsBlockHistCreation()) {
+// DOUT0("FindHistogram when blocked due to threaing?\n");
+// }
+
+ if (!handle) return nullptr;
+
+ dabc::Iterator iter(fTop);
+ while (iter.next()) {
+ dabc::Hierarchy item = iter.ref();
+ if (item.HasField("_dabc_hist"))
+ if (item.GetFieldPtr("bins")->GetDoubleArr() == handle)
+ return item;
+ }
+ return nullptr;
+}
+
+
+void elderdabc::VisConDabc::SetH1Title(elderdabc::H1handle h1, const char *title)
+{
+ auto item = FindHistogram(h1);
+ if (!item.null())
+ item.SetField("_title", title);
+}
+
+void elderdabc::VisConDabc::TagH1Time(elderdabc::H1handle h1)
+{
+ auto item = FindHistogram(h1);
+ if (!item.null()) {
+ auto now = dabc::DateTime().GetNow();
+ item.SetField("_humantime", now.AsString(3, true));
+ item.SetField("_time", now.AsUTCSeconds());
+ }
+}
+
+void elderdabc::VisConDabc::SetH2Title(elderdabc::H2handle h2, const char *title)
+{
+ auto item = FindHistogram(h2);
+ if (!item.null())
+ item.SetField("_title", title);
+}
+
+void elderdabc::VisConDabc::TagH2Time(elderdabc::H2handle h2)
+{
+ auto item = FindHistogram(h2);
+ if (!item.null()) {
+ auto now = dabc::DateTime().GetNow();
+ item.SetField("_humantime", now.AsString(3, true));
+ item.SetField("_time", now.AsUTCSeconds());
+ }
+}
+
+
+bool elderdabc::VisConDabc::ClearHistogram(dabc::Hierarchy &item)
+{
+ if (!item.HasField("_dabc_hist") || (item.GetFieldPtr("bins") == nullptr)) return false;
+
+ if (item.HasField("_no_reset")) return true;
+
+ int indx = item.GetField("_kind").AsStr()=="ROOT.TH1D" ? 3 : 6;
+
+ double* arr = item.GetFieldPtr("bins")->GetDoubleArr();
+ int len = item.GetFieldPtr("bins")->GetArraySize();
+ while (indxGetDoubleArr();
+ if (!bins) return false;
+
+ name.erase(0,5); // remove HCMD_ prefix
+
+ if ((name == "GetMean") || (name=="GetRMS") || (name=="GetEntries")) {
+ if (kind != "ROOT.TH1D") return false;
+ int nbins = item.GetField("nbins").AsInt();
+ double left = item.GetField("left").AsDouble();
+ double right = item.GetField("right").AsDouble();
+
+ double sum0 = 0, sum1 = 0, sum2 = 0;
+
+ for (int n=0;n0) {
+ mean = sum1/sum0;
+ rms = sqrt(sum2/sum0 - mean*mean);
+ }
+ if (name == "GetEntries") res = dabc::format("%14.7g",sum0);
+ else if (name == "GetMean") res = dabc::format("%8.6g",mean);
+ else res = dabc::format("%8.6g",rms);
+
+ } else
+ if (name=="Clear") {
+ res = ClearHistogram(item) ? "true" : "false";
+ } else {
+ return false;
+ }
+ }
+
+ cmd.SetStrRawData(res);
+
+ return true;
+}
+
+//typedef void StreamCallFunc(void*);
+
+//bool elderdabc::VisConDabc::CallFunc(const char* funcname, void* arg)
+//{
+// if (!funcname) return false;
+//
+// void* symbol = dabc::Factory::FindSymbol(funcname);
+// if (!symbol) return false;
+//
+// StreamCallFunc* func = (StreamCallFunc*) symbol;
+//
+// func(arg);
+//
+// return true;
+//}
+//
+//
+//bool elderdabc::VisConDabc::CreateStore(const char* storename)
+//{
+// fStore = dabc::mgr.CreateObject("root::TreeStore","elderdabc_store");
+// if (fStore.null()) {
+// fStoreInfo = "Fail to create root::TreeStore, check libDabcRoot plugin";
+// return false;
+// }
+//
+// dabc::Command cmd("Create");
+// cmd.SetStr("fname", storename);
+// cmd.SetStr("ftitle", "File with stored elderdabc data");
+// cmd.SetStr("tname", "T");
+// cmd.SetStr("ttitle", "Tree with elderdabc data");
+//
+// if (!fStore.Execute(cmd)) {
+// fStoreInfo = dabc::format("Fail to create ROOT file %s", storename);
+// return false;
+// }
+//
+// // set pointer to inform base class that storage exists
+// fTree = (TTree*) cmd.GetPtr("tree_ptr");
+//
+// fStoreInfo = dabc::format("Create ROOT file %s", storename);
+//
+// return true;
+//}
+//
+//bool elderdabc::VisConDabc::CloseStore()
+//{
+// fTree = nullptr;
+// fStore.Execute("Close");
+// fStore.Release();
+// fStoreInfo = "ROOT store closed";
+// return true;
+//}
+//
+//bool elderdabc::VisConDabc::CreateBranch(const char* name, const char* class_name, void** obj)
+//{
+// DOUT3("Create Branch1 %s", name);
+//
+// dabc::Command cmd("CreateBranch");
+// cmd.SetStr("name", name);
+// cmd.SetStr("class_name", class_name);
+// cmd.SetPtr("obj", (void*) obj);
+// return fStore.Execute(cmd);
+//}
+//
+//bool elderdabc::VisConDabc::CreateBranch(const char* name, void* member, const char* kind)
+//{
+// DOUT3("Create Branch2 %s", name);
+//
+// dabc::Command cmd("CreateBranch");
+// cmd.SetStr("name", name);
+// cmd.SetPtr("member", member);
+// cmd.SetStr("kind", kind);
+// return fStore.Execute(cmd);
+//}
+//
+//bool elderdabc::VisConDabc::StoreEvent()
+//{
+// if (fStore.null()) return false;
+//
+// dabc::Command cmd("Fill");
+// if (!fStore.Execute(cmd)) return false;
+//
+// fStoreInfo = cmd.GetStr("StoreInfo");
+//
+// return true;
+//}
diff --git a/plugins/mbs/mbs/LmdFile.h b/plugins/mbs/mbs/LmdFile.h
index e29001e5..3a3d8c08 100644
--- a/plugins/mbs/mbs/LmdFile.h
+++ b/plugins/mbs/mbs/LmdFile.h
@@ -81,10 +81,14 @@ namespace mbs {
return true;
}
+ /////// JAM24
+ /*
fprintf(stderr, "%s is original LMD file, which is not supported by DABC\n", fname);
Close();
return false;
-/*
+ */
+ /////// end JAM24
+
if ((fFileHdr.FullSize() > 0x8000) || (fFileHdr.FullSize() < sizeof(fFileHdr))) {
fprintf(stderr, "File header %u too large in file %s\n", (unsigned) fFileHdr.FullSize(), fname);
Close();
@@ -99,7 +103,7 @@ namespace mbs {
fReadingMode = true;
// fMbsFormat = true;
return true;
-*/
+
}
bool OpenWriting(const char* fname, const char* opt = nullptr)
@@ -175,12 +179,12 @@ namespace mbs {
uint64_t maxsz = *sz; *sz = 0;
- // printf("start buffer reading maxsz = %u\n", (unsigned) maxsz);
+ printf("start buffer reading maxsz = %u\n", (unsigned) maxsz);
// any data in LMD should be written with 4-byte wrapping
size_t readsz = io->fread(ptr, 1, maxsz, fd);
- // printf("readsz = %u\n", (unsigned) readsz);
+ printf("readsz = %u\n", (unsigned) readsz);
if (readsz == 0) return false;
diff --git a/plugins/mbs/src/LmdInput.cxx b/plugins/mbs/src/LmdInput.cxx
index 64a947f6..d92e5519 100644
--- a/plugins/mbs/src/LmdInput.cxx
+++ b/plugins/mbs/src/LmdInput.cxx
@@ -100,7 +100,7 @@ unsigned mbs::LmdInput::Read_Complete(dabc::Buffer& buf)
break;
}
- // DOUT0("Read buffer of size %u total %u", (unsigned) bufsize, (unsigned) buf.SegmentSize(0));
+ //DOUT0("Read buffer of size %u total %u", (unsigned) bufsize, (unsigned) buf.SegmentSize(0));
buf.SetTotalSize(bufsize);
buf.SetTypeId(mbs::mbt_MbsEvents);
diff --git a/plugins/olmd/CMakeLists.txt b/plugins/olmd/CMakeLists.txt
new file mode 100644
index 00000000..33a82148
--- /dev/null
+++ b/plugins/olmd/CMakeLists.txt
@@ -0,0 +1,89 @@
+dabc_link_library(
+ DabcOlmd
+ SOURCES mbsapibase/f_his_hist.c
+ mbsapibase/f_his_swpbas.c
+ mbsapibase/f_his_toupper.c
+ mbsapibase/f_mbs_status.c
+ mbsapibase/f_stccomm.c
+ mbsapibase/f_swaplw.c
+ mbsapibase/f_ut_compress.c
+ mbsapibase/f_ut_seg_show.c
+ mbsapibase/f_ut_status.c
+ mbsapibase/f_ut_time.c
+ mbsapi/f_evcli.c
+ mbsapi/f_evt.c
+ mbsapi/fLmd.c
+ mbsapi/f_radware.c
+ mbsapi/f_ut_utime.c
+ src/Factory.cxx
+ src/OlmdInput.cxx
+ src/OlmdFile.cxx
+ HEADERS mbsapibase/err_mask_def.h
+ mbsapibase/errnum_def.h
+ mbsapibase/f_his_hist.h
+ mbsapibase/f_his_swpbas.h
+ mbsapibase/f_his_toupper.h
+ mbsapibase/f_mbs_status.h
+ mbsapibase/f_stccomm.h
+ mbsapibase/f_swaplw.h
+ mbsapibase/f_ut_compress.h
+ mbsapibase/f_ut_seg_show.h
+ mbsapibase/f_ut_status.h
+ mbsapibase/f_ut_time.h
+ mbsapibase/ml_def.h
+ mbsapibase/mo_def.h
+ mbsapibase/portnum_def.h
+ mbsapibase/sbs_def.h
+ mbsapibase/s_daqst.h
+ mbsapibase/s_errstat.h
+ mbsapibase/s_head.h
+ mbsapibase/s_his_comm.h
+ mbsapibase/s_his_head.h
+ mbsapibase/s_pol_cond.h
+ mbsapibase/s_set_ml.h
+ mbsapibase/s_set_mo.h
+ mbsapibase/s_setup.h
+ mbsapibase/s_win_cond.h
+ mbsapibase/sys_def.h
+ mbsapibase/typedefs.h
+ mbsapibase/typedefs_nt.h
+ mbsapi/clnt_buf_def.h
+ mbsapi/f_evcli.h
+ mbsapi/f_evt.h
+ mbsapi/fLmd.h
+ mbsapi/f_radware.h
+ mbsapi/f_ut_utime.h
+ mbsapi/gps_sc_def.h
+ mbsapi/s_bufhe.h
+ mbsapi/s_bufhe_swap.h
+ mbsapi/s_clntbuf.h
+ mbsapi/s_clnt_filter.h
+ mbsapi/s_clnt_filter_swap.h
+ mbsapi/s_evhe.h
+ mbsapi/s_evhe_swap.h
+ mbsapi/s_filhe.h
+ mbsapi/s_filhe_swap.h
+ mbsapi/s_filter.h
+ mbsapi/s_flt_descr.h
+ mbsapi/s_flt_descr_swap.h
+ mbsapi/sMbs.h
+ mbsapi/s_opc1.h
+ mbsapi/s_pat.h
+ mbsapi/s_spe.h
+ mbsapi/s_stdint.h
+ mbsapi/s_ve10_1.h
+ mbsapi/s_ve10_1_swap.h
+ mbsapi/s_ves10_1.h
+ mbsapi/s_ves10_1_swap.h
+ olmd/Factory.h
+ olmd/OlmdFile.h
+ olmd/OlmdInput.h
+ INCDIR olmd
+ LIBRARIES dabc::DabcBase dabc::DabcMbs
+ INCLUDES mbsapi mbsapibase
+ DEFINITIONS Linux _LARGEFILE64_SOURCE
+ COPY_HEADERS)
+
+dabc_install_plugin_data(
+ DabcOlmd
+ DESTINATION ${DABC_INSTALL_PLUGINDIR}/olmd)
diff --git a/plugins/olmd/mbsapi/clnt_buf_def.h b/plugins/olmd/mbsapi/clnt_buf_def.h
new file mode 100644
index 00000000..34bc1be1
--- /dev/null
+++ b/plugins/olmd/mbsapi/clnt_buf_def.h
@@ -0,0 +1,64 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef CLNT_BUF_DEF_H
+#define CLNT_BUF_DEF_H
+
+/* CLNT_BUF_DEF.H
+ *
+ * definitions MUST be EQUAL for GPS-Server, GPS-Client and SBS-Monitor
+ * modif: 24-Feb-1994 RSM CLNT__BUFHEAD
+ *
+ */
+/* +++ length in bytes +++ */
+#define CLNT__OUTBUFHEAD 344 /* header length (300) inluding
+ * CLNT_INFO_CONTROL and
+ * CLNT_INFO_CLIENT
+ * but without *p_clntoutbuf[2]
+ * and *p_client. Data trans-
+ * mission starts at l_dlen
+ */
+#define CLNT__INFO_CONTROL 24 /* len of info from
+ * s_control to be copied to
+ * s_clntoutbuf
+ */
+#define CLNT__INFO_CLIENT 20 /* len of info from
+ * s_client to be copied to
+ * s_clntoutbuf
+ */
+#define CLNT__SMALLBUF 512 /* size of smallest buffer
+ * to be sent
+ */
+#define CLNT__RESTBUF 168 /* begin of rest buffer addr
+ * is &p_clntoutbuf->
+ * c_buffer[CLNT_RESTBUF]
+ * CLNT_RESTBUF =
+ * CLNT_SMALLBUF -
+ * CLNT_OUTBUFHEAD
+ */
+#define CLNT__BUFHEAD 336 /* Header of output/input in
+ * s_clntbuf and
+ * s_clntoutbuf
+ * from l_dlen to
+ * l_clntoutbuf_fltm
+ */
+#define CLNT__BUFH_LW 11 /* Header from l_testbit
+ * to l_msgtyp in LW */
+#define CLNT__MSGLEN 256 /* Length of message string
+ */
+#define CLNT__REST_LW 11 /* rest of header after
+ * s_clntbuf.c_message[] to
+ * s_clntbuf.c_buffer[0]
+ */
+
+#endif
diff --git a/plugins/olmd/mbsapi/fLmd.c b/plugins/olmd/mbsapi/fLmd.c
new file mode 100644
index 00000000..faf951b3
--- /dev/null
+++ b/plugins/olmd/mbsapi/fLmd.c
@@ -0,0 +1,1028 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef Lynx /* LynxOS */
+#include
+#include
+#include
+#endif
+
+#ifdef Linux /* Linux */
+#include
+#include
+#endif
+
+#ifdef Solaris /* Solaris */
+#include
+#include
+#endif
+
+#ifdef Darwin /* Max OS X */
+#include
+#include
+#define fgetpos64 fgetpos
+#define fopen64 fopen
+#define fseeko64 fseek
+#define fpos64_t fpos_t
+#endif
+
+#ifdef _MSC_VER
+#include
+#include
+
+#define fgetpos64 fgetpos
+#define fopen64 fopen
+#define fseeko64 fseek
+#define fpos64_t fpos_t
+#endif
+
+#include "fLmd.h"
+#include "f_ut_time.h"
+
+
+int32_t fLmdWriteBuffer(sLmdControl *, char *, uint32_t);
+uint32_t fLmdCleanup(sLmdControl *);
+void fLmdOffsetResize(sLmdControl *, uint32_t);
+uint32_t fLmdOffsetSet(sLmdControl *, uint32_t );
+uint32_t fLmdOffsetRead(sLmdControl *);
+uint32_t fLmdOffsetWrite(sLmdControl *);
+lmdoff_t fLmdOffsetGet(sLmdControl *, uint32_t);
+void fLmdOffsetElements(sLmdControl *, uint32_t, uint32_t *, uint32_t *);
+#define OFFSET__ENTRIES 250000
+
+//===============================================================
+uint32_t fLmdPutOpen(sLmdControl *pLmdControl,
+ char *Filename,
+ sMbsFileHeader *pBuffHead, // LMD__STANDARD_HEADER (NULL) or address
+ uint32_t iBytes, // LMD__NO_BUFFER (0) or buffer size
+ uint32_t iOver, // LMD__[NO_]OVERWRITE
+ uint32_t iUseOffset, // LMD__[NO_]INDEX
+ uint32_t iLargeFile) // LMD__[NO_]LARGE_FILE
+{
+ int32_t iReturn;
+ struct timespec clock;
+
+ memset(pLmdControl,0,sizeof(sLmdControl));
+
+ // allocate header or take extern
+ if(pBuffHead == LMD__STANDARD_HEADER){
+ pLmdControl->pMbsFileHeader = (sMbsFileHeader *)malloc(sizeof(sMbsFileHeader));
+ if (!pLmdControl->pMbsFileHeader) {
+ printf("fLmdPutOpen: memory allocation error\n");
+ return(LMD__FAILURE);
+ }
+ memset(pLmdControl->pMbsFileHeader,0,sizeof(sMbsFileHeader));
+ pLmdControl->iInternHeader=1;
+ } else {
+ pLmdControl->pMbsFileHeader= pBuffHead;
+ pLmdControl->iInternHeader=0;
+ }
+
+ clock_gettime(CLOCK_REALTIME,&clock);
+ pLmdControl->pMbsFileHeader->iTimeSpecSec=clock.tv_sec;
+ pLmdControl->pMbsFileHeader->iTimeSpecNanoSec=clock.tv_nsec;
+
+ pLmdControl->pMbsFileHeader->iType=LMD__TYPE_FILE_HEADER_101_1;
+ pLmdControl->pMbsFileHeader->iEndian=1;
+ strcpy(pLmdControl->cFile,Filename);
+
+ // optionally allocate buffer
+ if(iBytes > 0){
+ pLmdControl->pBuffer = (int16_t*) malloc(iBytes);
+ pLmdControl->iInternBuffer = 1;
+ }
+ pLmdControl->iBufferWords=iBytes/2;
+ pLmdControl->iLeftWords=iBytes/2;
+ // open file
+ if(iOver == LMD__NO_OVERWRITE){ // do not overwrite
+ if((pLmdControl->fFile=(FILE *)fopen64(Filename,"r") )!=NULL){
+ printf("fLmdPutOpen: File exists: %s\n",Filename);
+ fLmdCleanup(pLmdControl);
+ fclose(pLmdControl->fFile);
+ return(PUTLMD__FILE_EXIST);
+ }
+ }
+
+ if((pLmdControl->fFile=(FILE *)fopen64(Filename,"w+") )== NULL){
+ printf("fLmdPutOpen: Error open file %s\n",Filename);
+ fLmdCleanup(pLmdControl);
+ return(PUTLMD__OPEN_ERR);
+ }
+
+ if(iLargeFile == LMD__LARGE_FILE)pLmdControl->iOffsetSize=8;
+ else pLmdControl->iOffsetSize=4;
+ pLmdControl->pMbsFileHeader->iOffsetSize=pLmdControl->iOffsetSize;
+
+ // write header
+ iReturn=fLmdWriteBuffer(pLmdControl,(char *)pLmdControl->pMbsFileHeader,
+ (pLmdControl->pMbsFileHeader->iUsedWords)*2+sizeof(sMbsFileHeader));
+ pLmdControl->iBytes+=iReturn;
+
+ if(iUseOffset == LMD__INDEX)fLmdOffsetResize(pLmdControl,iReturn/4); // create and set first value
+ printf("fLmdPutOpen: %s. Bytes:%d over:%d table:%d large:%d.\n",
+ Filename,iBytes,iOver,iUseOffset,iLargeFile);
+ return(LMD__SUCCESS);
+}
+
+//===============================================================
+uint32_t fLmdPutElement(sLmdControl *pLmdControl,sMbsHeader *pHeader)
+{
+ uint32_t *ps, *pd, i, elements;
+ int64_t fileleft,used;
+ int32_t iReturn;
+
+ // enough space left?
+ if(pLmdControl->iOffsetEntries && (pLmdControl->iOffsetSize == 4)){
+ elements=pLmdControl->iElements+2;
+ used=pLmdControl->iBytes/4;
+ fileleft=0xffffffff - used - (4+elements); // size of table
+ if((int64_t)(pHeader->iWords/2+2) > fileleft){
+ printf("fLmdPutElement: File size exceed\n");
+ return(PUTLMD__EXCEED);
+ }
+ }
+ // save largest size in header
+ if((pHeader->iWords+4) > pLmdControl->pMbsFileHeader->iMaxWords)
+ pLmdControl->pMbsFileHeader->iMaxWords=pHeader->iWords+4;
+ // no buffer, write element directly
+ if(pLmdControl->iBufferWords == 0){
+ pLmdControl->pMbsHeader=pHeader;
+ iReturn=fLmdWriteBuffer(pLmdControl,(char *)pHeader,(pHeader->iWords+4)*2);
+ pLmdControl->iBytes+=iReturn;
+ if((uint32_t) iReturn != (pHeader->iWords+4)*2){
+ printf("fLmdPutElement: Write error \n");
+ return LMD__FAILURE;
+ }
+ pLmdControl->pMbsFileHeader->iElements++;
+ pLmdControl->iElements++;
+ if(pLmdControl->iOffsetEntries)fLmdOffsetSet(pLmdControl,iReturn/4);
+ return(LMD__SUCCESS);
+
+ } // end no buffer
+ if((pHeader->iWords+4) > pLmdControl->iLeftWords){ // flash buffer to file
+ iReturn = fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pBuffer,
+ (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2);
+ pLmdControl->iBytes+=iReturn;
+ if((uint32_t) iReturn != (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2)
+ return LMD__FAILURE;
+ pLmdControl->iLeftWords=pLmdControl->iBufferWords; // buffer free
+ }
+ if((pHeader->iWords+4) > pLmdControl->iLeftWords){ // element too big for buffer
+ printf("fLmdPutElement: Element too big: %d words\n",pHeader->iWords+4);
+ return(PUTLMD__TOOBIG);
+ }
+ // copy to buffer
+ ps=(uint32_t *)pHeader;
+ pd=(uint32_t *)pLmdControl->pBuffer+(pLmdControl->iBufferWords-pLmdControl->iLeftWords)/2;
+ iReturn=(pHeader->iWords+4)/2; // here 32b words
+ for(i=0;ipMbsFileHeader->iElements++;
+ pLmdControl->iElements++;
+ pLmdControl->iLeftWords -= (pHeader->iWords+4);
+ if(pLmdControl->iOffsetEntries)
+ fLmdOffsetSet(pLmdControl,iReturn);
+ return (LMD__SUCCESS);
+}
+
+//===============================================================
+uint32_t fLmdPutBuffer(sLmdControl *pLmdControl, sMbsHeader *pHeader, uint32_t Items)
+{
+ sMbsHeader *pH;
+ uint32_t Bytes=0,TotalBytes=0,i, elements;
+ int64_t fileleft,used;
+ int32_t iReturn;
+
+ // check if total buffer fits in file
+ if(pLmdControl->iOffsetEntries && (pLmdControl->iOffsetSize == 4)){
+ pH=pHeader; // SL 16.11.2009 - pH was not initialized in this branch
+ elements=pLmdControl->iElements+Items+2;
+ used=pLmdControl->iBytes/4;
+ fileleft=0xffffffff - used - (4+elements); // size of table
+ for(i=0;iiWords)*2;
+ TotalBytes += Bytes;
+ pH=(sMbsHeader *)((int16_t*)pH + Bytes/2);
+ }
+ if((int64_t)TotalBytes/4 > fileleft){
+ printf("fLmdPutElement: File size exceed\n");
+ return(PUTLMD__EXCEED);
+ }
+ Bytes=0;
+ TotalBytes=0;
+ }
+ pH = pHeader;
+ for(i=0;iiElements++;
+ Bytes = (4+pH->iWords)*2;
+ TotalBytes += Bytes;
+ if(pLmdControl->iOffsetEntries)fLmdOffsetSet(pLmdControl,Bytes/4);
+ if((pH->iWords+4) > pLmdControl->pMbsFileHeader->iMaxWords)
+ pLmdControl->pMbsFileHeader->iMaxWords=pH->iWords+4;
+ pH=(sMbsHeader *)((int16_t *)pH+Bytes/2);
+ }
+ iReturn = fLmdWriteBuffer(pLmdControl,(char *)pHeader,TotalBytes);
+ pLmdControl->iBytes+=iReturn;
+ if((uint32_t) iReturn != TotalBytes)
+ return LMD__FAILURE;
+
+ pLmdControl->pMbsFileHeader->iElements += Items;
+ return(LMD__SUCCESS);
+}
+
+//===============================================================
+uint32_t fLmdPutClose(sLmdControl *pLmdControl)
+{
+ int32_t iReturn;
+
+ if(pLmdControl->iBufferWords > pLmdControl->iLeftWords){ // write last buffer
+ iReturn = fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pBuffer,
+ (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2);
+ pLmdControl->iBytes+=iReturn;
+ if((uint32_t)iReturn != (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2) {
+ printf("fLmdPutClose: Error writing last buffer. Closing file.\n");
+ // rewind file and rewrite header
+ rewind(pLmdControl->fFile); /* rewind file, rewrite header */
+ fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pMbsFileHeader,
+ sizeof(sMbsFileHeader));
+ fLmdCleanup(pLmdControl);
+ return(LMD__FAILURE);
+ }
+ }
+ if(pLmdControl->iOffsetEntries)
+ if(fLmdOffsetWrite(pLmdControl) != LMD__SUCCESS)
+ pLmdControl->pMbsFileHeader->iTableOffset=0; // table could not be written
+
+ // rewind file and rewrite header
+ rewind(pLmdControl->fFile); /* rewind file, rewrite header */
+ fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pMbsFileHeader,
+ sizeof(sMbsFileHeader));
+ return(fLmdGetClose(pLmdControl));
+}
+
+#ifndef FILEONLY
+//===============================================================
+uint32_t fLmdInitMbs(sLmdControl *pLmdControl,
+ char *Nodename,
+ uint32_t iMaxBytes,
+ uint32_t iBuffers,
+ uint32_t iStreams,
+ uint32_t iPort,
+ uint32_t iTimeout)
+{
+ if(iBuffers > 1){printf("fLmdInitMbs: Event spanning not supported!\n");return(LMD__FAILURE);}
+ if(iStreams > 0){printf("fLmdInitMbs: MBS not in DABC mode!\n");return(LMD__FAILURE);}
+ pLmdControl->iPort=iPort;
+ strcpy(pLmdControl->cFile,Nodename);
+ if(pLmdControl->pBuffer == NULL) pLmdControl->pBuffer = (int16_t*) malloc(iMaxBytes);
+ pLmdControl->iBufferWords=iMaxBytes/2;
+ pLmdControl->iInternBuffer=1;
+ pLmdControl->iTCP=pLmdControl->pTCP->socket;
+ pLmdControl->iTcpTimeout=iTimeout;
+ pLmdControl->iTCPowner=0;
+ return(LMD__SUCCESS);
+}
+//===============================================================
+uint32_t fLmdCloseMbs(sLmdControl *pLmdControl)
+{
+
+ int32_t stat;
+ char cClose[12];
+ // send request buffer for stream server
+ if(pLmdControl->iPort == PORT__STREAM) {
+ memset(cClose,0,sizeof(cClose));
+ strcpy(cClose, "CLOSE");
+ stat=f_stc_write(cClose,12,pLmdControl->iTCP);
+ }
+ stat=f_stc_close(pLmdControl->pTCP);
+ pLmdControl->pMbsFileHeader = NULL; // was reference only
+ if(pLmdControl->iTCPowner == 0) pLmdControl->pTCP=NULL; // was reference only
+ fLmdCleanup(pLmdControl);
+ return(stat);
+}
+//===============================================================
+uint32_t fLmdGetMbsEvent(sLmdControl *pLmdControl, sMbsHeader** event)
+{
+ uint32_t stat;
+ sMbsHeader *pM;
+ *event=NULL;
+ if(pLmdControl->iLeftWords == 0){ // get new buffer
+ stat=fLmdGetMbsBuffer(pLmdControl,NULL,0,NULL,NULL);
+ if(stat != LMD__SUCCESS){
+ return(stat);
+ }
+ // first event behind header:
+ pLmdControl->pMbsHeader=(sMbsHeader *)(pLmdControl->pBuffer+sizeof(sMbsBufferHeader)/2);
+ }
+ pM=pLmdControl->pMbsHeader; // current to be returned
+ pLmdControl->iLeftWords -= (pLmdControl->pMbsHeader->iWords+4);
+ pLmdControl->pMbsHeader =
+ (sMbsHeader *)((int16_t *)pLmdControl->pMbsHeader +
+ pLmdControl->pMbsHeader->iWords+4);
+ pLmdControl->iElements++;
+ *event=pM;
+ return(LMD__SUCCESS);
+}
+//===============================================================
+uint32_t fLmdGetMbsBuffer(sLmdControl *pLmdControl, sMbsBufferHeader *pBuffer, uint32_t iBytes, uint32_t *iElements, uint32_t *iBytesUsed)
+{
+
+ sMbsBufferHeader *pBuf;
+ uint32_t usedBytes = 0, leftBytes = 0;
+ int32_t iReturn;
+ char cRequest[12];
+
+ leftBytes = iBytes;
+ pBuf = pBuffer;
+ if(pBuf == NULL){
+ pBuf = (sMbsBufferHeader *)pLmdControl->pBuffer; // internal buffer
+ leftBytes = pLmdControl->iBufferWords*2; // size of this buffer
+ }
+ if(pBuf == NULL){
+ printf("fLmdGetMbsBuffer: Need buffer to read\n");
+ return(LMD__FAILURE);
+ }
+ if (leftBytes < sizeof(sMbsBufferHeader)) {
+ printf("fLmdGetMbsBuffer: %s buffer size %d too small for %d bytes\n", pLmdControl->cFile, leftBytes,
+ (int)sizeof(sMbsBufferHeader));
+ return (LMD__FAILURE);
+ }
+ // send request buffer for stream server
+ if(pLmdControl->iPort == PORT__STREAM) {
+ memset(cRequest,0,sizeof(cRequest));
+ strcpy(cRequest, "GETEVT");
+ iReturn=f_stc_write(cRequest,12,pLmdControl->iTCP);
+ }
+ iReturn=f_stc_read((int32_t *)pBuf,sizeof(sMbsBufferHeader),pLmdControl->iTCP,pLmdControl->iTcpTimeout);
+ if(iReturn == STC__TIMEOUT) return(LMD__TIMEOUT);
+ if(iReturn != STC__SUCCESS) return(LMD__FAILURE);
+ if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pBuf,sizeof(sMbsBufferHeader)/4);
+ if(leftBytes < (sizeof(sMbsBufferHeader)+2*pBuf->iUsedWords)){
+ printf("fLmdGetMbsBuffer: %s buffer size %d too small for %lu bytes\n",
+ pLmdControl->cFile,leftBytes,(long unsigned) (sizeof(sMbsBufferHeader)+2*pBuf->iMaxWords));
+ return(LMD__FAILURE);
+ }
+ usedBytes = pBuf->iUsedWords*2;
+ if((pBuf->iType & 0xffff) == 100)
+ iReturn=f_stc_read((int32_t *)(pBuf+1),usedBytes,pLmdControl->iTCP,-1);
+ if(iReturn == STC__TIMEOUT) return(LMD__TIMEOUT);
+ if(iReturn != STC__SUCCESS) return(LMD__FAILURE);
+ if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)(pBuf+1),usedBytes/4);
+ if(iBytesUsed != NULL)*iBytesUsed =usedBytes+sizeof(sMbsBufferHeader);
+ if(iElements != NULL)*iElements =pBuf->iElements;
+ pLmdControl->iBytes += usedBytes;
+ pLmdControl->iLeftWords = usedBytes/2; // without header
+ pLmdControl->pMbsFileHeader = (sMbsFileHeader *)pBuf;
+ return(LMD__SUCCESS);
+}
+#endif // FILEONLY
+
+//===============================================================
+uint32_t fLmdGetOpen(sLmdControl *pLmdControl,
+ char *Filename,
+ sMbsFileHeader *pBuffHead, // LMD__INTERNAL_HEADER (NULL) or address of file header
+ uint32_t iBytes, // LMD__NO_BUFFER (0) or LMD__MIN_BUFFER or internal buffersize
+ uint32_t iUseOffset) // LMD__[NO_]INDEX
+{
+ int32_t iReturn;
+ uint32_t bufferBytes=0;
+
+ memset(pLmdControl,0,sizeof(sLmdControl));
+ if(pBuffHead == LMD__INTERNAL_HEADER){
+ pLmdControl->pMbsFileHeader = (sMbsFileHeader *)malloc(sizeof(sMbsFileHeader));
+ pLmdControl->iInternHeader=1;
+ } else {
+ pLmdControl->pMbsFileHeader = pBuffHead;
+ pLmdControl->iInternHeader=0;
+ }
+ memset(pLmdControl->pMbsFileHeader,0,sizeof(sMbsFileHeader));
+
+ // copy file name to control structure
+ strcpy(pLmdControl->cFile,Filename);
+ if((pLmdControl->fFile=(FILE *)fopen64(Filename,"r"))== NULL)
+ {
+ printf("fLmdGetOpen: File not found: %s\n",Filename);
+ fLmdCleanup(pLmdControl);
+ return(GETLMD__NOFILE);
+ }
+ /* read header */
+ iReturn=fLmdReadBuffer(pLmdControl,
+ (char *)pLmdControl->pMbsFileHeader,
+ sizeof(sMbsFileHeader));
+ if(iReturn!=sizeof(sMbsFileHeader)) {
+ printf("fLmdGetOpen: LMD format error: no LMD file: %s\n",Filename);
+ fLmdGetClose(pLmdControl);
+ return(GETLMD__NOLMDFILE);
+ }
+ // check type and subtype, and endian
+ if(pLmdControl->pMbsFileHeader->iEndian != 1) pLmdControl->iSwap=1;
+ if(pLmdControl->iSwap){
+ printf("do swap !!!\n");
+ fLmdSwap4((uint32_t *)pLmdControl->pMbsFileHeader,sizeof(sMbsFileHeader)/4);
+ fLmdSwap8((uint64_t *)&pLmdControl->pMbsFileHeader->iTableOffset,1);
+ }
+ if(pLmdControl->pMbsFileHeader->iType != LMD__TYPE_FILE_HEADER_101_1){
+ printf("fLmdGetOpen: LMD format error: no LMD file: %s, type is %0x\n",
+ Filename,pLmdControl->pMbsFileHeader->iType);
+ fLmdGetClose(pLmdControl);
+ return(GETLMD__NOLMDFILE);
+ }
+
+ if((iUseOffset == LMD__INDEX)&&(pLmdControl->pMbsFileHeader->iTableOffset > 0)){
+ // printf("fLmdGetOpen: use table in file: %s\n",Filename);
+ pLmdControl->iOffsetSize=pLmdControl->pMbsFileHeader->iOffsetSize;
+ iReturn=fLmdOffsetRead(pLmdControl); // read offset table
+ if(iReturn != LMD__SUCCESS){
+ printf("fLmdGetOpen: Index format error: %s\n",Filename);
+ fLmdGetClose(pLmdControl);
+ return(iReturn);
+ }
+ }
+
+ pLmdControl->iBytes+=iReturn;
+ // more of header?
+ if(pLmdControl->pMbsFileHeader->iUsedWords > 0)
+ {
+ // Read this additional information without swapping.
+ // Could be mostly strings. Caller must know.
+ pLmdControl->cHeader = malloc(pLmdControl->pMbsFileHeader->iUsedWords*2);
+ iReturn = fLmdReadBuffer(pLmdControl,pLmdControl->cHeader,
+ pLmdControl->pMbsFileHeader->iUsedWords*2 );
+ if((uint32_t) iReturn != pLmdControl->pMbsFileHeader->iUsedWords*2) {
+ printf("fLmdGetOpen: LMD format error: no LMD file: %s\n",Filename);
+ fLmdGetClose(pLmdControl);
+ return(GETLMD__NOLMDFILE);
+ }
+ }
+
+ bufferBytes = iBytes;
+ if(bufferBytes < pLmdControl->pMbsFileHeader->iMaxWords*2)
+ bufferBytes = pLmdControl->pMbsFileHeader->iMaxWords*2;
+ fLmdPrintFileHeader(1,pLmdControl->pMbsFileHeader);
+ pLmdControl->pBuffer = (int16_t *)malloc(bufferBytes);
+ pLmdControl->iInternBuffer = 1;
+ pLmdControl->iBufferWords=bufferBytes/2; // will be increased if necessary
+
+ printf("fLmdGetOpen: %s words %u\n", Filename, pLmdControl->iBufferWords);
+
+ pLmdControl->iLeftWords = 0; // buffer empty, read with first fLmdGetElement
+ pLmdControl->pMbsHeader = NULL;
+ return(LMD__SUCCESS);
+}
+
+//===============================================================
+uint32_t fLmdGetBuffer(sLmdControl *pLmdControl, sMbsHeader *pMbsHeader, uint32_t iBytes, uint32_t *iElements,
+ uint32_t *iBytesUsed)
+{
+
+ sMbsHeader *pm;
+ uint32_t elem = 0, leftBytes = 0, used, elem_sz;
+ int32_t iReturn;
+
+ if (iBytes < pLmdControl->pMbsFileHeader->iMaxWords) {
+ printf("fLmdGetBuffer: %s buffer size %d too small for %d bytes\n", pLmdControl->cFile, iBytes,
+ pLmdControl->pMbsFileHeader->iMaxWords);
+ return (LMD__FAILURE);
+ }
+ if (pMbsHeader == NULL) {
+ printf("fLmdGetBuffer: Need buffer to read\n");
+ return (LMD__FAILURE);
+ }
+ *iBytesUsed = 0;
+ *iElements = 0;
+ if (pLmdControl->iElements == pLmdControl->pMbsFileHeader->iElements)
+ return (GETLMD__EOFILE);
+
+ // Offset table
+ if (pLmdControl->iOffsetEntries) { // use offsets to read elements fitting in buffer
+ fLmdOffsetElements(pLmdControl, iBytes, &elem, &used);
+ // printf("Read %d bytes of %d, elements %d\n",used,iBytes,elem);
+ iReturn = fLmdReadBuffer(pLmdControl, (char *)pMbsHeader, used);
+ if (iReturn <= 0) {
+ printf("fLmdGetBuffer: EOF: %s\n", pLmdControl->cFile);
+ return (GETLMD__EOFILE);
+ }
+ if ((uint32_t) iReturn != used) {
+ printf("fLmdGetBuffer: LMD read error: unexpected EOF: %s %u %u\n", pLmdControl->cFile, iReturn, used);
+ return (GETLMD__NOLMDFILE);
+ }
+ *iBytesUsed = used;
+ *iElements = elem;
+ if (pLmdControl->iSwap)
+ fLmdSwap4((uint32_t *)pMbsHeader, iReturn / 4);
+ pLmdControl->iBytes += iReturn;
+ return (LMD__SUCCESS);
+ }
+ // no offset table
+ // do we have fragment stored?
+ leftBytes = pLmdControl->iLeftWords * 2;
+ if (leftBytes > 0) {
+ if (leftBytes > iBytes) {
+ printf("fLmdGetBuffer: stored piece of data (%u) larger than provided buffer (%u)\n",
+ leftBytes, iBytes);
+ return(LMD__FAILURE);
+ }
+
+ if (pLmdControl->pMbsHeader == 0) {
+ printf("fLmdGetBuffer: Internal error pMbsHeader==0\n");
+ return(LMD__FAILURE);
+ }
+
+ memcpy(pMbsHeader, pLmdControl->pMbsHeader, leftBytes);
+ }
+ iReturn = fLmdReadBuffer(pLmdControl,(char *)pMbsHeader+leftBytes, iBytes-leftBytes);
+ if(iReturn <= 0) {
+ printf("fLmdGetBuffer: EOF: %s\n",pLmdControl->cFile);
+ if (leftBytes>0)
+ printf("fLmdGetBuffer: EOF while we have some rest data (%u)\n", leftBytes);
+ else
+ return(GETLMD__EOFILE);
+ }
+
+ if(iReturn > (iBytes-leftBytes)) {
+ printf("fLmdGetBuffer: LMD read error %s - too many bytes read %u wants %u",
+ pLmdControl->cFile, iReturn, iBytes-leftBytes);
+ return(GETLMD__NOLMDFILE);
+ }
+
+ if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pMbsHeader+leftBytes/4,iReturn/4);
+ pLmdControl->iBytes += iReturn;
+ leftBytes += iReturn; // thats what is in the buffer
+ // step through buffer to get number of elements and size
+ pm=pMbsHeader;
+ while(leftBytes >=8){
+ if(pm->iType == LMD__TYPE_FILE_INDEX_101_2) break; // file index is last
+ elem_sz = (pm->iWords+4)*2;
+ if(elem_sz > leftBytes) break; // pm valid but incomplete data
+
+ *iBytesUsed += elem_sz;
+ *iElements += 1;
+ pLmdControl->iElements++;
+ pm = (sMbsHeader *)((char*)pm + elem_sz);
+ leftBytes -= elem_sz;
+ }
+ //printf("Read %d bytes of %d, elements %d\n",*iBytesUsed,iBytes,*iElements);
+ // fragment left? copy to internal buffer
+ if(leftBytes>0){
+ if(leftBytes > pLmdControl->iBufferWords*2){
+ printf("fLmdGetBuffer: ERROR: internal buffer overflow. Needed:%d available:%d\n",
+ leftBytes,pLmdControl->iBufferWords*2);
+ return(LMD__FAILURE);
+ } else {
+ memcpy(pLmdControl->pBuffer,pm,leftBytes);
+ }
+ }
+ pLmdControl->iLeftWords = leftBytes/2;
+ if (pLmdControl->iLeftWords>0)
+ pLmdControl->pMbsHeader = (sMbsHeader*)pLmdControl->pBuffer;
+ else
+ pLmdControl->pMbsHeader = 0;
+
+ return(LMD__SUCCESS);
+}
+//===============================================================
+uint32_t fLmdGetElement(sLmdControl *pLmdControl, uint32_t iEvent, sMbsHeader **event)
+{
+ sMbsHeader *pM;
+ uint32_t i, evsz;
+ int32_t iReturn;
+ *event=NULL;
+
+ if(iEvent == LMD__NO_INDEX) {
+ if(pLmdControl->pBuffer==NULL) return(GETLMD__NOBUFFER); // internal buffer needed
+ if(pLmdControl->pMbsFileHeader->iElements == 0) return(GETLMD__NOMORE);
+
+ // check if we need to read extra data
+ if ((pLmdControl->iLeftWords < 4) ||
+ (pLmdControl->pMbsHeader == 0) ||
+ (pLmdControl->pMbsHeader->iWords+4 > pLmdControl->iLeftWords)) {
+ // first copy old data, if it exists
+ if (pLmdControl->iLeftWords > 0) {
+ memmove(pLmdControl->pBuffer, pLmdControl->pMbsHeader, pLmdControl->iLeftWords*2);
+// printf("copy to the begin rest %u bytes", pLmdControl->iLeftWords*2);
+ }
+
+ // second, try to read more bytes
+
+ iReturn = fLmdReadBuffer(pLmdControl,
+ (char *)(pLmdControl->pBuffer+pLmdControl->iLeftWords),
+ (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2);
+
+ if(iReturn <= 0) { printf("fLmdGetElement: EOF\n"); return(GETLMD__EOFILE); }
+
+ if(pLmdControl->iSwap) fLmdSwap4((uint32_t *)(pLmdControl->pBuffer+pLmdControl->iLeftWords),iReturn/4);
+
+ pLmdControl->iBytes += iReturn;
+ pLmdControl->pMbsHeader=(sMbsHeader *)pLmdControl->pBuffer;
+ pLmdControl->iLeftWords += iReturn/2;
+ }
+
+ // check if read buffer enough for event
+
+ evsz = (pLmdControl->pMbsHeader->iWords + 4) * 2;
+
+ if (evsz > pLmdControl->iLeftWords*2) {
+ printf ("fLmdGetElement: Error, full element %u does not fit in buffer %u",
+ evsz, pLmdControl->iLeftWords*2);
+ return (GETLMD__TOOBIG);
+ }
+
+ pLmdControl->pMbsFileHeader->iElements--;
+ pM = pLmdControl->pMbsHeader;
+ pLmdControl->pMbsHeader = (sMbsHeader *) ((char*) pM + evsz);
+ pLmdControl->iLeftWords -= evsz/2;
+ pLmdControl->iElements++;
+ *event=pM;
+ return(LMD__SUCCESS);
+ }
+ // get indexed event
+ if(pLmdControl->iOffsetEntries){
+ if(iEvent >= pLmdControl->iOffsetEntries)return(GETLMD__OUTOF_RANGE);
+ fseeko64(pLmdControl->fFile,fLmdOffsetGet(pLmdControl,iEvent-1)*4,SEEK_SET);
+ i=(fLmdOffsetGet(pLmdControl,iEvent)-fLmdOffsetGet(pLmdControl,iEvent-1));
+ iReturn = fLmdReadBuffer(pLmdControl,(char *)pLmdControl->pBuffer,i*4);
+ if(iReturn <= 0) {
+ printf("fLmdGetElement: EOF\n");
+ return(GETLMD__EOFILE);
+ }
+ if((uint32_t) iReturn != (i*4)) {
+ printf("fLmdGetBuffer: LMD read error: unexpected EOF: %s\n",pLmdControl->cFile);
+ return(GETLMD__EOFILE);
+ }
+ if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pLmdControl->pBuffer,iReturn/4);
+ pLmdControl->pMbsHeader=(sMbsHeader *)pLmdControl->pBuffer;
+ if((pLmdControl->pMbsHeader->iWords+4) != i*2){
+ printf("fLmdGetElement: Error Event %d: size from table is %d, header %d\n",
+ iEvent,i/2,pLmdControl->pMbsHeader->iWords+4);
+ return(GETLMD__SIZE_ERROR);
+ }
+ pLmdControl->iBytes+=iReturn;
+ *event=pLmdControl->pMbsHeader;
+ return(LMD__SUCCESS);
+ }
+ else return(GETLMD__NOMORE);
+ // return zero if no more events
+}
+//===============================================================
+uint32_t fLmdGetClose(sLmdControl *pLmdControl)
+{
+ fLmdCleanup(pLmdControl); // cleanup except fFile
+ if(fclose(pLmdControl->fFile) != 0) {
+ pLmdControl->fFile=NULL;
+ return(LMD__CLOSE_ERR);
+ }
+ pLmdControl->fFile=NULL;
+ return(LMD__SUCCESS);
+}
+//===============================================================
+int32_t fLmdReadBuffer(sLmdControl *pLmdControl, char *buffer, uint32_t bytes){
+ int32_t IObytes;
+ IObytes=(int32_t)fread(buffer,1,bytes,pLmdControl->fFile);
+ //if(IObytes < bytes) printf("Read %s: request %d bytes, got %d\n",pLmdControl->cFile,bytes,IObytes);
+ return(IObytes);
+}
+//===============================================================
+int32_t fLmdWriteBuffer(sLmdControl *pLmdControl, char *buffer, uint32_t bytes){
+ int32_t IObytes;
+ IObytes=(int32_t)fwrite(buffer,1,bytes,pLmdControl->fFile);
+ //if(IObytes < bytes) printf("Write %s: request %d bytes, put %d\n",
+ // pLmdControl->cFile,bytes,IObytes);
+ return(IObytes);
+}
+//===============================================================
+uint64_t fLmdGetBytesWritten(sLmdControl *pLmdControl)
+{
+ uint64_t bytes;
+ bytes=pLmdControl->iBytes;
+ // add pending data size in current buffer
+ if(pLmdControl->iBufferWords > pLmdControl->iLeftWords)
+ bytes += (pLmdControl->iBufferWords - pLmdControl->iLeftWords)*2;
+ // add table size which will be written at close
+ if ((pLmdControl->pOffset4!=NULL)||(pLmdControl->pOffset8!=NULL))
+ bytes += (pLmdControl->iElements+1)*pLmdControl->iOffsetSize;
+ return bytes;
+}
+//===============================================================
+uint32_t fLmdCleanup(sLmdControl *pLmdControl)
+{
+ // do not clean fFile
+ if(pLmdControl->pTCP != NULL)free(pLmdControl->pTCP);
+ if(pLmdControl->cHeader != NULL)free(pLmdControl->cHeader);
+ if(pLmdControl->pOffset4 != NULL)free(pLmdControl->pOffset4);
+ if(pLmdControl->pOffset8 != NULL)free(pLmdControl->pOffset8);
+ if((pLmdControl->pBuffer != NULL) && (pLmdControl->iInternBuffer>0))
+ free(pLmdControl->pBuffer);
+ if((pLmdControl->pMbsFileHeader != NULL) && (pLmdControl->iInternHeader>0))
+ free(pLmdControl->pMbsFileHeader);
+ pLmdControl->pTCP=NULL;
+ pLmdControl->cHeader=NULL;
+ pLmdControl->pBuffer=NULL;
+ pLmdControl->iInternBuffer=0;
+ pLmdControl->pOffset4=NULL;
+ pLmdControl->pOffset8=NULL;
+ pLmdControl->pMbsFileHeader=NULL;
+ pLmdControl->iInternHeader=0;
+ pLmdControl->pMbsHeader=NULL;
+ return (LMD__SUCCESS);
+}
+//===============================================================
+// can be called after GetOpen or ConnectMbs
+uint32_t fLmdGetSwap(sLmdControl *pLmdControl)
+{
+ if(pLmdControl != NULL)
+ return pLmdControl->iSwap;
+ return (uint32_t) -1;
+}
+//===============================================================
+// can be called after PutOpen or before PutClose
+void fLmdSetWrittenEndian(sLmdControl *pLmdControl,uint32_t iE)
+{
+ if(pLmdControl->pMbsFileHeader != NULL)
+ pLmdControl->pMbsFileHeader->iWrittenEndian=iE;
+ else
+ printf("fLmdSetWrittenEndian: No file header allocated!\n");
+}
+//===============================================================
+// can be called after GetOpen or GetMbsEvent
+uint32_t fLmdGetWrittenEndian(sLmdControl *pLmdControl)
+{
+ if(pLmdControl->pMbsFileHeader != NULL)
+ return(pLmdControl->pMbsFileHeader->iWrittenEndian);
+
+ printf("fLmdGetWrittenEndian: No file header allocated!\n");
+ return(LMD__ENDIAN_UNKNOWN);
+}
+//===============================================================
+sLmdControl * fLmdAllocateControl(void)
+{
+ sLmdControl *x;
+ x = (sLmdControl *)malloc(sizeof(sLmdControl));
+ if (x) memset(x,0,sizeof(sLmdControl));
+ return x;
+}
+//===============================================================
+void fLmdOffsetElements(sLmdControl *pLmdControl, uint32_t bytes, uint32_t *elements, uint32_t *used)
+{
+ lmdoff_t *off1,*off2;
+ uint32_t elem=0,i,*iff1,*iff2;
+
+ if(pLmdControl->iOffsetSize == 4){
+ iff1=pLmdControl->pOffset4+pLmdControl->iElements;
+ iff2=iff1;
+ for(i=pLmdControl->iElements;iiOffsetEntries-1;i++){
+ if((*(iff1+1)-*iff2)>bytes/4) break;
+ iff1++;
+ elem++;
+ pLmdControl->iElements++;
+ }
+ *used=(*iff1-*iff2)*4;
+ *elements=elem;
+ }
+ else if(pLmdControl->iOffsetSize == 8){
+ off1=pLmdControl->pOffset8+pLmdControl->iElements;
+ off2=off1;
+ for(i=pLmdControl->iElements;iiOffsetEntries-1;i++){
+ if((*(off1+1)-*off2)>bytes/4) break;
+ off1++;
+ elem++;
+ pLmdControl->iElements++;
+ }
+ *used=(*off1-*off2)*4;
+ *elements=elem;
+ }
+}
+//===============================================================
+uint32_t fLmdOffsetRead(sLmdControl *pLmdControl)
+{
+ int32_t iReturn;
+ sMbsHeader *pTableHead;
+
+ pTableHead=(sMbsHeader *)malloc(16); // header with 8 bytes data for future use.
+ fseeko64(pLmdControl->fFile,(lmdoff_t)pLmdControl->pMbsFileHeader->iTableOffset*4,SEEK_SET);
+ iReturn = fLmdReadBuffer(pLmdControl, (char *)pTableHead,16);
+ if(iReturn!=16) {
+ printf("fLmdGetBuffer: LMD read error: unexpected EOF: %s\n",pLmdControl->cFile);
+ free(pTableHead);
+ return(GETLMD__NOLMDFILE);
+ }
+ if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pTableHead,4);
+ if(pTableHead->iType != LMD__TYPE_FILE_INDEX_101_2){
+ printf("fLmdOffsetTable: LMD format error: no index table: %s, type %0x\n",
+ pLmdControl->cFile,pTableHead->iType);
+ free(pTableHead);
+ return(GETLMD__NOLMDFILE);
+ }
+ //printf("Table: words:%d type:%08x\n",pTableHead->iWords,pTableHead->iType);
+ free(pTableHead);
+ pLmdControl->iOffsetEntries=pLmdControl->pMbsFileHeader->iElements+1;
+ pLmdControl->pOffset8=(lmdoff_t *)malloc(pLmdControl->iOffsetEntries*pLmdControl->iOffsetSize);
+ iReturn = fLmdReadBuffer(pLmdControl,
+ (char *)pLmdControl->pOffset8,
+ pLmdControl->iOffsetEntries*pLmdControl->iOffsetSize);
+ if((uint32_t) iReturn != pLmdControl->iOffsetEntries*pLmdControl->iOffsetSize) {
+ printf("fLmdOffsetTable: LMD format error: no index table: %s\n",pLmdControl->cFile);
+ pLmdControl->iOffsetEntries = 0;
+ return(GETLMD__NOLMDFILE);
+ }
+ if(pLmdControl->iSwap){
+ fLmdSwap4((uint32_t *)pLmdControl->pOffset8,iReturn/4);
+ if(pLmdControl->iOffsetSize == 8)
+ fLmdSwap8((uint64_t *)pLmdControl->pOffset8,iReturn/8);
+ }
+ // go back behing header
+ fseeko64(pLmdControl->fFile,(lmdoff_t)sizeof(sMbsFileHeader),SEEK_SET);
+ // use small table
+ if(pLmdControl->iOffsetSize == 4){
+ pLmdControl->pOffset4= (uint32_t *)pLmdControl->pOffset8;
+ pLmdControl->pOffset8=NULL;
+ }
+ return(LMD__SUCCESS);
+}
+//===============================================================
+uint32_t fLmdOffsetWrite(sLmdControl *pLmdControl)
+{
+ int32_t iReturn;
+ char *pbuf;
+ lmdoff_t current;
+ sMbsHeader *pTableHead;
+ pTableHead = (sMbsHeader *)malloc(16); // header with 8 bytes data for future use.
+ if (!pTableHead) {
+ printf("fLmdOffsetWrite: memory allocation error\n");
+ return (LMD__FAILURE);
+ }
+ memset(pTableHead,0,16);
+ pTableHead->iWords=(pLmdControl->iElements+1)*pLmdControl->iOffsetSize/2+4;
+ pTableHead->iType=LMD__TYPE_FILE_INDEX_101_2;
+/* printf("Table: words:%d type:%08x offbytes:%d\n", */
+/* pTableHead->iWords,pTableHead->iType,pLmdControl->iOffsetSize); */
+ iReturn = fgetpos64(pLmdControl->fFile,(fpos64_t *) ¤t);
+ iReturn = fLmdWriteBuffer(pLmdControl, (char *)pTableHead,16);
+ free(pTableHead);
+ pbuf=(char *)pLmdControl->pOffset4; // try short table
+ if(pbuf == NULL) pbuf=(char *)pLmdControl->pOffset8;
+ iReturn = fLmdWriteBuffer(pLmdControl, pbuf,
+ (pLmdControl->iElements+1)*pLmdControl->iOffsetSize);
+ if(pLmdControl->pOffset8)
+ pLmdControl->pMbsFileHeader->iTableOffset = *(pLmdControl->pOffset8+pLmdControl->iElements);
+ if(pLmdControl->pOffset4)
+ pLmdControl->pMbsFileHeader->iTableOffset = *(pLmdControl->pOffset4 + pLmdControl->iElements);
+ if (current / 4 != pLmdControl->pMbsFileHeader->iTableOffset) {
+ printf("Table offset mismatch: current:%llu calculated:%llu, cur-cal %llu\n", (long long unsigned)current / 4,
+ (long long unsigned)pLmdControl->pMbsFileHeader->iTableOffset,
+ (long long unsigned)(current / 4 - pLmdControl->pMbsFileHeader->iTableOffset));
+ return (LMD__FAILURE);
+ }
+ if((uint32_t) iReturn != (pLmdControl->iElements+1)*pLmdControl->iOffsetSize){
+ printf("Table write error \n");
+ return(LMD__FAILURE);
+ }
+ return(LMD__SUCCESS);
+}
+//===============================================================
+uint32_t fLmdOffsetSet(sLmdControl *pLmdControl, uint32_t lwords)
+{
+ if(pLmdControl->iElements >= pLmdControl->iOffsetEntries)fLmdOffsetResize(pLmdControl,0);
+ if(pLmdControl->pOffset8){
+ *(pLmdControl->pOffset8+pLmdControl->iElements)=
+ *(pLmdControl->pOffset8+pLmdControl->iElements-1)+(lmdoff_t)lwords;
+ }
+ if(pLmdControl->pOffset4){
+ *(pLmdControl->pOffset4+pLmdControl->iElements)=
+ *(pLmdControl->pOffset4+pLmdControl->iElements-1)+lwords;
+ }
+ return(LMD__SUCCESS);
+}
+//===============================================================
+lmdoff_t fLmdOffsetGet(sLmdControl *pLmdControl, uint32_t index)
+{
+ if (pLmdControl->pOffset8)
+ return (*(pLmdControl->pOffset8 + index));
+ if (pLmdControl->pOffset4)
+ return ((lmdoff_t) * (pLmdControl->pOffset4 + index));
+ return 0;
+}
+//===============================================================
+void fLmdOffsetResize(sLmdControl *pLmdControl, uint32_t firstValue){
+ lmdoff_t *newOffset;
+ uint32_t oldEntries,newEntries;
+
+ oldEntries=pLmdControl->iOffsetEntries;
+ newEntries=oldEntries+OFFSET__ENTRIES;
+ newOffset = (lmdoff_t *)malloc(newEntries*pLmdControl->iOffsetSize);
+ memset(newOffset,0,newEntries*pLmdControl->iOffsetSize);
+ if(oldEntries > 0){ //table was expanded
+ //printf("Resize table %d to %d entries\n",oldEntries,newEntries);
+ if(pLmdControl->pOffset8){
+ memcpy(newOffset,pLmdControl->pOffset8,oldEntries*pLmdControl->iOffsetSize);
+ free(pLmdControl->pOffset8);
+ pLmdControl->pOffset8 = newOffset;
+ }
+ if(pLmdControl->pOffset4){
+ memcpy(newOffset,pLmdControl->pOffset4,oldEntries*pLmdControl->iOffsetSize);
+ free(pLmdControl->pOffset4);
+ pLmdControl->pOffset4 = (uint32_t *)newOffset;
+ }
+ }
+ else { // table was new
+ //printf("Create table %d entries, first offset %d\n",newEntries,firstValue);
+ if(pLmdControl->iOffsetSize==8){
+ pLmdControl->pOffset8 = newOffset;
+ *pLmdControl->pOffset8 = (lmdoff_t)firstValue;
+ }
+ if(pLmdControl->iOffsetSize==4){
+ pLmdControl->pOffset4 = (uint32_t *)newOffset;
+ *pLmdControl->pOffset4 = firstValue;
+ }
+ }
+ pLmdControl->iOffsetEntries = newEntries;
+}
+//===============================================================
+void fLmdPrintBufferHeader(uint32_t iVerbose, sMbsBufferHeader *pMbsBufferHeader)
+{
+ if (iVerbose) {
+ if (pMbsBufferHeader) {
+ printf("BfHd: # %d, DataWords:%d Type:%08x Elements:%d sec:%d.%d MaxWords:%d\n", pMbsBufferHeader->iBuffer,
+ pMbsBufferHeader->iUsedWords, pMbsBufferHeader->iType, pMbsBufferHeader->iElements,
+ pMbsBufferHeader->iTimeSpecSec, pMbsBufferHeader->iTimeSpecNanoSec / 1000, pMbsBufferHeader->iMaxWords);
+ }
+ }
+}
+//===============================================================
+void fLmdPrintFileHeader(uint32_t iVerbose, sMbsFileHeader *pMbsFileHeader)
+{
+ if (iVerbose) {
+ if (pMbsFileHeader) {
+ printf("FiHd: DataWords:%d Type:%d.%d Elements:%d sec:%d.%d MaxWords:%d Index: %llx[%d]\n",
+ pMbsFileHeader->iUsedWords, pMbsFileHeader->iType & 0xffff, pMbsFileHeader->iType >> 16,
+ pMbsFileHeader->iElements, pMbsFileHeader->iTimeSpecSec, pMbsFileHeader->iTimeSpecNanoSec / 1000,
+ pMbsFileHeader->iMaxWords, (long long unsigned) pMbsFileHeader->iTableOffset, pMbsFileHeader->iOffsetSize);
+ }
+ }
+}
+//===============================================================
+void fLmdPrintHeader(uint32_t iVerbose, sMbsHeader *pMbsHeader)
+{
+ if (iVerbose) {
+ if (pMbsHeader) {
+ printf("ElHd: words:%d type:%08x\n", pMbsHeader->iWords, pMbsHeader->iType);
+ }
+ }
+}
+//===============================================================
+void fLmdPrintEvent(uint32_t iVerbose, sMbsEventHeader *pMbsEventHeader)
+{
+ if (iVerbose) {
+ if (pMbsEventHeader) {
+ printf("EvHd: words:%6d type:%08x trigger:%2d #:%4d\n", pMbsEventHeader->iWords, pMbsEventHeader->iType,
+ pMbsEventHeader->iTrigger >> 16, pMbsEventHeader->iEventNumber);
+ }
+ }
+}
+//===============================================================
+void fLmdPrintControl(uint32_t iVerbose, sLmdControl *pLmdControl)
+{
+ if (iVerbose) {
+ printf("Ctrl: file:%s words:%d left:%d bytes read:%llu elements:%d\n", pLmdControl->cFile,
+ pLmdControl->iBufferWords, pLmdControl->iLeftWords, (long long unsigned) pLmdControl->iBytes, pLmdControl->iElements);
+ fLmdPrintFileHeader(iVerbose, pLmdControl->pMbsFileHeader);
+ fLmdPrintEvent(iVerbose, (sMbsEventHeader *)pLmdControl->pMbsHeader);
+ }
+}
+//===============================================================
+void fLmdSwap4(uint32_t *array, uint32_t items)
+{
+ uint32_t i, *pp;
+ pp = array;
+ for (i = 0; i < items; i++) {
+ *pp = (*pp >> 24) + ((*pp >> 8) & 0x0000ff00) + ((*pp << 8) & 0x00ff0000) + (*pp << 24);
+ pp++;
+ }
+}
+//===============================================================
+void fLmdSwap8(uint64_t *array, uint32_t items)
+{
+ uint64_t *pp;
+ uint32_t i;
+ pp = array;
+ for (i = 0; i < items; i++) {
+ *pp = (*pp << 32) + (*pp >> 32);
+ pp++;
+ }
+}
diff --git a/plugins/olmd/mbsapi/fLmd.h b/plugins/olmd/mbsapi/fLmd.h
new file mode 100644
index 00000000..9dde8c0c
--- /dev/null
+++ b/plugins/olmd/mbsapi/fLmd.h
@@ -0,0 +1,101 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef MbsLmdStruct_H
+#define MbsLmdStruct_H
+
+#include
+
+#include "sMbs.h"
+
+#ifndef FILEONLY
+#include "f_stccomm.h"
+#endif
+
+#define LMD__SUCCESS 0
+#define LMD__FAILURE 1
+#define LMD__CLOSE_ERR 3
+#define GETLMD__NOFILE 2
+#define GETLMD__NOLMDFILE 4
+#define GETLMD__EOFILE 5
+#define GETLMD__NOMORE 6
+#define GETLMD__NOBUFFER 7
+#define GETLMD__TOOBIG 8
+#define GETLMD__OUTOF_RANGE 9
+#define GETLMD__SIZE_ERROR 10
+#define LMD__TIMEOUT 50
+#define PUTLMD__FILE_EXIST 101
+#define PUTLMD__TOOBIG 102
+#define PUTLMD__OPEN_ERR 103
+#define PUTLMD__EXCEED 104
+#define PORT__TRANS 6000
+#define PORT__STREAM 6002
+
+typedef struct
+{
+ FILE *fFile; /* file descripter or server No. */
+ int16_t *pBuffer; /* pointer to internal buffer */
+ uint32_t iBufferWords; /* internal buffer size */
+ uint32_t iLeftWords; /* left words in buffer */
+ uint32_t iInternHeader; /* has intern allocated header buffer */
+ uint32_t iInternBuffer; /* has intern allocated buffer */
+ uint32_t iElements; /* events since open */
+ uint64_t iBytes; /* bytes since open */
+ char cFile[512]; /* channel name */
+ uint32_t iSwap;
+ uint32_t iVerbose;
+ char *cHeader; /* header data buffer */
+ uint32_t *pOffset4; /* offset table */
+ lmdoff_t *pOffset8; /* long offset table */
+ lmdoff_t oTableOffset; /* greater zero when Long offset in file */
+ uint32_t iOffsetSize; /* Offset size, 4 or 8 [bytes] */
+ uint32_t iOffsetEntries;/* offset table length */
+ sMbsFileHeader *pMbsFileHeader;
+ sMbsHeader *pMbsHeader;
+ struct s_tcpcomm *pTCP;
+ uint32_t iTCP;
+ uint32_t iPort;
+ uint32_t iTcpTimeout;
+ uint32_t iTCPowner;
+} sLmdControl;
+
+sLmdControl * fLmdAllocateControl(void);
+uint32_t fLmdPutOpen(sLmdControl*,char*,sMbsFileHeader*,uint32_t,uint32_t,uint32_t,uint32_t);
+uint32_t fLmdPutElement(sLmdControl*,sMbsHeader*);
+uint32_t fLmdPutBuffer(sLmdControl*, sMbsHeader*,uint32_t);
+uint32_t fLmdPutClose(sLmdControl*);
+#ifndef FILEONLY
+uint32_t fLmdInitMbs(sLmdControl*,char*,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t);
+uint32_t fLmdGetMbsBuffer(sLmdControl*,sMbsBufferHeader*,uint32_t,uint32_t*,uint32_t*);
+uint32_t fLmdGetMbsEvent(sLmdControl*,sMbsHeader**);
+uint32_t fLmdCloseMbs(sLmdControl*);
+#endif
+uint32_t fLmdGetOpen(sLmdControl*,char*,sMbsFileHeader*,uint32_t,uint32_t);
+uint32_t fLmdGetBuffer(sLmdControl*,sMbsHeader*,uint32_t,uint32_t*,uint32_t*);
+int32_t fLmdReadBuffer(sLmdControl*,char*,uint32_t);
+uint32_t fLmdGetElement(sLmdControl*,uint32_t,sMbsHeader**);
+uint32_t fLmdGetClose(sLmdControl*);
+void fLmdPrintBufferHeader(uint32_t,sMbsBufferHeader*);
+void fLmdPrintFileHeader(uint32_t,sMbsFileHeader*);
+void fLmdPrintHeader(uint32_t,sMbsHeader*);
+void fLmdPrintEvent(uint32_t,sMbsEventHeader*);
+void fLmdPrintControl(uint32_t,sLmdControl*);
+void fLmdVerbose(sLmdControl*,uint32_t);
+void fLmdSwap4(uint32_t*,uint32_t);
+void fLmdSwap8(uint64_t*,uint32_t);
+void fLmdSetWrittenEndian(sLmdControl *,uint32_t);
+uint32_t fLmdGetWrittenEndian(sLmdControl *);
+uint32_t fLmdGetSwap(sLmdControl *);
+uint64_t fLmdGetBytesWritten(sLmdControl *);
+
+#endif
diff --git a/plugins/olmd/mbsapi/f_evcli.c b/plugins/olmd/mbsapi/f_evcli.c
new file mode 100644
index 00000000..7ba847c5
--- /dev/null
+++ b/plugins/olmd/mbsapi/f_evcli.c
@@ -0,0 +1,1847 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_evcli */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evcli_xxx() */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : API for GOOSY - Event - Server or */
+/* SBS - Event - Server . */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*2+Description***+***********+****************************************/
+/* */
+/*+ FUNCTION : Client for test purpose GOOSY - PAW - Server and */
+/* SBS - Event - Server. */
+/* (for detailed information see PC_CLIPAW) */
+/* */
+/*2+Implementation**********+******************************************/
+/* */
+/*+ PROCEDURES : see f_evcli_proc */
+/* */
+/*+ File name : f_evcli.c */
+/* */
+/*+ Version : 1.01 */
+/*+ Author : R.S. Mayer, H.Essel */
+/*+ Last Update : 28-feb-2000 */
+/* */
+/*2+Internals***************+******************************************/
+/* */
+/*+ Utility : */
+/*+ File name : m_evcli.c */
+/*+ Home direct.: LEA$SRC */
+/*+ Created : 28-feb-2000 */
+/* */
+/*2+Updates*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/*1- C Procedure *************+*********************************************/
+
+/* ++++++++++++++ !!!! IMPLEMENTATION !!!! +++++++++++++++++++++++++++++++ */
+#include "typedefs.h"
+
+
+#define F__SWAP(ps,l,pd) f_swaplw((int *)ps,(int)l,(int *)pd)
+#ifdef VMS /* ++++++++++++++ VMS ++++++++++++++++++++++++++++ */
+#define UNIXENV 0 /* switch UNIX or VMS */
+
+/* standard headers ----- */
+#include
+#include
+#include
+#include
+#include
+#include
+#endif /* VMS */
+
+#ifdef Lynx /* ++++++++++++++++ Lynx +++++++++++++++++++++++++++ */
+#define UNIXENV 1 /* switch UNIX or VMS */
+#endif /* Lynx */
+
+#ifdef HPUX /* +++++++++++++++++ HPUX ++++++++++++++++++++++++++++ */
+#define UNIXENV 1 /* switch UNIX or VMS */
+#define _HPUX_SOURCE /* this stuff is needed before */
+#define _POSIX_SOURCE /* any include is done */
+#endif /* HPUX */
+
+#ifdef Linux /* +++++++++++++++++ Linux ++++++++++++++++++++++++ */
+#define UNIXENV 1 /* switch UNIX or VMS */
+#endif
+
+#ifdef Solaris /* +++++++++++++++++ Solaris ++++++++++++++++++++++++ */
+#define UNIXENV 1 /* switch UNIX or VMS */
+#endif
+
+#ifdef Darwin /* +++++++++++++++++ Max OS X ++++++++++++++++++++++++ */
+#define UNIXENV 1 /* switch UNIX or VMS */
+#endif
+
+
+#ifdef GSI__WINNT /* +++++++++++++++++ Windows NT ++++++++++++++++++++++++ */
+#define UNIXENV 1 /* switch UNIX or VMS */
+#define _ALL_SOURCE /* for types.h typedef u_char... */
+#define _POSIX_SOURCE /* any include is done */
+#endif
+
+
+#ifdef _AIX /* +++++++++++++++++ AIX ++++++++++++++++++++++++++ */
+#define UNIXENV 1 /* switch UNIX or VMS */
+#define _ALL_SOURCE /* for types.h typedef u_char... */
+#define _POSIX_SOURCE /* any include is done */
+#define IN_AIX 1
+#else
+#define IN_AIX 0
+#endif /* !_AIX */
+
+/* ++++++++++++++++ include UNIX standard headers +++++++++++++++++++++++++ */
+#if UNIXENV == 1
+#include
+#ifdef GSI__WINNT
+#include
+#else
+#include /* ? */
+#include
+#endif
+#include
+#include
+#include
+#include
+#include
+#endif /* UNIXENV */
+
+/* ++++++++++++++++++++++ goopaw include files ++++++++++++++++++++++++++ */
+#include "gps_sc_def.h" /* must be first */
+#include "s_filter.h"
+#include "clnt_buf_def.h"
+#include "s_clntbuf.h"
+
+// DABC
+#include "fLmd.h"
+// --DABC
+
+#include "f_evcli.h"
+#include "f_swaplw.h"
+
+#include "s_flt_descr.h"
+#include "s_clnt_filter.h"
+#include "s_opc1.h"
+#include "s_pat.h"
+
+void f_clnup(ADDRS [], int *);
+void f_clnup_save(ADDRS [], int *);
+int f_fltdscr(struct s_clnt_filter *);
+int f_read_server(s_evt_channel *, int *, int, int);
+int f_send_ackn(int, int);
+
+int swapw(unsigned short *, unsigned short *, unsigned int);
+int swapl(unsigned int *, unsigned int *, unsigned int);
+
+static int i_debug = 0; /* message level (0-3) */
+
+#define EVT_MAX 1000
+#define TCP__TIMEOUT 3000 /* TCP timeout reading buffer */
+#define FLUSH__TIME 3 /* flush time interval for MBS event server */
+#define STDOUT_BUFIO_ 1
+
+// JAM1-6-2021- test if this helps the streamserver problems
+// #define DISABLE_POLLING_TIMEOUT 1
+
+
+static int unsigned lf_swap = 0; /* save swap on RX */
+static int unsigned l_endian_serv; /* save endian server */
+int i_channel; /* TCP/IP channel */
+int unsigned l_clnt_sts; /* status for ackn. */
+int l_status;
+static char c_modnam[] = "f_evcli";
+short i_sign = 1;
+int l_timeout;
+static struct s_tcpcomm s_tcpcomm_ec = {0,0,0};
+
+static struct {
+ int l_ack_buf; /* read client buff received */
+ int l_ack_bytes; /* read client bytes received */
+ int unsigned l_clnt_sts; /* client sts 1:o.k. 8:lst buf*/
+} s_ackn;
+
+/* ++ vectors of pointer and devices for cleanup */
+ADDRS v_mem_clnup[8];
+
+/***************************************************************************/
+int f_evcli_con(s_evt_channel *ps_chan, char *pc_node, int l_aport, int l_aevents, int l_asample)
+/***************************************************************************/
+{
+ short i_h, i_m, i_s;
+ char c_node[32], c_retmsg[256];
+ int l_port;
+ int l_len_lw2, l_sts, l_retval; /* len for 2nd swap */
+ struct s_opc1 *p_opc1;
+ struct s_clnt_filter *p_clnt_filter;
+ struct s_clntbuf *p_clntbuf;
+
+ v_mem_clnup[0] = 0;
+
+ /* +++ allocate filter structure +++ */
+ p_clnt_filter = (struct s_clnt_filter *) malloc( sizeof(struct s_clnt_filter) );
+ if (p_clnt_filter == NULL)
+ {
+ printf("E-%s: calloc(,...s_clnt_filter) failed!\n", c_modnam);
+ printf("F-%s: aborting program execution!\n",c_modnam);
+ f_clnup(v_mem_clnup, NULL);
+ return(-1);
+ }
+ ps_chan->pc_evt_buf=(char *) p_clnt_filter;
+ /* save value for clnup */
+ f_clnup_save(v_mem_clnup, (int *) p_clnt_filter);
+ memset( (void *) p_clnt_filter, 0, sizeof(struct s_clnt_filter) );
+
+ p_clnt_filter->l_testbit = GPS__ENV_TESTBIT; /* set testbit */
+ p_clnt_filter->l_endian = GPS__ENV_ENDIAN; /* set endian */
+ p_clnt_filter->l_numb_of_evt = l_aevents;
+ p_opc1 = (struct s_opc1 *) &p_clnt_filter->filter[0].l_opcode;
+ p_opc1->b1_evtsev = 1;
+ p_opc1->b1_selflt = 1;
+ p_opc1->b1_selwrt = 1;
+ p_opc1->b3_opc = 0;
+ p_opc1->b1_lnkf1 = 0;
+ p_opc1->b1_lnkf2 = 0;
+ p_opc1->h_fltspec = 0;
+ p_opc1->h_next_fltblk = 1;
+ p_opc1->h_flt_len = 1;
+
+ l_status = f_fltdscr(p_clnt_filter);
+ /*
+ printf("evtsev: %d selflt: %d selwrt: %d opc: %d lnk1: %d lnk2: %d fltspec: %d next: %d len: %d\n"
+,p_opc1->b1_evtsev
+,p_opc1->b1_selflt
+,p_opc1->b1_selwrt
+,p_opc1->b3_opc
+,p_opc1->b1_lnkf1
+,p_opc1->b1_lnkf2
+,p_opc1->h_fltspec
+,p_opc1->h_next_fltblk
+,p_opc1->h_flt_len);
+ */
+ if ((l_status & 1) == 0)
+ {
+ printf("E-%s: Severe Error in f_fltdscr! Status:%d\n",
+ c_modnam,
+ l_status);
+ f_clnup(v_mem_clnup, NULL);
+ return(-1);
+ }
+ p_clnt_filter->l_sample_rate = l_asample;
+ p_clnt_filter->l_flush_rate = FLUSH__TIME;
+
+ l_timeout = TCP__TIMEOUT ;
+ strncpy(c_node,pc_node, sizeof(c_node));
+ l_port = l_aport;
+
+ l_status = (int) f_stc_connectserver(c_node,
+ l_port,
+ &i_channel,
+ &s_tcpcomm_ec);
+ if ((l_status & 1) != STC__SUCCESS)
+ {
+ printf("E-%s: Error connecting node:%s, port:%d. Msg:\n",
+ c_modnam,
+ c_node,
+ l_port);
+ f_stc_disperror((int) l_status,c_retmsg, 0);
+ f_stc_close(&s_tcpcomm_ec);
+ return(l_status);
+ }
+
+ ps_chan->l_channel_no=i_channel;
+ /* + buffer flushing time + */
+ i_h = p_clnt_filter->l_flush_rate / 3600; /* hours */
+ i_s = p_clnt_filter->l_flush_rate - i_h * 3600;
+ i_m = i_s / 60; /* minutes */
+ i_s = i_s - i_m * 60; /* seconds */
+
+ /* +++++++++++++++++++++++++++++++++ */
+ /* +++ send these data to server +++ */
+ /* +++++++++++++++++++++++++++++++++ */
+ /* len to transm [bytes] = 3 LW + filter + 1LW */
+ l_status = (int) f_stc_write( (char *) p_clnt_filter,
+ GPS__CLNT_SNDFLT,
+ i_channel);
+ if (l_status != STC__SUCCESS)
+ {
+ printf("E-%s: Error in f_write_tcp(p_flt,...)! Status:%d. Msg:\n",
+ c_modnam,
+ l_status);
+ f_stc_disperror((int) l_status,c_retmsg, 0);
+ f_stc_close(&s_tcpcomm_ec);
+ return(l_status);
+ }
+ /* + + + + + + + + + + + + + + */
+ /* +++ alloc input buffer +++ */
+ /* + + + + + + + + + + + + + + */
+ p_clntbuf = (struct s_clntbuf *) malloc(sizeof(struct s_clntbuf));
+ if (p_clntbuf == NULL)
+ {
+ printf("E-%s: malloc(p_clntbuf) failed!\n", c_modnam);
+ printf("F-%s: aborting program execution!\n",c_modnam);
+ f_stc_close(&s_tcpcomm_ec);
+ return(-1);
+ }
+ /* save value for clnup */
+ f_clnup_save(v_mem_clnup, (int *) p_clntbuf);
+
+ ps_chan->pc_io_buf = (char *) p_clntbuf;
+ ps_chan->l_io_buf_size = GPS__OUTBUFSIZ + CLNT__OUTBUFHEAD;
+ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+ /* ++++ first read on server, get machine type & swap ++++ */
+ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+ memset(p_clntbuf,0, sizeof(struct s_clntbuf)); /* clear memory */
+ l_status = f_read_server(ps_chan,
+ &l_retval,
+ l_timeout,
+ i_channel);
+ if (l_status != TRUE)
+ {
+ printf("E-%s: Error reading 1st buffer: f_read_server()!\n", c_modnam);
+ f_stc_close(&s_tcpcomm_ec);
+ return(l_status);
+ }
+
+ /* ++++++++++++++++++++++++++++++++++++ */
+ /* +++ check if a LW swap is needed +++ */
+ /* ++++++++++++++++++++++++++++++++++++ */
+ lf_swap = (p_clntbuf->l_testbit == GPS__ENV_TESTBIT) ? 0 : 1;
+ l_endian_serv = p_clntbuf->l_endian;
+
+ if (lf_swap)
+ /* + + + + + + + + + + + + + + + + + */
+ /* +++ swap after every receive +++ */
+ /* + + + + + + + + + + + + + + + + + */
+ {
+ l_sts = F__SWAP(&p_clntbuf->l_testbit,CLNT__BUFH_LW,0);
+
+ l_len_lw2 = CLNT__REST_LW + p_clntbuf->l_dlen/4; /* !!! */
+ l_sts = F__SWAP(&p_clntbuf->l_inbuf_read_cnt, l_len_lw2, 0);
+
+ (void) l_sts; // fix compiler warning
+
+ if (p_clntbuf->l_testbit != GPS__ENV_TESTBIT) /* */
+ {
+ printf("F-%s: Error swapping first buffer from client\n",
+ c_modnam);
+ f_stc_close(&s_tcpcomm_ec);
+ return(-1);
+ }
+ }
+
+ /* + + + + + + + + + + + + + + + + + + + + + + + + + */
+ /* +++ first buffer should be a message buffer! +++ */
+ /* + + + + + + + + + + + + + + + + + + + + + + + + + */
+ if (p_clntbuf->l_buffertype & 16)
+ {
+ }
+
+ if (p_clntbuf->l_buffertype & 2) { /* buffer contains message */
+ /*
+ switch (p_clntbuf->l_msgtyp & 15)
+ {
+ case 1:
+ case 2: printf("MSG-type:W: %s\n", p_clntbuf->c_message); break;
+ case 4: printf("MSG-type:E: %s\n", p_clntbuf->c_message); break;
+ case 8: printf("MSG-type:F: %s\n", p_clntbuf->c_message); break;
+ default: printf("Unknown MSG-type:%d:\n%s\n",p_clntbuf->l_msgtyp,p_clntbuf->c_message);
+ }
+ */
+ }
+
+ return(STC__SUCCESS);
+} /* f_evcli_con */
+
+
+/***************************************************************************/
+int f_evcli_buf(s_evt_channel *ps_chan)
+/***************************************************************************/
+{
+ // s_ve10_1 *ps_ve10_1;
+ char *ps_buf;
+ int l_len_lw2, l_sts, l_retval; /* len for 2nd swap */
+ struct s_clntbuf *p_clntbuf;
+ unsigned int *pl_inbuf;
+
+ /* ++++++++++++++++++++++++++++++ */
+ /* +++ send acknowledge buffer +++ */
+ /* ++++++++++++++++++++++++++++++ */
+
+ l_status = f_send_ackn(1, ps_chan->l_channel_no);
+ if (l_status != TRUE)
+ {
+ printf("E-%s: Error sending acknowledge: f_send_ackn()!\n", c_modnam);
+ f_stc_close(&s_tcpcomm_ec);
+ return(l_status);
+ }
+ /* +++++++++++++++++++++++++ */
+ /* +++ read input buffer +++ */
+ /* +++++++++++++++++++++++++ */
+ p_clntbuf = (struct s_clntbuf *) ps_chan->pc_io_buf;
+ ps_buf = ps_chan->pc_io_buf; /* save for comparison */
+ memset(p_clntbuf,0, ps_chan->l_io_buf_size);
+ l_status = f_read_server(ps_chan,
+ &l_retval,
+ l_timeout,
+ ps_chan->l_channel_no);
+
+ /* in case pc_io_buf has been reallocated */
+ if(ps_buf != ps_chan->pc_io_buf)
+ {
+ f_clnup(v_mem_clnup, NULL); /* free all old buffers */
+ p_clntbuf = (struct s_clntbuf *) ps_chan->pc_io_buf;
+ f_clnup_save(v_mem_clnup, (int *) p_clntbuf);
+ }
+ if (l_status != TRUE)
+ {
+ printf("E-%s: Error reading buffer: f_read_server()!\n", c_modnam);
+ f_stc_close(&s_tcpcomm_ec);
+ return(l_status);
+ }
+ l_clnt_sts = 0; /* reset */
+
+ /* +++++++++++++++++++++++++++++++++ */
+ /* +++ swap every buffer in loop +++ */
+ /* +++++++++++++++++++++++++++++++++ */
+ if (lf_swap)
+ {
+ l_sts = F__SWAP(&p_clntbuf->l_testbit,CLNT__BUFH_LW, 0);
+ l_len_lw2 = CLNT__REST_LW + p_clntbuf->l_dlen/4; /* !!! */
+
+ /* 4 byte swap */
+ pl_inbuf = &p_clntbuf->l_inbuf_read_cnt;
+ l_sts = F__SWAP(pl_inbuf, l_len_lw2, 0);
+ }
+ /* printf("Buffer %8d bytes, dlen %8d events %6d\n",l_retval,p_clntbuf->l_dlen,p_clntbuf->l_events);
+ ps_ve10_1=(s_ve10_1 *)&p_clntbuf->c_buffer[0];
+ for(ii=0;iil_events;ii++)
+ {printf("Event %2d, t/s %3d %2d, len %d\n",ii+1,ps_ve10_1->i_type,ps_ve10_1->i_subtype,ps_ve10_1->l_dlen);
+ ps_ve10_1 = (s_ve10_1 *) ((short *)ps_ve10_1 + ps_ve10_1->l_dlen + 4); }
+ */
+ /* ++++++++++++++++++++++++ */
+ /* +++ message handling +++ */
+ /* ++++++++++++++++++++++++ */
+ l_sts=STC__SUCCESS;
+ if (p_clntbuf->l_buffertype & 2)
+ { /* buffer contains message */
+ switch (p_clntbuf->l_msgtyp & 15)
+ {
+ case 1:
+ case 2:
+ if((strstr(p_clntbuf->c_message, "no event data") == NULL) &&
+ (strstr(p_clntbuf->c_message, "flushed") == NULL))
+ printf("MSG-type:W: %s\n", p_clntbuf->c_message);
+ break;
+ case 4:
+ printf("MSG-type:E: %s\n", p_clntbuf->c_message);
+ break;
+ case 8:
+ printf("MSG-type:F: %s\n", p_clntbuf->c_message);
+ break;
+ default:
+ printf("Unknown MSG-type:%d:\n%s\n",p_clntbuf->l_msgtyp,p_clntbuf->c_message);
+ }
+ l_sts = STC__TIMEOUT; /* buffer without events */
+ }
+ else
+ {
+ if(p_clntbuf->l_events == 0)
+ {
+ l_sts = STC__TIMEOUT;
+ }
+ }
+ ps_chan->pc_evt_buf = (char *)&p_clntbuf->c_buffer[0];
+ ps_chan->l_evt_buf_posi = 1; /* number of events */
+ // ps_ve10_1 = (s_ve10_1 *) ps_chan->pc_evt_buf;
+ return l_sts;
+} /* end f_evcli_buf */
+
+/***************************************************************************/
+int f_evcli_evt(s_evt_channel *ps_chan)
+/***************************************************************************/
+{
+ int *ps_int;
+ s_ve10_1 *ps_ve10_1;
+ struct s_clntbuf *p_clntbuf;
+
+ p_clntbuf = (struct s_clntbuf *) ps_chan->pc_io_buf;
+ if(ps_chan->l_evt_buf_posi < p_clntbuf->l_events)
+ {
+ ps_chan->l_evt_buf_posi++;
+ ps_ve10_1 = (s_ve10_1 *) ps_chan->pc_evt_buf;
+ ps_int = (int *) ps_chan->pc_evt_buf;
+ ps_int += ps_ve10_1->l_dlen/2 + 2;
+ ps_chan->pc_evt_buf = (char *) ps_int;
+ return(STC__SUCCESS);
+ }
+ else return(-1);
+}
+/***************************************************************************/
+int f_evcli_close(s_evt_channel *ps_chan)
+/***************************************************************************/
+{
+ /* ++++++++++++++++++++++++++++++ */
+ /* +++ send acknowledge buffer +++ */
+ /* ++++++++++++++++++++++++++++++ */
+ l_status = f_send_ackn(8, ps_chan->l_channel_no);
+ if (l_status != TRUE)
+ {
+ printf("E-%s: Error sending acknowledge: f_send_ackn()!\n", c_modnam);
+ return(l_status);
+ }
+
+ f_clnup(v_mem_clnup, NULL);
+ f_stc_discclient(ps_chan->l_channel_no);
+ f_stc_close(&s_tcpcomm_ec);
+ return(STC__SUCCESS);
+}
+
+
+/*2+F_FLTDSCR***+******************************************************/
+/* */
+/*+ Module : F_FLTDSCR */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : sts = f_fltdscr(p_clnt_filter) */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Read and check the event filter and construct the */
+/* filter descriptor. */
+/* */
+/*+ ARGUMENTS : p_clnt_filter: Pointer to structure s_clnt_filter */
+/* */
+/*+ FUNCTION : Read and check the event filter and construct the */
+/* filter descriptor. Output via "printf". */
+/* See also I$PS_FLTDSC_PRTCL */
+/* */
+/*+ Return type : int (32 bit) */
+/*+ Status codes: bit 0: success */
+/* bit 1: warning */
+/*+ Initialize : - */
+/*+ Include name: - */
+/* */
+/*3+Implementation************+****************************************/
+/* */
+/*+ File name : PC_PROC.C */
+/*+ Version : 1.01 */
+/*+ Author : R.S. Mayer */
+/*+ Last Update : 14-JUN-1993 */
+/*+ Object libr.: GOOSHRLIB */
+/*3+Updates*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*3+Description***+***********+****************************************/
+/*1- C Procedure ***********+******************************************/
+int f_fltdscr(struct s_clnt_filter * p_clnt_filter) /* read filter, check and */
+{
+ static char flt_modnam[] = "f_fltdscr";
+ struct s_filter *p_filter;
+ struct s_opc1 *p_opc1;
+ struct s_flt_descr *p_flt_descr;
+
+ short i_fltdescnt = 0;
+ // short i_fltcnt = 0;
+ short i_fltblkcnt = 0;
+ short i, i_flt_len = 0,
+ i_fltblkbeg, i_fltblkend, j;
+ short if_newfltblk = 1;
+ short i_next_fltblk = 0; // SL 16.11.2009 add initialization to 0
+ // short i_descr; /* test */
+ int l_evtdescr, *pl_evtdescr, *pl_sev1descr, *pl_sev2descr;
+ short i_lasevtflt, i_1stsevflt;
+
+ int unsigned l_retsts = 0;
+
+ /* +++ action +++ */
+ if (i_debug == 2)
+ printf("--->D-%s: addr_filter p:%p\n", flt_modnam, p_clnt_filter);
+
+ /* init pointer */
+ p_flt_descr = (struct s_flt_descr *) &p_clnt_filter->flt_descr[0];
+
+ /* +++ loop over all filter block descriptors +++ */
+ for (i = 0; i < GPS__MAXFLT; i++)
+ {
+ p_filter = (struct s_filter *) &p_clnt_filter->filter[i];
+ p_opc1 = (struct s_opc1 *) &p_filter->l_opcode;
+
+ if (i_debug == 2)
+ printf("D-%s: i:%d opc:%x flt_len:%d\n",
+ flt_modnam,
+ i,
+ p_filter->l_opcode,
+ p_opc1->h_flt_len);
+
+ if (i == i_next_fltblk)
+ if_newfltblk = 1;
+
+ if (p_opc1->h_flt_len == 0)
+ {
+ // i_fltcnt = i;
+ p_opc1->h_next_fltblk = 0; /* no next descriptor */
+ p_flt_descr->h_nextdescr = 0; /* no next descriptor */
+ break; /* no more filter */
+ } /* if (p_opc1->h_next_fltblk == 0) */
+
+/* if (p_opc1->b3_opc == 0) {
+ * printf("I-%s: b3_opc == 0. Take all events!\n",
+ * flt_modnam);
+ * }
+ */
+
+ if (if_newfltblk)
+ {
+ if_newfltblk = 0;
+ i_fltblkcnt++;
+ i_flt_len = p_opc1->h_flt_len;
+ i_next_fltblk = i + i_flt_len;
+ i_fltblkbeg = i;
+ i_fltblkend = i_next_fltblk - 1;
+
+ if (p_opc1->b1_selwrt == 1) {
+ /* write block */
+ p_flt_descr = (struct s_flt_descr *) &p_clnt_filter->flt_descr[0];
+ // i_descr = 0; /* test */
+
+ if (p_flt_descr->hf_wrtdescr == 1 &&
+ p_clnt_filter->flt_descr[0].i_descriptors <= 0)
+ {
+ printf("W-%s: >1 write blocks, previous one(s) ignored!\n",
+ flt_modnam);
+ l_retsts = l_retsts | 2;
+ }
+
+ p_flt_descr->hf_wrtdescr = 1;
+ p_flt_descr->hf_fltdescr = 0;
+ p_flt_descr->h_fltblkbeg = i_fltblkbeg;
+ p_flt_descr->h_fltblkend = i_fltblkend;
+ p_flt_descr->h_nextdescr = 1;
+
+ /* save write block values */
+ p_clnt_filter->if_wrtevt = (p_opc1->b1_evtsev == 1) ? 1 : 0;
+ p_clnt_filter->if_wrtsev = (p_opc1->b1_evtsev != 1) ? 1 : 0;
+ } /* if (p_opc1->b1_selwrt == 1) */
+
+ if (p_opc1->b1_selflt == 1) {
+ /* filter block */
+ if (i_fltdescnt == 0)
+ i_fltdescnt++;
+ // i_descr = i_fltdescnt; /* test */
+ p_flt_descr = (struct s_flt_descr *) &p_clnt_filter->flt_descr[i_fltdescnt];
+ p_flt_descr->hf_wrtdescr = 0;
+ p_flt_descr->hf_fltdescr = 1;
+ p_flt_descr->h_fltblkbeg = i_fltblkbeg;
+ p_flt_descr->h_fltblkend = i_fltblkend;
+ p_flt_descr->h_nextdescr = ++i_fltdescnt;
+ /* save write block values */
+ if (p_opc1->b1_evtsev == 1)
+ p_clnt_filter->if_fltevt = 1;
+ else
+ p_clnt_filter->if_fltsev = 1;
+ } /* if (p_opc1->b1_selflt == 1) */
+
+ } /* if (if_newfltblk) */
+
+ /* identical values for the whole flt blk */
+ p_opc1->h_flt_len = i_flt_len;
+ p_opc1->h_next_fltblk = i_next_fltblk;
+
+ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+ /* ++++ build pattern and offset values from h_fltspec ++++ */
+ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+
+ /* ++++ check if Filter specification is valid ++++ */
+ if ((p_opc1->h_fltspec > 15) && (p_opc1->b1_evtsev == 1))
+ {
+ printf("E-%s: Filter specification %d invalid for events\n",
+ flt_modnam,
+ p_opc1->h_fltspec);
+ return(FALSE); /* abort with error */
+ }
+ if ((p_opc1->h_fltspec < 2) && (p_opc1->b1_evtsev != 1))
+ {
+ printf("E-%s: Filter specification %d invalid for subevents\n",
+ flt_modnam,
+ p_opc1->h_fltspec);
+ return(FALSE); /* abort with error */
+ }
+
+ switch (p_opc1->h_fltspec)
+ {
+ case 0: /* ++++ take all ++++ */
+ if (p_opc1->b3_opc != 0) {
+ printf("W-%s: Take all. Set opcode to 0, next time\n",
+ flt_modnam);
+ p_opc1->b3_opc = 0;
+ l_retsts = l_retsts | 2;
+ }
+ break;
+
+ case 1: /* ++++ trigger ++++ */
+/* if (p_filter->l_offset >= 0)
+ */
+ p_filter->l_offset = -5; /* trigger = event + 5 W */
+ p_filter->l_pattern = p_filter->l_pattern & 0xFFFF;
+ break;
+
+ case 2: /* ++++ pattern and offset ++++ */
+ break;
+
+ case 4: /* W ++++ type ++++ */
+/* if (p_filter->l_offset >= 0)
+ */
+ p_filter->l_offset = -2; /* type = evt(sev) + 2 W */
+ p_filter->l_pattern = p_filter->l_pattern & 0xFFFF;
+
+ break;
+
+ case 8: /* W ++++ subtype ++++ */
+/* if (p_filter->l_offset >= 0)
+ */
+ p_filter->l_offset = -3; /* subtype = evt(sev) + 3 W */
+ p_filter->l_pattern = p_filter->l_pattern & 0xFFFF;
+
+ break;
+
+ case 12: /* LW ++++ type and subtype ++++ */
+/* if (p_filter->l_offset >= 0)
+ */
+ p_filter->l_offset = 1; /* type-subtype = evt(sev) + 1 LW*/
+
+ break;
+
+ case 16: /* W ++++ procid ++++ */
+/* if (p_filter->l_offset >= 0)
+ */
+ p_filter->l_offset = -4; /* procid = sev + 4 W */
+ p_filter->l_pattern = p_filter->l_pattern & 0xFFFF;
+
+ break;
+
+ case 32: /* W ++++ subcrate,contr ++++*/
+/* if (p_filter->l_offset >= 0)
+ */
+ p_filter->l_offset = -5; /* subcrate,contr = sev + 5 W */
+ p_filter->l_pattern = p_filter->l_pattern & 0xFFFF;
+
+ break;
+
+ case 48: /* LW ++++procid,subcr,contr ++++*/
+/* if (p_filter->l_offset >= 0)
+ */
+ p_filter->l_offset = 2; /* procid,subc,ctrl = sev + 2 LW */
+
+ break;
+
+ default:
+ printf("W-%s: FLTSPEC %d NOT FOUND\n",
+ flt_modnam,
+ p_opc1->h_fltspec);
+ l_retsts = l_retsts | 2;
+ } /* switch case */
+
+
+
+ } /* for */
+
+ p_flt_descr = (struct s_flt_descr *) &p_clnt_filter->flt_descr[0];
+ if (p_flt_descr->hf_wrtdescr != 1) {
+ printf("E-%s: The write filter is missing! Filter is invalid!\n",
+ flt_modnam);
+ return(FALSE);
+ }
+
+ if (!(p_clnt_filter->if_fltevt || p_clnt_filter->if_fltsev)) {
+ printf("E-%s: The filter itself is missing! Filter is invalid!\n",
+ flt_modnam);
+ return(FALSE);
+ }
+
+/* printf(
+ * "I-%s: p_clnt:%d: found %d flts in %d blks with %d descript.\n",
+ * flt_modnam,
+ * p_clnt_filter,
+ * i_fltcnt,
+ * i_fltblkcnt,
+ * i_fltdescnt);
+ */
+
+ if ( (p_clnt_filter->if_fltevt == 1) && (p_clnt_filter->if_fltsev == 1) ) {
+ m_sort_descr:; /* sort event and subevent filter */
+ i_lasevtflt = 0; /* last event filter init */
+ i_1stsevflt = i_fltdescnt; /* first subevent filter init */
+ /* sort filter blocks: flt event should come before flt sev */
+ for (i = 1; i < i_fltdescnt; i++) {
+ p_flt_descr = (struct s_flt_descr *) &p_clnt_filter->flt_descr[i];
+ p_filter = (struct s_filter *)
+ &p_clnt_filter->filter[(int)p_flt_descr->h_fltblkbeg];
+ p_opc1 = (struct s_opc1 *) &p_filter->l_opcode;
+
+ if ( (p_opc1->b1_selflt == 1) && (p_opc1->b1_evtsev == 1) )
+ i_lasevtflt = i; /* save last evt flt found */
+
+ if ( (p_opc1->b1_selflt == 1) &&
+ (p_opc1->b1_evtsev == 0) &&
+ (i_1stsevflt == i_fltdescnt) )
+ i_1stsevflt = i; /* save last evt flt found */
+
+ if (i_1stsevflt < i_lasevtflt) { /* evt flt after sev flt */
+ printf(
+ "W-%s 1stsevflt:%d lastevtflt:%d. Evt flt should come first\n",
+ flt_modnam,
+ i_1stsevflt,
+ i_lasevtflt);
+ l_retsts = l_retsts | 2;
+ /* copy first LW from evt descr */
+ pl_evtdescr = (int *) &p_clnt_filter->flt_descr[i_lasevtflt];
+ l_evtdescr = *pl_evtdescr;
+ /* shift the subevent descriptors */
+ for (j = i_lasevtflt; j > i_1stsevflt; j--) {
+ pl_sev1descr = (int *) &p_clnt_filter->flt_descr[j-1];
+ pl_sev2descr = (int *) &p_clnt_filter->flt_descr[j];
+ *pl_sev2descr = *pl_sev1descr;
+ }
+ pl_evtdescr = (int *) &p_clnt_filter->flt_descr[i_1stsevflt];
+ *pl_evtdescr = l_evtdescr;
+ goto m_sort_descr; /* until descr is in right order */
+ } /* if */
+
+ } /* for */
+
+ } /* if (...if_fltevt... && ...if_fltsev...) */
+
+ /* + + + Max number of descriptors + + + */
+ p_clnt_filter->flt_descr[0].i_descriptors = i_fltdescnt;
+
+ /* ++++ check the subevent filter blocks ++++ */
+ /* + the first filter in the sev flt blk identifies the sev + */
+ /* + normaly Procid or Procid + Subcrate + */
+ if (p_clnt_filter->if_fltsev == 1) {
+ for (i = 1; i < p_clnt_filter->flt_descr[0].i_descriptors; i++) {
+ p_flt_descr = (struct s_flt_descr *) &p_clnt_filter->flt_descr[i];
+ /* ++ addr of the first filter in the flt blk ++ */
+ p_filter = (struct s_filter *)
+ &p_clnt_filter->filter[(int)p_flt_descr->h_fltblkbeg];
+ p_opc1 = (struct s_opc1 *) &p_filter->l_opcode;
+
+ } /* for */
+ } /* if (p_clnt_filter->if_fltsev... */
+
+ return(l_retsts | 1);
+
+} /* end f_fltdscr */
+
+
+
+/*2+F_FLTRD***+********************************************************/
+/* */
+/*+ Module : F_FLTRD */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : sts = f_fltrd(p_clnt_filter, c_file) */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Reads filter specification from a file */
+/* */
+/*+ ARGUMENTS : */
+/*+ p_clnt_filter: Pointer to structure s_clnt_filter */
+/*+ c_file : Pointer to file name string */
+/* */
+/*+ FUNCTION : Opens the file and reads filter specification */
+/* */
+/*+ Return type : int (32 bit) */
+/*+ Status codes: - */
+/*+ Initialize : - */
+/*+ Include name: - */
+/* */
+/*3+Implementation************+****************************************/
+/* */
+/*+ File name : PC_PROC.C */
+/*+ Version : 1.01 */
+/*+ Author : R.S. Mayer */
+/*+ Last Update : 14-JUN-1993 */
+/*+ Object libr.: GOOSHRLIB */
+/*3+Updates*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/*- 25-Jan-1994 : problems with sscanf removed (RSM) */
+/* */
+/*3+Description***+***********+****************************************/
+/*1- C Procedure ***********+******************************************/
+int f_fltrd(struct s_clnt_filter *p_clnt_filter, char *c_file)
+{
+
+ /* ++++ declaration ++++ */
+ FILE *infile;
+
+ static char fltrd_modnam[] = "f_fltrd";
+ struct s_filter *p_filter;
+ struct s_opc1 *p_opc1 = NULL;
+
+ char c_retmsg[256];
+ char c_line[80], c_comment[80], *c_fsts, *p_com, *p_minus;
+ short i_fltblklen = 0;
+ short i_currflt = 0;
+ short i;
+ int l_scan=0;
+
+ int unsigned l_pattern;
+ int l_offset;
+ int unsigned l_offset_unsigned;
+
+ short i_evtsev,i_selflt,i_selwrt,i_opc,i_lnkf1,
+ i_lnkf2,i_fltspec;
+ short if_hex, if_comment;
+
+ char *fgets( char *str, int maxchar, FILE *file_ptr);
+
+ /* +++ action +++ */
+
+ if ( (infile = fopen(c_file,"r")) == 0)
+ { /* open file for data input */
+ sprintf(c_retmsg,"E-%s: fopen(File=%s) ",
+ fltrd_modnam,
+ c_file);
+ perror(c_retmsg);
+ fclose(infile);
+ return(FALSE);
+ }
+
+ printf("Filter definition from file %s\n", c_file);
+ printf("=======================================\n");
+
+ while (l_scan != EOF && i_fltblklen < GPS__MAXFLT)
+ {
+ m_read_nxtblklen:;
+
+ memset(c_line,0,sizeof(c_line));
+
+ if ( (c_fsts = fgets(c_line, sizeof(c_line), infile)) == 0)
+ {
+ if (i_debug == 2)
+ printf("D-%s: File=%s: Last input line.\n",
+ fltrd_modnam,
+ c_file);
+ break;
+ }
+
+ if_comment = 0; /* reset flag */
+ p_com = strpbrk(c_line,"!/*"); /* find position of comment */
+ if (p_com != NULL) { /* found a comment */
+ if_comment = 1; /* set flag */
+ strncpy(c_comment, p_com, sizeof(c_comment)); /* copy comment */
+ *p_com = '\0'; /* mark end of str at beg of comm*/
+ if (i_debug == 2)
+ printf(" - D: comment:%s", c_comment);
+
+ }
+
+ l_scan = sscanf(c_line, "%hd", &i_fltblklen);
+ if (if_comment && (l_scan < 1) )
+ goto m_read_nxtblklen;
+
+ if (l_scan == EOF || l_scan == 0 || c_fsts == NULL)
+ {
+ if (i_debug == 2)
+ printf("D-%s: Last input line.\n",c_file);
+ break;
+ }
+
+ if (i_fltblklen + i_currflt >= GPS__MAXFLT)
+ {
+ printf("E-%s: too long. Last filter block ignored\n",
+ fltrd_modnam);
+ fclose(infile);
+ return(3);
+ }
+ if (i_debug == 2)
+ printf("D-%s: Fltblklen:%d\n", fltrd_modnam, i_fltblklen);
+
+ for (i = i_currflt; i < i_fltblklen + i_currflt; i++)
+ {
+ m_read_nxtline:;
+
+ memset(c_line,0,sizeof(c_line));
+
+ if ( (c_fsts = fgets(c_line, sizeof(c_line), infile)) == 0)
+ {
+ sprintf(c_retmsg,"E-%s: Error reading:fgets(File=%s) ",
+ fltrd_modnam,
+ c_file);
+ perror(c_retmsg);
+ fclose(infile);
+ return(FALSE);
+ }
+
+ if (i_debug == 2)
+ printf("D-%s: line:%s", fltrd_modnam, c_line);
+
+ if_comment = 0; /* reset flag */
+ p_com = strpbrk(c_line, "!/*"); /* find position of comment */
+ if (p_com != NULL) { /* found a comment */
+ if_comment = 1; /* set flag */
+ strncpy(c_comment, p_com, sizeof(c_comment)); /* copy comment */
+ *p_com = '\0'; /* mark end of str at beg of comm*/
+ if (i_debug == 2)
+ printf(" - D: comment:%s", c_comment);
+ }
+
+ l_scan = sscanf(c_line,"%hd %hd %hd %hd %hd %hd %hd %u %d",
+ &i_evtsev,
+ &i_selflt,
+ &i_selwrt,
+ &i_opc,
+ &i_lnkf1,
+ &i_lnkf2,
+ &i_fltspec,
+ &l_pattern,
+ &l_offset);
+ if_hex = 0; /* set flag null */
+ if (l_scan == 9)
+ goto m_ok_assign;
+
+ if_hex = 1; /* set flag null */
+ p_minus = strchr(c_line,'-'); /* find minus sign in offset */
+
+ if (p_minus != NULL) /* found minus sign */
+ *p_minus = ' '; /* replace minus with blank */
+
+ l_scan = sscanf(c_line,"%hd %hd %hd %hd %hd %hd %hd %x %x",
+ &i_evtsev,
+ &i_selflt,
+ &i_selwrt,
+ &i_opc,
+ &i_lnkf1,
+ &i_lnkf2,
+ &i_fltspec,
+ &l_pattern,
+ &l_offset_unsigned);
+
+ l_offset = (p_minus != NULL) ? -1*(int)l_offset_unsigned : l_offset_unsigned;
+
+ if (l_scan < 9)
+ {
+ if (if_comment)
+ goto m_read_nxtline;
+
+ printf(
+ "E-%s: scanned only %d(of 9) var., last 2 must be dec or hexa\n",
+ fltrd_modnam,
+ l_scan);
+ fclose(infile);
+ return(FALSE);
+ }
+
+ m_ok_assign:
+ if (i_debug == 2) {
+ sprintf( c_retmsg,
+ "%s es:%d f:%d w:%d opc:%d lf1:%d lf2:%d flt:%d p:%x o:%x",
+ (if_hex) ? "HEX:" : "DEC:",
+ i_evtsev,
+ i_selflt,
+ i_selwrt,
+ i_opc,
+ i_lnkf1,
+ i_lnkf2,
+ i_fltspec,
+ l_pattern,
+ (unsigned) l_offset);
+ printf("D-%s: %s\n", fltrd_modnam, c_retmsg);
+ }
+
+ p_filter = (struct s_filter *) &p_clnt_filter->filter[i];
+ p_opc1 = (struct s_opc1 *) &p_filter->l_opcode;
+
+ p_opc1->h_next_fltblk = (char) i_fltblklen + i_currflt;
+ p_opc1->h_flt_len = (char) i_fltblklen;
+
+ p_filter->l_pattern = l_pattern;
+ p_filter->l_offset = l_offset;
+
+ p_opc1->b1_evtsev = i_evtsev;
+ p_opc1->b1_selflt = i_selflt;
+ p_opc1->b1_selwrt = i_selwrt;
+ p_opc1->b3_opc = i_opc;
+ p_opc1->b1_lnkf1 = i_lnkf1;
+ p_opc1->b1_lnkf2 = i_lnkf2;
+ p_opc1->h_fltspec = (char) i_fltspec;
+
+ } /* for */
+
+ i_currflt = (short) p_opc1->h_next_fltblk;
+
+ } /* while */
+
+ fclose(infile);
+
+ return(TRUE);
+}
+
+
+
+/*2+F_TYPFLT***+*******************************************************/
+/* */
+/*+ Module : F_TYPFLT */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : sts = f_typflt(p_clnt_filter) */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Type the filter conditions. */
+/* */
+/*+ ARGUMENTS : p_clnt_filter: Pointer to s__clnt_filter */
+/* */
+/*+ FUNCTION : Type the filter conditions. Output via "printf". */
+/* See also I$PS_TYPFLT_PRTCL. */
+/* */
+/*+ Return type : int (32 bit) 1: success 0: fault */
+/*+ Status codes: - */
+/*+ Initialize : - */
+/*+ Include name: - */
+/* */
+/*3+Implementation************+****************************************/
+/* */
+/*+ File name : PC_PROC.C */
+/*+ Version : 1.01 */
+/*+ Author : R.S. Mayer */
+/*+ Last Update : 14-JUN-1993 */
+/*+ Object libr.: GOOSHRLIB */
+/*3+Updates*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/*- 12-Jan-1994 : Bug removed in subcrate,control (RSM) */
+/* */
+/*3+Description***+***********+****************************************/
+/*1- C Procedure ***********+******************************************/
+int f_typflt(struct s_clnt_filter *p_clnt_filter)
+{
+ static char typflt_modnam[] = "f_typflt";
+ struct s_filter *p_filter;
+ struct s_opc1 *p_opc1;
+ struct s_flt_descr *p_flt_descr;
+ struct s_pat1 *p_pat1;
+ struct s_pat2 *p_pat2;
+ struct s_pat3 *p_pat3;
+
+ short i_fltdescnt, j, i;
+
+ /* +++ action +++ */
+
+ /* + + + Max number of descriptors + + + */
+ i_fltdescnt = p_clnt_filter->flt_descr[0].i_descriptors;
+
+ /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */
+ /* + + + Output filter conditions for Write and Filter + + + */
+ /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */
+/* printf("Explanation: object OPCODE mask\n===========\n");
+ */
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf(
+ "Write:%s %s Filter:%s %s object OPCODE mask",
+ (p_clnt_filter->if_wrtevt > 0) ? "EVENT" : "",
+ (p_clnt_filter->if_wrtsev > 0) ? "SUBEVENT" : "",
+ (p_clnt_filter->if_fltevt > 0) ? "EVENT" : "",
+ (p_clnt_filter->if_fltsev > 0) ? "SUBEVENT" : "");
+ for (i = 0; i < i_fltdescnt; i++) {
+ p_flt_descr = (struct s_flt_descr *) &p_clnt_filter->flt_descr[i];
+ p_filter = (struct s_filter *)
+ &p_clnt_filter->filter[(int)p_flt_descr->h_fltblkbeg];
+ p_opc1 = (struct s_opc1 *) &p_filter->l_opcode;
+
+ if ( (i_debug == 1) || (i_debug == 2) )
+ {
+ if (i > 1)
+ printf("\n<<%s>>\n", (p_opc1->b1_lnkf2 == 1) ? "A_N_D" : "O_R" );
+ printf("\n=>>FILTER set %d :",i);
+ printf(" Select:%s Filter:%s Write:%s Filter[%d:%d]:\n",
+ (p_opc1->b1_evtsev == 1) ? "EVENT" : "SUBEVENT",
+ (p_opc1->b1_selflt == 1) ? "ON" : "OFF",
+ (p_opc1->b1_selwrt == 1) ? "ON" : "OFF",
+ p_flt_descr->h_fltblkbeg,
+ p_flt_descr->h_fltblkend );
+ }
+
+ /* +++ subevt flt blk id +++ */
+ if (p_opc1->b1_evtsev == 0 && p_opc1->b1_selflt == 1)
+ {
+ p_filter = (struct s_filter *)
+ &p_clnt_filter->filter[(int)p_flt_descr->h_fltblkbeg];
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf(
+ " Filter set id is fltspec:%d == mask:H%x (see 1st filt. below)\n",
+ p_opc1->h_fltspec,
+ p_filter->l_pattern);
+ }
+
+
+ /* +++ loop over all filters in this filter block +++ */
+ for (j = p_flt_descr->h_fltblkbeg;
+ j <= p_flt_descr->h_fltblkend;
+ j++) {
+ p_filter = (struct s_filter *) &p_clnt_filter->filter[j];
+ p_opc1 = (struct s_opc1 *) &p_filter->l_opcode;
+ if ( (j > p_flt_descr->h_fltblkbeg) &&
+ (p_opc1->b1_selflt == 1) &&
+ ( (i_debug == 1) || (i_debug == 2) ) )
+ printf(" <%s>\n", (p_opc1->b1_lnkf1 == 1) ? "A_N_D" : "O_R" );
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf(" =>%2d: opcode: ", i + 1);
+
+ switch (p_opc1->b3_opc) {
+ case 0:
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf("!! (ALL) ");
+ break;
+ case 1:
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf("== (IDENT) ");
+ break;
+
+ case 2:
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf("&& (ANY) ");
+ break;
+
+ case 3:
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf("&= (INCL) ");
+ break;
+
+ case 4:
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf("^= (EXCL) ");
+ break;
+
+ case 5:
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf("< (LT) ");
+ break;
+
+ case 6:
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf(">= (GE) ");
+ break;
+
+ default:
+ printf("W-OPCODE %d NOT FOUND\n",p_opc1->b3_opc);
+ }
+
+ switch (p_opc1->h_fltspec) {
+ case 0: /* ++++ take all ++++ */
+ if (p_opc1->b3_opc != 0) {
+ p_opc1->b3_opc = 0;
+ printf("W-%s: Take all. Opcode is %d\n",
+ typflt_modnam,
+ p_opc1->b3_opc);
+ }
+ break;
+
+ case 1: /* ++++ trigger ++++ */
+ p_pat1 = (struct s_pat1 *) &p_filter->l_pattern;
+ if ( (i_debug == 1) || (i_debug == 2) )
+ {
+ printf("trigger:%2d",p_pat1->i_trigger);
+ printf(" (mask:%d offs:%d %s)\n",
+ p_filter->l_pattern,
+ (p_filter->l_offset >= 0) ?
+ p_filter->l_offset : -p_filter->l_offset,
+ (p_filter->l_offset >= 0) ? "LW" : "W");
+ }
+ break;
+
+ case 2: /* ++++ pattern and offset ++++ */
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf("mask:H%x offset:%d %s\n",
+ p_filter->l_pattern,
+ (p_filter->l_offset >= 0) ?
+ p_filter->l_offset : -p_filter->l_offset,
+ (p_filter->l_offset >= 0) ?
+ "LW" : "W" );
+ break;
+
+ case 4: /* W ++++ type ++++ */
+ if ( (i_debug == 1) || (i_debug == 2) )
+ {
+ printf("type:%d ",
+ p_filter->l_pattern);
+ printf(" (mask:%d offs:%d %s)\n",
+ p_filter->l_pattern,
+ (p_filter->l_offset >= 0) ?
+ p_filter->l_offset : -p_filter->l_offset,
+ (p_filter->l_offset >= 0) ? "LW" : "W");
+ }
+ break;
+
+ case 8: /* W ++++ subtype ++++ */
+ if ( (i_debug == 1) || (i_debug == 2) )
+ {
+ printf("subtype:%d ",
+ p_filter->l_pattern);
+ printf(" (mask:%d offs:%d %s)\n",
+ p_filter->l_pattern,
+ (p_filter->l_offset >= 0) ?
+ p_filter->l_offset : -p_filter->l_offset,
+ (p_filter->l_offset >= 0) ? "LW" : "W");
+ }
+ break;
+
+ case 12: /* W ++++ type and subtype ++++ */
+ p_pat3 = (struct s_pat3 *) &p_filter->l_pattern;
+ if ( (i_debug == 1) || (i_debug == 2) )
+ {
+ printf("type:%d subtype:%d",
+ p_pat3->i_type,
+ p_pat3->i_subtype);
+ printf(" (mask:H%x offs:%d %s)\n",
+ p_filter->l_pattern,
+ (p_filter->l_offset >= 0) ?
+ p_filter->l_offset : -p_filter->l_offset,
+ (p_filter->l_offset >= 0) ? "LW" : "W");
+ }
+ break;
+
+ case 16: /* ++++ procid ++++*/
+ p_pat2 = (struct s_pat2 *) &p_filter->l_pattern;
+ if ( (i_debug == 1) || (i_debug == 2) )
+ {
+ printf("procid:%d ",
+ p_pat2->i_procid);
+ printf(" (mask:%d offs:%d %s)\n",
+ p_filter->l_pattern,
+ (p_filter->l_offset >= 0) ?
+ p_filter->l_offset : -p_filter->l_offset,
+ (p_filter->l_offset >= 0) ? "LW" : "W");
+ }
+ break;
+
+ case 32: /* W ++++ subcrate,contr ++++*/
+ if ( (i_debug == 1) || (i_debug == 2) )
+ {
+ printf("subcrate:%d control:%d",
+ p_filter->l_pattern & 0x00FF,
+ ((unsigned) (p_filter->l_pattern & 0xFF00)) >> 8);
+ printf(" (mask:H%x offs:%d %s)\n",
+ p_filter->l_pattern,
+ (p_filter->l_offset >= 0) ?
+ p_filter->l_offset : -p_filter->l_offset,
+ (p_filter->l_offset >= 0) ? "LW" : "W");
+ }
+ break;
+
+ case 48: /* LW ++++procid,subcr,contr ++++*/
+ p_pat2 = (struct s_pat2 *) &p_filter->l_pattern;
+ if ( (i_debug == 1) || (i_debug == 2) )
+ {
+ printf("procid:%2d subcr:%d contr:%d",
+ p_pat2->i_procid,
+ p_pat2->h_subcrate,
+ p_pat2->h_control);
+ printf(" (mask:H%x offs:%d %s)\n",
+ p_filter->l_pattern,
+ (p_filter->l_offset >= 0) ?
+ p_filter->l_offset : -p_filter->l_offset,
+ (p_filter->l_offset >= 0) ? "LW" : "W");
+ }
+ break;
+
+ default:
+ printf("W-FLTSPEC %d NOT FOUND\n",p_opc1->h_fltspec);
+ } /* switch case */
+
+ /* ++++ check if Filter specification is valid ++++ */
+ if ((p_opc1->h_fltspec > 15) && (p_opc1->b1_evtsev == 1)) {
+ printf("E-%s: Filter specification %d invalid for events\n",
+ typflt_modnam,
+ p_opc1->h_fltspec);
+ return(FALSE); /* abort with error */
+ }
+ if ((p_opc1->h_fltspec < 2) && (p_opc1->b1_evtsev != 1)) {
+ printf("E-%s: Filter specification %d invalid for subevents\n",
+ typflt_modnam,
+ p_opc1->h_fltspec);
+ return(FALSE); /* abort with error */
+ }
+
+ } /* for (j... */
+
+ } /* for (i... */
+ if ( (i_debug == 1) || (i_debug == 2) )
+ printf("\n\n");
+
+ return(TRUE);
+} /* end f_typflt */
+
+
+
+
+/*2+F_READ_SERVER***+**************************************************/
+/* */
+/*+ Module : F_READ_SERVER */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : sts = f_read_server(p_clntbuf, */
+/* p_bytrd, */
+/* arg_timeout, */
+/* i_chan) */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Read a buffer from the server */
+/* */
+/*+ ARGUMENTS : */
+/*+ p_clntbuf: Pointer to structure s_clntbuf */
+/*+ p_bytrd : Pointer to (int) Number of read bytes */
+/*+ arg_timeout: (int) Timeout in seconds */
+/*+ i_chan : (int) channel number */
+/* */
+/*+ FUNCTION : Read a buffer of the type s_clntbuf from the */
+/* server. */
+/* */
+/*+ Return type : int (32 bit) */
+/*+ Status codes: 1: success */
+/* 0: fault */
+/*+ Initialize : - */
+/*+ Include name: - */
+/* */
+/*3+Implementation************+****************************************/
+/* */
+/*+ File name : PC_PROC.C */
+/*+ Version : 1.01 */
+/*+ Author : R.S. Mayer */
+/*+ Last Update : 14-JUN-1993 */
+/*+ Object libr.: GOOSHRLIB */
+/*3+Updates*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/*- 26-Jan-1994 : Swap inserted (RSM) */
+/*- 24-Feb-1994 : Bug removed (RSM) */
+/* */
+/*3+Description***+***********+****************************************/
+/*1- C Procedure ***********+******************************************/
+int f_read_server(s_evt_channel *ps_chan, int *p_bytrd, int arg_timeout, int i_chan)
+{
+ /* ++++ declarations ++++ */
+ int l_maxbytes;
+ int l_status1, ii, im, *pl; /* !!! */
+ int l_bytrec, l_2ndbuf_byt;
+ int l_buftord, l_buffertype;
+ static char readserv_modnam[] = "f_read_server";
+ char c_retmsg[256];
+ char *pc;
+ int *pl_d, *pl_s;
+ struct s_clntbuf *p_clntbuf;
+ short j;
+
+// JAM1-6-2021- test if this helps the streamserver problems
+#ifndef DISABLE_POLLING_TIMEOUT
+
+ int _tmout, _retry;
+
+ _retry = 0;
+ _tmout = arg_timeout;
+
+ if (ps_chan->cb_polling) {
+ _tmout = 555555; // special value, should produce 0.05s timeout
+ _retry = 100000; // approx 5000 sec
+ }
+#endif
+ /* ++++ action ++++ */
+
+ p_clntbuf = (struct s_clntbuf *) ps_chan->pc_io_buf;
+ l_maxbytes = ps_chan->l_io_buf_size;
+ /* + + + + + + + + + + + + + + + */
+ /* + + + read first buffer + + + */
+ /* + + + + + + + + + + + + + + + */
+ if (i_debug == 2)
+ printf("D-%s: **Rd 1st Buf: at %p to %p = %d bytes\n",
+ readserv_modnam,
+ (char *) p_clntbuf,
+ ((char *) p_clntbuf) + (CLNT__SMALLBUF - 1),
+ CLNT__SMALLBUF);
+
+
+ *p_bytrd = CLNT__SMALLBUF;
+
+// JAM1-6-2021- test if this helps the streamserver problems
+#ifndef DISABLE_POLLING_TIMEOUT
+read_again:
+
+ l_status1 = f_stc_read( (char *) p_clntbuf,
+ (int) CLNT__SMALLBUF,
+ i_chan,
+ _tmout);
+
+ if ((_retry-- > 0) && (l_status1 == STC__TIMEOUT)) {
+ ps_chan->cb_polling();
+ goto read_again;
+ }
+#else
+ l_status1 = f_stc_read( (char *) p_clntbuf,
+ (int) CLNT__SMALLBUF,
+ i_chan,
+ arg_timeout);
+#endif
+
+ if (l_status1 != STC__SUCCESS)
+ {
+ printf("E-%s: Error reading first buffer. Msg follows:",readserv_modnam);
+ f_stc_disperror(l_status1,c_retmsg, 0);
+ return(FALSE);
+ }
+
+ /* +++ copy the relevant length values +++ */
+ l_buftord = p_clntbuf->l_numbuftosnd;
+ l_bytrec = p_clntbuf->l_bytestosnd;
+ l_buffertype = p_clntbuf->l_buffertype;
+
+ /* +++ test for byte swap +++ */
+ if (p_clntbuf->l_testbit != GPS__ENV_TESTBIT)
+ {
+ if (i_debug == 2)
+ printf("D-%s: Need swap to receive from %s to %s ENDIAN\n",
+ readserv_modnam,
+ (p_clntbuf->l_endian == 0) ? "LITTLE" : "BIG",
+ (GPS__ENV_ENDIAN == 0) ? "LITTLE" : "BIG");
+
+ l_status1 = F__SWAP(&l_buftord, 1, 0);
+ if (l_status1 != 0) printf("E-%s: Error swapping l_buftord. l_sts:%d\n", readserv_modnam,l_status1);
+ l_status1 = F__SWAP(&l_bytrec , 1, 0);
+ if (l_status1 != 0) printf("E-%s: Error swapping l_bytrec l_sts:%d\n", readserv_modnam,l_status1);
+ l_status1 = F__SWAP(&l_buffertype, 1, 0);
+ if (l_status1 != 0) printf("E-%s: Error swapping l_buffertype l_sts:%d\n", readserv_modnam,l_status1);
+ if (i_debug == 2)
+ printf("D-%s: buffers:%d, bytes:%d, buffertype:%d\n",
+ readserv_modnam,
+ l_buftord,
+ l_bytrec,
+ l_buffertype);
+
+ }
+ if (l_buftord == 1)
+ {
+ if (l_bytrec > CLNT__SMALLBUF)
+ {
+ printf("E-%s: Buffer sent:%d Bytes_to_rd:%d > %d\n",
+ readserv_modnam,
+ l_buftord,
+ l_bytrec,
+ CLNT__SMALLBUF);
+ return(FALSE);
+ }
+ goto m_snd_ackn;
+ }
+
+ l_2ndbuf_byt = l_bytrec - CLNT__SMALLBUF; /* rest of bytes in 2nd buffer*/
+
+ /* + + + + + + + + + + + + + + */
+ /* + + + read 2nd buffer + + + */
+ /* + + + + + + + + + + + + + + */
+ if (i_debug == 2)
+ {
+ printf("D-%s: begin of c_buffer[148] in LW (all hex)\n", readserv_modnam);
+ pl = (int *) &p_clntbuf->c_buffer[148];
+ for (j=0; j<5; j++)
+ {
+ printf("%p:%8x ",pl,*(pl));
+ pl++;
+ printf("%p:%8x ",pl,*(pl));
+ pl++;
+ printf("%p:%8x ",pl,*(pl));
+ pl++;
+ printf("\n");
+ }
+ printf("D-%s: **Rd 2nd Buf: at %p (buf[%d]) to %p = %d b\n",
+ readserv_modnam,
+ (char *) &p_clntbuf->c_buffer[CLNT__RESTBUF],
+ CLNT__RESTBUF,
+ ((char *) &p_clntbuf->c_buffer[CLNT__RESTBUF]) + (l_2ndbuf_byt - 1),
+ l_2ndbuf_byt);
+ }
+ *p_bytrd += l_2ndbuf_byt;
+ l_buftord = 2;
+ /* check if buffer if big enough, reallocate if not */
+ /* old buffer is freed by caller */
+ if(l_bytrec > l_maxbytes)
+ {
+ im=l_bytrec;
+ l_bytrec=(int)(1.2*(float)l_bytrec);
+ l_bytrec=((l_bytrec>>12)+1);
+ l_bytrec=(l_bytrec<<12);
+ /* printf("reallocate for %d (%d) bytes\n",im,l_bytrec);fflush(stdout);*/
+ pc = (char*) malloc(l_bytrec);
+ pl_d=(int *)pc;
+ for(ii=0;iipc_io_buf;
+ for(ii=0;iipc_io_buf = pc;
+ ps_chan->l_io_buf_size = l_bytrec;
+ p_clntbuf = (struct s_clntbuf *) pc;
+ }
+ pl = (int *) &p_clntbuf->c_buffer[CLNT__RESTBUF];
+ im=l_2ndbuf_byt/16384;
+ l_2ndbuf_byt=l_2ndbuf_byt%16384;
+ for(ii=0;ii 0)
+ {
+ l_status1 = f_stc_read( pl,l_2ndbuf_byt,i_chan,arg_timeout);
+ }
+ if (l_status1 != STC__SUCCESS)
+ {
+ printf("E-%s: Error reading second buffer. Msg follows:",readserv_modnam);
+ f_stc_disperror(l_status1,c_retmsg, 0);
+ return(FALSE);
+ }
+
+ if (i_debug == 2)
+ {
+ printf("D-%s: begin of c_buffer[148] in LW (all hex)\n", readserv_modnam);
+ pl = (int *) &p_clntbuf->c_buffer[148];
+ for (j=0; j<5; j++)
+ {
+ printf("%p:%8x ",pl,*(pl));
+ pl++;
+ printf("%p:%8x ",pl,*(pl));
+ pl++;
+ printf("%p:%8x ",pl,*(pl));
+ pl++;
+
+ printf("\n");
+ }
+ }
+
+ m_snd_ackn:; /* +++ set and send 12 bytes ackn */
+ /* ++++++++++++++++++++++++++++++++++ */
+ /* + + + send acknowledge buffer + + + */
+ /* ++++++++++++++++++++++++++++++++++ */
+ s_ackn.l_ack_buf = l_buftord;
+ s_ackn.l_ack_bytes = *p_bytrd;
+ s_ackn.l_clnt_sts = 1; /* success */
+
+ if ((l_buffertype & 8) != 0)
+ s_ackn.l_clnt_sts = s_ackn.l_clnt_sts | 8; /* set bit for last buffer */
+
+ return(TRUE);
+}
+
+
+/*2+F_SEND_ACKN*****+**************************************************/
+/* */
+/*+ Module : F_SEND_ACKN */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : sts = f_send_ackn(l_clnt_sts, i_chan) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Send acknowledge buffer to the server */
+/* */
+/*+ ARGUMENTS : */
+/*+ l_clnt_sts: Status. Status bits will be set in addition to the */
+/* status bits set by f_read_server in s_ackn struct. */
+/*+ i_chan : (int) channel number */
+/* */
+/*+ FUNCTION : Send the acknowledge buffer. Set additional bits in */
+/* the status word, i.e. "last buffer" etc. */
+/* */
+/*+ Return type : int (32 bit) */
+/*+ Status codes: 1: success */
+/* 0: fault */
+/*+ Initialize : - */
+/*+ Include name: - */
+/* */
+/*3+Implementation************+****************************************/
+/* */
+/*+ File name : PC_PROC.C */
+/*+ Version : 1.01 */
+/*+ Author : R.S. Mayer */
+/*+ Last Update : 11-Apr-1994 */
+/*+ Object libr.: GOOSHRLIB */
+/*3+Updates*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*3+Description***+***********+****************************************/
+/*1- C Procedure ***********+******************************************/
+int f_send_ackn(int l_clnt_sts1, int i_chan)
+{
+ /* ++++ declarations ++++ */
+ int l_status1; /* !!! */
+ static char sackn_modnam[] = "f_send_ackn";
+ char c_retmsg[256];
+
+ if (i_debug == 2)
+ printf("I-%s s_ackn.l_clnt_sts:%d l_clnt_sts:%d\n",
+ sackn_modnam,
+ s_ackn.l_clnt_sts,
+ l_clnt_sts1);
+
+ /* +++++++++++++++++++++++++++++++ */
+ /* +++ set status of ackn buf +++ */
+ /* +++++++++++++++++++++++++++++++ */
+ s_ackn.l_clnt_sts = s_ackn.l_clnt_sts | l_clnt_sts1; /* success */
+
+ /* ++++++++++++++++++++++++++++++ */
+ /* +++ send acknowledge buffer +++ */
+ /* ++++++++++++++++++++++++++++++ */
+ l_status1 = f_stc_write( (char *) &s_ackn,
+ 12,
+ i_chan);
+
+ if (l_status1 != STC__SUCCESS)
+ {
+ printf("E-%s: Error in f_stc_write(&s_ackn,...)! Msg follows:",
+ sackn_modnam);
+ f_stc_disperror(l_status1,c_retmsg, 0);
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+
+/*2+F_STRTOUPPER***+***************************************************/
+/* */
+/*+ Module : F_STRTOUPPER */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : sts = f_strtoupper(u, l) */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Converts a '\0' terminated string to upper case. */
+/* */
+/*+ ARGUMENTS : */
+/*+ u : Pointer to upper case string (result) */
+/*+ l : Pointer to lower case string (argument) */
+/* */
+/*+ FUNCTION : Converts a '\0' terminated string to upper case. */
+/* */
+/*+ Return type : int (32 bit) */
+/*+ Status codes: - */
+/*+ Initialize : - */
+/*+ Include name: - */
+/* */
+/*3+Implementation************+****************************************/
+/* */
+/*+ File name : PC_PROC.C */
+/*+ Version : 1.01 */
+/*+ Author : R.S. Mayer */
+/*+ Last Update : 14-JUN-1993 */
+/*+ Object libr.: GOOSHRLIB */
+/*3+Updates*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*3+Description***+***********+****************************************/
+/*1- C Procedure ***********+******************************************/
+void f_strtoupper(char *u, char *l)
+{
+ for ( ; *l != '\0'; ++l, ++u)
+ *u = toupper(*l);
+
+ *u = '\0';
+ return;
+}
+
+
+/*2+F_CLNUP ***+*******************************************************/
+/* */
+/*+ Module : F_CLNUP */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_clnup(v_mem, p_keyb) */
+/* */
+/* */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Cleanup allocated memory and dealloc devices */
+/* */
+/*+ ARGUMENTS : */
+/*+ v_mem[] : (int) [0]:maxidx=n [1:n]:ptr to allocated memory */
+/*+ p_keyb : Pointer to s_keyb or NULL. */
+/* */
+/*+ FUNCTION : Cleanup allocated memory and dealloc devices */
+/* Calls free(v_mem[i]) and f_ttydass(p_keyb) */
+/* */
+/* */
+/*+ Return type : void */
+/*+ Status codes: - */
+/*+ Initialize : - */
+/*+ Include name: - */
+/* */
+/*3+Implementation************+****************************************/
+/* */
+/*+ File name : PC_PROC.C */
+/*+ Version : 1.01 */
+/*+ Author : R.S. Mayer */
+/*+ Last Update : 14-JUN-1993 */
+/*+ Object libr.: GOOSHRLIB */
+/*3+Updates*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/*- 14-Jan-94 : prototype TTYSTUFF(f_ttydass()) (RSM) */
+/*- 08-Apr-94 : Accept NULL pointer for p_keyb. /HE */
+/* */
+/*3+Description***+***********+****************************************/
+/*1- C Procedure ***********+******************************************/
+/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+void f_clnup(ADDRS v_mem[], int *p_keyb)
+/* cleanup: free allocated memory and dealloc allocated device(s) */
+{
+ /* ++++ declaration ++++ */
+ short i;
+
+ for (i = 1; i <= v_mem[0]; i++)
+ {
+ if(v_mem[i] != 0) free((void *) v_mem[i]);
+ v_mem[i]=0;
+ }
+ v_mem[0]=0;
+}
+/*******************************************************************/
+void f_clnup_save(ADDRS v_mem[], int *p_keyb)
+/* cleanup: free allocated memory and dealloc allocated device(s) */
+{
+ /* ++++ declaration ++++ */
+ v_mem[++v_mem[0]] = (ADDRS) p_keyb; /* was (int) before JA */
+}
+/* ------------------------------------------------------------------------- */
diff --git a/plugins/olmd/mbsapi/f_evcli.h b/plugins/olmd/mbsapi/f_evcli.h
new file mode 100644
index 00000000..bc475211
--- /dev/null
+++ b/plugins/olmd/mbsapi/f_evcli.h
@@ -0,0 +1,24 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef F_EVCLI_H
+#define F_EVCLI_H
+
+#include "f_evt.h"
+
+int f_evcli_con(s_evt_channel *ps_chan, char *pc_node, int l_aport, int l_aevents, int l_asample);
+int f_evcli_buf(s_evt_channel *ps_chan);
+int f_evcli_evt(s_evt_channel *ps_chan);
+int f_evcli_close(s_evt_channel *ps_chan);
+
+#endif
diff --git a/plugins/olmd/mbsapi/f_evt.c b/plugins/olmd/mbsapi/f_evt.c
new file mode 100644
index 00000000..112c64b3
--- /dev/null
+++ b/plugins/olmd/mbsapi/f_evt.c
@@ -0,0 +1,2826 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#include "typedefs.h"
+#include "f_stccomm.h"
+#include "f_ut_time.h"
+
+#ifdef GSI__LYNX
+#undef unix
+#endif
+
+#ifdef GSI__LINUX /* Linux */
+#undef unix
+#endif
+
+#ifdef GSI__SOLARIS /* Solaris */
+#undef unix
+#endif
+
+#ifdef GSI__WINNT /* Windows NT */
+#endif
+
+#ifdef GSI__AIX
+#define AIX_DEC
+#endif
+
+#ifdef unix /* DEC OSF/1 */
+#define AIX_DEC
+#endif
+
+#ifdef GSI__WINNT
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define DEF_FILE_ACCE S_IREAD|S_IWRITE /* rw */
+#define GET__OPEN_FLAG O_RDONLY|O_BINARY
+#define PUT__OPEN_APD_FLAG O_RDWR|O_APPEND
+#define PUT__CRT_FLAG O_CREAT|O_RDWR
+#define PUT__CRT_OPT ""
+
+
+#include
+#define WS_VERSION_REQD 0x0101
+#define WS_VERSION_MAJOR HIBYTE(WS_VERSION_REQD)
+#define WS_VERSION_MINOR LOBYTE(WS_VERSION_REQD)
+#define MIN_SOCKETS_REQD 6
+// WSADATA wsaData;
+#endif
+
+#ifdef Linux /* Linux */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define DEF_FILE_ACCE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH /* rw-r--r-- */
+#define GET__OPEN_FLAG O_RDONLY
+#define PUT__OPEN_APD_FLAG O_RDWR|O_APPEND
+#define PUT__CRT_FLAG O_CREAT|O_RDWR
+#define PUT__CRT_OPT ""
+#endif
+
+#ifdef Solaris /* Linux */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define DEF_FILE_ACCE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH /* rw-r--r-- */
+#define GET__OPEN_FLAG O_RDONLY
+#define PUT__OPEN_APD_FLAG O_RDWR|O_APPEND
+#define PUT__CRT_FLAG O_CREAT|O_RDWR
+#define PUT__CRT_OPT ""
+#endif
+
+#ifdef Darwin /* MaxOS X */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define DEF_FILE_ACCE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH /* rw-r--r-- */
+#define GET__OPEN_FLAG O_RDONLY
+#define PUT__OPEN_APD_FLAG O_RDWR|O_APPEND
+#define PUT__CRT_FLAG O_CREAT|O_RDWR
+#define PUT__CRT_OPT ""
+#endif
+
+
+
+#ifdef _AIX
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define DEF_FILE_ACCE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH /* rw-r--r-- */
+#define GET__OPEN_FLAG O_RDONLY
+#define PUT__OPEN_APD_FLAG O_RDWR|O_APPEND
+#define PUT__CRT_FLAG O_CREAT|O_RDWR
+#define PUT__CRT_OPT ""
+#endif
+
+#include "s_filhe.h"
+
+
+#ifdef RFIO
+#define RFIO_open rfio_open
+#define RFIO_close rfio_close
+#define RFIO_read rfio_read
+#define RFIO_lseek rfio_lseek
+#include "rawapin.h" /* RFIO stuff */
+#else
+#define RFIO_open open
+#define RFIO_close close
+#define RFIO_read read
+#define RFIO_lseek lseek
+#endif
+
+#ifdef GSI__WINNT
+#define own_getpid _getpid
+#else
+#define own_getpid getpid
+#endif
+
+
+// DABC
+#include "fLmd.h"
+// -- DABC
+
+#include "gps_sc_def.h"
+#include "f_evt.h"
+#include "f_evcli.h"
+#include "portnum_def.h"
+
+INTS4 f_evt_get_newbuf(s_evt_channel *);
+INTS4 f_evt_check_buf(CHARS *,INTS4 *, INTS4 *, INTS4 *, INTS4 *);
+INTS4 f_evt_ini_bufhe(s_evt_channel *ps_chan);
+INTS4 f_evt_swap_filhe(s_bufhe *);
+INTS4 f_ut_utime(INTS4, INTS4, CHARS *);
+
+static struct s_tcpcomm s_tcpcomm_st_evt;
+static CHARS c_temp[MAX_BUF_LGTH];
+static int l_gl_source_port = 0;
+
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_evt__example */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : Examples for calling event API */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : See f_evt_examples.c */
+/* */
+/* */
+/*2+Implementation************+****************************************/
+/*+ User Example : In m_lea_user.c */
+/*+ Channel structure : defined in f_evt.h */
+/*+ File name : f_evt.c */
+/*+ Version : 1.01 */
+/*+ Author : H.Essel */
+/*+ Created : 16-Feb-2000 */
+/*+ Updates : Date Purpose */
+/*1- C Procedure *************+****************************************/
+
+
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 52 */
+/* D-64220 Darmstadt */
+/* */
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_evt_get_subevent */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l_sts = f_evt_get_subevent(ve10_1 *,subevent,**head,**data,*lwords) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : get subevent pointer */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ ve10_1 : (s_ve10_1 *) event header pointer */
+/*+ subevent : subevent number (1,2,3...) */
+/* If = 0, f_evt_get_subevent returns the number of */
+/* subevents. In this case the following arguments */
+/* might be NULL. */
+/*+ head : Address of s_ves10_1 subevent header pointer */
+/*+ data : Address of INTS4 event data pointer */
+/*+ lwords : Address of INTS4 to get number of data longwords */
+/* */
+/*+ Return type : int */
+/*- GETEVT__SUCCESS : Found subevent. */
+/*- GETEVT__NOMORE : No more subevents. */
+/*+ Declaration : */
+/* INTS4 f_evt_get_subevent( */
+/* s_ve10_1 *, INTS4, INTS4 **, INTS4 **, INTS4 *); */
+/*1- C Procedure *************+****************************************/
+INTS4 f_evt_get_subevent(s_ve10_1 *ps_ve10_1, INTS4 l_subevent, INTS4 **pl_se, INTS4 **pl_d,INTS4 *pl_lwords)
+{
+ s_ves10_1 *ps_ves10_1;
+ INTS4 l_total,l_sub,l_sum;
+ INTS4 ll,*pl_next;
+
+ if(ps_ve10_1 == NULL) return(GETEVT__FAILURE);
+ pl_next = (INTS4 *) (ps_ve10_1 + 1);
+ l_total = ps_ve10_1->l_dlen-4; /* total words in subevents */
+ l_sum = 0;
+ ll=0;
+ while(l_sum < l_total)
+ {
+ ps_ves10_1 = (s_ves10_1 *) pl_next;
+ ll++;
+ if(ll == l_subevent)
+ {
+ if(pl_lwords != NULL) *pl_lwords = ps_ves10_1->l_dlen/2-1;
+ if(pl_se != NULL) *pl_se = (INTS4 *) ps_ves10_1;
+ if(pl_d != NULL) *pl_d = (INTS4 *) (ps_ves10_1+1);
+ return(GETEVT__SUCCESS);
+ }
+ l_sub = ps_ves10_1->l_dlen+4; /* total words of subevent */
+ l_sum += l_sub;
+ pl_next = (INTS4 *)(ps_ves10_1);
+ pl_next += l_sub/2;
+ }
+ if(pl_lwords != NULL) *pl_lwords = ll;
+ if(pl_se != NULL) *pl_se = NULL;
+ if(pl_d != NULL) *pl_d = NULL;
+ if(l_subevent == 0) return(ll);
+ else return(GETEVT__NOMORE);
+}
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 52 */
+/* D-64220 Darmstadt */
+/* */
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_evt_type */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l_status = f_evt_type(bufhe,evhe,sid,long,hex,data) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : print event */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ bufhe : (s_bufhe *) buffer header pointer (=NULL no output) */
+/*+ evhe : (s_evhe *) event header pointer (=NULL no output) */
+/*+ sid : subevent ID (-1 is all) */
+/*+ long : output longwords */
+/*+ hex : output hex longwords */
+/*+ data : output data */
+/* */
+/*+ Return type : int */
+/*+ Declaration : */
+/* INTS4 f_evt_type( */
+/* s_bufhe *,s_evhe *, INTS4, INTS4, INTS4, INTS4); */
+/*1- C Procedure *************+****************************************/
+INTS4 f_evt_type(s_bufhe *ps_bufhe,s_evhe *ps_evhe, INTS4 l_subid,INTS4 l_long,INTS4 l_hex,INTS4 l_data)
+{
+ s_ves10_1 *ps_ves10_1;
+ s_ve10_1 *ps_ve10_1;
+ s_filhe *ps_filhe;
+ INTS4 *pl_data;
+ INTS4 l_s;
+ INTS4 l, ll, l_status, l_ldata, l_used;
+ CHARS c_line[132];
+ CHARS c_full[132];
+ CHARS c_time[32];
+
+ strcpy(c_full," ");
+ l_ldata=l_data;
+ if((l_hex+l_long) > 0) l_ldata=1;
+
+ /* Print buffer header (file header) */
+ if(ps_bufhe != NULL)
+ {
+ sprintf(c_line,"--------------------------------------------------------");
+ printf("%s\n",c_line);
+ /* calculate real buffer size */
+ ll=ps_bufhe->l_dlen*2;
+ if(ll%512 > 0)ll += 512-ll%512;
+ /* file header */
+ l_status = f_ut_utime(ps_bufhe->l_time[0],ps_bufhe->l_time[1],c_time);
+ if(ps_bufhe->i_type == 2000)
+ {
+ ps_filhe=(s_filhe *)ps_bufhe;
+ sprintf(c_line,"File header info:");
+ printf("%s\n",c_line);
+ sprintf(c_line,"Size: %d [%d b], used %d [b]",ps_filhe->filhe_dlen,ll,ps_filhe->filhe_used*2);
+ printf("%s\n",c_line);
+ sprintf(c_line,"Label: %s",ps_filhe->filhe_label);
+ printf("%s\n",c_line);
+ sprintf(c_line,"File: %s",ps_filhe->filhe_file);
+ printf("%s\n",c_line);
+ sprintf(c_line,"User: %s",ps_filhe->filhe_user);
+ printf("%s\n",c_line);
+ sprintf(c_line,"Time: %s",ps_filhe->filhe_time);
+ printf("%s\n",c_line);
+ sprintf(c_line,"Run: %s",ps_filhe->filhe_run);
+ printf("%s\n",c_line);
+ sprintf(c_line,"Exp: %s",ps_filhe->filhe_exp);
+ printf("%s\n",c_line);
+ for(ll=0;llfilhe_lines;ll++)
+ {
+ sprintf(c_line,"comment: %s",ps_filhe->s_strings[ll].string);
+ printf("%s\n",c_line);
+ }
+ }
+ else
+ {
+ l_used=ps_bufhe->i_used;
+ if(ps_bufhe->l_dlen > MAX__DLEN)l_used=ps_bufhe->l_free[2];
+ sprintf(c_line,"Buffer %9d, Length %5d[w] Size %5d[b] used %5d[w] %s",
+ ps_bufhe->l_buf,
+ ps_bufhe->l_dlen,
+ ll,l_used,
+ c_time);
+ printf("%s\n",c_line);
+ sprintf(c_line," Events %3d Type/Subtype %5d %5d FragEnd=%d FragBegin=%d Total %5d[w]",
+ ps_bufhe->l_evt,
+ ps_bufhe->i_type,
+ ps_bufhe->i_subtype,
+ ps_bufhe->h_end,
+ ps_bufhe->h_begin,
+ ps_bufhe->l_free[1]);
+ printf("%s\n",c_line);
+ }
+ sprintf(c_line,"--------------------------------------------------------");
+ printf("%s\n",c_line);
+ }
+
+ if(ps_evhe == NULL) return(0);
+
+ /* print event 4,x or 6,x */
+ if(ps_evhe->i_type != 10)
+ {
+ sprintf(c_line,"Event type %d, subtype %d, data longwords %d",
+ ps_evhe->i_type,ps_evhe->i_subtype,ps_evhe->l_dlen/2);
+ printf("%s\n",c_line);
+ if((l_ldata != 0) & ((ps_evhe->i_type == 4)|(ps_evhe->i_type == 6)))
+ { /* output data, assume data as longword */
+ pl_data = (INTS4 *)ps_evhe;
+ pl_data += 2;
+ for(l=0;ll_dlen/2;l++)
+ {
+ sprintf(c_line,"%08x ",*pl_data);
+ strncat(c_full, c_line, sizeof(c_full)-1);
+ pl_data++;
+ if(l%8 == 7) {
+ printf("%s\n",c_full);
+ strcpy(c_full," ");
+ }
+ }
+ if(strlen(c_full) > 2) printf("%s\n",c_full);
+ }
+ return(0);
+ }
+
+ /* Print event 10,1 */
+ ps_ve10_1 = (s_ve10_1 *)ps_evhe;
+ /* Print event header */
+ sprintf(c_line,"Event %9d Type/Subtype %5d %5d Length %5d[w] Trigger %2d",
+ ps_ve10_1->l_count,
+ ps_ve10_1->i_type,
+ ps_ve10_1->i_subtype,
+ ps_ve10_1->l_dlen,
+ ps_ve10_1->i_trigger);
+ printf("%s\n",c_line);
+
+ /********************/
+ l_s=0;
+ l_status=0;
+ while(l_status == 0)
+ {
+ l_s++;
+ l_status=f_evt_get_subevent(ps_ve10_1,l_s,(INTS4 **)&ps_ves10_1,(INTS4 **)&pl_data,(INTS4 *)&ll);
+ if(l_status == 0)
+ {
+ if((l_subid < 0)|(l_subid == ps_ves10_1->i_procid))
+ {
+ sprintf(c_line," SubEv ID %6d Type/Subtype %5d %5d Length %5d[w] Control %2d Subcrate %2d",
+ ps_ves10_1->i_procid,
+ ps_ves10_1->i_type,
+ ps_ves10_1->i_subtype,
+ ps_ves10_1->l_dlen,
+ ps_ves10_1->h_control,
+ ps_ves10_1->h_subcrate);
+ printf("%s\n",c_line);
+ if(l_ldata != 0)
+ { /* output data */
+ if((l_long != 0) | (l_hex != 0))
+ { /* In this case we assume data as one longword per channel */
+ for(l=0;l>16)&0xffff,*pl_data&0xffff);
+ else sprintf(c_line,"%8d ",*pl_data);
+ strncat(c_full, c_line, sizeof(c_full)-1);
+ pl_data++;
+ if(l%8 == 7)
+ {
+ printf("%s\n",c_full);
+ strcpy(c_full," ");
+ }
+ }
+ if(strlen(c_full) > 2)printf("%s\n",c_full);
+ strcpy(c_full," ");
+ }
+ else
+ { /* In this case we assume data as two words per channel */
+ for(l=0;l>16)&0xffff);
+ strncat(c_full, c_line, sizeof(c_full)-1);
+ pl_data++;
+ if(l%4 == 3)
+ {
+ printf("%s\n",c_full);
+ strcpy(c_full," ");
+ }
+ }
+ if(strlen(c_full) > 2)printf("%s\n",c_full);
+ strcpy(c_full," ");
+ }
+ }
+ }
+ }
+ }
+ return(0);
+}
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_source_port */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_source_port(long l_port) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_source_port sets port number for event source */
+/*+ ARGUMENTS : */
+/*+ l_port : Port number: */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*+ Declaration : */
+/* INTS4 f_evt_source_port(INTS4); */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_source_port(INTS4 l_port)
+{
+ l_gl_source_port=l_port;
+ if (l_port>0) printf("Use MBS source port %d\n",l_port);
+ return 0;
+}
+
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_rev_port */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_rev_port(long l_port) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_rev_port sets port number for event server */
+/*+ ARGUMENTS : */
+/*+ l_port : Port number: */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*+ Declaration : */
+/* INTS4 f_evt_rev_port(INTS4); */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_rev_port(INTS4 l_port)
+{
+ l_gl_source_port=l_port;
+ if (l_port>0) printf("Use MBS source port %d\n",l_port);
+ return 0;
+}
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_get_open */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_open(long l_mode, char &c_server[], s_evt_channel &s_chan, */
+/* char **ps_info, long l_sample,l_para)*/
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_get_open opens an event stream from specified*/
+/* channel. */
+/*+ ARGUMENTS : */
+/*+ l_mode : Type of server: */
+/*- GETEVT__FILE : Input from file */
+/*- GETEVT__STREAM : Input from MBS stream server */
+/*- GETEVT__TRANS : Input from MBS transport */
+/*- GETEVT__EVENT : Input from MBS event server */
+/*- GETEVT__REVSERV: Input from remote event server */
+/*+ c_server : Node of server or file name. */
+/*+ s_chan : structure s_evt_channel, must be allocated. */
+/*+ ps_info : address of pointer. If it is not NULL, then */
+/* try to return file header or other information */
+/* about server. If it is NULL, then returns nothing. */
+/*+ l_sample : used by event server to send only every */
+/* 'l_sample' event. */
+/*+ l_para : currently not used */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__NOFILE : file does not exist. */
+/*- GETEVT__RDERR : read server error. */
+/*- GETEVT__NOSERVER : can not connect server. */
+/*+ Declaration : */
+/* INTS4 f_evt_get_open( */
+/* INTS4, CHARS *, s_evt_channel *, CHARS **, INTS4, INTS4); */
+/*+ FUNCTION : Opens the input channel and save context in s_chan. */
+/*+ NOTE : Up to four input channels can be opened. */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_get_open(INTS4 l_mode, CHARS *pc_server, s_evt_channel *ps_chan,
+ CHARS **ps_info, INTS4 l_sample, INTS4 l_param)
+{
+
+ INTS4 l_swap, l_swap_head, l_is_goosybuf, l_filehead=0, l_size, l_size_head, l_dummy, l_header_size = 0, l_port;
+ CHARS c_file[256], *pc_temp;
+ s_filhe *ps_filhe;
+ INTS4 l_status;
+
+ ps_chan->cb_polling = NULL;
+
+ l_port = l_gl_source_port;
+
+#ifndef GSI__WINNT
+// disable automatic detection of RFIO on Windows while file name can contain ":"
+ if((pc_temp=strchr(pc_server,':')) != NULL) {
+ l_mode=GETEVT__RFIO;
+ /* printf("rfio file %s\n",pc_server);*/
+ }
+#endif
+
+#ifndef RFIO
+ if(l_mode == GETEVT__RFIO)
+ {
+ printf("rfio not supported!\n");
+ return(GETEVT__NOFILE);
+ }
+#endif
+
+ if(ps_info != NULL) *ps_info=NULL;
+ // when timeout is already set by f_evt_timeout(), do not overwrite
+ if(ps_chan->l_timeout == 0) ps_chan->l_timeout=-1; /* no timeout */
+ strcpy(ps_chan->c_channel,pc_server);
+ switch(l_mode) {
+ case GETEVT__FILE :
+ strcpy(c_file,pc_server);
+ if(strlen(c_file) < 5) strncat(c_file, ".lmd", sizeof(c_file)-1);
+ else {
+ pc_temp = (CHARS *) &c_file[strlen(c_file)-4];
+ if((strcmp(pc_temp,".LMD") != 0) &&
+ (strcmp(pc_temp,".lmd") != 0)) strncat(c_file, ".lmd", sizeof(c_file)-1);
+ }
+
+ if((ps_chan->l_channel_no=open(c_file,GET__OPEN_FLAG))== -1)
+ {
+ return(GETEVT__NOFILE);
+ }
+ /* read first 512 bytes */
+ if(read(ps_chan->l_channel_no,c_temp,MIN_BUF_LGTH)!=MIN_BUF_LGTH) {
+ printf("LMD format error: no LMD file: %s\n",c_file);
+ close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+// DABC
+ ps_chan->pLmd=NULL;
+ if((*((INTS4 *)(c_temp+4)) == LMD__TYPE_FILE_HEADER_101_1)||
+ (*((INTS4 *)(c_temp+4)) == 0x65000100)){
+ close(ps_chan->l_channel_no);
+ ps_chan->pLmd=fLmdAllocateControl();
+ fLmdGetOpen(ps_chan->pLmd,c_file,NULL,LMD__BUFFER,LMD__NO_INDEX);
+ ps_chan->l_server_type=l_mode;
+ return GETEVT__SUCCESS;
+ }
+// -- DABC
+ /* check for file header, return size and swap */
+ f_evt_check_buf(c_temp, &l_size_head, &l_is_goosybuf, &l_swap_head, &l_filehead);
+ if(((l_is_goosybuf == 0) & (l_filehead == 0)) | (l_size_head == 0)) {
+ printf("LMD format error: swap=%d, header=%d, isLMD=%d, size=%d\n",l_swap_head,l_filehead,l_is_goosybuf,l_size_head);
+ close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+
+ /* read file header and first buffer and check for goosy header */
+ if(l_filehead == 1) {
+ lseek(ps_chan->l_channel_no, 0, SEEK_SET); /* rewind file */
+ l_header_size=l_size_head;
+ if(((s_filhe *)c_temp)->filhe_dlen > MAX__DLEN){
+ l_header_size=((s_filhe *)c_temp)->filhe_used*2+48;
+ // printf("Large buffer, read short header %d bytes\n",l_header_size);
+ }
+ if(read(ps_chan->l_channel_no,c_temp,l_header_size)!=l_header_size){
+ printf("LMD format error: no LMD file: %s\n",c_file);
+ close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+ if(read(ps_chan->l_channel_no,c_temp,MIN_BUF_LGTH)!=MIN_BUF_LGTH) {
+ close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__RDERR);
+ }
+ f_evt_check_buf(c_temp, &l_size, &l_is_goosybuf, &l_swap, &l_dummy);
+ if((l_is_goosybuf == 0) | (l_size != l_size_head) | (l_swap != l_swap_head)) {
+ printf("LMD format error: swap=%d, isLMD=%d, size=%d\n",l_swap,l_is_goosybuf,l_size);
+ close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+ }/* check buffer behind header */
+ ps_chan->l_buf_size=l_size_head;
+ lseek(ps_chan->l_channel_no, 0, SEEK_SET); /* rewind file */
+ if(ps_info != NULL) *ps_info=NULL;
+ /* found file header */
+ if(l_filehead == 1) {
+ if(read(ps_chan->l_channel_no,c_temp,l_header_size)!=l_header_size) {
+ printf("LMD format error: no LMD file: %s\n",c_file);
+ close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+ ps_filhe = (s_filhe *) c_temp;
+ if(ps_info != NULL) {/* if user want file header be returned */
+ if( l_swap_head == 1) f_evt_swap_filhe((s_bufhe *)ps_filhe);
+ *ps_info=c_temp; /* now , get file header and return */
+ }
+ /*
+ printf("type %d, subtype %d\n",ps_filhe->filhe_type,ps_filhe->filhe_subtype);
+ printf("strings %d %d %d %d %d %x\n",
+ ps_filhe->filhe_label_l,
+ ps_filhe->filhe_file_l,
+ ps_filhe->filhe_user_l,
+ ps_filhe->filhe_run_l,
+ ps_filhe->filhe_exp_l,
+ ps_filhe->filhe_lines);
+ pi=(INTS2 *)&ps_filhe->s_strings;
+ for(l_dummy=0;l_dummyfilhe_lines;l_dummy++)
+ {
+ printf("comment %d, %s\n",*pi,(c_temp+366+l_dummy*80));
+ pi += 40;
+ }
+ */
+ } /* file header */
+
+ /* points to a real buffer start */
+ /* and read header buffer, if there */
+ ps_chan->l_io_buf_size=ps_chan->l_buf_size;
+ /* may larger, but must multiplexed */
+ break;
+ case GETEVT__STREAM :
+
+ if (l_port<=0) l_port = PORT__STREAM_SERV;
+
+ /* initialize connection with stream server */
+ if(f_stc_connectserver(pc_server,l_port,&ps_chan->l_channel_no,
+ &s_tcpcomm_st_evt)!=STC__SUCCESS)
+ {
+ return(GETEVT__NOSERVER);
+ }
+
+ l_status=f_stc_read(c_temp,16,ps_chan->l_channel_no,ps_chan->l_timeout);
+ if(l_status == STC__TIMEOUT) return(GETEVT__TIMEOUT);
+ if(l_status != STC__SUCCESS) return(GETEVT__RDERR);
+
+ if( *((INTS4 *)(c_temp))!=1)f_evt_swap(c_temp, 16);
+ ps_chan->l_buf_size=*((INTS4 *)(c_temp+4)); /* buffer size */
+ ps_chan->l_bufs_in_stream=*((INTS4 *)(c_temp+8));
+ /* # buffers per stream */
+ ps_chan->l_stream_bufs = 0; /* counter */
+
+ ps_chan->l_io_buf_size=(ps_chan->l_buf_size)*(ps_chan->l_bufs_in_stream);
+// DABC
+ ps_chan->pLmd=NULL;
+ if(*((INTS4 *)(c_temp+12)) == 0) {
+ ps_chan->pLmd=fLmdAllocateControl();
+ ps_chan->pLmd->pTCP=&s_tcpcomm_st_evt;
+ // SL: we should deliver default portnumber while it is used only to identify transport
+ fLmdInitMbs(ps_chan->pLmd,pc_server,ps_chan->l_buf_size,ps_chan->l_bufs_in_stream,0,PORT__STREAM_SERV,ps_chan->l_timeout);
+ printf("f_evt_get_open for STREAM: port=%d timeout=%d \n",l_port, ps_chan->l_timeout);
+
+ ps_chan->l_server_type=l_mode;
+ return GETEVT__SUCCESS;
+ }
+// -- DABC
+ break;
+ case GETEVT__TRANS :
+
+ if (l_port<=0) l_port = PORT__TRANSPORT;
+
+ /* initialize connection with stream server */
+ if(f_stc_connectserver(pc_server,l_port,&ps_chan->l_channel_no,
+ &s_tcpcomm_st_evt)!=STC__SUCCESS)
+ {
+ return(GETEVT__NOSERVER);
+ }
+
+ l_status=f_stc_read(c_temp,16,ps_chan->l_channel_no,ps_chan->l_timeout);
+ if(l_status == STC__TIMEOUT) return(GETEVT__TIMEOUT);
+ if(l_status != STC__SUCCESS) return(GETEVT__RDERR);
+
+ if( *((INTS4 *)(c_temp))!=1)f_evt_swap(c_temp, 16);
+ ps_chan->l_buf_size=*((INTS4 *)(c_temp+4)); /* buffer size */
+ ps_chan->l_bufs_in_stream=*((INTS4 *)(c_temp+8));
+ /* # buffers per stream */
+ ps_chan->l_io_buf_size=ps_chan->l_buf_size;
+// DABC
+ ps_chan->pLmd=NULL;
+ if(*((INTS4 *)(c_temp+12)) == 0) {
+ ps_chan->pLmd=fLmdAllocateControl();
+ ps_chan->pLmd->pTCP=&s_tcpcomm_st_evt;
+ fLmdInitMbs(ps_chan->pLmd,pc_server,ps_chan->l_buf_size,ps_chan->l_bufs_in_stream,0,PORT__TRANSPORT,ps_chan->l_timeout);
+ printf("f_evt_get_open for TRANSPORT: port=%d timeout=%d \n",l_port, ps_chan->l_timeout);
+ ps_chan->l_server_type=l_mode;
+ return GETEVT__SUCCESS;
+ }
+// -- DABC
+ break;
+ case GETEVT__REVSERV :
+ if (l_port<=0) l_port = PORT__EVENT_SERV;
+ if(f_evcli_con(ps_chan, pc_server, l_port, -1, l_sample)!=STC__SUCCESS)
+ {
+ return(GETEVT__NOSERVER);
+ }
+ break;
+ case GETEVT__EVENT :
+ if (l_port<=0) l_port = PORT__EVENT_SERV;
+ if(f_evcli_con(ps_chan, pc_server, l_port, -1, l_sample)!=STC__SUCCESS)
+ {
+ return(GETEVT__NOSERVER);
+ }
+ break;
+ case GETEVT__RFIO :
+ ps_chan->l_channel_no=-1;
+ ps_chan->l_channel_no=RFIO_open(pc_server,GET__OPEN_FLAG,0);
+ if(ps_chan->l_channel_no < 0) return(GETEVT__NOSERVER);
+ /* read first 512 bytes */
+ if(RFIO_read(ps_chan->l_channel_no,c_temp,MIN_BUF_LGTH)!=MIN_BUF_LGTH)
+ {
+ printf("LMD format error: no LMD file: %s\n",pc_server);
+ RFIO_close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+ /* check for file header, return size and swap */
+ f_evt_check_buf(c_temp, &l_size_head, &l_is_goosybuf, &l_swap_head, &l_filehead);
+ if(((l_is_goosybuf == 0) & (l_filehead == 0)) | (l_size_head == 0))
+ {
+ printf("LMD format error: swap=%d, header=%d, isLMD=%d, size=%d\n",l_swap_head,l_filehead,l_is_goosybuf,l_size_head);
+ RFIO_close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+ /* read file header and first buffer and check for goosy header */
+ if(l_filehead == 1)
+ {
+ RFIO_lseek(ps_chan->l_channel_no, 0, SEEK_SET); /* rewind file */
+ if(RFIO_read(ps_chan->l_channel_no,c_temp,l_size_head)!=l_size_head)
+ {
+ printf("LMD format error: no LMD file: %s\n",pc_server);
+ RFIO_close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+ if(RFIO_read(ps_chan->l_channel_no,c_temp,MIN_BUF_LGTH)!=MIN_BUF_LGTH)
+ {
+ RFIO_close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__RDERR);
+ }
+ f_evt_check_buf(c_temp, &l_size, &l_is_goosybuf, &l_swap, &l_dummy);
+ if((l_is_goosybuf == 0) | (l_size != l_size_head) | (l_swap != l_swap_head))
+ {
+ printf("LMD format error: swap=%d, isLMD=%d, size=%d\n",l_swap,l_is_goosybuf,l_size);
+ RFIO_close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+ }/* check buffer behind header */
+ ps_chan->l_buf_size=l_size_head;
+ RFIO_lseek(ps_chan->l_channel_no, 0, SEEK_SET); /* rewind file */
+ if(ps_info != NULL)*ps_info=NULL;
+ /* found file header */
+ if(l_filehead == 1)
+ {
+ if(RFIO_read(ps_chan->l_channel_no,c_temp,l_size_head)!=l_size_head)
+ {
+ printf("LMD format error: no LMD file: %s\n",pc_server);
+ RFIO_close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ return(GETEVT__NOLMDFILE);
+ }
+ ps_filhe=(s_filhe *)c_temp;
+ if(ps_info != NULL) /* if user want file header be returned */
+ {
+ if( l_swap_head == 1) f_evt_swap_filhe((s_bufhe *)ps_filhe);
+ *ps_info=c_temp; /* now , get file header and return */
+ }
+ /*
+ printf("type %d, subtype %d\n",ps_filhe->filhe_type,ps_filhe->filhe_subtype);
+ printf("strings %d %d %d %d %d %x\n",
+ ps_filhe->filhe_label_l,
+ ps_filhe->filhe_file_l,
+ ps_filhe->filhe_user_l,
+ ps_filhe->filhe_run_l,
+ ps_filhe->filhe_exp_l,
+ ps_filhe->filhe_lines);
+ pi=(INTS2 *)&ps_filhe->s_strings;
+ for(l_dummy=0;l_dummyfilhe_lines;l_dummy++)
+ {
+ printf("comment %d, %s\n",*pi,(c_temp+366+l_dummy*80));
+ pi += 40;
+ }
+ */
+ }/* file header */
+ ps_chan->l_io_buf_size=ps_chan->l_buf_size;
+ break;
+ default :
+ if(ps_info != NULL) *ps_info=NULL;
+ return(GETEVT__NOSERVER);
+ } /* end of switch */
+
+ if((l_mode != GETEVT__EVENT)&(l_mode != GETEVT__REVSERV))
+ {
+ if( (ps_chan->pc_io_buf=malloc(ps_chan->l_io_buf_size))==NULL)
+ {
+ printf("Memory allocation error\n");
+ exit(2);
+ }
+ ps_chan->l_evt_buf_size=ps_chan->l_io_buf_size;
+ if( (ps_chan->pc_evt_buf=malloc(ps_chan->l_evt_buf_size))==NULL)
+ {
+ printf("Memory allocation error\n");
+ exit(2);
+ }
+ } /* l_mode != GETEVT__EVENT */
+ ps_chan->l_server_type=l_mode;
+ ps_chan->l_first_get=1; /* so we will first call f_getvet_get */
+ return GETEVT__SUCCESS;
+} /* end of f_evt_get_open */
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_get_event */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_event(s_evt_channel &s_chan, long **ppl_buffer, long **ppl_goobuf) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_get_event returnes address of event */
+/*+ ARGUMENTS : */
+/*+ s_chan : Input channel from open. */
+/*+ ppl_buffer: Address of pointer. Returns address of event. */
+/*+ ppl_goobuf: Address of pointer. Returns address of buffer. */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__FRAGMENT : Event fragment found. */
+/*- GETEVT__NOMORE : No more events. */
+/*- GETEVT__RDERR : read server or file error */
+/*- GETEVT__TIMEOUT : when enabled by f_evt_timeout */
+/*+ Declaration : */
+/* INTS4 f_evt_get_event( */
+/* s_evt_channel *, INTS4 **, INTS4 **); */
+/*+ FUNCTION : Get next event and returnes pointer. The pointer */
+/* may point to the event in the buffer or internal */
+/* event buffer (spanned events). The content of the */
+/* pointer may be destroyed by next call. */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_get_event(s_evt_channel *ps_chan, INTS4 **ppl_buffer, INTS4 **ppl_goobuf)
+{
+ INTS4 l_temp,l_prev_ok = 1, l_stat = 0, l_used;
+ s_bufhe *ps_bufhe_cur = NULL;
+ sMbsHeader *pevt = NULL;
+
+// DABC
+
+ if(ps_chan->pLmd != NULL) {
+ if(ps_chan->l_server_type == GETEVT__TRANS) {
+ l_stat = fLmdGetMbsEvent(ps_chan->pLmd, &pevt);
+ } else if(ps_chan->l_server_type == GETEVT__STREAM) {
+ l_stat = fLmdGetMbsEvent(ps_chan->pLmd, &pevt);
+ } else if(ps_chan->l_server_type == GETEVT__FILE) {
+ l_stat = fLmdGetElement(ps_chan->pLmd,LMD__NO_INDEX, &pevt);
+ }
+
+ // any error, then pointer is null
+ if(pevt==NULL) {
+ if (ps_chan->l_server_type == GETEVT__FILE){
+ if(l_stat == GETLMD__NOMORE) return GETEVT__NOMORE;
+ if(l_stat == GETLMD__EOFILE) return GETEVT__NOMORE;
+ if(l_stat == GETLMD__NOBUFFER) return GETEVT__FAILURE;
+ return GETEVT__RDERR;
+ } else {
+ if(l_stat == LMD__TIMEOUT) return GETEVT__TIMEOUT;
+ return GETEVT__RDERR;
+ }
+ }
+ // OK
+ if(ppl_goobuf)*ppl_goobuf = NULL;
+ *ppl_buffer = (INTS4 *)pevt;
+ return(GETEVT__SUCCESS);
+ }
+// -- DABC
+
+ if((ps_chan->l_server_type == GETEVT__EVENT)|(ps_chan->l_server_type == GETEVT__REVSERV))
+ {
+ *ppl_goobuf = NULL;
+ if(f_evcli_evt(ps_chan) != STC__SUCCESS) /* no more event, get new buffer */
+ {
+ l_stat = f_evcli_buf(ps_chan);
+ if(l_stat == STC__TIMEOUT) return(GETEVT__TIMEOUT);
+ if(l_stat != STC__SUCCESS) return(GETEVT__FAILURE);
+ }
+ *ppl_buffer = (INTS4 *) ps_chan->pc_evt_buf;
+ return(GETEVT__SUCCESS);
+ }
+
+ /* e.g. read_buffer is 16384, GOOSY buffer may be only 2048, *
+ * this ps_chan->l_io_buf_posi indicats when the read_buffer is finished */
+
+ if(ps_chan->l_first_get==1)
+ {
+ ps_chan->l_buf_posi=0; /* goosy buffer position */
+ ps_chan->l_buf_lmt=0; /* end of this goosy buffer */
+ ps_chan->l_io_buf_posi=MAX_LONG; /* Iuput buffer(for read file) position */
+ ps_chan->l_first_buf=1; /* boolean */
+ ps_chan->l_first_get=0; /* boolean */
+ }
+ /* why we need this part codes? beacause we may (open, get, close) *
+ * and (open, get, close) again!!! Especially when we use m-histo *
+ * so the second or later (open,get,close) should reset these *
+ * static value */
+
+ ps_chan->l_evt_buf_posi=0;
+/* above, internal event buffer position, internal buffer will be returned */
+
+ while(1)
+ {
+ /* if previous goosy buffer has finished, read a new buffer from i/o buffer,
+ or from file if i/o buffer is all readout */
+ while (ps_chan->l_buf_posi >= ps_chan->l_buf_lmt)
+ {
+ /* if this i/o buffer is read to end */
+ /* end of this read_buffer which may contain several GOOSY buffers*/
+ if(ps_chan->l_io_buf_posi>=ps_chan->l_io_buf_size)
+ {
+ if((l_temp=f_evt_get_newbuf(ps_chan))!=GETEVT__SUCCESS) return(l_temp);
+ ps_chan->l_io_buf_posi=0;
+ } /* end of real read server */
+ ps_chan->ps_bufhe = (s_bufhe*) (ps_chan->pc_io_buf+ps_chan->l_io_buf_posi);
+ l_prev_ok = (ps_chan->l_buf_no == (ps_chan->ps_bufhe->l_buf-1)) ? 1 : 0;
+ ps_chan->l_buf_no = ps_chan->ps_bufhe->l_buf;
+ if(ps_chan->ps_bufhe->i_type == 2000) { /* file header */
+ printf("Unsolicited file header found!\n");
+ ps_chan->l_io_buf_posi += ps_chan->l_buf_size;
+ ps_chan->l_buf_posi = ps_chan->l_io_buf_posi;
+ ps_chan->l_buf_lmt = ps_chan->l_io_buf_posi;
+ } else {
+ l_used=ps_chan->ps_bufhe->l_free[2]; // large buffers HE, Oct 2007
+ if(ps_chan->ps_bufhe->l_dlen <= MAX__DLEN)l_used=ps_chan->ps_bufhe->i_used;
+ ps_chan->l_buf_posi = ps_chan->l_io_buf_posi + sizeof(s_bufhe);
+ ps_chan->l_buf_lmt = ps_chan->l_buf_posi + l_used*2;
+ ps_chan->l_io_buf_posi += ps_chan->l_buf_size;
+ }
+ } /* end of read file while loop */
+
+ /* now, ps_chan->l_buf_posi points to start of an event or spanned event */
+ ps_chan->ps_ve10_1 = (s_ve10_1 *) (ps_chan->pc_io_buf + ps_chan->l_buf_posi);
+ if( (ps_chan->l_evt_buf_posi != 0) || ((ps_chan->ps_bufhe->h_end==1) && (ps_chan->l_first_buf==1)) ) { /* if this is a spanned part of an event */
+ ps_chan->l_buf_posi += sizeof(s_evhe);
+ ps_chan->l_frag_len = ps_chan->ps_ve10_1->l_dlen*2;
+ } else /* if this is a real start of an event */
+ ps_chan->l_frag_len = (ps_chan->ps_ve10_1->l_dlen-4)*2 + sizeof(s_ve10_1);
+
+ if(ps_chan->l_frag_len + ps_chan->l_buf_posi > ps_chan->l_buf_lmt)
+ {
+ return(GETEVT__FRAGMENT);
+ }
+
+ /* if ps_chan->l_buf_posi is not start of an event and ps_chan->l_first_buf =1 *
+ * then skip to next event */
+ if((ps_chan->ps_bufhe->h_end==1)&&((ps_chan->l_first_buf==1) || (l_prev_ok == 0))) {
+ /* if the first buffer is spanned at begin, then skip */
+ ps_chan->l_first_buf=0; /* 24-Apr-1996 */
+ l_prev_ok=1; /* 2001 HE */
+ ps_chan->l_evt_buf_posi=0; /* 2001 HE stuff in event buffer obsolete */
+ ps_chan->l_buf_posi += ps_chan->l_frag_len;
+ /* now,ps_chan->l_buf_posi points to start of an event or spanned event */
+ continue; /* continue "while" loop */
+ }
+
+ ps_chan->l_first_buf=0;
+
+ /* if ps_chan->l_buf_posi is start of an event and the event is not *
+ * spanned, then return pointer */
+ if( (ps_chan->l_evt_buf_posi == 0) &&
+ ( (ps_chan->ps_bufhe->h_begin == 0) || ((ps_chan->l_buf_posi+ps_chan->l_frag_len) < ps_chan->l_buf_lmt) ) )
+ {
+ *ppl_buffer = (INTS4 *)(ps_chan->pc_io_buf+ps_chan->l_buf_posi);
+ ps_chan->l_buf_posi += ps_chan->l_frag_len;
+ ps_chan->l_evt_buf_posi = 0;
+ if(ppl_goobuf) *ppl_goobuf = (INTS4 *) (ps_chan->ps_bufhe);
+ return(GETEVT__SUCCESS);
+ }
+
+ /* 2001 HE if we start a spanned event, save buffer header of first buffer */
+ if(ps_chan->l_evt_buf_posi == 0)
+ {
+ memcpy((CHARS *)&ps_chan->s_bufhe_1,(CHARS *)ps_chan->ps_bufhe,sizeof(s_bufhe));
+ ps_bufhe_cur=(s_bufhe *)&ps_chan->s_bufhe_1;
+ }
+ /* copy the part of this event which in this buffer into *
+ * internal buffer, data will be moved by realloc function */
+ if(ps_chan->l_evt_buf_sizel_evt_buf_posi+ps_chan->l_frag_len)
+ {
+ ps_chan->l_evt_buf_size=ps_chan->l_evt_buf_posi+ps_chan->l_frag_len;
+ if( (ps_chan->pc_evt_buf=realloc
+ (ps_chan->pc_evt_buf, ps_chan->l_evt_buf_size))==NULL)
+ {
+ printf("Memory allocation error\n");
+ exit(2);
+ }
+ }
+ memcpy(ps_chan->pc_evt_buf+ps_chan->l_evt_buf_posi,ps_chan->pc_io_buf+ps_chan->l_buf_posi,
+ ps_chan->l_frag_len);
+ ps_chan->l_buf_posi += ps_chan->l_frag_len;
+ if(ps_chan->l_evt_buf_posi == 0)
+ {
+ }
+ ps_chan->l_evt_buf_posi += ps_chan->l_frag_len;
+
+ if((ps_chan->ps_bufhe->h_begin!=1)||(ps_chan->l_buf_posil_buf_lmt))
+ {
+ /* change event header's l_dlen */
+ ((s_ve10_1 *)(ps_chan->pc_evt_buf))->l_dlen=ps_chan->l_evt_buf_posi/2-4;
+ *ppl_buffer=(INTS4 *)(ps_chan->pc_evt_buf);
+ if(ppl_goobuf)*ppl_goobuf=(INTS4 *)(ps_bufhe_cur);
+ return(GETEVT__SUCCESS);
+ }
+ }/* if this event spanned to next buffer, then loop */
+} /* end of f_evt_get_event */
+
+/*1+ C Main ******************+****************************************/
+/*+ Module : f_evt_get_close */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_close( s_evt_channel &s_chan) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_get_close closes event stream of specified */
+/* channel. */
+/*+ ARGUMENTS : */
+/*+ s_chan : Input channel from open. */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__CLOSE_ERR : close server or file error */
+/*+ Declaration : */
+/* INTS4 f_evt_get_close(s_evt_channel *); */
+/*+ FUNCTION : Closes the specified input channel. */
+/*1- C Main ******************+****************************************/
+INTS4 f_evt_get_close(s_evt_channel * ps_chan)
+{
+ INTS4 l_close_failure;
+
+// DABC
+ if(ps_chan->pLmd != NULL){
+ if(ps_chan->l_server_type == GETEVT__TRANS)fLmdCloseMbs(ps_chan->pLmd);
+ else if(ps_chan->l_server_type == GETEVT__STREAM)fLmdCloseMbs(ps_chan->pLmd);
+ else if(ps_chan->l_server_type == GETEVT__FILE) fLmdGetClose(ps_chan->pLmd);
+ free(ps_chan->pLmd);
+ ps_chan->pLmd=NULL;
+ return GETEVT__SUCCESS;
+ }
+// -- DABC
+ l_close_failure=0;
+ if(ps_chan->l_channel_no >= 0)
+ {
+ switch(ps_chan->l_server_type)
+ {
+ case GETEVT__FILE :
+ if(close(ps_chan->l_channel_no)==-1) l_close_failure=1;
+ if(ps_chan->pc_io_buf != NULL)free(ps_chan->pc_io_buf);
+ if(ps_chan->pc_evt_buf != NULL)free(ps_chan->pc_evt_buf);
+ break;
+ case GETEVT__STREAM :
+ /* disconnect with stream server */
+ f_stc_write("CLOSE", 12, ps_chan->l_channel_no);
+ if(f_stc_discclient(ps_chan->l_channel_no)!=STC__SUCCESS)l_close_failure=1;
+ if(f_stc_close(&s_tcpcomm_st_evt)!=STC__SUCCESS) l_close_failure=1;
+ if(ps_chan->pc_io_buf != NULL)free(ps_chan->pc_io_buf);
+ if(ps_chan->pc_evt_buf != NULL)free(ps_chan->pc_evt_buf);
+ break;
+ case GETEVT__TRANS :
+ /* disconnect with stream server */
+ if(f_stc_discclient(ps_chan->l_channel_no)!=STC__SUCCESS)l_close_failure=1;
+ if(f_stc_close(&s_tcpcomm_st_evt)!=STC__SUCCESS) l_close_failure=1;
+ if(ps_chan->pc_io_buf != NULL)free(ps_chan->pc_io_buf);
+ if(ps_chan->pc_evt_buf != NULL)free(ps_chan->pc_evt_buf);
+ break;
+ case GETEVT__REVSERV :
+ case GETEVT__EVENT :
+ if(f_evcli_close(ps_chan)!=STC__SUCCESS) l_close_failure=1;
+ break;
+ case GETEVT__RFIO :
+ RFIO_close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ if(ps_chan->pc_io_buf != NULL)free(ps_chan->pc_io_buf);
+ if(ps_chan->pc_evt_buf != NULL)free(ps_chan->pc_evt_buf);
+ break;
+ default :
+ l_close_failure=1;
+ } /* end of switch */
+ ps_chan->pc_io_buf=NULL;
+ ps_chan->l_channel_no=-1;
+ if(l_close_failure==1) return(GETEVT__CLOSE_ERR);
+ return GETEVT__SUCCESS;
+ }
+return GETEVT__SUCCESS;
+
+} /* end of f_evt_get_close */
+
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_put_open */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_put_open(char *c_file[], long l_size, long l_stream, long l_type, */
+/* long l_subtype, s_evt_channel *ps_chan, char *ps_filhe) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_put_open opens an event output stream. */
+/*+ ARGUMENTS : */
+/*+ c_file : Name of file. */
+/*+ l_size : Size of output buffers in bytes. */
+/*+ l_stream : Number of buffers with spanning events. */
+/*+ l_type : Buffer type number */
+/*+ l_subtype : Buffer subtype number */
+/*+ ps_chan : Address of channel structure which will be returned.*/
+/*+ ps_filhe : Address of user specified file header */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- PUTEVT__SUCCESS : success. */
+/*- PUTEVT__FILE_EXIST: file already exists. */
+/*- PUTEVT__FAILURE : failure. */
+/*+ Declaration : */
+/* INTS4 f_evt_put_open( */
+/* CHARS *,INTS4,INTS4,INTS4,INTS4,s_evt_channel *,CHARS *); */
+/*+ FUNCTION : Opens the output channel and save context in */
+/* s_evt_channel structure. */
+/*+ NOTE : Up to four output channels can be opened. */
+/* User Example : In m_lea_user.c */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_put_open(CHARS *pc_file, INTS4 l_size, INTS4 l_stream,
+ INTS4 l_type, INTS4 l_subtype, s_evt_channel *ps_chan, CHARS *ps_filhe)
+{
+ s_filhe *ps_file_head;
+ INTS4 l_write_size;
+ INTS4 l_status;
+ time_t s_timet;
+ struct timespec s_timespec;
+ CHARS c_mode[80];
+ CHARS c_file[256], *pc_temp;
+
+// DABC
+ ps_chan->pLmd=NULL;
+ if(l_stream == 0) {
+ ps_chan->pLmd=fLmdAllocateControl();
+ l_status=fLmdPutOpen(ps_chan->pLmd,pc_file,NULL,l_size,
+ LMD__NO_OVERWRITE,LMD__INDEX,LMD__LARGE_FILE);
+ return(l_status);
+ }
+// -- DABC
+
+ ps_chan->l_first_put=1;
+
+ ps_chan->l_buf_size=l_size;
+ ps_chan->l_bufs_in_stream=l_stream;
+ ps_chan->l_buf_type=l_type;
+ ps_chan->l_buf_subtype=l_subtype;
+ ps_chan->l_io_buf_size=ps_chan->l_buf_size * ps_chan->l_bufs_in_stream;
+ if( (ps_chan->pc_io_buf=malloc(ps_chan->l_io_buf_size))==NULL)
+ {
+ printf("Memory allocation error\n");
+ exit(2);
+ }
+
+ strcpy(c_file,pc_file);
+ if(strlen(c_file) < 5) strncat(c_file,".lmd", sizeof(c_file)-1);
+ else
+ {
+ pc_temp = (CHARS *) &c_file[strlen(c_file)-4];
+ if((strcmp(pc_temp,".LMD") != 0) &&
+ (strcmp(pc_temp,".lmd") != 0)) strncat(c_file, ".lmd", sizeof(c_file)-1);
+ }
+ if((ps_chan->l_channel_no=open(c_file,PUT__OPEN_APD_FLAG) )!= -1) {
+ return(PUTEVT__FILE_EXIST);
+ } else
+ {
+ if((ps_chan->l_channel_no=open(c_file,PUT__CRT_FLAG,
+ DEF_FILE_ACCE) )== -1)
+ return(PUTEVT__FAILURE);
+ /* open OK */
+ else
+ {
+ /* output file header */
+ ps_file_head=(s_filhe *)ps_chan->pc_io_buf;
+ /* if user specify file header */
+ if(ps_filhe != NULL) {
+ memcpy(ps_file_head, ps_filhe,ps_chan->l_buf_size );
+ } else {
+ memset( ps_file_head, 0, ps_chan->l_buf_size);
+ snprintf(ps_file_head->filhe_run, sizeof(ps_file_head->filhe_run), "Pid %d%c", own_getpid(),'\0');
+ ps_file_head->filhe_run_l = (INTS2) strlen(ps_file_head->filhe_run);
+ }
+ ps_file_head->filhe_dlen=ps_chan->l_buf_size/2;
+ ps_file_head->filhe_subtype=1;
+ ps_file_head->filhe_type=2000;
+ clock_gettime(CLOCK_REALTIME, &s_timespec);
+ ps_file_head->filhe_stime[0] = (INTS4) s_timespec.tv_sec;
+ ps_file_head->filhe_stime[1] = (INTS4) s_timespec.tv_nsec/1000000;
+ ps_file_head->filhe_free[0] = 1;
+ ps_file_head->filhe_file_l = (INTS2) strlen(c_file);/* not include \0 */
+ strncpy(ps_file_head->filhe_file, c_file, sizeof(ps_file_head->filhe_file));
+ strncpy(ps_file_head->filhe_user, getenv("USER"), sizeof(ps_file_head->filhe_user)); /* user name */
+ ps_file_head->filhe_user_l = (INTS2) strlen(ps_file_head->filhe_user);
+ time(&s_timet);/* get calendar time */
+ strncpy(c_mode, ctime(&s_timet), sizeof(c_mode));
+ strncpy(ps_file_head->filhe_time, &c_mode[4], sizeof(ps_file_head->filhe_time));
+ ps_file_head->filhe_time[20]=' ';
+ l_write_size=write(ps_chan->l_channel_no,(CHARS *)ps_file_head,
+ ps_chan->l_buf_size);
+ if(l_write_size==-1)
+ {
+ return(PUTEVT__WRERR);
+ }
+ if(l_write_size!=ps_chan->l_buf_size)
+ {
+ return(PUTEVT__TOOBIG);
+ }
+ return(PUTEVT__SUCCESS);
+ }
+ }
+} /* end of f_evt_put_open */
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_put_event */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_put_event(s_evt_channel *ps_chan, long &la_evt_buf[]) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_put_event outputs event */
+/*+ ARGUMENTS : */
+/*+ ps_chan : Address of channel structure as returned from */
+/* f_evt_put_open. */
+/*+ la_evt_buf : event data array. Standard GSI event structure. */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- PUTEVT__SUCCESS : success. */
+/*- PUTEVT__WRERR : read server or file error */
+/*+ Declaration : */
+/* INTS4 f_evt_put_event(s_evt_channel *, INTS4 *); */
+/*+ FUNCTION : Copies current event into output buffer. Writes */
+/* buffer to file, when full. */
+/*1- C Main ****************+******************************************/
+
+INTS4 f_evt_put_event(s_evt_channel *ps_chan, INTS4 *pl_evt_buf)
+{
+ INTS4 l_evt_buf_posi;
+ INTS4 l_buf_remain_size; /* net free space of I/O buffer */
+ INTS4 l_write_size, l_temp, l_free;
+ INTS4 l_status;
+ CHARS *pc_addr;
+ s_bufhe *ps_bufhe;
+
+// DABC
+ if(ps_chan->pLmd != NULL){
+ l_status=fLmdPutElement(ps_chan->pLmd,(sMbsHeader *)pl_evt_buf);
+ return(l_status);
+ }
+// -- DABC
+ if(ps_chan->l_first_put==1)
+ {
+ ps_chan->l_first_put=0;
+ ps_chan->l_io_buf_posi=0;
+ ps_chan->l_buf_no=1;
+ }
+ l_evt_buf_posi=0;
+ ps_chan->l_evt_size=( ((s_ve10_1 *)(pl_evt_buf))->l_dlen)*2 + sizeof(s_evhe);
+
+ /* get l_buf_remain_size is available size in stream */
+ l_buf_remain_size = ps_chan->l_io_buf_size - ps_chan->l_io_buf_posi;
+ l_temp = (l_buf_remain_size / ps_chan->l_buf_size)*(sizeof(s_bufhe)+sizeof(s_evhe) );
+ l_buf_remain_size -= l_temp;/* minus space occupied by buffer header and spanned event header */
+
+ if(ps_chan->l_evt_size>l_buf_remain_size)/* output this i/o buffer */
+ {
+ memset(ps_chan->pc_io_buf+ps_chan->l_io_buf_posi, 0, ps_chan->l_io_buf_size-ps_chan->l_io_buf_posi);
+ /* clear rest of this GOOSY buffer */
+ l_temp=(ps_chan->l_io_buf_posi/ps_chan->l_buf_size)*ps_chan->l_buf_size;
+ if(ps_chan->l_io_buf_posi%ps_chan->l_buf_size == 0) l_temp -= ps_chan->l_buf_size;
+ /* l_temp points to start of last GOOSY buf in i/o buf area */
+ ps_chan->ps_bufhe=(s_bufhe *)(ps_chan->pc_io_buf + l_temp);
+ if(l_temp == 0)ps_chan->ps_bufhe->h_end = 0; /* first buf in stream, no end */
+ else ps_chan->ps_bufhe->h_end = ((s_bufhe *)((CHARS *)ps_chan->ps_bufhe - ps_chan->l_buf_size))->h_begin;
+ ps_chan->ps_bufhe->h_begin = 0; /* evt has end, so not spanned to next buf */
+ for(l_temp=0;l_templ_io_buf_size;l_temp+=ps_chan->l_buf_size)
+ {
+ pc_addr = ps_chan->pc_io_buf+l_temp;
+ ps_bufhe=(s_bufhe *)pc_addr;
+ if(ps_bufhe->l_evt>0)/* do not write empty buffers */
+ {
+ l_write_size=write(ps_chan->l_channel_no, pc_addr,ps_chan->l_buf_size);
+ if(l_write_size==-1) return(PUTEVT__WRERR);
+ if(l_write_size!=ps_chan->l_buf_size) return(PUTEVT__TOOBIG);
+ }
+ else ps_chan->l_buf_no--; /* decrement buffer number for not written buffer */
+ } /* buffer output loop */
+ ps_chan->l_io_buf_posi=0;
+ ps_chan->ps_bufhe=(s_bufhe *)ps_chan->pc_io_buf;
+ /* get l_buf_remain_size of new stream */
+ l_buf_remain_size = ps_chan->l_io_buf_size;
+ l_temp = (l_buf_remain_size / ps_chan->l_buf_size) * (sizeof(s_bufhe)+sizeof(s_evhe) );
+ l_buf_remain_size -= l_temp; /* minus space occupied by buf header and spanned event header */
+ l_buf_remain_size += sizeof(s_evhe);/* 1st buf always no span */
+ /* if event can not fit in a new stream, then error */
+ if(ps_chan->l_evt_size>l_buf_remain_size) return(PUTEVT__TOO_SMALLS);
+ }
+
+ if(ps_chan->l_io_buf_posi == 0)f_evt_ini_bufhe(ps_chan);/* init all buffer headers */
+
+ /* write event into i/o buf till end of event, change ps_chan->l_io_buf_posi */
+ while(l_evt_buf_posil_evt_size)
+ {
+ ps_chan->ps_ve10_1 = (s_ve10_1 *)(ps_chan->pc_io_buf + ps_chan->l_io_buf_posi);
+ if((ps_chan->l_io_buf_posi%ps_chan->l_buf_size) == 0)
+ {
+ ps_chan->l_io_buf_posi += sizeof(s_bufhe);
+ ps_chan->ps_ve10_1 = (s_ve10_1 *)(ps_chan->pc_io_buf + ps_chan->l_io_buf_posi);/* behind header */
+ if(l_evt_buf_posi != 0)
+ {
+ ps_chan->l_io_buf_posi += sizeof(s_evhe); /* behind element header */
+ l_write_size=(ps_chan->l_io_buf_posi/ps_chan->l_buf_size)*ps_chan->l_buf_size;
+ /* l_write_size points to start of this GOOSY buf in i/o buf area */
+ ps_chan->ps_bufhe=(s_bufhe *)(ps_chan->pc_io_buf + l_write_size);
+ ps_chan->ps_bufhe->i_used += sizeof(s_evhe)/2;
+ }
+ }
+ l_write_size=(ps_chan->l_io_buf_posi/ps_chan->l_buf_size)*ps_chan->l_buf_size;
+ /* l_write_size points to start of this GOOSY buf in i/o buf area */
+ ps_chan->ps_bufhe=(s_bufhe *)(ps_chan->pc_io_buf + l_write_size);
+ l_write_size = l_write_size + ps_chan->l_buf_size - ps_chan->l_io_buf_posi;
+ /* l_write_size is remain free space in this GOOSY buf */
+ if(l_write_size>(ps_chan->l_evt_size-l_evt_buf_posi))
+ l_write_size=(ps_chan->l_evt_size-l_evt_buf_posi);
+ memcpy(ps_chan->pc_io_buf + ps_chan->l_io_buf_posi, (CHARS *)pl_evt_buf + l_evt_buf_posi, l_write_size);
+ ps_chan->ps_bufhe->l_evt ++; /* number of fragments */
+ ps_chan->l_io_buf_posi += l_write_size;
+ l_evt_buf_posi += l_write_size;
+ ps_chan->ps_bufhe->i_used += l_write_size/2;
+ /* if the remain free space of GOOSY buffer does not large enough *
+ * to hold even a event header, then turn to next GOOSY buffer and *
+ * fill buffer header. or 8 long words aligned ???????? */
+ l_free=(ps_chan->l_io_buf_posi/ps_chan->l_buf_size)*ps_chan->l_buf_size;
+ /* l_free points to start of this GOOSY buf in i/o buf area */
+ l_free = l_free + ps_chan->l_buf_size - ps_chan->l_io_buf_posi;
+ if(l_free==ps_chan->l_buf_size)l_free=0;
+ /* l_free is remain free space in this GOOSY buf */
+ if(l_freel_io_buf_posi += l_free;
+ /* change spanned evt header l_dlen */
+ if(l_evt_buf_posi!=l_write_size)
+ {
+ ps_chan->ps_ve10_1->l_dlen= l_write_size/2;
+ ps_chan->ps_ve10_1->i_subtype = ps_chan->l_buf_subtype;
+ ps_chan->ps_ve10_1->i_type = ps_chan->l_buf_type;
+ }
+ else ps_chan->ps_ve10_1->l_dlen= (l_write_size-sizeof(s_evhe))/2; /* header of first frag */
+ if((ps_chan->l_io_buf_posi%ps_chan->l_buf_size) == 0)
+ {
+ if(l_evt_buf_posil_evt_size) ps_chan->ps_bufhe->h_begin = 1;
+ if(ps_chan->l_io_buf_posi > ps_chan->l_buf_size) /* so first buf in stream */
+ ps_chan->ps_bufhe->h_end = ((s_bufhe *)((CHARS *)ps_chan->ps_bufhe - ps_chan->l_buf_size))->h_begin;
+ ps_chan->ps_bufhe->l_free[1] = ((s_ve10_1 *)(pl_evt_buf))->l_dlen; /* lgth of last event in buf */
+ } /* end of processs prev buffer head and ... */
+
+ } /* end of write event into i/o buf till end of event */
+ return(PUTEVT__SUCCESS);
+} /* end of f_evt_put_event */
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_put_buffer */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_put_buffer(s_evt_channel *ps_chan, s_bufhe *ps_bufhe) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_put_buffer outputs buffer */
+/*+ ARGUMENTS : */
+/*+ ps_chan : Address of channel structure as returned from */
+/* f_evt_put_open. */
+/*+ ps_bufhe : Buffer. */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- PUTEVT__SUCCESS : success. */
+/*- PUTEVT__WRERR : read server or file error */
+/*+ Declaration : */
+/* INTS4 f_evt_put_buffer(s_evt_channel *, s_bufhe *); */
+/*+ FUNCTION : Writes buffer to file. */
+/*1- C Main ****************+******************************************/
+
+INTS4 f_evt_put_buffer(s_evt_channel *ps_chan, s_bufhe *ps_bufhe)
+{
+ INTS4 l_write_size;
+ INTS4 l_status;
+
+// DABC
+ if(ps_chan->pLmd != NULL){
+ l_status=fLmdPutBuffer(ps_chan->pLmd,(sMbsHeader *)(ps_bufhe+1),ps_bufhe->l_evt);
+ return(l_status);
+ }
+// -- DABC
+ ps_chan->l_io_buf_posi = ps_chan->l_buf_size;
+ ps_chan->l_io_buf_size = ps_chan->l_buf_size;
+ l_write_size=write(ps_chan->l_channel_no, (CHARS *) ps_bufhe, ps_chan->l_buf_size);
+ if(l_write_size==-1)
+ {
+ return(PUTEVT__WRERR);
+ }
+ if(l_write_size!=ps_chan->l_buf_size)
+ {
+ return(PUTEVT__TOOBIG);
+ }
+ return PUTEVT__SUCCESS;
+} /* end of f_evt_put_buffer */
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_put_close */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_put_close(s_evt_channel *ps_chan) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_put_close closes specified channel. */
+/*+ ARGUMENTS : */
+/*+ channel : Channel number. */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- PUTEVT__SUCCESS : success. */
+/*- PUTEVT__FAILURE : failure. */
+/*- PUTEVT__CLOSE_ERR : close server or file error */
+/*+ Declaration : */
+/* INTS4 f_evt_put_close(s_evt_channel *); */
+/*+ FUNCTION : Closes the specified output channel after writing */
+/* last buffer. */
+/*1- C Main ****************+******************************************/
+
+INTS4 f_evt_put_close(s_evt_channel *ps_chan)
+{
+ INTS4 l_write_size, l_temp, l_temp2;
+ INTS4 l_status;
+
+// DABC
+ if(ps_chan->pLmd != NULL){
+ l_status=fLmdPutClose(ps_chan->pLmd);
+ return(l_status);
+ }
+// -- DABC
+ if(ps_chan->l_first_put==1) goto g_close;
+
+ /* if not the end of GOOSY buf, fill buffer header */
+ if((ps_chan->l_io_buf_posi%ps_chan->l_buf_size) != 0)
+ {
+ l_temp=(ps_chan->l_io_buf_posi/ps_chan->l_buf_size)*ps_chan->l_buf_size;
+ /* l_temp points to start of this GOOSY buf in i/o buf area */
+ memset(ps_chan->pc_io_buf+ps_chan->l_io_buf_posi, 0,
+ l_temp+ps_chan->l_buf_size-ps_chan->l_io_buf_posi);
+ /* clear rest of this GOOSY buffer */
+ ps_chan->ps_bufhe=(s_bufhe *)(ps_chan->pc_io_buf + l_temp);
+
+ ps_chan->ps_bufhe->l_dlen = (ps_chan->l_buf_size - sizeof(s_bufhe))/2;
+ ps_chan->ps_bufhe->h_begin = 0; /* evt has end, so not spanned to next buf */
+ if(l_temp == 0) /* so fisrt buf in stream */
+ ps_chan->ps_bufhe->h_end = 0;
+ else
+ ps_chan->ps_bufhe->h_end = ((s_bufhe *)((CHARS *)ps_chan->ps_bufhe - ps_chan->l_buf_size))
+ ->h_begin;
+ ps_chan->ps_bufhe->i_used = (ps_chan->l_io_buf_posi%ps_chan->l_buf_size -
+ sizeof(s_bufhe))/2;
+ } /* end of process of infilished buffer header */
+
+ /* if at the end of io buf, need not flush */
+ if(ps_chan->l_io_buf_posi!=ps_chan->l_io_buf_size)
+ {
+ if((ps_chan->l_io_buf_posi%ps_chan->l_buf_size) != 0)
+ l_write_size=(ps_chan->l_io_buf_posi/ps_chan->l_buf_size+1) *
+ ps_chan->l_buf_size;
+ else
+ l_write_size=ps_chan->l_io_buf_posi;
+
+ for(l_temp=0;l_templ_buf_size){
+/* why use this loop instead of write the whole io_buf out? because in
+ VMS side, the record can only be l_buf_size big, not l_write_size big */
+ l_temp2=write(ps_chan->l_channel_no, ps_chan->pc_io_buf+l_temp,
+ ps_chan->l_buf_size);
+ if(l_temp2==-1)
+ {
+ return(PUTEVT__WRERR);
+ }
+ if(l_temp2!=ps_chan->l_buf_size)
+ {
+ return(PUTEVT__TOOBIG);
+ }
+ }
+ } /* end of flush */
+
+g_close:
+ free(ps_chan->pc_io_buf);
+ /* free io buffer Memory */
+
+ l_status=close(ps_chan->l_channel_no);
+ ps_chan->l_channel_no=-1;
+ if(l_status == -1) return(PUTEVT__CLOSE_ERR);
+ else return PUTEVT__SUCCESS;
+} /* end of f_evt_put_close */
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_error */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_error( long l_error , char &c_string[], long l_out ) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_error displays error messages. */
+/*+ ARGUMENTS : */
+/*+ l_error : The error id as returned from other calls */
+/*+ c_string : The string into f_evt_error() copies the message....*/
+/*+ l_out : specifies the output device for the error message. */
+/*- out = 1 : error message is copied to string. */
+/*- out = 0 : error message is printed on terminal. */
+/*+ Return type : int (longword). */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__FAILURE : failure */
+/*+ Declaration : */
+/* INTS4 f_evt_error( INTS4 , CHARS * , INTS4 ); */
+/*+ FUNCTION : f_evt_error displays the error message for the */
+/* error id ( l_error ). If out = 1 the error */
+/* message is copied into string, else */
+/* f_evt_error prints the message on terminal. */
+/*1- C Main ******************+****************************************/
+INTS4 f_evt_error( INTS4 l_error , CHARS *pc_dest , INTS4 l_out )
+{
+ CHARS c_line[80];
+
+ switch( l_error )
+ {
+ case GETEVT__NOFILE :
+ sprintf(c_line,"-I-f_evt: no such input file");
+ break;
+ case GETEVT__NOTAGFILE :
+ sprintf(c_line,"-I-f_evt: no such tag file");
+ break;
+ case GETEVT__NOTAG :
+ sprintf(c_line,"-I-f_evt: no such event tag");
+ break;
+ case GETEVT__TIMEOUT :
+ sprintf(c_line,"-I-f_evt: time out");
+ break;
+ case GETEVT__NOSERVER :
+ sprintf(c_line,"-I-f_evt: no such server");
+ break;
+ case GETEVT__RDERR :
+ sprintf(c_line,"-I-f_evt: read server error");
+ break;
+ case GETEVT__TAGRDERR :
+ sprintf(c_line,"-I-f_evt: read tag file error");
+ break;
+ case GETEVT__TAGWRERR :
+ sprintf(c_line,"-I-f_evt: write tag file error");
+ break;
+ case GETEVT__FRAGMENT :
+ sprintf(c_line,"-I-f_evt: data format error");
+ break;
+ case GETEVT__NOMORE :
+ sprintf(c_line,"-I-f_evt: no more event");
+ break;
+ case GETEVT__CLOSE_ERR:
+ sprintf(c_line,"-I-f_evt: close server error");
+ break;
+ case GETEVT__FAILURE :
+ sprintf(c_line,"-I-f_evt: failure");
+ break;
+ case GETEVT__NOCHANNEL :
+ sprintf(c_line,"-I-f_evt: too many channels");
+ break;
+ case GETEVT__NOLMDFILE :
+ sprintf(c_line,"-I-f_evt: input file is no LMD file");
+ break;
+ case GETEVT__SUCCESS :
+ sprintf(c_line,"-I-f_evt: success");
+ break;
+ case PUTEVT__FILE_EXIST :
+ sprintf(c_line,"-I-f_evt: output file already exist");
+ break;
+ case PUTEVT__WRERR :
+ sprintf(c_line,"-I-f_evt: write file error");
+ break;
+ case PUTEVT__TOOBIG :
+ sprintf(c_line,"-I-f_evt: output file too large");
+ break;
+ case PUTEVT__TOO_SMALLS:
+ sprintf(c_line,"-I-f_evt: event can not fit in a stream");
+ break;
+ case PUTEVT__CLOSE_ERR :
+ sprintf(c_line,"-I-f_evt: close output error");
+ break;
+ case PUTEVT__FAILURE :
+ sprintf(c_line,"-I-f_evt: output failure");
+ break;
+ case PUTEVT__NOCHANNEL :
+ sprintf(c_line,"-I-f_evt: too many channels");
+ break;
+ default :
+ sprintf(c_line,"-I-f_evt: unknown message id %d",l_error);
+ if(l_out == 0)printf("%s\n",c_line);
+ if(l_out==1)strcpy(pc_dest,c_line);
+ return GETEVT__FAILURE;
+ } /* end switch( l_error ) */
+
+ if(l_out == 0)printf("%s\n",c_line);
+ if(l_out == 1)strcpy(pc_dest,c_line);
+
+ return GETEVT__SUCCESS;
+} /* end of f_evt_error */
+
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_get_buffer */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_buffer(s_evt_channel &s_chan, INTS4 *pl_buffer) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_get_buffer read one buffer from server into */
+/* user buffer. */
+/*+ ARGUMENTS : */
+/*+ s_chan : structure s_evt_channel. */
+/*+ pl_buffer : Address of user buffer */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__FAILURE : failure */
+/*- GETEVT__RDERR : read server or file error */
+/*- GETEVT__NOMORE : No more events. */
+/*- GETEVT__TIMEOUT : when enabled by f_evt_timeout */
+/*+ Declaration : */
+/* INTS4 f_evt_get_buffer(s_evt_channel *, INTS4 *); */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_get_buffer(s_evt_channel *ps_chan, INTS4 *ps_buffer)
+{
+ INTS4 l_temp;
+ // CHARS * pc_temp;
+ INTS4 l_status;
+
+ // pc_temp=(CHARS *)ps_chan->pc_io_buf;
+ switch(ps_chan->l_server_type)
+ {
+ case GETEVT__FILE :
+ l_temp=read(ps_chan->l_channel_no,ps_buffer, ps_chan->l_buf_size);
+ if(l_temp == 0)
+ /* if end of file, then exit */
+ {
+ ps_chan->l_io_buf_size = 0;
+ return(GETEVT__NOMORE);
+ }
+ else if(l_temp == -1)
+ {
+ ps_chan->l_io_buf_size = 0;
+ return(GETEVT__RDERR);
+ }
+ break;
+ case GETEVT__RFIO :
+ l_temp=RFIO_read(ps_chan->l_channel_no,(CHARS *)ps_buffer, ps_chan->l_buf_size);
+ if(l_temp == 0)
+ {
+ ps_chan->l_io_buf_size = 0;
+ return(GETEVT__NOMORE);
+ }
+ else if(l_temp == -1)
+ {
+ ps_chan->l_io_buf_size = 0;
+ return(GETEVT__RDERR);
+ }
+ break;
+ case GETEVT__STREAM :
+ if(ps_chan->l_stream_bufs == 0)
+ if(f_stc_write("GETEVT", 12, ps_chan->l_channel_no)!=STC__SUCCESS)
+ {
+ return(GETEVT__FAILURE);
+ }
+
+ l_status=f_stc_read(ps_buffer, ps_chan->l_buf_size, ps_chan->l_channel_no,ps_chan->l_timeout);
+ if(l_status == STC__TIMEOUT) return(GETEVT__TIMEOUT);
+ if(l_status != STC__SUCCESS) return(GETEVT__RDERR);
+ ps_chan->l_stream_bufs++;
+ if(ps_chan->l_stream_bufs == ps_chan->l_bufs_in_stream)ps_chan->l_stream_bufs = 0;
+ break;
+ case GETEVT__TRANS :
+ l_status=f_stc_read(ps_buffer, ps_chan->l_buf_size, ps_chan->l_channel_no,ps_chan->l_timeout);
+ if(l_status == STC__TIMEOUT) return(GETEVT__TIMEOUT);
+ if(l_status != STC__SUCCESS) return(GETEVT__RDERR);
+ break;
+ case GETEVT__REVSERV :
+ case GETEVT__EVENT :
+ default :
+ return(GETEVT__FAILURE);
+ } /* end of switch */
+
+ /* swap */
+ if( ((s_bufhe *)(ps_buffer))->l_free[0] != 1)
+ f_evt_swap((CHARS *)ps_buffer, ps_chan->l_buf_size);
+
+ return(GETEVT__SUCCESS);
+} /* end of f_evt_get_buffer */
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_skip_buffer */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_skip_buffer(s_evt_channel &s_chan, INTS4 l_buffer) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Skip buffers in file. */
+/*+ ARGUMENTS : */
+/*+ s_chan : structure s_evt_channel. */
+/*+ l_buffer : buffers to skip */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__FAILURE : failure */
+/*- GETEVT__RDERR : read server or file error */
+/*- GETEVT__NOMORE : No more events. */
+/*- GETEVT__TIMEOUT : when enabled by f_evt_timeout */
+/*+ Declaration : */
+/* INTS4 f_evt_skip_buffer(s_evt_channel *, INTS4); */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_skip_buffer(s_evt_channel *ps_chan, INTS4 l_buffer)
+{
+ INTS4 l_temp;
+ // CHARS * pc_temp;
+
+ // pc_temp=(CHARS *)ps_chan->pc_io_buf;
+ switch(ps_chan->l_server_type)
+ {
+ case GETEVT__FILE :
+ l_temp=lseek(ps_chan->l_channel_no,l_buffer*ps_chan->l_buf_size,SEEK_CUR);
+ if(l_temp == -1)
+ /* if end of file, then exit */
+ {
+ return(GETEVT__NOMORE);
+ }
+ break;
+ case GETEVT__RFIO :
+ l_temp=RFIO_lseek(ps_chan->l_channel_no,l_buffer*ps_chan->l_buf_size,SEEK_CUR);
+ if(l_temp == -1)
+ {
+ return(GETEVT__NOMORE);
+ }
+ break;
+ case GETEVT__STREAM :
+ case GETEVT__TRANS :
+ case GETEVT__REVSERV :
+ case GETEVT__EVENT :
+ default : return(GETEVT__FAILURE);
+ } /* end of switch */
+
+ ps_chan->l_first_get=1; /* so we will first call f_getevt_get */
+ return(GETEVT__SUCCESS);
+} /* end of f_evt_skip_buffer */
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_timeout */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_timeout(s_evt_channel *ps_chan, seconds) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Set a timeout for TCP read operations */
+/*+ ARGUMENTS : */
+/*+ ps_chan : Address of channel structure. */
+/*+ seconds : -1: wait (default) */
+/* >0: if after n seconds no data arrived, */
+/* read functions return GETEVT__TIMEOUT. */
+/*+ Return type : INTS4 */
+/*+ Declaration : */
+/* INTS4 f_evt_timeout(s_evt_channel *, INTS4 ); */
+/*+ FUNCTION : Set a timeout for TCP read operations. */
+/* The calls of f_evt_get_event, f_evt_get_buffer */
+/* will return GETEVT__TIMEOUT when seconds have been */
+/* set to positive value. */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_timeout(s_evt_channel *ps_chan, INTS4 l_sec)
+{
+ ps_chan->l_timeout = l_sec;
+ return(GETEVT__SUCCESS);
+} /* end of f_evt_timeout */
+
+/*1- C Main ****************+******************************************/
+/*+ Module : f_evt_swap */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : sts = f_evt_swap(char &c_source[], long l_length) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Long word byte swap. */
+/*+ ARGUMENTS : */
+/*+ c_source : source data array. */
+/*+ l_length : length (in bytes) */
+/*+ FUNCTION : Long word byte swap. Works on the source field. */
+/*+ Return type : int */
+/*+ Status codes: bit 0: success */
+/*1- C Procedure ***********+******************************************/
+INTS4 f_evt_swap(CHARS * pc_source, INTS4 l_length)
+{
+ CHARS * p_s, * p_d;
+ INTS4 l_save;
+ CHARS ch_temp;
+
+ if(l_length%4 == 2){
+ ch_temp=*(pc_source+l_length-2);
+ *(pc_source+l_length-2)=*(pc_source+l_length-1);
+ *(pc_source+l_length-1)=ch_temp;
+ }
+ l_length=(l_length/4)*4; /* aligned */
+ for(p_d=pc_source,p_s=(CHARS *)&l_save; p_di_type == 2000)
+ {
+ ps_filhe=(s_filhe *)ps_bufhe;
+ f_evt_swap((CHARS *)&ps_filhe->filhe_lines,4);/* number of comment lines ps_filhe->filhe_lines*/
+ ps_filhe->filhe_label_l=ps_filhe->filhe_label_l>>8;
+ ps_filhe->filhe_file_l =ps_filhe->filhe_file_l >>8;
+ ps_filhe->filhe_user_l =ps_filhe->filhe_user_l >>8;
+ ps_filhe->filhe_run_l =ps_filhe->filhe_run_l >>8;
+ ps_filhe->filhe_exp_l =ps_filhe->filhe_exp_l >>8;
+ pi=(INTS2 *)&ps_filhe->s_strings;
+ for(ii=0;iifilhe_lines;ii++) {
+ *pi=*pi>>8;
+ pi += 40;
+ }
+ }
+
+ return(0);
+} /* end of f_evt_swap */
+
+/*1- C Main ****************+******************************************/
+/*+ Module : f_evt_get_buffer_ptr */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_buffer_ptr(s_evt_channel &s_chan) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_get_buffer_ptr returns buffer pointer */
+/*+ ARGUMENTS : */
+/*+ s_chan : structure s_evt_channel. */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*1- C Main ****************+******************************************/
+CHARS * f_evt_get_buffer_ptr(s_evt_channel *ps_chan)
+{
+ return(ps_chan->pc_io_buf);
+}
+/*1- C Main ****************+******************************************/
+/*+ Module : f_evt_get_newbuf */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_newbuf(s_evt_channel &s_chan) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_evt_get_newbuf read a buffer from server */
+/*+ ARGUMENTS : */
+/*+ s_chan : structure s_evt_channel. */
+/*+ Return type : int. */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__FAILURE : failure */
+/*- GETEVT__RDERR : read server or file error */
+/*- GETEVT__NOMORE : No more events. */
+/*- GETEVT__TIMEOUT : when enabled by f_evt_timeout */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_get_newbuf(s_evt_channel *ps_chan)
+{
+ INTS4 l_temp;
+ CHARS * pc_temp;
+ INTS4 l_status;
+
+ pc_temp=(CHARS *)ps_chan->pc_io_buf;
+ switch(ps_chan->l_server_type)
+ {
+ case GETEVT__FILE :
+ while(1){
+ l_temp=read(ps_chan->l_channel_no,pc_temp, ps_chan->l_io_buf_size);
+ if(l_temp == 0) return(GETEVT__NOMORE);
+ if(l_temp == -1) return(GETEVT__RDERR);
+ if(l_temp < ps_chan->l_io_buf_size)return(GETEVT__RDERR);
+ break; /* skip out while(1) */
+ } /* end of while(1) */
+ break;
+ case GETEVT__STREAM :
+ if(f_stc_write("GETEVT", 12, ps_chan->l_channel_no)!=STC__SUCCESS)
+ {
+ return(GETEVT__FAILURE);
+ }
+
+ for(l_temp=0; l_templ_bufs_in_stream; l_temp++)
+ {
+ l_status=f_stc_read(pc_temp, ps_chan->l_buf_size, ps_chan->l_channel_no,ps_chan->l_timeout);
+ if(l_status == STC__TIMEOUT) return(GETEVT__TIMEOUT);
+ if(l_status != STC__SUCCESS) return(GETEVT__RDERR);
+ pc_temp+=ps_chan->l_buf_size;
+ }
+ l_temp=((s_bufhe *)(ps_chan->pc_io_buf))->l_evt;
+ if( ((s_bufhe *)(ps_chan->pc_io_buf))->l_free[0] !=1) // swap
+ f_evt_swap((CHARS *)&l_temp,4);
+ if(l_temp < 0) {// server will shutdown
+ printf("**** I-f_evt: Stream server request for disconnect!\n");
+ f_evt_get_close(ps_chan);
+ return(GETEVT__RDERR);
+ }
+ /* if first buffer is empty, all are empty */
+ if( ((s_bufhe *)(ps_chan->pc_io_buf))->l_evt == 0) return(GETEVT__TIMEOUT);
+ break;
+ case GETEVT__TRANS :
+ l_status=f_stc_read(pc_temp, ps_chan->l_buf_size, ps_chan->l_channel_no,ps_chan->l_timeout);
+ l_temp=((s_bufhe *)(ps_chan->pc_io_buf))->l_evt;
+ if( ((s_bufhe *)(ps_chan->pc_io_buf))->l_free[0] !=1) // swap
+ f_evt_swap((CHARS *)&l_temp,4);
+ if(l_temp < 0) {// server will shutdown
+ printf("**** I-f_evt: Transport server request for disconnect!\n");
+ f_evt_get_close(ps_chan);
+ return(GETEVT__RDERR);
+ }
+ if(l_status == STC__TIMEOUT) return(GETEVT__TIMEOUT);
+ if(l_status != STC__SUCCESS) return(GETEVT__RDERR);
+ break;
+ case GETEVT__RFIO :
+ l_temp=RFIO_read(ps_chan->l_channel_no,pc_temp, ps_chan->l_io_buf_size);
+ if(l_temp == 0) return(GETEVT__NOMORE);
+ if(l_temp == -1) return(GETEVT__RDERR);
+ if(l_temp < ps_chan->l_io_buf_size)return(GETEVT__RDERR);
+ break;
+ case GETEVT__REVSERV :
+ case GETEVT__EVENT :
+ default :
+ return(GETEVT__FAILURE);
+ } /* end of switch */
+
+ if( ((s_bufhe *)(ps_chan->pc_io_buf))->l_free[0] !=1) // swap
+ f_evt_swap(ps_chan->pc_io_buf, ps_chan->l_io_buf_size);
+
+ return(GETEVT__SUCCESS);
+} /* end of f_evt_get_newbuf */
+
+/*1- C Main ****************+******************************************/
+/*+ Module : f_evt_check_buf */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_check_buf(CHARS *pc_head, INTS4 *pl_goosybuf, */
+/* INTS4 *pl_swap, INTS4 *pl_filehead) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : check a buffer is a file header or GOOSY buffer, */
+/* and whether it's swaped. */
+/*+ ARGUMENTS : */
+/*+ pc_head : pointer to the buffer to be checked. */
+/*+ pl_goosybuf : 1 is goosy buffer, 0 is header */
+/*+ pl_swap : 1 means different endian, 0 means same endian. */
+/*+ pl_filehead : 1 means first buffer is header */
+/*+ Return type : void */
+/*+ Status codes: */
+/*+ FUNCTION : check a buffer is a file header or GOOSY buffer, */
+/* and whether it's swaped. */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_check_buf(CHARS *pc_head, INTS4 *pl_size, INTS4 *pl_is_goosybuf, INTS4 *pl_swap, INTS4 *pl_filehead)
+{
+ INTU4 l_size;
+
+ *pl_is_goosybuf=0;
+ *pl_filehead=0;
+ *pl_size=0;
+ *pl_swap=0;
+ /* first check if it's file header */
+ if( (((s_filhe *)(pc_head))->filhe_subtype==1)&&
+ (((s_filhe *)(pc_head))->filhe_type==2000) )
+ {
+ *pl_swap=0;
+ *pl_is_goosybuf=0;
+ *pl_filehead=1;
+ l_size=((s_bufhe *)(pc_head))->l_dlen*2;
+ if(l_size%512 > 0) l_size += sizeof(s_bufhe);
+ if((l_size>>24) > 0) *pl_size=0;
+ else *pl_size=l_size;
+ return(PUTEVT__SUCCESS);
+ }
+ f_evt_swap(pc_head, sizeof(s_filhe));
+ if( (((s_filhe *)(pc_head))->filhe_subtype==1)&&
+ (((s_filhe *)(pc_head))->filhe_type==2000) )
+ {
+ *pl_swap=1;
+ *pl_is_goosybuf=0;
+ *pl_filehead=1;
+ l_size=((s_bufhe *)(pc_head))->l_dlen*2;
+ if(l_size%512 > 0) l_size += sizeof(s_bufhe);
+ if((l_size>>24) > 0) *pl_size=0;
+ else *pl_size=l_size;
+ return(PUTEVT__SUCCESS);
+ }
+
+ /* if not file header, check if it's goosy buffer header */
+ l_size=((s_bufhe *)(pc_head))->l_dlen*2;
+ if(l_size%512 > 0) l_size += sizeof(s_bufhe);
+ if( (((l_size>>24) == 0) && (l_size > 0)) &&
+ (((s_bufhe *)(pc_head))->h_begin < 2) &&
+ (((s_bufhe *)(pc_head))->h_begin >= 0) &&
+ (((s_bufhe *)(pc_head))->h_end < 2) &&
+ (((s_bufhe *)(pc_head))->h_end >= 0) &&
+ //(((s_bufhe *)(pc_head))->i_used<=(MAX_BUF_LGTH-sizeof(s_bufhe))/2)&&
+ ((((s_bufhe *)(pc_head))->i_used>0)||(((s_bufhe *)(pc_head))->l_free[2] > 0))&&
+ //(((s_bufhe *)(pc_head))->i_used>0)&&
+ ( (((s_bufhe *)(pc_head))->l_free[0] == 1)||
+ (((s_bufhe *)(pc_head))->l_free[0] == 0)||
+/* above, because some old lsm file forgot to set this bit, so it's zero */
+ (((s_bufhe *)(pc_head))->l_free[0]==256*256*256) ) )
+ {
+ *pl_swap=1; /* !!!, because already swaped once */
+ *pl_is_goosybuf=1;
+ *pl_size=l_size;
+ return(PUTEVT__SUCCESS);
+ }
+ f_evt_swap(pc_head, sizeof(s_filhe));
+ l_size=((s_bufhe *)(pc_head))->l_dlen*2+sizeof(s_bufhe);
+ if( (((l_size>>24)== 0)&&(l_size > 0))&&
+ (((s_bufhe *)(pc_head))->l_dlen > 0)&&
+ (((s_bufhe *)(pc_head))->h_begin < 2)&&
+ (((s_bufhe *)(pc_head))->h_begin >= 0)&&
+ (((s_bufhe *)(pc_head))->h_end < 2)&&
+ (((s_bufhe *)(pc_head))->h_end >= 0)&&
+ //(((s_bufhe *)(pc_head))->i_used<=(MAX_BUF_LGTH-sizeof(s_bufhe))/2)&&
+ ((((s_bufhe *)(pc_head))->i_used>0)||(((s_bufhe *)(pc_head))->l_free[2] > 0))&&
+ //(((s_bufhe *)(pc_head))->i_used>0)&&
+ ( (((s_bufhe *)(pc_head))->l_free[0] == 1)||
+ (((s_bufhe *)(pc_head))->l_free[0] == 0)||
+/* above, because some old lsm file forgot to set this bit, so it's zero */
+ (((s_bufhe *)(pc_head))->l_free[0]==256*256*256) ) )
+ {
+ *pl_swap=0; /* !!!, because already swaped 2 times */
+ *pl_is_goosybuf=1;
+ *pl_size=l_size;
+ return(PUTEVT__SUCCESS);
+ }
+ return(PUTEVT__SUCCESS);
+} /* end of f_evt_check_buf */
+
+/*1- C Main ****************+******************************************/
+/*+ Module : f_evt_ini_bufhe */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_ini_bufhe(s_evt_channel *ps_chan) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : pre-fill each GOOSY buffer header in a stream */
+/*+ ARGUMENTS : */
+/*+ ps_chan : Address of channel structure. */
+/*+ Return type : void . */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_ini_bufhe(s_evt_channel *ps_chan)
+{
+ INTS4 l_temp;
+ struct timespec s_timespec;
+
+ /* because "timeb" is not "typedef", so we must use "struct" */
+
+ for(l_temp=0; l_templ_io_buf_size; l_temp += ps_chan->l_buf_size)
+ {
+ ps_chan->ps_bufhe=(s_bufhe *)(ps_chan->pc_io_buf + l_temp);
+ ps_chan->ps_bufhe->l_dlen = (ps_chan->l_buf_size - sizeof(s_bufhe))/2;
+ ps_chan->ps_bufhe->i_subtype = ps_chan->l_buf_subtype;
+ ps_chan->ps_bufhe->i_type = ps_chan->l_buf_type;
+ ps_chan->ps_bufhe->h_begin = 0;
+ ps_chan->ps_bufhe->h_end = 0;
+ ps_chan->ps_bufhe->i_used = 0;
+ ps_chan->ps_bufhe->l_buf = ps_chan->l_buf_no; ps_chan->l_buf_no++;
+ ps_chan->ps_bufhe->l_evt = 0;
+ ps_chan->ps_bufhe->l_current_i = 0;
+ clock_gettime(CLOCK_REALTIME, &s_timespec);
+ ps_chan->ps_bufhe->l_time[0] = (INTS4) s_timespec.tv_sec;
+ ps_chan->ps_bufhe->l_time[1] = (INTS4) s_timespec.tv_nsec/1000000;
+ ps_chan->ps_bufhe->l_free[0] = 1; /* for swap flag */
+ ps_chan->ps_bufhe->l_free[1] = 0;
+ ps_chan->ps_bufhe->l_free[2] = 0;
+ ps_chan->ps_bufhe->l_free[3] = 0;
+ }
+ return(PUTEVT__SUCCESS);
+} /* end of f_evt_ini_bufhe */
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_cre_tagfile */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_cre_tagfile(lmdfile,tagfile,filter) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Create a tag file from lmd file */
+/*+ ARGUMENTS : */
+/*+ lmdfile : LMD file name */
+/*+ tagfile : tag file name */
+/*+ filter : optional function for filter */
+/*+ Return type : INTS4 . */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__NOFILE : file does not exist. */
+/*- GETEVT__TAGWRERR : tag file write error. */
+/*- GETEVT__RDERR : lmd read error. */
+/*+ Declaration : */
+/* INTS4 f_evt_cre_tagfile(CHARS *,CHARS *, INTS4 (*)()); */
+/*+ FUNCTION : Create a tag file from lmd file */
+/*+ filter : The filter function is called at the beginning */
+/* with a NULL as argument, then for each event */
+/* with the event pointer. Returning 0 skips the event, */
+/* 1 takes the event into the tag file. */
+/* Different tag files can be created from one lmd file. */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_tag_filter(s_ve10_1 *ps_ve10_1)
+{
+ /* take it */
+return(1);
+//if(ps_ve10_1 != NULL)
+//{
+// printf("Filter %9d Type/Subtype %5d %5d Length %5d[w] Trigger %2d\n",
+// ps_ve10_1->l_count,
+// ps_ve10_1->i_type,
+// ps_ve10_1->i_subtype,
+// ps_ve10_1->l_dlen,
+// ps_ve10_1->i_trigger);
+// if(ps_ve10_1->l_count%2) return(1); /* take it */
+// else return(0); /* skip it */
+//}
+//else printf("Initialized filter function\n");
+// return(0);
+}
+INTS4 f_evt_cre_tagfile(CHARS *pc_lmd, CHARS *pc_tag,INTS4 (*e_filter)(s_ve10_1 *))
+{
+ INTS4 ii,l_take_it,l_temp,l_chan,l_out,l_file_pos=0,l_bufnr=0,l_events=0;
+ INTS4 l_firste = 0, *pl, l_len, l_last=-1, l_lin=0, l_fragsize;
+ INTS4 l_swap=0, l_swap_head, l_is_goosybuf, l_filehead=0, l_size=0, l_size_head, l_dummy, l_evsize,l_evt_buf_size=0;
+ INTU4 *ps,*pd;
+ CHARS *pc_evt_buf=NULL;
+ s_ve10_1 *ps_ve10_1;
+ s_bufhe *ps_bufhe;
+ s_taghe s_taghe;
+ s_tag s_tag;
+
+ s_tag.l_event = 0;
+ s_tag.l_offset = 0;
+
+ ps_bufhe = (s_bufhe *)c_temp;
+ printf("LMD file %s, TAG file %s\n",pc_lmd,pc_tag);
+ /* get file attributes */
+ if((l_chan=open(pc_lmd,GET__OPEN_FLAG))== -1) return(GETEVT__NOFILE);
+ /* read first 512 bytes */
+ if(read(l_chan,c_temp,MIN_BUF_LGTH)!=MIN_BUF_LGTH)
+ {
+ close(l_chan);
+ return(GETEVT__RDERR);
+ }
+ /* check for file header, return size and swap */
+ f_evt_check_buf(c_temp, &l_size_head, &l_is_goosybuf, &l_swap_head, &l_filehead);
+ if(((l_is_goosybuf == 0) & (l_filehead == 0)) | (l_size_head == 0))
+ {
+ printf("LMD format error: swap=%d, header=%d, isLMD=%d, size=%d\n",l_swap_head,l_filehead,l_is_goosybuf,l_size_head);
+ close(l_chan);
+ return(GETEVT__NOLMDFILE);
+ }
+ /* read file header and first buffer and check for goosy header */
+ if(l_filehead == 1)
+ {
+ lseek(l_chan, 0, SEEK_SET); /* rewind file */
+ if(read(l_chan,c_temp,l_size_head)!=l_size_head)
+ {
+ close(l_chan);
+ return(GETEVT__RDERR);
+ }
+ if(read(l_chan,c_temp,MIN_BUF_LGTH)!=MIN_BUF_LGTH)
+ {
+ close(l_chan);
+ return(GETEVT__RDERR);
+ }
+ f_evt_check_buf(c_temp, &l_size, &l_is_goosybuf, &l_swap, &l_dummy);
+ if((l_is_goosybuf == 0) | (l_size != l_size_head) | (l_swap != l_swap_head))
+ {
+ printf("LMD format error: swap=%d, isLMD=%d, size=%d\n",l_swap,l_is_goosybuf,l_size);
+ close(l_chan);
+ return(GETEVT__NOLMDFILE);
+ }
+ }/* check buffer behind header */
+
+ lseek(l_chan, 0, SEEK_SET); /* rewind file */
+
+ printf("Buffer swap %d, File header %d, LMD buffer %d, size %d[b]\n",l_swap,l_filehead,l_is_goosybuf,l_size);
+
+ /* found file header, skip */
+ if(l_filehead == 1)
+ {
+ if(read(l_chan,c_temp,l_size)!=l_size)
+ {
+ close(l_chan);
+ return(GETEVT__RDERR);
+ }
+ l_file_pos += l_size;
+ l_bufnr++;
+ }
+
+ /* Open and create tag file */
+ if((l_out=open(pc_tag,PUT__CRT_FLAG,DEF_FILE_ACCE))== -1) return(GETEVT__NOFILE);
+ write(l_out,(CHARS *)&s_taghe,sizeof(s_taghe));
+
+ /* Initialize filter function */
+ if(e_filter != NULL) ii=(*e_filter)(NULL);
+
+ while(read(l_chan,c_temp,l_size)==l_size)
+ {
+ l_file_pos=l_bufnr*l_size;
+ if(l_swap) f_evt_swap(c_temp,l_size);
+ if((ps_bufhe->h_end)&(ps_bufhe->h_begin)&(ps_bufhe->l_evt==1))
+ {
+ /* only fragment, next buffer */
+ /* printf("Event fragment skipped Buffer %6d\n",l_bufnr);*/
+ l_bufnr++;
+ continue;
+ }
+ ps_ve10_1=(s_ve10_1 *)(ps_bufhe + 1);
+ pl = (INTS4 *)ps_ve10_1;
+ l_file_pos += sizeof(s_bufhe);
+ /* skip fragment at begin */
+ if(ps_bufhe->h_end)
+ {
+ l_len = (*pl>>1)+2;
+ l_file_pos += (l_len<<2); /* bytes */
+ ps_ve10_1=(s_ve10_1 *)(pl+l_len);
+ pl = (INTS4 *)ps_ve10_1;
+ ps_bufhe->l_evt--;
+ /* printf("Event fragment end skipped Buffer %6d\n",l_bufnr);*/
+ }
+ for(ii=1;iil_evt;ii++) /* except last element */
+ {
+ /*printf("Event %10d pos %10d Buffer %6d\n",ps_ve10_1->l_count, l_file_pos,l_bufnr);*/
+ if(e_filter != NULL) l_take_it=(*e_filter)(ps_ve10_1);
+ else l_take_it=1;
+ l_len = (*pl>>1)+2;
+ s_tag.l_event=ps_ve10_1->l_count;
+ s_tag.l_offset=l_file_pos;
+ if(l_take_it)
+ {
+ l_events++;
+ if(ps_ve10_1->l_count != (l_last+1))
+ {
+ l_lin++;
+ if(l_lin == 1)l_firste=ps_ve10_1->l_count;
+ /* printf("New event number offset %d, index %d\n",ps_ve10_1->l_count,l_events);*/
+ }
+ l_last=ps_ve10_1->l_count;
+ if(write(l_out,(CHARS *)&s_tag,sizeof(s_tag)) != sizeof(s_tag))
+ {
+ close(l_chan);
+ close(l_out);
+ return(GETEVT__TAGWRERR);
+ }
+ }
+ l_file_pos += (l_len<<2); /* bytes */
+ ps_ve10_1=(s_ve10_1 *)(pl+l_len);
+ pl = (INTS4 *)ps_ve10_1;
+ }
+
+ if(ps_bufhe->l_evt > 0)
+ {
+ if(ps_ve10_1->l_dlen < 4) printf("Buffer %d Event fragment %10d dlen %d ts %d %d trigger %d\n"
+ ,l_bufnr,ps_ve10_1->l_count,ps_ve10_1->l_dlen,ps_ve10_1->i_type,
+ ps_ve10_1->i_subtype,ps_ve10_1->i_trigger);
+ s_tag.l_event=ps_ve10_1->l_count;
+ if(ps_bufhe->h_begin)
+ {
+ /* copy event to event buffer for filter function */
+ if(e_filter != NULL)
+ {
+ /* is event buffer big enough? */
+ l_evsize=ps_bufhe->l_free[1]+4; /* total words */
+ if(l_evt_buf_size < l_evsize*2)
+ {
+ if(pc_evt_buf != NULL)free(pc_evt_buf);
+ l_evt_buf_size=l_evsize*2;
+ pc_evt_buf=(CHARS *)malloc(l_evt_buf_size);
+ }
+ /* copy event fragment to buffer */
+ ps=(INTU4 *)ps_ve10_1;
+ pd=(INTU4 *)pc_evt_buf;
+ l_fragsize = ps_ve10_1->l_dlen+4; /* fragment size + header [w] */
+ for(ii=0;iil_dlen=l_evsize-4;
+ /* rewind last buffer, will be read again by while loop */
+ l_bufnr--;
+ lseek(l_chan, -l_size, SEEK_CUR);
+ }
+ s_tag.l_offset=-l_file_pos;
+ /* printf("Event %10d pos %10d Buffer -%6d\n",ps_ve10_1->l_count, l_file_pos,l_bufnr);*/
+ }
+ else
+ {
+ s_tag.l_offset=l_file_pos;
+ /* printf("Event %10d pos %10d Buffer %6d\n",ps_ve10_1->l_count, l_file_pos,l_bufnr);*/
+ }
+ if(e_filter != NULL)l_take_it=(*e_filter)(ps_ve10_1);
+ else l_take_it=1;
+ if(l_take_it)
+ {
+ l_events++;
+ if(ps_ve10_1->l_count != (l_last+1))
+ {
+ l_lin++;
+ if(l_lin == 1)l_firste=ps_ve10_1->l_count;
+ /* printf("New event number offset %d, index %d\n",ps_ve10_1->l_count,l_events);*/
+ }
+ l_last=ps_ve10_1->l_count;
+ if(write(l_out,(CHARS *)&s_tag,sizeof(s_tag)) != sizeof(s_tag))
+ {
+ close(l_chan);
+ close(l_out);
+ return(GETEVT__TAGWRERR);
+ }
+ }
+ }
+ l_bufnr++;
+ /* if(l_bufnr > 3) break; */
+ }
+ lseek(l_out, 0, SEEK_SET); /* rewind file */
+ s_taghe.l_endian = 1;
+ s_taghe.l_version = 1;
+ s_taghe.l_bufsize = l_size;
+ s_taghe.l_buffers = l_bufnr;
+ s_taghe.l_events = l_events;
+ s_taghe.l_filesize = sizeof(s_tag)*l_events;
+ s_taghe.l_linear = (l_lin == 1);
+ s_taghe.l_first = l_firste;
+ s_taghe.l_last = s_tag.l_event;
+ if(write(l_out,(CHARS *)&s_taghe,sizeof(s_taghe)) != sizeof(s_taghe))
+ {
+ close(l_chan);
+ close(l_out);
+ return(GETEVT__TAGWRERR);
+ }
+ close(l_chan);
+ close(l_out);
+ printf("Buffers %6d, of size %d, Events %10d, first %d, last %d "
+ ,s_taghe.l_buffers
+ ,s_taghe.l_bufsize
+ ,s_taghe.l_events
+ ,s_taghe.l_first
+ ,s_taghe.l_last);
+ if(s_taghe.l_linear)printf("linear\n");
+ else printf("not linear\n");
+
+ return(GETEVT__SUCCESS);
+} /* end of f_evt_cre_tagfile */
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_get_tagopen */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_tagopen(channel,tagfile,lmdfile,header,print) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Open tag and lmd file */
+/*+ ARGUMENTS : */
+/*+ channel : s_evt_channel* , must be allocated. */
+/*+ tagfile : Name of tag file */
+/*+ filename : LMD file name */
+/*+ header : address of CHARS pointer. If it is not NULL, then */
+/* try to return file header or other information */
+/* about server. If it is NULL, then returns nothing. */
+/*+ print : Print flag: 1=verbose */
+/*+ Return type : INTS4 . */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__NOFILE : file does not exist. */
+/*- GETEVT__TAGRDERR : tag file read error. */
+/*- GETEVT__RDERR : read server error. */
+/*+ Declaration : */
+/* INTS4 f_evt_get_tagopen( */
+/* s_evt_channel *,CHARS *,CHARS *,CHARS **,INTS4); */
+/*+ FUNCTION : Open tag file and lmd file. If no tag file is found, */
+/* a standard f_evt_get_open is called. In this case */
+/* following tag functions call standard f_evt_get functions. */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_get_tagopen(s_evt_channel *ps_chan,CHARS *pc_tag,CHARS *pc_lmd, CHARS **ps_head, INTS4 l_prihe)
+{
+ INTS4 ii;
+ s_bufhe *ps_bufhe;
+
+ ps_chan->ps_tag = NULL; /* tagfile buffer */
+ ps_chan->ps_taghe = NULL;
+ if(l_prihe)printf("LMD file %s, TAG file %s\n",pc_lmd,pc_tag);
+
+ /* if tag file name not specified, do not try to open it SL:11.11.09*/
+ if ((pc_tag == NULL) || (*pc_tag == 0))
+ ps_chan->l_tagfile_no = -1;
+ else
+ ps_chan->l_tagfile_no = open(pc_tag, GET__OPEN_FLAG);
+
+ /* open tag file and read header */
+ if(ps_chan->l_tagfile_no == -1)
+ {
+ /* no tag file, use normal open */
+ /*=============================================*/
+ ii=f_evt_get_open(GETEVT__FILE, pc_lmd, ps_chan, (CHARS **) &ps_bufhe,0,0);
+ *ps_head = (CHARS *) ps_bufhe;
+ if(ii!=GETEVT__SUCCESS)
+ {
+ printf("Error opening input file %s\n",pc_lmd);
+ return (ii);
+ }
+ /* printf("No tag file for %s\n",pc_lmd); */
+ if(l_prihe) ii = f_evt_type(ps_bufhe,NULL,0,0,0,0);
+ return(GETEVT__SUCCESS);
+ }
+ /*=============================================*/
+ /* tag file found */
+ ps_chan->ps_taghe = (s_taghe *)malloc(sizeof(s_taghe));
+ if(read(ps_chan->l_tagfile_no,(CHARS *)ps_chan->ps_taghe,sizeof(s_taghe))!=sizeof(s_taghe))
+ {
+ free(ps_chan->ps_taghe);
+ ps_chan->ps_taghe = NULL;
+ close(ps_chan->l_tagfile_no);
+ return(GETEVT__TAGRDERR);
+ }
+ if(ps_chan->ps_taghe->l_endian != 1)ps_chan->l_tagswap=1;
+ if(ps_chan->l_tagswap)f_evt_swap((CHARS *)ps_chan->ps_taghe,sizeof(s_taghe));
+ if(l_prihe)
+ {
+ printf("Buffers %6d, of size %d, Events %10d, first %d, last %d"
+ ,ps_chan->ps_taghe->l_buffers
+ ,ps_chan->ps_taghe->l_bufsize
+ ,ps_chan->ps_taghe->l_events
+ ,ps_chan->ps_taghe->l_first
+ ,ps_chan->ps_taghe->l_last);
+ if(ps_chan->ps_taghe->l_linear)printf(" linear\n");
+ else printf(" not linear\n");
+ }
+ if((ps_chan->l_channel_no=open(pc_lmd,GET__OPEN_FLAG))== -1)
+ {
+ if(ps_chan->ps_taghe != NULL) free(ps_chan->ps_taghe);
+ ps_chan->ps_taghe = NULL;
+ close(ps_chan->l_tagfile_no);
+ return(GETEVT__NOFILE);
+ }
+ /* read buffer header to check if we have to swap */
+ ps_bufhe = (s_bufhe *)c_temp;
+ if(read(ps_chan->l_channel_no,c_temp,ps_chan->ps_taghe->l_bufsize)!=ps_chan->ps_taghe->l_bufsize)
+ {
+ if(ps_chan->ps_taghe != NULL) free(ps_chan->ps_taghe);
+ ps_chan->ps_taghe = NULL;
+ if(ps_chan->ps_tag != NULL) free(ps_chan->ps_tag);
+ ps_chan->ps_tag = NULL;
+ close(ps_chan->l_tagfile_no);
+ close(ps_chan->l_channel_no);
+ return(GETEVT__RDERR);
+ }
+ if(ps_chan->ps_taghe->l_linear == 0)
+ {
+ ps_chan->ps_tag = (s_tag *)malloc(ps_chan->ps_taghe->l_filesize);
+ if(read(ps_chan->l_tagfile_no,(CHARS *)ps_chan->ps_tag,ps_chan->ps_taghe->l_filesize)!=ps_chan->ps_taghe->l_filesize)
+ {
+ if(ps_chan->ps_taghe != NULL) free(ps_chan->ps_taghe);
+ ps_chan->ps_taghe = NULL;
+ if(ps_chan->ps_tag != NULL) free(ps_chan->ps_tag);
+ ps_chan->ps_tag = NULL;
+ close(ps_chan->l_tagfile_no);
+ close(ps_chan->l_channel_no);
+ return(GETEVT__TAGRDERR);
+ }
+ }
+ if(ps_bufhe->l_free[0] != 1)ps_chan->l_lmdswap=1;
+ if(ps_chan->l_lmdswap)f_evt_swap_filhe(ps_bufhe);
+ if(l_prihe) ii = f_evt_type(ps_bufhe,NULL,0,0,0,0);
+ if(ps_head != NULL)
+ {
+ if(ps_bufhe->i_type == 2000) *ps_head = (CHARS *)ps_bufhe;
+ }
+ ps_chan->l_evt_buf_size=0;
+ ps_chan->pc_evt_buf=NULL;
+ ps_chan->l_io_buf_posi=0; /* keeps index of last event */
+ return(GETEVT__SUCCESS);
+}
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_get_tagnext */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_tagnext(channel,skip,**event) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Get tagged event from lmd file */
+/*+ ARGUMENTS : */
+/*+ channel : s_evt_channel* , must be allocated. */
+/*+ event : address of pointer. If it is not NULL, then */
+/* return event pointer. */
+/*+ Return type : INTS4 . */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__NOFILE : file does not exist. */
+/*- GETEVT__TAGRDERR : tag file read error. */
+/*- GETEVT__RDERR : lmd read error. */
+/*- GETEVT__FRAGMENT : Event fragment found. */
+/*- GETEVT__NOMORE : No more events. */
+/*+ Declaration : */
+/* INTS4 f_evt_get_tagnext(s_evt_channel *,INTS4,INTS4 **); */
+/*+ FUNCTION : Get next event at current position, either in tag */
+/* file, or in lmd file. Optional events are skipped. */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_get_tagnext(s_evt_channel *ps_chan,INTS4 l_skip, INTS4 **pl_event)
+{
+ INTS4 ii = 0,*pl = NULL,kk;
+ /* no tagfile */
+ /*=============================================*/
+ if(ps_chan->ps_taghe == NULL)
+ {
+ for(kk=0;kk<=l_skip;kk++)
+ {
+ ii=f_evt_get_event(ps_chan, (INTS4 **) &pl, NULL);
+ if(ii != GETEVT__SUCCESS) break;
+ }
+ }
+ /*=============================================*/
+ else
+ {
+ /* l_io_buf_posi is the index of last event */
+ ii=f_evt_get_tagevent(ps_chan,ps_chan->l_io_buf_posi+l_skip+1,1,(INTS4 **)&pl);
+ }
+ if(pl_event != NULL) *pl_event=pl;
+ return(ii);
+}
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_get_tagevent */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_tagevent(*channel, value, mode, **event) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Get tagged event from lmd file */
+/*+ ARGUMENTS : */
+/*+ channel : s_evt_channel* , must be allocated. */
+/*+ value : event number or index */
+/*+ mode : 0: value is number, 1: value is index */
+/*+ event : address of pointer. If it is not NULL, then */
+/* return event pointer. */
+/*+ Return type : INTS4 . */
+/*+ Status codes: */
+/*- GETEVT__SUCCESS : success. */
+/*- GETEVT__TAGRDERR : tag file read error. */
+/*- GETEVT__RDERR : lmd read error. */
+/*- GETEVT__FRAGMENT : Event fragment found. */
+/*- GETEVT__NOMORE : No more events. */
+/*- GETEVT__NOTAG : Specified event not in tag file. */
+/*+ Declaration : */
+/* INTS4 f_evt_get_tagevent( */
+/* s_evt_channel *,INTS4,INTS4,INTS4 **); */
+/*+ FUNCTION : Get tag event. If no tag file is there, skip */
+/* events, or look for event number */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_get_tagevent(s_evt_channel *ps_chan,INTS4 l_value, INTS4 l_type, INTS4 **pl_event)
+{
+ INTS4 ii,kk, /*l_evt,*/ l_off,l_typ,l_val,l_evsize,l_fragsize;
+ INTS4 la_head[2], *pl = NULL;
+ CHARS *pc;
+ s_ve10_1 *ps_ve10_1;
+ s_bufhe *ps_bufhe;
+ s_tag *ps_tag;
+ s_tag s_tag_l;
+
+ l_typ=l_type;
+ l_val=l_value;
+ /* no tagfile */
+ /*=============================================*/
+ if(ps_chan->ps_taghe == NULL)
+ {
+ /* search by index */
+ if(l_type == 1)
+ {
+ if(l_val == 0) l_val=1;
+ for(kk=0;kkl_count != l_val)
+ {
+ ii=f_evt_get_event(ps_chan, (INTS4 **) &ps_ve10_1, NULL);
+ if(ii != GETEVT__SUCCESS)return(ii);
+ }
+ *pl_event = (INTS4 *)ps_ve10_1;
+ }
+ return(GETEVT__SUCCESS);
+ }
+ /*=============================================*/
+ ps_ve10_1 = (s_ve10_1 *)c_temp;
+ ps_bufhe = (s_bufhe *)c_temp;
+
+ /* linear==1 means that event numbers are subsequent. */
+ /* in that case we can calculate index from number */
+ if(ps_chan->ps_taghe->l_linear)
+ {
+ if(l_typ == 0)l_val=l_value-ps_chan->ps_taghe->l_first+1;
+ l_typ=1;
+ }
+ /* search by index or by value */
+ if(l_typ == 1)
+ {
+ if(l_val > ps_chan->ps_taghe->l_events)
+ {
+ printf("Event index %d not found\n",l_val);
+ return(GETEVT__NOTAG);
+ }
+ if(l_val == 0) l_val=1;
+ ps_tag=(s_tag *)&s_tag_l;
+ lseek(ps_chan->l_tagfile_no, (l_val-1)*sizeof(s_tag)+sizeof(s_taghe), SEEK_SET); /* set file offset*/
+ if(read(ps_chan->l_tagfile_no,(CHARS *)ps_tag,sizeof(s_tag))!=sizeof(s_tag))
+ {
+ return(GETEVT__TAGRDERR);
+ }
+ if(ps_chan->l_tagswap)f_evt_swap((CHARS *)ps_tag,sizeof(s_tag));
+ ps_chan->l_io_buf_posi=l_val; /* keeps index */
+ }
+ else
+ {
+ ps_tag=ps_chan->ps_tag;
+ for(ii=1;ii<=ps_chan->ps_taghe->l_events;ii++)
+ {
+ if(ps_tag->l_event == l_val) break;
+ ps_tag++;
+ }
+ if(ps_tag->l_event != l_val)
+ {
+ printf("Event number %d not found\n",l_val);
+ return(GETEVT__NOTAG);
+ }
+ ps_chan->l_io_buf_posi=ii; /* keeps index of last event */
+ }
+ /* now we have the requested event in ps_tag */
+ l_off=ps_tag->l_offset;
+ if(l_off < 0) l_off=((-l_off)/ps_chan->ps_taghe->l_bufsize)*ps_chan->ps_taghe->l_bufsize;
+ // l_evt = ps_tag->l_event;
+ /* full event in buffer, read */
+ if(ps_tag->l_offset > 0)
+ {
+ ps_ve10_1 = (s_ve10_1 *)c_temp;
+ lseek(ps_chan->l_channel_no, l_off, SEEK_SET); /* set file offset*/
+ if(read(ps_chan->l_channel_no,c_temp,8)!=8) return(GETEVT__RDERR);
+ if(ps_chan->l_lmdswap)f_evt_swap(c_temp,8);
+ if(read(ps_chan->l_channel_no,(CHARS *)&c_temp[8],ps_ve10_1->l_dlen*2)!=ps_ve10_1->l_dlen*2)return(GETEVT__RDERR);
+ if(ps_chan->l_lmdswap)f_evt_swap((CHARS *)&c_temp[8],ps_ve10_1->l_dlen*2);
+ /*ii=f_evt_type(NULL,(s_evhe *)ps_ve10_1,-1,0,1,1);*/
+ }
+ else
+ /* spanning event begin, read to event buffer */
+ {
+ lseek(ps_chan->l_channel_no, l_off, SEEK_SET); /* set file offset to buffer begin */
+ if(read(ps_chan->l_channel_no,c_temp,sizeof(s_bufhe))!=sizeof(s_bufhe)) return(GETEVT__RDERR);
+ if(ps_chan->l_lmdswap)f_evt_swap(c_temp,sizeof(s_bufhe));
+ /* is event buffer big enough? */
+ l_evsize=ps_bufhe->l_free[1]+4; /* total words */
+ if(ps_chan->l_evt_buf_size < l_evsize*2)
+ {
+ if(ps_chan->pc_evt_buf != NULL)free(ps_chan->pc_evt_buf);
+ ps_chan->l_evt_buf_size=l_evsize*2;
+ ps_chan->pc_evt_buf=(CHARS *)malloc(ps_chan->l_evt_buf_size);
+ }
+ l_fragsize=0;
+ ps_ve10_1 = (s_ve10_1 *)ps_chan->pc_evt_buf;
+ lseek(ps_chan->l_channel_no, -ps_tag->l_offset, SEEK_SET); /* set file offset*/
+ if(read(ps_chan->l_channel_no,ps_chan->pc_evt_buf,8)!=8) return(GETEVT__RDERR);
+ if(ps_chan->l_lmdswap)f_evt_swap(ps_chan->pc_evt_buf,8);
+ pc=ps_chan->pc_evt_buf+8;
+ /* read fragment */
+ if(read(ps_chan->l_channel_no,pc,ps_ve10_1->l_dlen*2)!=ps_ve10_1->l_dlen*2)return(GETEVT__RDERR);
+ l_fragsize += ps_ve10_1->l_dlen+4; /* fragment size + header [w] */
+ pc += ps_ve10_1->l_dlen*2; /* next in event buffer */
+ ps_ve10_1->l_dlen=l_evsize-4; /* set correct event size */
+ /* loop over fragments */
+ while(l_fragsize < l_evsize)
+ {
+ l_off += ps_chan->ps_taghe->l_bufsize; /* next buffer absolut address */
+ lseek(ps_chan->l_channel_no,l_off+sizeof(s_bufhe), SEEK_SET); /* set file offset*/
+ if(read(ps_chan->l_channel_no,(CHARS *)&la_head,8)!=8) return(GETEVT__RDERR);
+ if(ps_chan->l_lmdswap)f_evt_swap((CHARS *)&la_head,8);
+ if(read(ps_chan->l_channel_no,pc,la_head[0]*2)!=la_head[0]*2) return(GETEVT__RDERR);
+ pc += la_head[0]*2;
+ l_fragsize += la_head[0];
+ }
+ /* now swap whole event in buffer */
+ pc=ps_chan->pc_evt_buf+8; /* header already swapped */
+ ps_ve10_1 = (s_ve10_1 *)ps_chan->pc_evt_buf;
+ if(ps_chan->l_lmdswap)f_evt_swap(pc,ps_ve10_1->l_dlen*2);
+ }
+ *pl_event = (INTS4 *)ps_ve10_1;
+ return(GETEVT__SUCCESS);
+} /* end of f_evt_ini_bufhe */
+
+/*1+ C Main ****************+******************************************/
+/*+ Module : f_evt_get_tagclose */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_evt_get_tagclose(s_evt_channel) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Close tag and lmd file, cleanup s_evt_channel */
+/*+ ARGUMENTS : */
+/*+ channel : s_evt_channel* , must be allocated. */
+/*+ Return type : INTS4 */
+/*+ Declaration : */
+/* INTS4 f_evt_get_tagclose(s_evt_channel *); */
+/*+ FUNCTION : Create a tag file from lmd file */
+/*1- C Main ****************+******************************************/
+INTS4 f_evt_get_tagclose(s_evt_channel *ps_chan)
+{
+ /*=============================================*/
+ if(ps_chan->ps_taghe == NULL)
+ {
+ f_evt_get_close(ps_chan);
+ return(GETEVT__SUCCESS);
+ }
+ /*=============================================*/
+ free(ps_chan->ps_taghe);
+ if(ps_chan->ps_tag != NULL) free(ps_chan->ps_tag);
+ if(ps_chan->pc_evt_buf != NULL) free(ps_chan->pc_evt_buf);
+ close(ps_chan->l_tagfile_no);
+ close(ps_chan->l_channel_no);
+ memset((void *)ps_chan, 0, sizeof(s_evt_channel)); /* clear memory */
+ return(GETEVT__SUCCESS);
+}
+
+s_evt_channel *f_evt_control(void)
+{
+ s_evt_channel *x;
+ x = (s_evt_channel *)malloc(sizeof(s_evt_channel));
+ if (x != NULL)
+ memset(x, 0, sizeof(s_evt_channel));
+ return(x);
+ }
diff --git a/plugins/olmd/mbsapi/f_evt.h b/plugins/olmd/mbsapi/f_evt.h
new file mode 100644
index 00000000..c6e5bfde
--- /dev/null
+++ b/plugins/olmd/mbsapi/f_evt.h
@@ -0,0 +1,157 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef F_EVT_H
+#define F_EVT_H
+
+#include "typedefs.h"
+
+/* ++++++++++++++++ include UNIX standard headers +++++++++++++++++++++++++ */
+
+#include "s_ve10_1.h"
+#include "s_ves10_1.h"
+#include "s_evhe.h"
+#include "s_bufhe.h"
+
+#define MAX_BUF_LGTH 32768
+#define MIN_BUF_LGTH 512
+#define MAX_BUFS_IN_STREAM 100 /* at a maximum, 100 buffers per stream */
+#define MAX_LONG 99999999 /* maximum long data */
+
+typedef struct
+{
+ INTS4 l_endian;
+ INTS4 l_version;
+ INTS4 l_bufsize;
+ INTS4 l_buffers;
+ INTS4 l_events;
+ INTS4 l_filesize;
+ INTS4 l_first;
+ INTS4 l_last;
+ INTS4 l_linear;
+} s_taghe;
+
+typedef struct
+{
+ INTS4 l_event;
+ INTS4 l_offset;
+} s_tag;
+
+struct sLmdControl;
+
+
+typedef struct
+{
+ INTS4 l_server_type; /* number specifying input source */
+ INTS4 l_buf_type; /* buffer type number */
+ INTS4 l_buf_subtype; /* buffer subtype number */
+ INTS4 l_channel_no; /* file descripter or server No. */
+ INTS4 l_buf_size; /* buffer size */
+ INTS4 l_buf_no;
+ INTS4 l_buf_posi;
+ INTS4 l_buf_lmt;
+ INTS4 l_bufs_in_stream; /* # of buffers per stream */
+ INTS4 l_stream_bufs;
+ INTS4 l_io_buf_size; /* I/O buffer size=l_buf_size*l_bufs_in_stream */
+ INTS4 l_io_buf_posi;
+ INTS4 l_evt_buf_size; /* internal buffer size */
+ INTS4 l_evt_buf_posi;
+ INTS4 l_evt_size;
+ INTS4 l_timeout; /* -1 (default) no timeout */
+ INTS4 l_events; /* events since open */
+ INTS4 l_buffers; /* buffers since open */
+ INTS4 l_kbytes; /* kbytes since open */
+ INTS4 l_first_get;
+ INTS4 l_first_put;
+ INTS4 l_first_buf;
+ INTS4 l_frag_len;
+ CHARS *pc_io_buf; /* pointer to I/O buffer to server */
+ CHARS *pc_evt_buf; /* pointer to internal event buffer */
+ s_bufhe *ps_bufhe;
+ s_bufhe s_bufhe_1; /* keep buffer header of 1st buffer for spanned event */
+ s_ve10_1 *ps_ve10_1;
+ CHARS c_channel[128]; /* channel name */
+ INTS4 l_tagfile_no; /* file descripter or server No. */
+ INTS4 l_tagswap;
+ INTS4 l_lmdswap;
+ s_taghe *ps_taghe;
+ s_tag *ps_tag;
+ sLmdControl *pLmd;
+ void (*cb_polling)(void); /* function to call when polling for timeout */
+} s_evt_channel;
+
+INTS4 f_evt_cre_tagfile(CHARS *,CHARS *, INTS4 (*)());
+INTS4 f_evt_get_tagopen(s_evt_channel *,CHARS *,CHARS *,CHARS **,INTS4);
+INTS4 f_evt_get_tagevent(s_evt_channel *,INTS4,INTS4,INTS4 **);
+INTS4 f_evt_get_tagnext(s_evt_channel *,INTS4,INTS4 **);
+INTS4 f_evt_get_tagclose(s_evt_channel *);
+INTS4 f_evt_get_open(INTS4, CHARS *, s_evt_channel *, CHARS **, INTS4, INTS4);
+INTS4 f_evt_get_event(s_evt_channel *, INTS4 **, INTS4 **);
+INTS4 f_evt_get_subevent(s_ve10_1 *,INTS4,INTS4 **,INTS4 **,INTS4 *);
+INTS4 f_evt_get_buffer(s_evt_channel *, INTS4 *);
+INTS4 f_evt_get_close(s_evt_channel *);
+CHARS * f_evt_get_buffer_ptr(s_evt_channel *);
+INTS4 f_evt_skip_buffer(s_evt_channel *, INTS4);
+INTS4 f_evt_put_open(CHARS *,INTS4,INTS4,INTS4,INTS4,s_evt_channel *,CHARS *);
+INTS4 f_evt_put_event(s_evt_channel *, INTS4 *);
+INTS4 f_evt_put_buffer(s_evt_channel *, s_bufhe *);
+INTS4 f_evt_put_close(s_evt_channel *);
+INTS4 f_evt_type(s_bufhe *,s_evhe *,INTS4,INTS4,INTS4,INTS4);
+INTS4 f_evt_error( INTS4 , CHARS * , INTS4 );
+INTS4 f_evt_timeout(s_evt_channel *, INTS4 );
+INTS4 f_evt_source_port(INTS4 l_port);
+INTS4 f_evt_rev_port(INTS4); /* obsolete */
+INTS4 f_evt_swap(CHARS *, INTS4);
+s_evt_channel * f_evt_control(void);
+
+/* ******************************/
+/* Input selector */
+/* ******************************/
+#define GETEVT__FILE 1
+#define GETEVT__STREAM 2
+#define GETEVT__TRANS 3
+#define GETEVT__EVENT 4
+#define GETEVT__REVSERV 5
+#define GETEVT__RFIO 6
+#define GETEVT__TAGINDEX 10
+#define GETEVT__TAGNUMBER 11
+/* ********************************************************************** */
+/* error messages */
+/* ********************************************************************** */
+#define GETEVT__SUCCESS 0
+#define GETEVT__FAILURE 1
+#define GETEVT__FRAGMENT 2
+#define GETEVT__NOMORE 3
+#define GETEVT__NOFILE 4
+#define GETEVT__NOSERVER 5
+#define GETEVT__RDERR 6
+#define GETEVT__CLOSE_ERR 7
+#define GETEVT__NOCHANNEL 8
+#define GETEVT__TIMEOUT 9
+#define GETEVT__NOTAGFILE 10
+#define GETEVT__NOTAG 11
+#define GETEVT__TAGRDERR 12
+#define GETEVT__TAGWRERR 13
+#define GETEVT__NOLMDFILE 14
+
+#define PUTEVT__SUCCESS 0
+#define PUTEVT__FILE_EXIST 101
+#define PUTEVT__FAILURE 102
+#define PUTEVT__TOOBIG 103
+#define PUTEVT__TOO_SMALLS 104
+#define PUTEVT__CLOSE_ERR 105
+#define PUTEVT__WRERR 106
+#define PUTEVT__NOCHANNEL 107
+
+#endif
+/***************** End f_evt.h ******************************/
diff --git a/plugins/olmd/mbsapi/f_radware.c b/plugins/olmd/mbsapi/f_radware.c
new file mode 100644
index 00000000..32621db0
--- /dev/null
+++ b/plugins/olmd/mbsapi/f_radware.c
@@ -0,0 +1,125 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "f_radware.h"
+#include "typedefs.h"
+
+#ifdef GSI__WINNT
+#include
+#else
+#include
+#endif
+
+#define HIS__BASPERM 0774
+//*************************************************************
+int f_radware_out1d(char *pc_file, char *pc_name, float *pr_data, int l_chan, int l_over)
+{
+ int i32_fd, i32_bytes, i32_hislen;
+ int l_status,l_head[6];
+ char c_str[128];
+
+ if(l_over) // delete old file
+{
+ strcpy(c_str,"rm ");
+ strncat(c_str, pc_file, sizeof(c_str)-1);
+ system(c_str);
+}
+i32_fd = open(pc_file, O_WRONLY | O_CREAT | O_EXCL, HIS__BASPERM);
+if (i32_fd < 0)
+{
+ printf("Error %d opening file %s, already exists?\n",errno, pc_file);
+ return(1);
+}
+//write file
+strncpy(c_str,pc_name, sizeof(c_str));
+strncat(c_str," ", sizeof(c_str)-1);
+l_head[0]=24;
+l_head[1]=1;
+l_head[2]=1;
+l_head[3]=1;
+l_head[4]=24;
+l_head[5]=l_chan*4; /* record size */
+
+i32_bytes = write(i32_fd, (char *) l_head, 4);
+i32_bytes += write(i32_fd, c_str, 8);
+l_head[0] = l_chan;
+i32_bytes += write(i32_fd, (char *) l_head, 24); /* includes record size */
+
+i32_bytes += write(i32_fd, (char *) pr_data, l_chan*4);
+l_head[0] = l_chan*4;
+i32_bytes += write(i32_fd, (char *) l_head, 4);
+
+i32_hislen = l_chan*4 + 40;
+if (i32_bytes == i32_hislen)
+{
+ // printf("Histogram %32s: %d bytes (data %d) written to %s\n",
+ // pc_name,i32_bytes,l_chan*4,pc_file);
+}
+else
+{
+ printf("Error %d. Dumping histogram:%s, %d bytes written to %s\n",
+ errno,pc_name,i32_bytes,pc_file);
+}
+l_status = close(i32_fd);
+if (l_status != 0)
+{
+ printf("Error %d. Close %s failed!\n",errno,pc_file);
+ return(1);
+}
+return(0);
+}
+//*************************************************************
+int f_radware_out2d(char *pc_file, char *pc_name, int *pl_data, int l_chan, int l_over)
+{
+ int i32_fd, i32_bytes;
+ int l_status;
+ char c_str[128];
+
+if(l_over)
+{
+ strcpy(c_str,"rm ");
+ strncat(c_str,pc_file, sizeof(c_str)-1);
+ system(c_str);
+}
+i32_fd = open(pc_file, O_WRONLY | O_CREAT | O_EXCL, HIS__BASPERM);
+if (i32_fd < 0)
+{
+ printf("Error %d opening file %s, already exists?\n",errno, pc_file);
+ return(1);
+}
+i32_bytes = write(i32_fd, (char *) pl_data, l_chan*4);
+if (i32_bytes == l_chan*4)
+{
+ // printf("Histogram %32s: %d bytes written to %s\n",
+ // pc_name,i32_bytes,pc_file);
+}
+else
+{
+ printf("Error %d. Dumping histogram:%s, only %d bytes written to %s\n",
+ errno,pc_name,i32_bytes,pc_file);
+}
+l_status = close(i32_fd);
+if (l_status != 0)
+{
+ printf("Error %d. Close %s failed!\n",errno,pc_file);
+ return(1);
+}
+return(0);
+}
diff --git a/plugins/olmd/mbsapi/f_radware.h b/plugins/olmd/mbsapi/f_radware.h
new file mode 100644
index 00000000..938d2170
--- /dev/null
+++ b/plugins/olmd/mbsapi/f_radware.h
@@ -0,0 +1,28 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef F_RADWARE_H
+#define F_RADWARE_H
+
+// Output functions for Radware
+
+int f_radware_out1d(char *file, char *histogram, float *data, int channels, int over);
+int f_radware_out2d(char *file, char *histogram, int *data, int channels, int over);
+
+// file : output file name
+// histogram: name of histogram
+// data : pointer to data (float for 1d, int for 2d)
+// channels : # of channels
+// over : flag, if = 1, delete file first
+
+#endif
diff --git a/plugins/olmd/mbsapi/f_ut_utime.c b/plugins/olmd/mbsapi/f_ut_utime.c
new file mode 100644
index 00000000..2b0bd31c
--- /dev/null
+++ b/plugins/olmd/mbsapi/f_ut_utime.c
@@ -0,0 +1,108 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#include "f_ut_utime.h"
+
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 52 */
+/* D-64220 Darmstadt */
+/* */
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_ut_utime */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : char * = f_ut_utime(l_sec,l_msec,char *pc_time) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Returns date/time string in VMS format */
+/* day-month-year hours:min:sec.00 */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ l_sec : Seconds as returned from ftime function */
+/*+ l_msec : Milliseconds */
+/*+ pc_time : Address of string (23 characters) */
+/* */
+/*2+Implementation************+****************************************/
+/*+ Utility : util */
+/*+ File name : f_ut_utime.c */
+/*+ Home direct.: path */
+/*+ Declaration : char *f_ut_utime(char *); */
+/*+ Version : 1.01 */
+/*+ Author : H.G.Essel */
+/*+ Created : 24-Mar-1994 */
+/*+ Object libr.: */
+/*+ Updates : Date Purpose */
+/*- 14-apr-97 : POSIX now OK on Lynx /HE */
+/* gcc -mposix4d9 -mthreads -DLynx */
+/*1- C Procedure *************+****************************************/
+
+#include
+#include
+#include "f_ut_time.h"
+
+INTS4 f_ut_utime(INTS4 l_sec, INTS4 l_msec, CHARS *pc_time)
+{
+ // struct timeb tp;
+ struct timespec tp;
+ struct tm st_time;
+#ifndef _MSC_VER
+ struct tm buf_time;
+#endif
+ CHARS c_allmon[37]="JanFebMarAprMayJunJulAugSepOctNovDec";
+ CHARS c_mon[4];
+ CHARS *pc_mon;
+
+ if(l_sec == 0) {
+ strcpy(pc_time,"no valid date");
+ return(0);
+ }
+ *pc_time=0;
+ if (l_sec < 0) {
+ clock_gettime(CLOCK_REALTIME, &tp);
+ l_msec = tp.tv_nsec / 1000000;
+ } else {
+ tp.tv_sec = l_sec;
+ }
+#ifdef _MSC_VER
+ st_time = *localtime(&tp.tv_sec);
+#else
+ st_time = *localtime_r(&tp.tv_sec, &buf_time);
+#endif
+ pc_mon = (CHARS *) &c_allmon;
+ pc_mon += (st_time.tm_mon * 3);
+ strncpy(c_mon,pc_mon,3);
+ c_mon[3]='\0';
+ if(st_time.tm_year < 100)
+ sprintf(pc_time,"%02d-%s-19%02d %02d:%02d:%02d.%02d"
+ ,st_time.tm_mday
+ ,c_mon
+ ,st_time.tm_year
+ ,st_time.tm_hour
+ ,st_time.tm_min
+ ,st_time.tm_sec
+ ,l_msec/10);
+ else
+ sprintf(pc_time,"%02d-%s-20%02d %02d:%02d:%02d.%02d"
+ ,st_time.tm_mday
+ ,c_mon
+ ,st_time.tm_year-100
+ ,st_time.tm_hour
+ ,st_time.tm_min
+ ,st_time.tm_sec
+ ,l_msec/10);
+ return(0);
+}
diff --git a/plugins/olmd/mbsapi/f_ut_utime.h b/plugins/olmd/mbsapi/f_ut_utime.h
new file mode 100644
index 00000000..f427338a
--- /dev/null
+++ b/plugins/olmd/mbsapi/f_ut_utime.h
@@ -0,0 +1,21 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef F_UT_UTIME_H
+#define F_UT_UTIME_H
+
+#include "typedefs.h"
+
+INTS4 f_ut_utime(INTS4 l_sec, INTS4 l_msec, CHARS *pc_time);
+
+#endif
diff --git a/plugins/olmd/mbsapi/gps_sc_def.h b/plugins/olmd/mbsapi/gps_sc_def.h
new file mode 100644
index 00000000..1a5ab210
--- /dev/null
+++ b/plugins/olmd/mbsapi/gps_sc_def.h
@@ -0,0 +1,102 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+/*********************************************************************
+ * GPS_SC_DEF.H
+ *
+ * Include file MUST be EQUAL on GPS-Server, GPS-Client and SBS-Monitor
+ *
+ * 02-Feb-1994, RSM: file renamed from M_PAW_SC.H and def. names modified
+ *
+ *********************************************************************
+ * 10. 3.98, H.G: implemented in Linux
+ *********************************************************************
+ */
+
+#ifndef GPS_SC_DEF_H
+#define GPS_SC_DEF_H
+
+#include "typedefs.h"
+
+#define EB__BUFFER_DATA 131072
+#define GPS__OUTBUFSIZ 16384 /* client output buffer siz*/
+ /* bytes */
+#define GPS__EVT_BUFSIZ 16384 /* event buffer size for */
+ /* spanned evt in bytes */
+#define GPS__MAXFLT 32
+#define GPS__MAXFLTDESCR 16
+#define GPS__MAXCLIENTS 6
+
+#define GPS__CLNT_SNDFLT 404 /* (GPS__MAXFLT * 3 +
+ * 5LW) * 4
+ */
+ /* length in bytes! */
+ /* the filter is used in "s_client.h". For filter */
+ /* and descriptor definition see "s_filter.h", for */
+ /* length definitions "s_clntbuf.h", "s_clntoutbuf.h"*/
+
+
+/* +++++++++++++++++++++++++++++++++++++ */
+/* +++ environment of the TX partner +++ */
+/* +++++++++++++++++++++++++++++++++++++ */
+#define GPS__ENV_TESTBIT 0x00000001
+
+/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+/* ++ the setting of GPS__ENV_ENDIEN is implementation dependent!! ++ */
+/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */
+/* little endian (bit0 on the right side) DEC, INTEL machines */
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */
+#ifdef VMS /* DEC: VMS, OpenVMS */
+#define GPS__ENV_ENDIAN 0x0
+#endif
+
+#ifdef ultrix /* DEC Ultrix */
+#define GPS__ENV_ENDIAN 0x0
+#endif
+
+#ifdef Linux /* Linux */
+#define GPS__ENV_ENDIAN 0x0
+#endif
+
+#ifdef GSI__WINNT /* Windows NT */
+#define GPS__ENV_ENDIAN 0x0
+#endif
+
+#ifdef Darwin /* Mac OS X */
+#define GPS__ENV_ENDIAN 0x0
+#endif
+
+
+
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */
+/* big endian (bit0 on the left side) IBM, HP, 68xxx... */
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */
+#ifdef _AIX /* AIX */
+#define GPS__ENV_ENDIAN 0xFFFFFFFF
+#endif
+
+#ifdef HPUX /* HP-UX */
+#define GPS__ENV_ENDIAN 0xFFFFFFFF
+#endif
+
+#ifdef Lynx /* LynxOS */
+#define GPS__ENV_ENDIAN 0xFFFFFFFF
+#endif
+
+#ifdef Solaris /* Sun Sparc Solaris */
+#define GPS__ENV_ENDIAN 0xFFFFFFFF
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/sMbs.h b/plugins/olmd/mbsapi/sMbs.h
new file mode 100644
index 00000000..c3800e75
--- /dev/null
+++ b/plugins/olmd/mbsapi/sMbs.h
@@ -0,0 +1,128 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef MbsStruct_H
+#define MbsStruct_H
+
+#define LMD__TYPE_FILE_HEADER_101_1 0x00010065
+#define LMD__TYPE_EVENT_HEADER_10_1 0x0001000a
+#define LMD__TYPE_FILE_INDEX_101_2 0x00020065
+#define LMD__TYPE_BUFFER_HEADER_10_1 0x0001000a
+#define LMD__TYPE_BUFFER_HEADER_100_1 0x00010064
+#define LMD__TYPE_TIME_STAMP_11_1 0x0001000b
+#define LMD__GET_EVENTS NULL
+#define LMD__STANDARD_HEADER NULL
+#define LMD__INTERNAL_HEADER NULL
+#define LMD__INDEX 1
+#define LMD__OVERWRITE 1
+#define LMD__LARGE_FILE 1
+#define LMD__MIN_BUFFER 0
+#define LMD__BUFFER 1
+#define LMD__VERBOSE 1
+#define LMD__NO_VERBOSE 0
+#define LMD__NO_BUFFER 0
+#define LMD__NO_INDEX 0
+#define LMD__NO_OVERWRITE 0
+#define LMD__NO_LARGE_FILE 0
+#define LMD__NO_VERBOSE 0
+#define LMD__VERBOSE 1
+#define LMD__ENDIAN_LITTLE 1
+#define LMD__ENDIAN_BIG 2
+#define LMD__ENDIAN_UNKNOWN 0
+
+#include "s_stdint.h"
+
+typedef uint64_t lmdoff_t;
+
+// must #include
+// on Lynx, define int32_t, uint32_t, int16_t
+// structure used to talk between client and server
+// Client connects to server (MBS) and reads this structure first
+
+//--------------------------------------------------
+// Structure maps the MBS transport info buffer
+typedef struct{
+ uint32_t iEndian; // byte order. Set to 1 by sender
+ uint32_t iMaxBytes; // maximum buffer size
+ uint32_t iBuffers; // buffers per stream
+ uint32_t iStreams; // number of streams
+} sMbsTransportInfo;
+
+//--------------------------------------------------
+// Buffer header, maps s_bufhe, some fields used in different way
+typedef struct{
+ uint32_t iMaxWords; // compatible with s_bufhe (total buffer size - header)
+ uint32_t iType; // compatible with s_bufhe, low=type (=100), high=subtype
+ uint32_t iUsed; // not used for iMaxWords>MAX__DLEN (16360), low 16bits only
+ uint32_t iBuffer; // compatible with s_bufhe
+ uint32_t iElements; // compatible with s_bufhe
+ uint32_t iTemp; // Used volatile
+ uint32_t iTimeSpecSec; // compatible with s_bufhe (2*32bit)
+ uint32_t iTimeSpecNanoSec; // compatible with s_bufhe (2*32bit)
+ // struct timespec TimeSpec;
+ uint32_t iEndian; // compatible with s_bufhe free[0]
+ uint32_t iWrittenEndian;// one of LMD__ENDIAN_x
+ uint32_t iUsedWords; // total words without header to read for type=100, free[2]
+ uint32_t iFree3; // free[3]
+} sMbsBufferHeader;
+
+//--------------------------------------------------
+// Buffer header, maps s_bufhe
+typedef struct{
+ uint32_t iMaxWords; // compatible with s_bufhe (total buffer size - header)
+ uint32_t iType; // compatible with s_bufhe, low=type (=100), high=subtype
+ lmdoff_t iTableOffset; // optional offset to element offset table in file
+ uint32_t iElements; // compatible with s_bufhe
+ uint32_t iOffsetSize; // Offset size, 4 or 8 [bytes]
+ uint32_t iTimeSpecSec; // compatible with s_bufhe (2*32bit)
+ uint32_t iTimeSpecNanoSec; // compatible with s_bufhe (2*32bit)
+ // struct timespec TimeSpec;
+ uint32_t iEndian; // compatible with s_bufhe free[0]
+ uint32_t iWrittenEndian;// one of LMD__ENDIAN_x
+ uint32_t iUsedWords; // total words without header to read for type=100, free[2]
+ uint32_t iFree3; // free[3]
+} sMbsFileHeader;
+
+//--------------------------------------------------
+typedef struct{
+ uint32_t iMaxWords;
+ uint32_t iType;
+ uint32_t iTimeSpecSec;
+ uint32_t iTimeSpecNanoSec;
+} sMbsTimeStamp;
+
+//--------------------------------------------------
+// maps s_evhe
+typedef struct{
+ uint32_t iWords; // following data words
+ uint32_t iType; // compatible with s_ve10_1, low=type (=10), high=subtype
+} sMbsHeader;
+
+//--------------------------------------------------
+// maps s_ve10_1
+typedef struct{
+ uint32_t iWords; // data words + 4
+ uint32_t iType; // compatible with s_ve10_1, low=type (=10), high=subtype
+ uint32_t iTrigger;
+ uint32_t iEventNumber;
+} sMbsEventHeader;
+
+//--------------------------------------------------
+// maps s_ves10_1
+typedef struct{
+ uint32_t iWords; // data words + 2
+ uint32_t iType; // compatible with s_ves10_1, low=type (=10), high=subtype
+ uint32_t iSubeventID; // 2 low bytes=procid, next byte=subcrate, high byte control
+} sMbsSubeventHeader;
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_bufhe.h b/plugins/olmd/mbsapi/s_bufhe.h
new file mode 100644
index 00000000..aa7314c1
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_bufhe.h
@@ -0,0 +1,59 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_BUFHE_H
+#define S_BUFHE_H
+
+#include "typedefs.h"
+/* Generated from SA$BUFHE.TXT */
+/* Swapping enabled */
+ /* ================= GSI Buffer header ======================= */
+#define MAX__DLEN 16360
+
+#if MBS_ENDIAN == 1
+
+typedef struct
+{
+INTS4 l_dlen; /* Length of data field in words */
+INTS2 i_subtype;
+INTS2 i_type;
+CHARS h_begin; /* Fragment at end of buffer */
+CHARS h_end; /* Fragment at begin of buffer */
+INTS2 i_used; /* Used length of data field in words */
+INTS4 l_buf; /* Current buffer number */
+INTS4 l_evt; /* Number of fragments */
+INTS4 l_current_i; /* Index, temporarily used */
+INTS4 l_time[2];
+INTS4 l_free[4];
+} s_bufhe;
+
+#else
+
+typedef struct
+{
+INTS4 l_dlen; /* Length of data field in words */
+INTS2 i_type;
+INTS2 i_subtype;
+INTS2 i_used; /* Used length of data field in words */
+CHARS h_end; /* Fragment at begin of buffer */
+CHARS h_begin; /* Fragment at end of buffer */
+INTS4 l_buf; /* Current buffer number */
+INTS4 l_evt; /* Number of fragments */
+INTS4 l_current_i; /* Index, temporarily used */
+INTS4 l_time[2];
+INTS4 l_free[4];
+} s_bufhe;
+
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_bufhe_swap.h b/plugins/olmd/mbsapi/s_bufhe_swap.h
new file mode 100644
index 00000000..64c01572
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_bufhe_swap.h
@@ -0,0 +1,19 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_BUFHE_SWAP_H
+#define S_BUFHE_SWAP_H
+
+#include "s_bufhe.h"
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_clnt_filter.h b/plugins/olmd/mbsapi/s_clnt_filter.h
new file mode 100644
index 00000000..adadbe8f
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_clnt_filter.h
@@ -0,0 +1,63 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+/* filter structure for CLIENT */
+
+#ifndef S_CLNT_FILTER_H
+#define S_CLNT_FILTER_H
+
+#include "gps_sc_def.h"
+
+#if MBS_ENDIAN == 1
+
+struct s_clnt_filter
+ {
+/* -------> Swapped <-------- */
+/* --------=========--------- */
+ /* --- control byte ordering and machine type (2LW) ---- */
+ unsigned long l_testbit; /* bit pattern */
+ unsigned long l_endian; /* endian of sender */
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ long l_numb_of_evt; /* numb of events to send */
+ long l_sample_rate; /* flt match sample rate */
+ long l_flush_rate; /* buffer flushing rate [sec]*/
+ struct s_filter filter[GPS__MAXFLT];/* 32 filter express (3LW) */
+ struct s_flt_descr flt_descr[GPS__MAXFLTDESCR]; /* Filter descriptor*/
+ short unsigned if_fltsev; /* filter on subevent */
+ short unsigned if_fltevt; /* filter on event */
+ short unsigned if_wrtsev; /* write subevts (numb of sev)*/
+ short unsigned if_wrtevt; /* write whole event */
+ };
+
+#else
+
+struct s_clnt_filter
+ {
+ /* --- control byte ordering and machine type (2LW) ---- */
+ unsigned int l_testbit; /* bit pattern */
+ unsigned int l_endian; /* endian of sender */
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ int l_numb_of_evt; /* numb of events to send */
+ int l_sample_rate; /* flt match sample rate */
+ int l_flush_rate; /* buffer flushing rate [sec]*/
+ struct s_filter filter[GPS__MAXFLT];/* 32 filter express (3LW) */
+ struct s_flt_descr flt_descr[GPS__MAXFLTDESCR]; /* Filter descriptor*/
+ short unsigned if_fltevt; /* filter on event */
+ short unsigned if_fltsev; /* filter on subevent */
+ short unsigned if_wrtevt; /* write whole event */
+ short unsigned if_wrtsev; /* write subevts (numb of sev)*/
+ };
+
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_clnt_filter_swap.h b/plugins/olmd/mbsapi/s_clnt_filter_swap.h
new file mode 100644
index 00000000..ae6eb7f9
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_clnt_filter_swap.h
@@ -0,0 +1,19 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_CLNT_FILTER_SWAP_H
+#define S_CLNT_FILTER_SWAP_H
+
+#include "s_clnt_filter.h"
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_clntbuf.h b/plugins/olmd/mbsapi/s_clntbuf.h
new file mode 100644
index 00000000..eb7fcf7d
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_clntbuf.h
@@ -0,0 +1,74 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+/*************************************************************************/
+/* +++ GSI Darmstadt +++ */
+/* +++ +++ */
+/*************************************************************************/
+/*+File name S_CLNTBUF.H */
+/* */
+/*************************************************************************/
+/*+ Update Date Purpose */
+/*- 10-Dec-1993 : Define testbit and low or high endian */
+/* and some types changed and 2LW added */
+/*- 27-Jan-1994 : CLNT_BUFH_LW changed to 11 (RSM) */
+/*- 02-Feb-1994 : definitions in CLNT_BUF_DEF.H , */
+/* def. names changed. (RSM) */
+/*************************************************************************/
+
+/* RSM 19-MAR-1993 */
+/* is a part of s_clntoutbuf */
+
+#ifndef S_CLNTBUF_H
+#define S_CLNTBUF_H
+
+struct s_clntbuf
+ {
+ /* ------ first part of s_clntoutbuf omitted ----------- */
+ /* --- control byte ordering and machine type (2LW) ---- */
+ unsigned int l_testbit; /* bit pattern */
+ unsigned int l_endian; /* endian of sender */
+ /* ----------------------------------------------------- */
+ /* ----- length is CLNT__BUFHEAD ----------------------- */
+ int l_dlen; /* data length [bytes] */
+ int l_free; /* free length [bytes] */
+ int l_events; /* events in buffer */
+ int l_maxbufsiz; /* maximum buffer size */
+ int l_bytestosnd; /* sent bytes */
+ int l_numbuftosnd; /* number of buffers to send */
+ int l_client_con; /* currently connect clients */
+ int unsigned l_buffertype; /* type: data:1 msg:2 flush:4 */
+ /* last:8 1stBUF:16 */
+ /* (inclusive) (mask) */
+ int unsigned l_msgtyp; /* I:1 W:2 E:4 F:8 (exclusive)*/
+ char c_message[CLNT__MSGLEN]; /* error msg and other */
+ /* ----- part of s_control structure ------------------- */
+ /* ----- length is CLNT__INFO_CONTROL ------------------ */
+ int unsigned l_inbuf_read_cnt; /* count read buffer */
+ int unsigned l_inbuf_rdok_cnt; /* count read buffer that are o.k */
+ int unsigned l_inbuf_skip_cnt; /* count skipped buffer */
+ int unsigned l_inbuf_byrd_cnt; /* count read bytes */
+ int unsigned l_inbuf_proc_cnt; /* count processed buffer */
+ int unsigned l_inbuf_prev_cnt; /* count processed events */
+ /* ----- part of s_client structure -------------------- */
+ /* ----- length is CLNT__INFO_CLIENT ------------------- */
+ int unsigned l_clntoutbuf_sdev; /* sent events */
+ int unsigned l_clntoutbuf_sdby; /* sent bytes */
+ int unsigned l_clntoutbuf_sdbf; /* sent buffer */
+ int unsigned l_clntoutbuf_prev; /* processed evt since con */
+ int unsigned l_clntoutbuf_fltm; /* filter matched on evt */
+ /* ----------------------------------------------------------------- */
+ char c_buffer[GPS__OUTBUFSIZ];
+ };
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_evhe.h b/plugins/olmd/mbsapi/s_evhe.h
new file mode 100644
index 00000000..325b5e82
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_evhe.h
@@ -0,0 +1,41 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_EVHE_H
+#define S_EVHE_H
+
+#include "typedefs.h"
+
+#if MBS_ENDIAN == 1
+
+/* ================= GSI VME General event header =============== */
+typedef struct
+{
+INTS4 l_dlen; /* Length of data in words */
+INTS2 i_subtype;
+INTS2 i_type;
+} s_evhe;
+ /* ------------------------------------------------------------------ */
+
+#else
+
+typedef struct
+{
+INTS4 l_dlen; /* Length of data in words */
+INTS2 i_type;
+INTS2 i_subtype;
+} s_evhe;
+
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_evhe_swap.h b/plugins/olmd/mbsapi/s_evhe_swap.h
new file mode 100644
index 00000000..56b72a24
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_evhe_swap.h
@@ -0,0 +1,19 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_EVHE_SWAP_H
+#define S_EVHE_SWAP_H
+
+#include "s_evhe.h"
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_filhe.h b/plugins/olmd/mbsapi/s_filhe.h
new file mode 100644
index 00000000..02b4f880
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_filhe.h
@@ -0,0 +1,84 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_FILHE_H
+#define S_FILHE_H
+
+#include "typedefs.h"
+
+struct cv_string
+{
+ INTS2 string_l;
+ CHARS string[78];
+} ;
+
+
+#if MBS_ENDIAN == 1
+
+typedef struct {
+ INTS4 filhe_dlen; /* length of data in words */
+ INTS2 filhe_subtype; /* = 1 */
+ INTS2 filhe_type; /* = 2000 */
+ INTS2 filhe_frag;
+ INTS2 filhe_used;
+ INTS4 filhe_buf;
+ INTS4 filhe_evt;
+ INTS4 filhe_current_i;
+ INTS4 filhe_stime[2];
+ INTS4 filhe_free[4]; /* free[0] = 1 -> swap */
+ INTS2 filhe_label_l; /* length of tape label string */
+ CHARS filhe_label[30]; /* tape label */
+ INTS2 filhe_file_l; /* length of file name */
+ CHARS filhe_file[86]; /* file name */
+ INTS2 filhe_user_l; /* length of user name */
+ CHARS filhe_user[30]; /* user name */
+ CHARS filhe_time[24]; /* date and time string */
+ INTS2 filhe_run_l; /* length of run id */
+ CHARS filhe_run[66]; /* run id */
+ INTS2 filhe_exp_l; /* length of explanation */
+ CHARS filhe_exp[66]; /* explanation */
+ INTS4 filhe_lines; /* # of comment lines */
+ struct cv_string s_strings[30]; /* max 30 comment lines */
+} s_filhe;
+
+#else
+
+typedef struct {
+ INTS4 filhe_dlen; /* length of data in words */
+ INTS2 filhe_type; /* = 2000 */
+ INTS2 filhe_subtype; /* = 1 */
+ INTS2 filhe_used;
+ INTS2 filhe_frag;
+ INTS4 filhe_buf;
+ INTS4 filhe_evt;
+ INTS4 filhe_current_i;
+ INTS4 filhe_stime[2];
+ INTS4 filhe_free[4]; /* free[0] = 1 -> swap */
+ INTS2 filhe_label_l; /* length of tape label string */
+ CHARS filhe_label[30]; /* tape label */
+ INTS2 filhe_file_l; /* length of file name */
+ CHARS filhe_file[86]; /* file name */
+ INTS2 filhe_user_l; /* length of user name */
+ CHARS filhe_user[30]; /* user name */
+ CHARS filhe_time[24]; /* date and time string */
+ INTS2 filhe_run_l; /* length of run id */
+ CHARS filhe_run[66]; /* run id */
+ INTS2 filhe_exp_l; /* length of explanation */
+ CHARS filhe_exp[66]; /* explanation */
+ INTS4 filhe_lines; /* # of comment lines */
+ struct cv_string s_strings[30]; /* max 30 comment lines */
+} s_filhe;
+
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_filhe_swap.h b/plugins/olmd/mbsapi/s_filhe_swap.h
new file mode 100644
index 00000000..c2464f6d
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_filhe_swap.h
@@ -0,0 +1,19 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_FILHE_SWAP_H
+#define S_FILHE_SWAP_H
+
+#include "s_filhe.h"
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_filter.h b/plugins/olmd/mbsapi/s_filter.h
new file mode 100644
index 00000000..02dc3a67
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_filter.h
@@ -0,0 +1,30 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_FILTER_H
+#define S_FILTER_H
+
+#include "typedefs.h"
+/* +++ s_filter.h +++
+ * client structure for SBS monitor
+ * (see also s_filter.h for GPS-Server on (Open)VMS / clients)
+ * R.S. Mayer
+ * 18-Feb-1994
+*/
+struct s_filter {
+ INTU4 l_pattern;
+ INTS4 l_offset; /* offset >0: LW <0: Words */
+ INTU4 l_opcode;
+};
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_flt_descr.h b/plugins/olmd/mbsapi/s_flt_descr.h
new file mode 100644
index 00000000..b71ffb31
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_flt_descr.h
@@ -0,0 +1,55 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_FLT_DESCR_H
+#define S_FLT_DESCR_H
+
+#include "typedefs.h"
+
+#if MBS_ENDIAN == 1
+
+/* filter descriptor */
+/* -------> Swapped <-------- */
+/* --------=========--------- */
+struct s_flt_descr {
+ /* indices to filter[] */
+ char h_fltblkend; /* end filter block */
+ char h_fltblkbeg; /* begin filter block */
+ char hf_fltdescr; /* filter descriptor */
+ char hf_wrtdescr; /* write descriptor */
+ /* index to flt_descr[] */
+ short i_descriptors; /* number of descriptors */
+ char h_dummy;
+ char h_nextdescr; /* next descriptor */
+ };
+
+
+#else
+
+/* filter descriptor */
+struct s_flt_descr
+ {
+ char hf_wrtdescr; /* write descriptor */
+ char hf_fltdescr; /* filter descriptor */
+ /* indices to filter[] */
+ char h_fltblkbeg; /* begin filter block */
+ char h_fltblkend; /* end filter block */
+ /* index to flt_descr[] */
+ char h_nextdescr; /* next descriptor */
+ char h_dummy;
+ short i_descriptors; /* number of descriptors */
+ };
+
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_flt_descr_swap.h b/plugins/olmd/mbsapi/s_flt_descr_swap.h
new file mode 100644
index 00000000..58e85efc
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_flt_descr_swap.h
@@ -0,0 +1,19 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_FLT_DESCR_SWAP_H
+#define S_FLT_DESCR_SWAP_H
+
+#include "s_flt_descr.h"
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_opc1.h b/plugins/olmd/mbsapi/s_opc1.h
new file mode 100644
index 00000000..4b717a33
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_opc1.h
@@ -0,0 +1,56 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_OPC1_H
+#define S_OPC1_H
+
+#include "typedefs.h"
+
+#if MBS_ENDIAN == 1
+
+struct s_opc1 { /* ++ byte1 (LSB) ++ */
+ char h_flt_len; /* ++ byte4 (MSB) ++ length of filter*/
+ char h_next_fltblk; /* ++ byte3 ++ next filter blk */
+ char h_fltspec; /* ++ byte2 filter specification */
+ /* +++ 25-Jan-1994 reversed bit sequence +++ */
+ unsigned b1_lnkf2 :1; /* lnk different flts blks */
+ unsigned b1_lnkf1 :1; /* lnk filters: and:1 or:0 */
+ unsigned b3_opc :3; /* opcode */
+ unsigned b1_selwrt:1; /* select write of evt/sev */
+ unsigned b1_selflt:1; /* select event/subevent filter */
+ unsigned b1_evtsev :1; /* 1:event/0:subevt active for sel */
+/* REM : h_next_fltblk and h_flt_len are ABSOLUTE adresses !!! */
+};
+
+
+#else
+
+/* struct for filter opcode */
+struct s_opc1
+ { /* ++ byte1 (LSB) ++ */
+ unsigned b1_evtsev :1; /* 1:event/0:subevt active for sel */
+ unsigned b1_selflt:1; /* select event/subevent filter */
+ unsigned b1_selwrt:1; /* select write of evt/sev */
+ unsigned b3_opc :3; /* opcode */
+ unsigned b1_lnkf1 :1; /* lnk filters: and:1 or:0 */
+ unsigned b1_lnkf2 :1; /* lnk different flts blks */
+ char h_fltspec; /* ++ byte2 filter specification */
+ char h_next_fltblk; /* ++ byte3 ++ next filter blk */
+ char h_flt_len; /* ++ byte4 (MSB) ++ length of filter*/
+ };
+
+/* REM : h_next_fltblk and h_flt_len are ABSOLUTE adresses !!! */
+
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_pat.h b/plugins/olmd/mbsapi/s_pat.h
new file mode 100644
index 00000000..edc941cc
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_pat.h
@@ -0,0 +1,65 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_PAT_H
+#define S_PAT_H
+
+#include "typedefs.h"
+
+#if MBS_ENDIAN == 1
+
+/* identities for filter patterns */
+struct s_pat1
+ {
+ short i_dummy;
+ short i_trigger;
+ };
+
+struct s_pat2
+ {
+ char h_control;
+ char h_subcrate;
+ short i_procid;
+ };
+
+struct s_pat3
+ {
+ short i_subtype;
+ short i_type;
+ };
+
+#else
+
+/* identities for filter patterns */
+struct s_pat1
+ {
+ short i_trigger;
+ short i_dummy;
+ };
+
+struct s_pat2
+ {
+ short i_procid;
+ char h_subcrate;
+ char h_control;
+ };
+
+struct s_pat3
+ {
+ short i_type;
+ short i_subtype;
+ };
+
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_spe.h b/plugins/olmd/mbsapi/s_spe.h
new file mode 100644
index 00000000..7878cc93
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_spe.h
@@ -0,0 +1,75 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_SPE_H
+#define S_SPE_H
+
+#include "typedefs.h"
+/* s_spe.h
+ * =======
+ *
+ * Author : Ilya Kutznetsov, R. S. Mayer
+ * Created : 20-Sep-1994
+ *
+ * modified : 14-Oct-1994 Prepared for 2-dim histograms /RSM
+ * 15-Nov-1994 Slot numbers for binary tree. /RSM
+ * 02-Dec-1994 align structure. /RSM
+ */
+
+#define HIS__HISNAMLEN 32 /* max lenght of histogram name string */
+
+typedef struct
+{
+ INTU4 ul_attr; /* flag */
+ INTS4 l_version; /* structure version mumber */
+ INTS4 i_slotlef; /* next slot left (sort) */
+ INTS4 i_slotrig; /* next slot right (sort) */
+ INTS4 l_protected; /* clear histogram? */
+ INTS4 l_bins_1; /* number of bins in dim=1 */
+ INTS4 l_bins_2; /* number of bins in dim=2 */
+ INTS4 l_dim; /* dimension size */
+ INTS4 l_data; /* relative pointer to data, */
+ INTU4 l_counts; /* total sum of counts */
+ REAL8 d_contents; /* total sum of counts */
+ INTU4 l_spare1; /* spare */
+ INTU4 l_spare2; /* spare */
+ INTU4 l_spare3; /* spare */
+ INTU4 l_spare4; /* spare */
+ INTU4 l_spare5; /* spare */
+ /* + + + dim = 1 + + + */
+ INTS4 l_outlim_up_counts; /* no of counts that are */
+ INTS4 l_outlim_low_counts; /* out of range */
+ REAL4 r_limits_low; /* upper limit */
+ REAL4 r_limits_up; /* lower limit */
+ REAL4 r_binsize; /* bin size */
+ REAL4 r_factor; /* linear trans. */
+ REAL4 r_offset; /* offset */
+ /* + + + dim = 2 + + + */
+ INTS4 l_outlim_up_counts_2; /* no of counts that are */
+ INTS4 l_outlim_low_counts_2; /* out of range */
+ REAL4 r_limits_low_2; /* energy limits dim = 2 */
+ REAL4 r_limits_up_2; /* energy limits dim = 2 */
+ REAL4 r_binsize_2; /* bin size */
+ REAL4 r_factor_2; /* linear trans. */
+ REAL4 r_offset_2;
+ /* +++ character strings +++ */
+ CHARS c_name[HIS__HISNAMLEN]; /* spect's name */
+ CHARS c_dtype[4]; /* data flag */
+ CHARS c_data_time_cre[28]; /* creation time */
+ CHARS c_clear_date[28]; /* clearing time */
+ CHARS c_lettering_res[64]; /* lettering data content */
+ CHARS c_lettering_1[64]; /* lettering 1st axis */
+ CHARS c_lettering_2[64]; /* lettering 2nd axis */
+} s_spe ;
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_stdint.h b/plugins/olmd/mbsapi/s_stdint.h
new file mode 100644
index 00000000..a33551ab
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_stdint.h
@@ -0,0 +1,65 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_STDINT_H
+#define S_STDINT_H
+
+// this is minimum types set for fixed-size integers
+
+#ifdef _MSC_VER
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include
+#include
+
+typedef __int8 int8_t;
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+#endif
+
+#ifdef Lynx
+
+typedef char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef long int64_t;
+typedef unsigned long uint64_t;
+
+#endif
+
+#ifdef Linux
+#include
+#endif
+
+#ifdef Solaris
+#include
+#endif
+
+#ifdef Darwin
+#include
+#endif
+
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_ve10_1.h b/plugins/olmd/mbsapi/s_ve10_1.h
new file mode 100644
index 00000000..482db286
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_ve10_1.h
@@ -0,0 +1,47 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_VE10_1_H
+#define S_VE10_1_H
+
+#include "typedefs.h"
+/* ================= GSI VME Event header ======================= */
+
+#if MBS_ENDIAN == 1
+
+typedef struct
+{
+INTS4 l_dlen; /* Data length + 4 in words */
+INTS2 i_subtype;
+INTS2 i_type;
+INTS2 i_trigger; /* Trigger number */
+INTS2 i_dummy; /* Not used yet */
+INTS4 l_count; /* Current event number */
+} s_ve10_1;
+ /* ------------------------------------------------------------------ */
+
+#else
+
+typedef struct
+{
+INTS4 l_dlen; /* Data length + 4 in words */
+INTS2 i_type;
+INTS2 i_subtype;
+INTS2 i_dummy; /* Not used yet */
+INTS2 i_trigger; /* Trigger number */
+INTS4 l_count; /* Current event number */
+} s_ve10_1;
+
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_ve10_1_swap.h b/plugins/olmd/mbsapi/s_ve10_1_swap.h
new file mode 100644
index 00000000..6d2298fd
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_ve10_1_swap.h
@@ -0,0 +1,19 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_VE10_1_SWAP_H
+#define S_VE10_1_SWAP_H
+
+#include "s_ve10_1.h"
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_ves10_1.h b/plugins/olmd/mbsapi/s_ves10_1.h
new file mode 100644
index 00000000..24ae8522
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_ves10_1.h
@@ -0,0 +1,47 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_VES10_1_H
+#define S_VES10_1_H
+
+#include "typedefs.h"
+/* ================= GSI VME Subevent header ======================= */
+
+#if MBS_ENDIAN == 1
+
+typedef struct
+{
+INTS4 l_dlen; /* Data length +2 in words */
+INTS2 i_subtype;
+INTS2 i_type;
+CHARS h_control; /* Processor type code */
+CHARS h_subcrate; /* Subcrate number */
+INTS2 i_procid; /* Processor ID [as loaded from VAX] */
+} s_ves10_1 ;
+ /* ------------------------------------------------------------------ */
+
+#else
+
+typedef struct
+{
+INTS4 l_dlen; /* Data length +2 in words */
+INTS2 i_type;
+INTS2 i_subtype;
+INTS2 i_procid; /* Processor ID [as loaded from VAX] */
+CHARS h_subcrate; /* Subcrate number */
+CHARS h_control; /* Processor type code */
+} s_ves10_1 ;
+
+#endif
+
+#endif
diff --git a/plugins/olmd/mbsapi/s_ves10_1_swap.h b/plugins/olmd/mbsapi/s_ves10_1_swap.h
new file mode 100644
index 00000000..3cd84e5b
--- /dev/null
+++ b/plugins/olmd/mbsapi/s_ves10_1_swap.h
@@ -0,0 +1,19 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef S_VES10_1_SWAP_H
+#define S_VES10_1_SWAP_H
+
+#include "s_ves10_1.h"
+
+#endif
diff --git a/plugins/olmd/mbsapibase/err_mask_def.h b/plugins/olmd/mbsapibase/err_mask_def.h
new file mode 100644
index 00000000..748ee6b2
--- /dev/null
+++ b/plugins/olmd/mbsapibase/err_mask_def.h
@@ -0,0 +1,50 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef ERR_MASK_DEF_H
+#define ERR_MASK_DEF_H
+
+#include "typedefs.h"
+/* ++++++++++++++++++++++++++
+ * +++ err_mask_def.h +++
+ * ++++++++++++++++++++++++++
+ * RSMayer
+ * 08-Feb-1994
+ * output mask definitions
+ * last update: 10-Feb-1994:RSM, MASK__DEBUG, MASK__VERBOSE
+ * last update: 15-Feb-1994:RSM, File renamed to err_mask_def.h
+ */
+
+#define MASK__DEBUG 1 /* output for debug purpose */
+#define MASK__VERBOSE 2 /* verbose output */
+/* */
+#define MASK__PRTNULL 0x0 /* no output, i.e. output suppressed */
+#define MASK__PRTTERM 0x80000000 /* Terminal output only */
+#define MASK__PRTSLOG 0x20000000 /* Log file output */
+#define MASK__PRTT 0xa0000000 /* Terminal and log file output */
+#define MASK__PRTGLOG 0x10000000 /* not implemented */
+#define MASK__PRTPLOG 0x08000000 /* not implemented */
+#define MASK__PRTCLOG 0x04000000 /* not implemented */
+#define MASK__PRTERRL 0x40000000 /* not implemented */
+/* */
+#define MASK__PRTL 0x20000000 /* not implemented */
+#define MASK__PRTE 0xf0000000 /* not implemented */
+#define MASK__PRTG 0xb0000000 /* not implemented */
+/* */
+#define MASK__PRTNOPAD 0x00000100 /* not implemented */
+/* */
+#define MASK__PRTOPEN 1 /* not implemented */
+#define MASK__PRTCLOSE 2 /* not implemented */
+#define MASK__PRTFLUSH 4 /* not implemented */
+
+#endif
diff --git a/plugins/olmd/mbsapibase/errnum_def.h b/plugins/olmd/mbsapibase/errnum_def.h
new file mode 100644
index 00000000..366b0642
--- /dev/null
+++ b/plugins/olmd/mbsapibase/errnum_def.h
@@ -0,0 +1,168 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef ERRNUM_DEF_H
+#define ERRNUM_DEF_H
+
+#include "typedefs.h"
+/* ++++++++++++++++++++++
+ * +++ errnum_def.h +++
+ * ++++++++++++++++++++++
+ * RSMayer
+ * 07-Feb-1994
+ * error numbers
+ * last modification:
+ * 23-Mar-1994 RSMayer insert EVent_server error numbers
+ * 25-Mar-1994 RSMayer ERR__SIGNAL, SETTASK, SETVERB, CLRVERB added.
+ * 31-Mar-1994 RSMayer ERR__USBFTY, ERR__NKNBFTY.
+ * 12-Jul-1994 RSMayer Error numbers and msg. for Esone Server
+ * 16-Feb-1995 RSMayer new error numbers. /RSM
+ * 08-Mar-1995 RSMayer some basic error number text modified.
+*/
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!! error numbers MUST be changed in s_error.h TOO !!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* !!! bit1:0 succes, bit1:1 error, i.e. odd numbers are errors! !!! */
+
+/* +++ UTIlity error numbers start with 0 +++ */
+#define ERR__SUCCESS 0 /* Normal successful completion && */
+#define ERR__ERROR 1 /* Error: && */
+/* */
+#define ERR__INFO 2 /* && */ /* only text */
+#define ERR__ERR 3 /* && */ /* only text */
+#define ERR__WARN 4 /* Warning: && */
+/* */
+#define ERR__ERRNF 7 /* Error number && not found */
+#define ERR__MSKNF 9 /* Mask && not found */
+#define ERR__MSKNIMPL 11 /* Mask && not implemented */
+#define ERR__FNIMPL 13 /* Feature not implemented. && */
+#define ERR__SYSERR 15 /* System error: && */
+#define ERR__SIGNAL 16 /* Signal: && */
+
+#define ERR__SETTASK 60 /* Set task name &&. */
+#define ERR__SETVERB 62 /* Verbosity flag set: &&. */
+#define ERR__CLRVERB 64 /* Verbosity flag cleared: &&. */
+#define ERR__STS 66 /* errstat &&. */
+#define ERR__INIT 68 /* Using f_ut_error local ctrl structure. */
+#define ERR__INITERR 69 /* Warn: Not specified, using local ctrl structure.*/
+#define ERR__INITGET 70 /* Get f_ut_error ctrl structure. &&.*/
+#define ERR__INITADDR 71 /* Invalid addr:
+ Read or write f_ut_error ctrl structure. */
+#define ERR__INITPUT 72 /* Put f_ut_error ctrl structure. &&.*/
+#define ERR__TEST 74 /* Test f_ut_error: &&. */
+#define ERR__ENALOG 76 /* Enable message log: &&. */
+#define ERR__DISLOG 78 /* Disable message log: &&. */
+
+#define ERR__MSG_COMM 80 /* Write command style to f_ut_send_msg */
+#define ERR__MSG_INFO 81 /* Write info style to f_ut_send_msg */
+#define ERR__MSG_ERROR 82 /* Write error style to f_ut_send_msg */
+
+
+/* +++ COLlector error numbers start with 100 +++ */
+#define ERR__COL_HISENA 101 /* Histogramming already enabled. && */
+#define ERR__COL_FIEVT 103 /* first event was not triggertype 14 */
+#define ERR__COL_TRMIS 105 /* trigger type or local event counter mismatch */
+#define ERR__COL_TRTYP 107 /* trigger type is out of range (1-15) */
+#define ERR__COL_BIGEV 109 /* event is bigger than stream capacity */
+#define ERR__COL_DAMIS 111 /* mismatch in pipe data buffers 0,1 */
+
+
+/* +++ RD (Readout) error numbers start with 200 +++ */
+#define ERR__RD_FITRG 201 /* first trigger type was not 14 */
+#define ERR__RD_NORDT 203 /* table readout specified but no readout table */
+ /* was loaded */
+#define ERR__RD_LECMIS 205 /* local event counter differs more than 1 count */
+ /* compared to previous one (modula 32) */
+#define ERR__RD_TRTYP 207 /* trigger type is out of range (1-15) */
+#define ERR__RD_TRMIS 209 /* trigger type is out of range (1-15) */
+
+
+/* +++ TRansport error numbers start with 300 +++ */
+#define ERR__MALLOC 301
+#define ERR__SCSI_WRTFILEMARK 303
+#define ERR__SCSI_WRITE 305
+#define ERR__SCSI_REWIND 307
+#define ERR__SCSI_UNLOAD 309
+#define ERR__SCSI_OPEN 311
+#define ERR__SCSI_SETBLKSIZE 313
+#define ERR__SCSI_UNKNMEDIA 315
+#define ERR__SCSI_MSENSE 317
+#define ERR__SCSI_INQUIRY 319
+#define ERR__SCSI_MSELECT 321
+
+
+/* +++ EVent_server error numbers start with 400 +++ */
+#define ERR__EV_CLNOTMR 400 /* Warning: Client not marked. && */
+#define ERR__EV_CLAMRK 402 /* Warning: Client allready marked. && */
+#define ERR__EV_ECLAMRK 403 /* Client allready marked. && */
+#define ERR__EV_CLNOTV 404 /* Warning: Client not valid. && */
+#define ERR__EV_ECLNOTV 405 /* Client not valid. && */
+#define ERR__EV_CLNRDY 406 /* No client ready/active. && */
+#define ERR__EV_FLTNV 407 /* Filter not valid. && */
+#define ERR__EV_WARNFLT 408 /* Warning for filter. && */
+#define ERR__EV_EBFACKN 409 /* Buffer acknoledge. && */
+#define ERR__EV_WBFACKN 410 /* Warning: Buffer acknoledge. && */
+#define ERR__EV_WBACKTO 412 /* Warning: Buffer acknoledge timeout. && */
+#define ERR__EV_WBFPEND 414 /* Buffer pending. && */
+#define ERR__EV_CLNSTS 415 /* Wrong client status. && */
+#define ERR__EV_LSTBUF 416 /* Info: Was last buffer. && */
+#define ERR__EV_WRTBUF 417 /* Error writing buffer. && */
+#define ERR__EV_CLNACC 419 /* Error client accept . && */
+#define ERR__EV_RELSTR 420 /* Release stream: &&. */
+#define ERR__EV_USBFTY 421 /* Unsupported buffer typ: &&. */
+#define ERR__EV_UKNBFTY 423 /* Unknown buffer typ: &&. */
+#define ERR__EV_UKNEVTY 425 /* Unknown event typ: &&. */
+#define ERR__EV_UKNSETY 427 /* Unknown subevent typ: &&. */
+#define ERR__EV_EVTOOBIG 429 /* Event too big for buffer: &&. */
+/* */
+
+/* +++ ESone_server error numbers start with 500 +++ */
+#define ERR__ES_CLNOTMR 500 /* Warning: Client not marked. && */
+#define ERR__ES_CLAMRK 502 /* Warning: Client allready marked. && */
+#define ERR__ES_BFRDTO 514 /* Buffer read timeout. && */
+#define ERR__ES_ERDBUF 515 /* Error reading buffer. && */
+#define ERR__ES_LSTBUF 516 /* Info: Was last buffer. && */
+#define ERR__ES_WRTBUF 517 /* Error writing buffer. && */
+#define ERR__ES_CLNACC 519 /* Error client accept. && */
+#define ERR__ES_MAXCLN 521 /* Maximum number of clients exceeded. && */
+#define ERR__ES_BFSTRD 530 /* Buffer status read: && */
+#define ERR__ES_BFSTWR 532 /* Buffer status write: && */
+#define ERR__ES_BFPROC 534 /* Buffer in process: && */
+#define ERR__ES_EESONE 537 /* Error in Esone call: && */
+/* */
+
+/* +++ Histogram_manager error numbers start with 600 +++ */
+#define ERR__HIS_SPNFND 601 /* Error: Histogram && not found */
+#define ERR__HIS_EOFSPN 602 /* Warn: End of histogram list. && */
+#define ERR__HIS_RANGES 603 /* Error: Value out of range. && */
+#define ERR__HIS_WRNGNO 605 /* Error: Wrong number typed */
+#define ERR__HIS_EANAL 607 /* Error in analysis: && */
+#define ERR__HIS_NFREEM 609 /* Error: Can't get the memory */
+#define ERR__HIS_NOPENF 611 /* Error: Can't open the file */
+#define ERR__HIS_INVHIS 613 /* Error: Invalid histogram name or too long */
+#define ERR__HIS_NALFNO 615 /* Error: Only alphanumeric symbols allowed */
+#define ERR__HIS_NOMEMR 617 /* Error: No memory allocated */
+#define ERR__HIS_HALREX 619 /* Histogram && already exists */
+#define ERR__HIS_NFREDP 621 /* No free memory in data pool && */
+#define ERR__HIS_HTABFU 623 /* Histogram table full && */
+#define ERR__HIS_EWPAR 625 /* Wrong parameter && */
+#define ERR__HIS_SKIPEVT 626 /* Skip event &&. */
+#define ERR__HIS_SKIPSEV 628 /* Skip subevent &&. */
+#define ERR__HIS_NBASATT 629 /* No Base attached. &&*/
+#define ERR__HIS_BASATT 630 /* Base && already attached. */
+#define ERR__HIS_NHISBAS 631 /* Base && is not a histogram base. */
+#define ERR__HIS_DBLOCK 633 /* Base locked by another user. && */
+/* */
+
+#endif
diff --git a/plugins/olmd/mbsapibase/f_his_hist.c b/plugins/olmd/mbsapibase/f_his_hist.c
new file mode 100644
index 00000000..1e8dfc0f
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_his_hist.c
@@ -0,0 +1,712 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#include "typedefs.h"
+#include "f_his_hist.h"
+#include "f_his_toupper.h"
+#include "f_his_swpbas.h"
+#include "f_stccomm.h"
+#include "f_swaplw.h"
+#include "f_ut_compress.h"
+#include "portnum_def.h"
+#include
+#include
+#include
+#include
+#include
+static CHARS c_gl_serv_access[64];
+static CHARS c_gl_serv_base[32];
+static INTS4 l_gl_serv_port;
+static INTS4 l_gl_serv_chan;
+static INTS4 l_gl_serv_verb;
+struct s_tcpcomm *ps_tcpserv;
+s_his_comm s_his_comm_serv;
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ C Procedure ***********+******************************************/
+/* */
+/*+ Module : f_his_getbas */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l=f_his_getbas(char server, int port, char base, char password, int **p_buf)*/
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Returns list of histogram available from server */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ c_server : Node of server. */
+/*+ l_port : Port number (must be known from server) */
+/*+ c_base : Histogram base name */
+/*+ c_password : Password if required from server */
+/*+ p_buf : Address of buffer pointer. */
+/* Data base is allocated and address returned. */
+/* */
+/*+ Return type : int. */
+/*- COMM__SUCCESS : OK */
+/*- COMM__ERROR : Error */
+/*- COMM__NOACCESS: Password wrong */
+/*- COMM__NOBASE : Base wrong */
+/*- COMM__NOSERVER: Cannot connect (Port?) */
+/*- COMM__NOHIST : Histogram not there */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ FUNCTION : Connects to histogram server. */
+/* Allocates and returns LEA data base */
+/* Bse must be compressed by server. */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ File name : f_his_hist.c */
+/*+ Version : 1.01 */
+/*+ Author : Hans Essel */
+/*+ Created : 21-May-2000 */
+/*+ Updates : Date Purpose */
+/* */
+/*1- C Main ****************+******************************************/
+INTS4 f_his_getbas(CHARS *pc_server, INTS4 l_port, CHARS *pc_base, CHARS *pc_access,INTS4 **p_buffer)
+{
+s_his_comm s_his_comm_cli;
+INTS4 i_j,i_l,l_status,l_chan,l_swap,l_buffer;
+INTS4 *pl_all,*pl_l;
+s_compress *ps_compress;
+struct s_tcpcomm *ps_tcpcli;
+
+ps_tcpcli = (struct s_tcpcomm *) malloc (sizeof( struct s_tcpcomm));
+pl_all = NULL;
+
+/* get base ***************************************************/
+s_his_comm_cli.lu_endian=1;
+s_his_comm_cli.lu_size=0;
+s_his_comm_cli.lu_histos=0;
+s_his_comm_cli.lu_action=COMM__GETBASE;
+s_his_comm_cli.l_status=COMM__SUCCESS;
+strcpy(s_his_comm_cli.c_histo,"*");
+strcpy(s_his_comm_cli.c_access,pc_access);
+strcpy(s_his_comm_cli.c_base,pc_base);
+l_status = f_stc_connectserver (pc_server,l_port, &l_chan, ps_tcpcli);
+if(l_status != STC__SUCCESS) {l_status=COMM__NOSERVER;goto g_return;}
+l_status = f_stc_write(&s_his_comm_cli,sizeof(s_his_comm),l_chan);
+if(l_status != STC__SUCCESS) {l_status=COMM__ERROR;goto g_return;}
+l_status = f_stc_read (&s_his_comm_cli,sizeof(s_his_comm),l_chan,-1);
+if(l_status != STC__SUCCESS) {l_status=COMM__ERROR;goto g_return;}
+l_swap = (s_his_comm_cli.lu_endian > 1);
+if(l_swap) l_status = f_swaplw((INTS4 *)&s_his_comm_cli,5,NULL);
+if(s_his_comm_cli.l_status != COMM__SUCCESS) {l_status=s_his_comm_cli.l_status;goto g_return;}
+
+/* allocate buffer for compressed base */
+pl_all = (INTS4 *)malloc(s_his_comm_cli.lu_size);
+l_buffer = s_his_comm_cli.lu_size;
+/* break total buffer in TCP buffers */
+pl_l=pl_all;
+i_l=l_buffer/16384;
+l_buffer=l_buffer%16384;
+for(i_j=0;i_j 0) l_status = f_stc_read (pl_l,l_buffer,l_chan,-1);
+if(l_status != STC__SUCCESS) {l_status=COMM__ERROR;goto g_return;}
+/* uncompress base */
+ps_compress = (s_compress *) pl_all;
+if(l_swap == 1)
+{
+ f_swaplw((INTS4 *)pl_all,sizeof(s_compress)/4,NULL);
+ pl_l=pl_all+(sizeof(s_compress)/4);
+ f_swaplw((INTS4 *)pl_l,ps_compress->l_masks,NULL);
+}
+*p_buffer = (INTS4 *)malloc(ps_compress->l_full_bytes);
+f_ut_compr_unpack((INTU1 *)pl_all,(INTU1 *) *p_buffer,ps_compress->l_full_bytes);
+if(l_swap == 1) l_status = f_his_swpbas((s_head*) *p_buffer);
+
+l_status=COMM__SUCCESS;
+g_return:
+f_stc_discclient (l_chan);
+f_stc_close (ps_tcpcli);
+free(pl_all);
+free(ps_tcpcli);
+return(l_status);
+}
+/*1+ C Procedure ***********+******************************************/
+/* */
+/*+ Module : f_his_getdir */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l=f_his_getdir(char server, int port, char base, char password,*/
+/* char histo, int **p_buf, int **l_histos)*/
+/* */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Returns list of histogram available from server */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ c_server : Node of server. */
+/*+ l_port : Port number (must be known from server) */
+/*+ c_base : Histogram base name */
+/*+ c_password : Password if required from server */
+/*+ c_histo : Histogram wildcard */
+/*+ p_buf : Address of buffer pointer. */
+/* If NULL, buffer is allocated, if not l_histos gives */
+/* size of buffer in sizeof(s_his_head). */
+/*+ l_histos : Size in sizeof(s_his_head) of buffer, */
+/* returns number of histograms */
+/* */
+/*+ Return type : int. */
+/*- COMM__SUCCESS : OK */
+/*- COMM__ERROR : Error */
+/*- COMM__NOACCESS: Password wrong */
+/*- COMM__NOBASE : Base wrong */
+/*- COMM__NOSERVER: Cannot connect (Port?) */
+/*- COMM__NOHIST : Histogram not there */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ FUNCTION : Connects to histogram server. */
+/* Returns buffer with s_his_head slots */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ File name : f_his_hist.c */
+/*+ Version : 1.01 */
+/*+ Author : Hans Essel */
+/*+ Created : 21-May-2000 */
+/*+ Updates : Date Purpose */
+/* */
+/*1- C Main ****************+******************************************/
+INTS4 f_his_getdir(CHARS *pc_server, INTS4 l_port, CHARS *pc_base, CHARS *pc_access, CHARS *pc_histo
+ ,INTS4 **p_buffer, INTS4 *pl_histos)
+{
+s_his_comm s_his_comm_cli;
+s_his_head *ps_his_head;
+INTS4 i_j,i_l,l_status,l_chan,l_swap,l_buffer,l_histos,l_size;
+INTS4 *pl_all,*pl_l;
+struct s_tcpcomm *ps_tcpcli;
+
+ps_tcpcli = (struct s_tcpcomm *) malloc (sizeof( struct s_tcpcomm));
+
+/* get directory ***************************************************/
+s_his_comm_cli.lu_endian=1;
+s_his_comm_cli.lu_size=0;
+s_his_comm_cli.lu_histos=0;
+s_his_comm_cli.lu_action=COMM__GETDIR;
+s_his_comm_cli.l_status=COMM__SUCCESS;
+strcpy(s_his_comm_cli.c_histo,pc_histo);
+strcpy(s_his_comm_cli.c_access,pc_access);
+strcpy(s_his_comm_cli.c_base,pc_base);
+l_status = f_stc_connectserver (pc_server,l_port, &l_chan, ps_tcpcli);
+if(l_status != STC__SUCCESS) {l_status=COMM__NOSERVER;goto g_return;}
+l_status = f_stc_write(&s_his_comm_cli,sizeof(s_his_comm),l_chan);
+if(l_status != STC__SUCCESS) {l_status=COMM__ERROR;goto g_return;}
+l_status = f_stc_read (&s_his_comm_cli,sizeof(s_his_comm),l_chan,-1);
+if(l_status != STC__SUCCESS) {l_status=COMM__ERROR;goto g_return;}
+l_swap = (s_his_comm_cli.lu_endian > 1);
+if(l_swap) l_status = f_swaplw((INTS4 *)&s_his_comm_cli,5,NULL);
+if(s_his_comm_cli.l_status != COMM__SUCCESS) {l_status=s_his_comm_cli.l_status;goto g_return;}
+
+l_histos=s_his_comm_cli.lu_histos;
+l_size=sizeof(s_his_head)*l_histos;
+/* allocate buffer */
+if(*p_buffer == 0)
+{
+ pl_all = (INTS4 *)malloc(l_size);
+ *p_buffer = pl_all;
+}
+else
+{
+ if(*pl_histos < l_histos) {l_status=COMM__ERROR;goto g_return;}
+ pl_all = *p_buffer;
+}
+*pl_histos = l_histos;
+l_buffer = s_his_comm_cli.lu_size;
+/* break total buffer in TCP buffers */
+pl_l=pl_all;
+i_l=l_buffer/16384;
+l_buffer=l_buffer%16384;
+for(i_j=0;i_j 0) l_status = f_stc_read (pl_l,l_buffer,l_chan,-1);
+if(l_status != STC__SUCCESS) {l_status=COMM__ERROR;goto g_return;}
+
+ps_his_head = (s_his_head *)pl_all;
+for(i_j=0;i_j 1);
+if(l_swap) l_status = f_swaplw((INTS4 *)&s_his_comm_cli,5,NULL);
+if(s_his_comm_cli.l_status != COMM__SUCCESS) {l_status=s_his_comm_cli.l_status;goto g_return;}
+
+l_size=s_his_comm_cli.lu_size-sizeof(s_his_head);
+/* allocate buffer */
+if(*p_buffer == 0)
+{
+ pl_all = (INTS4 *)malloc(l_size);
+ *p_buffer = pl_all;
+}
+else
+{
+ if(*pl_size < l_size) {l_status=COMM__ERROR;goto g_return;}
+ pl_all = *p_buffer;
+}
+/* allocate header buffer */
+if(*p_head == 0)
+{
+ ps_his_head = (s_his_head *)malloc(sizeof(s_his_head));
+ *p_head = ps_his_head;
+}
+else ps_his_head = *p_head;
+
+l_status = f_stc_read (ps_his_head,sizeof(s_his_head),l_chan,-1);
+if(l_swap) l_status = f_swaplw((INTS4 *)ps_his_head,16,NULL);
+
+*pl_size = l_size;
+l_buffer = l_size;
+
+/* break total buffer in TCP buffers */
+pl_l=pl_all;
+i_l=l_buffer/16384;
+l_buffer=l_buffer%16384;
+for(i_j=0;i_j 0) l_status = f_stc_read (pl_l,l_buffer,l_chan,-1);
+if(l_status != STC__SUCCESS) {l_status=COMM__ERROR;goto g_return;}
+
+if(l_swap) l_status = f_swaplw((INTS4 *)pl_all,l_size/4,NULL);
+
+l_status=COMM__SUCCESS;
+g_return:
+f_stc_discclient (l_chan);
+f_stc_close (ps_tcpcli);
+free(ps_tcpcli);
+return(l_status);
+}
+/*1+ C Procedure ***********+******************************************/
+/* */
+/*+ Module : f_his_server */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l=f_his_server(int *pl_port, char base, char accesss)*/
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Start histogram server */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ pl_port : Address to receive port number used. */
+/*+ base : Base name */
+/*+ access : Password */
+/* */
+/*+ Return type : int. */
+/*- COMM__SUCCESS : OK */
+/*- COMM__ERROR : Error */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ FUNCTION : Creates histogram server. */
+/* Returns port number */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ File name : f_his_hist.c */
+/*+ Version : 1.01 */
+/*+ Author : Hans Essel */
+/*+ Created : 21-May-2000 */
+/*+ Updates : Date Purpose */
+/* */
+/*1- C Main ****************+******************************************/
+INTS4 f_his_server(CHARS *pc_base, CHARS *pc_access, INTS4 *pl_port)
+{
+INTS4 l_status;
+
+ps_tcpserv = (struct s_tcpcomm *) malloc (sizeof( struct s_tcpcomm));
+l_gl_serv_port=PORT__HIST_SERV;
+strcpy(c_gl_serv_access,pc_access);
+strcpy(c_gl_serv_base,pc_base);
+f_his_toupper(c_gl_serv_access,sizeof(c_gl_serv_access));
+f_his_toupper(c_gl_serv_base,sizeof(c_gl_serv_base));
+
+while((l_status = f_stc_createserver (&l_gl_serv_port, ps_tcpserv)) != STC__SUCCESS)
+{
+ l_gl_serv_port++;
+ if(l_gl_serv_port > PORT__HIST_SERV + 20)
+ {
+ printf("Error creating histogram server\n");
+ return(COMM__ERROR);
+ }
+}
+*pl_port=l_gl_serv_port;
+return(0);
+}
+
+/*1+ C Procedure ***********+******************************************/
+/* */
+/*+ Module : f_his_wait */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l=f_his_wait(int *pl_action, char histogram) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Wait for client */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ pl_action : Address to receive required action. */
+/*+ histogram : Histogram sepc. */
+/* */
+/*+ Return type : int. */
+/*- COMM__SUCCESS : OK */
+/*- COMM__ERROR : Error */
+/*- COMM__NOACCESS: Password wrong */
+/*- COMM__NOBASE : Base wrong */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ FUNCTION : Waits for client to connect. */
+/* Returns action required. */
+/* Checks for correct base and password */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ File name : f_his_hist.c */
+/*+ Version : 1.01 */
+/*+ Author : Hans Essel */
+/*+ Created : 21-May-2000 */
+/*+ Updates : Date Purpose */
+/* */
+/*1- C Main ****************+******************************************/
+INTS4 f_his_wait(INTS4 *pl_action, CHARS *pc_histo)
+{
+INTS4 l_status;
+/* Wait for client to connect */
+ if(l_gl_serv_verb == 1) {printf("Waiting for client on port %d [%s] \n",l_gl_serv_port,c_gl_serv_access);}
+ l_status = f_stc_acceptclient (ps_tcpserv, &l_gl_serv_chan);
+ if(l_status != STC__SUCCESS) { printf("error accepting client\n"); return(COMM__ERROR);}
+ if(l_gl_serv_verb == 1) {printf("Client connected. \n");}
+ l_status = f_stc_read (&s_his_comm_serv,sizeof(s_his_comm),l_gl_serv_chan,-1);
+ if(l_status != STC__SUCCESS) { printf("error reading client\n"); f_stc_discclient(l_gl_serv_chan);return(COMM__ERROR); }
+ /* check access */
+ f_his_toupper(s_his_comm_serv.c_access,sizeof(s_his_comm_serv.c_access));
+ f_his_toupper(s_his_comm_serv.c_base,sizeof(s_his_comm_serv.c_base));
+ if((strlen(c_gl_serv_access) != 0) &
+ (strcmp(s_his_comm_serv.c_access,c_gl_serv_access) != 0))
+ {
+ printf("Client connected with wrong password [%s]. \n",s_his_comm_serv.c_access);
+ s_his_comm_serv.lu_endian=1;
+ s_his_comm_serv.lu_size=0;
+ s_his_comm_serv.lu_histos=0;
+ s_his_comm_serv.l_status=COMM__NOACCESS;
+ l_status = f_stc_write (&s_his_comm_serv,sizeof(s_his_comm), l_gl_serv_chan);
+ f_stc_discclient (l_gl_serv_chan);
+ return(COMM__NOACCESS);
+ }
+ /* check base name */
+ if(strcmp(s_his_comm_serv.c_base,c_gl_serv_base) != 0)
+ {
+ printf("Client connected for wrong base [%s]. \n",s_his_comm_serv.c_base);
+ s_his_comm_serv.lu_endian=1;
+ s_his_comm_serv.lu_size=0;
+ s_his_comm_serv.lu_histos=0;
+ s_his_comm_serv.l_status=COMM__NOBASE;
+ l_status = f_stc_write (&s_his_comm_serv,sizeof(s_his_comm), l_gl_serv_chan);
+ f_stc_discclient (l_gl_serv_chan);
+ return(COMM__NOBASE);
+ }
+ if(s_his_comm_serv.lu_endian > 100) l_status = f_swaplw((INTS4 *)&s_his_comm_serv,5,NULL);
+ if(l_gl_serv_verb == 1) {printf("%d: %d %d %d %d %d \"%s\" \"%s\" \"%s\"\n",l_status
+ ,s_his_comm_serv.lu_endian
+ ,s_his_comm_serv.lu_action
+ ,s_his_comm_serv.lu_histos
+ ,s_his_comm_serv.lu_size
+ ,s_his_comm_serv.l_status
+ ,s_his_comm_serv.c_access
+ ,s_his_comm_serv.c_base
+ ,s_his_comm_serv.c_histo);}
+*pl_action=s_his_comm_serv.lu_action;
+strcpy(pc_histo,s_his_comm_serv.c_histo);
+return(COMM__SUCCESS);
+}
+
+/*1+ C Procedure ***********+******************************************/
+/* */
+/*+ Module : f_his_senddir */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l=f_his_senddir(s_his_head *ps_head, int l_histos) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Send list of available histogram */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ ps_head : Address of header list. */
+/*+ l_histos : Number of histograms */
+/* */
+/*+ Return type : int. */
+/*- COMM__SUCCESS : OK */
+/*- COMM__ERROR : Error */
+/*- COMM__NOHIST : Histogram not there */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ FUNCTION : Send list of s_his_head to client. */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ File name : f_his_hist.c */
+/*+ Version : 1.01 */
+/*+ Author : Hans Essel */
+/*+ Created : 21-May-2000 */
+/*+ Updates : Date Purpose */
+/* */
+/*1- C Main ****************+******************************************/
+INTS4 f_his_senddir(s_his_head *ps_head, INTS4 l_histos)
+{
+INTS4 *pl_l,i_j,i_l,l_buffer,l_status;
+
+if(l_gl_serv_verb == 1) {printf("Send directory %s. \n",s_his_comm_serv.c_histo);}
+s_his_comm_serv.lu_histos=l_histos;
+s_his_comm_serv.lu_endian=1;
+s_his_comm_serv.lu_action=COMM__PUTDIR;
+s_his_comm_serv.lu_size=sizeof(s_his_head)*s_his_comm_serv.lu_histos;
+s_his_comm_serv.l_status=COMM__SUCCESS;
+l_status = f_stc_write (&s_his_comm_serv,sizeof(s_his_comm), l_gl_serv_chan);
+if(l_status != STC__SUCCESS)
+{ printf("error writing comm to client\n"); f_stc_discclient(l_gl_serv_chan);return(COMM__ERROR);}
+
+/* break total buffer in TCP buffers */
+pl_l=(INTS4 *)ps_head;
+l_buffer = s_his_comm_serv.lu_size;
+i_l=l_buffer/16384;
+l_buffer=l_buffer%16384;
+for(i_j=0;i_j 0) l_status = f_stc_write (pl_l,l_buffer,l_gl_serv_chan);
+
+if(l_status != STC__SUCCESS)
+{ printf("error writing directory to client\n"); f_stc_discclient(l_gl_serv_chan);return(COMM__ERROR);}
+f_stc_discclient (l_gl_serv_chan);
+return(COMM__SUCCESS);
+}
+/*1+ C Procedure ***********+******************************************/
+/* */
+/*+ Module : f_his_sendhis */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l=f_his_sendhis(s_his_head *ps_head, int histos, char *histo, int *data)*/
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Send histogram */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ ps_head : Address of header list. */
+/*+ histos : Number of histograms */
+/*+ histo : Name of requested histograms */
+/*+ data : Pointer array to histogram data */
+/* */
+/*+ Return type : int. */
+/*- COMM__SUCCESS : OK */
+/*- COMM__ERROR : Error */
+/*- COMM__NOHIST : Histogram not there */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ FUNCTION : Send one s_his_head and data to client. */
+/* Histogram is searched by name. */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ File name : f_his_hist.c */
+/*+ Version : 1.01 */
+/*+ Author : Hans Essel */
+/*+ Created : 21-May-2000 */
+/*+ Updates : Date Purpose */
+/* */
+/*1- C Main ****************+******************************************/
+INTS4 f_his_sendhis(s_his_head *ps_head, INTS4 l_histos, CHARS *pc_histo, INTS4 *pl_data)
+{
+s_his_head *ps_his_head;
+INTS4 *pl_l,i_j,i_l,ll,l_buffer,l_status;
+
+s_his_comm_serv.lu_endian=1;
+s_his_comm_serv.lu_histos=0;
+s_his_comm_serv.lu_action=COMM__PUTHIST;
+ps_his_head = ps_head;
+for(ll=0;llc_name,pc_histo) == 0)
+ {
+ s_his_comm_serv.lu_histos=1;
+ s_his_comm_serv.l_status=COMM__SUCCESS;
+ s_his_comm_serv.lu_size=sizeof(s_his_head)+ps_his_head->l_bins_1 * ps_his_head->l_bins_2 * 4;
+ l_status = f_stc_write (&s_his_comm_serv,sizeof(s_his_comm), l_gl_serv_chan);
+ if(l_status != STC__SUCCESS)
+ { printf("error writing comm to client\n"); f_stc_discclient(l_gl_serv_chan); return(COMM__ERROR);}
+ if(l_gl_serv_verb == 1) printf("%-32s %8lu\n",ps_his_head->c_name, (long unsigned) (s_his_comm_serv.lu_size-sizeof(s_his_head)));
+ l_status = f_stc_write (ps_his_head,sizeof(s_his_head), l_gl_serv_chan);
+ if(l_status != STC__SUCCESS)
+ { printf("error writing header to client\n"); f_stc_discclient(l_gl_serv_chan); return(COMM__ERROR); }
+
+ /* break total buffer in TCP buffers */
+ l_buffer = s_his_comm_serv.lu_size-sizeof(s_his_head);
+ i_l=l_buffer/16384;
+ l_buffer=l_buffer%16384;
+ for(i_j=0;i_j 0) l_status = f_stc_write (pl_l,l_buffer,l_gl_serv_chan);
+ if(l_status != STC__SUCCESS)
+ { printf("error writing data to client\n"); f_stc_discclient(l_gl_serv_chan); return(COMM__ERROR); }
+ break;
+ } /* found */
+ ps_his_head++;
+} /* loop */
+if(s_his_comm_serv.lu_histos == 0)
+{
+ if(l_gl_serv_verb == 1) {printf("Histogram %s not found\n",pc_histo);}
+ s_his_comm_serv.l_status=COMM__NOHIST;
+ s_his_comm_serv.lu_size=0;
+ l_status = f_stc_write (&s_his_comm_serv,sizeof(s_his_comm), l_gl_serv_chan);
+ if(l_status != STC__SUCCESS)
+ { printf("error writing comm to client\n"); f_stc_discclient(l_gl_serv_chan); return(COMM__ERROR); }
+ f_stc_discclient (l_gl_serv_chan);
+ return(COMM__NOHIST);
+}
+f_stc_discclient (l_gl_serv_chan);
+return(COMM__SUCCESS);
+}
+/*1+ C Procedure ***********+******************************************/
+/* */
+/*+ Module : f_his_close */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l=f_his_close() */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Stop server, close sockets */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ Return type : int. */
+/*- COMM__SUCCESS : OK */
+/*- COMM__ERROR : Error */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ FUNCTION : Stop server, close sockets . */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ File name : f_his_hist.c */
+/*+ Version : 1.01 */
+/*+ Author : Hans Essel */
+/*+ Created : 21-May-2000 */
+/*+ Updates : Date Purpose */
+/* */
+/*1- C Main ****************+******************************************/
+INTS4 f_his_close(void)
+{
+ printf("Exit histogram server\n");
+ f_stc_close (ps_tcpserv);
+ free(ps_tcpserv);
+ return(COMM__SUCCESS);
+}
diff --git a/plugins/olmd/mbsapibase/f_his_hist.h b/plugins/olmd/mbsapibase/f_his_hist.h
new file mode 100644
index 00000000..6ab4daf4
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_his_hist.h
@@ -0,0 +1,31 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef F_HIS_HIST_H
+#define F_HIS_HIST_H
+
+#include "typedefs.h"
+#include "s_his_comm.h"
+#include "s_his_head.h"
+
+/* node, port, base, password, histogram, [header, ] buffer, size */
+INTS4 f_his_getbas(CHARS *, INTS4, CHARS *, CHARS *, INTS4 **);
+INTS4 f_his_getdir(CHARS *, INTS4, CHARS *, CHARS *, CHARS *, INTS4 **, INTS4 *);
+INTS4 f_his_gethis(CHARS *, INTS4, CHARS *, CHARS *, CHARS *, s_his_head **, INTS4 **, INTS4*);
+INTS4 f_his_server(CHARS *, CHARS *, INTS4 *);
+INTS4 f_his_wait(INTS4 *, CHARS *);
+INTS4 f_his_senddir(s_his_head *, INTS4);
+INTS4 f_his_sendhis(s_his_head *, INTS4, CHARS *, INTS4*);
+INTS4 f_his_close(void);
+
+#endif
diff --git a/plugins/olmd/mbsapibase/f_his_swpbas.c b/plugins/olmd/mbsapibase/f_his_swpbas.c
new file mode 100644
index 00000000..b16e2b16
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_his_swpbas.c
@@ -0,0 +1,128 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 52 */
+/* D-64220 Darmstadt */
+/* */
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_his_swpbas */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l_status = f_his_swpbas(ps_head) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Swaps whole base (except strings) */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ ps_head : (s_head *) input */
+/* pointer to header structure, address of shared */
+/* segment. */
+/*+ Return type : int */
+/* */
+/*2+Description***+***********+****************************************/
+/* */
+/*+ CALLING : l_status = f_his_swpbas(ps_head) */
+/* */
+/*+ FUNCTION : */
+/* */
+/*3+Function******+***********+****************************************/
+/* */
+/* */
+/* */
+/*2+Implementation************+****************************************/
+/*+ Utility : f_his_swpbas */
+/*+ File name : f_his_swpbas.c */
+/*+ Home direct.: /sbs/prod/src */
+/*+ Version : 1.01 */
+/*+ Author : H.G.Essel */
+/*+ Created : 06-Jul-2000 */
+/*+ Object libr.: */
+/*+ Updates : Date Purpose */
+/*1- C Procedure *************+****************************************/
+
+#include "f_his_swpbas.h"
+
+#include
+#include
+#include "s_spe.h"
+#include "s_pol_cond.h"
+#include "s_win_cond.h"
+#include "f_swaplw.h"
+
+INTS4 f_his_swpbas(s_head *ps_head)
+{
+ INTS4 i;
+ s_spe *ps_spe;
+ s_win *ps_win;
+ s_pol *ps_pol;
+ INTS4 *pl;
+
+/* swap first two LWs to get correct size */
+pl=(INTS4 *)ps_head;
+f_swaplw(pl,2,NULL);
+if(ps_head->l_endian != 1)
+{
+ printf("endian was wrong %x\n",ps_head->l_endian);
+ return(-1);
+}
+
+/* swap whole base */
+pl += 2;
+f_swaplw(pl,ps_head->l_len-2,NULL);
+
+/* swap back strings in header */
+pl=(INTS4 *)&ps_head->c_date;
+f_swaplw(pl,23,NULL);
+
+/* swap back strings in all slots */
+ps_spe=(s_spe *)(ps_head+1);
+pl=(INTS4 *)&ps_spe->c_name;
+for(i=0;ii_slot;i++)
+{
+ f_swaplw(pl,71,NULL);
+ pl += (sizeof(s_spe)/4);
+}
+
+/* swap back strings in all conditions */
+if(ps_head->l_cond_win > 0)
+{
+pl=(INTS4 *)ps_head;
+pl = pl + ps_head->l_cond_win;
+ps_win = (s_win *)(pl + 1);
+/*reswap window names */
+for(i=0;i< * pl;i++)
+{
+ f_swaplw((INTS4 *)ps_win->c_name,28,NULL);
+ ps_win++;
+}
+}
+if(ps_head->l_cond_pol > 0)
+{
+pl=(INTS4 *)ps_head;
+pl = pl + ps_head->l_cond_pol;
+ps_pol = (s_pol *)(pl + 1);
+/*reswap window names */
+for(i=0;i < *pl;i++)
+{
+ f_swaplw((INTS4 *)ps_pol->c_name,28,NULL);
+ ps_pol++;
+}
+}
+return(0);
+}
+
diff --git a/plugins/olmd/mbsapibase/f_his_swpbas.h b/plugins/olmd/mbsapibase/f_his_swpbas.h
new file mode 100644
index 00000000..3f6de1d1
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_his_swpbas.h
@@ -0,0 +1,22 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef F_HIS_SWPBAS_H
+#define F_HIS_SWPBAS_H
+
+#include "typedefs.h"
+#include "s_head.h"
+
+INTS4 f_his_swpbas(s_head *ps_head);
+
+#endif
diff --git a/plugins/olmd/mbsapibase/f_his_toupper.c b/plugins/olmd/mbsapibase/f_his_toupper.c
new file mode 100644
index 00000000..bf937bdb
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_his_toupper.c
@@ -0,0 +1,75 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 52 */
+/* D-64220 Darmstadt */
+/* */
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_his_toupper */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_his_toupper(string,i_max) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Convert string to upper case. */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ string : (char *) input/output */
+/* pointer to character string */
+/* */
+/*+ i_max : int input */
+/* maximum number of char to be converted. */
+/* */
+/*+ Return type : void */
+/* */
+/*2+Description***+***********+****************************************/
+/* */
+/*+ CALLING : f_his_tolower(string,i_max) */
+/* */
+/*+ FUNCTION : Converts string to upper case until '\0' or */
+/* the specified maximum number of characters */
+/* */
+/*3+Function******+***********+****************************************/
+/* */
+/*2+Implementation************+****************************************/
+/*+ Utility : f_his_toupper */
+/*+ File name : f_his_toupper.c */
+/*+ Home direct.: /sbs/prod/src */
+/*+ Version : 1.01 */
+/*+ Author : Ilya Kuznetsov */
+/*+ Created : 20-Sep-1994 */
+/*+ Object libr.: libxxx.a */
+/*+ Updates : Date Purpose */
+/*- 11-Oct-94 : changes/RSM */
+/*1- C Procedure *************+****************************************/
+
+#include "f_his_toupper.h"
+
+#include
+
+void f_his_toupper(CHARS* c, INTS4 i)
+/* +++ convert string to uppercase, max i char +++ */
+{
+ INTS4 i_j=0;
+ while (!((c[i_j]=='\0') || (i_j==i)))
+ {
+ c[i_j]=(CHARS)toupper((INTS4)c[i_j]);
+ i_j++;
+ }
+ c[i_j] = '\0';
+}
diff --git a/plugins/olmd/mbsapibase/f_his_toupper.h b/plugins/olmd/mbsapibase/f_his_toupper.h
new file mode 100644
index 00000000..de7c73d6
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_his_toupper.h
@@ -0,0 +1,21 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef F_HIS_TOUPPER_H
+#define F_HIS_TOUPPER_H
+
+#include "typedefs.h"
+
+void f_his_toupper(CHARS* c, INTS4 i);
+
+#endif
diff --git a/plugins/olmd/mbsapibase/f_mbs_status.c b/plugins/olmd/mbsapibase/f_mbs_status.c
new file mode 100644
index 00000000..5cddf51b
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_mbs_status.c
@@ -0,0 +1,200 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#include "typedefs.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sbs_def.h"
+#include "sys_def.h"
+#include "ml_def.h"
+#include "portnum_def.h"
+#include "f_stccomm.h"
+#include "f_ut_status.h"
+#include "f_mbs_status.h"
+
+INTS4 l_gl_tcp_chan;
+
+int l_status,l;
+
+#define VERSION__DAQST 2
+#define VERSION__SETUP 1
+#define VERSION__SET_ML 1
+#define VERSION__SET_MO 1
+
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_mbs_status */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l_status=f_mbs_status(s_daqst, socket) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Read s_daqst from socket. */
+/* */
+/*+ ARGUMENTS : */
+/*+ s_daqst : pointer to s_daqst */
+/*+ socket : Tcp socket from connect */
+/*1- C Procedure *************+****************************************/
+INTS4 f_mbs_status(CHARS *c_node, s_daqst *ps_daqst)
+{
+ struct s_tcpcomm *ps_tcpcomm;
+
+ ps_tcpcomm = (struct s_tcpcomm *) malloc (sizeof( struct s_tcpcomm));
+ l_status = f_stc_connectserver (c_node,PORT__STAT_SERV,&l_gl_tcp_chan,ps_tcpcomm);
+ if (l_status != STC__SUCCESS)
+ {
+ free(ps_tcpcomm);
+ return(-2);
+ }
+ l_status = f_ut_status_r (ps_daqst, l_gl_tcp_chan);
+ f_stc_discclient (l_gl_tcp_chan);
+ free(ps_tcpcomm);
+ return l_status;
+}
+
+
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_mbs_setup */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l_status=f_mbs_setup(s_setup, socket) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Read s_setup from socket. */
+/* */
+/*+ ARGUMENTS : */
+/*+ s_setup : pointer to s_setup */
+/*+ socket : Tcp socket from connect */
+/*1- C Procedure *************+****************************************/
+INTS4 f_mbs_setup(CHARS *c_node, s_setup *ps_setup)
+{
+ s_daqst *ps_daqst;
+ struct s_tcpcomm *ps_tcpcomm;
+
+ ps_tcpcomm = (struct s_tcpcomm *) malloc (sizeof( struct s_tcpcomm));
+ l_status = f_stc_connectserver (c_node,PORT__STAT_SERV,&l_gl_tcp_chan,ps_tcpcomm);
+ if (l_status != STC__SUCCESS)
+ {
+ free(ps_tcpcomm);
+ return(-2);
+ }
+ ps_daqst = (s_daqst *) malloc (sizeof( s_daqst));
+ l_status = f_ut_status_r (ps_daqst, l_gl_tcp_chan);
+ f_stc_discclient (l_gl_tcp_chan);
+ l_status = f_stc_connectserver (c_node,PORT__STAT_SERV,&l_gl_tcp_chan,ps_tcpcomm);
+ if (l_status != STC__SUCCESS)
+ {
+ free(ps_tcpcomm);
+ free(ps_daqst);
+ return(-1);
+ }
+ if(ps_daqst->bh_setup_loaded == 0) l_status=-3;
+ else l_status = f_ut_setup_r (ps_setup, l_gl_tcp_chan);
+ f_stc_discclient (l_gl_tcp_chan);
+ free(ps_daqst);
+ free(ps_tcpcomm);
+ return l_status;
+}
+
+
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_mbs_ml_setup */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l_status=f_mbs_ml_setup(s_set_ml, socket) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Read s_set_ml from socket. */
+/* */
+/*+ ARGUMENTS : */
+/*+ s_set_ml : pointer to s_set_ml */
+/*+ socket : Tcp socket from connect */
+/*1- C Procedure *************+****************************************/
+INTS4 f_mbs_ml_setup(CHARS *c_node, s_set_ml *ps_set_ml)
+{
+ s_daqst *ps_daqst;
+ struct s_tcpcomm *ps_tcpcomm;
+
+ ps_tcpcomm = (struct s_tcpcomm *) malloc (sizeof( struct s_tcpcomm));
+ l_status = f_stc_connectserver (c_node,PORT__STAT_SERV,&l_gl_tcp_chan,ps_tcpcomm);
+ if (l_status != STC__SUCCESS)
+ {
+ free(ps_tcpcomm);
+ return(-2);
+ }
+ ps_daqst = (s_daqst *) malloc (sizeof( s_daqst));
+ l_status = f_ut_status_r (ps_daqst, l_gl_tcp_chan);
+ f_stc_discclient (l_gl_tcp_chan);
+ l_status = f_stc_connectserver (c_node,PORT__STAT_SERV,&l_gl_tcp_chan,ps_tcpcomm);
+ if (l_status != STC__SUCCESS)
+ {
+ free(ps_tcpcomm);
+ free(ps_daqst);
+ return(-1);
+ }
+ if(ps_daqst->bh_set_ml_loaded == 0) l_status=-3;
+ else l_status = f_ut_set_ml_r (ps_set_ml, l_gl_tcp_chan);
+ f_stc_discclient (l_gl_tcp_chan);
+ free(ps_tcpcomm);
+ free(ps_daqst);
+ return l_status;
+}
+/*1+ C Procedure *************+****************************************/
+/* */
+/*+ Module : f_mbs_mo_setup */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : l_status=f_mbs_mo_setup(s_set_mo, socket) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : Read s_set_mo from socket. */
+/* */
+/*+ ARGUMENTS : */
+/*+ s_set_mo : pointer to s_set_mo */
+/*+ socket : Tcp socket from connect */
+/*1- C Procedure *************+****************************************/
+INTS4 f_mbs_mo_setup(CHARS *c_node, s_set_mo *ps_set_mo)
+{
+ s_daqst *ps_daqst;
+ struct s_tcpcomm *ps_tcpcomm;
+
+ ps_tcpcomm = (struct s_tcpcomm *) malloc (sizeof( struct s_tcpcomm));
+ l_status = f_stc_connectserver (c_node,PORT__STAT_SERV,&l_gl_tcp_chan,ps_tcpcomm);
+ if (l_status != STC__SUCCESS)
+ {
+ free(ps_tcpcomm);
+ return(-2);
+ }
+ ps_daqst = (s_daqst *) malloc (sizeof( s_daqst));
+ l_status = f_ut_status_r (ps_daqst, l_gl_tcp_chan);
+ f_stc_discclient (l_gl_tcp_chan);
+ l_status = f_stc_connectserver (c_node,PORT__STAT_SERV,&l_gl_tcp_chan,ps_tcpcomm);
+ if (l_status != STC__SUCCESS)
+ {
+ free(ps_tcpcomm);
+ free(ps_daqst);
+ return(-1);
+ }
+ if(ps_daqst->bh_set_mo_loaded == 0) l_status=-3;
+ else l_status = f_ut_set_mo_r (ps_set_mo, l_gl_tcp_chan);
+ f_stc_discclient (l_gl_tcp_chan);
+ free(ps_tcpcomm);
+ free(ps_daqst);
+ return l_status;
+}
diff --git a/plugins/olmd/mbsapibase/f_mbs_status.h b/plugins/olmd/mbsapibase/f_mbs_status.h
new file mode 100644
index 00000000..e0d97fad
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_mbs_status.h
@@ -0,0 +1,28 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#ifndef F_MBS_STATUS_H
+#define F_MBS_STATUS_H
+
+#include "typedefs.h"
+#include "s_daqst.h"
+#include "s_setup.h"
+#include "s_set_ml.h"
+#include "s_set_mo.h"
+
+INTS4 f_mbs_status(CHARS *c_node, s_daqst *ps_daqst);
+INTS4 f_mbs_setup(CHARS *c_node, s_setup *ps_setup);
+INTS4 f_mbs_ml_setup(CHARS *c_node, s_set_ml *ps_set_ml);
+INTS4 f_mbs_mo_setup(CHARS *c_node, s_set_mo *ps_set_mo);
+
+#endif
diff --git a/plugins/olmd/mbsapibase/f_stccomm.c b/plugins/olmd/mbsapibase/f_stccomm.c
new file mode 100644
index 00000000..f44571a8
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_stccomm.c
@@ -0,0 +1,1489 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+#include "f_stccomm.h"
+
+// JAM1-6-2021- test if this helps the streamserver problems
+// #define DISABLE_POLLING_TIMEOUT 1
+
+
+
+CHARS c_msg[80];
+/*#define DEBUG 1*/
+
+/* %%+HEAD: */
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ PLI Main ****************+****************************************/
+/* */
+/*+ Module : f_stc_read */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_stc_read( INTS1 p_buffer , INTS4 i_buflen , */
+/* INTS4 i_channel , INTS4 i_timeout ) */
+/* */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_stc_read read bytes from a connected socket */
+/* and places them in a buffer (p_buffer). */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ p_buffer : Pointer to free data buffer. */
+/* */
+/*+ i_buflen : buffer length. */
+/* */
+/*+ i_channel : Id from the connected socket. */
+/* */
+/*+ i_timeout : Timeout value ( seconds ) for read from socket. */
+/*- i_timeout = 0 : Return immediately after */
+/* checking the connected socket. */
+/*- i_timeout > 0 : Return when the specified socket */
+/* is ready for I/O, but don't wait */
+/* beyond a fixed amount of time. */
+/*- i_timeout = -1 : Return only when the specified */
+/* socket is ready for I/O. */
+/* */
+/*+ Return type : integer. */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ CALLING : f_stc_read ( INTS1 p_buffer , INTS4 i_buflen , */
+/* INTS4 i_channel , INTS4 i_timeout ) */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ p_buffer : Pointer to free data buffer. */
+/* */
+/*+ i_buflen : buffer length. */
+/* */
+/*+ i_channel : Id from the connected socket. */
+/* */
+/*+ i_timeout : Timeout value ( seconds ) for read from socket. */
+/* */
+/*- i_timeout = 0 : Return immediately after checking */
+/* the connected socket. */
+/*- i_timeout > 0 : Return when the specified socket */
+/* is ready for I/O, but don't wait */
+/* beyond a fixed amount of time. */
+/*- i_timeout = -1 : Return only when the specified */
+/* socket is ready for I/O. */
+/* */
+/*+ FUNCTION : Read bytes from a connected socket and places them */
+/* in a buffer (p_buffer) */
+/* The procedure f_stc_read wait max timeout seconds */
+/* getting data from the socket. */
+/* */
+/*+ REMARKS : - */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ Input/Output: SYS$INPUT, SYS$OUTPUT */
+/*+ Return type : INTEGER */
+/*+ Status codes: */
+/*- STC__SUCCESS : success. */
+/*- STC__FAIlURE : failure. */
+/*- STC__INVSOCK : invalid socket number. */
+/*- STC__INVBUF : buffer points outside allocated */
+/* adress space. */
+/*- STC__NGBUFSIZE : buffer length is negative. */
+/*- STC__INVTIME : time limit is unacceptable negativ */
+/* or to long. */
+/*- STC__TIMEOUT : timeout read from socket. */
+/*+ File name : */
+/*+ Version : 1.01 */
+/*+ Author : R.Fritzsche */
+/*+ Last Update : 17-Jul-1995 */
+/* */
+/*2+UPDATES*******+***********+*********************************************/
+/* */
+/*+ Updates : Date Purpose */
+/*- 17-Jul-1995 : f_stc_connectserver H.G. */
+/* close socket in case of failure to avoid */
+/* hanging sockets */
+/*- 17-Jul-1995 : f_stc_discclient H.G. */
+/* remove shutdown (which didn't work and */
+/* inibited close) and make close in any case */
+/*- 17-Jul-1995 : f_stc_disperror H.G. */
+/* new message no.: STC__ECONNREF */
+/* */
+/*2+INTERNALS*****+***********+*********************************************/
+/* */
+/*+ Utility : EXAMPLES */
+/*+ Compile lib.: GOOINC.TLB */
+/*+ Home direct.: GOO$EXAMPLES */
+/*+ Created : 25-Jan-1994 */
+/* */
+/*1- PLI Main ****************+****************************************/
+/* %%-HEAD: */
+
+INTS4 f_stc_read(void *p_buffer, INTS4 i_buflen, INTS4 i_channel, INTS4 i_timeout)
+{
+ INTS4 retval , buflen_tmp;
+ INTS1 *p_buffer_tmp;
+ INTS4 i_retry = 0;
+ struct timeval read_timeout;
+ fd_set xrmask,xwmask,xemask;
+ INTS4 num_of_bytes_read = 0;
+
+ buflen_tmp = i_buflen;
+ p_buffer_tmp = (INTS1*) p_buffer; /* actual pointer to buffer */
+
+ FD_ZERO(&xrmask);
+ FD_ZERO(&xemask);
+ FD_ZERO(&xwmask);
+ FD_SET(i_channel,&xrmask);
+ read_timeout.tv_sec = i_timeout;
+ read_timeout.tv_usec = 0;
+
+ // JAM1-6-2021- test if this helps the streamserver problems
+#ifndef DISABLE_POLLING_TIMEOUT
+ if (i_timeout == 555555) {
+ read_timeout.tv_sec = 0;
+ read_timeout.tv_usec = 50000; // 0.05 sec
+ }
+#endif
+
+#ifdef DEBUG
+ printf("STC: read %6d bytes channel %d ",i_buflen,i_channel);fflush(stdout);
+#endif
+ while( num_of_bytes_read < i_buflen && buflen_tmp > 0 )
+ {
+ if( i_timeout >= 0 )
+ {
+ /*
+#ifdef GSI__AIX
+ retval = select(32,&xrmask,&xwmask,&xemask,&read_timeout);
+#else
+ retval = select(32,&rmask,&wmask,&emask,&read_timeout);
+#endif
+ */
+
+ /* Changed by S.Linev, 18.09.2007 */
+ // retval = select(32,(fd_set*) &rmask, (fd_set*) &wmask, (fd_set*) &emask,&read_timeout);
+ retval = select(i_channel+1, &xrmask, &xwmask, &xemask, &read_timeout);
+
+ switch( retval )
+ {
+ case -1:
+ switch( errno )
+ {
+ case EBADF : return STC__INVSOCK;
+ case EINVAL : return STC__INVTIME;
+ case EINTR : continue;
+ case ECONNRESET : return STC__ECONNRES;
+ default : sprintf(c_msg,"STC select error channel %d",i_channel);
+ perror(c_msg);
+ return STC__FAILURE;
+ }
+ case 0: return STC__TIMEOUT;
+ }
+ }
+ /* ------------------------------------------------------- */
+ /* read data from the connect socket. */
+ /* ------------------------------------------------------- */
+#ifdef DEBUG
+ printf("read ");fflush(stdout);
+#endif
+#ifdef GSI__WINNT
+ retval = recv(i_channel, p_buffer_tmp, buflen_tmp, 0); /* Mohammad Al-Turany 31.07.00 */
+#else
+ retval = read(i_channel, p_buffer_tmp, buflen_tmp);
+#endif
+ if( retval == -1 )
+ {
+ switch( errno )
+ {
+ case EBADF : return STC__INVSOCK;
+ case EFAULT : return STC__INVBUF;
+ case EINVAL : return STC__NGBUFSIZE;
+ case EINTR : return STC__EINTR;
+ case ECONNRESET : return STC__ECONNRES;
+ default : sprintf(c_msg,"STC read error channel %d",i_channel);
+ perror(c_msg);
+ return STC__FAILURE;
+ } /* switch( errno ) */
+
+ } /* if( retval == -1 ) */
+
+ /* ------------------------------------------------------- */
+ /* set the num of bytes to read in the next */
+ /* read statement. */
+ /* ------------------------------------------------------- */
+
+ num_of_bytes_read += retval;
+ buflen_tmp -= retval;
+ p_buffer_tmp += retval; /* calc actual pointer */
+ if( ++i_retry == 100000 ) {
+ printf("Request %d bytes, read %d, timeout after 100000 retries\n",i_buflen,num_of_bytes_read);
+ return STC__NODATA;
+ }
+ // JAM1-6-2021- test if this helps the streamserver problems
+#ifndef DISABLE_POLLING_TIMEOUT
+ if (i_timeout == 555555) {
+ read_timeout.tv_sec = 0;
+ read_timeout.tv_usec = 50000;
+ } else {
+ read_timeout.tv_sec = 100;
+ read_timeout.tv_usec = 0;
+ }
+#else
+ read_timeout.tv_sec = 100;
+ read_timeout.tv_usec = 0;
+#endif
+
+ } /* end while */
+
+
+#ifdef DEBUG
+ printf("done\n"); fflush(stdout);
+#endif
+ if( num_of_bytes_read == i_buflen ) return STC__SUCCESS;
+
+ return STC__FAILURE;
+} /* f_stc_read() */
+
+/* ------------------------------------------------------------------------- */
+
+/* %%+HEAD: */
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ PLI Main ****************+****************************************/
+/* */
+/*+ Module : f_stc_write */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_stc_write( INTS1 p_buffer , INTS4 i_buflen , */
+/* INTS4 i_channel ) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_stc_write. write a buffer to a connected */
+/* socket. */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ p_buffer : Pointer to buffer. */
+/* */
+/*+ i_buflen : length of buffer. */
+/* */
+/*+ i_channel : Id from the connected socket. */
+/* */
+/*+ Return type : integer. */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ CALLING : f_stc_write( INTS1 p_buffer , INTS4 i_buflen , */
+/* INTS4 i_channel ) */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ p_buffer : Pointer to buffer. */
+/* */
+/*+ i_buflen : length of buffer. */
+/* */
+/*+ i_channel : Id from the connected socket. */
+/* */
+/*+ FUNCTION : Write a specified buffer to a connected socket */
+/* */
+/*+ REMARKS : - */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ Input/Output: SYS$INPUT, SYS$OUTPUT */
+/*+ Return type : INTEGER */
+/*+ Status codes: */
+/*- STC__SUCCESS : success. */
+/*- STC__FAILURE : failure. */
+/*- STC__INVSOCK : invalid socket number. */
+/*- STC__NOTSOCK : socket number points to a file */
+/* not a socket. */
+/*- STC__INVADDR : invalid address specified in */
+/* parameter. */
+/*+ File name : */
+/*+ Version : 1.01 */
+/*+ Author : R.Fritzsche */
+/*+ Last Update : 27-Jan-1994 */
+/* */
+/*2+UPDATES*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*2+INTERNALS*****+***********+****************************************/
+/* */
+/*+ Utility : EXAMPLES */
+/*+ Compile lib.: GOOINC.TLB */
+/*+ Home direct.: GOO$EXAMPLES */
+/*+ Created : 25-Jan-1994 */
+/* */
+/*1- PLI Main ****************+****************************************/
+/* %%-HEAD: */
+
+INTS4 f_stc_write(void *p_buffer, INTS4 i_buflen, INTS4 i_channel)
+{
+ INTS4 l_retval;
+
+ /* ---------------------------------------------------------- */
+ /* send data to server. */
+ /* ---------------------------------------------------------- */
+
+#ifdef DEBUG
+ printf("STC: write %5d bytes channel %d ",i_buflen,i_channel);fflush(stdout);
+#endif
+ l_retval = send(i_channel , p_buffer , i_buflen , 0);
+
+ switch( l_retval )
+ {
+ case -1:
+ switch( errno )
+ {
+ case EBADF : return STC__INVSOCK;
+ case ENOTSOCK : return STC__NOTSOCK;
+ case EFAULT : return STC__INVADDR;
+ default : sprintf(c_msg,"STC write error channel %d",i_channel);
+ perror(c_msg);
+ return STC__FAILURE;
+ } /* switch( errno ) */
+
+ } /* switch( l_retval ) */
+
+ /* ---------------------------------------------------------- */
+ /* send() returns the number of bytes sent. */
+ /* ---------------------------------------------------------- */
+
+#ifdef DEBUG
+ printf("done\n");fflush(stdout);
+#endif
+ if(l_retval == i_buflen) return STC__SUCCESS;
+
+ return STC__FAILURE;
+} /* end f_stc_write() */
+
+
+/* %%+HEAD: */
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ PLI Main ****************+****************************************/
+/* */
+/*+ Module : f_stc_connectserver */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_stc_connectserver( CHARS c_node , INTS4 l_port , */
+/* INTS4 pi_channel , */
+/* struct s_tcpcomm ps_client ) */
+/* */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_stc_connectserver. connect a client process to a */
+/* server process. */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ c_node : Name of server node */
+/* */
+/*+ l_port : Portnumber from server */
+/* */
+/*+ pi_channel : Pointer to channel number. */
+/* i_channel specifies the address that will be filled */
+/* in with the actual socket Id. */
+/* */
+/*+ pc_client : Pointer to structure s_tcpcomm. */
+/* s_client specifies the address that will be filled */
+/* in with the actual communication values. */
+/* */
+/* */
+/*+ Return type : integer. */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ CALLING : f_stc_connectserver( CHARS c_node , INTS4 l_port , */
+/* INTS4 pi_channel , */
+/* struct s_tcpcomm ps_client ) */
+/*+ ARGUMENTS : */
+/* */
+/*+ c_node : Name of server node */
+/* */
+/*+ l_port : Portnumber from server */
+/* */
+/*+ pi_channel : Pointer to channel number. */
+/* i_channel specifies the address that will be filled */
+/* in with the actual socket Id. */
+/* */
+/*+ ps_client : Pointer to structure s_tcpcomm. */
+/* s_client specifies the address that will be filled */
+/* in with the actual communication values. */
+/* */
+/*+ FUNCTION : f_stc_connectserver. connect a client process to a */
+/* server process on node "c_node"*/
+/* and port "l_port". */
+/* f_stc_connectserver() modify */
+/* the channel number and fill the*/
+/* structure s_tcpcomm. */
+/* The channel number is required */
+/* to read and write data, to the */
+/* connected server. */
+/*+ REMARKS : - */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ Input/Output: SYS$INPUT, SYS$OUTPUT */
+/*+ Return type : INTEGER */
+/*+ Status codes: */
+/*- STC__SUCCESS : success. */
+/*- STC__FAILURE : failure. */
+/*- STC__INVADDRF: The specified address family is not */
+/* supported. */
+/*- STC__SOCKNSUP: The specified socket type is not */
+/* supported. */
+/*- STC__INVPROTO: The specified protocol is not */
+/* supported. */
+/*- STC__SOCKTABF: The per-process descriptor table */
+/* is full. */
+/*- STC__SOCKSPAF: No buffer space is available. The */
+/* socket can't be created. */
+/*- STC__INVSOCK : invalid socket number. */
+/*- STC__NOTSOCK : socket number points to a file not a */
+/* socket. */
+/*- STC__SOCKISC : socket is already connected. */
+/*- STC__CONNTOUT: connection timed out without */
+/* establishing a connection. */
+/*- STC__NETUNREA: The network is not reachable from */
+/* this host. */
+/*- STC__PORTINUS: The specified Internet Address and */
+/* port is already in use. */
+/*+ File name : */
+/*+ Version : 1.01 */
+/*+ Author : R.Fritzsche */
+/*+ Last Update : 24-Jan-1994 */
+/* */
+/*2+UPDATES*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*2+INTERNALS*****+***********+****************************************/
+/* */
+/*+ Utility : EXAMPLES */
+/*+ Compile lib.: GOOINC.TLB */
+/*+ Home direct.: GOO$EXAMPLES */
+/*+ Created : 24-Jan-1994 */
+/* */
+/*1- PLI Main ****************+****************************************/
+/* %%-HEAD: */
+
+INTS4 f_stc_connectserver(CHARS *c_node, INTS4 l_port, INTS4 *pi_channel, struct s_tcpcomm *ps_client)
+{
+ INTS4 retval ;
+ struct s_tcpcomm s_client;
+
+
+ /* ----------------------------------------------------------------------- */
+ /* init communication socket. */
+ /* ----------------------------------------------------------------------- */
+
+
+#ifdef GSI__WINNT
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ wVersionRequested = MAKEWORD( 2, 2 );
+ //err = WSAStartup( wVersionRequested, &wsaData );
+ if (WSAStartup( wVersionRequested, &wsaData) != 0) {
+ printf("WinSock NOT found");
+ /* Tell the user that we could not find a usable */
+ /* WinSock DLL. */
+ }
+
+ if ( LOBYTE( wsaData.wVersion ) != 2 ||
+ HIBYTE( wsaData.wVersion ) != 2 ) {
+ /* Tell the user that we could not find a usable */
+ /* WinSock DLL.
+ */
+ printf("WinSock %d.%d",LOBYTE( wsaData.wVersion ),HIBYTE( wsaData.wVersion ));
+ WSACleanup( );
+ }
+
+#endif
+
+ s_client.socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ *ps_client = s_client;
+ *pi_channel = s_client.socket; /* save channel also in case of error */
+ /* 17.7.95, H.G. */
+ switch( s_client.socket )
+ {
+ case -1:
+ switch( errno )
+ {
+ case EAFNOSUPPORT : return STC__INVADDRF;
+ case ESOCKTNOSUPPORT : return STC__SOCKNSUP;
+ case EPROTONOSUPPORT : return STC__INVPROTO;
+ case EMFILE : return STC__SOCKTABF;
+ case ENOBUFS : return STC__SOCKSPAF;
+ default : return STC__FAILURE;
+ } /* switch( errno ) */
+ } /* switch( s_client.socket) */
+
+
+ if(( s_client.hostentptr = gethostbyname(c_node)) == NULL)
+ {
+
+#ifdef GSI__WINNT
+ closesocket(s_client.socket); /* Mohammad Al-Turany 31.07.00*/
+#else
+ close(s_client.socket); /* close socket here and in any case! */
+ /* H.G., 17.7.95 */
+#endif
+ /* printf("--E--f_stc_connectserver(): error gethostbyname: >%s<\n",c_node);*/
+ return STC__FAILURE;
+ }
+
+
+ s_client.hostentstruct = *s_client.hostentptr;
+ s_client.sock.sin_family = s_client.hostentstruct.h_addrtype;
+ s_client.sock.sin_port = htons(l_port);
+ s_client.sock.sin_addr =
+ * ((struct in_addr *) s_client.hostentstruct.h_addr);
+
+ retval = connect( s_client.socket,
+ ( struct sockaddr *) &s_client.sock,
+ sizeof(s_client.sock));
+ if( retval == -1)
+ {
+#ifdef GSI__WINNT
+ closesocket(s_client.socket); /* Mohammad Al-Turany 31.07.00*/
+#else
+ close(s_client.socket); /* close socket here and in any case! */
+ /* H.G., 17.7.95 */
+#endif
+ switch( errno )
+ {
+ case EBADF : return STC__INVSOCK;
+ case ENOTSOCK : return STC__NOTSOCK;
+ case EISCONN : return STC__SOCKISC;
+ case ETIMEDOUT : return STC__CONNTOUT;
+ case ENETUNREACH : return STC__NETUNREA;
+ case EADDRINUSE : return STC__PORTINUS;
+ case ECONNREFUSED : return STC__ECONNREF;
+ default : return STC__FAILURE;
+ } /* switch( errno ) */
+ }
+
+ *ps_client = s_client;
+
+ return STC__SUCCESS;
+
+} /* f_stc_connectserver() */
+
+/* %%+HEAD: */
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ PLI Main ****************+****************************************/
+/* */
+/*+ Module : f_stc_acceptclient */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_stc_acceptclient( struct s_tcpcomm s_server , */
+/* INTS4 pi_channel ) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_stc_acceptclient. completes a connection between */
+/* server and client. */
+/* f_stc_acceptclient() modify the */
+/* channel Id from the accepted */
+/* client. The channel Id is */
+/* required to read and write data */
+/* to the client. */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ s_server : Pointer to structure s_tcpcomm. */
+/* */
+/*+ pi_channel : Id from the connected client. */
+/* i_channel specifies the address that will be filled */
+/* in with the actual client socket Id. */
+/* */
+/*+ Return type : integer. */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ CALLING : f_stc_acceptclient( struct s_tcpcomm s_server , */
+/* INTS4 pi_channel ) */
+/* */
+/*+ PURPOSE : f_stc_acceptclient. completes a connection between */
+/* server and client. */
+/* f_stc_acceptclient() modify the */
+/* channel Id from the accepted */
+/* client. The channel Id is */
+/* required to read and write data */
+/* to the client. */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ s_server : Pointer to structure s_tcpcomm. */
+/* */
+/*+ pi_channel : Id from the connected client. */
+/* i_channel specifies the address that will be filled */
+/* in with the actual client socket id. */
+/* */
+/*+ Return type : integer. */
+/* */
+/*+ REMARKS : - */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ Input/Output: SYS$INPUT, SYS$OUTPUT */
+/*+ Return type : INTEGER */
+/*+ Status codes: Status of last command */
+/*- STC__SUCCESS : success. */
+/*- STC__FAILURE : failure. */
+/*- STC__INVSOCK : invalid socket number. */
+/*- STC__NOTSOCK : socket number points to a file not */
+/* a socket. */
+/*+ File name : GOO$EXAMPLES: */
+/*+ Version : 1.01 */
+/*+ Author : R.Fritzsche */
+/*+ Last Update : 25-Jan-1994 */
+/* */
+/*2+UPDATES*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*2+INTERNALS*****+***********+****************************************/
+/* */
+/*+ Utility : EXAMPLES */
+/*+ Compile lib.: GOOINC.TLB */
+/*+ Home direct.: GOO$EXAMPLES */
+/*+ Created : 15-Jan-1994 */
+/* */
+/*1- PLI Main ****************+****************************************/
+/* %%-HEAD: */
+
+INTS4 f_stc_acceptclient(struct s_tcpcomm *ps_server, INTS4 *pi_channel)
+{
+#ifdef GSI__AIX
+ *pi_channel = accept( ps_server->sock_rw,
+ ( struct sockaddr *) &ps_server->sock_name,
+ (socklen_t *) &ps_server->namelength);
+#else
+#ifdef GSI__WINNT
+ *pi_channel = accept( ps_server->sock_rw,
+ ( struct sockaddr *) &ps_server->sock_name,
+ (int *) &ps_server->namelength);
+#else
+ *pi_channel = accept( ps_server->sock_rw,
+ ( struct sockaddr *) &ps_server->sock_name,
+ (socklen_t *) &ps_server->namelength);
+#endif
+#endif
+if( *pi_channel == -1)
+{
+ switch( errno )
+ {
+ case EBADF : return STC__INVSOCK;
+ case ENOTSOCK : return STC__NOTSOCK;
+ default : return STC__FAILURE;
+ } /* switch( errno ) */
+}
+
+/*
+ hostname of remote node.
+ he = gethostbyaddr( ps_server->sock_name.sin_addr.s_addr,
+ sizeof(ps_server->sock_name.sin_addr.s_addr),
+ AF_INET );
+
+ if( he != NULL )
+ printf("name of client: %s\n",he->h_name);
+ */
+
+ return STC__SUCCESS;
+} /* end f_stc_acceptclient() */
+
+/* %%+HEAD: */
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ PLI Main ****************+****************************************/
+/* */
+/*+ Module : f_stc_createserver */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_stc_createserver( INTS4 pl_port , */
+/* struct s_tcpcomm ps_server ) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_stc_createserver creates an endpoint for */
+/* client-server communications. */
+/* The endpoint of communication */
+/* data is not the process name. */
+/* The client-server communication */
+/* use portnumbers as endpoints of */
+/* communications. */
+/* The port numbers in the range */
+/* 1 to 1023 are privileged ports. */
+/* User can use ports in the range */
+/* 1024 to 65535. */
+/* also you can use portnumber 0, */
+/* then f_stc_createserver() search*/
+/* for a free portnumber and modify*/
+/* the value from l_port, */
+/* else f_stc_createserver() */
+/* returns 0 */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ l_port : Pointer to Portnumber. ( 1024 - 65535 ) or ( 0 ). */
+/* */
+/*+ s_server : Pointer to structure s_tcpcomm */
+/* s_server specifies the address that will be filled */
+/* in with the actual communication values. */
+/* */
+/*+ Return type : integer. */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ CALLING : f_stc_createserver( INTS4 l_port , */
+/* struct s_tcpcomm s_server) */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ l_port : Pointer to Portnumber. ( 1024 - 65535 ) or ( 0 ). */
+/* l_port specifies the address that will be filled */
+/* in with the actual server portnumber. */
+/* */
+/*+ S_SERVER : Pointer to structure s_tcpcomm */
+/* s_server specifies the address that will be filled */
+/* in with the actual communication values. */
+/* */
+/*+ FUNCTION : f_stc_createserver creates an endpoint for */
+/* client - server communications. */
+/* The endpoint of communication for */
+/* data is not the a process name. */
+/* The client - server communication */
+/* use portnumbers as endpoints of */
+/* communications. */
+/* The port numbers in the range */
+/* 1 to 1023 are privileged ports. */
+/* User can use ports in the range */
+/* 1024 to 65535. */
+/* also you can use portnumber 0, */
+/* then f_stc_createserver() search */
+/* for a free portnumber and write */
+/* the free portnumber to l_port, */
+/* else f_stc_createserver() */
+/* returns 0 */
+/* */
+/*+ REMARKS : - */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ Input/Output: SYS$INPUT, SYS$OUTPUT */
+/*+ Return type : INTEGER */
+/*+ Status codes: */
+/*- STC__SUCCESS : success. */
+/*- STC__FAILURE : failure. */
+/*- STC__INVADDRF : The specified address family is not */
+/* supported. */
+/*- STC__SOCKNSUP : The specified socket type is not */
+/* supported. */
+/*- STC__INVPROTO : The specified protocol is not */
+/* supported. */
+/*- STC__SOCKTABF : The per-process descriptor table */
+/* is full. */
+/*- STC__SOCKSPAF : No buffer space is available. */
+/* The socket can't be created. */
+/*- STC__INVSOCK : invalid socket number. */
+/*- STC__NOTSOCK : socket number points to a file not */
+/* a socket. */
+/*- STC__PORTINUS : The specified Internet Address */
+/* and port is already in use. */
+/*- STC__SOCKISC : socket is already connected. */
+/*- STC__SOCKISP : socket address is protected and the */
+/* current user has inadequate */
+/* permission to access it. */
+/*+ File name : */
+/*+ Version : 1.01 */
+/*+ Author : R.Fritzsche */
+/*+ Last Update : 25-Jan-1994 */
+/* */
+/*2+UPDATES*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*2+INTERNALS*****+***********+****************************************/
+/* */
+/*+ Utility : EXAMPLES */
+/*+ Compile lib.: GOOINC.TLB */
+/*+ Home direct.: GOO$EXAMPLES */
+/*+ Created : 25-Jan-1994 */
+/* */
+/*1- PLI Main ****************+****************************************/
+/* %%-HEAD: */
+
+INTS4 f_stc_createserver(INTS4 *pl_port, struct s_tcpcomm *ps_server)
+{
+
+ INTS4 retval , retry;
+ struct s_tcpcomm s_server;
+
+
+#ifdef GSI__WINNT
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ wVersionRequested = MAKEWORD( 2, 2 );
+ //err = WSAStartup( wVersionRequested, &wsaData );
+ if (WSAStartup( wVersionRequested, &wsaData) != 0) {
+ printf("WinSock NOT found");
+ /* Tell the user that we could not find a usable */
+ /* WinSock DLL. */
+ }
+
+ if ( LOBYTE( wsaData.wVersion ) != 2 ||
+ HIBYTE( wsaData.wVersion ) != 2 ) {
+ /* Tell the user that we could not find a usable */
+ /* WinSock DLL.
+ */
+ printf("WinSock %d.%d",LOBYTE( wsaData.wVersion ),HIBYTE( wsaData.wVersion ));
+ WSACleanup( );
+ }
+
+#endif
+
+ if( *pl_port == 0 ) {
+ retry = 1 ;
+ *pl_port = 1024;
+ }
+ else
+ retry = 0;
+
+ s_server.sock_rw = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ switch( s_server.sock_rw )
+ {
+ case -1:
+ switch( errno )
+ {
+ case EAFNOSUPPORT : return STC__INVADDRF;
+ case ESOCKTNOSUPPORT : return STC__SOCKNSUP;
+ case EPROTONOSUPPORT : return STC__INVPROTO;
+ case EMFILE : return STC__SOCKTABF;
+ case ENOBUFS : return STC__SOCKSPAF;
+ default : return STC__FAILURE;
+ } /* switch( errno ) */
+ } /* switch( s_server.sock_rw) */
+
+
+ retval = gethostname(s_server.hostname,sizeof(s_server.hostname));
+ if(retval)
+ {
+ printf("--E--f_stc_createserver() error get local hostname\n");
+ return STC__FAILURE;
+ }
+
+ if((s_server.hostentptr = gethostbyname (s_server.hostname)) == NULL)
+ {
+ printf("--E--f_stc_createserver() error get local Internet address\n");
+ return STC__FAILURE;
+ }
+
+ bzero( (CHARS *) &s_server.sock_name , sizeof( s_server.sock_name ) );
+ s_server.sock_name.sin_family = AF_INET;
+ s_server.sock_name.sin_addr.s_addr = htonl(INADDR_ANY);
+ s_server.sock_name.sin_port = htons(*pl_port);
+
+ retval = bind( s_server.sock_rw,
+ (struct sockaddr *) &s_server.sock_name,
+ sizeof(s_server.sock_name));
+
+ if( retval == -1 && retry == 0 )
+ {
+ close( s_server.sock_rw );
+
+ switch( errno )
+ {
+ case EBADF : return STC__INVSOCK;
+ case ENOTSOCK : return STC__NOTSOCK;
+ case EADDRINUSE : return STC__PORTINUS;
+ case EINVAL : return STC__SOCKISC;
+ case EACCES : return STC__SOCKISP;
+ default : return STC__FAILURE;
+ }
+ }
+
+ retval = -1;
+
+ while ( retval == -1 && retry == 1 )
+ {
+
+ s_server.sock_rw = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ switch( s_server.sock_rw )
+ {
+ case -1:
+ switch( errno )
+ {
+ case EAFNOSUPPORT : return STC__INVADDRF;
+ case ESOCKTNOSUPPORT : return STC__SOCKNSUP;
+ case EPROTONOSUPPORT : return STC__INVPROTO;
+ case EMFILE : return STC__SOCKTABF;
+ case ENOBUFS : return STC__SOCKSPAF;
+ default : return STC__FAILURE;
+ }
+ }
+
+ retval = gethostname(s_server.hostname,sizeof(s_server.hostname));
+ if(retval)
+ {
+ printf("--E--f_stc_createserver() error get local hostname\n");
+ return STC__FAILURE;
+ }
+
+
+ if((s_server.hostentptr = gethostbyname (s_server.hostname)) == NULL)
+ {
+ printf("--E--f_stc_createserver() error get local Internet address\n");
+ return STC__FAILURE;
+ }
+
+ retval = -1;
+
+ bzero( (CHARS *) &s_server.sock_name , sizeof( s_server.sock_name ) );
+ s_server.sock_name.sin_family = AF_INET;
+ s_server.sock_name.sin_addr.s_addr = htonl(INADDR_ANY);
+ s_server.sock_name.sin_port = htons(*pl_port);
+
+ retval = bind( s_server.sock_rw,
+ (struct sockaddr *) &s_server.sock_name,
+ sizeof(s_server.sock_name));
+ if( retval == -1 )
+ {
+ close( s_server.sock_rw );
+
+ *pl_port += 1;
+
+ if( *pl_port > 65535 )
+ {
+ printf("--E--f_stc_createserver() portnumber exceeded > 655535\n");
+
+ switch( errno )
+ {
+ case EBADF : return STC__INVSOCK;
+ case ENOTSOCK : return STC__NOTSOCK;
+ case EADDRINUSE : return STC__PORTINUS;
+ case EINVAL : return STC__SOCKISC;
+ case EACCES : return STC__SOCKISP;
+ default : return STC__FAILURE;
+ } /* end switch( errno ) */
+
+ } /* end if *pl_port > ... ) */
+
+ } /* end if (retval == -1 ) */
+
+
+ }
+
+ retval = listen(s_server.sock_rw,5);
+ if( retval == -1 )
+ {
+ switch( errno )
+ {
+ case EBADF : return STC__INVSOCK;
+ case ENOTSOCK : return STC__NOTSOCK;
+ default : return STC__FAILURE;
+ }
+ }
+
+ s_server.namelength = sizeof( s_server.sock_name);
+
+ *ps_server = s_server;
+
+ return STC__SUCCESS;
+} /* end f_stc_createserver() */
+
+/* %%+HEAD: */
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ PLI Main ****************+****************************************/
+/* */
+/*+ Module : f_stc_close */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_stc_close( struct s_tcpcomm ps_tcp ) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_stc_close close the client server */
+/* communication. */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ S_TCP : Pointer to structure s_tcpcomm. */
+/* */
+/*+ Return type : integer. */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ CALLING : f_stc_close( struct s_tcpcomm ps_tcp ) */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ FUNCTION : f_stc_close close the client server */
+/* communication. */
+/* */
+/*+ S_TCP : Pointer to structure s_tcpcomm. */
+/* */
+/*+ REMARKS : - */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ Input/Output: SYS$INPUT, SYS$OUTPUT */
+/*+ Return type : INTEGER */
+/*+ File name : */
+/*+ Version : 1.01 */
+/*+ Author : R.Fritzsche */
+/*+ Last Update : 25-Jan-1994 */
+/* */
+/*2+UPDATES*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*2+INTERNALS*****+***********+****************************************/
+/* */
+/*+ Utility : EXAMPLES */
+/*+ Compile lib.: GOOCINC.TLB */
+/*+ Home direct.: GOO$EXAMPLES */
+/*+ Created : 25-Jan-1994 */
+/* */
+/*1- PLI Main ****************+****************************************/
+/* %%-HEAD: */
+
+INTS4 f_stc_close(struct s_tcpcomm * ps_tcp)
+{
+ INTS4 retval;
+
+ if( ps_tcp->socket )
+ {
+ retval = shutdown( ps_tcp->socket,2);
+ if(retval == -1) {
+ return STC__FAILURE;
+ }
+ retval = close(ps_tcp->socket);
+ if(retval == -1) {
+ return STC__FAILURE;
+ }
+
+ return STC__SUCCESS;
+ }
+
+ return STC__FAILURE;
+} /* f_stc_close() */
+
+/* %%+HEAD: */
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ PLI Main ****************+****************************************/
+/* */
+/*+ Module : f_stc_discclient */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_stc_discclient( INTS4 i_channel ) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_stc_discclient close the specified client */
+/* server communication. */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ I_CHANNEL : Channel Id from the specified client. */
+/* */
+/*+ Return type : integer. */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ CALLING : f_stc_discclient( INTS4 i_channel ) */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ FUNCTION : f_stc_discclient close the specified client */
+/* server communication. */
+/* */
+/*+ I_CHANNEL : Channel Id from the specified client. */
+/* */
+/*+ REMARKS : - */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ Input/Output: SYS$INPUT, SYS$OUTPUT */
+/*+ Return type : INTEGER */
+/*+ File name : */
+/*+ Version : 1.01 */
+/*+ Author : R.Fritzsche */
+/*+ Last Update : 01-Mar-1994 */
+/* */
+/*2+UPDATES*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*2+INTERNALS*****+***********+****************************************/
+/* */
+/*+ Utility : EXAMPLES */
+/*+ Compile lib.: */
+/*+ Home direct.: */
+/*+ Created : 01-Mar-1994 */
+/* */
+/*1- PLI Main ****************+****************************************/
+/* %%-HEAD: */
+
+INTS4 f_stc_discclient(INTS4 i_channel)
+{
+ INTS4 retval;
+
+ /* call of shutdown removed 17.7.95, H.G. */
+ retval = close( i_channel );
+ if(retval == -1)
+ return STC__FAILURE;
+
+ return STC__SUCCESS;
+} /* f_stc_discclient() */
+
+/* %%+HEAD: */
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ PLI Main ****************+****************************************/
+/* */
+/*+ Module : f_stc_listenserver */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_stc_listenserver( struct s_tcpcomm ps_server ) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_stc_listenserver look for a pending client */
+/* connection on the specified */
+/* server. */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ PS_SERVER : Pointer to structure s_tcpcomm. */
+/* */
+/*+ Return type : integer. */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ CALLING : f_stc_listenserver( struct s_tcpcomm ps_server ) */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ FUNCTION : f_stc_listenserver look for a pending client */
+/* connection on the specified */
+/* server. */
+/* */
+/*+ PS_SERVER : Pointer to structure s_tcpcomm. */
+/* */
+/*+ REMARKS : - */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ Input/Output: SYS$INPUT, SYS$OUTPUT */
+/*+ Return type : INTEGER */
+/*+ Status codes: */
+/*- STC__SUCCESS : success. */
+/*- STC__FAIlURE : failure. */
+/*- STC__INVSOCK : invalid socket number. */
+/*- STC__TIMEOUT : timeout. */
+/*- STC__INVTIME : time limit is unacceptable */
+/* negativ or to long. */
+/*+ File name : */
+/*+ Version : 1.01 */
+/*+ Author : R.Fritzsche */
+/*+ Last Update : 25-Jan-1994 */
+/* */
+/*2+UPDATES*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*2+INTERNALS*****+***********+****************************************/
+/* */
+/*+ Utility : EXAMPLES */
+/*+ Compile lib.: GOOCINC.TLB */
+/*+ Home direct.: GOO$EXAMPLES */
+/*+ Created : 25-Jan-1994 */
+/* */
+/*1- PLI Main ****************+****************************************/
+/* %%-HEAD: */
+
+INTS4 f_stc_listenserver(struct s_tcpcomm *ps_server)
+{
+ struct timeval read_timeout;
+ fd_set rset , allset , wset , eset;
+ INTS4 listenfd , maxfd , sts;
+
+ read_timeout.tv_sec = 0;
+ read_timeout.tv_usec = 0;
+
+ listenfd = ps_server->sock_rw;
+
+ FD_ZERO(&rset);
+ FD_ZERO(&wset);
+ FD_ZERO(&eset);
+ FD_ZERO(&allset);
+ FD_SET(listenfd,&rset);
+ FD_SET(listenfd,&wset);
+ FD_SET(listenfd,&eset);
+ maxfd = listenfd;
+
+ sts = select( maxfd + 1 , &rset ,
+ &wset ,
+ &eset , &read_timeout);
+ switch( sts )
+ {
+ case -1:
+ switch( errno )
+ {
+ case EBADF : return STC__INVSOCK;
+ case EINVAL : return STC__INVTIME;
+ default : return STC__FAILURE;
+ } /* switch( errno ) */
+
+ case 0: return STC__TIMEOUT;
+
+ } /* end switch( sts ) */
+
+ if( FD_ISSET(listenfd,&eset)) {
+ return STC__SUCCESS;
+ }
+
+ if( FD_ISSET(listenfd,&rset)) {
+ return STC__SUCCESS;
+ }
+
+ if( FD_ISSET(listenfd,&wset)) {
+ return STC__SUCCESS;
+ }
+
+ return STC__FAILURE;
+}
+
+
+/* %%+HEAD: */
+/*****************+***********+****************************************/
+/* */
+/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
+/* Postfach 11 05 41 */
+/* D-6100 Darmstadt 11 */
+/* */
+/*1+ PLI Main ****************+****************************************/
+/* */
+/*+ Module : f_stc_disperror */
+/* */
+/*--------------------------------------------------------------------*/
+/*+ CALLING : f_stc_disperror( INTS4 i_error , CHARS c_string[256], */
+/* INTS4 i_out ) */
+/*--------------------------------------------------------------------*/
+/* */
+/*+ PURPOSE : f_stc_disperror displays the error message for the */
+/* error id ( i_error ) */
+/* if i_out = 1 the error message is */
+/* copied into c_string, else */
+/* f_stc_disperror() print the message */
+/* on the terminal. */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ I_ERROR : The error id. */
+/* */
+/*+ C_STRING : The string into f_stc_disperror() copies the */
+/* message. */
+/* */
+/*+ I_OUT : specifies the output device for the error message. */
+/* */
+/*- I_OUT = 1 : the error message is copied into */
+/* the string. */
+/*- I_OUT = 0 : the error message is printed on */
+/* the terminal. */
+/* */
+/*+ Return type : integer. */
+/* */
+/*2+DESCRIPTION***+***********+****************************************/
+/* */
+/*+ CALLING : f_stc_disperror( INTS4 i_error , CHARS c_string[256], */
+/* INTS4 i_out ) */
+/* */
+/*+ ARGUMENTS : */
+/* */
+/*+ I_ERROR : The error id. */
+/* */
+/*+ C_STRING : The string into f_stc_disperror() copies the */
+/* message. */
+/* */
+/*+ I_OUT : specifies the output device for the error message. */
+/* */
+/*- I_OUT = 1 : the error message is copied into the */
+/* string. */
+/*- I_OUT = 0 : the error message is printed on the */
+/* terminal. */
+/* */
+/*+ FUNCTION : f_stc_disperror displays the error message for the */
+/* error id ( i_error ) */
+/* if i_out = 1 the error message is */
+/* copied into c_string, else */
+/* f_stc_disperror() print the message */
+/* on the terminal. */
+/* */
+/*+ REMARKS : - */
+/* */
+/*2+IMPLEMENTATION************+****************************************/
+/* */
+/*+ Input/Output: SYS$INPUT, SYS$OUTPUT */
+/*+ Return type : INTEGER */
+/*+ Status codes: */
+/*- STC__SUCCESS : success. */
+/*- STC__FAIlURE : failure. */
+/*+ File name : */
+/*+ Version : 1.01 */
+/*+ Author : R.Fritzsche */
+/*+ Last Update : 28-Jan-1994 */
+/* */
+/*2+UPDATES*******+***********+****************************************/
+/* */
+/*+ Updates : Date Purpose */
+/* */
+/*2+INTERNALS*****+***********+****************************************/
+/* */
+/*+ Utility : EXAMPLES */
+/*+ Compile lib.: GOOCINC.TLB */
+/*+ Home direct.: GOO$EXAMPLES */
+/*+ Created : 28-Jan-1994 */
+/* */
+/*1- PLI Main ****************+****************************************/
+/* %%-HEAD: */
+
+INTS4 f_stc_disperror(INTS4 i_error, CHARS *c_dest, INTS4 i_out)
+{
+ CHARS c_line[80];
+
+ switch( i_error )
+ {
+ case STC__FAILURE :
+ sprintf(c_line,"-I- f_stc failure");
+ break;
+ case STC__SUCCESS :
+ sprintf(c_line,"-I- f_stc failure");
+ break;
+ case STC__INVSOCK :
+ sprintf(c_line,"-I- f_stc invalid socket number");
+ break;
+ case STC__INVBUF :
+ sprintf(c_line,"-I- f_stc buffer points outside allocated address space");
+ break;
+ case STC__NGBUFSIZE :
+ sprintf(c_line,"-I- f_stc buffer length is negative");
+ break;
+ case STC__INVTIME :
+ sprintf(c_line,"-I- f_stc time limit is negativ or to long");
+ break;
+ case STC__TIMEOUT :
+ sprintf(c_line,"-I- f_stc timeout read data from socket");
+ break;
+ case STC__NOTSOCK :
+ sprintf(c_line,"-I- f_stc socket number points to a file not a socket");
+ break;
+ case STC__INVADDR :
+ sprintf(c_line,"-I- f_stc invalid address specified in parameter");
+ break;
+ case STC__INVADDRF :
+ sprintf(c_line,"-I- f_stc the specified address family is not supported");
+ break;
+ case STC__SOCKNSUP :
+ sprintf(c_line,"-I- f_stc The specified socket type is not supported.");
+ break;
+ case STC__INVPROTO :
+ sprintf(c_line,"-I- f_stc The specified protocol is not supported.");
+ break;
+ case STC__SOCKTABF :
+ sprintf(c_line,"-I- f_stc The per-process descriptor table is full.");
+ break;
+ case STC__SOCKSPAF :
+ sprintf(c_line,"-I- f_stc No buffer space is available. The socket can't be created");
+ break;
+ case STC__SOCKISC :
+ sprintf(c_line,"-I- f_stc socket is already connected.");
+ break;
+ case STC__CONNTOUT :
+ sprintf(c_line,"-I- f_stc connection timed out without establishing a connection.");
+ break;
+ case STC__NETUNREA :
+ sprintf(c_line,"-I- f_stc The network is not reachable from this host.");
+ break;
+ case STC__PORTINUS :
+ sprintf(c_line,"-I- f_stc The specified Internet Address and port is already in use.");
+ break;
+ case STC__SOCKISP :
+ sprintf(c_line,"-I- f_stc socket address is protected.");
+ break;
+ case STC__ECONNREF : /* added 17.7.95, H.G. */
+ sprintf(c_line,"-I- f_stc connection refused.");
+ break;
+ case TPS__ECPORTS :
+ sprintf(c_line,"-I- f_stc error connect portserver");
+ break;
+ case TPS__EREGSERV :
+ sprintf(c_line,"-I- f_stc error register service at portserver");
+ break;
+ case TPS__EWTOPORTS :
+ sprintf(c_line,"-I- f_stc error write buffer to portserver");
+ break;
+ case TPS__ERMFRPORTS :
+ sprintf(c_line,"-I- f_stc error read status message from portserver");
+ break;
+ case TPS__EGSERVICE :
+ sprintf(c_line,"-I- f_stc error get spec. info from portserver");
+ break;
+ default:
+ sprintf(c_line,"-I- f_stc unknown message id %d",i_error);
+ if(i_out == 0) printf("%s\n",c_line);
+ if(i_out == 1) strcpy(c_dest,c_line);
+ return STC__FAILURE;
+ } /* end switch( i_error ) */
+
+ if(i_out==0) printf("%s\n",c_line);
+ if(i_out==1) strcpy(c_dest,c_line);
+
+ return STC__SUCCESS;
+} /* f_stc_disperror() */
diff --git a/plugins/olmd/mbsapibase/f_stccomm.h b/plugins/olmd/mbsapibase/f_stccomm.h
new file mode 100644
index 00000000..25235571
--- /dev/null
+++ b/plugins/olmd/mbsapibase/f_stccomm.h
@@ -0,0 +1,416 @@
+// $Id$
+//-----------------------------------------------------------------------
+// The GSI Online Offline Object Oriented (Go4) Project
+// Experiment Data Processing at EE department, GSI
+//-----------------------------------------------------------------------
+// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+// Planckstr. 1, 64291 Darmstadt, Germany
+// Contact: http://go4.gsi.de
+//-----------------------------------------------------------------------
+// This software can be used under the license agreements as stated
+// in Go4License.txt file which is part of the distribution.
+//-----------------------------------------------------------------------
+
+/*************************************************************************/
+/* F_STCCOMM.H */
+/* 18.7.95, H.G.: add message no. STC__ECONNREF */
+/*************************************************************************/
+
+#ifndef F_STCCOMM_H
+#define F_STCCOMM_H
+
+#include "typedefs.h" /* typedef INTS1, INTS2, ... */
+
+#ifdef GSI__WINNT
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define bzero(a,n) memset(a,0,n)
+
+#endif
+/* **************** WINDOWS_NT ********************************/
+
+
+#ifdef VMS
+INTS4 SYS$TRNLNM();
+#endif
+
+#ifdef _HPUX_SOURCE
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#ifdef VMS
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+/*
+ * The maximum number of file descriptors is now a configurable option
+ * (max_nofile variable in /sys/conf/{mips|vax}/param.c).
+ * The getdtablesize(2) system call should be used to obtain the
+ * current limit. The value returned by getdtablesize() must be greater
+ * than 64, and less than or equal to MAX_NOFILE in types.h . The
+ * MAX_NOFILE define is needed for backward compatability with broken
+ * programs that need a static sized array for selecting. These programs
+ * should be modified to use the getdtablesize() interface for sizing.
+ */
+#define MAX_NOFILE 4096 /* This should not exist ! */
+#define NBBY 8 /* number of bits in a byte */
+/*
+ * Select uses bit masks of file descriptors in longs.
+ * These macros manipulate such bit fields (the filesystem macros use chars).
+ * FD_SETSIZE may be defined by the user, but the default here
+ * should be >= NOFILE (param.h).
+ */
+#ifndef FD_SETSIZE
+#define FD_SETSIZE MAX_NOFILE
+#endif /* FD_SETSIZE */
+
+/* How many things we'll allow select to use. 0 if unlimited */
+
+#define MAXSELFD MAX_NOFILE
+/*typedef INTS4 fd_mask;*/
+#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask (power of 2!)*/
+#define NFDSHIFT 5 /* Shift based on above */
+#ifndef howmany
+#define howmany(x, y) (((x)+((y)-1))/(y))
+#endif /* howmany */
+
+#define bzero(a,n) memset(a,0,n)
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) bzero((INTS1 *)(p), sizeof(*(p)))
+
+#endif /* VMS */
+
+#ifdef OSK
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct timeval {
+ INTS4 tv_sec;
+ INTS4 tv_usec;
+};
+
+#endif /* OSK */
+
+#ifdef ultrix
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#ifdef Lynx
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#ifdef GSI__LINUX
+#undef unix
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#ifdef GSI__SOLARIS
+#undef unix
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include