From a09c57ddecf8c6fe663fcd90c8c5c984fc86adc5 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Fri, 19 Nov 1999 01:57:41 +0000 Subject: [PATCH] * Fixed a *serious* memory leak in the database function wrappers. * Updated version number to 5.60 -- run setup when installing this version. --- citadel/ChangeLog | 5 +- citadel/database.c | 139 +++++++++++++++++++++++---------------------- 2 files changed, 75 insertions(+), 69 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index ec1b6f295..a99508ebc 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,8 @@ $Log$ +Revision 1.419 1999/11/19 01:57:40 ajc +* Fixed a *serious* memory leak in the database function wrappers. +* Updated version number to 5.60 -- run setup when installing this version. + Revision 1.418 1999/11/18 03:29:20 ajc * Changed the order of parameters in <.A>ide ystem config into a more logical grouping. @@ -1453,4 +1457,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import - diff --git a/citadel/database.c b/citadel/database.c index 2f2df05ac..061647395 100644 --- a/citadel/database.c +++ b/citadel/database.c @@ -48,7 +48,8 @@ datum *dtkey; * Reclaim unused space in the databases. We need to do each one of * these discretely, rather than in a loop. */ -void defrag_databases(void) { +void defrag_databases(void) +{ /* defrag the message base */ lprintf(7, "Defragmenting message base\n"); @@ -83,14 +84,15 @@ void defrag_databases(void) { gdbm_reorganize(gdbms[CDB_FLOORTAB]); end_critical_section(S_DATABASE); end_critical_section(S_FLOORTAB); - } +} /* * Open the various gdbm databases we'll be using. Any database which * does not exist should be created. */ -void open_databases(void) { +void open_databases(void) +{ lprintf(7, "%s\n", gdbm_version); /* @@ -102,95 +104,91 @@ void open_databases(void) { /* a critical section is unnecessary, as this function is called before any other threads are created. and it causes problems on BSDI. - begin_critical_section(S_DATABASE); + begin_critical_section(S_DATABASE); */ gdbms[CDB_MSGMAIN] = gdbm_open("data/msgmain.gdbm", 8192, - GDBM_WRCREAT, 0600, NULL); + GDBM_WRCREAT, 0600, NULL); if (gdbms[CDB_MSGMAIN] == NULL) { lprintf(2, "Cannot open msgmain: %s\n", gdbm_strerror(gdbm_errno)); exit(1); - } - + } gdbms[CDB_USERSUPP] = gdbm_open("data/usersupp.gdbm", 0, - GDBM_WRCREAT, 0600, NULL); + GDBM_WRCREAT, 0600, NULL); if (gdbms[CDB_USERSUPP] == NULL) { lprintf(2, "Cannot open usersupp: %s\n", gdbm_strerror(gdbm_errno)); exit(1); - } - + } gdbms[CDB_VISIT] = gdbm_open("data/visit.gdbm", 0, - GDBM_WRCREAT, 0600, NULL); + GDBM_WRCREAT, 0600, NULL); if (gdbms[CDB_VISIT] == NULL) { lprintf(2, "Cannot open visit file: %s\n", gdbm_strerror(gdbm_errno)); exit(1); - } - + } gdbms[CDB_QUICKROOM] = gdbm_open("data/quickroom.gdbm", 0, - GDBM_WRCREAT, 0600, NULL); + GDBM_WRCREAT, 0600, NULL); if (gdbms[CDB_QUICKROOM] == NULL) { lprintf(2, "Cannot open quickroom: %s\n", gdbm_strerror(gdbm_errno)); exit(1); - } - + } gdbms[CDB_FLOORTAB] = gdbm_open("data/floortab.gdbm", 0, - GDBM_WRCREAT, 0600, NULL); + GDBM_WRCREAT, 0600, NULL); if (gdbms[CDB_FLOORTAB] == NULL) { lprintf(2, "Cannot open floortab: %s\n", gdbm_strerror(gdbm_errno)); exit(1); - } - + } gdbms[CDB_MSGLISTS] = gdbm_open("data/msglists.gdbm", 0, - GDBM_WRCREAT, 0600, NULL); + GDBM_WRCREAT, 0600, NULL); if (gdbms[CDB_MSGLISTS] == NULL) { lprintf(2, "Cannot open msglists: %s\n", gdbm_strerror(gdbm_errno)); exit(1); - } - + } /* - end_critical_section(S_DATABASE); + end_critical_section(S_DATABASE); */ - } +} /* * Close all of the gdbm database files we've opened. This can be done * in a loop, since it's just a bunch of closes. */ -void close_databases(void) { +void close_databases(void) +{ int a; begin_critical_section(S_DATABASE); - for (a=0; alen = dret.dsize; tempcdb->ptr = dret.dptr; - return(tempcdb); - } + return (tempcdb); +} /* * Free a cdbdata item (ok, this is really no big deal, but we might need to do * more complex stuff with other database managers in the future). */ -void cdb_free(struct cdbdata *cdb) { +void cdb_free(struct cdbdata *cdb) +{ phree(cdb->ptr); phree(cdb); - } +} /* @@ -280,17 +278,17 @@ void cdb_free(struct cdbdata *cdb) { * that is open. There is guaranteed to be no more than one traversal in * progress per session at any given time.) */ -void cdb_rewind(int cdb) { +void cdb_rewind(int cdb) +{ while (max_keys <= CC->cs_pid) { ++max_keys; if (dtkey == NULL) { dtkey = (datum *) - mallok( (sizeof(datum) * max_keys) ); - } - else { + mallok((sizeof(datum) * max_keys)); + } else { dtkey = (datum *) - reallok(dtkey, (sizeof(datum) * max_keys) ); + reallok(dtkey, (sizeof(datum) * max_keys)); } dtkey[max_keys - 1].dsize = 0; dtkey[max_keys - 1].dptr = NULL; @@ -298,41 +296,46 @@ void cdb_rewind(int cdb) { if (dtkey[CC->cs_pid].dptr != NULL) { phree(dtkey[CC->cs_pid].dptr); - } - + } begin_critical_section(S_DATABASE); dtkey[CC->cs_pid] = gdbm_firstkey(gdbms[cdb]); end_critical_section(S_DATABASE); - } +} /* * Fetch the next item in a sequential search. Returns a pointer to a * cdbdata structure, or NULL if we've hit the end. */ -struct cdbdata *cdb_next_item(int cdb) { +struct cdbdata *cdb_next_item(int cdb) +{ datum dret; struct cdbdata *cdbret; + void *ptr = NULL; + - if (dtkey[CC->cs_pid].dptr == NULL) { /* end of file */ return NULL; - } - + } begin_critical_section(S_DATABASE); dret = gdbm_fetch(gdbms[cdb], dtkey[CC->cs_pid]); end_critical_section(S_DATABASE); if (dret.dptr == NULL) { /* bad read */ phree(dtkey[CC->cs_pid].dptr); return NULL; - } - + } cdbret = (struct cdbdata *) mallok(sizeof(struct cdbdata)); cdbret->len = dret.dsize; cdbret->ptr = dret.dptr; + ptr = dtkey[CC->cs_pid].dptr; begin_critical_section(S_DATABASE); dtkey[CC->cs_pid] = gdbm_nextkey(gdbms[cdb], dtkey[CC->cs_pid]); end_critical_section(S_DATABASE); - return(cdbret); + + if (ptr != NULL) { /* Free the previous key. */ + free(ptr); } + + return (cdbret); +} -- 2.39.2