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 4717 2010-04-29 00:36:57Z amaudruz $
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 HAVE_FTPLIB into makefile (!vxWorks) */
00098 
00099 #define TRACE
00100 #include "midas.h"
00101 #include "msystem.h"
00102 
00103 #ifdef HAVE_FTPLIB
00104 #include "ftplib.h"
00105 #endif
00106 
00107 #ifdef HAVE_ZLIB
00108 #include "zlib.h"
00109 #endif
00110 
00111 #define HAVE_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 HAVE_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 HAVE_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 = TRUE;        // 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 HAVE_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 HAVE_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 HAVE_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 HAVE_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 HAVE_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 HAVE_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 HAVE_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 HAVE_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 HAVE_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 HAVE_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 HAVE_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 + 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 
02800    return;
02801 }
02802 
02803 /*------------------------------------------------------------------*/
02804 void yb_any_bank_display(void *pmbh, void *pbk, INT data_fmt, INT dsp_mode, INT dsp_fmt)
02805 /********************************************************************\
02806 Routine: external yb_any_bank_display
02807 Purpose: display on screen the given bank.
02808 Input:
02809 void * pbk          pointer to the bank
02810 INT  data_fmt       YBOS or MIDAS
02811 INT  dsp_mode       display mode (RAW/BANK)
02812 INT  dsp_fmt        display format (DSP_DEC/HEX)
02813 Output:             
02814 none
02815 Function value:
02816 none
02817 \********************************************************************/
02818 {
02819    if (dsp_mode == DSP_RAW)
02820       yb_any_raw_bank_display(pbk, data_fmt, dsp_fmt);
02821    else {
02822       if (data_fmt == FORMAT_MIDAS) {
02823          if (bk_is32(pmbh))
02824             midas_bank_display32((BANK32 *) pbk, dsp_fmt);
02825          else
02826             midas_bank_display((BANK *) pbk, dsp_fmt);
02827       } else if (data_fmt == FORMAT_YBOS)
02828          ybos_bank_display((YBOS_BANK_HEADER *) pbk, dsp_fmt);
02829    }
02830    return;
02831 }
02832 
02833 /*------------------------------------------------------------------*/
02834 void yb_any_raw_bank_display(void *pbank, INT data_fmt, INT dsp_fmt)
02835 /********************************************************************\
02836 Routine: yb_any_raw_bank_display
02837 Purpose: display on screen the RAW data of a given YBOS/MIDAS bank.
02838 Input:
02839 void  * pbank          pointer to the bank name
02840 INT     data_fmt       uses the YBOS or MIDAS event structure
02841 INT     dsp_fmt        display format (DSP_DEC/HEX)
02842 Output:
02843 none
02844 Function value:
02845 none
02846 \********************************************************************/
02847 {
02848    DWORD *pdata = NULL, lrl = 0, j, i;
02849 
02850    if (data_fmt == FORMAT_YBOS) {
02851       lrl = (((YBOS_BANK_HEADER *) pbank)->length) - 1;
02852       pdata = (DWORD *) (((YBOS_BANK_HEADER *) pbank) + 1);
02853    } else if (data_fmt == FORMAT_MIDAS) {
02854       lrl = ((BANK *) pbank)->data_size >> 2;   /* in DWORD */
02855       pdata = (DWORD *) ((BANK *) (pbank) + 1);
02856    }
02857 
02858    for (i = 0; i < lrl; i += NLINE) {
02859       j = 0;
02860       printf("\n%4i-> ", i + j + 1);
02861       for (j = 0; j < NLINE; j++) {
02862          if ((i + j) < lrl) {
02863             if (dsp_fmt == DSP_DEC)
02864                printf("%8.i ", *((DWORD *) pdata));
02865             if (dsp_fmt == DSP_ASC)
02866                printf("%8.8x ", *((DWORD *) pdata));
02867             if (dsp_fmt == DSP_HEX)
02868                printf("%8.8x ", *((DWORD *) pdata));
02869             pdata++;
02870          }
02871       }
02872    }
02873 }
02874 
02875 /*------------------------------------------------------------------*/
02876 void ybos_bank_display(YBOS_BANK_HEADER * pybk, INT dsp_fmt)
02877 /********************************************************************\
02878 Routine: ybos_event_display
02879 Purpose: display on screen the YBOS data in YBOS bank mode.
02880 Input:
02881 YBOS_BANK_HEADER * pybk     pointer to the bank header
02882 INT     dsp_fmt             display format (DSP_DEC/HEX)
02883 Output:             
02884 none
02885 Function value:
02886 none
02887 \********************************************************************/
02888 {
02889    char bank_name[5], strbktype[32];
02890    DWORD length_type = 0;
02891    DWORD *pdata, *pendbk;
02892    INT i, j;
02893 
02894    j = 8;                       /* elements within line */
02895    i = 1;                       /* data counter */
02896 
02897    pdata = (DWORD *) (pybk + 1);
02898    memcpy(&bank_name[0], (char *) &pybk->name, 4);
02899    bank_name[4] = 0;
02900 
02901    if (pybk->type == D8_BKTYPE) {
02902       length_type = ((pybk->length - 1) >> 1);
02903       sprintf(strbktype, "double*8 (FMT machine dependent)");
02904    }
02905    if (pybk->type == F4_BKTYPE) {
02906       length_type = pybk->length - 1;
02907       strcpy(strbktype, "Real*4 (FMT machine dependent)");
02908    }
02909    if (pybk->type == I4_BKTYPE) {
02910       length_type = pybk->length - 1;
02911       strcpy(strbktype, "Integer*4");
02912    }
02913    if (pybk->type == I2_BKTYPE) {
02914       length_type = ((pybk->length - 1) << 1);
02915       strcpy(strbktype, "Integer*2");
02916    }
02917    if (pybk->type == I1_BKTYPE) {
02918       length_type = ((pybk->length - 1) << 2);
02919       strcpy(strbktype, "8 bit Bytes");
02920    }
02921    if (pybk->type == A1_BKTYPE) {
02922       length_type = ((pybk->length - 1) << 2);
02923       strcpy(strbktype, "8 bit ASCII");
02924    }
02925    printf("\nBank:%s Length: %i(I*1)/%i(I*4)/%i(Type) Type:%s",
02926           bank_name, ((pybk->length - 1) << 2), pybk->length - 1, length_type, strbktype);
02927    j = 16;
02928 
02929    pendbk = pdata + pybk->length - 1;
02930    while ((BYTE *) pdata < (BYTE *) pendbk) {
02931       switch (pybk->type) {
02932       case D8_BKTYPE:
02933          if (j > 7) {
02934             printf("\n%4i-> ", i);
02935             j = 0;
02936             i += 8;
02937          }
02938          printf("%15.5le  ", *((double *) pdata));
02939          pdata = (DWORD *) (((double *) pdata) + 1);
02940          j++;
02941          break;
02942       case F4_BKTYPE:
02943          if (j > 7) {
02944             printf("\n%4i-> ", i);
02945             j = 0;
02946             i += 8;
02947          }
02948          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
02949             printf("%8.3e ", *((float *) pdata));
02950          if (dsp_fmt == DSP_HEX)
02951             printf("0x%8.8x ", *((DWORD *) pdata));
02952          pdata++;
02953          j++;
02954          break;
02955       case I4_BKTYPE:
02956          if (j > 7) {
02957             printf("\n%4i-> ", i);
02958             j = 0;
02959             i += 8;
02960          }
02961          if (dsp_fmt == DSP_DEC)
02962             printf("%8.1i ", *((DWORD *) pdata));
02963          if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
02964             printf("0x%8.8x ", *((DWORD *) pdata));
02965          pdata++;
02966          j++;
02967          break;
02968       case I2_BKTYPE:
02969          if (j > 7) {
02970             printf("\n%4i-> ", i);
02971             j = 0;
02972             i += 8;
02973          }
02974          if (dsp_fmt == DSP_DEC)
02975             printf("%5.1i ", *((WORD *) pdata));
02976          if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
02977             printf("0x%4.4x ", *((WORD *) pdata));
02978          pdata = (DWORD *) (((WORD *) pdata) + 1);
02979          j++;
02980          break;
02981       case A1_BKTYPE:
02982          if (j > 15) {
02983             printf("\n%4i-> ", i);
02984             j = 0;
02985             i += 16;
02986          }
02987          if ((dsp_fmt == DSP_ASC) || (dsp_fmt == DSP_UNK))
02988             printf("%1.1s ", (char *) pdata);
02989          if (dsp_fmt == DSP_DEC)
02990             printf("%2.i ", *((BYTE *) pdata));
02991          if (dsp_fmt == DSP_HEX)
02992             printf("0x%2.2x ", *((BYTE *) pdata));
02993          pdata = (DWORD *) (((BYTE *) pdata) + 1);
02994          j++;
02995          break;
02996       case I1_BKTYPE:
02997          if (j > 7) {
02998             printf("\n%4i-> ", i);
02999             j = 0;
03000             i += 8;
03001          }
03002          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03003             printf("%4.i ", *((BYTE *) pdata));
03004          if (dsp_fmt == DSP_HEX)
03005             printf("0x%2.2x ", *((BYTE *) pdata));
03006          pdata = (DWORD *) (((BYTE *) pdata) + 1);
03007          j++;
03008          break;
03009       default:
03010          printf("ybos_bak_display-E- Unknown bank type %i\n", pybk->type);
03011          break;
03012 
03013       }                         /* switch */
03014    }                            /* while next bank */
03015    printf("\n");
03016    return;
03017 }
03018 
03019 /*------------------------------------------------------------------*/
03020 void midas_bank_display(BANK * pbk, INT dsp_fmt)
03021 /******************************* *************************************\
03022 Routine: midas_bank_display
03023 Purpose: display on screen the pointed MIDAS bank data using MIDAS Bank structure.
03024 Input:
03025 BANK *  pbk            pointer to the BANK
03026 INT     dsp_fmt        display format (DSP_DEC/HEX)
03027 Output:
03028 none
03029 Function value:
03030 none
03031 \********************************************************************/
03032 {
03033    char bank_name[5], strbktype[32];
03034    char *pdata, *pendbk;
03035    DWORD length_type = 0, lrl;
03036    INT type, i, j;
03037 
03038    lrl = pbk->data_size;        /* in bytes */
03039    type = pbk->type & 0xff;
03040    bank_name[4] = 0;
03041    memcpy(bank_name, (char *) (pbk->name), 4);
03042    pdata = (char *) (pbk + 1);
03043 
03044    j = 64;                      /* elements within line */
03045    i = 1;                       /* data counter */
03046    strcpy(strbktype, "Unknown format");
03047    if (type == TID_DOUBLE) {
03048       length_type = sizeof(double);
03049       strcpy(strbktype, "double*8");
03050    }
03051    if (type == TID_FLOAT) {
03052       length_type = sizeof(float);
03053       strcpy(strbktype, "Real*4 (FMT machine dependent)");
03054    }
03055    if (type == TID_DWORD) {
03056       length_type = sizeof(DWORD);
03057       strcpy(strbktype, "Unsigned Integer*4");
03058    }
03059    if (type == TID_INT) {
03060       length_type = sizeof(INT);
03061       strcpy(strbktype, "Signed Integer*4");
03062    }
03063    if (type == TID_WORD) {
03064       length_type = sizeof(WORD);
03065       strcpy(strbktype, "Unsigned Integer*2");
03066    }
03067    if (type == TID_SHORT) {
03068       length_type = sizeof(short);
03069       strcpy(strbktype, "Signed Integer*2");
03070    }
03071    if (type == TID_BYTE) {
03072       length_type = sizeof(BYTE);
03073       strcpy(strbktype, "Unsigned Bytes");
03074    }
03075    if (type == TID_SBYTE) {
03076       length_type = sizeof(BYTE);
03077       strcpy(strbktype, "Signed Bytes");
03078    }
03079    if (type == TID_BOOL) {
03080       length_type = sizeof(DWORD);
03081       strcpy(strbktype, "Boolean");
03082    }
03083    if (type == TID_CHAR) {
03084       length_type = sizeof(char);
03085       strcpy(strbktype, "8 bit ASCII");
03086    }
03087    if (type == TID_STRUCT) {
03088       length_type = sizeof(char);
03089       strcpy(strbktype, "STRUCT (not supported->8 bits)");
03090    }
03091    if (type == TID_STRING) {
03092       length_type = sizeof(char);
03093       strcpy(strbktype, "String 8bit ASCII");
03094    }
03095 
03096    printf("\nBank:%s Length: %i(I*1)/%i(I*4)/%i(Type) Type:%s",
03097           bank_name, lrl, lrl >> 2, lrl / (length_type == 0 ? 1 : length_type), strbktype);
03098 
03099    pendbk = pdata + lrl;
03100    while (pdata < pendbk) {
03101       switch (type) {
03102       case TID_DOUBLE:
03103          if (j > 3) {
03104             printf("\n%4i-> ", i);
03105             j = 0;
03106             i += 4;
03107          }
03108          printf("%15.5le    ", *((double *) pdata));
03109          pdata = (char *) (((double *) pdata) + 1);
03110          j++;
03111          break;
03112       case TID_FLOAT:
03113          if (j > 7) {
03114             printf("\n%4i-> ", i);
03115             j = 0;
03116             i += 8;
03117          }
03118          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03119             printf("%8.3e ", *((float *) pdata));
03120          if (dsp_fmt == DSP_HEX)
03121             printf("0x%8.8x ", *((DWORD *) pdata));
03122          pdata = (char *) (((DWORD *) pdata) + 1);
03123          j++;
03124          break;
03125       case TID_DWORD:
03126          if (j > 7) {
03127             printf("\n%4i-> ", i);
03128             j = 0;
03129             i += 8;
03130          }
03131          if (dsp_fmt == DSP_DEC)
03132             printf("%8.1i ", *((DWORD *) pdata));
03133          if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03134             printf("0x%8.8x ", *((DWORD *) pdata));
03135          pdata = (char *) (((DWORD *) pdata) + 1);
03136          j++;
03137          break;
03138       case TID_INT:
03139          if (j > 7) {
03140             printf("\n%4i-> ", i);
03141             j = 0;
03142             i += 8;
03143          }
03144          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03145             printf("%8.1i ", *((DWORD *) pdata));
03146          if (dsp_fmt == DSP_HEX)
03147             printf("0x%8.8x ", *((DWORD *) pdata));
03148          pdata = (char *) (((DWORD *) pdata) + 1);
03149          j++;
03150          break;
03151       case TID_WORD:
03152          if (j > 7) {
03153             printf("\n%4i-> ", i);
03154             j = 0;
03155             i += 8;
03156          }
03157          if (dsp_fmt == DSP_DEC)
03158             printf("%5.1i ", *((WORD *) pdata));
03159          if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03160             printf("0x%4.4x ", *((WORD *) pdata));
03161          pdata = (char *) (((WORD *) pdata) + 1);
03162          j++;
03163          break;
03164       case TID_SHORT:
03165          if (j > 7) {
03166             printf("\n%4i-> ", i);
03167             j = 0;
03168             i += 8;
03169          }
03170          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03171             printf("%5.1i ", *((short *) pdata));
03172          if (dsp_fmt == DSP_HEX)
03173             printf("0x%4.4x ", *((short *) pdata));
03174          pdata = (char *) (((short *) pdata) + 1);
03175          j++;
03176          break;
03177       case TID_BYTE:
03178       case TID_STRUCT:
03179          if (j > 15) {
03180             printf("\n%4i-> ", i);
03181             j = 0;
03182             i += 16;
03183          }
03184          if (dsp_fmt == DSP_DEC)
03185             printf("%4.i ", *((BYTE *) pdata));
03186          if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03187             printf("0x%2.2x ", *((BYTE *) pdata));
03188          pdata++;
03189          j++;
03190          break;
03191       case TID_SBYTE:
03192          if (j > 15) {
03193             printf("\n%4i-> ", i);
03194             j = 0;
03195             i += 16;
03196          }
03197          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03198             printf("%4.i ", *((BYTE *) pdata));
03199          if (dsp_fmt == DSP_HEX)
03200             printf("0x%2.2x ", *((BYTE *) pdata));
03201          pdata++;
03202          j++;
03203          break;
03204       case TID_BOOL:
03205          if (j > 15) {
03206             printf("\n%4i-> ", i);
03207             j = 0;
03208             i += 16;
03209          }
03210          (*((BOOL *) pdata) != 0) ? printf("Y ") : printf("N ");
03211          pdata = (char *) (((DWORD *) pdata) + 1);
03212          j++;
03213          break;
03214       case TID_CHAR:
03215       case TID_STRING:
03216          if (j > 15) {
03217             printf("\n%4i-> ", i);
03218             j = 0;
03219             i += 16;
03220          }
03221          if (dsp_fmt == DSP_DEC)
03222             printf("%3.i ", *((BYTE *) pdata));
03223          if ((dsp_fmt == DSP_ASC) || (dsp_fmt == DSP_UNK))
03224             printf("%1.1s ", (char *) pdata);
03225          if (dsp_fmt == DSP_HEX)
03226             printf("0x%2.2x ", *((BYTE *) pdata));
03227          pdata++;
03228          j++;
03229          break;
03230       default:
03231          printf("bank type not supported (%d)\n", type);
03232          return;
03233          break;
03234       }
03235    }                            /* end of bank */
03236    printf("\n");
03237    return;
03238 }
03239 
03240 /*------------------------------------------------------------------*/
03241 void midas_bank_display32(BANK32 * pbk, INT dsp_fmt)
03242 /********************************************************************\
03243 Routine: midas_bank_display32
03244 Purpose: display on screen the pointed MIDAS bank data using MIDAS Bank structure.
03245 for 32bit length banks
03246 Input:
03247 BANK32 *  pbk            pointer to the BANK
03248 INT     dsp_fmt        display format (DSP_DEC/HEX)
03249 Output:
03250 none
03251 Function value:
03252 none
03253 \********************************************************************/
03254 {
03255    char bank_name[5], strbktype[32];
03256    char *pdata, *pendbk;
03257    DWORD length_type = 0, lrl;
03258    INT type, i, j;
03259 
03260    lrl = pbk->data_size;        /* in bytes */
03261    type = pbk->type & 0xff;
03262    bank_name[4] = 0;
03263    memcpy(bank_name, (char *) (pbk->name), 4);
03264    pdata = (char *) (pbk + 1);
03265 
03266    j = 64;                      /* elements within line */
03267    i = 1;                       /* data counter */
03268    strcpy(strbktype, "Unknown format");
03269    if (type == TID_DOUBLE) {
03270       length_type = sizeof(double);
03271       strcpy(strbktype, "double*8");
03272    }
03273    if (type == TID_FLOAT) {
03274       length_type = sizeof(float);
03275       strcpy(strbktype, "Real*4 (FMT machine dependent)");
03276    }
03277    if (type == TID_DWORD) {
03278       length_type = sizeof(DWORD);
03279       strcpy(strbktype, "Unsigned Integer*4");
03280    }
03281    if (type == TID_INT) {
03282       length_type = sizeof(INT);
03283       strcpy(strbktype, "Signed Integer*4");
03284    }
03285    if (type == TID_WORD) {
03286       length_type = sizeof(WORD);
03287       strcpy(strbktype, "Unsigned Integer*2");
03288    }
03289    if (type == TID_SHORT) {
03290       length_type = sizeof(short);
03291       strcpy(strbktype, "Signed Integer*2");
03292    }
03293    if (type == TID_BYTE) {
03294       length_type = sizeof(BYTE);
03295       strcpy(strbktype, "Unsigned Bytes");
03296    }
03297    if (type == TID_SBYTE) {
03298       length_type = sizeof(BYTE);
03299       strcpy(strbktype, "Signed Bytes");
03300    }
03301    if (type == TID_BOOL) {
03302       length_type = sizeof(DWORD);
03303       strcpy(strbktype, "Boolean");
03304    }
03305    if (type == TID_CHAR) {
03306       length_type = sizeof(char);
03307       strcpy(strbktype, "8 bit ASCII");
03308    }
03309    if (type == TID_STRUCT) {
03310       length_type = sizeof(char);
03311       strcpy(strbktype, "STRUCT (not supported->8 bits)");
03312    }
03313    if (type == TID_STRING) {
03314       length_type = sizeof(char);
03315       strcpy(strbktype, "String 8bit ASCI");
03316    }
03317 
03318    printf("\nBank:%s Length: %i(I*1)/%i(I*4)/%i(Type) Type:%s",
03319           bank_name, lrl, lrl >> 2, lrl / (length_type == 0 ? 1 : length_type), strbktype);
03320 
03321    pendbk = pdata + lrl;
03322    while (pdata < pendbk) {
03323       switch (type) {
03324       case TID_DOUBLE:
03325          if (j > 3) {
03326             printf("\n%4i-> ", i);
03327             j = 0;
03328             i += 4;
03329          }
03330          printf("%15.5e    ", *((double *) pdata));
03331          pdata = (char *) (((double *) pdata) + 1);
03332          j++;
03333          break;
03334       case TID_FLOAT:
03335          if (j > 7) {
03336             printf("\n%4i-> ", i);
03337             j = 0;
03338             i += 8;
03339          }
03340          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03341             printf("%8.3e ", *((float *) pdata));
03342          if (dsp_fmt == DSP_HEX)
03343             printf("0x%8.8x ", *((DWORD *) pdata));
03344          pdata = (char *) (((DWORD *) pdata) + 1);
03345          j++;
03346          break;
03347       case TID_DWORD:
03348          if (j > 7) {
03349             printf("\n%4i-> ", i);
03350             j = 0;
03351             i += 8;
03352          }
03353          if (dsp_fmt == DSP_DEC)
03354             printf("%8.1i ", *((DWORD *) pdata));
03355          if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03356             printf("0x%8.8x ", *((DWORD *) pdata));
03357          pdata = (char *) (((DWORD *) pdata) + 1);
03358          j++;
03359          break;
03360       case TID_INT:
03361          if (j > 7) {
03362             printf("\n%4i-> ", i);
03363             j = 0;
03364             i += 8;
03365          }
03366          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03367             printf("%8.1i ", *((DWORD *) pdata));
03368          if (dsp_fmt == DSP_HEX)
03369             printf("0x%8.8x ", *((DWORD *) pdata));
03370          pdata = (char *) (((DWORD *) pdata) + 1);
03371          j++;
03372          break;
03373       case TID_WORD:
03374          if (j > 7) {
03375             printf("\n%4i-> ", i);
03376             j = 0;
03377             i += 8;
03378          }
03379          if (dsp_fmt == DSP_DEC)
03380             printf("%5.1i ", *((WORD *) pdata));
03381          if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03382             printf("0x%4.4x ", *((WORD *) pdata));
03383          pdata = (char *) (((WORD *) pdata) + 1);
03384          j++;
03385          break;
03386       case TID_SHORT:
03387          if (j > 7) {
03388             printf("\n%4i-> ", i);
03389             j = 0;
03390             i += 8;
03391          }
03392          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03393             printf("%5.1i ", *((short *) pdata));
03394          if (dsp_fmt == DSP_HEX)
03395             printf("0x%4.4x ", *((short *) pdata));
03396          pdata = (char *) (((short *) pdata) + 1);
03397          j++;
03398          break;
03399       case TID_BYTE:
03400       case TID_STRUCT:
03401          if (j > 15) {
03402             printf("\n%4i-> ", i);
03403             j = 0;
03404             i += 16;
03405          }
03406          if (dsp_fmt == DSP_DEC)
03407             printf("%4.i ", *((BYTE *) pdata));
03408          if ((dsp_fmt == DSP_HEX) || (dsp_fmt == DSP_UNK))
03409             printf("0x%2.2x ", *((BYTE *) pdata));
03410          pdata++;
03411          j++;
03412          break;
03413       case TID_SBYTE:
03414          if (j > 15) {
03415             printf("\n%4i-> ", i);
03416             j = 0;
03417             i += 16;
03418          }
03419          if ((dsp_fmt == DSP_DEC) || (dsp_fmt == DSP_UNK))
03420             printf("%4.i ", *((BYTE *) pdata));
03421          if (dsp_fmt == DSP_HEX)
03422             printf("0x%2.2x ", *((BYTE *) pdata));
03423          pdata++;
03424          j++;
03425          break;
03426       case TID_BOOL:
03427          if (j > 15) {
03428             printf("\n%4i-> ", i);
03429             j = 0;
03430             i += 16;
03431          }
03432          (*((BOOL *) pdata) != 0) ? printf("Y ") : printf("N ");
03433          pdata = (char *) (((DWORD *) pdata) + 1);
03434          j++;
03435          break;
03436       case TID_CHAR:
03437       case TID_STRING:
03438          if (j > 15) {
03439             printf("\n%4i-> ", i);
03440             j = 0;
03441             i += 16;
03442          }
03443          if (dsp_fmt == DSP_DEC)
03444             printf("%3.i ", *((BYTE *) pdata));
03445          if (dsp_fmt == DSP_ASC || (dsp_fmt == DSP_UNK))
03446             printf("%1.1s ", (char *) pdata);
03447          if (dsp_fmt == DSP_HEX)
03448             printf("0x%2.2x ", *((BYTE *) pdata));
03449          pdata++;
03450          j++;
03451          break;
03452       default:
03453          printf("bank type not supported (%d)\n", type);
03454          return;
03455          break;
03456       }
03457    }                            /* end of bank */
03458    printf("\n");
03459    return;
03460 }
03461 
03462 /*-- GENERAL file fragmentation and recovery -----Section d)--------*/
03463 /*-- GENERAL file fragmentation and recovery -----------------------*/
03464 /*-- GENERAL file fragmentation and recovery -----------------------*/
03465 /*-- GENERAL file fragmentation and recovery -----------------------*/
03466 /*------------------------------------------------------------------*/
03467 INT yb_file_recompose(void *pevt, INT format, char *svpath, INT file_mode)
03468 /********************************************************************\
03469 Routine: external file_recompose
03470 Purpose: Receive event which are expected to be file oriented with
03471 YM_xFILE header.
03472 Input:
03473 char * pevt           pointer to a YBOS event (->LRL).
03474 char * svpath         path where to save file
03475 INT    file_mode      NO_RUN : save file under original name
03476 ADD_RUN: cat run number at end of file name
03477 Output:
03478 none
03479 Function value:
03480 YB_SUCCESS         OP successfull
03481 YB_INCOMPLETE      file compose channels still open
03482 YB_COMPLETE        All file compose channels closed or complete
03483 status             -x error of inner call
03484 \********************************************************************/
03485 {
03486    YM_CFILE *pmyfch;
03487    int slot, status;
03488 
03489    if (file_mode == YB_NO_RECOVER)
03490       return YB_SUCCESS;
03491 
03492    if (format == FORMAT_YBOS) {
03493       if ((status = ybk_locate((DWORD *) pevt, "CFIL", &pmyfch)) <= 0)
03494          return (status);
03495    } else if (format == FORMAT_MIDAS) {
03496       if ((((EVENT_HEADER *) pevt)->event_id == EVENTID_BOR) ||
03497           (((EVENT_HEADER *) pevt)->event_id == EVENTID_EOR) ||
03498           (((EVENT_HEADER *) pevt)->event_id == EVENTID_MESSAGE))
03499          return YB_BANK_NOT_FOUND;
03500 
03501       pevt = (EVENT_HEADER *) pevt + 1;
03502       if ((status = bk_locate(pevt, "CFIL", &pmyfch)) <= 0)
03503          return (status);
03504    }
03505 
03506    printf("%i - %i - %i - %i - %i -%i -%i \n", pmyfch->file_ID,
03507           pmyfch->size, pmyfch->fragment_size, pmyfch->total_fragment,
03508           pmyfch->current_fragment, pmyfch->current_read_byte, pmyfch->run_number);
03509 
03510    /* check if file is in progress */
03511    for (slot = 0; slot < MAX_YM_FILE; slot++) {
03512       if ((ymfile[slot].fHandle != 0)
03513           && (pmyfch->file_ID == ymfile[slot].file_ID)) {
03514          /* Yep file in progress for that file_ID */
03515          if ((status = yb_ymfile_update(slot, format, pevt)) != YB_SUCCESS) {
03516             printf("yb_ymfile_update() failed\n");
03517             return status;
03518          }
03519          goto check;
03520       }
03521       /* next slot */
03522    }
03523    /* current fragment not registered => new file */
03524    /* open file, get slot back */
03525    if ((status = yb_ymfile_open(&slot, format, pevt, svpath, file_mode)) != YB_SUCCESS) {
03526       printf("yb_ymfile_open() failed\n");
03527       return status;
03528    }
03529    /* update file */
03530    if ((status = yb_ymfile_update(slot, format, pevt)) != YB_SUCCESS) {
03531       printf("yb_ymfile_update() failed\n");
03532       return status;
03533    }
03534 
03535  check:
03536    /* for completion of recovery on ALL files */
03537    for (slot = 0; slot < MAX_YM_FILE; slot++) {
03538       if (ymfile[slot].fHandle != 0) {
03539          /* Yes still some file composition in progress */
03540          return YB_INCOMPLETE;
03541       }
03542       /* next slot */
03543    }
03544    return YB_COMPLETE;
03545 }
03546 
03547 /*------------------------------------------------------------------*/
03548 INT yb_ymfile_open(int *slot, int fmt, void *pevt, char *svpath, INT file_mode)
03549 /********************************************************************\
03550 Routine: yb_ymfile_open
03551 Purpose: Prepare channel for receiving event of YM_FILE type.
03552 Input:
03553 void * pevt           pointer to the data portion of the event
03554 char * svpath         path where to save file
03555 INT    file_mode      NO_RUN : save file under original name
03556 ADD_RUN: cat run number at end of file name
03557 Output:
03558 INT  * slot           index of the opened channel
03559 Function value:
03560 YB_SUCCESS          Successful completion
03561 YB_FAIL_OPEN        cannot create output file
03562 YB_NOMORE_SLOT      no more slot for starting dump
03563 \********************************************************************/
03564 {
03565    YM_CFILE *pmyfch;
03566    YM_PFILE *pmyfph;
03567    char *pfilename;
03568    char srun[16], sslot[3];
03569    int i, status;
03570 
03571    /* initialize invalid slot */
03572    *slot = -1;
03573 
03574    if (fmt == FORMAT_YBOS) {
03575       if ((status = ybk_locate((DWORD *) pevt, "CFIL", &pmyfch)) <= 0)
03576          return (status);
03577       if ((status = ybk_locate((DWORD *) pevt, "PFIL", &pmyfph)) <= 0)
03578          return (status);
03579    } else if (fmt == FORMAT_MIDAS) {
03580       if ((status = bk_locate(pevt, "CFIL", &pmyfch)) <= 0)
03581          return (status);
03582       if ((status = bk_locate(pevt, "PFIL", &pmyfph)) <= 0)
03583          return (status);
03584    } else
03585       return -2;
03586    /* find free slot */
03587    for (i = 0; i < MAX_YM_FILE; i++)
03588       if (ymfile[i].fHandle == 0)
03589          break;
03590    if (i < MAX_YM_FILE) {
03591       /* copy necessary file header info */
03592       ymfile[i].file_ID = pmyfch->file_ID;
03593       strcpy(ymfile[i].path, pmyfph->path);
03594 
03595       /* extract file name */
03596       pfilename = pmyfph->path;
03597       if (strrchr(pmyfph->path, '/') > pfilename)
03598          pfilename = strrchr(pmyfph->path, '/');
03599       if (strrchr(pmyfph->path, '\\') > pfilename)
03600          pfilename = strrchr(pmyfph->path, '\\');
03601       if (strrchr(pmyfph->path, ':') > pfilename)
03602          pfilename = strrchr(pmyfph->path, ':');
03603       if (*pfilename != pmyfph->path[0])
03604          pfilename++;
03605 
03606       /* add path name */
03607       if (svpath[0] != 0) {
03608          ymfile[i].path[0] = 0;
03609          strncat(ymfile[i].path, svpath, strlen(svpath));
03610          if (ymfile[i].path[strlen(ymfile[i].path) - 1] != DIR_SEPARATOR)
03611             strcat(ymfile[i].path, DIR_SEPARATOR_STR);
03612          /* append the file name */
03613          strcat(ymfile[i].path, pfilename);
03614       }
03615       if (file_mode == YB_ADD_RUN) {    /* append run number */
03616          strcat(ymfile[i].path, ".");
03617          sprintf(srun, "Run%4.4i", pmyfch->run_number);
03618          strncat(ymfile[i].path, srun, strlen(srun));
03619       }
03620       /* differentiate the possible file dumps 
03621          as the path is unique */
03622       if (i > 0) {
03623          sprintf(sslot, ".%03i", i);
03624          strcat(ymfile[i].path, sslot);
03625       }
03626 
03627       /* open device */
03628       if ((ymfile[i].fHandle =
03629            open(ymfile[i].path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644)) == -1) {
03630          ymfile[i].fHandle = 0;
03631          printf("File %s cannot be created\n", ymfile[i].path);
03632          return (SS_FILE_ERROR);
03633       }
03634    } else {
03635       /* no more slot */
03636       printf("No more slot for file %s\n", pmyfph->path);
03637       return YB_NOMORE_SLOT;
03638    }
03639 
03640    ymfile[i].current_read_byte = 0;
03641    ymfile[i].current_fragment = 0;
03642    *slot = i;
03643    return YB_SUCCESS;
03644 }
03645 
03646 /*------------------------------------------------------------------*/
03647 INT yb_ymfile_update(int slot, int fmt, void *pevt)
03648 /********************************************************************\
03649 Routine: yb_ymfile_update
03650 Purpose: dump Midas/Ybos event to file for YBOS file oriented event type.
03651 Input:
03652 char * pevt           pointer to the data portion of the event.
03653 Output:
03654 INT  slot             valid index of the opened channel.
03655 Function value:
03656 YB_SUCCESS         Successful completion
03657 -1                     error
03658 \********************************************************************/
03659 {
03660    YM_CFILE *pmyfch;
03661    char *pmyfd;
03662    int status;
03663    int nwrite;
03664 
03665    if (fmt == FORMAT_YBOS) {
03666       if ((status = ybk_locate((DWORD *) pevt, "CFIL", &pmyfch)) <= 0)
03667          return (status);
03668       if ((status = ybk_locate((DWORD *) pevt, "DFIL", &pmyfd)) <= 0)
03669          return (status);
03670 
03671       /* check sequence order */
03672       if (ymfile[slot].current_fragment + 1 != pmyfch->current_fragment) {
03673          printf("Out of sequence %i / %i\n", ymfile[slot].current_fragment, pmyfch->current_fragment);
03674       }
03675       /* dump fragment to file */
03676       nwrite = write(ymfile[slot].fHandle, pmyfd, pmyfch->fragment_size);
03677 
03678       /* update current file record */
03679       ymfile[slot].current_read_byte += nwrite;
03680       ymfile[slot].current_fragment++;
03681       /* check if file has to be closed */
03682       if (ymfile[slot].current_fragment == pmyfch->total_fragment) {
03683          /* file complete */
03684          close(ymfile[slot].fHandle);
03685          printf("File %s (%i) completed\n", ymfile[slot].path, ymfile[slot].current_read_byte);
03686          /* cleanup slot */
03687          ymfile[slot].fHandle = 0;
03688          return YB_SUCCESS;
03689       } /* close file */
03690       else {
03691          /* fragment retrieved wait next one */
03692          return YB_SUCCESS;
03693       }
03694    } else if (fmt == FORMAT_MIDAS) {
03695       if ((status = bk_locate(pevt, "CFIL", &pmyfch)) <= 0)
03696          return (status);
03697       if ((status = bk_locate(pevt, "DFIL", &pmyfd)) <= 0)
03698          return (status);
03699 
03700       /* check sequence order */
03701       if (ymfile[slot].current_fragment + 1 != pmyfch->current_fragment) {
03702          printf("Out of sequence %i / %i\n", ymfile[slot].current_fragment, pmyfch->current_fragment);
03703       }
03704       /* dump fragment to file */
03705       nwrite = write(ymfile[slot].fHandle, pmyfd, pmyfch->fragment_size);
03706 
03707       /* update current file record */
03708       ymfile[slot].current_read_byte += nwrite;
03709       ymfile[slot].current_fragment++;
03710       /* check if file has to be closed */
03711       if (ymfile[slot].current_fragment == pmyfch->total_fragment) {
03712          /* file complete */
03713          close(ymfile[slot].fHandle);
03714          printf("File %s (%i) completed\n", ymfile[slot].path, ymfile[slot].current_read_byte);
03715          /* cleanup slot */
03716          ymfile[slot].fHandle = 0;
03717          return YB_SUCCESS;
03718       } /* close file */
03719       else {
03720          /* fragment retrieved wait next one */
03721          return YB_SUCCESS;
03722       }
03723    } else
03724       return YB_UNKNOWN_FORMAT;
03725 }
03726 #endif                          /* OS_VXWORKS Frontend */
03727 
03728 /*------------------------------------------------------------------*/
03729 /*------------------------------------------------------------------*/
03730 /*------------------------------------------------------------------*/
03731 /*--END of YBOS.C---------------------------------------------------*/
03732 /*------------------------------------------------------------------*/
03733 /*------------------------------------------------------------------*/
03734 /*------------------------------------------------------------------*/
03735 
03736 
03737 /**dox***************************************************************/
03738 #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
03739 
03740 /**dox***************************************************************/
03741                    /** @} *//* end of ybosbankc */
03742 
03743 /**dox***************************************************************/
03744                    /** @} *//* end of ybosincludecode */

Midas DOC Version 3.0.0 ---- 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