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

📄 server.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * server.c - server object functions * * Copyright (C) 2000, 2001 Stefan Jahn <stefan@lkcc.org> * Copyright (C) 2000 Raimund Jacob <raimi@lkcc.org> * * 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: server.c,v 1.28 2001/08/17 13:54:15 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#define _GNU_SOURCE#include <stdio.h>#include <string.h>#ifdef __MINGW32__# include <winsock2.h>#else# include <sys/types.h># include <sys/socket.h># include <netinet/in.h># include <arpa/inet.h>#endif#include "libserveez/alloc.h"#include "libserveez/hash.h"#include "libserveez/util.h"#include "libserveez/core.h"#include "libserveez/array.h"#include "libserveez/socket.h"#include "libserveez/server-core.h"#include "libserveez/server.h"#include "libserveez/binding.h"#include "libserveez/dynload.h"/* * The list of registered server. Feel free to add yours. */svz_array_t *svz_servertypes = NULL;/* * Add the server type @var{server} to the currently registered servers. */voidsvz_servertype_add (svz_servertype_t *server){  int n;  svz_servertype_t *stype;  /* Check if the server definition is valid. */  if (!server || !server->prefix || !server->description)    {      svz_log (LOG_ERROR, "invalid server type\n");      return;    }  /* Check if the server is already registered. */  svz_array_foreach (svz_servertypes, stype, n)    {      if (!strcmp (server->prefix, stype->prefix))	{	  svz_log (LOG_ERROR, "server type `%s' already registered\n", 		   server->description);	  return;	}    }  /* Run the global server type initializer. */  if (server->global_init != NULL)     if (server->global_init (server) < 0)       {	svz_log (LOG_ERROR, "error running global init for `%s'\n",		 server->description);	return;      }  /* Add this definition to the registered servers. */  if (svz_servertypes == NULL)    if ((svz_servertypes = svz_array_create (1)) == NULL)      return;  svz_array_add (svz_servertypes, server);}/* * Delete the server type with the index @var{index} from the list of * known server types and run its global finalizer if necessary. Moreover * we remove and finalize each server instance of this server type. */voidsvz_servertype_del (unsigned long index){  svz_servertype_t *stype;  svz_server_t **server;  int n, i;  /* Return here if there is no such server type. */  if (svz_servertypes == NULL || index >= svz_array_size (svz_servertypes))    return;  /* Run the server type's global finalizer if necessary and delete it      from the list of known servers then. */  if ((stype = svz_array_get (svz_servertypes, index)) != NULL)    {      /* Find server instance of this server type and remove and finalize	 them if necessary. */      n = svz_hash_size (svz_servers) - 1;      svz_hash_foreach_value (svz_servers, server, i)	{	  if (server[n]->type == stype)	    {	      svz_server_del (server[n]->name);	      i--;	    }	  n--;	}      if (stype->global_finalize != NULL)	stype->global_finalize (stype);      svz_array_del (svz_servertypes, index);    }}/* * Find a servertype definition by its short name. If @var{dynamic} is set * to non-zero an attempt is made to load a shared library that provides  * that servertype. Returns @code{NULL} if no server with the given variable  * prefix @var{name} has been found. */svz_servertype_t *svz_servertype_get (char *name, int dynamic){  svz_servertype_t *stype;  int n;  /* first, try with already loaded ones */  svz_array_foreach (svz_servertypes, stype, n)    {      if (!strcmp (name, stype->prefix))	return stype;    }  /* now, try dynamically */  if (dynamic)    {      if (NULL != (stype = svz_servertype_load (name)))	{	  svz_servertype_add (stype);	  return stype;	}    }  return NULL;}/* * Run the global finalizers of each server type and delete all server * types. */voidsvz_servertype_finalize (void){  int i;  svz_servertype_t *stype;  svz_log (LOG_NOTICE, "running global server type finalizers\n");  svz_array_foreach (svz_servertypes, stype, i)    {      if (stype->global_finalize != NULL)	stype->global_finalize (stype);    }  if (svz_servertypes != NULL)    {      svz_array_destroy (svz_servertypes);      svz_servertypes = NULL;    }}/* * Find a given server instances @var{server} server type. Return @code{NULL} * if there is no such server type (which should never occur since a server is * a child of an server type. */svz_servertype_t *svz_servertype_find (svz_server_t *server){  return server ? server->type : NULL;}#if ENABLE_DEBUG/* * Debug helper function to traverse all currently known server types. */voidsvz_servertype_print (void){  int s, i;  svz_servertype_t *stype;  svz_array_foreach (svz_servertypes, stype, s)    {      printf ("[%d] - %s\n", s, stype->description);      printf ("  detect_proto() at %p"	      "  connect_socket() at %p\n",	      (void *) stype->detect_proto, (void *) stype->connect_socket);            if (stype->prototype_start != NULL)	{	  printf ("  configblock %d byte at %p: \n",		  stype->prototype_size, stype->prototype_start);	  for (i = 0; stype->items[i].type != SVZ_ITEM_END; i++)	    {	      long offset = (char *) stype->items[i].address -		(char *) stype->prototype_start;	      	      printf ("   variable `%s' at offset %d, %sdefaultable: ",		      stype->items[i].name, (int) offset,		      stype->items[i].defaultable ? "" : "not ");	      switch (stype->items[i].type) 		{		case SVZ_ITEM_BOOL:		  printf ("bool\n");		  break;		case SVZ_ITEM_INT:		  printf ("int\n");		  break;		case SVZ_ITEM_INTARRAY:		  printf ("int array\n");		  break;		case SVZ_ITEM_STR:		  printf ("string\n");		  break;		case SVZ_ITEM_STRARRAY:		  printf ("string array\n");		  break;		case SVZ_ITEM_HASH:		  printf ("hash\n");		  break;		case SVZ_ITEM_PORTCFG:		  printf ("port configuration\n");		  break;		default:		  printf ("unknown\n");		}	    }	}       else 	{	  printf ("  no configuration option\n");	}    }}#endif /* ENABLE_DEBUG *//* * This is the list of actually instantiated servers. The hash table  * associates the servers' names with the server instances. */svz_hash_t *svz_servers = NULL;/* * Run all the server instances's notify routines. This should be regularly * called within the @code{svz_periodic_tasks()} function. */voidsvz_server_notifiers (void){  int n;  svz_server_t **server;  svz_hash_foreach_value (svz_servers, server, n)    {      if (server[n]->notify)	server[n]->notify (server[n]);    }}/* * Find a server instance by the given configuration structure @var{cfg}.  * Return @code{NULL} if there is no such configuration in any server * instance. */svz_server_t *svz_server_find (void *cfg){  int n;  svz_server_t **servers, *server = NULL;  svz_hash_foreach_value (svz_servers, servers, n)    {      if (servers[n]->cfg == cfg)	server = servers[n];    }  return server;}/* * Add the server instance @var{server} to the list of instantiated  * servers. Returns the previous value of that server if any or @code{NULL} * otherwise. */svz_server_t *svz_server_add (svz_server_t *server){  if (svz_servers == NULL)    svz_servers = svz_hash_create (4);  return svz_hash_put (svz_servers, server->name, server);}/* * Get the server instance with the given instance name @var{name}. * Return @code{NULL} if there is no such server yet. */svz_server_t *svz_server_get (char *name){  if (svz_servers == NULL || name == NULL)    return NULL;  return svz_hash_get (svz_servers, name);}/* * Remove the server instance identified by the name @var{name}. */voidsvz_server_del (char *name){  svz_server_t *server;  if (svz_servers == NULL)    return;  if ((server = svz_hash_delete (svz_servers, name)) != NULL)    {      svz_server_unbind (server);      svz_server_free (server);    }}/* * Release the configuration @var{cfg} of the given server type @var{server}. * If the servers configuration equals @code{NULL} no operation is  * performed. */voidsvz_config_free (svz_servertype_t *server, void *cfg){  int n;  void **target;  /* Return here if there nothing to do. */  if (server == NULL || cfg == NULL)    return;  /* Go through the list of configuration items. */  for (n = 0; server->items[n].type != SVZ_ITEM_END; n++)    {      /* Calculate the target address. */      target = (void **) ((long) cfg + 			  (long) ((long) server->items[n].address - 				  (long) server->prototype_start));      /* Depending on the type of configuration item we need to free	 different data structures. */      switch (server->items[n].type)         {          /* Integer array. */        case SVZ_ITEM_INTARRAY:	  if (*target)	    svz_config_intarray_destroy (*target);          break;	  /* Simple character string. */        case SVZ_ITEM_STR:	  if (*target)	    svz_free (*target);          break;          	  /* Array of strings. */        case SVZ_ITEM_STRARRAY:	  if (*target)	    svz_config_strarray_destroy (*target);          break;	  /* Hash table. */        case SVZ_ITEM_HASH:	  if (*target)	    svz_config_hash_destroy (*target);          break;	  /* Port configuration. */        case SVZ_ITEM_PORTCFG:	  if (*target)	    svz_portcfg_destroy (*target);          break;        }    }  svz_free (cfg);}/* * Clear each configuration item within the given configuration @var{cfg} of * the server type @var{server}. This function is used by  * @code{svz_server_configure()} after copying the default configuration. */static voidsvz_config_clobber (svz_servertype_t *server, void *cfg){  int n;  void **target;  /* Return here if there nothing to do. */  if (server == NULL || cfg == NULL)    return;  /* Go through the list of configuration items. */  for (n = 0; server->items[n].type != SVZ_ITEM_END; n++)    {      /* Calculate the target address. */      target = (void **) ((long) cfg + 			  (long) ((long) server->items[n].address - 				  (long) server->prototype_start));      /* Clobber only configuration items which are pointers. */      if (server->items[n].type == SVZ_ITEM_INTARRAY ||	  server->items[n].type == SVZ_ITEM_STR ||	  server->items[n].type == SVZ_ITEM_STRARRAY ||	  server->items[n].type == SVZ_ITEM_HASH ||	  server->items[n].type == SVZ_ITEM_PORTCFG)        {	  *target = NULL;	}    }}/* * Completely destroy the given server instance @var{server}. This  * especially means to go through each item of the server instances  * configuration. */voidsvz_server_free (svz_server_t *server){  svz_config_free (server->type, server->cfg);  svz_free (server->name);  svz_free (server);}/* * Create a new server instance of the server type @var{stype} with the * instance name @var{name}. */svz_server_t *svz_server_instantiate (svz_servertype_t *stype, char *name){

⌨️ 快捷键说明

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