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

Midas DOC Version 2.0.2 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Exaos Lee - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk