*/
struct smb_iconv_convenience {
+ TALLOC_CTX *child_ctx;
const char *unix_charset;
const char *dos_charset;
bool native_iconv;
return 0;
}
-_PUBLIC_ struct smb_iconv_convenience *smb_iconv_convenience_init(TALLOC_CTX *mem_ctx,
- const char *dos_charset,
- const char *unix_charset,
- bool native_iconv)
+/*
+ the old_ic is passed in here as the smb_iconv_convenience structure
+ is used as a global pointer in some places (eg. python modules). We
+ don't want to invalidate those global pointers, but we do want to
+ update them with the right charset information when loadparm
+ runs. To do that we need to re-use the structure pointer, but
+ re-fill the elements in the structure with the updated values
+ */
+_PUBLIC_ struct smb_iconv_convenience *smb_iconv_convenience_reinit(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset,
+ bool native_iconv,
+ struct smb_iconv_convenience *old_ic)
{
- struct smb_iconv_convenience *ret = talloc_zero(mem_ctx,
- struct smb_iconv_convenience);
+ struct smb_iconv_convenience *ret;
+ if (old_ic != NULL) {
+ ret = old_ic;
+ close_iconv_convenience(ret);
+ talloc_free(ret->child_ctx);
+ ZERO_STRUCTP(ret);
+ } else {
+ ret = talloc_zero(mem_ctx, struct smb_iconv_convenience);
+ }
if (ret == NULL) {
return NULL;
}
+ /* we use a child context to allow us to free all ptrs without
+ freeing the structure itself */
+ ret->child_ctx = talloc_new(ret);
+ if (ret->child_ctx == NULL) {
+ return NULL;
+ }
+
talloc_set_destructor(ret, close_iconv_convenience);
- ret->dos_charset = talloc_strdup(ret, dos_charset);
- ret->unix_charset = talloc_strdup(ret, unix_charset);
+ ret->dos_charset = talloc_strdup(ret->child_ctx, dos_charset);
+ ret->unix_charset = talloc_strdup(ret->child_ctx, unix_charset);
ret->native_iconv = native_iconv;
return ret;
int codepoint_cmpi(codepoint_t c1, codepoint_t c2);
/* Iconv convenience functions */
-struct smb_iconv_convenience *smb_iconv_convenience_init(TALLOC_CTX *mem_ctx,
- const char *dos_charset,
- const char *unix_charset,
- bool native_iconv);
+struct smb_iconv_convenience *smb_iconv_convenience_reinit(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset,
+ bool native_iconv,
+ struct smb_iconv_convenience *old_ic);
bool convert_string_convenience(struct smb_iconv_convenience *ic,
charset_t from, charset_t to,
static inline struct smb_iconv_convenience *get_iconv_convenience(void)
{
if (global_iconv_convenience == NULL)
- global_iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true);
+ global_iconv_convenience = smb_iconv_convenience_reinit(talloc_autofree_context(),
+ "ASCII", "UTF-8", true, NULL);
return global_iconv_convenience;
}
* this all the way down
*/
#if _SAMBA_BUILD_ == 4
- ndr->iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true);
+ ndr->iconv_convenience = smb_iconv_convenience_reinit(talloc_autofree_context(),
+ "ASCII", "UTF-8", true, NULL);
#endif
fn(ndr, name, flags, ptr);
* this all the way down
*/
#if _SAMBA_BUILD_ == 4
- ndr->iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true);
+ ndr->iconv_convenience = smb_iconv_convenience_reinit(talloc_autofree_context(),
+ "ASCII", "UTF-8", true, NULL);
#endif
fn(ndr, name, ptr);
uint8_t data[] = { 0x00, 0x00, 0x00, 0x00 };
DATA_BLOB b = { data, 4 };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
r.in.data = NULL;
\'f\', \'o\', \'o\', 0 };
DATA_BLOB b = { data, 8 };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
r.in.data = NULL;
};
DATA_BLOB b = { data, sizeof(data) };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
struct TestStringStruct str;
r.in.str = &str;
};
DATA_BLOB b = { data, sizeof(data) };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
struct TestStringStruct str;
r.in.str = &str;
};
DATA_BLOB b = { data, sizeof(data) };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
struct TestStringStruct str;
r.in.str = &str;
\'f\', \'o\', \'o\', 0 };
DATA_BLOB b = { data, 8 };
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
- smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+ smb_iconv_convenience_reinit(NULL, "ASCII", "UTF8", true, NULL));
struct TestString r;
char *str = NULL;
r.out.data = &str;
if (lp_ctx == NULL) {
static struct smb_iconv_convenience *fallback_ic = NULL;
if (fallback_ic == NULL)
- fallback_ic = smb_iconv_convenience_init(talloc_autofree_context(),
- "CP850", "UTF8", true);
+ fallback_ic = smb_iconv_convenience_reinit(talloc_autofree_context(),
+ "CP850", "UTF8", true, NULL);
return fallback_ic;
}
return lp_ctx->iconv_convenience;
_PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx)
{
- talloc_unlink(lp_ctx, lp_ctx->iconv_convenience);
- global_iconv_convenience = lp_ctx->iconv_convenience = smb_iconv_convenience_init_lp(lp_ctx, lp_ctx);
+ struct smb_iconv_convenience *old_ic = lp_ctx->iconv_convenience;
+ if (old_ic == NULL) {
+ old_ic = global_iconv_convenience;
+ }
+ lp_ctx->iconv_convenience = smb_iconv_convenience_reinit_lp(lp_ctx, lp_ctx, old_ic);
+ global_iconv_convenience = lp_ctx->iconv_convenience;
}
void lp_smbcli_options(struct loadparm_context *lp_ctx,
init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *subsystem);
const char *lp_messaging_path(TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx);
-struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx,
- struct loadparm_context *lp_ctx);
+struct smb_iconv_convenience *smb_iconv_convenience_reinit_lp(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
+ struct smb_iconv_convenience *old_ic);
const char *lp_sam_name(struct loadparm_context *lp_ctx);
return smbd_tmp_path(mem_ctx, lp_ctx, "messaging");
}
-struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx,
- struct loadparm_context *lp_ctx)
+struct smb_iconv_convenience *smb_iconv_convenience_reinit_lp(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
+ struct smb_iconv_convenience *old_ic)
{
- return smb_iconv_convenience_init(mem_ctx, lp_dos_charset(lp_ctx),
- lp_unix_charset(lp_ctx),
- lp_parm_bool(lp_ctx, NULL, "iconv", "native", true));
+ return smb_iconv_convenience_reinit(mem_ctx, lp_dos_charset(lp_ctx),
+ lp_unix_charset(lp_ctx),
+ lp_parm_bool(lp_ctx, NULL, "iconv", "native", true),
+ old_ic);
}
void py_load_samba_modules(void);
bool py_update_path(const char *bindir);
-#define py_iconv_convenience(mem_ctx) smb_iconv_convenience_init(mem_ctx, "ASCII", PyUnicode_GetDefaultEncoding(), true)
+#define py_iconv_convenience(mem_ctx) smb_iconv_convenience_reinit(mem_ctx, "ASCII", \
+ PyUnicode_GetDefaultEncoding(), true, NULL)
#endif /* __SAMBA_PYTHON_MODULES_H__ */