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