00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "midas.h"
00013 #include "msystem.h"
00014 #include "strlcpy.h"
00015 #include <assert.h>
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #if !defined(OS_VXWORKS)
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00034
00035 static HISTORY *_history;
00036 static INT _history_entries = 0;
00037 static char _hs_path_name[MAX_STRING_LENGTH];
00038
00039
00040 #endif
00041
00042
00043
00044
00045
00046
00047
00048
00049 INT hs_set_path(char *path)
00050 {
00051
00052 if (rpc_is_remote())
00053 rpc_call(RPC_HS_SET_PATH, path);
00054
00055 strcpy(_hs_path_name, path);
00056
00057
00058 if (strlen(_hs_path_name) > 0 && _hs_path_name[strlen(_hs_path_name) - 1] != DIR_SEPARATOR)
00059 strcat(_hs_path_name, DIR_SEPARATOR_STR);
00060
00061 return HS_SUCCESS;
00062 }
00063
00064
00065 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 INT hs_open_file(time_t ltime, char *suffix, INT mode, int *fh)
00079 {
00080 struct tm *tms;
00081 char file_name[256];
00082 time_t ttime;
00083
00084
00085 #if !defined(OS_VXWORKS)
00086 #if !defined(OS_VMS)
00087 tzset();
00088 #endif
00089 #endif
00090 ttime = (time_t) ltime;
00091 tms = localtime(&ttime);
00092
00093 sprintf(file_name, "%s%02d%02d%02d.%s", _hs_path_name,
00094 tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday, suffix);
00095
00096
00097 *fh = open(file_name, mode | O_BINARY, 0644);
00098
00099
00100
00101 return HS_SUCCESS;
00102 }
00103
00104
00105 INT hs_gen_index(DWORD ltime)
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 {
00126 char event_name[NAME_LENGTH];
00127 int fh, fhd, fhi;
00128 INT n;
00129 HIST_RECORD rec;
00130 INDEX_RECORD irec;
00131 DEF_RECORD def_rec;
00132 int recovering = 0;
00133
00134
00135 cm_msg(MINFO, "hs_gen_index", "generating index files for time %d", (int)ltime);
00136 printf("Recovering index files...\n");
00137
00138 if (ltime == 0)
00139 ltime = (DWORD) time(NULL);
00140
00141
00142 hs_open_file(ltime, "idx", O_RDWR | O_CREAT | O_TRUNC, &fhi);
00143 hs_open_file(ltime, "idf", O_RDWR | O_CREAT | O_TRUNC, &fhd);
00144
00145 if (fhd < 0 || fhi < 0) {
00146 cm_msg(MERROR, "hs_gen_index", "cannot create index file");
00147 return HS_FILE_ERROR;
00148 }
00149
00150
00151 hs_open_file(ltime, "hst", O_RDONLY, &fh);
00152 if (fh < 0)
00153 return HS_FILE_ERROR;
00154 lseek(fh, 0, SEEK_SET);
00155
00156
00157 do {
00158 n = read(fh, (char *) &rec, sizeof(rec));
00159
00160 if (n < sizeof(rec))
00161 break;
00162
00163
00164 if (rec.record_type == RT_DEF) {
00165
00166 read(fh, event_name, sizeof(event_name));
00167
00168 printf("Event definition %s, ID %d\n", event_name, rec.event_id);
00169
00170
00171 def_rec.event_id = rec.event_id;
00172 memcpy(def_rec.event_name, event_name, sizeof(event_name));
00173 def_rec.def_offset = TELL(fh) - sizeof(event_name) - sizeof(rec);
00174 write(fhd, (char *) &def_rec, sizeof(def_rec));
00175
00176
00177
00178
00179 lseek(fh, rec.data_size, SEEK_CUR);
00180 } else if (rec.record_type == RT_DATA && rec.data_size>1 && rec.data_size<1*1024*1024) {
00181
00182 irec.event_id = rec.event_id;
00183 irec.time = rec.time;
00184 irec.offset = TELL(fh) - sizeof(rec);
00185 write(fhi, (char *) &irec, sizeof(irec));
00186
00187
00188
00189
00190 lseek(fh, rec.data_size, SEEK_CUR);
00191 } else {
00192 if (!recovering)
00193 cm_msg(MERROR, "hs_gen_index", "broken history file for time %d, trying to recover", (int)ltime);
00194
00195 recovering = 1;
00196 lseek(fh, 1-sizeof(rec), SEEK_CUR);
00197
00198 continue;
00199 }
00200
00201 } while (TRUE);
00202
00203 close(fh);
00204 close(fhi);
00205 close(fhd);
00206
00207 printf("...done.\n");
00208
00209 return HS_SUCCESS;
00210 }
00211
00212
00213
00214 INT hs_search_file(DWORD * ltime, INT direction)
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 {
00236 time_t lt;
00237 int fh, fhd, fhi;
00238 struct tm *tms;
00239
00240 if (*ltime == 0)
00241 *ltime = ss_time();
00242
00243 lt = (time_t) * ltime;
00244 do {
00245
00246 hs_open_file(lt, "hst", O_RDONLY, &fh);
00247
00248
00249 if (fh < 0)
00250 lt += direction * 3600 * 24;
00251
00252
00253 } while (fh < 0 && (INT) * ltime - (INT) lt < 3600 * 24 * 365 && lt <= (time_t) ss_time());
00254
00255 if (fh < 0)
00256 return HS_FILE_ERROR;
00257
00258 if (lt != *ltime) {
00259
00260 tms = localtime(<);
00261 tms->tm_hour = tms->tm_min = tms->tm_sec = 0;
00262 *ltime = (DWORD) mktime(tms);
00263 }
00264
00265
00266 hs_open_file(*ltime, "idf", O_RDONLY, &fhd);
00267 hs_open_file(*ltime, "idx", O_RDONLY, &fhi);
00268
00269 close(fh);
00270 close(fhd);
00271 close(fhi);
00272
00273
00274 if (fhd < 0 || fhi < 0)
00275 hs_gen_index(*ltime);
00276
00277 return HS_SUCCESS;
00278 }
00279
00280
00281
00282 INT hs_define_event(DWORD event_id, char *name, TAG * tag, DWORD size)
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 {
00314
00315
00316
00317
00318
00319 {
00320 HIST_RECORD rec, prev_rec;
00321 DEF_RECORD def_rec;
00322 time_t ltime;
00323 char str[256], event_name[NAME_LENGTH], *buffer;
00324 int fh, fhi, fhd;
00325 INT i, n, len, index, status, mutex;
00326 struct tm *tmb;
00327
00328
00329 cm_get_experiment_mutex(NULL, NULL, &mutex, NULL);
00330 status = ss_mutex_wait_for(mutex, 5 * 1000);
00331 if (status != SS_SUCCESS)
00332 return SUCCESS;
00333
00334
00335 if (_history_entries == 0) {
00336 _history = (HISTORY *) M_MALLOC(sizeof(HISTORY));
00337 memset(_history, 0, sizeof(HISTORY));
00338 if (_history == NULL) {
00339 ss_mutex_release(mutex);
00340 return HS_NO_MEMORY;
00341 }
00342
00343 _history_entries = 1;
00344 index = 0;
00345 } else {
00346
00347 for (i = 0; i < _history_entries; i++)
00348 if (_history[i].event_id == event_id)
00349 break;
00350
00351
00352 if (i == _history_entries) {
00353 _history = (HISTORY *) realloc(_history, sizeof(HISTORY) * (_history_entries + 1));
00354 memset(&_history[_history_entries], 0, sizeof(HISTORY));
00355
00356 _history_entries++;
00357 if (_history == NULL) {
00358 _history_entries--;
00359 ss_mutex_release(mutex);
00360 return HS_NO_MEMORY;
00361 }
00362 }
00363 index = i;
00364 }
00365
00366
00367 rec.record_type = RT_DEF;
00368 rec.event_id = event_id;
00369 rec.time = (DWORD) time(NULL);
00370 rec.data_size = size;
00371 strncpy(event_name, name, NAME_LENGTH);
00372
00373
00374 for (i = 0; (DWORD) i < size / sizeof(TAG); i++) {
00375 len = strlen(tag[i].name);
00376 memset(tag[i].name + len, 0, NAME_LENGTH - len);
00377 }
00378
00379
00380 if (!_history[index].hist_fh) {
00381
00382 hs_open_file(rec.time, "hst", O_CREAT | O_RDWR, &fh);
00383 if (fh < 0) {
00384 ss_mutex_release(mutex);
00385 return HS_FILE_ERROR;
00386 }
00387
00388
00389 hs_open_file(rec.time, "idf", O_CREAT | O_RDWR, &fhd);
00390 hs_open_file(rec.time, "idx", O_CREAT | O_RDWR, &fhi);
00391 lseek(fh, 0, SEEK_END);
00392 lseek(fhi, 0, SEEK_END);
00393 lseek(fhd, 0, SEEK_END);
00394
00395
00396 if (TELL(fh) > 0 && TELL(fhd) == 0) {
00397 close(fh);
00398 close(fhi);
00399 close(fhd);
00400 hs_gen_index(rec.time);
00401 hs_open_file(rec.time, "hst", O_RDWR, &fh);
00402 hs_open_file(rec.time, "idx", O_RDWR, &fhi);
00403 hs_open_file(rec.time, "idf", O_RDWR, &fhd);
00404 lseek(fh, 0, SEEK_END);
00405 lseek(fhi, 0, SEEK_END);
00406 lseek(fhd, 0, SEEK_END);
00407 }
00408
00409 ltime = (time_t) rec.time;
00410 tmb = localtime(<ime);
00411 tmb->tm_hour = tmb->tm_min = tmb->tm_sec = 0;
00412
00413
00414 _history[index].hist_fh = fh;
00415 _history[index].index_fh = fhi;
00416 _history[index].def_fh = fhd;
00417 _history[index].def_offset = TELL(fh);
00418 _history[index].event_id = event_id;
00419 strcpy(_history[index].event_name, event_name);
00420 _history[index].base_time = (DWORD) mktime(tmb);
00421 _history[index].n_tag = size / sizeof(TAG);
00422 _history[index].tag = (TAG *) M_MALLOC(size);
00423 memcpy(_history[index].tag, tag, size);
00424
00425
00426 n = TELL(fhd) / sizeof(def_rec);
00427 def_rec.event_id = 0;
00428 for (i = n - 1; i >= 0; i--) {
00429 lseek(fhd, i * sizeof(def_rec), SEEK_SET);
00430 read(fhd, (char *) &def_rec, sizeof(def_rec));
00431 if (def_rec.event_id == event_id)
00432 break;
00433 }
00434 lseek(fhd, 0, SEEK_END);
00435
00436
00437 if (def_rec.event_id == event_id) {
00438 buffer = (char *) M_MALLOC(size);
00439 memset(buffer, 0, size);
00440
00441 lseek(fh, def_rec.def_offset, SEEK_SET);
00442 read(fh, (char *) &prev_rec, sizeof(prev_rec));
00443 read(fh, str, NAME_LENGTH);
00444 read(fh, buffer, size);
00445 lseek(fh, 0, SEEK_END);
00446
00447 if (prev_rec.data_size != size || strcmp(str, event_name) != 0 || memcmp(buffer, tag, size) != 0) {
00448
00449 write(fh, (char *) &rec, sizeof(rec));
00450 write(fh, event_name, NAME_LENGTH);
00451 write(fh, (char *) tag, size);
00452
00453
00454 def_rec.event_id = event_id;
00455 memcpy(def_rec.event_name, event_name, sizeof(event_name));
00456 def_rec.def_offset = _history[index].def_offset;
00457 write(fhd, (char *) &def_rec, sizeof(def_rec));
00458 } else
00459
00460 _history[index].def_offset = def_rec.def_offset;
00461
00462 M_FREE(buffer);
00463 } else {
00464
00465 write(fh, (char *) &rec, sizeof(rec));
00466 write(fh, event_name, NAME_LENGTH);
00467 write(fh, (char *) tag, size);
00468
00469
00470 def_rec.event_id = event_id;
00471 memcpy(def_rec.event_name, event_name, sizeof(event_name));
00472 def_rec.def_offset = _history[index].def_offset;
00473 write(fhd, (char *) &def_rec, sizeof(def_rec));
00474 }
00475 } else {
00476 fh = _history[index].hist_fh;
00477 fhd = _history[index].def_fh;
00478
00479
00480 buffer = (char *) M_MALLOC(size);
00481 memset(buffer, 0, size);
00482
00483 lseek(fh, _history[index].def_offset, SEEK_SET);
00484 read(fh, (char *) &prev_rec, sizeof(prev_rec));
00485 read(fh, str, NAME_LENGTH);
00486 read(fh, buffer, size);
00487
00488 lseek(fh, 0, SEEK_END);
00489 lseek(fhd, 0, SEEK_END);
00490
00491 if (prev_rec.data_size != size || strcmp(str, event_name) != 0 || memcmp(buffer, tag, size) != 0) {
00492
00493 _history[index].def_offset = TELL(fh);
00494
00495
00496 write(fh, (char *) &rec, sizeof(rec));
00497 write(fh, event_name, NAME_LENGTH);
00498 write(fh, (char *) tag, size);
00499
00500
00501 def_rec.event_id = event_id;
00502 memcpy(def_rec.event_name, event_name, sizeof(event_name));
00503 def_rec.def_offset = _history[index].def_offset;
00504 write(fhd, (char *) &def_rec, sizeof(def_rec));
00505 }
00506
00507 M_FREE(buffer);
00508 }
00509
00510 ss_mutex_release(mutex);
00511 }
00512
00513 return HS_SUCCESS;
00514 }
00515
00516
00517
00518 INT hs_write_event(DWORD event_id, void *data, DWORD size)
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 {
00542
00543
00544
00545
00546
00547 HIST_RECORD rec, drec;
00548 DEF_RECORD def_rec;
00549 INDEX_RECORD irec;
00550 int fh, fhi, fhd, last_pos_data, last_pos_index;
00551 INT index, mutex, status;
00552 struct tm tmb, tmr;
00553 time_t ltime;
00554
00555
00556 cm_get_experiment_mutex(NULL, NULL, &mutex, NULL);
00557 status = ss_mutex_wait_for(mutex, 5 * 1000);
00558 if (status != SS_SUCCESS) {
00559 cm_msg(MERROR, "hs_write_event", "mutex timeout");
00560 return SUCCESS;
00561 }
00562
00563
00564 for (index = 0; index < _history_entries; index++)
00565 if (_history[index].event_id == event_id)
00566 break;
00567 if (index == _history_entries) {
00568 ss_mutex_release(mutex);
00569 return HS_UNDEFINED_EVENT;
00570 }
00571
00572
00573 rec.record_type = RT_DATA;
00574 rec.event_id = _history[index].event_id;
00575 rec.time = (DWORD) time(NULL);
00576 rec.def_offset = _history[index].def_offset;
00577 rec.data_size = size;
00578
00579 irec.event_id = _history[index].event_id;
00580 irec.time = rec.time;
00581
00582
00583 ltime = (time_t) rec.time;
00584 memcpy(&tmr, localtime(<ime), sizeof(tmr));
00585 ltime = (time_t) _history[index].base_time;
00586 memcpy(&tmb, localtime(<ime), sizeof(tmb));
00587
00588 if (tmr.tm_yday != tmb.tm_yday) {
00589
00590 close(_history[index].hist_fh);
00591 close(_history[index].def_fh);
00592 close(_history[index].index_fh);
00593
00594
00595 hs_open_file(rec.time, "hst", O_CREAT | O_RDWR, &fh);
00596 if (fh < 0) {
00597 ss_mutex_release(mutex);
00598 return HS_FILE_ERROR;
00599 }
00600
00601
00602 hs_open_file(rec.time, "idx", O_CREAT | O_RDWR, &fhi);
00603 if (fhi < 0) {
00604 ss_mutex_release(mutex);
00605 return HS_FILE_ERROR;
00606 }
00607
00608
00609 hs_open_file(rec.time, "idf", O_CREAT | O_RDWR, &fhd);
00610 if (fhd < 0) {
00611 ss_mutex_release(mutex);
00612 return HS_FILE_ERROR;
00613 }
00614
00615 lseek(fh, 0, SEEK_END);
00616 lseek(fhi, 0, SEEK_END);
00617 lseek(fhd, 0, SEEK_END);
00618
00619
00620 _history[index].hist_fh = fh;
00621 _history[index].index_fh = fhi;
00622 _history[index].def_fh = fhd;
00623
00624 _history[index].def_offset = TELL(fh);
00625 rec.def_offset = _history[index].def_offset;
00626
00627 tmr.tm_hour = tmr.tm_min = tmr.tm_sec = 0;
00628 _history[index].base_time = (DWORD) mktime(&tmr);
00629
00630
00631 drec.record_type = RT_DEF;
00632 drec.event_id = _history[index].event_id;
00633 drec.time = rec.time;
00634 drec.data_size = _history[index].n_tag * sizeof(TAG);
00635
00636 write(fh, (char *) &drec, sizeof(drec));
00637 write(fh, _history[index].event_name, NAME_LENGTH);
00638 write(fh, (char *) _history[index].tag, drec.data_size);
00639
00640
00641 def_rec.event_id = _history[index].event_id;
00642 memcpy(def_rec.event_name, _history[index].event_name, sizeof(def_rec.event_name));
00643 def_rec.def_offset = _history[index].def_offset;
00644 write(fhd, (char *) &def_rec, sizeof(def_rec));
00645 }
00646
00647
00648 lseek(_history[index].hist_fh, 0, SEEK_END);
00649 last_pos_data = irec.offset = TELL(_history[index].hist_fh);
00650
00651
00652 write(_history[index].hist_fh, (char *) &rec, sizeof(rec));
00653
00654
00655 if (write(_history[index].hist_fh, (char *) data, size) < (int)size) {
00656
00657 lseek(_history[index].hist_fh, last_pos_data, SEEK_SET);
00658 TRUNCATE(_history[index].hist_fh);
00659 ss_mutex_release(mutex);
00660 return HS_FILE_ERROR;
00661 }
00662
00663
00664 lseek(_history[index].index_fh, 0, SEEK_END);
00665 last_pos_index = TELL(_history[index].index_fh);
00666 if (write(_history[index].index_fh, (char *) &irec, sizeof(irec)) < sizeof(irec)) {
00667
00668 lseek(_history[index].hist_fh, last_pos_data, SEEK_SET);
00669 TRUNCATE(_history[index].hist_fh);
00670 lseek(_history[index].index_fh, last_pos_index, SEEK_SET);
00671 TRUNCATE(_history[index].index_fh);
00672 ss_mutex_release(mutex);
00673 return HS_FILE_ERROR;
00674 }
00675
00676 ss_mutex_release(mutex);
00677 return HS_SUCCESS;
00678 }
00679
00680
00681
00682 INT hs_enum_events(DWORD ltime, char *event_name, DWORD * name_size, INT event_id[], DWORD * id_size)
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 {
00705 int fh, fhd;
00706 INT status, i, j, n;
00707 DEF_RECORD def_rec;
00708
00709 if (rpc_is_remote())
00710 return rpc_call(RPC_HS_ENUM_EVENTS, ltime, event_name, name_size, event_id, id_size);
00711
00712
00713 status = hs_search_file(<ime, -1);
00714 if (status != HS_SUCCESS) {
00715 cm_msg(MERROR, "hs_enum_events", "cannot find recent history file");
00716 return HS_FILE_ERROR;
00717 }
00718
00719
00720 hs_open_file(ltime, "hst", O_RDONLY, &fh);
00721 hs_open_file(ltime, "idf", O_RDONLY, &fhd);
00722 if (fh < 0 || fhd < 0) {
00723 cm_msg(MERROR, "hs_enum_events", "cannot open index files");
00724 return HS_FILE_ERROR;
00725 }
00726 lseek(fhd, 0, SEEK_SET);
00727
00728
00729 n = 0;
00730 do {
00731
00732 j = read(fhd, (char *) &def_rec, sizeof(def_rec));
00733 if (j < (int) sizeof(def_rec))
00734 break;
00735
00736
00737 for (i = 0; i < n; i++)
00738 if (event_id[i] == (INT) def_rec.event_id) {
00739 strcpy(event_name + i * NAME_LENGTH, def_rec.event_name);
00740 break;
00741 }
00742
00743
00744 if (i == n) {
00745 if (i * NAME_LENGTH > (INT) * name_size || i * sizeof(INT) > (INT) * id_size) {
00746 cm_msg(MERROR, "hs_enum_events", "index buffer too small");
00747 close(fh);
00748 close(fhd);
00749 return HS_NO_MEMORY;
00750 }
00751
00752
00753 strcpy(event_name + i * NAME_LENGTH, def_rec.event_name);
00754 event_id[i] = def_rec.event_id;
00755 n++;
00756 }
00757 } while (TRUE);
00758
00759 close(fh);
00760 close(fhd);
00761 *name_size = n * NAME_LENGTH;
00762 *id_size = n * sizeof(INT);
00763
00764 return HS_SUCCESS;
00765 }
00766
00767
00768
00769 INT hs_count_events(DWORD ltime, DWORD * count)
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 {
00788 int fh, fhd;
00789 INT status, i, j, n;
00790 DWORD *id;
00791 DEF_RECORD def_rec;
00792
00793 if (rpc_is_remote())
00794 return rpc_call(RPC_HS_COUNT_EVENTS, ltime, count);
00795
00796
00797 status = hs_search_file(<ime, -1);
00798 if (status != HS_SUCCESS) {
00799 cm_msg(MERROR, "hs_count_events", "cannot find recent history file");
00800 return HS_FILE_ERROR;
00801 }
00802
00803
00804 hs_open_file(ltime, "hst", O_RDONLY, &fh);
00805 hs_open_file(ltime, "idf", O_RDONLY, &fhd);
00806 if (fh < 0 || fhd < 0) {
00807 cm_msg(MERROR, "hs_count_events", "cannot open index files");
00808 return HS_FILE_ERROR;
00809 }
00810
00811
00812 lseek(fhd, 0, SEEK_END);
00813 id = (DWORD *) M_MALLOC(TELL(fhd) / sizeof(def_rec) * sizeof(DWORD));
00814 lseek(fhd, 0, SEEK_SET);
00815
00816
00817 n = 0;
00818 do {
00819
00820 j = read(fhd, (char *) &def_rec, sizeof(def_rec));
00821 if (j < (int) sizeof(def_rec))
00822 break;
00823
00824
00825 for (i = 0; i < n; i++)
00826 if (id[i] == def_rec.event_id)
00827 break;
00828
00829
00830 if (i == n) {
00831 id[i] = def_rec.event_id;
00832 n++;
00833 }
00834 } while (TRUE);
00835
00836
00837 M_FREE(id);
00838 close(fh);
00839 close(fhd);
00840 *count = n;
00841
00842 return HS_SUCCESS;
00843 }
00844
00845
00846
00847 INT hs_get_event_id(DWORD ltime, char *name, DWORD * id)
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 {
00868 int fh, fhd;
00869 INT status, i;
00870 DWORD lt;
00871 DEF_RECORD def_rec;
00872
00873 if (rpc_is_remote())
00874 return rpc_call(RPC_HS_GET_EVENT_ID, ltime, name, id);
00875
00876
00877 if (ltime == 0)
00878 ltime = (DWORD) time(NULL);
00879
00880 lt = ltime;
00881
00882 do {
00883 status = hs_search_file(<, -1);
00884 if (status != HS_SUCCESS) {
00885 cm_msg(MERROR, "hs_count_events", "cannot find recent history file");
00886 return HS_FILE_ERROR;
00887 }
00888
00889
00890 hs_open_file(lt, "hst", O_RDONLY, &fh);
00891 hs_open_file(lt, "idf", O_RDONLY, &fhd);
00892 if (fh < 0 || fhd < 0) {
00893 cm_msg(MERROR, "hs_count_events", "cannot open index files");
00894 return HS_FILE_ERROR;
00895 }
00896
00897
00898 *id = 0;
00899 do {
00900
00901 i = read(fhd, (char *) &def_rec, sizeof(def_rec));
00902 if (i < (int) sizeof(def_rec))
00903 break;
00904
00905 if (strcmp(name, def_rec.event_name) == 0) {
00906 *id = def_rec.event_id;
00907 close(fh);
00908 close(fhd);
00909 return HS_SUCCESS;
00910 }
00911 } while (TRUE);
00912
00913 close(fh);
00914 close(fhd);
00915
00916
00917 lt -= 3600 * 24;
00918
00919 } while (lt > ltime - 3600 * 24 * 365 * 10);
00920
00921 return HS_UNDEFINED_EVENT;
00922 }
00923
00924
00925
00926 INT hs_count_vars(DWORD ltime, DWORD event_id, DWORD * count)
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 {
00945 int fh, fhd;
00946 INT i, n, status;
00947 DEF_RECORD def_rec;
00948 HIST_RECORD rec;
00949
00950 if (rpc_is_remote())
00951 return rpc_call(RPC_HS_COUNT_VARS, ltime, event_id, count);
00952
00953
00954 status = hs_search_file(<ime, -1);
00955 if (status != HS_SUCCESS) {
00956 cm_msg(MERROR, "hs_count_tags", "cannot find recent history file");
00957 return HS_FILE_ERROR;
00958 }
00959
00960
00961 hs_open_file(ltime, "hst", O_RDONLY, &fh);
00962 hs_open_file(ltime, "idf", O_RDONLY, &fhd);
00963 if (fh < 0 || fhd < 0) {
00964 cm_msg(MERROR, "hs_count_tags", "cannot open index files");
00965 return HS_FILE_ERROR;
00966 }
00967
00968
00969 lseek(fhd, 0, SEEK_END);
00970 n = TELL(fhd) / sizeof(def_rec);
00971 def_rec.event_id = 0;
00972 for (i = n - 1; i >= 0; i--) {
00973 lseek(fhd, i * sizeof(def_rec), SEEK_SET);
00974 read(fhd, (char *) &def_rec, sizeof(def_rec));
00975 if (def_rec.event_id == event_id)
00976 break;
00977 }
00978 if (def_rec.event_id != event_id) {
00979 cm_msg(MERROR, "hs_count_tags", "event %d not found in index file", event_id);
00980 return HS_FILE_ERROR;
00981 }
00982
00983
00984 lseek(fh, def_rec.def_offset, SEEK_SET);
00985 read(fh, (char *) &rec, sizeof(rec));
00986 *count = rec.data_size / sizeof(TAG);
00987
00988 close(fh);
00989 close(fhd);
00990
00991 return HS_SUCCESS;
00992 }
00993
00994
00995
00996 INT hs_enum_vars(DWORD ltime, DWORD event_id, char *var_name, DWORD * size, DWORD * var_n, DWORD * n_size)
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019 {
01020 char str[256];
01021 int fh, fhd;
01022 INT i, n, status;
01023 DEF_RECORD def_rec;
01024 HIST_RECORD rec;
01025 TAG *tag;
01026
01027 if (rpc_is_remote())
01028 return rpc_call(RPC_HS_ENUM_VARS, ltime, event_id, var_name, size);
01029
01030
01031 status = hs_search_file(<ime, -1);
01032 if (status != HS_SUCCESS) {
01033 cm_msg(MERROR, "hs_enum_vars", "cannot find recent history file");
01034 return HS_FILE_ERROR;
01035 }
01036
01037
01038 hs_open_file(ltime, "hst", O_RDONLY, &fh);
01039 hs_open_file(ltime, "idf", O_RDONLY, &fhd);
01040 if (fh < 0 || fhd < 0) {
01041 cm_msg(MERROR, "hs_enum_vars", "cannot open index files");
01042 return HS_FILE_ERROR;
01043 }
01044
01045
01046 lseek(fhd, 0, SEEK_END);
01047 n = TELL(fhd) / sizeof(def_rec);
01048 def_rec.event_id = 0;
01049 for (i = n - 1; i >= 0; i--) {
01050 lseek(fhd, i * sizeof(def_rec), SEEK_SET);
01051 read(fhd, (char *) &def_rec, sizeof(def_rec));
01052 if (def_rec.event_id == event_id)
01053 break;
01054 }
01055 if (def_rec.event_id != event_id) {
01056 cm_msg(MERROR, "hs_enum_vars", "event %d not found in index file", event_id);
01057 return HS_FILE_ERROR;
01058 }
01059
01060
01061 lseek(fh, def_rec.def_offset, SEEK_SET);
01062 read(fh, (char *) &rec, sizeof(rec));
01063 read(fh, str, NAME_LENGTH);
01064
01065
01066 n = rec.data_size / sizeof(TAG);
01067 tag = (TAG *) M_MALLOC(rec.data_size);
01068 read(fh, (char *) tag, rec.data_size);
01069
01070 if (n * NAME_LENGTH > (INT) * size || n * sizeof(DWORD) > *n_size) {
01071
01072
01073 for (i = 0; i < (INT) * size / NAME_LENGTH; i++) {
01074 strcpy(var_name + i * NAME_LENGTH, tag[i].name);
01075 var_n[i] = tag[i].n_data;
01076 }
01077
01078 cm_msg(MERROR, "hs_enum_vars", "tag buffer too small");
01079 M_FREE(tag);
01080 close(fh);
01081 close(fhd);
01082 return HS_NO_MEMORY;
01083 }
01084
01085
01086 for (i = 0; i < n; i++) {
01087 strcpy(var_name + i * NAME_LENGTH, tag[i].name);
01088 var_n[i] = tag[i].n_data;
01089 }
01090 *size = n * NAME_LENGTH;
01091 *n_size = n * sizeof(DWORD);
01092
01093 M_FREE(tag);
01094 close(fh);
01095 close(fhd);
01096
01097 return HS_SUCCESS;
01098 }
01099
01100
01101
01102 INT hs_get_var(DWORD ltime, DWORD event_id, char *var_name, DWORD * type, INT * n_data)
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125 {
01126 char str[256];
01127 int fh, fhd;
01128 INT i, n, status;
01129 DEF_RECORD def_rec;
01130 HIST_RECORD rec;
01131 TAG *tag;
01132
01133 if (rpc_is_remote())
01134 return rpc_call(RPC_HS_GET_VAR, ltime, event_id, var_name, type, n_data);
01135
01136
01137 status = hs_search_file(<ime, -1);
01138 if (status != HS_SUCCESS) {
01139 cm_msg(MERROR, "hs_get_var", "cannot find recent history file");
01140 return HS_FILE_ERROR;
01141 }
01142
01143
01144 hs_open_file(ltime, "hst", O_RDONLY, &fh);
01145 hs_open_file(ltime, "idf", O_RDONLY, &fhd);
01146 if (fh < 0 || fhd < 0) {
01147 cm_msg(MERROR, "hs_get_var", "cannot open index files");
01148 return HS_FILE_ERROR;
01149 }
01150
01151
01152 lseek(fhd, 0, SEEK_END);
01153 n = TELL(fhd) / sizeof(def_rec);
01154 def_rec.event_id = 0;
01155 for (i = n - 1; i >= 0; i--) {
01156 lseek(fhd, i * sizeof(def_rec), SEEK_SET);
01157 read(fhd, (char *) &def_rec, sizeof(def_rec));
01158 if (def_rec.event_id == event_id)
01159 break;
01160 }
01161 if (def_rec.event_id != event_id) {
01162 cm_msg(MERROR, "hs_get_var", "event %d not found in index file", event_id);
01163 return HS_FILE_ERROR;
01164 }
01165
01166
01167 lseek(fh, def_rec.def_offset, SEEK_SET);
01168 read(fh, (char *) &rec, sizeof(rec));
01169 read(fh, str, NAME_LENGTH);
01170
01171
01172 n = rec.data_size / sizeof(TAG);
01173 tag = (TAG *) M_MALLOC(rec.data_size);
01174 read(fh, (char *) tag, rec.data_size);
01175
01176
01177 for (i = 0; i < n; i++)
01178 if (strcmp(tag[i].name, var_name) == 0)
01179 break;
01180
01181 close(fh);
01182 close(fhd);
01183
01184 if (i < n) {
01185 *type = tag[i].type;
01186 *n_data = tag[i].n_data;
01187 } else {
01188 *type = *n_data = 0;
01189 cm_msg(MERROR, "hs_get_var", "variable %s not found", var_name);
01190 M_FREE(tag);
01191 return HS_UNDEFINED_VAR;
01192 }
01193
01194 M_FREE(tag);
01195 return HS_SUCCESS;
01196 }
01197
01198
01199
01200 INT hs_read(DWORD event_id, DWORD start_time, DWORD end_time,
01201 DWORD interval, char *tag_name, DWORD var_index,
01202 DWORD * time_buffer, DWORD * tbsize, void *data_buffer, DWORD * dbsize, DWORD * type, DWORD * n)
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238 {
01239 DWORD prev_time, last_irec_time;
01240 int fh, fhd, fhi, cp = 0;
01241 INT i, delta, index = 0, status, cache_size;
01242 INDEX_RECORD irec, *pirec;
01243 HIST_RECORD rec, drec;
01244 INT old_def_offset, var_size = 0, var_offset = 0;
01245 TAG *tag;
01246 char str[NAME_LENGTH];
01247 struct tm *tms;
01248 char *cache = NULL;
01249 time_t ltime;
01250 int rd;
01251
01252
01253
01254 #if 0
01255 if (rpc_is_remote())
01256 return rpc_call(RPC_HS_READ, event_id, start_time, end_time, interval,
01257 tag_name, var_index, time_buffer, tbsize, data_buffer, dbsize, type, n);
01258 #endif
01259
01260
01261 if (start_time == 0)
01262 start_time = (DWORD) time(NULL) - 3600;
01263 if (end_time == 0)
01264 end_time = (DWORD) time(NULL);
01265
01266 *n = 0;
01267 prev_time = 0;
01268 last_irec_time = start_time;
01269
01270
01271 status = hs_search_file(&start_time, 1);
01272 if (status != HS_SUCCESS) {
01273 cm_msg(MERROR, "hs_read", "cannot find recent history file");
01274 *tbsize = *dbsize = *n = 0;
01275 return HS_FILE_ERROR;
01276 }
01277
01278
01279 hs_open_file(start_time, "hst", O_RDONLY, &fh);
01280 hs_open_file(start_time, "idf", O_RDONLY, &fhd);
01281 hs_open_file(start_time, "idx", O_RDONLY, &fhi);
01282 if (fh < 0 || fhd < 0 || fhi < 0) {
01283 cm_msg(MERROR, "hs_read", "cannot open index files");
01284 *tbsize = *dbsize = *n = 0;
01285 if (fh>0) close(fh);
01286 if (fhd>0) close(fhd);
01287 if (fhi>0) close(fhi);
01288 return HS_FILE_ERROR;
01289 }
01290
01291
01292 lseek(fhi, 0, SEEK_END);
01293 cache_size = TELL(fhi);
01294
01295 if (cache_size == 0) {
01296 goto nextday;
01297 }
01298
01299 if (cache_size > 0) {
01300 cache = (char *) M_MALLOC(cache_size);
01301 if (cache) {
01302 lseek(fhi, 0, SEEK_SET);
01303 i = read(fhi, cache, cache_size);
01304 if (i < cache_size) {
01305 M_FREE(cache);
01306 if (fh>0) close(fh);
01307 if (fhd>0) close(fhd);
01308 if (fhi>0) close(fhi);
01309 return HS_FILE_ERROR;
01310 }
01311 }
01312
01313
01314 if (cache == NULL) {
01315 lseek(fhi, 0, SEEK_END);
01316 delta = (TELL(fhi) / sizeof(irec)) / 2;
01317 lseek(fhi, delta * sizeof(irec), SEEK_SET);
01318 do {
01319 delta = (int) (abs(delta) / 2.0 + 0.5);
01320 rd = read(fhi, (char *) &irec, sizeof(irec));
01321 assert(rd == sizeof(irec));
01322 if (irec.time > start_time)
01323 delta = -delta;
01324
01325 lseek(fhi, (delta - 1) * sizeof(irec), SEEK_CUR);
01326 } while (abs(delta) > 1 && irec.time != start_time);
01327 rd = read(fhi, (char *) &irec, sizeof(irec));
01328 assert(rd == sizeof(irec));
01329 if (irec.time > start_time)
01330 delta = -abs(delta);
01331
01332 i = TELL(fhi) + (delta - 1) * sizeof(irec);
01333 if (i <= 0)
01334 lseek(fhi, 0, SEEK_SET);
01335 else
01336 lseek(fhi, (delta - 1) * sizeof(irec), SEEK_CUR);
01337 rd = read(fhi, (char *) &irec, sizeof(irec));
01338 assert(rd == sizeof(irec));
01339 } else {
01340 delta = (cache_size / sizeof(irec)) / 2;
01341 cp = delta * sizeof(irec);
01342 do {
01343 delta = (int) (abs(delta) / 2.0 + 0.5);
01344 pirec = (INDEX_RECORD *) (cache + cp);
01345
01346
01347
01348 if (pirec->time > start_time)
01349 delta = -delta;
01350
01351 cp = cp + delta * sizeof(irec);
01352
01353 if (cp < 0)
01354 cp = 0;
01355 } while (abs(delta) > 1 && pirec->time != start_time);
01356 pirec = (INDEX_RECORD *) (cache + cp);
01357 if (pirec->time > start_time)
01358 delta = -abs(delta);
01359
01360 if (cp <= delta * (int) sizeof(irec))
01361 cp = 0;
01362 else
01363 cp = cp + delta * sizeof(irec);
01364
01365 if (cp >= cache_size)
01366 cp = cache_size - sizeof(irec);
01367 if (cp < 0)
01368 cp = 0;
01369
01370 memcpy(&irec, (INDEX_RECORD *) (cache + cp), sizeof(irec));
01371 cp += sizeof(irec);
01372 }
01373 } else {
01374
01375 cache = NULL;
01376 irec.time = start_time;
01377 }
01378
01379
01380 old_def_offset = -1;
01381 last_irec_time = start_time - 24*60*60;
01382 do {
01383
01384
01385 if (irec.time < last_irec_time) {
01386 cm_msg(MERROR, "hs_read",
01387 "corrupted history data: time does not increase: %d -> %d", last_irec_time, irec.time);
01388
01389 if (fh>0) close(fh);
01390 if (fhd>0) close(fhd);
01391 if (fhi>0) close(fhi);
01392 hs_gen_index(last_irec_time);
01393 return HS_SUCCESS;
01394 }
01395 last_irec_time = irec.time;
01396 if (irec.event_id == event_id && irec.time <= end_time && irec.time >= start_time) {
01397
01398 if (irec.time >= prev_time + interval) {
01399 prev_time = irec.time;
01400 lseek(fh, irec.offset, SEEK_SET);
01401 rd = read(fh, (char *) &rec, sizeof(rec));
01402 if (rd != sizeof(rec)) {
01403 cm_msg(MERROR, "hs_read", "corrupted history data at time %d: read() of %d bytes returned %d, errno %d (%s)", (int)irec.time, sizeof(rec), rd, errno, strerror(errno));
01404
01405 if (fh>0) close(fh);
01406 if (fhd>0) close(fhd);
01407 if (fhi>0) close(fhi);
01408 hs_gen_index(last_irec_time);
01409 return HS_SUCCESS;
01410 }
01411
01412
01413 if ((INT) rec.def_offset != old_def_offset) {
01414 lseek(fh, rec.def_offset, SEEK_SET);
01415 read(fh, (char *) &drec, sizeof(drec));
01416 read(fh, str, NAME_LENGTH);
01417
01418 tag = (TAG *) M_MALLOC(drec.data_size);
01419 if (tag == NULL) {
01420 *n = *tbsize = *dbsize = 0;
01421 if (cache)
01422 M_FREE(cache);
01423 close(fh);
01424 close(fhd);
01425 close(fhi);
01426 return HS_NO_MEMORY;
01427 }
01428 read(fh, (char *) tag, drec.data_size);
01429
01430
01431 index = -1;
01432 for (i = 0; (DWORD) i < drec.data_size / sizeof(TAG); i++)
01433 if (equal_ustring(tag[i].name, tag_name)) {
01434 index = i;
01435 break;
01436 }
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449 if (index >= 0 && var_index >= tag[i].n_data) {
01450 *n = *tbsize = *dbsize = 0;
01451 if (cache)
01452 M_FREE(cache);
01453 M_FREE(tag);
01454 close(fh);
01455 close(fhd);
01456 close(fhi);
01457 return HS_WRONG_INDEX;
01458 }
01459
01460
01461 if (index >= 0) {
01462 *type = tag[i].type;
01463
01464
01465 for (i = 0, var_offset = 0; i < index; i++)
01466 var_offset += rpc_tid_size(tag[i].type) * tag[i].n_data;
01467
01468
01469 if (tag[index].type == TID_STRING)
01470 var_size = tag[i].n_data;
01471 else
01472 var_size = rpc_tid_size(tag[index].type);
01473
01474 var_offset += var_size * var_index;
01475 }
01476
01477 M_FREE(tag);
01478 old_def_offset = rec.def_offset;
01479 lseek(fh, irec.offset + sizeof(rec), SEEK_SET);
01480 }
01481
01482 if (index >= 0) {
01483
01484 if ((*n) * sizeof(DWORD) >= *tbsize || (*n) * var_size >= *dbsize) {
01485 *dbsize = (*n) * var_size;
01486 *tbsize = (*n) * sizeof(DWORD);
01487 if (cache)
01488 M_FREE(cache);
01489 close(fh);
01490 close(fhd);
01491 close(fhi);
01492 return HS_TRUNCATED;
01493 }
01494
01495
01496 time_buffer[*n] = irec.time;
01497
01498
01499 lseek(fh, var_offset, SEEK_CUR);
01500 read(fh, (char *) data_buffer + (*n) * var_size, var_size);
01501
01502
01503 (*n)++;
01504 }
01505 }
01506 }
01507
01508
01509 if (cache) {
01510 if (cp >= cache_size) {
01511 i = -1;
01512 M_FREE(cache);
01513 cache = NULL;
01514 } else {
01515
01516 try_again:
01517
01518 i = sizeof(irec);
01519
01520 memcpy(&irec, cache + cp, sizeof(irec));
01521 cp += sizeof(irec);
01522
01523
01524 if (irec.time < last_irec_time || irec.time > last_irec_time + 24*60*60) {
01525
01526
01527
01528
01529
01530 while (cp < cache_size) {
01531 DWORD* evidp = (DWORD*)(cache + cp);
01532 if (*evidp == event_id) {
01533
01534 goto try_again;
01535 }
01536
01537 cp++;
01538 }
01539
01540 i = -1;
01541 }
01542 }
01543 } else
01544 i = read(fhi, (char *) &irec, sizeof(irec));
01545
01546
01547 if (i <= 0) {
01548 close(fh);
01549 close(fhd);
01550 close(fhi);
01551 fh = fhd = fhi = 0;
01552
01553 nextday:
01554
01555
01556 ltime = (time_t) last_irec_time;
01557 tms = localtime(<ime);
01558 tms->tm_hour = tms->tm_min = tms->tm_sec = 0;
01559 last_irec_time = (DWORD) mktime(tms);
01560
01561 last_irec_time += 3600 * 24;
01562
01563 if (last_irec_time > end_time)
01564 break;
01565
01566
01567 status = hs_search_file(&last_irec_time, 1);
01568 if (status != HS_SUCCESS)
01569 break;
01570
01571
01572 hs_open_file(last_irec_time, "hst", O_RDONLY, &fh);
01573 hs_open_file(last_irec_time, "idf", O_RDONLY, &fhd);
01574 hs_open_file(last_irec_time, "idx", O_RDONLY, &fhi);
01575 if (fh < 0 || fhd < 0 || fhi < 0) {
01576 cm_msg(MERROR, "hs_read", "cannot open index files");
01577 break;
01578 }
01579
01580
01581 lseek(fhi, 0, SEEK_END);
01582 cache_size = TELL(fhi);
01583
01584 if (cache_size == 0) {
01585 goto nextday;
01586 }
01587
01588 lseek(fhi, 0, SEEK_SET);
01589 cache = (char *) M_MALLOC(cache_size);
01590 if (cache) {
01591 i = read(fhi, cache, cache_size);
01592 if (i < cache_size)
01593 break;
01594
01595 cp = 0;
01596 memcpy(&irec, cache, sizeof(irec));
01597 } else {
01598
01599 i = read(fhi, (char *) &irec, sizeof(irec));
01600 if (i <= 0)
01601 break;
01602 assert(i == sizeof(irec));
01603 }
01604
01605
01606 old_def_offset = -1;
01607 }
01608
01609
01610 } while (irec.time < end_time);
01611
01612 if (cache)
01613 M_FREE(cache);
01614 if (fh) close(fh);
01615 if (fhd) close(fhd);
01616 if (fhi) close(fhi);
01617
01618 *dbsize = *n * var_size;
01619 *tbsize = *n * sizeof(DWORD);
01620
01621 return HS_SUCCESS;
01622 }
01623
01624
01625 #endif
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640 INT hs_dump(DWORD event_id, DWORD start_time, DWORD end_time, DWORD interval, BOOL binary_time)
01641 {
01642 DWORD prev_time, last_irec_time;
01643 time_t ltime;
01644 int fh, fhd, fhi;
01645 INT i, j, delta, status, n_tag = 0, old_n_tag = 0;
01646 INDEX_RECORD irec;
01647 HIST_RECORD rec, drec;
01648 INT old_def_offset, offset;
01649 TAG *tag = NULL, *old_tag = NULL;
01650 char str[NAME_LENGTH], data_buffer[10000];
01651 struct tm *tms;
01652
01653
01654 if (start_time == 0)
01655 start_time = (DWORD) time(NULL) - 3600;
01656 if (end_time == 0)
01657 end_time = (DWORD) time(NULL);
01658
01659
01660 status = hs_search_file(&start_time, 1);
01661 if (status != HS_SUCCESS) {
01662 cm_msg(MERROR, "hs_dump", "cannot find recent history file");
01663 return HS_FILE_ERROR;
01664 }
01665
01666
01667 hs_open_file(start_time, "hst", O_RDONLY, &fh);
01668 hs_open_file(start_time, "idf", O_RDONLY, &fhd);
01669 hs_open_file(start_time, "idx", O_RDONLY, &fhi);
01670 if (fh < 0 || fhd < 0 || fhi < 0) {
01671 cm_msg(MERROR, "hs_dump", "cannot open index files");
01672 return HS_FILE_ERROR;
01673 }
01674
01675
01676 lseek(fhi, 0, SEEK_END);
01677 delta = (TELL(fhi) / sizeof(irec)) / 2;
01678 lseek(fhi, delta * sizeof(irec), SEEK_SET);
01679 do {
01680 delta = (int) (abs(delta) / 2.0 + 0.5);
01681 read(fhi, (char *) &irec, sizeof(irec));
01682 if (irec.time > start_time)
01683 delta = -delta;
01684
01685 i = lseek(fhi, (delta - 1) * sizeof(irec), SEEK_CUR);
01686 } while (abs(delta) > 1 && irec.time != start_time);
01687 read(fhi, (char *) &irec, sizeof(irec));
01688 if (irec.time > start_time)
01689 delta = -abs(delta);
01690
01691 i = TELL(fhi) + (delta - 1) * sizeof(irec);
01692 if (i <= 0)
01693 lseek(fhi, 0, SEEK_SET);
01694 else
01695 lseek(fhi, (delta - 1) * sizeof(irec), SEEK_CUR);
01696 read(fhi, (char *) &irec, sizeof(irec));
01697
01698
01699 old_def_offset = -1;
01700 prev_time = 0;
01701 last_irec_time = 0;
01702 do {
01703 if (irec.time < last_irec_time) {
01704 cm_msg(MERROR, "hs_dump",
01705 "corrupted history data: time does not increase: %d -> %d", last_irec_time, irec.time);
01706 hs_gen_index(last_irec_time);
01707 return HS_FILE_ERROR;
01708 }
01709 last_irec_time = irec.time;
01710 if (irec.event_id == event_id && irec.time <= end_time && irec.time >= start_time) {
01711 if (irec.time >= prev_time + interval) {
01712 prev_time = irec.time;
01713 lseek(fh, irec.offset, SEEK_SET);
01714 read(fh, (char *) &rec, sizeof(rec));
01715
01716
01717 if ((INT) rec.def_offset != old_def_offset) {
01718 lseek(fh, rec.def_offset, SEEK_SET);
01719 read(fh, (char *) &drec, sizeof(drec));
01720 read(fh, str, NAME_LENGTH);
01721
01722 if (tag == NULL)
01723 tag = (TAG *) M_MALLOC(drec.data_size);
01724 else
01725 tag = (TAG *) realloc(tag, drec.data_size);
01726 if (tag == NULL)
01727 return HS_NO_MEMORY;
01728 read(fh, (char *) tag, drec.data_size);
01729 n_tag = drec.data_size / sizeof(TAG);
01730
01731
01732 if (old_tag == NULL || old_n_tag != n_tag || memcmp(old_tag, tag, drec.data_size) != 0) {
01733 printf("Date\t");
01734 for (i = 0; i < n_tag; i++) {
01735 if (tag[i].n_data == 1 || tag[i].type == TID_STRING)
01736 printf("%s\t", tag[i].name);
01737 else
01738 for (j = 0; j < (INT) tag[i].n_data; j++)
01739 printf("%s%d\t", tag[i].name, j);
01740 }
01741 printf("\n");
01742
01743 if (old_tag == NULL)
01744 old_tag = (TAG *) M_MALLOC(drec.data_size);
01745 else
01746 old_tag = (TAG *) realloc(old_tag, drec.data_size);
01747 memcpy(old_tag, tag, drec.data_size);
01748 old_n_tag = n_tag;
01749 }
01750
01751 old_def_offset = rec.def_offset;
01752 lseek(fh, irec.offset + sizeof(rec), SEEK_SET);
01753 }
01754
01755
01756 if (binary_time)
01757 printf("%d ", irec.time);
01758 else {
01759 ltime = (time_t) irec.time;
01760 sprintf(str, "%s", ctime(<ime) + 4);
01761 str[20] = '\t';
01762 printf(str);
01763 }
01764
01765
01766 read(fh, data_buffer, rec.data_size);
01767
01768
01769 offset = 0;
01770 for (i = 0; i < n_tag; i++) {
01771
01772 if (tag[i].type == TID_STRING) {
01773 printf("%s\t", data_buffer + offset);
01774 offset += tag[i].n_data;
01775 } else if (tag[i].n_data == 1) {
01776
01777 db_sprintf(str, data_buffer + offset, rpc_tid_size(tag[i].type), 0, tag[i].type);
01778 printf("%s\t", str);
01779 offset += rpc_tid_size(tag[i].type);
01780 } else
01781
01782 for (j = 0; j < (INT) tag[i].n_data; j++) {
01783 db_sprintf(str, data_buffer + offset, rpc_tid_size(tag[i].type), 0, tag[i].type);
01784 printf("%s\t", str);
01785 offset += rpc_tid_size(tag[i].type);
01786 }
01787 }
01788 printf("\n");
01789 }
01790 }
01791
01792
01793 i = read(fhi, (char *) &irec, sizeof(irec));
01794
01795
01796 if (i <= 0) {
01797 close(fh);
01798 close(fhd);
01799 close(fhi);
01800
01801
01802 ltime = (time_t) last_irec_time;
01803 tms = localtime(<ime);
01804 tms->tm_hour = tms->tm_min = tms->tm_sec = 0;
01805 last_irec_time = (DWORD) mktime(tms);
01806
01807 last_irec_time += 3600 * 24;
01808 if (last_irec_time > end_time)
01809 break;
01810
01811
01812 status = hs_search_file((DWORD *) & last_irec_time, 1);
01813 if (status != HS_SUCCESS)
01814 break;
01815
01816
01817 hs_open_file(last_irec_time, "hst", O_RDONLY, &fh);
01818 hs_open_file(last_irec_time, "idf", O_RDONLY, &fhd);
01819 hs_open_file(last_irec_time, "idx", O_RDONLY, &fhi);
01820 if (fh < 0 || fhd < 0 || fhi < 0) {
01821 cm_msg(MERROR, "hs_dump", "cannot open index files");
01822 break;
01823 }
01824
01825
01826 i = read(fhi, (char *) &irec, sizeof(irec));
01827 if (i <= 0)
01828 break;
01829
01830
01831 old_def_offset = -1;
01832 }
01833 } while (irec.time < end_time);
01834
01835 M_FREE(tag);
01836 M_FREE(old_tag);
01837 close(fh);
01838 close(fhd);
01839 close(fhi);
01840
01841 return HS_SUCCESS;
01842 }
01843
01844
01845 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01846
01847
01848 INT hs_fdump(char *file_name, DWORD id, BOOL binary_time)
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868 {
01869 int fh;
01870 INT n;
01871 time_t ltime;
01872 HIST_RECORD rec;
01873 char event_name[NAME_LENGTH];
01874 char str[256];
01875
01876
01877 sprintf(str, "%s%s", _hs_path_name, file_name);
01878 fh = open(str, O_RDONLY | O_BINARY, 0644);
01879 if (fh < 0) {
01880 cm_msg(MERROR, "hs_fdump", "cannot open file %s", str);
01881 return HS_FILE_ERROR;
01882 }
01883
01884
01885 do {
01886 n = read(fh, (char *) &rec, sizeof(rec));
01887 if (n < sizeof(rec))
01888 break;
01889
01890
01891 if (rec.record_type == RT_DEF) {
01892
01893 read(fh, event_name, sizeof(event_name));
01894
01895 if (rec.event_id == id || id == 0)
01896 printf("Event definition %s, ID %d\n", event_name, rec.event_id);
01897
01898
01899 lseek(fh, rec.data_size, SEEK_CUR);
01900 } else {
01901
01902 if (binary_time)
01903 sprintf(str, "%d ", rec.time);
01904 else {
01905 ltime = (time_t) rec.time;
01906 strcpy(str, ctime(<ime) + 4);
01907 str[15] = 0;
01908 }
01909 if (rec.event_id == id || id == 0)
01910 printf("ID %d, %s, size %d\n", rec.event_id, str, rec.data_size);
01911
01912
01913 lseek(fh, rec.data_size, SEEK_CUR);
01914 }
01915
01916 } while (TRUE);
01917
01918 close(fh);
01919
01920 return HS_SUCCESS;
01921 }
01922 #endif
01923
01924
01925 #endif
01926
01927
01928
01929
01930