/* * file ini_file.h - parsing ini-file into a database * * $Id: ini_file.c,v 1.8 2004/05/14 10:00:33 alfie Exp $ * * Program XBLAST * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2; or (at your option) * any later version * * This program is distributed in the hope that it will be entertaining, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ini_file.h" #include "str_util.h" #include "util.h" /* * local types */ /* single entry */ struct _db_entry { XBAtom atom; char *value; struct _db_entry *next; }; /* one complete section */ struct _db_section { XBAtom atom; XBBool changed; DBEntry *entry; struct _db_section *next; }; /* one database */ struct _db_root { DBType type; XBAtom atom; XBBool changed; DBSection *section; DBRoot *next; }; /* * local variables */ /* database list */ static DBRoot *db_list[NUM_DT] = { NULL, NULL, NULL, NULL, // XBCC }; /* path for database file */ static const char *db_path[NUM_DT] = { "config", GAME_DATADIR"/level", "demo", "central", // XBCC }; /* file extension */ static const char *db_ext[NUM_DT] = { "cfg", "xal", "dem", "dat", // XBCC }; /* * create a new Database */ DBRoot * DB_Create (DBType type, XBAtom atom) { DBRoot *db; assert (ATOM_INVALID != atom); /* create new database */ db = calloc (1, sizeof (DBRoot)); assert (NULL != db); db->atom = atom; db->type = type; db->changed = XBTrue; /* store in list */ db->next = db_list[type]; db_list[type] = db; /* thatīs all */ return db; } /* DB_Create */ /* * retrieve an existing database */ const DBRoot * DB_Get (DBType type, XBAtom atom) { const DBRoot *db; assert (ATOM_INVALID != atom); for (db = db_list[type]; db != NULL; db = db->next) { if (db->atom == atom) { return db; } } return NULL; } /* DB_Get */ /* * delete an entry */ static void FreeEntry (DBEntry *entry) { assert (entry != NULL); assert (entry->value != NULL); free (entry->value); free (entry); } /* FreeEntry */ /* * remove an entry from section */ void DB_DeleteEntry (DBSection *section, XBAtom atom) { DBEntry *save, *ptr; assert (section != NULL); section->changed = XBTrue; /* do we have any entries ? */ if (NULL == section->entry) { return; } assert (ATOM_INVALID != atom); /* it is the first entry ? */ if (section->entry->atom == atom) { save = section->entry; section->entry = section->entry->next; FreeEntry (save); } else { for (ptr = section->entry; ptr->next != NULL; ptr = ptr->next) { if (ptr->next->atom == atom) { save = ptr->next; ptr->next = ptr->next->next; FreeEntry (save); break; } } } } /* DB_DeleteEntry */ /* * (recursiley) delete section */ static void FreeSection (DBSection *section) { DBEntry *entry; DBEntry *nextEntry; assert (NULL != section); /* clear all entries */ for (entry = section->entry; entry != NULL; entry = nextEntry) { nextEntry = entry->next; FreeEntry (entry); } free (section); } /* FreeSection */ /* * delete a section */ void DB_DeleteSection (DBRoot *db, XBAtom atom) { DBSection *save, *ptr; assert (db != NULL); db->changed = XBTrue; /* do we have any sections ? */ if (NULL == db->section) { return; } assert (ATOM_INVALID != atom); /* it is the first section ? */ if (db->section->atom == atom) { save = db->section; db->section = db->section->next; FreeSection (save); } else { for (ptr = db->section; ptr->next != NULL; ptr = ptr->next) { if (ptr->next->atom == atom) { save = ptr->next; ptr->next = ptr->next->next; FreeSection (save); break; } } } } /* DB_DeleteSection */ void DB_DeleteAll (DBRoot *db) { DBSection *save; assert (db != NULL); db->changed = XBTrue; /* do we have any sections ? */ if (NULL == db->section) { return; } while(db->section != NULL) { save = db->section; db->section = db->section->next; FreeSection (save); } } /* DB_DeleteSection */ /* * (recursiley) delete database */ static void FreeRoot (DBRoot *db) { DBSection *section; DBSection *nextSection; assert (db != NULL); /* clear all sections */ for (section = db->section; section != NULL; section = nextSection) { nextSection = section->next; FreeSection (section); } free (db); } /* DB_Delete */ void DB_Delete (DBRoot *db) { DBRoot *ptr; assert (db_list[db->type] != NULL); /* check if first element in list */ if (db_list[db->type] == db) { db_list[db->type] = db_list[db->type]->next; } else { for (ptr = db_list[db->type]; ptr->next != NULL; ptr = ptr->next) { if (db == ptr->next) { ptr->next = db->next; break; } } } FreeRoot (db); } /* DB_Delete */ /* * create a new section */ DBSection * DB_CreateSection (DBRoot *db, XBAtom atom) { DBSection *section; /* create new data strutcure */ assert (NULL != db); assert (ATOM_INVALID != atom); /* try to find section first */ for (section = db->section; section != NULL; section = section->next) { if (section->atom == atom) { return section; } } /* create new section */ db->changed = XBTrue; section = calloc (1, sizeof (DBSection)); assert (NULL != section); section->atom = atom; section->changed = XBTrue; /* store in database */ section->next = db->section; db->section = section; /* thatīs all */ return section; } /* DB_CreateSection */ /* * number of sections */ int DB_NumSections (const DBRoot *db) { const DBSection *ptr; int num = 0; assert (NULL != db); /* find section */ for (ptr = db->section; ptr != NULL; ptr = ptr->next) { num ++; } return num; } /* DB_NumSections */ /* * get the name of the nth section */ XBAtom DB_IndexSection (const DBRoot *db, int index) { const DBSection *ptr; int num = 0; assert (NULL != db); /* find section */ for (ptr = db->section; ptr != NULL; ptr = ptr->next) { if (num == index) { return ptr->atom; } num ++; } return ATOM_INVALID; } /* DB_IndexSection */ /* * retrieve a section */ const DBSection * DB_GetSection (const DBRoot *db, XBAtom atom) { const DBSection *ptr; assert (NULL != db); assert (ATOM_INVALID != atom); /* find section */ for (ptr = db->section; ptr != NULL; ptr = ptr->next) { if (ptr->atom == atom) { return ptr; } } return NULL; } /* DB_GetSection */ /* * create a new database entry */ XBBool DB_CreateEntryString (DBSection *section, XBAtom atom, const char *value) { DBEntry *entry; assert (ATOM_INVALID != atom); assert (NULL != section); /* mark as changed */ section->changed = XBTrue; /* try to find entry first */ for (entry = section->entry; entry != NULL; entry = entry->next) { if (entry->atom == atom) { if (NULL != entry->value) { free (entry->value); } entry->value = DupString (value); assert (NULL != entry->value); return XBTrue; } } /* create new data strutcure */ entry = calloc (1, sizeof (DBEntry)); assert (NULL != entry); entry->atom = atom; entry->value = DupString (value); assert (NULL != entry->value); /* store in database */ entry->next = section->entry; section->entry = entry; /* thatīs all */ return XBTrue; } /* DB_CreateEntryString */ /* * create a new datbase entry */ XBBool DB_CreateEntryAtom (DBSection *section, XBAtom atom, XBAtom value) { return DB_CreateEntryString (section, atom, GUI_AtomToString (value)); } /* DB_CreateEntryAtom */ /* * create a new database entry */ XBBool DB_CreateEntryInt (DBSection *section, XBAtom atom, int value) { char tmp[32]; sprintf (tmp, "%d", value); return DB_CreateEntryString (section, atom, tmp); } /* DB_CreateEntry */ /* * create a new database entry */ XBBool DB_CreateEntryGameResult (DBSection *section, XBAtom atom, int score) { char tmp[32]; sprintf (tmp, "%d",score); return DB_CreateEntryString (section, atom, tmp); } /* DB_CreateEntry */ /* * create a new database entry */ XBBool DB_CreateEntryPlayerRating(DBSection *section, XBAtom atom, int PID, float rating) { char tmp[32]; sprintf (tmp, "%d %f", PID, rating); return DB_CreateEntryString (section, atom, tmp); } /* * create a new database entry */ XBBool DB_CreateEntryBool (DBSection *section, XBAtom atom, XBBool value) { return DB_CreateEntryString (section, atom, value ? "true" : "false"); } /* DB_CreateEntry */ /* * create a new database entry */ XBBool DB_CreateEntryColor (DBSection *section, XBAtom atom, XBColor color) { char tmp[32]; sprintf (tmp, "#%02x%02x%02x", GET_RED (color) << 3, GET_GREEN (color) << 3, GET_BLUE (color) << 3); return DB_CreateEntryString (section, atom, tmp); } /* DB_CreateEntry */ /* * create a new database entry */ XBBool DB_CreateEntryTime (DBSection *section, XBAtom atom, time_t value) { char tmp[64]; size_t len; len = sprintf (tmp, "%lu ; %s", value, ctime (&value)); /* cut trailing newline*/ tmp[len - 1] = 0; return DB_CreateEntryString (section, atom, tmp); } /* DB_CreateEntry */ /* * create a new database entry */ XBBool DB_CreateEntryFloat (DBSection *section, XBAtom atom, double value) { char tmp[32]; sprintf (tmp, "%f", value); return DB_CreateEntryString (section, atom, tmp); } /* DB_CreateEntry */ /* * number of entries */ int DB_NumEntries (const DBSection *section) { const DBEntry *ptr; int num = 0; assert (NULL != section); /* find section */ for (ptr = section->entry; ptr != NULL; ptr = ptr->next) { num ++; } return num; } /* DB_NumSections */ /* * get the name of the nth section */ XBAtom DB_IndexEntry (const DBSection *section, int index) { const DBEntry *ptr; int num = 0; assert (NULL != section); /* find section */ for (ptr = section->entry; ptr != NULL; ptr = ptr->next) { if (num == index) { return ptr->atom; } num ++; } return ATOM_INVALID; } /* DB_IndexSection */ /* * retrieve a database entry */ static const DBEntry * GetEntry (const DBSection *section, XBAtom atom) { const DBEntry *ptr; assert (section != NULL); /* find entry */ for (ptr = section->entry; ptr != NULL; ptr = ptr->next) { if (ptr->atom == atom) { return ptr; } } return NULL; } /* DB_GetEntry */ /* * get value string for entry */ XBBool DB_GetEntryString (const DBSection *section, XBAtom atom, const char **pValue) { const DBEntry *entry; assert (pValue != NULL); entry = GetEntry (section, atom); if (NULL == entry) { return XBFalse; } assert (entry->value != NULL); *pValue = entry->value; return XBTrue; } /* DB_GetEntryString */ /* * get value as atom from string */ XBBool DB_GetEntryAtom (const DBSection *section, XBAtom atom, XBAtom *pValue) { const DBEntry *entry; assert (pValue != NULL); entry = GetEntry (section, atom); if (NULL == entry) { return XBFalse; } assert (NULL != entry->value); *pValue = GUI_StringToAtom (entry->value); return (ATOM_INVALID != *pValue); } /* DB_GetEntryAtom */ /* * get value as int from string */ XBBool DB_GetEntryInt (const DBSection *section, XBAtom atom, int *pValue) { const DBEntry *entry; assert (pValue != NULL); entry = GetEntry (section, atom); if (NULL == entry) { return XBFalse; } assert (NULL != entry->value); return (1 == sscanf (entry->value, "%d", pValue)) ? XBTrue : XBFalse; } /* DB_GetEntryInt */ /* * get value as int from string */ XBBool DB_GetEntryBool (const DBSection *section, XBAtom atom, XBBool *pValue) { const DBEntry *entry; assert (pValue != NULL); entry = GetEntry (section, atom); if (NULL == entry) { return XBFalse; } assert (NULL != entry->value); if (0 == strcmp (entry->value, "true") ) { *pValue = XBTrue; } else if (0 == strcmp (entry->value, "false") ) { *pValue = XBFalse; } else { return XBFalse; } return XBTrue; } /* DB_GetEntryBool */ /* * get value as int from string */ XBBool DB_GetEntryColor (const DBSection *section, XBAtom atom, XBColor *pValue) { const DBEntry *entry; unsigned red, green, blue; char hash; assert (pValue != NULL); entry = GetEntry (section, atom); if (NULL == entry) { return XBFalse; } assert (NULL != entry->value); if (4 != sscanf (entry->value, "%c%2X%2X%2X", &hash, &red, &green, &blue) ) { return XBFalse; } if (hash != '#') { return XBFalse; } *pValue = SET_COLOR (red >> 3, green >> 3, blue >> 3); return XBTrue; } /* DB_GetEntryColor */ /* * get value as int from string */ XBBool DB_GetEntryTime (const DBSection *section, XBAtom atom, time_t *pValue) { const DBEntry *entry; assert (pValue != NULL); entry = GetEntry (section, atom); if (NULL == entry) { return XBFalse; } assert (NULL != entry->value); return (1 == sscanf (entry->value, "%lu", pValue)) ? XBTrue : XBFalse; } /* DB_GetEntryTime */ /* * get value as double from string */ XBBool DB_GetEntryFloat (const DBSection *section, XBAtom atom, double *pValue) { const DBEntry *entry; assert (pValue != NULL); entry = GetEntry (section, atom); if (NULL == entry) { return XBFalse; } assert (NULL != entry->value); return (1 == sscanf (entry->value, "%lf", pValue)) ? XBTrue : XBFalse; } /* DB_GetEntryInt */ /* * get value as double from string */ XBBool DB_GetEntryPos (const DBSection *section, XBAtom atom, BMPosition *pValue) { const DBEntry *entry; assert (pValue != NULL); entry = GetEntry (section, atom); if (NULL == entry) { return XBFalse; } assert (NULL != entry->value); return (2 == sscanf (entry->value, "%hd%hd", &pValue->x, &pValue->y)) ? XBTrue : XBFalse; } /* DB_GetEntryInt */ /* * */ static const char * ParseSection (const char *line) { const char *left; char *dst; static char result[256]; /* check left side */ for (left = line; *left != 0 && isspace (*left); left ++) continue; if (*left != '[') { return NULL; } left ++; dst = result; while (*left != ']') { if ('\0' == *left) { /* premature end of line */ return NULL; } *dst = *left; dst ++; left ++; } *dst = '\0'; return result; } /* ParseSection */ /* * */ const char * DB_IntToString (const DBToInt *table, int value) { const DBToInt *ptr; assert (NULL != table); for (ptr = table; ptr->key != NULL; ptr ++) { if (ptr->value == value) { return ptr->key; } } return NULL; } /* TableString */ /* * convert value string to int */ XBBool DB_ConvertEntryInt (const DBSection *section, XBAtom atom, int *pValue, const DBToInt *convTable) { const DBEntry *entry; const DBToInt *ptr; int cmp; if (NULL == (entry = GetEntry (section, atom) ) ) { return XBFalse; } assert (convTable != NULL); for (ptr = convTable; ptr->key != NULL; ptr ++) { cmp = strcmp (ptr->key, entry->value); // fprintf(stderr,"- %s %s \n",ptr->key,entry->value ); if (0 == cmp) { /* match */ assert (pValue != NULL); *pValue = ptr->value; return XBTrue; } else if (cmp > 0) { return XBFalse; } } return XBFalse; } /* DB_ConvertEntryInt */ /* * convert value string to int */ XBBool DB_ConvertEntryData (const DBSection *section, XBAtom atom, void **pValue, const DBToData *convTable) { const DBEntry *entry; const DBToData *ptr; int cmp; if (NULL == (entry = GetEntry (section, atom) ) ) { return XBFalse; } assert (convTable != NULL); for (ptr = convTable; ptr->key != NULL; ptr ++) { cmp = strcmp (ptr->key, entry->value); // fprintf(stderr,"| %s %s \n",ptr->key,entry->value ); if (0 == cmp) { /* match */ assert (pValue != NULL); *pValue = ptr->value; return XBTrue; } else if (cmp > 0) { return XBFalse; } } return XBFalse; } /* DB_ConvertEntryInt */ /* * convert value string to int */ XBBool DB_ConvertEntryFlags (const DBSection *section, XBAtom atom, unsigned *pValue, const DBToInt *convTable) { const DBEntry *entry; const DBToInt *ptr; int cmp; int i, argc; char **argv; if (NULL == (entry = GetEntry (section, atom) ) ) { return XBFalse; } assert (convTable != NULL); assert (pValue != NULL); *pValue = 0; /* split value string */ argv = SplitString (entry->value, &argc); assert (NULL != argv); /* parse list */ for (i = 0; i < argc; i ++) { for (ptr = convTable; ptr->key != NULL; ptr ++) { cmp = strcmp (ptr->key, argv[i]); // fprintf(stderr," %s %s \n",ptr->key, argv[i]); if (0 == cmp) { /* match */ *pValue |= ptr->value; break; } else if (cmp > 0) { free ((char *) argv); return XBFalse; } } } free ((char *) argv); return XBTrue; } /* DB_ConvertEntryInt */ /* * get the name of the nth section */ size_t DB_PrintEntry (char *buffer, const DBSection *section, int index) { const DBEntry *ptr; int num = 0; assert (NULL != buffer); assert (NULL != section); /* find section */ for (ptr = section->entry; ptr != NULL; ptr = ptr->next) { if (num == index) { // if(ptr->atom=atomIdenPassword ) { //return sprintf (buffer, "%s=*", GUI_AtomToString (ptr->atom)); //} else { return sprintf (buffer, "%s=%s", GUI_AtomToString (ptr->atom), ptr->value); //} } num ++; } /* entry not found */ buffer[0] = 0; return 0; } /* DB_IndexSection */ /* * * External level files could also come from windows environment, * where '\r' can be considered an EOL char for ini-file purposes. */ int XB_iniEOL( char c ) { switch ( c ) { case '\n': /* FALLTHRU */ case '\r': return 1; default: return 0; } } /* * */ static const char * ParseEntryName (const char *line) { const char *src; char *dst; static char result[256]; src = line; dst = result; while (*src != '=') { if ('\0' == *src) { /* premature end of line */ return NULL; } *dst = *src; dst ++; src ++; } *dst = '\0'; return result; } /* ParseEntryName */ /* * */ static const char * ParseEntryValue (const char *line) { const char *src; char *dst; static char result[256]; dst = result; src = strchr (line, '='); if (NULL == src) { return NULL; } src ++; while (isspace (*src) ) { src ++; } while ((!XB_iniEOL(*src)) && (*src != '\0')) { *dst = *src; dst ++; src ++; } *dst = 0; return result; } /* ParseEntryName */ /* * create entry by parsing text line */ XBBool DB_ParseEntry (DBSection *section, const char *line) { const char *entryName; assert (NULL != section); assert (NULL != line); /* parse entry */ if (NULL == (entryName = ParseEntryName (line) ) ) { return XBFalse; } return DB_CreateEntryString (section, GUI_StringToAtom (entryName), ParseEntryValue (line) ); } /* DB_ParseEntry */ /* * get atom (= filename) of database */ XBAtom DB_Atom (const DBRoot *db) { assert (NULL != db); return db->atom; } /* DB_Changed */ /* * set atom (= filename) of database */ void DB_SetAtom (DBRoot *db, XBAtom atom) { db->atom = atom; db->changed = XBTrue; } /* DB_Changed */ /* * check if database has changed */ XBBool DB_Changed (const DBRoot *db) { const DBSection *section; if (db->changed) { return XBTrue; } for (section = db->section; section != NULL; section = section->next) { if (section->changed) { return XBTrue; } } return XBFalse; } /* DB_Changed */ /* * mark database as unchanged */ static void MarkUnchanged (DBRoot *db) { DBSection *section; /* mark all as unchanged */ db->changed = XBFalse; for (section = db->section; section != NULL; section = section->next) { section->changed = XBFalse; } } /* MarkUnchanged */ /* * file name for database */ static FILE * OpenDBFile (const DBRoot *db, const char *mode) { char db_name[320]; assert (NULL != db); assert (NULL != mode); /* add index for demos */ sprintf (db_name, "%s", GUI_AtomToString (db->atom) ); return FileOpen (db_path[db->type], db_name, db_ext[db->type], mode); } /* OpenDBFile */ /* * load database from file */ XBBool DB_Load (DBRoot *db) { FILE *fp; DBSection *section; char line[256]; const char *sectionName; const char *entryName; assert (db != NULL); assert (ATOM_INVALID != db->atom); /* try to open file */ if (NULL == (fp = OpenDBFile (db, "r") ) ) { return XBFalse; } /* parse it */ section = NULL; while (NULL != fgets (line, sizeof (line), fp) ) { if (NULL != (sectionName = ParseSection (line) ) ) { section = DB_CreateSection (db, GUI_StringToAtom (sectionName) ); } else if (NULL != section && NULL != (entryName = ParseEntryName (line) ) ) { (void) DB_CreateEntryString (section, GUI_StringToAtom (entryName), ParseEntryValue (line) ); } } /* mark all as unchanged */ MarkUnchanged (db); /* thatīs all */ fclose (fp); return XBTrue; } /* DB_Load */ /* * store database in file */ XBBool DB_Store (DBRoot *db) { FILE *fp; const DBSection *section; const DBEntry *entry; if (NULL == (fp = OpenDBFile (db, "w") ) ) { return XBFalse; } /* now write it */ for (section = db->section; section != NULL; section = section->next) { fprintf (fp, "[%s]\n", GUI_AtomToString (section->atom) ); for (entry = section->entry; entry != NULL; entry = entry->next) { fprintf (fp, "%s=%s\n", GUI_AtomToString (entry->atom), entry->value); } fprintf (fp, "\n"); } /* mark all as unchanged */ MarkUnchanged (db); /* thatīs all */ fclose (fp); return XBTrue; } /* DB_Store */ /* * check if file directory database must be updated */ static XBBool CheckInsertFile (const DBRoot *db, const char *name, XBAtom timeAtom, time_t mtime) { const DBSection *section; time_t ltime; /* does file exists in database */ section = DB_GetSection (db, GUI_StringToAtom (name) ); if (NULL == section) { return XBFalse; } /* has the file been modified */ if (! DB_GetEntryTime (section, timeAtom, <ime) || ltime != mtime) { return XBFalse; } return XBTrue; } /* CheckLevelFile */ /* * insert file intro database */ static XBBool InsertFile (DBRoot *db, DBType type, const char *name, XBAtom timeAtom, time_t mtime, XBAtom fromAtom, DBLoadDirFunc func) { DBRoot *dbFile = NULL; DBSection *toSection = NULL; const DBSection *fromSection = NULL; const DBEntry *entry = NULL; XBAtom toAtom = GUI_StringToAtom (name); /* sanity check */ /* try to load level */ dbFile = DB_Create (type, toAtom); assert (dbFile != NULL); if (! DB_Load (dbFile) ) { goto Error; } /* find section to copy */ fromSection = DB_GetSection (dbFile, fromAtom); if (NULL == fromSection) { goto Error; } /* new entry for level */ toSection = DB_CreateSection (db, toAtom); assert (NULL != toSection); /* create entry for file modification time */ DB_CreateEntryTime (toSection, timeAtom, mtime); /* now copy section */ for (entry = fromSection->entry; NULL != entry; entry = entry->next) { (void) DB_CreateEntryString (toSection, entry->atom, entry->value); } /* call user function if any */ if (NULL != func) { (*func) (toSection); } /* clean up */ DB_Delete (dbFile); return XBTrue; Error: if (NULL != dbFile) { DB_Delete (dbFile); } if (NULL != toSection) { DB_DeleteSection (db, toAtom); } return XBFalse; } /* CheckInsertFile */ /* * mark section as changed */ static void UpdateFile (DBRoot *db, const char *name) { DBSection *section = DB_CreateSection (db, GUI_StringToAtom (name)); assert (NULL != section); section->changed = XBTrue; } /* UpdateFile */ /* * delete any unchanged sections */ static XBBool DeleteUnchangedSections (DBRoot *db) { DBSection *ptr; DBSection *next; XBBool deleted = XBFalse; assert (NULL != db); /* delete first section, while unchanged */ while (NULL != db->section && ! db->section->changed) { next = db->section->next; FreeSection (db->section); db->section = next; deleted = XBTrue; #ifdef DEBUG putchar ('-'); #endif } /* now proceed with the rest */ if (NULL != db->section) { for (ptr = db->section; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { while (NULL != ptr->next && ! ptr->next->changed) { next = ptr->next->next; FreeSection (ptr->next); ptr->next = next; deleted = XBTrue; #ifdef DEBUG putchar ('-'); #endif } } } #ifdef DEBUG fflush (stdout); #endif return deleted; } /* DeleteUnchangedSections */ /* * load complete directory of files into database, */ XBBool DB_LoadDir (DBRoot *db, const char *path, const char *ext, DBType type, XBAtom timeAtom, XBAtom section, DBLoadDirFunc func) { XBBool changed; XBDir *fileList; XBDir *ptr; /* sanity cheks */ assert (NULL != db); assert (NULL != path); assert (NULL != ext); /* load database from file */ DB_Load (db); /* now compare with current directory contents */ changed = XBFalse; fileList = CreateFileList (path, ext); for (ptr = fileList; NULL != ptr; ptr = ptr->next) { if (! CheckInsertFile (db, ptr->name, timeAtom, ptr->mtime) ) { InsertFile (db, type, ptr->name, timeAtom, ptr->mtime, section, func); changed = XBTrue; #ifdef DEBUG putchar ('*'); #endif } else { UpdateFile (db, ptr->name); #ifdef DEBUG putchar ('.'); #endif } #ifdef DEBUG fflush (stdout); #endif } /* now delete "unchanged section", because the do not have any related files */ if (DeleteUnchangedSections (db) ) { changed = XBTrue; } if (NULL != fileList) { DeleteFileList (fileList); #ifdef DEBUG putchar ('\n'); #endif } return changed; } /* DB_LoadDir */ /* MESSAGEDAY */ int ReadMessageOfTheDay(int m,char *s,int *l) { FILE *fp; int i; char *c,*d; i=0; fp=FileOpen(db_path[3], "message", "txt", "r"); if(NULL!=fp) { c=s; i=0; l[i]=0; while(1) { d=fgets(c,m-l[i],fp); if(d==NULL) break; i++; l[i]=strlen(s)-1; c=s+strlen(s)-1; } l[i+1]=strlen(s); /* printf("%s\n",s); for(j=0;j