charlock.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 2001 faster (lqx@cic.tsinghua.edu.cn)
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #include "common/setup_before.h"
  19. #include "setup.h"
  20. #include <stdio.h>
  21. #ifdef STDC_HEADERS
  22. # include <stdlib.h>
  23. #else
  24. # ifdef HAVE_MALLOC_H
  25. #  include <malloc.h>
  26. # endif
  27. #endif
  28. #ifdef HAVE_STRING_H
  29. # include <string.h>
  30. #else
  31. # ifdef HAVE_STRINGS_H
  32. #  include <strings.h>
  33. # endif
  34. # ifdef HAVE_MEMORY_H
  35. #  include <memory.h>
  36. # endif
  37. #endif
  38. #include "compat/strcasecmp.h"
  39. #include <ctype.h>
  40. #ifdef HAVE_LIMITS_H
  41. # include <limits.h>
  42. #endif
  43. #include "charlock.h"
  44. #include "common/introtate.h"
  45. #include "common/setup_after.h"
  46. /* FIXME: for simplification, no multiple realm support now */
  47. /* local functions */
  48. static int cl_insert_to_gsq_list(unsigned int gsid, t_charlockinfo *pcl);
  49. static int cl_delete_from_gsq_list(t_charlockinfo *pcl);
  50. static unsigned int string_hash(char const *string);
  51. /* variables */
  52. static unsigned int clitbl_len = 0;
  53. static unsigned int gsqtbl_len = 0;
  54. static t_charlockinfo * * clitbl = NULL;
  55. static t_charlockinfo * * gsqtbl = NULL;
  56. int cl_init(unsigned int tbllen, unsigned int maxgs)
  57. {
  58. if (!tbllen || !maxgs) return -1;
  59. cl_destroy();
  60. clitbl = (t_charlockinfo**)malloc(tbllen*sizeof(t_charlockinfo**));
  61. if (!clitbl) return -1;
  62. gsqtbl = (t_charlockinfo**)malloc(maxgs*sizeof(t_charlockinfo**));
  63. if (!gsqtbl) {
  64. free(clitbl);
  65. return -1;
  66. }
  67. memset(clitbl, 0, tbllen*sizeof(t_charlockinfo**));
  68. memset(gsqtbl, 0, maxgs*sizeof(t_charlockinfo**));
  69. clitbl_len = tbllen;
  70. gsqtbl_len = maxgs;
  71. return 0;
  72. }
  73. int cl_destroy(void)
  74. {
  75. unsigned int i;
  76. t_charlockinfo * ptl, * ptmp;
  77. if (clitbl) {
  78. for (i=0; i<clitbl_len; i++) {
  79. ptl=clitbl[i];
  80. while (ptl) {
  81. ptmp=ptl;
  82. ptl=ptl->next;
  83. free(ptmp);
  84. }
  85. }
  86. free(clitbl);
  87. }
  88. if (gsqtbl) free(gsqtbl);
  89. clitbl = gsqtbl = NULL;
  90. clitbl_len = gsqtbl_len = 0;
  91. return 0;
  92. }
  93. int cl_query_charlock_status(unsigned char *charname,
  94. unsigned char *realmname, unsigned int *gsid)
  95. {
  96. t_charlockinfo *pcl;
  97. unsigned int hashval;
  98. if (!charname || !realmname) return -1;
  99. if (!clitbl_len || !gsqtbl) return -1;
  100. if (strlen(charname)>=MAX_CHARNAME_LEN) return -1;
  101. hashval = string_hash(charname) % clitbl_len;
  102. pcl = clitbl[hashval];
  103. while(pcl)
  104. {
  105. if (strcasecmp(pcl->charname, charname) == 0) {
  106. *gsid = pcl->gsid;
  107. return 1; /* found the char, it is locked */
  108. }
  109. pcl = pcl->next;
  110. }
  111. return 0; /* not found, it is unlocked */
  112. }
  113. int cl_lock_char(unsigned char *charname,
  114. unsigned char *realmname, unsigned int gsid)
  115. {
  116. t_charlockinfo *pcl, *ptmp;
  117. unsigned int hashval;
  118. if (!charname || !realmname) return -1;
  119. if (!clitbl_len || !gsqtbl) return -1;
  120. if (strlen(charname)>=MAX_CHARNAME_LEN) return -1;
  121. hashval = string_hash(charname) % clitbl_len;
  122. pcl = clitbl[hashval];
  123. ptmp = NULL;
  124. while(pcl)
  125. {
  126. if (strcasecmp(pcl->charname, charname) == 0)
  127. return 0; /* found the char is already locked */
  128. ptmp = pcl;
  129. pcl = pcl->next;
  130. }
  131. /* not found, locked it */
  132. pcl = (t_charlockinfo*)malloc(sizeof(t_charlockinfo));
  133. if (!pcl) return -1; /* no free memory available :( */
  134. memset(pcl, 0, sizeof(t_charlockinfo));
  135. strncpy(pcl->charname, charname, MAX_CHARNAME_LEN-1);
  136. strncpy(pcl->realmname, realmname, MAX_REALMNAME_LEN-1);
  137. pcl->gsid = gsid;
  138. /* add to hash table link list */
  139. if (ptmp) ptmp->next = pcl;
  140. else clitbl[hashval] = pcl;
  141. /* add to gs specified link list */
  142. cl_insert_to_gsq_list(gsid, pcl);
  143. return 0;
  144. }
  145. int cl_unlock_char(unsigned char *charname, unsigned char *realmname, unsigned int gsid)
  146. {
  147. t_charlockinfo *pcl, *ptmp;
  148. unsigned int hashval;
  149. if (!charname || !realmname) return -1;
  150. if (!clitbl_len || !gsqtbl) return 0;
  151. if (strlen(charname)>=MAX_CHARNAME_LEN) return -1;
  152. hashval = string_hash(charname) % clitbl_len;
  153. pcl = clitbl[hashval];
  154. ptmp = NULL;
  155. while(pcl)
  156. {
  157. if ((strcasecmp(pcl->charname, charname) == 0) && (pcl->gsid==gsid)) {
  158. cl_delete_from_gsq_list(pcl);
  159. if (ptmp) ptmp->next = pcl->next;
  160. else clitbl[hashval] = pcl->next;
  161. free(pcl);
  162. return 0;
  163. }
  164. ptmp = pcl;
  165. pcl = pcl->next;
  166. }
  167. return 0;
  168. }
  169. int cl_unlock_all_char_by_gsid(unsigned int gsid)
  170. {
  171. unsigned int index_pos;
  172. t_charlockinfo *pcl, *pnext;
  173. index_pos = gsid % gsqtbl_len;
  174. pcl = gsqtbl[index_pos];
  175. while(pcl)
  176. {
  177. pnext = pcl->gsqnext;
  178. cl_unlock_char(pcl->charname, pcl->realmname, gsid);
  179. pcl = pnext;
  180. }
  181. return 0;
  182. }
  183. static int cl_insert_to_gsq_list(unsigned int gsid, t_charlockinfo *pcl)
  184. {
  185. unsigned int index_pos;
  186. t_charlockinfo *ptmp;
  187. if (!pcl) return -1;
  188. index_pos = gsid % gsqtbl_len;
  189. ptmp = gsqtbl[index_pos];
  190. gsqtbl[index_pos] = pcl;
  191. if (ptmp) {
  192. pcl->gsqnext = ptmp;
  193. ptmp->gsqprev = pcl;
  194. }
  195. return 0;
  196. }
  197. static int cl_delete_from_gsq_list(t_charlockinfo *pcl)
  198. {
  199. unsigned int index_pos;
  200. t_charlockinfo *pprev, *pnext;
  201. if (!pcl) return -1;
  202. index_pos = (pcl->gsid) % gsqtbl_len;
  203. pprev = pcl->gsqprev;
  204. pnext = pcl->gsqnext;
  205. if (pprev) pprev->gsqnext = pnext;
  206. else gsqtbl[index_pos] = pnext;
  207. if (pnext) pnext->gsqprev = pprev;
  208. return 0;
  209. }
  210. static unsigned int string_hash(char const *string)
  211. {
  212. unsigned int i;
  213. unsigned int pos;
  214. unsigned int hash;
  215. unsigned int ch;
  216. if (!string) return 0;
  217. for (hash=0,pos=0,i=0; i<strlen(string); i++)
  218. {
  219. if (isascii((int)string[i]))
  220. ch = (unsigned int)(unsigned char)tolower((int)string[i]);
  221. else
  222. ch = (unsigned int)(unsigned char)string[i];
  223. hash ^= ROTL(ch,pos,sizeof(unsigned int)*CHAR_BIT);
  224. pos += CHAR_BIT-1;
  225. }
  226. return hash;
  227. }