1/* Copyright 1994 NEC Corporation, Tokyo, Japan. 2 * 3 * Permission to use, copy, modify, distribute and sell this software 4 * and its documentation for any purpose is hereby granted without 5 * fee, provided that the above copyright notice appear in all copies 6 * and that both that copyright notice and this permission notice 7 * appear in supporting documentation, and that the name of NEC 8 * Corporation not be used in advertising or publicity pertaining to 9 * distribution of the software without specific, written prior 10 * permission. NEC Corporation makes no representations about the 11 * suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 16 * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 18 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 19 * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#if !defined(lint) && !defined(__CODECENTER__) 24static char rcsid[]="$Id: fq.c 10525 2004-12-23 21:23:50Z korli $"; 25#endif 26 27#include "RKintern.h" 28 29#include <string.h> 30#include <unistd.h> 31#include <fcntl.h> 32 33#ifdef WIN 34#include <fcntl.h> 35#include <sys\types.h> 36#include <sys\stat.h> 37#endif 38 39#define dm_xdm dm_extdata.ptr 40 41 42static int WrToRut(struct RUT *ruc, unsigned long csn, unsigned long tick); 43static unsigned long UpdateFrst(struct RUT *ruc); 44static struct WRT *allocWRT(unsigned long size); 45static int writeNV(int fd, struct NV *nv); 46static void freeRUT(struct RUT *ruc); 47static int SaveRUC(int fr, struct RUT *ruc); 48 49struct xqm { 50 off_t ex_boff; 51 long ex_bsiz; 52}; 53 54struct RUT * 55allocRUT(unsigned long hn) 56{ 57 struct RUT *tempo; 58 59 if (!(tempo = (struct RUT *)calloc(1, sizeof(struct RUT)))) 60 return((struct RUT *) 0); 61 if (!(tempo->dp = (struct CTdata **)calloc((size_t) hn, sizeof(struct CTdata *)))){ 62 free(tempo); 63 return((struct RUT *) 0); 64 } 65 return tempo; 66} 67 68inline int 69WrToRut(struct RUT *ruc, unsigned long csn, unsigned long tick) 70{ 71 unsigned long whn; 72 struct CTdata *wd, **pwd; 73 74 whn = HashFunc(csn); 75 for (pwd = ruc->dp+whn, wd = *pwd ; wd; pwd = &wd->next, wd = *pwd) { 76 if (wd->ct[0] == csn) { 77 WriteCT(csn, tick, wd->ct); 78 return 0; 79 } 80 } 81 if (!(wd = (struct CTdata *)calloc(1, sizeof(struct CTdata)))) 82 return -1; 83 *pwd = wd; 84 WriteCT(csn, tick, wd->ct); 85 return 1; 86} 87 88static 89unsigned long 90UpdateFrst(struct RUT *ruc) 91{ 92 unsigned long wmin, wtick, frst, lc; 93 struct CTdata *wd; 94 95 wmin = 0xffffffffL; 96 frst = 0xfffffL; 97 98 for (lc = 0; lc < HN; lc++) { 99 for (wd = *(ruc->dp+lc) ; wd; wd = wd->next) { 100 if (wmin > (wtick = wd->ct[1])) { 101 frst = wd->ct[0]; 102 wmin = wtick; 103 } 104 } 105 } 106 if(frst == (unsigned long) 0xffffffff) 107 return (unsigned long) 0L; 108 return frst; 109} 110 111inline int 112deleteCT(struct RUT *ruc, unsigned long csn) 113{ 114 unsigned long whn; 115 struct CTdata *wd, **pre; 116 117 whn = HashFunc(csn); 118 119 for (pre = ruc->dp+whn, wd = *pre; ; pre = &wd->next, wd = *pre){ 120 if (!wd) 121 return 0; 122 if (wd->ct[0] == csn) 123 break; 124 } 125 *pre = wd->next; 126 free(wd); 127 return 1; 128} 129 130unsigned long 131searchRut(struct RUT *ruc, unsigned long csn) 132{ 133 unsigned long whn; 134 struct CTdata *wd; 135 136 whn = HashFunc(csn); 137 for (wd = *(ruc->dp+whn) ; wd; wd = wd->next) { 138 if (wd->ct[0] == csn) 139 return wd->ct[1]; 140 } 141 return (unsigned long) 0L; 142} 143 144inline 145struct CTdata * 146searchCTadd(struct RUT *ruc, unsigned long csn) 147{ 148 unsigned long whn; 149 struct CTdata *wd; 150 151 whn = HashFunc(csn); 152 for (wd = *(ruc->dp+whn) ; wd; wd = wd->next) { 153 if (wd->ct[0] == csn) 154 return wd; 155 } 156 return (struct CTdata *) 0; 157} 158 159int 160entryRut(struct RUT *ruc, unsigned long csn, unsigned long tick) 161{ 162 struct CTdata *wpadd; 163 int retval; 164 165 retval = 1; 166 if (ruc->cs < ruc->sz) 167 switch (WrToRut(ruc, csn, tick)) { 168 case 0: 169 break; 170 case 1: 171 if (++(ruc->cs) == ruc->sz) 172 ruc->frst = UpdateFrst(ruc); 173 break; 174 case -1: 175 return (int) 0; 176 } 177 else { 178 wpadd = searchCTadd(ruc, csn); 179 if (wpadd) { 180 WriteCT(csn, tick, wpadd->ct); 181 if (csn == ruc->frst) 182 ruc->frst = UpdateFrst(ruc); 183 } 184 else { 185 if (deleteCT(ruc, ruc->frst)){ 186 if (WrToRut(ruc, csn, tick) < 0){ 187 ruc->cs -= 1L; 188 retval = 0; 189 } 190 } 191 else 192 retval = 0; 193 ruc->frst = UpdateFrst(ruc); 194 } 195 } 196 return retval; 197} 198 199static 200struct WRT * 201allocWRT(unsigned long size) 202{ 203 struct WRT *tempo; 204 205 if (!(tempo = (struct WRT *)calloc(1, sizeof(struct WRT)))) 206 return((struct WRT *) 0); 207 if (!(tempo->buf = (unsigned char *)calloc(1, (int) 5*size))){ 208 free(tempo); 209 return((struct WRT *) 0); 210 } 211 tempo->sz = size; 212 return tempo; 213} 214 215inline 216struct WRT * 217readWRT(int fr) 218{ 219 unsigned long wsz, wcs, wfrst, wtm; 220 unsigned char ll[4]; 221 struct WRT *wrt; 222#ifdef WIN 223 DWORD dummy; 224#endif 225 226#ifndef WIN 227 if (read(fr, (char *)ll, 4) != 4) 228 return (struct WRT *) 0; 229 wsz = (unsigned long) bst4_to_l(ll); 230 if (read(fr, (char *)ll, 4) != 4) 231 return (struct WRT *) 0; 232 wcs = (unsigned long) bst4_to_l(ll); 233 if (read(fr, (char *)ll, 4) != 4) 234 return (struct WRT *) 0; 235 wfrst = (unsigned long) bst4_to_l(ll); 236 if (read(fr, (char *)ll, 4) != 4) 237 return (struct WRT *) 0; 238 wtm = (unsigned long) bst4_to_l(ll); 239 if (!(wrt = allocWRT(wsz))) 240 return (struct WRT *) 0; 241#else 242 if (!ReadFile(fr, (char *)ll, 4, &dummy, NULL) || dummy != 4) 243 return (struct WRT *) 0; 244 wsz = (unsigned long) bst4_to_l(ll); 245 if (!ReadFile(fr, (char *)ll, 4, &dummy, NULL) || dummy != 4) 246 return (struct WRT *) 0; 247 wcs = (unsigned long) bst4_to_l(ll); 248 if (!ReadFile(fr, (char *)ll, 4, &dummy, NULL) || dummy != 4) 249 return (struct WRT *) 0; 250 wfrst = (unsigned long) bst4_to_l(ll); 251 if (!ReadFile(fr, (char *)ll, 4, &dummy, NULL) || dummy != 4) 252 return (struct WRT *) 0; 253 wtm = (unsigned long) bst4_to_l(ll); 254 if (!(wrt = allocWRT(wsz))) 255 return (struct WRT *) 0; 256#endif 257 258 wrt->cs = wcs; 259 wrt->frst = wfrst; 260 wrt->tm = wtm; 261 if (wsz) { 262 if 263#ifndef WIN 264 (read(fr, wrt->buf, (unsigned) 5*wsz) != 5*(int)wsz) 265#else 266 (!ReadFile(fr, wrt->buf, (unsigned) 5*wsz, &dummy, NULL) || 267 dummy != (unsigned)5*(int)wsz) 268#endif 269 { 270 freeWRT(wrt); 271 return (struct WRT *) 0; 272 } 273 } 274 return wrt; 275} 276 277inline int 278writeToWRT(int fr, struct WRT *wrt) 279{ 280 unsigned char ll[4]; 281 282#ifndef WIN 283 l_to_bst4(wrt->sz, ll); 284 if (write(fr, (char *)ll, 4) != 4) 285 return 0; 286 l_to_bst4(wrt->cs, ll); 287 if (write(fr, (char *)ll, 4) != 4) 288 return 0; 289 l_to_bst4(wrt->frst, ll); 290 if (write(fr, (char *)ll, 4) != 4) 291 return 0; 292 l_to_bst4(wrt->tm, ll); 293 if (write(fr, (char *)ll, 4) != 4) 294 return 0; 295 if (wrt->sz) { 296 if (write(fr, wrt->buf, (unsigned) 5*wrt->sz) != 5*(int)wrt->sz) 297 return 0; 298 } 299 return 1; 300#else 301 DWORD written; 302 303 l_to_bst4(wrt->sz, ll); 304 if (WriteFile(fr, (char *)ll, 4, &written, NULL) && written == 4){ 305 l_to_bst4(wrt->cs, ll); 306 if (WriteFile(fr, (char *)ll, 4, &written, NULL) && written == 4) { 307 l_to_bst4(wrt->frst, ll); 308 if (WriteFile(fr, (char *)ll, 4, &written, NULL) && written == 4) { 309 l_to_bst4(wrt->tm, ll); 310 if (WriteFile(fr, (char *)ll, 4, &written, NULL) && written == 4) { 311 if (wrt->sz) { 312 if (WriteFile(fr, wrt->buf, (unsigned)5*wrt->sz, &written, NULL) && 313 written == 5*wrt->sz) { 314 return 1; 315 } 316 } 317 } 318 } 319 } 320 } 321 return 0; 322#endif 323} 324 325inline void 326abolishNV(struct NV *nv) 327 328{ 329 struct NVE *p, **q, *r; 330 unsigned i; 331 332 if (nv && nv->tsz && nv->buf) { 333 for (i = 0, q = nv->buf + i; i < nv->tsz; i++, q = nv->buf + i) { 334 for (p = *q; p; p = r) { 335 r = p->next; 336 if (p->data) 337 free(p->data); 338 free(p); 339 } 340 } 341 free(nv->buf); 342 free(nv); 343 } 344 return; 345} 346 347inline struct NV * 348readNV(int fd) 349{ 350 struct NV nv, *vn; 351 unsigned char ll[4], *buf, *p; 352 long i, cnt; 353 354 vn = (struct NV *)malloc(sizeof(struct NV)); 355 if (vn) { 356#ifndef WIN 357 if (read(fd, (char *)ll, 4) == 4) { 358 nv.sz = bst4_to_l(ll); 359 if (read(fd, (char *)ll, 4) == 4) { 360 cnt = bst4_to_l(ll); 361 if (read(fd, (char *)ll, 4) == 4) { 362 nv.tsz = bst4_to_l(ll); 363 if (read(fd, (char *)ll, 4) == 4) { 364 goto read_ok; 365 } 366 } 367 } 368 } 369#else 370 if (ReadFile(fd, (char *)ll, 4, &dummy, NULL) && dummy == 4) { 371 nv.sz = bst4_to_l(ll); 372 if (ReadFile(fd, (char *)ll, 4, &dummy, NULL) && dummy == 4) { 373 cnt = bst4_to_l(ll); 374 if (ReadFile(fd, (char *)ll, 4, &dummy, NULL) && dummy == 4) { 375 nv.tsz = bst4_to_l(ll); 376 if (ReadFile(fd, (char *)ll, 4, &dummy, NULL) && dummy == 4) { 377 goto read_ok; 378 } 379 } 380 } 381 } 382#endif 383 free(vn); 384 } 385 return (struct NV *)0; 386 387 read_ok: 388 389 nv.cnt = nv.csz = 0L; 390 nv.head.left = nv.head.right = &nv.head; 391 if (nv.sz) { 392 if (!(nv.buf = (struct NVE **)calloc((size_t)nv.tsz, sizeof(struct NVE *)))) { 393 free(vn); 394 return((struct NV *)0); 395 } 396 if 397#ifndef WIN 398 (!(buf = (unsigned char *)malloc((size_t)nv.sz)) || 399 read(fd, buf, (unsigned int)nv.sz) != (int)nv.sz) 400#else 401 (!(buf = (unsigned char *)malloc((size_t)nv.sz)) || 402 !ReadFile(fd, buf, (unsigned int)nv.sz, &dummy, NULL) || 403 dummy != (int)nv.sz) 404#endif 405 { 406 free(nv.buf); 407 if (buf) 408 free(buf); 409 free(vn); 410 return((struct NV *)0); 411 } 412 for (p = buf, i = 0L; i < cnt; i++, p += *p*2 + 2) 413 if ((unsigned long) (p - buf) + *p * 2 + 2 < nv.sz) 414 _RkRegisterNV(&nv, p + 2, (int)*p, (int)*(p + 1)); 415 free(buf); 416 } else { 417 free(vn); 418 return((struct NV *)0); 419 } 420 *vn = nv; 421 vn->head.right->left = &vn->head; 422 vn->head.left->right = &vn->head; 423 return(vn); 424} 425 426static int 427writeNV(int fd, struct NV *nv) 428{ 429 unsigned char ll[4]; 430 unsigned char *buf = (unsigned char *)0, *r; 431 struct NVE *p, **q; 432 unsigned long i; 433#ifdef WIN 434 DWORD dummy; 435#endif 436 437 if (!nv) 438 return(-1); 439 if (nv->buf) { 440 if (!(buf = (unsigned char *)malloc((size_t)nv->sz))) 441 return(-1); 442 for (r = buf, i = 0L, q = nv->buf; i < nv->tsz; i++, q = nv->buf + i) { 443 for (p = *q; p; q = &p->next, p = *q) { 444 if ((unsigned long) (r - buf) + *(p->data)*2 + 2 < nv->sz) { 445 memcpy(r, p->data, *(p->data)*2+2); 446 r += *(p->data)*2+2; 447 } else { 448 i = nv->tsz; 449 break; 450 } 451 } 452 } 453 } 454 455#ifndef WIN 456 l_to_bst4(nv->sz, ll); 457 if (write(fd, (char *)ll, 4) == 4) { 458 l_to_bst4(nv->cnt, ll); 459 if (write(fd, (char *)ll, 4) == 4) { 460 l_to_bst4(nv->tsz, ll); 461 if (write(fd, (char *)ll, 4) == 4) { 462 l_to_bst4((unsigned long)0, ll); 463 if (write(fd, (char *)ll, 4) == 4) { 464 if (!nv->sz || 465 (buf && write(fd, buf, (int) nv->sz) == (int)nv->sz)) { 466 goto write_ok; 467 } 468 } 469 } 470 } 471 } 472#else 473 l_to_bst4(nv->sz, ll); 474 if (WriteFile(fd, (char *)ll, 4, &dummy, NULL) && dummy == 4) { 475 l_to_bst4(nv->cnt, ll); 476 if (WriteFile(fd, (char *)ll, 4, &dummy, NULL) && dummy == 4) { 477 l_to_bst4(nv->tsz, ll); 478 if (WriteFile(fd, (char *)ll, 4, &dummy, NULL) && dummy == 4) { 479 l_to_bst4((unsigned long)0, ll); 480 if (WriteFile(fd, (char *)ll, 4, &dummy, NULL) && dummy == 4) { 481 if (!nv->sz || 482 (buf && WriteFile(fd, buf, (int) nv->sz, &dummy, NULL) && 483 dummy == (int)nv->sz)) { 484 goto write_ok; 485 } 486 } 487 } 488 } 489 } 490#endif 491 if (buf) free(buf); 492 return(-1); 493 494 write_ok: 495 if (buf) free(buf); 496 return(0); 497} 498 499static void 500freeRUT(struct RUT *ruc) 501{ 502 struct CTdata *wd, *nex; 503 unsigned long lc; 504 505 for (lc = 0; lc < HN; lc++) { 506 for (wd = *(ruc->dp+lc); wd; wd = nex) { 507 nex = wd->next; 508 free(wd); 509 } 510 } 511 free(ruc->dp); 512 free(ruc); 513} 514 515struct RUT * 516LoadRUC(int fr) 517{ 518 struct WRT *wruc; 519 struct RUT *ruc; 520 unsigned long lc, csn, tick; 521 522 if (!(wruc = readWRT(fr))) 523 return (struct RUT *) 0; 524 525 if (!(ruc = allocRUT(HN))) { 526 freeWRT(wruc); 527 return (struct RUT *) 0; 528 } 529 530 ruc->sz = wruc->sz; 531 ruc->cs = 0L; 532 ruc->frst = wruc->frst; 533 ruc->tm = wruc->tm; 534 535 for (lc = 0; lc < wruc->cs; lc++) { 536 unsigned char *tmp = wruc->buf + 5 * lc; 537 csn = a_csn(tmp); 538 tick = _RkGetTick(0) - a_tick(wruc->buf+5*lc); 539 if (!entryRut(ruc, csn, tick)) { 540 freeRUT(ruc); 541 ruc = (struct RUT *) 0; 542 } 543 } 544 freeWRT(wruc); 545 return ruc; 546} 547 548#ifndef WIN 549static int SaveRUC (int, struct RUT *); 550#else 551static int SaveRUC (HANDLE, struct RUT *); 552#endif 553 554static int 555SaveRUC(int fr, struct RUT *ruc) 556{ 557 struct WRT *wruc; 558 struct CTdata *wdp; 559 unsigned long lc, count; 560 int retval; 561 562 if (!ruc) 563 return (int) 0; 564 retval = 1; 565 if (!(wruc = allocWRT(ruc->sz))){ 566 freeRUT(ruc); 567 return (int) 0; 568 } 569 wruc->sz = ruc->sz; 570 wruc->cs = ruc->cs; 571 wruc->frst = ruc->frst; 572 wruc->tm = ruc->tm; 573 574 count = 0L; 575 for (lc = 0L; lc < HN; lc++) { 576 for (wdp = *(ruc->dp+lc) ; wdp; wdp = wdp->next) { 577 WriteVal(wdp->ct[0], _RkGetTick(0) - wdp->ct[1], wruc->buf+5*count); 578 count ++; 579 } 580 } 581 if (count != ruc->cs) { 582 retval = (int) 0; 583 } 584 if (!writeToWRT(fr, wruc)) 585 retval = 0; 586 freeWRT(wruc); 587 return retval; 588} 589 590inline int 591FQscan(struct DF *df, struct DM *codm, char *file, int *w) 592{ 593 int count = 0; 594 struct HD hd; 595 struct DM *dm, *dmh; 596 unsigned char ll[4]; 597 unsigned long bitsiz, bitoff; 598 off_t off; 599 int fd; 600 601 *w = 1; 602 if ((fd = open(file, 2)) < 0) { 603 *w = 0; 604 if ((fd = open(file, 0)) < 0) 605 return -1; 606 } 607 608 for (off = 0; _RkReadHeader(fd, &hd, off) >= 0;) { 609 long start = off; 610 611 if (!hd.data[HD_DMNM].ptr || 612 (strncmp(".fq", 613 (char *)hd.data[HD_DMNM].ptr + 614 strlen((char *)hd.data[HD_DMNM].ptr) - (sizeof(".fq") - 1), 615 sizeof(".fq") - 1) && 616 strncmp(".cld", 617 (char *)hd.data[HD_DMNM].ptr + 618 strlen((char *)hd.data[HD_DMNM].ptr) - (sizeof(".cld") - 1), 619 sizeof(".cld") - 1)) ) { 620 break; 621 } 622 if (!codm->dm_xdm 623 || (long)((struct ND *)codm->dm_xdm)->time != hd.data[HD_TIME].var 624 || (long)((struct ND *)codm->dm_xdm)->rec != hd.data[HD_REC].var 625 || (long)((struct ND *)codm->dm_xdm)->can != hd.data[HD_CAN].var) 626 break; 627 off += hd.data[HD_HSZ].var; 628 (void)lseek(fd, off, 0); 629 (void)read(fd, (char *)ll, 4); 630 off += 4; 631 bitsiz = L4TOL(ll); 632 bitoff = off; 633 off += bitsiz; 634 (void)lseek(fd, off, 0); 635 dmh = &df->df_members; 636 for (dm = dmh->dm_next; dm != dmh; dm = dm->dm_next) { 637 if (!strcmp((char *)dm->dm_dicname, (char *)hd.data[HD_CODM].ptr)) { 638 struct xqm *xqm; 639 640 if (!(xqm = (struct xqm *)malloc(sizeof(struct xqm)))) 641 break; 642 dm->dm_extdata.ptr = (pointer)xqm; 643 xqm->ex_boff = bitoff; 644 xqm->ex_bsiz = bitsiz; 645 dm->dm_flags |= DM_EXIST; 646 dm->dm_offset = start; 647 count++; 648 break; 649 } 650 } 651 _RkClearHeader(&hd); 652 } 653 _RkClearHeader(&hd); 654 if (!count) { 655 (void)close(fd); 656 return -1; 657 } 658 df->df_size = off; 659 df->df_extdata.var = (long)fd; 660 return fd; 661} 662 663int 664FQopen(struct DM *dm, struct DM *qm, char *file, int mode) 665{ 666 struct DF *df; 667 struct DD *dd; 668 struct xqm *xqm; 669 int writable; 670#ifndef WIN 671 int fd; 672#else 673 HANDLE fd; 674#endif 675 676 /* missing file info ? */ 677 if (!(df = qm->dm_file) || !(dd = df->df_direct)) 678 return -1; 679 /* initialize df */ 680 if (!df->df_rcount) { 681 df->df_extdata.var = (long)FQscan(df, dm, file, &writable); 682 if (df->df_extdata.var < 0) 683 return -1; 684 if (writable) 685 df->df_flags |= DF_WRITABLE; 686 else 687 df->df_flags &= ~DF_WRITABLE; 688 df->df_flags |= DF_EXIST; 689 dd->dd_rcount++; 690 } 691 /* 692 * this member is not included. 693 */ 694 if (!(qm->dm_flags & DM_EXIST)) 695 return -1; 696 if (strcmp(dm->dm_dicname, qm->dm_dicname)) 697 return -1; 698 /* */ 699 xqm = (struct xqm *)qm->dm_extdata.ptr; 700#ifndef WIN 701 fd = df->df_extdata.var; 702#else 703 fd = df->df_extdata.hnd; 704#endif 705 706 qm->dm_rut = (struct RUT *)0; 707 qm->dm_nv = (struct NV *)0; 708 /* dispatch */ 709 qm->dm_qbits = (unsigned char *)malloc((unsigned)xqm->ex_bsiz); 710 if (!qm->dm_qbits) 711 return -1; 712#ifndef WIN 713 (void)lseek(fd, xqm->ex_boff, 0); 714 (void)read(fd, (char *)qm->dm_qbits, (int)xqm->ex_bsiz); 715#else 716 { 717 DWORD dummy; 718 719 (void)SetFilePointer(fd, xqm->ex_boff, NULL, FILE_BEGIN); 720 (void)ReadFile(fd, (char *)qm->dm_qbits, (int)xqm->ex_bsiz, 721 &dummy, NULL); 722 } 723#endif 724 qm->dm_rut = LoadRUC(fd); 725 qm->dm_nv = readNV(fd); 726 df->df_rcount++; 727 if ((mode & DM_WRITABLE) && (df->df_flags & DF_WRITABLE)) { 728 qm->dm_flags |= DM_WRITABLE; 729 } 730 return 0; 731} 732 733/* 734 * CLOSE 735 */ 736/*ARGSUSED*/ 737void 738FQclose(struct RkContext *cx, struct DM *dm, struct DM *qm, char *file) 739{ 740 struct DF *df = qm->dm_file; 741 struct xqm *xqm; 742#ifndef WIN 743 int fd = (int)df->df_extdata.var; 744#else 745 HANDLE fd = df->df_extdata.hnd; 746#endif 747 748 xqm = (struct xqm *)qm->dm_extdata.ptr; 749 if (xqm) { 750 if (qm->dm_qbits) { 751 if (qm->dm_flags & DM_UPDATED) { 752#ifndef WIN 753 (void)lseek(fd, xqm->ex_boff, 0); 754 (void)write(fd, (char *)qm->dm_qbits, (int)xqm->ex_bsiz); 755#else 756 DWORD dummy; 757 758 (void)SetFilePointer(fd, xqm->ex_boff, NULL, FILE_BEGIN); 759 (void)ReadFile(fd, (char *)qm->dm_qbits, (int)xqm->ex_bsiz, 760 &dummy, NULL); 761#endif 762 }; 763 free(qm->dm_qbits); 764 qm->dm_qbits = (unsigned char *)0; 765 } 766 } 767 if (qm->dm_rut) { 768 if (qm->dm_flags & DM_UPDATED) 769 SaveRUC(fd, qm->dm_rut); 770 freeRUT(qm->dm_rut); 771 qm->dm_rut = (struct RUT *)0; 772 } 773 if (qm->dm_nv) { 774 if (qm-> dm_flags & DM_UPDATED) 775 writeNV(fd, qm->dm_nv); 776 abolishNV(qm->dm_nv); 777 qm->dm_nv = (struct NV *)0; 778 } 779 qm->dm_flags &= ~DM_UPDATED; 780 if (--df->df_rcount == 0) { 781 struct DM *dmh, *ddm; 782 783#ifndef WIN 784 (void)close(fd); 785#else 786 (void)CloseHandle(fd); 787#endif 788 dmh = &df->df_members; 789 for (ddm = dmh->dm_next; ddm != dmh; ddm = ddm->dm_next) { 790 xqm = (struct xqm *)ddm->dm_extdata.ptr; 791 if (xqm) { 792 free(xqm); 793 ddm->dm_extdata.ptr = (pointer)0; 794 } 795 } 796 } 797} 798 799int 800FQsync(struct RkContext *cx, struct DM *dm, struct DM *qm, char *file) 801/* ARGSUSED */ 802{ 803 struct DF *df = qm->dm_file; 804 struct xqm *xqm; 805 int rv; 806#ifndef WIN 807 int fd = (int)df->df_extdata.var; 808#else 809 HANDLE fd = df->df_extdata.hnd; 810#endif 811 812 rv = 0; 813 xqm = (struct xqm *)qm->dm_extdata.ptr; 814 if (xqm) { 815 if (qm->dm_qbits) { 816 if (qm->dm_flags & DM_UPDATED) { 817#ifndef WIN 818 (void)lseek(fd, xqm->ex_boff, 0); 819 if (write(fd, (char *)qm->dm_qbits, (int)xqm->ex_bsiz) != 820 (int) xqm->ex_bsiz) 821 rv = -1; 822#else 823 DWORD dummy; 824 825 (void)SetFilePointer(fd, xqm->ex_boff, NULL, FILE_BEGIN); 826 if (!WriteFile(fd, (char *)qm->dm_qbits, (int)xqm->ex_bsiz, 827 &dummy, NULL) || (DWORD)xqm->ex_bsiz != dummy) { 828 rv = -1; 829 } 830#endif 831 if (qm->dm_rut) 832 rv = SaveRUC(fd, qm->dm_rut) - 1; 833 if (qm->dm_nv) 834 rv = writeNV(fd, qm->dm_nv); 835 } 836 if (!rv) 837 qm->dm_flags &= ~DM_UPDATED; 838 } 839 } 840 return (rv); 841} 842 843 844