MIDAS
Midas Elog Functions (el_xxx)

Functions

static void el_decode (const char *message, const char *key, char *result, int size)
 
static void xwrite (const char *filename, int fd, const void *data, int size)
 
static int xread (const char *filename, int fd, void *data, int size)
 
static void xtruncate (const char *filename, int fd)
 
INT el_submit (int run, const char *author, const char *type, const char *syst, const char *subject, const char *text, const char *reply_to, const char *encoding, const char *afilename1, const char *buffer1, INT buffer_size1, const char *afilename2, const char *buffer2, INT buffer_size2, const char *afilename3, const char *buffer3, INT buffer_size3, char *tag, INT tag_size)
 
INT el_search_message (char *tag, int *fh, BOOL walk, char *xfilename, int xfilename_size)
 
INT el_retrieve (char *tag, char *date, int *run, char *author, char *type, char *syst, char *subject, char *text, int *textsize, char *orig_tag, char *reply_tag, char *attachment1, char *attachment2, char *attachment3, char *encoding)
 
INT el_search_run (int run, char *return_tag)
 
INT el_delete_message (const char *tag)
 

Detailed Description

dox


Function Documentation

◆ el_decode()

static void el_decode ( const char *  message,
const char *  key,
char *  result,
int  size 
)
static

dox

Definition at line 37 of file elog.cxx.

38 {
39  int i;
40  const char *pc;
41 
42  if (result == NULL)
43  return;
44 
45  *result = 0;
46 
47  pc = strstr(message, key);
48 
49  if (!pc)
50  return;
51 
52  pc += strlen(key);
53 
54  for (i=0; i<size; i++) {
55  if (pc[i] == 0)
56  break;
57  if (pc[i] == '\n')
58  break;
59  result[i] = pc[i];
60  }
61 
62  assert(i<=size); // ensure that code above did not overrun the "result" array
63 
64  if (i==size)
65  result[size-1] = 0;
66  else
67  result[i] = 0;
68 }
KEY key
Definition: mdump.cxx:37
INT i
Definition: mdump.cxx:35
#define message(type, str)
Definition: midas_macro.h:262
Here is the caller graph for this function:

◆ el_delete_message()

INT el_delete_message ( const char *  tag)

Definition at line 1016 of file elog.cxx.

1033 {
1034 #ifdef LOCAL_ROUTINES
1035  INT size, fh, semaphore, offset = 0, tail_size, status;
1036  char dir[256];
1037  char str[256];
1038  char file_name[256+256+10];
1039  HNDLE hDB;
1040  char *buffer = NULL;
1041 
1043 
1044  /* request semaphore */
1045  cm_get_experiment_semaphore(NULL, &semaphore, NULL, NULL);
1046  status = ss_semaphore_wait_for(semaphore, 5 * 60 * 1000);
1047  if (status != SS_SUCCESS) {
1048  cm_msg(MERROR, "el_delete_message",
1049  "Cannot lock experiment semaphore, ss_semaphore_wait_for() status %d", status);
1050  abort();
1051  }
1052 
1053  /* generate file name YYMMDD.log in data directory */
1055 
1056  size = sizeof(dir);
1057  memset(dir, 0, size);
1058  status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
1059  if (status != DB_SUCCESS)
1060  db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
1061 
1062  if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
1063  strcat(dir, DIR_SEPARATOR_STR);
1064 
1065  strcpy(str, tag);
1066  if (strchr(str, '.')) {
1067  offset = atoi(strchr(str, '.') + 1);
1068  *strchr(str, '.') = 0;
1069  }
1070  sprintf(file_name, "%s%s.log", dir, str);
1071  fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
1072  if (fh < 0) {
1073  ss_semaphore_release(semaphore);
1074  return EL_FILE_ERROR;
1075  }
1076  lseek(fh, offset, SEEK_SET);
1077  xread(file_name, fh, str, 16);
1078  size = atoi(str + 9);
1079 
1080  /* buffer tail of logfile */
1081  lseek(fh, 0, SEEK_END);
1082  tail_size = TELL(fh) - (offset + size);
1083 
1084  if (tail_size > 0) {
1085  buffer = (char *) M_MALLOC(tail_size);
1086  if (buffer == NULL) {
1087  close(fh);
1088  ss_semaphore_release(semaphore);
1089  return EL_FILE_ERROR;
1090  }
1091 
1092  lseek(fh, offset + size, SEEK_SET);
1093  xread(file_name, fh, buffer, tail_size);
1094  }
1095  lseek(fh, offset, SEEK_SET);
1096 
1097  if (tail_size > 0) {
1098  xwrite(file_name, fh, buffer, tail_size);
1099  M_FREE(buffer);
1100  }
1101 
1102  /* truncate file here */
1103 #ifdef OS_WINNT
1104  chsize(fh, TELL(fh));
1105 #else
1106  xtruncate(file_name, fh);
1107 #endif
1108 
1109  /* if file length gets zero, delete file */
1110  tail_size = lseek(fh, 0, SEEK_END);
1111  close(fh);
1112 
1113  if (tail_size == 0)
1114  remove(file_name);
1115 
1116  /* release elog semaphore */
1117  ss_semaphore_release(semaphore);
1118 #endif /* LOCAL_ROUTINES */
1119 
1120  return EL_SUCCESS;
1121 }
#define FALSE
Definition: cfortran.h:309
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition: midas.cxx:3005
INT cm_get_experiment_semaphore(INT *semaphore_alarm, INT *semaphore_elog, INT *semaphore_history, INT *semaphore_msg)
Definition: midas.cxx:3027
static void xwrite(const char *filename, int fd, const void *data, int size)
Definition: elog.cxx:70
static int xread(const char *filename, int fd, void *data, int size)
Definition: elog.cxx:78
static void xtruncate(const char *filename, int fd)
Definition: elog.cxx:91
#define DB_SUCCESS
Definition: midas.h:637
#define SS_SUCCESS
Definition: midas.h:669
#define EL_SUCCESS
Definition: midas.h:751
#define EL_FILE_ERROR
Definition: midas.h:752
#define TID_STRING
Definition: midas.h:353
#define MERROR
Definition: midas.h:565
#define O_BINARY
Definition: msystem.h:219
INT ss_semaphore_release(HNDLE semaphore_handle)
Definition: system.cxx:2720
INT ss_semaphore_wait_for(HNDLE semaphore_handle, INT timeout)
Definition: system.cxx:2600
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition: midas.cxx:917
#define TELL(fh)
Definition: msystem.h:243
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition: odb.cxx:5405
HNDLE hDB
main ODB handle
Definition: mana.cxx:207
static int offset
Definition: mgd.cxx:1500
#define DIR_SEPARATOR
Definition: midas.h:193
INT HNDLE
Definition: midas.h:132
#define M_MALLOC(x)
Definition: midas.h:1550
#define DIR_SEPARATOR_STR
Definition: midas.h:194
int INT
Definition: midas.h:129
#define M_FREE(x)
Definition: midas.h:1552
#define TRUE
Definition: midas.h:182
static std::string remove(const std::string s, char c)
Definition: mjsonrpc.cxx:252
char str[256]
Definition: odbhist.cxx:33
char file_name[256]
Definition: odbhist.cxx:41
DWORD status
Definition: odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ el_retrieve()

INT el_retrieve ( char *  tag,
char *  date,
int *  run,
char *  author,
char *  type,
char *  syst,
char *  subject,
char *  text,
int *  textsize,
char *  orig_tag,
char *  reply_tag,
char *  attachment1,
char *  attachment2,
char *  attachment3,
char *  encoding 
)

Definition at line 772 of file elog.cxx.

806 {
807  int size, fh = 0, search_status, rd;
808  char str[256], *p;
809  char thread[256];
810  char attachment_all[3*256+100]; /* size of attachement1/2/3 from show_elog_submit_query() */
811  char *message = NULL;
812  size_t message_size = 0;
813  char filename[256];
814 
815  if (tag[0]) {
816  search_status = el_search_message(tag, &fh, TRUE, filename, sizeof(filename));
817  if (search_status != EL_SUCCESS)
818  return search_status;
819  } else {
820  /* open most recent message */
821  strcpy(tag, "-1");
822  search_status = el_search_message(tag, &fh, TRUE, filename, sizeof(filename));
823  if (search_status != EL_SUCCESS)
824  return search_status;
825  }
826 
827  //printf("el_retrieve: reading [%s]\n", filename);
828 
829  /* extract message size */
830  TELL(fh);
831  rd = xread(filename, fh, str, 15);
832  if (rd != 15)
833  return EL_FILE_ERROR;
834 
835  /* make sure the input string is zero-terminated before we call atoi() */
836  str[15] = 0;
837 
838  /* get size */
839  size = atoi(str + 9);
840 
841  if ((strncmp(str, "$Start$:", 8) != 0) || (size <= 15)) {
842  cm_msg(MERROR, "el_retrieve", "cannot read from \'%s\', corrupted file: no $Start$ or bad size in \"%s\"", filename, str);
843  close(fh);
844  return EL_FILE_ERROR;
845  }
846 
847  message_size = size + 1;
848  message = (char*)malloc(message_size);
849 
850  if (!message) {
851  cm_msg(MERROR, "el_retrieve", "cannot read from \'%s\', cannot malloc() %d bytes, errno %d (%s)", filename, (int)message_size, errno, strerror(errno));
852  free(message);
853  close(fh);
854  return EL_FILE_ERROR;
855  }
856 
857  memset(message, 0, message_size);
858 
859  rd = read(fh, message, size);
860  if (rd <= 0 || !((rd + 15 == size) || (rd == size))) {
861  cm_msg(MERROR, "el_retrieve", "cannot read from \'%s\', read(%d) returned %d, errno %d (%s)", filename, size, rd, errno, strerror(errno));
862  free(message);
863  close(fh);
864  return EL_FILE_ERROR;
865  }
866 
867  close(fh);
868 
869  /* decode message */
870  if (strstr(message, "Run: ") && run)
871  *run = atoi(strstr(message, "Run: ") + 5);
872 
873  el_decode(message, "Date: ", date, 80); /* size from show_elog_submit_query() */
874  el_decode(message, "Thread: ", thread, sizeof(thread));
875  el_decode(message, "Author: ", author, 80); /* size from show_elog_submit_query() */
876  el_decode(message, "Type: ", type, 80); /* size from show_elog_submit_query() */
877  el_decode(message, "System: ", syst, 80); /* size from show_elog_submit_query() */
878  el_decode(message, "Subject: ", subject, 256); /* size from show_elog_submit_query() */
879  el_decode(message, "Attachment: ", attachment_all, sizeof(attachment_all));
880  el_decode(message, "Encoding: ", encoding, 80); /* size from show_elog_submit_query() */
881 
882  /* break apart attachements */
883  if (attachment1 && attachment2 && attachment3) {
884  attachment1[0] = attachment2[0] = attachment3[0] = 0;
885  p = strtok(attachment_all, ",");
886  if (p != NULL) {
887  strlcpy(attachment1, p, 256); /* size from show_elog_submit_query() */
888  p = strtok(NULL, ",");
889  if (p != NULL) {
890  strlcpy(attachment2, p, 256); /* size from show_elog_submit_query() */
891  p = strtok(NULL, ",");
892  if (p != NULL)
893  strlcpy(attachment3, p, 256); /* size from show_elog_submit_query() */
894  }
895  }
896  }
897 
898  /* conver thread in reply-to and reply-from */
899  if (orig_tag != NULL && reply_tag != NULL) {
900  p = strtok(thread, " \r");
901  if (p != NULL)
902  strcpy(orig_tag, p);
903  else
904  strcpy(orig_tag, "");
905  p = strtok(NULL, " \r");
906  if (p != NULL)
907  strcpy(reply_tag, p);
908  else
909  strcpy(reply_tag, "");
910  if (atoi(orig_tag) == 0)
911  orig_tag[0] = 0;
912  if (atoi(reply_tag) == 0)
913  reply_tag[0] = 0;
914  }
915 
916  p = strstr(message, "========================================\n");
917 
918  if (text != NULL) {
919  if (p != NULL) {
920  p += 41;
921  if ((int) strlen(p) >= *textsize) {
922  strncpy(text, p, *textsize - 1);
923  text[*textsize - 1] = 0;
924  free(message);
925  return EL_TRUNCATED;
926  } else {
927  strcpy(text, p);
928 
929  /* strip end tag */
930  if (strstr(text, "$End$"))
931  *strstr(text, "$End$") = 0;
932 
933  *textsize = strlen(text);
934  }
935  } else {
936  text[0] = 0;
937  *textsize = 0;
938  }
939  }
940 
941  free(message);
942  message = NULL;
943 
944  if (search_status == EL_LAST_MSG)
945  return EL_LAST_MSG;
946 
947  return EL_SUCCESS;
948 }
double textsize
Definition: HandleSIS.cxx:188
static void el_decode(const char *message, const char *key, char *result, int size)
Definition: elog.cxx:37
INT el_search_message(char *tag, int *fh, BOOL walk, char *xfilename, int xfilename_size)
Definition: elog.cxx:502
#define EL_TRUNCATED
Definition: midas.h:754
#define EL_LAST_MSG
Definition: midas.h:756
INT type
Definition: mana.cxx:269
size_t EXPRT strlcpy(char *dst, const char *src, size_t size)
#define read(n, a, f)
Definition: midas_macro.h:242
INT thread(void *p)
Definition: odbedit.cxx:46
DWORD run
Definition: odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ el_search_message()

INT el_search_message ( char *  tag,
int *  fh,
BOOL  walk,
char *  xfilename,
int  xfilename_size 
)

dox

Definition at line 502 of file elog.cxx.

503 {
504  int i, size, offset, direction, status;
505  struct tm tms;
506  time_t lt, ltime=0, lact;
507  char str[256];
508  char dir[256];
509  char file_name[256+100];
510  HNDLE hDB;
511 
512  ss_tzset(); // required by localtime_r()
513 
514  if (xfilename && xfilename_size > 0)
515  *xfilename = 0;
516 
517  /* open file */
519 
520  size = sizeof(dir);
521  memset(dir, 0, size);
522  status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
523  if (status != DB_SUCCESS)
524  db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
525 
526  if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
527  strcat(dir, DIR_SEPARATOR_STR);
528 
529  /* check tag for direction */
530  direction = 0;
531  if (strpbrk(tag, "+-")) {
532  direction = atoi(strpbrk(tag, "+-"));
533  *strpbrk(tag, "+-") = 0;
534  }
535 
536  /* if tag is given, open file directly */
537  if (tag[0]) {
538  /* extract time structure from tag */
539  memset(&tms, 0, sizeof(struct tm));
540  tms.tm_year = (tag[0] - '0') * 10 + (tag[1] - '0');
541  tms.tm_mon = (tag[2] - '0') * 10 + (tag[3] - '0') - 1;
542  tms.tm_mday = (tag[4] - '0') * 10 + (tag[5] - '0');
543  tms.tm_hour = 12;
544 
545  if (tms.tm_year < 90)
546  tms.tm_year += 100;
547  ltime = lt = ss_mktime(&tms);
548 
549  strcpy(str, tag);
550  if (strchr(str, '.')) {
551  offset = atoi(strchr(str, '.') + 1);
552  *strchr(str, '.') = 0;
553  } else
554  return EL_FILE_ERROR;
555 
556  do {
557  localtime_r(&ltime, &tms);
558 
559  sprintf(file_name, "%s%02d%02d%02d.log", dir, tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
560 
561  if (xfilename)
562  strlcpy(xfilename, file_name, xfilename_size);
563 
564  *fh = open(file_name, O_RDWR | O_BINARY, 0644);
565 
566  if (*fh < 0) {
567  if (!walk)
568  return EL_FILE_ERROR;
569 
570  if (direction == -1)
571  ltime -= 3600 * 24; /* one day back */
572  else
573  ltime += 3600 * 24; /* go forward one day */
574 
575  /* set new tag */
576  localtime_r(&ltime, &tms);
577  sprintf(tag, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
578  }
579 
580  /* in forward direction, stop today */
581  if (direction != -1 && ltime > time(NULL) + 3600 * 24)
582  break;
583 
584  /* in backward direction, go back 10 years */
585  if (direction == -1 && abs((INT) lt - (INT) ltime) > 3600 * 24 * 365 * 10)
586  break;
587 
588  } while (*fh < 0);
589 
590  if (*fh < 0)
591  return EL_FILE_ERROR;
592 
593  lseek(*fh, offset, SEEK_SET);
594 
595  /* check if start of message */
596  i = xread(file_name, *fh, str, 15);
597  if (i <= 0) {
598  close(*fh);
599  return EL_FILE_ERROR;
600  }
601 
602  if (strncmp(str, "$Start$: ", 9) != 0) {
603  close(*fh);
604  return EL_FILE_ERROR;
605  }
606 
607  lseek(*fh, offset, SEEK_SET);
608  }
609 
610  /* open most recent file if no tag given */
611  if (tag[0] == 0) {
612  time((time_t *) &lt);
613  ltime = lt;
614  do {
615  localtime_r(&ltime, &tms);
616 
617  sprintf(file_name, "%s%02d%02d%02d.log", dir, tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
618 
619  if (xfilename)
620  strlcpy(xfilename, file_name, xfilename_size);
621 
622  *fh = open(file_name, O_RDWR | O_BINARY, 0644);
623 
624  if (*fh < 0)
625  ltime -= 3600 * 24; /* one day back */
626 
627  } while (*fh < 0 && (INT) lt - (INT) ltime < 3600 * 24 * 365);
628 
629  if (*fh < 0)
630  return EL_FILE_ERROR;
631 
632  /* remember tag */
633  sprintf(tag, "%02d%02d%02d", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
634 
635  lseek(*fh, 0, SEEK_END);
636 
637  sprintf(tag + strlen(tag), ".%d", (int) TELL(*fh));
638  }
639 
640 
641  if (direction == -1) {
642  /* seek previous message */
643 
644  if (TELL(*fh) == 0) {
645  /* go back one day */
646  close(*fh);
647 
648  lt = ltime;
649  do {
650  lt -= 3600 * 24;
651  localtime_r(&lt, &tms);
652  sprintf(str, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
653 
655 
656  if (xfilename)
657  strlcpy(xfilename, file_name, xfilename_size);
658 
659  } while (status != EL_SUCCESS && (INT) ltime - (INT) lt < 3600 * 24 * 365);
660 
661  if (status != EL_SUCCESS)
662  return EL_FIRST_MSG;
663 
664  /* adjust tag */
665  strcpy(tag, str);
666 
667  /* go to end of current file */
668  lseek(*fh, 0, SEEK_END);
669  }
670 
671  /* read previous message size */
672  lseek(*fh, -17, SEEK_CUR);
673  i = xread(file_name, *fh, str, 17);
674  if (i <= 0) {
675  close(*fh);
676  return EL_FILE_ERROR;
677  }
678 
679  if (strncmp(str, "$End$: ", 7) != 0) {
680  close(*fh);
681  return EL_FILE_ERROR;
682  }
683 
684  /* make sure the input string to atoi() is zero-terminated:
685  * $End$: 355garbage
686  * 01234567890123456789 */
687  str[15] = 0;
688 
689  size = atoi(str + 7);
690  if (size <= 15) {
691  close(*fh);
692  return EL_FILE_ERROR;
693  }
694 
695  lseek(*fh, -size, SEEK_CUR);
696 
697  /* adjust tag */
698  sprintf(strchr(tag, '.') + 1, "%d", (int) TELL(*fh));
699  }
700 
701  if (direction == 1) {
702  /* seek next message */
703 
704  /* read current message size */
705  TELL(*fh);
706 
707  i = xread(file_name, *fh, str, 15);
708  if (i <= 0) {
709  close(*fh);
710  return EL_FILE_ERROR;
711  }
712  lseek(*fh, -15, SEEK_CUR);
713 
714  if (strncmp(str, "$Start$: ", 9) != 0) {
715  close(*fh);
716  return EL_FILE_ERROR;
717  }
718 
719  /* make sure the input string to atoi() is zero-terminated
720  * $Start$: 606garbage
721  * 01234567890123456789 */
722  str[15] = 0;
723 
724  size = atoi(str + 9);
725 
726  if (size <= 15) {
727  close(*fh);
728  return EL_FILE_ERROR;
729  }
730 
731  lseek(*fh, size, SEEK_CUR);
732 
733  /* if EOF, goto next day */
734  i = xread(file_name, *fh, str, 15);
735  if (i < 15) {
736  close(*fh);
737  time((time_t *) &lact);
738 
739  lt = ltime;
740  do {
741  lt += 3600 * 24;
742  localtime_r(&lt, &tms);
743  sprintf(str, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
744 
746 
747  if (xfilename)
748  strlcpy(xfilename, file_name, xfilename_size);
749 
750  } while (status != EL_SUCCESS && (INT) lt - (INT) lact < 3600 * 24);
751 
752  if (status != EL_SUCCESS)
753  return EL_LAST_MSG;
754 
755  /* adjust tag */
756  strcpy(tag, str);
757 
758  /* go to beginning of current file */
759  lseek(*fh, 0, SEEK_SET);
760  } else
761  lseek(*fh, -15, SEEK_CUR);
762 
763  /* adjust tag */
764  sprintf(strchr(tag, '.') + 1, "%d", (int) TELL(*fh));
765  }
766 
767  return EL_SUCCESS;
768 }
#define EL_FIRST_MSG
Definition: midas.h:755
time_t ss_mktime(struct tm *tms)
Definition: system.cxx:3304
void ss_tzset()
Definition: system.cxx:3294
MUTEX_T * tm
Definition: odbedit.cxx:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ el_search_run()

INT el_search_run ( int  run,
char *  return_tag 
)

Definition at line 952 of file elog.cxx.

970 {
971  int actual_run=0, fh, status;
972  char tag[256];
973 
974  tag[0] = return_tag[0] = 0;
975 
976  do {
977  /* open first message in file */
978  strcat(tag, "-1");
979  status = el_search_message(tag, &fh, TRUE, NULL, 0);
980  if (status == EL_FIRST_MSG)
981  break;
982  if (status != EL_SUCCESS)
983  return status;
984  close(fh);
985 
986  if (strchr(tag, '.') != NULL)
987  strcpy(strchr(tag, '.'), ".0");
988 
989  el_retrieve(tag, NULL, &actual_run, NULL, NULL,
990  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
991  } while (actual_run >= run);
992 
993  while (actual_run < run) {
994  strcat(tag, "+1");
995  status = el_search_message(tag, &fh, TRUE, NULL, 0);
996  if (status == EL_LAST_MSG)
997  break;
998  if (status != EL_SUCCESS)
999  return status;
1000  close(fh);
1001 
1002  el_retrieve(tag, NULL, &actual_run, NULL, NULL,
1003  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1004  }
1005 
1006  strcpy(return_tag, tag);
1007 
1008  if (status == EL_LAST_MSG || status == EL_FIRST_MSG)
1009  return status;
1010 
1011  return EL_SUCCESS;
1012 }
INT el_retrieve(char *tag, char *date, int *run, char *author, char *type, char *syst, char *subject, char *text, int *textsize, char *orig_tag, char *reply_tag, char *attachment1, char *attachment2, char *attachment3, char *encoding)
Definition: elog.cxx:772
Here is the call graph for this function:
Here is the caller graph for this function:

◆ el_submit()

INT el_submit ( int  run,
const char *  author,
const char *  type,
const char *  syst,
const char *  subject,
const char *  text,
const char *  reply_to,
const char *  encoding,
const char *  afilename1,
const char *  buffer1,
INT  buffer_size1,
const char *  afilename2,
const char *  buffer2,
INT  buffer_size2,
const char *  afilename3,
const char *  buffer3,
INT  buffer_size3,
char *  tag,
INT  tag_size 
)

dox Submit an ELog entry.

Parameters
runRun Number.
authorMessage author.
typeMessage type.
systMessage system.
subjectSubject.
textMessage text.
reply_toIn reply to this message.
encodingText encoding, either HTML or plain.
afilename1File name of attachment.
buffer1File contents.
buffer_size1Size of buffer in bytes.
afilename2File name of attachment.
buffer2File contents.
buffer_size2Size of buffer in bytes.
afilename3File name of attachment.
buffer3File contents.
buffer_size3Size of buffer in bytes.
tagIf given, edit existing message.
tag_sizeMaximum size of tag.
Returns
EL_SUCCESS

Definition at line 126 of file elog.cxx.

131 {
132  if (rpc_is_remote())
133  return rpc_call(RPC_EL_SUBMIT, run, author, type, syst, subject,
134  text, reply_to, encoding,
135  afilename1, buffer1, buffer_size1,
136  afilename2, buffer2, buffer_size2, afilename3, buffer3, buffer_size3, tag, tag_size);
137 
138 #ifdef LOCAL_ROUTINES
139  {
140  INT size, fh, status, run_number, semaphore, idx, offset = 0, tail_size = 0;
141  char file_name[256+256+100];
142  char afile_name[3][256+256];
143  char dir[256];
144  char start_str[80], end_str[80], last[80], date[80], thread[80], attachment[256];
145  HNDLE hDB;
146  time_t now;
147  char *p;
148  char* message = NULL;
149  size_t message_size = 0;
150  BOOL bedit;
151  struct tm tms;
152 
154 
155  bedit = (tag[0] != 0);
156 
157  /* request semaphore */
158  cm_get_experiment_semaphore(NULL, &semaphore, NULL, NULL);
159  status = ss_semaphore_wait_for(semaphore, 5 * 60 * 1000);
160  if (status != SS_SUCCESS) {
161  cm_msg(MERROR, "el_submit", "Cannot lock experiment semaphore, ss_semaphore_wait_for() status %d", status);
162  abort();
163  }
164 
165  /* get run number from ODB if not given */
166  if (run > 0)
167  run_number = run;
168  else {
169  /* get run number */
170  size = sizeof(run_number);
171  status = db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT, TRUE);
172  assert(status == SUCCESS);
173  }
174 
175  if (run_number < 0) {
176  cm_msg(MERROR, "el_submit", "aborting on attempt to use invalid run number %d", run_number);
177  abort();
178  }
179 
180  for (idx = 0; idx < 3; idx++) {
181  /* generate filename for attachment */
182  afile_name[idx][0] = file_name[0] = 0;
183 
184  char afilename[256];
185  const char* buffer = NULL;
186  int buffer_size = 0;
187 
188  if (idx == 0) {
189  strlcpy(afilename, afilename1, sizeof(afilename));
190  buffer = buffer1;
191  buffer_size = buffer_size1;
192  } else if (idx == 1) {
193  strlcpy(afilename, afilename2, sizeof(afilename));
194  buffer = buffer2;
195  buffer_size = buffer_size2;
196  } else if (idx == 2) {
197  strlcpy(afilename, afilename3, sizeof(afilename));
198  buffer = buffer3;
199  buffer_size = buffer_size3;
200  }
201 
202  if (afilename[0]) {
203  strcpy(file_name, afilename);
204  p = file_name;
205  while (strchr(p, ':'))
206  p = strchr(p, ':') + 1;
207  while (strchr(p, '\\'))
208  p = strchr(p, '\\') + 1; /* NT */
209  while (strchr(p, '/'))
210  p = strchr(p, '/') + 1; /* Unix */
211  while (strchr(p, ']'))
212  p = strchr(p, ']') + 1; /* VMS */
213 
214  /* assemble ELog filename */
215  if (p[0]) {
216  dir[0] = 0;
217  if (hDB > 0) {
218  size = sizeof(dir);
219  memset(dir, 0, size);
220  status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
221  if (status != DB_SUCCESS)
222  db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
223 
224  if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
225  strcat(dir, DIR_SEPARATOR_STR);
226  }
227 
228  ss_tzset();
229  time(&now);
230  localtime_r(&now, &tms);
231 
232  char str[256];
233  strlcpy(str, p, sizeof(str));
234  sprintf(afile_name[idx], "%02d%02d%02d_%02d%02d%02d_%s",
235  tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday,
236  tms.tm_hour, tms.tm_min, tms.tm_sec, str);
237  sprintf(file_name, "%s%02d%02d%02d_%02d%02d%02d_%s", dir,
238  tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday,
239  tms.tm_hour, tms.tm_min, tms.tm_sec, str);
240 
241  /* save attachment */
242  fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
243  if (fh < 0) {
244  cm_msg(MERROR, "el_submit", "Cannot write attachment file \"%s\", open() returned %d, errno %d (%s)", file_name, fh, errno, strerror(errno));
245  } else {
246  xwrite(file_name, fh, buffer, buffer_size);
247  close(fh);
248  }
249  }
250  }
251  } // loop over attachmnents
252 
253  /* generate new file name YYMMDD.log in data directory */
255 
256  size = sizeof(dir);
257  memset(dir, 0, size);
258  status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
259  if (status != DB_SUCCESS)
260  db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
261 
262  if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
263  strcat(dir, DIR_SEPARATOR_STR);
264 
265  ss_tzset();
266 
267  char* buffer = NULL;
268 
269  if (bedit) {
270  /* edit existing message */
271  char str[256];
272  strlcpy(str, tag, sizeof(str));
273  if (strchr(str, '.')) {
274  offset = atoi(strchr(str, '.') + 1);
275  *strchr(str, '.') = 0;
276  }
277  sprintf(file_name, "%s%s.log", dir, str);
278  fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
279  if (fh < 0) {
280  ss_semaphore_release(semaphore);
281  return EL_FILE_ERROR;
282  }
283  lseek(fh, offset, SEEK_SET);
284  xread(file_name, fh, str, 16);
285 
286  if (strncmp(str, "$Start$", 7) != 0) {
287  cm_msg(MERROR, "el_submit", "cannot read from \'%s\', corrupted file: no $Start$ in \"%s\"", file_name, str);
288  close(fh);
289  return EL_FILE_ERROR;
290  }
291 
292  size = atoi(str + 9);
293 
294  if (size < 1) {
295  cm_msg(MERROR, "el_submit", "cannot read from \'%s\', corrupted file: bad size %d in \"%s\"", file_name, size, str);
296  close(fh);
297  return EL_FILE_ERROR;
298  }
299 
300  message = (char*)malloc(size);
301 
302  if (!message) {
303  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));
304  close(fh);
305  return EL_FILE_ERROR;
306  }
307 
308  status = read(fh, message, size);
309  if (status != size && status + 16 != size) {
310  free(message);
311  return EL_FILE_ERROR;
312  }
313 
314  el_decode(message, "Date: ", date, sizeof(date));
315  el_decode(message, "Thread: ", thread, sizeof(thread));
316  el_decode(message, "Attachment: ", attachment, sizeof(attachment));
317 
318  free(message);
319  message = NULL;
320 
321  /* buffer tail of logfile */
322  lseek(fh, 0, SEEK_END);
323  tail_size = TELL(fh) - (offset + size);
324 
325  if (tail_size > 0) {
326  int n;
327 
328  buffer = (char *) M_MALLOC(tail_size);
329  if (buffer == NULL) {
330  close(fh);
331  ss_semaphore_release(semaphore);
332  return EL_FILE_ERROR;
333  }
334 
335  lseek(fh, offset + size, SEEK_SET);
336  n = xread(file_name, fh, buffer, tail_size);
337  if (n != tail_size)
338  return EL_FILE_ERROR;
339  }
340  lseek(fh, offset, SEEK_SET);
341  } else {
342  /* create new message */
343  ss_tzset(); // required by localtime_r()
344  time(&now);
345  localtime_r(&now, &tms);
346 
347  sprintf(file_name, "%s%02d%02d%02d.log", dir, tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
348 
349  fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
350  if (fh < 0) {
351  ss_semaphore_release(semaphore);
352  return EL_FILE_ERROR;
353  }
354 
355  assert(sizeof(date) >= 32);
356  ctime_r(&now, date);
357  date[24] = 0;
358 
359  if (reply_to[0])
360  sprintf(thread, "%16s %16s", reply_to, "0");
361  else
362  sprintf(thread, "%16s %16s", "0", "0");
363 
364  lseek(fh, 0, SEEK_END);
365  }
366 
367  message_size = 1000;
368  message_size += strlen(date);
369  message_size += strlen(author);
370  message_size += strlen(type);
371  message_size += strlen(syst);
372  message_size += strlen(subject);
373  message_size += strlen(attachment);
374  message_size += strlen(afile_name[0]);
375  message_size += strlen(afile_name[1]);
376  message_size += strlen(afile_name[2]);
377  message_size += strlen(encoding);
378  message_size += strlen(text);
379 
380  //printf("message_size %d, text %d\n", (int)message_size, (int)strlen(text));
381 
382  message = (char*)malloc(message_size);
383 
384  if (!message) {
385  cm_msg(MERROR, "el_submit", "cannot malloc() %d bytes: errno %d (%s)", size, errno, strerror(errno));
386  close(fh);
387  return EL_FILE_ERROR;
388  }
389 
390  /* compose message */
391 
392  sprintf(message, "Date: %s\n", date);
393  sprintf(message + strlen(message), "Thread: %s\n", thread);
394  sprintf(message + strlen(message), "Run: %d\n", run_number);
395  sprintf(message + strlen(message), "Author: %s\n", author);
396  sprintf(message + strlen(message), "Type: %s\n", type);
397  sprintf(message + strlen(message), "System: %s\n", syst);
398  sprintf(message + strlen(message), "Subject: %s\n", subject);
399 
400  /* keep original attachment if edit and no new attachment */
401  if (bedit && afile_name[0][0] == 0 && afile_name[1][0] == 0 && afile_name[2][0] == 0)
402  sprintf(message + strlen(message), "Attachment: %s", attachment);
403  else {
404  sprintf(message + strlen(message), "Attachment: %s", afile_name[0]);
405  if (afile_name[1][0])
406  sprintf(message + strlen(message), ",%s", afile_name[1]);
407  if (afile_name[2][0])
408  sprintf(message + strlen(message), ",%s", afile_name[2]);
409  }
410  sprintf(message + strlen(message), "\n");
411 
412  sprintf(message + strlen(message), "Encoding: %s\n", encoding);
413  sprintf(message + strlen(message), "========================================\n");
414  strcat(message, text);
415 
416  assert(strlen(message) < message_size); /* bomb out on array overrun. */
417 
418  size = 0;
419  sprintf(start_str, "$Start$: %6d\n", size);
420  sprintf(end_str, "$End$: %6d\n\f", size);
421 
422  size = strlen(message) + strlen(start_str) + strlen(end_str);
423 
424  if (tag != NULL && !bedit) {
425  sprintf(tag, "%02d%02d%02d.%d", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday, (int) TELL(fh));
426  }
427 
428  /* size has to fit in 6 digits */
429  assert(size < 999999);
430 
431  sprintf(start_str, "$Start$: %6d\n", size);
432  sprintf(end_str, "$End$: %6d\n\f", size);
433 
434  xwrite(file_name, fh, start_str, strlen(start_str));
435  xwrite(file_name, fh, message, strlen(message));
436  xwrite(file_name, fh, end_str, strlen(end_str));
437 
438  free(message);
439  message = NULL;
440  message_size = 0;
441 
442  if (bedit) {
443  if (tail_size > 0) {
444  xwrite(file_name, fh, buffer, tail_size);
445  M_FREE(buffer);
446  }
447 
448  /* truncate file here */
449 #ifdef OS_WINNT
450  chsize(fh, TELL(fh));
451 #else
452  xtruncate(file_name, fh);
453 #endif
454  }
455 
456  close(fh);
457 
458  /* if reply, mark original message */
459  if (reply_to[0] && !bedit) {
460  strcpy(last, reply_to);
461  do {
462  char filename[256];
463  status = el_search_message(last, &fh, FALSE, filename, sizeof(filename));
464  if (status == EL_SUCCESS) {
465  /* position to next thread location */
466  lseek(fh, 72, SEEK_CUR);
467  char str[256];
468  memset(str, 0, sizeof(str));
469  xread(filename, fh, str, 16);
470  lseek(fh, -16, SEEK_CUR);
471 
472  /* if no reply yet, set it */
473  if (atoi(str) == 0) {
474  sprintf(str, "%16s", tag);
475  xwrite(filename, fh, str, 16);
476  close(fh);
477  break;
478  } else {
479  /* if reply set, find last one in chain */
480  strcpy(last, strtok(str, " "));
481  close(fh);
482  }
483  } else
484  /* stop on error */
485  break;
486 
487  } while (TRUE);
488  }
489 
490  /* release elog semaphore */
491  ss_semaphore_release(semaphore);
492  }
493 #endif /* LOCAL_ROUTINES */
494 
495  return EL_SUCCESS;
496 }
#define SUCCESS
Definition: mcstd.h:54
#define TID_INT
Definition: midas.h:345
#define RPC_EL_SUBMIT
Definition: mrpc.h:111
bool rpc_is_remote(void)
Definition: midas.cxx:12728
INT rpc_call(DWORD routine_id,...)
Definition: midas.cxx:13630
INT run_number[2]
Definition: mana.cxx:246
DWORD n[4]
Definition: mana.cxx:247
DWORD BOOL
Definition: midas.h:105
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xread()

static int xread ( const char *  filename,
int  fd,
void *  data,
int  size 
)
static

Definition at line 78 of file elog.cxx.

79 {
80  int rd = read(fd, data, size);
81  if (rd == 0) {
82  // end of file
83  } else if (rd < 0) {
84  cm_msg(MERROR, "xread", "cannot read from \'%s\', read(%d) returned %d, errno %d (%s)", filename, size, rd, errno, strerror(errno));
85  } else if (rd != size) {
86  cm_msg(MERROR, "xread", "truncated read from \'%s\', read(%d) returned %d", filename, size, rd);
87  }
88  return rd;
89 }
void * data
Definition: mana.cxx:268
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xtruncate()

static void xtruncate ( const char *  filename,
int  fd 
)
static

Definition at line 91 of file elog.cxx.

92 {
93  int tr = ftruncate(fd, TELL(fd));
94  if (tr != 0) {
95  cm_msg(MERROR, "xtruncate", "cannot truncate \'%s\', ftruncate() returned %d, errno %d (%s)", filename, tr, errno, strerror(errno));
96  }
97 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xwrite()

static void xwrite ( const char *  filename,
int  fd,
const void *  data,
int  size 
)
static

Definition at line 70 of file elog.cxx.

71 {
72  int wr = write(fd, data, size);
73  if (wr != size) {
74  cm_msg(MERROR, "xwrite", "cannot write to \'%s\', write(%d) returned %d, errno %d (%s)", filename, size, wr, errno, strerror(errno));
75  }
76 }
#define write(n, a, f, d)
Definition: midas_macro.h:245
Here is the call graph for this function:
Here is the caller graph for this function: