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