⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 awcs-proto.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * awcs-proto.c - aWCS protocol implementation * * Copyright (C) 2000, 2001 Stefan Jahn <stefan@lkcc.org> * Copyright (C) 1999 Martin Grabmueller <mgrabmue@cs.tu-berlin.de> * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. *  * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this package; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA.   * * $Id: awcs-proto.c,v 1.34 2001/08/12 10:59:04 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#if ENABLE_AWCS_PROTO#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#if HAVE_UNISTD_H# include <unistd.h>#endif#ifdef __MINGW32__# include <winsock2.h>#endif#ifndef __MINGW32__# include <netinet/in.h>#endif#include "libserveez.h"#include "awcs-proto.h"/* * The aWCS server instance configuration. */awcs_config_t awcs_config ={  NULL,           /* aWCS Master server */  0,              /* Was Master server detected ? */  NULL            /* aWCS clients user base hash */};/* * Definition of the configuration items delivered by the  * configuration language. */svz_key_value_pair_t awcs_config_prototype [] ={  SVZ_REGISTER_END ()};/* * The aWCS server definition. */svz_servertype_t awcs_server_definition ={  "aWCS server",         /* server description */  "aWCS",                /* server prefix used in the config file "aWCS?" */  NULL,                  /* global initialization */  awcs_init,             /* server instance initialization */  awcs_detect_proto,     /* protocol detection routine */  awcs_connect_socket,   /* callback when detected */  awcs_finalize,         /* server instance finalization */  NULL,                  /* global finalization */  NULL,                  /* client info */  NULL,                  /* server info */  NULL,                  /* server timer */  NULL,                  /* handle request callback */  &awcs_config,          /* the instance configuration */  sizeof (awcs_config),  /* sizeof the instance configuration */  awcs_config_prototype  /* configuration definitions  */};/* * These 3 (three) routines are for modifying the client hash key * processing. Because we are using unique IDs for identifying aWCS  * clients it is not necessary to have character strings here. */static unsignedawcs_hash_keylen (char *id){  return 4;}static int awcs_hash_equals (char *id1, char *id2){  return memcmp (id1, id2, 4);} static unsigned long awcs_hash_code (char *id){  unsigned long code = SVZ_UINT32 (id);  return code;}/* * Local aWCS server instance initialization routine. */intawcs_init (svz_server_t *server){  awcs_config_t *cfg = server->cfg;  /* initialize server instance */  cfg->master = 0;  cfg->clients = svz_hash_create (4);  cfg->clients->code = awcs_hash_code;  cfg->clients->keylen = awcs_hash_keylen;  cfg->clients->equals = awcs_hash_equals;  cfg->server = NULL;  return 0;}/* * Local aWCS server instance finalizer. */intawcs_finalize (svz_server_t *server){  awcs_config_t *cfg = server->cfg;    svz_hash_destroy (cfg->clients);    return 0;}/* * Gets called when a nslookup coserver has resolved a IP address * for socket SOCK to name and has been identified as an aWCS client. */intawcs_nslookup_done (char *host, int id, int version){  awcs_config_t *cfg;  svz_socket_t *sock = svz_sock_find (id, version);  if (host && sock)    {      cfg = sock->cfg;      if (!cfg->server)	{#if ENABLE_DEBUG	  svz_log (LOG_DEBUG, "awcs: no master server (nslookup_done)\n");#endif	  return -1;	}#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "awcs: sending resolved ip to master\n");#endif      if (svz_sock_printf (cfg->server, AWCS_ID_FMT " %d " AWCS_ID_FMT " %s%c",			   cfg->server->id,			   STATUS_NSLOOKUP,			   sock->id,			   host, '\0'))	{	  svz_log (LOG_FATAL, "awcs: master write error\n");	  svz_sock_schedule_for_shutdown (cfg->server);	  cfg->server = NULL;	  awcs_disconnect_clients (cfg);	  return -1;	}    }  return 0;}/* * Gets called when a ident coserver has resolved a IP address * for socket SOCK to name and has been identified as an aWCS client. */intawcs_ident_done (char *user, int id, int version){  svz_socket_t *sock = svz_sock_find (id, version);  awcs_config_t *cfg;  if (user && sock)    {      cfg = sock->cfg;      if (!cfg->server)	{#if ENABLE_DEBUG	  svz_log (LOG_DEBUG, "awcs: no master server (ident_done)\n");#endif	  return -1;	}#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "awcs: sending identified client to master\n");#endif      if (svz_sock_printf (cfg->server, AWCS_ID_FMT " %d " AWCS_ID_FMT " %s%c",			   cfg->server->id,			   STATUS_IDENT,			   sock->id,			   user, '\0'))	{	  svz_log (LOG_FATAL, "awcs: master write error\n");	  svz_sock_schedule_for_shutdown (cfg->server);	  cfg->server = NULL;	  awcs_disconnect_clients (cfg);	  return -1;	}    }  return 0;}/* * This is called when a valid aWCS client has been connected. * The routine reports this to the Master server and invokes * a reverse nslookup and a ident request. */static intawcs_status_connected (svz_socket_t *sock){  unsigned short port;  unsigned long addr;  awcs_config_t *cfg = sock->cfg;  if (!cfg->server)    {#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "awcs: no master server (status_connected)\n");#endif      return -1;    }  addr = sock->remote_addr;  port = sock->remote_port;#if ENABLE_DEBUG  svz_log (LOG_DEBUG, "awcs: sending connect on socket id %d to master\n",	   sock->id);#endif  if (svz_sock_printf (cfg->server, AWCS_ID_FMT " %d " AWCS_ID_FMT " %s:%u%c",		       cfg->server->id,		       STATUS_CONNECT,		       sock->id,		       svz_inet_ntoa (addr),		       htons (port), '\0'))    {      svz_log (LOG_FATAL, "awcs: master write error\n");      svz_sock_schedule_for_shutdown (cfg->server);      cfg->server = NULL;      awcs_disconnect_clients (cfg);      return -1;    }  /*   * Initiate a reverse nslookup and ident request for a real client.   */  if (sock != cfg->server)    {      svz_coserver_rdns (addr, awcs_nslookup_done, sock->id, sock->version);      svz_coserver_ident (sock, awcs_ident_done, sock->id, sock->version);    }  return 0;}/* * Send a status message to the master server * telling it that client `client' has disconnected. `reason' * is an error code telling how the client got disconnected. */static intawcs_status_disconnected (svz_socket_t *sock, int reason){  awcs_config_t *cfg = sock->cfg;  if (!cfg->server)    {#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "awcs: no master server (status_disconnected)\n");#endif      return -1;    }#if ENABLE_DEBUG  svz_log (LOG_DEBUG, "awcs: sending disconnect on socket %d to master\n",	   sock->sock_desc);#endif /* ENABLE_DEBUG */  if (svz_sock_printf (cfg->server, AWCS_ID_FMT " %d " AWCS_ID_FMT " %d%c", 		       cfg->server->id,		       STATUS_DISCONNECT,		       sock->id, 		       reason, '\0'))    {      svz_log (LOG_FATAL, "awcs: master write error\n");      svz_sock_schedule_for_shutdown (cfg->server);      cfg->server = NULL;      awcs_disconnect_clients (cfg);      return -1;    }    return 0;}/* * Send a status message to the master server * telling it that client `client' has been kicked. `reason' * is an error code telling why the client got kicked. */static intawcs_status_kicked (svz_socket_t *sock, int reason){  awcs_config_t *cfg = sock->cfg;    if (!cfg->server)    {#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "awcs: no master server (status_kicked)\n");#endif      return -1;    }  if (svz_sock_printf (cfg->server, AWCS_ID_FMT " %d " AWCS_ID_FMT " %d%c",		       cfg->server->id,		       STATUS_KICK,		       sock->id, 		       reason, '\0'))    {      svz_log (LOG_FATAL, "awcs: master write error\n");      svz_sock_schedule_for_shutdown (cfg->server);      cfg->server = NULL;      awcs_disconnect_clients (cfg);      return -1;    }  return 0;}/* * Send a message to the master server indicating this server * is still alive. */static intawcs_status_alive (awcs_config_t *cfg){  if (!cfg->server)    {#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "awcs: no master server (status_alive)\n");#endif /* ENABLE_DEBUG */      return -1;    }  if (svz_sock_printf (cfg->server, AWCS_ID_FMT " %d 42%c",		       cfg->server->id,		       STATUS_ALIVE, '\0'))    {      svz_log (LOG_FATAL, "awcs: master write error\n");      svz_sock_schedule_for_shutdown (cfg->server);      cfg->server = NULL;      awcs_disconnect_clients (cfg);      return -1;    }    return 0;}static intawcs_status_notify (awcs_config_t *cfg) {  if (!cfg->server)    {#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "awcs: no master server (status_notify)\n");#endif /* ENABLE_DEBUG */      return -1;    }  if (svz_sock_printf (cfg->server, AWCS_ID_FMT " %d 42%c",		       cfg->server->id,		       STATUS_NOTIFY, '\0'))    {      svz_log (LOG_FATAL, "awcs: master write error\n");      svz_sock_schedule_for_shutdown (cfg->server);      cfg->server = NULL;      awcs_disconnect_clients (cfg);      return -1;    }  return 0;}/* * Broadcast message `cmd' to all connected aWCS clients. */static intawcs_process_broadcast (awcs_config_t *cfg, char *cmd, int cmd_len){  svz_socket_t **sock;  int n;  #if ENABLE_DEBUG  svz_log (LOG_DEBUG, "awcs: broadcasting\n");#endif /* ENABLE_DEBUG */  if ((sock = (svz_socket_t **) svz_hash_values (cfg->clients)) != NULL)    {      for (n = 0; n < svz_hash_size (cfg->clients); n++)	{	  if (svz_sock_write (sock[n], cmd, cmd_len))	    {	      svz_sock_schedule_for_shutdown (sock[n]);	    }	}      svz_hash_xfree (sock);    }  return 0;}/* * This macro parse an aWCS id at the given memory location @var{ptr}. The * result will be stored in @var{id} and @var{ptr} points to the following * non numerical byte afterwards. */#define awcs_process_id(id, ptr)           \  (id) = 0;                                \  while (*(ptr) >= '0' && *(ptr) <= '9') { \    (id) *= 10;                            \    (id) += *(ptr) - '0';                  \    (ptr)++; }                             \  if (*(ptr) == ',') (ptr)++/* * Send message @var{cmd} to all clients in the client list at the start  * of @var{cmd}. */static intawcs_process_multicast (awcs_config_t *cfg, char *cmd, int cmd_len){  char *msg;  int address;  svz_socket_t *sock;  /* Parse the actual message first. */  msg = cmd;  while (*msg++ != ' ');  cmd_len -= (msg - cmd);  /* Go through the client list. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -