~ubuntu-branches/ubuntu/trusty/gq/trusty

« back to all changes in this revision

Viewing changes to src/gq-utilities.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese
  • Date: 2009-10-25 23:34:56 UTC
  • mfrom: (1.1.4 upstream) (3.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091025233456-i794n3yg2cff930j
Tags: 1.3.4-1
* QA upload.
  + Set maintainer to Debian QA Group <packages@qa.debian.org>.
* New upstream release. (Closes: #534705).
  + Does not segfault on amd64. (Closes: #444312).
  + Remove all existing patches and change patch system to quilt.
  + Replace dpatch build-dep with quilt.
* 01_desktop_file.diff - Remove encoding and bogus categories 
  from desktop file.
* Copy in config.{sub,guess} on configure, rm them on clean.
  + Add build-dep on autotools-dev.
* Make clean not ignore errors.
* Add copyright holders and version path to GPL (GPL-2).
* Update watch file to use SF redirector. (Closes: #449749).
* Bump debhelper build-dep and compat to 5.
* Bump Standards Version to 3.8.3.
  + Menu policy transition.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    GQ -- a GTK-based LDAP client
 
3
    Copyright (C) 1998-2003 Bert Vermeulen
 
4
    Copyright (C) 2002-2003 Peter Stamfest
 
5
    Copyright (C) 2006      Sven Herzberg
 
6
 
 
7
    This program is released under the Gnu General Public License with
 
8
    the additional exemption that compiling, linking, and/or using
 
9
    OpenSSL is allowed.
 
10
 
 
11
    This program is free software; you can redistribute it and/or modify
 
12
    it under the terms of the GNU General Public License as published by
 
13
    the Free Software Foundation; either version 2 of the License, or
 
14
    (at your option) any later version.
 
15
 
 
16
    This program is distributed in the hope that it will be useful,
 
17
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
    GNU General Public License for more details.
 
20
 
 
21
    You should have received a copy of the GNU General Public License
 
22
    along with this program; if not, write to the Free Software
 
23
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
24
*/
 
25
 
 
26
#include "gq-utilities.h"
 
27
 
 
28
#include <glib.h>
 
29
#include <glib/gi18n.h>
 
30
#include <gtk/gtk.h>
 
31
#include <gdk/gdkkeysyms.h>
 
32
 
 
33
#include <stdio.h>
 
34
#include <unistd.h>
 
35
#include <string.h>
 
36
#include <pwd.h>
 
37
#include <errno.h>
 
38
 
 
39
#ifdef HAVE_CONFIG_H
 
40
# include <config.h>
 
41
#endif /* HAVE_CONFIG_H */
 
42
 
 
43
#include <lber.h>
 
44
#ifdef HAVE_LDAP_STR2OBJECTCLASS
 
45
#    include <ldap_schema.h>
 
46
#endif
 
47
#ifdef LDAP_OPT_NETWORK_TIMEOUT
 
48
#include <sys/time.h>
 
49
#endif
 
50
 
 
51
#include <glade/glade.h>
 
52
 
 
53
#include "debug.h"
 
54
#include "configfile.h"
 
55
#include "common.h"
 
56
#include "encode.h"
 
57
#include "errorchain.h"
 
58
#include "gq-input-form.h"
 
59
#include "gq-ldap.h"
 
60
#include "gq-server-list.h"
 
61
#include "gq-window.h"          /* message_log_append */
 
62
#include "schema.h"
 
63
#include "template.h"
 
64
 
 
65
/*
 
66
 * clear cached server schema
 
67
 */
 
68
void clear_server_schema(GqServer *server)
 
69
{
 
70
#ifdef HAVE_LDAP_STR2OBJECTCLASS
 
71
     GList *list;
 
72
     struct server_schema *ss;
 
73
 
 
74
     if(server->ss) {
 
75
          ss = server->ss;
 
76
 
 
77
          /* objectclasses */
 
78
          list = ss->oc;
 
79
          if(list) {
 
80
               while(list) {
 
81
                    ldap_objectclass_free(list->data);
 
82
                    list = list->next;
 
83
               }
 
84
               g_list_free(ss->oc);
 
85
          }
 
86
 
 
87
          /* attribute types */
 
88
          list = ss->at;
 
89
          if(list) {
 
90
               while(list) {
 
91
                    ldap_attributetype_free(list->data);
 
92
                    list = list->next;
 
93
               }
 
94
               g_list_free(ss->at);
 
95
          }
 
96
 
 
97
          /* matching rules */
 
98
          list = ss->mr;
 
99
          if(list) {
 
100
               while(list) {
 
101
                    ldap_matchingrule_free(list->data);
 
102
                    list = list->next;
 
103
               }
 
104
               g_list_free(ss->mr);
 
105
          }
 
106
 
 
107
          /* syntaxes */
 
108
          list = ss->s;
 
109
          if(list) {
 
110
               while(list) {
 
111
                    ldap_syntax_free(list->data);
 
112
                    list = list->next;
 
113
               }
 
114
               g_list_free(ss->s);
 
115
          }
 
116
 
 
117
          FREE(server->ss, "struct server_schema");
 
118
          server->ss = NULL;
 
119
     }
 
120
     else
 
121
          server->flags &= ~SERVER_HAS_NO_SCHEMA;
 
122
#endif
 
123
 
 
124
}
 
125
 
 
126
 
 
127
/*
 
128
 * delete entry
 
129
 */
 
130
static gboolean
 
131
delete_entry_recursive(int          delete_context,
 
132
                       GqServer   * server,
 
133
                       gchar const* dn,
 
134
                       gboolean     recursive)
 
135
{
 
136
     LDAP *ld;
 
137
     int msg;
 
138
     gboolean rc = TRUE;
 
139
     LDAPControl c;
 
140
     LDAPControl *ctrls[2] = { NULL, NULL } ;
 
141
     LDAPMessage *res = NULL, *e;
 
142
 
 
143
     c.ldctl_oid                = LDAP_CONTROL_MANAGEDSAIT;
 
144
     c.ldctl_value.bv_val       = NULL;
 
145
     c.ldctl_value.bv_len       = 0;
 
146
     c.ldctl_iscritical = 1;
 
147
     
 
148
     ctrls[0] = &c;
 
149
 
 
150
     /* FIXME confirm-mod check here */
 
151
 
 
152
     set_busycursor();
 
153
 
 
154
     if( (ld = open_connection(delete_context, server) ) == NULL) {
 
155
          set_normalcursor();
 
156
          return(FALSE);
 
157
     }
 
158
 
 
159
     if (recursive) {
 
160
          int something_to_do = 1;
 
161
          static char* attrs [] = {"dn", NULL};
 
162
 
 
163
          while (something_to_do) {
 
164
               something_to_do = 0;
 
165
               msg = ldap_search_ext_s(ld, dn,
 
166
                                       LDAP_SCOPE_ONELEVEL,
 
167
                                       "(objectClass=*)",
 
168
                                       (char **)attrs,  /* attrs */
 
169
                                       1,               /* attrsonly */
 
170
                                       ctrls,           /* serverctrls */
 
171
                                       NULL,            /* clientctrls */
 
172
                                       NULL,            /* timeout */
 
173
                                       LDAP_NO_LIMIT,   /* sizelimit */
 
174
                                       &res);
 
175
 
 
176
               if(msg == LDAP_NOT_SUPPORTED) {
 
177
                    msg = ldap_search_s(ld, dn, LDAP_SCOPE_ONELEVEL,
 
178
                                        "(objectClass=*)",
 
179
                                        (char **) attrs, 1, &res);
 
180
               }
 
181
 
 
182
               if(msg == LDAP_SUCCESS) {
 
183
                    for (e = ldap_first_entry(ld, res); e ;
 
184
                         e = ldap_next_entry(ld, e)) {
 
185
                         char *dn2 = ldap_get_dn(ld, e);
 
186
                         gboolean delok = delete_entry_full(delete_context,
 
187
                                                            server, dn2);
 
188
                         if (dn2) ldap_memfree(dn2);
 
189
 
 
190
                         if (delok) {
 
191
                              something_to_do = 1;
 
192
                         } else {
 
193
                              goto done;
 
194
                         }
 
195
                    }
 
196
               } else if (msg == LDAP_SERVER_DOWN) {
 
197
                    server->server_down++;
 
198
                    goto done;
 
199
               }
 
200
               if (res) ldap_msgfree(res);
 
201
               res = NULL;
 
202
          }
 
203
     }
 
204
 
 
205
     statusbar_msg(_("Deleting: %s"), dn);
 
206
 
 
207
     msg = ldap_delete_ext_s(ld, dn, ctrls, NULL);
 
208
 
 
209
     if(msg == LDAP_NOT_SUPPORTED) {
 
210
          msg = ldap_delete_s(ld, dn);
 
211
     }
 
212
 
 
213
#if HAVE_LDAP_CLIENT_CACHE
 
214
     ldap_uncache_entry(ld, dn);
 
215
#endif
 
216
 
 
217
     if(msg != LDAP_SUCCESS) {
 
218
          error_push(delete_context, 
 
219
                     "Error deleting DN '%1$s' on '%2$s': %3$s", 
 
220
                     dn, gq_server_get_name(server), ldap_err2string(msg));
 
221
          rc = FALSE;
 
222
     }
 
223
     else {
 
224
          statusbar_msg(_("Deleted %s"), dn);
 
225
     }
 
226
 
 
227
 done:
 
228
     if (res) ldap_msgfree(res);
 
229
     set_normalcursor();
 
230
     close_connection(server, FALSE);
 
231
 
 
232
     return(rc);
 
233
}
 
234
 
 
235
 
 
236
gboolean
 
237
delete_entry(int          delete_context,
 
238
             GqServer   * server,
 
239
             gchar const* dn)
 
240
{
 
241
        return delete_entry_recursive(delete_context, server, dn, FALSE);
 
242
}
 
243
 
 
244
gboolean
 
245
delete_entry_full(int          delete_context,
 
246
                  GqServer   * server,
 
247
                  gchar const* dn)
 
248
{
 
249
        return delete_entry_recursive(delete_context, server, dn, TRUE);
 
250
}
 
251
 
 
252
/*
 
253
 * display hourglass cursor on mainwin
 
254
 */
 
255
void set_busycursor(void)
 
256
{
 
257
     GdkCursor *busycursor;
 
258
 
 
259
     busycursor = gdk_cursor_new(GDK_WATCH);
 
260
     gdk_window_set_cursor(mainwin.mainwin->window, busycursor);
 
261
     gdk_cursor_destroy(busycursor);
 
262
 
 
263
}
 
264
 
 
265
 
 
266
/*
 
267
 * set mainwin cursor to default
 
268
 */
 
269
void set_normalcursor(void)
 
270
{
 
271
 
 
272
     gdk_window_set_cursor(mainwin.mainwin->window, NULL);
 
273
 
 
274
}
 
275
 
 
276
/*
 
277
 * callback for key_press_event on a widget, destroys obj if key was esc
 
278
 */
 
279
int close_on_esc(GtkWidget *widget, GdkEventKey *event, gpointer obj)
 
280
{
 
281
     if(event && event->type == GDK_KEY_PRESS && event->keyval == GDK_Escape) {
 
282
          gtk_widget_destroy(GTK_WIDGET(obj));
 
283
          g_signal_stop_emission_by_name(widget, "key_press_event");
 
284
          return(TRUE);
 
285
     }
 
286
 
 
287
     return(FALSE);
 
288
}
 
289
 
 
290
 
 
291
/*
 
292
 * callback for key_press_event on a widget, calls func if key was esc
 
293
 */
 
294
int func_on_esc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
 
295
{
 
296
     void (*func)(GtkWidget *);
 
297
 
 
298
     if(event && event->type == GDK_KEY_PRESS && event->keyval == GDK_Escape) {
 
299
          func = gtk_object_get_data(GTK_OBJECT(window), "close_func");
 
300
          func(widget);
 
301
          g_signal_stop_emission_by_name(widget, "key_press_event");
 
302
          return(TRUE);
 
303
     }
 
304
 
 
305
     return(FALSE);
 
306
}
 
307
 
 
308
 
 
309
int tokenize(const struct tokenlist *list, const char *keyword)
 
310
{
 
311
     int i;
 
312
 
 
313
     for(i = 0; list[i].keyword && strlen(list[i].keyword); i++)
 
314
          if(!strcasecmp(list[i].keyword, keyword))
 
315
               return(list[i].token);
 
316
 
 
317
     return(0);
 
318
}
 
319
 
 
320
 
 
321
const char *detokenize(const struct tokenlist *list, int token)
 
322
{
 
323
     int i;
 
324
 
 
325
     for(i = 0; list[i].keyword && strlen(list[i].keyword); i++)
 
326
          if(list[i].token == token)
 
327
               return(list[i].keyword);
 
328
 
 
329
     return(list[0].keyword);
 
330
}
 
331
 
 
332
 
 
333
const void *detokenize_data(const struct tokenlist *list, int token)
 
334
{
 
335
     int i;
 
336
 
 
337
     for(i = 0; strlen(list[i].keyword); i++)
 
338
          if(list[i].token == token)
 
339
               return(list[i].data);
 
340
 
 
341
     return(list[0].data);
 
342
}
 
343
 
 
344
/*
 
345
 * return pointer to username (must be freed)
 
346
 */
 
347
char *get_username(void)
 
348
{
 
349
     struct passwd *pwent;
 
350
     char *username;
 
351
 
 
352
     username = NULL;
 
353
     pwent = getpwuid(getuid());
 
354
     if(pwent && pwent->pw_name)
 
355
          username = strdup(pwent->pw_name);
 
356
     endpwent();
 
357
 
 
358
     return(username);
 
359
}
 
360
 
 
361
 
 
362
/* these should probably belong to GqWindow */
 
363
#warning "FIXME: move into GqWindow"
 
364
static guint context = 0, msgid = 0;
 
365
 
 
366
 
 
367
/*
 
368
 * display message in main window's statusbar, and flushes the
 
369
 * GTK event queue
 
370
 */
 
371
void
 
372
statusbar_msg(gchar const* fmt, ...)
 
373
{
 
374
     /* do not use g_string_sprintf, as it usually does not support
 
375
        numbered arguments */
 
376
     int len = strlen(fmt) * 2;
 
377
     char *buf;
 
378
     int n;
 
379
 
 
380
     if (len > 0) {
 
381
          for (;;) {
 
382
               va_list ap;
 
383
               buf = g_malloc(len);
 
384
               *buf = 0;
 
385
               
 
386
               va_start(ap, fmt);
 
387
               n = g_vsnprintf(buf, len, fmt, ap);
 
388
               va_end(ap);
 
389
               
 
390
               if (n > len || n == -1) {
 
391
                    g_free(buf);
 
392
                    len *= 2;
 
393
                    continue;
 
394
               }
 
395
               break;
 
396
          } 
 
397
     } else {
 
398
          buf = g_strdup("");
 
399
     }
 
400
 
 
401
     statusbar_msg_clear();
 
402
 
 
403
     msgid = gtk_statusbar_push(GTK_STATUSBAR(mainwin.statusbar), 
 
404
                                context, buf);
 
405
     message_log_append(buf);
 
406
     g_free(buf);
 
407
 
 
408
     /* make sure statusbar gets updated right away */
 
409
        gq_main_loop_flush();
 
410
}
 
411
 
 
412
void statusbar_msg_clear()
 
413
{
 
414
     if(!context)
 
415
          context =
 
416
               gtk_statusbar_get_context_id(GTK_STATUSBAR(mainwin.statusbar),
 
417
                                            "mainwin");
 
418
     if(msgid)
 
419
          gtk_statusbar_remove(GTK_STATUSBAR(mainwin.statusbar),
 
420
                               context, msgid);
 
421
}
 
422
 
 
423
/*
 
424
 * return pointer to GqServer matching the canonical name
 
425
 */
 
426
GqServer *server_by_canon_name(const char *name,
 
427
                                        gboolean include_transient)
 
428
{
 
429
     GqServer *server = NULL;
 
430
     GList *I;
 
431
 
 
432
     if(name == NULL || name[0] == '\0')
 
433
          return NULL;
 
434
 
 
435
     server = gq_server_list_get_by_canon_name(gq_server_list_get(), name);
 
436
     if(!server && include_transient) {
 
437
          for (I = transient_servers ; I ; I = g_list_next(I)) {
 
438
               if(!strcmp(((GqServer*)I->data)->canon_name, name)) {
 
439
                    server = I->data;
 
440
                    break;
 
441
               }
 
442
          }
 
443
     }
 
444
     return server;
 
445
}
 
446
 
 
447
gboolean
 
448
is_transient_server(const GqServer *server) {
 
449
        g_return_val_if_fail(GQ_IS_SERVER(server), FALSE);
 
450
        return !gq_server_list_contains(gq_server_list_get(), server);
 
451
}
 
452
 
 
453
/*
 
454
 * check if entry has a subtree
 
455
 */
 
456
int is_leaf_entry(int error_context,
 
457
                  GqServer *server, char *dn)
 
458
{
 
459
     LDAP *ld;
 
460
     LDAPMessage *res;
 
461
     int msg, is_leaf, rc;
 
462
     char *attrs[] = {
 
463
          LDAP_NO_ATTRS,
 
464
          NULL
 
465
     };
 
466
     LDAPControl c;
 
467
     LDAPControl *ctrls[2] = { NULL, NULL } ;
 
468
 
 
469
     /*  ManageDSAit  */
 
470
     c.ldctl_oid                = LDAP_CONTROL_MANAGEDSAIT;
 
471
     c.ldctl_value.bv_val       = NULL;
 
472
     c.ldctl_value.bv_len       = 0;
 
473
     c.ldctl_iscritical = 1;
 
474
     
 
475
     ctrls[0] = &c;
 
476
 
 
477
     is_leaf = 0;
 
478
 
 
479
     set_busycursor();
 
480
 
 
481
     if( (ld = open_connection(error_context, server) ) == NULL) {
 
482
          set_normalcursor();
 
483
          return(-1);
 
484
     }
 
485
 
 
486
     statusbar_msg(_("Checking subtree for %s"), dn);
 
487
 
 
488
     rc = ldap_search_ext(ld, dn, LDAP_SCOPE_ONELEVEL, "(objectclass=*)",
 
489
                           attrs,               /* attrs */
 
490
                           0,                   /* attrsonly */
 
491
                           ctrls,               /* serverctrls */
 
492
                           NULL,                /* clientctrls */
 
493
                           NULL,                /* timeout */
 
494
                           LDAP_NO_LIMIT,       /* sizelimit */
 
495
                           &msg);
 
496
 
 
497
     if(rc != -1) {
 
498
          if( (ldap_result(ld, msg, 0, NULL, &res) != LDAP_RES_SEARCH_ENTRY))
 
499
               is_leaf = 1;
 
500
          ldap_msgfree(res);
 
501
          ldap_abandon(ld, msg);
 
502
     }
 
503
 
 
504
     close_connection(server, FALSE);
 
505
     set_normalcursor();
 
506
     statusbar_msg_clear();
 
507
 
 
508
     return(is_leaf);
 
509
}
 
510
 
 
511
/*
 
512
 * check if child is a direct subentry of possible_parent
 
513
 */
 
514
gboolean is_direct_parent(char *child, char *possible_parent) 
 
515
{
 
516
     /* SHOULD use gq_ldap_explode_dn for this */
 
517
     char *c = g_utf8_strchr(child, -1, ',');
 
518
     if (c && (strcasecmp(c + 1, possible_parent) == 0)) return TRUE;
 
519
     return FALSE;
 
520
}
 
521
 
 
522
/*
 
523
 * check if child is a (possibly indirect) subentry of possible_ancestor
 
524
 */
 
525
gboolean
 
526
is_ancestor(gchar const* child,
 
527
            gchar const* possible_ancestor) 
 
528
{
 
529
     char **rdn = gq_ldap_explode_dn(child, FALSE);
 
530
     GString *s;
 
531
     int n;
 
532
     gboolean rc = FALSE;
 
533
 
 
534
     for (n = 0 ; rdn[n] ; n++) {
 
535
     }
 
536
 
 
537
     s = g_string_new("");
 
538
     for (n-- ; n >= 0 ; n--) {
 
539
          g_string_insert(s, 0, rdn[n]);
 
540
          if ((strcasecmp(s->str, possible_ancestor) == 0)) {
 
541
               rc = TRUE;
 
542
               break;
 
543
          }
 
544
          g_string_insert(s, 0, ",");
 
545
     }
 
546
 
 
547
     g_string_free(s, TRUE);
 
548
     gq_exploded_free(rdn);
 
549
 
 
550
     return rc;
 
551
}
 
552
 
 
553
GList *ar2glist(char *ar[])
 
554
{
 
555
     GList *tmp;
 
556
     int i;
 
557
 
 
558
     if(ar == NULL) {
 
559
          /* gtk_combo_set_popdown_strings() can't handle an
 
560
             empty list, so give it a list with an empty entry */
 
561
          tmp = g_list_append(NULL, "");
 
562
          return(tmp);
 
563
     }
 
564
 
 
565
     tmp = NULL;
 
566
     i = 0;
 
567
     while(ar[i])
 
568
          tmp = g_list_append(tmp, ar[i++]);
 
569
 
 
570
     return(tmp);
 
571
}
 
572
 
 
573
 
 
574
/*
 
575
 * pops up a warning dialog (with hand icon), and displays all messages in
 
576
 * the GList , one per line. The GList is freed here.
 
577
 */
 
578
void warning_popup(GList *messages)
 
579
{
 
580
     GList *list;
 
581
     GtkWidget *window, *vbox1, *vbox2, *vbox3, *label, *hbox0;
 
582
     GtkWidget *hbox1, *ok_button;
 
583
     GtkWidget *pixmap;
 
584
 
 
585
     window = gtk_dialog_new();
 
586
     gtk_container_border_width(GTK_CONTAINER(window), CONTAINER_BORDER_WIDTH);
 
587
     gtk_window_set_title(GTK_WINDOW(window), _("Warning"));
 
588
     gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
 
589
     vbox1 = GTK_DIALOG(window)->vbox;
 
590
     gtk_widget_show(vbox1);
 
591
 
 
592
     hbox1 = gtk_hbox_new(FALSE, 0);
 
593
     gtk_widget_show(hbox1);
 
594
     gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 10);
 
595
     pixmap = gtk_image_new_from_file(PACKAGE_PREFIX "/share/pixmaps/gq/warning.xpm");
 
596
     gtk_widget_show(pixmap);
 
597
     gtk_box_pack_start(GTK_BOX(hbox1), pixmap, TRUE, TRUE, 10);
 
598
 
 
599
     vbox2 = gtk_vbox_new(FALSE, 0);
 
600
     gtk_widget_show(vbox2);
 
601
     gtk_box_pack_start(GTK_BOX(hbox1), vbox2, TRUE, TRUE, 10);
 
602
 
 
603
     list = messages;
 
604
     while(list) {
 
605
          label = gtk_label_new((char *) list->data);
 
606
          gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
 
607
          gtk_widget_show(label);
 
608
          gtk_box_pack_start(GTK_BOX(vbox2), label, TRUE, TRUE, 0);
 
609
          list = list->next;
 
610
     }
 
611
 
 
612
     /* OK button */
 
613
     vbox3 = GTK_DIALOG(window)->action_area;
 
614
     gtk_widget_show(vbox3);
 
615
 
 
616
     hbox0 = gtk_hbutton_box_new();
 
617
     gtk_widget_show(hbox0);
 
618
     gtk_box_pack_start(GTK_BOX(vbox3), hbox0, TRUE, TRUE, 0);
 
619
 
 
620
     ok_button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
 
621
 
 
622
     g_signal_connect_swapped(ok_button, "clicked",
 
623
                               G_CALLBACK(gtk_widget_destroy),
 
624
                               window);
 
625
     gtk_box_pack_start(GTK_BOX(hbox0), ok_button, FALSE, FALSE, 0);
 
626
     GTK_WIDGET_SET_FLAGS(ok_button, GTK_CAN_DEFAULT);
 
627
     gtk_widget_grab_default(ok_button);
 
628
     gtk_widget_show(ok_button);
 
629
 
 
630
     /* what does this mean? PS: 20030928 - FIXME */
 
631
     g_signal_connect_swapped(window, "destroy",
 
632
                               G_CALLBACK(gtk_widget_destroy),
 
633
                               window);
 
634
 
 
635
     g_signal_connect_swapped(window, "key_press_event",
 
636
                               G_CALLBACK(close_on_esc),
 
637
                               window);
 
638
 
 
639
     gtk_widget_show(window);
 
640
 
 
641
     g_list_free(messages);
 
642
 
 
643
}
 
644
 
 
645
 
 
646
void single_warning_popup(char *message)
 
647
{
 
648
     GList *msglist;
 
649
 
 
650
     msglist = g_list_append(NULL, message);
 
651
     warning_popup(msglist);
 
652
 
 
653
}
 
654
 
 
655
 
 
656
#ifdef HAVE_LDAP_STR2OBJECTCLASS
 
657
GList *find_at_by_mr_oid(GqServer *server, const char *oid)
 
658
{
 
659
     GList *list, *srvlist;
 
660
     LDAPAttributeType *at;
 
661
 
 
662
     list = NULL;
 
663
     srvlist = server->ss->at;
 
664
     while(srvlist) {
 
665
          at = (LDAPAttributeType *) srvlist->data;
 
666
 
 
667
          if( (at->at_equality_oid && !strcasecmp(oid, at->at_equality_oid)) ||
 
668
              (at->at_ordering_oid && !strcasecmp(oid, at->at_ordering_oid)) ||
 
669
              (at->at_substr_oid && !strcasecmp(oid, at->at_substr_oid)) ) {
 
670
               if(at->at_names && at->at_names[0])
 
671
                    list = g_list_append(list, at->at_names[0]);
 
672
               else
 
673
                    list = g_list_append(list, at->at_oid);
 
674
          }
 
675
          srvlist = srvlist->next;
 
676
     }
 
677
 
 
678
     return(list);
 
679
}
 
680
 
 
681
LDAPAttributeType *find_canonical_at_by_at(struct server_schema *schema,
 
682
                                           const char *attr)
 
683
{
 
684
     GList *atlist;
 
685
     char **n;
 
686
     
 
687
     if (!schema) return NULL;
 
688
     
 
689
     for ( atlist = schema->at ; atlist ; atlist = atlist->next ) {
 
690
          LDAPAttributeType *at = (LDAPAttributeType *) atlist->data;
 
691
          if (!at) continue;
 
692
          
 
693
          for (n = at->at_names ; n && *n ; n++) {
 
694
/*             printf("%s ", *n); */
 
695
               if (strcasecmp(*n, attr) == 0) {
 
696
                    /* found! */
 
697
                    return at;
 
698
               }
 
699
          }
 
700
     }
 
701
     return NULL;
 
702
}
 
703
 
 
704
GList *find_at_by_s_oid(GqServer *server, const char *oid)
 
705
{
 
706
     GList *list, *srvlist;
 
707
     LDAPAttributeType *at;
 
708
 
 
709
     list = NULL;
 
710
     srvlist = server->ss->at;
 
711
     while(srvlist) {
 
712
          at = (LDAPAttributeType *) srvlist->data;
 
713
 
 
714
          if(at->at_syntax_oid && !strcasecmp(oid, at->at_syntax_oid)) {
 
715
               if(at->at_names && at->at_names[0])
 
716
                    list = g_list_append(list, at->at_names[0]);
 
717
               else
 
718
                    list = g_list_append(list, at->at_oid);
 
719
          }
 
720
          srvlist = srvlist->next;
 
721
     }
 
722
 
 
723
     return(list);
 
724
}
 
725
 
 
726
 
 
727
GList *find_mr_by_s_oid(GqServer *server, const char *oid)
 
728
{
 
729
     GList *list, *srvlist;
 
730
     LDAPMatchingRule *mr;
 
731
 
 
732
     list = NULL;
 
733
     srvlist = server->ss->mr;
 
734
     while(srvlist) {
 
735
          mr = (LDAPMatchingRule *) srvlist->data;
 
736
 
 
737
          if(mr->mr_syntax_oid && !strcasecmp(oid, mr->mr_syntax_oid)) {
 
738
               if(mr->mr_names && mr->mr_names[0])
 
739
                    list = g_list_append(list, mr->mr_names[0]);
 
740
               else
 
741
                    list = g_list_append(list, mr->mr_oid);
 
742
          }
 
743
          srvlist = srvlist->next;
 
744
     }
 
745
 
 
746
     return(list);
 
747
}
 
748
 
 
749
 
 
750
GList *find_oc_by_at(int error_context,
 
751
                     GqServer *server, const char *atname)
 
752
{
 
753
     GList *list, *oclist;
 
754
     LDAPObjectClass *oc;
 
755
     int i, found;
 
756
     struct server_schema *ss = NULL;
 
757
 
 
758
     list = NULL;
 
759
 
 
760
     if (server == NULL) return NULL;
 
761
     ss = get_schema(error_context, server);
 
762
     if (ss == NULL) return NULL;
 
763
 
 
764
     oclist = ss->oc;
 
765
     while(oclist) {
 
766
          oc = (LDAPObjectClass *) oclist->data;
 
767
 
 
768
          found = 0;
 
769
 
 
770
          if(oc->oc_at_oids_must) {
 
771
               i = 0;
 
772
               while(oc->oc_at_oids_must[i] && !found) {
 
773
                    if(!strcasecmp(atname, oc->oc_at_oids_must[i])) {
 
774
                         found = 1;
 
775
                         if(oc->oc_names && oc->oc_names[0])
 
776
                              list = g_list_append(list, oc->oc_names[0]);
 
777
                         else
 
778
                              list = g_list_append(list, oc->oc_oid);
 
779
                    }
 
780
                    i++;
 
781
               }
 
782
          }
 
783
 
 
784
          if(oc->oc_at_oids_may) {
 
785
               i = 0;
 
786
               while(oc->oc_at_oids_may[i] && !found) {
 
787
                    if(!strcasecmp(atname, oc->oc_at_oids_may[i])) {
 
788
                         found = 1;
 
789
                         if(oc->oc_names && oc->oc_names[0])
 
790
                              list = g_list_append(list, oc->oc_names[0]);
 
791
                         else
 
792
                              list = g_list_append(list, oc->oc_oid);
 
793
                    }
 
794
                    i++;
 
795
               }
 
796
          }
 
797
 
 
798
          oclist = oclist->next;
 
799
     }
 
800
 
 
801
     return(list);
 
802
}
 
803
 
 
804
const char *find_s_by_at_oid(int error_context, GqServer *server,
 
805
                             const char *oid)
 
806
{
 
807
     GList *srvlist;
 
808
     LDAPAttributeType *at;
 
809
     char **c;
 
810
     struct server_schema *ss = NULL;
 
811
 
 
812
     if (server == NULL) return NULL;
 
813
     ss = get_schema(error_context, server);
 
814
 
 
815
     if(ss == NULL || ss->at == NULL)
 
816
          return(NULL);
 
817
 
 
818
     srvlist = ss->at;
 
819
     while(srvlist) {
 
820
          at = (LDAPAttributeType *) srvlist->data;
 
821
 
 
822
          for (c = at->at_names ; c && *c ; c++) {
 
823
              if (!strcasecmp(oid, *c)) {
 
824
                  return at->at_syntax_oid;
 
825
              }
 
826
          }
 
827
          srvlist = srvlist->next;
 
828
     }
 
829
 
 
830
     return NULL;
 
831
}
 
832
 
 
833
#else /* HAVE_LDAP_STR2OBJECTCLASS */
 
834
 
 
835
 
 
836
/* fall back to attributeName to find syntax. */
 
837
 
 
838
struct oid2syntax_t {
 
839
     const char *oid;
 
840
     const char *syntax;
 
841
};
 
842
 
 
843
static struct oid2syntax_t oid2syntax[] = {
 
844
     { "userPassword", "1.3.6.1.4.1.1466.115.121.1.40" },
 
845
     { "jpegPhoto", "1.3.6.1.4.1.1466.115.121.1.28" },
 
846
     { "audio", "1.3.6.1.4.1.1466.115.121.1.4" },
 
847
     { "photo", "1.3.6.1.4.1.1466.115.121.1.4" },
 
848
     { NULL, NULL },
 
849
};
 
850
 
 
851
const char *find_s_by_at_oid(GqServer *server, const char *oid)
 
852
{
 
853
     struct oid2syntax_t *os;
 
854
     for (os = oid2syntax ; os->oid ; os++) {
 
855
          if (strcasecmp(os->oid, oid) == 0) return os->syntax;
 
856
     }
 
857
     
 
858
     return "1.3.6.1.4.1.1466.115.121.1.3";
 
859
}
 
860
 
 
861
 
 
862
#endif /* HAVE_LDAP_STR2OBJECTCLASS */
 
863
 
 
864
 
 
865
struct gq_template *find_template_by_name(const char *templatename)
 
866
{
 
867
     GList *I;
 
868
 
 
869
     for(I = config->templates ; I ; I = g_list_next(I)) {
 
870
          struct gq_template *template = 
 
871
               (struct gq_template *) I->data;
 
872
          if(!strcasecmp(templatename, template->name))
 
873
               return template;
 
874
     }
 
875
     return NULL;
 
876
}
 
877
 
 
878
 
 
879
 
 
880
void dump_mods(LDAPMod **mods)
 
881
{
 
882
     LDAPMod *mod;
 
883
     int cmod, cval;
 
884
 
 
885
     cmod = 0;
 
886
     while(mods[cmod]) {
 
887
          mod = mods[cmod];
 
888
          switch(mod->mod_op) {
 
889
          case LDAP_MOD_ADD: printf("LDAP_MOD_ADD"); break;
 
890
          case LDAP_MOD_DELETE: printf("LDAP_MOD_DELETE"); break;
 
891
          case LDAP_MOD_REPLACE: printf("LDAP_MOD_REPLACE"); break;
 
892
          case LDAP_MOD_BVALUES: printf("LDAP_MOD_BVALUES"); break;
 
893
          }
 
894
          printf(" %s\n", mod->mod_type);
 
895
          cval = 0;
 
896
          while(mod->mod_values && mod->mod_values[cval]) {
 
897
               printf("\t%s\n", mod->mod_values[cval]);
 
898
               cval++;
 
899
          }
 
900
 
 
901
          cmod++;
 
902
     }
 
903
 
 
904
 
 
905
}
 
906
 
 
907
struct popup_comm {
 
908
     int destroyed;
 
909
     int ended;
 
910
     int rc;
 
911
};
 
912
 
 
913
static struct popup_comm *new_popup_comm() 
 
914
{
 
915
     struct popup_comm *n = g_malloc0(sizeof(struct popup_comm));
 
916
     n->ended = n->destroyed = n->rc = 0;
 
917
     return n;
 
918
}
 
919
 
 
920
static void free_popup_comm(struct popup_comm *c)
 
921
{
 
922
     g_assert(c);
 
923
     g_free(c);
 
924
}
 
925
 
 
926
/* gtk2 checked (multiple destroy callbacks safety), confidence 0.7 */
 
927
static void
 
928
query_destroy(struct popup_comm* comm)
 
929
{
 
930
     g_assert(comm);
 
931
     if (!comm) return;
 
932
     if (!comm->ended)
 
933
          gtk_main_quit(); /* quits only nested main loop */
 
934
     comm->destroyed = 1;
 
935
}
 
936
 
 
937
static void
 
938
query_ok(struct popup_comm* comm)
 
939
{
 
940
     gtk_main_quit();
 
941
     comm->rc = 1;
 
942
}
 
943
 
 
944
static void
 
945
query_cancel(struct popup_comm* comm)
 
946
{
 
947
     gtk_main_quit();
 
948
     comm->rc = 0;
 
949
}
 
950
 
 
951
/* pops up a dialog to retrieve user data via a GtkEntry. This
 
952
   functions waits for the data and puts it into outbuf.
 
953
 
 
954
   inout_buf afterward points to allocate memory that has to be free'd
 
955
   using g_free. As an input parameter it points to the current value
 
956
   of the information to be entered (if not NULL). The passed-in
 
957
   information will not be changed.
 
958
*/
 
959
 
 
960
int query_popup(const char *title, gchar **inout_buf, gboolean is_password,
 
961
                GtkWidget *modal_for)
 
962
{
 
963
     GtkWidget *window, *vbox1, *vbox2, *label, *inputbox, *button, *hbox0;
 
964
     int rc;
 
965
     GtkWidget *f = gtk_grab_get_current();
 
966
     struct popup_comm *comm = new_popup_comm();
 
967
 
 
968
     /* This is a BAD hack - it solves a problem with the query popup
 
969
        dialog that locks up focus handling with all the
 
970
        window-managers I have been able to test this with. Actually,
 
971
        it should be sufficient to let go of the focus, but
 
972
        hiding/showing seems to work... (as I do not know how to
 
973
        release the focus in gtk) - Any gtk Hackers around? */
 
974
     if (f != NULL) {
 
975
         gtk_widget_hide(f);
 
976
         gtk_widget_show(f);
 
977
     }
 
978
 
 
979
     if (modal_for) {
 
980
          modal_for = gtk_widget_get_toplevel(modal_for);
 
981
     }
 
982
 
 
983
     window = gtk_dialog_new();
 
984
     gtk_container_border_width(GTK_CONTAINER(window), CONTAINER_BORDER_WIDTH);
 
985
     gtk_window_set_title(GTK_WINDOW(window), title);
 
986
     gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
 
987
        g_signal_connect_swapped(window, "destroy",
 
988
                                 G_CALLBACK(query_destroy), comm);
 
989
     g_signal_connect_swapped(window, "key_press_event",
 
990
                               G_CALLBACK(close_on_esc),
 
991
                               window);
 
992
 
 
993
     if (modal_for) {
 
994
          gtk_window_set_modal(GTK_WINDOW(window), TRUE);
 
995
          gtk_window_set_transient_for(GTK_WINDOW(window),
 
996
                                       GTK_WINDOW(modal_for));
 
997
     }
 
998
 
 
999
     vbox1 = GTK_DIALOG(window)->vbox;
 
1000
     gtk_widget_show(vbox1);
 
1001
 
 
1002
     label = gtk_label_new(title);
 
1003
     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
 
1004
     gtk_widget_show(label);
 
1005
     gtk_box_pack_start(GTK_BOX(vbox1), label, TRUE, TRUE, 0);
 
1006
 
 
1007
     inputbox = gtk_entry_new();
 
1008
 
 
1009
     GTK_WIDGET_SET_FLAGS(inputbox, GTK_CAN_FOCUS);
 
1010
     GTK_WIDGET_SET_FLAGS(inputbox, GTK_CAN_DEFAULT);
 
1011
     if (is_password) {
 
1012
          gtk_entry_set_visibility(GTK_ENTRY(inputbox), FALSE);
 
1013
     }
 
1014
 
 
1015
     if (inout_buf && *inout_buf) {
 
1016
          int pos = 0;
 
1017
          gtk_editable_insert_text(GTK_EDITABLE(inputbox),
 
1018
                                   *inout_buf, strlen(*inout_buf), &pos);
 
1019
     }
 
1020
 
 
1021
     gtk_widget_show(inputbox);
 
1022
        g_signal_connect_swapped(inputbox, "activate",
 
1023
                                 G_CALLBACK(query_ok), comm);
 
1024
     gtk_box_pack_end(GTK_BOX(vbox1), inputbox, TRUE, TRUE, 5);
 
1025
 
 
1026
     vbox2 = GTK_DIALOG(window)->action_area;
 
1027
     gtk_container_border_width(GTK_CONTAINER(vbox2), 0);
 
1028
     gtk_widget_show(vbox2);
 
1029
 
 
1030
     hbox0 = gtk_hbutton_box_new();
 
1031
     gtk_widget_show(hbox0);
 
1032
     gtk_box_pack_start(GTK_BOX(vbox2), hbox0, TRUE, TRUE, 0);
 
1033
 
 
1034
     button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
 
1035
 
 
1036
        g_signal_connect_swapped(button, "clicked",
 
1037
                                 G_CALLBACK(query_ok), comm);
 
1038
     gtk_box_pack_end(GTK_BOX(hbox0), button, FALSE, FALSE, 0);
 
1039
     GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
 
1040
     GTK_WIDGET_SET_FLAGS(button, GTK_RECEIVES_DEFAULT);
 
1041
     gtk_widget_grab_default(button);
 
1042
     gtk_widget_show(button);
 
1043
 
 
1044
     button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
 
1045
 
 
1046
        g_signal_connect_swapped(button, "clicked",
 
1047
                                 G_CALLBACK(query_cancel), comm);
 
1048
 
 
1049
     gtk_box_pack_end(GTK_BOX(hbox0), button, FALSE, FALSE, 0);
 
1050
     gtk_widget_show(button);
 
1051
 
 
1052
/*       gtk_window_set_transient_for(GTK_WINDOW(window),  */
 
1053
/*                                GTK_WINDOW(getMainWin())); */
 
1054
     gtk_widget_grab_focus(GTK_WIDGET(window));
 
1055
     gtk_window_set_modal(GTK_WINDOW(window), TRUE);
 
1056
 
 
1057
     gtk_widget_show(window);
 
1058
     gtk_widget_grab_focus(inputbox);
 
1059
 
 
1060
     gtk_main();
 
1061
     comm->ended = 1;
 
1062
 
 
1063
     if (! comm->destroyed && comm->rc) {
 
1064
         *inout_buf = gtk_editable_get_chars(GTK_EDITABLE(inputbox), 0, -1);
 
1065
     } else {
 
1066
         *inout_buf = NULL;
 
1067
     }
 
1068
 
 
1069
     if (! comm->destroyed ) {
 
1070
         gtk_widget_destroy(window);
 
1071
     }
 
1072
 
 
1073
     rc = comm->rc;
 
1074
     free_popup_comm(comm);
 
1075
 
 
1076
     return rc;
 
1077
}
 
1078
 
 
1079
 
 
1080
/* pops up a question dialog to ask the user a simple question. This
 
1081
   functions waits for the answer and returns it. */
 
1082
gboolean
 
1083
question_popup(GtkWindow  * parent,
 
1084
               gchar const* title,
 
1085
               gchar const* question)
 
1086
{
 
1087
        GtkWidget* window;
 
1088
        gboolean   rc;
 
1089
        GtkWidget* f = gtk_grab_get_current();
 
1090
 
 
1091
     /* This is a BAD hack - it solves a problem with the query popup
 
1092
        dialog that locks up focus handling with all the
 
1093
        window-managers I have been able to test this with. Actually,
 
1094
        it should be sufficient to let go of the focus, but
 
1095
        hiding/showing seems to work... (as I do not know how to
 
1096
        release the focus in gtk) - Any gtk Hackers around? */
 
1097
#warning "FIXME: we should be able to remove this one"
 
1098
        if (f != NULL) {
 
1099
                gtk_widget_hide(f);
 
1100
                gtk_widget_show(f);
 
1101
        }
 
1102
 
 
1103
        window = gtk_message_dialog_new(parent, GTK_DIALOG_MODAL,
 
1104
                                        GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
 
1105
                                        "%s", title);
 
1106
        gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(window),
 
1107
                                                 "%s", question);
 
1108
        gtk_window_set_title(GTK_WINDOW(window), title);
 
1109
        gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
 
1110
 
 
1111
        rc = gtk_dialog_run(GTK_DIALOG(window)) == GTK_RESPONSE_YES;
 
1112
        gtk_widget_destroy(window);
 
1113
 
 
1114
        return rc;
 
1115
}
 
1116
 
 
1117
/*
 
1118
 * get all suffixes a server considers itself authorative for.
 
1119
 */
 
1120
 
 
1121
GList *get_suffixes(int error_context, GqServer *server)
 
1122
{
 
1123
     LDAP *ld;
 
1124
     LDAPMessage *res, *e;
 
1125
     int msg, i;
 
1126
     int num_suffixes = 0;
 
1127
     char **vals;
 
1128
     char *ldapv3_config[] = {
 
1129
          "namingcontexts",
 
1130
          NULL
 
1131
     };
 
1132
     
 
1133
     GList *suffixes = NULL;
 
1134
     
 
1135
     set_busycursor();
 
1136
     
 
1137
     if( (ld = open_connection(error_context, server)) == NULL) {
 
1138
          set_normalcursor();
 
1139
          return NULL;
 
1140
     }
 
1141
     
 
1142
     /* try LDAP V3 style config */
 
1143
     statusbar_msg(_("Base search on NULL DN on server '%s'"), gq_server_get_name(server));
 
1144
     msg = ldap_search_s(ld, "", LDAP_SCOPE_BASE, "(objectclass=*)",
 
1145
                         ldapv3_config, 0, &res);
 
1146
     if(msg == LDAP_SUCCESS) {
 
1147
          e = ldap_first_entry(ld, res);
 
1148
          while (e) {
 
1149
               vals = ldap_get_values(ld, e, "namingcontexts");
 
1150
               if (vals) {
 
1151
                    for(i = 0; vals[i]; i++) {
 
1152
                         suffixes = g_list_append(suffixes, g_strdup(vals[i]));
 
1153
/*                       add_suffix(entry, ctreeroot, node, vals[i]); */
 
1154
                         num_suffixes++;
 
1155
                    }
 
1156
                    ldap_value_free(vals);
 
1157
               }
 
1158
               e = ldap_next_entry(ld, e);
 
1159
          }
 
1160
          ldap_msgfree(res);
 
1161
     } else if (msg == LDAP_SERVER_DOWN) {
 
1162
          server->server_down++;
 
1163
          /* do not try V2 in case of server down problems */
 
1164
     }
 
1165
 
 
1166
     if(num_suffixes == 0) {
 
1167
          /* try Umich style config */
 
1168
          statusbar_msg(_("Base search on cn=config"));
 
1169
          msg = ldap_search_s(ld, "cn=config", LDAP_SCOPE_BASE,
 
1170
                              "(objectclass=*)", NULL, 0, &res);
 
1171
          
 
1172
          if(msg == LDAP_SUCCESS) {
 
1173
               e = ldap_first_entry(ld, res);
 
1174
               while (e) {
 
1175
                    char **valptr;
 
1176
                    
 
1177
                    vals = ldap_get_values(ld, e, "database");
 
1178
                    if (vals) {
 
1179
                         for (valptr = vals; valptr && *valptr; valptr++) {
 
1180
                              char *p = *valptr;
 
1181
                                   
 
1182
                              i = 0;
 
1183
                              while (p[i] && p[i] != ':')
 
1184
                                   i++;
 
1185
                              while (p[i] && (p[i] == ':' || p[i] == ' '))
 
1186
                                   i++;
 
1187
                              if (p[i]) {
 
1188
                                   int len = strlen(p + i);
 
1189
                                        
 
1190
                                   while (p[i + len - 1] == ' ')
 
1191
                                        len--;
 
1192
                                   p[i + len] = '\0';
 
1193
 
 
1194
                                   suffixes = g_list_append(suffixes,
 
1195
                                                            g_strdup(p + i));
 
1196
/*                                 add_suffix(entry, ctreeroot, node, p + i); */
 
1197
                                   num_suffixes++;
 
1198
                              }
 
1199
                         }
 
1200
                         ldap_value_free(vals);
 
1201
                    }
 
1202
                    e = ldap_next_entry(ld, e);
 
1203
               }
 
1204
               ldap_msgfree(res);
 
1205
          } else if (msg == LDAP_SERVER_DOWN) {
 
1206
               server->server_down++;
 
1207
          }
 
1208
     }
 
1209
 
 
1210
 
 
1211
     /* add the configured base DN if it's a different one */
 
1212
     if(strlen(server->basedn) && (g_list_find_custom(suffixes, server->basedn, (GCompareFunc) strcmp) == NULL)) {
 
1213
                suffixes = g_list_append(suffixes, g_strdup(server->basedn));
 
1214
                num_suffixes++;
 
1215
     }
 
1216
 
 
1217
     set_normalcursor();
 
1218
     close_connection(server, FALSE);
 
1219
 
 
1220
     statusbar_msg(ngettext("One suffix found", "%d suffixes found",
 
1221
                            num_suffixes),
 
1222
                   num_suffixes);
 
1223
 
 
1224
     return g_list_first(suffixes);
 
1225
}
 
1226
 
 
1227
#ifdef HAVE_LDAP_STR2DN
 
1228
 
 
1229
/* OpenLDAP 2.1 both deprecated and broke ldap_explode_dn in one go (I
 
1230
   won't comment on this).
 
1231
 
 
1232
   NOTE: this is just a first try to adapt code from Pierangelo
 
1233
   Masarati <masarati@aero.polimi.it>
 
1234
*/
 
1235
 
 
1236
gchar**
 
1237
gq_ldap_explode_dn(gchar const* dn,
 
1238
                   int          dummy G_GNUC_UNUSED)
 
1239
{
 
1240
        int i, rc;
 
1241
#if LDAP_API_VERSION > 2004
 
1242
        LDAPDN parts;
 
1243
#else
 
1244
        LDAPDN *parts;
 
1245
#endif
 
1246
        GArray* array = NULL;
 
1247
        gchar **retval = NULL;
 
1248
 
 
1249
        rc = ldap_str2dn(dn, &parts, LDAP_DN_FORMAT_LDAPV3);
 
1250
 
 
1251
        if (rc != LDAP_SUCCESS || parts == NULL) {
 
1252
                return NULL;
 
1253
        }
 
1254
 
 
1255
        array = g_array_new(TRUE, TRUE, sizeof(gchar*));
 
1256
        for(i = 0; parts[i]; i++) {
 
1257
                gchar* part = NULL;
 
1258
                ldap_rdn2str(
 
1259
#if LDAP_API_VERSION > 2004
 
1260
                        parts[i],
 
1261
#else
 
1262
                        parts[0][i],
 
1263
#endif
 
1264
                        &part, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY );
 
1265
                if(part && *part) {
 
1266
                        /* don't append the last (empty) part, to be compatible
 
1267
                         * to ldap_explode_dn() */
 
1268
                        g_array_append_val(array, part);
 
1269
                }
 
1270
        }
 
1271
        retval = (gchar**)array->data;
 
1272
        g_array_free(array, FALSE);
 
1273
        return retval;
 
1274
}
 
1275
 
 
1276
void gq_exploded_free(char **exploded_dn)
 
1277
{
 
1278
     if (exploded_dn) free(exploded_dn);
 
1279
}
 
1280
 
 
1281
#endif
 
1282
 
 
1283
static GtkWidget *enable_uline(GtkWidget *label) {
 
1284
     gtk_label_set_use_underline(GTK_LABEL(label), TRUE);
 
1285
     return label;
 
1286
}
 
1287
 
 
1288
static GtkWidget *bin_enable_uline(GtkWidget *w) {
 
1289
     GtkWidget *l;
 
1290
     l = gtk_bin_get_child(GTK_BIN(w));
 
1291
     enable_uline(l);
 
1292
     return w;
 
1293
}
 
1294
 
 
1295
 
 
1296
GtkWidget *gq_label_new(const char *text) {
 
1297
     return gtk_label_new_with_mnemonic(text);
 
1298
}
 
1299
 
 
1300
 
 
1301
GtkWidget *gq_radio_button_new_with_label(GSList *group,
 
1302
                                          const gchar *label) 
 
1303
{
 
1304
     return bin_enable_uline(gtk_radio_button_new_with_label(group, label));
 
1305
}
 
1306
 
 
1307
GtkWidget *gq_menu_item_new_with_label(const gchar *text) {
 
1308
     return bin_enable_uline(gtk_menu_item_new_with_label(text));
 
1309
}
 
1310
 
 
1311
GtkWidget *gq_check_button_new_with_label(const gchar *text) {
 
1312
     return bin_enable_uline(gtk_check_button_new_with_label(text));
 
1313
}
 
1314
 
 
1315
GtkWidget *gq_button_new_with_label(const gchar *text) {
 
1316
     return bin_enable_uline(gtk_button_new_with_label(text));
 
1317
}
 
1318
 
 
1319
GtkWidget *gq_toggle_button_new_with_label(const gchar *text) {
 
1320
     return bin_enable_uline(gtk_toggle_button_new_with_label(text));
 
1321
}
 
1322