mlogger.c File Reference

Go to the source code of this file.

Data Structures

struct  hist_log_s
struct  MIDAS_INFO
struct  EVENT_DEF

Defines

#define HAVE_LOGGING
#define LOGGER_TIMEOUT   60000
#define MAX_CHANNELS   10
#define EVENT_DEF_CACHE_SIZE   30
#define STR_INC(p, base)

Functions

 CHN_SETTINGS_STR (chn_settings_str)
void receive_event (HNDLE hBuf, HNDLE request_id, EVENT_HEADER *pheader, void *pevent)
INT log_write (LOG_CHN *log_chn, EVENT_HEADER *pheader)
void log_system_history (HNDLE hDB, HNDLE hKey, void *info)
int log_generate_file_name (LOG_CHN *log_chn)
void logger_init ()
void log_odb_dump (LOG_CHN *log_chn, short int event_id, INT run_number)
void odb_save (const char *filename)
INT tape_open (char *dev, INT *handle)
INT ftp_error (char *message)
INT ftp_open (char *destination, FTP_CON **con)
INT midas_flush_buffer (LOG_CHN *log_chn)
INT midas_write (LOG_CHN *log_chn, EVENT_HEADER *pevent, INT evt_size)
INT midas_log_open (LOG_CHN *log_chn, INT run_number)
INT midas_log_close (LOG_CHN *log_chn, INT run_number)
EVENT_DEFdb_get_event_definition (short int event_id)
INT dump_write (LOG_CHN *log_chn, EVENT_HEADER *pevent, INT evt_size)
INT dump_log_open (LOG_CHN *log_chn, INT run_number)
INT dump_log_close (LOG_CHN *log_chn, INT run_number)
INT ascii_write (LOG_CHN *log_chn, EVENT_HEADER *pevent, INT evt_size)
INT ascii_log_open (LOG_CHN *log_chn, INT run_number)
INT ascii_log_close (LOG_CHN *log_chn, INT run_number)
INT log_open (LOG_CHN *log_chn, INT run_number)
INT log_close (LOG_CHN *log_chn, INT run_number)
int stop_the_run (int restart)
int start_the_run ()
void log_history (HNDLE hDB, HNDLE hKey, void *info)
static int add_event (int *indexp, int event_id, const char *event_name, HNDLE hKey, int ntags, const TAG *tags, int period, int hotlink)
static int get_event_id (int eq_id, const char *eq_name, const char *var_name)
INT open_history ()
void close_history ()
INT log_callback (INT index, void *prpc_param[])
int close_channels (int run_number, BOOL *p_tape_flag)
int close_buffers ()
static int write_history (DWORD transition, DWORD run_number)
INT tr_start (INT run_number, char *error)
INT tr_start_abort (INT run_number, char *error)
INT tr_stop (INT run_number, char *error)
INT tr_pause (INT run_number, char *error)
INT tr_resume (INT run_number, char *error)
int main (int argc, char *argv[])

Variables

INT local_state
BOOL in_stop_transition = FALSE
BOOL tape_message = TRUE
BOOL verbose = FALSE
BOOL stop_requested = FALSE
BOOL start_requested = FALSE
DWORD auto_restart = 0
DWORD run_start_time
DWORD subrun_start_time
LOG_CHN log_chn [MAX_CHANNELS]
static int hist_log_size = 0
static int hist_log_max = 0
static hist_log_shist_log = NULL
HNDLE hDB
static std::vector< MidasHistoryInterface * > mh


Define Documentation

#define EVENT_DEF_CACHE_SIZE   30

#define HAVE_LOGGING

Definition at line 18 of file mlogger.c.

#define LOGGER_TIMEOUT   60000

Definition at line 48 of file mlogger.c.

#define MAX_CHANNELS   10

Definition at line 50 of file mlogger.c.

#define STR_INC ( p,
base   ) 

Value:

{ p+=strlen(p); \
                          if (p > base+sizeof(base)) \
                            cm_msg(MERROR, "STR_INC", "ASCII buffer too small"); }

Definition at line 1363 of file mlogger.c.


Function Documentation

static int add_event ( int *  indexp,
int  event_id,
const char *  event_name,
HNDLE  hKey,
int  ntags,
const TAG tags,
int  period,
int  hotlink 
) [static]

Definition at line 2586 of file mlogger.c.

Referenced by open_history().

02587 {
02588    int status;
02589    int size, i;
02590    int oldTags = 0;
02591    int disableTags = 0;
02592    int index = *indexp;
02593 
02594    if (0) {   
02595       /* print the tags */
02596       printf("add_event: event %d, name \"%s\", ntags %d\n", event_id, event_name, ntags);
02597       for (i=0; i<ntags; i++) {
02598          printf("tag %d: name \"%s\", type %d, n_data %d\n", i, tags[i].name, tags[i].type, tags[i].n_data);
02599       }
02600    }
02601 
02602 
02603    /* check for duplicate event id's */
02604    for (i=0; i<index; i++) {
02605       if (hist_log[i].event_id == event_id) {
02606          cm_msg(MERROR, "add_event", "Duplicate event id %d for \'%s\'", event_id, event_name);
02607          return 0;
02608       }
02609       if (strcmp(hist_log[i].event_name, event_name) == 0) {
02610          cm_msg(MERROR, "add_event", "Duplicate event name \'%s\' with event id %d", event_name, event_id);
02611          return 0;
02612       }
02613    }
02614 
02615    while (index >= hist_log_size) {
02616       int new_size = 2*hist_log_size;
02617 
02618       if (hist_log_size == 0)
02619          new_size = 10;
02620 
02621       hist_log = (hist_log_s*)realloc(hist_log, sizeof(hist_log[0])*new_size);
02622       assert(hist_log!=NULL);
02623 
02624       hist_log_size = new_size;
02625    }
02626 
02627    if (index >= hist_log_max)
02628       hist_log_max = index + 1;
02629 
02630    /* check for invalid history tags */
02631    for (i=0; i<ntags; i++) {
02632       if (tags[i].type == TID_STRING) {
02633          cm_msg(MERROR, "add_event", "Invalid tag %d \'%s\' in event %d \'%s\': cannot do history for TID_STRING data, sorry!", i, tags[i].name, event_id, event_name);
02634          return 0;
02635       }
02636       if (rpc_tid_size(tags[i].type) == 0) {
02637          cm_msg(MERROR, "add_event", "Invalid tag %d \'%s\' in event %d \'%s\': type %d size is zero", i, tags[i].name, event_id, event_name, tags[i].type);
02638          return 0;
02639       }
02640    }
02641 
02642    /* check for trailing spaces in tag names */
02643    for (i=0; i<ntags; i++) {
02644       if (isspace(tags[i].name[strlen(tags[i].name)-1])) {
02645          cm_msg(MERROR, "add_event", "Invalid tag %d \'%s\' in event %d \'%s\': has trailing spaces", i, tags[i].name, event_id, event_name);
02646          return 0;
02647       }
02648    }
02649    
02650    for (unsigned i=0; i<mh.size(); i++) {
02651       status = mh[i]->hs_define_event(event_name, ntags, tags);
02652       if (status != HS_SUCCESS) {
02653          cm_msg(MERROR, "add_event", "Cannot define event \"%s\", hs_define_event() status %d", event_name, status);
02654          return 0;
02655       }
02656    }
02657 
02658    status = hs_define_event(event_id, (char*)event_name, (TAG*)tags, sizeof(TAG) * ntags);
02659    assert(status == DB_SUCCESS);
02660 
02661    status = db_get_record_size(hDB, hKey, 0, &size);
02662    assert(status == DB_SUCCESS);
02663 
02664    /* setup hist_log structure for this event */
02665    strlcpy(hist_log[index].event_name, event_name, sizeof(hist_log[index].event_name));
02666    hist_log[index].event_id    = event_id;
02667    hist_log[index].n_var       = ntags;
02668    hist_log[index].hKeyVar     = hKey;
02669    hist_log[index].buffer_size = size;
02670    hist_log[index].buffer      = (char*)malloc(size);
02671    hist_log[index].period      = period;
02672    hist_log[index].last_log    = 0;
02673 
02674    if (hist_log[index].buffer == NULL) {
02675       cm_msg(MERROR, "add_event", "Cannot allocate data buffer for event \"%s\" size %d", event_name, size);
02676       return 0;
02677    }
02678    
02679    /* open hot link to variables */
02680    if (hotlink) {
02681       status = db_open_record(hDB, hKey, hist_log[index].buffer,
02682                               size, MODE_READ, log_history, NULL);
02683       if (status != DB_SUCCESS) {
02684          cm_msg(MERROR, "add_event",
02685                 "Cannot hotlink event %d \"%s\" for history logging, db_open_record() status %d",
02686                 event_id, event_name, status);
02687          return status;
02688       }
02689    }
02690    
02691    if (verbose)
02692       printf("Created event %d for equipment \"%s\", %d tags, size %d\n", event_id, event_name, ntags, size);
02693 
02694    /* create history tags for mhttpd */
02695 
02696    disableTags = 0;
02697    size = sizeof(disableTags);
02698    status = db_get_value(hDB, 0, "/History/DisableTags", &disableTags, &size, TID_BOOL, TRUE);
02699 
02700    oldTags = 0;
02701    size = sizeof(oldTags);
02702    status = db_get_value(hDB, 0, "/History/CreateOldTags", &oldTags, &size, TID_BOOL, FALSE);
02703 
02704    if (disableTags) {
02705       HNDLE hKey;
02706 
02707       status = db_find_key(hDB, 0, "/History/Tags", &hKey);
02708       if (status == DB_SUCCESS) {
02709          status = db_delete_key(hDB, hKey, FALSE);
02710          if (status != DB_SUCCESS)
02711             cm_msg(MERROR, "add_event", "Cannot delete /History/Tags, db_delete_key() status %d", status);
02712       }
02713 
02714    } else if (oldTags) {
02715 
02716       char buf[256];
02717 
02718       sprintf(buf, "/History/Tags/%d", event_id);
02719 
02720       //printf("Set tag \'%s\' = \'%s\'\n", buf, event_name);
02721 
02722       status = db_set_value(hDB, 0, buf, (void*)event_name, strlen(event_name)+1, 1, TID_STRING);
02723       assert(status == DB_SUCCESS);
02724 
02725       for (i=0; i<ntags; i++) {
02726          WORD v = (WORD) tags[i].n_data;
02727          sprintf(buf, "/History/Tags/Tags %d/%s", event_id, tags[i].name);
02728 
02729          //printf("Set tag \'%s\' = %d\n", buf, v);
02730 
02731          status = db_set_value(hDB, 0, buf, &v, sizeof(v), 1, TID_WORD);
02732          assert(status == DB_SUCCESS);
02733 
02734          if (strlen(tags[i].name) == NAME_LENGTH-1)
02735             cm_msg(MERROR, "add_event",
02736                    "Tag name \'%s\' in event %d (%s) may have been truncated to %d characters",
02737                    tags[i].name, event_id, event_name, NAME_LENGTH-1);
02738       }
02739 
02740    } else {
02741 
02742       const int kLength = 32 + NAME_LENGTH + NAME_LENGTH;
02743       char buf[kLength];
02744       HNDLE hKey;
02745 
02746       sprintf(buf, "/History/Tags/%d", event_id);
02747       status = db_find_key(hDB, 0, buf, &hKey);
02748 
02749       if (status == DB_SUCCESS) {
02750          // add new tags
02751          KEY key;
02752 
02753          status = db_get_key(hDB, hKey, &key);
02754          assert(status == DB_SUCCESS);
02755 
02756          assert(key.type == TID_STRING);
02757 
02758          if (key.item_size < kLength && key.num_values == 1) {
02759             // old style tags are present. Convert them to new style!
02760 
02761             HNDLE hTags;
02762 
02763             cm_msg(MINFO, "add_event", "Converting old event %d (%s) tags to new style", event_id, event_name);
02764 
02765             status = db_set_data(hDB, hKey, event_name, kLength, 1, TID_STRING);
02766             assert(status == DB_SUCCESS);
02767 
02768             sprintf(buf, "/History/Tags/Tags %d", event_id);
02769 
02770             status = db_find_key(hDB, 0, buf, &hTags);
02771 
02772             if (status == DB_SUCCESS) {
02773                for (i=0; ; i++) {
02774                   HNDLE h;
02775                   int size;
02776                   KEY key;
02777                   WORD w;
02778 
02779                   status = db_enum_key(hDB, hTags, i, &h);
02780                   if (status == DB_NO_MORE_SUBKEYS)
02781                      break;
02782                   assert(status == DB_SUCCESS);
02783 
02784                   status = db_get_key(hDB, h, &key);
02785 
02786                   size = sizeof(w);
02787                   status = db_get_data(hDB, h, &w, &size, TID_WORD);
02788                   assert(status == DB_SUCCESS);
02789 
02790                   sprintf(buf, "%d[%d] %s", 0, w, key.name);
02791                   
02792                   status = db_set_data_index(hDB, hKey, buf, kLength, 1+i, TID_STRING);
02793                   assert(status == DB_SUCCESS);
02794                }
02795 
02796                status = db_delete_key(hDB, hTags, TRUE);
02797                assert(status == DB_SUCCESS);
02798             }
02799 
02800             // format conversion has changed the key, get it again
02801             status = db_get_key(hDB, hKey, &key);
02802             assert(status == DB_SUCCESS);
02803          }
02804 
02805          if (1) {
02806             // add new tags
02807          
02808             int size = key.item_size * key.num_values;
02809             int num = key.num_values;
02810 
02811             char* s = (char*)malloc(size);
02812             assert(s != NULL);
02813 
02814             TAG* t = (TAG*)malloc(sizeof(TAG)*(key.num_values + ntags));
02815             assert(t != NULL);
02816 
02817             status = db_get_data(hDB, hKey, s, &size, TID_STRING);
02818             assert(status == DB_SUCCESS);
02819 
02820             for (i=1; i<key.num_values; i++) {
02821                char* ss = s + i*key.item_size;
02822 
02823                t[i].type = 0;
02824                t[i].n_data = 0;
02825                t[i].name[0] = 0;
02826 
02827                if (isdigit(ss[0])) {
02828                   //sscanf(ss, "%d[%d] %s", &t[i].type, &t[i].n_data, t[i].name);
02829 
02830                   t[i].type = strtoul(ss, &ss, 0);
02831                   assert(*ss == '[');
02832                   ss++;
02833                   t[i].n_data = strtoul(ss, &ss, 0);
02834                   assert(*ss == ']');
02835                   ss++;
02836                   assert(*ss == ' ');
02837                   ss++;
02838                   strlcpy(t[i].name, ss, sizeof(t[i].name));
02839 
02840                   //printf("type %d, n_data %d, name [%s]\n", t[i].type, t[i].n_data, t[i].name);
02841                }
02842             }
02843 
02844             for (i=0; i<ntags; i++) {
02845                int j;
02846                int k = 0;
02847 
02848                for (j=1; j<key.num_values; j++) {
02849                   if (equal_ustring((char*)tags[i].name, (char*)t[j].name)) {
02850                      if ((tags[i].type!=t[j].type) || (tags[i].n_data!=t[j].n_data)) {
02851                         cm_msg(MINFO, "add_event", "Event %d (%s) tag \"%s\" type and size changed from %d[%d] to %d[%d]",
02852                                event_id, event_name,
02853                                tags[i].name,
02854                                t[j].type, t[j].n_data,
02855                                tags[i].type, tags[i].n_data);
02856                         k = j;
02857                         break;
02858                      }
02859 
02860                      k = -1;
02861                      break;
02862                   }
02863                }
02864 
02865                // if tag not present, k==0, so append it to the array
02866 
02867                if (k==0)
02868                   k = num;
02869 
02870                if (k > 0) {
02871                   sprintf(buf, "%d[%d] %s", tags[i].type, tags[i].n_data, tags[i].name);
02872 
02873                   status = db_set_data_index(hDB, hKey, buf, kLength, k, TID_STRING);
02874                   assert(status == DB_SUCCESS);
02875 
02876                   if (k >= num)
02877                      num = k+1;
02878                }
02879             }
02880 
02881             free(s);
02882             free(t);
02883          }
02884 
02885       } else if (status == DB_NO_KEY) {
02886          // create new array of tags
02887          status = db_create_key(hDB, 0, buf, TID_STRING);
02888          assert(status == DB_SUCCESS);
02889 
02890          status = db_find_key(hDB, 0, buf, &hKey);
02891          assert(status == DB_SUCCESS);
02892 
02893          status = db_set_data(hDB, hKey, event_name, kLength, 1, TID_STRING);
02894          assert(status == DB_SUCCESS);
02895 
02896          for (i=0; i<ntags; i++) {
02897             sprintf(buf, "%d[%d] %s", tags[i].type, tags[i].n_data, tags[i].name);
02898 
02899             status = db_set_data_index(hDB, hKey, buf, kLength, 1+i, TID_STRING);
02900             assert(status == DB_SUCCESS);
02901          }
02902       } else {
02903          cm_msg(MERROR, "add_event", "Error: db_find_key(%s) status %d", buf, status);
02904          return 0;
02905       }
02906    }
02907 
02908    *indexp = index+1;
02909 
02910    return SUCCESS;
02911 }

INT ascii_log_close ( LOG_CHN *  log_chn,
INT  run_number 
)

Definition at line 1814 of file mlogger.c.

01815 {
01816    /* Write EOF if Tape */
01817    if (log_chn->type == LOG_TYPE_TAPE) {
01818       /* writing EOF mark on tape only */
01819       ss_tape_write_eof(log_chn->handle);
01820       ss_tape_close(log_chn->handle);
01821    } else if (log_chn->type == LOG_TYPE_FTP) {
01822       ftp_close(log_chn->ftp_con);
01823       ftp_bye(log_chn->ftp_con);
01824    } else
01825       close(log_chn->handle);
01826 
01827    return SS_SUCCESS;
01828 }

INT ascii_log_open ( LOG_CHN *  log_chn,
INT  run_number 
)

Definition at line 1772 of file mlogger.c.

01773 {
01774    INT status;
01775    EVENT_HEADER event;
01776 
01777    /* Create device channel */
01778    if (log_chn->type == LOG_TYPE_TAPE) {
01779       status = tape_open(log_chn->path, &log_chn->handle);
01780       if (status != SS_SUCCESS) {
01781          log_chn->handle = 0;
01782          return status;
01783       }
01784    } else if (log_chn->type == LOG_TYPE_FTP) {
01785       status = ftp_open(log_chn->path, &log_chn->ftp_con);
01786       if (status != SS_SUCCESS) {
01787          log_chn->handle = 0;
01788          return status;
01789       } else
01790          log_chn->handle = 1;
01791    } else {
01792       log_chn->handle = open(log_chn->path, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);
01793 
01794       if (log_chn->handle < 0) {
01795          log_chn->handle = 0;
01796          return SS_FILE_ERROR;
01797       }
01798    }
01799 
01800    /* write ODB dump */
01801    if (log_chn->settings.odb_dump) {
01802       event.event_id = EVENTID_BOR;
01803       event.data_size = 0;
01804       event.serial_number = run_number;
01805 
01806       ascii_write(log_chn, &event, sizeof(EVENT_HEADER));
01807    }
01808 
01809    return SS_SUCCESS;
01810 }

INT ascii_write ( LOG_CHN *  log_chn,
EVENT_HEADER pevent,
INT  evt_size 
)

Definition at line 1611 of file mlogger.c.

01612 {
01613    INT status, size, i, j;
01614    EVENT_DEF *event_def;
01615    BANK_HEADER *pbh;
01616    BANK *pbk;
01617    BANK32 *pbk32;
01618    void *pdata;
01619    char buffer[10000], name[5], type_name[10];
01620    char *ph, header_line[10000];
01621    char *pd, data_line[10000];
01622    HNDLE hKey;
01623    KEY key;
01624    static short int last_event_id = -1;
01625    DWORD bkname;
01626    WORD bktype;
01627 
01628    if (pevent->serial_number == 0)
01629       last_event_id = -1;
01630 
01631    event_def = db_get_event_definition(pevent->event_id);
01632    if (event_def == NULL)
01633       return SS_SUCCESS;
01634 
01635    name[4] = 0;
01636    header_line[0] = 0;
01637    data_line[0] = 0;
01638    ph = header_line;
01639    pd = data_line;
01640 
01641   /*---- MIDAS format ----------------------------------------------*/
01642    if (event_def->format == FORMAT_MIDAS) {
01643       LRS1882_DATA *lrs1882;
01644       LRS1877_DATA *lrs1877;
01645       LRS1877_HEADER *lrs1877_header;
01646 
01647       pbh = (BANK_HEADER *) (pevent + 1);
01648       bk_swap(pbh, FALSE);
01649 
01650       pbk = NULL;
01651       pbk32 = NULL;
01652       do {
01653          /* scan all banks */
01654          if (bk_is32(pbh)) {
01655             size = bk_iterate32(pbh, &pbk32, &pdata);
01656             if (pbk32 == NULL)
01657                break;
01658             bkname = *((DWORD *) pbk32->name);
01659             bktype = (WORD) pbk32->type;
01660          } else {
01661             size = bk_iterate(pbh, &pbk, &pdata);
01662             if (pbk == NULL)
01663                break;
01664             bkname = *((DWORD *) pbk->name);
01665             bktype = (WORD) pbk->type;
01666          }
01667 
01668          if (rpc_tid_size(bktype & 0xFF))
01669             size /= rpc_tid_size(bktype & 0xFF);
01670 
01671          lrs1882 = (LRS1882_DATA *) pdata;
01672          lrs1877 = (LRS1877_DATA *) pdata;
01673          lrs1877_header = (LRS1877_HEADER *) pdata;
01674 
01675          /* write bank header */
01676          *((DWORD *) name) = bkname;
01677 
01678          if ((bktype & 0xFF00) == 0)
01679             strcpy(type_name, rpc_tid_name(bktype & 0xFF));
01680          else if ((bktype & 0xFF00) == TID_LRS1882)
01681             strcpy(type_name, "LRS1882");
01682          else if ((bktype & 0xFF00) == TID_LRS1877)
01683             strcpy(type_name, "LRS1877");
01684          else if ((bktype & 0xFF00) == TID_PCOS3)
01685             strcpy(type_name, "PCOS3");
01686          else
01687             strcpy(type_name, "unknown");
01688 
01689          sprintf(ph, "%s[%d]\t", name, size);
01690          STR_INC(ph, header_line);
01691 
01692          /* write data */
01693          for (i = 0; i < size; i++) {
01694             db_sprintf(pd, pdata, size, i, bktype & 0xFF);
01695             strcat(pd, "\t");
01696             STR_INC(pd, data_line);
01697          }
01698 
01699       } while (1);
01700    }
01701 
01702   /*---- FIXED format ----------------------------------------------*/
01703    if (event_def->format == FORMAT_FIXED) {
01704       if (event_def->hDefKey == 0)
01705          cm_msg(MERROR, "ascii_write", "cannot find event definition");
01706       else {
01707          pdata = (char *) (pevent + 1);
01708          for (i = 0;; i++) {
01709             status = db_enum_key(hDB, event_def->hDefKey, i, &hKey);
01710             if (status == DB_NO_MORE_SUBKEYS)
01711                break;
01712 
01713             db_get_key(hDB, hKey, &key);
01714 
01715             /* adjust for alignment */
01716             pdata = (void *) VALIGN(pdata, MIN(ss_get_struct_align(), key.item_size));
01717 
01718             for (j = 0; j < key.num_values; j++) {
01719                if (pevent->event_id != last_event_id) {
01720                   if (key.num_values == 1)
01721                      sprintf(ph, "%s\t", key.name);
01722                   else
01723                      sprintf(ph, "%s%d\t", key.name, j);
01724 
01725                   STR_INC(ph, header_line);
01726                }
01727 
01728                db_sprintf(pd, pdata, key.item_size, j, key.type);
01729                strcat(pd, "\t");
01730                STR_INC(pd, data_line);
01731             }
01732 
01733             /* shift data pointer to next item */
01734             pdata = ((char *) pdata) + key.item_size * key.num_values;
01735          }
01736       }
01737    }
01738 
01739    if (*(pd - 1) == '\t')
01740       *(pd - 1) = '\n';
01741 
01742    if (last_event_id != pevent->event_id) {
01743       if (*(ph - 1) == '\t')
01744          *(ph - 1) = '\n';
01745       last_event_id = pevent->event_id;
01746       strcpy(buffer, header_line);
01747       strcat(buffer, data_line);
01748    } else
01749       strcpy(buffer, data_line);
01750 
01751    /* write buffer to device */
01752    size = strlen(buffer);
01753 
01754    if (log_chn->type == LOG_TYPE_TAPE)
01755       status = ss_tape_write(log_chn->handle, buffer, size);
01756    else if (log_chn->type == LOG_TYPE_FTP)
01757       status = ftp_send(log_chn->ftp_con->data, buffer, size) == size ?
01758           SS_SUCCESS : SS_FILE_ERROR;
01759    else
01760       status = write(log_chn->handle, buffer, size) == size ? SS_SUCCESS : SS_FILE_ERROR;
01761 
01762    /* update statistics */
01763    log_chn->statistics.events_written++;
01764    log_chn->statistics.bytes_written += size;
01765    log_chn->statistics.bytes_written_total += size;
01766 
01767    return status;
01768 }

CHN_SETTINGS_STR ( chn_settings_str   ) 

INT close_buffers ( void   ) 

Definition at line 3814 of file mlogger.c.

Referenced by scan_fragment(), tr_start(), tr_start_abort(), and tr_stop().

03815 {
03816    int i;
03817 
03818    /* close buffers */
03819    for (i = 0; i < MAX_CHANNELS; i++) {
03820 #ifndef FAL_MAIN
03821       if (log_chn[i].buffer_handle) {
03822          INT j;
03823 
03824          bm_close_buffer(log_chn[i].buffer_handle);
03825          for (j = i + 1; j < MAX_CHANNELS; j++)
03826             if (log_chn[j].buffer_handle == log_chn[i].buffer_handle)
03827                log_chn[j].buffer_handle = 0;
03828       }
03829 
03830       if (log_chn[i].msg_request_id)
03831          bm_delete_request(log_chn[i].msg_request_id);
03832 #endif
03833 
03834       /* clear channel info */
03835       memset(&log_chn[i].handle, 0, sizeof(LOG_CHN));
03836    }
03837 
03838    return SUCCESS;
03839 }

int close_channels ( int  run_number,
BOOL p_tape_flag 
)

Definition at line 3764 of file mlogger.c.

Referenced by tr_start(), tr_start_abort(), and tr_stop().

03765 {
03766    int i;
03767    BOOL tape_flag = FALSE;
03768 
03769    for (i = 0; i < MAX_CHANNELS; i++) {
03770       if (log_chn[i].handle || log_chn[i].ftp_con) {
03771          /* generate MTALK message */
03772          if (log_chn[i].type == LOG_TYPE_TAPE && tape_message) {
03773             tape_flag = TRUE;
03774             cm_msg(MTALK, "tr_stop", "closing tape channel #%d, please wait", i);
03775          }
03776 #ifndef FAL_MAIN
03777          /* wait until buffer is empty */
03778          if (log_chn[i].buffer_handle) {
03779 #ifdef DELAYED_STOP
03780             DWORD start_time;
03781 
03782             start_time = ss_millitime();
03783             do {
03784                cm_yield(100);
03785             } while (ss_millitime() - start_time < DELAYED_STOP);
03786 #else
03787             INT n_bytes;
03788             do {
03789                bm_get_buffer_level(log_chn[i].buffer_handle, &n_bytes);
03790                if (n_bytes > 0)
03791                   cm_yield(100);
03792             } while (n_bytes > 0);
03793 #endif
03794          }
03795 #endif                          /* FAL_MAIN */
03796 
03797          /* close logging channel */
03798          log_close(&log_chn[i], run_number);
03799 
03800          /* close statistics record */
03801          db_set_record(hDB, log_chn[i].stats_hkey, &log_chn[i].statistics, sizeof(CHN_STATISTICS), 0);
03802          db_close_record(hDB, log_chn[i].stats_hkey);
03803          db_close_record(hDB, log_chn[i].settings_hkey);
03804          log_chn[i].stats_hkey = log_chn[i].settings_hkey = 0;
03805       }
03806    }
03807 
03808    if (p_tape_flag)
03809       *p_tape_flag = tape_flag;
03810 
03811    return SUCCESS;
03812 }

void close_history (  ) 

Definition at line 3479 of file mlogger.c.

03480 {
03481    INT i, status;
03482    HNDLE hKeyRoot, hKey;
03483 
03484    /* close system history */
03485    status = db_find_key(hDB, 0, "/History/Links", &hKeyRoot);
03486    if (status != DB_SUCCESS) {
03487       for (i = 0;; i++) {
03488          status = db_enum_key(hDB, hKeyRoot, i, &hKey);
03489          if (status == DB_NO_MORE_SUBKEYS)
03490             break;
03491          db_close_record(hDB, hKey);
03492       }
03493    }
03494 
03495    /* close event history */
03496    for (i = 1; i < hist_log_max; i++)
03497       if (hist_log[i].hKeyVar) {
03498          db_close_record(hDB, hist_log[i].hKeyVar);
03499          hist_log[i].hKeyVar = 0;
03500          if (hist_log[i].buffer)
03501             free(hist_log[i].buffer);
03502          hist_log[i].buffer = NULL;
03503       }
03504 
03505    for (unsigned h=0; h<mh.size(); h++)
03506       status  = mh[h]->hs_disconnect();
03507 }

EVENT_DEF* db_get_event_definition ( short int  event_id  ) 

Definition at line 1274 of file mlogger.c.

01275 {
01276    INT i, index, status, size;
01277    char str[80];
01278    HNDLE hKey, hKeyRoot;
01279    WORD id;
01280 
01281 #define EVENT_DEF_CACHE_SIZE 30
01282    static EVENT_DEF *event_def = NULL;
01283 
01284    /* allocate memory for cache */
01285    if (event_def == NULL)
01286       event_def = (EVENT_DEF *) calloc(EVENT_DEF_CACHE_SIZE, sizeof(EVENT_DEF));
01287 
01288    /* lookup if event definition in cache */
01289    for (i = 0; event_def[i].event_id; i++)
01290       if (event_def[i].event_id == event_id)
01291          return &event_def[i];
01292 
01293    /* search free cache entry */
01294    for (index = 0; index < EVENT_DEF_CACHE_SIZE; index++)
01295       if (event_def[index].event_id == 0)
01296          break;
01297 
01298    if (index == EVENT_DEF_CACHE_SIZE) {
01299       cm_msg(MERROR, "db_get_event_definition", "too many event definitions");
01300       return NULL;
01301    }
01302 
01303    /* check for system events */
01304    if (event_id < 0) {
01305       event_def[index].event_id = event_id;
01306       event_def[index].format = FORMAT_ASCII;
01307       event_def[index].hDefKey = 0;
01308       return &event_def[index];
01309    }
01310 
01311    status = db_find_key(hDB, 0, "/equipment", &hKeyRoot);
01312    if (status != DB_SUCCESS) {
01313       cm_msg(MERROR, "db_get_event_definition", "cannot find /equipment entry in ODB");
01314       return NULL;
01315    }
01316 
01317    for (i = 0;; i++) {
01318       /* search for client with specific name */
01319       status = db_enum_key(hDB, hKeyRoot, i, &hKey);
01320       if (status == DB_NO_MORE_SUBKEYS) {
01321          sprintf(str, "Cannot find event id %d under /equipment", event_id);
01322          cm_msg(MERROR, "db_get_event_definition", str);
01323          return NULL;
01324       }
01325 
01326       size = sizeof(id);
01327       status = db_get_value(hDB, hKey, "Common/Event ID", &id, &size, TID_WORD, TRUE);
01328       if (status != DB_SUCCESS)
01329          continue;
01330 
01331       if (id == event_id) {
01332          /* set cache entry */
01333          event_def[index].event_id = id;
01334 
01335          size = sizeof(str);
01336          str[0] = 0;
01337          db_get_value(hDB, hKey, "Common/Format", str, &size, TID_STRING, TRUE);
01338 
01339          if (equal_ustring(str, "Fixed"))
01340             event_def[index].format = FORMAT_FIXED;
01341          else if (equal_ustring(str, "ASCII"))
01342             event_def[index].format = FORMAT_ASCII;
01343          else if (equal_ustring(str, "MIDAS"))
01344             event_def[index].format = FORMAT_MIDAS;
01345          else if (equal_ustring(str, "YBOS"))
01346             event_def[index].format = FORMAT_YBOS;
01347          else if (equal_ustring(str, "DUMP"))
01348             event_def[index].format = FORMAT_DUMP;
01349          else {
01350             cm_msg(MERROR, "db_get_event_definition", "unknown data format");
01351             event_def[index].event_id = 0;
01352             return NULL;
01353          }
01354 
01355          db_find_key(hDB, hKey, "Variables", &event_def[index].hDefKey);
01356          return &event_def[index];
01357       }
01358    }
01359 }

INT dump_log_close ( LOG_CHN *  log_chn,
INT  run_number 
)

Definition at line 1589 of file mlogger.c.

01590 {
01591    /* write ODB dump */
01592    if (log_chn->settings.odb_dump)
01593       log_odb_dump(log_chn, EVENTID_EOR, run_number);
01594 
01595    /* Write EOF if Tape */
01596    if (log_chn->type == LOG_TYPE_TAPE) {
01597       /* writing EOF mark on tape only */
01598       ss_tape_write_eof(log_chn->handle);
01599       ss_tape_close(log_chn->handle);
01600    } else if (log_chn->type == LOG_TYPE_FTP) {
01601       ftp_close(log_chn->ftp_con);
01602       ftp_bye(log_chn->ftp_con);
01603    } else
01604       close(log_chn->handle);
01605 
01606    return SS_SUCCESS;
01607 }

INT dump_log_open ( LOG_CHN *  log_chn,
INT  run_number 
)

Definition at line 1553 of file mlogger.c.

01554 {
01555    INT status;
01556 
01557    /* Create device channel */
01558    if (log_chn->type == LOG_TYPE_TAPE) {
01559       status = tape_open(log_chn->path, &log_chn->handle);
01560       if (status != SS_SUCCESS) {
01561          log_chn->handle = 0;
01562          return status;
01563       }
01564    } else if (log_chn->type == LOG_TYPE_FTP) {
01565       status = ftp_open(log_chn->path, &log_chn->ftp_con);
01566       if (status != SS_SUCCESS) {
01567          log_chn->handle = 0;
01568          return status;
01569       } else
01570          log_chn->handle = 1;
01571    } else {
01572       log_chn->handle = open(log_chn->path, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);
01573 
01574       if (log_chn->handle < 0) {
01575          log_chn->handle = 0;
01576          return SS_FILE_ERROR;
01577       }
01578    }
01579 
01580    /* write ODB dump */
01581    if (log_chn->settings.odb_dump)
01582       log_odb_dump(log_chn, EVENTID_BOR, run_number);
01583 
01584    return SS_SUCCESS;
01585 }

INT dump_write ( LOG_CHN *  log_chn,
EVENT_HEADER pevent,
INT  evt_size 
)

Definition at line 1368 of file mlogger.c.

01369 {
01370    INT status, size, i, j;
01371    EVENT_DEF *event_def;
01372    BANK_HEADER *pbh;
01373    BANK *pbk;
01374    BANK32 *pbk32;
01375    void *pdata;
01376    char buffer[100000], *pbuf, name[5], type_name[10];
01377    HNDLE hKey;
01378    KEY key;
01379    DWORD bkname;
01380    WORD bktype;
01381 
01382    event_def = db_get_event_definition(pevent->event_id);
01383    if (event_def == NULL)
01384       return SS_SUCCESS;
01385 
01386    /* write event header */
01387    pbuf = buffer;
01388    name[4] = 0;
01389 
01390    if (pevent->event_id == EVENTID_BOR)
01391       sprintf(pbuf, "%%ID BOR NR %d\n", pevent->serial_number);
01392    else if (pevent->event_id == EVENTID_EOR)
01393       sprintf(pbuf, "%%ID EOR NR %d\n", pevent->serial_number);
01394    else
01395       sprintf(pbuf, "%%ID %d TR %d NR %d\n", pevent->event_id, pevent->trigger_mask, pevent->serial_number);
01396    STR_INC(pbuf, buffer);
01397 
01398   /*---- MIDAS format ----------------------------------------------*/
01399    if (event_def->format == FORMAT_MIDAS) {
01400       LRS1882_DATA *lrs1882;
01401       LRS1877_DATA *lrs1877;
01402       LRS1877_HEADER *lrs1877_header;
01403 
01404       pbh = (BANK_HEADER *) (pevent + 1);
01405       bk_swap(pbh, FALSE);
01406 
01407       pbk = NULL;
01408       pbk32 = NULL;
01409       do {
01410          /* scan all banks */
01411          if (bk_is32(pbh)) {
01412             size = bk_iterate32(pbh, &pbk32, &pdata);
01413             if (pbk32 == NULL)
01414                break;
01415             bkname = *((DWORD *) pbk32->name);
01416             bktype = (WORD) pbk32->type;
01417          } else {
01418             size = bk_iterate(pbh, &pbk, &pdata);
01419             if (pbk == NULL)
01420                break;
01421             bkname = *((DWORD *) pbk->name);
01422             bktype = (WORD) pbk->type;
01423          }
01424 
01425          if (rpc_tid_size(bktype & 0xFF))
01426             size /= rpc_tid_size(bktype & 0xFF);
01427 
01428          lrs1882 = (LRS1882_DATA *) pdata;
01429          lrs1877 = (LRS1877_DATA *) pdata;
01430          lrs1877_header = (LRS1877_HEADER *) pdata;
01431 
01432          /* write bank header */
01433          *((DWORD *) name) = bkname;
01434 
01435          if ((bktype & 0xFF00) == 0)
01436             strcpy(type_name, rpc_tid_name(bktype & 0xFF));
01437          else if ((bktype & 0xFF00) == TID_LRS1882)
01438             strcpy(type_name, "LRS1882");
01439          else if ((bktype & 0xFF00) == TID_LRS1877)
01440             strcpy(type_name, "LRS1877");
01441          else if ((bktype & 0xFF00) == TID_PCOS3)
01442             strcpy(type_name, "PCOS3");
01443          else
01444             strcpy(type_name, "unknown");
01445 
01446          sprintf(pbuf, "BK %s TP %s SZ %d\n", name, type_name, size);
01447          STR_INC(pbuf, buffer);
01448 
01449          /* write data */
01450          for (i = 0; i < size; i++) {
01451             if ((bktype & 0xFF00) == 0)
01452                db_sprintf(pbuf, pdata, size, i, bktype & 0xFF);
01453 
01454             else if ((bktype & 0xFF00) == TID_LRS1882)
01455                sprintf(pbuf, "GA %d CH %02d DA %d", lrs1882[i].geo_addr, lrs1882[i].channel, lrs1882[i].data);
01456 
01457             else if ((bktype & 0xFF00) == TID_LRS1877) {
01458                if (i == 0)      /* header */
01459                   sprintf(pbuf, "GA %d BF %d CN %d",
01460                           lrs1877_header[i].geo_addr, lrs1877_header[i].buffer, lrs1877_header[i].count);
01461                else             /* data */
01462                   sprintf(pbuf, "GA %d CH %02d ED %d DA %1.1lf",
01463                           lrs1877[i].geo_addr, lrs1877[i].channel, lrs1877[i].edge, lrs1877[i].data * 0.5);
01464             }
01465 
01466             else if ((bktype & 0xFF00) == TID_PCOS3)
01467                *pbuf = '\0';
01468             else
01469                db_sprintf(pbuf, pdata, size, i, bktype & 0xFF);
01470 
01471             strcat(pbuf, "\n");
01472             STR_INC(pbuf, buffer);
01473          }
01474 
01475       } while (1);
01476    }
01477 
01478   /*---- FIXED format ----------------------------------------------*/
01479    if (event_def->format == FORMAT_FIXED) {
01480       if (event_def->hDefKey == 0)
01481          cm_msg(MERROR, "dump_write", "cannot find event definition");
01482       else {
01483          pdata = (char *) (pevent + 1);
01484          for (i = 0;; i++) {
01485             status = db_enum_key(hDB, event_def->hDefKey, i, &hKey);
01486             if (status == DB_NO_MORE_SUBKEYS)
01487                break;
01488 
01489             db_get_key(hDB, hKey, &key);
01490             sprintf(pbuf, "%s\n", key.name);
01491             STR_INC(pbuf, buffer);
01492 
01493             /* adjust for alignment */
01494             pdata = (void *) VALIGN(pdata, MIN(ss_get_struct_align(), key.item_size));
01495 
01496             for (j = 0; j < key.num_values; j++) {
01497                db_sprintf(pbuf, pdata, key.item_size, j, key.type);
01498                strcat(pbuf, "\n");
01499                STR_INC(pbuf, buffer);
01500             }
01501 
01502             /* shift data pointer to next item */
01503             pdata = ((char *) pdata) + key.item_size * key.num_values;
01504          }
01505       }
01506    }
01507 
01508   /*---- ASCII format ----------------------------------------------*/
01509    if (event_def->format == FORMAT_ASCII) {
01510       /* write event header to device */
01511       size = strlen(buffer);
01512       if (log_chn->type == LOG_TYPE_TAPE)
01513          status = ss_tape_write(log_chn->handle, buffer, size);
01514       else
01515          status = write(log_chn->handle, buffer, size) == size ? SS_SUCCESS : SS_FILE_ERROR;
01516 
01517       /* write event directly to device */
01518       size = strlen((char *) (pevent + 1));
01519       if (log_chn->type == LOG_TYPE_TAPE)
01520          status = ss_tape_write(log_chn->handle, (char *) (pevent + 1), size);
01521       else if (log_chn->type == LOG_TYPE_FTP)
01522          status = ftp_send((log_chn->ftp_con)->data, buffer, size) == size ?
01523              SS_SUCCESS : SS_FILE_ERROR;
01524       else
01525          status = write(log_chn->handle, (char *) (pevent + 1), size) == size ? SS_SUCCESS : SS_FILE_ERROR;
01526    } else {
01527       /* non-ascii format: only write buffer */
01528 
01529       /* insert empty line after each event */
01530       strcat(pbuf, "\n");
01531       size = strlen(buffer);
01532 
01533       /* write record to device */
01534       if (log_chn->type == LOG_TYPE_TAPE)
01535          status = ss_tape_write(log_chn->handle, buffer, size);
01536       else if (log_chn->type == LOG_TYPE_FTP)
01537          status = ftp_send((log_chn->ftp_con)->data, buffer, size) == size ?
01538              SS_SUCCESS : SS_FILE_ERROR;
01539       else
01540          status = write(log_chn->handle, buffer, size) == size ? SS_SUCCESS : SS_FILE_ERROR;
01541    }
01542 
01543    /* update statistics */
01544    log_chn->statistics.events_written++;
01545    log_chn->statistics.bytes_written += size;
01546    log_chn->statistics.bytes_written_total += size;
01547 
01548    return status;
01549 }

INT ftp_error ( char *  message  ) 

Definition at line 899 of file mlogger.c.

00900 {
00901    cm_msg(MERROR, "ftp_error", message);
00902    return 1;
00903 }

INT ftp_open ( char *  destination,
FTP_CON **  con 
)

Definition at line 905 of file mlogger.c.

00906 {
00907    INT status;
00908    short port = 0;
00909    char *token, host_name[HOST_NAME_LENGTH],
00910        user[32], pass[32], directory[256], file_name[256], file_mode[256];
00911 
00912    /*
00913       destination should have the form:
00914       host, port, user, password, directory, run%05d.mid
00915     */
00916 
00917    /* break destination in components */
00918    token = strtok(destination, ",");
00919    if (token)
00920       strcpy(host_name, token);
00921 
00922    token = strtok(NULL, ", ");
00923    if (token)
00924       port = atoi(token);
00925 
00926    token = strtok(NULL, ", ");
00927    if (token)
00928       strcpy(user, token);
00929 
00930    token = strtok(NULL, ", ");
00931    if (token)
00932       strcpy(pass, token);
00933 
00934    token = strtok(NULL, ", ");
00935    if (token)
00936       strcpy(directory, token);
00937 
00938    token = strtok(NULL, ", ");
00939    if (token)
00940       strcpy(file_name, token);
00941 
00942    token = strtok(NULL, ", ");
00943    file_mode[0] = 0;
00944    if (token)
00945       strcpy(file_mode, token);
00946 
00947 #ifdef FAL_MAIN
00948    ftp_debug(NULL, ftp_error);
00949 #else
00950    ftp_debug((int (*)(char *)) puts, ftp_error);
00951 #endif
00952 
00953    status = ftp_login(con, host_name, port, user, pass, "");
00954    if (status >= 0)
00955       return status;
00956 
00957    status = ftp_chdir(*con, directory);
00958    if (status >= 0)
00959       return status;
00960 
00961    status = ftp_binary(*con);
00962    if (status >= 0)
00963       return status;
00964 
00965    if (file_mode[0]) {
00966       status = ftp_command(*con, "umask %s", file_mode, 200, 250, EOF);
00967       if (status >= 0)
00968          return status;
00969    }
00970 
00971    if (ftp_open_write(*con, file_name) >= 0)
00972       return (*con)->err_no;
00973 
00974    return SS_SUCCESS;
00975 }

static int get_event_id ( int  eq_id,
const char *  eq_name,
const char *  var_name 
) [static]

Definition at line 2913 of file mlogger.c.

02914 {
02915    HNDLE hDB, hKeyRoot;
02916    char name[NAME_LENGTH+NAME_LENGTH+2];
02917    int status, i;
02918    WORD max_id = 0;
02919 
02920    strlcpy(name, eq_name, sizeof(name));
02921    strlcat(name, ":", sizeof(name));
02922    strlcat(name, var_name, sizeof(name));
02923 
02924    //printf("Looking for event id for \'%s\'\n", name);
02925 
02926    cm_get_experiment_database(&hDB, NULL);
02927    
02928    status = db_find_key(hDB, 0, "/History/Events", &hKeyRoot);
02929    if (status == DB_SUCCESS) {
02930       for (i = 0;; i++) {
02931          HNDLE hKey;
02932          KEY key;
02933          WORD evid;
02934          int size;
02935          char tmp[NAME_LENGTH+NAME_LENGTH+2];
02936          
02937          status = db_enum_key(hDB, hKeyRoot, i, &hKey);
02938          if (status != DB_SUCCESS)
02939            break;
02940          
02941          status = db_get_key(hDB, hKey, &key);
02942          assert(status == DB_SUCCESS);
02943          
02944          //printf("key \'%s\'\n", key.name);
02945          
02946          evid = (WORD) strtol(key.name, NULL, 0);
02947          if (evid == 0)
02948             continue;
02949 
02950          size = sizeof(tmp);
02951          status = db_get_data(hDB, hKey, tmp, &size, TID_STRING);
02952          //printf("status %d\n", status);
02953          assert(status == DB_SUCCESS);
02954 
02955          //printf("got %d \'%s\' looking for \'%s\'\n", evid, tmp, name);
02956 
02957          if (equal_ustring(name, tmp))
02958             return evid;
02959 
02960          if (evid/1000 == eq_id)
02961             max_id = evid;
02962       }
02963    }
02964 
02965    //printf("eq_id %d, max_id %d\n", eq_id, max_id);
02966 
02967    if (max_id == 0)
02968       max_id = eq_id * 1000;
02969 
02970    if (max_id < 1000)
02971       max_id = 1000;
02972 
02973    while (1) {
02974       char tmp[NAME_LENGTH+NAME_LENGTH+2];
02975       HNDLE hKey;
02976       WORD evid = max_id + 1;
02977 
02978       sprintf(tmp,"/History/Events/%d", evid);
02979 
02980       status = db_find_key(hDB, 0, tmp, &hKey);
02981       if (status == DB_SUCCESS) {
02982          max_id = evid;
02983          assert(max_id < 65000);
02984          continue;
02985       }
02986 
02987       status = db_set_value(hDB, 0, tmp, name, strlen(name)+1, 1, TID_STRING);
02988       assert(status == DB_SUCCESS);
02989 
02990       return evid;
02991    }
02992 
02993    /* not reached */
02994    return 0;
02995 }

INT log_callback ( INT  index,
void *  prpc_param[] 
)

Definition at line 3598 of file mlogger.c.

03599 {
03600    HNDLE hKeyRoot, hKeyChannel;
03601    INT i, status, size, channel, izero, htape, online_mode;
03602    DWORD watchdog_timeout;
03603    BOOL watchdog_flag;
03604    char str[256];
03605    double dzero;
03606 
03607    /* rewind tapes */
03608    if (index == RPC_LOG_REWIND) {
03609       channel = *((INT *) prpc_param[0]);
03610 
03611       /* loop over all channels */
03612       status = db_find_key(hDB, 0, "/Logger/Channels", &hKeyRoot);
03613       if (status != DB_SUCCESS) {
03614          cm_msg(MERROR, "log_callback", "cannot find Logger/Channels entry in database");
03615          return 0;
03616       }
03617 
03618       /* check online mode */
03619       online_mode = 0;
03620       size = sizeof(online_mode);
03621       db_get_value(hDB, 0, "/Runinfo/online mode", &online_mode, &size, TID_INT, TRUE);
03622 
03623       for (i = 0; i < MAX_CHANNELS; i++) {
03624          status = db_enum_key(hDB, hKeyRoot, i, &hKeyChannel);
03625          if (status == DB_NO_MORE_SUBKEYS)
03626             break;
03627 
03628          /* skip if wrong channel, -1 means rewind all channels */
03629          if (channel != i && channel != -1)
03630             continue;
03631 
03632          if (status == DB_SUCCESS) {
03633             size = sizeof(str);
03634             status = db_get_value(hDB, hKeyChannel, "Settings/Type", str, &size, TID_STRING, TRUE);
03635             if (status != DB_SUCCESS)
03636                continue;
03637 
03638             if (equal_ustring(str, "Tape")) {
03639                size = sizeof(str);
03640                status = db_get_value(hDB, hKeyChannel, "Settings/Filename", str, &size, TID_STRING, TRUE);
03641                if (status != DB_SUCCESS)
03642                   continue;
03643 
03644                if (ss_tape_open(str, O_RDONLY, &htape) == SS_SUCCESS) {
03645                   cm_msg(MTALK, "log_callback", "rewinding tape #%d, please wait", i);
03646 
03647                   cm_get_watchdog_params(&watchdog_flag, &watchdog_timeout);
03648                   cm_set_watchdog_params(watchdog_flag, 300000);        /* 5 min for tape rewind */
03649                   ss_tape_rewind(htape);
03650                   if (online_mode)
03651                      ss_tape_unmount(htape);
03652                   cm_set_watchdog_params(watchdog_flag, watchdog_timeout);
03653 
03654                   cm_msg(MINFO, "log_callback", "Tape %s rewound sucessfully", str);
03655                } else
03656                   cm_msg(MERROR, "log_callback", "Cannot rewind tape %s", str);
03657 
03658                ss_tape_close(htape);
03659 
03660                /* clear statistics */
03661                dzero = izero = 0;
03662                log_chn[i].statistics.bytes_written_total = 0;
03663                log_chn[i].statistics.files_written = 0;
03664                db_set_value(hDB, hKeyChannel, "Statistics/Bytes written total", &dzero,
03665                             sizeof(dzero), 1, TID_DOUBLE);
03666                db_set_value(hDB, hKeyChannel, "Statistics/Files written", &izero, sizeof(izero), 1, TID_INT);
03667             }
03668          }
03669       }
03670 
03671       cm_msg(MTALK, "log_callback", "tape rewind finished");
03672    }
03673 
03674    return RPC_SUCCESS;
03675 }

INT log_close ( LOG_CHN *  log_chn,
INT  run_number 
)

Definition at line 2292 of file mlogger.c.

02293 {
02294    if (log_chn->format == FORMAT_YBOS)
02295      assert(!"YBOS not supported anymore");
02296 
02297    if (log_chn->format == FORMAT_ASCII)
02298       ascii_log_close(log_chn, run_number);
02299 
02300    if (log_chn->format == FORMAT_DUMP)
02301       dump_log_close(log_chn, run_number);
02302 
02303 #ifdef HAVE_ROOT
02304    if (log_chn->format == FORMAT_ROOT)
02305       root_log_close(log_chn, run_number);
02306 #endif
02307 
02308    if (log_chn->format == FORMAT_MIDAS)
02309       midas_log_close(log_chn, run_number);
02310 
02311    log_chn->statistics.files_written += 1;
02312    log_chn->handle = 0;
02313    log_chn->ftp_con = NULL;
02314 
02315    return SS_SUCCESS;
02316 }

int log_generate_file_name ( LOG_CHN *  log_chn  ) 

Definition at line 3679 of file mlogger.c.

Referenced by tr_start().

03680 {
03681    INT size, status, run_number;
03682    char str[256], path[256], dir[256], data_dir[256];
03683    CHN_SETTINGS *chn_settings;
03684    time_t now;
03685    struct tm *tms;
03686 
03687    chn_settings = &log_chn->settings;
03688    size = sizeof(run_number);
03689    status = db_get_value(hDB, 0, "Runinfo/Run number", &run_number, &size, TID_INT, TRUE);
03690    assert(status == SUCCESS);
03691 
03692    data_dir[0] = 0;
03693 
03694    /* if disk, precede filename with directory if not already there */
03695    if (log_chn->type == LOG_TYPE_DISK && chn_settings->filename[0] != DIR_SEPARATOR) {
03696       size = sizeof(data_dir);
03697       dir[0] = 0;
03698       db_get_value(hDB, 0, "/Logger/Data Dir", data_dir, &size, TID_STRING, TRUE);
03699       if (data_dir[0] != 0)
03700          if (data_dir[strlen(data_dir) - 1] != DIR_SEPARATOR)
03701             strcat(data_dir, DIR_SEPARATOR_STR);
03702       strcpy(str, data_dir);
03703 
03704       /* append subdirectory if requested */
03705       if (chn_settings->subdir_format[0]) {
03706          tzset();
03707          time(&now);
03708          tms = localtime(&now);
03709 
03710          strftime(dir, sizeof(dir), chn_settings->subdir_format, tms);
03711          strcat(str, dir);
03712          strcat(str, DIR_SEPARATOR_STR);
03713       }
03714 
03715       /* create directory if needed */
03716 #ifdef OS_WINNT
03717       status = mkdir(str);
03718 #else
03719       status = mkdir(str, 0755);
03720 #endif
03721 #if !defined(HAVE_MYSQL) && !defined(OS_WINNT)  /* errno not working with mySQL lib */
03722       if (status == -1 && errno != EEXIST)
03723          cm_msg(MERROR, "log_generate_file_name", "Cannot create subdirectory %s", str);
03724 #endif
03725 
03726       strcat(str, chn_settings->filename);
03727    } else
03728       strcpy(str, chn_settings->filename);
03729 
03730    /* check if two "%" are present in filename */
03731    if (strchr(str, '%')) {
03732       if (strchr(strchr(str, '%')+1, '%')) {
03733          /* substitude first "%d" by current run number, second "%d" by subrun number */
03734          sprintf(path, str, run_number, log_chn->subrun_number);
03735       } else {
03736          /* substitue "%d" by current run number */
03737          sprintf(path, str, run_number);
03738       }
03739    } else
03740       strcpy(path, str);
03741 
03742    strcpy(log_chn->path, path);
03743 
03744    /* write back current file name to ODB */
03745    if (strncmp(path, data_dir, strlen(data_dir)) == 0)
03746       strcpy(str, path + strlen(data_dir));
03747    else
03748       strcpy(str, path);
03749    db_set_value(hDB, log_chn->settings_hkey, "Current filename", str, 256, 1, TID_STRING);
03750 
03751    return CM_SUCCESS;
03752 }

void log_history ( HNDLE  hDB,
HNDLE  hKey,
void *  info 
)

void log_odb_dump ( LOG_CHN *  log_chn,
short int  event_id,
INT  run_number 
)

Definition at line 174 of file mlogger.c.

00175 {
00176    INT status, buffer_size, size;
00177    EVENT_HEADER *pevent;
00178 
00179    /* write ODB dump */
00180    buffer_size = 100000;
00181    do {
00182       pevent = (EVENT_HEADER *) malloc(buffer_size);
00183       if (pevent == NULL) {
00184          cm_msg(MERROR, "log_odb_dump", "Cannot allocate ODB dump buffer");
00185          break;
00186       }
00187 
00188       size = buffer_size - sizeof(EVENT_HEADER);
00189       status = db_copy_xml(hDB, 0, (char *) (pevent + 1), &size);
00190 
00191       /* following line would dump ODB in old ASCII format instead of XML */
00192       //status = db_copy(hDB, 0, (char *) (pevent + 1), &size, "");
00193       if (status != DB_TRUNCATED) {
00194          bm_compose_event(pevent, event_id, MIDAS_MAGIC,
00195                           buffer_size - sizeof(EVENT_HEADER) - size + 1, run_number);
00196          log_write(log_chn, pevent);
00197          free(pevent);
00198          break;
00199       }
00200 
00201       /* increase buffer size if truncated */
00202       free(pevent);
00203       buffer_size *= 10;
00204    } while (1);
00205 }

INT log_open ( LOG_CHN *  log_chn,
INT  run_number 
)

Definition at line 2262 of file mlogger.c.

02263 {
02264    INT status;
02265 
02266    if (equal_ustring(log_chn->settings.format, "YBOS")) {
02267      assert(!"YBOS not supported anymore");
02268    } else if (equal_ustring(log_chn->settings.format, "ASCII")) {
02269       log_chn->format = FORMAT_ASCII;
02270       status = ascii_log_open(log_chn, run_number);
02271    } else if (equal_ustring(log_chn->settings.format, "DUMP")) {
02272       log_chn->format = FORMAT_DUMP;
02273       status = dump_log_open(log_chn, run_number);
02274    } else if (equal_ustring(log_chn->settings.format, "ROOT")) {
02275 #ifdef HAVE_ROOT
02276       log_chn->format = FORMAT_ROOT;
02277       status = root_log_open(log_chn, run_number);
02278 #else
02279       return SS_NO_ROOT;
02280 #endif
02281    } else if (equal_ustring(log_chn->settings.format, "MIDAS")) {
02282       log_chn->format = FORMAT_MIDAS;
02283       status = midas_log_open(log_chn, run_number);
02284    } else
02285       return SS_INVALID_FORMAT;
02286 
02287    return status;
02288 }

void log_system_history ( HNDLE  hDB,
HNDLE  hKey,
void *  info 
)

INT log_write ( LOG_CHN *  log_chn,
EVENT_HEADER pheader 
)

void logger_init (  ) 

Definition at line 102 of file mlogger.c.

00103 {
00104    INT size, status, delay, index;
00105    BOOL flag;
00106    HNDLE hKey, hKeyChannel;
00107    KEY key;
00108    char str[256];
00109 
00110    /*---- create /logger entries -----*/
00111 
00112    cm_get_path(str);
00113    size = sizeof(str);
00114    db_get_value(hDB, 0, "/Logger/Data dir", str, &size, TID_STRING, TRUE);
00115 
00116    strcpy(str, "midas.log");
00117    size = sizeof(str);
00118    db_get_value(hDB, 0, "/Logger/Message file", str, &size, TID_STRING, TRUE);
00119 
00120    size = sizeof(BOOL);
00121    flag = TRUE;
00122    db_get_value(hDB, 0, "/Logger/Write data", &flag, &size, TID_BOOL, TRUE);
00123 
00124    flag = FALSE;
00125    db_get_value(hDB, 0, "/Logger/ODB Dump", &flag, &size, TID_BOOL, TRUE);
00126 
00127    strcpy(str, "run%05d.odb");
00128    size = sizeof(str);
00129    db_get_value(hDB, 0, "/Logger/ODB Dump File", str, &size, TID_STRING, TRUE);
00130 
00131    flag = FALSE;
00132    size = sizeof(BOOL);
00133    db_get_value(hDB, 0, "/Logger/Auto restart", &flag, &size, TID_BOOL, TRUE);
00134 
00135    delay = 0;
00136    size = sizeof(INT);
00137    db_get_value(hDB, 0, "/Logger/Auto restart delay", &delay, &size, TID_INT, TRUE);
00138 
00139    flag = TRUE;
00140    db_get_value(hDB, 0, "/Logger/Tape message", &flag, &size, TID_BOOL, TRUE);
00141 
00142    /* create at least one logging channel */
00143    status = db_find_key(hDB, 0, "/Logger/Channels/0", &hKey);
00144    if (status != DB_SUCCESS) {
00145       /* if no channels are defined, define at least one */
00146       status = db_create_record(hDB, 0, "/Logger/Channels/0", strcomb(chn_settings_str));
00147       if (status != DB_SUCCESS)
00148          cm_msg(MERROR, "logger_init", "Cannot create channel entry in database");
00149    } else {
00150       /* check format of other channels */
00151       status = db_find_key(hDB, 0, "/Logger/Channels", &hKey);
00152       if (status == DB_SUCCESS) {
00153          for (index = 0; index < MAX_CHANNELS; index++) {
00154             status = db_enum_key(hDB, hKey, index, &hKeyChannel);
00155             if (status == DB_NO_MORE_SUBKEYS)
00156                break;
00157 
00158             db_get_key(hDB, hKeyChannel, &key);
00159             status = db_check_record(hDB, hKey, key.name, strcomb(chn_settings_str), TRUE);
00160             if (status != DB_SUCCESS && status != DB_OPEN_RECORD) {
00161                cm_msg(MERROR, "logger_init", "Cannot create/check channel record");
00162                break;
00163             }
00164          }
00165       }
00166    }
00167 #ifdef HAVE_MYSQL
00168    create_sql_tree();
00169 #endif
00170 }

int main ( int  argc,
char *  argv[] 
)

Definition at line 4314 of file mlogger.c.

04315 {
04316    INT status, msg, i, size, ch = 0;
04317    char host_name[HOST_NAME_LENGTH], exp_name[NAME_LENGTH], dir[256];
04318    BOOL debug, daemon, save_mode;
04319    DWORD last_time_kb = 0;
04320    DWORD last_time_stat = 0;
04321    DWORD duration;
04322    HNDLE hktemp;
04323 
04324 #ifdef HAVE_ROOT
04325    char **rargv;
04326    int rargc;
04327 
04328    /* copy first argument */
04329    rargc = 0;
04330    rargv = (char **) malloc(sizeof(char *) * 2);
04331    rargv[rargc] = (char *) malloc(strlen(argv[rargc]) + 1);
04332    strcpy(rargv[rargc], argv[rargc]);
04333    rargc++;
04334 
04335    /* append argument "-b" for batch mode without graphics */
04336    rargv[rargc++] = "-b";
04337 
04338    TApplication theApp("mlogger", &rargc, rargv);
04339 
04340    /* free argument memory */
04341    free(rargv[0]);
04342    free(rargv);
04343 
04344 #endif
04345 
04346    setbuf(stdout, NULL);
04347    setbuf(stderr, NULL);
04348 
04349    /* get default from environment */
04350    cm_get_environment(host_name, sizeof(host_name), exp_name, sizeof(exp_name));
04351 
04352    debug = daemon = save_mode = FALSE;
04353 
04354    /* parse command line parameters */
04355    for (i = 1; i < argc; i++) {
04356       if (argv[i][0] == '-' && argv[i][1] == 'd')
04357          debug = TRUE;
04358       else if (argv[i][0] == '-' && argv[i][1] == 'D')
04359          daemon = TRUE;
04360       else if (argv[i][0] == '-' && argv[i][1] == 's')
04361          save_mode = TRUE;
04362       else if (argv[i][0] == '-' && argv[i][1] == 'v')
04363          verbose = TRUE;
04364       else if (argv[i][0] == '-') {
04365          if (i + 1 >= argc || argv[i + 1][0] == '-')
04366             goto usage;
04367          if (argv[i][1] == 'e')
04368             strcpy(exp_name, argv[++i]);
04369          else {
04370           usage:
04371             printf("usage: mlogger [-e Experiment] [-d] [-D] [-s] [-v]\n\n");
04372             return 1;
04373          }
04374       }
04375    }
04376 
04377    if (daemon) {
04378       printf("Becoming a daemon...\n");
04379       ss_daemon_init(FALSE);
04380    }
04381 
04382    status = cm_connect_experiment(host_name, exp_name, "Logger", NULL);
04383    if (status != CM_SUCCESS)
04384       return 1;
04385 
04386    /* check if logger already running */
04387    status = cm_exist("Logger", FALSE);
04388    if (status == CM_SUCCESS) {
04389       printf("Logger runs already.\n");
04390       cm_disconnect_experiment();
04391       return 1;
04392    }
04393 
04394    cm_get_experiment_database(&hDB, NULL);
04395 
04396    /* set default watchdog timeout */
04397    cm_set_watchdog_params(TRUE, LOGGER_TIMEOUT);
04398 
04399    /* turn off watchdog if in debug mode */
04400    if (debug)
04401       cm_set_watchdog_params(TRUE, 0);
04402 
04403    /* turn on save mode */
04404    if (save_mode) {
04405       cm_set_watchdog_params(FALSE, 0);
04406       db_protect_database(hDB);
04407    }
04408 
04409    /* register transition callbacks */
04410    if (cm_register_transition(TR_START, tr_start, 200) != CM_SUCCESS) {
04411       cm_msg(MERROR, "main", "cannot register callbacks");
04412       return 1;
04413    }
04414 
04415    cm_register_transition(TR_STARTABORT, tr_start_abort, 800);
04416    cm_register_transition(TR_STOP, tr_stop, 800);
04417    cm_register_transition(TR_PAUSE, tr_pause, 800);
04418    cm_register_transition(TR_RESUME, tr_resume, 200);
04419 
04420    /* register callback for rewinding tapes */
04421    cm_register_function(RPC_LOG_REWIND, log_callback);
04422 
04423    /* initialize ODB */
04424    logger_init();
04425 
04426    /* obtain current state */
04427    local_state = STATE_STOPPED;
04428    size = sizeof(local_state);
04429    status = db_get_value(hDB, 0, "/Runinfo/State", &local_state, &size, TID_INT, true);
04430 
04431    /* open history logging */
04432    if (open_history() != CM_SUCCESS) {
04433       printf("Error in history system, aborting startup.\n");
04434       cm_disconnect_experiment();
04435       return 1;
04436    }
04437 
04438    /* turn off message display, turn on message logging */
04439    cm_set_msg_print(MT_ALL, 0, NULL);
04440 
04441    /* print startup message */
04442    size = sizeof(dir);
04443    db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
04444    printf("Log     directory is %s\n", dir);
04445    printf("Data    directory is same as Log unless specified in channels/\n");
04446 
04447    /* Alternate History and Elog path */
04448    size = sizeof(dir);
04449    dir[0] = 0;
04450    status = db_find_key(hDB, 0, "/Logger/History dir", &hktemp);
04451    if (status == DB_SUCCESS)
04452       db_get_value(hDB, 0, "/Logger/History dir", dir, &size, TID_STRING, TRUE);
04453    else
04454       sprintf(dir, "same as Log");
04455    printf("History directory is %s\n", dir);
04456 
04457    size = sizeof(dir);
04458    dir[0] = 0;
04459    status = db_find_key(hDB, 0, "/Logger/Elog dir", &hktemp);
04460    if (status == DB_SUCCESS)
04461       db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, TRUE);
04462    else
04463       sprintf(dir, "same as Log");
04464    printf("ELog    directory is %s\n", dir);
04465 
04466 #ifdef HAVE_MYSQL
04467    {
04468       char sql_host[256], sql_db[256], sql_table[256];
04469 
04470       status = db_find_key(hDB, 0, "/Logger/SQL/Hostname", &hktemp);
04471       if (status == DB_SUCCESS) {
04472          size = 256;
04473          db_get_value(hDB, 0, "/Logger/SQL/Hostname", sql_host, &size, TID_STRING, FALSE);
04474          size = 256;
04475          db_get_value(hDB, 0, "/Logger/SQL/Database", sql_db, &size, TID_STRING, FALSE);
04476          size = 256;
04477          db_get_value(hDB, 0, "/Logger/SQL/Table", sql_table, &size, TID_STRING, FALSE);
04478          printf("SQL     database is %s/%s/%s", sql_host, sql_db, sql_table);
04479       }
04480    }
04481 #endif
04482 
04483    printf("\nMIDAS logger started. Stop with \"!\"\n");
04484 
04485    /* initialize ss_getchar() */
04486    ss_getchar(0);
04487 
04488    do {
04489       msg = cm_yield(1000);
04490 
04491       /* update channel statistics once every second */
04492       if (ss_millitime() - last_time_stat > 1000) {
04493          last_time_stat = ss_millitime();
04494          db_send_changed_records();
04495       }
04496 
04497       /* check for auto restart */
04498       if (auto_restart && ss_time() > auto_restart) {
04499          status = start_the_run();
04500       }
04501 
04502       /* check if time is reached to stop run */
04503       duration = 0;
04504       size = sizeof(duration);
04505       db_get_value(hDB, 0, "/Logger/Run duration", &duration, &size, TID_DWORD, true);
04506       if (!stop_requested && !in_stop_transition && local_state != STATE_STOPPED &&
04507           duration > 0 && ss_time() >= run_start_time + duration) {
04508          cm_msg(MTALK, "main", "stopping run after %d seconds", duration);
04509          status = stop_the_run(1);
04510       }
04511 
04512       /* check keyboard once every second */
04513       if (ss_millitime() - last_time_kb > 1000) {
04514          last_time_kb = ss_millitime();
04515 
04516          ch = 0;
04517          while (ss_kbhit()) {
04518             ch = ss_getchar(0);
04519             if (ch == -1)
04520                ch = getchar();
04521 
04522             if ((char) ch == '!')
04523                break;
04524          }
04525       }
04526 
04527    } while (msg != RPC_SHUTDOWN && msg != SS_ABORT && ch != '!');
04528 
04529    /* reset terminal */
04530    ss_getchar(TRUE);
04531 
04532    /* close history logging */
04533    close_history();
04534 
04535    cm_disconnect_experiment();
04536 
04537    return 0;
04538 }

INT midas_flush_buffer ( LOG_CHN *  log_chn  ) 

Definition at line 979 of file mlogger.c.

00980 {
00981    INT size, written;
00982    MIDAS_INFO *info;
00983 
00984    info = (MIDAS_INFO *) log_chn->format_info;
00985    size = (POINTER_T) info->write_pointer - (POINTER_T) info->buffer;
00986 
00987    if (size == 0)
00988       return 0;
00989 
00990    /* write record to device */
00991    if (log_chn->type == LOG_TYPE_TAPE)
00992       written = ss_tape_write(log_chn->handle, info->buffer, size);
00993    else if (log_chn->type == LOG_TYPE_FTP)
00994       written =
00995           ftp_send(((FTP_CON *) log_chn->ftp_con)->data, info->buffer,
00996                    size) == size ? SS_SUCCESS : SS_FILE_ERROR;
00997    else if (log_chn->gzfile) {
00998 #ifdef HAVE_ZLIB
00999       z_streamp s;
01000       INT i;
01001 
01002       s = (z_streamp) log_chn->gzfile;
01003       written = s->total_out;
01004       i = gzwrite(log_chn->gzfile, info->buffer, size);
01005       if (i != size)
01006          return -1;
01007       written = s->total_out - written;
01008 #else
01009       assert(!"this cannot happen! support for ZLIB not compiled in");
01010 #endif
01011    } else if (log_chn->handle) {
01012 #ifdef OS_WINNT
01013       WriteFile((HANDLE) log_chn->handle, info->buffer, size, (unsigned long *) &written, NULL);
01014 #else
01015       written = write(log_chn->handle, info->buffer, size);
01016 #endif
01017    } else {
01018       /* we are writing into the void!?! */
01019       written = 0;
01020    }
01021 
01022    info->write_pointer = info->buffer;
01023 
01024    return written;
01025 }

INT midas_log_close ( LOG_CHN *  log_chn,
INT  run_number 
)

Definition at line 1213 of file mlogger.c.

01214 {
01215    int written;
01216 
01217    /* write ODB dump */
01218    if (log_chn->settings.odb_dump)
01219       log_odb_dump(log_chn, EVENTID_EOR, run_number);
01220 
01221    written = midas_flush_buffer(log_chn);
01222 
01223    /* update statistics */
01224    log_chn->statistics.bytes_written += written;
01225    log_chn->statistics.bytes_written_total += written;
01226 
01227    /* Write EOF if Tape */
01228    if (log_chn->type == LOG_TYPE_TAPE) {
01229       /* writing EOF mark on tape Fonly */
01230       ss_tape_write_eof(log_chn->handle);
01231       ss_tape_close(log_chn->handle);
01232    } else if (log_chn->type == LOG_TYPE_FTP) {
01233       ftp_close(log_chn->ftp_con);
01234       ftp_bye(log_chn->ftp_con);
01235    } else {
01236       if (log_chn->gzfile) {
01237 #ifdef HAVE_ZLIB
01238          z_streamp s;
01239 
01240          s = (z_streamp) log_chn->gzfile;
01241          written = s->total_out;
01242          gzflush(log_chn->gzfile, Z_FULL_FLUSH);
01243          written = s->total_out - written;
01244          gzclose(log_chn->gzfile);
01245          log_chn->statistics.bytes_written += written;
01246          log_chn->statistics.bytes_written_total += written;
01247          log_chn->gzfile = NULL;
01248 #else
01249          assert(!"this cannot happen! support for ZLIB not compiled in");
01250 #endif
01251       }
01252 #ifdef OS_WINNT
01253       CloseHandle((HANDLE) log_chn->handle);
01254 #else
01255       close(log_chn->handle);
01256 #endif
01257       log_chn->handle = 0;
01258    }
01259 
01260    free(((MIDAS_INFO *) log_chn->format_info)->buffer);
01261    free(log_chn->format_info);
01262 
01263    return SS_SUCCESS;
01264 }

INT midas_log_open ( LOG_CHN *  log_chn,
INT  run_number 
)

Definition at line 1085 of file mlogger.c.

01086 {
01087    MIDAS_INFO *info;
01088    INT status;
01089 
01090    /* allocate MIDAS buffer info */
01091    log_chn->format_info = (void **) malloc(sizeof(MIDAS_INFO));
01092 
01093    info = (MIDAS_INFO *) log_chn->format_info;
01094    if (info == NULL) {
01095       log_chn->handle = 0;
01096       return SS_NO_MEMORY;
01097    }
01098 
01099    /* allocate full ring buffer for that channel */
01100    if ((info->buffer = (char *) malloc(TAPE_BUFFER_SIZE)) == NULL) {
01101       free(info);
01102       log_chn->handle = 0;
01103       return SS_NO_MEMORY;
01104    }
01105 
01106    info->write_pointer = info->buffer;
01107 
01108    /* Create device channel */
01109    if (log_chn->type == LOG_TYPE_TAPE) {
01110       status = tape_open(log_chn->path, &log_chn->handle);
01111       if (status != SS_SUCCESS) {
01112          free(info->buffer);
01113          free(info);
01114          log_chn->handle = 0;
01115          return status;
01116       }
01117    } else if (log_chn->type == LOG_TYPE_FTP) {
01118       status = ftp_open(log_chn->path, &log_chn->ftp_con);
01119       if (status != SS_SUCCESS) {
01120          free(info->buffer);
01121          free(info);
01122          log_chn->handle = 0;
01123          return status;
01124       } else
01125          log_chn->handle = 1;
01126    } else {
01127       /* check if file exists */
01128       if (strstr(log_chn->path, "null") == NULL) {
01129          log_chn->handle = open(log_chn->path, O_RDONLY);
01130          if (log_chn->handle > 0) {
01131             /* check if file length is nonzero */
01132             if (lseek(log_chn->handle, 0, SEEK_END) > 0) {
01133                close(log_chn->handle);
01134                free(info->buffer);
01135                free(info);
01136                log_chn->handle = 0;
01137                return SS_FILE_EXISTS;
01138             }
01139          }
01140       }
01141 
01142       log_chn->gzfile = NULL;
01143       log_chn->handle = 0;
01144          
01145       /* check that compression level and file name match each other */
01146       if (1) {
01147          char *sufp = strstr(log_chn->path, ".gz");
01148          int isgz = sufp && sufp[3]==0;
01149          
01150          if (log_chn->compression>0 && !isgz) {
01151             cm_msg(MERROR, "midas_log_open", "Compression level %d enabled, but output file name \'%s\' does not end with '.gz'", log_chn->compression, log_chn->path);
01152             free(info->buffer);
01153             free(info);
01154             return SS_FILE_ERROR;
01155          }
01156 
01157          if (log_chn->compression==0 && isgz) {
01158             cm_msg(MERROR, "midas_log_open",
01159                    "Output file name ends with '.gz', but compression level is zero");
01160             free(info->buffer);
01161             free(info);
01162             return SS_FILE_ERROR;
01163          }
01164       }
01165 
01166 #ifdef OS_WINNT
01167       log_chn->handle = (int) CreateFile(log_chn->path, GENERIC_WRITE, FILE_SHARE_READ, NULL,
01168                                          CREATE_ALWAYS,
01169                                          FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_SEQUENTIAL_SCAN, 0);
01170 #else
01171       log_chn->handle = open(log_chn->path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644);
01172 #endif
01173       if (log_chn->handle < 0) {
01174          free(info->buffer);
01175          free(info);
01176          log_chn->handle = 0;
01177          return SS_FILE_ERROR;
01178       }
01179 
01180       if (log_chn->compression > 0) {
01181 #ifdef HAVE_ZLIB
01182          log_chn->gzfile = gzdopen(log_chn->handle, "wb");
01183          if (log_chn->gzfile == NULL) {
01184             cm_msg(MERROR, "midas_log_open",
01185                    "Error: gzdopen() failed, cannot open compression stream");
01186             free(info->buffer);
01187             free(info);
01188             log_chn->handle = 0;
01189             return SS_FILE_ERROR;
01190          }
01191 
01192          gzsetparams(log_chn->gzfile, log_chn->compression, Z_DEFAULT_STRATEGY);
01193 #else
01194          cm_msg(MERROR, "midas_log_open", "Compression enabled but ZLIB support not compiled in");
01195          close(log_chn->handle);
01196          free(info->buffer);
01197          free(info);
01198          log_chn->handle = 0;
01199          return SS_FILE_ERROR;
01200 #endif
01201       }
01202    }
01203 
01204    /* write ODB dump */
01205    if (log_chn->settings.odb_dump)
01206       log_odb_dump(log_chn, EVENTID_BOR, run_number);
01207 
01208    return SS_SUCCESS;
01209 }

INT midas_write ( LOG_CHN *  log_chn,
EVENT_HEADER pevent,
INT  evt_size 
)

Definition at line 1030 of file mlogger.c.

01031 {
01032    INT i, written, size_left;
01033    MIDAS_INFO *info;
01034 
01035    info = (MIDAS_INFO *) log_chn->format_info;
01036    written = 0;
01037 
01038    /* check if event fits into buffer */
01039    size_left = TAPE_BUFFER_SIZE - ((POINTER_T) info->write_pointer - (POINTER_T) info->buffer);
01040 
01041    if (size_left < evt_size) {
01042       /* copy first part of event */
01043       memcpy(info->write_pointer, pevent, size_left);
01044       info->write_pointer += size_left;
01045 
01046       /* flush buffer */
01047       written += midas_flush_buffer(log_chn);
01048       if (written < 0)
01049          return SS_FILE_ERROR;
01050 
01051       /* several writes for large events */
01052       while (evt_size - size_left >= TAPE_BUFFER_SIZE) {
01053          memcpy(info->buffer, (char *) pevent + size_left, TAPE_BUFFER_SIZE);
01054          info->write_pointer += TAPE_BUFFER_SIZE;
01055          size_left += TAPE_BUFFER_SIZE;
01056 
01057          i = midas_flush_buffer(log_chn);
01058          if (i < 0)
01059             return SS_FILE_ERROR;
01060 
01061          written += i;
01062       }
01063 
01064       /* copy remaining part of event */
01065       memcpy(info->buffer, (char *) pevent + size_left, evt_size - size_left);
01066       info->write_pointer = info->buffer + (evt_size - size_left);
01067    } else {
01068       /* copy event to buffer */
01069       memcpy(info->write_pointer, pevent, evt_size);
01070       info->write_pointer += evt_size;
01071    }
01072 
01073    /* update statistics */
01074    log_chn->statistics.events_written++;
01075    log_chn->statistics.bytes_written_uncompressed += evt_size;
01076    log_chn->statistics.bytes_written += written;
01077    log_chn->statistics.bytes_written_subrun += written;
01078    log_chn->statistics.bytes_written_total += written;
01079 
01080    return SS_SUCCESS;
01081 }

void odb_save ( const char *  filename  ) 

Definition at line 209 of file mlogger.c.

00210 {
00211    int size;
00212    char dir[256];
00213    char path[256];
00214 
00215    if (strchr(filename, DIR_SEPARATOR) == NULL) {
00216       size = sizeof(dir);
00217       dir[0] = 0;
00218       db_get_value(hDB, 0, "/Logger/Data Dir", dir, &size, TID_STRING, TRUE);
00219       if (dir[0] != 0)
00220          if (dir[strlen(dir) - 1] != DIR_SEPARATOR)
00221             strcat(dir, DIR_SEPARATOR_STR);
00222       strcpy(path, dir);
00223       strcat(path, filename);
00224    } else
00225       strcpy(path, filename);
00226 
00227    if (strstr(filename, ".xml") || strstr(filename, ".XML"))
00228       db_save_xml(hDB, 0, path);
00229    else
00230       db_save(hDB, 0, path, FALSE);
00231 }

INT open_history (  ) 

Definition at line 2997 of file mlogger.c.

02998 {
02999    INT size, index, i_tag, status, i, j, li, max_event_id;
03000    int ieq;
03001    INT n_var, n_tags, n_names = 0;
03002    HNDLE hKeyRoot, hKeyVar, hKeyNames, hLinkKey, hVarKey, hKeyEq, hHistKey, hKey;
03003    DWORD history;
03004    TAG *tag = NULL;
03005    KEY key, varkey, linkkey, histkey;
03006    WORD eq_id;
03007    char str[256], eq_name[NAME_LENGTH], hist_name[NAME_LENGTH];
03008    BOOL single_names;
03009    int count_events = 0;
03010    int global_per_variable_history = 0;
03011 
03012    for (unsigned i=0; i<mh.size(); i++)
03013       delete mh[i];
03014    mh.clear();
03015 
03016 #ifdef HAVE_ODBC
03017    int debug = 0;
03018    size = sizeof(debug);
03019    status = db_get_value(hDB, 0, "/Logger/ODBC_Debug", &debug, &size, TID_INT, TRUE);
03020    assert(status==DB_SUCCESS);
03021 
03022    /* check ODBC connection */
03023    char dsn[256];
03024    size = sizeof(dsn);
03025    dsn[0] = 0;
03026 
03027    status = db_get_value(hDB, 0, "/Logger/ODBC_DSN", dsn, &size, TID_STRING, TRUE);
03028    assert(status==DB_SUCCESS);
03029 
03030    if (debug == 2) {
03031 
03032       MidasHistoryInterface* hi = MakeMidasHistorySqlDebug();
03033       assert(hi);
03034 
03035       hi->hs_set_debug(debug);
03036       
03037       status = hi->hs_connect(dsn);
03038       if (status != HS_SUCCESS) {
03039          cm_msg(MERROR, "open_history", "Cannot connect to SQL debug driver \'%s\', status %d", dsn, status);
03040          return status;
03041       }
03042 
03043       mh.push_back(hi);
03044 
03045    } else if (strlen(dsn)>1 && dsn[0]!='#') {
03046 
03047       MidasHistoryInterface* hi = MakeMidasHistoryODBC();
03048       assert(hi);
03049 
03050       hi->hs_set_debug(debug);
03051       
03052       status = hi->hs_connect(dsn);
03053       if (status != HS_SUCCESS) {
03054          cm_msg(MERROR, "open_history", "Cannot connect to ODBC database with DSN \'%s\', status %d", dsn, status);
03055          return status;
03056       }
03057 
03058       mh.push_back(hi);
03059    }
03060 #endif
03061 
03062    for (unsigned i=0; i<mh.size(); i++) {
03063       status = mh[i]->hs_clear_cache();
03064       assert(status == HS_SUCCESS);
03065    }
03066 
03067    /* set directory for history files */
03068    size = sizeof(str);
03069    str[0] = 0;
03070    status = db_get_value(hDB, 0, "/Logger/History Dir", str, &size, TID_STRING, FALSE);
03071    if (status != DB_SUCCESS)
03072       db_get_value(hDB, 0, "/Logger/Data Dir", str, &size, TID_STRING, TRUE);
03073 
03074    if (str[0] != 0)
03075       hs_set_path(str);
03076 
03077    if (db_find_key(hDB, 0, "/History/Links", &hKeyRoot) != DB_SUCCESS ||
03078        db_find_key(hDB, 0, "/History/Links/System", &hKeyRoot) != DB_SUCCESS) {
03079       /* create default history keys */
03080       db_create_key(hDB, 0, "/History/Links", TID_KEY);
03081 
03082       if (db_find_key(hDB, 0, "/Equipment/Trigger/Statistics/Events per sec.", &hKeyEq) == DB_SUCCESS)
03083          db_create_link(hDB, 0, "/History/Links/System/Trigger per sec.",
03084                         "/Equipment/Trigger/Statistics/Events per sec.");
03085 
03086       if (db_find_key(hDB, 0, "/Equipment/Trigger/Statistics/kBytes per sec.", &hKeyEq) == DB_SUCCESS)
03087          db_create_link(hDB, 0, "/History/Links/System/Trigger kB per sec.",
03088                         "/Equipment/Trigger/Statistics/kBytes per sec.");
03089    }
03090 
03091    /*---- define equipment events as history ------------------------*/
03092 
03093    max_event_id = 0;
03094 
03095    status = db_find_key(hDB, 0, "/Equipment", &hKeyRoot);
03096    if (status != DB_SUCCESS) {
03097       cm_msg(MERROR, "open_history", "Cannot find Equipment entry in database");
03098       return 0;
03099    }
03100 
03101    size = sizeof(int);
03102    status = db_get_value(hDB, 0, "/History/PerVariableHistory", &global_per_variable_history, &size, TID_INT, TRUE);
03103    assert(status==DB_SUCCESS);
03104 
03105    /* loop over equipment */
03106    index = 0;
03107    for (ieq = 0; ; ieq++) {
03108       status = db_enum_key(hDB, hKeyRoot, ieq, &hKeyEq);
03109       if (status != DB_SUCCESS)
03110          break;
03111 
03112       /* check history flag */
03113       size = sizeof(history);
03114       db_get_value(hDB, hKeyEq, "Common/Log history", &history, &size, TID_INT, TRUE);
03115 
03116       /* define history tags only if log history flag is on */
03117       if (history > 0) {
03118          BOOL per_variable_history = global_per_variable_history;
03119 
03120          /* get equipment name */
03121          db_get_key(hDB, hKeyEq, &key);
03122          strcpy(eq_name, key.name);
03123 
03124          if (strchr(eq_name, ':'))
03125             cm_msg(MERROR, "open_history", "Equipment name \'%s\' contains characters \':\', this may break the history system", eq_name);
03126 
03127          status = db_find_key(hDB, hKeyEq, "Variables", &hKeyVar);
03128          if (status != DB_SUCCESS) {
03129             cm_msg(MERROR, "open_history", "Cannot find /Equipment/%s/Variables entry in database", eq_name);
03130             return 0;
03131          }
03132 
03133          size = sizeof(eq_id);
03134          status = db_get_value(hDB, hKeyEq, "Common/Event ID", &eq_id, &size, TID_WORD, TRUE);
03135          assert(status == DB_SUCCESS);
03136 
03137          size = sizeof(int);
03138          status = db_get_value(hDB, hKeyEq, "Settings/PerVariableHistory", &per_variable_history, &size, TID_INT, FALSE);
03139          assert(status == DB_SUCCESS || status == DB_NO_KEY);
03140 
03141          if (verbose)
03142             printf
03143                 ("\n==================== Equipment \"%s\", ID %d  =======================\n",
03144                  eq_name, eq_id);
03145 
03146          /* count keys in variables tree */
03147          for (n_var = 0, n_tags = 0;; n_var++) {
03148             status = db_enum_key(hDB, hKeyVar, n_var, &hKey);
03149             if (status == DB_NO_MORE_SUBKEYS)
03150                break;
03151             db_get_key(hDB, hKey, &key);
03152             if (key.type != TID_KEY) {
03153                n_tags += key.num_values;
03154             }
03155             else {
03156                int ii;
03157                for (ii=0;; ii++) {
03158                   KEY vvarkey;
03159                   HNDLE hhKey;
03160 
03161                   status = db_enum_key(hDB, hKey, ii, &hhKey);
03162                   if (status == DB_NO_MORE_SUBKEYS)
03163                      break;
03164 
03165                   /* get variable key */
03166                   db_get_key(hDB, hhKey, &vvarkey);
03167 
03168                   n_tags += vvarkey.num_values;
03169                }
03170             }
03171          }
03172 
03173          if (n_var == 0)
03174             cm_msg(MERROR, "open_history", "defined event %d with no variables in ODB", eq_id);
03175 
03176          /* create tag array */
03177          tag = (TAG *) malloc(sizeof(TAG) * n_tags);
03178  
03179          i_tag = 0;
03180          for (i=0; ; i++) {
03181             status = db_enum_key(hDB, hKeyVar, i, &hKey);
03182             if (status == DB_NO_MORE_SUBKEYS)
03183                break;
03184 
03185             /* get variable key */
03186             db_get_key(hDB, hKey, &varkey);
03187 
03188             /* look for names */
03189             db_find_key(hDB, hKeyEq, "Settings/Names", &hKeyNames);
03190             single_names = (hKeyNames > 0);
03191             if (hKeyNames) {
03192                if (verbose)
03193                   printf("Using \"/Equipment/%s/Settings/Names\" for variable \"%s\"\n",
03194                          eq_name, varkey.name);
03195 
03196                /* define tags from names list */
03197                db_get_key(hDB, hKeyNames, &key);
03198                n_names = key.num_values;
03199             } else {
03200                sprintf(str, "Settings/Names %s", varkey.name);
03201                db_find_key(hDB, hKeyEq, str, &hKeyNames);
03202                if (hKeyNames) {
03203                   if (verbose)
03204                      printf
03205                          ("Using \"/Equipment/%s/Settings/Names %s\" for variable \"%s\"\n",
03206                           eq_name, varkey.name, varkey.name);
03207 
03208                   /* define tags from names list */
03209                   db_get_key(hDB, hKeyNames, &key);
03210                   n_names = key.num_values;
03211                }
03212             }
03213 
03214             if (hKeyNames && n_names < varkey.num_values) {
03215                cm_msg(MERROR, "open_history",
03216                       "Array size mismatch: \"/Equipment/%s/Settings/%s\" has %d entries while \"/Equipment/%s/Variables/%s\" has %d entries",
03217                       eq_name, key.name, n_names,
03218                       eq_name, varkey.name, varkey.num_values);
03219                free(tag);
03220                return 0;
03221             }
03222 
03223             if (hKeyNames) {
03224                /* loop over array elements */
03225                for (j = 0; j < varkey.num_values; j++) {
03226                   char xname[256];
03227 
03228                   tag[i_tag].name[0] = 0;
03229 
03230                   /* get name #j */
03231                   size = sizeof(xname);
03232                   status = db_get_data_index(hDB, hKeyNames, xname, &size, j, TID_STRING);
03233                   if (status == DB_SUCCESS)
03234                      strlcpy(tag[i_tag].name, xname, sizeof(tag[i_tag].name));
03235 
03236                   if (strlen(tag[i_tag].name) < 1) {
03237                      char buf[256];
03238                      sprintf(buf, "%d", j);
03239                      strlcpy(tag[i_tag].name, varkey.name, NAME_LENGTH);
03240                      strlcat(tag[i_tag].name, "_", NAME_LENGTH);
03241                      strlcat(tag[i_tag].name, buf, NAME_LENGTH);
03242                   }
03243 
03244                   /* append variable key name for single name array */
03245                   if (single_names) {
03246                      if (strlen(tag[i_tag].name) + 1 + strlen(varkey.name) >= NAME_LENGTH) {
03247                         cm_msg(MERROR, "open_history",
03248                                "Name for history entry \"%s %s\" too long", tag[i_tag].name, varkey.name);
03249                         free(tag);
03250                         return 0;
03251                      }
03252                      strlcat(tag[i_tag].name, " ", NAME_LENGTH);
03253                      strlcat(tag[i_tag].name, varkey.name, NAME_LENGTH);
03254                   }
03255 
03256                   tag[i_tag].type = varkey.type;
03257                   tag[i_tag].n_data = 1;
03258 
03259                   if (verbose)
03260                      printf("Defined tag %d, name \"%s\", type %d, num_values %d\n",
03261                             i_tag, tag[i_tag].name, tag[i_tag].type, tag[i_tag].n_data);
03262 
03263                   i_tag++;
03264                }
03265             } else if (varkey.type == TID_KEY) {
03266                int ii;
03267                for (ii=0;; ii++) {
03268                   KEY vvarkey;
03269                   HNDLE hhKey;
03270 
03271                   status = db_enum_key(hDB, hKey, ii, &hhKey);
03272                   if (status == DB_NO_MORE_SUBKEYS)
03273                      break;
03274 
03275                   /* get variable key */
03276                   db_get_key(hDB, hhKey, &vvarkey);
03277 
03278                   strlcpy(tag[i_tag].name, varkey.name, NAME_LENGTH);
03279                   strlcat(tag[i_tag].name, "_", NAME_LENGTH);
03280                   strlcat(tag[i_tag].name, vvarkey.name, NAME_LENGTH);
03281                   tag[i_tag].type = vvarkey.type;
03282                   tag[i_tag].n_data = vvarkey.num_values;
03283 
03284                   if (verbose)
03285                      printf("Defined tag %d, name \"%s\", type %d, num_values %d\n", i_tag, tag[i_tag].name,
03286                             tag[i_tag].type, tag[i_tag].n_data);
03287 
03288                   i_tag++;
03289                }
03290             } else {
03291                strlcpy(tag[i_tag].name, varkey.name, NAME_LENGTH);
03292                tag[i_tag].type = varkey.type;
03293                tag[i_tag].n_data = varkey.num_values;
03294 
03295                if (verbose)
03296                   printf("Defined tag %d, name \"%s\", type %d, num_values %d\n", i_tag, tag[i_tag].name,
03297                          tag[i_tag].type, tag[i_tag].n_data);
03298 
03299                i_tag++;
03300             }
03301 
03302             if (per_variable_history && i_tag>0) {
03303                WORD event_id;
03304                char event_name[NAME_LENGTH];
03305 
03306                event_id = get_event_id(eq_id, eq_name, varkey.name);
03307                assert(event_id > 0);
03308 
03309                strlcpy(event_name, eq_name, NAME_LENGTH);
03310                strlcat(event_name, "/", NAME_LENGTH);
03311                strlcat(event_name, varkey.name, NAME_LENGTH);
03312 
03313                assert(i_tag <= n_tags);
03314 
03315                status = add_event(&index, event_id, event_name, hKey, i_tag, tag, history, 1);
03316                if (status != DB_SUCCESS)
03317                   return status;
03318 
03319                count_events++;
03320 
03321                i_tag = 0;
03322             } /* if per-variable history */
03323 
03324          } /* loop over variables */
03325 
03326          if (!per_variable_history && i_tag>0) {
03327             assert(i_tag <= n_tags);
03328 
03329             status = add_event(&index, eq_id, eq_name, hKeyVar, i_tag, tag, history, 1);
03330             if (status != DB_SUCCESS)
03331                return status;
03332 
03333             count_events++;
03334          }
03335 
03336          if (tag)
03337             free(tag);
03338 
03339          /* remember maximum event id for later use with system events */
03340          if (eq_id > max_event_id)
03341             max_event_id = eq_id;
03342       }
03343    } /* loop over equipments */
03344 
03345    /*---- define linked trees ---------------------------------------*/
03346 
03347    /* round up event id */
03348    max_event_id = ((int) ((max_event_id + 1) / 10) + 1) * 10;
03349 
03350    status = db_find_key(hDB, 0, "/History/Links", &hKeyRoot);
03351    if (status == DB_SUCCESS) {
03352       for (li = 0;; li++) {
03353          status = db_enum_link(hDB, hKeyRoot, li, &hHistKey);
03354          if (status == DB_NO_MORE_SUBKEYS)
03355             break;
03356 
03357          db_get_key(hDB, hHistKey, &histkey);
03358          strcpy(hist_name, histkey.name);
03359          db_enum_key(hDB, hKeyRoot, li, &hHistKey);
03360 
03361          db_get_key(hDB, hHistKey, &key);
03362          if (key.type != TID_KEY) {
03363             cm_msg(MERROR, "open_history", "Only subkeys allows in /history/links");
03364             continue;
03365          }
03366 
03367          if (verbose)
03368             printf
03369                 ("\n==================== History link \"%s\", ID %d  =======================\n",
03370                  hist_name, max_event_id);
03371 
03372          /* count subkeys in link */
03373          for (i = n_var = 0;; i++) {
03374             status = db_enum_key(hDB, hHistKey, i, &hKey);
03375             if (status == DB_NO_MORE_SUBKEYS)
03376                break;
03377 
03378             if (status == DB_SUCCESS && db_get_key(hDB, hKey, &key) == DB_SUCCESS) {
03379                if (key.type != TID_KEY)
03380                   n_var++;
03381             } else {
03382                db_enum_link(hDB, hHistKey, i, &hKey);
03383                db_get_key(hDB, hKey, &key);
03384                cm_msg(MERROR, "open_history",
03385                       "History link /History/Links/%s/%s is invalid", hist_name, key.name);
03386                return 0;
03387             }
03388          }
03389 
03390          if (n_var == 0)
03391             cm_msg(MERROR, "open_history", "History event %s has no variables in ODB", hist_name);
03392          else {
03393             /* create tag array */
03394             tag = (TAG *) malloc(sizeof(TAG) * n_var);
03395 
03396             for (i = 0, size = 0, n_var = 0;; i++) {
03397                status = db_enum_link(hDB, hHistKey, i, &hLinkKey);
03398                if (status == DB_NO_MORE_SUBKEYS)
03399                   break;
03400 
03401                /* get link key */
03402                db_get_key(hDB, hLinkKey, &linkkey);
03403 
03404                if (linkkey.type == TID_KEY)
03405                   continue;
03406 
03407                /* get link target */
03408                db_enum_key(hDB, hHistKey, i, &hVarKey);
03409                if (db_get_key(hDB, hVarKey, &varkey) == DB_SUCCESS) {
03410                   /* hot-link individual values */
03411                   if (histkey.type == TID_KEY)
03412                      db_open_record(hDB, hVarKey, NULL, varkey.total_size, MODE_READ,
03413                                     log_system_history, (void *) (POINTER_T) index);
03414 
03415                   strcpy(tag[n_var].name, linkkey.name);
03416                   tag[n_var].type = varkey.type;
03417                   tag[n_var].n_data = varkey.num_values;
03418 
03419                   if (verbose)
03420                      printf("Defined tag \"%s\", type %d, num_values %d\n",
03421                             tag[n_var].name, tag[n_var].type, tag[n_var].n_data);
03422 
03423                   size += varkey.total_size;
03424                   n_var++;
03425                }
03426             }
03427 
03428             /* hot-link whole subtree */
03429             if (histkey.type == TID_LINK)
03430                db_open_record(hDB, hHistKey, NULL, size, MODE_READ, log_system_history,
03431                               (void *) (POINTER_T) index);
03432 
03433             status = add_event(&index, max_event_id, hist_name, hHistKey, n_var, tag, 10, 0);
03434             if (status != DB_SUCCESS)
03435                return status;
03436 
03437             free(tag);
03438 
03439             count_events++;
03440             max_event_id++;
03441          }
03442       }
03443    }
03444 
03445    /*---- define run start/stop event -------------------------------*/
03446 
03447    tag = (TAG *) malloc(sizeof(TAG) * 2);
03448 
03449    strcpy(tag[0].name, "State");
03450    tag[0].type = TID_DWORD;
03451    tag[0].n_data = 1;
03452 
03453    strcpy(tag[1].name, "Run number");
03454    tag[1].type = TID_DWORD;
03455    tag[1].n_data = 1;
03456 
03457    const char* event_name = "Run transitions";
03458 
03459    for (unsigned i=0; i<mh.size(); i++) {
03460       status = mh[i]->hs_define_event(event_name, 2, tag);
03461       if (status != HS_SUCCESS) {
03462          cm_msg(MERROR, "add_event", "Cannot define event \"%s\", hs_define_event() status %d", event_name, status);
03463          return 0;
03464       }
03465    }
03466 
03467    hs_define_event(0, (char*)event_name, tag, sizeof(TAG) * 2);
03468    free(tag);
03469 
03470    /* outcommented not to produce a log entry on every run
03471    cm_msg(MINFO, "open_history", "Configured history with %d events", count_events);
03472    */
03473 
03474    return CM_SUCCESS;
03475 }

void receive_event ( HNDLE  hBuf,
HNDLE  request_id,
EVENT_HEADER pheader,
void *  pevent 
)

Definition at line 3247 of file mana.c.

03250 {
03251    INT i;
03252    ANALYZE_REQUEST *par;
03253    static DWORD buffer_size = 0;
03254    static char *buffer = NULL;
03255    char *pb;
03256 
03257    if (buffer == NULL) {
03258       buffer = (char *) malloc(MAX_EVENT_SIZE + sizeof(EVENT_HEADER));
03259 
03260       if (buffer == NULL) {
03261          cm_msg(MERROR, "receive_event", "Not enough memory to buffer event of size %d",
03262                 buffer_size);
03263          return;
03264       }
03265    }
03266 
03267    /* align buffer */
03268    pb = (char *) ALIGN8((POINTER_T) buffer);
03269 
03270    /* copy event to local buffer */
03271    memcpy(pb, pheader, pheader->data_size + sizeof(EVENT_HEADER));
03272 
03273    par = analyze_request;
03274 
03275    for (i = 0; par->event_name[0]; par++)
03276       if (par->buffer_handle == buffer_handle && par->request_id == request_id) {
03277          process_event(par, (EVENT_HEADER *) pb);
03278       }
03279 }

int start_the_run (  ) 

Definition at line 2357 of file mlogger.c.

Referenced by main().

02358 {
02359    int status, size, state, run_number;
02360    int flag, trans_flag;
02361    char errstr[256];
02362 
02363    start_requested = FALSE;
02364    auto_restart = 0;
02365 
02366    /* check if autorestart is still on */
02367    size = sizeof(BOOL);
02368    flag = FALSE;
02369    db_get_value(hDB, 0, "/Logger/Auto restart", &flag, &size, TID_BOOL, TRUE);
02370 
02371    if (!flag) {
02372       cm_msg(MINFO, "main", "Run auto restart canceled");
02373       return SUCCESS;
02374    }
02375 
02376    /* check if really stopped */
02377    size = sizeof(state);
02378    status = db_get_value(hDB, 0, "Runinfo/State", &state, &size, TID_INT, TRUE);
02379    if (status != DB_SUCCESS) {
02380       cm_msg(MERROR, "main", "cannot get Runinfo/State in database");
02381       return status;
02382    }
02383   
02384    if (state != STATE_STOPPED)
02385       return SUCCESS;
02386 
02387    size = sizeof(run_number);
02388    status = db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT, TRUE);
02389    assert(status == SUCCESS);
02390     
02391    if (run_number <= 0) {
02392       cm_msg(MERROR, "main", "aborting on attempt to use invalid run number %d", run_number);
02393       abort();
02394    }
02395     
02396    size = sizeof(BOOL);
02397    flag = FALSE;
02398    db_get_value(hDB, 0, "/Logger/Async transitions", &flag, &size, TID_BOOL, TRUE);
02399 
02400    if (flag)
02401       trans_flag = ASYNC;
02402    else
02403       trans_flag = DETACH;
02404 
02405    cm_msg(MTALK, "main", "starting new run");
02406    status = cm_transition(TR_START, run_number + 1, errstr, sizeof(errstr), trans_flag, verbose);
02407    if (status != CM_SUCCESS)
02408       cm_msg(MERROR, "main", "cannot restart run: %s", errstr);
02409 
02410    return status;
02411 }

int stop_the_run ( int  restart  ) 

Definition at line 2320 of file mlogger.c.

Referenced by main().

02321 {
02322    int status;
02323    char errstr[256];
02324    int size, flag, trans_flag;
02325 
02326    if (restart) {
02327       size = sizeof(BOOL);
02328       flag = FALSE;
02329       db_get_value(hDB, 0, "/Logger/Auto restart", &flag, &size, TID_BOOL, TRUE);
02330 
02331       if (flag) {
02332          start_requested = TRUE;
02333          auto_restart = 0;
02334       }
02335    }
02336 
02337    stop_requested = TRUE;
02338 
02339    size = sizeof(BOOL);
02340    flag = FALSE;
02341    db_get_value(hDB, 0, "/Logger/Async transitions", &flag, &size, TID_BOOL, TRUE);
02342 
02343    if (flag)
02344       trans_flag = ASYNC;
02345    else
02346       trans_flag = DETACH;
02347 
02348    status = cm_transition(TR_STOP, 0, errstr, sizeof(errstr), trans_flag, verbose);
02349    if (status != CM_SUCCESS) {
02350       cm_msg(MERROR, "log_write", "cannot stop the run: %s", errstr);
02351       return status;
02352    }
02353 
02354    return status;
02355 }

INT tape_open ( char *  dev,
INT handle 
)

Definition at line 872 of file mlogger.c.

00873 {
00874    INT status, count;
00875    char buffer[16];
00876 
00877    status = ss_tape_open(dev, O_RDWR | O_CREAT | O_TRUNC, handle);
00878    if (status != SS_SUCCESS)
00879       return status;
00880 
00881    /* check if tape contains data */
00882    count = sizeof(buffer);
00883    status = ss_tape_read(*handle, buffer, &count);
00884 
00885    if (count == sizeof(buffer)) {
00886       /* tape contains data -> don't start */
00887       ss_tape_rskip(*handle, -1);
00888       cm_msg(MINFO, "tape_open", "Tape contains data, please spool tape with 'mtape seod'");
00889       cm_msg(MINFO, "tape_open", "or erase it with 'mtape weof', 'mtape rewind', then try again.");
00890       ss_tape_close(*handle);
00891       return SS_TAPE_ERROR;
00892    }
00893 
00894    return SS_SUCCESS;
00895 }

INT tr_pause ( INT  run_number,
char *  error 
)

Definition at line 4264 of file mlogger.c.

04265 {
04266    /* write transition event into history */
04267    write_history(STATE_PAUSED, run_number);
04268 
04269    local_state = STATE_PAUSED;
04270 
04271    return CM_SUCCESS;
04272 }

INT tr_resume ( INT  run_number,
char *  error 
)

Definition at line 4274 of file mlogger.c.

04275 {
04276    /* write transition event into history */
04277    write_history(STATE_RUNNING, run_number);
04278 
04279    local_state = STATE_RUNNING;
04280 
04281    return CM_SUCCESS;
04282 }

INT tr_start ( INT  run_number,
char *  error 
)

Definition at line 3861 of file mlogger.c.

03864           :
03865 
03866     Loop through channels defined in /logger/channels.
03867     Neglect channels with are not active.
03868     If "filename" contains a "%", substitute it by the
03869     current run number. Open logging channel and
03870     corresponding buffer. Place a event request
03871     into the buffer.
03872 
03873 \********************************************************************/
03874 {
03875    INT size, index, status;
03876    HNDLE hKeyRoot, hKeyChannel;
03877    CHN_SETTINGS *chn_settings;
03878    KEY key;
03879    BOOL write_data, tape_flag = FALSE;
03880 
03881    if (verbose)
03882       printf("tr_start: run %d\n", run_number);
03883 
03884    /* save current ODB */
03885    odb_save("last.xml");
03886 
03887    in_stop_transition = TRUE;
03888 
03889    close_channels(run_number, NULL);
03890    close_buffers();
03891 
03892    in_stop_transition = FALSE;
03893 
03894    run_start_time = subrun_start_time = ss_time();
03895 
03896    /* read global logging flag */
03897    size = sizeof(BOOL);
03898    write_data = TRUE;
03899    db_get_value(hDB, 0, "/Logger/Write data", &write_data, &size, TID_BOOL, TRUE);
03900 
03901    /* read tape message flag */
03902    size = sizeof(tape_message);
03903    db_get_value(hDB, 0, "/Logger/Tape message", &tape_message, &size, TID_BOOL, TRUE);
03904 
03905    /* loop over all channels */
03906    status = db_find_key(hDB, 0, "/Logger/Channels", &hKeyRoot);
03907    if (status != DB_SUCCESS) {
03908       /* if no channels are defined, define at least one */
03909       status = db_create_record(hDB, 0, "/Logger/Channels/0/", strcomb(chn_settings_str));
03910       if (status != DB_SUCCESS) {
03911          strcpy(error, "Cannot create channel entry in database");
03912          cm_msg(MERROR, "tr_start", error);
03913          return 0;
03914       }
03915 
03916       status = db_find_key(hDB, 0, "/Logger/Channels", &hKeyRoot);
03917       if (status != DB_SUCCESS) {
03918          strcpy(error, "Cannot create channel entry in database");
03919          cm_msg(MERROR, "tr_start", error);
03920          return 0;
03921       }
03922    }
03923 
03924    for (index = 0; index < MAX_CHANNELS; index++) {
03925       status = db_enum_key(hDB, hKeyRoot, index, &hKeyChannel);
03926       if (status == DB_NO_MORE_SUBKEYS)
03927          break;
03928 
03929       /* correct channel record */
03930       db_get_key(hDB, hKeyChannel, &key);
03931       status = db_check_record(hDB, hKeyRoot, key.name, strcomb(chn_settings_str), TRUE);
03932       if (status != DB_SUCCESS && status != DB_OPEN_RECORD) {
03933          cm_msg(MERROR, "tr_start", "Cannot create/check channel record, status %d", status);
03934          break;
03935       }
03936 
03937       if (status == DB_SUCCESS || status == DB_OPEN_RECORD) {
03938          /* if file already open, we had an abort on the previous start. So
03939             close and delete file in order to create a new one */
03940          if (log_chn[index].handle) {
03941             log_close(&log_chn[index], run_number);
03942             if (log_chn[index].type == LOG_TYPE_DISK) {
03943                cm_msg(MINFO, "tr_start", "Deleting previous file \"%s\"", log_chn[index].path);
03944                unlink(log_chn[index].path);
03945             }
03946          }
03947 
03948          /* if FTP channel already open, don't re-open it again */
03949          if (log_chn[index].ftp_con)
03950             continue;
03951 
03952          /* save settings key */
03953          status = db_find_key(hDB, hKeyChannel, "Settings", &log_chn[index].settings_hkey);
03954          if (status != DB_SUCCESS) {
03955             strcpy(error, "Cannot find channel settings info");
03956             cm_msg(MERROR, "tr_start", error);
03957             return 0;
03958          }
03959 
03960          /* save statistics key */
03961          status = db_find_key(hDB, hKeyChannel, "Statistics", &log_chn[index].stats_hkey);
03962          if (status != DB_SUCCESS) {
03963             strcpy(error, "Cannot find channel statistics info");
03964             cm_msg(MERROR, "tr_start", error);
03965             return 0;
03966          }
03967 
03968          /* clear statistics */
03969          size = sizeof(CHN_STATISTICS);
03970          db_get_record(hDB, log_chn[index].stats_hkey, &log_chn[index].statistics, &size, 0);
03971 
03972          log_chn[index].statistics.events_written = 0;
03973          log_chn[index].statistics.bytes_written = 0;
03974          log_chn[index].statistics.bytes_written_uncompressed = 0;
03975          log_chn[index].statistics.bytes_written_subrun = 0;
03976 
03977          db_set_record(hDB, log_chn[index].stats_hkey, &log_chn[index].statistics, size, 0);
03978 
03979          /* get channel info structure */
03980          chn_settings = &log_chn[index].settings;
03981          size = sizeof(CHN_SETTINGS);
03982          status = db_get_record(hDB, log_chn[index].settings_hkey, chn_settings, &size, 0);
03983          if (status != DB_SUCCESS) {
03984             strcpy(error, "Cannot read channel info");
03985             cm_msg(MERROR, "tr_start", error);
03986             return 0;
03987          }
03988 
03989          /* don't start run if tape is full */
03990          if (log_chn[index].type == LOG_TYPE_TAPE &&
03991              chn_settings->tape_capacity > 0 &&
03992              log_chn[index].statistics.bytes_written_total >= chn_settings->tape_capacity) {
03993             strcpy(error, "Tape capacity reached. Please load new tape");
03994             cm_msg(MERROR, "tr_start", error);
03995             return 0;
03996          }
03997 
03998          /* check if active */
03999          if (!chn_settings->active || !write_data)
04000             continue;
04001 
04002          /* check for type */
04003          if (equal_ustring(chn_settings->type, "Tape"))
04004             log_chn[index].type = LOG_TYPE_TAPE;
04005          else if (equal_ustring(chn_settings->type, "FTP"))
04006             log_chn[index].type = LOG_TYPE_FTP;
04007          else if (equal_ustring(chn_settings->type, "Disk"))
04008             log_chn[index].type = LOG_TYPE_DISK;
04009          else {
04010             sprintf(error,
04011                     "Invalid channel type \"%s\", pease use \"Tape\", \"FTP\" or \"Disk\"",
04012                     chn_settings->type);
04013             cm_msg(MERROR, "tr_start", error);
04014             return 0;
04015          }
04016 
04017          /* set compression level */
04018          log_chn[index].compression = 0;
04019          size = sizeof(log_chn[index].compression);
04020          status = db_get_value(hDB, log_chn[index].settings_hkey, "Compression", &log_chn[index].compression, &size, TID_INT, FALSE);
04021          
04022          /* initialize subrun number */
04023          log_chn[index].subrun_number = 0;
04024 
04025          log_generate_file_name(&log_chn[index]);
04026 
04027          if (log_chn[index].type == LOG_TYPE_TAPE &&
04028              log_chn[index].statistics.bytes_written_total == 0 && tape_message) {
04029             tape_flag = TRUE;
04030             cm_msg(MTALK, "tr_start", "mounting tape #%d, please wait", index);
04031          }
04032 
04033          /* open logging channel */
04034          status = log_open(&log_chn[index], run_number);
04035 
04036          /* return if logging channel couldn't be opened */
04037          if (status != SS_SUCCESS) {
04038             if (status == SS_FILE_ERROR)
04039                sprintf(error, "Cannot open file \'%s\' (See messages)", log_chn[index].path);
04040             if (status == SS_FILE_EXISTS)
04041                sprintf(error, "File \'%s\' exists already, run start aborted", log_chn[index].path);
04042             if (status == SS_NO_TAPE)
04043                sprintf(error, "No tape in device \'%s\'", log_chn[index].path);
04044             if (status == SS_TAPE_ERROR)
04045                sprintf(error, "Tape error, cannot start run");
04046             if (status == SS_DEV_BUSY)
04047                sprintf(error, "Device \'%s\' used by someone else", log_chn[index].path);
04048             if (status == FTP_NET_ERROR || status == FTP_RESPONSE_ERROR)
04049                sprintf(error, "Cannot open FTP channel to \'%s\'", log_chn[index].path);
04050             if (status == SS_NO_ROOT)
04051                sprintf(error, "No ROOT support compiled into mlogger, please compile with -DHAVE_ROOT flag");
04052 
04053             if (status == SS_INVALID_FORMAT)
04054                sprintf(error,
04055                        "Invalid data format, please use \"MIDAS\", \"ASCII\", \"DUMP\" or \"ROOT\"");
04056 
04057             cm_msg(MERROR, "tr_start", error);
04058             return 0;
04059          }
04060 
04061          /* close records if open from previous run start with abort */
04062          if (log_chn[index].stats_hkey)
04063             db_close_record(hDB, log_chn[index].stats_hkey);
04064          if (log_chn[index].settings_hkey)
04065             db_close_record(hDB, log_chn[index].settings_hkey);
04066 
04067          /* open hot link to statistics tree */
04068          status =
04069              db_open_record(hDB, log_chn[index].stats_hkey, &log_chn[index].statistics,
04070                             sizeof(CHN_STATISTICS), MODE_WRITE, NULL, NULL);
04071          if (status != DB_SUCCESS)
04072             cm_msg(MERROR, "tr_start", "cannot open statistics record, probably other logger is using it");
04073 
04074          /* open hot link to settings tree */
04075          status =
04076              db_open_record(hDB, log_chn[index].settings_hkey, &log_chn[index].settings,
04077                             sizeof(CHN_SETTINGS), MODE_READ, NULL, NULL);
04078          if (status != DB_SUCCESS)
04079             cm_msg(MERROR, "tr_start",
04080                    "cannot open channel settings record, probably other logger is using it");
04081 
04082 #ifndef FAL_MAIN
04083          /* open buffer */
04084          status = bm_open_buffer(chn_settings->buffer, 2 * MAX_EVENT_SIZE, &log_chn[index].buffer_handle);
04085          if (status != BM_SUCCESS && status != BM_CREATED) {
04086             sprintf(error, "Cannot open buffer %s", chn_settings->buffer);
04087             cm_msg(MERROR, "tr_start", error);
04088             return 0;
04089          }
04090          bm_set_cache_size(log_chn[index].buffer_handle, 100000, 0);
04091 
04092          /* place event request */
04093          status = bm_request_event(log_chn[index].buffer_handle,
04094                                    (short) chn_settings->event_id,
04095                                    (short) chn_settings->trigger_mask,
04096                                    GET_ALL, &log_chn[index].request_id, receive_event);
04097 
04098          if (status != BM_SUCCESS) {
04099             sprintf(error, "Cannot place event request");
04100             cm_msg(MERROR, "tr_start", error);
04101             return 0;
04102          }
04103 
04104          /* open message buffer if requested */
04105          if (chn_settings->log_messages) {
04106             status =
04107                 bm_open_buffer(MESSAGE_BUFFER_NAME, MESSAGE_BUFFER_SIZE, &log_chn[index].msg_buffer_handle);
04108             if (status != BM_SUCCESS && status != BM_CREATED) {
04109                sprintf(error, "Cannot open buffer %s", MESSAGE_BUFFER_NAME);
04110                cm_msg(MERROR, "tr_start", error);
04111                return 0;
04112             }
04113 
04114             /* place event request */
04115             status = bm_request_event(log_chn[index].msg_buffer_handle,
04116                                       (short) EVENTID_MESSAGE,
04117                                       (short) chn_settings->log_messages,
04118                                       GET_ALL, &log_chn[index].msg_request_id, receive_event);
04119 
04120             if (status != BM_SUCCESS) {
04121                sprintf(error, "Cannot place event request");
04122                cm_msg(MERROR, "tr_start", error);
04123                return 0;
04124             }
04125          }
04126 #endif
04127       }
04128    }
04129 
04130    if (tape_flag && tape_message)
04131       cm_msg(MTALK, "tr_start", "tape mounting finished");
04132 
04133    /* reopen history channels if event definition has changed */
04134    close_history();
04135    status = open_history();
04136    if (status != CM_SUCCESS) {
04137       sprintf(error, "Error in history system, aborting run start");
04138       cm_msg(MERROR, "tr_start", error);
04139       return 0;
04140    }
04141 
04142    /* write transition event into history */
04143    write_history(STATE_RUNNING, run_number);
04144 
04145 
04146 #ifdef HAVE_MYSQL
04147    /* write to SQL database if requested */
04148    write_sql(TRUE);
04149 #endif
04150 
04151    local_state = STATE_RUNNING;
04152    run_start_time = subrun_start_time = ss_time();
04153 
04154    return CM_SUCCESS;
04155 }

INT tr_start_abort ( INT  run_number,
char *  error 
)

Definition at line 4159 of file mlogger.c.

Referenced by main().

04160 {
04161    int i;
04162 
04163    if (verbose)
04164       printf("tr_start_abort: run %d\n", run_number);
04165 
04166    in_stop_transition = TRUE;
04167 
04168    for (i = 0; i < MAX_CHANNELS; i++)
04169       if (log_chn[i].handle && log_chn[i].type == LOG_TYPE_DISK) {
04170          cm_msg(MINFO, "tr_start_abort", "Deleting previous file \"%s\"", log_chn[i].path);
04171          unlink(log_chn[i].path);
04172       }
04173 
04174    close_channels(run_number, NULL);
04175    close_buffers();
04176 
04177    in_stop_transition = FALSE;
04178 
04179    local_state = STATE_STOPPED;
04180 
04181    return CM_SUCCESS;
04182 }

INT tr_stop ( INT  run_number,
char *  error 
)

Definition at line 4186 of file mlogger.c.

04189            :
04190 
04191      Wait until buffers are empty, then close logging channels
04192 
04193 \********************************************************************/
04194 {
04195    INT  size;
04196    BOOL flag, tape_flag = FALSE;
04197    char filename[256];
04198    char str[256];
04199 
04200    if (verbose)
04201       printf("tr_stop: run %d\n", run_number);
04202 
04203    if (in_stop_transition)
04204       return CM_SUCCESS;
04205 
04206    in_stop_transition = TRUE;
04207 
04208    close_channels(run_number, &tape_flag);
04209    close_buffers();
04210 
04211    /* ODB dump if requested */
04212    size = sizeof(flag);
04213    flag = 0;
04214    db_get_value(hDB, 0, "/Logger/ODB Dump", &flag, &size, TID_BOOL, TRUE);
04215    if (flag) {
04216       strcpy(str, "run%d.odb");
04217       size = sizeof(str);
04218       str[0] = 0;
04219       db_get_value(hDB, 0, "/Logger/ODB Dump File", str, &size, TID_STRING, TRUE);
04220       if (str[0] == 0)
04221          strcpy(str, "run%d.odb");
04222 
04223       /* substitue "%d" by current run number */
04224       if (strchr(str, '%'))
04225          sprintf(filename, str, run_number);
04226       else
04227          strcpy(filename, str);
04228 
04229       odb_save(filename);
04230    }
04231 #ifdef HAVE_MYSQL
04232    /* write to SQL database if requested */
04233    write_sql(FALSE);
04234 #endif
04235 
04236    in_stop_transition = FALSE;
04237 
04238    if (tape_flag & tape_message)
04239       cm_msg(MTALK, "tr_stop", "all tape channels closed");
04240 
04241    /* write transition event into history */
04242    write_history(STATE_STOPPED, run_number);
04243 
04244    /* clear flag */
04245    stop_requested = FALSE;
04246 
04247    if (start_requested) {
04248       int delay = 0;
04249       size = sizeof(delay);
04250       db_get_value(hDB, 0, "/Logger/Auto restart delay", &delay, &size, TID_INT, TRUE);
04251       auto_restart = ss_time() + delay; /* start after specified delay */
04252       start_requested = FALSE;
04253    }
04254 
04255    local_state = STATE_STOPPED;
04256 
04257    return CM_SUCCESS;
04258 }

static int write_history ( DWORD  transition,
DWORD  run_number 
) [static]

Definition at line 3843 of file mlogger.c.

Referenced by tr_pause(), tr_resume(), tr_start(), and tr_stop().

03844 {
03845    DWORD eb[2];
03846    eb[0] = transition;
03847    eb[1] = run_number;
03848 
03849    hs_write_event(0, eb, sizeof(eb));
03850 
03851    time_t now = time(NULL);
03852 
03853    for (unsigned h=0; h<mh.size(); h++)
03854       mh[h]->hs_write_event("Run transitions", now, sizeof(eb), (const char*)eb);
03855 
03856    return SUCCESS;
03857 }


Variable Documentation

DWORD auto_restart = 0

Definition at line 58 of file mlogger.c.

HNDLE hDB

Definition at line 78 of file mlogger.c.

hist_log_s* hist_log = NULL [static]

Definition at line 76 of file mlogger.c.

int hist_log_max = 0 [static]

Definition at line 75 of file mlogger.c.

Referenced by add_event(), and close_history().

int hist_log_size = 0 [static]

Definition at line 74 of file mlogger.c.

Referenced by add_event().

BOOL in_stop_transition = FALSE

Definition at line 53 of file mlogger.c.

INT local_state

Definition at line 52 of file mlogger.c.

Referenced by main(), tr_pause(), tr_resume(), tr_start(), tr_start_abort(), and tr_stop().

LOG_CHN log_chn[MAX_CHANNELS]

Definition at line 61 of file mlogger.c.

std::vector<MidasHistoryInterface*> mh [static]

Definition at line 2584 of file mlogger.c.

DWORD run_start_time

Definition at line 59 of file mlogger.c.

Referenced by main(), and tr_start().

BOOL start_requested = FALSE

Definition at line 57 of file mlogger.c.

Referenced by start_the_run(), stop_the_run(), and tr_stop().

BOOL stop_requested = FALSE

Definition at line 56 of file mlogger.c.

Referenced by log_write(), main(), scan_fragment(), stop_the_run(), and tr_stop().

DWORD subrun_start_time

Definition at line 59 of file mlogger.c.

Referenced by tr_start().

BOOL tape_message = TRUE

Definition at line 54 of file mlogger.c.

BOOL verbose = FALSE

Definition at line 55 of file mlogger.c.


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