1 // Copyright (C) 1999,2000 Bruce Guenter <bruceg@em.ca>
2 //
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
17 #include <config.h>
18 #include <errno.h>
19 #include "vpwtable.h"
20 #include <gdbm.h>
21 #include <unistd.h>
22
23 class gdbm_vpwtable_writer : public vpwtable_writer
24 {
25 private:
26 const mystring tmpname;
27 const mystring destname;
28 GDBM_FILE out;
29 bool opened;
30 public:
31 gdbm_vpwtable_writer(const mystring& filename);
32 ~gdbm_vpwtable_writer();
33 bool operator!() const;
34 bool put(const vpwentry& vpw);
35 bool end();
36 bool abort();
37 };
38
start_write() const39 vpwtable_writer* vpwtable::start_write() const
40 {
41 return new gdbm_vpwtable_writer(filename);
42 }
43
gdbm_vpwtable_writer(const mystring & filename)44 gdbm_vpwtable_writer::gdbm_vpwtable_writer(const mystring& filename)
45 : tmpname(filename + ".tmp"), destname(filename),
46 out(gdbm_open((char*)filename.c_str(), 0, GDBM_NEWDB|GDBM_FAST, 0600, 0)),
47 opened(true)
48 {
49 }
50
~gdbm_vpwtable_writer()51 gdbm_vpwtable_writer::~gdbm_vpwtable_writer()
52 {
53 end();
54 }
55
operator !() const56 bool gdbm_vpwtable_writer::operator!() const
57 {
58 return opened;
59 }
60
put(const vpwentry & vpw)61 bool gdbm_vpwtable_writer::put(const vpwentry& vpw)
62 {
63 mystring name = vpw.name.lower();
64 datum key = { (char*)name.c_str(), static_cast<int>(name.length()) };
65 mystring binary = vpw.to_record();
66 datum data = { (char*)binary.c_str(), static_cast<int>(binary.length()) };
67 return gdbm_store(out, key, data, GDBM_INSERT) == 0;
68 }
69
end()70 bool gdbm_vpwtable_writer::end()
71 {
72 if(!opened)
73 return false;
74 gdbm_sync(out);
75 opened = false;
76 return gdbm_close(out) == 0 &&
77 rename(tmpname.c_str(), destname.c_str()) == 0;
78 }
79
abort()80 bool gdbm_vpwtable_writer::abort()
81 {
82 if(!opened)
83 return false;
84 opened = false;
85 gdbm_close(out);
86 return unlink(tmpname.c_str()) == 0;
87 }
88