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

Midas DOC Version 1.9.5 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - 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