| 1 |
pippijn |
1.1 |
/* |
| 2 |
pippijn |
1.4 |
* Copyright © 2005-2006 Atheme Development Group |
| 3 |
pippijn |
1.2 |
* Rights to this code are as documented in doc/pod/license.pod. |
| 4 |
pippijn |
1.1 |
* |
| 5 |
|
|
* This file contains the implementation of the Atheme 0.1 |
| 6 |
|
|
* flatfile database format, with metadata extensions. |
| 7 |
|
|
* |
| 8 |
pippijn |
1.5 |
* $Id: flatfile.C,v 1.4 2007-08-28 17:08:07 pippijn Exp $ |
| 9 |
pippijn |
1.1 |
*/ |
| 10 |
|
|
|
| 11 |
|
|
#include "atheme.h" |
| 12 |
pippijn |
1.4 |
#include <ermyth/database.h> |
| 13 |
pippijn |
1.1 |
#include <account/chanacs.h> |
| 14 |
|
|
#include <account/kline.h> |
| 15 |
|
|
#include <account/metadata.h> |
| 16 |
|
|
#include <account/mychan.h> |
| 17 |
|
|
#include <account/mymemo.h> |
| 18 |
|
|
#include <account/mynick.h> |
| 19 |
|
|
#include <account/myuser.h> |
| 20 |
|
|
#include <account/svsignore.h> |
| 21 |
|
|
|
| 22 |
pippijn |
1.5 |
static char const rcsid[] = "$Id: flatfile.C,v 1.4 2007-08-28 17:08:07 pippijn Exp $"; |
| 23 |
pippijn |
1.1 |
|
| 24 |
|
|
/* database versions */ |
| 25 |
pippijn |
1.4 |
#define DB_SHRIKE 1 |
| 26 |
|
|
#define DB_ATHEME 2 |
| 27 |
pippijn |
1.1 |
|
| 28 |
pippijn |
1.4 |
namespace database |
| 29 |
pippijn |
1.1 |
{ |
| 30 |
pippijn |
1.4 |
/* flatfile state */ |
| 31 |
|
|
unsigned int muout = 0, mcout = 0, caout = 0, kout = 0; |
| 32 |
|
|
|
| 33 |
|
|
struct flatfile : handler |
| 34 |
pippijn |
1.1 |
{ |
| 35 |
pippijn |
1.4 |
virtual void save (); |
| 36 |
|
|
virtual void load (); |
| 37 |
|
|
}; |
| 38 |
|
|
|
| 39 |
|
|
struct flatfile_save_myusers_cb |
| 40 |
pippijn |
1.1 |
{ |
| 41 |
pippijn |
1.4 |
flatfile_save_myusers_cb (FILE *file) |
| 42 |
|
|
: f (file) |
| 43 |
pippijn |
1.1 |
{ |
| 44 |
|
|
} |
| 45 |
pippijn |
1.4 |
|
| 46 |
|
|
void operator () (myuser_pair &it) |
| 47 |
pippijn |
1.1 |
{ |
| 48 |
pippijn |
1.4 |
myuser_t *mu = it.second; |
| 49 |
|
|
metadata_map::iterator mdit, mdet; |
| 50 |
|
|
myuser_t::memo_vector::iterator mzit, mzet; |
| 51 |
|
|
myuser_t::mzignore_vector::iterator miit, miet; |
| 52 |
|
|
node_t *tn; |
| 53 |
|
|
|
| 54 |
|
|
/* MU <name> <pass> <email> <registered> [lastlogin] [failnum*] [lastfail*] |
| 55 |
|
|
* [lastfailon*] [flags] |
| 56 |
|
|
* |
| 57 |
|
|
* * failnum, lastfail, and lastfailon are deprecated (moved to metadata) |
| 58 |
|
|
*/ |
| 59 |
|
|
fprintf (f, "MU %s %s %s %ld", mu->name, mu->pass, mu->email, mu->registered); |
| 60 |
|
|
fprintf (f, " %ld", mu->lastlogin); |
| 61 |
|
|
fprintf (f, " 0 0 0"); |
| 62 |
|
|
if (!mu->logins.empty ()) |
| 63 |
|
|
fprintf (f, " %d\n", mu->flags & ~MU_NOBURSTLOGIN); |
| 64 |
|
|
else |
| 65 |
|
|
fprintf (f, " %d\n", mu->flags); |
| 66 |
|
|
|
| 67 |
|
|
muout++; |
| 68 |
pippijn |
1.1 |
|
| 69 |
pippijn |
1.4 |
for (mdit = mu->mdmap.begin (), mdet = mu->mdmap.end (); mdit != mdet; ++mdit) |
| 70 |
pippijn |
1.1 |
{ |
| 71 |
|
|
metadata *md = mdit->second; |
| 72 |
pippijn |
1.4 |
fprintf (f, "MD U %s %s %s\n", mu->name, md->key, md->value); |
| 73 |
|
|
} |
| 74 |
|
|
|
| 75 |
|
|
for (mzit = mu->memos.begin (), mzet = mu->memos.end (); mzit != mzet; ++mzit) |
| 76 |
|
|
{ |
| 77 |
|
|
mymemo_t *mz = *mzit; |
| 78 |
|
|
fprintf (f, "ME %s %s %lu %lu %s\n", mu->name, mz->sender, (unsigned long) mz->sent, (unsigned long) mz->status, mz->text); |
| 79 |
|
|
} |
| 80 |
|
|
|
| 81 |
|
|
for (miit = mu->memo_ignores.begin (), miet = mu->memo_ignores.end (); miit != miet; ++miit) |
| 82 |
|
|
fprintf (f, "MI %s %s\n", mu->name, *miit); |
| 83 |
|
|
|
| 84 |
|
|
LIST_FOREACH (tn, mu->access_list.head) |
| 85 |
|
|
{ |
| 86 |
|
|
fprintf (f, "AC %s %s\n", mu->name, (char *) tn->data); |
| 87 |
pippijn |
1.1 |
} |
| 88 |
|
|
|
| 89 |
pippijn |
1.4 |
LIST_FOREACH (tn, mu->nicks.head) |
| 90 |
|
|
{ |
| 91 |
|
|
mynick_t *mn = static_cast<mynick_t *> (tn->data); |
| 92 |
|
|
|
| 93 |
|
|
fprintf (f, "MN %s %s %ld %ld\n", mu->name, mn->nick, (long) mn->registered, (long) mn->lastseen); |
| 94 |
|
|
} |
| 95 |
pippijn |
1.1 |
} |
| 96 |
pippijn |
1.4 |
|
| 97 |
|
|
private: |
| 98 |
|
|
FILE *f; |
| 99 |
|
|
}; |
| 100 |
|
|
|
| 101 |
|
|
/* write db */ |
| 102 |
|
|
void |
| 103 |
|
|
flatfile::save () |
| 104 |
|
|
{ |
| 105 |
|
|
myuser_t *mu; |
| 106 |
|
|
mychan_t *mc; |
| 107 |
|
|
chanacs_t *ca; |
| 108 |
|
|
kline_t *k; |
| 109 |
|
|
svsignore_t *svsignore; |
| 110 |
|
|
soper_t *soper; |
| 111 |
|
|
node_t *n, *tn; |
| 112 |
|
|
FILE *f; |
| 113 |
|
|
int errno1, was_errored = 0; |
| 114 |
|
|
dictionary_iteration_state_t state; |
| 115 |
|
|
svsignore_vector::iterator siit, siet; |
| 116 |
|
|
kline_vector::iterator klit, klet; |
| 117 |
|
|
metadata_map::iterator mdit, mdet; |
| 118 |
|
|
|
| 119 |
|
|
errno = 0; |
| 120 |
|
|
|
| 121 |
|
|
/* reset state */ |
| 122 |
|
|
muout = 0, mcout = 0, caout = 0, kout = 0; |
| 123 |
|
|
|
| 124 |
|
|
/* write to a temporary file first */ |
| 125 |
|
|
if (!(f = fopen (DATADIR "/" PACKAGE_NAME ".db.new", "w"))) |
| 126 |
pippijn |
1.1 |
{ |
| 127 |
pippijn |
1.4 |
errno1 = errno; |
| 128 |
|
|
slog (LG_ERROR, "flatfile::save(): cannot create " PACKAGE_NAME ".db.new: %s", strerror (errno1)); |
| 129 |
|
|
wallops (_("\2DATABASE ERROR\2: flatfile::save(): cannot create %s.db.new: %s"), PACKAGE_NAME, strerror (errno1)); |
| 130 |
|
|
snoop (_("\2DATABASE ERROR\2: flatfile::save(): cannot create %s.db.new: %s"), PACKAGE_NAME, strerror (errno1)); |
| 131 |
|
|
return; |
| 132 |
pippijn |
1.1 |
} |
| 133 |
|
|
|
| 134 |
pippijn |
1.4 |
/* write the database version */ |
| 135 |
|
|
fprintf (f, "DBV 6\n"); |
| 136 |
|
|
fprintf (f, "CF %s\n", bitmask_to_flags (ca_all, chanacs_flags)); |
| 137 |
|
|
|
| 138 |
|
|
slog (LG_DEBUG, "flatfile::save(): saving myusers"); |
| 139 |
|
|
|
| 140 |
|
|
std::for_each (mulist.begin (), mulist.end (), flatfile_save_myusers_cb (f)); |
| 141 |
|
|
|
| 142 |
|
|
slog (LG_DEBUG, "flatfile::save(): saving mychans"); |
| 143 |
|
|
|
| 144 |
|
|
DICTIONARY_FOREACH (mc, mychan_t, &state, mclist) |
| 145 |
pippijn |
1.1 |
{ |
| 146 |
pippijn |
1.4 |
/* find a founder */ |
| 147 |
|
|
mu = NULL; |
| 148 |
|
|
LIST_FOREACH (tn, mc->chanacs.head) |
| 149 |
|
|
{ |
| 150 |
|
|
ca = static_cast<chanacs_t *> (tn->data); |
| 151 |
|
|
if (ca->myuser != NULL && ca->level & CA_FOUNDER) |
| 152 |
|
|
{ |
| 153 |
|
|
mu = ca->myuser; |
| 154 |
|
|
break; |
| 155 |
|
|
} |
| 156 |
|
|
} |
| 157 |
|
|
/* MC <name> <pass> <founder> <registered> [used] [flags] |
| 158 |
|
|
* [mlock_on] [mlock_off] [mlock_limit] [mlock_key] |
| 159 |
|
|
* PASS is now ignored -- replaced with a "0" to avoid having to special-case this version |
| 160 |
|
|
*/ |
| 161 |
|
|
fprintf (f, "MC %s %s %s %ld %ld", mc->name, "0", mu != NULL ? mu->name : "*", (long)mc->registered, (long)mc->used); |
| 162 |
|
|
fprintf (f, " %d", mc->flags); |
| 163 |
|
|
fprintf (f, " %d", mc->mlock_on); |
| 164 |
|
|
fprintf (f, " %d", mc->mlock_off); |
| 165 |
|
|
fprintf (f, " %d", mc->mlock_limit); |
| 166 |
|
|
|
| 167 |
|
|
if (mc->mlock_key) |
| 168 |
|
|
fprintf (f, " %s\n", mc->mlock_key); |
| 169 |
|
|
else |
| 170 |
|
|
fprintf (f, "\n"); |
| 171 |
|
|
|
| 172 |
|
|
mcout++; |
| 173 |
|
|
|
| 174 |
|
|
LIST_FOREACH (tn, mc->chanacs.head) |
| 175 |
pippijn |
1.1 |
{ |
| 176 |
pippijn |
1.4 |
ca = (chanacs_t *) tn->data; |
| 177 |
|
|
|
| 178 |
|
|
fprintf (f, "CA %s %s %s %ld\n", ca->mychan->name, ca->myuser ? ca->myuser->name : ca->host, bitmask_to_flags (ca->level, chanacs_flags), ca->ts); |
| 179 |
|
|
|
| 180 |
|
|
for (mdit = ca->mdmap.begin (), mdet = ca->mdmap.end (); mdit != mdet; ++mdit) |
| 181 |
|
|
{ |
| 182 |
|
|
metadata *md = mdit->second; |
| 183 |
|
|
|
| 184 |
|
|
fprintf (f, "MD A %s:%s %s %s\n", ca->mychan->name, (ca->myuser) ? ca->myuser->name : ca->host, md->key, md->value); |
| 185 |
|
|
} |
| 186 |
|
|
|
| 187 |
|
|
caout++; |
| 188 |
pippijn |
1.1 |
} |
| 189 |
pippijn |
1.4 |
|
| 190 |
|
|
for (mdit = mc->mdmap.begin (), mdet = mc->mdmap.end (); mdit != mdet; ++mdit) |
| 191 |
|
|
{ |
| 192 |
|
|
metadata *md = mdit->second; |
| 193 |
|
|
|
| 194 |
|
|
fprintf (f, "MD C %s %s %s\n", mc->name, md->key, md->value); |
| 195 |
|
|
} |
| 196 |
pippijn |
1.1 |
} |
| 197 |
pippijn |
1.4 |
|
| 198 |
|
|
/* subscriptions -- we have to walk the myuser table again |
| 199 |
|
|
because otherwise we could encounter unknowns on restart. */ |
| 200 |
|
|
slog (LG_DEBUG, "flatfile::save(): saving subscriptions"); |
| 201 |
|
|
|
| 202 |
|
|
myuser_map::iterator muit = mulist.begin (); |
| 203 |
|
|
myuser_map::iterator muet = mulist.end (); |
| 204 |
|
|
while (muit != muet) |
| 205 |
|
|
{ |
| 206 |
|
|
mu = muit->second; |
| 207 |
|
|
metadata_subscription_t *subscriptor; |
| 208 |
|
|
|
| 209 |
|
|
LIST_FOREACH (n, mu->subscriptions.head) |
| 210 |
|
|
{ |
| 211 |
|
|
node_t *i; |
| 212 |
|
|
dynstr str (64); |
| 213 |
|
|
subscriptor = (metadata_subscription_t *) n->data; |
| 214 |
|
|
|
| 215 |
|
|
LIST_FOREACH (i, subscriptor->taglist.head) |
| 216 |
|
|
{ |
| 217 |
|
|
str.append (static_cast<char *> (i->data), strlen (static_cast<char *> (i->data))); |
| 218 |
|
|
|
| 219 |
|
|
if (i->next) |
| 220 |
|
|
str.append (','); |
| 221 |
|
|
} |
| 222 |
|
|
|
| 223 |
|
|
fprintf (f, "SU %s %s %s\n", mu->name, subscriptor->mu->name, str.c_str ()); |
| 224 |
|
|
} |
| 225 |
|
|
++muit; |
| 226 |
|
|
} |
| 227 |
|
|
|
| 228 |
|
|
/* Services ignores */ |
| 229 |
|
|
slog (LG_DEBUG, "flatfile::save(): saving svsignores"); |
| 230 |
|
|
|
| 231 |
|
|
for (siit = svs_ignore_list.begin (), siet = svs_ignore_list.end (); siit != siet; ++siit) |
| 232 |
|
|
{ |
| 233 |
|
|
svsignore = *siit; |
| 234 |
|
|
|
| 235 |
|
|
/* SI <mask> <settime> <setby> <reason> */ |
| 236 |
|
|
fprintf (f, "SI %s %ld %s %s\n", svsignore->mask, (long) svsignore->settime, svsignore->setby, svsignore->reason); |
| 237 |
|
|
} |
| 238 |
|
|
|
| 239 |
|
|
/* Services operators */ |
| 240 |
|
|
slog (LG_DEBUG, "flatfile::save(): saving sopers"); |
| 241 |
|
|
|
| 242 |
|
|
LIST_FOREACH (n, soperlist.head) |
| 243 |
pippijn |
1.1 |
{ |
| 244 |
pippijn |
1.4 |
soper = static_cast<soper_t *> (n->data); |
| 245 |
|
|
|
| 246 |
|
|
if (soper->flags & SOPER_CONF || soper->myuser == NULL) |
| 247 |
|
|
continue; |
| 248 |
|
|
|
| 249 |
|
|
/* SO <account> <operclass> <flags> */ |
| 250 |
|
|
fprintf (f, "SO %s %s %d\n", soper->myuser->name, soper->classname, soper->flags); |
| 251 |
pippijn |
1.1 |
} |
| 252 |
|
|
|
| 253 |
pippijn |
1.4 |
slog (LG_DEBUG, "flatfile::save(): saving klines"); |
| 254 |
|
|
|
| 255 |
|
|
for (klit = klnlist.begin (), klet = klnlist.end (); klit != klet; ++klit) |
| 256 |
|
|
{ |
| 257 |
|
|
k = *klit; |
| 258 |
|
|
|
| 259 |
|
|
/* KL <user> <host> <duration> <settime> <setby> <reason> */ |
| 260 |
|
|
fprintf (f, "KL %s %s %ld %ld %s %s\n", k->user, k->host, k->duration, (long) k->settime, k->setby, k->reason); |
| 261 |
|
|
|
| 262 |
|
|
kout++; |
| 263 |
|
|
} |
| 264 |
|
|
|
| 265 |
|
|
/* DE <muout> <mcout> <caout> <kout> */ |
| 266 |
|
|
fprintf (f, "DE %d %d %d %d\n", muout, mcout, caout, kout); |
| 267 |
|
|
|
| 268 |
|
|
was_errored = ferror (f); |
| 269 |
|
|
was_errored |= fclose (f); |
| 270 |
|
|
if (was_errored) |
| 271 |
|
|
{ |
| 272 |
|
|
errno1 = errno; |
| 273 |
|
|
slog (LG_ERROR, "flatfile::save(): cannot write to " PACKAGE_NAME ".db.new: %s", strerror (errno1)); |
| 274 |
|
|
wallops (_("\2DATABASE ERROR\2: flatfile::save(): cannot write to %s.db.new: %s"), PACKAGE_NAME, strerror (errno1)); |
| 275 |
|
|
snoop (_("\2DATABASE ERROR\2: flatfile::save(): cannot write to %s.db.new: %s"), PACKAGE_NAME, strerror (errno1)); |
| 276 |
|
|
return; |
| 277 |
|
|
} |
| 278 |
|
|
|
| 279 |
|
|
/* now, replace the old database with the new one, using an atomic rename */ |
| 280 |
|
|
unlink (DATADIR "/" PACKAGE_NAME ".db"); |
| 281 |
|
|
|
| 282 |
|
|
if ((rename (DATADIR "/" PACKAGE_NAME ".db.new", DATADIR "/" PACKAGE_NAME ".db")) < 0) |
| 283 |
|
|
{ |
| 284 |
|
|
errno1 = errno; |
| 285 |
|
|
slog (LG_ERROR, "flatfile::save(): cannot rename " PACKAGE_NAME ".db.new to " PACKAGE_NAME ".db: %s", strerror (errno1)); |
| 286 |
|
|
wallops (_("\2DATABASE ERROR\2: flatfile::save(): cannot rename %s.db.new to %s.db: %s"), PACKAGE_NAME, strerror (errno1)); |
| 287 |
|
|
snoop (_("\2DATABASE ERROR\2: flatfile::save(): cannot rename %s.db.new to %s.db: %s"), PACKAGE_NAME, strerror (errno1)); |
| 288 |
|
|
return; |
| 289 |
|
|
} |
| 290 |
|
|
} |
| 291 |
|
|
|
| 292 |
|
|
/* loads db */ |
| 293 |
|
|
void |
| 294 |
|
|
flatfile::load () |
| 295 |
pippijn |
1.1 |
{ |
| 296 |
pippijn |
1.4 |
myuser_t *mu, *founder = NULL; |
| 297 |
|
|
mychan_t *mc; |
| 298 |
|
|
kline_t *k; |
| 299 |
|
|
svsignore_t *svsignore; |
| 300 |
|
|
unsigned int i = 0, linecnt = 0, muin = 0, mcin = 0, cain = 0, kin = 0; |
| 301 |
|
|
FILE *f; |
| 302 |
|
|
char *item, *s, dBuf[BUFSIZE]; |
| 303 |
|
|
unsigned int their_ca_all = ca_all; |
| 304 |
|
|
|
| 305 |
|
|
f = fopen (DATADIR "/" PACKAGE_NAME ".db", "r"); |
| 306 |
|
|
if (f == NULL) |
| 307 |
|
|
{ |
| 308 |
|
|
if (errno == ENOENT) |
| 309 |
|
|
{ |
| 310 |
|
|
slog (LG_ERROR, "flatfile::load(): %s does not exist, creating it", DATADIR "/" PACKAGE_NAME ".db"); |
| 311 |
|
|
return; |
| 312 |
|
|
} |
| 313 |
|
|
else |
| 314 |
|
|
{ |
| 315 |
|
|
slog (LG_ERROR, "flatfile::load(): can't open %s for reading: %s", DATADIR "/" PACKAGE_NAME ".db", strerror (errno)); |
| 316 |
|
|
slog (LG_ERROR, "flatfile::load(): exiting to avoid data loss"); |
| 317 |
|
|
exit (1); |
| 318 |
|
|
} |
| 319 |
|
|
} |
| 320 |
|
|
|
| 321 |
|
|
slog (LG_DEBUG, "flatfile::load(): ----------------------- loading ------------------------"); |
| 322 |
|
|
|
| 323 |
|
|
/* start reading it, one line at a time */ |
| 324 |
|
|
while (fgets (dBuf, BUFSIZE, f)) |
| 325 |
|
|
{ |
| 326 |
|
|
linecnt++; |
| 327 |
|
|
|
| 328 |
|
|
/* check for unimportant lines */ |
| 329 |
|
|
item = strtok (dBuf, " "); |
| 330 |
|
|
strip (item); |
| 331 |
|
|
|
| 332 |
|
|
if (*item == '#' || *item == '\n' || *item == '\t' || *item == ' ' || *item == '\0' || *item == '\r' || !*item) |
| 333 |
|
|
continue; |
| 334 |
|
|
|
| 335 |
|
|
/* database version */ |
| 336 |
|
|
if (!strcmp ("DBV", item)) |
| 337 |
|
|
{ |
| 338 |
|
|
i = atoi (strtok (NULL, " ")); |
| 339 |
|
|
if (i > 6) |
| 340 |
|
|
{ |
| 341 |
|
|
slog (LG_INFO, "flatfile::load(): database version is %d; I only understand " |
| 342 |
|
|
"6 (Ermyth 2.3), " |
| 343 |
|
|
"5 (Atheme 2.0, 2.1), " |
| 344 |
|
|
"4 (Atheme 0.2), " |
| 345 |
|
|
"3 (Atheme 0.2 without CA_ACLVIEW), " |
| 346 |
|
|
"2 (Atheme 0.1) or " |
| 347 |
|
|
"1 (Shrike)", i); |
| 348 |
|
|
exit (EXIT_FAILURE); |
| 349 |
|
|
} |
| 350 |
|
|
} |
| 351 |
|
|
|
| 352 |
|
|
/* enabled chanacs flags */ |
| 353 |
|
|
if (!strcmp ("CF", item)) |
| 354 |
|
|
{ |
| 355 |
|
|
s = strtok (NULL, " "); |
| 356 |
|
|
if (s == NULL) |
| 357 |
|
|
slog (LG_INFO, "flatfile::load(): missing param to CF"); |
| 358 |
|
|
else |
| 359 |
|
|
{ |
| 360 |
|
|
their_ca_all = flags_to_bitmask (s, chanacs_flags, 0); |
| 361 |
|
|
if (their_ca_all & ~ca_all) |
| 362 |
|
|
slog (LG_ERROR, "flatfile::load(): losing flags %s from file", bitmask_to_flags (their_ca_all & ~ca_all, chanacs_flags)); |
| 363 |
|
|
if (~their_ca_all & ca_all) |
| 364 |
|
|
slog (LG_ERROR, "flatfile::load(): making up flags %s not present in file", bitmask_to_flags (~their_ca_all & ca_all, chanacs_flags)); |
| 365 |
|
|
} |
| 366 |
|
|
} |
| 367 |
|
|
|
| 368 |
|
|
/* myusers */ |
| 369 |
|
|
if (!strcmp ("MU", item)) |
| 370 |
|
|
{ |
| 371 |
|
|
char *muname, *mupass, *muemail; |
| 372 |
|
|
|
| 373 |
|
|
if ((s = strtok (NULL, " "))) |
| 374 |
|
|
{ |
| 375 |
|
|
/* We need to know the flags before we myuser_add, |
| 376 |
|
|
* so we need a few temporary places to put stuff. |
| 377 |
|
|
*/ |
| 378 |
|
|
unsigned int registered, lastlogin; |
| 379 |
|
|
char *failnum, *lastfailaddr, *lastfailtime; |
| 380 |
|
|
|
| 381 |
pippijn |
1.5 |
if ((mu = myuser_t::find (s))) |
| 382 |
pippijn |
1.4 |
continue; |
| 383 |
|
|
|
| 384 |
|
|
muin++; |
| 385 |
|
|
|
| 386 |
|
|
muname = s; |
| 387 |
|
|
mupass = strtok (NULL, " "); |
| 388 |
|
|
muemail = strtok (NULL, " "); |
| 389 |
|
|
|
| 390 |
|
|
registered = atoi (strtok (NULL, " ")); |
| 391 |
|
|
lastlogin = atoi (strtok (NULL, " ")); |
| 392 |
|
|
failnum = strtok (NULL, " "); |
| 393 |
|
|
lastfailaddr = strtok (NULL, " "); |
| 394 |
|
|
lastfailtime = strtok (NULL, " "); |
| 395 |
|
|
|
| 396 |
|
|
mu = myuser_add (muname, mupass, muemail, atol (strtok (NULL, " "))); |
| 397 |
|
|
|
| 398 |
|
|
mu->registered = registered; |
| 399 |
|
|
mu->lastlogin = lastlogin; |
| 400 |
|
|
|
| 401 |
|
|
if (strcmp (failnum, "0")) |
| 402 |
|
|
mu->add_metadata ("private:loginfail:failnum", failnum); |
| 403 |
|
|
if (strcmp (lastfailaddr, "0")) |
| 404 |
|
|
mu->add_metadata ("private:loginfail:lastfailaddr", lastfailaddr); |
| 405 |
|
|
if (strcmp (lastfailtime, "0")) |
| 406 |
|
|
mu->add_metadata ("private:loginfail:lastfailtime", lastfailtime); |
| 407 |
|
|
|
| 408 |
|
|
/* Verification keys were moved to metadata, |
| 409 |
|
|
* but we'll still accept them from legacy |
| 410 |
|
|
* databases. Note that we only transfer over |
| 411 |
|
|
* initial registration keys -- I don't think |
| 412 |
|
|
* we saved mu->temp, so we can't transition |
| 413 |
|
|
* e-mail change keys anyway. --alambert |
| 414 |
|
|
*/ |
| 415 |
|
|
if ((s = strtok (NULL, " "))) |
| 416 |
|
|
{ |
| 417 |
|
|
strip (s); |
| 418 |
|
|
mu->add_metadata ("private:verify:register:key", s); |
| 419 |
|
|
mu->add_metadata ("private:verify:register:timestamp", "0"); |
| 420 |
|
|
} |
| 421 |
|
|
} |
| 422 |
|
|
} |
| 423 |
|
|
|
| 424 |
|
|
if (!strcmp ("ME", item)) |
| 425 |
|
|
{ |
| 426 |
|
|
char *sender, *text; |
| 427 |
|
|
time_t mtime; |
| 428 |
|
|
unsigned int status; |
| 429 |
|
|
mymemo_t *mz; |
| 430 |
|
|
|
| 431 |
pippijn |
1.5 |
mu = myuser_t::find (strtok (NULL, " ")); |
| 432 |
pippijn |
1.4 |
sender = strtok (NULL, " "); |
| 433 |
|
|
mtime = atoi (strtok (NULL, " ")); |
| 434 |
|
|
status = atoi (strtok (NULL, " ")); |
| 435 |
|
|
text = strtok (NULL, "\n"); |
| 436 |
|
|
|
| 437 |
|
|
if (!mu) |
| 438 |
|
|
{ |
| 439 |
|
|
slog (LG_DEBUG, "flatfile::load(): memo for unknown account"); |
| 440 |
|
|
continue; |
| 441 |
|
|
} |
| 442 |
|
|
|
| 443 |
|
|
if (!sender || !mtime || !text) |
| 444 |
|
|
continue; |
| 445 |
|
|
|
| 446 |
|
|
mz = new mymemo_t; |
| 447 |
|
|
|
| 448 |
|
|
strlcpy (mz->sender, sender, NICKLEN); |
| 449 |
|
|
strlcpy (mz->text, text, MEMOLEN); |
| 450 |
|
|
mz->sent = mtime; |
| 451 |
|
|
mz->status = status; |
| 452 |
|
|
|
| 453 |
|
|
if (!(mz->status & MEMO_READ)) |
| 454 |
|
|
mu->memoct_new++; |
| 455 |
|
|
|
| 456 |
|
|
mu->memos.insert (mz); |
| 457 |
|
|
} |
| 458 |
|
|
|
| 459 |
|
|
if (!strcmp ("MI", item)) |
| 460 |
|
|
{ |
| 461 |
|
|
char *user, *target; |
| 462 |
|
|
|
| 463 |
|
|
user = strtok (NULL, " "); |
| 464 |
|
|
target = strtok (NULL, "\n"); |
| 465 |
|
|
|
| 466 |
pippijn |
1.5 |
mu = myuser_t::find (user); |
| 467 |
pippijn |
1.4 |
|
| 468 |
|
|
if (!mu) |
| 469 |
|
|
{ |
| 470 |
|
|
slog (LG_DEBUG, "flatfile::load(): invalid ignore (MI %s %s)", user, target); |
| 471 |
|
|
continue; |
| 472 |
|
|
} |
| 473 |
|
|
|
| 474 |
|
|
mu->memo_ignores.insert (sstrdup (target)); |
| 475 |
|
|
} |
| 476 |
|
|
|
| 477 |
|
|
/* myuser access list */ |
| 478 |
|
|
if (!strcmp ("AC", item)) |
| 479 |
|
|
{ |
| 480 |
|
|
char *user, *mask; |
| 481 |
|
|
|
| 482 |
|
|
user = strtok (NULL, " "); |
| 483 |
|
|
mask = strtok (NULL, "\n"); |
| 484 |
|
|
|
| 485 |
pippijn |
1.5 |
mu = myuser_t::find (user); |
| 486 |
pippijn |
1.4 |
|
| 487 |
|
|
if (mu == NULL) |
| 488 |
|
|
{ |
| 489 |
|
|
slog (LG_DEBUG, "flatfile::load(): invalid access entry<%s> for unknown user<%s>", mask, user); |
| 490 |
|
|
continue; |
| 491 |
|
|
} |
| 492 |
|
|
|
| 493 |
pippijn |
1.5 |
mu->access_add (mask); |
| 494 |
pippijn |
1.4 |
} |
| 495 |
|
|
|
| 496 |
|
|
/* registered nick */ |
| 497 |
|
|
if (!strcmp ("MN", item)) |
| 498 |
|
|
{ |
| 499 |
|
|
char *user, *nick, *treg, *tseen; |
| 500 |
|
|
mynick_t *mn; |
| 501 |
|
|
|
| 502 |
|
|
user = strtok (NULL, " "); |
| 503 |
|
|
nick = strtok (NULL, " "); |
| 504 |
|
|
treg = strtok (NULL, " "); |
| 505 |
|
|
tseen = strtok (NULL, " "); |
| 506 |
|
|
|
| 507 |
pippijn |
1.5 |
mu = myuser_t::find (user); |
| 508 |
pippijn |
1.4 |
if (mu == NULL || nick == NULL || tseen == NULL) |
| 509 |
|
|
{ |
| 510 |
|
|
slog (LG_DEBUG, "flatfile::load(): invalid registered nick<%s> for user<%s>", nick, user); |
| 511 |
|
|
continue; |
| 512 |
|
|
} |
| 513 |
|
|
|
| 514 |
|
|
mn = mynick_add (mu, nick); |
| 515 |
|
|
mn->registered = atoi (treg); |
| 516 |
|
|
mn->lastseen = atoi (tseen); |
| 517 |
|
|
} |
| 518 |
|
|
|
| 519 |
|
|
/* subscriptions */ |
| 520 |
|
|
if (!strcmp ("SU", item)) |
| 521 |
|
|
{ |
| 522 |
|
|
char *user, *sub_user, *tags, *tag; |
| 523 |
|
|
myuser_t *subscriptor; |
| 524 |
|
|
metadata_subscription_t *md; |
| 525 |
|
|
|
| 526 |
|
|
user = strtok (NULL, " "); |
| 527 |
|
|
sub_user = strtok (NULL, " "); |
| 528 |
|
|
tags = strtok (NULL, "\n"); |
| 529 |
|
|
if (!user || !sub_user || !tags) |
| 530 |
|
|
{ |
| 531 |
|
|
slog (LG_INFO, "flatfile::load(): invalid subscription (line %d)", linecnt); |
| 532 |
|
|
continue; |
| 533 |
|
|
} |
| 534 |
|
|
|
| 535 |
|
|
strip (tags); |
| 536 |
|
|
|
| 537 |
pippijn |
1.5 |
mu = myuser_t::find (user); |
| 538 |
|
|
subscriptor = myuser_t::find (sub_user); |
| 539 |
pippijn |
1.4 |
if (!mu || !subscriptor) |
| 540 |
|
|
{ |
| 541 |
|
|
slog (LG_INFO, "flatfile::load(): invalid subscription <%s,%s> (line %d)", user, sub_user, linecnt); |
| 542 |
|
|
continue; |
| 543 |
|
|
} |
| 544 |
|
|
|
| 545 |
|
|
md = new metadata_subscription_t; |
| 546 |
|
|
md->mu = subscriptor; |
| 547 |
|
|
|
| 548 |
|
|
tag = strtok (tags, ","); |
| 549 |
|
|
do |
| 550 |
|
|
node_add (sstrdup (tag), node_create (), &md->taglist); |
| 551 |
|
|
while ((tag = strtok (NULL, ",")) != NULL); |
| 552 |
|
|
|
| 553 |
|
|
node_add (md, node_create (), &mu->subscriptions); |
| 554 |
|
|
} |
| 555 |
|
|
|
| 556 |
|
|
/* services oper */ |
| 557 |
|
|
if (!strcmp ("SO", item)) |
| 558 |
|
|
{ |
| 559 |
|
|
char *user, *classname, *flagstr; |
| 560 |
|
|
|
| 561 |
|
|
user = strtok (NULL, " "); |
| 562 |
|
|
classname = strtok (NULL, " "); |
| 563 |
|
|
flagstr = strtok (NULL, "\n"); |
| 564 |
|
|
|
| 565 |
pippijn |
1.5 |
mu = myuser_t::find (user); |
| 566 |
pippijn |
1.4 |
|
| 567 |
|
|
if (!mu || !classname || !flagstr) |
| 568 |
|
|
{ |
| 569 |
|
|
slog (LG_DEBUG, "flatfile::load(): invalid services oper (SO %s %s %s)", user, classname, flagstr); |
| 570 |
|
|
continue; |
| 571 |
|
|
} |
| 572 |
|
|
soper_add (mu->name, classname, atoi (flagstr) & ~SOPER_CONF); |
| 573 |
|
|
} |
| 574 |
|
|
|
| 575 |
|
|
/* mychans */ |
| 576 |
|
|
if (!strcmp ("MC", item)) |
| 577 |
|
|
{ |
| 578 |
|
|
char *mcname, *mcpass; |
| 579 |
|
|
|
| 580 |
|
|
if ((s = strtok (NULL, " "))) |
| 581 |
|
|
{ |
| 582 |
|
|
if ((mc = mychan_find (s))) |
| 583 |
|
|
continue; |
| 584 |
|
|
|
| 585 |
|
|
mcin++; |
| 586 |
|
|
|
| 587 |
|
|
mcname = s; |
| 588 |
|
|
/* unused */ |
| 589 |
|
|
mcpass = strtok (NULL, " "); |
| 590 |
|
|
|
| 591 |
|
|
mc = mychan_add (mcname); |
| 592 |
|
|
|
| 593 |
pippijn |
1.5 |
founder = myuser_t::find (strtok (NULL, " ")); |
| 594 |
pippijn |
1.4 |
|
| 595 |
|
|
mc->registered = atoi (strtok (NULL, " ")); |
| 596 |
|
|
mc->used = atoi (strtok (NULL, " ")); |
| 597 |
|
|
mc->flags = atoi (strtok (NULL, " ")); |
| 598 |
|
|
|
| 599 |
|
|
mc->mlock_on = atoi (strtok (NULL, " ")); |
| 600 |
|
|
mc->mlock_off = atoi (strtok (NULL, " ")); |
| 601 |
|
|
mc->mlock_limit = atoi (strtok (NULL, " ")); |
| 602 |
|
|
|
| 603 |
|
|
if ((s = strtok (NULL, " "))) |
| 604 |
|
|
{ |
| 605 |
|
|
strip (s); |
| 606 |
|
|
if (*s != '\0' && *s != ':' && !strchr (s, ',')) |
| 607 |
|
|
mc->mlock_key = sstrdup (s); |
| 608 |
|
|
} |
| 609 |
|
|
|
| 610 |
|
|
if (i < 5 && config_options.join_chans) |
| 611 |
|
|
mc->flags |= MC_GUARD; |
| 612 |
|
|
} |
| 613 |
|
|
} |
| 614 |
|
|
|
| 615 |
|
|
/* Metadata entry */ |
| 616 |
|
|
if (!strcmp ("MD", item)) |
| 617 |
|
|
{ |
| 618 |
|
|
char *type = strtok (NULL, " "); |
| 619 |
|
|
char *name = strtok (NULL, " "); |
| 620 |
|
|
char *property = strtok (NULL, " "); |
| 621 |
|
|
char *value = strtok (NULL, ""); |
| 622 |
|
|
|
| 623 |
|
|
if (!type || !name || !property || !value) |
| 624 |
|
|
continue; |
| 625 |
|
|
|
| 626 |
|
|
strip (value); |
| 627 |
|
|
|
| 628 |
|
|
if (*type == 'U') |
| 629 |
|
|
{ |
| 630 |
pippijn |
1.5 |
mu = myuser_t::find (name); |
| 631 |
pippijn |
1.4 |
if (mu != NULL) |
| 632 |
|
|
mu->add_metadata (property, value); |
| 633 |
|
|
} |
| 634 |
|
|
else if (*type == 'C') |
| 635 |
|
|
{ |
| 636 |
|
|
mc = mychan_find (name); |
| 637 |
|
|
if (mc != NULL) |
| 638 |
|
|
mc->add_metadata (property, value); |
| 639 |
|
|
} |
| 640 |
|
|
else if (*type == 'A') |
| 641 |
|
|
{ |
| 642 |
|
|
chanacs_t *ca; |
| 643 |
|
|
char *mask; |
| 644 |
|
|
|
| 645 |
|
|
mask = strrchr (name, ':'); |
| 646 |
|
|
if (mask != NULL) |
| 647 |
|
|
{ |
| 648 |
|
|
*mask++ = '\0'; |
| 649 |
|
|
ca = chanacs_find_by_mask (mychan_find (name), mask, CA_NONE); |
| 650 |
|
|
if (ca != NULL) |
| 651 |
|
|
ca->add_metadata (property, value); |
| 652 |
|
|
} |
| 653 |
|
|
} |
| 654 |
|
|
} |
| 655 |
|
|
|
| 656 |
|
|
/* Channel URLs */ |
| 657 |
|
|
if (!strcmp ("UR", item)) |
| 658 |
|
|
{ |
| 659 |
|
|
char *chan, *url; |
| 660 |
|
|
|
| 661 |
|
|
chan = strtok (NULL, " "); |
| 662 |
|
|
url = strtok (NULL, " "); |
| 663 |
|
|
|
| 664 |
|
|
strip (url); |
| 665 |
|
|
|
| 666 |
|
|
if (chan && url) |
| 667 |
|
|
{ |
| 668 |
|
|
mc = mychan_find (chan); |
| 669 |
|
|
|
| 670 |
|
|
if (mc) |
| 671 |
|
|
mc->add_metadata ("url", url); |
| 672 |
|
|
} |
| 673 |
|
|
} |
| 674 |
|
|
|
| 675 |
|
|
/* Channel entry messages */ |
| 676 |
|
|
if (!strcmp ("EM", item)) |
| 677 |
|
|
{ |
| 678 |
|
|
char *chan, *message; |
| 679 |
|
|
|
| 680 |
|
|
chan = strtok (NULL, " "); |
| 681 |
|
|
message = strtok (NULL, ""); |
| 682 |
|
|
|
| 683 |
|
|
strip (message); |
| 684 |
|
|
|
| 685 |
|
|
if (chan && message) |
| 686 |
|
|
{ |
| 687 |
|
|
mc = mychan_find (chan); |
| 688 |
|
|
|
| 689 |
|
|
if (mc) |
| 690 |
|
|
mc->add_metadata ("private:entrymsg", message); |
| 691 |
|
|
} |
| 692 |
|
|
} |
| 693 |
|
|
|
| 694 |
|
|
/* chanacs */ |
| 695 |
|
|
if (!strcmp ("CA", item)) |
| 696 |
|
|
{ |
| 697 |
|
|
chanacs_t *ca; |
| 698 |
|
|
char *cachan, *causer; |
| 699 |
|
|
|
| 700 |
|
|
cachan = strtok (NULL, " "); |
| 701 |
|
|
causer = strtok (NULL, " "); |
| 702 |
|
|
|
| 703 |
|
|
if (cachan && causer) |
| 704 |
|
|
{ |
| 705 |
|
|
mc = mychan_find (cachan); |
| 706 |
pippijn |
1.5 |
mu = myuser_t::find (causer); |
| 707 |
pippijn |
1.4 |
|
| 708 |
|
|
if (mc == NULL || (mu == NULL && !validhostmask (causer))) |
| 709 |
|
|
{ |
| 710 |
|
|
slog (LG_ERROR, "flatfile::load(): invalid chanacs (line %d)", linecnt); |
| 711 |
|
|
continue; |
| 712 |
|
|
} |
| 713 |
|
|
|
| 714 |
|
|
cain++; |
| 715 |
|
|
|
| 716 |
|
|
if (i >= DB_ATHEME) |
| 717 |
|
|
{ |
| 718 |
|
|
unsigned int fl = flags_to_bitmask (strtok (NULL, " "), chanacs_flags, 0x0); |
| 719 |
|
|
char const * const tsstr = strtok (NULL, " "); |
| 720 |
|
|
time_t ts = 0; |
| 721 |
|
|
|
| 722 |
|
|
/* Compatibility with oldworld databases. --nenolod */ |
| 723 |
|
|
/* arbitrary cutoff to avoid touching newer +voOt entries -- jilles */ |
| 724 |
|
|
if (fl == OLD_CA_AOP && i < 4) |
| 725 |
|
|
fl = CA_AOP_DEF; |
| 726 |
|
|
|
| 727 |
|
|
/* |
| 728 |
|
|
* If the database revision is version 6 or newer, CA entries are |
| 729 |
|
|
* timestamped... otherwise we use 0 as the last modified TS |
| 730 |
|
|
* --nenolod/jilles |
| 731 |
|
|
*/ |
| 732 |
|
|
if (tsstr != NULL) |
| 733 |
|
|
ts = atoi (tsstr); |
| 734 |
|
|
|
| 735 |
|
|
/* previous to CA_ACLVIEW, everyone could view |
| 736 |
|
|
* access lists. If they aren't AKICKed, upgrade |
| 737 |
|
|
* them. This keeps us from breaking old XOPs. |
| 738 |
|
|
*/ |
| 739 |
|
|
if (i < 4) |
| 740 |
|
|
if (!(fl & CA_AKICK)) |
| 741 |
|
|
fl |= CA_ACLVIEW; |
| 742 |
|
|
|
| 743 |
|
|
/* Grant +h if they have +o, |
| 744 |
|
|
* the file does not have +h enabled |
| 745 |
|
|
* and we currently have +h enabled. |
| 746 |
|
|
* This preserves AOP, SOP and +*. |
| 747 |
|
|
*/ |
| 748 |
|
|
if (fl & CA_OP && !(their_ca_all & CA_HALFOP) && ca_all & CA_HALFOP) |
| 749 |
|
|
fl |= CA_HALFOP; |
| 750 |
|
|
|
| 751 |
|
|
/* Set new-style founder flag */ |
| 752 |
|
|
if (founder != NULL && mu == founder && !(their_ca_all & CA_FOUNDER)) |
| 753 |
|
|
fl |= CA_FOUNDER; |
| 754 |
|
|
|
| 755 |
|
|
if ((!mu) && (validhostmask (causer))) |
| 756 |
|
|
ca = chanacs_add_host (mc, causer, fl, ts); |
| 757 |
|
|
else |
| 758 |
|
|
ca = chanacs_add (mc, mu, fl, ts); |
| 759 |
|
|
} |
| 760 |
|
|
else if (i == DB_SHRIKE) /* DB_SHRIKE */ |
| 761 |
|
|
{ |
| 762 |
|
|
unsigned int fl = atol (strtok (NULL, " ")); |
| 763 |
|
|
unsigned int fl2 = 0x0; |
| 764 |
|
|
time_t ts = NOW; |
| 765 |
|
|
|
| 766 |
|
|
switch (fl) |
| 767 |
|
|
{ |
| 768 |
|
|
case SHRIKE_CA_VOP: |
| 769 |
|
|
fl2 = chansvs.ca_vop; |
| 770 |
|
|
case SHRIKE_CA_AOP: |
| 771 |
|
|
fl2 = chansvs.ca_aop; |
| 772 |
|
|
case SHRIKE_CA_SOP: |
| 773 |
|
|
fl2 = chansvs.ca_sop; |
| 774 |
|
|
case SHRIKE_CA_SUCCESSOR: |
| 775 |
|
|
fl2 = CA_SUCCESSOR_0; |
| 776 |
|
|
case SHRIKE_CA_FOUNDER: |
| 777 |
|
|
fl2 = CA_FOUNDER_0; |
| 778 |
|
|
} |
| 779 |
|
|
|
| 780 |
|
|
if ((!mu) && (validhostmask (causer))) |
| 781 |
|
|
ca = chanacs_add_host (mc, causer, fl2, ts); |
| 782 |
|
|
else |
| 783 |
|
|
ca = chanacs_add (mc, mu, fl2, ts); |
| 784 |
|
|
} |
| 785 |
|
|
} |
| 786 |
|
|
} |
| 787 |
|
|
|
| 788 |
|
|
|
| 789 |
|
|
/* Services ignores */ |
| 790 |
|
|
if (!strcmp ("SI", item)) |
| 791 |
|
|
{ |
| 792 |
|
|
char *mask, *setby, *reason, *tmp; |
| 793 |
|
|
time_t settime; |
| 794 |
|
|
|
| 795 |
|
|
mask = strtok (NULL, " "); |
| 796 |
|
|
tmp = strtok (NULL, " "); |
| 797 |
|
|
settime = atol (tmp); |
| 798 |
|
|
setby = strtok (NULL, " "); |
| 799 |
|
|
reason = strtok (NULL, ""); |
| 800 |
|
|
|
| 801 |
|
|
strip (reason); |
| 802 |
|
|
|
| 803 |
|
|
svsignore = svsignore_add (mask, reason); |
| 804 |
|
|
svsignore->settime = settime; |
| 805 |
|
|
svsignore->setby = sstrdup (setby); |
| 806 |
|
|
|
| 807 |
|
|
} |
| 808 |
|
|
|
| 809 |
|
|
/* klines */ |
| 810 |
|
|
if (!strcmp ("KL", item)) |
| 811 |
|
|
{ |
| 812 |
|
|
char *user, *host, *reason, *setby, *tmp; |
| 813 |
|
|
time_t settime; |
| 814 |
|
|
long duration; |
| 815 |
|
|
|
| 816 |
|
|
user = strtok (NULL, " "); |
| 817 |
|
|
host = strtok (NULL, " "); |
| 818 |
|
|
tmp = strtok (NULL, " "); |
| 819 |
|
|
duration = atol (tmp); |
| 820 |
|
|
tmp = strtok (NULL, " "); |
| 821 |
|
|
settime = atol (tmp); |
| 822 |
|
|
setby = strtok (NULL, " "); |
| 823 |
|
|
reason = strtok (NULL, ""); |
| 824 |
|
|
|
| 825 |
|
|
strip (reason); |
| 826 |
|
|
|
| 827 |
|
|
k = kline_add (user, host, reason, duration); |
| 828 |
|
|
k->settime = settime; |
| 829 |
|
|
/* XXX this is not nice, oh well -- jilles */ |
| 830 |
|
|
k->expires = k->settime + k->duration; |
| 831 |
|
|
k->setby = sstrdup (setby); |
| 832 |
|
|
|
| 833 |
|
|
kin++; |
| 834 |
|
|
} |
| 835 |
|
|
|
| 836 |
|
|
/* end */ |
| 837 |
|
|
if (!strcmp ("DE", item)) |
| 838 |
|
|
{ |
| 839 |
|
|
i = atoi (strtok (NULL, " ")); |
| 840 |
|
|
if (i != muin) |
| 841 |
|
|
slog (LG_ERROR, "flatfile::load(): got %d myusers; expected %d", muin, i); |
| 842 |
|
|
|
| 843 |
|
|
i = atoi (strtok (NULL, " ")); |
| 844 |
|
|
if (i != mcin) |
| 845 |
|
|
slog (LG_ERROR, "flatfile::load(): got %d mychans; expected %d", mcin, i); |
| 846 |
|
|
|
| 847 |
|
|
i = atoi (strtok (NULL, " ")); |
| 848 |
|
|
if (i != cain) |
| 849 |
|
|
slog (LG_ERROR, "flatfile::load(): got %d chanacs; expected %d", cain, i); |
| 850 |
|
|
|
| 851 |
|
|
if ((s = strtok (NULL, " "))) |
| 852 |
|
|
if ((i = atoi (s)) != kin) |
| 853 |
|
|
slog (LG_ERROR, "flatfile::load(): got %d klines; expected %d", kin, i); |
| 854 |
|
|
} |
| 855 |
|
|
} |
| 856 |
|
|
|
| 857 |
|
|
fclose (f); |
| 858 |
|
|
|
| 859 |
|
|
slog (LG_DEBUG, "flatfile::load(): ------------------------- done -------------------------"); |
| 860 |
pippijn |
1.1 |
} |
| 861 |
pippijn |
1.4 |
} // namespace database |
| 862 |
pippijn |
1.1 |
|
| 863 |
pippijn |
1.4 |
#define FACREG_TYPE database::flatfile |
| 864 |
|
|
#define FACREG_TYPE_NAME "flatfile" |
| 865 |
|
|
#define FACREG_INTERFACE_TYPE database::handler |
| 866 |
|
|
#include <ermyth/factory_reg.h> |