1 /*
2 ** Copyright 2000-2007 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5
6 #include "config.h"
7 #include "cmlmsublist.h"
8 #include <string.h>
9
10 static const char rcsid[]="$Id: cmlmsublist.C,v 1.5 2007/12/17 12:09:18 mrsam Exp $";
11
SubscriberList(bool wantalias)12 SubscriberList::SubscriberList( bool wantalias)
13 : dirp(0), next_func( wantalias ? &SubscriberList::openalias:
14 &SubscriberList::domain )
15 {
16 }
17
~SubscriberList()18 SubscriberList::~SubscriberList()
19 {
20 if (dirp) closedir(dirp);
21 }
22
23 //
24 // Read addresses from dedicated domain files.
25 //
26
domain(std::string & ret)27 bool SubscriberList::domain(std::string &ret)
28 {
29 struct dirent *de;
30 std::string key;
31 std::string val;
32
33 if (!dirp) dirp=opendir(DOMAINS);
34
35 if (domain_file.IsOpen()) // A domain file is currently open
36 {
37 key=domain_file.FetchNextKeyVal(val);
38
39 if (key.size())
40 {
41 ret=key;
42 sub_info=val;
43 return (true);
44 }
45
46 domain_file.Close();
47 }
48
49 // Searching for the next domain file.
50
51 while (dirp && (de=readdir(dirp)) != 0)
52 {
53 if (de->d_name[0] == '.') continue;
54 if (strchr(de->d_name, '.') == 0) continue;
55
56 std::string filename;
57
58 filename=DOMAINS "/";
59 filename += de->d_name;
60
61 if (domain_file.Open(filename, "R") == 0)
62 {
63 key=domain_file.FetchFirstKeyVal(val);
64 if (key.size())
65 {
66 ret=key;
67 sub_info=val;
68 return (true);
69 }
70 domain_file.Close();
71 }
72 }
73 closedir(dirp);
74 dirp=0;
75
76 // Now, read the miscellaneous database
77
78 if (domain_file.Open(MISC, "R")) return (false);
79
80 key=domain_file.FetchFirstKeyVal(val);
81 if (key.size() == 0)
82 {
83 domain_file.Close();
84 return (false);
85 }
86
87 splitmisc(val, misclist);
88 next_func= &SubscriberList::shared;
89 return (shared(ret));
90 }
91
splitmisc(std::string s,std::list<std::string> & misclist)92 void SubscriberList::splitmisc(std::string s,
93 std::list<std::string> &misclist)
94 {
95 misclist.clear();
96
97 std::string::iterator b=s.begin(), e=s.end(), p=b;
98
99 while (b != e)
100 {
101 if (*b == 0)
102 {
103 misclist.push_back(std::string(p, b));
104 p= ++b;
105 continue;
106 }
107 ++b;
108 continue;
109 }
110
111 if (p != b)
112 misclist.push_back(std::string(p, e));
113 }
114
joinmisc(const std::list<std::string> & misclist)115 std::string SubscriberList::joinmisc(const std::list<std::string> &misclist)
116 {
117 std::list<std::string>::const_iterator mb, me;
118 std::string r;
119
120 mb=misclist.begin();
121 me=misclist.end();
122
123 while (mb != me)
124 {
125 r += *mb++;
126 r.push_back((char)0);
127 }
128
129 return r;
130 }
131
132 // Read the miscellaneous database file
133
shared(std::string & ret)134 bool SubscriberList::shared(std::string &ret)
135 {
136 while (misclist.empty())
137 {
138 if (!domain_file.IsOpen())
139 return false;
140
141 std::string key;
142 std::string val;
143
144 key=domain_file.FetchNextKeyVal(val);
145
146 if (key.size() == 0)
147 {
148 domain_file.Close();
149 return false;
150 }
151
152 splitmisc(val, misclist);
153 }
154
155 ret=misclist.front();
156 misclist.pop_front();
157 sub_info="";
158
159 if (!misclist.empty())
160 {
161 sub_info=misclist.front();
162 misclist.pop_front();
163 }
164
165 return true;
166 }
167
168 // Read the alias file, instead of the subscriber database.
169
openalias(std::string & ret)170 bool SubscriberList::openalias(std::string &ret)
171 {
172 if (domain_file.Open( ALIASES, "R" )) return false;
173
174 next_func= &SubscriberList::nextalias;
175
176 std::string keys, vals;
177
178 keys=domain_file.FetchFirstKeyVal(vals);
179
180 if (keys.size() == 0)
181 return false;
182
183 ret=keys;
184 posting_alias=vals;
185
186 if (ret.substr(0, 1) == "1")
187 return nextalias(ret);
188 ret=ret.substr(1);
189
190 return true;
191 }
192
nextalias(std::string & ret)193 bool SubscriberList::nextalias(std::string &ret)
194 {
195 do
196 {
197 std::string keys, vals;
198
199 keys=domain_file.FetchNextKeyVal(vals);
200
201 if (keys.size() == 0)
202 return false;
203
204 ret=keys;
205 posting_alias=vals;
206 } while (ret.substr(0, 1) == "1");
207
208 ret=ret.substr(1);
209 return true;
210 }
211