MIDAS
Loading...
Searching...
No Matches
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:34
INT i
Definition mdump.cxx:32
#define message(type, str)
Here is the caller graph for this function:

◆ el_delete_message()

INT el_delete_message ( const char *  tag)

Definition at line 1018 of file elog.cxx.

1035{
1036#ifdef LOCAL_ROUTINES
1037 INT size, fh, semaphore, offset = 0, tail_size, status;
1038 char dir[256];
1039 char str[256];
1040 char file_name[256+256+10];
1041 HNDLE hDB;
1042 char *buffer = NULL;
1043
1045
1046 /* request semaphore */
1047 cm_get_experiment_semaphore(NULL, &semaphore, NULL, NULL);
1048 status = ss_semaphore_wait_for(semaphore, 5 * 60 * 1000);
1049 if (status != SS_SUCCESS) {
1050 cm_msg(MERROR, "el_delete_message",
1051 "Cannot lock experiment semaphore, ss_semaphore_wait_for() status %d", status);
1052 abort();
1053 }
1054
1055 /* generate file name YYMMDD.log in data directory */
1057
1058 size = sizeof(dir);
1059 memset(dir, 0, size);
1060 status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
1061 if (status != DB_SUCCESS)
1062 db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
1063
1064 if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
1065 strcat(dir, DIR_SEPARATOR_STR);
1066
1067 strcpy(str, tag);
1068 if (strchr(str, '.')) {
1069 offset = atoi(strchr(str, '.') + 1);
1070 *strchr(str, '.') = 0;
1071 }
1072 sprintf(file_name, "%s%s.log", dir, str);
1073 fh = open(file_name, O_CREAT | O_RDWR | O_BINARY, 0644);
1074 if (fh < 0) {
1075 ss_semaphore_release(semaphore);
1076 return EL_FILE_ERROR;
1077 }
1078 lseek(fh, offset, SEEK_SET);
1079 xread(file_name, fh, str, 16);
1080 size = atoi(str + 9);
1081
1082 /* buffer tail of logfile */
1083 lseek(fh, 0, SEEK_END);
1084 tail_size = TELL(fh) - (offset + size);
1085
1086 if (tail_size > 0) {
1087 buffer = (char *) M_MALLOC(tail_size);
1088 if (buffer == NULL) {
1089 close(fh);
1090 ss_semaphore_release(semaphore);
1091 return EL_FILE_ERROR;
1092 }
1093
1094 lseek(fh, offset + size, SEEK_SET);
1095 xread(file_name, fh, buffer, tail_size);
1096 }
1097 lseek(fh, offset, SEEK_SET);
1098
1099 if (tail_size > 0) {
1100 xwrite(file_name, fh, buffer, tail_size);
1101 M_FREE(buffer);
1102 }
1103
1104 /* truncate file here */
1105#ifdef OS_WINNT
1106 chsize(fh, TELL(fh));
1107#else
1108 xtruncate(file_name, fh);
1109#endif
1110
1111 /* if file length gets zero, delete file */
1112 tail_size = lseek(fh, 0, SEEK_END);
1113 close(fh);
1114
1115 if (tail_size == 0)
1117
1118 /* release elog semaphore */
1119 ss_semaphore_release(semaphore);
1120#endif /* LOCAL_ROUTINES */
1121
1122 return EL_SUCCESS;
1123}
#define FALSE
Definition cfortran.h:309
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3027
INT cm_get_experiment_semaphore(INT *semaphore_alarm, INT *semaphore_elog, INT *semaphore_history, INT *semaphore_msg)
Definition midas.cxx:3049
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:632
#define SS_SUCCESS
Definition midas.h:664
#define EL_SUCCESS
Definition midas.h:746
#define EL_FILE_ERROR
Definition midas.h:747
#define TID_STRING
Definition midas.h:346
#define MERROR
Definition midas.h:559
#define O_BINARY
Definition msystem.h:226
INT ss_semaphore_release(HNDLE semaphore_handle)
Definition system.cxx:2853
INT ss_semaphore_wait_for(HNDLE semaphore_handle, DWORD timeout_millisec)
Definition system.cxx:2711
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:931
#define TELL(fh)
Definition msystem.h:250
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5185
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:1551
#define DIR_SEPARATOR_STR
Definition midas.h:194
int INT
Definition midas.h:129
#define M_FREE(x)
Definition midas.h:1553
#define TRUE
Definition midas.h:182
static std::string remove(const std::string s, char c)
Definition mjsonrpc.cxx:253
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 774 of file elog.cxx.

808{
809 int size, fh = 0, search_status, rd;
810 char str[256], *p;
811 char thread[256];
812 char attachment_all[3*256+100]; /* size of attachement1/2/3 from show_elog_submit_query() */
813 char *message = NULL;
814 size_t message_size = 0;
815 char filename[256];
816
817 if (tag[0]) {
818 search_status = el_search_message(tag, &fh, TRUE, filename, sizeof(filename));
819 if (search_status != EL_SUCCESS)
820 return search_status;
821 } else {
822 /* open most recent message */
823 strcpy(tag, "-1");
824 search_status = el_search_message(tag, &fh, TRUE, filename, sizeof(filename));
825 if (search_status != EL_SUCCESS)
826 return search_status;
827 }
828
829 //printf("el_retrieve: reading [%s]\n", filename);
830
831 /* extract message size */
832 TELL(fh);
833 rd = xread(filename, fh, str, 15);
834 if (rd != 15)
835 return EL_FILE_ERROR;
836
837 /* make sure the input string is zero-terminated before we call atoi() */
838 str[15] = 0;
839
840 /* get size */
841 size = atoi(str + 9);
842
843 if ((strncmp(str, "$Start$:", 8) != 0) || (size <= 15)) {
844 cm_msg(MERROR, "el_retrieve", "cannot read from \'%s\', corrupted file: no $Start$ or bad size in \"%s\"", filename, str);
845 close(fh);
846 return EL_FILE_ERROR;
847 }
848
849 message_size = size + 1;
850 message = (char*)malloc(message_size);
851
852 if (!message) {
853 cm_msg(MERROR, "el_retrieve", "cannot read from \'%s\', cannot malloc() %d bytes, errno %d (%s)", filename, (int)message_size, errno, strerror(errno));
854 free(message);
855 close(fh);
856 return EL_FILE_ERROR;
857 }
858
859 memset(message, 0, message_size);
860
861 rd = read(fh, message, size);
862 if (rd <= 0 || !((rd + 15 == size) || (rd == size))) {
863 cm_msg(MERROR, "el_retrieve", "cannot read from \'%s\', read(%d) returned %d, errno %d (%s)", filename, size, rd, errno, strerror(errno));
864 free(message);
865 close(fh);
866 return EL_FILE_ERROR;
867 }
868
869 close(fh);
870
871 /* decode message */
872 if (strstr(message, "Run: ") && run)
873 *run = atoi(strstr(message, "Run: ") + 5);
874
875 el_decode(message, "Date: ", date, 80); /* size from show_elog_submit_query() */
876 el_decode(message, "Thread: ", thread, sizeof(thread));
877 el_decode(message, "Author: ", author, 80); /* size from show_elog_submit_query() */
878 el_decode(message, "Type: ", type, 80); /* size from show_elog_submit_query() */
879 el_decode(message, "System: ", syst, 80); /* size from show_elog_submit_query() */
880 el_decode(message, "Subject: ", subject, 256); /* size from show_elog_submit_query() */
881 el_decode(message, "Attachment: ", attachment_all, sizeof(attachment_all));
882 el_decode(message, "Encoding: ", encoding, 80); /* size from show_elog_submit_query() */
883
884 /* break apart attachements */
885 if (attachment1 && attachment2 && attachment3) {
886 attachment1[0] = attachment2[0] = attachment3[0] = 0;
887 p = strtok(attachment_all, ",");
888 if (p != NULL) {
889 mstrlcpy(attachment1, p, 256); /* size from show_elog_submit_query() */
890 p = strtok(NULL, ",");
891 if (p != NULL) {
892 mstrlcpy(attachment2, p, 256); /* size from show_elog_submit_query() */
893 p = strtok(NULL, ",");
894 if (p != NULL)
895 mstrlcpy(attachment3, p, 256); /* size from show_elog_submit_query() */
896 }
897 }
898 }
899
900 /* conver thread in reply-to and reply-from */
901 if (orig_tag != NULL && reply_tag != NULL) {
902 p = strtok(thread, " \r");
903 if (p != NULL)
904 strcpy(orig_tag, p);
905 else
906 strcpy(orig_tag, "");
907 p = strtok(NULL, " \r");
908 if (p != NULL)
909 strcpy(reply_tag, p);
910 else
911 strcpy(reply_tag, "");
912 if (atoi(orig_tag) == 0)
913 orig_tag[0] = 0;
914 if (atoi(reply_tag) == 0)
915 reply_tag[0] = 0;
916 }
917
918 p = strstr(message, "========================================\n");
919
920 if (text != NULL) {
921 if (p != NULL) {
922 p += 41;
923 if ((int) strlen(p) >= *textsize) {
924 strncpy(text, p, *textsize - 1);
925 text[*textsize - 1] = 0;
926 free(message);
927 return EL_TRUNCATED;
928 } else {
929 strcpy(text, p);
930
931 /* strip end tag */
932 if (strstr(text, "$End$"))
933 *strstr(text, "$End$") = 0;
934
935 *textsize = strlen(text);
936 }
937 } else {
938 text[0] = 0;
939 *textsize = 0;
940 }
941 }
942
943 free(message);
944 message = NULL;
945
946 if (search_status == EL_LAST_MSG)
947 return EL_LAST_MSG;
948
949 return EL_SUCCESS;
950}
double textsize
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:749
#define EL_LAST_MSG
Definition midas.h:751
INT type
Definition mana.cxx:269
#define read(n, a, f)
INT thread(void *p)
Definition odbedit.cxx:43
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 assert(tag != NULL);
513
514 ss_tzset(); // required by localtime_r()
515
516 if (xfilename && xfilename_size > 0)
517 *xfilename = 0;
518
519 /* open file */
521
522 size = sizeof(dir);
523 memset(dir, 0, size);
524 status = db_get_value(hDB, 0, "/Logger/Elog dir", dir, &size, TID_STRING, FALSE);
525 if (status != DB_SUCCESS)
526 db_get_value(hDB, 0, "/Logger/Data dir", dir, &size, TID_STRING, TRUE);
527
528 if (dir[0] != 0 && dir[strlen(dir) - 1] != DIR_SEPARATOR)
529 strcat(dir, DIR_SEPARATOR_STR);
530
531 /* check tag for direction */
532 direction = 0;
533 if (strpbrk(tag, "+-")) {
534 direction = atoi(strpbrk(tag, "+-"));
535 *strpbrk(tag, "+-") = 0;
536 }
537
538 /* if tag is given, open file directly */
539 if (tag[0]) {
540 /* extract time structure from tag */
541 memset(&tms, 0, sizeof(struct tm));
542 tms.tm_year = (tag[0] - '0') * 10 + (tag[1] - '0');
543 tms.tm_mon = (tag[2] - '0') * 10 + (tag[3] - '0') - 1;
544 tms.tm_mday = (tag[4] - '0') * 10 + (tag[5] - '0');
545 tms.tm_hour = 12;
546
547 if (tms.tm_year < 90)
548 tms.tm_year += 100;
549 ltime = lt = ss_mktime(&tms);
550
551 strcpy(str, tag);
552 if (strchr(str, '.')) {
553 offset = atoi(strchr(str, '.') + 1);
554 *strchr(str, '.') = 0;
555 } else
556 return EL_FILE_ERROR;
557
558 do {
559 localtime_r(&ltime, &tms);
560
561 sprintf(file_name, "%s%02d%02d%02d.log", dir, tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
562
563 if (xfilename)
564 mstrlcpy(xfilename, file_name, xfilename_size);
565
566 *fh = open(file_name, O_RDWR | O_BINARY, 0644);
567
568 if (*fh < 0) {
569 if (!walk)
570 return EL_FILE_ERROR;
571
572 if (direction == -1)
573 ltime -= 3600 * 24; /* one day back */
574 else
575 ltime += 3600 * 24; /* go forward one day */
576
577 /* set new tag */
578 localtime_r(&ltime, &tms);
579 sprintf(tag, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
580 }
581
582 /* in forward direction, stop today */
583 if (direction != -1 && ltime > time(NULL) + 3600 * 24)
584 break;
585
586 /* in backward direction, go back 10 years */
587 if (direction == -1 && abs((INT) lt - (INT) ltime) > 3600 * 24 * 365 * 10)
588 break;
589
590 } while (*fh < 0);
591
592 if (*fh < 0)
593 return EL_FILE_ERROR;
594
595 lseek(*fh, offset, SEEK_SET);
596
597 /* check if start of message */
598 i = xread(file_name, *fh, str, 15);
599 if (i <= 0) {
600 close(*fh);
601 return EL_FILE_ERROR;
602 }
603
604 if (strncmp(str, "$Start$: ", 9) != 0) {
605 close(*fh);
606 return EL_FILE_ERROR;
607 }
608
609 lseek(*fh, offset, SEEK_SET);
610 }
611
612 /* open most recent file if no tag given */
613 if (tag[0] == 0) {
614 time((time_t *) &lt);
615 ltime = lt;
616 do {
617 localtime_r(&ltime, &tms);
618
619 sprintf(file_name, "%s%02d%02d%02d.log", dir, tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
620
621 if (xfilename)
622 mstrlcpy(xfilename, file_name, xfilename_size);
623
624 *fh = open(file_name, O_RDWR | O_BINARY, 0644);
625
626 if (*fh < 0)
627 ltime -= 3600 * 24; /* one day back */
628
629 } while (*fh < 0 && (INT) lt - (INT) ltime < 3600 * 24 * 365);
630
631 if (*fh < 0)
632 return EL_FILE_ERROR;
633
634 /* remember tag */
635 sprintf(tag, "%02d%02d%02d", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
636
637 lseek(*fh, 0, SEEK_END);
638
639 sprintf(tag + strlen(tag), ".%d", (int) TELL(*fh));
640 }
641
642
643 if (direction == -1) {
644 /* seek previous message */
645
646 if (TELL(*fh) == 0) {
647 /* go back one day */
648 close(*fh);
649
650 lt = ltime;
651 do {
652 lt -= 3600 * 24;
653 localtime_r(&lt, &tms);
654 sprintf(str, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
655
657
658 if (xfilename)
659 mstrlcpy(xfilename, file_name, xfilename_size);
660
661 } while (status != EL_SUCCESS && (INT) ltime - (INT) lt < 3600 * 24 * 365);
662
663 if (status != EL_SUCCESS)
664 return EL_FIRST_MSG;
665
666 /* adjust tag */
667 strcpy(tag, str);
668
669 /* go to end of current file */
670 lseek(*fh, 0, SEEK_END);
671 }
672
673 /* read previous message size */
674 lseek(*fh, -17, SEEK_CUR);
675 i = xread(file_name, *fh, str, 17);
676 if (i <= 0) {
677 close(*fh);
678 return EL_FILE_ERROR;
679 }
680
681 if (strncmp(str, "$End$: ", 7) != 0) {
682 close(*fh);
683 return EL_FILE_ERROR;
684 }
685
686 /* make sure the input string to atoi() is zero-terminated:
687 * $End$: 355garbage
688 * 01234567890123456789 */
689 str[15] = 0;
690
691 size = atoi(str + 7);
692 if (size <= 15) {
693 close(*fh);
694 return EL_FILE_ERROR;
695 }
696
697 lseek(*fh, -size, SEEK_CUR);
698
699 /* adjust tag */
700 sprintf(strchr(tag, '.') + 1, "%d", (int) TELL(*fh));
701 }
702
703 if (direction == 1) {
704 /* seek next message */
705
706 /* read current message size */
707 TELL(*fh);
708
709 i = xread(file_name, *fh, str, 15);
710 if (i <= 0) {
711 close(*fh);
712 return EL_FILE_ERROR;
713 }
714 lseek(*fh, -15, SEEK_CUR);
715
716 if (strncmp(str, "$Start$: ", 9) != 0) {
717 close(*fh);
718 return EL_FILE_ERROR;
719 }
720
721 /* make sure the input string to atoi() is zero-terminated
722 * $Start$: 606garbage
723 * 01234567890123456789 */
724 str[15] = 0;
725
726 size = atoi(str + 9);
727
728 if (size <= 15) {
729 close(*fh);
730 return EL_FILE_ERROR;
731 }
732
733 lseek(*fh, size, SEEK_CUR);
734
735 /* if EOF, goto next day */
736 i = xread(file_name, *fh, str, 15);
737 if (i < 15) {
738 close(*fh);
739 time((time_t *) &lact);
740
741 lt = ltime;
742 do {
743 lt += 3600 * 24;
744 localtime_r(&lt, &tms);
745 sprintf(str, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
746
748
749 if (xfilename)
750 mstrlcpy(xfilename, file_name, xfilename_size);
751
752 } while (status != EL_SUCCESS && (INT) lt - (INT) lact < 3600 * 24);
753
754 if (status != EL_SUCCESS)
755 return EL_LAST_MSG;
756
757 /* adjust tag */
758 strcpy(tag, str);
759
760 /* go to beginning of current file */
761 lseek(*fh, 0, SEEK_SET);
762 } else
763 lseek(*fh, -15, SEEK_CUR);
764
765 /* adjust tag */
766 sprintf(strchr(tag, '.') + 1, "%d", (int) TELL(*fh));
767 }
768
769 return EL_SUCCESS;
770}
#define EL_FIRST_MSG
Definition midas.h:750
time_t ss_mktime(struct tm *tms)
Definition system.cxx:3437
void ss_tzset()
Definition system.cxx:3427
MUTEX_T * tm
Definition odbedit.cxx:39
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 954 of file elog.cxx.

972{
973 int actual_run=0, fh, status;
974 char tag[256];
975
976 tag[0] = return_tag[0] = 0;
977
978 do {
979 /* open first message in file */
980 strcat(tag, "-1");
981 status = el_search_message(tag, &fh, TRUE, NULL, 0);
982 if (status == EL_FIRST_MSG)
983 break;
984 if (status != EL_SUCCESS)
985 return status;
986 close(fh);
987
988 if (strchr(tag, '.') != NULL)
989 strcpy(strchr(tag, '.'), ".0");
990
991 el_retrieve(tag, NULL, &actual_run, NULL, NULL,
992 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
993 } while (actual_run >= run);
994
995 while (actual_run < run) {
996 strcat(tag, "+1");
997 status = el_search_message(tag, &fh, TRUE, NULL, 0);
998 if (status == EL_LAST_MSG)
999 break;
1000 if (status != EL_SUCCESS)
1001 return status;
1002 close(fh);
1003
1004 el_retrieve(tag, NULL, &actual_run, NULL, NULL,
1005 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1006 }
1007
1008 strcpy(return_tag, tag);
1009
1011 return status;
1012
1013 return EL_SUCCESS;
1014}
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:774
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 mstrlcpy(afilename, afilename1, sizeof(afilename));
190 buffer = buffer1;
191 buffer_size = buffer_size1;
192 } else if (idx == 1) {
193 mstrlcpy(afilename, afilename2, sizeof(afilename));
194 buffer = buffer2;
195 buffer_size = buffer_size2;
196 } else if (idx == 2) {
197 mstrlcpy(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 mstrlcpy(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 mstrlcpy(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:338
#define RPC_EL_SUBMIT
Definition mrpc.h:112
bool rpc_is_remote(void)
Definition midas.cxx:12892
INT rpc_call(DWORD routine_id,...)
Definition midas.cxx:14115
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)
Here is the call graph for this function:
Here is the caller graph for this function: