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