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/************************************************************************/ 24/* THIS SOURCE CODE IS MODIFIED FOR TKO BY T.MURAI 1997 25/************************************************************************/ 26 27 28#if !defined(lint) && !defined(__CODECENTER__) 29 static char rcsid[]="$Id: dd.c 10525 2004-12-23 21:23:50Z korli $"; 30#endif 31/*LINTLIBRARY*/ 32 33#include "RKintern.h" 34 35#include <string.h> 36#include <unistd.h> 37#include <ctype.h> 38 39#include <stdio.h> 40#include <time.h> 41#include <sys/types.h> 42#include <sys/stat.h> 43#include <fcntl.h> 44 45#define cx_gwt cx_extdata.ptr 46#define STRCMP(d, s) strcmp((char *)(d), (char *)(s)) 47 48#define RK_READABLE 'r' 49#define RK_WRITABLE 'w' 50 51static void _RkFreeDM(struct DM *dm); 52static struct DM *_RkAllocDM(struct DF *df, unsigned char *dicname, unsigned char *nickname, int iclass); 53static struct DF *_RkCreateDF(struct DD *dd, unsigned char *lnk, int type); 54static void _RkFreeDF(struct DF *df); 55static struct DF *_RkAllocDF(struct DD *dd, unsigned char *lnk, int type); 56static int _RkParseDicsDir(char *line, char *lnk, char *member, char *nickname, int *dftype, int *dmclass, int *r_return, int *w_return); 57static void _RkFreeDD(struct DD *dd); 58 59/* 60* DM 61*/ 62inline 63struct DM * 64_RkCreateDM(struct DF *df, unsigned char *dicname, unsigned char *nickname, int iclass) 65{ 66 struct DM *dm; 67 68 dm = (struct DM *)calloc(1, sizeof(struct DM)); 69 if (dm) { 70 dm->dm_next = dm->dm_prev = dm; 71 dm->dm_file = df; 72 dm->dm_dicname = strdup((char *)dicname); 73 if (dm->dm_dicname) { 74 dm->dm_nickname = strdup((char *)nickname); 75 if (dm->dm_nickname) { 76 dm->dm_class = iclass; 77 dm->dm_flags = dm->dm_packbyte = dm->dm_rcount = 0; 78 dm->dm_gram = (struct RkGram *)0; 79 dm->dm_extdata.ptr = (pointer)0; 80 dm->dm_rut = (struct RUT *)0; 81 dm->dm_nv = (struct NV *)0; 82 return dm; 83 } 84 free(dm->dm_dicname); 85 } 86 free(dm); 87 } 88 return 0; 89} 90 91static 92void 93_RkFreeDM(struct DM *dm) 94{ 95if (dm) { 96 dm->dm_next->dm_prev = dm->dm_prev; 97 dm->dm_prev->dm_next = dm->dm_next; 98 if (dm->dm_dicname) 99 free(dm->dm_dicname); 100 if (dm->dm_nickname) 101 free(dm->dm_nickname); 102 free(dm); 103}; 104} 105 106inline 107struct DM * 108_RkAllocDM(struct DF *df, unsigned char *dicname, unsigned char *nickname, int iclass) 109{ 110 struct DM *m, *mh = &df->df_members; 111 112 for (m = mh->dm_next; m != mh; m = m->dm_next) { 113 if (!STRCMP(m->dm_dicname, dicname)) { 114 return m; 115 } 116 } 117 m = _RkCreateDM(df, dicname, nickname, iclass); 118 if (m) { 119 m->dm_next = mh; 120 m->dm_prev = mh->dm_prev; 121 mh->dm_prev = m; 122 m->dm_prev->dm_next = m; 123 } 124 return(m); 125} 126 127/* 128* DF 129*/ 130inline 131struct DF * 132_RkCreateDF(struct DD *dd, unsigned char *lnk, int type) 133{ 134 struct DF *df; 135 136 df = (struct DF *)calloc(1, sizeof(struct DF)); 137 if (df) { 138 struct DM *dm = &df->df_members; 139 140 df->df_next = df->df_prev = df; 141 df->df_direct = dd; 142 dm->dm_next = dm->dm_prev = dm; 143 144 if (!(df->df_link = strdup((char *)lnk))) { 145 free(df); 146 return(0); 147 }; 148 df->df_rcount = 0; 149 df->df_type = type; 150 df->df_extdata.ptr = (pointer)0; 151 }; 152 return(df); 153} 154 155static 156void 157_RkFreeDF(struct DF *df) 158{ 159 struct DM *m, *n; 160 161 if (df) { 162 struct DM *mh = &df->df_members; 163 164 /* remove all members in this file */ 165 for (m = mh->dm_next; m != mh; m = n) { 166 n = m->dm_next; 167 _RkFreeDM(m); 168 }; 169 /* unlink from directory list */ 170 df->df_next->df_prev = df->df_prev; 171 df->df_prev->df_next = df->df_next; 172 if (df->df_link) 173 free(df->df_link); 174 free(df); 175 }; 176} 177 178static 179struct DF * 180_RkAllocDF(struct DD *dd, unsigned char *lnk, int type) 181{ 182 struct DF *f; 183 struct DF *fh = &dd->dd_files; 184 185 for (f = fh->df_next; f != fh; f = f->df_next) { 186 if (!STRCMP(f->df_link, lnk)) { 187 return(f); 188 } 189 } 190 f = _RkCreateDF(dd, lnk, type); 191 if (f) { 192 f->df_next = fh; 193 f->df_prev = fh->df_prev; 194 fh->df_prev = f; 195 f->df_prev->df_next = f; 196 }; 197 return(f); 198} 199 200int 201_RkRealizeDF(struct DF *df) 202{ 203 struct DD *dd = df->df_direct; 204 char *pathname; 205#ifdef WIN 206 int oldmask; 207#else 208 unsigned long oldmask; 209#endif 210 int t; 211 212 _RkRealizeDD(dd); 213 /* create path filename */ 214 pathname = _RkCreatePath(df->df_direct, df->df_link); 215 if (pathname) { 216 oldmask = umask(2); 217 /* create a file */ 218#ifdef WIN 219{ 220 HANDLE fd; 221 fd = CreateFile(pathname, GENERIC_WRITE, 222 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 223 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 224 if (fd == INVALID_HANDLE_VALUE) { 225 t = -1; 226 }else{ 227 CloseHandle(fd); 228 t = 0; 229 } 230} 231#else 232 t = close(creat(pathname, CREAT_MODE)); 233#endif 234 free(pathname); 235 (void)umask(oldmask); 236 if (t >= 0) { 237 return 0; 238 } 239 } 240 return -1; 241} 242 243static int 244_RkParseDicsDir(char *line, char *lnk, char *member, char *nickname, int *dftype, int *dmclass, int *r_return, int *w_return) /* ¥¢¥¯¥»¥¹¸¢¤òÊÖ¤¹½ê */ 245{ 246 char *s, *d, *t, par, ch; 247 int count; 248 249 *dftype = -1; 250 *dmclass = -1; 251 *r_return = *w_return = 0; /* ¸¢Íø̵¤· */ 252 if (!isalpha(line[0])) 253 return -1; 254 255 /* parse line %s.s(%s.%s) -%s--%c%c- */ 256 257 for (s = line; *s && isspace(*s);) { 258 s++; 259 } 260 if (!*s) 261 return -1; 262 263 /* link name */ 264 for (d = lnk, count = 0; *s && *s != '('; count++) { 265 if (count < RK_LINK_BMAX) { 266 *d++ = *s++; 267 } else { 268 return -1; 269 } 270 } 271 if (!count) 272 return -1; 273 if (count++ < RK_LINK_BMAX) { 274 *d = 0; 275 } 276 if (!*s++) 277 return -1; 278 if (count > RK_LINK_BMAX) 279 return -1; 280 if (!(t = (char *)strrchr(lnk, '.'))) 281 return -1; 282 if (!STRCMP(t, ".d") || !STRCMP(t, ".cbd")) 283 *dftype = DF_PERMDIC; 284 else if (!STRCMP(t, ".t") || !STRCMP(t, ".ctd")) 285 *dftype = DF_TEMPDIC; 286 else if (!STRCMP(t, ".fq") || !STRCMP(t, ".cld")) 287 *dftype = DF_FREQDIC; 288 else if (!STRCMP(t, ".ruc")) 289 *dftype = DF_RUCDIC; 290 else 291 return -1; 292 /* member name */ 293 for (d = member, count = 0; *s && *s != ')'; count++) { 294 if (count < RK_MEMBER_BMAX) { 295 *d++ = *s++; 296 } else { 297 return -1; 298 } 299 } 300 if (!count) 301 return -1; 302 if (count++ < RK_MEMBER_BMAX) 303 *d = 0; 304 if (!*s++) 305 return -1; 306 if (count > RK_MEMBER_BMAX) 307 return -1; 308 if (!(t = (char *)strrchr(member, '.'))) 309 return -1; 310 if (!STRCMP(t, ".mwd")) 311 *dmclass = ND_MWD; 312 else if (!STRCMP(t, ".swd")) 313 *dmclass = ND_SWD; 314 else if (!STRCMP(t, ".pre")) 315 *dmclass = ND_PRE; 316 else if (!STRCMP(t, ".suc")) 317 *dmclass = ND_SUC; 318 else 319 return -1; 320 /* nickname */ 321 for (; *s && isspace(*s);) { 322 s++; 323 } 324 if (!(par = *s++)) 325 return -1; 326 327 for (d = nickname, count = 0; *s && *s != par; count++) { 328 if (count < RK_NICK_BMAX) { 329 *d++ = *s++; 330 } else { 331 return -1; 332 } 333 } 334 if (!count) 335 return -1; 336 if (count++ < RK_NICK_BMAX) 337 *d = 0; 338 if (!*s++) 339 return -1; 340 if (count > RK_NICK_BMAX) 341 return -1; 342 343 *w_return = 1; /* ²¼°Ì¸ß´¹¤Î¤¿¤á¤³¤³¤Þ¤Ç¤·¤«¤Ê¤¤¾ì¹ç¤Ï writable ¤Ë¤¹¤ë */ 344 345 while ((ch = *s) && ch != par) { 346 s++;/* 1 ¥Õ¥£¡¼¥ë¥ÉÆɤßÈô¤Ð¤· */ 347 } 348 349 if (*s++ /* == par ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤ï¤± */) { 350 /* ¥¢¥¯¥»¥¹¸¢´ØÏ¢ */ 351 *w_return = 0; 352 while ((ch = *s) && ch != par) { 353 if (ch == RK_READABLE) { 354 *r_return = 1; 355 } 356else if (ch == RK_WRITABLE) { 357 *w_return = 1; 358 } else { 359 return -1; 360} 361 s++; 362 } 363 } 364 365 return 0; 366} 367 368/* 369* DD - dictonary directory record 370*/ 371inline 372struct DD * 373_RkCreateDD(unsigned char *path, unsigned char *name) 374{ 375 struct DD *dd; 376 377 dd = (struct DD *)calloc(1, sizeof(struct DD)); 378 if (dd) { 379 dd->dd_next = dd->dd_prev = dd; 380 dd->dd_path = strdup((char *)path); 381 if (dd->dd_path) { 382 dd->dd_name = strdup((char *)name); 383 if (dd->dd_name) { 384 dd->dd_rcount = 0; 385 dd->dd_files.df_next = dd->dd_files.df_prev = &dd->dd_files; 386 dd->dd_flags = 0; 387 dd->dd_text.ddt_next = dd->dd_text.ddt_prev = &dd->dd_text; 388 return dd; 389 } 390 free(dd->dd_path); 391 } 392 free(dd); 393 } 394 return (struct DD *)0; 395} 396 397static 398void 399_RkFreeDD(struct DD *dd) 400{ 401 struct DF *f, *g; 402 struct DF *fh = &dd->dd_files; 403 struct DDT *ddLines; 404 struct DDT *p, *q; 405 406 if (dd) { 407 for (f = fh->df_next; f != fh; f = g) { 408 g = f->df_next; 409 _RkFreeDF(f); 410 }; 411 dd->dd_next->dd_prev = dd->dd_prev; 412 dd->dd_prev->dd_next = dd->dd_next; 413 if (dd->dd_path) 414 free(dd->dd_path); 415 if (dd->dd_name) 416 free(dd->dd_name); 417 418 ddLines = &dd->dd_text; 419 for (p = ddLines->ddt_next; p != ddLines; p = q) { 420 q = p->ddt_next; 421 p->ddt_next->ddt_prev = p->ddt_prev; 422 p->ddt_prev->ddt_next = p->ddt_next; 423 if (p->ddt_spec) 424 free(p->ddt_spec); 425 free(p); 426 }; 427 free(dd); 428 }; 429} 430 431inline struct DD * 432_RkLookupDD(struct DD *dd, unsigned char *name) 433{ 434 struct DD *d; 435 436 for (d = dd->dd_next; d != dd; d = d->dd_next) 437 if (!STRCMP(d->dd_name, name)) 438 return d; 439 return (struct DD *)0; 440} 441 442/* _RkReadDD 443* read a DD directory using dics.dir file. 444*/ 445inline struct DD * 446_RkReadDD(char *name) 447{ 448 char *dics_dir = "/dics.dir"; 449 struct DD *dd = (struct DD *)0; 450 struct DF *df; 451 struct DM *dm; 452 struct DDT *ddLines; 453 struct DDT *ddt; 454 struct RkParam *sx = RkGetSystem(); 455 int r, w; 456 int fdes; 457 FILE *fp; 458 459#ifndef USE_MALLOC_FOR_BIG_ARRAY 460 char direct[RK_PATH_BMAX]; 461 char file[RK_PATH_BMAX]; 462 char path[RK_PATH_BMAX]; 463 unsigned char line[RK_LINE_BMAX]; 464 unsigned char lnk[RK_LINK_BMAX+1]; 465 unsigned char member[RK_MEMBER_BMAX+1]; 466 unsigned char nickname[RK_NICK_BMAX+1]; 467#else 468 char *direct, *file, *path; 469 unsigned char *line, *lnk, *member, *nickname; 470 direct = (char *)malloc(RK_PATH_BMAX); 471 file = (char *)malloc(RK_PATH_BMAX); 472 path = (char *)malloc(RK_PATH_BMAX); 473 line = (unsigned char *)malloc(RK_LINE_BMAX); 474 lnk = (unsigned char *)malloc(RK_LINK_BMAX + 1); 475 member = (unsigned char *)malloc(RK_MEMBER_BMAX + 1); 476 nickname = (unsigned char *)malloc(RK_NICK_BMAX + 1); 477 if (!direct || !file || !path || !line || !lnk || !member || !nickname) { 478 if (direct) free(direct); 479 if (file) free(file); 480 if (path) free(path); 481 if (line) free(line); 482 if (lnk) free(lnk); 483 if (member) free(member); 484 if (nickname) free(nickname); 485 return dd; 486 } 487#endif 488 489 /* create dd even if there is no directory or dics.dir file */ 490 sprintf(path, "%s/%s", sx->ddhome, name); 491 dd = _RkCreateDD((unsigned char *)path, (unsigned char *)name); 492 if (!dd) { 493 goto return_dd; 494 } 495 /* jisho table ga aruka ? */ 496 if (strlen(path) + strlen(dics_dir) + 1 >= RK_PATH_BMAX) { 497 dd = (struct DD *)0; 498 goto return_dd; 499 } 500 sprintf(direct, "%s%s", path, dics_dir); 501 502 /* check for accessing right */ 503 if ((fdes = open(direct, 0)) < 0) { /* no file? */ 504 dd->dd_flags |= DD_WRITEOK; 505 } 506else { 507 struct stat buf; 508 509 if (fstat(fdes, &buf) == 0) { 510 if (buf.st_mode & 004) { /* if readable for others */ 511 dd->dd_flags |= DD_READOK; 512 } 513 } 514 close(fdes); 515 if (!close(open(direct, 2))) { 516 dd->dd_flags |= DD_WRITEOK; 517 } 518} 519 520 fp = fopen(direct, "r"); 521if (!fp) { 522 goto return_dd; 523} 524 ddLines = &dd->dd_text; 525 /* read dics_dir lines */ 526 while (fgets((char *)line, RK_LINE_BMAX, fp)) 527{ 528 int dftype, dmclass; 529 530 ddt = (struct DDT *)malloc(sizeof(struct DDT)); 531 if (!ddt) 532 continue; 533 534 ddt->ddt_spec = (char *)malloc(strlen((char *)line) + 2); /* 2 for \n\0 */ 535 if (!ddt->ddt_spec) 536 { 537 free(ddt); 538 continue; 539 }; 540{ 541 int len = strlen((char *)line); 542 if (line[len - 1] == '\n') { 543 line[len - 1] = '\0'; 544 } 545} 546 strcpy(ddt->ddt_spec, (char *)line); 547 ddt->ddt_next = ddLines; 548 ddt->ddt_prev = ddLines->ddt_prev; 549 ddt->ddt_status = 1; 550 ddLines->ddt_prev = ddt; 551 ddt->ddt_prev->ddt_next = ddt; 552 553 if (_RkParseDicsDir(ddt->ddt_spec, (char *)lnk, (char *)member, 554 (char *)nickname, &dftype, &dmclass, &r, &w) < 0) { 555 continue; 556 } 557 558 if (strlen((char *)path) + strlen((char *)lnk) + 1 >= RK_PATH_BMAX) 559 continue; 560 sprintf(file, "%s/%s", path, (char *)lnk); 561 if (close(open(file, 0)) < 0) 562 continue; 563 df = _RkAllocDF(dd, lnk, dftype); 564 if (df) { 565 dm = _RkAllocDM(df, member, nickname, dmclass); 566 if (dm) { 567 dm->dm_line = ddt; 568 if (r) { 569 dm->dm_flags |= DM_READOK; 570 } 571 if (w) { 572 dm->dm_flags |= DM_WRITEOK; 573 } 574 ddt->ddt_status = 0; 575 }; 576 }; 577}; 578 (void)fclose(fp); 579 580return_dd: 581#ifdef USE_MALLOC_FOR_BIG_ARRAY 582 free(direct); 583 free(file); 584 free(path); 585 free(line); 586 free(lnk); 587 free(member); 588 free(nickname); 589#endif 590 return dd; 591} 592 593inline 594struct DD * 595_RkOpenDD(char *name) 596{ 597 struct RkParam *sx = RkGetSystem(); 598 struct DD *dd; 599 struct DD *knownDD = &sx->dd; 600 601 dd = _RkLookupDD(knownDD, (unsigned char *)name); 602 if (dd) 603 return dd; 604 dd = _RkReadDD(name); 605 /* link to the known list */ 606 if (dd) { 607 dd->dd_next = knownDD; 608 dd->dd_prev = knownDD->dd_prev; 609 knownDD->dd_prev = dd; 610 dd->dd_prev->dd_next = dd; 611 }; 612 return dd; 613} 614 615char * 616_RkCreatePath(struct DD *dd, char *name) 617{ 618 unsigned sz; 619 char *ddname; 620 621 if (!dd || !dd->dd_path || !name) 622 return (char *)0; 623 sz = strlen(dd->dd_path) + strlen(name) + 2; 624 ddname = (char *)malloc(sz); 625 if (ddname) { 626 sprintf(ddname, "%s/%s", dd->dd_path, name); 627 }; 628 return ddname; 629} 630 631char * 632_RkCreateUniquePath(struct DD *dd, char *proto) 633{ 634 static char newLinkName[RK_LINK_BMAX]; 635 unsigned i; 636 637 /* now checking ... */ 638 if (!dd || !dd->dd_path || !proto) 639 return (char *)0; 640 /* create directory */ 641 if (_RkRealizeDD(dd) < 0) 642 return (char *)0; 643 /* try at most 100 times */ 644 for (i = 1; i < 100; i++) { 645 int count; 646 struct DF *f; 647 struct DF *fh = &dd->dd_files; 648 unsigned long oldmask; 649 char *filename; 650 651 count = 0; 652 sprintf(newLinkName, proto, i); 653 for (f = fh->df_next; f != fh; f = f->df_next) 654 if (!STRCMP(f->df_link, newLinkName)) 655 count++; 656 if (count) 657 continue; 658 filename = _RkCreatePath(dd, newLinkName); 659 if (filename) { 660 oldmask = umask(2); 661 662 if (close(creat(filename, CREAT_MODE)) < 0) 663 count++; 664 free(filename); 665 (void)umask(oldmask); 666 if (!count) 667 return newLinkName; 668 }; 669 }; 670 return (char *)0; 671} 672 673char * 674_RkMakePath(struct DF *df) 675{ 676 if (df) 677 return _RkCreatePath(df->df_direct, df->df_link); 678 else 679 return (char *)0; 680} 681 682int 683_RkRealizeDD(struct DD *dd) 684{ 685 struct DDT *ddLines; 686 struct DDT *ddt; 687 int n; 688 int ret = -1; 689 int tmpres; 690 int fdes; 691 long tloc; 692 693 char *whattime, *header, *dicsdir, *backup; 694 whattime = (char *)malloc(RK_LINE_BMAX); 695 header = (char *)malloc(RK_LINE_BMAX); 696 dicsdir = (char *)malloc(RK_PATH_BMAX); 697 backup = (char *)malloc(RK_PATH_BMAX); 698 if (!whattime || !header || !dicsdir || !backup) { 699 if (whattime) free(whattime); 700 if (header) free(header); 701 if (dicsdir) free(dicsdir); 702 if (backup) free(backup); 703 return ret; 704 } 705 /* create directory if needed */ 706 if (close(open(dd->dd_path, 0, 0664)) < 0) { 707 if (mkdir(dd->dd_path, MKDIR_MODE) < 0) { 708 goto return_ret; 709 } 710 /* change owner 711 if (pw) 712 chown(dd->dd_path, getuid(), pw->pw_gid); 713 */ 714 } 715 716 /* dics.dir */ 717 sprintf(dicsdir, "%s/dics.dir", dd->dd_path); 718 backup[0] = 0; 719 tmpres = close(open(dicsdir, 0)); 720 if (tmpres >= 0) { 721 sprintf(backup, "%s/#dics.dir", dd->dd_path); 722 if (rename(dicsdir, backup)) { 723 goto return_ret; 724 } 725 }; 726 /* create dics.dir */ 727 728 if ((fdes = creat(dicsdir, CREAT_MODE)) < 0) 729 { 730 if (backup[0]) { 731 rename(backup, dicsdir); 732 } 733 goto return_ret; 734 }; 735 /* header */ 736 tloc = time(0); 737 strcpy(whattime, ctime(&tloc)); 738 whattime[strlen(whattime)-1] = 0; 739 n = sprintf(header, "#CANNA dics.dir [%s] %s\n", whattime, dd->dd_name); 740 // n = strlen(header); 741 tmpres = write(fdes, header, n); 742 if (tmpres != n) { 743 if (backup[0]) { 744 rename(backup, dicsdir); 745 } 746 else 747 unlink(dicsdir); 748 close(fdes); 749 goto return_ret; 750 }; 751 /* fill up bodies */ 752 ddLines = &dd->dd_text; 753 for (ddt = ddLines->ddt_next; ddt != ddLines; ddt = ddt->ddt_next) 754 if (strncmp(ddt->ddt_spec, "#CANNA ", 7)) { 755 n = strlen(ddt->ddt_spec); 756 ddt->ddt_spec[n] = '\n'; 757 tmpres = write(fdes, ddt->ddt_spec, n + 1); 758 if (tmpres > 0) { 759 tmpres--; /* for \n */ 760 } 761 762 763 ddt->ddt_spec[n] = '\0'; 764 765 if (tmpres != n) { 766 if (backup[0]) { 767 rename(backup, dicsdir); 768 } 769 else 770 unlink(dicsdir); 771 close(fdes); 772 goto return_ret; 773 }; 774 }; 775 close(fdes); 776 /* change owner 777 if (pw) 778 chown(dicsdir, getuid(), pw->pw_gid); 779 */ 780 ret = 0; 781 782return_ret: 783 free(whattime); 784 free(header); 785 free(dicsdir); 786 free(backup); 787 return ret; 788} 789 790/* 791* DDP 792*/ 793int 794_RkIsInDDP(struct DD **ddp, struct DD *dd) 795{ 796 while (*ddp) 797 if (*ddp++ == dd) 798 return 1; 799 return 0; 800} 801 802static 803int 804_RkCountDDP( 805 struct DD **ddp) 806{ 807 int count = 0; 808 809 if (ddp) 810 while (ddp[count]) count++; 811 return count; 812} 813 814struct DD ** 815_RkCopyDDP( 816 struct DD **ddp) 817{ 818 struct DD **newc = (struct DD **)0; 819 int i; 820 struct DD *dd; 821 822 if (ddp) { 823 int count = _RkCountDDP(ddp); 824 825 newc = (struct DD **)calloc(count + 1, (unsigned)sizeof(struct DD *)); 826 if (newc) 827 for (i = 0; (dd = newc[i] = ddp[i]) != (struct DD *)0 ; i++) 828 dd->dd_rcount++; 829 }; 830 return newc; 831} 832 833inline 834struct DD ** 835_RkAppendDDP( 836 struct DD **ddp, 837 struct DD *dd) 838{ 839 struct DD **newc; 840 int i; 841 int count = _RkCountDDP(ddp); 842 843 newc = (struct DD **)calloc(count + 2, (unsigned)sizeof(struct DD *)); 844 if (newc) { 845 if (ddp) { 846 for (i = 0; i < count; i++) newc[i] = ddp[i]; 847 free(ddp); 848 }; 849 newc[count++] = dd; 850 newc[count] = (struct DD *)0; 851 dd->dd_rcount++; 852 } else 853 newc = ddp; 854 return newc; 855} 856 857struct DD ** 858_RkCreateDDP( 859 char *ddpath) 860{ 861 char *d, *s; 862 struct DD *dd; 863 struct DD **ddp = (struct DD **)0; 864#ifndef USE_MALLOC_FOR_BIG_ARRAY 865 char dir[RK_PATH_BMAX + 1]; 866#else 867 char *dir = (char *)malloc(RK_PATH_BMAX + 1); 868 if (!dir) { 869 return ddp; 870 } 871#endif 872 873 for (s = ddpath; *s; ) { 874 int count; 875 876 for (;*s && isspace(*s);) { 877 s++; 878 } 879 if (!*s) 880 break; 881 for (d = dir, count = 0; *s; count++) 882 if (*s == ':') { 883 s++; 884 break; 885 } else { 886 if (count < RK_PATH_BMAX) 887 *d++ = *s; 888 s++; 889 }; 890 *d = 0; 891 dd = _RkOpenDD(dir); 892 if (dd) 893 ddp = _RkAppendDDP(ddp, dd); 894 }; 895#ifdef USE_MALLOC_FOR_BIG_ARRAY 896 free(dir); 897#endif 898 return ddp; 899} 900 901void 902_RkFreeDDP( 903 struct DD **ddp) 904{ 905 struct DD *dd; 906 int i; 907 908 if (ddp) { 909 for (i = 0; (dd = ddp[i]) != (struct DD *)0 ; i++) 910 if (--dd->dd_rcount == 0) { 911 _RkFreeDD(dd); 912 }; 913 free(ddp); 914 }; 915} 916 917/* _RkSearchDDP/Q 918* search dictionary file by nickname 919*/ 920struct DM * 921_RkSearchDDP( 922 struct DD **ddp, 923 char *name) 924{ 925 struct DD *dd; 926 struct DF *f, *fh; 927 struct DM *m, *mh; 928 int i; 929 930 if (ddp) { 931 for (i = 0; (dd = ddp[i]) != (struct DD *)0 ; i++) { 932 fh = &dd->dd_files; 933 for (f = fh->df_next; f && (f != fh); f = f->df_next) { 934 if (f->df_type == DF_FREQDIC) { 935 /* Ʊ¤¸¥Ç¥£¥ì¥¯¥È¥ê³¬ÁØ¤Ç¤Ï .fq ¤«¤éõ¤¹ */ 936 mh = &f->df_members; 937 for (m = mh->dm_next; m != mh; m = m->dm_next) { 938 if (!STRCMP(m->dm_nickname, name)) { 939 return m; 940 } 941 } 942 } 943 } 944 fh = &dd->dd_files; 945 for (f = fh->df_next; f && (f != fh); f = f->df_next) { 946 if (f->df_type != DF_RUCDIC && f->df_type != DF_FREQDIC) { 947 mh = &f->df_members; 948 for (m = mh->dm_next ; m != mh; m = m->dm_next) { 949 if (!STRCMP(m->dm_nickname, name)) { 950 return m; 951 } 952 } 953 } 954 } 955 } 956 } 957 return (struct DM *)0; 958} 959 960/* _RkSearchDDQ 961¤¢¤ë¥¿¥¤¥×¤Î¼½ñ¤À¤±Ãµ¤·¤ÆÊÖ¤¹ 962*/ 963 964struct DM * 965_RkSearchDDQ( 966 struct DD **ddp, 967 char *name, 968 int type) 969{ 970 struct DD *dd; 971 struct DF *f, *fh; 972 struct DM *m, *mh; 973 int i; 974 975 if (ddp) { 976 for (i = 0; (dd = ddp[i]) != (struct DD *)0 ; i++) { 977 fh = &dd->dd_files; 978 for (f = fh->df_next; f && (f != fh); f = f->df_next) 979 if (f->df_type == (unsigned)type) { 980 mh = &f->df_members; 981 for (m = mh->dm_next; m != mh; m = m->dm_next) { 982 if (!STRCMP(m->dm_nickname, name)) 983 return(m); 984 }; 985 }; 986 }; 987 }; 988 return((struct DM *)0); 989} 990 991/* 992_RkSearchUDDP() 993 ºÇ½é¤Ë¸«ÉÕ¤«¤ë¤Î¤¬¥·¥¹¥Æ¥à¼½ñ¤Ë¤¢¤ë¤ä¤Ä¤«¤É¤¦¤«¤òȽÃǤ·¤Ê¤¬¤éÊÖ¤¹ 994*/ 995 996struct DM * 997_RkSearchUDDP( 998 struct DD **ddp, 999 unsigned char *name) 1000{ 1001 struct DM *dm = _RkSearchDDP(ddp, (char *)name); 1002 1003 if (dm && STRCMP(dm->dm_file->df_direct->dd_name, SYSTEM_DDHOME_NAME)) { 1004 return dm; 1005 } 1006 return((struct DM *)0); 1007} 1008 1009/* ¼½ñ¥á¥ó¥Ð̾¤Ç¼½ñ¤òõ¤¹ 1010 1011³Ø½¬¥Õ¥¡¥¤¥ë¤Ï½ü³°¤·¤Æõ¤¹ 1012*/ 1013 1014struct DM * 1015_RkSearchDDMEM( 1016 struct DD **ddp, 1017 char *name) 1018{ 1019 struct DD *dd; 1020 struct DF *f, *fh; 1021 struct DM *m, *mh; 1022 int i; 1023 1024 if (ddp) { 1025 for (i = 0; (dd = ddp[i]) != (struct DD *)0 ; i++) { 1026 fh = &dd->dd_files; 1027 for (f = fh->df_next; f && (f != fh); f = f->df_next) { 1028 if (f->df_type != DF_FREQDIC && f->df_type != DF_RUCDIC) { 1029 mh = &f->df_members; 1030 for (m = mh->dm_next; m != mh; m = m->dm_next) { 1031 if (!STRCMP(m->dm_dicname, name)) { 1032 return m; 1033 } 1034 } 1035 } 1036 } 1037 } 1038 } 1039 return (struct DM *)0; 1040} 1041 1042/* 1043_RkSearchDicWithFreq -- ¼½ñ(³Ø½¬¼½ñ¤ò´Þ¤à)¤òõ¤·ÊÖ¤¹¡£ 1044 1045ddpath ¤ÎÀèƬ¤«¤é½ç¤Ë³Ø½¬¥Õ¥¡¥¤¥ë¤¢¤ë¤¤¤Ï¼½ñ¤ò¤µ¤¬¤·¡¢¤ß¤Ä¤«¤Ã¤¿¤Î 1046¤òÊÖ¤¹¡£³Ø½¬¥Õ¥¡¥¤¥ë¤¬¤ß¤Ä¤«¤Ã¤¿¾ì¹ç¤Ë¤Ï³Ø½¬¥Õ¥¡¥¤¥ë¤Î¸µ¼½ñ¤òõ¤·¤Æ 1047¤½¤ì¤ò dm ¤ËÊÖ¤·¡¢³Ø½¬¥Õ¥¡¥¤¥ë¼«¿È¤Ï qmp ¤ÎÀè¤Ë³ÊǼ¤·¤ÆÊÖ¤¹¡£ 1048 1049*/ 1050 1051struct DM * 1052_RkSearchDicWithFreq( 1053 struct DD **ddpath, 1054 char *name, 1055 struct DM **qmp) 1056{ 1057 struct DD *udd[2]; 1058 struct DM *dm, *qm; 1059 1060 udd[1] = (struct DD *)0; 1061 1062 *qmp = (struct DM *)0; 1063 while (*ddpath) { 1064 udd[0] = *ddpath; 1065 qm = _RkSearchDDQ(udd, name, DF_FREQDIC); 1066 if (qm) { 1067 *qmp = qm; 1068 return _RkSearchDDMEM(ddpath, qm->dm_dicname); 1069 } 1070 dm = _RkSearchDDP(udd, name); 1071 if (dm) { 1072 return dm; 1073 } 1074 ddpath++; 1075 } 1076 return (struct DM *)0; 1077} 1078 1079/* DMcheck 1080 1081DMcreate ¤Ç name ¤òÂ裳°ú¿ô¤ËÉÕ¤±¤Æ¤¤¤¿»þ¤Î¥Á¥§¥Ã¥¯¤òÆÈΩ¤µ¤»¤¿¡£ 1082 1083return value; 10841: OK 10850: bad 1086*/ 1087 1088int 1089DMcheck(char *spec, char *name) 1090{ 1091 int dftype, dmclass; 1092 int r, w, ret; 1093#ifndef USE_MALLOC_FOR_BIG_ARRAY 1094 char lnk[RK_LINK_BMAX+1]; 1095 char member[RK_MEMBER_BMAX+1]; 1096 char nickname[RK_NICK_BMAX+1]; 1097#else 1098 char *lnk, *member, *nickname; 1099 lnk = (char *)malloc(RK_LINK_BMAX + 1); 1100 member = (char *)malloc(RK_MEMBER_BMAX + 1); 1101 nickname = (char *)malloc(RK_NICK_BMAX + 1); 1102 if (!lnk || !member || !nickname) { 1103 if (lnk) free(lnk); 1104 if (member) free(member); 1105 if (nickname) free(nickname); 1106 return 0; 1107 } 1108#endif 1109 1110 if (_RkParseDicsDir(spec, lnk, member, nickname, &dftype, &dmclass, 1111 &r, &w) < 0 || 1112 STRCMP(nickname, name)) { 1113 ret = 0; 1114 } 1115else { 1116 ret = 1; 1117} 1118#ifdef USE_MALLOC_FOR_BIG_ARRAY 1119 free(lnk); 1120 free(member); 1121 free(nickname); 1122#endif 1123 return ret; 1124} 1125 1126/* DMcreate 1127* create a newc member under dd 1128* DMcreate does not create an actual dictionary file. 1129*/ 1130struct DM * 1131DMcreate( 1132 struct DD *dd, 1133 char *spec) 1134{ 1135 int dftype, dmclass; 1136 struct DF *df; 1137 struct DM *dm = (struct DM *)0; 1138 struct DDT *ddt; 1139 struct DDT *ddLines = &dd->dd_text; 1140 int r, w; 1141#ifndef USE_MALLOC_FOR_BIG_ARRAY 1142 char lnk[RK_LINK_BMAX+1]; 1143 char member[RK_MEMBER_BMAX+1]; 1144 char nickname[RK_NICK_BMAX+1]; 1145#else 1146 char *lnk, *member, *nickname; 1147 lnk = (char *)malloc(RK_LINK_BMAX + 1); 1148 member = (char *)malloc(RK_MEMBER_BMAX + 1); 1149 nickname = (char *)malloc(RK_NICK_BMAX + 1); 1150 if (!lnk || !member || !nickname) { 1151 if (lnk) free(lnk); 1152 if (member) free(member); 1153 if (nickname) free(nickname); 1154 return dm; 1155 } 1156#endif 1157 1158 if (_RkParseDicsDir(spec, lnk, member, nickname, &dftype, &dmclass, 1159 &r, &w) >= 0) { 1160 int len = strlen(spec); 1161 if (spec[len - 1] == '\n') { 1162 spec[len - 1] = '\0'; 1163 } 1164 1165 ddt = (struct DDT *)malloc(sizeof(struct DDT)); 1166 if (ddt) { 1167 ddt->ddt_spec = (char *)malloc(strlen(spec) + 3); /* 3 for \r\n\0 */ 1168 if (ddt->ddt_spec) { 1169 strcpy(ddt->ddt_spec, spec); 1170 df = _RkAllocDF(dd, (unsigned char *)lnk, dftype); 1171 if (df) { 1172 dm = _RkAllocDM(df, (unsigned char *)member, 1173 (unsigned char *)nickname, dmclass); 1174 if (dm) { 1175 ddt->ddt_next = ddLines; 1176 ddt->ddt_prev = ddLines->ddt_prev; 1177 ddLines->ddt_prev = ddt; 1178 ddt->ddt_prev->ddt_next = ddt; 1179 ddt->ddt_status = 0; 1180 dm->dm_line = ddt; 1181 dm->dm_flags |= DM_WRITEOK; /* default access right */ 1182 goto return_dm; 1183 } 1184 _RkFreeDF(df); 1185 } 1186 free(ddt->ddt_spec); 1187 } 1188 free(ddt); 1189 } 1190 } 1191return_dm: 1192#ifdef USE_MALLOC_FOR_BIG_ARRAY 1193 free(lnk); 1194 free(member); 1195 free(nickname); 1196#endif 1197 return(dm); 1198} 1199 1200int 1201DMremove( 1202 struct DM *dm) 1203{ 1204 struct DF *df = dm->dm_file; 1205 struct DDT *ddt = dm->dm_line; 1206 1207 1208 /* free up dirs.dic line */ 1209 if (ddt) { 1210 ddt->ddt_next->ddt_prev = ddt->ddt_prev; 1211 ddt->ddt_prev->ddt_next = ddt->ddt_next; 1212 if (ddt->ddt_spec) 1213 free(ddt->ddt_spec); 1214 free(ddt); 1215 }; 1216 /* free dm itself */ 1217 _RkFreeDM(dm); 1218 if (df) { 1219 struct DM *mh = &df->df_members; 1220 1221 if (mh == mh->dm_next) 1222 _RkFreeDF(df); 1223 }; 1224 return 0; 1225} 1226 1227int 1228DMrename( 1229 struct DM *dm, 1230 unsigned char *nickname) 1231{ 1232 struct DF *df = dm->dm_file; 1233 struct DDT *ddt = dm->dm_line; 1234 char *new_spec; 1235 char *new_nick; 1236 char member[5]; 1237 char *dicname = (char *)0; 1238 int ret = -1; 1239#ifndef USE_MALLOC_FOR_BIG_ARRAY 1240 char spec[RK_LINE_BMAX]; 1241#else 1242 char *spec = (char *)malloc(RK_LINE_BMAX); 1243 if (!spec) { 1244 return ret; 1245 } 1246#endif 1247 1248 if (!df || !df->df_link || !dm->dm_file || !ddt || !ddt->ddt_spec) 1249 goto return_ret; 1250 if (df->df_type == DF_FREQDIC) { 1251 dicname = dm->dm_dicname; 1252 } 1253 switch (dm->dm_class) { 1254 default: 1255 case ND_MWD: 1256 (void)strcpy(member, ".mwd"); 1257 break; 1258 case ND_SWD: 1259 (void)strcpy(member, ".swd"); 1260 break; 1261 case ND_PRE: 1262 (void)strcpy(member, ".pre"); 1263 break; 1264 case ND_SUC: 1265 (void)strcpy(member, ".suc"); 1266 break; 1267 }; 1268 (void)sprintf(spec, "%s(%s) -%s--%s%s-", df->df_link, 1269 dicname ? dicname : member, nickname, 1270 (dm->dm_flags & DM_READOK) ? "r" : "", 1271 (dm->dm_flags & DM_WRITEOK) ? "w" : ""); 1272 new_spec = (char *)malloc(strlen(spec) + 3); /* 3 for \r\n\0 */ 1273 if (!new_spec) { 1274 goto return_ret; 1275 } 1276 strcpy(new_spec, spec); 1277 if (!(new_nick = strdup((char *)nickname))) { 1278 free(new_spec); 1279 goto return_ret; 1280 }; 1281 free(ddt->ddt_spec); 1282 ddt->ddt_spec = new_spec; 1283 free(dm->dm_nickname); 1284 dm->dm_nickname = new_nick; 1285 ret = 0; 1286 1287return_ret: 1288#ifdef USE_MALLOC_FOR_BIG_ARRAY 1289 free(spec); 1290#endif 1291 return ret; 1292} 1293 1294int 1295DMchmod(struct DM *dm, int mode) 1296{ 1297 struct DF *df = dm->dm_file; 1298 struct DDT *ddt = dm->dm_line; 1299 char *new_spec; 1300 unsigned newflags = dm->dm_flags; 1301 int ret = -1; 1302#ifndef USE_MALLOC_FOR_BIG_ARRAY 1303 char spec[RK_LINE_BMAX]; 1304#else 1305 char *spec = (char *)malloc(RK_LINE_BMAX); 1306 if (!spec) { 1307 return ret; 1308 } 1309#endif 1310 1311 if (!df || !df->df_link || !ddt || !ddt->ddt_spec) 1312 goto return_ret; 1313 1314 /* READ ¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤ÎÁàºî */ 1315 if ((mode & (RK_ENABLE_READ | RK_DISABLE_READ)) == RK_ENABLE_READ) { 1316 newflags |= DM_READOK; 1317 } 1318else if ((mode & (RK_ENABLE_READ | RK_DISABLE_READ)) == RK_DISABLE_READ) { 1319 newflags &= ~DM_READOK; 1320} 1321 1322 /* WRITE ¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤ÎÁàºî */ 1323 if ((mode & (RK_ENABLE_WRITE | RK_DISABLE_WRITE)) == RK_ENABLE_WRITE) { 1324 newflags |= DM_WRITEOK; 1325 } 1326else if ((mode & (RK_ENABLE_WRITE | RK_DISABLE_WRITE)) == RK_DISABLE_WRITE) { 1327 newflags &= ~DM_WRITEOK; 1328} 1329 1330 if (newflags != dm->dm_flags) { 1331 if (df->df_direct->dd_flags & DD_WRITEOK) { 1332 dm->dm_flags = newflags; 1333 (void)sprintf(spec, "%s(%s) -%s--%s%s-", 1334 df->df_link, dm->dm_dicname, dm->dm_nickname, 1335 (dm->dm_flags & DM_READOK) ? "r" : "", 1336 (dm->dm_flags & DM_WRITEOK) ? "w" : ""); 1337 new_spec = (char *)malloc(strlen(spec) + 3); /* 3 for \r\n\0 */ 1338 if (!new_spec) { 1339 ret = NOTALC; 1340 goto return_ret; 1341 } 1342 strcpy(new_spec, spec); 1343 free(ddt->ddt_spec); 1344 ddt->ddt_spec = new_spec; 1345 } 1346 } 1347 ret = (((dm->dm_flags & DM_WRITEOK) ? RK_ENABLE_WRITE : RK_DISABLE_WRITE) | 1348 ((dm->dm_flags & DM_READOK) ? RK_ENABLE_READ : RK_DISABLE_READ)); 1349 1350return_ret: 1351#ifdef USE_MALLOC_FOR_BIG_ARRAY 1352 free(spec); 1353#endif 1354 return ret; 1355} 1356 1357int 1358DDchmod(struct DD *dd, int mode) 1359{ 1360 char *dicsdir; 1361 unsigned newflags = dd->dd_flags; 1362 1363 /* READ ¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤ÎÁàºî */ 1364 if ((mode & (RK_ENABLE_READ | RK_DISABLE_READ)) == RK_ENABLE_READ) { 1365 newflags |= DD_READOK; 1366 } 1367else if ((mode & (RK_ENABLE_READ | RK_DISABLE_READ)) == RK_DISABLE_READ) { 1368 newflags &= ~DD_READOK; 1369} 1370 1371 /* WRITE ¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤ÎÁàºî */ 1372 if ((mode & (RK_ENABLE_WRITE | RK_DISABLE_WRITE)) == RK_ENABLE_WRITE) { 1373 newflags |= DD_WRITEOK; 1374 } 1375else if ((mode & (RK_ENABLE_WRITE | RK_DISABLE_WRITE)) == RK_DISABLE_WRITE) { 1376 newflags &= ~DD_WRITEOK; 1377} 1378 1379 if (newflags != dd->dd_flags) { 1380 dicsdir = (char *)malloc(strlen(dd->dd_path) + strlen("/dics.dir") + 1); 1381 if (dicsdir) { 1382 int filemode; 1383 1384 sprintf(dicsdir, "%s/dics.dir", dd->dd_path); 1385 1386 filemode = ((newflags & DD_WRITEOK) ? 0640 : 0440) 1387 | ((newflags & DD_READOK) ? 04 : 0); 1388 1389 if (chmod(dicsdir, filemode) == 0) { 1390 dd->dd_flags = newflags; 1391 } 1392 free(dicsdir); 1393 } 1394 } 1395 newflags = dd->dd_flags; 1396 return (((newflags & DD_WRITEOK) ? RK_ENABLE_WRITE : RK_DISABLE_WRITE) | 1397 ((newflags & DD_READOK) ? RK_ENABLE_READ : RK_DISABLE_READ)); 1398} 1399 1400int 1401_RkMountMD( 1402 struct RkContext *cx, 1403 struct DM *dm, 1404 struct DM *qm, 1405 int mode, 1406 int firsttime) 1407{ 1408 struct MD *md, *head; 1409 struct DF *df; 1410 struct DD *dd; 1411 char *file; 1412 int status; 1413 1414 if (!dm || !(md = (struct MD *)calloc(1, sizeof(struct MD)))) 1415 return -1; 1416 /* increment the reference counter */ 1417 if (dm->dm_rcount == 0) { 1418 df = dm->dm_file; 1419 dd = df->df_direct; 1420 if (!(file = _RkCreatePath(dd, df->df_link))) { 1421 free(md); 1422 return -1; 1423 }; 1424 status = DST_OPEN(dm, file, DM_WRITABLE, cx->gram->gramdic); 1425 free(file); 1426 if (status) { 1427 free(md); 1428 return -1; 1429 }; 1430 }; 1431 if (qm && qm->dm_rcount == 0) { 1432 df = qm->dm_file; 1433 dd = df->df_direct; 1434 if (!(file = _RkCreatePath(dd, df->df_link))) { 1435 free(md); 1436 return -1; 1437 }; 1438 status = FQopen(dm, qm, file, DM_WRITABLE); 1439 free(file); 1440 if (status) { 1441 free(md); 1442 return -1; 1443 }; 1444 }; 1445 /* use the dic as the default grammatical dic if it contains */ 1446 if (firsttime && DM2TYPE(dm) == DF_PERMDIC && dm->dm_gram) { 1447 cx->gram = dm->dm_gram; 1448 cx->gram->refcount++; 1449 } 1450 /* increment the reference counter */ 1451 dm->dm_rcount++; 1452 if (qm) { 1453 qm->dm_rcount++; 1454 if (!cx->nv && qm->dm_nv) 1455 cx->nv = qm->dm_nv; 1456 } 1457 /* put it at the end of the mount list */ 1458 head = cx->md[dm->dm_class]; 1459 md->md_next = head; 1460 md->md_prev = head->md_prev; 1461 head->md_prev = md; 1462 md->md_prev->md_next = md; 1463 md->md_dic = dm; 1464 md->md_freq = qm; 1465 md->md_flags = mode&MD_WRITE; 1466 /* wait for the translation to finish */ 1467 if (IS_XFERCTX(cx)) 1468 md->md_flags |= MD_MPEND; 1469 return 0; 1470} 1471 1472void 1473_RkUmountMD( 1474 struct RkContext *cx, 1475 struct MD *md) 1476{ 1477 struct DM *dm = md->md_dic; 1478 struct DM *qm = md->md_freq; 1479 struct DF *df; 1480 struct DD *dd; 1481 char *file; 1482 1483 cx->dmprev = (struct DM *)0; 1484 cx->qmprev = (struct DM *)0; 1485 if (IS_XFERCTX(cx)) 1486 md->md_flags |= MD_UPEND; 1487 else { 1488 md->md_prev->md_next = md->md_next; 1489 md->md_next->md_prev = md->md_prev; 1490 free(md); 1491 if (qm) { 1492 df = qm->dm_file; 1493 dd = df->df_direct; 1494 if (cx->nv == qm->dm_nv) 1495 cx->nv = (struct NV *)0; 1496 if (qm->dm_rcount > 0 && --qm->dm_rcount == 0) { 1497 file = _RkCreatePath(dd, df->df_link); 1498 if (file) { 1499 FQclose(cx, dm, qm, file); 1500 if (!df->df_rcount) { 1501 if (dd->dd_rcount > 0 && --dd->dd_rcount == 0) 1502 _RkFreeDD(dd); 1503 }; 1504 free(file); 1505 }; 1506 }; 1507 }; 1508 if (dm->dm_rcount > 0 && --dm->dm_rcount == 0) { 1509 df = dm->dm_file; 1510 dd = df->df_direct; 1511 file = _RkCreatePath(dd, df->df_link); 1512 if (file) { 1513 (void)DST_CLOSE(dm, file, cx->gram->gramdic); 1514 if (df->df_rcount == 0) { 1515 if (dd->dd_rcount > 0 && --dd->dd_rcount == 0) 1516 _RkFreeDD(dd); 1517 }; 1518 free(file); 1519 }; 1520 }; 1521 }; 1522} 1523