LCOV - code coverage report
Current view: top level - src/pool - config.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 57 67 85.1 %
Date: 2024-03-23 09:12:27 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* TDSPool - Connection pooling for TDS based databases
       2             :  * Copyright (C) 2001 Brian Bruns
       3             :  * Copyright (C) 2005 Frediano Ziglio
       4             :  *
       5             :  * This program is free software; you can redistribute it and/or modify
       6             :  * it under the terms of the GNU General Public License as published by
       7             :  * the Free Software Foundation; either version 2 of the License, or
       8             :  * (at your option) any later version.
       9             :  *
      10             :  * This program is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :  * GNU General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU General Public License
      16             :  * along with this program; if not, write to the Free Software
      17             :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      18             :  *
      19             :  */
      20             : 
      21             : #include <config.h>
      22             : 
      23             : #include <stdarg.h>
      24             : #include <stdio.h>
      25             : #include <ctype.h>
      26             : #include <errno.h>
      27             : 
      28             : #if HAVE_STDLIB_H
      29             : #include <stdlib.h>
      30             : #endif /* HAVE_STDLIB_H */
      31             : 
      32             : #if HAVE_STRING_H
      33             : #include <string.h>
      34             : #endif
      35             : 
      36             : #ifdef HAVE_LIMITS_H
      37             : #include <limits.h>
      38             : #endif
      39             : 
      40             : #include "pool.h"
      41             : #include <freetds/configs.h>
      42             : 
      43             : #define POOL_STR_SERVER "server"
      44             : #define POOL_STR_PORT   "port"
      45             : #define POOL_STR_USER   "user"
      46             : #define POOL_STR_PASSWORD       "password"
      47             : #define POOL_STR_DATABASE       "database"
      48             : #define POOL_STR_SERVER_USER    "server user"
      49             : #define POOL_STR_SERVER_PASSWORD        "server password"
      50             : #define POOL_STR_MAX_MBR_AGE    "max member age"
      51             : #define POOL_STR_MAX_POOL_CONN  "max pool conn"
      52             : #define POOL_STR_MIN_POOL_CONN  "min pool conn"
      53             : #define POOL_STR_MAX_POOL_USERS "max pool users"
      54             : 
      55             : typedef struct {
      56             :         TDS_POOL *pool;
      57             :         char **err;
      58             : } conf_params;
      59             : 
      60             : static void pool_parse(const char *option, const char *value, void *param);
      61             : static bool pool_read_conf_file(const char *path, const char *poolname, conf_params *params);
      62             : 
      63             : bool
      64           2 : pool_read_conf_files(const char *path, const char *poolname, TDS_POOL * pool, char **err)
      65             : {
      66           2 :         bool found = false;
      67           2 :         conf_params params = { pool, err };
      68             : 
      69           2 :         if (path && !found)
      70           0 :                 return pool_read_conf_file(path, poolname, &params);
      71             : 
      72             :         if (!found) {
      73           2 :                 char *path = tds_get_home_file(".pool.conf");
      74           2 :                 if (path) {
      75           2 :                         found = pool_read_conf_file(path, poolname, &params);
      76           2 :                         free(path);
      77             :                 }
      78             :         }
      79             : 
      80           2 :         if (!found)
      81           2 :                 found = pool_read_conf_file(FREETDS_POOLCONFFILE, poolname, &params);
      82             : 
      83             :         return found;
      84             : }
      85             : 
      86             : static bool
      87           4 : pool_read_conf_file(const char *path, const char *poolname, conf_params *params)
      88             : {
      89             :         FILE *in;
      90           4 :         bool found = false;
      91             : 
      92           4 :         in = fopen(path, "r");
      93           4 :         if (in) {
      94           2 :                 tdsdump_log(TDS_DBG_INFO1, "Found conf file %s reading sections\n", path);
      95           2 :                 tds_read_conf_section(in, "global", pool_parse, params);
      96           2 :                 rewind(in);
      97           2 :                 found = tds_read_conf_section(in, poolname, pool_parse, params);
      98           2 :                 fclose(in);
      99             :         }
     100             : 
     101           4 :         return found;
     102             : }
     103             : 
     104             : /**
     105             :  * Parse an unsigned number, returns -1 on error.
     106             :  * Returns a signed int to make possible to return negative
     107             :  * values for include numbers (we don't need big numbers)
     108             :  */
     109             : static int
     110           8 : pool_get_uint(const char *value)
     111             : {
     112             :         char *end;
     113             :         unsigned long int val;
     114             : 
     115           8 :         errno = 0;
     116           8 :         val = strtoul(value, &end, 0);
     117           8 :         if (errno != 0 || end == value || val > INT_MAX)
     118             :                 return -1;
     119           8 :         return (int) val;
     120             : }
     121             : 
     122             : static void
     123          16 : pool_parse(const char *option, const char *value, void *param)
     124             : {
     125          16 :         conf_params *params = (conf_params *) param;
     126          16 :         TDS_POOL *pool = params->pool;
     127          16 :         int val = 0;
     128             : 
     129          16 :         if (!strcmp(option, POOL_STR_PORT)) {
     130           2 :                 val = pool_get_uint(value);
     131           2 :                 if (val < 1 || val >= 65536)
     132           0 :                         val = -1;
     133           0 :                 pool->port = val;
     134          14 :         } else if (!strcmp(option, POOL_STR_SERVER)) {
     135           2 :                 free(pool->server);
     136           2 :                 pool->server = strdup(value);
     137          12 :         } else if (!strcmp(option, POOL_STR_USER)) {
     138           2 :                 free(pool->user);
     139           2 :                 pool->user = strdup(value);
     140          10 :         } else if (!strcmp(option, POOL_STR_DATABASE)) {
     141           2 :                 free(pool->database);
     142           2 :                 pool->database = strdup(value);
     143           8 :         } else if (!strcmp(option, POOL_STR_PASSWORD)) {
     144           2 :                 free(pool->password);
     145           2 :                 pool->password = strdup(value);
     146           6 :         } else if (!strcmp(option, POOL_STR_SERVER_USER)) {
     147           0 :                 free(pool->server_user);
     148           0 :                 pool->server_user = strdup(value);
     149           6 :         } else if (!strcmp(option, POOL_STR_SERVER_PASSWORD)) {
     150           0 :                 free(pool->server_password);
     151           0 :                 pool->server_password = strdup(value);
     152           6 :         } else if (!strcmp(option, POOL_STR_MAX_MBR_AGE)) {
     153           2 :                 val = pool_get_uint(value);
     154           2 :                 pool->max_member_age = val;
     155           4 :         } else if (!strcmp(option, POOL_STR_MAX_POOL_CONN)) {
     156           2 :                 val = pool_get_uint(value);
     157           2 :                 pool->max_open_conn = val;
     158           2 :         } else if (!strcmp(option, POOL_STR_MIN_POOL_CONN)) {
     159           2 :                 val = pool_get_uint(value);
     160           2 :                 pool->min_open_conn = val;
     161             :         }
     162           8 :         if (val < 0) {
     163           0 :                 free(*params->err);
     164           0 :                 if (asprintf(params->err, "Invalid value '%s' specified for %s", value, option) < 0)
     165           0 :                         *params->err = "Memory error parsing options";
     166             :         }
     167          16 : }

Generated by: LCOV version 1.13