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[]="@(#) 102.1 $Id: dic.c 14875 2005-11-12 21:25:31Z bonefish $"; 25#endif 26/*LINTLIBRARY*/ 27 28#include "RKintern.h" 29 30#include <stdio.h> /* for sprintf */ 31#include <string.h> 32#include <unistd.h> 33#include <fcntl.h> 34 35#define dm_td dm_extdata.ptr 36#define cx_gwt cx_extdata.ptr 37#define Is_Gwt_CTX(cx) 38 39#define ND2RK(s) ((0x80 >> (int)(s)) & 0xff) 40#define STRCMP(d, s) strcmp((char *)(d), (char *)(s)) 41 42#define FREQ_TEMPLATE "frq%d.cld" 43#define USER_TEMPLATE "usr%d.ctd" 44#define PERM_TEMPLATE "bin%d.cbd" 45 46#define DEFAULT_PERMISSION "w" 47 48static int locatepath(struct DD *userDDP[], struct DD *ddpath[], int mode); 49static struct td_n_tupple *pushTdn(struct RkContext *cx, struct TD *tdp); 50 51/* locatepath -- �������������������������������� mode ������������������������ 52 53 return value: 54 0: �������� 55 ACCES: ������������(�������������������������������������������� DDPATH ������������������������) 56 */ 57 58static int 59locatepath(struct DD *userDDP[], struct DD *ddpath[], int mode) 60{ 61 /* find dictionary under system and user/group directory */ 62 if (mode & RK_SYS_DIC) { 63 if (ddpath[2]) { 64 userDDP[0] = ddpath[2]; 65 } 66 else { 67 return ACCES; 68 } 69 } else 70 if (mode & RK_GRP_DIC) { 71 if (ddpath[1] && ddpath[2]) { 72 /* ������������������������������������������������������������������������������������ */ 73 userDDP[0] = ddpath[1]; 74 } 75 else { 76 return ACCES; 77 } 78 } 79 else { /* �������������������� */ 80 userDDP[0] = ddpath[0]; 81 } 82 userDDP[1] = (struct DD*)0; 83 return 0; 84} 85 86 87/* int 88 * RkwCreateDic(cx_num, dicname, mode) 89 * 90 * ������������ 91 * int cx_num ���������������������������������������� 92 * unsigned char *dicname �������������������������������� 93 * int mode ������������������������������������������������OR 94 * �������������������� 95 * #define Rk_MWD 0x80 96 * #define Rk_SWD 0x40 97 * #define Rk_PRE 0x20 98 * #define Rk_SUC 0x10 99 * �������������������� 100 * #define KYOUSEI 0x01 101 * ���������������������������� 0x00 102#define PL_DIC (0x0100) 103#define PL_ALLOW (PL_DIC << 1) 104#define PL_INHIBIT (PL_DIC << 2) 105#define PL_FORCE (PL_DIC << 3) 106 * 107 * �������������������� 108 * ������������������������ 0 109 * ������������������������(����������������������������) 1 110 * �������������������������������������������������������� -6 NOTALC 111 * ������������������������������������������������������������ -9 BADF 112 * dics.dir������������������������������������ -10 BADDR 113 * GetDicFilename����������������-1������������ -13 ACCES 114 * MakeDicFile���������������������������� -13 ACCES 115 * CreatDic���������������������������� -13 ACCES 116 * �������������������������������������������������������� -16 MOUNT 117 * ����������������������������������������(����������������������������) -17 EXIST 118 * ������������������������������������������������ -26 TXTBSY 119 * mode���������������������������������������� -99 BADARG 120 * �������������������������������������������������������������������� -100 BADCONT 121 */ 122 123int 124RkwCreateDic(int cx_num, char *dicname, int mode) 125{ 126 struct RkParam *sx = RkGetSystem(); 127 128 struct RkContext *cx = RkGetContext(cx_num); 129 struct DM *sm, *um, *tm; 130 int type; 131 struct DD *userDDP[2], *systemDDP[2]; 132 char *filename, extent[5]; 133 int ret; 134#ifndef USE_MALLOC_FOR_BIG_ARRAY 135 char spec[RK_LINE_BMAX]; 136#else 137 char *spec = (char *)malloc(RK_LINE_BMAX); 138 if (!spec) { 139 return NOTALC; 140 } 141#endif 142 143 if(!dicname || !dicname[0]) { 144 ret = ACCES; 145 goto return_ret; 146 } 147 if (strlen(dicname) >= (unsigned)RK_NICK_BMAX) { 148 ret = INVAL; 149 goto return_ret; 150 } 151 if ( !cx || !cx->ddpath || !cx->ddpath[0] ) { 152 ret = BADCONT; 153 goto return_ret; 154 } 155 if ( !sx || !sx->ddpath || !sx->ddpath[0] ) { 156 ret = BADCONT; 157 goto return_ret; 158 } 159#ifndef STANDALONE /* Is it true ? */ 160 if ( cx->ddpath[0] == sx->ddpath[0] ) { 161 ret = BADCONT; 162 goto return_ret; 163 } 164#endif 165 166 if (locatepath(userDDP, cx->ddpath, mode) < 0) { 167 ret = ACCES; 168 goto return_ret; 169 } 170 if (!(userDDP[0]->dd_flags & DD_WRITEOK)) { 171 ret = ACCES; 172 goto return_ret; 173 } 174 175 systemDDP[0] = sx->ddpath[0]; 176 systemDDP[1] = (struct DD *)0; 177 178 type = (mode & PL_DIC) ? DF_FREQDIC : DF_TEMPDIC; 179/* find dictionary in current mount list */ 180 sm = _RkSearchDDQ(systemDDP, dicname, type); 181 um = _RkSearchDDQ(userDDP, dicname, type); 182 183 if (um && !(mode & KYOUSEI)) { 184 ret = EXIST; 185 goto return_ret; 186 } 187 188 if (mode & PL_DIC) { 189 if (!sm) { 190 if(_RkSearchDDQ(systemDDP, dicname, DF_TEMPDIC)) { 191 ret = BADF; 192 goto return_ret; 193 } 194 ret = NOENT; 195 goto return_ret; 196 } 197 if (!um) { 198 struct DM *dm; 199 200 if (!(filename = _RkCreateUniquePath(userDDP[0], FREQ_TEMPLATE))) { 201 ret = ACCES; 202 goto return_ret; 203 } 204 (void)sprintf(spec, "%s(%s) -%s--%s-\n", 205 filename, sm->dm_dicname, sm->dm_nickname, 206 DEFAULT_PERMISSION); 207 if (!DMcheck(spec, dicname)) { 208 ret = NOENT; 209 goto return_ret; 210 } 211 if (!(dm = DMcreate(userDDP[0], spec))) { 212 ret = NOTALC; 213 goto return_ret; 214 } 215 if (copyFile(sm, dm)) { 216 ret = ACCES; 217 goto return_ret; 218 }else{ 219 ret = 0; 220 goto return_ret; 221 } 222 } else { 223 if (!(ND2RK(um->dm_class) & mode)) { 224 ret = INVAL; 225 goto return_ret; 226 } 227 if ( um->dm_rcount > 0 ) { 228 ret = TXTBSY; 229 goto return_ret; 230 } 231 if ( !um->dm_file ) { 232 ret = BADCONT; /* INVAL SHOULD BE REPLACED... MAKO 1225 */ 233 goto return_ret; 234 } 235 236 if(_RkRealizeDF(um->dm_file)) {/* ������������������������������������������������ kon 1993.11 */ 237 ret = ACCES; 238 goto return_ret; 239 } 240 if ( copyFile(sm, um) ) { 241 ret = ACCES; 242 goto return_ret; 243 }else{ 244 ret = 1; 245 goto return_ret; 246 } 247 } 248 } else { 249 /* um = _RkSearchDDQ(userDDP, dicname, DF_TEMPDIC);*/ 250 tm = _RkSearchDDP(userDDP, dicname); 251 if (tm != um) { 252 ret = BADF; 253 goto return_ret; 254 } 255 if (!um) { 256 if (!(filename = _RkCreateUniquePath(userDDP[0], USER_TEMPLATE))) { 257 ret = ACCES; 258 goto return_ret; 259 } 260 if (mode & Rk_MWD) { 261 (void)strcpy(extent, "mwd"); 262 } else if (mode & Rk_SWD) { 263 (void)strcpy(extent, "swd"); 264 } else if (mode & Rk_PRE) { 265 (void)strcpy(extent, "pre"); 266 } else if (mode & Rk_SUC) { 267 (void)strcpy(extent, "suc"); 268 } else { 269 /* return INVAL; */ 270 (void)strcpy(extent, "mwd"); 271 }; 272 (void)sprintf(spec, "%s(.%s) -%s--%s-\n", filename, extent, dicname, 273 DEFAULT_PERMISSION); 274 if (!DMcheck(spec, dicname)) { 275 ret = NOENT; 276 goto return_ret; 277 } 278 if (!DMcreate(userDDP[0], spec)) { 279 ret = NOTALC; 280 goto return_ret; 281 } 282 _RkRealizeDD(userDDP[0]); 283 ret = 0; 284 goto return_ret; 285 } else { 286 if ( um->dm_rcount > 0 ) { 287 ret = TXTBSY; 288 goto return_ret; 289 } 290 if ( !um->dm_file ) { 291 ret = BADCONT; /* INVAL SHOULD BE REPLACED... MAKO 1225 */ 292 goto return_ret; 293 } 294 sprintf(spec, "%s(%s) -%s--%s%s-\n", 295 um->dm_file->df_link, um->dm_dicname, um->dm_nickname, 296 (um->dm_flags & DM_READOK) ? "r" : "", 297 (um->dm_flags & DM_WRITEOK) ? "w" : ""); 298 if(_RkRealizeDF(um->dm_file)) { 299 ret = ACCES; 300 goto return_ret; 301 } 302 ret = 1; /* backward compatiblity ... 1224 Xmas */ 303 } 304 } 305 return_ret: 306#ifdef USE_MALLOC_FOR_BIG_ARRAY 307 free(spec); 308#endif 309 return ret; 310} 311 312int copyFile(struct DM *src, struct DM *dst) 313{ 314 struct DF *srcF = src->dm_file; 315 struct DD *srcD = srcF->df_direct; 316 struct DF *dstF = dst->dm_file; 317 struct DD *dstD = dstF->df_direct; 318 char *srcN, *dstN; 319#ifndef WIN 320 int srcFd, dstFd; 321 int n; 322#else 323 HANDLE srcFd, dstFd; 324 DWORD n, nextn; 325#endif 326 int ecount = 0; 327 328 srcN = _RkCreatePath(srcD, srcF->df_link); 329 if (srcN) { 330#ifdef WIN 331 srcFd = CreateFile(srcN, GENERIC_READ, 332 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 333 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 334#else 335 srcFd = open(srcN, 0); 336#endif 337 free(srcN); 338 if 339#ifdef WIN 340 (srcFd != INVALID_HANDLE_VALUE) 341#else 342 (srcFd >= 0) 343#endif 344 { 345 dstN = _RkCreatePath(dstD, dstF->df_link); 346 if (dstN) { 347#ifdef WIN 348 dstFd = CreateFile(dstN, GENERIC_WRITE, 349 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 350 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 351#else 352 dstFd = creat(dstN, 0666); 353#endif 354 free(dstN); 355 356 if 357#ifdef WIN 358 (dstFd != INVALID_HANDLE_VALUE) 359#else 360 (dstFd >= 0) 361#endif 362 { 363 char b[RK_BUFFER_SIZE]; 364 /* I will leave this array on the stack because it may be a rare 365 case to use this function. 1996.6.5 kon */ 366 367 _RkRealizeDD(dstD); 368 369 while 370#ifdef WIN 371 (ReadFile(srcFd, b, RK_BUFFER_SIZE, &n, NULL) && n > 0) 372#else 373 ((n = read(srcFd, b, RK_BUFFER_SIZE)) > 0) 374#endif 375 { /* do copy */ 376 if 377#ifdef WIN 378 (!WriteFile(dstFd, b, n, &nextn, NULL) || nextn != n) 379#else 380 ( write(dstFd, b, n) != n ) 381#endif 382 { 383 ecount++; 384 break; 385 } 386 } 387 if ( 388#ifdef WIN 389 !CloseHandle(dstFd) 390#else 391 close(dstFd) < 0 392#endif 393 || n < 0) 394 { 395 ecount++; 396 } 397 } 398 } 399#ifdef WIN 400 CloseHandle(srcFd); 401#else 402 close(srcFd); 403#endif 404 } 405 } 406 return ecount ? -1 : 0; 407} 408 409/* 410 * RkwListDic(cx_num, dirname, buf, size) 411 * int cx_num; ���������������������������������������� 412 * unsigned char *dirname; ������������������������������������������������������������������������ 413 * unsigned char *buf; ������������������������������������������������������������ 414 * int size; �������������������������������� 415 * 416 * �������������������� 417 * ������������������������ ���������������� 418 * ������������������������������������������������������������ BADCONT 419 * RkwCreateContext���������������������������� BADCONT 420 * RkwSetDicPath���������������������������� NOTALC 421 */ 422int 423RkwListDic(int cx_num, char *dirname, char *buf, int size) 424{ 425 int dicscnt; 426 int new_cx_num; 427 428 if(!dirname || !strlen(dirname)) 429 return 0; 430 if (cx_num < 0) 431 return BADCONT; 432 if((new_cx_num = RkwCreateContext()) < 0) 433 return BADCONT; 434 if (RkwSetDicPath(new_cx_num, dirname) == -1) { 435 RkwCloseContext(new_cx_num); 436 return NOTALC; 437 } 438 dicscnt = RkwGetDicList(new_cx_num, buf, size); 439 (void)RkwCloseContext(new_cx_num); 440 return (dicscnt); 441} 442 443/* int 444 * RkwRemoveDic(cx_num, dicname, mode) 445 * 446 * ���������������������������������������������������������������������������������������������������� 447 * ���������������������������������������� 448 * 449 * ������������ 450 * int cx_num ���������������������������������������� 451 * unsigned char *dicname ������������ 452 * 453 * �������������������� 454 * ������������������������ 0 455 * ���������������������������������������� -2 NOENT 456 * ������������������������������������������������������������ -9 BADF 457 * RemoveDic��������������������-1������������ -13 ACCES 458 * ���������������������������������������� -26 TXTBSY 459 * �������������������������������������������������������������������� -100 BADCONT 460 */ 461int 462RkwRemoveDic(int cx_num, char *dicname, int mode) 463{ 464 struct RkContext *cx = RkGetContext(cx_num); 465/* struct RkParam *sx = RkGetSystem(); */ 466 struct DD *userDDP[2], *dum_direct; 467 struct DM *dm; 468 char *path; 469 int res; 470 471 if(!dicname) 472 return NOENT; 473 if ( !cx || !cx->ddpath || !cx->ddpath[0] ) 474 return BADCONT; 475 476 if (locatepath(userDDP, cx->ddpath, mode) < 0) { 477 return ACCES; 478 } 479 480 /* find dictionary in current mount list */ 481 dm = _RkSearchDDP(userDDP, (char *)dicname); 482 if (!dm || ((mode & PL_DIC) && dm->dm_file->df_type != DF_FREQDIC)) { 483 return NOENT; 484 } 485 if ( dm->dm_rcount > 0 ) 486 return TXTBSY; 487 if ( !dm->dm_file ) /* ? */ 488 return BADCONT; 489 if (!(dm->dm_file->df_direct->dd_flags & DD_WRITEOK) || 490 (!(dm->dm_flags & DM_WRITEOK) && !(mode & KYOUSEI))) { 491 return ACCES; 492 } 493 if (!(path = _RkMakePath(dm->dm_file))) 494 return NOTALC; 495 res = unlink(path); 496 free(path); 497 if(res) 498 return ACCES; 499 dum_direct = dm->dm_file->df_direct; 500 DMremove(dm); 501 (void)_RkRealizeDD(dum_direct); 502 return 0; 503} 504 505/* int 506 * RkwRenameDic(cx_num, oldnick, newnick, mode) 507 * 508 * ���������������������������������������������������������������������������������������������������� 509 * ���������������������������������������������������� 510 * 511 * ������������ 512 * int cx_num ���������������������������������������� 513 * unsigned char *oldnick ������������������������ 514 * unsigned char *newnick ������������������������ 515 * int mode �������������������� 516 * 517 * ������������ (RKdic.h��������) 518 * ������������������������ 0 519 * oldnick�������������������������������� -2 NOENT 520 * RemoveDic��������������������-1������������ -2 NOENT 521 * ������������������������������������������������������������ -9 BADF 522 * RenameDicFile��������������������-1������������ -13 ACCES 523 * newnick���������������������������� -17 EXIST 524 * oldnick�������������������������������������������� -26 TXTBSY 525 * newnick�������������������������������������������� -26 TXTBSY 526 * �������������������������������������������������������������������� -100 BADCONT 527 */ 528int 529RkwRenameDic(int cx_num, char *old, char *newc, int mode) 530{ 531 struct RkContext *cx = RkGetContext(cx_num); 532 struct DD *userDDP[2], *dd; 533 struct DM *dm1, *dm2; 534 char *path; 535 char spec[RK_LINE_BMAX]; 536 /* I leave this array on the stack because this will not glow so big. 537 1996.6.5 kon */ 538 539 if(!old || !*old) 540 return NOENT; 541 if(!newc || !*newc) 542 return ACCES; 543 if (!cx || !cx->ddpath || !cx->ddpath[0]) 544 return BADCONT; 545 if (strlen((char *)newc) >= (unsigned)RK_NICK_BMAX) { 546 return INVAL; 547 } 548 549 if (locatepath(userDDP, cx->ddpath, mode) < 0) { 550 return ACCES; 551 } 552 553 dm1 = _RkSearchDDP(userDDP, (char *)old); 554 if (!dm1) { 555 return NOENT; 556 } 557 558 dd = dm1->dm_file->df_direct; 559 if (!(dd->dd_flags & DD_WRITEOK)) { 560 return ACCES; 561 } 562 563 dm2 = _RkSearchDDP(userDDP, (char *)newc); 564 565 if (dm1->dm_rcount > 0) 566 return TXTBSY; 567 if (dm2) { /* ���������������������������������������������������������������������������� */ 568 if (dm2->dm_rcount > 0) 569 return TXTBSY; 570 if (!(mode & KYOUSEI)) 571 return EXIST; 572 if (!(path = _RkMakePath(dm2->dm_file))) 573 return NOTALC; 574 (void)unlink(path); 575 free(path); 576 DMremove(dm2); 577 DMrename(dm1, (unsigned char *)newc); 578 (void)_RkRealizeDD(dd); 579 return 1; 580 } else { 581 (void)sprintf(spec, "%s(.%s) -%s--%s%s-\n", "tmp.ctd", "mwd", newc, 582 (dm1->dm_flags & DM_READOK) ? "r" : "", 583 (dm1->dm_flags & DM_WRITEOK) ? "w" : ""); 584 if (!DMcheck(spec, newc)) 585 return NOENT; /* ���������������������������������������������������� (1993.11 ����) */ 586 /* ������������������������������������������������������������ (1993.11 ����) */ 587 DMrename(dm1, (unsigned char *)newc); 588 (void)_RkRealizeDD(dd); 589 return 0; 590 } 591} 592 593/* int 594 * RkwCopyDic(cx, dir, from, to, mode) 595 * 596 * ������������������������������������ 597 * 598 * ������������ 599 * int cx ���������������������������������������� 600 * char *dir ���������������������������� 601 * char *from ���������������������������� 602 * char *to ���������������������������� 603 * int mode ������������ 604 * 605 * ������������ (RKdic.h��������) 606 * ������������������������ 0 607 * oldnick�������������������������������� -2 NOENT 608 * RemoveDic��������������������-1������������ -2 NOENT 609 * ���������������������������������������������������������������� -9 BADF 610 * RenameDicFile��������������������-1������������ -13 ACCES 611 * ������������������������������������������������ NOTALC 612 * ���������������������������������������� INVAL 613 * newnick���������������������������� -17 EXIST 614 * oldnick�������������������������������������������� -26 TXTBSY 615 * newnick�������������������������������������������� -26 TXTBSY 616 * �������������������������������������������������������������������� -100 BADCONT 617 */ 618 619int 620RkwCopyDic(int co, char *dir, char *from, char *to, int mode) 621{ 622 struct RkContext *cx; 623 struct DD *userDDP[2]; 624 struct DM *dm1, *dm2; 625 char *path, *perm = DEFAULT_PERMISSION; 626 char *myddname; 627 int res, v, con; 628 629 if (!dir || !*dir) { 630 return BADF; 631 } 632 if (!from || !*from) 633 return NOENT; 634 if (!to || !*to) 635 return ACCES; 636 if (strlen((char *)to) >= (unsigned)RK_NICK_BMAX) { 637 return INVAL; 638 } 639 640 res = BADCONT; 641 con = RkwCreateContext(); 642 643 cx = RkGetContext(co); 644 if (!cx || !cx->ddpath || !cx->ddpath[0]) { 645 if (con >= 0) 646 RkwCloseContext(con); 647 return BADCONT; 648 } 649 650 if (con >= 0) { 651 int n = 2; /* for system dic */ 652 switch (mode & (RK_GRP_DIC | RK_SYS_DIC)) { 653 case RK_GRP_DIC: 654 n = 1; /* for group dic */ 655 case RK_SYS_DIC: 656 if (!cx->ddpath[2]) { 657 return BADCONT; 658 } 659 myddname = cx->ddpath[n]->dd_name; 660 break; 661 default: 662 myddname = cx->ddpath[0]->dd_name; 663 break; 664 } 665 666 res = NOTALC; 667 path = (char *)malloc(strlen(dir) + 1 + strlen(myddname) + 1); 668 if (path) { 669 sprintf(path, "%s:%s", dir, myddname); 670 671 res = NOTALC; 672 v = RkwSetDicPath(con, path); 673 free(path); 674 if (v >= 0) { 675 struct RkContext *cy = RkGetContext(con); 676 677 res = ACCES; 678 if (cy->ddpath[1]->dd_flags & DD_WRITEOK) { 679 userDDP[0] = cy->ddpath[0]; 680 userDDP[1] = (struct DD *)0; 681 682 res = NOENT; 683 dm1 = _RkSearchDDP(userDDP, from); 684 if (dm1) { 685 int type = dm1->dm_file->df_type; 686 687 res = BADF; 688 if (type != DF_RUCDIC) { 689 userDDP[0] = cy->ddpath[1]; 690 userDDP[1] = (struct DD *)0; 691 692 dm2 = _RkSearchDDP(userDDP, to); 693 if (dm2) { /* to �������������������������������������������������������� */ 694 if (dm2->dm_rcount > 0) { 695 res = TXTBSY; 696 goto newdicUsed; 697 } 698 if (!(mode & KYOUSEI)) { 699 res = EXIST; 700 goto newdicUsed; 701 } 702 if (!(path = _RkMakePath(dm2->dm_file))) { 703 res = NOTALC; 704 goto newdicUsed; 705 } 706 (void)unlink(path); 707 free(path); 708 switch (dm2->dm_flags & (DM_READOK | DM_WRITEOK)) { 709 case (DM_READOK | DM_WRITEOK): 710 perm = "rw"; 711 break; 712 case DM_READOK: 713 perm = "r"; 714 break; 715 case DM_WRITEOK: 716 perm = "w"; 717 break; 718 default: 719 perm = ""; 720 break; 721 } 722 DMremove(dm2); 723 } 724 725 { /* ������������������������������������ */ 726 char *ptemplate, *filename; 727 728 RkwSync(co, from); /* sometimes, this failes to an error */ 729 ptemplate = 730 (type == DF_FREQDIC) ? (char*)FREQ_TEMPLATE : 731 (type == DF_TEMPDIC) ? (char*)USER_TEMPLATE : 732 (char*)PERM_TEMPLATE; 733 734 res = ACCES; 735 filename = _RkCreateUniquePath(userDDP[0], ptemplate); 736 if (filename) { 737 char spec[RK_LINE_BMAX]; 738 /* I leave this array on the stack because this will not glow so big. 739 1996.6.5 kon */ 740 741 (void)sprintf(spec, "%s(%s) -%s--%s-\n", 742 filename, dm1->dm_dicname, to, perm); 743 res = NOTALC; 744 dm2 = DMcreate(userDDP[0], spec); 745 if (dm2) { 746 res = ACCES; 747 if (copyFile(dm1, dm2) == 0) { 748 (void)_RkRealizeDD(userDDP[0]); 749 res = 0; 750 } 751 else { 752 DMremove(dm2); 753 } 754 } 755 } 756 } 757 } 758 } 759 newdicUsed:; 760 } 761 } 762 } 763 RkwCloseContext(con); 764 } 765 return res; 766} 767 768/* int 769 * RkwChmodDic(cx_num, dicname, mode) 770 * 771 * ������������������������������������������������ 772 * 773 * ������������ 774 * int cx_num ������������������������ 775 * char dicname ������������ 776 * int mode ������������ 777 * 778 * ������������ (RKdic.h��������) 779 * ������������������������ 0 780 * dicname�������������������������������� -2 NOENT 781 * DMchmod ��������������������-1������������ -13 ACCES 782 * �������������������������������������������������������������������� -100 BADCONT 783 */ 784int 785RkwChmodDic(int cx_num, char *dicname, int mode) 786{ 787 struct RkContext *cx = RkGetContext(cx_num); 788 struct DD *dd, *userDDP[2]; 789 struct DM *dm; 790 int res; 791 unsigned dirmode; 792 793 res = BADCONT; 794 if (cx && cx->ddpath && cx->ddpath[0]) { 795 dirmode = mode & RK_DIRECTORY; 796 if (dirmode != 0) { /* ������������������������ */ 797 switch (dirmode) { 798 case RK_SYS_DIR: 799 dd = (struct DD *)0; /* or SX.ddpath[0] */ 800 break; 801 case RK_GRP_DIR: 802 if (cx->ddpath[1] && cx->ddpath[2]) { 803 dd = cx->ddpath[1]; 804 } 805 break; 806 default: /* RK_USR_DIR */ 807 dd = cx->ddpath[0]; 808 break; 809 } 810 res = dd ? DDchmod(dd, mode) : ACCES; 811 } 812 else { /* ���������������� */ 813 res = ACCES; 814 if (locatepath(userDDP, cx->ddpath, mode) == 0) { 815 res = NOENT; 816 if(dicname && *dicname) { 817 dm = _RkSearchDDP(userDDP, dicname); 818 res = NOENT; 819 if (dm) { 820 struct DD *dd = dm->dm_file->df_direct; 821 822 res = DMchmod(dm, mode); 823 if (res >= 0) { 824 (void)_RkRealizeDD(dd); 825 } 826 else { 827 res = ACCES; 828 } 829 } 830 } 831 } 832 } 833 } 834 return res; 835} 836 837/* 838 * GetLine(cx, gram, tdp, line) 839 * struct RkContext *cx 840 * struct RkKxGram *gram 841 * struct TD *tdp 842 * WCHAR_T *line 843 * 844 * ������������ �������� 0 845 * �������� -1 846 */ 847static struct td_n_tupple * 848pushTdn(struct RkContext *cx, struct TD *tdp) 849{ 850 struct td_n_tupple *newtd; 851 struct _rec *gwt; 852 if (!cx || !(gwt = (struct _rec *)cx->cx_gwt) || 853 !(newtd = (struct td_n_tupple *)malloc(sizeof(struct td_n_tupple)))) { 854 return (struct td_n_tupple *)0; 855 } 856 newtd->td = (char *)tdp; 857 newtd->n = 0; 858 newtd->next = (struct td_n_tupple *)gwt->tdn; 859 gwt->tdn = (struct td_n_tupple *)newtd; 860 return newtd; 861} 862 863void 864freeTdn(struct RkContext *cx) 865{ 866 struct td_n_tupple *work; 867 struct _rec *gwt = (struct _rec *)cx->cx_gwt; 868 if (gwt) { 869 while((work = gwt->tdn) != (struct td_n_tupple *)0) { 870 gwt->tdn = work->next; 871 free(work); 872 }; 873 }; 874} 875 876inline void 877popTdn(struct RkContext *cx) 878{ 879 struct td_n_tupple *work; 880 struct _rec *gwt = (struct _rec *)cx->cx_gwt; 881 work = gwt->tdn; 882 if (work) { 883 gwt->tdn = work->next; 884 free(work); 885 } 886} 887 888inline int 889GetLine(struct RkContext *cx, struct RkKxGram *gram, struct TD *tdp, WCHAR_T *line, int size) 890{ 891 struct TD *vtd; 892 struct TN *vtn; 893 struct _rec *gwt = (struct _rec *)cx->cx_gwt; 894 895 if (tdp) { 896 if (gwt->tdn) 897 freeTdn(cx); 898 if(!pushTdn(cx, tdp)) 899 return NOTALC; 900 } 901 while (gwt->tdn && gwt->tdn->n >= (int)((struct TD *)gwt->tdn->td)->td_n) 902 popTdn(cx); 903 if (gwt->tdn == (struct td_n_tupple *)0) 904 return -1; 905 vtd = (struct TD *)gwt->tdn->td; 906 vtn = vtd->td_node + gwt->tdn->n; 907 while ( !IsWordNode(vtn) ) { 908 gwt->tdn->n++; 909 if(!pushTdn(cx, vtn->tn_tree)) 910 return NOTALC; 911 vtd = (struct TD *)gwt->tdn->td; 912 vtn = vtd->td_node; 913 } 914 if (RkUparseWrec(gram, vtn->tn_word->word, line, size, vtn->tn_word->lucks)) { 915 gwt->tdn->n++; 916 return 0; 917 } else 918 return -1; 919} 920 921/* 922 * RkwGetWordTextDic(cx_num, dirname, dicname, info, infolen) 923 * 924 * int cx_num ������������������������NO 925 * unsigned char *dirname ���������������������������� 926 * unsigned char *dicname ������������ 927 * unsigned char *info ���������������� 928 * int infolen ���������������������������� 929 * 930 * ������������ : ������������info������������������������ 931 * ���������������������������������������� ���������������� 932 * RkwCreateContext�������������������� BADCONT 933 * RkwDuplicateContext�������������������� BADCONT 934 * RkGetContext�������������������� BADCONT 935 * RkwSetDicPath�������������������� NOTALC 936 * RkwMountDic�������������������� NOENT 937 * SearchUDDP�������������������� NOENT 938 * ������������������������������������ -9 BADF 939 * dics.dir������������������������������������ -10 BADDR 940 */ 941int 942RkwGetWordTextDic(int cx_num, unsigned char *dirname, unsigned char *dicname, WCHAR_T *info, int infolen) 943{ 944 struct RkContext *new_cx, *cx; 945 struct DM *dm; 946 int new_cx_num; 947 struct TD *initial_td; 948 unsigned size; 949 unsigned char *buff = 0; 950 struct _rec *gwt; 951 952 if (!dicname || !dirname || !info || !(cx = RkGetContext(cx_num)) || 953 !(gwt = (struct _rec *)cx->cx_gwt)) 954 return BADCONT; 955 956 if(dicname[0] != '\0') { 957 size = strlen((char *)dicname) + 1; 958 if (!(buff = (unsigned char *)malloc(size))) 959 return (NOTALC); 960 (void)strcpy((char *)buff, (char *)dicname); 961 962 if(dirname[0] != '\0') { 963 if((new_cx_num = RkwCreateContext()) < 0) { 964 free(buff); 965 return BADCONT; 966 } 967 if(RkwSetDicPath(new_cx_num, (char *)dirname) < 0) { 968 RkwCloseContext(new_cx_num); 969 free(buff); 970 return NOTALC; 971 } 972 } else { 973 if ((new_cx_num = RkwDuplicateContext(cx_num)) < 0) { 974 free(buff); 975 return BADCONT; 976 } 977 } 978 if (!(cx = RkGetContext(cx_num)) || !(gwt = (struct _rec *)cx->cx_gwt)) { 979 RkwCloseContext(new_cx_num); 980 free(buff); 981 return BADCONT; 982 } 983 984 if (!(new_cx = RkGetContext(new_cx_num))) { 985 if(dirname[0] != '\0') { 986 RkwCloseContext(new_cx_num); 987 free(buff); 988 return BADCONT; 989 } 990 } 991 if (gwt->gwt_cx >= 0) { 992 RkwCloseContext(gwt->gwt_cx); 993 gwt->gwt_cx = -1; 994 } 995 996 if(!STRCMP(dirname, SYSTEM_DDHOME_NAME)) { 997 if (!(dm = _RkSearchDDP(new_cx->ddpath, (char *)dicname))) { 998 if (dirname[0] != '\0') { 999 RkwCloseContext(new_cx_num); 1000 } 1001 free(buff); 1002 return NOENT; 1003 } 1004 } else { 1005 if (!(dm = _RkSearchUDDP(new_cx->ddpath, dicname))) { 1006 if(dirname[0] != '\0') { 1007 RkwCloseContext(new_cx_num); 1008 } 1009 free(buff); 1010 return NOENT; 1011 } 1012 } 1013 if (DM2TYPE(dm) != DF_TEMPDIC ) { 1014 if(dirname[0] != '\0') { 1015 RkwCloseContext(new_cx_num); 1016 } 1017 free(buff); 1018 return BADF; 1019 } 1020 if(RkwMountDic(new_cx_num, (char *)dicname,0) == -1) { 1021 RkwCloseContext(new_cx_num); 1022 free(buff); 1023 return NOMOUNT; 1024 } 1025 1026 if (!_RkSearchDDP(new_cx->ddpath, (char *)dicname)) { 1027 RkwCloseContext(new_cx_num); 1028 free(buff); 1029 return BADDR; 1030 } 1031 gwt->gwt_cx = new_cx_num; 1032 if (gwt->gwt_dicname) 1033 free(gwt->gwt_dicname); 1034 gwt->gwt_dicname = buff; 1035 initial_td = (struct TD *)dm->dm_td; 1036 } 1037 else { 1038 if ((new_cx_num = gwt->gwt_cx) < 0 1039 || !(new_cx = RkGetContext(new_cx_num))) { 1040 if (gwt->gwt_dicname) 1041 free(gwt->gwt_dicname); 1042 gwt->gwt_dicname = (unsigned char *)0; 1043 return BADCONT; 1044 } 1045 initial_td = (struct TD *)0; 1046 } 1047 if (GetLine(new_cx, cx->gram->gramdic, (struct TD *)initial_td, 1048 info, infolen) < 0) { 1049 RkwUnmountDic(new_cx_num, (char *)gwt->gwt_dicname); 1050 RkwCloseContext(new_cx_num); 1051 gwt->gwt_cx = -1; 1052 return 0; 1053 } 1054 infolen = uslen((WCHAR_T *)info); 1055 return infolen; 1056} 1057