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