PageRenderTime 27ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/1.0/server/function.c

http://as3chat.googlecode.com/
C | 349 lines | 298 code | 41 blank | 10 comment | 90 complexity | b013b50f8976c270d27129219534326a MD5 | raw file
  1. #include "MyleftServer.h"
  2. void sleep_thread(int sec);
  3. void *heartbeat(void *args) {
  4. int i;
  5. while (1) {
  6. sleep_thread(20);
  7. time(&mytimestamp);
  8. p = gmtime(&mytimestamp);
  9. for (i = 0; i < MAX_FDS; i++) {
  10. if (fd_clients[i] == NULL) {
  11. continue;
  12. }
  13. if ((mytimestamp - fd_clients[i]->keepalivetime) > 60) {
  14. log_write(LOG_DEBUG, "60???????????", __FILE__, __LINE__);
  15. node_del(fd_clients[i]);
  16. }
  17. }
  18. pthread_testcancel();
  19. }
  20. pthread_exit(NULL);
  21. }
  22. void sleep_thread(int sec) {
  23. struct timespec wake;
  24. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  25. pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  26. time(&mytimestamp);
  27. p = gmtime(&mytimestamp);
  28. wake.tv_sec = mytimestamp + sec;
  29. //??????sec??msec?????????????????????
  30. //nsec = now.tv_usec * 1000 + (msec % 1000000) * 1000;
  31. //wake.tv_sec = now.tv_sec + msec / 1000000 + nsec / 1000000000;
  32. wake.tv_nsec = 0;
  33. pthread_mutex_lock(&mutex);
  34. pthread_cond_timedwait(&cond, &mutex, &wake);
  35. pthread_mutex_unlock(&mutex);
  36. pthread_mutex_destroy(&mutex);
  37. pthread_cond_destroy(&cond);
  38. }
  39. void md5(const char *str, char *dec) {
  40. MD5_CTX ctx;
  41. unsigned char digest[16];
  42. MD5_Init(&ctx);
  43. MD5_Update(&ctx, str, strlen(str));
  44. MD5_Final(digest, &ctx);
  45. char tmp[3] = {'\0'};
  46. int i;
  47. for (i = 0; i < sizeof (digest); i++) {
  48. sprintf(tmp, "%02x", digest[i]);
  49. strcat(dec, tmp);
  50. }
  51. printf("%s\n", dec);
  52. }
  53. int evutil_make_socket_nonblocking(int fd) {
  54. if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
  55. log_write(LOG_ERR, "fcntl(O_NONBLOCK) failed", __FILE__, __LINE__);
  56. return (EXIT_FAILURE);
  57. }
  58. return (EXIT_SUCCESS);
  59. }
  60. int join_room(clients *p, int roomid) {
  61. char msgbuffer[MAX_BUFFER_LENGTH];
  62. printf("join_room:%d\n", roomid);
  63. if (p == NULL || roomid > MAX_ROOMS || roomid < 0 || rooms[roomid].enable == 0 || p->roomid == roomid) {
  64. return RETURN_FAILURE;
  65. }
  66. if (p->roomid >= 0) {
  67. leave_room(p);
  68. }
  69. pthread_mutex_lock(&t_mutex_room[roomid]);
  70. if (roomid < MAX_ROOMS && roomid>-1 && rooms[roomid].enable) {
  71. p->roomid = roomid;
  72. if (rooms[roomid].client == NULL) {
  73. rooms[roomid].client = p;
  74. } else {
  75. clients *client = rooms[roomid].client;
  76. log_write(LOG_DEBUG, "???????", __FILE__, __LINE__);
  77. while (client->next != NULL) {
  78. log_write(LOG_DEBUG, "????", __FILE__, __LINE__);
  79. client = client->next;
  80. }
  81. client->next = p;
  82. p->next = NULL;
  83. }
  84. rooms[roomid].num++;
  85. //??????????
  86. printf("??????????:%d\n", p->fd, __FILE__, __LINE__);
  87. bzero(msgbuffer, sizeof (msgbuffer));
  88. snprintf(msgbuffer, sizeof (msgbuffer), "<event type='%d' roomid='%d' name='%s' message='??????'/>", EV_TYPE_CHANGE_ROOM, roomid, rooms[roomid].name);
  89. send_message(p->fd, msgbuffer);
  90. //????????????
  91. bzero(msgbuffer, sizeof (msgbuffer));
  92. snprintf(msgbuffer, sizeof (msgbuffer), "<event type='%d' username='%s'/>", EV_TYPE_USER_LOGIN, p->username);
  93. send_message_all(p->fd, msgbuffer);
  94. //??????
  95. log_write(LOG_DEBUG, "??????", __FILE__, __LINE__);
  96. send_userlist(p);
  97. log_write(LOG_ERR, "roomresetlock", __FILE__, __LINE__);
  98. }
  99. pthread_mutex_unlock(&t_mutex_room[roomid]);
  100. return RETURN_SUCCESS;
  101. }
  102. int leave_room(clients *p) {
  103. char msgbuffer[MAX_BUFFER_LENGTH];
  104. log_write(LOG_ERR, "leave_room", __FILE__, __LINE__);
  105. if (p == NULL || p->roomid > MAX_ROOMS || p->roomid < 0) {
  106. return RETURN_FAILURE;
  107. }
  108. int roomid = p->roomid;
  109. pthread_mutex_lock(&t_mutex_room[roomid]);
  110. if (roomid < MAX_ROOMS && roomid>-1 && rooms[p->roomid].client != NULL) {
  111. log_write(LOG_ERR, "leave_room2", __FILE__, __LINE__);
  112. clients *client = rooms[roomid].client;
  113. clients *prev = NULL;
  114. log_write(LOG_ERR, "leave_room-", __FILE__, __LINE__);
  115. while (client != NULL) {
  116. log_write(LOG_ERR, "leave_room--", __FILE__, __LINE__);
  117. if (client->fd == p->fd) {
  118. rooms[roomid].num--;
  119. log_write(LOG_ERR, "leave_room3", __FILE__, __LINE__);
  120. if (prev != NULL) {
  121. prev->next = client->next;
  122. } else {
  123. rooms[roomid].client = client->next;
  124. }
  125. break;
  126. }
  127. prev = client;
  128. client = client->next;
  129. }
  130. if (p->state == FD_STATE_SUCCESS) {
  131. bzero(msgbuffer, sizeof (msgbuffer));
  132. snprintf(msgbuffer, sizeof (msgbuffer), "<event type='%d' username='%s'/>", EV_TYPE_USER_LOGOUT, p->username);
  133. send_message_all(p->fd, msgbuffer);
  134. p->roomid = -1;
  135. }
  136. log_write(LOG_ERR, "roomresetlock", __FILE__, __LINE__);
  137. }
  138. pthread_mutex_unlock(&t_mutex_room[roomid]);
  139. log_write(LOG_DEBUG, "leave_room end", __FILE__, __LINE__);
  140. return RETURN_SUCCESS;
  141. }
  142. int node_add(clients *p) {
  143. log_write(LOG_ERR, "node_add", __FILE__, __LINE__);
  144. if (p != NULL) {
  145. log_write(LOG_ERR, "node_add2", __FILE__, __LINE__);
  146. hash_item *item = (hash_item *) malloc(sizeof (hash_item));
  147. item->key = p->username;
  148. item->data = (void *) p->fd;
  149. item->next = NULL;
  150. hash_add(item);
  151. }
  152. log_write(LOG_ERR, "node_add end", __FILE__, __LINE__);
  153. return RETURN_SUCCESS;
  154. }
  155. int node_del(clients *p) {
  156. log_write(LOG_ERR, "node_del", __FILE__, __LINE__);
  157. if (p != NULL) {
  158. close(p->fd);
  159. log_write(LOG_ERR, "node_del--", __FILE__, __LINE__);
  160. leave_room(p);
  161. hash_del(p->username, p->fd);
  162. fd_clients[p->fd] = NULL;
  163. free(p);
  164. p = NULL;
  165. log_write(LOG_DEBUG, "node_del11", __FILE__, __LINE__);
  166. }
  167. log_write(LOG_ERR, "node_del2", __FILE__, __LINE__);
  168. return RETURN_SUCCESS;
  169. }
  170. void send_userlist(clients *node) {
  171. printf("roomid:%d,enable:%d, name:%s\n", node->roomid, rooms[node->roomid].enable, rooms[node->roomid].name);
  172. if (node->roomid < MAX_ROOMS && node->roomid>-1 && rooms[node->roomid].enable) {
  173. clients *p = rooms[node->roomid].client;
  174. char msgbuffer[MAX_BUFFER_LENGTH];
  175. while (p != NULL) {
  176. if (p->fd != node->fd && p->state == FD_STATE_SUCCESS) {
  177. bzero(msgbuffer, sizeof (msgbuffer));
  178. snprintf(msgbuffer, sizeof (msgbuffer), "<event type='%d' username='%s' x='%d' y='%d' />", EV_TYPE_USER_ADD, p->username, p->x, p->y);
  179. send_message(node->fd, msgbuffer);
  180. }
  181. p = p->next;
  182. }
  183. }
  184. }
  185. void send_roomlist(clients *node) {
  186. char msgbuffer[MAX_BUFFER_LENGTH];
  187. int i;
  188. for (i = 0; i < MAX_ROOMS; i++) {
  189. if (rooms[i].enable) {
  190. printf("?%d??:%s\n", i, rooms[i].name);
  191. bzero(msgbuffer, sizeof (msgbuffer));
  192. snprintf(msgbuffer, sizeof (msgbuffer), "<event type='%d' roomid='%d' name='%s' num='%d'/>", EV_TYPE_ROOM_ADD, i, rooms[i].name, rooms[i].num);
  193. send_message(node->fd, msgbuffer);
  194. } else {
  195. break;
  196. }
  197. }
  198. }
  199. void other_same_username(clients *node) {
  200. char msgbuffer[MAX_BUFFER_LENGTH];
  201. if (node != NULL) {
  202. leave_room(node);
  203. log_write(LOG_DEBUG, "??????", __FILE__, __LINE__);
  204. if (node->state == FD_STATE_SUCCESS) {
  205. node->state = FD_STATE_WAIT;
  206. bzero(msgbuffer, sizeof (msgbuffer));
  207. snprintf(msgbuffer, sizeof (msgbuffer), "<event type='%d' message='?????????'/>", EV_TYPE_AUTH_OTHER_LOGIN);
  208. send_message(node->fd, msgbuffer);
  209. bzero(msgbuffer, sizeof (msgbuffer));
  210. //??????????
  211. snprintf(msgbuffer, sizeof (msgbuffer), "<event type='%d' username='%s'/>", EV_TYPE_USER_LOGOUT, node->username);
  212. send_message_all(node->fd, msgbuffer);
  213. }
  214. }
  215. }
  216. clients *get_fdnode_byname(const char *uname, int ufd) {
  217. log_write(LOG_ERR, "get_fdnode_byname", __FILE__, __LINE__);
  218. log_write(LOG_ERR, uname, __FILE__, __LINE__);
  219. hash_item *found_item = hash_search(uname);
  220. int fd = -1;
  221. while (found_item != NULL) {
  222. log_write(LOG_ERR, found_item->key, __FILE__, __LINE__);
  223. if (strcmp(found_item->key, uname) == 0 && (ufd < 0 || (int) found_item->data != ufd)) {
  224. fd = (int) found_item->data;
  225. break;
  226. }
  227. found_item = found_item->next;
  228. }
  229. return fd >= 0 ? fd_clients[fd] : NULL;
  230. }
  231. void send_message(const int fd, const char* message) {
  232. printf("message:%s, to :%d,file:%s, line:%d\n", message, fd, __FILE__, __LINE__);
  233. int ret = -1;
  234. if (message != NULL) {
  235. ret = write(fd, message, strlen(message));
  236. }
  237. }
  238. //????
  239. void send_message_all(const int fd, const char* message) {
  240. if (fd_clients[fd] == NULL || message == NULL) return;
  241. clients *client = fd_clients[fd];
  242. if (client->roomid < MAX_ROOMS && client->roomid>-1 && rooms[client->roomid].client != NULL) {
  243. printf("send_message_all:%s, file:%s, line:%d\n", message, __FILE__, __LINE__);
  244. clients *p = rooms[client->roomid].client;
  245. while (p != NULL) {
  246. if (p->state == FD_STATE_SUCCESS) {
  247. printf("message:%s, to :%d,file:%s, line:%d\n", message, p->fd, __FILE__, __LINE__);
  248. send_message(p->fd, message);
  249. }
  250. p = p->next;
  251. }
  252. }
  253. }
  254. int get_attribute(char* xml, char* attribute, char* buffer, int len) {
  255. // Get to the start of the attribute
  256. char* as = strstr(xml, attribute);
  257. if (!as) return (RETURN_FAILURE);
  258. // Read the attribute
  259. char* start = NULL;
  260. int numchars = 0;
  261. int i = 0;
  262. for (i = 0; i < strlen(as); i++) {
  263. if (start) numchars++;
  264. if (*(as + i) == '\'' || *(as + i) == '"') {
  265. if (!start)
  266. start = (as + i + 1);
  267. else
  268. break;
  269. }
  270. }
  271. // Store the result in the buffer
  272. if (numchars > len) return (RETURN_FAILURE);
  273. strncpy(buffer, start, numchars);
  274. *(buffer + numchars - 1) = '\0';
  275. return (RETURN_SUCCESS);
  276. }
  277. // Extracts the contents of the xml tag given and stores it in the buffer
  278. int get_tag(char* xml, char* tag, char* buffer, int len) {
  279. char tagopen[32];
  280. char tagclose[32];
  281. char inone[32];
  282. snprintf(tagopen, sizeof (tagopen), "<%s", tag);
  283. snprintf(tagclose, sizeof (tagclose), "</%s>", tag);
  284. snprintf(inone, sizeof (inone), "<%s/>", tag);
  285. // If the tag is present, but has no content, stop now
  286. if (strstr(xml, inone)) return (RETURN_SUCCESS);
  287. // Get to the start of the tag
  288. char* as = strstr(xml, tagopen);
  289. if (!as) return (RETURN_FAILURE);
  290. char* ap = strstr(as, ">") + sizeof (char);
  291. if (!as) return (RETURN_FAILURE);
  292. // Find the end
  293. int i = 0;
  294. while (*(ap + (sizeof (char) * i)) != '<') i++;
  295. // Store the result in the buffer
  296. if (i > len) return (RETURN_FAILURE);
  297. strncpy(buffer, ap, i);
  298. *(buffer + i) = '\0';
  299. return (RETURN_SUCCESS);
  300. }