00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00117 #include "xdasd_mcache.h"
00118 #include "xdasd_parse.h"
00119 #include "xdasd_log.h"
00120
00121 #include "xdas_base.h"
00122 #include "xdas_wire.h"
00123
00124 #ifdef _WIN32
00125
00126 # define WIN32_LEAN_AND_MEAN
00127 # include <windows.h>
00128 # include <direct.h>
00129 # include <io.h>
00130 # include <fcntl.h>
00131 # include <sys/types.h>
00132 # include <sys/stat.h>
00133 # define mkdir(x,y) _mkdir(x)
00134 # define open _open
00135 # define lseek _lseek
00136 # define read _read
00137 # define write _write
00138 # define close _close
00139 # define unlink _unlink
00140 # define MC_FILE_ATTRS (_S_IREAD | _S_IWRITE)
00141 # define MC_OPEN_FLAGS (_O_RDWR | _O_BINARY)
00142 # define MC_CREATE_FLAGS (_O_RDWR | _O_CREAT | _O_BINARY)
00143
00144 #else
00145
00146 # ifdef HAVE_CONFIG_H
00147 # include "config.h"
00148 # endif
00149 # include <unistd.h>
00150 # include <sys/types.h>
00151 # include <sys/stat.h>
00152 # include <fcntl.h>
00153 # include <dirent.h>
00154 # if HAVE_INTTYPES_H
00155 # include <inttypes.h>
00156 # else
00157 # if HAVE_STDINT_H
00158 # include <stdint.h>
00159 # endif
00160 # endif
00161 # define MC_FILE_ATTRS (0644)
00162 # define MC_DIR_ATTRS (0744)
00163 # define MC_OPEN_FLAGS (O_RDWR)
00164 # define MC_CREATE_FLAGS (O_RDWR | O_CREAT)
00165 #endif
00166
00167 #include <stddef.h>
00168 #include <stdio.h>
00169 #include <stdlib.h>
00170 #include <string.h>
00171 #include <malloc.h>
00172
00177
00178
00179
00180
00181 #ifdef XDASD_MCACHE_TEST
00182 # define MCACHE_MAX_FILESZ (1024 + 512)
00183 # define MCACHE_MAX_RECSZ (512 + 256)
00184 #else
00185 # define MCACHE_MAX_FILESZ (1024 * 1024)
00186 # define MCACHE_MAX_RECSZ (64 * 1024)
00187 #endif
00188
00190 #define MCACHE_BASE_FNAME "xdasd.cache"
00191
00192
00193 #define MCH_BOF 0
00194 #define MCH_EOF 1
00195 #define MCH_LIM 2
00196
00198 typedef struct mcfile_
00199 {
00200 int fh;
00201 unsigned usecnt;
00202 unsigned fileno;
00203 uint32_t header[3];
00204 char fname[FILENAME_MAX];
00205 } mcfile_t;
00206
00208 typedef struct mcache_
00209 {
00210 unsigned lofno;
00211 unsigned hifno;
00212 mcfile_t * ifp;
00213 mcfile_t * ofp;
00214 char mcdir[FILENAME_MAX];
00215 } mcache_t;
00216
00217 #ifdef _WIN32
00218
00219
00220
00221 #define dirent _finddata_t
00222 #define d_name name
00223
00225 typedef struct DIR_tag
00226 {
00227 intptr_t handle;
00228 struct _finddata_t fileinfo;
00229 char filespec[FILENAME_MAX];
00230 } DIR;
00231
00240 static DIR * opendir(const char * name)
00241 {
00242 DIR * dir;
00243 size_t dirlen;
00244 if ((dir = (DIR *)malloc(sizeof(*dir))) == 0)
00245 return 0;
00246 memset(dir, 0, sizeof(*dir));
00247 dir->handle = -1;
00248 strncpy(dir->filespec, name, sizeof(dir->filespec));
00249 dir->filespec[sizeof(dir->filespec) - 1] = 0;
00250 dirlen = strlen(dir->filespec);
00251 if (dirlen > 0 && (dir->filespec[dirlen - 1] == '\\'
00252 || dir->filespec[dirlen - 1] == '/'))
00253 dir->filespec[--dirlen] = 0;
00254 strcpy(dir->filespec + dirlen, "\\*");
00255 return dir;
00256 }
00257
00266 static struct dirent * readdir(DIR * dir)
00267 {
00268 if ((dir->handle == -1 && (dir->handle =
00269 _findfirst(dir->filespec, &dir->fileinfo)) == -1)
00270 || _findnext(dir->handle, &dir->fileinfo) != 0)
00271 return 0;
00272 return &dir->fileinfo;
00273 }
00274
00283 static int closedir(DIR * dir)
00284 {
00285 int rc = _findclose(dir->handle);
00286 free(dir);
00287 return rc;
00288 }
00289
00290 #endif
00291
00315 static void mcache_calc_file_range(const char * mcdir,
00316 unsigned * lowp, unsigned * highp)
00317 {
00318 DIR * dp;
00319 unsigned low = (unsigned)(-1);
00320 unsigned high = 0;
00321
00322
00323 if ((dp = opendir(mcdir)) != 0)
00324 {
00325 struct dirent * de;
00326
00327
00328 while ((de = readdir(dp)) != 0)
00329 {
00330 size_t namelen = strlen(de->d_name);
00331 if (namelen > 12 && strncmp("xdasd.cache.", de->d_name, 12) == 0)
00332 {
00333 unsigned fcval = atoi(de->d_name + 12);
00334 if (fcval != 0)
00335 {
00336 if (fcval < low)
00337 low = fcval;
00338 if (fcval > high)
00339 high = fcval;
00340 }
00341 }
00342 }
00343 closedir(dp);
00344 }
00345
00346
00347 *lowp = low < (unsigned)(-1)? low: 1;
00348 *highp = high > 0? high: 1;
00349 }
00350
00364 static void mcache_close(mcfile_t * fp, int ferase)
00365 {
00366 if (fp != 0 && --fp->usecnt == 0)
00367 {
00368 close(fp->fh);
00369 if (ferase)
00370 unlink(fp->fname);
00371 free(fp);
00372 }
00373 }
00374
00388 static mcfile_t * mcache_dup(mcfile_t * fp)
00389 {
00390 if (fp)
00391 fp->usecnt++;
00392 return fp;
00393 }
00394
00403 static int mcache_read_file_header(mcfile_t * fp)
00404 {
00405 char header[sizeof(fp->header)];
00406 char * cp = header;
00407
00408 if (read(fp->fh, header, sizeof(header)) != sizeof(header))
00409 return -1;
00410
00411 fp->header[MCH_BOF] = xdas_get_uint32(&cp);
00412 fp->header[MCH_EOF] = xdas_get_uint32(&cp);
00413 fp->header[MCH_LIM] = xdas_get_uint32(&cp);
00414
00415 if (fp->header[MCH_LIM] > MCACHE_MAX_FILESZ
00416 || fp->header[MCH_EOF] > fp->header[MCH_LIM]
00417 || fp->header[MCH_BOF] > fp->header[MCH_EOF])
00418 return -1;
00419
00420 return 0;
00421 }
00422
00431 static int mcache_write_file_header(mcfile_t * fp)
00432 {
00433 char header[sizeof(fp->header)];
00434 char * cp = header;
00435
00436 xdas_put_uint32(&cp, fp->header[MCH_BOF]);
00437 xdas_put_uint32(&cp, fp->header[MCH_EOF]);
00438 xdas_put_uint32(&cp, fp->header[MCH_LIM]);
00439
00440 if (lseek(fp->fh, 0, SEEK_SET) == (off_t)(-1)
00441 || write(fp->fh, header, sizeof(header)) != sizeof(header))
00442 return -1;
00443
00444 return 0;
00445 }
00446
00457 static int mcache_open(const char * mcdir, unsigned fileno, mcfile_t ** fpp)
00458 {
00459 mcfile_t * fp;
00460
00461
00462 if ((fp = (mcfile_t *)malloc(sizeof(*fp))) == 0)
00463 return -1;
00464 memset(fp, 0, sizeof(*fp));
00465 fp->usecnt++;
00466 fp->fileno = fileno;
00467
00468
00469 sprintf(fp->fname, "%s/" MCACHE_BASE_FNAME ".%d", mcdir, fileno);
00470 if ((fp->fh = open(fp->fname, MC_OPEN_FLAGS)) < 0)
00471 {
00472 free(fp);
00473 return -1;
00474 }
00475
00476
00477 if (mcache_read_file_header(fp) < 0)
00478 {
00479 mcache_close(fp, 0);
00480 return -1;
00481 }
00482 *fpp = fp;
00483 return 0;
00484 }
00485
00496 static int mcache_create(const char * mcdir, unsigned fileno, mcfile_t ** fpp)
00497 {
00498 mcfile_t * fp;
00499
00500 mkdir(mcdir, MC_DIR_ATTRS);
00501
00502
00503 if ((fp = (mcfile_t *)malloc(sizeof(*fp))) == 0)
00504 return -1;
00505 memset(fp, 0, sizeof(*fp));
00506 fp->usecnt++;
00507 fp->fileno = fileno;
00508
00509
00510 sprintf(fp->fname, "%s/" MCACHE_BASE_FNAME ".%d", mcdir, fileno);
00511 if ((fp->fh = open(fp->fname, MC_CREATE_FLAGS, MC_FILE_ATTRS)) < 0)
00512 {
00513 free(fp);
00514 return -1;
00515 }
00516
00517 fp->header[MCH_BOF] = sizeof(fp->header);
00518 fp->header[MCH_EOF] = sizeof(fp->header);
00519 fp->header[MCH_LIM] = MCACHE_MAX_FILESZ;
00520 if (mcache_write_file_header(fp) < 0)
00521 {
00522 mcache_close(fp, 1);
00523 return -1;
00524 }
00525
00526
00527
00528 *fpp = fp;
00529 return 0;
00530 }
00531
00542 static int mcache_write_record(mcfile_t * fp, Parsed * parsed, size_t msgsz)
00543 {
00544 char buf[2 * sizeof(uint32_t) + (XDAS_FIELD_COUNT + 1) * sizeof(uint16_t)];
00545 char * cp = buf;
00546 int i;
00547
00548
00549
00550
00551
00552
00553
00554 xdas_put_uint32(&cp, sizeof(buf) - sizeof(uint32_t) + msgsz);
00555 xdas_put_uint32(&cp, parsed->flags & PMF_IMPORTED);
00556 for (i = 0; i < XDAS_FIELD_COUNT + 1; i++)
00557 xdas_put_uint16(&cp, (uint16_t)(parsed->parsed[i] - parsed->msg));
00558
00559
00560 if (lseek(fp->fh, fp->header[MCH_EOF], SEEK_SET) == (off_t)(-1)
00561 || write(fp->fh, buf, sizeof(buf)) != sizeof(buf)
00562 || write(fp->fh, parsed->msg, (unsigned)msgsz) != (int)msgsz)
00563 return -1;
00564
00565
00566 fp->header[MCH_EOF] += (uint32_t)(sizeof(buf) + msgsz);
00567 if (mcache_write_file_header(fp) < 0)
00568 return -1;
00569
00570
00571
00572 return 0;
00573 }
00574
00591 static Parsed * mcache_read_record(mcfile_t * fp)
00592 {
00593 size_t recsz;
00594 uint32_t u32recsz;
00595 Parsed * parsed = 0;
00596
00597 if (lseek(fp->fh, fp->header[MCH_BOF], SEEK_SET) != (off_t)(-1)
00598 && read(fp->fh, &u32recsz, sizeof(u32recsz)) == sizeof(u32recsz)
00599 && (recsz = AS_UINT32(&u32recsz)) < MCACHE_MAX_RECSZ)
00600 {
00601 char buf[sizeof(uint32_t) + (XDAS_FIELD_COUNT + 1) * sizeof(uint16_t)];
00602 size_t msgsz = recsz - sizeof(buf);
00603 size_t allocsz = offsetof(Parsed, msg) + msgsz;
00604 char * cp = buf;
00605 int i;
00606
00607
00608
00609
00610
00611
00612
00613 if ((parsed = (Parsed *)malloc(allocsz)) == 0
00614 || read(fp->fh, buf, sizeof(buf)) != sizeof(buf)
00615 || read(fp->fh, parsed->msg, (unsigned)msgsz) != (int)msgsz)
00616 {
00617 free(parsed);
00618 return 0;
00619 }
00620
00621
00622 memset(parsed, 0, offsetof(Parsed, parsed));
00623 parsed->structsz = allocsz;
00624 parsed->flags = xdas_get_uint32(&cp);
00625 for (i = 0; i < XDAS_FIELD_COUNT + 1; i++)
00626 {
00627 parsed->parsed[i] = parsed->msg + xdas_get_uint16(&cp);
00628 if (parsed->parsed[i] < parsed->msg
00629 || parsed->parsed[i] > parsed->msg + msgsz)
00630 {
00631 free(parsed);
00632 return 0;
00633 }
00634 }
00635 }
00636 return parsed;
00637 }
00638
00647 static int mcache_update_bof(mcfile_t * fp)
00648 {
00649 uint32_t u32msgsz;
00650
00651
00652 if (fp->header[MCH_BOF] >= fp->header[MCH_EOF]
00653 || lseek(fp->fh, fp->header[MCH_BOF], SEEK_SET) == (off_t)(-1)
00654 || read(fp->fh, &u32msgsz, sizeof(u32msgsz)) != sizeof(u32msgsz))
00655 return -1;
00656
00657
00658 fp->header[MCH_BOF] += sizeof(u32msgsz) + AS_UINT32(&u32msgsz);
00659 if (mcache_write_file_header(fp) < 0)
00660 return -1;
00661
00662
00663
00664 return 0;
00665 }
00666
00679 static int mcache_put_msg(mcache_t * mcp, Parsed * parsed)
00680 {
00681 unsigned nextfno = mcp->hifno;
00682 size_t msgsz = parsed->parsed[XDAS_FIELD_COUNT] - parsed->parsed[0];
00683 size_t recsz = 2 * sizeof(uint32_t)
00684 + (XDAS_FIELD_COUNT + 1) * sizeof(uint16_t) + msgsz;
00685
00686
00687
00688
00689
00690
00691
00692 do
00693 {
00694 if (mcp->ifp != 0)
00695 {
00696
00697 if (mcp->ifp->header[MCH_EOF] + recsz > mcp->ifp->header[MCH_LIM])
00698 {
00699 nextfno = mcp->ifp->fileno + 1;
00700 mcache_close(mcp->ifp, 0);
00701 mcp->ifp = 0;
00702 }
00703 }
00704
00705
00706 if (mcp->ifp == 0)
00707 {
00708 if (mcp->ofp && nextfno == mcp->ofp->fileno)
00709 mcp->ifp = mcache_dup(mcp->ofp);
00710 else if (mcache_open(mcp->mcdir, nextfno, &mcp->ifp) < 0
00711 && mcache_create(mcp->mcdir, nextfno, &mcp->ifp) < 0)
00712 {
00713 xdasd_log(0, "MCACHE: Unable to open message cache for write.\n");
00714 return -1;
00715 }
00716 }
00717 } while (mcp->ifp->header[MCH_EOF] + recsz > mcp->ifp->header[MCH_LIM]);
00718
00719
00720 if (mcache_write_record(mcp->ifp, parsed, msgsz) < 0)
00721 {
00722 xdasd_log(0, "MCACHE: Unable to write to message cache.\n");
00723 return -1;
00724 }
00725 return 0;
00726 }
00727
00744 static Parsed * mcache_get_msg(mcache_t * mcp)
00745 {
00746 unsigned nextfno = mcp->lofno;
00747
00748
00749 if (mcp->ofp != 0)
00750 {
00751
00752 if (mcache_update_bof(mcp->ofp) < 0)
00753 return 0;
00754
00755
00756 if (mcp->ofp->header[MCH_BOF] >= mcp->ofp->header[MCH_EOF])
00757 {
00758
00759
00760 if (mcp->ifp != 0 && mcp->ofp->fileno == mcp->ifp->fileno)
00761 {
00762 mcp->lofno = mcp->hifno = 1;
00763 mcache_close(mcp->ifp, 0);
00764 mcp->ifp = 0;
00765 }
00766
00767
00768 nextfno = mcp->ofp->fileno + 1;
00769 mcache_close(mcp->ofp, 1);
00770 mcp->ofp = 0;
00771 }
00772 }
00773
00774
00775 if (mcp->ofp == 0)
00776 {
00777
00778 if (mcp->ifp && nextfno == mcp->ifp->fileno)
00779 mcp->ofp = mcache_dup(mcp->ifp);
00780 else if (mcache_open(mcp->mcdir, nextfno, &mcp->ofp) < 0)
00781 return 0;
00782 }
00783
00784
00785 return mcache_read_record(mcp->ofp);
00786 }
00787
00791
00792
00802 int xdasd_mcache_put_msg(MsgCache mc, Parsed * parsed)
00803 {
00804 return mcache_put_msg((mcache_t *)mc, parsed);
00805 }
00806
00818 Parsed * xdasd_mcache_get_msg(MsgCache mc)
00819 {
00820 return mcache_get_msg((mcache_t *)mc);
00821 }
00822
00835 MsgCache xdasd_mcache_create(const char * msgfdir)
00836 {
00837 mcache_t * mcp;
00838
00839 if ((mcp = (mcache_t *)malloc(sizeof(*mcp))) == 0)
00840 return 0;
00841
00842
00843 strncpy(mcp->mcdir, msgfdir, sizeof(mcp->mcdir));
00844 mcp->mcdir[sizeof(mcp->mcdir) - 1] = 0;
00845 mcp->ifp = mcp->ofp = 0;
00846
00847
00848 mcache_calc_file_range(mcp->mcdir, &mcp->lofno, &mcp->hifno);
00849
00850 return (MsgCache)mcp;
00851 }
00852
00859 void xdasd_mcache_destroy(MsgCache mc)
00860 {
00861 mcache_t * mcp = (mcache_t *)mc;
00862
00863
00864 mcache_close(mcp->ifp, 0);
00865 mcache_close(mcp->ofp, 0);
00866 free(mcp);
00867 }
00868
00869
00870
00871 #ifdef XDASD_MCACHE_TEST
00872
00873 #include <stdio.h>
00874 #include <stdlib.h>
00875 #include <stdarg.h>
00876
00883 void xdasd_log(int level, const char * fmt, ... )
00884 {
00885 #ifdef LOG_TO_STDOUT
00886 va_list args;
00887 va_start(args, fmt);
00888 vprintf(fmt, args);
00889 va_end(args);
00890 #else
00891 (void)fmt;
00892 #endif
00893 }
00894
00901 int xdasd_log_level(void) { return 0; }
00902
00923 int main(int argc, char ** argv)
00924 {
00925
00926 #define TESTMSG1 \
00927 "HDR:00A8:OX1:1CB1B348:::time.nist.gov:MST7MDT:0x10000001:0:ORG:" \
00928 "originator_location_name:originator_location_address:" \
00929 "originator_service_type:originator_authentication_authority:" \
00930 "originator_principal_name:originator_principal_id:" \
00931 "INT:initiator_auth_authority:initiator_domain_name:initiator_domain_id:" \
00932 "TGT:target_location_name:target_location_address:target_service_type:" \
00933 "target_auth_authority:target_principal_name:target_principal_id:" \
00934 "SRC:pointer_to_source_domain:EVT:event_specific_info:END"
00935
00936 #define TESTMSG2 \
00937 "HDR:00B8:OX1:1FB7AC54:::time.ms.com:MST5MDT:0x10000002:0:ORG:" \
00938 "org_location_name:org_location_address:org_service_type:" \
00939 "org_auth_authority:org_principal_name:org_principal_id:INT:" \
00940 "int_auth_authority:int_domain_specific_name:int_domain_specific_id:" \
00941 "TGT:tgt_location_name:tgt_location_address:tgt_service_type:" \
00942 "tgt_auth_authority:tgt_principal_name:tgt_principal_id:" \
00943 "SRC:pointer_to_source_domain:EVT:event_specific_information:END"
00944
00945 static struct
00946 {
00947 char * msg;
00948 size_t msgsz;
00949 } msgs[] =
00950 {
00951 {TESTMSG1, sizeof(TESTMSG1) - 1},
00952 {TESTMSG2, sizeof(TESTMSG2) - 1},
00953 {TESTMSG2, sizeof(TESTMSG2) - 1},
00954 {TESTMSG1, sizeof(TESTMSG1) - 1},
00955 {TESTMSG2, sizeof(TESTMSG2) - 1},
00956 {TESTMSG1, sizeof(TESTMSG1) - 1},
00957 {TESTMSG1, sizeof(TESTMSG1) - 1},
00958 };
00959
00960 int i, j;
00961 DIR * dir;
00962 MsgCache mc;
00963 Parsed * parsed;
00964 struct dirent * de;
00965 char * cache_path = argc > 1? argv[1]: ".";
00966
00967
00968 if ((dir = opendir(cache_path)) != 0)
00969 {
00970 while ((de = readdir(dir)) != 0)
00971 if (strncmp(de->d_name, MCACHE_BASE_FNAME,
00972 sizeof(MCACHE_BASE_FNAME) - 1) == 0)
00973 {
00974 char fpath[FILENAME_MAX];
00975 sprintf(fpath, "%s\\%s", cache_path, de->d_name);
00976 unlink(fpath);
00977 }
00978 closedir(dir);
00979 }
00980
00981
00982 mc = xdasd_mcache_create(cache_path);
00983
00984
00985 for (i = 0; i < (sizeof(msgs)/sizeof(*msgs)) / 2; i++)
00986 {
00987 int err;
00988
00989 if ((err = xdasd_parse_message(PMF_IMPORTED,
00990 msgs[i].msgsz, msgs[i].msg, &parsed)) != 0)
00991 {
00992 xdasd_log(0, "%s: error %d at: %s(%d), loop %d.\n",
00993 argv[0], err, __FILE__, __LINE__, i);
00994 exit(1);
00995 }
00996 if ((err = xdasd_mcache_put_msg(mc, parsed)) != 0)
00997 {
00998 xdasd_log(0, "%s: error %d at: %s(%d), loop %d.\n",
00999 argv[0], err, __FILE__, __LINE__, i);
01000 exit(1);
01001 }
01002 xdasd_parse_free(parsed);
01003 }
01004
01005
01006 xdasd_mcache_destroy(mc);
01007
01008
01009 mc = xdasd_mcache_create(cache_path);
01010
01011
01012 for (j = 0; j < 2; j++)
01013 {
01014 parsed = xdasd_mcache_get_msg(mc);
01015 if (parsed == 0 || parsed->parsed[XDAS_FIELD_COUNT]
01016 - parsed->parsed[0] - 1 != (int)msgs[j].msgsz
01017 || strncmp(parsed->msg, msgs[j].msg, msgs[j].msgsz) != 0)
01018 {
01019 xdasd_log(0, "%s: corrupt cache detected at %s(%d), loop %d.\n",
01020 argv[0], __FILE__, __LINE__, j);
01021 exit(1); \
01022 }
01023 xdasd_parse_free(parsed);
01024 }
01025
01026
01027 xdasd_mcache_destroy(mc);
01028
01029
01030 mc = xdasd_mcache_create(cache_path);
01031
01032
01033 for ( ; i < sizeof(msgs)/sizeof(*msgs); i++)
01034 {
01035 int err;
01036
01037 if ((err = xdasd_parse_message(PMF_IMPORTED,
01038 msgs[i].msgsz, msgs[i].msg, &parsed)) != 0)
01039 {
01040 xdasd_log(0, "%s: error %d at: %s(%d), loop %d.\n",
01041 argv[0], err, __FILE__, __LINE__, i);
01042 exit(1);
01043 }
01044 if ((err = xdasd_mcache_put_msg(mc, parsed)) != 0)
01045 {
01046 xdasd_log(0, "%s: error %d at: %s(%d), loop %d.\n",
01047 argv[0], err, __FILE__, __LINE__, i);
01048 exit(1);
01049 }
01050 xdasd_parse_free(parsed);
01051 }
01052
01053
01054 xdasd_mcache_destroy(mc);
01055
01056
01057 mc = xdasd_mcache_create(cache_path);
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 for (--j; j < sizeof(msgs)/sizeof(*msgs); j++)
01068 {
01069 parsed = xdasd_mcache_get_msg(mc);
01070 if (parsed == 0 || parsed->parsed[XDAS_FIELD_COUNT]
01071 - parsed->parsed[0] - 1 != (int)msgs[j].msgsz
01072 || strncmp(parsed->msg, msgs[j].msg, msgs[j].msgsz) != 0)
01073 {
01074 xdasd_log(0, "%s: corrupt cache detected at %s(%d), loop %d.\n",
01075 argv[0], __FILE__, __LINE__, j);
01076 exit(1); \
01077 }
01078 xdasd_parse_free(parsed);
01079 }
01080
01081
01082
01083
01084 if ((parsed = xdasd_mcache_get_msg(mc)) != 0)
01085 {
01086 xdasd_log(0, "%s: read past end of cache detected at %s(%d).\n",
01087 argv[0], __FILE__, __LINE__);
01088 exit(1); \
01089 }
01090
01091
01092 xdasd_mcache_destroy(mc);
01093
01094
01095 if ((dir = opendir(cache_path)) != 0)
01096 {
01097 while ((de = readdir(dir)) != 0)
01098 if (strncmp(de->d_name, MCACHE_BASE_FNAME,
01099 sizeof(MCACHE_BASE_FNAME) - 1) == 0)
01100 {
01101 xdasd_log(0, "%s: file %s in cache didn't get removed.\n",
01102 argv[0], de->d_name);
01103 exit(1);
01104 }
01105 closedir(dir);
01106 }
01107 return 0;
01108 }
01109
01110 #endif
01111