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