elog.c

Go to the documentation of this file.
00001 /********************************************************************\
00002 
00003   Name:         ELOG.C
00004   Created by:   Stefan Ritt
00005 
00006   Contents:     MIDAS elog functions
00007 
00008   $Id: elog.c 4172 2008-04-03 19:16:57Z olchanski $
00009 
00010 \********************************************************************/
00011 
00012 #include "midas.h"
00013 #include "msystem.h"
00014 #include "strlcpy.h"
00015 #include <assert.h>
00016 
00017 /** @defgroup elfunctioncode Midas Elog Functions (el_xxx)
00018  */
00019 
00020 /**dox***************************************************************/
00021 /** @addtogroup elfunctioncode
00022  *
00023  *  @{  */
00024 
00025 /**dox***************************************************************/
00026 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00027 
00028 /********************************************************************\
00029 *                                                                    *
00030 *               Electronic logbook functions                         *
00031 *                                                                    *
00032 \********************************************************************/
00033 
00034 /********************************************************************/
00035 void el_decode(char *message, char *key, char *result, int size)
00036 {
00037    char *rstart = result;
00038    char *pc;
00039 
00040    if (result == NULL)
00041       return;
00042 
00043    *result = 0;
00044 
00045    if (strstr(message, key)) {
00046       for (pc = strstr(message, key) + strlen(key); *pc != '\n';)
00047          *result++ = *pc++;
00048       *result = 0;
00049    }
00050 
00051    assert((int) strlen(rstart) < size);
00052 }
00053 
00054 /**dox***************************************************************/
00055 #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
00056 
00057 /********************************************************************/
00058 /**
00059 Submit an ELog entry.
00060 @param run  Run Number.
00061 @param author Message author.
00062 @param type Message type.
00063 @param syst Message system.
00064 @param subject Subject.
00065 @param text Message text.
00066 @param reply_to In reply to this message.
00067 @param encoding Text encoding, either HTML or plain.
00068 @param afilename1   File name of attachment.
00069 @param buffer1      File contents.
00070 @param buffer_size1 Size of buffer in bytes.
00071 @param afilename2   File name of attachment.
00072 @param buffer2      File contents.
00073 @param buffer_size2 Size of buffer in bytes.
00074 @param afilename3   File name of attachment.
00075 @param buffer3      File contents.
00076 @param buffer_size3 Size of buffer in bytes.
00077 @param tag          If given, edit existing message.
00078 @param tag_size     Maximum size of tag.
00079 @return EL_SUCCESS
00080 */
00081 INT el_submit(int run, const char *author, const char *type, const char *syst, const char *subject,
00082               const char *text, const char *reply_to, const char *encoding,
00083               const char *afilename1, char *buffer1, INT buffer_size1,
00084               const char *afilename2, char *buffer2, INT buffer_size2,
00085               const char *afilename3, char *buffer3, INT buffer_size3, char *tag, INT tag_size)
00086 {
00087    if (rpc_is_remote())
00088       return rpc_call(RPC_EL_SUBMIT, run, author, type, syst, subject,
00089                       text, reply_to, encoding,
00090                       afilename1, buffer1, buffer_size1,
00091                       afilename2, buffer2, buffer_size2, afilename3, buffer3, buffer_size3, tag, tag_size);
00092 
00093 #ifdef LOCAL_ROUTINES
00094    {
00095       INT n, size, fh, status, run_number, mutex, buffer_size = 0, idx, offset = 0, tail_size = 0;
00096       struct tm *tms = NULL;
00097       char afilename[256], file_name[256], afile_name[3][256], dir[256], str[256],
00098           start_str[80], end_str[80], last[80], date[80], thread[80], attachment[256];
00099       HNDLE hDB;
00100       time_t now;
00101       char message[10000], *p;
00102       char *buffer = NULL;
00103       BOOL bedit;
00104 
00105       cm_get_experiment_database(&hDB, NULL);
00106 
00107       bedit = (tag[0] != 0);
00108 
00109       /* request semaphore */
00110       cm_get_experiment_mutex(NULL, &mutex, NULL, NULL);
00111       status = ss_mutex_wait_for(mutex, 5 * 60 * 1000);
00112       if (status != SS_SUCCESS) {
00113          cm_msg(MERROR, "el_submit", "Cannot lock experiment mutex, ss_mutex_wait_for() status %d", status);
00114          abort();
00115       }
00116 
00117       /* get run number from ODB if not given */
00118       if (run > 0)
00119          run_number = run;
00120       else {
00121          /* get run number */
00122          size = sizeof(run_number);
00123          status = db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT, TRUE);
00124          assert(status == SUCCESS);
00125       }
00126 
00127       if (run_number < 0) {
00128          cm_msg(MERROR, "el_submit", "aborting on attempt to use invalid run number %d", run_number);
00129          abort();
00130       }
00131 
00132       for (idx = 0; idx < 3; idx++) {
00133          /* generate filename for attachment */
00134          afile_name[idx][0] = file_name[0] = 0;
00135 
00136          if (idx == 0) {
00137             strcpy(afilename, afilename1);
00138             buffer = buffer1;
00139             buffer_size = buffer_size1;
00140          } else if (idx == 1) {
00141             strcpy(afilename, afilename2);
00142             buffer = buffer2;
00143             buffer_size = buffer_size2;
00144          } else if (idx == 2) {
00145             strcpy(afilename, afilename3);
00146             buffer = buffer3;
00147             buffer_size = buffer_size3;
00148          }
00149 
00150          if (afilename[0]) {
00151             strcpy(file_name, afilename);
00152             p = file_name;
00153             while (strchr(p, ':'))
00154                p = strchr(p, ':') + 1;
00155             while (strchr(p, '\\'))
00156                p = strchr(p, '\\') + 1; /* NT */
00157             while (strchr(p, '/'))
00158                p = strchr(p, '/') + 1;  /* Unix */
00159             while (strchr(p, ']'))
00160                p = strchr(p, ']') + 1;  /* VMS */
00161 
00162             /* assemble ELog filename */
00163             if (p[0]) {
00164                dir[0] = 0;
00165                if (hDB > 0) {
00166                   size = sizeof(dir);
00167                   memset(dir, 0, size);
00168                   status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
00169                   if (status != DB_SUCCESS)
00170                      db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
00171 
00172                   if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
00173                      strcat(dir, DIR_SEPARATOR_STR);
00174                }
00175 #if !defined(OS_VXWORKS)
00176 #if !defined(OS_VMS)
00177                tzset();
00178 #endif
00179 #endif
00180 
00181                time(&now);
00182                tms = localtime(&now);
00183 
00184                strcpy(str, p);
00185                sprintf(afile_name[idx], "%02d%02d%02d_%02d%02d%02d_%s",
00186                        tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday,
00187                        tms->tm_hour, tms->tm_min, tms->tm_sec, str);
00188                sprintf(file_name, "%s%02d%02d%02d_%02d%02d%02d_%s", dir,
00189                        tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday,
00190                        tms->tm_hour, tms->tm_min, tms->tm_sec, str);
00191 
00192                /* save attachment */
00193                fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
00194                if (fh < 0) {
00195                   cm_msg(MERROR, "el_submit", "Cannot write attachment file \"%s\"", file_name);
00196                } else {
00197                   write(fh, buffer, buffer_size);
00198                   close(fh);
00199                }
00200             }
00201          }
00202       }
00203 
00204       /* generate new file name YYMMDD.log in data directory */
00205       cm_get_experiment_database(&hDB, NULL);
00206 
00207       size = sizeof(dir);
00208       memset(dir, 0, size);
00209       status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
00210       if (status != DB_SUCCESS)
00211          db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
00212 
00213       if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
00214          strcat(dir, DIR_SEPARATOR_STR);
00215 
00216 #if !defined(OS_VXWORKS)
00217 #if !defined(OS_VMS)
00218       tzset();
00219 #endif
00220 #endif
00221 
00222       if (bedit) {
00223          /* edit existing message */
00224          strcpy(str, tag);
00225          if (strchr(str, '.')) {
00226             offset = atoi(strchr(str, '.') + 1);
00227             *strchr(str, '.') = 0;
00228          }
00229          sprintf(file_name, "%s%s.log", dir, str);
00230          fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
00231          if (fh < 0) {
00232             ss_mutex_release(mutex);
00233             return EL_FILE_ERROR;
00234          }
00235          lseek(fh, offset, SEEK_SET);
00236          read(fh, str, 16);
00237          assert(strncmp(str, "$Start$", 7) == 0);
00238 
00239          size = atoi(str + 9);
00240          read(fh, message, size);
00241 
00242          el_decode(message, "Date: ", date, sizeof(date));
00243          el_decode(message, "Thread: ", thread, sizeof(thread));
00244          el_decode(message, "Attachment: ", attachment, sizeof(attachment));
00245 
00246          /* buffer tail of logfile */
00247          lseek(fh, 0, SEEK_END);
00248          tail_size = TELL(fh) - (offset + size);
00249 
00250          if (tail_size > 0) {
00251             buffer = (char *) M_MALLOC(tail_size);
00252             if (buffer == NULL) {
00253                close(fh);
00254                ss_mutex_release(mutex);
00255                return EL_FILE_ERROR;
00256             }
00257 
00258             lseek(fh, offset + size, SEEK_SET);
00259             n = read(fh, buffer, tail_size);
00260             assert(n == tail_size);
00261          }
00262          lseek(fh, offset, SEEK_SET);
00263       } else {
00264          /* create new message */
00265          time(&now);
00266          tms = localtime(&now);
00267 
00268          sprintf(file_name, "%s%02d%02d%02d.log", dir, tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday);
00269 
00270          fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
00271          if (fh < 0) {
00272             ss_mutex_release(mutex);
00273             return EL_FILE_ERROR;
00274          }
00275 
00276          strcpy(date, ctime(&now));
00277          date[24] = 0;
00278 
00279          if (reply_to[0])
00280             sprintf(thread, "%16s %16s", reply_to, "0");
00281          else
00282             sprintf(thread, "%16s %16s", "0", "0");
00283 
00284          lseek(fh, 0, SEEK_END);
00285       }
00286 
00287       /* compose message */
00288 
00289       sprintf(message, "Date: %s\n", date);
00290       sprintf(message + strlen(message), "Thread: %s\n", thread);
00291       sprintf(message + strlen(message), "Run: %d\n", run_number);
00292       sprintf(message + strlen(message), "Author: %s\n", author);
00293       sprintf(message + strlen(message), "Type: %s\n", type);
00294       sprintf(message + strlen(message), "System: %s\n", syst);
00295       sprintf(message + strlen(message), "Subject: %s\n", subject);
00296 
00297       /* keep original attachment if edit and no new attachment */
00298       if (bedit && afile_name[0][0] == 0 && afile_name[1][0] == 0 && afile_name[2][0] == 0)
00299          sprintf(message + strlen(message), "Attachment: %s", attachment);
00300       else {
00301          sprintf(message + strlen(message), "Attachment: %s", afile_name[0]);
00302          if (afile_name[1][0])
00303             sprintf(message + strlen(message), ",%s", afile_name[1]);
00304          if (afile_name[2][0])
00305             sprintf(message + strlen(message), ",%s", afile_name[2]);
00306       }
00307       sprintf(message + strlen(message), "\n");
00308 
00309       sprintf(message + strlen(message), "Encoding: %s\n", encoding);
00310       sprintf(message + strlen(message), "========================================\n");
00311       strcat(message, text);
00312 
00313       assert(strlen(message) < sizeof(message));        /* bomb out on array overrun. */
00314 
00315       size = 0;
00316       sprintf(start_str, "$Start$: %6d\n", size);
00317       sprintf(end_str, "$End$:   %6d\n\f", size);
00318 
00319       size = strlen(message) + strlen(start_str) + strlen(end_str);
00320 
00321       if (tag != NULL && !bedit)
00322          sprintf(tag, "%02d%02d%02d.%d", tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday, (int) TELL(fh));
00323 
00324       /* size has to fit in 6 digits */
00325       assert(size < 999999);
00326 
00327       sprintf(start_str, "$Start$: %6d\n", size);
00328       sprintf(end_str, "$End$:   %6d\n\f", size);
00329 
00330       write(fh, start_str, strlen(start_str));
00331       write(fh, message, strlen(message));
00332       write(fh, end_str, strlen(end_str));
00333 
00334       if (bedit) {
00335          if (tail_size > 0) {
00336             n = write(fh, buffer, tail_size);
00337             M_FREE(buffer);
00338          }
00339 
00340          /* truncate file here */
00341 #ifdef OS_WINNT
00342          chsize(fh, TELL(fh));
00343 #else
00344          ftruncate(fh, TELL(fh));
00345 #endif
00346       }
00347 
00348       close(fh);
00349 
00350       /* if reply, mark original message */
00351       if (reply_to[0] && !bedit) {
00352          strcpy(last, reply_to);
00353          do {
00354             status = el_search_message(last, &fh, FALSE);
00355             if (status == EL_SUCCESS) {
00356                /* position to next thread location */
00357                lseek(fh, 72, SEEK_CUR);
00358                memset(str, 0, sizeof(str));
00359                read(fh, str, 16);
00360                lseek(fh, -16, SEEK_CUR);
00361 
00362                /* if no reply yet, set it */
00363                if (atoi(str) == 0) {
00364                   sprintf(str, "%16s", tag);
00365                   write(fh, str, 16);
00366                   close(fh);
00367                   break;
00368                } else {
00369                   /* if reply set, find last one in chain */
00370                   strcpy(last, strtok(str, " "));
00371                   close(fh);
00372                }
00373             } else
00374                /* stop on error */
00375                break;
00376 
00377          } while (TRUE);
00378       }
00379 
00380       /* release elog mutex */
00381       ss_mutex_release(mutex);
00382    }
00383 #endif                          /* LOCAL_ROUTINES */
00384 
00385    return EL_SUCCESS;
00386 }
00387 
00388 /**dox***************************************************************/
00389 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00390 
00391 /********************************************************************/
00392 INT el_search_message(char *tag, int *fh, BOOL walk)
00393 {
00394    int i, size, offset, direction, last, status;
00395    struct tm *tms, ltms;
00396    time_t lt, ltime, lact;
00397    char str[256], file_name[256], dir[256];
00398    HNDLE hDB;
00399 
00400 #if !defined(OS_VXWORKS)
00401 #if !defined(OS_VMS)
00402    tzset();
00403 #endif
00404 #endif
00405 
00406    /* open file */
00407    cm_get_experiment_database(&hDB, NULL);
00408 
00409    size = sizeof(dir);
00410    memset(dir, 0, size);
00411    status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
00412    if (status != DB_SUCCESS)
00413       db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
00414 
00415    if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
00416       strcat(dir, DIR_SEPARATOR_STR);
00417 
00418    /* check tag for direction */
00419    direction = 0;
00420    if (strpbrk(tag, "+-")) {
00421       direction = atoi(strpbrk(tag, "+-"));
00422       *strpbrk(tag, "+-") = 0;
00423    }
00424 
00425    /* if tag is given, open file directly */
00426    if (tag[0]) {
00427       /* extract time structure from tag */
00428       tms = &ltms;
00429       memset(tms, 0, sizeof(struct tm));
00430       tms->tm_year = (tag[0] - '0') * 10 + (tag[1] - '0');
00431       tms->tm_mon = (tag[2] - '0') * 10 + (tag[3] - '0') - 1;
00432       tms->tm_mday = (tag[4] - '0') * 10 + (tag[5] - '0');
00433       tms->tm_hour = 12;
00434 
00435       if (tms->tm_year < 90)
00436          tms->tm_year += 100;
00437       ltime = lt = mktime(tms);
00438 
00439       strcpy(str, tag);
00440       if (strchr(str, '.')) {
00441          offset = atoi(strchr(str, '.') + 1);
00442          *strchr(str, '.') = 0;
00443       } else
00444          return EL_FILE_ERROR;
00445 
00446       do {
00447          tms = localtime(&ltime);
00448 
00449          sprintf(file_name, "%s%02d%02d%02d.log", dir, tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday);
00450          *fh = open(file_name, O_RDWR | O_BINARY, 0644);
00451 
00452          if (*fh < 0) {
00453             if (!walk)
00454                return EL_FILE_ERROR;
00455 
00456             if (direction == -1)
00457                ltime -= 3600 * 24;      /* one day back */
00458             else
00459                ltime += 3600 * 24;      /* go forward one day */
00460 
00461             /* set new tag */
00462             tms = localtime(&ltime);
00463             sprintf(tag, "%02d%02d%02d.0", tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday);
00464          }
00465 
00466          /* in forward direction, stop today */
00467          if (direction != -1 && ltime > time(NULL) + 3600 * 24)
00468             break;
00469 
00470          /* in backward direction, go back 10 years */
00471          if (direction == -1 && abs((INT) lt - (INT) ltime) > 3600 * 24 * 365 * 10)
00472             break;
00473 
00474       } while (*fh < 0);
00475 
00476       if (*fh < 0)
00477          return EL_FILE_ERROR;
00478 
00479       lseek(*fh, offset, SEEK_SET);
00480 
00481       /* check if start of message */
00482       i = read(*fh, str, 15);
00483       if (i <= 0) {
00484          close(*fh);
00485          return EL_FILE_ERROR;
00486       }
00487 
00488       if (strncmp(str, "$Start$: ", 9) != 0) {
00489          close(*fh);
00490          return EL_FILE_ERROR;
00491       }
00492 
00493       lseek(*fh, offset, SEEK_SET);
00494    }
00495 
00496    /* open most recent file if no tag given */
00497    if (tag[0] == 0) {
00498       time((time_t *) &lt);
00499       ltime = lt;
00500       do {
00501          tms = localtime(&ltime);
00502 
00503          sprintf(file_name, "%s%02d%02d%02d.log", dir, tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday);
00504          *fh = open(file_name, O_RDWR | O_BINARY, 0644);
00505 
00506          if (*fh < 0)
00507             ltime -= 3600 * 24; /* one day back */
00508 
00509       } while (*fh < 0 && (INT) lt - (INT) ltime < 3600 * 24 * 365);
00510 
00511       if (*fh < 0)
00512          return EL_FILE_ERROR;
00513 
00514       /* remember tag */
00515       sprintf(tag, "%02d%02d%02d", tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday);
00516 
00517       lseek(*fh, 0, SEEK_END);
00518 
00519       sprintf(tag + strlen(tag), ".%d", (int) TELL(*fh));
00520    }
00521 
00522 
00523    if (direction == -1) {
00524       /* seek previous message */
00525 
00526       if (TELL(*fh) == 0) {
00527          /* go back one day */
00528          close(*fh);
00529 
00530          lt = ltime;
00531          do {
00532             lt -= 3600 * 24;
00533             tms = localtime(&lt);
00534             sprintf(str, "%02d%02d%02d.0", tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday);
00535 
00536             status = el_search_message(str, fh, FALSE);
00537 
00538          } while (status != EL_SUCCESS && (INT) ltime - (INT) lt < 3600 * 24 * 365);
00539 
00540          if (status != EL_SUCCESS)
00541             return EL_FIRST_MSG;
00542 
00543          /* adjust tag */
00544          strcpy(tag, str);
00545 
00546          /* go to end of current file */
00547          lseek(*fh, 0, SEEK_END);
00548       }
00549 
00550       /* read previous message size */
00551       lseek(*fh, -17, SEEK_CUR);
00552       i = read(*fh, str, 17);
00553       if (i <= 0) {
00554          close(*fh);
00555          return EL_FILE_ERROR;
00556       }
00557 
00558       if (strncmp(str, "$End$: ", 7) != 0) {
00559          close(*fh);
00560          return EL_FILE_ERROR;
00561       }
00562 
00563       /* make sure the input string to atoi() is zero-terminated:
00564        * $End$:      355garbage
00565        * 01234567890123456789 */
00566       str[15] = 0;
00567 
00568       size = atoi(str + 7);
00569       assert(size > 15);
00570 
00571       lseek(*fh, -size, SEEK_CUR);
00572 
00573       /* adjust tag */
00574       sprintf(strchr(tag, '.') + 1, "%d", (int) TELL(*fh));
00575    }
00576 
00577    if (direction == 1) {
00578       /* seek next message */
00579 
00580       /* read current message size */
00581       last = TELL(*fh);
00582 
00583       i = read(*fh, str, 15);
00584       if (i <= 0) {
00585          close(*fh);
00586          return EL_FILE_ERROR;
00587       }
00588       lseek(*fh, -15, SEEK_CUR);
00589 
00590       if (strncmp(str, "$Start$: ", 9) != 0) {
00591          close(*fh);
00592          return EL_FILE_ERROR;
00593       }
00594 
00595       /* make sure the input string to atoi() is zero-terminated
00596        * $Start$:    606garbage
00597        * 01234567890123456789 */
00598       str[15] = 0;
00599 
00600       size = atoi(str + 9);
00601       assert(size > 15);
00602 
00603       lseek(*fh, size, SEEK_CUR);
00604 
00605       /* if EOF, goto next day */
00606       i = read(*fh, str, 15);
00607       if (i < 15) {
00608          close(*fh);
00609          time((time_t *) &lact);
00610 
00611          lt = ltime;
00612          do {
00613             lt += 3600 * 24;
00614             tms = localtime(&lt);
00615             sprintf(str, "%02d%02d%02d.0", tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday);
00616 
00617             status = el_search_message(str, fh, FALSE);
00618 
00619          } while (status != EL_SUCCESS && (INT) lt - (INT) lact < 3600 * 24);
00620 
00621          if (status != EL_SUCCESS)
00622             return EL_LAST_MSG;
00623 
00624          /* adjust tag */
00625          strcpy(tag, str);
00626 
00627          /* go to beginning of current file */
00628          lseek(*fh, 0, SEEK_SET);
00629       } else
00630          lseek(*fh, -15, SEEK_CUR);
00631 
00632       /* adjust tag */
00633       sprintf(strchr(tag, '.') + 1, "%d", (int) TELL(*fh));
00634    }
00635 
00636    return EL_SUCCESS;
00637 }
00638 
00639 
00640 /********************************************************************/
00641 INT el_retrieve(char *tag, char *date, int *run, char *author, char *type,
00642                 char *syst, char *subject, char *text, int *textsize,
00643                 char *orig_tag, char *reply_tag,
00644                 char *attachment1, char *attachment2, char *attachment3, char *encoding)
00645 /********************************************************************\
00646 
00647   Routine: el_retrieve
00648 
00649   Purpose: Retrieve an ELog entry by its message tab
00650 
00651   Input:
00652     char   *tag             tag in the form YYMMDD.offset
00653     int    *size            Size of text buffer
00654 
00655   Output:
00656     char   *tag             tag of retrieved message
00657     char   *date            Date/time of message recording
00658     int    *run             Run number
00659     char   *author          Message author
00660     char   *type            Message type
00661     char   *syst            Message system
00662     char   *subject         Subject
00663     char   *text            Message text
00664     char   *orig_tag        Original message if this one is a reply
00665     char   *reply_tag       Reply for current message
00666     char   *attachment1/2/3 File attachment
00667     char   *encoding        Encoding of message
00668     int    *size            Actual message text size
00669 
00670   Function value:
00671     EL_SUCCESS              Successful completion
00672     EL_LAST_MSG             Last message in log
00673 
00674 \********************************************************************/
00675 {
00676    int size, fh = 0, offset, search_status, rd;
00677    char str[256], *p;
00678    char message[10000], thread[256], attachment_all[256];
00679 
00680    if (tag[0]) {
00681       search_status = el_search_message(tag, &fh, TRUE);
00682       if (search_status != EL_SUCCESS)
00683          return search_status;
00684    } else {
00685       /* open most recent message */
00686       strcpy(tag, "-1");
00687       search_status = el_search_message(tag, &fh, TRUE);
00688       if (search_status != EL_SUCCESS)
00689          return search_status;
00690    }
00691 
00692    /* extract message size */
00693    offset = TELL(fh);
00694    rd = read(fh, str, 15);
00695    assert(rd == 15);
00696 
00697    /* make sure the input string is zero-terminated before we call atoi() */
00698    str[15] = 0;
00699 
00700    /* get size */
00701    size = atoi(str + 9);
00702 
00703    assert(strncmp(str, "$Start$:", 8) == 0);
00704    assert(size > 15);
00705    assert(size < (int)sizeof(message));
00706 
00707    memset(message, 0, sizeof(message));
00708 
00709    rd = read(fh, message, size);
00710    assert(rd > 0);
00711    assert((rd + 15 == size) || (rd == size));
00712 
00713    close(fh);
00714 
00715    /* decode message */
00716    if (strstr(message, "Run: ") && run)
00717       *run = atoi(strstr(message, "Run: ") + 5);
00718 
00719    el_decode(message, "Date: ", date, 80);      /* size from show_elog_submit_query() */
00720    el_decode(message, "Thread: ", thread, sizeof(thread));
00721    el_decode(message, "Author: ", author, 80);  /* size from show_elog_submit_query() */
00722    el_decode(message, "Type: ", type, 80);      /* size from show_elog_submit_query() */
00723    el_decode(message, "System: ", syst, 80);  /* size from show_elog_submit_query() */
00724    el_decode(message, "Subject: ", subject, 256);       /* size from show_elog_submit_query() */
00725    el_decode(message, "Attachment: ", attachment_all, sizeof(attachment_all));
00726    el_decode(message, "Encoding: ", encoding, 80);      /* size from show_elog_submit_query() */
00727 
00728    /* break apart attachements */
00729    if (attachment1 && attachment2 && attachment3) {
00730       attachment1[0] = attachment2[0] = attachment3[0] = 0;
00731       p = strtok(attachment_all, ",");
00732       if (p != NULL) {
00733          strcpy(attachment1, p);
00734          p = strtok(NULL, ",");
00735          if (p != NULL) {
00736             strcpy(attachment2, p);
00737             p = strtok(NULL, ",");
00738             if (p != NULL)
00739                strcpy(attachment3, p);
00740          }
00741       }
00742 
00743       assert(strlen(attachment1) < 256);        /* size from show_elog_submit_query() */
00744       assert(strlen(attachment2) < 256);        /* size from show_elog_submit_query() */
00745       assert(strlen(attachment3) < 256);        /* size from show_elog_submit_query() */
00746    }
00747 
00748    /* conver thread in reply-to and reply-from */
00749    if (orig_tag != NULL && reply_tag != NULL) {
00750       p = strtok(thread, " \r");
00751       if (p != NULL)
00752          strcpy(orig_tag, p);
00753       else
00754          strcpy(orig_tag, "");
00755       p = strtok(NULL, " \r");
00756       if (p != NULL)
00757          strcpy(reply_tag, p);
00758       else
00759          strcpy(reply_tag, "");
00760       if (atoi(orig_tag) == 0)
00761          orig_tag[0] = 0;
00762       if (atoi(reply_tag) == 0)
00763          reply_tag[0] = 0;
00764    }
00765 
00766    p = strstr(message, "========================================\n");
00767 
00768    if (text != NULL) {
00769       if (p != NULL) {
00770          p += 41;
00771          if ((int) strlen(p) >= *textsize) {
00772             strncpy(text, p, *textsize - 1);
00773             text[*textsize - 1] = 0;
00774             return EL_TRUNCATED;
00775          } else {
00776             strcpy(text, p);
00777 
00778             /* strip end tag */
00779             if (strstr(text, "$End$"))
00780                *strstr(text, "$End$") = 0;
00781 
00782             *textsize = strlen(text);
00783          }
00784       } else {
00785          text[0] = 0;
00786          *textsize = 0;
00787       }
00788    }
00789 
00790    if (search_status == EL_LAST_MSG)
00791       return EL_LAST_MSG;
00792 
00793    return EL_SUCCESS;
00794 }
00795 
00796 
00797 /********************************************************************/
00798 INT el_search_run(int run, char *return_tag)
00799 /********************************************************************\
00800 
00801   Routine: el_search_run
00802 
00803   Purpose: Find first message belonging to a specific run
00804 
00805   Input:
00806     int    run              Run number
00807 
00808   Output:
00809     char   *tag             tag of retrieved message
00810 
00811   Function value:
00812     EL_SUCCESS              Successful completion
00813     EL_LAST_MSG             Last message in log
00814 
00815 \********************************************************************/
00816 {
00817    int actual_run, fh, status;
00818    char tag[256];
00819 
00820    tag[0] = return_tag[0] = 0;
00821 
00822    do {
00823       /* open first message in file */
00824       strcat(tag, "-1");
00825       status = el_search_message(tag, &fh, TRUE);
00826       if (status == EL_FIRST_MSG)
00827          break;
00828       if (status != EL_SUCCESS)
00829          return status;
00830       close(fh);
00831 
00832       if (strchr(tag, '.') != NULL)
00833          strcpy(strchr(tag, '.'), ".0");
00834 
00835       el_retrieve(tag, NULL, &actual_run, NULL, NULL,
00836                   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
00837    } while (actual_run >= run);
00838 
00839    while (actual_run < run) {
00840       strcat(tag, "+1");
00841       status = el_search_message(tag, &fh, TRUE);
00842       if (status == EL_LAST_MSG)
00843          break;
00844       if (status != EL_SUCCESS)
00845          return status;
00846       close(fh);
00847 
00848       el_retrieve(tag, NULL, &actual_run, NULL, NULL,
00849                   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
00850    }
00851 
00852    strcpy(return_tag, tag);
00853 
00854    if (status == EL_LAST_MSG || status == EL_FIRST_MSG)
00855       return status;
00856 
00857    return EL_SUCCESS;
00858 }
00859 
00860 
00861 /********************************************************************/
00862 INT el_delete_message(char *tag)
00863 /********************************************************************\
00864 
00865   Routine: el_submit
00866 
00867   Purpose: Submit an ELog entry
00868 
00869   Input:
00870     char   *tag             Message tage
00871 
00872   Output:
00873     <none>
00874 
00875   Function value:
00876     EL_SUCCESS              Successful completion
00877 
00878 \********************************************************************/
00879 {
00880 #ifdef LOCAL_ROUTINES
00881    INT n, size, fh, mutex, offset = 0, tail_size, status;
00882    char dir[256], str[256], file_name[256];
00883    HNDLE hDB;
00884    char *buffer = NULL;
00885 
00886    cm_get_experiment_database(&hDB, NULL);
00887 
00888    /* request semaphore */
00889    cm_get_experiment_mutex(NULL, &mutex, NULL, NULL);
00890    status = ss_mutex_wait_for(mutex, 5 * 60 * 1000);
00891    if (status != SS_SUCCESS) {
00892       cm_msg(MERROR, "el_delete_message",
00893              "Cannot lock experiment mutex, ss_mutex_wait_for() status %d", status);
00894       abort();
00895    }
00896 
00897    /* generate file name YYMMDD.log in data directory */
00898    cm_get_experiment_database(&hDB, NULL);
00899 
00900    size = sizeof(dir);
00901    memset(dir, 0, size);
00902    status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
00903    if (status != DB_SUCCESS)
00904       db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
00905 
00906    if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
00907       strcat(dir, DIR_SEPARATOR_STR);
00908 
00909    strcpy(str, tag);
00910    if (strchr(str, '.')) {
00911       offset = atoi(strchr(str, '.') + 1);
00912       *strchr(str, '.') = 0;
00913    }
00914    sprintf(file_name, "%s%s.log", dir, str);
00915    fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
00916    if (fh < 0) {
00917       ss_mutex_release(mutex);
00918       return EL_FILE_ERROR;
00919    }
00920    lseek(fh, offset, SEEK_SET);
00921    read(fh, str, 16);
00922    size = atoi(str + 9);
00923 
00924    /* buffer tail of logfile */
00925    lseek(fh, 0, SEEK_END);
00926    tail_size = TELL(fh) - (offset + size);
00927 
00928    if (tail_size > 0) {
00929       buffer = (char *) M_MALLOC(tail_size);
00930       if (buffer == NULL) {
00931          close(fh);
00932          ss_mutex_release(mutex);
00933          return EL_FILE_ERROR;
00934       }
00935 
00936       lseek(fh, offset + size, SEEK_SET);
00937       n = read(fh, buffer, tail_size);
00938    }
00939    lseek(fh, offset, SEEK_SET);
00940 
00941    if (tail_size > 0) {
00942       n = write(fh, buffer, tail_size);
00943       M_FREE(buffer);
00944    }
00945 
00946    /* truncate file here */
00947 #ifdef OS_WINNT
00948    chsize(fh, TELL(fh));
00949 #else
00950    ftruncate(fh, TELL(fh));
00951 #endif
00952 
00953    /* if file length gets zero, delete file */
00954    tail_size = lseek(fh, 0, SEEK_END);
00955    close(fh);
00956 
00957    if (tail_size == 0)
00958       remove(file_name);
00959 
00960    /* release elog mutex */
00961    ss_mutex_release(mutex);
00962 #endif                          /* LOCAL_ROUTINES */
00963 
00964    return EL_SUCCESS;
00965 }
00966 
00967 /**dox***************************************************************/
00968 #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
00969 
00970 /**dox***************************************************************/
00971 /** @} *//* end of elfunctioncode */
00972 

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