LCOV - code coverage report
Current view: top level - src/pool - config.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 56 66 84.8 %
Date: 2026-11-07 23:58:45 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             : {
      57             :         TDS_POOL *pool;
      58             :         char **err;
      59             : } conf_params;
      60             : 
      61             : static bool pool_parse(const char *option, const char *value, void *param);
      62             : static bool pool_read_conf_file(const tds_dir_char * path, const char *poolname, conf_params * params);
      63             : 
      64             : bool
      65           2 : pool_read_conf_files(const tds_dir_char *path, const char *poolname, TDS_POOL *pool, char **err)
      66             : {
      67           2 :         bool found = false;
      68           2 :         conf_params params = { pool, err };
      69             : 
      70           2 :         if (path && !found)
      71           0 :                 return pool_read_conf_file(path, poolname, &params);
      72             : 
      73             :         if (!found) {
      74           2 :                 tds_dir_char *path = tds_get_home_file(TDS_DIR(".pool.conf"));
      75             : 
      76           2 :                 if (path) {
      77           2 :                         found = pool_read_conf_file(path, poolname, &params);
      78           2 :                         free(path);
      79             :                 }
      80             :         }
      81             : 
      82           2 :         if (!found)
      83           2 :                 found = pool_read_conf_file(FREETDS_POOLCONFFILE, poolname, &params);
      84             : 
      85             :         return found;
      86             : }
      87             : 
      88             : static bool
      89           4 : pool_read_conf_file(const tds_dir_char *path, const char *poolname, conf_params *params)
      90             : {
      91             :         FILE *in;
      92           4 :         bool found = false;
      93             : 
      94           4 :         in = tds_dir_open(path, TDS_DIR("r"));
      95           4 :         if (in) {
      96           2 :                 tdsdump_log(TDS_DBG_INFO1, "Found conf file %" tdsPRIdir " reading sections\n", path);
      97           2 :                 tds_read_conf_section(in, "global", pool_parse, params);
      98           2 :                 rewind(in);
      99           2 :                 found = tds_read_conf_section(in, poolname, pool_parse, params);
     100           2 :                 fclose(in);
     101             :         }
     102             : 
     103           4 :         return found;
     104             : }
     105             : 
     106             : /**
     107             :  * Parse an unsigned number, returns -1 on error.
     108             :  * Returns a signed int to make possible to return negative
     109             :  * values for include numbers (we don't need big numbers)
     110             :  */
     111             : static int
     112           8 : pool_get_uint(const char *value)
     113             : {
     114             :         char *end;
     115             :         unsigned long int val;
     116             : 
     117           8 :         errno = 0;
     118           8 :         val = strtoul(value, &end, 0);
     119           8 :         if (errno != 0 || end == value || val > INT_MAX)
     120             :                 return -1;
     121           8 :         return (int) val;
     122             : }
     123             : 
     124             : static bool
     125          16 : pool_parse(const char *option, const char *value, void *param)
     126             : {
     127          16 :         conf_params *params = (conf_params *) param;
     128          16 :         TDS_POOL *pool = params->pool;
     129          16 :         int val = 0;
     130             : 
     131          16 :         if (!strcmp(option, POOL_STR_PORT)) {
     132           2 :                 val = pool_get_uint(value);
     133           2 :                 if (val < 1 || val >= 65536)
     134           0 :                         val = -1;
     135           0 :                 pool->port = val;
     136          14 :         } else if (!strcmp(option, POOL_STR_SERVER)) {
     137           2 :                 free(pool->server);
     138           2 :                 pool->server = strdup(value);
     139          12 :         } else if (!strcmp(option, POOL_STR_USER)) {
     140           2 :                 free(pool->user);
     141           2 :                 pool->user = strdup(value);
     142          10 :         } else if (!strcmp(option, POOL_STR_DATABASE)) {
     143           2 :                 free(pool->database);
     144           2 :                 pool->database = strdup(value);
     145           8 :         } else if (!strcmp(option, POOL_STR_PASSWORD)) {
     146           2 :                 free(pool->password);
     147           2 :                 pool->password = strdup(value);
     148           6 :         } else if (!strcmp(option, POOL_STR_SERVER_USER)) {
     149           0 :                 free(pool->server_user);
     150           0 :                 pool->server_user = strdup(value);
     151           6 :         } else if (!strcmp(option, POOL_STR_SERVER_PASSWORD)) {
     152           0 :                 free(pool->server_password);
     153           0 :                 pool->server_password = strdup(value);
     154           6 :         } else if (!strcmp(option, POOL_STR_MAX_MBR_AGE)) {
     155           2 :                 val = pool_get_uint(value);
     156           2 :                 pool->max_member_age = val;
     157           4 :         } else if (!strcmp(option, POOL_STR_MAX_POOL_CONN)) {
     158           2 :                 val = pool_get_uint(value);
     159           2 :                 pool->max_open_conn = val;
     160           2 :         } else if (!strcmp(option, POOL_STR_MIN_POOL_CONN)) {
     161           2 :                 val = pool_get_uint(value);
     162           2 :                 pool->min_open_conn = val;
     163             :         }
     164           8 :         if (val < 0) {
     165           0 :                 free(*params->err);
     166           0 :                 if (asprintf(params->err, "Invalid value '%s' specified for %s", value, option) < 0)
     167           0 :                         *params->err = "Memory error parsing options";
     168             :                 return false;
     169             :         }
     170             :         return true;
     171             : }

Generated by: LCOV version 1.13