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

📄 server.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
  svz_server_t *server;    /* Create server instance itself. */  server = (svz_server_t *) svz_malloc (sizeof (svz_server_t));  server->name = svz_strdup (name);  server->type = stype;  /* Transfer callbacks. */  server->detect_proto = stype->detect_proto;  server->connect_socket = stype->connect_socket;  server->handle_request = stype->handle_request;  server->init = stype->init;  server->finalize = stype->finalize;  server->info_client = stype->info_client;  server->info_server = stype->info_server;  server->notify = stype->notify;  server->description = stype->description;  return server;}/* * Create an array (@code{svz_array_t}) of integers. The given integer * array @var{intarray} is a list of integers where its first element which * is @code{intarray[0]} contains the actual length of the given array. */svz_array_t *svz_config_intarray_create (int *intarray){  int i;  svz_array_t *array = svz_array_create (1);  if (intarray)    {      for (i = 0; i < intarray[0]; i++)	svz_array_add (array, (void *) ((long) intarray[i + 1]));    }  return array;}/* * Destroy the given integer array @var{intarray}. This function is the * counter part of @code{svz_config_intarray_create()}. */voidsvz_config_intarray_destroy (svz_array_t *intarray){  if (intarray)    {      svz_array_destroy (intarray);    }}/* * Make a plain copy of the given integer array @var{intarray}. If this * value is @code{NULL} no operation is performed and the return value * is @code{NULL} too. */svz_array_t *svz_config_intarray_dup (svz_array_t *intarray){  int i;  void *value;  svz_array_t *array = NULL;    if (intarray)    {      array = svz_array_create (svz_array_size (intarray));      svz_array_foreach (intarray, value, i)	svz_array_add (array, value);    }  return array;}/* * Create an array of strings. The given list of strings @var{strarray} * must be @code{NULL} terminated in order to indicate its end. */svz_array_t *svz_config_strarray_create (char **strarray){  int i;  svz_array_t *array = svz_array_create (1);  if (strarray)    {      for (i = 0; strarray[i] != NULL; i++)	svz_array_add (array, svz_strdup (strarray[i]));    }  return array;}/* * Destroy the given string array @var{strarray}. */voidsvz_config_strarray_destroy (svz_array_t *strarray){  int i;  char *string;  if (strarray)    {      svz_array_foreach (strarray, string, i)	svz_free (string);      svz_array_destroy (strarray);    }}/* * Duplicate the given array of strings @var{strarray}. Return @code{NULL} * if @var{strarray} equals @code{NULL}. */svz_array_t *svz_config_strarray_dup (svz_array_t *strarray){  int i;  char *value;  svz_array_t *array = NULL;    if (strarray)    {      array = svz_array_create (svz_array_size (strarray));      svz_array_foreach (strarray, value, i)	svz_array_add (array, svz_strdup (value));    }  return array;}/* * Create a hash table from the given array of strings @var{strarray} which * must be @code{NULL} terminated in order to indicate the end of the list.  * The array consists of pairs of strings where the first one specifies a  * key and the following the associated string value. This function is  * useful when creating default values for server type configurations. */svz_hash_t *svz_config_hash_create (char **strarray){  int i;  svz_hash_t *hash = svz_hash_create (4);  if (strarray)    {      for (i = 0; strarray[i] != NULL; i += 2)	{	  if (strarray[i + 1])	    {	      svz_hash_put (hash, strarray[i], svz_strdup (strarray[i + 1]));	    }	}    }  return hash;}/* * This function is the counter part of @code{svz_config_hash_create()}. It * destroys the given hash table @var{strhash} assuming it is a hash  * associating strings with strings. */voidsvz_config_hash_destroy (svz_hash_t *strhash){  char **strarray;  int i;  if (strhash)    {      svz_hash_foreach_value (strhash, strarray, i)	svz_free (strarray[i]);      svz_hash_destroy (strhash);    }}/* * Duplicate the given hash table @var{strhash} assuming it is a hash  * associating strings with strings. Return @code{NULL} if @var{strhash} is * @code{NULL} too. */svz_hash_t *svz_config_hash_dup (svz_hash_t *strhash){  svz_hash_t *hash = NULL;  int i;  char **keys;  if (strhash)    {      hash = svz_hash_create (4);      svz_hash_foreach_key (strhash, keys, i)	{	  svz_hash_put (hash, keys[i], 			svz_strdup (svz_hash_get (strhash, keys[i])));	}    }  return hash;}/* * This function configures a server instance by modifying its default * configuration by the @var{configure} callbacks. Therefore you need to pass * the type of server in @var{server}, the @var{name} of the server instance * and the (optional) modifier callback structure @var{configure}. The * @var{arg} argument is passed to each of the callbacks (e.g. specifying * a scheme cell). The function returns either a valid server instance  * configuration or @code{NULL} on errors. */void *svz_server_configure (svz_servertype_t *server, 		      char *name, 		      void *arg,		      svz_server_config_t *configure){  int e, n, error = 0;  int hasdef;  void *cfg = NULL, *def, *target = NULL;  unsigned long offset;  /* Run the 'before' callback first. */  if (configure && configure->before)    if (SVZ_ITEM_OK != configure->before (name, arg))      return NULL;  /* Make a simple copy of the example configuration structure definition      for that server instance. */  if (server->prototype_size == 0)    goto out;  cfg = svz_malloc (server->prototype_size);  memcpy (cfg, server->prototype_start, server->prototype_size);  /* Clear all server configuration items which are pointers. Thus we     are able to reverse the changes below. */  svz_config_clobber (server, cfg);  /* Go through list of configuration items. */  for (n = 0; server->items[n].type != SVZ_ITEM_END; n++)    {      /* Calculate the target address. */      offset = (char *) server->items[n].address - 	(char *) server->prototype_start;      hasdef = server->items[n].defaultable;      def = server->items[n].address;      target = (char *) cfg + offset;      e = SVZ_ITEM_DEFAULT_ERRMSG;      /* Check the address of the target. */      if ((unsigned long) target < (unsigned long) cfg ||	  (unsigned long) target >= 	  ((unsigned long) cfg + (unsigned long) server->prototype_size))	{	  svz_log (LOG_FATAL, "%s: invalid target address for %s `%s'\n",		   server->prefix, SVZ_ITEM_TEXT (server->items[n].type),		   server->items[n].name);	  error = -1;	  continue;	}      /* Depending on the type of configuration item we need at this	 point we call the given callbacks and check their return values. */      switch (server->items[n].type)         {	  /* Integer value. */        case SVZ_ITEM_INT:	  if (configure && configure->integer)	    e = configure->integer (name, arg, server->items[n].name,				    (int *) target, hasdef, *(int *) def);          break;	  /* Boolean value. */        case SVZ_ITEM_BOOL:	  if (configure && configure->boolean)	    e = configure->boolean (name, arg, server->items[n].name,				    (int *) target, hasdef, *(int *) def);          break;          /* Integer array. */        case SVZ_ITEM_INTARRAY:	  if (configure && configure->intarray)	    e = configure->intarray (name, arg, server->items[n].name,				     (svz_array_t **) target, hasdef,				     *(svz_array_t **) def);          break;	  /* Simple string. */        case SVZ_ITEM_STR:	  if (configure && configure->string)	    e = configure->string (name, arg, server->items[n].name,				   (char **) target, hasdef, *(char **) def);          break;          	  /* Array of strings. */        case SVZ_ITEM_STRARRAY:	  if (configure && configure->strarray)	    e = configure->strarray (name, arg, server->items[n].name,				     (svz_array_t **) target, hasdef, 				     *(svz_array_t **) def);          break;	  /* Hash table. */        case SVZ_ITEM_HASH:	  if (configure && configure->hash)	    e = configure->hash (name, arg, server->items[n].name,				 (svz_hash_t **) target, hasdef,				 *(svz_hash_t **) def);          break;	  /* Port configuration. */        case SVZ_ITEM_PORTCFG:	  if (configure && configure->portcfg)	    e = configure->portcfg (name, arg, server->items[n].name,				    (svz_portcfg_t **) target, hasdef,				    *(svz_portcfg_t **) def);          break;	  /* Unknown configuration item. */        default:          svz_log (LOG_FATAL, 		   "inconsistent ITEM_ data in server type `%s'\n",		   server->description);          error = -1;	  e = -1; /* special */        }      /* Check the return value of the configure functions. */      switch (e)	{	  /* Special case: skip. */	case -1:	  break;	  /* Successfully configured. */	case SVZ_ITEM_OK:	  break;	  /* Use the default value, if any. */	case SVZ_ITEM_DEFAULT:	case SVZ_ITEM_DEFAULT_ERRMSG:	  /* Target not configured. Defaultable ? */	  if (!server->items[n].defaultable)	    {	      if (SVZ_ITEM_DEFAULT_ERRMSG == e)		svz_log (LOG_ERROR,			 "`%s' lacks a default %s for `%s' in `%s'\n",			 server->description, 			 SVZ_ITEM_TEXT (server->items[n].type),			 server->items[n].name, name);	      error = -1;	      break;	    }	  /* Go on, using default values. */	  switch (server->items[n].type) 	    {	    case SVZ_ITEM_INT: /* Normal integer. */	      *(int *) target = *(int *) def;	      break;	    case SVZ_ITEM_BOOL: /* Boolean value. */	      *(int *) target = *(int *) def;	      break;	    case SVZ_ITEM_INTARRAY: /* Integer array. */	      *(svz_array_t **) target = 		svz_config_intarray_dup (*(svz_array_t **) def);	      break;	    case SVZ_ITEM_STR: /* Character string. */	      *(char **) target = (char *) svz_strdup (*(char **) def);	      break;	    case SVZ_ITEM_STRARRAY: /* Array of strings. */	      *(svz_array_t **) target = 		svz_config_strarray_dup (*(svz_array_t **) def);	      break;	    case SVZ_ITEM_HASH: /* Hash table. */	      *(svz_hash_t **) target = 		svz_config_hash_dup (*(svz_hash_t **) def);	      break;	    case SVZ_ITEM_PORTCFG: /* Port configuration. */	      *(svz_portcfg_t **) target =		svz_portcfg_dup (*(svz_portcfg_t **) def);	      break;	    }	  break;	  /* Configuring failed. Skip error messages. */	case SVZ_ITEM_FAILED:	  error = -1;	  break;	  /* Configuring failed. Print error messages. */	case SVZ_ITEM_FAILED_ERRMSG:	  svz_log (LOG_ERROR,		   "invalid %s value for `%s' in `%s'\n",		   SVZ_ITEM_TEXT (server->items[n].type),		   server->items[n].name, name);	  error = -1;	  break;	  /* Special case: Configure callback invalid. */	default:	  svz_log (LOG_FATAL,		   "invalid SVZ_ITEM_ value (%d) returned by %s "		   "callback for `%s'\n",		   e, SVZ_ITEM_TEXT (server->items[n].type),		   server->items[n].name);	  error = -1;	}    } out:  /* Run the 'after' callback last. */  if (configure && configure->after)    if (SVZ_ITEM_OK != configure->after (name, arg))      error = -1;  /* Release memory reserved for configuration on errors. This means     to reverse the above changes. */  if (error)    {      svz_config_free (server, cfg);      cfg = NULL;    }  return cfg;}/* * Run the initializers of all servers, return -1 if some server did not * think it is a good idea to run. */intsvz_server_init_all (void){  int errneous = 0, i;  svz_server_t **server;  svz_log (LOG_NOTICE, "initializing all server instances\n");  svz_hash_foreach_value (svz_servers, server, i)    {      if (server[i]->init != NULL) 	if (server[i]->init (server[i]) < 0) 	  {	    errneous = -1;	    svz_log (LOG_ERROR, "error initializing `%s'\n", server[i]->name);	  }    }  return errneous;}/* * Run the local finalizers for all server instances. */intsvz_server_finalize_all (void){  int i, n;  svz_server_t **server;  svz_log (LOG_NOTICE, "running all server finalizers\n");  n = svz_hash_size (svz_servers) - 1;  svz_hash_foreach_value (svz_servers, server, i)    {      if (server[n]->finalize != NULL)	server[n]->finalize (server[n]);      svz_server_del (server[n]->name);      i--;      n--;    }  svz_hash_destroy (svz_servers);  svz_servers = NULL;  return 0;}

⌨️ 快捷键说明

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