ybos.c

Go to the documentation of this file.
00001 /*  Copyright (c) 1993      TRIUMF Data Acquistion Group
00002  *  Please leave this header in any reproduction of that distribution
00003  *
00004  *  TRIUMF Data Acquisition Group, 4004 Wesbrook Mall, Vancouver, B.C. V6T 2A3
00005  *  Email: online@triumf.ca         Tel: (604) 222-1047    Fax: (604) 222-1074
00006  *         amaudruz@triumf.ca                            Local:           6234
00007  * ---------------------------------------------------------------------------
00008    $Log: ybos.c,v $
00009    Revision 1.56  2003/10/30 14:17:07  midas
00010    Added 'umask' for FTP connections
00011 
00012    Revision 1.55  2003/10/03 19:00:45  pierre
00013    fix event display format
00014 
00015    Revision 1.54  2003/06/12 19:19:13  pierre
00016    handle TID_STRUCT bank type (->8bit)
00017 
00018    Revision 1.53  2003/05/17 22:37:48  pierre
00019    ybos large file fix
00020 
00021    Revision 1.52  2003/04/23 23:09:30  pierre
00022    Fixed compiler warning
00023 
00024    Revision 1.51  2003/04/17 16:53:35  pierre
00025    fix tape return code for WINNT
00026 
00027    Revision 1.50  2003/04/16 05:45:21  pierre
00028    fix EOD return , add -DLARGEFILE64_SOURCE support
00029 
00030    Revision 1.49  2003/04/15 22:24:56  pierre
00031    fix for compilation with -Wall
00032 
00033    Revision 1.48  2003/04/11 18:56:47  pierre
00034    Made file compile under VC++ 5.0
00035 
00036    Revision 1.47  2003/04/10 15:51:18  pierre
00037    remove bk_find
00038 
00039    Revision 1.46  2003/04/10 15:45:45  pierre
00040    Made file compile under C++
00041 
00042    Revision 1.45  2002/09/18 16:37:55  pierre
00043    remove bk_list()
00044 
00045    Revision 1.44  2002/08/29 22:12:16  pierre
00046    WORD casting for evt display
00047 
00048    Revision 1.43  2002/08/02 19:42:30  pierre
00049    ifdef vxWorks all the logger & mdump functions
00050 
00051    Revision 1.42  2002/07/14 00:19:59  pierre
00052    add DSP_UNK, fix YB_DONE
00053 
00054    Revision 1.41  2002/07/12 19:31:41  pierre
00055    deallocation error in yb_any_file_rclose
00056 
00057    Revision 1.40  2002/06/10 22:51:27  pierre
00058    fix undefined types
00059 
00060    Revision 1.39  2002/06/08 06:05:22  pierre
00061    improve mdump display format
00062 
00063    Revision 1.38  2002/05/28 17:34:19  pierre
00064    Fix bug for large events (bigger than 8192 bytes), Renee Poutissou
00065 
00066    Revision 1.37  2002/05/08 19:54:41  midas
00067    Added extra parameter to function db_get_value()
00068 
00069    Revision 1.36  2002/03/05 01:17:24  pierre
00070    Add default case, TID_SBYTE
00071 
00072    Revision 1.35  2002/03/05 01:04:37  pierre
00073    add TID_SHORT for display
00074 
00075    Revision 1.34  2001/12/12 17:52:19  pierre
00076    1.8.3-2 doc++
00077 
00078    Revision 1.33  2001/11/09 20:28:16  pierre
00079    Fix replay for YBOS format
00080 
00081    Revision 1.32  2001/09/14 17:04:57  pierre
00082    fix gzread for Midas fmt
00083 
00084    Revision 1.31  2001/07/20 20:38:26  pierre
00085    -Make ybk_close_... return bank size in bytes
00086    -Fix replay (mdump) when file size less than 32K (fmt=midas)
00087 
00088    Revision 1.30  2001/04/30 19:58:03  pierre
00089    - fix ybk_iterate for return -1 instead of 0 (empty bank possible)
00090 
00091    Revision 1.29  2000/09/28 13:11:21  midas
00092    Fixed compiler warning
00093 
00094    Revision 1.28  2000/07/21 18:27:32  pierre
00095    - Include YBOS version >4.0 support by default, otherwise use in Makefile
00096      -DYBOS_VERSION_3_3 for MIDAS_PREF_FLAGS
00097 
00098    Revision 1.27  2000/05/04 14:50:12  midas
00099    Return yb_tid_size[] via new function ybos_get_tid_size()
00100 
00101    Revision 1.26  2000/04/26 19:10:25  pierre
00102    -Moved first round of doc++ comments from ybos.h to here
00103 
00104    Revision 1.25  2000/02/25 18:53:48  pierre
00105    - fix typo in function name dm_()
00106 
00107    Revision 1.24  2000/01/25 18:57:07  pierre
00108    - fix midas replay end of file
00109 
00110    Revision 1.23  1999/12/20 22:15:53  pierre
00111    - remove #define INCLUDE_FTP due to VxWorks (moved into Makefile)
00112 
00113    Revision 1.22  1999/12/17 19:49:01  pierre
00114    - fix return event length in ybos_event_get
00115 
00116    Revision 1.21  1999/12/13 23:26:40  pierre
00117    - Active FTP for YBOS format (yb_any_file_wopen)
00118    - Remove printf dbg in ybos_write()
00119 
00120    Revision 1.20  1999/09/30 22:56:46  pierre
00121    - Change TID_DOUBLE, D8_BKTYPE display format
00122    - fix return yb_any_swap
00123 
00124    Revision 1.19  1999/09/29 20:41:21  pierre
00125    - several fixes for bk32, added TID_DOUBLE display.
00126 
00127    Revision 1.18  1999/09/24 00:13:43  pierre
00128    - include bk32 option
00129    - Fix some pointers
00130 
00131    Revision 1.17  1999/07/24 00:41:54  pierre
00132    - Fix midas_physrec_get(void **prec, ...) for lazylogger
00133 
00134    Revision 1.16  1999/07/23 07:04:54  midas
00135    Fixed compiler warnings
00136 
00137    Revision 1.15  1999/07/22 19:06:07  pierre
00138    - Added D8_BKTYPE for Ybos
00139    - Fix long event for MIDAS
00140    - Allow FIXED event display in raw format
00141 
00142    Revision 1.14  1999/06/23 09:43:02  midas
00143    Added ftp functionality (for lazylogger)
00144 
00145    Revision 1.13  1999/02/11 13:18:58  midas
00146    Fixed bug in opening disk file under NT
00147 
00148    Revision 1.12  1999/01/22 09:29:51  midas
00149    Fixed typo with braces
00150 
00151    Revision 1.11  1999/01/20 08:39:19  midas
00152    Fixed even more compiler warnings
00153 
00154    Revision 1.10  1999/01/19 19:58:06  pierre
00155    - Fix several compiler warnings
00156 
00157    Revision 1.9  1999/01/18 17:42:59  pierre
00158    - Added lost cvs log flag
00159 
00160  *
00161  *  Description : ybos.c : contains support for the YBOS structure.
00162  *              : YBOS is a 4bytes aligned structure. The FIRST element
00163  *                of a YBOS event is always the LRL (Logical Record Length)
00164  *                This element represent the event size in 4 bytes count!
00165  *            
00166  *                The event structure is the following 
00167  *                        Midas event        Ybos event
00168  *         pheader ->     EVENT_HEADER      EVENT_HEADER      
00169  *         pmbkh   ->     BANK_HEADER           LRL             <- plrl
00170  *                        BANK              YBOS_BANK_HEADER    <- pybk
00171  *
00172  *                pevent is used for yb_any_....() pointing to pheader for MIDAS
00173  *                                                 pointing to plrl    for YBOS
00174  *                All ybk_...() requires plrl as input pointer
00175  *                All  bk_...() requires pmbkh as input pointer
00176  *
00177  *                While replaying data, the EVENT_HEADER has been striped out
00178  *                from the event in the YBOS format. In this case the plrl is the
00179  *                first data of the event. NO MORE EVENT_HEADER is present. In order
00180  *                to provide anyway some evnt info, The FE could produce a EVID bank
00181  *                containing a "copy" of the EVENT_HEADER (see ybos_simfe.c)
00182  *                If the EVID is present in the YBOS event, mdump will try to recover 
00183  *                this info and display it.
00184  *
00185  *                function marked with * are externaly accessible
00186  *
00187  *   Section a)*: bank manipulation.
00188  *                ybk_init
00189  *                ybk_create, ybk_create_chaos
00190  *                ybk_close, ybk_close_chaos
00191  *                ybk_size, ybk_list, ybk_find, ybk_locate, ybk_iterate
00192  *   Section b) : mlogger functions.
00193  *                *ybos_log_open,      *ybos_write,      *ybos_log_close
00194  *                ybos_log_dump,       ybos_buffer_flush 
00195  *                ybos_logfile_close,  ybos_logfile_open, 
00196  *   Section c)   utilities (mdump, lazylogger, etc...)
00197  *                *yb_any_file_ropen,   *yb_any_file_rclose (uses my struct)
00198  *                *yb_any_file_wopen    *yb_any_file_wclose
00199  *                *yb_any_physrec_get:   ybos_physrec_get
00200  *                                       midas_physrec_get
00201  *                yb_any_dev_os_read,  yb_any_dev_os_write
00202  *                *yb_any_log_write
00203  *                *yb_any_physrec_skip:  ybos_physrec_skip
00204  *                *yb_any_physrec_display
00205  *                *yb_any_all_info_display
00206  *                *yb_any_event_swap:    ybos_event_swap
00207  *                *yb_any_event_get:     ybos_event_get
00208  *                                       midas_event_get
00209  *                *yb_any_event_display: yb_any_raw_event_display
00210  *                                       yb_any_bank_event_display
00211  *                *yb_any_bank_display:  yb_any_raw_bank_display
00212  *                                       ybos_bank_display
00213  *                                       midas_bank_display
00214  *   Section d)   File fragmentation and recovery
00215  *                *feodb_file_dump:    yb_file_fragment
00216  *                *yb_file_recompose : yb_ymfile_open
00217  *                                     yb_ymfile_update
00218  *
00219  *                gz not tested
00220  *                ftp channel not tested
00221  *
00222 
00223  *          online replay MIDAS YBOS NT UNIX TAPE DISK FTP largeEVT frag/recomp
00224  *                
00225  */
00226 
00227 /**dox***************************************************************/
00228 /** @file ybos.c
00229 The YBOS file
00230 */
00231 
00232 /**dox***************************************************************/
00233 /** @defgroup ybosbankc YBOS Bank Functions (ybk_xxx)
00234  */
00235 
00236 /**dox***************************************************************/
00237 /** @addtogroup ybosincludecode
00238  *  
00239  *  @{  */
00240 
00241 /**dox***************************************************************/
00242 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00243 
00244 
00245 /* include files */
00246 /* moved #define INCLUDE_FTPLIB into makefile (!vxWorks) */
00247 
00248 #define TRACE
00249 #include "midas.h"
00250 #include "msystem.h"
00251 
00252 #ifdef INCLUDE_FTPLIB
00253 #include "ftplib.h"
00254 #endif
00255 
00256 #ifdef INCLUDE_ZLIB
00257 #include "zlib.h"
00258 #endif
00259 
00260 #define INCLUDE_LOGGING
00261 #include "ybos.h"
00262 
00263 INT yb_tid_size[] = {
00264   0,                            /* 0 not defined */
00265   2,                            /* 1 integer *2 */
00266   1,                            /* 2 ASCII bytes */
00267   4,                            /* 3 Integer *4 */
00268   4,                            /* 4 float *4 */
00269   8,                            /* 5 double */
00270   0,                            /* 6 undefined */
00271   0,                            /* 7 undefined */
00272   1,                            /* 8 logical*1 */
00273 };
00274 
00275 /*---- Hidden prototypes ---------------------------------------------------*/
00276 /* File fragmentation and recovery */
00277 INT yb_any_dev_os_read(INT handle, INT type, void *prec, DWORD nbytes,
00278                        DWORD * nread);
00279 INT yb_any_dev_os_write(INT handle, INT type, void *prec, DWORD nbytes,
00280                         DWORD * written);
00281 INT yb_ymfile_update(int slot, int fmt, void *pevt);
00282 INT yb_ymfile_open(int *slot, int fmt, void *pevt, char *svpath,
00283                    INT file_mode);
00284 INT yb_file_fragment(EQUIPMENT * eqp, EVENT_HEADER * pevent,
00285                      INT run_number, char *path);
00286 
00287 INT midas_event_skip(INT evtn);
00288 INT ybos_physrec_skip(INT bl);
00289 
00290 INT ybos_physrec_get(DWORD ** prec, DWORD * readn);
00291 INT midas_physrec_get(void *prec, DWORD * readn);
00292 
00293 void yb_any_bank_event_display(void *pevent, INT data_fmt, INT dsp_fmt);
00294 void yb_any_raw_event_display(void *pevent, INT data_fmt, INT dsp_fmt);
00295 
00296 void yb_any_raw_bank_display(void *pbank, INT data_fmt, INT dsp_fmt);
00297 void ybos_bank_display(YBOS_BANK_HEADER * pybk, INT dsp_fmt);
00298 void midas_bank_display(BANK * pbk, INT dsp_fmt);
00299 void midas_bank_display32(BANK32 * pbk, INT dsp_fmt);
00300 
00301 INT ybos_event_get(DWORD ** plrl, DWORD * size);
00302 INT midas_event_get(void **pevent, DWORD * size);
00303 INT ybos_event_swap(DWORD * pevt);
00304 
00305 INT ybos_buffer_flush(LOG_CHN * log_chn, INT run_number);
00306 INT ybos_logfile_open(INT type, char *path, HNDLE * handle);
00307 INT ybos_logfile_close(INT type, HNDLE handle);
00308 void ybos_log_dump(LOG_CHN * log_chn, short int event_id, INT run_number);
00309 
00310 /* MAGTA parameters for YBOS disk file
00311    When the disk file has a *BOT record at the BOF then,
00312    VMS can read nicely the file. YBOS package knows how to
00313    deal with this too. The format in I*4 is then:
00314    0x00000004 (record length in bytes)
00315    0x544f422a (the record content "*BOT")
00316    0x7ff8 (record length in bytes)
00317    0x1ffd x 0x00000000 (empty record)
00318    0x7ff8 (record length in bytes)
00319    0x1ffd x user data
00320    0x7ff8 (record length in bytes)
00321    0x1ffd x user data
00322    :
00323    :
00324    */
00325 
00326 #ifdef INCLUDE_FTPLIB
00327 FTP_CON *ftp_con;
00328 #endif
00329 
00330 /* magta stuff */
00331 DWORD *pbot, *pbktop = NULL;
00332 char *ptopmrd;
00333 DWORD magta[3] = { 0x00000004, 0x544f422a, 0x00007ff8 };
00334 
00335 /* For Fragmentation */
00336 R_YM_FILE ymfile[MAX_YM_FILE];
00337 struct stat *filestat;
00338 
00339 #ifdef INCLUDE_ZLIB
00340 gzFile filegz;
00341 #endif
00342 
00343 /* General YBOS/MIDAS struct for util */
00344 struct {
00345   INT handle;                   /* file handle */
00346   char name[MAX_FILE_PATH];     /* Device name (/dev/nrmt0h) */
00347 
00348   char *pmp;                    /* ptr to a physical TAPE_BUFFER_SIZE block */
00349   EVENT_HEADER *pmh;            /* ptr to Midas event (midas bank_header) */
00350   EVENT_HEADER *pme;            /* ptr to Midas content (event+1) (midas bank_header) */
00351   char *pmrd;                   /* current point in the phyical record */
00352 
00353   char *pmagta;                 /* dummy zone for magta stuff */
00354   YBOS_PHYSREC_HEADER *pyh;     /* ptr to ybos physical block header */
00355   DWORD *pylrl;                 /* ptr to ybos logical record */
00356   DWORD *pyrd;                  /* ptr to current loc in physical record */
00357 
00358   DWORD evtn;                   /* current event number */
00359   DWORD serial;                 /* serial event number */
00360   DWORD evtlen;                 /* current event length (-1 if not available) */
00361   DWORD size;                   /* ybos block size or midas max_evt_size */
00362   DWORD recn;                   /* ybos current physical record number */
00363   INT fmt;                      /* contains FORMAT type */
00364   INT type;                     /* Device type (tape, disk, ...) */
00365   DWORD runn;                   /* run number */
00366   BOOL zipfile;
00367   BOOL magtafl;
00368 } my;
00369 
00370 /**dox***************************************************************/
00371 #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
00372 
00373 /**dox***************************************************************/
00374 /** @addtogroup ybosbankc
00375  *  
00376  *  @{  */
00377 
00378 /*--BANK MANIPULATION-----Section a)--------------------------------*/
00379 /*--BANK MANIPULATION-----------------------------------------------*/
00380 /*--BANK MANIPULATION-----------------------------------------------*/
00381 /*--BANK MANIPULATION-----------------------------------------------*/
00382 /*--BANK MANIPULATION-----------------------------------------------*/
00383 /*--BANK MANIPULATION-----------------------------------------------*/
00384 /*------------------------------------------------------------------*/
00385 /*------------------------------------------------------------------*/
00386 /*------------------------------------------------------------------*/
00387 /********************************************************************/
00388 /**
00389 Initializes an event for YBOS banks structure.
00390 
00391 Before banks can be created in an event, ybk_init()
00392 has to be called first.  See @ref YBOS_bank_examples.
00393 @param plrl    pointer to the first DWORD of the event area of event 
00394 @return void
00395 */
00396 void ybk_init(DWORD * plrl)
00397 {
00398   *plrl = 0;
00399   return;
00400 }
00401 
00402 /**dox***************************************************************/
00403 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00404 
00405 static YBOS_BANK_HEADER *__pbkh;
00406 
00407 /**dox***************************************************************/
00408 #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
00409 
00410 /********************************************************************/
00411 /**
00412 Define the following memory area to be a YBOS bank with the
00413 given attribute.  See @ref YBOS_bank_examples.
00414 
00415 Before banks can be created in an event, ybk_init(). 
00416 has to be called first. YBOS does not support mixed bank type. i.e: all the
00417 data are expected to be of the same type. YBOS is a 4 bytes bank aligned structure.
00418 Padding is performed at the closing of the bank (see ybk_close) with values of
00419 0x0f or/and 0x0ffb. See @ref YBOS_bank_examples.
00420 @param plrl   pointer to the first DWORD of the event area.
00421 @param bkname name to be assigned to the breated bank (max 4 char)
00422 @param bktype @ref YBOS_Bank_Types of the values for the entire created bank.
00423 @param pbkdat return pointer to the first empty data location.
00424 @return void
00425 */
00426 void ybk_create(DWORD * plrl, char *bkname, DWORD bktype, void *pbkdat)
00427 {
00428   DWORD dname = 0;
00429   __pbkh =
00430       (YBOS_BANK_HEADER *) (((DWORD *) (plrl + 1)) + (*(DWORD *) plrl));
00431   strncpy((char *) &dname, bkname, 4);
00432   __pbkh->name = *((DWORD *) bkname);
00433   __pbkh->number = 1;
00434   __pbkh->index = 0;
00435   __pbkh->length = 0;
00436   __pbkh->type = bktype;
00437   *((DWORD **) pbkdat) = (DWORD *) (__pbkh + 1);
00438   return;
00439 }
00440 
00441 /**dox***************************************************************/
00442 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00443 
00444 static DWORD *__pchaosi4;
00445 
00446 /********************************************************************/
00447 void ybk_create_chaos(DWORD * plrl, char *bkname, DWORD bktype,
00448                       void *pbkdat)
00449 /********************************************************************\
00450 Routine: ybk_create
00451 Purpose: fills up the bank header,
00452 reserve the first 4bytes for the size of the bank in bt unit
00453 and return the pointer to the user space.
00454 Input:
00455 DWORD * pevt          pointer to the top of the YBOS event (LRL)
00456 char  * bname         Bank name should be char*4
00457 DWORD   bktype            Bank type can by either
00458 I2_BKTYPE, I1_BKTYPE, I4_BKTYPE, F4_BKTYPE
00459 Output:
00460 void    *pbkdat       pointer to first valid data of the created bank
00461 Function value:
00462 none
00463 \********************************************************************/
00464 {
00465   DWORD dname = 0;
00466   __pbkh = (YBOS_BANK_HEADER *) ((plrl + 1) + (*plrl));
00467   strncpy((char *) &dname, bkname, 4);
00468   __pbkh->name = *((DWORD *) bkname);
00469   __pbkh->number = 1;
00470   __pbkh->index = 0;
00471   __pbkh->length = 0;
00472   __pbkh->type = bktype;
00473 
00474   *((DWORD **) pbkdat) = (DWORD *) (__pbkh + 1);
00475   __pchaosi4 = (DWORD *) (*(DWORD *) pbkdat);
00476   *((DWORD **) pbkdat) += 1;
00477   return;
00478 }
00479 
00480 /*------------------------------------------------------------------*/
00481 INT ybk_close_chaos(DWORD * plrl, DWORD bktype, void *pbkdat)
00482 /********************************************************************\
00483 Routine: ybk_close_chaos
00484 Purpose: patch the end of the event to the next 4 byte boundary,
00485 fills up the bank header,
00486 compute the data size in bt unit.
00487 update the LRL (pevt)
00488 Input:
00489 DWORD * pevt          pointer to the top of the YBOS event (LRL).
00490 DWORD   bt            bank type
00491 I2_BKTYPE, I1_BKTYPE, I4_BKTYPE, F4_BKTYPE
00492 void  * pbkdat        pointer to the user area
00493 Output:
00494 none
00495 Function value: Number of bytes in the bank.
00496 \********************************************************************/
00497 {
00498   switch (bktype) {
00499   case D8_BKTYPE:
00500     *__pchaosi4 = (DWORD) ((double *) pbkdat - (double *) __pchaosi4 - 1);
00501     break;
00502   case I4_BKTYPE:
00503   case F4_BKTYPE:
00504     *__pchaosi4 = (DWORD) ((DWORD *) pbkdat - __pchaosi4 - 1);
00505     break;
00506   case I2_BKTYPE:
00507     *__pchaosi4 = (DWORD) ((WORD *) pbkdat - (WORD *) __pchaosi4 - 2);
00508     SWAP_D2WORD(__pchaosi4);
00509     break;
00510   case I1_BKTYPE:
00511   case A1_BKTYPE:
00512     *__pchaosi4 = (DWORD) ((BYTE *) pbkdat - (BYTE *) __pchaosi4 - 4);
00513     break;
00514   default:
00515     printf(" unknown YBOS bank type (%ld)\n", bktype);
00516     break;
00517   }
00518 
00519   return ybk_close(plrl, pbkdat);
00520 }
00521 
00522 /**dox***************************************************************/
00523 #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
00524 
00525 /********************************************************************/
00526 /**
00527 Close the YBOS bank previously created by ybk_create().
00528 
00529 The data pointer pdata must be obtained by ybk_create() and
00530 used as an address to fill a bank. It is incremented with every value written
00531 to the bank and finally points to a location just after the last byte of the
00532 bank. It is then passed to ybk_close() to finish the bank creation. YBOS is a
00533 4 bytes bank aligned structure. Padding is performed at the closing of the bank
00534 with values of 0x0f or/and 0x0ffb. See @ref YBOS_bank_examples.
00535 @param plrl pointer to current composed event.
00536 @param pbkdat  pointer to the current data.
00537 @return number number of bytes contained in bank.
00538 */
00539 INT ybk_close(DWORD * plrl, void *pbkdat)
00540 {
00541   DWORD tdlen;
00542   /* align pbkdat to I*4 */
00543   if (((DWORD) pbkdat & 0x1) != 0) {
00544     *((BYTE *) pbkdat) = 0x0f;
00545     pbkdat = (void *) (((BYTE *) pbkdat) + 1);
00546   }
00547   if (((DWORD) pbkdat & 0x2) != 0) {
00548     *((WORD *) pbkdat) = 0x0ffb;
00549     pbkdat = (void *) (((WORD *) pbkdat) + 1);
00550   }
00551 
00552   /* length in byte */
00553   tdlen =
00554       (DWORD) ((char *) pbkdat - (char *) __pbkh -
00555                sizeof(YBOS_BANK_HEADER));
00556 
00557   /* YBOS bank length in I4 */
00558   __pbkh->length = (tdlen + 4) / 4;     /* (+Bank Type &@#$!) YBOS bank length */
00559 
00560   /* adjust Logical Record Length (entry point from the system) */
00561   *plrl += __pbkh->length + (sizeof(YBOS_BANK_HEADER) / 4) - 1;
00562   return __pbkh->length;
00563 }
00564 
00565 /********************************************************************/
00566 /**
00567 Returns the size in bytes of the event composed of YBOS bank(s).
00568 @param plrl pointer to the area of event
00569 @return number of bytes contained in data area of the event 
00570 */
00571 INT ybk_size(DWORD * plrl)
00572 {
00573   return (*((DWORD *) plrl) * 4 + 4);
00574 }
00575 
00576 /********************************************************************/
00577 /**
00578 Returns the size in bytes of the event composed of YBOS bank(s).
00579 
00580 The bk_list() has to be a predefined string of max size of
00581 YB_STRING_BANKLIST_MAX.
00582 @param plrl pointer to the area of event
00583 @param bklist Filled character string of the YBOS bank names found in the event.
00584 @return number of banks found in this event.
00585 */
00586 INT ybk_list(DWORD * plrl, char *bklist)
00587 {
00588 
00589   YBOS_BANK_HEADER *pbk;
00590   DWORD *pendevt, nbk;
00591 
00592   pbk = (YBOS_BANK_HEADER *) (plrl + 1);
00593 
00594   /* end of event pointer skip LRL, point to YBOS_BANK_HEADER */
00595   pendevt = (DWORD *) pbk + *plrl;
00596 
00597   /* check if bank_type in range */
00598   if (pbk->type >= MAX_BKTYPE)
00599     return (YB_WRONG_BANK_TYPE);
00600 
00601   /*init bank counter and returned string */
00602   nbk = 0;
00603   bklist[0] = 0;
00604 
00605   /* scan event */
00606   while ((DWORD *) pbk < pendevt) {
00607     /* update the number of bank counter */
00608     nbk++;
00609 
00610     if (nbk > YB_BANKLIST_MAX) {
00611       cm_msg(MINFO, "ybk_list", "over %i banks -> truncated",
00612              YB_BANKLIST_MAX);
00613       return (nbk);
00614     }
00615 
00616     /* append ybos bank name to list */
00617     strncat(bklist, (char *) &(pbk->name), 4);
00618 
00619     /* skip to next bank */
00620     pbk = (YBOS_BANK_HEADER *) (((DWORD *) pbk) + pbk->length + 4);
00621   }
00622   return (nbk);
00623 }
00624 
00625 /********************************************************************/
00626 /**
00627 Find the requested bank and return the infirmation if the bank as well
00628 as the pointer to the top of the data section.
00629 @param plrl     pointer to the area of event.
00630 @param bkname   name of the bank to be located.
00631 @param bklen    returned length in 4bytes unit of the bank.
00632 @param bktype   returned bank type.
00633 @param pbk      pointer to the first data of the found bank.
00634 @return  YB_SUCCESS, YB_BANK_NOT_FOUND, YB_WRONG_BANK_TYPE
00635 */
00636 INT ybk_find(DWORD * plrl, char *bkname, DWORD * bklen, DWORD * bktype,
00637              void **pbk)
00638 {
00639   YBOS_BANK_HEADER *pevt;
00640   DWORD *pendevt;
00641 
00642   pevt = (YBOS_BANK_HEADER *) (plrl + 1);
00643 
00644   /* end of event pointer skip LRL, point to YBOS_BANK_HEADER */
00645   pendevt = (DWORD *) pevt + *plrl;
00646 
00647   /* check if bank_type in range */
00648   if (pevt->type >= MAX_BKTYPE)
00649     return (YB_WRONG_BANK_TYPE);
00650 
00651   /* init returned variables */
00652   *bklen = 0;
00653   *bktype = 0;
00654 
00655   /* scan event */
00656   while ((DWORD *) pevt < pendevt) {
00657     /* check bank name */
00658     if (strncmp((char *) &(pevt->name), bkname, 4) == 0) {      /* bank name match */
00659       /* extract bank length */
00660       *bklen = pevt->length - 1;        /* exclude bank type */
00661 
00662       /* extract bank type */
00663       *bktype = pevt->type;
00664 
00665       /* return point to bank name */
00666       *pbk = &pevt->name;
00667       return (YB_SUCCESS);
00668     } else {
00669       /* skip to next bank */
00670       pevt = (YBOS_BANK_HEADER *) (((DWORD *) pevt) + pevt->length + 4);
00671     }
00672   }
00673   return (YB_BANK_NOT_FOUND);
00674 }
00675 
00676 /********************************************************************/
00677 /**
00678 Locate the requested bank and return the pointer to the top of the data section.
00679 @param plrl pointer to the area of event
00680 @param bkname name of the bank to be located.
00681 @param pdata pointer to the first data of the located bank.
00682 @return  Number of DWORD in bank or YB_BANK_NOT_FOUND, YB_WRONG_BANK_TYPE (<0)
00683 */
00684 INT ybk_locate(DWORD * plrl, char *bkname, void *pdata)
00685 {
00686   YBOS_BANK_HEADER *pybk;
00687   DWORD *pendevt;
00688 
00689   pybk = (YBOS_BANK_HEADER *) (plrl + 1);
00690 
00691   /* end of event pointer skip LRL, point to YBOS_BANK_HEADER */
00692   pendevt = (DWORD *) pybk + *plrl;
00693 
00694   /* check if bank_type in range */
00695   if (pybk->type >= MAX_BKTYPE)
00696     return (YB_WRONG_BANK_TYPE);
00697 
00698   /* scan event */
00699   while ((DWORD *) pybk < pendevt) {
00700     /* check bank name */
00701     if (strncmp((char *) &(pybk->name), bkname, 4) == 0) {      /* bank name match */
00702       /* extract bank length */
00703 
00704       /* return pointer to data section */
00705       *((void **) pdata) = pybk + 1;
00706       return (pybk->length - 1);
00707     } else {
00708       /* skip to next bank */
00709       pybk = (YBOS_BANK_HEADER *) (((DWORD *) pybk) + pybk->length + 4);
00710     }
00711   }
00712   return (YB_BANK_NOT_FOUND);
00713 }
00714 
00715 /********************************************************************/
00716 /**
00717 Returns the bank header pointer and data pointer of the given bank name.
00718 @param   plrl pointer to the area of event.
00719 @param   pybkh pointer to the YBOS bank header.
00720 @param   pdata pointer to the first data of the current bank.
00721 @return  data length in 4 bytes unit. return -1 if no more bank found.
00722 */
00723 INT ybk_iterate(DWORD * plrl, YBOS_BANK_HEADER ** pybkh, void **pdata)
00724 {
00725   static int len;
00726   static DWORD *pendevt;
00727   static DWORD *pybk;
00728   /*PAA char bname[5]; */
00729 
00730   /* the event may have several bank
00731      check if we have been already in here */
00732   if (*pybkh == NULL) {
00733     /* first time in (skip lrl) */
00734     *pybkh = (YBOS_BANK_HEADER *) (plrl + 1);
00735 
00736     if ((*pybkh)->type > I1_BKTYPE) {
00737       *pdata = NULL;
00738       *pybkh = (YBOS_BANK_HEADER *) * pdata;
00739       return (YB_WRONG_BANK_TYPE);
00740     }
00741 
00742     /* end of event pointer (+ lrl) */
00743     pendevt = plrl + *plrl;
00744 
00745     /* skip the EVID bank if present */
00746     /*-PAA- keep it in for a little while Dec 17/98
00747     *((DWORD *)bname) = (*pybkh)->name;
00748     if (strncmp (bname,"EVID",4) == 0)
00749     {
00750     len = (*pybkh)->length;
00751     (YBOS_BANK_HEADER *)(*pybkh)++;
00752     pybk = (DWORD *) *pybkh;
00753     pybk += len - 1;
00754     *pybkh = (YBOS_BANK_HEADER *) pybk;
00755     }
00756     */
00757   } else {
00758     /* already been in iterate */
00759     /* skip current pointed bank ( + bank_length + header) */
00760     len = (*pybkh)->length;
00761     (YBOS_BANK_HEADER *) (*pybkh)++;
00762     pybk = (DWORD *) * pybkh;
00763     pybk += len - 1;
00764     *pybkh = (YBOS_BANK_HEADER *) pybk;
00765   }
00766 
00767   /* check for end of event */
00768   if ((DWORD *) (*pybkh) < pendevt) {
00769     /* points to the data section */
00770     *pdata = (void *) (*pybkh + 1);
00771 
00772     /* length always in I*4 due to YBOS -1 because type included in length !@# */
00773     return ((*pybkh)->length - 1);
00774   } else {
00775     /* no more bank in this event */
00776     *pdata = NULL;
00777     *pybkh = (YBOS_BANK_HEADER *) * pdata;
00778     return (-1);
00779   }
00780 }
00781 
00782 /**dox***************************************************************/
00783 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00784 
00785 /*-- GENERAL file fragmentation and recovery -----Section d)--------*/
00786 /*-- GENERAL file fragmentation and recovery -----------------------*/
00787 /*-- GENERAL file fragmentation and recovery -----------------------*/
00788 /*-- GENERAL file fragmentation and recovery -----------------------*/
00789 /*------------------------------------------------------------------*/
00790 INT feodb_file_dump(EQUIPMENT * eqp, char *eqpname,
00791                     char *pevent, INT run_number, char *path)
00792 /********************************************************************\
00793 Routine: feodb_file_dump
00794 Purpose: Access ODB for the /Equipment/<equip_name>/Dump.
00795 in order to scan for file name and dump the files content to the
00796 Midas buffer channel.
00797 Input:
00798 EQUIPMENT * eqp           Current equipment
00799 INT       run_number      current run_number
00800 char      * path          full file name specification
00801 Output:
00802 none
00803 Function value:
00804 0                      Successful completion
00805 DB_INVALID_NAME        Equipment doesn't match request
00806 \********************************************************************/
00807 {
00808   EQUIPMENT *peqp;
00809   INT index, size, status;
00810   HNDLE hDB, hKey, hKeydump;
00811   char strpath[MAX_FILE_PATH], Dumpfile[MAX_FILE_PATH];
00812   char odb_entry[MAX_FILE_PATH];
00813   BOOL eqpfound = FALSE;
00814 
00815   cm_get_experiment_database(&hDB, &hKey);
00816   peqp = eqp;
00817 
00818   /* find the equipment info for this job */
00819   while (*(peqp->name) != 0) {
00820     if (equal_ustring((peqp->name), eqpname)) {
00821       eqpfound = TRUE;
00822       break;
00823     }
00824     peqp++;
00825   }
00826   if (!eqpfound)
00827     return DB_INVALID_NAME;
00828 
00829   /* loop over all channels */
00830   sprintf(odb_entry, "/Equipment/%s/Dump", path);
00831   status = db_find_key(hDB, 0, odb_entry, &hKey);
00832   if (status != DB_SUCCESS) {
00833     cm_msg(MINFO, "ybos_odb_file_dump", "odb_access_file -I- %s not found",
00834            odb_entry);
00835     return YB_SUCCESS;
00836   }
00837   index = 0;
00838   while ((status =
00839           db_enum_key(hDB, hKey, index,
00840                       &hKeydump)) != DB_NO_MORE_SUBKEYS) {
00841     if (status == DB_SUCCESS) {
00842       size = sizeof(strpath);
00843       db_get_path(hDB, hKeydump, strpath, size);
00844       db_get_value(hDB, 0, strpath, Dumpfile, &size, TID_STRING, TRUE);
00845       yb_file_fragment(peqp, (EVENT_HEADER *) pevent, run_number,
00846                        Dumpfile);
00847     }
00848     index++;
00849   }
00850   return (YB_SUCCESS);
00851 }
00852 
00853 /*------------------------------------------------------------------*/
00854 INT yb_file_fragment(EQUIPMENT * eqp, EVENT_HEADER * pevent,
00855                      INT run_number, char *path)
00856 /********************************************************************\
00857 Routine: yb_file_fragment
00858 Purpose: Fragment file in order to send it through Midas.
00859 Compose an event of the form of:
00860 Midas_header[(YM_CFILE)(YM_PFILE)(YM_DFILE)]
00861 Specific for the fe for either format YBOS/MIDAS
00862 Input:
00863 EQUIPMENT * eqp        Current equipment
00864 INT   run_number       currrent run_number
00865 char * path            full file name specification
00866 Output:
00867 none
00868 Function value:
00869 YB_SUCCESS          Successful completion
00870 SS_FILE_ERROR       file access error
00871 \********************************************************************/
00872 {
00873   INT dmpf, remaining;
00874   INT nread, filesize, nfrag;
00875   INT allheader_size;
00876   DWORD *pbuf, *pcfile, *pmy;
00877   YM_CFILE myc_fileh;
00878   YM_PFILE myp_fileh;
00879   int send_sock, flag;
00880 
00881   /* check if file exists */
00882   /* Open for read (will fail if file does not exist) */
00883   if ((dmpf = open(path, O_RDONLY | O_BINARY, 0644)) == -1) {
00884     cm_msg(MINFO, "ybos_file_fragment",
00885            "File dump -Failure- on open file %s", path);
00886     return SS_FILE_ERROR;
00887   }
00888 
00889   /* get file size */
00890   filestat = (struct stat *) malloc(sizeof(struct stat));
00891   stat(path, filestat);
00892   filesize = filestat->st_size;
00893   free(filestat);
00894   cm_msg(MINFO, "ybos_file_fragment", "Accessing File %s (%i)", path,
00895          filesize);
00896 
00897   /*-PAA-Oct06/97 added for ring buffer option */
00898   send_sock = rpc_get_send_sock();
00899 
00900   /* compute fragmentation & initialize */
00901   nfrag = filesize / MAX_FRAG_SIZE;
00902 
00903   /* Generate a unique FILE ID */
00904   srand((unsigned) time(NULL));
00905   srand((unsigned) time(NULL));
00906 
00907   /* Fill file YM_CFILE header */
00908   myc_fileh.file_ID = rand();
00909   myc_fileh.size = filesize;
00910   myc_fileh.total_fragment =
00911       nfrag + (((filesize % MAX_FRAG_SIZE) == 0) ? 0 : 1);
00912   myc_fileh.current_fragment = 0;
00913   myc_fileh.current_read_byte = 0;
00914   myc_fileh.run_number = run_number;
00915   myc_fileh.spare = 0x1234abcd;
00916 
00917   /* Fill file YM_PFILE header */
00918   memset(myp_fileh.path, 0, sizeof(YM_PFILE));
00919   /* first remove path if present */
00920   if (strrchr(path, '/') != NULL) {
00921     strncpy(myp_fileh.path, strrchr(path, '/') + 1,
00922             strlen(strrchr(path, '/')));
00923   } else
00924     strcpy(myp_fileh.path, path);
00925 
00926   /* allocate space */
00927   allheader_size = sizeof(EVENT_HEADER)
00928       + sizeof(YBOS_BANK_HEADER)        /* EVID bank header */
00929       +5 * sizeof(DWORD)        /* EVID data size */
00930       +sizeof(YM_CFILE)
00931       + sizeof(YM_PFILE) + 64;
00932 
00933   flag = 0;
00934   pevent -= 1;
00935 
00936   /* read file */
00937   while (myc_fileh.current_fragment <= nfrag) {
00938     /* pevent passed by fe for first event only */
00939     if (flag)
00940       pevent = dm_pointer_get();
00941     flag = 1;
00942 
00943     /* bank header */
00944     pmy = (DWORD *) (pevent + 1);
00945 
00946     /*-PAA-Oct06/97 for ring buffer reset the LRL */
00947     if (eqp->format == FORMAT_YBOS)
00948       ybk_init((DWORD *) pmy);
00949     else if (eqp->format == FORMAT_MIDAS)
00950       bk_init(pmy);
00951 
00952     /*---- EVID bank ----*/
00953     if (eqp->format == FORMAT_YBOS) {
00954       YBOS_EVID_BANK(pmy, myc_fileh.current_fragment,
00955                      (eqp->info.event_id << 16) | (eqp->info.trigger_mask)
00956                      , eqp->serial_number, run_number);
00957     } else if (eqp->format == FORMAT_MIDAS) {
00958       MIDAS_EVID_BANK(pmy, myc_fileh.current_fragment,
00959                       (eqp->info.event_id << 16) | (eqp->info.trigger_mask)
00960                       , eqp->serial_number, run_number);
00961     }
00962 
00963     /* Create Control file bank */
00964     if (eqp->format == FORMAT_YBOS)
00965       ybk_create(pmy, "CFIL", I4_BKTYPE, (DWORD *) & pbuf);
00966     else if (eqp->format == FORMAT_MIDAS)
00967       bk_create(pmy, "CFIL", TID_DWORD, &pbuf);
00968 
00969     /* save pointer for later */
00970     pcfile = pbuf;
00971     pbuf = (DWORD *) (((char *) pbuf) + sizeof(YM_CFILE));
00972     if (eqp->format == FORMAT_YBOS)
00973       ybk_close(pmy, pbuf);
00974     else if (eqp->format == FORMAT_MIDAS)
00975       bk_close(pmy, pbuf);
00976 
00977     /* Create Path file name bank */
00978     if (eqp->format == FORMAT_YBOS)
00979       ybk_create(pmy, "PFIL", A1_BKTYPE, (DWORD *) & pbuf);
00980     else if (eqp->format == FORMAT_MIDAS)
00981       bk_create(pmy, "PFIL", TID_CHAR, &pbuf);
00982     memcpy((char *) pbuf, (char *) &myp_fileh, sizeof(YM_PFILE));
00983     pbuf = (DWORD *) (((char *) pbuf) + sizeof(YM_CFILE));
00984     if (eqp->format == FORMAT_YBOS)
00985       ybk_close(pmy, pbuf);
00986     else if (eqp->format == FORMAT_MIDAS)
00987       bk_close(pmy, pbuf);
00988 
00989     /* file content */
00990     if (eqp->format == FORMAT_YBOS)
00991       ybk_create(pmy, "DFIL", A1_BKTYPE, (DWORD *) & pbuf);
00992     else if (eqp->format == FORMAT_MIDAS)
00993       bk_create(pmy, "DFIL", TID_CHAR, (DWORD *) & pbuf);
00994     /* compute data length */
00995     remaining = filesize - myc_fileh.current_read_byte;
00996     nread =
00997         read(dmpf, (char *) pbuf,
00998              (remaining > MAX_FRAG_SIZE) ? MAX_FRAG_SIZE : remaining);
00999     /* adjust target pointer */
01000     pbuf = (DWORD *) (((char *) pbuf) + nread);
01001     /* keep track of statistic */
01002     myc_fileh.current_fragment++;
01003     myc_fileh.fragment_size = nread;
01004     myc_fileh.current_read_byte += nread;
01005     memcpy((char *) pcfile, (char *) &myc_fileh, sizeof(YM_CFILE));
01006 
01007     /* close YBOS bank */
01008     if (eqp->format == FORMAT_YBOS)
01009       ybk_close(pmy, pbuf);
01010     else if (eqp->format == FORMAT_MIDAS)
01011       bk_close(pmy, pbuf);
01012 
01013     /* Fill the Midas header */
01014     if (eqp->format == FORMAT_YBOS)
01015       bm_compose_event(pevent, eqp->info.event_id, eqp->info.trigger_mask,
01016                        ybk_size(pmy), eqp->serial_number++);
01017     else if (eqp->format == FORMAT_MIDAS)
01018       bm_compose_event(pevent, eqp->info.event_id, eqp->info.trigger_mask,
01019                        bk_size(pmy), eqp->serial_number++);
01020 
01021     /*-PAA-Oct06/97 Added the ring buffer option for FE event send */
01022     eqp->bytes_sent += pevent->data_size + sizeof(EVENT_HEADER);
01023     eqp->events_sent++;
01024     if (eqp->buffer_handle) {
01025     /*-PAA- Jun98 These events should be sent directly as they come before the run
01026     started. If the event channel has to be used, then care should be taken
01027     if interrupt are being used too. May requires buffer checks like in
01028       scheduler (mfe.c) */
01029       /* #undef USE_EVENT_CHANNEL */
01030 #ifdef USE_EVENT_CHANNEL
01031       dm_pointer_increment(eqp->buffer_handle,
01032                            pevent->data_size + sizeof(EVENT_HEADER));
01033 #else
01034       rpc_flush_event();
01035       bm_send_event(eqp->buffer_handle, pevent,
01036                     pevent->data_size + sizeof(EVENT_HEADER), SYNC);
01037 #endif
01038       eqp->odb_out++;
01039     }
01040   }
01041   /* close file */
01042   if (close(dmpf)) {
01043     cm_msg(MERROR, "fe_file_dump", "cannot close file: %s", path);
01044     return SS_FILE_ERROR;
01045   }
01046   return YB_SUCCESS;
01047 }
01048 
01049 /* Used in mfe */
01050 INT ybos_get_tid_size(INT tid)
01051 {
01052   if (tid < 8)
01053     return yb_tid_size[tid];
01054   return 0;
01055 }
01056 
01057 /*
01058 The entrie section below will not be included in the VxWorks built of the
01059 libmidas.a library. All the functions are logger, mdump related and therefore
01060 certaintly of no use under this OS. 
01061 */
01062 #if !defined (OS_VXWORKS)       /* Frontend */
01063 /*---- LOGGER YBOS format routines ----Section b)--------------------------*/
01064 /*---- LOGGER YBOS format routines ----------------------------------------*/
01065 /*---- LOGGER YBOS format routines ----------------------------------------*/
01066 /*---- LOGGER YBOS format routines ----------------------------------------*/
01067 /*---- LOGGER YBOS format routines ----------------------------------------*/
01068 
01069 INT ybos_log_open(LOG_CHN * log_chn, INT run_number)
01070 /********************************************************************\
01071 Routine: ybos_log_open, Should be used only by mlogger.
01072 Purpose: Open a logger channel in YBOS fmt
01073 Input:
01074 LOG_CHN * log_chn      Concern log channel
01075 INT   run_number       run number
01076 Output:
01077 none
01078 Function value:
01079 error, success
01080 \********************************************************************/
01081 {
01082   YBOS_INFO *ybos;
01083   INT status;
01084 
01085   /* allocate YBOS buffer info */
01086   log_chn->format_info = (void **) malloc(sizeof(YBOS_INFO));
01087 
01088   ybos = (YBOS_INFO *) log_chn->format_info;
01089 
01090   /* reset memory */
01091   memset(ybos, 0, sizeof(YBOS_INFO));
01092 
01093   if (ybos == NULL) {
01094     log_chn->handle = 0;
01095     return SS_NO_MEMORY;
01096   }
01097 
01098   /* allocate full ring buffer for that channel */
01099   if ((ybos->ptop = (DWORD *) malloc(YBOS_BUFFER_SIZE)) == NULL) {
01100     log_chn->handle = 0;
01101     return SS_NO_MEMORY;
01102   }
01103 
01104   memset((char *) ybos->ptop, 0, YBOS_BUFFER_SIZE);
01105   /* Setup YBOS pointers */
01106   ybos->reco = YBOS_HEADER_LENGTH;
01107   ybos->pbuf = ybos->ptop + YBOS_HEADER_LENGTH;
01108   ybos->pwrt = ybos->pbuf;
01109   ybos->pbot = ybos->ptop + YBOS_PHYREC_SIZE;
01110   ybos->pend = ybos->ptop + YBOS_BUFFER_SIZE;
01111   ybos->recn = 0;
01112   /* open logging device */
01113   status =
01114       ybos_logfile_open(log_chn->type, log_chn->path, &log_chn->handle);
01115   if (status != SS_SUCCESS) {
01116     free(ybos->ptop);
01117     free(ybos);
01118     log_chn->handle = 0;
01119     return status;
01120   }
01121 
01122   /* write ODB dump */
01123   if (log_chn->settings.odb_dump)
01124     ybos_log_dump(log_chn, EVENTID_BOR, run_number);
01125 
01126   return SS_SUCCESS;
01127 }
01128 
01129 /*------------------------------------------------------------------*/
01130 INT ybos_logfile_open(INT type, char *path, HNDLE * handle)
01131 /********************************************************************\
01132 Routine: ybos_logfile_open
01133 Purpose: Open a YBOS logging channel for either type (Disk/Tape)
01134 The device open is taken care here. But the writting is done
01135 through yb_any_dev_os_write for ybos magta.
01136 
01137 Input:
01138 INT type       : Disk, Tape
01139 char * path    : Device name
01140 
01141 Output:
01142 HNDLE * handle ; returned handle of the open device
01143 none
01144 Function value:
01145 error, success
01146 \********************************************************************/
01147 {
01148 #ifdef YBOS_VERSION_3_3
01149   INT status;
01150   DWORD written;
01151 #endif
01152 
01153   /* Create device channel */
01154   if (type == LOG_TYPE_TAPE) {
01155     /*-PAA- Should check for the TAPE_BUFFER_SIZE set in ss_tape_open() */
01156     return ss_tape_open(path, O_WRONLY | O_CREAT | O_TRUNC, handle);
01157   } else if (type == LOG_TYPE_DISK) {
01158 #ifdef OS_WINNT
01159     *handle = (int) CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL,
01160                                CREATE_ALWAYS,
01161                                FILE_ATTRIBUTE_NORMAL |
01162                                FILE_FLAG_WRITE_THROUGH |
01163                                FILE_FLAG_SEQUENTIAL_SCAN, 0);
01164 #else
01165 #ifdef _LARGEFILE64_SOURCE
01166     *handle =
01167         open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
01168              0644);
01169 #else
01170     *handle = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
01171 #endif
01172 #endif
01173     if (*handle < 0)
01174       return SS_FILE_ERROR;
01175 #ifdef YBOS_VERSION_3_3
01176     /* specific to YBOS Disk structure */
01177     /* write MAGTA header in bytes 0x4, "*BOT" */
01178     status =
01179         yb_any_dev_os_write(*handle, type, (char *) magta, 8, &written);
01180     if (status != SS_SUCCESS)
01181       return status;
01182 
01183     /* allocate temporary emtpy record */
01184     pbot = realloc(pbot, magta[2] - 4);
01185     memset((char *) pbot, 0, magta[2] - 4);
01186     /* write BOT empty record for MAGTA */
01187     status =
01188         yb_any_dev_os_write(*handle, type, (char *) pbot, magta[2] - 4,
01189                             &written);
01190     if (status != SS_SUCCESS)
01191       return status;
01192 #endif
01193   }
01194   return YB_SUCCESS;
01195 }
01196 
01197 /*------------------------------------------------------------------*/
01198 INT ybos_write(LOG_CHN * log_chn, EVENT_HEADER * pevent, INT evt_size)
01199 /********************************************************************\
01200 Routine: ybos_write
01201 Purpose: Write a YBOS event to the logger channel. Should be used only by 
01202 mlogger.
01203 Takes care of the EVENT_BOR and EVENT_MESSAGE which are 
01204 shiped as YBOS bank in A1_BKTYPE bank. named respectively
01205 MODB, MMSG
01206 Input:
01207 LOG_CHN *      log_chn      Concern log channel
01208 EVENT_HEADER * pevent       event pointer to Midas header
01209 INT            evt_size     event size in bytes seen by Midas
01210 Output:
01211 none
01212 Function value:
01213 error, success
01214 \********************************************************************/
01215 {
01216   short int evid, evmsk;
01217   BOOL large_evt;
01218   INT status, left_over_length, datasize;
01219   YBOS_INFO *ybos;
01220   DWORD *pbkdat;
01221   DWORD bfsize;
01222   YBOS_PHYSREC_HEADER *yb_phrh;
01223 
01224   /* Check the Event ID for :
01225      Midas BOR/EOR which include the ODB dump : 0x8000/0x8001
01226      Msg dump from MUSER flag from odb mainly : 0x8002
01227    */
01228 
01229   evid = pevent->event_id;
01230   evmsk = pevent->trigger_mask;
01231 
01232   /* shortcut to ybos struct */
01233   ybos = (YBOS_INFO *) log_chn->format_info;
01234 
01235   /* detect if event is message oriented (ASCII) */
01236   if ((evid >= EVENTID_BOR) && (evid <= EVENTID_MESSAGE)) {     /* skip ASCII dump if not MUSER */
01237     if (!(evmsk & MT_USER))
01238       return SS_SUCCESS;
01239 
01240     /* skip if MUSER  but not Log message enabled */
01241     if (MT_USER && !log_chn->settings.log_messages)
01242       return SS_SUCCESS;
01243 
01244     /* ASCII event has to be recasted YBOS */
01245     /* Inform if event too long (>32Kbytes) */
01246     if (pevent->data_size > MAX_EVENT_SIZE)
01247       cm_msg(MINFO, "ybos_write", "MMSG or MODB event too large");
01248 
01249     /* align to DWORD boundary in bytes */
01250     datasize = 4 * (pevent->data_size + 3) / 4;
01251 
01252     /* overall buffer size in bytes */
01253     bfsize = datasize + sizeof(YBOS_BANK_HEADER) + 4;   /* +LRL */
01254 
01255     /* allocate space */
01256     pbktop = (DWORD *) malloc(bfsize);
01257     if (pbktop == NULL) {
01258       cm_msg(MERROR, "ybos_write", "malloc error for ASCII dump");
01259       return SS_NO_MEMORY;
01260     }
01261     memset(pbktop, 0, bfsize);
01262     ybk_init(pbktop);
01263 
01264     /* open bank depending on event type */
01265     if (evid == EVENTID_MESSAGE)
01266       ybk_create(pbktop, "MMSG", A1_BKTYPE, &pbkdat);
01267     else
01268       ybk_create(pbktop, "MODB", A1_BKTYPE, &pbkdat);
01269 
01270     memcpy((char *) pbkdat, (char *) (pevent + 1), pevent->data_size);
01271     pbkdat = (DWORD *) (((char *) pbkdat) + datasize);
01272     ybk_close(pbktop, pbkdat);
01273 
01274     /* event size in bytes for Midas */
01275     evt_size = ybk_size(pbktop);
01276 
01277     /* swap bytes if necessary based on the ybos.bank_type */
01278     ybos_event_swap((DWORD *) pbktop);
01279 
01280     /* Event with MIDAS header striped out */
01281     memcpy((char *) ybos->pbuf, (char *) pbktop, evt_size);
01282 
01283     if (pbktop != NULL)
01284       free(pbktop);
01285     pbktop = NULL;
01286     status = SS_SUCCESS;
01287   } else {                      /* normal event */
01288     /* Strip the event from the Midas EVENT_HEADER */
01289     /* event size include the Midas EVENT_HEADER... don't need for ybos
01290        I do this in order to keep the log_write from mlogger intact */
01291 
01292     /* correct the event length. Now it is a pure YBOS event */
01293     pevent++;
01294 
01295     /* correct the event length in bytes */
01296     evt_size -= sizeof(EVENT_HEADER);
01297 
01298     /* swap bytes if necessary based on the ybos.bank_type */
01299     ybos_event_swap((DWORD *) pevent);
01300 
01301     /* I have ALWAYS enough space for the event <MAX_EVENT_SIZE */
01302     memcpy((char *) ybos->pbuf, (char *) pevent, evt_size);
01303 
01304     status = YB_SUCCESS;
01305   }
01306 
01307   /* move write pointer to next free location (DWORD) */
01308   ybos->pbuf += (4 * (evt_size + 3) / 4) >> 2;
01309 
01310   /* default not a large event */
01311   large_evt = FALSE;
01312 
01313   /* Loop over buffer until this condition 
01314      The event offset in the phys rec is ==0 if event larger than PHYREC_SIZE */
01315   while (ybos->pbuf >= ybos->pbot) {
01316     ybos->pwrt -= YBOS_HEADER_LENGTH;
01317     yb_phrh = (YBOS_PHYSREC_HEADER *) (ybos->pwrt);
01318     yb_phrh->rec_size = YBOS_PHYREC_SIZE - 1;   /* exclusive */
01319     yb_phrh->header_length = YBOS_HEADER_LENGTH;
01320     yb_phrh->rec_num = ybos->recn;
01321     yb_phrh->offset = large_evt ? 0 : ybos->reco;
01322 
01323     /* Write physical record to device */
01324     status =
01325         yb_any_log_write(log_chn->handle, log_chn->format, log_chn->type,
01326                          ybos->pwrt, YBOS_PHYREC_SIZE << 2);
01327     if (status != SS_SUCCESS)
01328       return status;
01329 
01330     /* update statistics */
01331 #ifdef YBOS_VERSION_3_3
01332     if (log_chn->type == LOG_TYPE_TAPE) {       /* statistics in bytes */
01333       log_chn->statistics.bytes_written += YBOS_PHYREC_SIZE << 2;
01334       log_chn->statistics.bytes_written_total += YBOS_PHYREC_SIZE << 2;
01335     } else {                    /* statistics in bytes + the extra magta */
01336       log_chn->statistics.bytes_written += YBOS_PHYREC_SIZE << 2 + 4;
01337       log_chn->statistics.bytes_written_total += YBOS_PHYREC_SIZE << 2 + 4;
01338     }
01339 #else
01340     log_chn->statistics.bytes_written += YBOS_PHYREC_SIZE << 2;
01341     log_chn->statistics.bytes_written_total += YBOS_PHYREC_SIZE << 2;
01342 #endif
01343 
01344     /* Update statistics */
01345     ybos->recn++;
01346 
01347     /* check if event is larger than YBOS_PHYREC_SIZE */
01348     if (ybos->pbuf >= ybos->pbot + (YBOS_PHYREC_SIZE - YBOS_HEADER_LENGTH)) {
01349       large_evt = TRUE;
01350       /* shift record window by one YBOS_PHYSREC - header */
01351       ybos->pwrt = ybos->pbot;
01352       ybos->pbot += (YBOS_PHYREC_SIZE - YBOS_HEADER_LENGTH);
01353     } else {
01354       large_evt = FALSE;
01355       /* adjust pointers */
01356       ybos->pwrt = ybos->ptop + YBOS_HEADER_LENGTH;
01357       left_over_length = ybos->pbuf - ybos->pbot;
01358       memcpy(ybos->pwrt, ybos->pbot, left_over_length << 2);    /* in bytes */
01359       ybos->pbuf = ybos->pwrt + left_over_length;
01360       ybos->pbot = ybos->ptop + YBOS_PHYREC_SIZE;
01361       ybos->reco = ybos->pbuf - ybos->pwrt + 4; /* YBOS header */
01362     }
01363   }
01364 
01365   /* update statistics */
01366   log_chn->statistics.events_written++;
01367 
01368   return status;
01369 }
01370 
01371 /*------------------------------------------------------------------*/
01372 INT ybos_buffer_flush(LOG_CHN * log_chn, INT run_number)
01373 /********************************************************************\
01374 Routine: ybos_buffer_flush
01375 Purpose: Empty the internal buffer to logger channel for YBOS fmt
01376 YBOS end of run marks (End of file) is -1 in the *plrl
01377 I'm writting an extra FULL YBOS_PHYSREC_SIZE of -1
01378 Input:
01379 LOG_CHN * log_chn      Concern log channel
01380 Output:
01381 none
01382 Function value:
01383 error, success
01384 \********************************************************************/
01385 {
01386   INT status;
01387   YBOS_INFO *ybos;
01388   YBOS_PHYSREC_HEADER *yb_phrh;
01389 
01390   ybos = (YBOS_INFO *) log_chn->format_info;
01391 
01392   /* dump the ODB if necessary */
01393   if (log_chn->settings.odb_dump)
01394     ybos_log_dump(log_chn, EVENTID_EOR, run_number);
01395 
01396   /* adjust read pointer to beg of record */
01397   ybos->pwrt -= YBOS_HEADER_LENGTH;
01398   yb_phrh = (YBOS_PHYSREC_HEADER *) ybos->pwrt;
01399 
01400   yb_phrh->rec_size = YBOS_PHYREC_SIZE - 1;     /* exclusive */
01401   yb_phrh->header_length = YBOS_HEADER_LENGTH;  /* inclusive */
01402   yb_phrh->rec_num = ybos->recn;
01403   yb_phrh->offset = ybos->reco; /* exclusive from block_size */
01404 
01405 /* YBOS known only about fix record size. The way to find out
01406 it there is no more valid event is to look at the LRL for -1
01407   put some extra -1 in the current physical record */
01408   memset((DWORD *) ybos->pbuf, -1, YBOS_PHYREC_SIZE << 2);
01409 
01410   /* write record to device */
01411   status =
01412       yb_any_log_write(log_chn->handle, log_chn->format, log_chn->type,
01413                        ybos->pwrt, YBOS_PHYREC_SIZE << 2);
01414 #ifdef YBOS_VERSION_3_3
01415   if (log_chn->type == LOG_TYPE_TAPE) {
01416     log_chn->statistics.bytes_written += YBOS_PHYREC_SIZE << 2;
01417     log_chn->statistics.bytes_written_total += YBOS_PHYREC_SIZE << 2;
01418   } else {
01419     /* write MAGTA header (4bytes)=0x7ff8 */
01420     log_chn->statistics.bytes_written += YBOS_PHYREC_SIZE << 2 + 4;
01421     log_chn->statistics.bytes_written_total += YBOS_PHYREC_SIZE << 2 + 4;
01422   }
01423 #else
01424   log_chn->statistics.bytes_written += YBOS_PHYREC_SIZE << 2;
01425   log_chn->statistics.bytes_written_total += YBOS_PHYREC_SIZE << 2;
01426 #endif
01427   return status;
01428 }
01429 
01430 /*------------------------------------------------------------------*/
01431 INT ybos_logfile_close(INT type, HNDLE handle)
01432 /********************************************************************\
01433 Routine: ybos_logfile_close
01434 Purpose: close a logging channel for either type (Disk/Tape)
01435 For the tape I'm writting just a EOF and expect the rewind command to 
01436 write another one if necessary. This way the run restart is faster.
01437 Input:
01438 INT type       : Disk, Tape
01439 HNDLE * handle ; returned handle of the open device
01440 
01441 Output:
01442 none
01443 Function value:
01444 error, success
01445 \********************************************************************/
01446 {
01447   INT status;
01448   /* Write EOF if Tape */
01449   if (type == LOG_TYPE_TAPE) {
01450     /* writing EOF mark on tape only */
01451     status = ss_tape_write_eof(handle);
01452 #ifdef OS_UNIX
01453     if (status != SS_SUCCESS) {
01454       if (errno == EIO)
01455         return SS_IO_ERROR;
01456       if (errno == ENOSPC)
01457         return SS_NO_SPACE;
01458       else
01459         return status;
01460     }
01461 #endif
01462 #ifdef OS_WINNT
01463     if (status != SS_SUCCESS) {
01464       if (errno == ERROR_END_OF_MEDIA)
01465         return SS_NO_SPACE;
01466       else
01467         return status;
01468     }
01469 #endif
01470 
01471     ss_tape_close(handle);
01472   } else if (type == LOG_TYPE_DISK) {
01473 #ifdef OS_WINNT
01474     CloseHandle((HANDLE) handle);
01475 #else
01476     close(handle);
01477 #endif
01478   }
01479   return YB_SUCCESS;
01480 }
01481 
01482 
01483 /*------------------------------------------------------------------*/
01484 INT ybos_log_close(LOG_CHN * log_chn, INT run_number)
01485 /********************************************************************\
01486 Routine: ybos_log_close
01487 Purpose: Close a YBOS logger channel, Should be used only by mlogger.
01488 Input:
01489 LOG_CHN * log_chn      Concern log channel
01490 INT   run_number       run number
01491 Output:
01492 none
01493 Function value:
01494 error, success
01495 \********************************************************************/
01496 {
01497   INT status;
01498   YBOS_INFO *ybos;
01499 
01500   ybos = (YBOS_INFO *) log_chn->format_info;
01501 
01502   /* Write EOF mark and close the device */
01503   /* flush buffer before closing */
01504   status = ybos_buffer_flush(log_chn, run_number);
01505 
01506   if (status != SS_SUCCESS)
01507     return status;
01508 
01509   status = ybos_logfile_close(log_chn->type, log_chn->handle);
01510 
01511   free(ybos->ptop);
01512   free(ybos);
01513 
01514   return SS_SUCCESS;
01515 }
01516 
01517 /*---- ODB   manipulation   ----------------------------------------*/
01518 void ybos_log_dump(LOG_CHN * log_chn, short int event_id, INT run_number)
01519 /********************************************************************\
01520 Routine: ybos_log_dump, used by mlogger, ybos_log_open
01521 Purpose: Serves the logger flag /logger/settings/ODB dump
01522 Extract the ODB in ASCII format and send it to the logger channel
01523 Compose a ybos bank in A1_BKTYPE regardless of the odb size.
01524 It uses ybos_write to compose the actual event. From here it looks
01525 like a MIDAS event.
01526 Input:
01527 LOG_CHN * log_chn      Concern log channel
01528 short in  event_id     event ID
01529 INT   run_number       run number
01530 Output:
01531 none
01532 Function value:
01533 none
01534 \********************************************************************/
01535 {
01536   INT status, buffer_size, size;
01537   EVENT_HEADER *pevent;
01538   HNDLE hDB;
01539 
01540   cm_get_experiment_database(&hDB, NULL);
01541   /* write ODB dump */
01542   buffer_size = 10000;
01543   do {
01544     pevent = (EVENT_HEADER *) malloc(buffer_size);
01545     if (pevent == NULL) {
01546       cm_msg(MERROR, "ybos_odb_log_dump",
01547              "Cannot allocate ODB dump buffer");
01548       break;
01549     }
01550 
01551     size = buffer_size - sizeof(EVENT_HEADER);
01552     status = db_copy(hDB, 0, (char *) (pevent + 1), &size, "");
01553     if (status != DB_TRUNCATED) {
01554       bm_compose_event(pevent, event_id, MIDAS_MAGIC,
01555                        buffer_size - sizeof(EVENT_HEADER) - size + 1,
01556                        run_number);
01557       ybos_write(log_chn, pevent,
01558                  pevent->data_size + sizeof(EVENT_HEADER));
01559       break;
01560     }
01561 
01562     /* increase buffer size if truncated */
01563     free(pevent);
01564     buffer_size *= 2;
01565   } while (1);
01566   free(pevent);
01567 }
01568 
01569 /*-- GENERAL mdump functions for MIDAS / YBOS -----Section c)-------*/
01570 /*-- GENERAL mdump functions for MIDAS / YBOS ----------------------*/
01571 /*-- GENERAL mdump functions for MIDAS / YBOS ----------------------*/
01572 /*-- GENERAL mdump functions for MIDAS / YBOS ----------------------*/
01573 /*-- GENERAL mdump functions for MIDAS / YBOS ----------------------*/
01574 /*------------------------------------------------------------------*/
01575 INT yb_any_file_ropen(char *infile, INT data_fmt)
01576 /********************************************************************\
01577 Routine: external yb_any_file_ropen
01578 Purpose: Open data file for replay for the given data format.
01579 It uses the local "my" structure.
01580 Input:
01581 INT data_fmt :  YBOS or MIDAS 
01582 char * infile : Data file name
01583 Output:
01584 none
01585 Function value:
01586 status : from lower function
01587 \********************************************************************/
01588 {
01589   INT status;
01590 
01591   /* fill up record with file name */
01592   strcpy(my.name, infile);
01593 
01594   /* find out what dev it is ? : check on /dev */
01595   my.zipfile = FALSE;
01596   if ((strncmp(my.name, "/dev", 4) == 0) ||
01597       (strncmp(my.name, "\\\\.\\", 4) == 0)) {
01598     /* tape device */
01599     my.type = LOG_TYPE_TAPE;
01600   } else {
01601     /* disk device */
01602     my.type = LOG_TYPE_DISK;
01603     if (strncmp(infile + strlen(infile) - 3, ".gz", 3) == 0)
01604       my.zipfile = TRUE;
01605   }
01606 
01607   /* open file */
01608   if (!my.zipfile) {
01609     if (my.type == LOG_TYPE_TAPE) {
01610       status = ss_tape_open(my.name, O_RDONLY | O_BINARY, &my.handle);
01611     }
01612 #ifdef _LARGEFILE64_SOURCE
01613     else if ((my.handle =
01614               open(my.name, O_RDONLY | O_BINARY | O_LARGEFILE,
01615                    0644)) == -1)
01616 #else
01617     else if ((my.handle = open(my.name, O_RDONLY | O_BINARY, 0644)) == -1)
01618 #endif
01619     {
01620       printf("dev name :%s Handle:%d \n", my.name, my.handle);
01621       return (SS_FILE_ERROR);
01622     }
01623   } else {
01624 #ifdef INCLUDE_ZLIB
01625     if (my.type == LOG_TYPE_TAPE) {
01626       printf(" Zip on tape not yet supported \n");
01627       return (SS_FILE_ERROR);
01628     }
01629     filegz = gzopen(my.name, "rb");
01630     my.handle = 0;
01631     if (filegz == NULL) {
01632       printf("dev name :%s gzopen error:%d \n", my.name, my.handle);
01633       return (SS_FILE_ERROR);
01634     }
01635 #else
01636     cm_msg(MERROR, "ybos.c",
01637            "Zlib not included ... gz file not supported");
01638     return (SS_FILE_ERROR);
01639 #endif
01640   }
01641 
01642   if (data_fmt == FORMAT_YBOS) {
01643     my.fmt = FORMAT_YBOS;
01644     my.size = YBOS_PHYREC_SIZE; /* in DWORD  */
01645     my.pmagta = (char *) malloc(32);
01646     if (my.pmagta == NULL)
01647       return SS_NO_MEMORY;
01648     my.pyh = (YBOS_PHYSREC_HEADER *) malloc(my.size * 14);
01649     if (my.pyh == NULL)
01650       return SS_NO_MEMORY;
01651     (my.pyh)->rec_size = my.size - 1;
01652     (my.pyh)->header_length = YBOS_HEADER_LENGTH;
01653     (my.pyh)->rec_num = 0;
01654     (my.pyh)->offset = 0;
01655     /* current ptr in the physical record */
01656     my.pyrd = (DWORD *) ((DWORD *) my.pyh + (my.pyh)->offset);
01657 
01658     /* allocate memory for one full event */
01659     my.pylrl = (DWORD *) malloc(MAX_EVENT_SIZE);        /* in bytes */
01660     if (my.pylrl == NULL)
01661       return SS_NO_MEMORY;
01662     memset((char *) my.pylrl, -1, MAX_EVENT_SIZE);
01663 
01664     /* reset first path */
01665     my.magtafl = FALSE;
01666   } else if (data_fmt == FORMAT_MIDAS) {
01667     my.fmt = FORMAT_MIDAS;
01668     my.size = TAPE_BUFFER_SIZE;
01669     my.pmp = (char *) malloc(my.size);
01670     if (my.pmp == NULL)
01671       return SS_NO_MEMORY;
01672     my.pme = (EVENT_HEADER *) my.pmp;
01673 
01674     /* allocate memory for one full event */
01675     if (my.pmrd != NULL)
01676       free(my.pmrd);
01677     my.pmrd = (char *) malloc(5 * MAX_EVENT_SIZE);      /* in bytes */
01678     ptopmrd = my.pmrd;
01679     if (my.pmrd == NULL)
01680       return SS_NO_MEMORY;
01681     memset((char *) my.pmrd, -1, 5 * MAX_EVENT_SIZE);
01682     my.pmh = (EVENT_HEADER *) my.pmrd;
01683   }
01684 
01685   /* initialize pertinent variables */
01686   my.recn = (DWORD) - 1;        /* physical record number */
01687   my.evtn = 0;
01688   return (YB_SUCCESS);
01689 }
01690 
01691 /*------------------------------------------------------------------*/
01692 INT yb_any_file_rclose(INT data_fmt)
01693 /********************************************************************
01694 Routine: external yb_any_file_rclose
01695 Purpose: Close a data file used for replay for the given data format
01696 Input:
01697 INT data_fmt :  YBOS or MIDAS 
01698 Output:
01699 none
01700 Function value:
01701 status : from lower function
01702 *******************************************************************/
01703 {
01704   switch (my.type) {
01705   case LOG_TYPE_TAPE:
01706   case LOG_TYPE_DISK:
01707     /* close file */
01708     if (my.zipfile) {
01709 #ifdef INCLUDE_ZLIB
01710       gzclose(filegz);
01711 #endif
01712     } else {
01713       if (my.handle != 0)
01714         close(my.handle);
01715     }
01716     break;
01717   }
01718   if (my.pmagta != NULL)
01719     free(my.pmagta);
01720   if (my.pyh != NULL)
01721     free(my.pyh);
01722   if (my.pylrl != NULL)
01723     free(my.pylrl);
01724   if (my.pmrd != NULL)
01725     free(my.pmrd);
01726   if (my.pmp != NULL)
01727     free(my.pmp);
01728   my.pylrl = NULL;
01729   my.pyh = NULL;
01730   my.pmagta = NULL;
01731   my.pmp = NULL;
01732   my.pmh = NULL;
01733   my.pmrd = NULL;
01734   return (YB_SUCCESS);
01735 }
01736 
01737 #ifdef INCLUDE_FTPLIB
01738 
01739 /* @ NOT TESTED @ */
01740 INT yb_ftp_open(char *destination, FTP_CON ** con)
01741 {
01742   INT status;
01743   short port = 0;
01744   char *token, host_name[HOST_NAME_LENGTH],
01745       user[32], pass[32], directory[256], file_name[256], file_mode[256];
01746 
01747   /* 
01748      destination should have the form:
01749      host, port, user, password, directory, run%05d.mid
01750    */
01751 
01752   /* break destination in components */
01753   token = strtok(destination, ",");
01754   if (token)
01755     strcpy(host_name, token);
01756 
01757   token = strtok(NULL, ", ");
01758   if (token)
01759     port = atoi(token);
01760 
01761   token = strtok(NULL, ", ");
01762   if (token)
01763     strcpy(user, token);
01764 
01765   token = strtok(NULL, ", ");
01766   if (token)
01767     strcpy(pass, token);
01768 
01769   token = strtok(NULL, ", ");
01770   if (token)
01771     strcpy(directory, token);
01772 
01773   token = strtok(NULL, ", ");
01774   if (token)
01775     strcpy(file_name, token);
01776 
01777   token = strtok(NULL, ", ");
01778   file_mode[0] = 0;
01779   if (token)
01780     strcpy(file_mode, token);
01781 
01782   status = ftp_login(con, host_name, port, user, pass, "");
01783   if (status >= 0)
01784     return status;
01785 
01786   status = ftp_chdir(*con, directory);
01787   if (status >= 0)
01788     return status;
01789 
01790   status = ftp_binary(*con);
01791   if (status >= 0)
01792     return status;
01793 
01794   if (file_mode[0]) {
01795     status = ftp_command(*con, "umask %s", file_mode, 200, 250, EOF);
01796     if (status >= 0)
01797       return status;
01798   }
01799 
01800   if (ftp_open_write(*con, file_name) >= 0)
01801     return (*con)->err_no;
01802 
01803   return SS_SUCCESS;
01804 }
01805 
01806 /* @ NOT TESTED @ */
01807 #endif
01808 
01809 /*------------------------------------------------------------------*/
01810 INT yb_any_file_wopen(INT type, INT data_fmt, char *filename, INT * hDev)
01811 /********************************************************************
01812 Routine: external yb_any_file_wopen
01813 Purpose: Open a data file for the given data format
01814 Input:
01815 INT type     :  Tape or Disk
01816 INT data_fmt :  YBOS or MIDAS
01817 char * filename : file to open
01818 Output:
01819 INT * hDev      : file handle
01820 Function value:
01821 status : from lower function
01822 *******************************************************************/
01823 {
01824   INT status = 0;
01825 
01826   if (type == LOG_TYPE_DISK)
01827     /* takes care of TapeLX/NT under ss_tape_open , DiskLX/NT here */
01828   {
01829     if (data_fmt == FORMAT_YBOS) {
01830       /* takes care of TapeLX/NT under ss_tape_open , DiskLX/NT there */
01831       status = ybos_logfile_open(type, filename, hDev);
01832     } else if (data_fmt == FORMAT_MIDAS) {
01833 #ifdef OS_WINNT
01834       *hDev =
01835           (int) CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
01836                            CREATE_ALWAYS,
01837                            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH
01838                            | FILE_FLAG_SEQUENTIAL_SCAN, 0);
01839 #else
01840       *hDev =
01841           open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
01842 #endif
01843       status = *hDev < 0 ? SS_FILE_ERROR : SS_SUCCESS;
01844     }
01845   } else if (type == LOG_TYPE_TAPE) {
01846     if (data_fmt == FORMAT_YBOS) {
01847       /* takes care of TapeLX/NT under ss_tape_open , DiskLX/NT there */
01848       status = ybos_logfile_open(type, filename, hDev);
01849     } else if (data_fmt == FORMAT_MIDAS)
01850       status = ss_tape_open(filename, O_WRONLY | O_CREAT | O_TRUNC, hDev);
01851   } else if (type == LOG_TYPE_FTP) {
01852 #ifdef INCLUDE_FTPLIB
01853     status = yb_ftp_open(filename, (FTP_CON **) & ftp_con);
01854     if (status != SS_SUCCESS) {
01855       *hDev = 0;
01856       return status;
01857     } else
01858       *hDev = 1;
01859 #else
01860     cm_msg(MERROR, "yb_any_file_wopen", "FTP support not included");
01861     return SS_FILE_ERROR;
01862 #endif
01863   }
01864 
01865   return status;
01866 }
01867 
01868 /*------------------------------------------------------------------*/
01869 INT yb_any_file_wclose(INT handle, INT type, INT data_fmt)
01870 /********************************************************************
01871 Routine: external yb_any_file_wclose
01872 Purpose: Close a data file used for replay for the given data format
01873 Input:
01874 INT data_fmt :  YBOS or MIDAS 
01875 Output:
01876 none
01877 Function value:
01878 status : from lower function
01879 *******************************************************************/
01880 {
01881   INT status;
01882   status = SS_SUCCESS;
01883   switch (type) {
01884   case LOG_TYPE_TAPE:
01885     /* writing EOF mark on tape Fonly */
01886     status = ss_tape_write_eof(handle);
01887     ss_tape_close(handle);
01888     break;
01889   case LOG_TYPE_DISK:
01890     /* close file */
01891     if (handle != 0)
01892 #ifdef OS_WINNT
01893       CloseHandle((HANDLE) handle);
01894 #else
01895       close(handle);
01896 #endif
01897     break;
01898   case LOG_TYPE_FTP:
01899 #ifdef INCLUDE_FTPLIB
01900     ftp_close(ftp_con);
01901     ftp_bye(ftp_con);
01902 #endif
01903     break;
01904   }
01905   if (status != SS_SUCCESS)
01906     return status;
01907   return (YB_SUCCESS);
01908 }
01909 
01910 /*------------------------------------------------------------------*/
01911 INT yb_any_dev_os_read(INT handle, INT type, void *prec, DWORD nbytes,
01912                        DWORD * readn)
01913 /********************************************************************\
01914 Routine: yb_any_dev_os_read
01915 Purpose: read nbytes from the type device.
01916 Input:
01917 INT  handle        file handler
01918 INT  type          Type of device (TAPE or DISK)
01919 void * prec        pointer to the record
01920 DWORD nbytes       # of bytes to read
01921 Output:
01922 DWORD *readn       # of bytes read
01923 Function value:
01924 YB_DONE            No more record to read
01925 YB_SUCCESS         Ok
01926 \********************************************************************/
01927 {
01928   INT status;
01929   if (type == LOG_TYPE_DISK)
01930     /* --------- DISK ---------- */
01931   {
01932     *readn = read(handle, prec, nbytes);
01933     if (*readn <= 0)
01934       status = SS_FILE_ERROR;
01935     else
01936       status = SS_SUCCESS;
01937     return status;
01938   }
01939   /* --------- TAPE ---------- */
01940 #ifdef OS_UNIX
01941   else if (type == LOG_TYPE_TAPE) {
01942     *readn = read(handle, prec, nbytes);
01943     if (*readn <= 0)
01944       status = SS_FILE_ERROR;
01945     else
01946       status = SS_SUCCESS;
01947     return status;
01948   }
01949 #endif
01950 
01951 #ifdef OS_WINNT
01952   else if (type == LOG_TYPE_TAPE) {
01953     if (!ReadFile((HANDLE) handle, prec, nbytes, readn, NULL))
01954       status = GetLastError();
01955     else
01956       status = SS_SUCCESS;
01957     if (status == ERROR_NO_DATA_DETECTED)
01958       status = SS_END_OF_TAPE;
01959 
01960     return status;
01961   }
01962 #endif                          /* OS_WINNT */
01963   else
01964     return SS_SUCCESS;
01965 }
01966 
01967 /*------------------------------------------------------------------*/
01968 INT yb_any_dev_os_write(INT handle, INT type, void *prec, DWORD nbytes,
01969                         DWORD * written)
01970 /********************************************************************\
01971 Routine: yb_any_dev_os_write
01972 Purpose: write nbytes to the device. This function is YBOS independent
01973 (NO magta stuff for disk)
01974 Input:
01975 INT  handle        file handler
01976 INT  type          Type of device (TAPE or DISK)
01977 void * prec        pointer to the record
01978 DWORD   nbytes     record length to be written
01979 Output:
01980 DWORD *written     # of written bytes
01981 Function value:
01982 INT status           # of written bytes or ERROR
01983 SS_FILE_ERROR      write error
01984 SS_SUCCESS         Ok
01985 \********************************************************************/
01986 {
01987   INT status;
01988   if (type == LOG_TYPE_DISK)
01989 #ifdef OS_WINNT
01990   {                             /* --------- DISK ---------- */
01991     WriteFile((HANDLE) handle, (char *) prec, nbytes, written, NULL);
01992     status = *written == nbytes ? SS_SUCCESS : SS_FILE_ERROR;
01993     return status;              /* return for DISK */
01994   }
01995 #else
01996   {                             /* --------- DISK ---------- */
01997     status = *written =
01998         write(handle, (char *) prec,
01999               nbytes) == nbytes ? SS_SUCCESS : SS_FILE_ERROR;
02000     return status;              /* return for DISK */
02001   }
02002 #endif
02003   else if (type == LOG_TYPE_TAPE) {     /* --------- TAPE ---------- */
02004 #ifdef OS_UNIX
02005     do {
02006       status = write(handle, (char *) prec, nbytes);
02007     } while (status == -1 && errno == EINTR);
02008     *written = status;
02009     if (*written != nbytes) {
02010       cm_msg(MERROR, "any_dev_os_write", strerror(errno));
02011       if (errno == EIO)
02012         return SS_IO_ERROR;
02013       if (errno == ENOSPC)
02014         return SS_NO_SPACE;
02015       else
02016         return SS_TAPE_ERROR;
02017     }
02018 #endif                          /* OS_UNIX */
02019 
02020 #ifdef OS_WINNT
02021     WriteFile((HANDLE) handle, (char *) prec, nbytes, written, NULL);
02022     if (*written != nbytes) {
02023       status = GetLastError();
02024       cm_msg(MERROR, "any_dev_os_write", "error %d", status);
02025       return SS_IO_ERROR;
02026     }
02027     return SS_SUCCESS;          /* return for TAPE */
02028 #endif                          /* OS_WINNT */
02029   } else if (type == LOG_TYPE_FTP)
02030 #ifdef INCLUDE_FTPLIB
02031   {
02032     *written =
02033         (DWORD) status =
02034         (INT) ftp_send(ftp_con->data, (char *) prec,
02035                        (int) nbytes) ==
02036         (int) nbytes ? SS_SUCCESS : SS_FILE_ERROR;
02037     return status;
02038   }
02039 #else
02040   {
02041     cm_msg(MERROR, "ybos", "FTP support not included");
02042     return SS_IO_ERROR;
02043   }
02044 #endif
02045   return SS_SUCCESS;
02046 }
02047 
02048 /*------------------------------------------------------------------*/
02049 INT yb_any_physrec_get(INT data_fmt, void **precord, DWORD * readn)
02050 /********************************************************************\
02051 Routine: external yb_any_physrec_get
02052 Purpose: Retrieve a physical record for the given data format
02053 Input:
02054 INT data_fmt :  YBOS or MIDAS 
02055 Output:
02056 void ** precord     pointer to the record
02057 DWORD * readn       record length in bytes
02058 Function value:
02059 status : from lower function
02060 \********************************************************************/
02061 {
02062   *precord = my.pmp;
02063   if (data_fmt == FORMAT_MIDAS)
02064     return midas_physrec_get(*precord, readn);
02065   else if (data_fmt == FORMAT_YBOS)
02066     return ybos_physrec_get((DWORD **) precord, readn);
02067   else
02068     return YB_UNKNOWN_FORMAT;
02069 }
02070 
02071 /*------------------------------------------------------------------*/
02072 INT ybos_physrec_get(DWORD ** precord, DWORD * readn)
02073 /********************************************************************\
02074 Routine: ybos_physrec_get
02075 Purpose: read one physical YBOS record.
02076 The number of bytes to be read is fixed under YBOS.
02077 It is defined by my.size, In case of Disk file the magta
02078 stuff has to be read/rejected first.
02079 Input:
02080 void ** precord     pointer to the record
02081 DWORD * readn       record length in bytes
02082 Output:
02083 none
02084 Function value:
02085 YB_DONE            No more record to read
02086 YB_SUCCESS         Ok
02087 \********************************************************************/
02088 {
02089   INT status;
02090 
02091 #ifdef YBOS_VERSION_3_3
02092   if (my.magtafl) {
02093     /* skip 4 bytes from MAGTA header */
02094     if (!my.zipfile) {
02095       status = yb_any_dev_os_read(my.handle, my.type, my.pmagta, 4, readn);
02096       if (status != SS_SUCCESS)
02097         return (YB_DONE);
02098     } else {                    /* --------- GZIP ---------- */
02099 #ifdef INCLUDE_ZLIB
02100       status = gzread(filegz, (char *) my.pmagta, 4);
02101       if (status <= 0)
02102         return (YB_DONE);
02103 #endif
02104     }
02105   }
02106 #endif
02107 
02108   /* read full YBOS physical record */
02109   if (!my.zipfile) {
02110     status =
02111         yb_any_dev_os_read(my.handle, my.type, my.pyh, my.size << 2,
02112                            readn);
02113     if (status != SS_SUCCESS)
02114       return (YB_DONE);
02115   } else {
02116 #ifdef INCLUDE_ZLIB
02117     status = gzread(filegz, (char *) my.pyh, my.size << 2);
02118     if (status <= 0)
02119       return (YB_DONE);
02120 #endif
02121   }
02122 
02123 #ifdef YBOS_VERSION_3_3
02124   /* check if header make sense for MAGTA there is extra stuff to get rid off */
02125   if ((!my.magtafl) && (*((DWORD *) my.pyh) == 0x00000004)) {
02126     /* set MAGTA flag */
02127     my.magtafl = TRUE;
02128     /* BOT of MAGTA skip record */
02129     if (!my.zipfile) {
02130       status = yb_any_dev_os_read(my.handle, my.type, my.pmagta, 8, readn);
02131       if (status != SS_SUCCESS)
02132         return (YB_DONE);
02133     } else {
02134 #ifdef INCLUDE_ZLIB
02135       status = gzread(filegz, (char *) my.pmagta, 8);
02136       if (status <= 0)
02137         return (YB_DONE);
02138 #endif
02139     }
02140 
02141     /* read full YBOS physical record */
02142     if (!my.zipfile) {
02143       status =
02144           yb_any_dev_os_read(my.handle, my.type, my.pyh, my.size << 2,
02145                              readn);
02146       if (status != SS_SUCCESS)
02147         return (YB_DONE);
02148     } else {
02149 #ifdef INCLUDE_ZLIB
02150       status = gzread(filegz, (char *) my.pyh, my.size << 2);
02151       if (status <= 0)
02152         return (YB_DONE);
02153 #endif
02154     }
02155   }
02156 #endif
02157 
02158   /* move current ptr of newly phys rec to first event */
02159   if ((my.pyh)->offset == 0) {
02160     /* no new event ==> full phys rec is continuation of the previous event
02161        leave pointer to continuation */
02162     my.pyrd = (DWORD *) my.pyh + (my.pyh)->offset;
02163   } else {
02164     /* new event in physical record 
02165        leave pointer to plrl */
02166     my.pyrd = (DWORD *) my.pyh + (my.pyh)->offset;
02167   }
02168   /* count blocks */
02169   my.recn++;
02170 
02171   *precord = (DWORD *) (my.pyh);
02172 
02173   return (YB_SUCCESS);
02174 }
02175 
02176 /*------------------------------------------------------------------*/
02177 INT midas_physrec_get(void *prec, DWORD * readn)
02178 /********************************************************************\
02179 Routine: midas_physrec_get
02180 Purpose: read one physical record.from a MIDAS run
02181 This is a "fake" physical record as Midas is
02182 not block structured. This function is used for
02183 reading a my.size record size. The return readn if different
02184 then my.size, will indicate a end of run. An extra read will
02185 indicate an eof.
02186 
02187 Input:
02188 void * prec        pointer to the record
02189 Output:
02190 DWORD *readn       retrieve number of bytes
02191 Function value:
02192 YB_DONE            No more record to read
02193 YB_SUCCESS         Ok
02194 \********************************************************************/
02195 {
02196   INT status = 0;
02197 
02198   /* read one block of data */
02199   if (!my.zipfile) {
02200     status = yb_any_dev_os_read(my.handle, my.type, prec, my.size, readn);
02201   } else {
02202 #ifdef INCLUDE_ZLIB
02203     *readn = gzread(filegz, (char *) prec, my.size);
02204     if (*readn <= 0)
02205       status = SS_FILE_ERROR;
02206     else
02207       status = SS_SUCCESS;
02208 #endif
02209   }
02210 
02211   if (status != SS_SUCCESS) {
02212     return (YB_DONE);
02213   } else {
02214     /* count blocks */
02215     my.recn++;
02216     return (YB_SUCCESS);
02217   }
02218 }
02219 
02220 /*------------------------------------------------------------------*/
02221 INT yb_any_log_write(INT handle, INT data_fmt, INT type, void *prec,
02222                      DWORD nbytes)
02223 /********************************************************************\
02224 Routine: external yb_any_log_write
02225 Purpose: Write a physical record to the out device, takes care of the
02226 magta under YBOS.
02227 
02228 Input:
02229 void handle   : file handle
02230 INT data_fmt  : YBOS or MIDAS 
02231 INT type      : Tape or disk 
02232 void *prec    : record pointer
02233 DWORD nbytes  : record length to be written
02234 Output:
02235 none
02236 Function value:
02237 status : from lower function  SS_SUCCESS, SS_FILE_ERROR
02238 \********************************************************************/
02239 {
02240   INT status;
02241   DWORD written;
02242 
02243 #ifdef YBOS_VERSION_3_3
02244   if ((type == LOG_TYPE_DISK) && (data_fmt == FORMAT_YBOS)) {   /* add the magta record if going to disk */
02245     status =
02246         yb_any_dev_os_write(handle, type, (char *) ((DWORD *) (magta + 2)),
02247                             4, &written);
02248     if (status != SS_SUCCESS)
02249       return status;
02250   }
02251 #endif
02252   /* write record */
02253   status = yb_any_dev_os_write(handle, type, prec, nbytes, &written);
02254   return status;
02255 }
02256 
02257 /*------------------------------------------------------------------*/
02258 INT yb_any_physrec_skip(INT data_fmt, INT bl)
02259 /********************************************************************\
02260 Routine: external yb_any_physrec_skip
02261 Purpose: Skip physical record until block = bl for the given data
02262 format, Under midas the skip is an event as no physical 
02263 record is present under that format,
02264 Input:
02265 INT data_fmt :  YBOS or MIDAS 
02266 INT bl:         block number (-1==all, 0 = first block)
02267 in case of MIDAS the bl represent an event
02268 Output:
02269 none
02270 Function value:
02271 status : from lower function
02272 \********************************************************************/
02273 {
02274   INT status;
02275 
02276   if (data_fmt == FORMAT_MIDAS) {
02277     status = midas_event_skip(bl);
02278     return YB_SUCCESS;
02279   } else if (data_fmt == FORMAT_YBOS)
02280     return ybos_physrec_skip(bl);
02281   else
02282     return YB_UNKNOWN_FORMAT;
02283 }
02284 
02285 /*------------------------------------------------------------------*/
02286 INT ybos_physrec_skip(INT bl)
02287 /********************************************************************\
02288 Routine: ybos_physrec_skip
02289 Purpose: skip physical record on a YBOS file.
02290 The physical record size is fixed (see ybos.h)
02291 Input:
02292 INT     bl            physical record number. (start at 0)
02293 if bl = -1 : skip skiping
02294 Output:
02295 none
02296 Function value:
02297 YB_SUCCESS        Ok
02298 \********************************************************************/
02299 {
02300   INT status;
02301   DWORD *prec, size;
02302 
02303   if (bl == -1) {
02304     if ((status = ybos_physrec_get(&prec, &size)) == YB_SUCCESS)
02305       return status;
02306   }
02307   while (ybos_physrec_get(&prec, &size) == YB_SUCCESS) {
02308     if ((INT) (my.pyh)->rec_num != bl) {
02309       printf("Skipping physical record_# ... ");
02310       printf("%ld \r", (my.pyh)->rec_num);
02311       fflush(stdout);
02312     } else {
02313       printf("\n");
02314       return YB_SUCCESS;
02315     }
02316   }
02317   return YB_DONE;
02318 }
02319 
02320 /*------------------------------------------------------------------*/
02321 INT midas_event_skip(INT evtn)
02322 /********************************************************************\
02323 Routine: midas_event_skip
02324 Purpose: skip event on a MIDAS file.
02325 Input:
02326 INT     evtn          event record number. (start at 0)
02327 if evt = -1 : skip skiping
02328 Output:
02329 none
02330 Function value:
02331 YB_SUCCESS        Ok
02332 \********************************************************************/
02333 {
02334   void *pevent;
02335   DWORD size;
02336 
02337   size = MAX_EVENT_SIZE;
02338   if (evtn == -1) {
02339     /*    if(midas_event_get(&pevent, &size) == YB_SUCCESS) */
02340     return YB_SUCCESS;
02341   }
02342   while (midas_event_get(&pevent, &size) == YB_SUCCESS) {
02343     if ((INT) my.evtn < evtn) {
02344       printf("Skipping event_# ... ");
02345       printf("%ld \r", my.evtn);
02346       fflush(stdout);
02347     } else {
02348       printf("\n");
02349       return YB_SUCCESS;
02350     }
02351   }
02352   return YB_DONE;
02353 }
02354 
02355 /*------------------------------------------------------------------*/
02356 INT yb_any_physrec_display(INT data_fmt)
02357 /********************************************************************\
02358 Routine: external yb_any_physrec_display
02359 Purpose: Display the physical record of the current record 
02360 for the given data format.
02361 Not possible for MIDAS as no physical record structure
02362 Input:
02363 INT data_fmt :  YBOS or MIDAS 
02364 Output:
02365 none
02366 Function value:
02367 status          Lower function
02368 \********************************************************************/
02369 {
02370   INT bz, j, i, k;
02371   DWORD *prec;
02372 
02373   if (data_fmt == FORMAT_MIDAS) {
02374     printf(">>> No physical record structure for Midas format <<<\n");
02375     return YB_DONE;
02376   } else if (data_fmt == FORMAT_YBOS) {
02377     yb_any_all_info_display(D_RECORD);
02378     bz = (my.pyh)->rec_size + 1;
02379     /* adjust local pointer to top of record to include record header */
02380     prec = (DWORD *) (my.pyh);
02381     k = (my.pyh)->rec_num;
02382     for (i = 0; i < bz; i += NLINE) {
02383       printf("R(%d)[%d] = ", k, i);
02384       for (j = 0; j < NLINE; j++) {
02385         if (i + j < bz) {
02386           printf("%8.8lx ", *prec);
02387           prec++;
02388         }
02389       }
02390       printf("\n");
02391     }
02392     return (YB_SUCCESS);
02393   } else
02394     return YB_UNKNOWN_FORMAT;
02395 }
02396 
02397 /*------------------------------------------------------------------*/
02398 INT yb_any_all_info_display(INT what)
02399 /********************************************************************\
02400 Routine: yb_any_all_info_display
02401 Purpose: display on screen all the info about "what".
02402 Input:
02403 INT     what              type of display.
02404 Output:
02405 none
02406 Function value:
02407 INT                 YB_SUCCESS
02408 YB_DONE
02409 \********************************************************************/
02410 {
02411   if (my.fmt == FORMAT_YBOS) {
02412     DWORD bz, hyl, ybn, of;
02413 
02414     bz = (my.pyh)->rec_size;
02415     hyl = (my.pyh)->header_length;
02416     ybn = (my.pyh)->rec_num;
02417     of = (my.pyh)->offset;
02418     switch (what) {
02419     case D_RECORD:
02420     case D_HEADER:
02421       printf("rec#%ld- ", my.recn);
02422       printf("%5ldbz %5ldhyl %5ldybn %5ldof\n", bz, hyl, ybn, of);
02423       break;
02424     case D_EVTLEN:
02425       printf("rec#%ld- ", my.recn);
02426       printf("%5ldbz %5ldhyl %5ldybn %5ldof ", bz, hyl, ybn, of);
02427       printf("%5ldel/x%lx %5ldev\n", my.evtlen, my.evtlen, my.evtn);
02428       break;
02429     }
02430   } else if (my.fmt == FORMAT_MIDAS) {
02431     DWORD mbn, run, ser;
02432     WORD id, msk;
02433     mbn = my.evtn;
02434     run = my.runn;
02435     id = my.pmh->event_id;
02436     msk = my.pmh->trigger_mask;
02437     ser = my.pmh->serial_number;
02438     switch (what) {
02439     case D_RECORD:
02440     case D_HEADER:
02441       printf(">>> No physical record structure for Midas format <<<\n");
02442       return YB_DONE;
02443       break;
02444     case D_EVTLEN:
02445       printf("Evt#%ld- ", my.evtn);
02446       printf("%lirun 0x%4.4uxid 0x%4.4uxmsk %5ldmevt#", run, id, msk, mbn);
02447       printf("%5ldel/x%lx %5ldserial\n", my.evtlen, my.evtlen, ser);
02448       break;
02449     }
02450   }
02451   return YB_SUCCESS;
02452 }
02453 
02454 /*------------------------------------------------------------------*/
02455 INT yb_any_event_swap(INT data_fmt, void *pevent)
02456 /********************************************************************\
02457 Routine: external yb_any_event_swap
02458 Purpose: Swap an event from the given data format.
02459 Input:
02460 INT data_fmt  : YBOS or MIDAS 
02461 void * pevent : pointer to either plrl or pheader
02462 Output:
02463 none
02464 Function value:
02465 status :  from the lower function
02466 \********************************************************************/
02467 {
02468   INT status;
02469   BANK_HEADER *pbh;
02470 
02471   if (data_fmt == FORMAT_MIDAS) {
02472     if ((((EVENT_HEADER *) pevent)->event_id == EVENTID_BOR) ||
02473         (((EVENT_HEADER *) pevent)->event_id == EVENTID_EOR) ||
02474         (((EVENT_HEADER *) pevent)->event_id == EVENTID_MESSAGE))
02475       return SS_SUCCESS;
02476     pbh = (BANK_HEADER *) (((EVENT_HEADER *) pevent) + 1);
02477     status = bk_swap(pbh, FALSE);
02478     return status == CM_SUCCESS ? YB_EVENT_NOT_SWAPPED : YB_SUCCESS;
02479   } else if (data_fmt == FORMAT_YBOS) {
02480     status = ybos_event_swap((DWORD *) pevent);
02481     return status == YB_EVENT_NOT_SWAPPED ? YB_SUCCESS : status;
02482   }
02483 
02484   return YB_UNKNOWN_FORMAT;
02485 }
02486 
02487 /*------------------------------------------------------------------*/
02488 INT ybos_event_swap(DWORD * plrl)
02489 /********************************************************************\
02490 Routine: ybos_event_swap
02491 Purpose: byte swap the entire YBOS event if necessary.
02492 chekc necessity of swapping by looking at the 
02493 bank type being < MAX_BKTYPE 
02494 Input:
02495 DWORD * plrl           pointer to the YBOS event
02496 Output:
02497 none
02498 Function value:
02499 YB_SUCCESS             Event has been swapped
02500 YB_EVENT_NOT_SWAPPED   Event has been not been swapped
02501 YB_SWAP_ERROR          swapping error
02502 \********************************************************************/
02503 {
02504   DWORD *pevt, *pnextb, *pendevt;
02505   DWORD bank_length, bank_type;
02506 
02507   /* check if event has to be swapped */
02508   if ((((YBOS_BANK_HEADER *) (plrl + 1))->type) < MAX_BKTYPE)
02509     return (YB_EVENT_NOT_SWAPPED);
02510 
02511   /* swap LRL */
02512   DWORD_SWAP(plrl);
02513   pevt = plrl + 1;
02514 
02515   /* end of event pointer */
02516   pendevt = pevt + *plrl;
02517 
02518   /* scan event */
02519   while (pevt < pendevt) {
02520     /* swap YBOS bank header for sure */
02521     /* bank name doesn't have to be swapped as it's an ASCII coded */
02522     pevt++;                     /* bank name */
02523 
02524     DWORD_SWAP(pevt);           /* bank number */
02525     pevt++;
02526 
02527     DWORD_SWAP(pevt);           /* bank index */
02528     pevt++;
02529 
02530     DWORD_SWAP(pevt);           /* bank length */
02531     bank_length = *pevt++;
02532 
02533     DWORD_SWAP(pevt);           /* bank type */
02534     bank_type = *pevt++;
02535 
02536     /* pevt left pointing at first data in bank */
02537 
02538     /* pointer to next bank (-1 due to type inclided in length #$%@ */
02539     pnextb = pevt + bank_length - 1;
02540 
02541     switch (bank_type) {
02542     case D8_BKTYPE:
02543       while ((BYTE *) pevt < (BYTE *) pnextb) {
02544         QWORD_SWAP(pevt);
02545         pevt = (DWORD *) (((double *) pevt) + 1);
02546       }
02547       break;
02548     case I4_BKTYPE:
02549     case F4_BKTYPE:
02550       while ((BYTE *) pevt < (BYTE *) pnextb) {
02551         DWORD_SWAP(pevt);
02552         pevt++;
02553       }
02554       break;
02555     case I2_BKTYPE:
02556       while ((BYTE *) pevt < (BYTE *) pnextb) {
02557         WORD_SWAP(pevt);
02558         pevt = (DWORD *) (((WORD *) pevt) + 1);
02559       }
02560       break;
02561     case I1_BKTYPE:
02562     case A1_BKTYPE:
02563       pevt = pnextb;
02564       break;
02565     default:
02566       printf("ybos_swap_event-E- Unknown bank type %li\n", bank_type);
02567       return (YB_SWAP_ERROR);
02568       break;
02569     }
02570   }
02571   return (YB_SUCCESS);
02572 }
02573 
02574 /*------------------------------------------------------------------*/
02575 INT yb_any_event_get(INT data_fmt, void **pevent, DWORD * readn)
02576 /********************************************************************\
02577 Routine: external yb_any_event_get
02578 Purpose: Retrieve an event from the given data format.
02579 Input:
02580 INT data_fmt :  YBOS or MIDAS 
02581 void ** pevent : either plrl or pheader
02582 Output:
02583 DWORD * readn : number of bytes read
02584 Function value:
02585 status : from lower function
02586 \********************************************************************/
02587 {
02588   INT status = 0;
02589 
02590   *pevent = NULL;
02591   if (data_fmt == FORMAT_MIDAS)
02592     status = midas_event_get(pevent, readn);
02593   else if (data_fmt == FORMAT_YBOS)
02594     status = ybos_event_get((DWORD **) pevent, readn);
02595   return (status);
02596 }
02597 
02598 /*------------------------------------------------------------------*/
02599 INT ybos_event_get(DWORD ** plrl, DWORD * readn)
02600 /********************************************************************\
02601 Routine: ybos_event_get
02602 Purpose: read one YBOS event.
02603 detect the end of run by checking the *plrl content (-1)
02604 Input:
02605 Output:
02606 DWORD ** plrl      points to LRL valid full YBOS event
02607 DWORD * readn      event size in Bytes 
02608 Function value:
02609 YB_DONE           No more record to read
02610 YB_SUCCESS        Ok
02611 \********************************************************************/
02612 {
02613   DWORD size, fpart, lpart, evt_length;
02614   DWORD *ptmp, *prec;
02615   INT status;
02616 
02617   /* detect end of run (no more events) 
02618      by checking the *pyrd == -1 */
02619   if ((INT) (*my.pyrd) == -1)
02620     return YB_DONE;
02621   /* extract event to local event area
02622      event may not be complete if larger then physical record size
02623      will be taken care below, ADD the lrl  */
02624   evt_length = *(my.pyrd) + 1;
02625   memcpy((char *) my.pylrl, (char *) my.pyrd, evt_length << 2);
02626 
02627   /* extract lrl in I*4 and include itself (lrl) */
02628 
02629   /* stop if LRL  = -1 ... I don't think it is necessary but I leave it in for now
02630      or forever... */
02631   if (evt_length - 1 == -1)
02632     return (YB_DONE);
02633 
02634   /* check if event cross physical record boundary */
02635   if ((my.pyrd + evt_length) >= (DWORD *) my.pyh + my.size) {
02636     /* upcomming event crosses block, then first copy first part of event */
02637     /* compute max copy for first part of event */
02638     fpart = (DWORD *) my.pyh + my.size - my.pyrd;
02639     memcpy((char *) my.pylrl, (char *) my.pyrd, fpart << 2);
02640 
02641     /* adjust temporary evt pointer all in I*4 */
02642     ptmp = my.pylrl + fpart;
02643 
02644     if ((evt_length - fpart) == 0) {
02645       /* get next physical record */
02646       if ((status = ybos_physrec_get(&prec, &size)) != YB_SUCCESS)
02647         return (status);
02648       my.pyrd = (DWORD *) my.pyh + my.pyh->header_length;
02649     } else {
02650       while ((evt_length - fpart) > 0) {
02651         lpart = evt_length - fpart;
02652         if (lpart > (YBOS_PHYREC_SIZE - YBOS_HEADER_LENGTH))
02653           lpart = (YBOS_PHYREC_SIZE - YBOS_HEADER_LENGTH);
02654 
02655         /* get next physical record */
02656         if ((status = ybos_physrec_get(&prec, &size)) != YB_SUCCESS)
02657           return (status);
02658 
02659         /* pyrd is left at the next lrl but here we comming from
02660            a cross boundary request so read just the pyrd to 
02661            pyh+header_length */
02662         my.pyrd = (DWORD *) my.pyh + my.pyh->header_length;
02663         /* now copy remaining from temporary pointer */
02664         memcpy((char *) ptmp, (char *) my.pyrd, lpart << 2);
02665 
02666         /* adjust pointer to next valid data (LRL) 
02667            should be equivalent to pyh+pyh->offset */
02668         my.pyrd += lpart;
02669         fpart += lpart;
02670         ptmp += lpart;
02671       }
02672     }
02673     if (my.pyrd != (DWORD *) my.pyh + my.pyh->offset) {
02674       printf(" event misalignment !! %p  %p \n",
02675              my.pyrd, (DWORD *) my.pyh + my.pyh->offset);
02676       printf("Event crossed boundary: length %ld\n", evt_length);
02677       my.pyrd = (DWORD *) my.pyh + my.pyh->offset;
02678     }
02679 
02680   } else {
02681     /* adjust pointer to next valid data (LRL) */
02682     my.pyrd += evt_length;
02683   }
02684   /* count event */
02685   my.evtn++;
02686 
02687   /*-PAA- Dec99 Danny adjust event size in I*4 */
02688   my.evtlen = evt_length;
02689   /* in bytes for the world */
02690   *readn = my.evtlen << 2;
02691   *plrl = (DWORD *) my.pylrl;
02692   return (YB_SUCCESS);
02693 }
02694 
02695 /*------------------------------------------------------------------*/
02696 INT midas_event_get(void **pevent, DWORD * readn)
02697 /********************************************************************\
02698 Routine: midas_event_get
02699 Purpose: read one MIDAS event.
02700 Will detect:
02701 The first pass in getting the record number being -1
02702 The last pass in checking the midas_physrec_get() readn
02703 being different then the my.size then flushing the current
02704 buffer until pointer goes beyond last event.
02705 Input:
02706 void ** pevent     points to MIDAS HEADER 
02707 Output:
02708 DWORD * readn      event size in bytes (MIDAS)
02709 Function value:
02710 YB_DONE           No more record to read
02711 YB_SUCCESS        Ok
02712 \********************************************************************/
02713 {
02714   INT status, leftover;
02715   DWORD fpart;
02716   static DWORD size = 0;
02717 
02718   /* save pointer */
02719   *pevent = (char *) my.pmh;
02720   if (size == 0)
02721     size = my.size;
02722 
02723   /* first time in get physrec once */
02724   if (my.recn == -1) {
02725     status = midas_physrec_get((void *) my.pmp, &size);
02726     if (status != YB_SUCCESS)
02727       return (YB_DONE);
02728   }
02729 
02730   /*-PAA- Jul 12/2002
02731     if (((my.pmp+size) - (char *)my.pme) == 0)
02732         return (YB_DONE);
02733   */
02734 
02735   /* copy header only */
02736   if (((my.pmp + size) - (char *) my.pme) < sizeof(EVENT_HEADER)) {
02737     fpart = (my.pmp + my.size) - (char *) my.pme;
02738     memcpy(my.pmh, my.pme, fpart);
02739     my.pmh = (EVENT_HEADER *) (((char *) my.pmh) + fpart);
02740     leftover = sizeof(EVENT_HEADER) - fpart;
02741     status = midas_physrec_get((void *) my.pmp, &size);
02742     if (status != YB_SUCCESS)
02743       return (YB_DONE);
02744     memset(my.pmp + size, -1, my.size - size);
02745     my.pme = (EVENT_HEADER *) my.pmp;
02746     memcpy(my.pmh, my.pme, leftover);
02747     my.pme = (EVENT_HEADER *) (((char *) my.pme) + leftover);
02748     my.pmh = (EVENT_HEADER *) * pevent;
02749   } else {
02750     memcpy(my.pmh, my.pme, sizeof(EVENT_HEADER));
02751     my.pme = (EVENT_HEADER *) (((char *) my.pme) + sizeof(EVENT_HEADER));
02752   }
02753   /* leave with pmh  to destination header
02754      pmrd to destination event (pmh+1)
02755      pme  to source event
02756    */
02757   my.pmrd = (char *) (my.pmh + 1);
02758 
02759   /* check for end of file */
02760   if (my.pmh->event_id == -1)
02761     return YB_DONE;
02762 
02763   /* copy event (without header) */
02764   leftover = my.pmh->data_size;
02765 
02766   /* check for block crossing */
02767   while (((my.pmp + size) - (char *) my.pme) < leftover) {
02768     fpart = (my.pmp + my.size) - (char *) my.pme;
02769     memcpy(my.pmrd, my.pme, fpart);
02770     my.pmrd += fpart;
02771     leftover -= fpart;
02772     status = midas_physrec_get((void *) my.pmp, &size);
02773     if (status != YB_SUCCESS)
02774       return (YB_DONE);
02775     memset(my.pmp + size, -1, my.size - size);
02776     my.pme = (EVENT_HEADER *) my.pmp;
02777   }
02778 
02779   /* copy left over or full event if no Xing */
02780   *readn = my.evtlen = my.pmh->data_size + sizeof(EVENT_HEADER);
02781   memcpy(my.pmrd, my.pme, leftover);
02782   my.pme = (EVENT_HEADER *) (((char *) my.pme) + leftover);
02783   my.evtn++;
02784   return YB_SUCCESS;
02785 }
02786 
02787 /*------------------------------------------------------------------*/
02788 void yb_any_event_display(void *pevent, INT data_fmt, INT dsp_mode,
02789                           INT dsp_fmt)
02790 /********************************************************************\
02791 Routine: external yb_any_event_display
02792 Purpose: display on screen the YBOS event in either RAW or YBOS mode
02793 and in either Decimal or Hexadecimal.
02794 Input:
02795 void *  pevent     pointer to either plrl or pheader.
02796 INT     data_fmt   uses the YBOS or MIDAS event structure
02797 INT     dsp_mode   display in RAW or Bank mode
02798 INT     dsp_fmt    display format (DSP_DEC/HEX)
02799 Output:
02800 none
02801 Function value:
02802 none
02803 \********************************************************************/
02804 {
02805   if (dsp_mode == DSP_RAW)
02806     yb_any_raw_event_display(pevent, data_fmt, dsp_fmt);
02807   else if (dsp_mode == DSP_BANK)
02808     yb_any_bank_event_display(pevent, data_fmt, dsp_fmt);
02809   else
02810     printf("yb_any_event_display- Unknown format:%i\n", dsp_fmt);
02811   return;
02812 }
02813 
02814 /*------------------------------------------------------------------*/
02815 void yb_any_raw_event_display(void *pevent, INT data_fmt, INT dsp_fmt)
02816 /********************************************************************\
02817 Routine: yb_any_raw_event_display
02818 Purpose: display on screen the RAW data of either YBOS or MIDAS format.
02819 Input:
02820 DWORD *  pevent         points to either plrl or pheader
02821 INT     data_fmt        uses the YBOS or MIDAS event structure
02822 INT      dsp_fmt        display format (DSP_DEC/HEX)
02823 Output:
02824 none
02825 Function value:
02826 none
02827 \********************************************************************/
02828 {
02829   DWORD lrl = 0, *pevt = NULL, j, i, total = 0;
02830 
02831   if (data_fmt == FORMAT_YBOS) {
02832     lrl = *((DWORD *) (pevent)) + 1;    /* include itself */
02833     pevt = (DWORD *) pevent;    /* local copy starting from the plrl */
02834   } else if (data_fmt == FORMAT_MIDAS) {
02835     lrl = ((((EVENT_HEADER *) pevent)->data_size) + sizeof(EVENT_HEADER)) / sizeof(DWORD);      /* in I*4 for raw including the header */
02836     pevt = (DWORD *) pevent;    /* local copy starting from the pheader */
02837   }
02838 
02839   for (i = 0; i < lrl; i += NLINE) {
02840     printf("%6.0ld->: ", total);
02841     for (j = 0; j < NLINE; j++) {
02842       if ((i + j) < lrl) {
02843         if (dsp_fmt == DSP_DEC)
02844           printf("%8.li ", *pevt);
02845         else
02846           printf("%8.8lx ", *pevt);
02847         pevt++;
02848       }
02849     }
02850     total += NLINE;
02851     printf("\n");
02852   }
02853 }
02854 
02855 /*------------------------------------------------------------------*/
02856 void yb_any_bank_event_display(void *pevent, INT data_fmt, INT dsp_fmt)
02857 /********************************************************************\
02858 Routine: ybos_bank_event_display
02859 Purpose: display on screen the event header, bank list and bank content
02860 for either ybos or midas format. In case of ybos check is EVID is 
02861 present if so extract its content (see macro ybos.h)
02862 Input:
02863 void * pevent          points to either plrl or pheader
02864 INT     data_fmt       uses the YBOS or MIDAS event structure
02865 INT     dsp_fmt        display format (DSP_DEC/HEX)
02866 Output:
02867 none
02868 Function value:
02869 none
02870 \********************************************************************/
02871 {
02872   char banklist[YB_STRING_BANKLIST_MAX];
02873   YBOS_BANK_HEADER *pybk;
02874   DWORD *pdata;
02875   DWORD bklen, bktyp;
02876   BANK_HEADER *pbh;
02877   BANK *pmbk;
02878   BANK32 *pmbk32;
02879   EVENT_HEADER *pheader;
02880   INT status;
02881 
02882   if (data_fmt == FORMAT_YBOS) {
02883     /* event header --> No event header in YBOS */
02884 
02885     /* bank list */
02886     status = ybk_list((DWORD *) pevent, banklist);
02887     printf("#banks:%i - Bank list:-%s-\n", status, banklist);
02888 
02889     /* check if EVID is present if so display its content */
02890     if ((status =
02891          ybk_find((DWORD *) pevent, "EVID", &bklen, &bktyp,
02892                   (void **) &pybk)) == YB_SUCCESS) {
02893       pdata = (DWORD *) ((YBOS_BANK_HEADER *) pybk + 1);
02894       printf
02895           ("--------- EVID --------- Event# %li ------Run#:%li--------\n",
02896            YBOS_EVID_EVENT_NB(pdata), YBOS_EVID_RUN_NUMBER(pdata));
02897       printf
02898           ("Evid:%4.4x- Mask:%4.4x- Serial:%li- Time:0x%lx- Dsize:%li/0x%lx",
02899            (WORD) YBOS_EVID_EVENT_ID(pdata),
02900            (WORD) YBOS_EVID_TRIGGER_MASK(pdata)
02901            , YBOS_EVID_SERIAL(pdata), YBOS_EVID_TIME(pdata)
02902            , ((YBOS_BANK_HEADER *) pybk)->length,
02903            ((YBOS_BANK_HEADER *) pybk)->length);
02904     }
02905 
02906     /* display bank content */
02907     pybk = NULL;
02908     while ((ybk_iterate((DWORD *) pevent, &pybk, (void **) &pdata) >= 0)
02909            && (pybk != NULL))
02910       ybos_bank_display(pybk, dsp_fmt);
02911   } else if (data_fmt == FORMAT_MIDAS) {
02912     /* skip these special events (NO bank structure) */
02913     pheader = (EVENT_HEADER *) pevent;
02914     if (pheader->event_id == EVENTID_BOR ||
02915         pheader->event_id == EVENTID_EOR ||
02916         pheader->event_id == EVENTID_MESSAGE)
02917       return;
02918 
02919     /* event header */
02920     printf
02921         ("Evid:%4.4x- Mask:%4.4x- Serial:%li- Time:0x%lx- Dsize:%li/0x%lx",
02922          (WORD) pheader->event_id, (WORD) pheader->trigger_mask,
02923          pheader->serial_number, pheader->time_stamp, pheader->data_size,
02924          pheader->data_size);
02925 
02926     /* check if format is MIDAS or FIXED */
02927     pbh = (BANK_HEADER *) (pheader + 1);
02928     if ((pbh->data_size + 8) == pheader->data_size) {
02929       /* bank list */
02930       status = bk_list((BANK_HEADER *) (pheader + 1), banklist);
02931       printf("\n#banks:%i - Bank list:-%s-\n", status, banklist);
02932 
02933       /* display bank content */
02934       if (bk_is32(pbh)) {
02935         pmbk32 = NULL;
02936         do {
02937           bk_iterate32(pbh, &pmbk32, &pdata);
02938           if (pmbk32 != NULL)
02939             midas_bank_display32(pmbk32, dsp_fmt);
02940         } while (pmbk32 != NULL);
02941       } else {
02942         pmbk = NULL;
02943         do {
02944           bk_iterate(pbh, &pmbk, &pdata);
02945           if (pmbk != NULL)
02946             midas_bank_display(pmbk, dsp_fmt);
02947         } while (pmbk != NULL);
02948       }
02949     } else {
02950       printf("\nFIXED event with Midas Header\n");
02951       yb_any_raw_event_display(pevent, data_fmt, dsp_fmt);
02952     }
02953   }
02954   return;
02955 }
02956 
02957 /*------------------------------------------------------------------*/
02958 void yb_any_bank_display(void *pmbh, void *pbk, INT data_fmt, INT dsp_mode,
02959                          INT dsp_fmt)
02960 /********************************************************************\
02961 Routine: external yb_any_bank_display
02962 Purpose: display on screen the given bank.
02963 Input:
02964 void * pbk          pointer to the bank
02965 INT  data_fmt       YBOS or MIDAS
02966 INT  dsp_mode       display mode (RAW/BANK)
02967 INT  dsp_fmt        display format (DSP_DEC/HEX)
02968 Output:             
02969 none
02970 Function value:
02971 none
02972 \********************************************************************/
02973 {
02974   if (dsp_mode == DSP_RAW)
02975     yb_any_raw_bank_display(pbk, data_fmt, dsp_fmt);
02976   else {
02977     if (data_fmt == FORMAT_MIDAS) {
02978       if (bk_is32(pmbh))
02979         midas_bank_display32((BANK32 *) pbk, dsp_fmt);
02980       else
02981         midas_bank_display((BANK *) pbk, dsp_fmt);
02982     } else if (data_fmt == FORMAT_YBOS)
02983       ybos_bank_display((YBOS_BANK_HEADER *) pbk, dsp_fmt);
02984   }
02985   return;
02986 }
02987 
02988 /*------------------------------------------------------------------*/
02989 void yb_any_raw_bank_display(void *pbank, INT data_fmt, INT dsp_fmt)
02990 /********************************************************************\
02991 Routine: yb_any_raw_bank_display
02992 Purpose: display on screen the RAW data of a given YBOS/MIDAS bank.
02993 Input:
02994 void  * pbank          pointer to the bank name
02995 INT     data_fmt       uses the YBOS or MIDAS event structure
02996 INT     dsp_fmt        display format (DSP_DEC/HEX)
02997 Output:
02998 none
02999 Function value:
03000 none
03001 \********************************************************************/
03002 {
03003   DWORD *pdata = NULL, lrl = 0, j, i;
03004 
03005   if (data_fmt == FORMAT_YBOS) {
03006     lrl = (((YBOS_BANK_HEADER *) pbank)->length) - 1;
03007     pdata = (DWORD *) (((YBOS_BANK_HEADER *) pbank) + 1);
03008   } else if (data_fmt == FORMAT_MIDAS) {
03009     lrl = ((BANK *) pbank)->data_size >> 2;     /* in DWORD */
03010     pdata = (DWORD *) ((BANK *) (pbank) + 1);
03011   }
03012 
03013   for (i = 0; i < lrl; i += NLINE) {
03014     j = 0;
03015     printf("\n%4li-> ", i + j + 1);
03016     for (j = 0; j < NLINE; j++) {
03017       if ((i + j) < lrl) {
03018         if (dsp_fmt == DSP_DEC)
03019           printf("%8.li ", *((DWORD *) pdata));
03020         if (dsp_fmt == DSP_ASC)
03021           printf("%8.8lx ", *((DWORD *) pdata));
03022         if (dsp_fmt == DSP_HEX)
03023           printf("%8.8lx ", *((DWORD *) pdata));
03024         pdata++;
03025       }
03026     }
03027   }
03028 }
03029 
03030 /*------------------------------------------------------------------*/
03031 void ybos_bank_display(YBOS_BANK_HEADER * pybk, INT dsp_fmt)
03032 /********************************************************************\
03033 Routine: ybos_event_display
03034 Purpose: display on screen the YBOS data in YBOS bank mode.
03035 Input:
03036 YBOS_BANK_HEADER * pybk     pointer to the bank header
03037 INT     dsp_fmt             display format (DSP_DEC/HEX)
03038 Output:             
03039 none
03040 Function value:
03041 none
03042 \********************************************************************/
03043 {
03044   char bank_name[5], strbktype[32];
03045   DWORD length_type = 0;
03046   DWORD *pdata, *pendbk;
03047   INT i, j;
03048 
03049   j = 8;                        /* elements within line */
03050   i = 1;                        /* data counter */
03051 
03052   pdata = (DWORD *) (pybk + 1);
03053   memcpy(&bank_name[0], (char *) &pybk->name, 4);
03054   bank_name[4] = 0;
03055 
03056   if (pybk->type == D8_BKTYPE) {
03057     length_type = ((pybk->length - 1) >> 1);
03058     sprintf(strbktype, "double*8 (FMT machine dependent)");
03059   }
03060   if (pybk->type == F4_BKTYPE) {
03061     length_type = pybk->length - 1;
03062     strcpy(strbktype, "Real*4 (FMT machine dependent)");
03063   }
03064   if (pybk->type == I4_BKTYPE) {
03065     length_type = pybk->length - 1;
03066     strcpy(strbktype, "Integer*4");
03067   }
03068   if (pybk->type == I2_BKTYPE) {
03069     length_type = ((pybk->length - 1) << 1);
03070     strcpy(strbktype, "Integer*2");
03071   }
03072   if (pybk->type == I1_BKTYPE) {
03073     length_type = ((pybk->length - 1) << 2);
03074     strcpy(strbktype, "8 bit Bytes");
03075   }
03076   if (pybk->type == A1_BKTYPE) {
03077     length_type = ((pybk->length - 1) << 2);
03078     strcpy(strbktype, "8 bit ASCII");
03079   }
03080   printf("\nBank:%s Length: %li(I*1)/%li(I*4)/%li(Type) Type:%s",
03081          bank_name, ((pybk->length - 1) << 2), pybk->length - 1,
03082          length_type, strbktype);
03083   j = 16;
03084 
03085   pendbk = pdata + pybk->length - 1;
03086   while ((BYTE *) pdata < (BYTE *) pendbk) {
03087     switch (pybk->type) {
03088     case D8_BKTYPE:
03089       if (j > 7) {
03090         printf("\n%4i-> ", i);
03091         j = 0;
03092         i += 8;
03093       }
03094       printf("%15.5le  ", *((double *) pdata));
03095       pdata = (DWORD *) (((double *) pdata) + 1);
03096       j++;
03097       break;
03098     case F4_BKTYPE:
03099       if (j > 7) {
03100         printf("\n%4i-> ", i);
03101         j = 0;
03102         i += 8;
03103       }
03104       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03105         printf("%8.3e ", *((float *) pdata));
03106       if (dsp_fmt == DSP_HEX)
03107         printf("0x%8.8lx ", *((DWORD *) pdata));
03108       pdata++;
03109       j++;
03110       break;
03111     case I4_BKTYPE:
03112       if (j > 7) {
03113         printf("\n%4i-> ", i);
03114         j = 0;
03115         i += 8;
03116       }
03117       if (dsp_fmt == DSP_DEC)
03118         printf("%8.1li ", *((DWORD *) pdata));
03119       if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03120         printf("0x%8.8lx ", *((DWORD *) pdata));
03121       pdata++;
03122       j++;
03123       break;
03124     case I2_BKTYPE:
03125       if (j > 7) {
03126         printf("\n%4i-> ", i);
03127         j = 0;
03128         i += 8;
03129       }
03130       if (dsp_fmt == DSP_DEC)
03131         printf("%5.1i ", *((WORD *) pdata));
03132       if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03133         printf("0x%4.4x ", *((WORD *) pdata));
03134       pdata = (DWORD *) (((WORD *) pdata) + 1);
03135       j++;
03136       break;
03137     case A1_BKTYPE:
03138       if (j > 15) {
03139         printf("\n%4i-> ", i);
03140         j = 0;
03141         i += 16;
03142       }
03143       if ((dsp_fmt == DSP_ASC) || (dsp_fmt == DSP_UNK))
03144         printf("%1.1s ", (char *) pdata);
03145       if (dsp_fmt == DSP_DEC)
03146         printf("%2.i ", *((BYTE *) pdata));
03147       if (dsp_fmt == DSP_HEX)
03148         printf("0x%2.2x ", *((BYTE *) pdata));
03149       pdata = (DWORD *) (((BYTE *) pdata) + 1);
03150       j++;
03151       break;
03152     case I1_BKTYPE:
03153       if (j > 7) {
03154         printf("\n%4i-> ", i);
03155         j = 0;
03156         i += 8;
03157       }
03158       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03159         printf("%4.i ", *((BYTE *) pdata));
03160       if (dsp_fmt == DSP_HEX)
03161         printf("0x%2.2x ", *((BYTE *) pdata));
03162       pdata = (DWORD *) (((BYTE *) pdata) + 1);
03163       j++;
03164       break;
03165     default:
03166       printf("ybos_bak_display-E- Unknown bank type %li\n", pybk->type);
03167       break;
03168 
03169     }                           /* switch */
03170   }                             /* while next bank */
03171   printf("\n");
03172   return;
03173 }
03174 
03175 /*------------------------------------------------------------------*/
03176 void midas_bank_display(BANK * pbk, INT dsp_fmt)
03177 /******************************* *************************************\
03178 Routine: midas_bank_display
03179 Purpose: display on screen the pointed MIDAS bank data using MIDAS Bank structure.
03180 Input:
03181 BANK *  pbk            pointer to the BANK
03182 INT     dsp_fmt        display format (DSP_DEC/HEX)
03183 Output:
03184 none
03185 Function value:
03186 none
03187 \********************************************************************/
03188 {
03189   char bank_name[5], strbktype[32];
03190   char *pdata, *pendbk;
03191   DWORD length_type = 0, lrl;
03192   INT type, i, j;
03193 
03194   lrl = pbk->data_size;         /* in bytes */
03195   type = pbk->type & 0xff;
03196   bank_name[4] = 0;
03197   memcpy(bank_name, (char *) (pbk->name), 4);
03198   pdata = (char *) (pbk + 1);
03199 
03200   j = 64;                       /* elements within line */
03201   i = 1;                        /* data counter */
03202   strcpy(strbktype, "Unknown format");
03203   if (type == TID_DOUBLE) {
03204     length_type = sizeof(double);
03205     strcpy(strbktype, "double*8");
03206   }
03207   if (type == TID_FLOAT) {
03208     length_type = sizeof(float);
03209     strcpy(strbktype, "Real*4 (FMT machine dependent)");
03210   }
03211   if (type == TID_DWORD) {
03212     length_type = sizeof(DWORD);
03213     strcpy(strbktype, "Unsigned Integer*4");
03214   }
03215   if (type == TID_INT) {
03216     length_type = sizeof(INT);
03217     strcpy(strbktype, "Signed Integer*4");
03218   }
03219   if (type == TID_WORD) {
03220     length_type = sizeof(WORD);
03221     strcpy(strbktype, "Unsigned Integer*2");
03222   }
03223   if (type == TID_SHORT) {
03224     length_type = sizeof(short);
03225     strcpy(strbktype, "Signed Integer*2");
03226   }
03227   if (type == TID_BYTE) {
03228     length_type = sizeof(BYTE);
03229     strcpy(strbktype, "Unsigned Bytes");
03230   }
03231   if (type == TID_SBYTE) {
03232     length_type = sizeof(BYTE);
03233     strcpy(strbktype, "Signed Bytes");
03234   }
03235   if (type == TID_BOOL) {
03236     length_type = sizeof(DWORD);
03237     strcpy(strbktype, "Boolean");
03238   }
03239   if (type == TID_CHAR) {
03240     length_type = sizeof(char);
03241     strcpy(strbktype, "8 bit ASCII");
03242   }
03243   if (type == TID_STRUCT) {
03244     length_type = sizeof(char);
03245     strcpy(strbktype, "STRUCT (not supported->8 bits)");
03246   }
03247 
03248   printf("\nBank:%s Length: %li(I*1)/%li(I*4)/%li(Type) Type:%s",
03249          bank_name, lrl, lrl >> 2, lrl / length_type, strbktype);
03250 
03251   pendbk = pdata + lrl;
03252   while (pdata < pendbk) {
03253     switch (type) {
03254     case TID_DOUBLE:
03255       if (j > 3) {
03256         printf("\n%4i-> ", i);
03257         j = 0;
03258         i += 4;
03259       }
03260       printf("%15.5le    ", *((double *) pdata));
03261       pdata = (char *) (((double *) pdata) + 1);
03262       j++;
03263       break;
03264     case TID_FLOAT:
03265       if (j > 7) {
03266         printf("\n%4i-> ", i);
03267         j = 0;
03268         i += 8;
03269       }
03270       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03271         printf("%8.3e ", *((float *) pdata));
03272       if (dsp_fmt == DSP_HEX)
03273         printf("0x%8.8lx ", *((DWORD *) pdata));
03274       pdata = (char *) (((DWORD *) pdata) + 1);
03275       j++;
03276       break;
03277     case TID_DWORD:
03278       if (j > 7) {
03279         printf("\n%4i-> ", i);
03280         j = 0;
03281         i += 8;
03282       }
03283       if (dsp_fmt == DSP_DEC)
03284         printf("%8.1li ", *((DWORD *) pdata));
03285       if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03286         printf("0x%8.8lx ", *((DWORD *) pdata));
03287       pdata = (char *) (((DWORD *) pdata) + 1);
03288       j++;
03289       break;
03290     case TID_INT:
03291       if (j > 7) {
03292         printf("\n%4i-> ", i);
03293         j = 0;
03294         i += 8;
03295       }
03296       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03297         printf("%8.1li ", *((DWORD *) pdata));
03298       if (dsp_fmt == DSP_HEX)
03299         printf("0x%8.8lx ", *((DWORD *) pdata));
03300       pdata = (char *) (((DWORD *) pdata) + 1);
03301       j++;
03302       break;
03303     case TID_WORD:
03304       if (j > 7) {
03305         printf("\n%4i-> ", i);
03306         j = 0;
03307         i += 8;
03308       }
03309       if (dsp_fmt == DSP_DEC)
03310         printf("%5.1i ", *((WORD *) pdata));
03311       if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03312         printf("0x%4.4x ", *((WORD *) pdata));
03313       pdata = (char *) (((WORD *) pdata) + 1);
03314       j++;
03315       break;
03316     case TID_SHORT:
03317       if (j > 7) {
03318         printf("\n%4i-> ", i);
03319         j = 0;
03320         i += 8;
03321       }
03322       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03323         printf("%5.1i ", *((short *) pdata));
03324       if (dsp_fmt == DSP_HEX)
03325         printf("0x%4.4x ", *((short *) pdata));
03326       pdata = (char *) (((short *) pdata) + 1);
03327       j++;
03328       break;
03329     case TID_BYTE:
03330     case TID_STRUCT:
03331       if (j > 15) {
03332         printf("\n%4i-> ", i);
03333         j = 0;
03334         i += 16;
03335       }
03336       if (dsp_fmt == DSP_DEC)
03337         printf("%4.i ", *((BYTE *) pdata));
03338       if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03339         printf("0x%2.2x ", *((BYTE *) pdata));
03340       pdata++;
03341       j++;
03342       break;
03343     case TID_SBYTE:
03344       if (j > 15) {
03345         printf("\n%4i-> ", i);
03346         j = 0;
03347         i += 16;
03348       }
03349       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03350         printf("%4.i ", *((BYTE *) pdata));
03351       if (dsp_fmt == DSP_HEX)
03352         printf("0x%2.2x ", *((BYTE *) pdata));
03353       pdata++;
03354       j++;
03355       break;
03356     case TID_BOOL:
03357       if (j > 15) {
03358         printf("\n%4i-> ", i);
03359         j = 0;
03360         i += 16;
03361       }
03362       (*((BOOL *) pdata) != 0) ? printf("Y ") : printf("N ");
03363       pdata = (char *) (((DWORD *) pdata) + 1);
03364       j++;
03365       break;
03366     case TID_CHAR:
03367       if (j > 15) {
03368         printf("\n%4i-> ", i);
03369         j = 0;
03370         i += 16;
03371       }
03372       if (dsp_fmt == DSP_DEC)
03373         printf("%3.i ", *((BYTE *) pdata));
03374       if ((dsp_fmt == DSP_ASC) || (dsp_fmt == DSP_UNK))
03375         printf("%1.1s ", (char *) pdata);
03376       if (dsp_fmt == DSP_HEX)
03377         printf("0x%2.2x ", *((BYTE *) pdata));
03378       pdata++;
03379       j++;
03380       break;
03381     default:
03382       printf("bank type not supported (%d)\n", type);
03383       return;
03384       break;
03385     }
03386   }                             /* end of bank */
03387   printf("\n");
03388   return;
03389 }
03390 
03391 /*------------------------------------------------------------------*/
03392 void midas_bank_display32(BANK32 * pbk, INT dsp_fmt)
03393 /********************************************************************\
03394 Routine: midas_bank_display32
03395 Purpose: display on screen the pointed MIDAS bank data using MIDAS Bank structure.
03396 for 32bit length banks
03397 Input:
03398 BANK32 *  pbk            pointer to the BANK
03399 INT     dsp_fmt        display format (DSP_DEC/HEX)
03400 Output:
03401 none
03402 Function value:
03403 none
03404 \********************************************************************/
03405 {
03406   char bank_name[5], strbktype[32];
03407   char *pdata, *pendbk;
03408   DWORD length_type = 0, lrl;
03409   INT type, i, j;
03410 
03411   lrl = pbk->data_size;         /* in bytes */
03412   type = pbk->type & 0xff;
03413   bank_name[4] = 0;
03414   memcpy(bank_name, (char *) (pbk->name), 4);
03415   pdata = (char *) (pbk + 1);
03416 
03417   j = 64;                       /* elements within line */
03418   i = 1;                        /* data counter */
03419   strcpy(strbktype, "Unknown format");
03420   if (type == TID_DOUBLE) {
03421     length_type = sizeof(double);
03422     strcpy(strbktype, "double*8");
03423   }
03424   if (type == TID_FLOAT) {
03425     length_type = sizeof(float);
03426     strcpy(strbktype, "Real*4 (FMT machine dependent)");
03427   }
03428   if (type == TID_DWORD) {
03429     length_type = sizeof(DWORD);
03430     strcpy(strbktype, "Unsigned Integer*4");
03431   }
03432   if (type == TID_INT) {
03433     length_type = sizeof(INT);
03434     strcpy(strbktype, "Signed Integer*4");
03435   }
03436   if (type == TID_WORD) {
03437     length_type = sizeof(WORD);
03438     strcpy(strbktype, "Unsigned Integer*2");
03439   }
03440   if (type == TID_SHORT) {
03441     length_type = sizeof(short);
03442     strcpy(strbktype, "Signed Integer*2");
03443   }
03444   if (type == TID_BYTE) {
03445     length_type = sizeof(BYTE);
03446     strcpy(strbktype, "8 bit Bytes");
03447   }
03448   if (type == TID_SBYTE) {
03449     length_type = sizeof(BYTE);
03450     strcpy(strbktype, "Signed Bytes");
03451   }
03452   if (type == TID_BOOL) {
03453     length_type = sizeof(DWORD);
03454     strcpy(strbktype, "Boolean");
03455   }
03456   if (type == TID_CHAR) {
03457     length_type = sizeof(char);
03458     strcpy(strbktype, "8 bit ASCII");
03459   }
03460   if (type == TID_STRUCT) {
03461     length_type = sizeof(char);
03462     strcpy(strbktype, "STRUCT (not supported->8 bits)");
03463   }
03464   printf("\nBank:%s Length: %li(I*1)/%li(I*4)/%li(Type) Type:%s",
03465          bank_name, lrl, lrl >> 2, lrl / length_type, strbktype);
03466 
03467   pendbk = pdata + lrl;
03468 
03469   while (pdata < pendbk) {
03470     switch (type) {
03471     case TID_DOUBLE:
03472       if (j > 3) {
03473         printf("\n%4i-> ", i);
03474         j = 0;
03475         i += 4;
03476       }
03477       printf("%15.5le    ", *((double *) pdata));
03478       pdata = (char *) (((double *) pdata) + 1);
03479       j++;
03480       break;
03481     case TID_FLOAT:
03482       if (j > 7) {
03483         printf("\n%4i-> ", i);
03484         j = 0;
03485         i += 8;
03486       }
03487       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03488         printf("%8.3e ", *((float *) pdata));
03489       if (dsp_fmt == DSP_HEX)
03490         printf("0x%8.8lx ", *((DWORD *) pdata));
03491       pdata = (char *) (((DWORD *) pdata) + 1);
03492       j++;
03493       break;
03494     case TID_DWORD:
03495       if (j > 7) {
03496         printf("\n%4i-> ", i);
03497         j = 0;
03498         i += 8;
03499       }
03500       if (dsp_fmt == DSP_DEC)
03501         printf("%8.1li ", *((DWORD *) pdata));
03502       if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03503         printf("0x%8.8lx ", *((DWORD *) pdata));
03504       pdata = (char *) (((DWORD *) pdata) + 1);
03505       j++;
03506       break;
03507     case TID_INT:
03508       if (j > 7) {
03509         printf("\n%4i-> ", i);
03510         j = 0;
03511         i += 8;
03512       }
03513       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03514         printf("%8.1li ", *((DWORD *) pdata));
03515       if (dsp_fmt == DSP_HEX)
03516         printf("0x%8.8lx ", *((DWORD *) pdata));
03517       pdata = (char *) (((DWORD *) pdata) + 1);
03518       j++;
03519       break;
03520     case TID_WORD:
03521       if (j > 7) {
03522         printf("\n%4i-> ", i);
03523         j = 0;
03524         i += 8;
03525       }
03526       if (dsp_fmt == DSP_DEC)
03527         printf("%5.1i ", *((WORD *) pdata));
03528       if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03529         printf("0x%4.4x ", *((WORD *) pdata));
03530       pdata = (char *) (((WORD *) pdata) + 1);
03531       j++;
03532       break;
03533     case TID_SHORT:
03534       if (j > 7) {
03535         printf("\n%4i-> ", i);
03536         j = 0;
03537         i += 8;
03538       }
03539       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03540         printf("%5.1i ", *((short *) pdata));
03541       if (dsp_fmt == DSP_HEX)
03542         printf("0x%4.4x ", *((short *) pdata));
03543       pdata = (char *) (((short *) pdata) + 1);
03544       j++;
03545       break;
03546     case TID_BYTE:
03547     case TID_STRUCT:
03548       if (j > 15) {
03549         printf("\n%4i-> ", i);
03550         j = 0;
03551         i += 16;
03552       }
03553       if (dsp_fmt == DSP_DEC)
03554         printf("%4.i ", *((BYTE *) pdata));
03555       if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03556         printf("0x%2.2x ", *((BYTE *) pdata));
03557       pdata++;
03558       j++;
03559       break;
03560     case TID_SBYTE:
03561       if (j > 15) {
03562         printf("\n%4i-> ", i);
03563         j = 0;
03564         i += 16;
03565       }
03566       if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03567         printf("%4.i ", *((BYTE *) pdata));
03568       if (dsp_fmt == DSP_HEX)
03569         printf("0x%2.2x ", *((BYTE *) pdata));
03570       pdata++;
03571       j++;
03572       break;
03573     case TID_BOOL:
03574       if (j > 15) {
03575         printf("\n%4i-> ", i);
03576         j = 0;
03577         i += 16;
03578       }
03579       (*((BOOL *) pdata) != 0) ? printf("Y ") : printf("N ");
03580       pdata = (char *) (((DWORD *) pdata) + 1);
03581       j++;
03582       break;
03583     case TID_CHAR:
03584       if (j > 15) {
03585         printf("\n%4i-> ", i);
03586         j = 0;
03587         i += 16;
03588       }
03589       if (dsp_fmt == DSP_DEC)
03590         printf("%3.i ", *((BYTE *) pdata));
03591       if (dsp_fmt == DSP_ASC || (dsp_fmt == DSP_UNK))
03592         printf("%1.1s ", (char *) pdata);
03593       if (dsp_fmt == DSP_HEX)
03594         printf("0x%2.2x ", *((BYTE *) pdata));
03595       pdata++;
03596       j++;
03597       break;
03598     default:
03599       printf("bank type not supported (%d)\n", type);
03600       return;
03601       break;
03602     }
03603   }                             /* end of bank */
03604   printf("\n");
03605   return;
03606 }
03607 
03608 /*-- GENERAL file fragmentation and recovery -----Section d)--------*/
03609 /*-- GENERAL file fragmentation and recovery -----------------------*/
03610 /*-- GENERAL file fragmentation and recovery -----------------------*/
03611 /*-- GENERAL file fragmentation and recovery -----------------------*/
03612 /*------------------------------------------------------------------*/
03613 INT yb_file_recompose(void *pevt, INT format, char *svpath, INT file_mode)
03614 /********************************************************************\
03615 Routine: external file_recompose
03616 Purpose: Receive event which are expected to be file oriented with
03617 YM_xFILE header.
03618 Input:
03619 char * pevt           pointer to a YBOS event (->LRL).
03620 char * svpath         path where to save file
03621 INT    file_mode      NO_RUN : save file under original name
03622 ADD_RUN: cat run number at end of file name
03623 Output:
03624 none
03625 Function value:
03626 YB_SUCCESS         OP successfull
03627 YB_INCOMPLETE      file compose channels still open
03628 YB_COMPLETE        All file compose channels closed or complete
03629 status             -x error of inner call
03630 \********************************************************************/
03631 {
03632   YM_CFILE *pmyfch;
03633   int slot, status;
03634 
03635   if (file_mode == YB_NO_RECOVER)
03636     return YB_SUCCESS;
03637 
03638   if (format == FORMAT_YBOS) {
03639     if ((status = ybk_locate((DWORD *) pevt, "CFIL", &pmyfch)) <= 0)
03640       return (status);
03641   } else if (format == FORMAT_MIDAS) {
03642     if ((((EVENT_HEADER *) pevt)->event_id == EVENTID_BOR) ||
03643         (((EVENT_HEADER *) pevt)->event_id == EVENTID_EOR) ||
03644         (((EVENT_HEADER *) pevt)->event_id == EVENTID_MESSAGE))
03645       return YB_BANK_NOT_FOUND;
03646 
03647     pevt = (EVENT_HEADER *) pevt + 1;
03648     if ((status = bk_locate(pevt, "CFIL", &pmyfch)) <= 0)
03649       return (status);
03650   }
03651 
03652   printf("%i - %i - %i - %i - %i -%i -%i \n", pmyfch->file_ID,
03653          pmyfch->size, pmyfch->fragment_size, pmyfch->total_fragment,
03654          pmyfch->current_fragment, pmyfch->current_read_byte,
03655          pmyfch->run_number);
03656 
03657   /* check if file is in progress */
03658   for (slot = 0; slot < MAX_YM_FILE; slot++) {
03659     if ((ymfile[slot].fHandle != 0)
03660         && (pmyfch->file_ID == ymfile[slot].file_ID)) {
03661       /* Yep file in progress for that file_ID */
03662       if ((status = yb_ymfile_update(slot, format, pevt)) != YB_SUCCESS) {
03663         printf("yb_ymfile_update() failed\n");
03664         return status;
03665       }
03666       goto check;
03667     }
03668     /* next slot */
03669   }
03670   /* current fragment not registered => new file */
03671   /* open file, get slot back */
03672   if ((status =
03673        yb_ymfile_open(&slot, format, pevt, svpath,
03674                       file_mode)) != YB_SUCCESS) {
03675     printf("yb_ymfile_open() failed\n");
03676     return status;
03677   }
03678   /* update file */
03679   if ((status = yb_ymfile_update(slot, format, pevt)) != YB_SUCCESS) {
03680     printf("yb_ymfile_update() failed\n");
03681     return status;
03682   }
03683 
03684 check:
03685   /* for completion of recovery on ALL files */
03686   for (slot = 0; slot < MAX_YM_FILE; slot++) {
03687     if (ymfile[slot].fHandle != 0) {
03688       /* Yes still some file composition in progress */
03689       return YB_INCOMPLETE;
03690     }
03691     /* next slot */
03692   }
03693   return YB_COMPLETE;
03694 }
03695 
03696 /*------------------------------------------------------------------*/
03697 INT yb_ymfile_open(int *slot, int fmt, void *pevt, char *svpath,
03698                    INT file_mode)
03699 /********************************************************************\
03700 Routine: yb_ymfile_open
03701 Purpose: Prepare channel for receiving event of YM_FILE type.
03702 Input:
03703 void * pevt           pointer to the data portion of the event
03704 char * svpath         path where to save file
03705 INT    file_mode      NO_RUN : save file under original name
03706 ADD_RUN: cat run number at end of file name
03707 Output:
03708 INT  * slot           index of the opened channel
03709 Function value:
03710 YB_SUCCESS          Successful completion
03711 YB_FAIL_OPEN        cannot create output file
03712 YB_NOMORE_SLOT      no more slot for starting dump
03713 \********************************************************************/
03714 {
03715   YM_CFILE *pmyfch;
03716   YM_PFILE *pmyfph;
03717   char *pfilename;
03718   char srun[16], sslot[3];
03719   int i, status;
03720 
03721   /* initialize invalid slot */
03722   *slot = -1;
03723 
03724   if (fmt == FORMAT_YBOS) {
03725     if ((status = ybk_locate((DWORD *) pevt, "CFIL", &pmyfch)) <= 0)
03726       return (status);
03727     if ((status = ybk_locate((DWORD *) pevt, "PFIL", &pmyfph)) <= 0)
03728       return (status);
03729   } else if (fmt == FORMAT_MIDAS) {
03730     if ((status = bk_locate(pevt, "CFIL", &pmyfch)) <= 0)
03731       return (status);
03732     if ((status = bk_locate(pevt, "PFIL", &pmyfph)) <= 0)
03733       return (status);
03734   } else
03735     return -2;
03736   /* find free slot */
03737   for (i = 0; i < MAX_YM_FILE; i++)
03738     if (ymfile[i].fHandle == 0)
03739       break;
03740   if (i < MAX_YM_FILE) {
03741     /* copy necessary file header info */
03742     ymfile[i].file_ID = pmyfch->file_ID;
03743     strcpy(ymfile[i].path, pmyfph->path);
03744 
03745     /* extract file name */
03746     pfilename = pmyfph->path;
03747     if (strrchr(pmyfph->path, '/') > pfilename)
03748       pfilename = strrchr(pmyfph->path, '/');
03749     if (strrchr(pmyfph->path, '\\') > pfilename)
03750       pfilename = strrchr(pmyfph->path, '\\');
03751     if (strrchr(pmyfph->path, ':') > pfilename)
03752       pfilename = strrchr(pmyfph->path, ':');
03753     if (*pfilename != pmyfph->path[0])
03754       pfilename++;
03755 
03756     /* add path name */
03757     if (svpath[0] != 0) {
03758       ymfile[i].path[0] = 0;
03759       strncat(ymfile[i].path, svpath, strlen(svpath));
03760       if (ymfile[i].path[strlen(ymfile[i].path) - 1] != DIR_SEPARATOR)
03761         strcat(ymfile[i].path, DIR_SEPARATOR_STR);
03762       /* append the file name */
03763       strcat(ymfile[i].path, pfilename);
03764     }
03765     if (file_mode == YB_ADD_RUN) {      /* append run number */
03766       strcat(ymfile[i].path, ".");
03767       sprintf(srun, "Run%4.4i", pmyfch->run_number);
03768       strncat(ymfile[i].path, srun, strlen(srun));
03769     }
03770     /* differentiate the possible file dumps 
03771        as the path is unique */
03772     if (i > 0) {
03773       sprintf(sslot, ".%03i", i);
03774       strcat(ymfile[i].path, sslot);
03775     }
03776 
03777     /* open device */
03778     if ((ymfile[i].fHandle =
03779          open(ymfile[i].path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
03780               0644)) == -1) {
03781       ymfile[i].fHandle = 0;
03782       printf("File %s cannot be created\n", ymfile[i].path);
03783       return (SS_FILE_ERROR);
03784     }
03785   } else {
03786     /* no more slot */
03787     printf("No more slot for file %s\n", pmyfph->path);
03788     return YB_NOMORE_SLOT;
03789   }
03790 
03791   ymfile[i].current_read_byte = 0;
03792   ymfile[i].current_fragment = 0;
03793   *slot = i;
03794   return YB_SUCCESS;
03795 }
03796 
03797 /*------------------------------------------------------------------*/
03798 INT yb_ymfile_update(int slot, int fmt, void *pevt)
03799 /********************************************************************\
03800 Routine: yb_ymfile_update
03801 Purpose: dump Midas/Ybos event to file for YBOS file oriented event type.
03802 Input:
03803 char * pevt           pointer to the data portion of the event.
03804 Output:
03805 INT  slot             valid index of the opened channel.
03806 Function value:
03807 YB_SUCCESS         Successful completion
03808 -1                     error
03809 \********************************************************************/
03810 {
03811   YM_CFILE *pmyfch;
03812   char *pmyfd;
03813   int status;
03814   int nwrite;
03815 
03816   if (fmt == FORMAT_YBOS) {
03817     if ((status = ybk_locate((DWORD *) pevt, "CFIL", &pmyfch)) <= 0)
03818       return (status);
03819     if ((status = ybk_locate((DWORD *) pevt, "DFIL", &pmyfd)) <= 0)
03820       return (status);
03821 
03822     /* check sequence order */
03823     if (ymfile[slot].current_fragment + 1 != pmyfch->current_fragment) {
03824       printf("Out of sequence %i / %i\n", ymfile[slot].current_fragment,
03825              pmyfch->current_fragment);
03826     }
03827     /* dump fragment to file */
03828     nwrite = write(ymfile[slot].fHandle, pmyfd, pmyfch->fragment_size);
03829 
03830     /* update current file record */
03831     ymfile[slot].current_read_byte += nwrite;
03832     ymfile[slot].current_fragment++;
03833     /* check if file has to be closed */
03834     if (ymfile[slot].current_fragment == pmyfch->total_fragment) {
03835       /* file complete */
03836       close(ymfile[slot].fHandle);
03837       printf("File %s (%i) completed\n", ymfile[slot].path,
03838              ymfile[slot].current_read_byte);
03839       /* cleanup slot */
03840       ymfile[slot].fHandle = 0;
03841       return YB_SUCCESS;
03842     } /* close file */
03843     else {
03844       /* fragment retrieved wait next one */
03845       return YB_SUCCESS;
03846     }
03847   } else if (fmt == FORMAT_MIDAS) {
03848     if ((status = bk_locate(pevt, "CFIL", &pmyfch)) <= 0)
03849       return (status);
03850     if ((status = bk_locate(pevt, "DFIL", &pmyfd)) <= 0)
03851       return (status);
03852 
03853     /* check sequence order */
03854     if (ymfile[slot].current_fragment + 1 != pmyfch->current_fragment) {
03855       printf("Out of sequence %i / %i\n", ymfile[slot].current_fragment,
03856              pmyfch->current_fragment);
03857     }
03858     /* dump fragment to file */
03859     nwrite = write(ymfile[slot].fHandle, pmyfd, pmyfch->fragment_size);
03860 
03861     /* update current file record */
03862     ymfile[slot].current_read_byte += nwrite;
03863     ymfile[slot].current_fragment++;
03864     /* check if file has to be closed */
03865     if (ymfile[slot].current_fragment == pmyfch->total_fragment) {
03866       /* file complete */
03867       close(ymfile[slot].fHandle);
03868       printf("File %s (%i) completed\n", ymfile[slot].path,
03869              ymfile[slot].current_read_byte);
03870       /* cleanup slot */
03871       ymfile[slot].fHandle = 0;
03872       return YB_SUCCESS;
03873     } /* close file */
03874     else {
03875       /* fragment retrieved wait next one */
03876       return YB_SUCCESS;
03877     }
03878   } else
03879     return YB_UNKNOWN_FORMAT;
03880 }
03881 #endif                          /* OS_VXWORKS Frontend */
03882 
03883 /*------------------------------------------------------------------*/
03884 /*------------------------------------------------------------------*/
03885 /*------------------------------------------------------------------*/
03886 /*--END of YBOS.C---------------------------------------------------*/
03887 /*------------------------------------------------------------------*/
03888 /*------------------------------------------------------------------*/
03889 /*------------------------------------------------------------------*/
03890 
03891 
03892 /**dox***************************************************************/
03893 #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
03894 
03895 /**dox***************************************************************/
03896 /** @} */// end of ybosbankc
03897 
03898 /**dox***************************************************************/
03899 /** @} */// end of ybosincludecode

Midas DOC Version 1.9.3 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Suzannah Daviel - Doxygen - Peter Green - Greg Hackman - Gertjan Hofman - Paul Knowles - Rudi Meier - Glenn Moloney - Dave Morris - Konstantin Olchanski - Renee Poutissou - Andreas Suter - Piotr Adam Zolnierczuk