Thread: [gq-commit] gq/src dn-browse.c,NONE,1.1 dn-browse.h,NONE,1.1 ref-browse.c,NONE,1.1 ref-browse.h,NONE
Status: Beta
Brought to you by:
sur5r
Update of /cvsroot/gqclient/gq/src In directory sc8-pr-cvs1:/tmp/cvs-serv2319 Modified Files: Makefile.am browse.c browse.h browse-dnd.c Added Files: dn-browse.c dn-browse.h ref-browse.c ref-browse.h server-browse.c server-browse.h Log Message: * Split browse.c into 4 files: browse.c, dn-browse.c, server-browse.c and ref-browse.c (browse.c was > 70K and more than 2k lines) * Added browse-entry specific context menus * Improved referral handling --- NEW FILE: dn-browse.c --- /* 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 the additional exemption that compiling, linking, and/or using OpenSSL is allowed. 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 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 */ /* $Id: dn-browse.c,v 1.1 2003/10/17 07:26:25 stamfest Exp $ */ #include <glib.h> #include <gtk/gtk.h> #include <string.h> #include <errno.h> /* errno */ #include <stdio.h> /* FILE */ #include <stdlib.h> /* free - MUST get rid of malloc/free */ #include "config.h" #include "common.h" #include "dn-browse.h" #include "ref-browse.h" #include "input.h" /* new_from_entry */ #include "search.h" /* fill_out_search */ #include "template.h" /* struct gq_template */ #include "formfill.h" /* formlist_from_entry */ #include "tinput.h" /* formfill_from_template */ #include "browse-dnd.h" /* copy_entry et al */ #include "configfile.h" /* config */ #include "errorchain.h" #include "util.h" #include "i18n.h" #include "utf8-compat.h" #include "ldif.h" static void tree_row_search_below(GtkMenuItem *menuitem, struct tab *tab) { GtkCTree *ctree; GtkCTreeNode *node; browse_entry *e; struct ldapserver *server; struct tab *search_tab; ctree = BROWSETAB(tab)->ctreeroot; node = BROWSETAB(tab)->tree_row_popped_up; e = (browse_entry *) gtk_ctree_node_get_row_data(ctree, node); assert(IS_DN_ENTRY(e)); server = server_from_node(ctree, node); if (e == NULL || server == NULL) return; search_tab = get_last_of_mode(SEARCH_MODE); if (!search_tab) { new_modetab(&mainwin, SEARCH_MODE); search_tab = get_last_of_mode(SEARCH_MODE); } if (search_tab) { #if GTK_MAJOR >= 2 fill_out_search(search_tab, server, ((dn_browse_entry *)e)->dn); #else char *dn_dec = decoded_string(((dn_browse_entry *)e)->dn); fill_out_search(search_tab, server, dn_dec); if (dn_dec) free(dn_dec); #endif } } static GtkCTreeNode *ref_browse_single_add(const char *uri, GtkCTree *ctree, GtkCTreeNode *node) { const char *labels[] = { NULL, NULL }; char *dummy[] = { "dummy", NULL }; ref_browse_entry *new_entry; GtkCTreeNode *new_item, *added = NULL; new_entry = (ref_browse_entry *) new_ref_browse_entry(uri); labels[0] = uri; added = gtk_ctree_insert_node(ctree, node, NULL, (char**) labels, /* bug in the GTK2 API: should be const */ 0, NULL, NULL, NULL, NULL, FALSE, FALSE); gtk_ctree_node_set_row_data_full(ctree, added, new_entry, (GtkDestroyNotify) destroy_browse_entry); /* add dummy node */ new_item = gtk_ctree_insert_node(ctree, added, NULL, dummy, 0, NULL, NULL, NULL, NULL, TRUE, FALSE); return added; } static void browse_new_from_entry_callback(GtkMenuItem *widget, dn_browse_entry *entry) { if (IS_DN_ENTRY(entry)) { char *dn = entry->dn; struct ldapserver *server = (struct ldapserver *) gtk_object_get_data(GTK_OBJECT(widget), "server"); new_from_entry(server, dn); } } static void browse_new_from_template_callback(GtkWidget *widget, struct gq_template *template) { #ifdef HAVE_LDAP_STR2OBJECTCLASS GList *formlist; struct ldapserver *server; struct inputform *iform; dn_browse_entry *entry; server = (struct ldapserver *) gtk_object_get_data(GTK_OBJECT(widget), "server"); entry = (dn_browse_entry *) gtk_object_get_data(GTK_OBJECT(widget), "entry"); if (!IS_DN_ENTRY(entry)) return; iform = new_inputform(); iform->dn = NULL; iform->server = server; formlist = formfill_from_template(server, template); if(formlist) { iform->formlist = formlist; if (entry && entry->dn) { /* don't need the RDN of the current entry */ char *newdn = g_malloc(strlen(entry->dn) + 2); newdn[0] = ','; newdn[1] = 0; strcat(newdn, entry->dn); iform->dn = newdn; } create_form_window(iform); create_form_content(iform); build_inputform(iform); } else { free_inputform(iform); } #endif /* HAVE_LDAP_STR2OBJECTCLASS */ } static void dump_subtree_ok_callback(GtkWidget *button, GtkWidget *filesel) { LDAPMessage *res = NULL, *e; LDAP *ld = NULL; GList *bases, *I; struct ldapserver *server; browse_entry *entry; int msg, num_entries; const char *filename; FILE *outfile = NULL; GString *out = NULL; GString *gmessage = NULL; /* GString *bigmessage = NULL; */ int written; int ctx; entry = gtk_object_get_data(GTK_OBJECT(filesel), "entry"); server = gtk_object_get_data(GTK_OBJECT(filesel), "server"); out = g_string_sized_new(2048); bases = NULL; /* if (IS_SERVER_ENTRY(entry)) { */ /* bases = get_suffixes(((server_browse_entry *)entry)->server); */ /* } else { */ bases = g_list_append(bases, strdup(((dn_browse_entry *)entry)->dn)); /* } */ ctx = error_new_context(_("Dump subtree")); if(g_list_length(bases) == 0) { error_push(ctx, _("Nothing to dump!")); goto fail; } set_busycursor(); /* obtain filename and open file for reading */ filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(filesel)); if( (outfile = fopen(filename, "w")) == NULL) { error_push(ctx, _("Could not open output file: %s"), strerror(errno)); goto fail; /* error_popup(_("Save failed"), strerror(errno)); */ } else { /* AFAIK, the UMich LDIF format doesn't take comments or a version string */ if (config->ldifformat != LDIF_UMICH) { g_string_truncate(out, 0); prepend_ldif_header(out, server, bases); written = fwrite(out->str, 1, out->len, outfile); if(written != out->len) { error_push(ctx, _("Save failed: Only %1$d of %2$d bytes written"), written, out->len); goto fail; /* sometimes goto is useful */ } } if( (ld = open_connection(server)) == NULL) { /* no extra error, open_connection does error reporting itself... */ goto fail; } num_entries = 0; 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); ldif_entry_out(out, ld, e, ctx); num_entries++; written = fwrite(out->str, 1, out->len, outfile); if(written != out->len) { g_string_sprintf(gmessage, _("%1$d of %2$d bytes written"), written, out->len); error_popup(_("Save failed"), gmessage->str); ldap_msgfree(res); close_connection(server, FALSE); goto fail; } } ldap_msgfree(res); } else if (msg == LDAP_SERVER_DOWN) { server->server_down++; ldap_msgfree(res); /* is this correct? */ error_push(ctx, _("Server down. Export may be incomplete!")); push_ldap_addl_error(ld, ctx); goto fail; } else { /* report error */ error_push(ctx, _("LDAP error. Export may be incomplete!")); push_ldap_addl_error(ld, ctx); /* statusbar_msg(ldap_err2string(ldap_result2error(ld, */ /* res, 1))); */ goto fail; } } statusbar_msg(ngettext("One entry exported to %2$s", "%1$d entries exported to %2$s", num_entries), num_entries, filename); } fail: /* labels are only good for cleaning up, really */ if (outfile) fclose(outfile); if (bases) { for (I = g_list_first(bases) ; I ; I = g_list_next(I)) { free(I->data); } g_list_free(bases); } set_normalcursor(); if (out) g_string_free(out, TRUE); if (gmessage) g_string_free(gmessage, TRUE); if (ld) close_connection(server, FALSE); gtk_widget_destroy(filesel); error_flush(ctx); } static void dump_subtree(GtkWidget *widget, struct tab *tab) { GtkWidget *filesel; GtkCTree *ctree; GtkCTreeNode *ctree_node; browse_entry *entry; struct ldapserver *server; ctree = BROWSETAB(tab)->ctreeroot; ctree_node = BROWSETAB(tab)->selected_ctree_node; entry = (browse_entry *) gtk_ctree_node_get_row_data(ctree, ctree_node); if (entry == NULL) return; if ((server = server_from_node(ctree, ctree_node)) == NULL) return; 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); gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "clicked", (GtkSignalFunc) dump_subtree_ok_callback, filesel); gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button), "clicked", (GtkSignalFunc) gtk_widget_destroy, GTK_OBJECT(filesel)); gtk_signal_connect_object(GTK_OBJECT(filesel), "key_press_event", (GtkSignalFunc) close_on_esc, (gpointer) filesel); gtk_widget_show(filesel); } static void delete_browse_entry(GtkWidget *widget, struct tab *tab) { GtkCTree *ctree; GtkCTreeNode *node; struct ldapserver *server; dn_browse_entry *entry; int do_delete; ctree = BROWSETAB(tab)->ctreeroot; node = BROWSETAB(tab)->selected_ctree_node; entry = (dn_browse_entry *) gtk_ctree_node_get_row_data(ctree, node); if (entry == NULL) return; if ((server = server_from_node(ctree, node)) == NULL) return; do_delete = 0; gtk_clist_freeze(GTK_CLIST(ctree)); if (!entry->seen) { /* toggle expansion twice to fire the expand callback */ gtk_ctree_toggle_expansion(ctree, node); gtk_ctree_toggle_expansion(ctree, node); } if (entry->leaf) { /* item is a leaf node */ do_delete = 1; } else { /* maybe delete everything in the subtree as well? should do another LDAP_SCOPE_SUBTREE search after each batch of deletes, in case the server is limiting the number of entries returned per search. This could get hairy... For now, just pop up a dialog box with a warning */ do_delete = question_popup(_("Warning"), _("This entry has a subtree!\n" "Do you want to delete every entry under it as well?")); } if (do_delete) { if (delete_entry_full(server, entry->dn, TRUE)) { browse_entry *p_entry; GtkCTreeNode *parent = GTK_CTREE_ROW(node)->parent; gtk_ctree_remove_node(ctree, node); /* the only thing left to do is to refresh the parent node in order to get the leaf flag of that entry right again */ p_entry = (browse_entry *) gtk_ctree_node_get_row_data(ctree, parent); if (p_entry) { assert(p_entry->base_methods); if (p_entry->base_methods->refresh) p_entry->base_methods->refresh(p_entry, ctree, parent, tab); } } } gtk_clist_thaw(GTK_CLIST(ctree)); } /* * Destructor for dn_browse_entry objects */ static void destroy_dn_browse_entry(dn_browse_entry *entry) { if (!entry) return; if (entry->dn) g_free(entry->dn); free(entry); } static void dn_browse_entry_expand(dn_browse_entry *entry, GtkCTree *ctree, GtkCTreeNode *node, struct tab *tab) { LDAP *ld = NULL; LDAPMessage *res = NULL, *e; struct ldapserver *server = NULL; int msg, rc, num_children, update_counter, err; char message[MAX_DN_LEN + 21]; char *dummy[] = { "dummy", NULL }; char *ref[] = { "ref", NULL }; char *c, **refs; int context = error_new_context(_("Expand entry")); assert(IS_DN_ENTRY(entry)); if (!entry->seen) { server = server_from_node(ctree, node); /* printf("server=%08lx host=%s dn=%s\n", (long) server, */ /* server->ldaphost, */ /* entry->dn); */ gtk_clist_freeze(GTK_CLIST(ctree)); while (GTK_CTREE_ROW(node)->children) { gtk_ctree_remove_node(ctree, GTK_CTREE_ROW(node)->children); } if( (ld = open_connection(server)) == NULL) { gtk_clist_thaw(GTK_CLIST(ctree)); error_flush(context); return; } #if HAVE_LDAP_CLIENT_CACHE if (entry->uncache) { ldap_uncache_entry(ld, entry->dn); entry->uncache = FALSE; } #endif #if GTK_MAJOR < 2 statusbar_msg(_("Onelevel search on %s"), c = decoded_string(entry->dn)); if (c) free(c); #else statusbar_msg(_("Onelevel search on %s"), entry->dn); #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("%s", ldap_err2string(msg)); close_connection(server, FALSE); gtk_clist_thaw(GTK_CLIST(ctree)); error_flush(context); return; } num_children = update_counter = 0; 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 *dn = ldap_get_dn(ld, e); dn_browse_single_add(dn, ctree, node); free(dn); num_children++; update_counter++; if(update_counter >= 100) { statusbar_msg(ngettext("One entry found (running)", "%d entries found (running)", num_children), num_children); update_counter = 0; } } ldap_msgfree(res); } entry->leaf = (num_children == 0); snprintf(message, sizeof(message), ngettext("One entry found (finished)", "%d entries found (finished)", num_children), num_children); ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &rc); if (rc == LDAP_SERVER_DOWN) { server->server_down++; gtk_clist_thaw(GTK_CLIST(ctree)); goto done; } if (res) { rc = ldap_parse_result(ld, res, &err, &c, NULL, &refs, NULL, 0); } if (rc != LDAP_SUCCESS) { error_push(context, ldap_err2string(rc)); push_ldap_addl_error(ld, context); if (rc == LDAP_SERVER_DOWN) { server->server_down++; } } else { if (err == LDAP_SIZELIMIT_EXCEEDED) { int l = strlen(message); snprintf(message + l, sizeof(message) - l, " - %s", _("size limit exceeded")); } else if (err == LDAP_TIMELIMIT_EXCEEDED) { int l = strlen(message); snprintf(message + l, sizeof(message) - l, " - %s", _("time limit exceeded")); } else if (err != LDAP_SUCCESS) { error_push(context, ldap_err2string(err)); push_ldap_addl_error(ld, context); if (c && strlen(c)) { error_push(context, _("Matched DN: %s"), c); } if (refs) { int i; for (i = 0 ; refs[i] ; i++) { error_push(context, _("Referral to: %s"), refs[i]); } } } } statusbar_msg(message); gtk_clist_thaw(GTK_CLIST(ctree)); entry->seen = TRUE; } /* XXX the code that sets this is #if0'ed, so this is dead code... if (g_hash_table_lookup(hash, "expand-all")) { GtkCTreeNode *n; gtk_clist_freeze(GTK_CLIST(ctree)); for (n = GTK_CTREE_ROW(node)->children ; n ; n = GTK_CTREE_NODE_NEXT(n)) { gtk_ctree_expand(ctree, n); } gtk_clist_thaw(GTK_CLIST(ctree)); } */ error_flush(context); done: if (res) ldap_msgfree(res); if (server && ld) close_connection(server, FALSE); } static void browse_edit_from_entry(dn_browse_entry *entry, GtkCTree *ctreeroot, GtkCTreeNode *ctreenode, struct tab *tab) { GList *oldlist, *newlist, *tmplist; GtkWidget *pane2_scrwin, *pane2_vbox; struct ldapserver *server; struct inputform *iform; char *dn; int hidden = 0; assert(IS_DN_ENTRY(entry)); if (ctreenode == NULL) return; if( (server = server_from_node(ctreeroot, ctreenode)) == NULL) return; dn = entry->dn; record_path(tab, (browse_entry *) entry, ctreeroot, ctreenode); ctreeroot = BROWSETAB(tab)->ctreeroot; /* delete old struct inputform (if any) */ iform = BROWSETAB(tab)->inputform; if(iform) { /* but first get current hide status */ hidden = iform->hide_status; inputform_free(iform); } iform = new_inputform(); BROWSETAB(tab)->inputform = iform; iform->server = server; iform->edit = 1; /* pass on "hide" status */ iform->hide_status = hidden; tmplist = NULL; oldlist = formlist_from_entry(server, dn, 0); #ifdef HAVE_LDAP_STR2OBJECTCLASS oldlist = add_schema_attrs(server, oldlist); #endif if(oldlist) { iform->oldlist = oldlist; newlist = dup_formlist(oldlist); iform->formlist = newlist; iform->olddn = g_strdup(dn); iform->dn = g_strdup(dn); if (ctreeroot) { iform->ctreeroot = ctreeroot; iform->ctree_refresh = GTK_CTREE_ROW(ctreenode)->parent; } /* XXX should free etc first */ pane2_scrwin = BROWSETAB(tab)->pane2_scrwin; gtk_container_remove(GTK_CONTAINER(pane2_scrwin), GTK_BIN(pane2_scrwin)->child); pane2_vbox = gtk_vbox_new(FALSE, 2); iform->target_vbox = pane2_vbox; BROWSETAB(tab)->pane2_vbox = pane2_vbox; gtk_widget_show(pane2_vbox); gtk_widget_set_parent_window(pane2_vbox, (mainwin.mainwin->window)); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(pane2_scrwin), pane2_vbox); create_form_content(iform); build_inputform(iform); } else { inputform_free(iform); BROWSETAB(tab)->inputform = NULL; } } static void dn_browse_entry_refresh(dn_browse_entry *entry, GtkCTree *ctree, GtkCTreeNode *node, struct tab *tab) { refresh_subtree(ctree, node); entry->base_methods->select((browse_entry *) entry, ctree, node, tab); } static char* dn_browse_entry_get_name(dn_browse_entry *entry, gboolean long_form) { char **exploded_dn; char *g; #if GTK_MAJOR < 2 char *l; #endif assert(IS_DN_ENTRY(entry)); if (long_form) { return g_strdup(entry->dn); } else { exploded_dn = gq_ldap_explode_dn(entry->dn, FALSE); #if GTK_MAJOR >= 2 g = g_strdup(exploded_dn[0]); #else l = decoded_string(exploded_dn[0]); /* impedance match -> malloc to g_malloc */ g = g_strdup(l); free(l); #endif gq_exploded_free(exploded_dn); return g; } } static void dn_browse_entry_popup(dn_browse_entry *entry, GtkWidget *menu, GtkWidget *ctreeroot, GtkCTreeNode *ctree_node, struct tab *tab) { GtkWidget *menu_item, *submenu; struct ldapserver *server; int is_dn; #ifdef HAVE_LDAP_STR2OBJECTCLASS GList *templatelist; struct gq_template *template; #endif assert(IS_DN_ENTRY(entry)); is_dn = IS_DN_ENTRY(entry); if ((server = server_from_node(GTK_CTREE(ctreeroot), ctree_node)) == NULL) return; /* New submenu */ menu_item = gtk_menu_item_new_with_label(_("New")); gtk_menu_append(GTK_MENU(menu), menu_item); submenu = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu); gtk_widget_show(menu_item); #ifdef HAVE_LDAP_STR2OBJECTCLASS templatelist = config->templates; while(templatelist) { 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); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(browse_new_from_template_callback), (gpointer) template); gtk_widget_show(menu_item); templatelist = templatelist->next; } #endif menu_item = gtk_menu_item_new_with_label(_("Use current entry")); gtk_object_set_data(GTK_OBJECT(menu_item), "server", server); gtk_menu_append(GTK_MENU(submenu), menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(browse_new_from_entry_callback), (gpointer) entry); gtk_widget_show(menu_item); #if 0 /* Expand all */ menu_item = gtk_menu_item_new_with_label(_("Expand all")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(tree_row_expand_all), (gpointer) tab); #endif #if 0 /* moved to server_browse_entry only. Just a clean-up of the menu, no technical reasons, just policy. */ /* Close connection */ menu_item = gtk_menu_item_new_with_label(_("Close Connection")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(tree_row_close_connection), (gpointer) tab); #endif /* Export to LDIF */ menu_item = gtk_menu_item_new_with_label(_("Export to LDIF")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(dump_subtree), (gpointer) tab); gtk_widget_show(menu_item); menu_item = gtk_menu_item_new(); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); /* Search below */ menu_item = gtk_menu_item_new_with_label(_("Search below")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(tree_row_search_below), (gpointer) tab); gtk_widget_show(menu_item); menu_item = gtk_menu_item_new(); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); #ifdef BROWSER_DND /* Copy */ menu_item = gtk_menu_item_new_with_label(_("Copy")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", (GtkSignalFunc) copy_entry, (gpointer) tab); if (!is_dn) { gtk_widget_set_sensitive(menu_item, FALSE); } gtk_widget_show(menu_item); /* Copy all */ menu_item = gtk_menu_item_new_with_label(_("Copy all")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", (GtkSignalFunc) copy_entry_all, (gpointer) tab); if (!is_dn) { gtk_widget_set_sensitive(menu_item, FALSE); } gtk_widget_show(menu_item); /* Paste */ menu_item = gtk_menu_item_new_with_label(_("Paste")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", (GtkSignalFunc) paste_entry, (gpointer) tab); if (!is_dn) { gtk_widget_set_sensitive(menu_item, FALSE); } gtk_widget_show(menu_item); menu_item = gtk_menu_item_new(); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); #endif /* Delete */ menu_item = gtk_menu_item_new_with_label(_("Delete")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", (GtkSignalFunc) delete_browse_entry, (gpointer) tab); if (!is_dn) { gtk_widget_set_sensitive(menu_item, FALSE); } gtk_widget_show(menu_item); } static struct browse_entry_vtab dn_vtab = { (browse_entry_destructor) destroy_dn_browse_entry, /* destroy */ (browse_entry_expand) dn_browse_entry_expand, /* expand */ (browse_entry_select) browse_edit_from_entry, /* select */ (browse_entry_refresh) dn_browse_entry_refresh, /* refresh */ (browse_entry_get_name) dn_browse_entry_get_name, /* get_name */ (browse_entry_popup) dn_browse_entry_popup, /* popup */ }; /* * Constructor for dn_browse_entry objects taking the dn */ browse_entry *new_dn_browse_entry(const char *dn) { dn_browse_entry *e; e = g_malloc0(sizeof(dn_browse_entry)); e->type = DN_BROWSE_ENTRY; e->base_methods = &dn_vtab; if (dn != NULL) e->dn = g_strdup(dn); e->seen = FALSE; e->leaf = FALSE; return (browse_entry *) e; } /* Local Variables: c-basic-offset: 5 End: */ --- NEW FILE: dn-browse.h --- /* 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 the additional exemption that compiling, linking, and/or using OpenSSL is allowed. 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 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 */ /* $Id: dn-browse.h,v 1.1 2003/10/17 07:26:25 stamfest Exp $ */ #ifndef GQ_DN_BROWSE_H_INCLUDED #define GQ_DN_BROWSE_H_INCLUDED #include "config.h" #include "browse.h" /**************************************************************************/ /* * A browse_entry describing a singe DN (eg. a single LDAP object) */ #define DN_BROWSE_ENTRY 1 typedef struct { /* common */ int type; struct browse_entry_vtab *base_methods; /* specific */ char *dn; gboolean seen; gboolean leaf; gboolean uncache; gboolean is_ref; /* set if this entry is a referral and children of it should thus become ref_browse_entry objects */ } dn_browse_entry; #define IS_DN_ENTRY(entry) IS_ENTRY((entry), DN_BROWSE_ENTRY) browse_entry *new_dn_browse_entry(const char *dn); #endif /* Local Variables: c-basic-offset: 5 End: */ --- NEW FILE: ref-browse.c --- /* 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 the additional exemption that compiling, linking, and/or using OpenSSL is allowed. 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 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 */ /* $Id: ref-browse.c,v 1.1 2003/10/17 07:26:25 stamfest Exp $ */ #include <glib.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #include <errno.h> #include <string.h> #include <config.h> #include "common.h" #include "dn-browse.h" #include "server-browse.h" #include "ref-browse.h" #include "configfile.h" /* free_ldapserver */ #include "prefs.h" /* create_edit_server_window */ #include "util.h" #include "i18n.h" #include "errorchain.h" /**************************************************************************/ static void free_ref_browse_entry(ref_browse_entry *entry) { if (!entry) return; assert(IS_REF_ENTRY(entry)); g_free_if(entry->uri); if (entry->server) { free_ldapserver(entry->server); entry->server = NULL; } g_free(entry); } /* * a ref browse entry was selected in the tree widget. * * put up some info. */ static void ref_browse_entry_selected(ref_browse_entry *entry, GtkCTree *ctree, GtkCTreeNode *node, struct tab *tab) { GtkWidget *pane2_scrwin, *pane2_vbox, *label, *e; GtkWidget *table; int row = 0; assert(IS_REF_ENTRY(entry)); record_path(tab, (browse_entry *) entry, ctree, node); pane2_scrwin = BROWSETAB(tab)->pane2_scrwin; pane2_vbox = BROWSETAB(tab)->pane2_vbox; /* gtk_widget_destroy(pane2_vbox); */ /* remove the viewport of the scrolled window. This should _really_ destroy the widgets below it. The pane2_scrwin is a GtkBin Object and thus has only one child, use this to obtain the viewport */ gtk_container_remove(GTK_CONTAINER(pane2_scrwin), GTK_BIN(pane2_scrwin)->child); pane2_vbox = gtk_vbox_new(FALSE, 2); BROWSETAB(tab)->pane2_vbox = pane2_vbox; gtk_widget_show(pane2_vbox); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(pane2_scrwin), pane2_vbox); table = gtk_table_new(5, 2, FALSE); gtk_container_border_width(GTK_CONTAINER(table), 5); gtk_widget_show(table); gtk_box_pack_start(GTK_BOX(pane2_vbox), table, FALSE, FALSE, 5); /* URI */ label = gtk_label_new(_("Referral URI")); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), entry->uri); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; } static void ref_browse_entry_expand(ref_browse_entry *entry, GtkCTree *ctree, GtkCTreeNode *node, struct tab *tab) { if (!entry->expanded) { LDAPURLDesc *desc = NULL; while (GTK_CTREE_ROW(node)->children) { gtk_ctree_remove_node(ctree, GTK_CTREE_ROW(node)->children); } if (ldap_url_parse(entry->uri, &desc) == 0) { const char *labels[] = { desc->lud_dn, NULL }; char *dummy[] = { "dummy", NULL }; struct ldapserver *server, *newserver; GtkCTreeNode *new_item, *added = NULL; browse_entry *new_entry; GString *new_uri = g_string_sized_new(strlen(entry->uri)); 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; /* check: do we have this server around already??? */ server = server_by_canon_name(new_uri->str); if (!server) { /* find parent server */ GtkCTreeRow *row = NULL; GtkCTreeNode *n; browse_entry *e; n = GTK_CTREE_ROW(node)->parent; for ( ; n ; n = row->parent ) { row = GTK_CTREE_ROW(n); e = (browse_entry *) gtk_ctree_node_get_row_data(ctree, n); /* FIXME: This is not OO */ if (IS_SERVER_ENTRY(e)) { server = ((server_browse_entry*) e)->server; break; } if (IS_REF_ENTRY(e)) { server = ((ref_browse_entry*) e)->server; break; } } } if (server) { copy_ldapserver(newserver, server); 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); canonicalize_ldapserver(newserver); entry->server = newserver; entry->expanded = TRUE; gtk_clist_freeze(GTK_CLIST(ctree)); new_entry = new_dn_browse_entry(desc->lud_dn); added = gtk_ctree_insert_node(ctree, node, NULL, (char**) labels, /* bug in the GTK2 API: should be const */ 0, NULL, NULL, NULL, NULL, FALSE, FALSE); gtk_ctree_node_set_row_data_full(ctree, added, new_entry, (GtkDestroyNotify) destroy_browse_entry); /* add dummy node */ new_item = gtk_ctree_insert_node(ctree, added, NULL, dummy, 0, NULL, NULL, NULL, NULL, TRUE, FALSE); gtk_clist_thaw(GTK_CLIST(ctree)); ldap_free_urldesc(desc); } } } char* ref_browse_entry_get_name(ref_browse_entry *entry, gboolean long_form) { char *g; #if GTK_MAJOR < 2 char *l; #endif assert(IS_REF_ENTRY(entry)); #if GTK_MAJOR >= 2 g = g_strdup(entry->uri); #else l = decoded_string(entry->uri); /* impedance match -> malloc to g_malloc */ g = g_strdup(l); free(l); #endif return g; } static void ref_browse_entry_refresh(ref_browse_entry *entry, GtkCTree *ctree, GtkCTreeNode *node, struct tab *tab) { assert(IS_REF_ENTRY(entry)); entry->expanded = 0; gtk_clist_freeze(GTK_CLIST(ctree)); ref_browse_entry_selected(entry, ctree, node, tab); /* toggle expansion twice to fire the expand callback and to return to the current expansion state */ gtk_ctree_toggle_expansion(ctree, node); gtk_ctree_toggle_expansion(ctree, node); /* server_browse_entry_expand(entry, ctree, node, tab); */ gtk_clist_thaw(GTK_CLIST(ctree)); } static void add_to_permanent_servers(struct ldapserver *server) { /* no assertion, it could happen... */ if (is_transient_server(server)) { if (server_by_name(server->name) == NULL) { struct ldapserver *s = new_ldapserver(); copy_ldapserver(s, server); config_add_server(config, s); update_serverlist(&mainwin); save_config(); } else { int ctx = error_new_context(_("Adding server permanently")); error_push(ctx, _("Another server with this name already exists.")); /* popup error */ error_flush(ctx); } } } /* popup method for BOTH server AND ref entries (the same for now...) */ static void ref_browse_entry_popup(dn_browse_entry *entry, GtkWidget *menu, GtkWidget *ctreeroot, GtkCTreeNode *ctree_node, struct tab *tab) { GtkWidget *menu_item; struct ldapserver *server; assert(IS_REF_ENTRY(entry)); server = server_from_node(GTK_CTREE(ctreeroot), ctree_node); /* Edit Server settings */ menu_item = gtk_menu_item_new_with_label(_("Edit Server")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); gtk_signal_connect_object(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(create_edit_server_window), (gpointer) server); gtk_widget_show(menu_item); if (server == NULL) { gtk_widget_set_sensitive(menu_item, FALSE); } /* Add to permanent list of servers */ menu_item = gtk_menu_item_new_with_label(_("Add to permanent list of servers")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); gtk_signal_connect_object(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(add_to_permanent_servers), (gpointer) server); gtk_widget_show(menu_item); if (server == NULL || !is_transient_server(server)) { gtk_widget_set_sensitive(menu_item, FALSE); } /* Close connection */ menu_item = gtk_menu_item_new_with_label(_("Close Connection")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(tree_row_close_connection), (gpointer) tab); gtk_widget_show(menu_item); if (server == NULL) { gtk_widget_set_sensitive(menu_item, FALSE); } } static struct browse_entry_vtab ref_vtab = { (browse_entry_destructor) free_ref_browse_entry, /* destroy */ (browse_entry_expand) ref_browse_entry_expand, /* expand */ (browse_entry_select) ref_browse_entry_selected, /* select */ (browse_entry_refresh) ref_browse_entry_refresh, /* refresh */ (browse_entry_get_name) ref_browse_entry_get_name, /* get_name */ (browse_entry_popup) ref_browse_entry_popup, /* popup */ }; browse_entry *new_ref_browse_entry(const char *uri) { ref_browse_entry *e; e = g_malloc0(sizeof(ref_browse_entry)); e->type = REF_BROWSE_ENTRY; e->base_methods = &ref_vtab; /* e->server = server; */ e->uri = g_strdup(uri); return (browse_entry *) e; } /* Local Variables: c-basic-offset: 5 End: */ --- NEW FILE: ref-browse.h --- /* 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 the additional exemption that compiling, linking, and/or using OpenSSL is allowed. 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 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 */ /* $Id: ref-browse.h,v 1.1 2003/10/17 07:26:25 stamfest Exp $ */ #ifndef GQ_REF_BROWSE_H_INCLUDED #define GQ_REF_BROWSE_H_INCLUDED #include "config.h" #include "browse.h" /**************************************************************************/ /* * A browse_entry object describing a dynamic LDAP server (referral) */ #define REF_BROWSE_ENTRY 3 typedef struct { /* common */ int type; struct browse_entry_vtab *base_methods; /* specific */ char *uri; struct ldapserver *server; gboolean expanded; } ref_browse_entry; #define IS_REF_ENTRY(entry) IS_ENTRY((entry), REF_BROWSE_ENTRY) browse_entry *new_ref_browse_entry(const char *uri); #endif /* Local Variables: c-basic-offset: 5 End: */ --- NEW FILE: server-browse.c --- /* 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 the additional exemption that compiling, linking, and/or using OpenSSL is allowed. 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 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 */ /* $Id: server-browse.c,v 1.1 2003/10/17 07:26:25 stamfest Exp $ */ #include <glib.h> #include <gtk/gtk.h> #include <errno.h> #include <string.h> #include <stdio.h> /* snprintf */ #include <config.h> #include "server-browse.h" #include "dn-browse.h" #include "prefs.h" /* create_edit_server_window */ #include "util.h" /* get_suffixes */ #include "i18n.h" #ifdef BROWSER_DND #include "browse-dnd.h" #endif /* #include "../icons/warning.xpm" */ /* * Really add a single suffix to the tree */ void add_suffix(server_browse_entry *entry, GtkCTree *ctreeroot, GtkCTreeNode *node, char *suffix) { GtkCTreeNode *new_item; char *labels[] = { suffix, NULL }; browse_entry *new_entry = new_dn_browse_entry(suffix); new_item = gtk_ctree_insert_node(ctreeroot, node, NULL, labels, 0, NULL, NULL, NULL, NULL, FALSE, FALSE); gtk_ctree_node_set_row_data_full(ctreeroot, new_item, new_entry, (GtkDestroyNotify) destroy_browse_entry); /* add dummy node to have something to expand */ labels[0] = "DUMMY"; new_item = gtk_ctree_insert_node(ctreeroot, new_item, NULL, labels, 0, NULL, NULL, NULL, NULL, TRUE, FALSE); } static void server_browse_entry_expand(server_browse_entry *entry, GtkCTree *ctree, GtkCTreeNode *node, struct tab *tab) { GList *suffixes = NULL, *next; assert(IS_SERVER_ENTRY(entry)); if (!entry->once_expanded) { /* printf("expanding %s\n", entry->server->name); */ while (GTK_CTREE_ROW(node)->children) { gtk_ctree_remove_node(ctree, GTK_CTREE_ROW(node)->children); } entry->once_expanded = 1; suffixes = get_suffixes(entry->server); gtk_clist_freeze(GTK_CLIST(ctree)); for (next = suffixes ; next ; next = g_list_next(next) ) { add_suffix(entry, ctree, node, next->data); g_free(next->data); next->data = NULL; } gtk_clist_thaw(GTK_CLIST(ctree)); g_list_free(suffixes); } } /* * a server was selected in the tree widget. * * put up some server info. */ static void server_browse_entry_selected(server_browse_entry *entry, GtkCTree *ctree, GtkCTreeNode *node, struct tab *tab) { GtkWidget *pane2_scrwin, *pane2_vbox, *label, *e; GtkWidget *table; char *server_name; int row = 0; char buf[128]; LDAP *ld; assert(IS_SERVER_ENTRY(entry)); ld = open_connection(entry->server); server_name = entry->server->name; /* dn_by_node(node); */ record_path(tab, (browse_entry *) entry, ctree, node); pane2_scrwin = BROWSETAB(tab)->pane2_scrwin; pane2_vbox = BROWSETAB(tab)->pane2_vbox; /* gtk_widget_destroy(pane2_vbox); */ /* remove the viewport of the scrolled window. This should _really_ destroy the widgets below it. The pane2_scrwin is a GtkBin Object and thus has only one child, use this to obtain the viewport */ gtk_container_remove(GTK_CONTAINER(pane2_scrwin), GTK_BIN(pane2_scrwin)->child); pane2_vbox = gtk_vbox_new(FALSE, 2); BROWSETAB(tab)->pane2_vbox = pane2_vbox; gtk_widget_show(pane2_vbox); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(pane2_scrwin), pane2_vbox); table = gtk_table_new(5, 2, FALSE); gtk_container_border_width(GTK_CONTAINER(table), 5); gtk_widget_show(table); gtk_box_pack_start(GTK_BOX(pane2_vbox), table, FALSE, FALSE, 5); /* Nickname */ label = gtk_label_new(_("Nickname")); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), server_name); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; /* Host name */ label = gtk_label_new(_("Hostname")); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), entry->server->ldaphost); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; /* Port */ label = gtk_label_new(_("Port")); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); snprintf(buf, sizeof(buf), "%d", entry->server->ldapport); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), buf); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; /* Connection caching */ label = gtk_label_new(_("Connection caching")); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); snprintf(buf, sizeof(buf), "%s", entry->server->cacheconn ? _("on") : _("off")); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), buf); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; /* TLS */ label = gtk_label_new(_("TLS")); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); snprintf(buf, sizeof(buf), "%s", entry->server->enabletls ? _("on") : _("off")); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), buf); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; #if HAVE_LDAP_CLIENT_CACHE label = gtk_label_new(_("Client-side caching")); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); snprintf(buf, sizeof(buf), "%s", (entry->server->local_cache_timeout >= 0) ? _("on") : _("off")); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), buf); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; #endif /* Connections so far */ label = gtk_label_new(_("Connections so far")); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); snprintf(buf, sizeof(buf), "%d", entry->server->incarnation); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), buf); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; if (ld) { int intdata; int rc; /* void *optdata; */ char *rootDSEattr[] = { "vendorName", _("Vendor Name"), /* RFC 3045 */ "vendorVersion", _("Vendor Version"), /* RFC 3045 */ "altServer", _("Alternative Server(s)"), /* RFC 2251 */ "supportedLDAPVersion", _("Supported LDAP Version"), /* RFC 2251 */ "supportedSASLMechanisms", _("Supported SASL Mechanisms"), /* RFC 2251 */ NULL }; LDAPMessage *res, *ee; BerElement *berptr; char *attr; char **vals; int i, msg; rc = ldap_get_option(ld, LDAP_OPT_PROTOCOL_VERSION, &intdata); /* LDAP protocol version */ label = gtk_label_new(_("LDAP protocol version")); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); snprintf(buf, sizeof(buf), "%d", intdata); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), buf); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; /* read some Information from the root DSE */ for (i = 0 ; rootDSEattr[i] && ld != NULL ; i += 2) { char *attrs[2] = { rootDSEattr[i], NULL }; msg = ldap_search_s(ld, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &res); if(msg != LDAP_SUCCESS) { if (msg == LDAP_SERVER_DOWN) { close_connection(entry->server, FALSE); ld = open_connection(entry->server); } statusbar_msg("%s", ldap_err2string(msg)); } else { if(res == NULL) continue; ee = ldap_first_entry(ld, res); if (ee == NULL) { ldap_msgfree(res); continue; } attr = ldap_first_attribute(ld, res, &berptr); if (attr == NULL) { ldap_msgfree(res); #ifndef HAVE_OPENLDAP_12 if(berptr) ber_free(berptr, 0); #endif continue; } vals = ldap_get_values(ld, res, attr); if (vals) { int j; for (j = 0 ; vals[j] ; j++) ; label = gtk_label_new(rootDSEattr[i + 1]); gtk_widget_show(label); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+j, GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); for (j = 0 ; vals[j] ; j++) { snprintf(buf, sizeof(buf), "%s", vals[j]); e = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(e), buf); gtk_widget_set_sensitive(e, FALSE); gtk_widget_show(e); gtk_table_attach(GTK_TABLE(table), e, 1, 2, row, row+1, GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); row++; } ldap_value_free(vals); } ldap_memfree(attr); #ifndef HAVE_OPENLDAP_12 if(berptr) ber_free(berptr, 0); #endif ldap_msgfree(res); } } close_connection(entry->server, FALSE); } /* gtk_box_pack_start(GTK_BOX(pane2_vbox), label, FALSE, FALSE, 0); */ } static void server_browse_entry_refresh(server_browse_entry *entry, GtkCTree *ctree, GtkCTreeNode *node, struct tab *tab) { assert(IS_SERVER_ENTRY(entry)); entry->once_expanded = 0; gtk_clist_freeze(GTK_CLIST(ctree)); server_browse_entry_selected(entry, ctree, node, tab); /* toggle expansion twice to fire the expand callback and to return to the current expansion state */ gtk_ctree_toggle_expansion(ctree, node); gtk_ctree_toggle_expansion(ctree, node); /* server_browse_entry_expand(entry, ctree, node, tab); */ gtk_clist_thaw(GTK_CLIST(ctree)); } char* server_browse_entry_get_name(server_browse_entry *entry, gboolean long_form) { assert(IS_SERVER_ENTRY(entry)); return g_strdup(entry->server->name); } /* popup method for BOTH server AND ref entries (the same for now...) */ static void server_browse_entry_popup(dn_browse_entry *entry, GtkWidget *menu, GtkWidget *ctreeroot, GtkCTreeNode *ctree_node, struct tab *tab) { GtkWidget *menu_item; struct ldapserver *server; assert(IS_SERVER_ENTRY(entry)); server = server_from_node(GTK_CTREE(ctreeroot), ctree_node); /* Edit Server settings */ menu_item = gtk_menu_item_new_with_label(_("Edit Server")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); gtk_signal_connect_object(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(create_edit_server_window), (gpointer) server); gtk_widget_show(menu_item); if (server == NULL) { gtk_widget_set_sensitive(menu_item, FALSE); } /* Close connection */ menu_item = gtk_menu_item_new_with_label(_("Close Connection")); gtk_menu_append(GTK_MENU(menu), menu_item); gtk_widget_show(menu_item); gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(tree_row_close_connection), (gpointer) tab); gtk_widget_show(menu_item); if (server == NULL) { gtk_widget_set_sensitive(menu_item, FALSE); } } static struct browse_entry_vtab server_vtab = { (browse_entry_destructor) NULL, /* destroy */ (browse_entry_expand) server_browse_entry_expand, /* expand */ (browse_entry_select) server_browse_entry_selected, /* select */ (browse_entry_refresh) server_browse_entry_refresh, /* refresh */ (browse_entry_get_name) server_browse_entry_get_name, /* get_name */ (browse_entry_popup) server_browse_entry_popup, /* popup */ }; browse_entry *new_server_browse_entry(struct ldapserver *server) { server_browse_entry *e; e = g_malloc0(sizeof(server_browse_entry)); e->type = SERVER_BROWSE_ENTRY; e->base_methods = &server_vtab; e->server = server; return (browse_entry *) e; } /* Local Variables: c-basic-offset: 5 End: */ --- NEW FILE: server-browse.h --- /* 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 the additional exemption that compiling, linking, and/or using OpenSSL is allowed. 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 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 */ /* $Id: server-browse.h,v 1.1 2003/10/17 07:26:25 stamfest Exp $ */ #ifndef GQ_SERVER_BROWSE_H_INCLUDED #define GQ_SERVER_BROWSE_H_INCLUDED #include "config.h" #include "browse.h" /**************************************************************************/ /* * A browse_entry object describing a LDAP server */ #define SERVER_BROWSE_ENTRY 2 typedef struct { /* common */ int type; struct browse_entry_vtab *base_methods; /* specific */ struct ldapserver *server; int once_expanded; } server_browse_entry; #define IS_SERVER_ENTRY(entry) IS_ENTRY((entry), SERVER_BROWSE_ENTRY) browse_entry *new_server_browse_entry(struct ldapserver *server); #endif /* Local Variables: c-basic-offset: 5 End: */ Index: Makefile.am =================================================================== RCS file: /cvsroot/gqclient/gq/src/Makefile.am,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** Makefile.am 17 Oct 2003 07:10:51 -0000 1.29 --- Makefile.am 17 Oct 2003 07:26:25 -0000 1.30 *************** *** 33,36 **** --- 33,39 ---- mainwin.c \ browse.c \ + dn-browse.c \ + server-browse.c \ + ref-browse.c \ schema.c \ schemabrowse.c \ *************** *** 77,80 **** --- 80,86 ---- mainwin.h \ browse.h \ + dn-browse.h \ + server-browse.h \ + ref-browse.h \ schema.h \ schemabrowse.h \ Index: browse.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/browse.c,v retrieving revision 1.83 retrieving revision 1.84 diff -C2 -d -r1.83 -r1.84 *** browse.c 17 Oct 2003 07:07:05 -0000 1.83 --- browse.c 17 Oct 2003 07:26:25 -0000 1.84 *************** *** 29,33 **** #include <gdk/gdkkeysyms.h> - #include <stdio.h> #include <errno.h> #include <string.h> --- 29,32 ---- *************** *** 38,41 **** --- 37,45 ---- #include "configfile.h" [...1833 lines suppressed...] ! gtk_menu_append(GTK_MENU(menu), menu_item); ! gtk_widget_show(menu_item); ! ! gtk_signal_connect(GTK_OBJECT(menu_item), "activate", ! GTK_SIGNAL_FUNC(tree_row_refresh), ! (gpointer) tab); ! entry->base_methods->popup((browse_entry*) entry, menu, ! ctreeroot, ctree_node, tab); ! gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, ! event->button, event->time); ! ! gtk_signal_emit_stop_by_name(GTK_OBJECT(ctreeroot), ! "button_press_event"); ! return(TRUE); } } #if GTK_MAJOR... [truncated message content] |