]>
git.cameronkatri.com Git - apple_cmds.git/blob - system_cmds/sa.tproj/db.c
2 * Copyright (c) 2007 Diomidis Spinellis
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD: src/usr.sbin/sa/db.c,v 1.3 2008/02/21 07:12:56 grog Exp $");
31 #include <sys/types.h>
46 /* Key used to store the version of the database data elements. */
47 #define VERSION_KEY "\0VERSION"
50 * Create the in-memory database, *mdb.
51 * If iflag is not set, fill-in mdb with the records of the disk-based
53 * Upgrade old-version records by calling v1_to_v2.
54 * Return 0 if OK, -1 on error.
57 db_copy_in(DB
**mdb
, const char *dbname
, const char *uname
, BTREEINFO
*bti
,
58 int (*v1_to_v2
)(DBT
*key
, DBT
*data
))
62 int error
, rv
, version
;
64 if ((*mdb
= dbopen(NULL
, O_RDWR
, 0, DB_BTREE
, bti
)) == NULL
)
70 if ((ddb
= dbopen(dbname
, O_RDONLY
, 0, DB_BTREE
, bti
)) == NULL
) {
73 warn("retrieving %s summary", uname
);
74 db_destroy(*mdb
, uname
);
80 /* Obtain/set version. */
82 key
.data
= &VERSION_KEY
;
83 key
.size
= sizeof(VERSION_KEY
);
85 rv
= DB_GET(ddb
, &key
, &data
, 0);
87 warn("get version key from %s stats", uname
);
90 } else if (rv
== 0) { /* It's there; verify version. */
91 if (data
.size
!= sizeof(version
)) {
92 warnx("invalid version size %zd in %s",
97 memcpy(&version
, data
.data
, data
.size
);
99 warnx("unsupported version %d in %s",
106 for (rv
= DB_SEQ(ddb
, &key
, &data
, R_FIRST
); rv
== 0;
107 rv
= DB_SEQ(ddb
, &key
, &data
, R_NEXT
)) {
109 /* See if this is a version record. */
110 if (key
.size
== sizeof(VERSION_KEY
) &&
111 memcmp(key
.data
, VERSION_KEY
, sizeof(VERSION_KEY
)) == 0)
114 /* Convert record from v1, if needed. */
115 if (version
== 1 && v1_to_v2(&key
, &data
) < 0) {
116 warn("converting %s stats", uname
);
121 /* Copy record to the in-memory database. */
122 if ((rv
= DB_PUT(*mdb
, &key
, &data
, 0)) < 0) {
123 warn("initializing %s stats", uname
);
129 warn("retrieving %s summary", uname
);
134 if (DB_CLOSE(ddb
) < 0) {
135 warn("closing %s summary", uname
);
140 db_destroy(*mdb
, uname
);
145 * Save the in-memory database mdb to the disk database dbname.
146 * Return 0 if OK, -1 on error.
149 db_copy_out(DB
*mdb
, const char *dbname
, const char *uname
, BTREEINFO
*bti
)
153 int error
, rv
, version
;
155 if ((ddb
= dbopen(dbname
, O_RDWR
|O_CREAT
|O_TRUNC
, 0644,
156 DB_BTREE
, bti
)) == NULL
) {
157 warn("creating %s summary", uname
);
163 for (rv
= DB_SEQ(mdb
, &key
, &data
, R_FIRST
);
164 rv
== 0; rv
= DB_SEQ(mdb
, &key
, &data
, R_NEXT
)) {
165 if ((rv
= DB_PUT(ddb
, &key
, &data
, 0)) < 0) {
166 warn("saving %s summary", uname
);
172 warn("retrieving %s stats", uname
);
178 /* Add a version record. */
179 key
.data
= &VERSION_KEY
;
180 key
.size
= sizeof(VERSION_KEY
);
182 data
.data
= &version
;
183 data
.size
= sizeof(version
);
184 if ((rv
= DB_PUT(ddb
, &key
, &data
, 0)) < 0) {
185 warn("add version record to %s stats", uname
);
187 } else if (rv
== 1) {
188 warnx("duplicate version record in %s stats", uname
);
192 version
= 1; // avoid unused warning
195 if (DB_SYNC(ddb
, 0) < 0) {
196 warn("syncing %s summary", uname
);
199 if (DB_CLOSE(ddb
) < 0) {
200 warn("closing %s summary", uname
);
207 db_destroy(DB
*db
, const char *uname
)
209 if (DB_CLOSE(db
) < 0)
210 warn("destroying %s stats", uname
);