}
}
+/**
+ * Destroy global objects allocated by init_iconv()
+ **/
+void gfree_charcnv(void)
+{
+ int c1, c2;
+
+ for (c1=0;c1<NUM_CHARSETS;c1++) {
+ for (c2=0;c2<NUM_CHARSETS;c2++) {
+ if ( conv_handles[c1][c2] ) {
+ smb_iconv_close( conv_handles[c1][c2] );
+ conv_handles[c1][c2] = 0;
+ }
+ }
+ }
+}
+
/**
* Initialize iconv conversion descriptors.
*
* Functions...
*/
+/***************************************************************************
+ Free memory pointed to by global pointers.
+****************************************************************************/
+
+void gfree_debugsyms(void)
+{
+ int i;
+
+ if ( classname_table ) {
+ for ( i = 0; i < debug_num_classes; i++ ) {
+ SAFE_FREE( classname_table[i] );
+ }
+ SAFE_FREE( classname_table );
+ }
+
+ if ( DEBUGLEVEL_CLASS != &debug_all_class_hack )
+ SAFE_FREE( DEBUGLEVEL_CLASS );
+
+ if ( DEBUGLEVEL_CLASS_ISSET != &debug_all_class_isset_hack )
+ SAFE_FREE( DEBUGLEVEL_CLASS_ISSET );
+}
/****************************************************************************
utility lists registered debug class names's
if (initialised)
return;
-
+
initialised = True;
message_register(MSG_DEBUG, debug_message);
void (*fn)(int msg_type, struct process_id pid, void *buf, size_t len);
} *dispatch_fns;
+/****************************************************************************
+ Free global objects.
+****************************************************************************/
+
+void gfree_messsges(void)
+{
+ struct dispatch_fns *dfn, *next;
+
+ /* delete the dispatch_fns list */
+ dfn = dispatch_fns;
+ while( dfn ) {
+ next = dfn->next;
+ DLIST_REMOVE(dispatch_fns, dfn);
+ SAFE_FREE(dfn);
+ dfn = next;
+ }
+}
+
/****************************************************************************
Notifications come in as signals.
****************************************************************************/
}
}
+/*
+ free allocated global memory
+*/
+
+void talloc_nc_free(void)
+{
+ if ( null_context )
+ talloc_free( (void*)null_context );
+}
+
/*
enable tracking of the NULL context
*/
return True;
}
+/***********************************************************************
+ Free memory allocated to global objects
+***********************************************************************/
+
+void gfree_names(void)
+{
+ SAFE_FREE( smb_myname );
+ SAFE_FREE( smb_myworkgroup );
+ SAFE_FREE( smb_scope );
+ free_netbios_names_array();
+}
+
+void gfree_all( void )
+{
+ gfree_names();
+ gfree_loadparm();
+ gfree_case_tables();
+ gfree_debugsyms();
+ gfree_charcnv();
+ gfree_messsges();
+
+ /* release the talloc null_context memory last */
+ talloc_nc_free();
+}
+
const char *my_netbios_names(int i)
{
return smb_my_netbios_names[i];
return p;
}
+/*******************************************************************
+ unmap or free memory
+*******************************************************************/
+
+BOOL unmap_file(void* start, size_t size)
+{
+#ifdef HAVE_MMAP
+ if ( munmap( start, size ) != 0 ) {
+ DEBUG( 1, ("map_file: Failed to unmap address %X "
+ "of size %d - %s\n",
+ start, size, strerror(errno) ));
+ return False;
+ }
+ return True;
+#else
+ SAFE_FREE( start );
+ return True;
+#endif
+}
+
/*******************************************************************
mmap (if possible) or read a file.
********************************************************************/
}
/* this is used to prevent lots of mallocs of size 1 */
-static char *null_string = NULL;
+static const char *null_string = "";
/**
Set a string value, allocing the space for the string
static BOOL string_init(char **dest,const char *src)
{
size_t l;
+
if (!src)
src = "";
l = strlen(src);
if (l == 0) {
- if (!null_string) {
- if((null_string = (char *)SMB_MALLOC(1)) == NULL) {
- DEBUG(0,("string_init: malloc fail for null_string.\n"));
- return False;
- }
- *null_string = 0;
- }
- *dest = null_string;
+ *dest = CONST_DISCARD(char*, null_string);
} else {
(*dest) = SMB_STRDUP(src);
if ((*dest) == NULL) {
static smb_ucs2_t *upcase_table;
static smb_ucs2_t *lowcase_table;
static uint8 *valid_table;
+static BOOL upcase_table_use_unmap;
+static BOOL lowcase_table_use_unmap;
+static BOOL valid_table_use_unmap;
/**
* This table says which Unicode characters are valid dos
**/
static uint8 doschar_table[8192]; /* 65536 characters / 8 bits/byte */
+/**
+ * Destroy global objects allocated by load_case_tables()
+ **/
+void gfree_case_tables(void)
+{
+ if ( upcase_table ) {
+ if ( upcase_table_use_unmap )
+ unmap_file(upcase_table, 0x20000);
+ else
+ SAFE_FREE(upcase_table);
+ }
+
+ if ( lowcase_table ) {
+ if ( lowcase_table_use_unmap )
+ unmap_file(lowcase_table, 0x20000);
+ else
+ SAFE_FREE(lowcase_table);
+ }
+
+ if ( valid_table ) {
+ if ( valid_table_use_unmap )
+ unmap_file(valid_table, 0x10000);
+ else
+ SAFE_FREE(valid_table);
+ }
+}
/**
* Load or generate the case handling tables.
initialised = 1;
upcase_table = map_file(lib_path("upcase.dat"), 0x20000);
+ upcase_table_use_unmap = ( upcase_table != NULL );
+
lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000);
+ lowcase_table_use_unmap = ( lowcase_table != NULL );
#ifdef HAVE_SETLOCALE
/* Get the name of the current locale. */
if (valid_file) {
valid_table = valid_file;
mapped_file = 1;
+ valid_table_use_unmap = True;
return;
}
* It might need to be regenerated if the code page changed.
* We know that we're not using a mapped file, so we can
* free() the old one. */
- if (valid_table) free(valid_table);
+ if (valid_table)
+ SAFE_FREE(valid_table);
+
+ /* use free rather than unmap */
+ valid_table_use_unmap = False;
DEBUG(2,("creating default valid table\n"));
valid_table = SMB_MALLOC(0x10000);
#define MAX_PASSWD_TRIES 3
+/*******************************************************************
+ Need this destructor to free global memory when the shared library
+ is unloaded
+*******************************************************************/
+
+void __attribute__ ((destructor)) _fini_pam_winbind(void)
+{
+ gfree_all();
+}
+
/* some syslogging */
static void _pam_log(int err, const char *format, ...)
{
return lp_numservices();
}
+/********************************************************
+ Destroy global resources allocated in this file
+********************************************************/
+
+void gfree_loadparm(void)
+{
+ struct file_lists *f;
+ struct file_lists *next;
+ int i;
+
+ lp_TALLOC_FREE();
+
+ /* Free the file lists */
+
+ f = file_lists;
+ while( f ) {
+ next = f->next;
+ SAFE_FREE( f->name );
+ SAFE_FREE( f->subfname );
+ SAFE_FREE( f );
+ f = next;
+ }
+
+ /* Free resources allocated to services */
+
+ for ( i = 0; i < iNumServices; i++ ) {
+ if ( VALID(i) ) {
+ free_service_byindex(i);
+ }
+ }
+
+ SAFE_FREE( ServicePtrs );
+ iNumServices = 0;
+
+ /* Now release all resources allocated to global
+ parameters and the default service */
+
+ for (i = 0; parm_table[i].label; i++)
+ {
+ if ( parm_table[i].type == P_STRING
+ || parm_table[i].type == P_USTRING )
+ {
+ string_free( (char**)parm_table[i].ptr );
+ }
+ else if (parm_table[i].type == P_LIST) {
+ str_list_free( (char***)parm_table[i].ptr );
+ }
+ }
+}
+
/***************************************************************************
Load the services array from the services file. Return True on success,
False on failure.