]> arthur.barton.de Git - netatalk.git/blob - etc/cnid_dbd/db_param.c
269808443b92af76dd01cbf8a804b68152f80eac
[netatalk.git] / etc / cnid_dbd / db_param.c
1 /*
2  * $Id: db_param.c,v 1.1.4.4.2.2 2005-09-27 10:40:41 didg Exp $
3  *
4  * Copyright (C) Joerg Lenneis 2003
5  * All Rights Reserved.  See COPYING.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12 #ifdef HAVE_UNISTD_H
13 #include <unistd.h>
14 #endif /* HAVE_UNISTD_H */
15 #ifdef HAVE_STRINGS_H
16 #include <strings.h>
17 #endif
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <errno.h>
21 #include <sys/param.h>
22 #include <sys/un.h>
23
24
25 #include <atalk/logger.h>
26
27 #include "db_param.h"
28
29
30 #define DB_PARAM_FN       "db_param"
31 #define MAXKEYLEN         64
32
33 #define DEFAULT_LOGFILE_AUTOREMOVE 0   
34 #define DEFAULT_CACHESIZE          1024 * 4 
35 #define DEFAULT_NOSYNC             0    
36 #define DEFAULT_FLUSH_FREQUENCY    100  
37 #define DEFAULT_FLUSH_INTERVAL     30   
38 #define DEFAULT_USOCK_FILE         "usock"
39 #define DEFAULT_FD_TABLE_SIZE      16
40 #define DEFAULT_IDLE_TIMEOUT       600
41 #define DEFAULT_CHECK              0
42
43 static struct db_param params;
44 static int parse_err;
45
46 static size_t usock_maxlen()
47 {
48     struct sockaddr_un addr;
49
50     return sizeof(addr.sun_path) - 1;
51 }
52
53 static int make_pathname(char *path, char *dir, char *fn, size_t maxlen)
54 {
55     size_t len;
56
57     if (fn[0] != '/') {
58         len = strlen(dir);
59         if (len + 1 + strlen(fn) > maxlen)
60             return -1;      
61         strcpy(path, dir);
62         if (path[len - 1] != '/')
63             strcat(path, "/");
64         strcat(path, fn);
65     } else {
66         if (strlen(fn) > maxlen)
67             return -1;
68         strcpy(path, fn);
69     }
70     return 0;
71 }
72
73 static void default_params(struct db_param *dbp, char *dir)
74 {        
75     dbp->check               = DEFAULT_CHECK;
76     dbp->logfile_autoremove  = DEFAULT_LOGFILE_AUTOREMOVE;
77     dbp->cachesize           = DEFAULT_CACHESIZE;
78     dbp->nosync              = DEFAULT_NOSYNC;
79     dbp->flush_frequency     = DEFAULT_FLUSH_FREQUENCY;
80     dbp->flush_interval      = DEFAULT_FLUSH_INTERVAL;
81     if (make_pathname(dbp->usock_file, dir, DEFAULT_USOCK_FILE, usock_maxlen()) < 0) {
82         /* Not an error yet, it might be set in the config file */
83         dbp->usock_file[0] = '\0';
84     }
85     dbp->fd_table_size       = DEFAULT_FD_TABLE_SIZE;
86     dbp->idle_timeout        = DEFAULT_IDLE_TIMEOUT;
87     return;
88 }
89
90 static int parse_int(char *val)
91 {
92     char *tmp;
93     int   result = 0;
94
95     result = strtol(val, &tmp, 10);
96     if (tmp[0] != '\0') {
97         LOG(log_error, logtype_cnid, "invalid characters in token %s", val);
98         parse_err++;
99     }
100     return result;
101 }
102
103
104 /* TODO: This configuration file reading routine is neither very robust (%s
105    buffer overflow) nor elegant, we need to add support for whitespace in
106    filenames as well. */
107
108 struct db_param *db_param_read(char *dir)
109 {
110     FILE *fp;
111     static char key[MAXKEYLEN + 1];
112     static char val[MAXPATHLEN + 1];
113     static char pfn[MAXPATHLEN + 1];
114     int    items;
115     
116     default_params(&params, dir);
117     
118     if (make_pathname(pfn, dir, DB_PARAM_FN, MAXPATHLEN) < 0) {
119         LOG(log_error, logtype_cnid, "Parameter filename too long");
120         return NULL;
121     }
122
123     if ((fp = fopen(pfn, "r")) == NULL) {
124         if (errno == ENOENT) {
125             if (strlen(params.usock_file) == 0) {
126                 LOG(log_error, logtype_cnid, "default usock filename too long");
127                 return NULL;
128             } else {
129                 return &params;
130             }
131         } else {
132             LOG(log_error, logtype_cnid, "error opening %s: %s", pfn, strerror(errno));
133             return NULL;
134         }
135     }
136     parse_err = 0;
137
138     while ((items = fscanf(fp, " %s %s", key, val)) != EOF) {
139         if (items != 2) {
140             LOG(log_error, logtype_cnid, "error parsing config file");
141             parse_err++;
142             break;
143         }
144         
145         if (! strcmp(key, "logfile_autoremove")) 
146             params.logfile_autoremove = parse_int(val);
147         else if (! strcmp(key, "cachesize"))
148             params.cachesize = parse_int(val);
149         else if (! strcmp(key, "nosync"))
150             params.nosync = parse_int(val);
151         else if (! strcmp(key, "check"))
152             params.check = parse_int(val);
153         else if (! strcmp(key, "flush_frequency"))
154             params.flush_frequency = parse_int(val);
155         else if (! strcmp(key, "flush_interval"))
156             params.flush_interval = parse_int(val);
157         else if (! strcmp(key, "usock_file")) {
158             if (make_pathname(params.usock_file, dir, val, usock_maxlen()) < 0) {
159                 LOG(log_error, logtype_cnid, "usock filename %s too long", val);
160                 parse_err++;
161             }
162         } else if (! strcmp(key, "fd_table_size"))
163             params.fd_table_size = parse_int(val);
164         else if (! strcmp(key, "idle_timeout"))
165             params.idle_timeout = parse_int(val);
166         else {
167             LOG(log_error, logtype_cnid, "error parsing %s -> %s in config file", key, val);
168             parse_err++;
169         }
170         if(parse_err)
171             break;
172     }
173     
174     if (strlen(params.usock_file) == 0) {
175         LOG(log_error, logtype_cnid, "default usock filename too long");
176         parse_err++;
177     }
178
179     fclose(fp);
180     if (! parse_err)
181         return &params;
182     else
183         return NULL;
184 }
185
186
187