• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.0/etc/cnid_dbd/
1/*
2 * $Id: db_param.c,v 1.9 2009-11-23 19:04:14 franklahm Exp $
3 *
4 * Copyright (C) Joerg Lenneis 2003
5 * Copyright (c) Frank Lahm 2009
6 * All Rights Reserved.  See COPYING.
7 */
8
9#ifdef HAVE_CONFIG_H
10#include "config.h"
11#endif /* HAVE_CONFIG_H */
12
13#include <unistd.h>
14#include <string.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <errno.h>
18#include <sys/param.h>
19#include <sys/un.h>
20#include <sys/select.h>
21#include <atalk/logger.h>
22
23#include "db_param.h"
24
25#define DB_PARAM_FN       "db_param"
26#define MAXKEYLEN         64
27
28static struct db_param params;
29static int parse_err;
30
31static size_t usock_maxlen(void)
32{
33    struct sockaddr_un addr;
34    return sizeof(addr.sun_path) - 1;
35}
36
37static int make_pathname(char *path, char *dir, char *fn, size_t maxlen)
38{
39    size_t len;
40
41    if (fn[0] != '/') {
42        len = strlen(dir);
43        if (len + 1 + strlen(fn) > maxlen)
44            return -1;
45        strcpy(path, dir);
46        if (path[len - 1] != '/')
47            strcat(path, "/");
48        strcat(path, fn);
49    } else {
50        if (strlen(fn) > maxlen)
51            return -1;
52        strcpy(path, fn);
53    }
54    return 0;
55}
56
57static void default_params(struct db_param *dbp, char *dir)
58{
59    dbp->logfile_autoremove  = DEFAULT_LOGFILE_AUTOREMOVE;
60    dbp->cachesize           = DEFAULT_CACHESIZE;
61    dbp->maxlocks            = DEFAULT_MAXLOCKS;
62    dbp->maxlockobjs         = DEFAULT_MAXLOCKOBJS;
63    dbp->flush_frequency     = DEFAULT_FLUSH_FREQUENCY;
64    dbp->flush_interval      = DEFAULT_FLUSH_INTERVAL;
65    if (make_pathname(dbp->usock_file, dir, DEFAULT_USOCK_FILE, usock_maxlen()) < 0) {
66        /* Not an error yet, it might be set in the config file */
67        dbp->usock_file[0] = '\0';
68    }
69    dbp->fd_table_size       = DEFAULT_FD_TABLE_SIZE;
70    if ( dbp->fd_table_size > FD_SETSIZE -1)
71        dbp->fd_table_size = FD_SETSIZE -1;
72    dbp->idle_timeout        = DEFAULT_IDLE_TIMEOUT;
73
74    return;
75}
76
77static int parse_int(char *val)
78{
79    char *tmp;
80    int   result = 0;
81
82    result = strtol(val, &tmp, 10);
83    if (tmp[0] != '\0') {
84        LOG(log_error, logtype_cnid, "invalid characters in token %s", val);
85        parse_err++;
86    }
87    return result;
88}
89
90
91/* TODO: This configuration file reading routine is neither very robust (%s
92   buffer overflow) nor elegant, we need to add support for whitespace in
93   filenames as well. */
94
95struct db_param *db_param_read(char *dir)
96{
97    FILE *fp;
98    static char key[MAXKEYLEN + 1];
99    static char val[MAXPATHLEN + 1];
100    static char pfn[MAXPATHLEN + 1];
101    int    items;
102
103    default_params(&params, dir);
104    params.dir = dir;
105
106    if (make_pathname(pfn, dir, DB_PARAM_FN, MAXPATHLEN) < 0) {
107        LOG(log_error, logtype_cnid, "Parameter filename too long");
108        return NULL;
109    }
110
111    if ((fp = fopen(pfn, "r")) == NULL) {
112        if (errno == ENOENT) {
113            if (strlen(params.usock_file) == 0) {
114                LOG(log_error, logtype_cnid, "default usock filename too long");
115                return NULL;
116            } else {
117                return &params;
118            }
119        } else {
120            LOG(log_error, logtype_cnid, "error opening %s: %s", pfn, strerror(errno));
121            return NULL;
122        }
123    }
124    parse_err = 0;
125
126    while ((items = fscanf(fp, " %s %s", key, val)) != EOF) {
127        if (items != 2) {
128            LOG(log_error, logtype_cnid, "error parsing config file");
129            parse_err++;
130            break;
131        }
132
133        /* Config for both cnid_meta and dbd */
134        if (! strcmp(key, "usock_file")) {
135            if (make_pathname(params.usock_file, dir, val, usock_maxlen()) < 0) {
136                LOG(log_error, logtype_cnid, "usock filename %s too long", val);
137                parse_err++;
138            } else
139                LOG(log_info, logtype_cnid, "db_param: setting UNIX domain socket filename to %s", params.usock_file);
140        }
141
142        if (! strcmp(key, "fd_table_size")) {
143            params.fd_table_size = parse_int(val);
144            LOG(log_info, logtype_cnid, "db_param: setting max number of concurrent afpd connections per volume (fd_table_size) to %d", params.fd_table_size);
145        } else if (! strcmp(key, "logfile_autoremove")) {
146            params.logfile_autoremove = parse_int(val);
147            LOG(log_info, logtype_cnid, "db_param: setting logfile_autoremove to %d", params.logfile_autoremove);
148        } else if (! strcmp(key, "cachesize")) {
149            params.cachesize = parse_int(val);
150            LOG(log_info, logtype_cnid, "db_param: setting cachesize to %d", params.cachesize);
151        } else if (! strcmp(key, "maxlocks")) {
152            params.maxlocks = parse_int(val);
153            LOG(log_info, logtype_cnid, "db_param: setting maxlocks to %d", params.maxlocks);
154        } else if (! strcmp(key, "maxlockobjs")) {
155            params.maxlockobjs = parse_int(val);
156            LOG(log_info, logtype_cnid, "db_param: setting maxlockobjs to %d", params.maxlockobjs);
157        } else if (! strcmp(key, "flush_frequency")) {
158            params.flush_frequency = parse_int(val);
159            LOG(log_info, logtype_cnid, "db_param: setting flush_frequency to %d", params.flush_frequency);
160        } else if (! strcmp(key, "flush_interval")) {
161            params.flush_interval = parse_int(val);
162            LOG(log_info, logtype_cnid, "db_param: setting flush_interval to %d", params.flush_interval);
163        } else if (! strcmp(key, "idle_timeout")) {
164            params.idle_timeout = parse_int(val);
165            LOG(log_info, logtype_cnid, "db_param: setting idle timeout to %d", params.idle_timeout);
166        }
167
168        if (parse_err)
169            break;
170    }
171
172    if (strlen(params.usock_file) == 0) {
173        LOG(log_error, logtype_cnid, "default usock filename too long");
174        parse_err++;
175    }
176
177    fclose(fp);
178    if (! parse_err) {
179        /* sanity checks */
180        if (params.flush_frequency <= 0)
181            params.flush_frequency = 86400;
182
183        if (params.flush_interval <= 0)
184            params.flush_interval = 1000000;
185
186        if (params.fd_table_size <= 2)
187            params.fd_table_size = 32;
188
189        if (params.idle_timeout <= 0)
190            params.idle_timeout = 86400;
191
192        return &params;
193    }
194    else
195        return NULL;
196}
197
198
199
200