[gq-commit] gq/src browse.c,1.85,1.86 browse.h,1.33,1.34 common.h,1.29,1.30 configfile.c,1.45,1.46 c
Status: Beta
Brought to you by:
sur5r
Update of /cvsroot/gqclient/gq/src In directory sc8-pr-cvs1:/tmp/cvs-serv325 Modified Files: browse.c browse.h common.h configfile.c configfile.h dn-browse.c dt_password.c errorchain.c formfill.c gq-xml.c input.c prefs.c ref-browse.c schemabrowse.c search.c search.h server-browse.c template.c tinput.c util.c util.h Log Message: * A HUGE change: struct ldapserver now uses reference counting. This is required to avoid some core-dumping bugs where servers get deleted and other parts of gq still hold references to such deleted server. There was no other elegant way to solve such problems. This change was also required for the referral support in search mode. The new policy here is: Whenever a ldapserver * gets stored permanently in some other structure ldapserver_ref must be called for this server. When the reference is no longer needed the server must be ldapserver_unref'd. This also includes cases where a ldapserver gets stored as data along with some GtkObject - set the unref call through gtk_object_set_data_full. THIS IS CRITICALLY IMPORTANT. * Referral support in search mode. This support does not use referral chasing in the LDAP library but does it itself. This is required in order to be able to edit and change entries obtained through a referral, because this information might be available only through the referral. * The requirements for browse mode and search mode were incompatible wrt ref handling. Thus the setting of the ManageDSAit control is now done on a per-search basis without much need to have a configuration option (the old show_ref setting). However, in search mode it might be interesting to be able to search from referrals instead of following them - TODO. This required the use for the ldap_search_ext extended search function. * Some cleanups Index: browse.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/browse.c,v retrieving revision 1.85 retrieving revision 1.86 diff -C2 -d -r1.85 -r1.86 *** browse.c 17 Oct 2003 10:20:36 -0000 1.85 --- browse.c 18 Oct 2003 08:26:59 -0000 1.86 *************** *** 654,658 **** GtkCTreeNode *tree_node_from_server_dn(GtkCTree *ctree, ! const struct ldapserver *server, const char *dn) { --- 654,658 ---- GtkCTreeNode *tree_node_from_server_dn(GtkCTree *ctree, ! struct ldapserver *server, const char *dn) { *************** *** 665,668 **** --- 665,669 ---- sd->found = NULL; + ldapserver_ref(server); gtk_ctree_pre_recursive(ctree, NULL, /* root */ *************** *** 671,674 **** --- 672,676 ---- thenode = sd->found; + ldapserver_unref(server); g_free(sd); *************** *** 677,681 **** ! GtkCTreeNode *server_node_from_server(GtkCTree *ctree, const struct ldapserver *server) { --- 679,683 ---- ! GtkCTreeNode *server_node_from_server(GtkCTree *ctree, struct ldapserver *server) { *************** *** 907,912 **** if ((ld = open_connection(server)) != NULL) { LDAPMessage *res, *e; ! int rc = ldap_search_s(ld, s->str, LDAP_SCOPE_BASE, ! "(objectClass=*)", attrs, 0, &res); if (rc == LDAP_SUCCESS) { e = ldap_first_entry(ld, res); --- 909,940 ---- if ((ld = open_connection(server)) != NULL) { LDAPMessage *res, *e; ! LDAPControl c; ! LDAPControl *ctrls[2] = { NULL, NULL } ; ! int rc, msg; ! ! /* int rc = ldap_search_s(ld, s->str, LDAP_SCOPE_BASE, */ ! /* "(objectClass=*)", attrs, 0, &res); */ ! ! c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT; ! c.ldctl_value.bv_val = NULL; ! c.ldctl_value.bv_len = 0; ! c.ldctl_iscritical = 1; ! ! ctrls[0] = &c; ! ! rc = ldap_search_ext(ld, s->str, ! LDAP_SCOPE_BASE, ! "(objectClass=*)", attrs, 0, ! ctrls, /* serverctrls */ ! NULL, /* clientctrls */ ! NULL, /* timeout */ ! LDAP_NO_LIMIT, /* sizelimit */ ! &msg); ! ! ! if (rc == LDAP_SUCCESS) { ! rc = ldap_result(ld, msg, 1, NULL, &res); ! } ! if (rc == LDAP_SUCCESS) { e = ldap_first_entry(ld, res); *************** *** 920,923 **** --- 948,953 ---- } ldap_msgfree(res); + } else { + /* FIXME report error */ } *************** *** 1091,1094 **** --- 1121,1125 ---- csl->list = g_list_append(csl->list, thisserver); + ldapserver_ref(thisserver); } } *************** *** 1125,1137 **** /* is this server still in the list of configured servers? */ ! struct ldapserver *server; ! GList *I; ! ! for (I = config->servers ; I ; I = g_list_next(I)) { ! server = (struct ldapserver *) I->data; ! if (thisserver == server) { ! found = 1; ! break; ! } } --- 1156,1161 ---- /* is this server still in the list of configured servers? */ ! if (g_list_find(config->servers, thisserver)) { ! found = 1; } *************** *** 1159,1163 **** } } ! if (csl.list) g_list_free(csl.list); } --- 1183,1191 ---- } } ! ! if (csl.list) { ! g_list_foreach(csl.list, (GFunc) ldapserver_unref, NULL); ! g_list_free(csl.list); ! } } Index: browse.h =================================================================== RCS file: /cvsroot/gqclient/gq/src/browse.h,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** browse.h 17 Oct 2003 07:26:25 -0000 1.33 --- browse.h 18 Oct 2003 08:26:59 -0000 1.34 *************** *** 167,171 **** GtkCTreeNode *tree_node_from_server_dn(GtkCTree *ctree, ! const struct ldapserver *server, const char *dn); --- 167,171 ---- GtkCTreeNode *tree_node_from_server_dn(GtkCTree *ctree, ! struct ldapserver *server, const char *dn); Index: common.h =================================================================== RCS file: /cvsroot/gqclient/gq/src/common.h,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** common.h 17 Oct 2003 06:52:39 -0000 1.29 --- common.h 18 Oct 2003 08:26:59 -0000 1.30 *************** *** 71,75 **** char *name; char *ldaphost; ! int ldapport; char *basedn; char *binddn; --- 71,75 ---- char *name; char *ldaphost; ! int ldapport; char *basedn; char *binddn; *************** *** 80,93 **** considerably */ char *enteredpw; ! int bindtype; char *saslmechanism; char *searchattr; ! int maxentries; ! int cacheconn; ! int enabletls; ! long local_cache_timeout; ! int ask_pw; ! int show_ref; ! int hide_internal; /* the canonical name of the host. Essentially this is the --- 80,93 ---- considerably */ char *enteredpw; ! int bindtype; char *saslmechanism; char *searchattr; ! int maxentries; ! int cacheconn; ! int enabletls; ! long local_cache_timeout; ! int ask_pw; ! int show_ref; ! int hide_internal; /* the canonical name of the host. Essentially this is the *************** *** 97,113 **** /* a flag indicating if ldaphost seems to be a URI or not */ ! int is_uri; LDAP *connection; ! int incarnation; /* number of bind operations done so far, ! never decremented - this is a purely ! statistical number */ ! int missing_closes; /* incremented on every open_connection, ! decremented on each close, close_connection ! really closes only if this drops to zero */ struct server_schema *ss; ! int flags; ! int version; /* server_down is a flag set by the SIGPIPE signal handler and in case of an LDAP_SERVER_DOWN error. It indicates that we should --- 97,135 ---- /* a flag indicating if ldaphost seems to be a URI or not */ ! int is_uri; ! ! /* if quiet is non-zero open_connection will not pop-up any error ! or questions */ ! int quiet; ! ! /* reference count. maintained through ldapserver_ref and ! ldapserver_unref. Similar to the reference counting within ! gtk. The last ldapserver_unref will delete the object (when ! refcount becomes <= 0). ! ! Whenever a ldapserver object get stored for a longer period of ! time (that is, whenever a structure holding a pointer to the ! object is not freed within the same function it is create in) ! the object should be ref'd. ! ! Objects are created with a refcount of 0. This means that such ! an object is actually "floating". ! */ ! int refcount; ! ! /* internal data */ LDAP *connection; ! int incarnation; /* number of bind operations done so far, ! never decremented - this is a purely ! statistical number */ ! int missing_closes; /* incremented on every open_connection, ! decremented on each close, ! close_connection really closes only if ! this drops to zero */ struct server_schema *ss; ! int flags; ! int version; /* server_down is a flag set by the SIGPIPE signal handler and in case of an LDAP_SERVER_DOWN error. It indicates that we should *************** *** 119,124 **** pages mention it though) nor is it actually available through ldap.h */ ! int server_down; }; #ifdef USE_G_SNPRINTF --- 141,150 ---- pages mention it though) nor is it actually available through ldap.h */ ! int server_down; }; + + void ldapserver_ref(struct ldapserver *); + void ldapserver_unref(struct ldapserver *); + #ifdef USE_G_SNPRINTF Index: configfile.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/configfile.c,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** configfile.c 17 Oct 2003 10:20:37 -0000 1.45 --- configfile.c 18 Oct 2003 08:26:59 -0000 1.46 *************** *** 52,55 **** --- 52,56 ---- struct gq_config *config; + GList *transient_servers = NULL; const struct tokenlist token_searchargument[] = { *************** *** 114,117 **** --- 115,120 ---- newserver->server_down = 0; + newserver->refcount = 0; + return(newserver); } *************** *** 120,123 **** --- 123,129 ---- #define DEEPCOPY(t,s,n) t->n = s->n ? g_strdup(s->n) : NULL #define SHALLOWCOPY(t,s,n) t->n = s->n + + /** NOTE: copy_ldapserver sets the target refcount to 0! */ + void copy_ldapserver(struct ldapserver *target, const struct ldapserver *source) *************** *** 152,155 **** --- 158,163 ---- target->version = LDAP_VERSION2; target->server_down = 0; + + target->refcount = 0; } *************** *** 172,176 **** } ! void free_ldapserver(struct ldapserver *server) { if (server->connection) { --- 180,184 ---- } ! static void free_ldapserver(struct ldapserver *server) { if (server->connection) { *************** *** 193,200 **** --- 201,230 ---- } + + void ldapserver_ref(struct ldapserver *server) + { + if (server) server->refcount++; + } + + void ldapserver_unref(struct ldapserver *server) + { + if (server) { + server->refcount--; + if (server->refcount <= 0) { + /* HACK HACK HACK : FIXME */ + if (is_transient_server(server)) { + transient_remove_server(server); + } + + free_ldapserver(server); + } + } + } + void config_add_server(struct gq_config *config, struct ldapserver *newserver) { config->servers = g_list_append(config->servers, newserver); + ldapserver_ref(newserver); } *************** *** 204,207 **** --- 234,249 ---- { config->servers = g_list_remove(config->servers, server); + ldapserver_unref(server); + } + + /* transient servers are transient by definition. Thus no _ref/_unref */ + void transient_add_server(struct ldapserver *newserver) + { + transient_servers = g_list_append(transient_servers, newserver); + } + + void transient_remove_server(struct ldapserver *server) + { + transient_servers = g_list_remove(transient_servers, server); } *************** *** 650,655 **** } - - config_write(wc, "<defaults>\n"); wc->indent++; --- 692,695 ---- *************** *** 808,813 **** server = (struct ldapserver *) I->data; close_connection(server, TRUE); ! free_ldapserver(server); } /* free templates */ --- 848,854 ---- server = (struct ldapserver *) I->data; close_connection(server, TRUE); ! ldapserver_unref(server); } + g_list_free(cfg->servers); /* free templates */ Index: configfile.h =================================================================== RCS file: /cvsroot/gqclient/gq/src/configfile.h,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** configfile.h 17 Oct 2003 06:52:39 -0000 1.31 --- configfile.h 18 Oct 2003 08:26:59 -0000 1.32 *************** *** 152,158 **** struct ldapserver *new_ldapserver(void); void copy_ldapserver(struct ldapserver *target, const struct ldapserver *source); - void free_ldapserver(struct ldapserver *server); /* canonicalize_ldapserver - to be called whenever the server-related --- 152,159 ---- struct ldapserver *new_ldapserver(void); + + /** NOTE: copy_ldapserver sets the target refcount to 0 */ void copy_ldapserver(struct ldapserver *target, const struct ldapserver *source); /* canonicalize_ldapserver - to be called whenever the server-related *************** *** 178,182 **** --- 179,188 ---- void free_config(struct gq_config *cfg); + void transient_add_server(struct ldapserver *newserver); + void transient_remove_server(struct ldapserver *server); + extern struct gq_config *config; + extern GList *transient_servers; + extern const struct tokenlist token_bindtype[]; extern const struct tokenlist token_ldifformat[]; Index: dn-browse.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/dn-browse.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** dn-browse.c 17 Oct 2003 10:20:37 -0000 1.2 --- dn-browse.c 18 Oct 2003 08:26:59 -0000 1.3 *************** *** 164,167 **** --- 164,168 ---- iform->dn = NULL; iform->server = server; + ldapserver_ref(server); formlist = formfill_from_template(server, template); *************** *** 180,185 **** create_form_content(iform); build_inputform(iform); ! } ! else { free_inputform(iform); } --- 181,185 ---- create_form_content(iform); build_inputform(iform); ! } else { free_inputform(iform); } *************** *** 262,270 **** gmessage = g_string_sized_new(256); for (I = g_list_first(bases) ; I ; I = g_list_next(I)) { statusbar_msg(_("Subtree search on %s"), (char *) I->data); msg = ldap_search_s(ld, (char *) I->data, LDAP_SCOPE_SUBTREE, "(objectclass=*)", NULL, 0, &res); ! if(msg == LDAP_SUCCESS) { for(e = ldap_first_entry(ld, res); e; e = ldap_next_entry(ld, e)) { g_string_truncate(out, 0); --- 262,296 ---- gmessage = g_string_sized_new(256); for (I = g_list_first(bases) ; I ; I = g_list_next(I)) { + LDAPControl ct; + LDAPControl *ctrls[2] = { NULL, NULL } ; + int rc; + statusbar_msg(_("Subtree search on %s"), (char *) I->data); msg = ldap_search_s(ld, (char *) I->data, LDAP_SCOPE_SUBTREE, "(objectclass=*)", NULL, 0, &res); ! ! ct.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT; ! ct.ldctl_value.bv_val = NULL; ! ct.ldctl_value.bv_len = 0; ! ct.ldctl_iscritical = 1; ! ! ctrls[0] = &ct; ! ! rc = ldap_search_ext(ld, (char *) I->data, ! LDAP_SCOPE_SUBTREE, ! "(objectClass=*)", NULL, 0, ! ctrls, /* serverctrls */ ! NULL, /* clientctrls */ ! NULL, /* timeout */ ! LDAP_NO_LIMIT, /* sizelimit */ ! &msg); ! ! ! if (rc != -1) { ! rc = ldap_result(ld, msg, 1, NULL, &res); ! } ! ! if (rc != -1) { for(e = ldap_first_entry(ld, res); e; e = ldap_next_entry(ld, e)) { g_string_truncate(out, 0); *************** *** 286,307 **** } ldap_msgfree(res); ! } else if (msg == LDAP_SERVER_DOWN) { ! server->server_down++; ! ldap_msgfree(res); /* is this correct? */ ! ! error_push(ctx, ! _("Server '%s' down. Export may be incomplete!"), ! server->name); ! push_ldap_addl_error(ld, ctx); ! goto fail; } else { ! /* report error */ ! error_push(ctx, ! _("LDAP error while searching below '%s'. Export may be incomplete!"), ! (char *) I->data); ! push_ldap_addl_error(ld, ctx); ! /* statusbar_msg(ldap_err2string(ldap_result2error(ld, */ ! /* res, 1))); */ ! goto fail; } } --- 312,335 ---- } ldap_msgfree(res); ! rc = LDAP_SUCCESS; } else { ! rc = ldap_result2error(ld, res, TRUE); ! if (msg == LDAP_SERVER_DOWN) { ! server->server_down++; ! ! error_push(ctx, ! _("Server '%s' down. Export may be incomplete!"), ! server->name); ! push_ldap_addl_error(ld, ctx); ! goto fail; ! } else { ! /* report error */ ! error_push(ctx, ! _("LDAP error while searching below '%s'." ! " Export may be incomplete!"), ! (char *) I->data); ! push_ldap_addl_error(ld, ctx); ! goto fail; ! } } } *************** *** 353,357 **** filesel = gtk_file_selection_new(_("Save LDIF")); ! gtk_object_set_data(GTK_OBJECT(filesel), "server", server); gtk_object_set_data(GTK_OBJECT(filesel), "entry", entry); --- 381,388 ---- filesel = gtk_file_selection_new(_("Save LDIF")); ! gtk_object_set_data_full(GTK_OBJECT(filesel), "server", ! server, (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_object_set_data(GTK_OBJECT(filesel), "entry", entry); *************** *** 476,479 **** --- 507,512 ---- char *c, **refs; int context = error_new_context(_("Expand entry")); + LDAPControl ct; + LDAPControl *ctrls[2] = { NULL, NULL } ; assert(IS_DN_ENTRY(entry)); *************** *** 513,561 **** #endif ! /* check if this is a referral object */ - if (server->show_ref) { - msg = ldap_search(ld, entry->dn, LDAP_SCOPE_BASE, - "objectclass=referral", ref, 0); ! if(msg == -1) { ! statusbar_msg("%s", ldap_err2string(msg)); ! close_connection(server, FALSE); ! gtk_clist_thaw(GTK_CLIST(ctree)); ! ! error_flush(context); ! return; ! } ! while((rc = ldap_result(ld, msg, 0, ! NULL, &res)) == LDAP_RES_SEARCH_ENTRY) { ! for(e = ldap_first_entry(ld, res) ; e != NULL ; ! e = ldap_next_entry(ld, e)) { ! char **vals = ldap_get_values(ld, e, "ref"); ! int i; ! ! if (vals == NULL) continue; ! for(i = 0; vals[i]; i++) { ! entry->is_ref = TRUE; /* now we know for sure */ ! ref_browse_single_add(vals[i], ctree, node); ! } } - ldap_msgfree(res); - } - if (entry->is_ref) { - entry->seen = TRUE; - statusbar_msg(_("Showing referrals")); - gtk_clist_thaw(GTK_CLIST(ctree)); - close_connection(server, FALSE); - return; } } ! msg = ldap_search(ld, entry->dn, LDAP_SCOPE_ONELEVEL, ! "objectclass=*", dummy, 1); ! ! if(msg == -1) { ! statusbar_msg("Error while searching below '%1$s': %2$s", entry->dn, ldap_err2string(msg)); --- 546,619 ---- #endif ! ct.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT; ! ct.ldctl_value.bv_val = NULL; ! ct.ldctl_value.bv_len = 0; ! ct.ldctl_iscritical = 1; ! ! ctrls[0] = &ct; ! /* check if this is a referral object */ ! rc = ldap_search_ext(ld, entry->dn, ! LDAP_SCOPE_BASE, ! "(objectClass=referral)", ref, 0, ! ctrls, /* serverctrls */ ! NULL, /* clientctrls */ ! NULL, /* timeout */ ! LDAP_NO_LIMIT, /* sizelimit */ ! &msg); ! if (rc != LDAP_SUCCESS) { ! statusbar_msg(_("Searching for '%1$s': %2$s"), ! entry->dn, ! ldap_err2string(msg)); ! close_connection(server, FALSE); ! gtk_clist_thaw(GTK_CLIST(ctree)); ! ! error_flush(context); ! return; ! ! } ! while((rc = ldap_result(ld, msg, 0, ! NULL, &res)) == LDAP_RES_SEARCH_ENTRY) { ! for(e = ldap_first_entry(ld, res) ; e != NULL ; ! e = ldap_next_entry(ld, e)) { ! char **vals = ldap_get_values(ld, e, "ref"); ! int i; ! ! if (vals == NULL) continue; ! ! for(i = 0; vals[i]; i++) { ! entry->is_ref = TRUE; /* now we know for sure */ ! ref_browse_single_add(vals[i], ctree, node); } } + ldap_msgfree(res); } ! if (entry->is_ref) { ! entry->seen = TRUE; ! statusbar_msg(_("Showing referrals")); ! gtk_clist_thaw(GTK_CLIST(ctree)); ! close_connection(server, FALSE); ! return; ! } ! ! ! ! ! ! rc = ldap_search_ext(ld, entry->dn, ! LDAP_SCOPE_ONELEVEL, ! "(objectClass=*)", dummy, 1, ! ctrls, /* serverctrls */ ! NULL, /* clientctrls */ ! NULL, /* timeout */ ! LDAP_NO_LIMIT, /* sizelimit */ ! &msg); ! ! if(rc != LDAP_SUCCESS) { ! statusbar_msg(_("Error while searching below '%1$s': %2$s"), entry->dn, ldap_err2string(msg)); *************** *** 708,711 **** --- 766,771 ---- iform->server = server; + ldapserver_ref(server); + iform->edit = 1; *************** *** 746,751 **** create_form_content(iform); build_inputform(iform); ! } ! else { inputform_free(iform); BROWSETAB(tab)->inputform = NULL; --- 806,810 ---- create_form_content(iform); build_inputform(iform); ! } else { inputform_free(iform); BROWSETAB(tab)->inputform = NULL; *************** *** 829,833 **** template = (struct gq_template *) templatelist->data; menu_item = gtk_menu_item_new_with_label(template->name); ! gtk_object_set_data(GTK_OBJECT(menu_item), "server", server); gtk_object_set_data(GTK_OBJECT(menu_item), "entry", entry); gtk_menu_append(GTK_MENU(submenu), menu_item); --- 888,895 ---- template = (struct gq_template *) templatelist->data; menu_item = gtk_menu_item_new_with_label(template->name); ! gtk_object_set_data_full(GTK_OBJECT(menu_item), "server", ! server, (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_object_set_data(GTK_OBJECT(menu_item), "entry", entry); gtk_menu_append(GTK_MENU(submenu), menu_item); Index: dt_password.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/dt_password.c,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** dt_password.c 17 Oct 2003 10:07:40 -0000 1.18 --- dt_password.c 18 Oct 2003 08:26:59 -0000 1.19 *************** *** 1,8 **** /* GQ -- a GTK-based LDAP client ! Copyright (C) 1998-2001 Bert Vermeulen ! ! This file (dt_password.c) is ! Copyright (C) 2002 by Peter Stamfest and Bert Vermeulen This program is released under the Gnu General Public License with --- 1,6 ---- /* GQ -- a GTK-based LDAP client ! Copyright (C) 1998-2003 Bert Vermeulen ! Copyright (C) 2002-2003 Peter Stamfest This program is released under the Gnu General Public License with *************** *** 352,356 **** if (temp > max_width) max_width = temp; ! cryptlist = g_list_append(cryptlist, cryptmap[i].keyword); } gtk_combo_set_popdown_strings(GTK_COMBO(combo), cryptlist); --- 350,354 ---- if (temp > max_width) max_width = temp; ! cryptlist = g_list_append(cryptlist, (char *) cryptmap[i].keyword); } gtk_combo_set_popdown_strings(GTK_COMBO(combo), cryptlist); Index: errorchain.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/errorchain.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** errorchain.c 17 Oct 2003 06:31:16 -0000 1.17 --- errorchain.c 18 Oct 2003 08:26:59 -0000 1.18 *************** *** 83,95 **** struct errchain *chain; GString *str; ! int n, a; a = strlen(fmt) + 50; str = g_string_sized_new(a); /* used for glib1 compatibility */ /* I hope it is ok to repeatadly use ap like this */ - do { n = vsnprintf(str->str, a - 1, fmt, ap); /* await both n==-1 and n > a -1 for not enough free space */ if (n > a - 1) { --- 83,95 ---- struct errchain *chain; GString *str; ! int n, a, retry = 0; a = strlen(fmt) + 50; str = g_string_sized_new(a); /* used for glib1 compatibility */ /* I hope it is ok to repeatadly use ap like this */ do { n = vsnprintf(str->str, a - 1, fmt, ap); + retry = 0; /* await both n==-1 and n > a -1 for not enough free space */ if (n > a - 1) { *************** *** 97,106 **** a = n + 2; str = g_string_sized_new(a); } else if (n == -1) { g_string_free(str, TRUE); a *= 2; str = g_string_sized_new(a); } ! } while (n > (a - 1) || n == -1); /* plug into messagechain */ --- 97,108 ---- a = n + 2; str = g_string_sized_new(a); + retry = 1; } else if (n == -1) { g_string_free(str, TRUE); a *= 2; str = g_string_sized_new(a); + retry = 1; } ! } while (retry); /* plug into messagechain */ Index: formfill.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/formfill.c,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** formfill.c 17 Oct 2003 06:28:59 -0000 1.39 --- formfill.c 18 Oct 2003 08:26:59 -0000 1.40 *************** *** 1,5 **** /* GQ -- a GTK-based LDAP client ! Copyright (C) 1998-2001 Bert Vermeulen This program is released under the Gnu General Public License with --- 1,6 ---- /* GQ -- a GTK-based LDAP client ! Copyright (C) 1998-2003 Bert Vermeulen ! Copyright (C) 2002-2003 Peter Stamfest This program is released under the Gnu General Public License with *************** *** 122,125 **** --- 123,127 ---- free_formfill_values(form); if (form->widgetList) g_list_free(form->widgetList); + if (form->server) ldapserver_unref(form->server); g_free(form); } *************** *** 237,240 **** --- 239,244 ---- form->server = server; + ldapserver_ref(server); + strncpy(form->attrname, c, MAX_ATTR_LEN); if (c) g_free(c); *************** *** 294,297 **** --- 298,303 ---- completly NUL inited object */ newform->server = oldform->server; + if (newform->server) ldapserver_ref(newform->server); + strncpy(newform->attrname, oldform->attrname, sizeof(newform->attrname)); Index: gq-xml.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/gq-xml.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** gq-xml.c 17 Oct 2003 07:27:51 -0000 1.7 --- gq-xml.c 18 Oct 2003 08:26:59 -0000 1.8 *************** *** 273,277 **** struct ldapserver *server = new_ldapserver(); e->data = server; ! e->free_data = (free_func) free_ldapserver; } --- 273,277 ---- struct ldapserver *server = new_ldapserver(); e->data = server; ! e->free_data = (free_func) ldapserver_unref; } *************** *** 294,298 **** canonicalize_ldapserver(server); ! c->servers = g_list_append(c->servers, server); e->data = NULL; --- 294,298 ---- canonicalize_ldapserver(server); ! config_add_server(c, server); e->data = NULL; Index: input.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/input.c,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** input.c 17 Oct 2003 10:20:38 -0000 1.72 --- input.c 18 Oct 2003 08:26:59 -0000 1.73 *************** *** 96,99 **** --- 96,103 ---- } + if (iform->server) { + ldapserver_unref(iform->server); + } + g_free(iform); } *************** *** 983,986 **** --- 987,991 ---- iform->close_window = 1; iform->server = server; + ldapserver_ref(server); iform->dn = g_strdup(dn); iform->olddn = g_strdup(dn); *************** *** 1003,1006 **** --- 1008,1012 ---- iform = new_inputform(); iform->server = server; + ldapserver_ref(server); #ifdef HAVE_LDAP_STR2OBJECTCLASS *************** *** 2278,2281 **** --- 2284,2288 ---- if(ff) { ff->server = server; + ldapserver_ref(server); strncpy(ff->attrname, outbuf, MAX_ATTR_LEN); ff->flags |= FLAG_EXTENSIBLE_OBJECT_ATTR; Index: prefs.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/prefs.c,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** prefs.c 17 Oct 2003 07:16:14 -0000 1.44 --- prefs.c 18 Oct 2003 08:26:59 -0000 1.45 *************** *** 157,163 **** if (cb_data->server) { config_remove_server(config, cb_data->server); - free_ldapserver(cb_data->server); } } g_free(cb_data); } --- 157,164 ---- if (cb_data->server) { config_remove_server(config, cb_data->server); } } + if (cb_data->server) + ldapserver_unref(cb_data->server); g_free(cb_data); } *************** *** 346,355 **** update_serverlist(&mainwin); ! if (cb_data->edit_new_server) { ! /* everything ok, take the server out of the cb_data (in case it ! was created anew, this will avoid that the cb_data destroy ! function deletes the ldapserver) */ ! cb_data->server = NULL; ! } gtk_widget_destroy(window); --- 347,356 ---- update_serverlist(&mainwin); ! /* if (cb_data->edit_new_server) { */ ! /* /\* everything ok, take the server out of the cb_data (in case it */ ! /* was created anew, this will avoid that the cb_data destroy */ ! /* function deletes the ldapserver) *\/ */ ! /* cb_data->server = NULL; */ ! /* } */ gtk_widget_destroy(window); *************** *** 445,448 **** --- 446,450 ---- cb_data->server = server; + ldapserver_ref(server); #if GTK_MAJOR < 2 *************** *** 1143,1147 **** serverlist[0] = server->name; gtk_clist_append(GTK_CLIST(clist), serverlist); ! gtk_clist_set_row_data(GTK_CLIST(clist), row, (gpointer) server); row++; } --- 1145,1152 ---- serverlist[0] = server->name; gtk_clist_append(GTK_CLIST(clist), serverlist); ! gtk_clist_set_row_data_full(GTK_CLIST(clist), row, ! (gpointer) server, ! (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); row++; } Index: ref-browse.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/ref-browse.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ref-browse.c 17 Oct 2003 10:20:38 -0000 1.2 --- ref-browse.c 18 Oct 2003 08:26:59 -0000 1.3 *************** *** 2,6 **** GQ -- a GTK-based LDAP client Copyright (C) 1998-2003 Bert Vermeulen ! Parts: Copyright (C) 2002-2003 Peter Stamfest <pe...@st...> This program is released under the Gnu General Public License with --- 2,6 ---- GQ -- a GTK-based LDAP client Copyright (C) 1998-2003 Bert Vermeulen ! Copyright (C) 2002-2003 Peter Stamfest <pe...@st...> This program is released under the Gnu General Public License with *************** *** 31,34 **** --- 31,35 ---- #include <errno.h> #include <string.h> + #include <stdlib.h> /* free */ #include <config.h> *************** *** 46,49 **** --- 47,51 ---- #include "i18n.h" #include "errorchain.h" + #include "encode.h" /**************************************************************************/ *************** *** 58,62 **** g_free_if(entry->uri); if (entry->server) { ! free_ldapserver(entry->server); entry->server = NULL; } --- 60,64 ---- g_free_if(entry->uri); if (entry->server) { ! ldapserver_unref(entry->server); /* removes from transient list as well */ entry->server = NULL; } *************** *** 163,168 **** newserver->show_ref = 1; /* check: do we have this server around already??? */ ! server = server_by_canon_name(new_uri->str); if (!server) { --- 165,171 ---- newserver->show_ref = 1; + #warning "ADD CONFIG FOR EXTENDED REFERENCE CHASING" /* check: do we have this server around already??? */ ! server = server_by_canon_name(new_uri->str, TRUE); if (!server) { *************** *** 203,207 **** --- 206,214 ---- canonicalize_ldapserver(newserver); + transient_add_server(newserver); + entry->server = newserver; + ldapserver_ref(newserver); + entry->expanded = TRUE; Index: schemabrowse.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/schemabrowse.c,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** schemabrowse.c 17 Oct 2003 07:27:51 -0000 1.25 --- schemabrowse.c 18 Oct 2003 08:26:59 -0000 1.26 *************** *** 192,197 **** SCHEMATAB(tab)->treeroot); gtk_object_set_data(GTK_OBJECT(new_item), "tab", tab); ! gtk_object_set_data(GTK_OBJECT(new_item), "server", ! (gpointer) server); gtk_tree_append(GTK_TREE(SCHEMATAB(tab)->treeroot), new_item); --- 192,199 ---- SCHEMATAB(tab)->treeroot); gtk_object_set_data(GTK_OBJECT(new_item), "tab", tab); ! gtk_object_set_data_full(GTK_OBJECT(new_item), "server", ! (gpointer) server, ! (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); gtk_tree_append(GTK_TREE(SCHEMATAB(tab)->treeroot), new_item); *************** *** 245,249 **** new_subtree = gtk_tree_new(); GTK_WIDGET_UNSET_FLAGS(new_subtree, GTK_CAN_FOCUS); ! gtk_object_set_data(GTK_OBJECT(new_subtree), "server", server); gtk_widget_show(new_subtree); gtk_tree_item_set_subtree(GTK_TREE_ITEM(new_item), new_subtree); --- 247,255 ---- new_subtree = gtk_tree_new(); GTK_WIDGET_UNSET_FLAGS(new_subtree, GTK_CAN_FOCUS); ! gtk_object_set_data_full(GTK_OBJECT(new_subtree), "server", ! server, ! (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_widget_show(new_subtree); gtk_tree_item_set_subtree(GTK_TREE_ITEM(new_item), new_subtree); *************** *** 279,283 **** new_subtree = gtk_tree_new(); GTK_WIDGET_UNSET_FLAGS(new_subtree, GTK_CAN_FOCUS); ! gtk_object_set_data(GTK_OBJECT(new_subtree), "server", server); gtk_widget_show(new_subtree); gtk_tree_item_set_subtree(GTK_TREE_ITEM(new_item), new_subtree); --- 285,293 ---- new_subtree = gtk_tree_new(); GTK_WIDGET_UNSET_FLAGS(new_subtree, GTK_CAN_FOCUS); ! gtk_object_set_data_full(GTK_OBJECT(new_subtree), "server", ! server, ! (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_widget_show(new_subtree); gtk_tree_item_set_subtree(GTK_TREE_ITEM(new_item), new_subtree); *************** *** 313,317 **** new_subtree = gtk_tree_new(); GTK_WIDGET_UNSET_FLAGS(new_subtree, GTK_CAN_FOCUS); ! gtk_object_set_data(GTK_OBJECT(new_subtree), "server", server); gtk_widget_show(new_subtree); gtk_tree_item_set_subtree(GTK_TREE_ITEM(new_item), new_subtree); --- 323,331 ---- new_subtree = gtk_tree_new(); GTK_WIDGET_UNSET_FLAGS(new_subtree, GTK_CAN_FOCUS); ! gtk_object_set_data_full(GTK_OBJECT(new_subtree), "server", ! server, ! (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_widget_show(new_subtree); gtk_tree_item_set_subtree(GTK_TREE_ITEM(new_item), new_subtree); *************** *** 347,351 **** new_subtree = gtk_tree_new(); GTK_WIDGET_UNSET_FLAGS(new_subtree, GTK_CAN_FOCUS); ! gtk_object_set_data(GTK_OBJECT(new_subtree), "server", server); gtk_widget_show(new_subtree); gtk_tree_item_set_subtree(GTK_TREE_ITEM(new_item), new_subtree); --- 361,369 ---- new_subtree = gtk_tree_new(); GTK_WIDGET_UNSET_FLAGS(new_subtree, GTK_CAN_FOCUS); ! gtk_object_set_data_full(GTK_OBJECT(new_subtree), "server", ! server, ! (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_widget_show(new_subtree); gtk_tree_item_set_subtree(GTK_TREE_ITEM(new_item), new_subtree); *************** *** 895,899 **** /* Required attributes */ clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_oc_vbox), "required"); ! gtk_object_set_data(GTK_OBJECT(clist), "server", server); gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); --- 913,920 ---- /* Required attributes */ clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_oc_vbox), "required"); ! gtk_object_set_data_full(GTK_OBJECT(clist), "server", ! server,(GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); *************** *** 909,913 **** /* Allowed attributes */ clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_oc_vbox), "allowed"); ! gtk_object_set_data(GTK_OBJECT(clist), "server", server); gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); --- 930,937 ---- /* Allowed attributes */ clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_oc_vbox), "allowed"); ! gtk_object_set_data_full(GTK_OBJECT(clist), "server", ! server, (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); *************** *** 1306,1310 **** clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_vbox), "usedoc"); ! gtk_object_set_data(GTK_OBJECT(clist), "server", server); gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); --- 1330,1337 ---- clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_vbox), "usedoc"); ! gtk_object_set_data_full(GTK_OBJECT(clist), "server", ! server, (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); *************** *** 1527,1531 **** clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_vbox), "usedin"); ! gtk_object_set_data(GTK_OBJECT(clist), "server", server); gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); --- 1554,1561 ---- clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_vbox), "usedin"); ! gtk_object_set_data_full(GTK_OBJECT(clist), "server", ! server, (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); *************** *** 1709,1713 **** /* Used in attribute types */ clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_vbox), "usedat"); ! gtk_object_set_data(GTK_OBJECT(clist), "server", server); gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); --- 1739,1746 ---- /* Used in attribute types */ clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_vbox), "usedat"); ! gtk_object_set_data_full(GTK_OBJECT(clist), "server", ! server, (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); *************** *** 1729,1733 **** /* Used in matching rules */ clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_vbox), "usedmr"); ! gtk_object_set_data(GTK_OBJECT(clist), "server", server); gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); --- 1762,1769 ---- /* Used in matching rules */ clist = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(target_vbox), "usedmr"); ! gtk_object_set_data_full(GTK_OBJECT(clist), "server", ! server, (GtkDestroyNotify) ldapserver_unref); ! ldapserver_ref(server); ! gtk_clist_freeze(GTK_CLIST(clist)); gtk_clist_clear(GTK_CLIST(clist)); Index: search.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/search.c,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** search.c 17 Oct 2003 07:07:07 -0000 1.53 --- search.c 18 Oct 2003 08:27:00 -0000 1.54 *************** *** 322,344 **** ! struct resultset *new_resultset(struct tab *tab) { ! struct resultset *newset, *tmpset; ! newset = g_malloc(sizeof(struct resultset)); ! newset->objectclass = NULL; ! newset->attributes = NULL; ! newset->num_attributes = 0; ! newset->next = NULL; newset->dn = g_strdup(""); ! ! if(SEARCHTAB(tab)->cur_resultset == NULL) { ! SEARCHTAB(tab)->cur_resultset = newset; ! } ! else { ! for(tmpset = SEARCHTAB(tab)->cur_resultset; tmpset->next; tmpset = tmpset->next) ! ; ! tmpset->next = newset; ! } return(newset); --- 322,334 ---- ! struct resultset *new_resultset(struct ldapserver *server) { ! struct resultset *newset; ! newset = g_malloc0(sizeof(struct resultset)); newset->dn = g_strdup(""); ! newset->server = server; ! ! if (server) ldapserver_ref(server); return(newset); *************** *** 348,360 **** void free_resultset(struct resultset *set) { ! struct resultset *nextset; ! ! while(set) { ! nextset = set->next; g_free_if(set->dn); g_free(set); - set = nextset; } - } --- 338,346 ---- void free_resultset(struct resultset *set) { ! if (set) { ! if (set->server) ldapserver_unref(set->server); g_free_if(set->dn); g_free(set); } } *************** *** 498,501 **** --- 484,716 ---- } + static int fill_one_row(struct ldapserver *server, + LDAP *ld, LDAPMessage *e, + GtkWidget *clist, + GString **tolist, + int *columns_done, + struct attrs *attrlist, + struct tab *tab) + { + BerElement *berptr; + int i; + gchar *cl[MAX_NUM_ATTRIBUTES]; + int cur_col; + int row; + char *dn, *attr, **vals; + struct resultset *set; + + #if GTK_MAJOR < 2 + char *decoded_value; + #endif + + /* not every attribute necessarily comes back for + * every entry, so clear this every time */ + for(i = 0; i < MAX_NUM_ATTRIBUTES; i++) { + cl[i] = NULL; + g_string_truncate(tolist[i], 0); + } + + dn = ldap_get_dn(ld, e); + /* store for later reference */ + set = new_resultset(server); + g_free_and_dup(set->dn, dn); + + if(config->showdn) { + #if GTK_MAJOR >= 2 + g_string_append(tolist[0], dn); + #else + decoded_value = decoded_string(dn); + g_string_append(tolist[0], decoded_value); + free(decoded_value); + #endif + cl[0] = tolist[0]->str; + } + #if defined(HAVE_LDAP_MEMFREE) + ldap_memfree(dn); + #else + free(dn); + #endif + + for(attr = ldap_first_attribute(ld, e, &berptr); attr != NULL; + attr = ldap_next_attribute(ld, e, berptr)) { + if (!show_in_search(server, attr)) { + ldap_memfree(attr); + continue; + } + + /* This should now work for ;binary as well */ + cur_col = column_by_attr(&attrlist, attr); + if(cur_col == MAX_NUM_ATTRIBUTES) { + ldap_memfree(attr); + break; + } + + if(!columns_done[cur_col]) { + char *c = attr_strip(attr); + gtk_clist_set_column_title(GTK_CLIST(clist), cur_col, c); + if (c) g_free(c); + gtk_clist_set_column_width(GTK_CLIST(clist), cur_col, 120); + gtk_clist_set_column_resizeable(GTK_CLIST(clist), cur_col, + TRUE); + columns_done[cur_col] = 1; + } + + vals = ldap_get_values(ld, e, attr); + if(vals) { + for(i = 0; vals[i] != NULL; i++) { + #if GTK_MAJOR >= 2 + if(i == 0) { + g_string_assign(tolist[cur_col], vals[i]); + } else { + g_string_append(tolist[cur_col], " "); + g_string_append(tolist[cur_col], vals[i]); + } + #else + decoded_value = decoded_string(vals[i]); + if(i == 0) + g_string_assign(tolist[cur_col], decoded_value); + else { + g_string_append(tolist[cur_col], " "); + g_string_append(tolist[cur_col], decoded_value); + } + free(decoded_value); + #endif + } + ldap_value_free(vals); + #if GTK_MAJOR >= 2 + if (g_utf8_validate(tolist[cur_col]->str, -1, NULL)) { + cl[cur_col] = tolist[cur_col]->str; + } else { + cl[cur_col] = ""; + } + #else + cl[cur_col] = tolist[cur_col]->str; + #endif + } + ldap_memfree(attr); + } + #ifndef HAVE_OPENLDAP12 + if(berptr) + ber_free(berptr, 0); + #endif + + + for(i = MAX_NUM_ATTRIBUTES ; i >= 0 ; i--) { + if (cl[i]) { + for ( ; i >= 0 ; i-- ) { + if (!cl[i]) { + cl[i] = ""; + } + } + break; + } + } + + /* insert row into result window */ + row = gtk_clist_append(GTK_CLIST(clist), cl); + gtk_clist_set_row_data_full(GTK_CLIST(clist), row, set, + (GtkDestroyNotify) free_resultset); + + return row; + } + + + struct chasing { + struct ldapserver *server; + char *base; + }; + + static struct chasing *new_chasing(struct ldapserver *server, + const char *base) + { + struct chasing *n = g_malloc0(sizeof(struct chasing)); + n->server = server; + n->base = g_strdup(base); + if (server) ldapserver_ref(server); + return n; + } + + static void free_chasing(struct chasing *ch) + { + if (ch->server) ldapserver_unref(ch->server); + g_free_if(ch->base); + g_free(ch); + } + + + static void add_referral(struct ldapserver *server, + const char *referral, GList **nextlevel) + { + LDAPURLDesc *desc = NULL; + + if (ldap_url_parse(referral, &desc) == 0) { + GString *new_uri = g_string_sized_new(strlen(referral)); + struct ldapserver *s, *newserver; + + g_string_sprintf(new_uri, "%s://%s:%d/", + desc->lud_scheme, + desc->lud_host, + desc->lud_port); + + newserver = new_ldapserver(); + + /* some sensible settings for the "usual" case: + Anonymous bind. Also show referrals */ + newserver->ask_pw = 0; + newserver->show_ref = 1; + + #warning "ADD CONFIG FOR EXTENDED REFERENCE CHASING" + /* check: do we have this server around already??? */ + s = server_by_canon_name(new_uri->str, TRUE); + + if (!s) { + s = server; + } + + if (s) { + copy_ldapserver(newserver, s); + statusbar_msg(_("Initialized temporary server-definition '%1$s' from existing server '%2$s'"), new_uri->str, server->name); + } else { + statusbar_msg(_("Created temporary server-definition '%1$s' with no pre-set values."), new_uri->str); + } + + g_free_and_dup(newserver->name, new_uri->str); + g_free_and_dup(newserver->ldaphost, new_uri->str); + g_free_and_dup(newserver->basedn, desc->lud_dn); + newserver->quiet = 1; + + canonicalize_ldapserver(newserver); + + transient_add_server(newserver); + + *nextlevel = g_list_append(*nextlevel, + new_chasing(newserver, desc->lud_dn)); + + ldap_free_urldesc(desc); + g_string_free(new_uri, TRUE); + } + } + + struct list_click_info { + int last_col; + int last_type; + }; + + static void click_column(GtkCList *clist, + gint column, + struct list_click_info *lci) + { + gtk_clist_set_sort_column(clist, column); + if (lci->last_col != column) { + lci->last_type = GTK_SORT_ASCENDING; + } else { + lci->last_type = (lci->last_type == GTK_SORT_ASCENDING) ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING; + } + lci->last_col = column; + + gtk_clist_set_sort_type(clist, lci->last_type); + gtk_clist_sort(clist); + + } void query(struct tab *tab) *************** *** 503,521 **** LDAP *ld; LDAPMessage *res, *e; - BerElement *berptr; GtkWidget *main_clist, *new_main_clist, *scrwin, *focusbox; GtkWidget *servcombo, *searchbase_combo; struct ldapserver *server; - struct resultset *set, *cur_resultset; - struct attrs *attrlist; gchar *cur_servername, *cur_searchbase, *enc_searchbase, *querystring; GString *tolist[MAX_NUM_ATTRIBUTES]; ! gchar *cl[MAX_NUM_ATTRIBUTES]; ! char *filter, *attr, *dn, **vals, *searchterm; int msg, rc, i, row; ! int cur_col, oc_col, columns_done[MAX_NUM_ATTRIBUTES]; ! #if GTK_MAJOR < 2 ! char *decoded_value; ! #endif if(SEARCHTAB(tab)->search_lock) return; --- 718,739 ---- LDAP *ld; LDAPMessage *res, *e; GtkWidget *main_clist, *new_main_clist, *scrwin, *focusbox; GtkWidget *servcombo, *searchbase_combo; struct ldapserver *server; gchar *cur_servername, *cur_searchbase, *enc_searchbase, *querystring; GString *tolist[MAX_NUM_ATTRIBUTES]; ! char *filter, *searchterm; int msg, rc, i, row; ! int oc_col, columns_done[MAX_NUM_ATTRIBUTES]; ! struct attrs *attrlist; ! LDAPControl c; ! LDAPControl *ctrls[2] = { NULL, NULL } ; ! char *base; ! struct list_click_info *lci; ! ! GList *thislevel = NULL, *nextlevel = NULL; ! int level = 0; ! struct chasing *ch = NULL; ! if(SEARCHTAB(tab)->search_lock) return; *************** *** 526,529 **** --- 744,748 ---- searchterm = gtk_editable_get_chars(GTK_EDITABLE(focusbox), 0, -1); querystring = encoded_string(searchterm); + g_free(searchterm); if(querystring[0] == 0) { *************** *** 537,541 **** servcombo = SEARCHTAB(tab)->serverlist_combo; ! cur_servername = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(servcombo)->entry), 0, -1); server = server_by_name(cur_servername); if(!server) { --- 756,762 ---- servcombo = SEARCHTAB(tab)->serverlist_combo; ! cur_servername = ! gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(servcombo)->entry), ! 0, -1); server = server_by_name(cur_servername); if(!server) { *************** *** 547,555 **** g_free(cur_servername); - if( (ld = open_connection(server)) == NULL) { - SEARCHTAB(tab)->search_lock = 0; - return; - } - filter = make_filter(server, querystring); free(querystring); --- 768,771 ---- *************** *** 561,595 **** enc_searchbase = encoded_string(cur_searchbase); - - if(config->sort_search) - msg = ldap_search_s(ld, enc_searchbase, LDAP_SCOPE_SUBTREE, - filter, NULL, 0, &res); - else - msg = ldap_search(ld, enc_searchbase, LDAP_SCOPE_SUBTREE, - filter, NULL, 0); g_free(cur_searchbase); - if (enc_searchbase) free(enc_searchbase); - free(filter); - - if((config->sort_search && msg != LDAP_SUCCESS) || msg == -1) { - if (config->sort_search && msg != LDAP_SERVER_DOWN) { - server->server_down++; - } - statusbar_msg("%s", ldap_err2string(msg == -1 ? LDAP_OTHER : msg)); - g_free(searchterm); - close_connection(server, FALSE); - SEARCHTAB(tab)->search_lock = 0; - return; - } - - cur_resultset = SEARCHTAB(tab)->cur_resultset; - if(cur_resultset) { - free_resultset(cur_resultset); - SEARCHTAB(tab)->cur_resultset = NULL; - } - - SEARCHTAB(tab)->cur_resultset_server = server; ! /* build new clist */ new_main_clist = gtk_clist_new(MAX_NUM_ATTRIBUTES); --- 777,783 ---- enc_searchbase = encoded_string(cur_searchbase); g_free(cur_searchbase); ! /* setup GUI - build new clist */ new_main_clist = gtk_clist_new(MAX_NUM_ATTRIBUTES); *************** *** 625,760 **** gtk_clist_set_column_title(GTK_CLIST(new_main_clist), 0, "DN"); gtk_clist_set_column_width(GTK_CLIST(new_main_clist), 0, 260); } oc_col = column_by_attr(&attrlist, "objectClass"); ! gtk_clist_set_column_title(GTK_CLIST(new_main_clist), oc_col, "objectClass"); gtk_clist_set_column_width(GTK_CLIST(new_main_clist), oc_col, 120); columns_done[oc_col] = 1; - if(config->showoc == 0) - gtk_clist_set_column_visibility(GTK_CLIST(new_main_clist), oc_col, 0); ! row = 0; ! if(!config->sort_search) ! rc = (ldap_result(ld, msg, 0, NULL, &res) == LDAP_RES_SEARCH_ENTRY); ! else ! rc = (ldap_sort_entries(ld, &res, NULL, strcasecmp) == LDAP_SUCCESS); for(i = 0; i < MAX_NUM_ATTRIBUTES; i++) { tolist[i] = g_string_sized_new(MAX_DN_LEN); } ! while(rc) { ! for(e = ldap_first_entry(ld, res); e != NULL; ! e = ldap_next_entry(ld, e)) { ! /* not every attribute necessarily comes back for every entry, ! * so clear this every time */ ! for(i = 0; i < MAX_NUM_ATTRIBUTES; i++) { ! cl[i] = NULL; ! g_string_truncate(tolist[i], 0); ! } ! dn = ldap_get_dn(ld, e); ! /* store for later reference */ ! set = new_resultset(tab); ! g_free_and_dup(set->dn, dn); ! if(config->showdn) { ! #if GTK_MAJOR >= 2 ! g_string_append(tolist[0], dn); ! #else ! decoded_value = decoded_string(dn); ! g_string_append(tolist[0], decoded_value); ! free(decoded_value); ! #endif ! cl[0] = tolist[0]->str; ! } ! #if defined(HAVE_LDAP_MEMFREE) ! ldap_memfree(dn); ! #else ! free(dn); ! #endif ! for(attr = ldap_first_attribute(ld, e, &berptr); attr != NULL; ! attr = ldap_next_attribute(ld, e, berptr)) { ! if (!show_in_search(server, attr)) { ! ldap_memfree(attr); ! continue; ! } ! /* This should now work for ;binary as well */ ! cur_col = column_by_attr(&attrlist, attr); ! if(cur_col == MAX_NUM_ATTRIBUTES) { ! ldap_memfree(attr); break; } ! ! if(!columns_done[cur_col]) { ! char *c = attr_strip(attr); ! gtk_clist_set_column_title(GTK_CLIST(new_main_clist), cur_col, c); ! if (c) g_free(c); ! gtk_clist_set_column_width(GTK_CLIST(new_main_clist), cur_col, 120); ! gtk_clist_set_column_resizeable(GTK_CLIST(new_main_clist), cur_col, TRUE); ! columns_done[cur_col] = 1; ! } ! ! vals = ldap_get_values(ld, e, attr); ! if(vals) { ! for(i = 0; vals[i] != NULL; i++) { ! #if GTK_MAJOR >= 2 ! if(i == 0) { ! g_string_assign(tolist[cur_col], vals[i]); ! } else { ! g_string_append(tolist[cur_col], " "); ! g_string_append(tolist[cur_col], vals[i]); } ! #else ! decoded_value = decoded_string(vals[i]); ! if(i == 0) ! g_string_assign(tolist[cur_col], decoded_value); ! else { ! g_string_append(tolist[cur_col], " "); ! g_string_append(tolist[cur_col], decoded_value); } ! free(decoded_value); ! #endif } ! ldap_value_free(vals); ! #if GTK_MAJOR >= 2 ! if (g_utf8_validate(tolist[cur_col]->str, -1, NULL)) { ! cl[cur_col] = tolist[cur_col]->str; ! } else { ! cl[cur_col] = ""; } - #else - cl[cur_col] = tolist[cur_col]->str; - #endif } ! ldap_memfree(attr); } ! #ifndef HAVE_OPENLDAP12 ! if(berptr) ! ber_free(berptr, 0); ! #endif ! ! /* insert row into result window */ ! gtk_clist_append(GTK_CLIST(new_main_clist), cl); ! gtk_clist_set_row_data(GTK_CLIST(new_main_clist), row, set); ! row++; } ! if(config->sort_search) ! rc = 0; ! else ! if(server->maxentries == 0 || row < server->maxentries) { ! ldap_msgfree(res); ! res = NULL; ! rc = (ldap_result(ld, msg, 0, NULL, &res) == LDAP_RES_SEARCH_ENTRY); ! } ! else ! rc = 0; ! } for(i = 0; i < MAX_NUM_ATTRIBUTES; i++) { --- 813,961 ---- gtk_clist_set_column_title(GTK_CLIST(new_main_clist), 0, "DN"); gtk_clist_set_column_width(GTK_CLIST(new_main_clist), 0, 260); + columns_done[0] = 1; } oc_col = column_by_attr(&attrlist, "objectClass"); ! gtk_clist_set_column_title(GTK_CLIST(new_main_clist), oc_col, ! "objectClass"); gtk_clist_set_column_width(GTK_CLIST(new_main_clist), oc_col, 120); columns_done[oc_col] = 1; ! gtk_clist_set_sort_column(GTK_CLIST(new_main_clist), 0); ! ! if(config->showoc == 0) ! gtk_clist_set_column_visibility(GTK_CLIST(new_main_clist), ! oc_col, 0); for(i = 0; i < MAX_NUM_ATTRIBUTES; i++) { tolist[i] = g_string_sized_new(MAX_DN_LEN); } + + /* do the search */ + if (server->show_ref) { + c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT; + c.ldctl_value.bv_val = NULL; + c.ldctl_value.bv_len = 0; + c.ldctl_iscritical = 1; ! ctrls[0] = &c; ! } ! thislevel = NULL; ! nextlevel = NULL; ! level = 0; ! ch = new_chasing(server, enc_searchbase); ! thislevel = g_list_append(thislevel, ch); ! if (enc_searchbase) free(enc_searchbase); ! gtk_clist_freeze(GTK_CLIST(new_main_clist)); ! row = 0; ! ! while (thislevel || nextlevel) { ! if (thislevel == NULL) { ! level++; ! thislevel = nextlevel; ! nextlevel = NULL; ! } ! ch = thislevel->data; ! thislevel = g_list_remove(thislevel, ch); ! server = ch->server; ! base = ch->base; ! if( (ld = open_connection(server)) != NULL) { ! statusbar_msg(_("Searching on server '%1$s' below '%2$s'"), ! server->name, base); ! rc = ldap_search_ext(ld, base, LDAP_SCOPE_SUBTREE, ! filter, NULL, 0, ! server->show_ref ? ctrls : NULL, ! /* serverctrls */ ! NULL, /* clientctrls */ ! NULL, /* timeout */ ! LDAP_NO_LIMIT, /* sizelimit */ ! &msg); ! ! if(rc == -1) { ! server->server_down++; ! statusbar_msg(_("Error searching below '%1$s': %2$s"), ! enc_searchbase, ldap_err2string(rc)); ! /* close_connection(server, FALSE); */ ! /* SEARCHTAB(tab)->search_lock = 0; */ ! /* return; */ ! goto cont; ! } ! ! for (rc = 1 ; rc ; ) { ! int code = ldap_result(ld, msg, 0, NULL, &res); ! if (code == -1) { ! /* error */ ! s... [truncated message content] |