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