]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/blacklist/bin/state.c
Import NetBSD's blacklist source from vendor tree
[FreeBSD/FreeBSD.git] / contrib / blacklist / bin / state.c
1 /*      $NetBSD: state.c,v 1.18 2016/04/04 15:52:56 christos Exp $      */
2
3 /*-
4  * Copyright (c) 2015 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Christos Zoulas.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <sys/cdefs.h>
36 __RCSID("$NetBSD: state.c,v 1.18 2016/04/04 15:52:56 christos Exp $");
37
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <syslog.h>
45 #include <netinet/in.h>
46
47 #include "bl.h"
48 #include "internal.h"
49 #include "conf.h"
50 #include "support.h"
51 #include "state.h"
52
53 static HASHINFO openinfo = {
54         4096,           /* bsize */
55         32,             /* ffactor */
56         256,            /* nelem */
57         8 * 1024 * 1024,/* cachesize */
58         NULL,           /* hash() */
59         0               /* lorder */
60 };
61
62 int
63 state_close(DB *db)
64 {
65         if (db == NULL)
66                 return -1;
67         if ((*db->close)(db) == -1) {
68                     (*lfun)(LOG_ERR, "%s: can't close db (%m)", __func__);
69                     return -1;
70         }
71         return 0;
72 }
73
74 DB *
75 state_open(const char *dbname, int flags, mode_t perm)
76 {
77         DB *db;
78
79 #ifdef __APPLE__
80         flags &= O_CREAT|O_EXCL|O_EXLOCK|O_NONBLOCK|O_RDONLY|
81              O_RDWR|O_SHLOCK|O_TRUNC;
82 #endif
83         db = dbopen(dbname, flags, perm, DB_HASH, &openinfo);
84         if (db == NULL) {
85                 if (errno == ENOENT && (flags & O_CREAT) == 0)
86                         return NULL;
87                 (*lfun)(LOG_ERR, "%s: can't open `%s' (%m)", __func__, dbname);
88         }
89         return db;
90 }
91
92 static int
93 state_sizecheck(const DBT *t)
94 {
95         if (sizeof(struct conf) == t->size)
96                 return 0;
97         (*lfun)(LOG_ERR, "Key size mismatch %zu != %zu", sizeof(struct conf),
98             t->size);
99         return -1;
100 }
101
102 static void
103 dumpkey(const struct conf *k)
104 {
105         char buf[10240];
106         blhexdump(buf, sizeof(buf), __func__, k, sizeof(*k));
107         (*lfun)(LOG_DEBUG, "%s", buf);
108         (*lfun)(LOG_DEBUG, "%s: %s", __func__,
109             conf_print(buf, sizeof(buf), "", "", k));
110
111 }
112
113 int
114 state_del(DB *db, const struct conf *c)
115 {
116         int rv;
117         DBT k;
118
119         if (db == NULL)
120                 return -1;
121
122         k.data = __UNCONST(c);
123         k.size = sizeof(*c);
124
125         switch (rv = (*db->del)(db, &k, 0)) {
126         case 0:
127         case 1:
128                 if (debug > 1) {
129                         (*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
130                         (*db->sync)(db, 0);
131                 }
132                 return 0;
133         default:
134                 (*lfun)(LOG_ERR, "%s: failed (%m)", __func__);
135                 return -1;
136         }
137 }
138
139 int
140 state_get(DB *db, const struct conf *c, struct dbinfo *dbi)
141 {
142         int rv;
143         DBT k, v;
144
145         if (db == NULL)
146                 return -1;
147
148         k.data = __UNCONST(c);
149         k.size = sizeof(*c);
150
151         switch (rv = (*db->get)(db, &k, &v, 0)) {
152         case 0:
153         case 1:
154                 if (rv)
155                         memset(dbi, 0, sizeof(*dbi));
156                 else
157                         memcpy(dbi, v.data, sizeof(*dbi));
158                 if (debug > 1)
159                         (*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
160                 return 0;
161         default:
162                 (*lfun)(LOG_ERR, "%s: failed (%m)", __func__);
163                 return -1;
164         }
165 }
166
167 int
168 state_put(DB *db, const struct conf *c, const struct dbinfo *dbi)
169 {
170         int rv;
171         DBT k, v;
172
173         if (db == NULL)
174                 return -1;
175
176         k.data = __UNCONST(c);
177         k.size = sizeof(*c);
178         v.data = __UNCONST(dbi);
179         v.size = sizeof(*dbi);
180
181         switch (rv = (*db->put)(db, &k, &v, 0)) {
182         case 0:
183                 if (debug > 1) {
184                         (*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
185                         (*db->sync)(db, 0);
186                 }
187                 return 0;
188         case 1:
189                 errno = EEXIST;
190                 /*FALLTHROUGH*/
191         default:
192                 (*lfun)(LOG_ERR, "%s: failed (%m)", __func__);
193                 return -1;
194         }
195 }
196
197 int
198 state_iterate(DB *db, struct conf *c, struct dbinfo *dbi, unsigned int first)
199 {
200         int rv;
201         DBT k, v;
202
203         if (db == NULL)
204                 return -1;
205
206         first = first ? R_FIRST : R_NEXT;
207
208         switch (rv = (*db->seq)(db, &k, &v, first)) {
209         case 0:
210                 if (state_sizecheck(&k) == -1)
211                         return -1;
212                 memcpy(c, k.data, sizeof(*c));
213                 if (debug > 2)
214                         dumpkey(c);
215                 memcpy(dbi, v.data, sizeof(*dbi));
216                 if (debug > 1)
217                         (*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
218                 return 1;
219         case 1:
220                 if (debug > 1)
221                         (*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
222                 return 0;
223         default:
224                 (*lfun)(LOG_ERR, "%s: failed (%m)", __func__);
225                 return -1;
226         }
227 }
228
229 int
230 state_sync(DB *db)
231 {
232         return (*db->sync)(db, 0);
233 }