LCOV - code coverage report
Current view: top level - src - elog.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 565 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 9 0

            Line data    Source code
       1              : /********************************************************************\
       2              : 
       3              :   Name:         ELOG.C
       4              :   Created by:   Stefan Ritt
       5              : 
       6              :   Contents:     MIDAS elog functions
       7              : 
       8              :   $Id$
       9              : 
      10              : \********************************************************************/
      11              : 
      12              : #include "midas.h"
      13              : #include "msystem.h"
      14              : #include "mstrlcpy.h"
      15              : #include <assert.h>
      16              : 
      17              : /** @defgroup elfunctioncode Midas Elog Functions (el_xxx)
      18              :  */
      19              : 
      20              : /**dox***************************************************************/
      21              : /** @addtogroup elfunctioncode
      22              :  *
      23              :  *  @{  */
      24              : 
      25              : /**dox***************************************************************/
      26              : #ifndef DOXYGEN_SHOULD_SKIP_THIS
      27              : 
      28              : /********************************************************************\
      29              : *                                                                    *
      30              : *               Electronic logbook functions                         *
      31              : *                                                                    *
      32              : \********************************************************************/
      33              : 
      34              : /********************************************************************/
      35            0 : static void el_decode(const char *message, const char *key, char *result, int size)
      36              : {
      37              :    int i;
      38              :    const char *pc;
      39              : 
      40            0 :    if (result == NULL)
      41            0 :       return;
      42              : 
      43            0 :    *result = 0;
      44              : 
      45            0 :    pc = strstr(message, key);
      46              : 
      47            0 :    if (!pc)
      48            0 :      return;
      49              : 
      50            0 :    pc += strlen(key);
      51              : 
      52            0 :    for (i=0; i<size; i++) {
      53            0 :      if (pc[i] == 0)
      54            0 :        break;
      55            0 :      if (pc[i] == '\n')
      56            0 :        break;
      57            0 :      result[i] = pc[i];
      58              :    }
      59              : 
      60            0 :    assert(i<=size); // ensure that code above did not overrun the "result" array
      61              : 
      62            0 :    if (i==size)
      63            0 :      result[size-1] = 0;
      64              :    else
      65            0 :      result[i] = 0;
      66              : }
      67              : 
      68            0 : static void xwrite(const char* filename, int fd, const void* data, int size)
      69              : {
      70            0 :    int wr = write(fd, data, size);
      71            0 :    if (wr != size) {
      72            0 :       cm_msg(MERROR, "xwrite", "cannot write to \'%s\', write(%d) returned %d, errno %d (%s)", filename, size, wr, errno, strerror(errno));
      73              :    }
      74            0 : }
      75              : 
      76            0 : static int xread(const char* filename, int fd, void* data, int size)
      77              : {
      78            0 :    int rd = read(fd, data, size);
      79            0 :    if (rd == 0) {
      80              :       // end of file
      81            0 :    } else if (rd < 0) {
      82            0 :       cm_msg(MERROR, "xread", "cannot read from \'%s\', read(%d) returned %d, errno %d (%s)", filename, size, rd, errno, strerror(errno));
      83            0 :    } else if (rd != size) {
      84            0 :       cm_msg(MERROR, "xread", "truncated read from \'%s\', read(%d) returned %d", filename, size, rd);
      85              :    }
      86            0 :    return rd;
      87              : }
      88              : 
      89            0 : static void xtruncate(const char* filename, int fd)
      90              : {
      91            0 :    int tr = ftruncate(fd, TELL(fd));
      92            0 :    if (tr != 0) {
      93            0 :       cm_msg(MERROR, "xtruncate", "cannot truncate \'%s\', ftruncate() returned %d, errno %d (%s)", filename, tr, errno, strerror(errno));
      94              :    }
      95            0 : }
      96              : 
      97              : /**dox***************************************************************/
      98              : #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
      99              : 
     100              : /********************************************************************/
     101              : /**
     102              : Submit an ELog entry.
     103              : @param run  Run Number.
     104              : @param author Message author.
     105              : @param type Message type.
     106              : @param syst Message system.
     107              : @param subject Subject.
     108              : @param text Message text.
     109              : @param reply_to In reply to this message.
     110              : @param encoding Text encoding, either HTML or plain.
     111              : @param afilename1   File name of attachment.
     112              : @param buffer1      File contents.
     113              : @param buffer_size1 Size of buffer in bytes.
     114              : @param afilename2   File name of attachment.
     115              : @param buffer2      File contents.
     116              : @param buffer_size2 Size of buffer in bytes.
     117              : @param afilename3   File name of attachment.
     118              : @param buffer3      File contents.
     119              : @param buffer_size3 Size of buffer in bytes.
     120              : @param tag          If given, edit existing message.
     121              : @param tag_size     Maximum size of tag.
     122              : @return EL_SUCCESS
     123              : */
     124            0 : INT el_submit(int run, const char *author, const char *type, const char *syst, const char *subject,
     125              :               const char *text, const char *reply_to, const char *encoding,
     126              :               const char *afilename1, const char *buffer1, INT buffer_size1,
     127              :               const char *afilename2, const char *buffer2, INT buffer_size2,
     128              :               const char *afilename3, const char *buffer3, INT buffer_size3, char *tag, INT tag_size)
     129              : {
     130            0 :    if (rpc_is_remote())
     131            0 :       return rpc_call(RPC_EL_SUBMIT, run, author, type, syst, subject,
     132              :                       text, reply_to, encoding,
     133              :                       afilename1, buffer1, buffer_size1,
     134            0 :                       afilename2, buffer2, buffer_size2, afilename3, buffer3, buffer_size3, tag, tag_size);
     135              : 
     136              : #ifdef LOCAL_ROUTINES
     137              :    {
     138            0 :       INT size, fh, status, run_number, semaphore, idx, offset = 0, tail_size = 0;
     139              :       char file_name[256+256+100];
     140              :       char afile_name[3][256+256];
     141              :       char dir[256];
     142              :       char start_str[80], end_str[80], last[80], date[80], thread[80], attachment[256];
     143              :       HNDLE hDB;
     144              :       time_t now;
     145              :       char *p;
     146            0 :       char* message = NULL;
     147            0 :       size_t message_size = 0;
     148              :       BOOL bedit;
     149              :       struct tm tms;
     150              : 
     151            0 :       cm_get_experiment_database(&hDB, NULL);
     152              : 
     153            0 :       bedit = (tag[0] != 0);
     154              : 
     155              :       /* request semaphore */
     156            0 :       cm_get_experiment_semaphore(NULL, &semaphore, NULL, NULL);
     157            0 :       status = ss_semaphore_wait_for(semaphore, 5 * 60 * 1000);
     158            0 :       if (status != SS_SUCCESS) {
     159            0 :          cm_msg(MERROR, "el_submit", "Cannot lock experiment semaphore, ss_semaphore_wait_for() status %d", status);
     160            0 :          abort();
     161              :       }
     162              : 
     163              :       /* get run number from ODB if not given */
     164            0 :       if (run > 0)
     165            0 :          run_number = run;
     166              :       else {
     167              :          /* get run number */
     168            0 :          size = sizeof(run_number);
     169            0 :          status = db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT, TRUE);
     170            0 :          assert(status == SUCCESS);
     171              :       }
     172              : 
     173            0 :       if (run_number < 0) {
     174            0 :          cm_msg(MERROR, "el_submit", "aborting on attempt to use invalid run number %d", run_number);
     175            0 :          abort();
     176              :       }
     177              : 
     178            0 :       for (idx = 0; idx < 3; idx++) {
     179              :          /* generate filename for attachment */
     180            0 :          afile_name[idx][0] = file_name[0] = 0;
     181              : 
     182              :          char afilename[256];
     183            0 :          const char* buffer = NULL;
     184            0 :          int buffer_size = 0;
     185              : 
     186            0 :          if (idx == 0) {
     187            0 :             mstrlcpy(afilename, afilename1, sizeof(afilename));
     188            0 :             buffer = buffer1;
     189            0 :             buffer_size = buffer_size1;
     190            0 :          } else if (idx == 1) {
     191            0 :             mstrlcpy(afilename, afilename2, sizeof(afilename));
     192            0 :             buffer = buffer2;
     193            0 :             buffer_size = buffer_size2;
     194            0 :          } else if (idx == 2) {
     195            0 :             mstrlcpy(afilename, afilename3, sizeof(afilename));
     196            0 :             buffer = buffer3;
     197            0 :             buffer_size = buffer_size3;
     198              :          }
     199              : 
     200            0 :          if (afilename[0]) {
     201            0 :             strcpy(file_name, afilename);
     202            0 :             p = file_name;
     203            0 :             while (strchr(p, ':'))
     204            0 :                p = strchr(p, ':') + 1;
     205            0 :             while (strchr(p, '\\'))
     206            0 :                p = strchr(p, '\\') + 1; /* NT */
     207            0 :             while (strchr(p, '/'))
     208            0 :                p = strchr(p, '/') + 1;  /* Unix */
     209            0 :             while (strchr(p, ']'))
     210            0 :                p = strchr(p, ']') + 1;  /* VMS */
     211              : 
     212              :             /* assemble ELog filename */
     213            0 :             if (p[0]) {
     214            0 :                dir[0] = 0;
     215            0 :                if (hDB > 0) {
     216            0 :                   size = sizeof(dir);
     217            0 :                   memset(dir, 0, size);
     218            0 :                   status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
     219            0 :                   if (status != DB_SUCCESS)
     220            0 :                      db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
     221              : 
     222            0 :                   if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
     223            0 :                      strcat(dir, DIR_SEPARATOR_STR);
     224              :                }
     225              : 
     226            0 :                ss_tzset();
     227            0 :                time(&now);
     228            0 :                localtime_r(&now, &tms);
     229              : 
     230              :                char str[256];
     231            0 :                mstrlcpy(str, p, sizeof(str));
     232            0 :                sprintf(afile_name[idx], "%02d%02d%02d_%02d%02d%02d_%s",
     233            0 :                        tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday,
     234              :                        tms.tm_hour, tms.tm_min, tms.tm_sec, str);
     235            0 :                sprintf(file_name, "%s%02d%02d%02d_%02d%02d%02d_%s", dir,
     236            0 :                        tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday,
     237              :                        tms.tm_hour, tms.tm_min, tms.tm_sec, str);
     238              : 
     239              :                /* save attachment */
     240            0 :                fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
     241            0 :                if (fh < 0) {
     242            0 :                   cm_msg(MERROR, "el_submit", "Cannot write attachment file \"%s\", open() returned %d, errno %d (%s)", file_name, fh, errno, strerror(errno));
     243              :                } else {
     244            0 :                   xwrite(file_name, fh, buffer, buffer_size);
     245            0 :                   close(fh);
     246              :                }
     247              :             }
     248              :          }
     249              :       } // loop over attachmnents
     250              : 
     251              :       /* generate new file name YYMMDD.log in data directory */
     252            0 :       cm_get_experiment_database(&hDB, NULL);
     253              : 
     254            0 :       size = sizeof(dir);
     255            0 :       memset(dir, 0, size);
     256            0 :       status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
     257            0 :       if (status != DB_SUCCESS)
     258            0 :          db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
     259              : 
     260            0 :       if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
     261            0 :          strcat(dir, DIR_SEPARATOR_STR);
     262              : 
     263            0 :       ss_tzset();
     264              : 
     265            0 :       char* buffer = NULL;
     266              : 
     267            0 :       if (bedit) {
     268              :          /* edit existing message */
     269              :          char str[256];
     270            0 :          mstrlcpy(str, tag, sizeof(str));
     271            0 :          if (strchr(str, '.')) {
     272            0 :             offset = atoi(strchr(str, '.') + 1);
     273            0 :             *strchr(str, '.') = 0;
     274              :          }
     275            0 :          sprintf(file_name, "%s%s.log", dir, str);
     276            0 :          fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
     277            0 :          if (fh < 0) {
     278            0 :             ss_semaphore_release(semaphore);
     279            0 :             return EL_FILE_ERROR;
     280              :          }
     281            0 :          lseek(fh, offset, SEEK_SET);
     282            0 :          xread(file_name, fh, str, 16);
     283              : 
     284            0 :          if (strncmp(str, "$Start$", 7) != 0) {
     285            0 :             cm_msg(MERROR, "el_submit", "cannot read from \'%s\', corrupted file: no $Start$ in \"%s\"", file_name, str);
     286            0 :             close(fh);
     287            0 :             return EL_FILE_ERROR;
     288              :          }
     289              : 
     290            0 :          size = atoi(str + 9);
     291              : 
     292            0 :          if (size < 1) {
     293            0 :             cm_msg(MERROR, "el_submit", "cannot read from \'%s\', corrupted file: bad size %d in \"%s\"", file_name, size, str);
     294            0 :             close(fh);
     295            0 :             return EL_FILE_ERROR;
     296              :          }
     297              : 
     298            0 :          message = (char*)malloc(size);
     299              : 
     300            0 :          if (!message) {
     301            0 :             cm_msg(MERROR, "el_submit", "cannot read from \'%s\', corrupted file: bad size %d in \"%s\", cannot malloc(%d): errno %d (%s)", file_name, size, str, size, errno, strerror(errno));
     302            0 :             close(fh);
     303            0 :             return EL_FILE_ERROR;
     304              :          }
     305              : 
     306            0 :          status = read(fh, message, size);
     307            0 :          if (status != size && status + 16 != size) {
     308            0 :             free(message);
     309            0 :             return EL_FILE_ERROR;
     310              :          }
     311              : 
     312            0 :          el_decode(message, "Date: ", date, sizeof(date));
     313            0 :          el_decode(message, "Thread: ", thread, sizeof(thread));
     314            0 :          el_decode(message, "Attachment: ", attachment, sizeof(attachment));
     315              : 
     316            0 :          free(message);
     317            0 :          message = NULL;
     318              : 
     319              :          /* buffer tail of logfile */
     320            0 :          lseek(fh, 0, SEEK_END);
     321            0 :          tail_size = TELL(fh) - (offset + size);
     322              : 
     323            0 :          if (tail_size > 0) {
     324              :             int n;
     325              : 
     326            0 :             buffer = (char *) M_MALLOC(tail_size);
     327            0 :             if (buffer == NULL) {
     328            0 :                close(fh);
     329            0 :                ss_semaphore_release(semaphore);
     330            0 :                return EL_FILE_ERROR;
     331              :             }
     332              : 
     333            0 :             lseek(fh, offset + size, SEEK_SET);
     334            0 :             n = xread(file_name, fh, buffer, tail_size);
     335            0 :             if (n != tail_size)
     336            0 :                return EL_FILE_ERROR;
     337              :          }
     338            0 :          lseek(fh, offset, SEEK_SET);
     339              :       } else {
     340              :          /* create new message */
     341            0 :          ss_tzset(); // required by localtime_r()
     342            0 :          time(&now);
     343            0 :          localtime_r(&now, &tms);
     344              : 
     345            0 :          sprintf(file_name, "%s%02d%02d%02d.log", dir, tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
     346              : 
     347            0 :          fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
     348            0 :          if (fh < 0) {
     349            0 :             ss_semaphore_release(semaphore);
     350            0 :             return EL_FILE_ERROR;
     351              :          }
     352              : 
     353              :          assert(sizeof(date) >= 32);
     354            0 :          ctime_r(&now, date);
     355            0 :          date[24] = 0;
     356              : 
     357            0 :          if (reply_to[0])
     358            0 :             sprintf(thread, "%16s %16s", reply_to, "0");
     359              :          else
     360            0 :             sprintf(thread, "%16s %16s", "0", "0");
     361              : 
     362            0 :          lseek(fh, 0, SEEK_END);
     363              :       }
     364              : 
     365            0 :       message_size = 1000;
     366            0 :       message_size += strlen(date);
     367            0 :       message_size += strlen(author);
     368            0 :       message_size += strlen(type);
     369            0 :       message_size += strlen(syst);
     370            0 :       message_size += strlen(subject);
     371            0 :       message_size += strlen(attachment);
     372            0 :       message_size += strlen(afile_name[0]);
     373            0 :       message_size += strlen(afile_name[1]);
     374            0 :       message_size += strlen(afile_name[2]);
     375            0 :       message_size += strlen(encoding);
     376            0 :       message_size += strlen(text);
     377              : 
     378              :       //printf("message_size %d, text %d\n", (int)message_size, (int)strlen(text));
     379              : 
     380            0 :       message = (char*)malloc(message_size);
     381              : 
     382            0 :       if (!message) {
     383            0 :          cm_msg(MERROR, "el_submit", "cannot malloc() %d bytes: errno %d (%s)", size, errno, strerror(errno));
     384            0 :          close(fh);
     385            0 :          return EL_FILE_ERROR;
     386              :       }
     387              : 
     388              :       /* compose message */
     389              : 
     390            0 :       sprintf(message, "Date: %s\n", date);
     391            0 :       sprintf(message + strlen(message), "Thread: %s\n", thread);
     392            0 :       sprintf(message + strlen(message), "Run: %d\n", run_number);
     393            0 :       sprintf(message + strlen(message), "Author: %s\n", author);
     394            0 :       sprintf(message + strlen(message), "Type: %s\n", type);
     395            0 :       sprintf(message + strlen(message), "System: %s\n", syst);
     396            0 :       sprintf(message + strlen(message), "Subject: %s\n", subject);
     397              : 
     398              :       /* keep original attachment if edit and no new attachment */
     399            0 :       if (bedit && afile_name[0][0] == 0 && afile_name[1][0] == 0 && afile_name[2][0] == 0)
     400            0 :          sprintf(message + strlen(message), "Attachment: %s", attachment);
     401              :       else {
     402            0 :          sprintf(message + strlen(message), "Attachment: %s", afile_name[0]);
     403            0 :          if (afile_name[1][0])
     404            0 :             sprintf(message + strlen(message), ",%s", afile_name[1]);
     405            0 :          if (afile_name[2][0])
     406            0 :             sprintf(message + strlen(message), ",%s", afile_name[2]);
     407              :       }
     408            0 :       sprintf(message + strlen(message), "\n");
     409              : 
     410            0 :       sprintf(message + strlen(message), "Encoding: %s\n", encoding);
     411            0 :       sprintf(message + strlen(message), "========================================\n");
     412            0 :       strcat(message, text);
     413              : 
     414            0 :       assert(strlen(message) < message_size);        /* bomb out on array overrun. */
     415              : 
     416            0 :       size = 0;
     417            0 :       sprintf(start_str, "$Start$: %6d\n", size);
     418            0 :       sprintf(end_str, "$End$:   %6d\n\f", size);
     419              : 
     420            0 :       size = strlen(message) + strlen(start_str) + strlen(end_str);
     421              : 
     422            0 :       if (tag != NULL && !bedit) {
     423            0 :          sprintf(tag, "%02d%02d%02d.%d", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday, (int) TELL(fh));
     424              :       }
     425              : 
     426              :       /* size has to fit in 6 digits */
     427            0 :       assert(size < 999999);
     428              : 
     429            0 :       sprintf(start_str, "$Start$: %6d\n", size);
     430            0 :       sprintf(end_str, "$End$:   %6d\n\f", size);
     431              : 
     432            0 :       xwrite(file_name, fh, start_str, strlen(start_str));
     433            0 :       xwrite(file_name, fh, message, strlen(message));
     434            0 :       xwrite(file_name, fh, end_str, strlen(end_str));
     435              : 
     436            0 :       free(message);
     437            0 :       message = NULL;
     438            0 :       message_size = 0;
     439              : 
     440            0 :       if (bedit) {
     441            0 :          if (tail_size > 0) {
     442            0 :             xwrite(file_name, fh, buffer, tail_size);
     443            0 :             M_FREE(buffer);
     444              :          }
     445              : 
     446              :          /* truncate file here */
     447              : #ifdef OS_WINNT
     448              :          chsize(fh, TELL(fh));
     449              : #else
     450            0 :          xtruncate(file_name, fh);
     451              : #endif
     452              :       }
     453              : 
     454            0 :       close(fh);
     455              : 
     456              :       /* if reply, mark original message */
     457            0 :       if (reply_to[0] && !bedit) {
     458            0 :          strcpy(last, reply_to);
     459              :          do {
     460              :             char filename[256];
     461            0 :             status = el_search_message(last, &fh, FALSE, filename, sizeof(filename));
     462            0 :             if (status == EL_SUCCESS) {
     463              :                /* position to next thread location */
     464            0 :                lseek(fh, 72, SEEK_CUR);
     465              :                char str[256];
     466            0 :                memset(str, 0, sizeof(str));
     467            0 :                xread(filename, fh, str, 16);
     468            0 :                lseek(fh, -16, SEEK_CUR);
     469              : 
     470              :                /* if no reply yet, set it */
     471            0 :                if (atoi(str) == 0) {
     472            0 :                   sprintf(str, "%16s", tag);
     473            0 :                   xwrite(filename, fh, str, 16);
     474            0 :                   close(fh);
     475            0 :                   break;
     476              :                } else {
     477              :                   /* if reply set, find last one in chain */
     478            0 :                   strcpy(last, strtok(str, " "));
     479            0 :                   close(fh);
     480              :                }
     481              :             } else
     482              :                /* stop on error */
     483            0 :                break;
     484              : 
     485            0 :          } while (TRUE);
     486              :       }
     487              : 
     488              :       /* release elog semaphore */
     489            0 :       ss_semaphore_release(semaphore);
     490              :    }
     491              : #endif                          /* LOCAL_ROUTINES */
     492              : 
     493            0 :    return EL_SUCCESS;
     494              : }
     495              : 
     496              : /**dox***************************************************************/
     497              : #ifndef DOXYGEN_SHOULD_SKIP_THIS
     498              : 
     499              : /********************************************************************/
     500            0 : INT el_search_message(char *tag, int *fh, BOOL walk, char *xfilename, int xfilename_size)
     501              : {
     502              :    int i, size, offset, direction, status;
     503              :    struct tm tms;
     504            0 :    time_t lt, ltime=0, lact;
     505              :    char str[256];
     506              :    char dir[256];
     507              :    char file_name[256+100];
     508              :    HNDLE hDB;
     509              : 
     510            0 :    ss_tzset(); // required by localtime_r()
     511              : 
     512            0 :    if (xfilename && xfilename_size > 0)
     513            0 :       *xfilename = 0;
     514              : 
     515              :    /* open file */
     516            0 :    cm_get_experiment_database(&hDB, NULL);
     517              : 
     518            0 :    size = sizeof(dir);
     519            0 :    memset(dir, 0, size);
     520            0 :    status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
     521            0 :    if (status != DB_SUCCESS)
     522            0 :       db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
     523              : 
     524            0 :    if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
     525            0 :       strcat(dir, DIR_SEPARATOR_STR);
     526              : 
     527              :    /* check tag for direction */
     528            0 :    direction = 0;
     529            0 :    if (strpbrk(tag, "+-")) {
     530            0 :       direction = atoi(strpbrk(tag, "+-"));
     531            0 :       *strpbrk(tag, "+-") = 0;
     532              :    }
     533              : 
     534              :    /* if tag is given, open file directly */
     535            0 :    if (tag[0]) {
     536              :       /* extract time structure from tag */
     537            0 :       memset(&tms, 0, sizeof(struct tm));
     538            0 :       tms.tm_year = (tag[0] - '0') * 10 + (tag[1] - '0');
     539            0 :       tms.tm_mon = (tag[2] - '0') * 10 + (tag[3] - '0') - 1;
     540            0 :       tms.tm_mday = (tag[4] - '0') * 10 + (tag[5] - '0');
     541            0 :       tms.tm_hour = 12;
     542              : 
     543            0 :       if (tms.tm_year < 90)
     544            0 :          tms.tm_year += 100;
     545            0 :       ltime = lt = ss_mktime(&tms);
     546              : 
     547            0 :       strcpy(str, tag);
     548            0 :       if (strchr(str, '.')) {
     549            0 :          offset = atoi(strchr(str, '.') + 1);
     550            0 :          *strchr(str, '.') = 0;
     551              :       } else
     552            0 :          return EL_FILE_ERROR;
     553              : 
     554              :       do {
     555            0 :          localtime_r(&ltime, &tms);
     556              : 
     557            0 :          sprintf(file_name, "%s%02d%02d%02d.log", dir, tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
     558              : 
     559            0 :          if (xfilename)
     560            0 :             mstrlcpy(xfilename, file_name, xfilename_size);
     561              : 
     562            0 :          *fh = open(file_name, O_RDWR | O_BINARY, 0644);
     563              : 
     564            0 :          if (*fh < 0) {
     565            0 :             if (!walk)
     566            0 :                return EL_FILE_ERROR;
     567              : 
     568            0 :             if (direction == -1)
     569            0 :                ltime -= 3600 * 24;      /* one day back */
     570              :             else
     571            0 :                ltime += 3600 * 24;      /* go forward one day */
     572              : 
     573              :             /* set new tag */
     574            0 :             localtime_r(&ltime, &tms);
     575            0 :             sprintf(tag, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
     576              :          }
     577              : 
     578              :          /* in forward direction, stop today */
     579            0 :          if (direction != -1 && ltime > time(NULL) + 3600 * 24)
     580            0 :             break;
     581              : 
     582              :          /* in backward direction, go back 10 years */
     583            0 :          if (direction == -1 && abs((INT) lt - (INT) ltime) > 3600 * 24 * 365 * 10)
     584            0 :             break;
     585              : 
     586            0 :       } while (*fh < 0);
     587              : 
     588            0 :       if (*fh < 0)
     589            0 :          return EL_FILE_ERROR;
     590              : 
     591            0 :       lseek(*fh, offset, SEEK_SET);
     592              : 
     593              :       /* check if start of message */
     594            0 :       i = xread(file_name, *fh, str, 15);
     595            0 :       if (i <= 0) {
     596            0 :          close(*fh);
     597            0 :          return EL_FILE_ERROR;
     598              :       }
     599              : 
     600            0 :       if (strncmp(str, "$Start$: ", 9) != 0) {
     601            0 :          close(*fh);
     602            0 :          return EL_FILE_ERROR;
     603              :       }
     604              : 
     605            0 :       lseek(*fh, offset, SEEK_SET);
     606              :    }
     607              : 
     608              :    /* open most recent file if no tag given */
     609            0 :    if (tag[0] == 0) {
     610            0 :       time((time_t *) &lt);
     611            0 :       ltime = lt;
     612              :       do {
     613            0 :          localtime_r(&ltime, &tms);
     614              : 
     615            0 :          sprintf(file_name, "%s%02d%02d%02d.log", dir, tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
     616              : 
     617            0 :          if (xfilename)
     618            0 :             mstrlcpy(xfilename, file_name, xfilename_size);
     619              : 
     620            0 :          *fh = open(file_name, O_RDWR | O_BINARY, 0644);
     621              : 
     622            0 :          if (*fh < 0)
     623            0 :             ltime -= 3600 * 24; /* one day back */
     624              : 
     625            0 :       } while (*fh < 0 && (INT) lt - (INT) ltime < 3600 * 24 * 365);
     626              : 
     627            0 :       if (*fh < 0)
     628            0 :          return EL_FILE_ERROR;
     629              : 
     630              :       /* remember tag */
     631            0 :       sprintf(tag, "%02d%02d%02d", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
     632              : 
     633            0 :       lseek(*fh, 0, SEEK_END);
     634              : 
     635            0 :       sprintf(tag + strlen(tag), ".%d", (int) TELL(*fh));
     636              :    }
     637              : 
     638              : 
     639            0 :    if (direction == -1) {
     640              :       /* seek previous message */
     641              : 
     642            0 :       if (TELL(*fh) == 0) {
     643              :          /* go back one day */
     644            0 :          close(*fh);
     645              : 
     646            0 :          lt = ltime;
     647              :          do {
     648            0 :             lt -= 3600 * 24;
     649            0 :             localtime_r(&lt, &tms);
     650            0 :             sprintf(str, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
     651              : 
     652            0 :             status = el_search_message(str, fh, FALSE, file_name, sizeof(file_name));
     653              : 
     654            0 :             if (xfilename)
     655            0 :                mstrlcpy(xfilename, file_name, xfilename_size);
     656              : 
     657            0 :          } while (status != EL_SUCCESS && (INT) ltime - (INT) lt < 3600 * 24 * 365);
     658              : 
     659            0 :          if (status != EL_SUCCESS)
     660            0 :             return EL_FIRST_MSG;
     661              : 
     662              :          /* adjust tag */
     663            0 :          strcpy(tag, str);
     664              : 
     665              :          /* go to end of current file */
     666            0 :          lseek(*fh, 0, SEEK_END);
     667              :       }
     668              : 
     669              :       /* read previous message size */
     670            0 :       lseek(*fh, -17, SEEK_CUR);
     671            0 :       i = xread(file_name, *fh, str, 17);
     672            0 :       if (i <= 0) {
     673            0 :          close(*fh);
     674            0 :          return EL_FILE_ERROR;
     675              :       }
     676              : 
     677            0 :       if (strncmp(str, "$End$: ", 7) != 0) {
     678            0 :          close(*fh);
     679            0 :          return EL_FILE_ERROR;
     680              :       }
     681              : 
     682              :       /* make sure the input string to atoi() is zero-terminated:
     683              :        * $End$:      355garbage
     684              :        * 01234567890123456789 */
     685            0 :       str[15] = 0;
     686              : 
     687            0 :       size = atoi(str + 7);
     688            0 :       if (size <= 15) {
     689            0 :          close(*fh);
     690            0 :          return EL_FILE_ERROR;
     691              :       }
     692              : 
     693            0 :       lseek(*fh, -size, SEEK_CUR);
     694              : 
     695              :       /* adjust tag */
     696            0 :       sprintf(strchr(tag, '.') + 1, "%d", (int) TELL(*fh));
     697              :    }
     698              : 
     699            0 :    if (direction == 1) {
     700              :       /* seek next message */
     701              : 
     702              :       /* read current message size */
     703            0 :       TELL(*fh);
     704              : 
     705            0 :       i = xread(file_name, *fh, str, 15);
     706            0 :       if (i <= 0) {
     707            0 :          close(*fh);
     708            0 :          return EL_FILE_ERROR;
     709              :       }
     710            0 :       lseek(*fh, -15, SEEK_CUR);
     711              : 
     712            0 :       if (strncmp(str, "$Start$: ", 9) != 0) {
     713            0 :          close(*fh);
     714            0 :          return EL_FILE_ERROR;
     715              :       }
     716              : 
     717              :       /* make sure the input string to atoi() is zero-terminated
     718              :        * $Start$:    606garbage
     719              :        * 01234567890123456789 */
     720            0 :       str[15] = 0;
     721              : 
     722            0 :       size = atoi(str + 9);
     723              : 
     724            0 :       if (size <= 15) {
     725            0 :          close(*fh);
     726            0 :          return EL_FILE_ERROR;
     727              :       }
     728              : 
     729            0 :       lseek(*fh, size, SEEK_CUR);
     730              : 
     731              :       /* if EOF, goto next day */
     732            0 :       i = xread(file_name, *fh, str, 15);
     733            0 :       if (i < 15) {
     734            0 :          close(*fh);
     735            0 :          time((time_t *) &lact);
     736              : 
     737            0 :          lt = ltime;
     738              :          do {
     739            0 :             lt += 3600 * 24;
     740            0 :             localtime_r(&lt, &tms);
     741            0 :             sprintf(str, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
     742              : 
     743            0 :             status = el_search_message(str, fh, FALSE, file_name, sizeof(file_name));
     744              : 
     745            0 :             if (xfilename)
     746            0 :                mstrlcpy(xfilename, file_name, xfilename_size);
     747              : 
     748            0 :          } while (status != EL_SUCCESS && (INT) lt - (INT) lact < 3600 * 24);
     749              : 
     750            0 :          if (status != EL_SUCCESS)
     751            0 :             return EL_LAST_MSG;
     752              : 
     753              :          /* adjust tag */
     754            0 :          strcpy(tag, str);
     755              : 
     756              :          /* go to beginning of current file */
     757            0 :          lseek(*fh, 0, SEEK_SET);
     758              :       } else
     759            0 :          lseek(*fh, -15, SEEK_CUR);
     760              : 
     761              :       /* adjust tag */
     762            0 :       sprintf(strchr(tag, '.') + 1, "%d", (int) TELL(*fh));
     763              :    }
     764              : 
     765            0 :    return EL_SUCCESS;
     766              : }
     767              : 
     768              : 
     769              : /********************************************************************/
     770            0 : INT el_retrieve(char *tag, char *date, int *run, char *author, char *type,
     771              :                 char *syst, char *subject, char *text, int *textsize,
     772              :                 char *orig_tag, char *reply_tag,
     773              :                 char *attachment1, char *attachment2, char *attachment3, char *encoding)
     774              : /********************************************************************\
     775              : 
     776              :   Routine: el_retrieve
     777              : 
     778              :   Purpose: Retrieve an ELog entry by its message tab
     779              : 
     780              :   Input:
     781              :     char   *tag             tag in the form YYMMDD.offset
     782              :     int    *size            Size of text buffer
     783              : 
     784              :   Output:
     785              :     char   *tag             tag of retrieved message
     786              :     char   *date            Date/time of message recording
     787              :     int    *run             Run number
     788              :     char   *author          Message author
     789              :     char   *type            Message type
     790              :     char   *syst            Message system
     791              :     char   *subject         Subject
     792              :     char   *text            Message text
     793              :     char   *orig_tag        Original message if this one is a reply
     794              :     char   *reply_tag       Reply for current message
     795              :     char   *attachment1/2/3 File attachment
     796              :     char   *encoding        Encoding of message
     797              :     int    *size            Actual message text size
     798              : 
     799              :   Function value:
     800              :     EL_SUCCESS              Successful completion
     801              :     EL_LAST_MSG             Last message in log
     802              : 
     803              : \********************************************************************/
     804              : {
     805            0 :    int size, fh = 0, search_status, rd;
     806              :    char str[256], *p;
     807              :    char thread[256];
     808              :    char attachment_all[3*256+100]; /* size of attachement1/2/3 from show_elog_submit_query() */
     809            0 :    char *message = NULL;
     810            0 :    size_t message_size = 0;
     811              :    char filename[256];
     812              : 
     813            0 :    if (tag[0]) {
     814            0 :       search_status = el_search_message(tag, &fh, TRUE, filename, sizeof(filename));
     815            0 :       if (search_status != EL_SUCCESS)
     816            0 :          return search_status;
     817              :    } else {
     818              :       /* open most recent message */
     819            0 :       strcpy(tag, "-1");
     820            0 :       search_status = el_search_message(tag, &fh, TRUE, filename, sizeof(filename));
     821            0 :       if (search_status != EL_SUCCESS)
     822            0 :          return search_status;
     823              :    }
     824              : 
     825              :    //printf("el_retrieve: reading [%s]\n", filename);
     826              : 
     827              :    /* extract message size */
     828            0 :    TELL(fh);
     829            0 :    rd = xread(filename, fh, str, 15);
     830            0 :    if (rd != 15)
     831            0 :       return EL_FILE_ERROR;
     832              : 
     833              :    /* make sure the input string is zero-terminated before we call atoi() */
     834            0 :    str[15] = 0;
     835              : 
     836              :    /* get size */
     837            0 :    size = atoi(str + 9);
     838              : 
     839            0 :    if ((strncmp(str, "$Start$:", 8) != 0) || (size <= 15)) {
     840            0 :       cm_msg(MERROR, "el_retrieve", "cannot read from \'%s\', corrupted file: no $Start$ or bad size in \"%s\"", filename, str);
     841            0 :       close(fh);
     842            0 :       return EL_FILE_ERROR;
     843              :    }
     844              : 
     845            0 :    message_size = size + 1;
     846            0 :    message = (char*)malloc(message_size);
     847              : 
     848            0 :    if (!message) {
     849            0 :       cm_msg(MERROR, "el_retrieve", "cannot read from \'%s\', cannot malloc() %d bytes, errno %d (%s)", filename, (int)message_size, errno, strerror(errno));
     850            0 :       free(message);
     851            0 :       close(fh);
     852            0 :       return EL_FILE_ERROR;
     853              :    }
     854              : 
     855            0 :    memset(message, 0, message_size);
     856              : 
     857            0 :    rd = read(fh, message, size);
     858            0 :    if (rd <= 0 || !((rd + 15 == size) || (rd == size))) {
     859            0 :       cm_msg(MERROR, "el_retrieve", "cannot read from \'%s\', read(%d) returned %d, errno %d (%s)", filename, size, rd, errno, strerror(errno));
     860            0 :       free(message);
     861            0 :       close(fh);
     862            0 :       return EL_FILE_ERROR;
     863              :    }
     864              : 
     865            0 :    close(fh);
     866              : 
     867              :    /* decode message */
     868            0 :    if (strstr(message, "Run: ") && run)
     869            0 :       *run = atoi(strstr(message, "Run: ") + 5);
     870              : 
     871            0 :    el_decode(message, "Date: ", date, 80);      /* size from show_elog_submit_query() */
     872            0 :    el_decode(message, "Thread: ", thread, sizeof(thread));
     873            0 :    el_decode(message, "Author: ", author, 80);  /* size from show_elog_submit_query() */
     874            0 :    el_decode(message, "Type: ", type, 80);      /* size from show_elog_submit_query() */
     875            0 :    el_decode(message, "System: ", syst, 80);  /* size from show_elog_submit_query() */
     876            0 :    el_decode(message, "Subject: ", subject, 256);       /* size from show_elog_submit_query() */
     877            0 :    el_decode(message, "Attachment: ", attachment_all, sizeof(attachment_all));
     878            0 :    el_decode(message, "Encoding: ", encoding, 80);      /* size from show_elog_submit_query() */
     879              : 
     880              :    /* break apart attachements */
     881            0 :    if (attachment1 && attachment2 && attachment3) {
     882            0 :       attachment1[0] = attachment2[0] = attachment3[0] = 0;
     883            0 :       p = strtok(attachment_all, ",");
     884            0 :       if (p != NULL) {
     885            0 :          mstrlcpy(attachment1, p, 256);          /* size from show_elog_submit_query() */
     886            0 :          p = strtok(NULL, ",");
     887            0 :          if (p != NULL) {
     888            0 :             mstrlcpy(attachment2, p, 256);       /* size from show_elog_submit_query() */
     889            0 :             p = strtok(NULL, ",");
     890            0 :             if (p != NULL)
     891            0 :                mstrlcpy(attachment3, p, 256);    /* size from show_elog_submit_query() */
     892              :          }
     893              :       }
     894              :    }
     895              : 
     896              :    /* conver thread in reply-to and reply-from */
     897            0 :    if (orig_tag != NULL && reply_tag != NULL) {
     898            0 :       p = strtok(thread, " \r");
     899            0 :       if (p != NULL)
     900            0 :          strcpy(orig_tag, p);
     901              :       else
     902            0 :          strcpy(orig_tag, "");
     903            0 :       p = strtok(NULL, " \r");
     904            0 :       if (p != NULL)
     905            0 :          strcpy(reply_tag, p);
     906              :       else
     907            0 :          strcpy(reply_tag, "");
     908            0 :       if (atoi(orig_tag) == 0)
     909            0 :          orig_tag[0] = 0;
     910            0 :       if (atoi(reply_tag) == 0)
     911            0 :          reply_tag[0] = 0;
     912              :    }
     913              : 
     914            0 :    p = strstr(message, "========================================\n");
     915              : 
     916            0 :    if (text != NULL) {
     917            0 :       if (p != NULL) {
     918            0 :          p += 41;
     919            0 :          if ((int) strlen(p) >= *textsize) {
     920            0 :             strncpy(text, p, *textsize - 1);
     921            0 :             text[*textsize - 1] = 0;
     922            0 :             free(message);
     923            0 :             return EL_TRUNCATED;
     924              :          } else {
     925            0 :             strcpy(text, p);
     926              : 
     927              :             /* strip end tag */
     928            0 :             if (strstr(text, "$End$"))
     929            0 :                *strstr(text, "$End$") = 0;
     930              : 
     931            0 :             *textsize = strlen(text);
     932              :          }
     933              :       } else {
     934            0 :          text[0] = 0;
     935            0 :          *textsize = 0;
     936              :       }
     937              :    }
     938              : 
     939            0 :    free(message);
     940            0 :    message = NULL;
     941              : 
     942            0 :    if (search_status == EL_LAST_MSG)
     943            0 :       return EL_LAST_MSG;
     944              : 
     945            0 :    return EL_SUCCESS;
     946              : }
     947              : 
     948              : 
     949              : /********************************************************************/
     950            0 : INT el_search_run(int run, char *return_tag)
     951              : /********************************************************************\
     952              : 
     953              :   Routine: el_search_run
     954              : 
     955              :   Purpose: Find first message belonging to a specific run
     956              : 
     957              :   Input:
     958              :     int    run              Run number
     959              : 
     960              :   Output:
     961              :     char   *tag             tag of retrieved message
     962              : 
     963              :   Function value:
     964              :     EL_SUCCESS              Successful completion
     965              :     EL_LAST_MSG             Last message in log
     966              : 
     967              : \********************************************************************/
     968              : {
     969            0 :    int actual_run=0, fh, status;
     970              :    char tag[256];
     971              : 
     972            0 :    tag[0] = return_tag[0] = 0;
     973              : 
     974              :    do {
     975              :       /* open first message in file */
     976            0 :       strcat(tag, "-1");
     977            0 :       status = el_search_message(tag, &fh, TRUE, NULL, 0);
     978            0 :       if (status == EL_FIRST_MSG)
     979            0 :          break;
     980            0 :       if (status != EL_SUCCESS)
     981            0 :          return status;
     982            0 :       close(fh);
     983              : 
     984            0 :       if (strchr(tag, '.') != NULL)
     985            0 :          strcpy(strchr(tag, '.'), ".0");
     986              : 
     987            0 :       el_retrieve(tag, NULL, &actual_run, NULL, NULL,
     988              :                   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
     989            0 :    } while (actual_run >= run);
     990              : 
     991            0 :    while (actual_run < run) {
     992            0 :       strcat(tag, "+1");
     993            0 :       status = el_search_message(tag, &fh, TRUE, NULL, 0);
     994            0 :       if (status == EL_LAST_MSG)
     995            0 :          break;
     996            0 :       if (status != EL_SUCCESS)
     997            0 :          return status;
     998            0 :       close(fh);
     999              : 
    1000            0 :       el_retrieve(tag, NULL, &actual_run, NULL, NULL,
    1001              :                   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
    1002              :    }
    1003              : 
    1004            0 :    strcpy(return_tag, tag);
    1005              : 
    1006            0 :    if (status == EL_LAST_MSG || status == EL_FIRST_MSG)
    1007            0 :       return status;
    1008              : 
    1009            0 :    return EL_SUCCESS;
    1010              : }
    1011              : 
    1012              : 
    1013              : /********************************************************************/
    1014            0 : INT el_delete_message(const char *tag)
    1015              : /********************************************************************\
    1016              : 
    1017              :   Routine: el_submit
    1018              : 
    1019              :   Purpose: Submit an ELog entry
    1020              : 
    1021              :   Input:
    1022              :     char   *tag             Message tage
    1023              : 
    1024              :   Output:
    1025              :     <none>
    1026              : 
    1027              :   Function value:
    1028              :     EL_SUCCESS              Successful completion
    1029              : 
    1030              : \********************************************************************/
    1031              : {
    1032              : #ifdef LOCAL_ROUTINES
    1033            0 :    INT size, fh, semaphore, offset = 0, tail_size, status;
    1034              :    char dir[256];
    1035              :    char str[256];
    1036              :    char file_name[256+256+10];
    1037              :    HNDLE hDB;
    1038            0 :    char *buffer = NULL;
    1039              : 
    1040            0 :    cm_get_experiment_database(&hDB, NULL);
    1041              : 
    1042              :    /* request semaphore */
    1043            0 :    cm_get_experiment_semaphore(NULL, &semaphore, NULL, NULL);
    1044            0 :    status = ss_semaphore_wait_for(semaphore, 5 * 60 * 1000);
    1045            0 :    if (status != SS_SUCCESS) {
    1046            0 :       cm_msg(MERROR, "el_delete_message",
    1047              :              "Cannot lock experiment semaphore, ss_semaphore_wait_for() status %d", status);
    1048            0 :       abort();
    1049              :    }
    1050              : 
    1051              :    /* generate file name YYMMDD.log in data directory */
    1052            0 :    cm_get_experiment_database(&hDB, NULL);
    1053              : 
    1054            0 :    size = sizeof(dir);
    1055            0 :    memset(dir, 0, size);
    1056            0 :    status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
    1057            0 :    if (status != DB_SUCCESS)
    1058            0 :       db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
    1059              : 
    1060            0 :    if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
    1061            0 :       strcat(dir, DIR_SEPARATOR_STR);
    1062              : 
    1063            0 :    strcpy(str, tag);
    1064            0 :    if (strchr(str, '.')) {
    1065            0 :       offset = atoi(strchr(str, '.') + 1);
    1066            0 :       *strchr(str, '.') = 0;
    1067              :    }
    1068            0 :    sprintf(file_name, "%s%s.log", dir, str);
    1069            0 :    fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
    1070            0 :    if (fh < 0) {
    1071            0 :       ss_semaphore_release(semaphore);
    1072            0 :       return EL_FILE_ERROR;
    1073              :    }
    1074            0 :    lseek(fh, offset, SEEK_SET);
    1075            0 :    xread(file_name, fh, str, 16);
    1076            0 :    size = atoi(str + 9);
    1077              : 
    1078              :    /* buffer tail of logfile */
    1079            0 :    lseek(fh, 0, SEEK_END);
    1080            0 :    tail_size = TELL(fh) - (offset + size);
    1081              : 
    1082            0 :    if (tail_size > 0) {
    1083            0 :       buffer = (char *) M_MALLOC(tail_size);
    1084            0 :       if (buffer == NULL) {
    1085            0 :          close(fh);
    1086            0 :          ss_semaphore_release(semaphore);
    1087            0 :          return EL_FILE_ERROR;
    1088              :       }
    1089              : 
    1090            0 :       lseek(fh, offset + size, SEEK_SET);
    1091            0 :       xread(file_name, fh, buffer, tail_size);
    1092              :    }
    1093            0 :    lseek(fh, offset, SEEK_SET);
    1094              : 
    1095            0 :    if (tail_size > 0) {
    1096            0 :       xwrite(file_name, fh, buffer, tail_size);
    1097            0 :       M_FREE(buffer);
    1098              :    }
    1099              : 
    1100              :    /* truncate file here */
    1101              : #ifdef OS_WINNT
    1102              :    chsize(fh, TELL(fh));
    1103              : #else
    1104            0 :    xtruncate(file_name, fh);
    1105              : #endif
    1106              : 
    1107              :    /* if file length gets zero, delete file */
    1108            0 :    tail_size = lseek(fh, 0, SEEK_END);
    1109            0 :    close(fh);
    1110              : 
    1111            0 :    if (tail_size == 0)
    1112            0 :       remove(file_name);
    1113              : 
    1114              :    /* release elog semaphore */
    1115            0 :    ss_semaphore_release(semaphore);
    1116              : #endif                          /* LOCAL_ROUTINES */
    1117              : 
    1118            0 :    return EL_SUCCESS;
    1119              : }
    1120              : 
    1121              : /**dox***************************************************************/
    1122              : #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
    1123              : 
    1124              : /**dox***************************************************************/
    1125              : /** @} *//* end of elfunctioncode */
    1126              : 
    1127              : /* emacs
    1128              :  * Local Variables:
    1129              :  * tab-width: 8
    1130              :  * c-basic-offset: 3
    1131              :  * indent-tabs-mode: nil
    1132              :  * End:
    1133              :  */
        

Generated by: LCOV version 2.0-1