/*
* insert in address ("hostname") order to find duplicates
*/
for (n = 0; n < kod_db_cnt; n++)
if (strcmp(kod_db[n]->hostname, pke->hostname) >= 0)
break;
int
write_kod_db(void)
{
FILE *db_s;
char *pch;
int dirmode;
register int a;
db_s = fopen(kod_db_file, "w");
/*
* If opening fails, blindly attempt to create each directory
* in the path first, then retry the open.
*/
if (NULL == db_s && strlen(kod_db_file)) {
dirmode = S_IRUSR | S_IWUSR | S_IXUSR
| S_IRGRP | S_IXGRP
| S_IROTH | S_IXOTH;
pch = strchr(kod_db_file + 1, DIR_SEP);
while (NULL != pch) {
*pch = '\0';
if (-1 == mkdir(kod_db_file, dirmode)
&& errno != EEXIST) {
msyslog(LOG_ERR, "mkdir(%s) failed: %m",
kod_db_file);
return FALSE;
}
*pch = DIR_SEP;
pch = strchr(pch + 1, DIR_SEP);
}
db_s = fopen(kod_db_file, "w");
}
if (NULL == db_s) {
msyslog(LOG_WARNING, "Can't open KOD db file %s for writing: %m",
kod_db_file);
return FALSE;
}
for (a = 0; a < kod_db_cnt; a++) {
fprintf(db_s, "%16.16llx %s %s\n", (unsigned long long)
kod_db[a]->timestamp, kod_db[a]->type,
kod_db[a]->hostname);
}
fflush(db_s);
fclose(db_s);
return TRUE;
}
void
kod_init_kod_db(
const char * db_file,
int readonly
)
{
/*
* Max. of 254 characters for hostname, 10 for timestamp, 4 for
* kisscode, 2 for spaces, 1 for \n, and 1 for \0
*/
char fbuf[254+10+4+2+1+1];
FILE *db_s;
int a, b, sepc, len;
unsigned long long ull;
char *str_ptr;
char error = 0;
TRACE(2, ("Initializing KOD DB...\n"));
kod_db_file = estrdup(db_file);
db_s = fopen(db_file, "r");
if (NULL == db_s) {
msyslog(LOG_WARNING, "kod_init_kod_db(): Cannot open KoD db file %s: %m",
db_file);
return;
}
if (debug)
printf("Starting to read KoD file %s...\n", db_file);
/* First let's see how many entries there are and check for right syntax */
while (!feof(db_s) && NULL != fgets(fbuf, sizeof(fbuf), db_s)) {
/* ignore blank lines */
if ('\n' == fbuf[0])
continue;
sepc = 0;
len = strlen(fbuf);
for (a = 0; a < len; a++) {
if (' ' == fbuf[a])
sepc++;
if ('\n' == fbuf[a]) {
if (sepc != 2) {
if (strcmp(db_file, "/dev/null"))
msyslog(LOG_DEBUG,
"Syntax error in KoD db file %s in line %i (missing space)",
db_file,
kod_db_cnt + 1);
fclose(db_s);
return;
}
sepc = 0;
kod_db_cnt++;
}
}
}
if (0 == kod_db_cnt) {
TRACE(2, ("KoD DB %s empty.\n", db_file));
goto wrapup;
}
TRACE(2, ("KoD DB %s contains %d entries, reading...\n", db_file, kod_db_cnt));
rewind(db_s);
/* Allocate the array of pointers to the struct kod_entry items */
kod_db = eallocarray(kod_db_cnt, sizeof(kod_db[0]));
/* Read contents of file */
for (b = 0;
!feof(db_s) && !ferror(db_s) && b < kod_db_cnt;
b++) {
if (ferror(db_s) || error) {
kod_db_cnt = b;
msyslog(LOG_WARNING, "An error occured while parsing the KoD db file %s",
db_file);
fclose(db_s);
return;
}
wrapup:
fclose(db_s);
for (a = 0; a < kod_db_cnt; a++)
TRACE(2, ("KoD entry %d: %s at %llx type %s\n", a,
kod_db[a]->hostname,
(unsigned long long)kod_db[a]->timestamp,
kod_db[a]->type));
if (!readonly && write_kod_db())
atexit(&atexit_write_kod_db);
}