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

Midas DOC Version 1.9.5 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - 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 - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk