DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T s

⟦d7f8f644e⟧ TextFile

    Length: 72513 (0x11b41)
    Types: TextFile
    Names: »sunint.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« 
        └─⟦de7628f85⟧ 
            └─⟦this⟧ »isode-6.0/others/quipu/uips/sunint/sunint.c« 

TextFile

/* sunint.c - sunview interface to directory */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/others/quipu/uips/sunint/RCS/sunint.c,v 7.0 89/11/23 22:09:19 mrose Rel $";
#endif

/* 
 * $Header: /f/osi/others/quipu/uips/sunint/RCS/sunint.c,v 7.0 89/11/23 22:09:19 mrose Rel $
 *
 *
 * $Log:	sunint.c,v $
 * Revision 7.0  89/11/23  22:09:19  mrose
 * Release 6.0
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


#include <stdio.h>
#include <ctype.h>
#include <sgtty.h>
#include <signal.h>

#include <suntool/sunview.h>
#include <suntool/panel.h>
#include <suntool/tty.h>
#include <suntool/scrollbar.h>
#include <suntool/seln.h>
#include <suntool/textsw.h>
#include <suntool/canvas.h>

#define foreach_av(a) for(eptr = a; eptr != NULLAV; eptr = eptr->avseq_next)
#define foreach_as(a) for(eptr = a; eptr != NULLATTR; eptr = eptr->attr_link)
#define ACTIVE 1
#define PASSIVE 0

#define DESCEND 1
#define READ 2
#define SET_NEW_DN 3
#define BACKTRACK 4
#define LIST 5
#define FORM_SEARCH 6
#define SEARCH 7
#define CURRENT_POS 8
#define SPECIFIED_POS 9
#define IGNORE 10
#define SIZELIMIT 500
#define SMALL_BUF 128

char *bitmap;

#include <varargs.h>
#include "quipu/util.h"
#include "quipu/common.h"
#include "quipu/entry.h"
#include "quipu/dua.h"
#include "quipu/photo.h"

static void yes_no_proc ();
static Frame init_get_arg_frame ();
static int get_data ();
static int get_string_specs ();
Attr_Sequence sun_dua_get_1_as ();

Filter get_filter ();
Filter sun_dua_build_filter ();

Frame base_frame,  search_frame, read_frame, confirm_frame, get_args_form;
static Frame init_get_args_form ();
static Frame init_get_strings_form ();
Panel dua_panel_win, control_panel, search_control_panel, read_control_panel,
search_panel_win;
Textsw read_text_win;
extern Textsw_index textsw_insert();
extern Textsw_index textsw_delete();
Panel_item prompt_for, dua_message,
search_message, read_message,
search_button, quit_button, 
path_title, path_header, root_button, win_below_title,
current_path_item[10],
dua_panel_entry[LOTS],
search_panel_entry[LOTS];

Panel_item        /*  passwd_text_item, yn_text_item, */
oc_text_item;

Panel_setting  put_data_proc (),put_base_object_string  ();
Panel_setting put_filter_text_proc (),put_base_object_select ();
Panel_setting put_search_depth_select (), put_filter_type_select ();

Panel_setting  put_base_object_string_proc ();
Panel_setting put_filter_string_proc (),put_string_base_object_select_proc ();
Panel_setting put_string_search_depth_select ();

Canvas read_canvas;

char current_dn_buffer[SMALL_BUF], dua_textsw_buf[LOTS], arg_data_buf[SMALL_BUF];
char * sun_dua_get_search_string ();

DN user_name;
DN dn;
DN ascend_proc ();
DN sun_dua_getdn ();
char * sun_dua_getyn ();
void set_filter_specs_defaults ();
void set_search_data_info_defaults ();
void quit_proc ();
void make_new_path ();
void back_to_root ();
void list_proc ();
void read_proc ();
void search_proc ();
void form_search_proc ();
void handle_root_button ();
void dua_handle_search_button ();
void clear_panel_win ();
void filt_substr ();
void clear_old_search_results ();
void  put_filter_match_proc ();
void get_oc_bit ();
void get_rdn_bit ();
void clear_old_path ();
void my_picture_print ();

char           *TidyString ();

Attr_Sequence eis_as;
int *approx;
int display_item_count;
int path_element_count;
int search_item_count;

int oidformat;
int args_entered_flag;

extern int PIC_LINESIZE;	/* from libphoto.a */

typedef struct {
	AttributeType attr_struct;
	char print_string[SMALL_BUF];
	char string_value[SMALL_BUF];
	int match_type;
} Temp_attr_bit;

typedef struct {
	int depth;
	DN dn_ptr;
} path_element_data, *PathElementData;


#define TEMPLATE_SIZE 10
#define TEMPLATE_LIST_SIZE 10
#define MAX_TEMPLATES 10

typedef struct {
	/*   char object_class[SMALL_BUF]; */
	char oc_print_string[SMALL_BUF];
	int attr_count;
	Temp_attr_bit Temp_attr_pieces[TEMPLATE_SIZE];
} Template;

Template Template_list[MAX_TEMPLATES];
int no_templates;
Menu search_menu, read_select_menu, path_select_menu, list_select_menu, 
root_button_menu;

typedef struct  {
	char attr_string[SMALL_BUF];
	int match_choice;
} filter_temp_attr;

typedef struct filter_specs_data {
	int search_subset;
	int base_object_select;
	char base_object_string[SMALL_BUF];
	int type;
	int filter_temp_choice;
	int filter_temp_attr_count;
	filter_temp_attr filter_temp_entries[10]; 
} filter_specs;

filter_specs *sun_dua_get_form_data ();
filter_specs the_filter_specs;

typedef struct search_data_info_data {
	int search_subset;
	int base_object_select;
	char base_object_string[SMALL_BUF];
	char filter_string[SMALL_BUF];
} search_data_info, *string_specs;

string_specs sun_dua_get_string_specs ();
search_data_info the_search_data_info;

static struct ds_bind_arg bindarg;
static struct ds_bind_arg bindresult;
static struct ds_bind_error binderr;

sunint_pictures();

int dn_print();
int sunint_dn_comp_print ();
int oc_print ();
char * sunint_error ();
quipu_pe_cmp();

main(argc,argv)

char    **argv;
int     argc;
{ 
	char * TidyString();

	quipu_syntaxes ();
	dsap_init(&argc,&argv);
	set_attribute_syntax (str2syntax("photo"),
		(IFP)pe_cpy,	NULLIFP,
		NULLIFP,        sunint_pictures,
		(IFP)pe_cpy,    quipu_pe_cmp,
		pe_free,        NULLCP,
		NULLIFP,        TRUE );


	(void) fprintf (stderr,"Connecting to dsa, please wait ...\n");


	bindarg.dba_version = DBA_VERSION_V1988;
	bindarg.dba_passwd_len = 0;
	bindarg.dba_passwd[0]  = 0;
	bindarg.dba_dn = NULLDN;
	if (ds_bind (&bindarg, &binderr, &bindresult) != OK) {
		fatal (-1,"Can't get connection");
	}
	user_name = NULLDN;

	set_up_templates ();

	base_frame = window_create ((Window) NULL, FRAME, 
	    FRAME_LABEL, "QUIPU Sunview DUA Interface",0);

	search_frame = window_create (base_frame, FRAME, 
	    FRAME_LABEL, "Search Results",0);

	read_frame = window_create (base_frame, FRAME, 
	    FRAME_LABEL, "Read Results",0);
	init_control_panel ();
	init_main_panel ();
	window_fit (base_frame);
	(void) window_set (base_frame, WIN_X, 10, WIN_Y, 10, 0);

	init_search_control_panel ();
	init_search_panel_win ();
	window_fit (search_frame);
	(void) window_set (search_frame, WIN_X, 150, WIN_Y, 150, 0);


	init_read_control_panel ();
	init_read_canvas ();
	init_read_text_win ();
	window_fit (read_frame);
	(void) window_set (read_frame, WIN_X, 250, WIN_Y, 250, 0);


	make_path_select_menu ();
	make_search_menu ();
	make_list_select_menu ();
	make_read_select_menu ();
	make_root_button_menu ();


	window_main_loop (base_frame);

}


set_up_templates ()

/* this procedure can later be replaced by a suitable tailoring procedure */

{
	(void) strcpy (Template_list[0].oc_print_string , "Country");
	Template_list[0].attr_count = 1;
	(void) strcpy (Template_list[0].Temp_attr_pieces[0].print_string , "Country: ");
	(void) strcpy (Template_list[0].Temp_attr_pieces[0].string_value , "c");
	Template_list[0].Temp_attr_pieces[0].attr_struct = AttrT_new ("c");

	(void) strcpy (Template_list[1].oc_print_string , "Organization");
	Template_list[1].attr_count = 4;
	(void) strcpy (Template_list[1].Temp_attr_pieces[0].print_string , "Organization: ");
	(void) strcpy (Template_list[1].Temp_attr_pieces[0].string_value , "o");
	Template_list[1].Temp_attr_pieces[0].attr_struct = AttrT_new ("o");

	(void) strcpy (Template_list[1].Temp_attr_pieces[1].print_string , "Business Category: ");
	(void) strcpy (Template_list[1].Temp_attr_pieces[1].string_value , "businessCategory");
	Template_list[1].Temp_attr_pieces[1].attr_struct = AttrT_new ("businessCategory");

	(void) strcpy (Template_list[1].Temp_attr_pieces[2].print_string , "Locality Name: ");
	(void) strcpy (Template_list[1].Temp_attr_pieces[2].string_value , "localityName");
	Template_list[1].Temp_attr_pieces[2].attr_struct = AttrT_new ("localityName");

	(void) strcpy (Template_list[1].Temp_attr_pieces[3].print_string , "State or Province Name: ");
	(void) strcpy (Template_list[1].Temp_attr_pieces[3].string_value , "stateOrProvinceName");
	Template_list[1].Temp_attr_pieces[3].attr_struct = AttrT_new ("stateOrProvinceName");

	(void) strcpy (Template_list[2].oc_print_string , "Organizational Unit");
	Template_list[2].attr_count = 3;
	(void) strcpy (Template_list[2].Temp_attr_pieces[0].print_string , "Organizational Unit: ");
	(void) strcpy (Template_list[2].Temp_attr_pieces[0].string_value , "ou");
	Template_list[2].Temp_attr_pieces[0].attr_struct = AttrT_new ("ou");

	(void) strcpy (Template_list[2].Temp_attr_pieces[1].print_string , "Business Category: ");
	(void) strcpy (Template_list[2].Temp_attr_pieces[1].string_value , "businessCategory");
	Template_list[2].Temp_attr_pieces[1].attr_struct = AttrT_new ("businessCategory");

	(void) strcpy (Template_list[2].Temp_attr_pieces[2].print_string , "Locality Name: ");
	(void) strcpy (Template_list[2].Temp_attr_pieces[2].string_value , "localityName");
	Template_list[2].Temp_attr_pieces[2].attr_struct = AttrT_new ("localityName");

	(void) strcpy (Template_list[3].oc_print_string , "Person");
	Template_list[3].attr_count = 3;
	(void) strcpy (Template_list[3].Temp_attr_pieces[0].print_string , "Name of Person: ");
	(void) strcpy (Template_list[3].Temp_attr_pieces[0].string_value , "cn");
	Template_list[3].Temp_attr_pieces[0].attr_struct = AttrT_new ("cn");

	(void) strcpy (Template_list[3].Temp_attr_pieces[1].print_string , "user id: ");
	(void) strcpy (Template_list[3].Temp_attr_pieces[1].string_value , "userid");
	Template_list[3].Temp_attr_pieces[1].attr_struct = AttrT_new ("userid");

	(void) strcpy (Template_list[3].Temp_attr_pieces[2].print_string , "Surname: ");
	(void) strcpy (Template_list[3].Temp_attr_pieces[2].string_value , "surname");
	Template_list[3].Temp_attr_pieces[2].attr_struct = AttrT_new ("surname");

	no_templates = 4;
}


/* Bits of code to create the menus to follow next ....*/


make_search_menu ()
{
	int i;
	search_menu = menu_create (0);
	for (i = 0; i < no_templates; i++)
	{ 
		(void) menu_set(search_menu, 
		    MENU_APPEND_ITEM,
		    menu_create_item (
		    MENU_STRING, Template_list[i].oc_print_string,
		    MENU_FEEDBACK, TRUE,
		    MENU_VALUE, i,
		    0),
		    0);
	}

	(void) menu_set(search_menu, 
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "General Search",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, i,
	    0),
	    0);
}

make_read_select_menu ()
{
	read_select_menu = menu_create (0);
	(void) menu_set(read_select_menu, 
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "set new position",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, SET_NEW_DN,
	    0),
	    0);

	(void) menu_set(read_select_menu, 
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "show details",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, READ,
	    0),
	    0);
}

make_path_select_menu ()
{
	path_select_menu = menu_create (0);
	(void) menu_set(path_select_menu, 
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "backtrack to here",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, BACKTRACK,
	    0),
	    0);

	(void) menu_set(path_select_menu, 
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "show details",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, READ,
	    0),
	    0);


	(void) menu_set(path_select_menu, 
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "show children",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, LIST,

	    0), 
	    0);
}

make_root_button_menu ()
{
	root_button_menu = menu_create (0);
	(void) menu_set(root_button_menu, 
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "backtrack to here",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, BACKTRACK,
	    0),
	    0);



	(void) menu_set(root_button_menu, 
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "show children",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, LIST,

	    0),
	    0);
}






make_list_select_menu ()
{
	list_select_menu = menu_create (0);
	(void) menu_set(list_select_menu,  
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "down to here",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, DESCEND,
	    0),
	    0);

	(void) menu_set(list_select_menu, 
	    MENU_APPEND_ITEM,
	    menu_create_item (
	    MENU_STRING, "show details",
	    MENU_FEEDBACK, TRUE,
	    MENU_VALUE, READ,
	    0),
	    0);
}


/* bits of code to set up the various subwindows now follow */

init_search_control_panel ()
{
	search_control_panel = window_create (search_frame, PANEL, WIN_ROWS, 6 ,
	    WIN_COLUMNS, 90,0);
	search_message = panel_create_item (search_control_panel , PANEL_TEXT,
	    PANEL_ITEM_X,   ATTR_COL(1),
	    PANEL_ITEM_Y,   ATTR_ROW(1),
	    PANEL_LAYOUT,   PANEL_HORIZONTAL,
	    PANEL_LABEL_BOLD,  TRUE,
	    PANEL_LABEL_STRING, "Message : ",
	    PANEL_VALUE,      "Search Results " ,
	    0);



}


init_read_control_panel ()
{
	read_control_panel = window_create (read_frame, PANEL, WIN_ROWS, 15 ,
	    WIN_COLUMNS, 50,0);
	read_message = panel_create_item (read_control_panel , PANEL_TEXT,
	    PANEL_ITEM_X,   ATTR_COL(1),
	    PANEL_ITEM_Y,   ATTR_ROW(1),
	    PANEL_LAYOUT,   PANEL_HORIZONTAL,
	    PANEL_LABEL_BOLD,  TRUE,
	    PANEL_LABEL_STRING, "Message : ",
	    PANEL_VALUE,      "Entry Information " ,
	    0);



}


init_control_panel ()
{ 
	int i;

	control_panel = window_create (base_frame, PANEL, WIN_ROWS, 12 ,
	    WIN_COLUMNS, 90,0);

	dua_message = panel_create_item (control_panel , PANEL_TEXT,
	    PANEL_ITEM_X,   ATTR_COL(15),
	    PANEL_ITEM_Y,   ATTR_ROW(0),
	    PANEL_LAYOUT,   PANEL_HORIZONTAL,
	    PANEL_LABEL_BOLD,  TRUE,
	    PANEL_LABEL_STRING, "Message : ",
	    PANEL_VALUE,      "" ,
	    0);

	path_title = panel_create_item (control_panel , PANEL_BUTTON,
	    PANEL_ITEM_X,   ATTR_COL(1),
	    PANEL_ITEM_Y,   ATTR_ROW(1),
	    PANEL_LABEL_BOLD,  TRUE,
	    PANEL_LABEL_STRING, "CURRENT PATH",
	    0);

	path_header = panel_create_item (control_panel , PANEL_BUTTON,
	    PANEL_ITEM_X,   ATTR_COL(1),
	    PANEL_ITEM_Y,   ATTR_ROW(2),
	    PANEL_LABEL_BOLD,  TRUE,
	    PANEL_LABEL_STRING, "RDN                OBJECT CLASS",
	    0);

	root_button = panel_create_item (control_panel , PANEL_BUTTON,
	    PANEL_ITEM_X,   ATTR_COL(1),
	    PANEL_ITEM_Y,   ATTR_ROW(3),
	    PANEL_LABEL_BOLD,  TRUE,
	    PANEL_LABEL_STRING, "Root",
	    PANEL_EVENT_PROC, handle_root_button,
	    0);


	search_button = panel_create_item (control_panel,
	    PANEL_BUTTON,
	    PANEL_ITEM_X, ATTR_COL(60),
	    PANEL_ITEM_Y, ATTR_ROW(2),
	    PANEL_LABEL_IMAGE, panel_button_image(control_panel, 
		    "SEARCH", 10 , (Pixfont *)NULL)   ,	   
	    PANEL_SHOW_ITEM,  TRUE,
	    PANEL_EVENT_PROC , dua_handle_search_button,
	    0);

	quit_button = panel_create_item (control_panel,
	    PANEL_BUTTON,
	    PANEL_ITEM_X, ATTR_COL(75),
	    PANEL_ITEM_Y, ATTR_ROW(2),
	    PANEL_LABEL_IMAGE, panel_button_image(control_panel, 
	    "QUIT", 10 , (Pixfont *)NULL)   ,	   
	    PANEL_SHOW_ITEM,  TRUE,
	    PANEL_NOTIFY_PROC , quit_proc,
	    0);

	win_below_title = panel_create_item (control_panel , PANEL_BUTTON,
	    PANEL_ITEM_X,   ATTR_COL(1),
	    PANEL_ITEM_Y,   ATTR_ROW(11),
	    PANEL_LABEL_BOLD,  TRUE,
	    PANEL_SHOW_ITEM,  TRUE,
	    PANEL_LABEL_STRING, "Object Classes and rdn's of children underneath",
	    0);

	for (i = 0; i < 10; i++)
		current_path_item [i] = (Panel_item ) NULL;
	path_element_count = 0;


}


init_read_text_win ()
{
	read_text_win = window_create (read_frame, TEXTSW, WIN_ROWS,
	    15,WIN_COLUMNS, 100, 
	    WIN_BELOW, read_control_panel,
	    WIN_X, 0,
	    TEXTSW_LINE_BREAK_ACTION, TEXTSW_WRAP_AT_WORD, 
	    0);

}

init_search_panel_win ()
{
	int i;
	search_panel_win = window_create (search_frame, 
	    PANEL, WIN_ROWS,20,
	    WIN_COLUMNS, 90,  WIN_X, 0,
	    WIN_BELOW, search_control_panel,
	    WIN_VERTICAL_SCROLLBAR, scrollbar_create(0),0);
	for (i = 0; i < LOTS; i++)
		search_panel_entry [i] = (Panel_item ) NULL;
	search_item_count = 0;

}

init_read_canvas ()
{
	read_canvas = window_create (read_frame, CANVAS,
	    CANVAS_AUTO_SHRINK, FALSE,
	    WIN_COLUMNS, 50,
	    WIN_ROWS, 20,
	    WIN_RIGHT_OF, read_control_panel,
	    WIN_VERTICAL_SCROLLBAR, scrollbar_create(0),
	    WIN_HORIZONTAL_SCROLLBAR, scrollbar_create(0),
	    0);
}


init_main_panel ()
{
	int i;
	dua_panel_win = window_create (base_frame, PANEL, WIN_ROWS,
	    20,WIN_COLUMNS, 90,  WIN_X, 0,
	    WIN_BELOW, control_panel,
	    WIN_VERTICAL_SCROLLBAR, scrollbar_create(0),0);
	for (i = 0; i < LOTS; i++)
		dua_panel_entry [i] = (Panel_item ) NULL;
	display_item_count = 0;

}



/* procedures for displaying the menus associated with various buttons */

void dua_handle_search_button(item,event)
Panel_item item;
Event *event;
{
	int choice;
	if (event_id(event) ==
	    MS_RIGHT && event_is_down (event)) {
		choice =(int)menu_show (search_menu, control_panel, event, 0);
		if (choice < no_templates)
		{
			form_search_proc (choice);
		}
		else
		{
			search_proc ();
		}
	}
	else
		(void) panel_default_handle_event (item,event);

}

handle_search_select(item,event)
Panel_item item;
Event *event;
{ 
	int choice;
	if (event_id(event) ==
	    MS_RIGHT && event_is_down (event)) {
		choice =(int) menu_show (read_select_menu, search_panel_win, event, 0);
		switch (choice) {  
		case SET_NEW_DN:
			set_new_dn_proc (item);
			break;
		case READ:
			read_proc (item);
			break;
		}
	}
	else
		(void) panel_default_handle_event (item,event);

}

void handle_path_select_button (item, event)
Panel_item item;
Event *event;
{ 
	Menu_item mitem;
	int choice;
	PathElementData client_data;
	if (event_id(event) ==
	    MS_RIGHT && event_is_down (event)) {
		client_data = (PathElementData) panel_get (item, PANEL_CLIENT_DATA);
		if (client_data->depth < (path_element_count))
		{
			mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 3);
			(void) menu_set (mitem, MENU_INACTIVE, TRUE, 0);
			mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 2);
			(void) menu_set (mitem, MENU_INACTIVE, FALSE, 0);
			mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 1);
			(void) menu_set (mitem, MENU_INACTIVE, FALSE, 0);
		}
		else
		{
			mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 3);
			(void) menu_set (mitem, MENU_INACTIVE, FALSE, 0);
			mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 2);
			(void) menu_set (mitem, MENU_INACTIVE, FALSE, 0);
			mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 1);
			(void) menu_set (mitem, MENU_INACTIVE, TRUE, 0);
		}

		choice =(int) menu_show (path_select_menu, control_panel , event, 0);
		switch (choice) { 
		case BACKTRACK:
			backtrack_proc (item);
			break;
		case READ:
			read_proc (item);
			break;
		case LIST:
			list_proc ();
			break;
		}
	}
	else
		(void) panel_default_handle_event (item,event);


}


void quit_proc ()
{  
/*
	(void) textsw_delete (read_text_win, (Textsw_index)0 , (Textsw_index)window_get ((Window)read_text_win, TEXTSW_LENGTH));
*/
	textsw_reset (read_text_win,(Textsw_index)0 , (Textsw_index)window_get ((Window)read_text_win, TEXTSW_LENGTH));
	(void) window_set (search_frame, FRAME_NO_CONFIRM, TRUE, 0);
	(void) window_set (read_frame, FRAME_NO_CONFIRM, TRUE, 0);
	(void) window_destroy (search_frame);
	(void) window_destroy (read_frame);
	(void) ds_unbind ();
	exit (0);
}

void handle_root_button (item, event)
Panel_item item;
Event *event;
{ 
	Menu_item mitem;
	int choice;
	if (dn == NULLDN)
	{
		mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 1);
		(void) menu_set (mitem, MENU_INACTIVE, TRUE, 0);
		mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 2);
		(void) menu_set (mitem, MENU_INACTIVE, TRUE, 0);
		mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 3);
		(void) menu_set (mitem, MENU_INACTIVE, FALSE, 0);
	}
	else
	{
		mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 1);
		(void) menu_set (mitem, MENU_INACTIVE, FALSE, 0);
		mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 2);
		(void) menu_set (mitem, MENU_INACTIVE, TRUE, 0);
		mitem = menu_get (path_select_menu, MENU_NTH_ITEM, 3);
		(void) menu_set (mitem, MENU_INACTIVE, TRUE, 0);
	}



	if (event_id(event) ==
	    MS_RIGHT && event_is_down (event)) {
		choice =(int) menu_show (path_select_menu, control_panel , event, 0);
		switch (choice) { 
		case BACKTRACK:
			back_to_root();
			break;
		case LIST:
			list_proc ();
			break;
		}
	}
	else
		(void) panel_default_handle_event (item,event);

}


handle_list_select (item, event)
Panel_item item;
Event *event;
{
	int choice;
	if (event_id(event) ==
	    MS_RIGHT && event_is_down (event)) {
		choice =(int) menu_show (list_select_menu, dua_panel_win , event, 0);
		switch (choice) {  
		case DESCEND:
			descend_proc (item);
			break;
		case READ:
			read_proc (item);
			break;
		}
	}
	else
		(void) panel_default_handle_event (item,event);

}


/* dua action procedures now follow*/
/* each parocedure is associated with a specific button in the*/
/* control panel of the dua interface or menu item */


descend_proc (item)
Panel_item item;
{ 
	int i;
	PathElementData client_data, got_client_data;
	char  panel_label_string[SMALL_BUF];
	client_data = (PathElementData) malloc (sizeof (path_element_data));
	i = path_element_count;
	client_data->depth = i + 1;
	got_client_data = (PathElementData) panel_get (item, PANEL_CLIENT_DATA);
	client_data->dn_ptr = dn_cpy (got_client_data->dn_ptr);
	dn_free (dn);
	dn = dn_cpy (got_client_data->dn_ptr);
	(void) strcpy (panel_label_string, (panel_get (item, PANEL_LABEL_STRING)));
	current_path_item[i] = panel_create_item (control_panel,
	    PANEL_BUTTON,
	    PANEL_ITEM_X, ATTR_COL(1),
	    PANEL_ITEM_Y, ATTR_ROW(i + 4),
	    PANEL_LABEL_STRING, panel_label_string,
	    PANEL_CLIENT_DATA, client_data,
	    PANEL_SHOW_ITEM,  TRUE,
	    PANEL_EVENT_PROC , handle_path_select_button,
	    0);
	(void) panel_set (current_path_item[i], PANEL_PAINT, PANEL_CLEAR, 0);
	path_element_count++;


	for ( i = 0; i < display_item_count; i++)
		(void) panel_set (dua_panel_entry[i], PANEL_SHOW_ITEM, FALSE, 0);
}



set_new_dn_proc(item)
Panel_item item;
{
	DN newdn ;
	int i;
	PathElementData client_data;
	client_data = (PathElementData) panel_get (item, PANEL_CLIENT_DATA);
	newdn = dn_cpy (client_data->dn_ptr);
	if (search_item_count != 0)
	{
		for ( i = 0; i < search_item_count; i++ )
		{ 
			(void) panel_set (search_panel_entry[i], PANEL_SHOW_ITEM, FALSE,0);
		}
	}
	(void) panel_set (search_message, PANEL_VALUE, " ", 0);
	make_new_path (newdn);
	dn_free (dn);
	dn = newdn;
	for ( i = 0; i < search_item_count; i++)
		(void) panel_set (search_panel_entry[i], PANEL_SHOW_ITEM, FALSE, 0);
}


backtrack_proc(item)
Panel_item item;
{
	DN newdn ;
	int i, pos;
	PathElementData client_data;
	client_data = (PathElementData) panel_get (item, PANEL_CLIENT_DATA);
	newdn = dn_cpy (client_data->dn_ptr);
	pos = client_data->depth;
	clear_old_path (pos);
	dn_free (dn);
	dn = newdn;
	for ( i = 0; i < display_item_count; i++)
		(void) panel_set (dua_panel_entry[i], PANEL_SHOW_ITEM, FALSE, 0);
}

/* This procedure uses the dsa search procedure to search forall */
/* entries at the next level down and returns a list of the dn's of all such entries */
/* together with the value of the corresponding object class. */
/* The object class descriptor together with the rdn get printed*/
/* out for each entry. */

void list_proc ()
{ 
	static struct ds_search_arg search_arg =
	{
		default_common_args,
		NULLDN,
		SRA_ONELEVEL,
		NULLFILTER, /* filter */
		FALSE,
		{       /* eis */
			FALSE,
			NULLATTR,
			EIS_ATTRIBUTESANDVALUES
		}
	};

	struct DSError error;
	struct ds_search_result result;
	int i;
	extern int sizelimit;
	PathElementData client_data;
	char panel_label_string[SMALL_BUF];
	DN eptr, trail;
	Filter simple_filter;

	search_arg.sra_common.ca_servicecontrol.svc_sizelimit = SIZELIMIT;
	search_arg.sra_baseobject = dn;
	search_arg.sra_eis.eis_select = as_comp_new (AttrT_new ("objectclass"), NULLAV, NULLACL_INFO);

	simple_filter = filter_alloc ();
	simple_filter->flt_next = NULLFILTER;
	simple_filter->flt_type = FILTER_AND;
	simple_filter->flt_un.flt_un_filter = NULLFILTER;
	search_arg.sra_filter = simple_filter;

	(void) panel_set(dua_message, PANEL_VALUE, "",0);

	if (ds_search (&search_arg,&error,&result) != DS_OK) {
		/* deal with error */
		(void) panel_set(dua_message, PANEL_VALUE, sunint_error(&error),0);
	} else {
		(void) panel_set(dua_message, PANEL_VALUE, "list operation succeeded",0);
		clear_panel_win ();
		i = 0;

		/* use data */
		correlate_search_results (&result);

		if (result.CSR_entries != NULLENTRYINFO)
		{
			EntryInfo *ptr;

			if (result.CSR_common.cr_aliasdereferenced)
			{
				(void) strcat (panel_label_string , "Alias dereferenced - base object is");
				(void) dn_decode (result.CSR_object);
				sunint_print (dn_print, (caddr_t)result.CSR_object, panel_label_string);
				dn_free (result.CSR_object);
				(void) panel_set(dua_message, PANEL_VALUE, panel_label_string,0);
			}

			for (ptr=result.CSR_entries;ptr!=NULLENTRYINFO;ptr=ptr->ent_next)
			{
				bzero (panel_label_string, SMALL_BUF);
				(void) dn_decode (ptr->ent_dn);
				(void) as_decode (ptr->ent_attr);

				client_data = (PathElementData) malloc (sizeof (path_element_data));
				client_data->depth = i;
				client_data->dn_ptr = dn_cpy (ptr->ent_dn);

				for (eptr = ptr->ent_dn; eptr != NULLDN; eptr = eptr->dn_parent)
					trail = eptr;
				sunint_print (sunint_dn_comp_print, (caddr_t)trail, panel_label_string);
				if (ptr->ent_attr != NULLATTR) {
					(void) strcat (panel_label_string, "  ");
					sunint_print (oc_print, (caddr_t)ptr->ent_attr->attr_value, panel_label_string);
				}

				dua_panel_entry[i] = panel_create_item (dua_panel_win,
				    PANEL_BUTTON,
				    PANEL_ITEM_X, ATTR_COL(0),
				    PANEL_ITEM_Y, ATTR_ROW(i),
				    PANEL_LABEL_STRING, panel_label_string,
				    PANEL_CLIENT_DATA, client_data ,
				    PANEL_EVENT_PROC, handle_list_select,
				    PANEL_SHOW_ITEM,  TRUE,
				    0);
				(void) panel_set (dua_panel_entry[i], PANEL_PAINT, PANEL_CLEAR, 0);
				i++;

				dn_free  (ptr->ent_dn);
				free ((char *)ptr);
				as_free (ptr->ent_attr);
				free ((char *)ptr);
			}
			if (result.CSR_limitproblem != LSR_NOLIMITPROBLEM){
				dua_panel_entry[i] = panel_create_item (dua_panel_win,
				    PANEL_BUTTON,
				    PANEL_ITEM_X, ATTR_COL(0),
				    PANEL_ITEM_Y, ATTR_ROW(i),
				    PANEL_LABEL_IMAGE, panel_button_image(dua_panel_win,
				    "Limit problem", 20 , (Pixfont *)0),
				    PANEL_CLIENT_DATA, ACTIVE,
				    PANEL_SHOW_ITEM,  TRUE,
				    0);
				(void) panel_set (dua_panel_entry[i], PANEL_PAINT, PANEL_CLEAR, 0);
				i++;
			}
			(void) panel_update_scrolling_size (dua_panel_win);
			display_item_count = i;
		}

		/*   entry_info_free (result.CSR_entries, 1); */
		as_free (search_arg.sra_eis.eis_select);
		filter_free (search_arg.sra_filter);
	}
}




void read_proc (item)
Panel_item item;
{
	PathElementData client_data;
	static struct ds_read_arg read_arg =
	{
		default_common_args,
		NULLDN,   /* read_arg DN */
		{       /* entry info selection */
			TRUE,
			NULLATTR,
			EIS_ATTRIBUTESANDVALUES
		}
	};

	struct ds_read_result   result;
	struct DSError          error;
	Pixwin *pw;
	char      *msg1 = "No attributes !!!", 
		  *msg2 = "Result of look up ...",
		  *msg3 = "Result of look up ...\n(Alias dereferenced)";

	client_data = ( PathElementData) panel_get (item, PANEL_CLIENT_DATA);

	read_arg.rda_object = client_data->dn_ptr;

	(void) panel_set(dua_message, PANEL_VALUE, "",0);

	if (ds_read (&read_arg,&error,&result) != DS_OK) {
		/* deal with error */
		(void) panel_set(dua_message, PANEL_VALUE, sunint_error(&error),0);
	} else {                /* use data */
		(void) textsw_delete ((Window)read_text_win, (Textsw_index)0 , (Textsw_index)window_get (read_text_win, TEXTSW_LENGTH));
		(void) window_set (read_frame, WIN_SHOW, TRUE, 0);

		pw = canvas_pixwin (read_canvas);
		(void) pw_writebackground (pw, 20 , 20 , 300, 300 , PIX_CLR);
		bzero (dua_textsw_buf, LOTS);

		if (result.rdr_entry.ent_attr == NULLATTR) {
			(void) textsw_insert (read_text_win, msg1, (long)strlen(msg1));
			return;
		}
		if (result.rdr_common.cr_aliasdereferenced)
			(void) panel_set (read_control_panel, PANEL_VALUE, msg3, 0);
		else
			(void) panel_set (read_control_panel, PANEL_VALUE, msg2, 0);

		add_entry_info_str (&result.rdr_entry, dua_textsw_buf);
		(void) textsw_insert (read_text_win, dua_textsw_buf, (long)strlen(dua_textsw_buf));
		entryinfo_comp_free (&result.rdr_entry,0);
	}
}


void set_filter_specs_defaults ()
{ 
	int i;
	the_filter_specs.search_subset = SRA_ONELEVEL;
	the_filter_specs.type = FILTER_OR;
	the_filter_specs.base_object_select = CURRENT_POS;
	for (i = 0; i < 10; i++)
	{ 
		the_filter_specs.filter_temp_entries[i].match_choice = FILTERITEM_APPROX;
		(void) strcpy (the_filter_specs.filter_temp_entries[i].attr_string , "\n");
	}
}

void set_search_data_info_defaults ()
{ 
	the_search_data_info.search_subset = SRA_ONELEVEL;
	the_search_data_info.base_object_select = CURRENT_POS;
	(void) strcpy (the_search_data_info.base_object_string , "\n");
	(void) strcpy (the_search_data_info.filter_string , "\n");

}


void search_proc()

{
	static struct ds_search_arg search_arg =
	{
		default_common_args,
		NULLDN,
		SRA_ONELEVEL,
		NULLFILTER, /* filter */
		FALSE,
		{       /* eis */
			FALSE,
			NULLATTR,
			EIS_ATTRIBUTESANDVALUES
		}
	};

	struct DSError error;
	struct ds_search_result result;
	char * name;
	string_specs got_string_specs;
	extern int sizelimit;
	char panel_label_string[SMALL_BUF];
	PathElementData client_data;
	int i;
	EntryInfo *ptr;
	DN eptr, trail;
	i = 0;
/*
	if ((int)window_get (search_frame, WIN_SHOW) != TRUE)
*/
		(void) window_set (search_frame, WIN_SHOW, TRUE, 0);
	clear_old_search_results ();
	search_arg.sra_common.ca_servicecontrol.svc_sizelimit = SIZELIMIT;
	set_search_data_info_defaults ();
	got_string_specs = sun_dua_get_string_specs ();
	if (got_string_specs == (search_data_info *)NULL) {
		(void) panel_set(dua_message, PANEL_VALUE, "no filter specified",0);
		return;
	}

	if (the_search_data_info.base_object_select == CURRENT_POS)
		search_arg.sra_baseobject = dn;
	else
		search_arg.sra_baseobject = str2dn (the_search_data_info.base_object_string);
	search_arg.sra_eis.eis_select = as_comp_new (AttrT_new ("objectclass"), NULLAV, NULLACL_INFO);
	if (the_search_data_info.search_subset == SRA_ONELEVEL)
		search_arg.sra_subset = SRA_ONELEVEL;
	else
		search_arg.sra_subset = SRA_WHOLESUBTREE;

	(void) panel_set(dua_message, PANEL_VALUE, "",0);

	name = the_search_data_info.filter_string ;

	if ((search_arg.sra_filter = get_filter (name)) == NULLFILTER) {
		(void) panel_set(dua_message, PANEL_VALUE, "incorrectly specified filter",0);
		return;
	}


	if (ds_search (&search_arg,&error,&result) != DS_OK) {
		/* deal with error */
		(void) panel_set(dua_message, PANEL_VALUE, "search error ",0);
		(void) panel_set (search_message, PANEL_VALUE, sunint_error(&error),0);
	} else {
		correlate_search_results (&result);

		if (result.CSR_entries != NULLENTRYINFO) {
			/* pop the search result  display frame if not already showing */
			if ((int)window_get (search_frame, WIN_SHOW) != TRUE)
				(void) window_set (search_frame, WIN_SHOW, TRUE, 0);
			search_item_count = 0;
			(void) panel_set (search_message, PANEL_VALUE, "Result of search is ...",0);
			if (result.CSR_common.cr_aliasdereferenced)
			{
				(void) strcat (panel_label_string , "Alias dereferenced - base object is");
				(void) dn_decode (result.CSR_object);
				sunint_print (dn_print, (caddr_t)result.CSR_object, panel_label_string);
				dn_free (result.CSR_object);
				(void) panel_set(search_message, PANEL_VALUE, panel_label_string,0);
			}

			for (ptr=result.CSR_entries;ptr!=NULLENTRYINFO;ptr=ptr->ent_next)
			{
				bzero (panel_label_string, SMALL_BUF);
				(void) dn_decode (ptr->ent_dn);
				(void) as_decode (ptr->ent_attr);

				client_data = (PathElementData) malloc (sizeof (path_element_data));
				client_data->depth = i;
				client_data->dn_ptr = dn_cpy (ptr->ent_dn);
				for (eptr = ptr->ent_dn; eptr != NULLDN; eptr = eptr->dn_parent)
					trail = eptr;
				(void) strcat (panel_label_string, "   ");
				sunint_print (sunint_dn_comp_print, (caddr_t) trail, panel_label_string);

				if (ptr->ent_attr != NULLATTR) {
					(void) strcat (panel_label_string, "  ");
					sunint_print (oc_print, (caddr_t)ptr->ent_attr->attr_value, panel_label_string);
				}
				search_panel_entry[i] = panel_create_item (search_panel_win,
				    PANEL_BUTTON,
				    PANEL_ITEM_X, ATTR_COL(0),
				    PANEL_ITEM_Y, ATTR_ROW(i),
				    PANEL_LABEL_STRING, panel_label_string,
				    PANEL_CLIENT_DATA, client_data ,
				    PANEL_EVENT_PROC, handle_search_select,
				    PANEL_SHOW_ITEM,  TRUE,
				    0);
				(void) panel_set (search_panel_entry[i], PANEL_PAINT, PANEL_CLEAR, 0);
				i++;

				dn_free  (ptr->ent_dn);
				free ((char *)ptr);
				as_free (ptr->ent_attr);
				free ((char *)ptr);
			}
			if (result.CSR_limitproblem != LSR_NOLIMITPROBLEM){
				(void) panel_set (search_message, PANEL_VALUE, "may have limit problems ",0);
				(void) panel_set (dua_message, PANEL_VALUE, "possible limit problems ",0);
			}
			(void) panel_update_scrolling_size (search_panel_win);
			search_item_count = i;
		}
		else
			(void) panel_set (search_message, PANEL_VALUE, "no matches found ",0);


		/*   entry_info_free (result.CSR_entries, 1); */
		as_free (search_arg.sra_eis.eis_select);
		filter_free (search_arg.sra_filter);


	}
}



void form_search_proc(choice)
int choice;
{
	static struct ds_search_arg search_arg =
	{
		default_common_args,
		NULLDN,
		SRA_ONELEVEL,
		NULLFILTER, /* filter */
		FALSE,
		{       /* eis */
			FALSE,
			NULLATTR,
			EIS_ATTRIBUTESANDVALUES
		}
	};

	struct DSError error;
	struct ds_search_result result;
	filter_specs * specs;
	char panel_label_string[SMALL_BUF];
	extern int sizelimit;
	PathElementData client_data;
	EntryInfo *ptr;
	int i;
	DN eptr,trail;

	i = 0;
	if ((int)window_get (search_frame, WIN_SHOW) != TRUE)
		(void) window_set (search_frame, WIN_SHOW, TRUE, 0);

	clear_old_search_results ();
	set_filter_specs_defaults ();

	search_arg.sra_common.ca_servicecontrol.svc_sizelimit = sizelimit;
	eis_as = NULLATTR;

	(void) panel_set(dua_message, PANEL_VALUE, "",0);

	specs = sun_dua_get_form_data (choice);
	if (specs == (filter_specs *)NULL) {
		(void) panel_set(dua_message, PANEL_VALUE, "no filter specified",0);
		return;
	}
	/* might later want to modify sun_dua_build_filter so that the filter specs are */
	/* not a global variable, but are created dynamically */
	if ((search_arg.sra_filter = sun_dua_build_filter ()) == NULLFILTER) {
		(void) panel_set(dua_message, PANEL_VALUE, "incorrect filter description",0);
		return;
	}
	if(the_filter_specs.base_object_select == CURRENT_POS)
		search_arg.sra_baseobject = dn;
	else
		search_arg.sra_baseobject = str2dn (the_filter_specs.base_object_string);
	search_arg.sra_subset = the_filter_specs.search_subset;
	search_arg.sra_eis.eis_select = as_comp_new (AttrT_new ("objectclass"), NULLAV, NULLACL_INFO);
	if (ds_search (&search_arg,&error,&result) != DS_OK) {
		/* deal with error */
		(void) panel_set(dua_message, PANEL_VALUE, "search error ",0);
		(void) panel_set(search_message, PANEL_VALUE, sunint_error(&error),0);
	} else {
		correlate_search_results (&result);

		if (result.CSR_entries != NULLENTRYINFO) {
			/* pop the search result  display frame if not already showing */
			if ((int)window_get (search_frame, WIN_SHOW) != TRUE)
				(void) window_set (search_frame, WIN_SHOW, TRUE, 0);
			search_item_count = 0;
			(void) panel_set (search_message, PANEL_VALUE, "Result of search is ...",0);
			if (result.CSR_common.cr_aliasdereferenced)
			{
				(void) strcat (panel_label_string , "Alias dereferenced - base object is");
				(void) dn_decode (result.CSR_object);
				sunint_print (dn_print, (caddr_t)result.CSR_object, panel_label_string);
				dn_free (result.CSR_object);
				(void) panel_set(search_message, PANEL_VALUE, panel_label_string,0);
			}

			for (ptr=result.CSR_entries;ptr!=NULLENTRYINFO;ptr=ptr->ent_next)
			{
				bzero (panel_label_string, SMALL_BUF);
				(void) dn_decode (ptr->ent_dn);
				(void) as_decode (ptr->ent_attr);

				client_data = (PathElementData) malloc (sizeof (path_element_data));
				client_data->depth = i;
				client_data->dn_ptr = dn_cpy (ptr->ent_dn);


				for (eptr = ptr->ent_dn; eptr != NULLDN; eptr = eptr->dn_parent)
					trail = eptr;
				(void) strcat (panel_label_string, "   ");
				sunint_print (sunint_dn_comp_print, (caddr_t) trail, panel_label_string);
				if (ptr->ent_attr != NULLATTR) {
					(void) strcat (panel_label_string, "  ");
					sunint_print (oc_print, (caddr_t)ptr->ent_attr->attr_value, panel_label_string);
				}

				search_panel_entry[i] = panel_create_item (search_panel_win,
				    PANEL_BUTTON,
				    PANEL_ITEM_X, ATTR_COL(0),
				    PANEL_ITEM_Y, ATTR_ROW(i),
				    PANEL_LABEL_STRING, panel_label_string,
				    PANEL_CLIENT_DATA, client_data ,
				    PANEL_EVENT_PROC, handle_search_select,
				    PANEL_SHOW_ITEM,  TRUE,
				    0);
				(void) panel_set (search_panel_entry[i], PANEL_PAINT, PANEL_CLEAR, 0);
				i++;

				dn_free  (ptr->ent_dn);
				free ((char *)ptr);
				as_free (ptr->ent_attr);
				free ((char *)ptr);
			}
			if (result.CSR_limitproblem != LSR_NOLIMITPROBLEM){
				(void) panel_set (search_message, PANEL_VALUE, "may have limit problems ",0);
				(void) panel_set (dua_message, PANEL_VALUE, "possible limit problems ",0);

			}
			(void) panel_update_scrolling_size (search_panel_win);
			search_item_count = i;
		}
		else
			(void) panel_set (search_message, PANEL_VALUE, "no matches found ",0);

		/*  entry_info_free (result.CSR_entries, 1); */
		as_free (search_arg.sra_eis.eis_select);
		filter_free (search_arg.sra_filter);


	}
}


Filter sun_dua_build_filter()
{
	int i, k ;
	Filter current_filter_item, succ_filter_item, start_filter_item;
	AttributeType at;
	current_filter_item = NULLFILTER;
	succ_filter_item = NULLFILTER;
	start_filter_item = NULLFILTER;

	k = the_filter_specs.filter_temp_choice;
	start_filter_item = filter_alloc ();
	start_filter_item->flt_next = NULLFILTER;
	start_filter_item->flt_type = the_filter_specs.type;

	start_filter_item->FUFILT = NULLFILTER;
	for (i = 0; i < the_filter_specs.filter_temp_attr_count; i++)
	{ 
		if (strlen (TidyString (the_filter_specs.filter_temp_entries[i].attr_string)) > 0)

		{ 
			if (the_filter_specs.filter_temp_entries[i].match_choice != IGNORE )

			{
				if (current_filter_item == NULLFILTER)
				{
					current_filter_item = filter_alloc ();
					current_filter_item->flt_next = NULLFILTER;
					current_filter_item->flt_type = FILTER_ITEM;
					current_filter_item->FUITEM.fi_type =  
					    the_filter_specs.filter_temp_entries[i].match_choice;

					start_filter_item->FUFILT = current_filter_item;
					switch (current_filter_item->FUITEM.fi_type) {
					case FILTERITEM_PRESENT:
						current_filter_item->FUITEM.UNTYPE = AttrT_cpy (Template_list[k].Temp_attr_pieces[i].attr_struct) ;
						break;
					case FILTERITEM_SUBSTRINGS: 
						{
							at =  AttrT_cpy (Template_list[k].Temp_attr_pieces[i].attr_struct) ;

							if (! sub_string(at->at_table->oa_syntax)) {
								(void) panel_set (dua_message, PANEL_VALUE, "Cant do a substring search if the type is not a string !!!",0);
								return (NULLFILTER);
							}
							filt_substr(&current_filter_item->FUITEM.UNSUB,at,the_filter_specs.filter_temp_entries[i].attr_string);
							break;
						}
					default:
						current_filter_item->FUITEM.UNAVA.ava_type = AttrT_cpy (Template_list[k].Temp_attr_pieces[i].attr_struct);

						current_filter_item->FUITEM.UNAVA.ava_value = str2AttrV (the_filter_specs.filter_temp_entries[i].attr_string,
						    current_filter_item->FUITEM.UNAVA.ava_type->at_table->oa_syntax);
						break;
					}
				}
				else {
					succ_filter_item = filter_alloc ();
					succ_filter_item->flt_next = NULLFILTER;
					current_filter_item->flt_next = succ_filter_item;
					current_filter_item = succ_filter_item;
					current_filter_item->flt_type = FILTER_ITEM ;
					current_filter_item->FUITEM.fi_type =  
					    the_filter_specs.filter_temp_entries[i].match_choice;

					switch (current_filter_item->FUITEM.fi_type) {
					case FILTERITEM_PRESENT:
						current_filter_item->FUITEM.UNTYPE = AttrT_cpy (Template_list[k].Temp_attr_pieces[i].attr_struct) ;
						break;
					case FILTERITEM_SUBSTRINGS: 
						{
							at = AttrT_cpy (Template_list[k].Temp_attr_pieces[i].attr_struct) ;
							if (! sub_string(at->at_table->oa_syntax)) {
								return NULLFILTER;
							}
							filt_substr(&current_filter_item->FUITEM.UNSUB,at,the_filter_specs.filter_temp_entries[i].attr_string);
							break;
						}
					default:
						current_filter_item->FUITEM.UNAVA.ava_type = AttrT_cpy (Template_list[k].Temp_attr_pieces[i].attr_struct);
						current_filter_item->FUITEM.UNAVA.ava_value = str2AttrV (the_filter_specs.filter_temp_entries[i].attr_string,
						    current_filter_item->FUITEM.UNAVA.ava_type->at_table->oa_syntax);
						break;
					}
				}
			}
		}
		else
			if (the_filter_specs.filter_temp_entries[i].match_choice == FILTERITEM_PRESENT)
			{
				if (current_filter_item == NULLFILTER)
				{
					current_filter_item = filter_alloc ();
					current_filter_item->flt_next = NULLFILTER;
					current_filter_item->flt_type = FILTER_ITEM;
					current_filter_item->FUITEM.fi_type =  
					    the_filter_specs.filter_temp_entries[i].match_choice;
					start_filter_item->FUFILT = current_filter_item;
					current_filter_item->FUITEM.UNTYPE = AttrT_cpy (Template_list[k].Temp_attr_pieces[i].attr_struct) ;
				}
				else {
					succ_filter_item = filter_alloc ();
					succ_filter_item->flt_next = NULLFILTER;
					current_filter_item->flt_next = succ_filter_item;
					current_filter_item = succ_filter_item;
					current_filter_item->flt_type = FILTER_ITEM ;
					current_filter_item->FUITEM.fi_type =  
					    the_filter_specs.filter_temp_entries[i].match_choice;
					current_filter_item->FUITEM.UNTYPE = AttrT_cpy (Template_list[k].Temp_attr_pieces[i].attr_struct) ;
				}
			}
	}
	return start_filter_item;
}



void filt_substr (substr,at,str)
Filter_Substrings * substr;
AttributeType at;
char *str;
{
	char * ptr;
	AttributeValue av;

	if ((ptr = index (str,'*')) == NULLCP)
		ptr = str + strlen (str);

	substr->fi_sub_initial = NULLAV;
	substr->fi_sub_any     = NULLAV;
	substr->fi_sub_final   = NULLAV;
	substr->fi_sub_type    = at;

	/* This is the 'initial' section of the string - maybe NULL */
	*ptr = '\0';
	str = TidyString (str);
	if (*str != 0) {
		av = str2AttrV (str, at->at_table->oa_syntax);
		substr->fi_sub_initial = avs_comp_new (av);
	}
	str = ptr + 1;

	/* Test for whether there are going to be any 'any' bits */
	if ((ptr = rindex(str, '*')) == NULLCP) {
		str = TidyString (str);
		if (*str != 0) {
			av = str2AttrV (str, at->at_table->oa_syntax);
			substr->fi_sub_final = avs_comp_new (av);
		}
		return;
	}

	*ptr = '\0';
	ptr = TidyString (ptr + 1);
	if ( *ptr != 0) {
		av = str2AttrV (str, at->at_table->oa_syntax);
		substr->fi_sub_final = avs_comp_new (av);
	}

	/* There are some internal 'any's to be found */
	do {
		if ((ptr = index(str, '*')) != NULLCP)
			*ptr = '\0';

		if (*str != 0) {
			str = TidyString (str);
			av = str2AttrV (str, at->at_table->oa_syntax);
			if (substr->fi_sub_any == NULLAV)
				substr->fi_sub_any = avs_comp_new (av);
			else
				substr->fi_sub_any = avs_merge (substr->fi_sub_any,avs_comp_new (av));
		}
		if (ptr != NULLCP)
			str = ptr + 1;
	} while(ptr != NULLCP);
}




/*routines for getting the various argument strings from the sunview*/
/*dua interface.These are essentially, modifications of Colin's various*/
/*routines. For now they're all here, but you may want to put them in*/
/*with the relevant files later on, so I've put in comments telling you which*/
/*quipu procedures they're based on. */

DN sun_dua_getdn ()
/*based on getdn*/
{
	DN str2dn();

	if (get_data ("Enter distinguished name", "dn:", 0 , 0))
		return (str2dn (arg_data_buf));
	else
		return NULLDN;
}


RDN sun_dua_getrdn()
/*based on getrdn*/
{
	RDN str2rdn();
	if (get_data ("Enter relative distinguished name", "rdn:", 0 , 0))
		return (str2rdn (arg_data_buf));
	else
		return NULLRDN;


}


char *sun_dua_get_attrT ()

{
	if (get_data ("Enter attribute type", "AttrT:", 0 , 0))
		return arg_data_buf;
	else
		return (char *) NULL;
}



char *sun_dua_get_attrV ()
{
	if (get_data ("Enter attribute value", "AttrV:", 0 , 0))
		return arg_data_buf;
	else
		return (char *) NULL;
}


sun_dua_get_ava (ava1)
AVA *ava1;
{
	char * name;
	char * TidyString();

	name = sun_dua_get_attrT ();
	if ( name == NULLCP || *name == 0)
		return (NOTOK);

	ava1->ava_type = AttrT_new (TidyString(name));
	if (ava1->ava_type == NULLAttrT) {
		(void) fprintf(stderr,"Invalid at %s",name);
		return (NOTOK);
	}

	if ( ! sub_string(ava1->ava_type->at_table->oa_syntax)) {
		(void) fprintf(stderr,"Can only compare string types");
		AttrT_free (ava1->ava_type);
		return (NOTOK);
	}


	name =  sun_dua_get_attrV ();
	ava1->ava_value = str2AttrV (TidyString(name), ava1->ava_type->at_table->oa_syntax);

	return (OK);
}


char *sun_dua_get_search_string ()
{
	if (get_data ("Enter search string", "Search string:", 0 , 0))
		return arg_data_buf;
	else
		return (char *) NULL;
}

filter_specs *sun_dua_get_form_data (selector)
int selector;
{
	if (get_form (selector))
		return (&the_filter_specs);
	else
		return ((filter_specs *) NULL);
}

string_specs sun_dua_get_string_specs ()
{
	if (get_string_specs ())
		return (&the_search_data_info);
	else
		return ((string_specs ) NULL);
}



char *sun_dua_getyn ()
{    
	if (get_data ("", "", 0 , 1))
		return "y";
	else
		return "n";
}



char *sun_dua_get_passwd ()
{
	if (get_data ("Enter password", "Password:", 1 , 0))
		return (arg_data_buf);
	else
		return ((char *) NULL);
}


Filter          get_filter_aux (str)
char           *str;
{
	int             gotit,
	bracketed;
	char            ch,
	och = '\0';
	Filter          result,
	    next,
	    ptr = NULLFILTER;

	result = filter_alloc ();
	result->FUFILT = NULLFILTER;
	result->flt_next = NULLFILTER;

	str = TidyString (str);

	/* Got a multiple-component string for parsing */

	do {
		bracketed = FALSE;
		if ((gotit = getop (str, &ch)) == -2)
			return (NULLFILTER);

		if (gotit < 0) {/* Match an open bracket. */
			if (*str == '(')
				if (str[strlen (str) - 1] == ')') {
					str[strlen (str) - 1] = '\0';
					++str;
					bracketed = TRUE;
				} 
				else {
					return (NULLFILTER);
				}

			if (och == '\0') {
				if (bracketed == TRUE) {
					gotit = 0;	/* Stop 'while' loop
												 * falling */
					continue;	/* Parse the internals */
				} else
					break;	/* Single item only */
			} else
				ch = och;	/* Use last operation */
		}
		if (och == '\0')/* Remember last operation */
			och = ch;
		else if (och != ch) {
			return (NULLFILTER);
		}
		if (gotit >= 0)	/* If got an op, make it null */
			str[gotit] = '\0';
		/* Recurse on the 'first' string */
		if ((next = get_filter_aux (str)) == NULLFILTER)
			return (NULLFILTER);
		if (ptr == NULLFILTER)
			ptr = next;
		else
			filter_append (ptr, next);
		str += gotit + 1;

		if (gotit >= 0) {	/* Match an and symbol */
			if (och == '&') {
				result->flt_type = FILTER_AND;
			} else {/* Match an or symbol */
				result->flt_type = FILTER_OR;
			}
			result->FUFILT = ptr;
		}
	}	while (gotit >= 0);
	if (och == '\0') {
		if (*str == '!') {	/* Match a not symbol */
			result->flt_type = FILTER_NOT;
			if ((result->FUFILT = get_filter_aux (str + 1)) == NULLFILTER)
				return (NULLFILTER);
		} else if (filteritem (str, result) == NOTOK)
			return (NULLFILTER);
	}
	return (result);
}


Filter          get_filter (str)
char           *str;
{
	char * ptr;
	Filter f;

	ptr = strdup (str);
	f = get_filter_aux (ptr);
	free (ptr);
	return (f);

}


getop (str, ch)
char           *str,
*ch;
{
	int             i,
	bracket = 0;

	for (i = 0; i < strlen (str); i++) {
		if (bracket == 0 && (str[i] == '&' || str[i] == '|')) {
			*ch = str[i];
			return (i);
		}
		if (str[i] == '(')
			++bracket;
		if (str[i] == ')')
			--bracket;
		if (bracket < 0) {
			return (-2);
		}
	}
	return (-1);
}

/* Regular Expression parser written by P.Sharpe */
/* Inca specific tailoring by CJR */
/* taken from dish */

#define debug(a,b)		/* remove debug statements */

Filter          get_filter ();
char           *TidyString ();

filteritem (str, fltr)
char           *str;
Filter          fltr;
{

	char           *ptr,
	*index (), *rindex ();
	AttributeValue  av;
	AttributeType   at;

	fltr->flt_type = FILTER_ITEM;

	if ((ptr = index (str, '=')) == NULLCP) {
		/* set default (cn~=) */
		fltr->FUITEM.fi_type = FILTERITEM_APPROX;
		at = AttrT_new (CN_OID);
	} else {
		switch (*--ptr) {
		case '~':
			fltr->FUITEM.fi_type = FILTERITEM_APPROX;
			*ptr = 0;
			break;
			/* > implies LESS THAN - read the standard ! */
		case '>':
			fltr->FUITEM.fi_type = FILTERITEM_GREATEROREQUAL;
			*ptr = 0;
			break;
		case '<':
			fltr->FUITEM.fi_type = FILTERITEM_LESSOREQUAL;
			*ptr = 0;
			break;
		default:
			fltr->FUITEM.fi_type = FILTERITEM_EQUALITY;
			break;
		}
		*++ptr = '\0';
		str = TidyString (str);
		at = AttrT_new (str);
		if (at == NULLAttrT) {
			return (NOTOK);
		}
		str = ptr + 1;
	}

	if (*str == '*') {
		if (*++str == 0) {
			fltr->FUITEM.fi_type = FILTERITEM_PRESENT;
			fltr->FUITEM.UNTYPE = at;
			return (OK);
		} else
			str--;
	}

	/* test for whether there is only the simple 'equality' case */
	if ((ptr = index (str, '*')) == NULLCP) {
		debug (1, ("[EXACT(%s)]", str));

		fltr->FUITEM.UNAVA.ava_type = at;
		str = TidyString (str);
		if ((fltr->FUITEM.UNAVA.ava_value = str2AttrV (str, at->at_table->oa_syntax)) == NULLAttrV)
			return (NOTOK);
		return (OK);
	}

	/*
	 * We have to parse the string for 'initial', 'final' and 'any'
	 * components 
	 */

	fltr->FUITEM.UNSUB.fi_sub_initial = NULLAV;
	fltr->FUITEM.UNSUB.fi_sub_any = NULLAV;
	fltr->FUITEM.UNSUB.fi_sub_final = NULLAV;
	fltr->FUITEM.UNSUB.fi_sub_type = at;
	fltr->FUITEM.fi_type = FILTERITEM_SUBSTRINGS;
	if ( ! sub_string (at->at_table->oa_syntax)) {
		return (NOTOK);
	}

	debug (1, ("[ "));
	/* This is the 'initial' section of the string - maybe NULL */
	*ptr = '\0';
	str = TidyString (str);
	if (*str != 0) {
		debug (1, ("INITIAL(%s) ", str));
		av = str2AttrV (str, at->at_table->oa_syntax);
		fltr->FUITEM.UNSUB.fi_sub_initial = avs_comp_new (av);
	}
	str = ptr + 1;

	/* Test for whether there are going to be any 'any' bits */
	if ((ptr = rindex (str, '*')) == NULLCP) {
		ptr = TidyString (str);
		if (*str != 0) {
			debug (1, ("FINAL(%s) ", str));
			av = str2AttrV (str, at->at_table->oa_syntax);
			fltr->FUITEM.UNSUB.fi_sub_final = avs_comp_new (av);
		}
		debug (1, ("]"));
		return (OK);
	}
	*ptr = '\0';
	ptr = TidyString (ptr + 1);
	if (*ptr != 0) {
		debug (1, ("FINAL(%s) ", ptr));
		av = str2AttrV (ptr, at->at_table->oa_syntax);
		fltr->FUITEM.UNSUB.fi_sub_final = avs_comp_new (av);
	}
	/* There are some internal 'any's to be found */
	do {
		AV_Sequence any_end;

		if ((ptr = index (str, '*')) != NULLCP)
			*ptr = '\0';

		if (*str != 0) {
			str = TidyString (str);
			debug (1, ("ANY(%s) ", str));
			av = str2AttrV (str, at->at_table->oa_syntax);
			if (fltr->FUITEM.UNSUB.fi_sub_any == NULLAV) {
				fltr->FUITEM.UNSUB.fi_sub_any = avs_comp_new (av);
				any_end = fltr->FUITEM.UNSUB.fi_sub_any;
			} else {
				any_end->avseq_next = avs_comp_new (av);
				any_end = any_end->avseq_next;
			}
		}
		if (ptr != NULLCP)
			str = ptr + 1;
	}
	    while (ptr != NULLCP);
	debug (1, ("]"));
	return (OK);
}




void clear_panel_win ()
{
	int i;
	if (display_item_count != 0)
	{
		for ( i = 0; i < display_item_count; i++ )
		{ 
			(void) panel_set (dua_panel_entry[i], PANEL_SHOW_ITEM, FALSE,0);
			(void) panel_destroy_item (dua_panel_entry[i]);
			dua_panel_entry[i] = (Panel_item ) NULL;
		}
	}
	display_item_count = 0;
}

void clear_old_search_results ()
{
	int i;
	if (search_item_count != 0)
	{
		for ( i = 0; i < search_item_count; i++ )
		{ 
			(void) panel_set (search_panel_entry[i], PANEL_SHOW_ITEM, FALSE,0);
			(void) panel_destroy_item (search_panel_entry[i]);
			search_panel_entry[i] = (Panel_item ) NULL;
		}
	}
	search_item_count = 0;
}
/* These procedures are to do with creating and running a pop-up*/
/* window which reads in the requested argument. The argument */
/* required is prompted for by a suitable message. The argument*/
/* is typed in at the keyboard, and displayed in a TEXT_ITEM in*/
/* the pop-up window and entered into a buffer called arg_data_buffer */
/* when the user hits a carriage return. The user can then confirm */
/* or reject the input data by clicking on either the yes or no buttons*/
/* in the pop-up window */


static Frame init_data_getter ();
static void yes_select ();
static void no_select ();


static int get_data ( message, title, mask_on, simple)
char *message;
char *title;
int mask_on;
int simple;
{
	Frame get_arg_frame;
	int  answer;
	/* create the frame for entering arguments */
	get_arg_frame = init_get_arg_frame (message, title, mask_on, simple);
	args_entered_flag = 0;
	/* force the user to enter the argument */
	answer = (int) window_loop (get_arg_frame);
	/* destroy the get_arg_frame */
	(void) window_set (get_arg_frame , FRAME_NO_CONFIRM, TRUE, 0);
	(void) window_destroy (get_arg_frame);
	return answer;
}


static Frame init_get_arg_frame (message, title, mask_on, simple)
char *message;
char *title;
int mask_on;
int simple;

{
	Frame get_arg_frame;
	Panel panel;
	int left, top, width, height;
	Rect *r;

	get_arg_frame = window_create ((Frame)0, FRAME, FRAME_SHOW_LABEL, FALSE, 0);
	panel = window_create (get_arg_frame, PANEL, 
	    WIN_ROWS, 15,
	    WIN_COLUMNS, 60, 0);
	if (!simple)
	{
		(void) panel_create_item (panel, PANEL_MESSAGE,
		    PANEL_ITEM_X, ATTR_COL (3),
		    PANEL_ITEM_Y, ATTR_ROW (3),
		    PANEL_LABEL_STRING, message, 0);
		if (mask_on)
			(void) panel_create_item (panel, PANEL_TEXT,
			    PANEL_ITEM_X, ATTR_COL (3),
			    PANEL_ITEM_Y, ATTR_ROW (6),
			    PANEL_LABEL_STRING, title,
			    PANEL_MASK_CHAR, '*',
			    PANEL_NOTIFY_PROC, put_data_proc, 0);

		else
			(void) panel_create_item (panel, PANEL_TEXT,
			    PANEL_ITEM_X, ATTR_COL (3),
			    PANEL_ITEM_Y, ATTR_ROW (6),
			    PANEL_LABEL_STRING, title,
			    PANEL_NOTIFY_PROC, put_data_proc, 0);
	}

	(void) panel_create_item (panel, PANEL_BUTTON,
	    PANEL_ITEM_X, ATTR_COL (20),
	    PANEL_ITEM_Y, ATTR_ROW (9),
	    PANEL_LABEL_IMAGE, panel_button_image (panel,
	    "YES", 3 , (Pixfont *)NULL ),
	    PANEL_CLIENT_DATA, 1,
	    PANEL_NOTIFY_PROC, yes_no_proc, 0);

	(void) panel_create_item (panel, PANEL_BUTTON,
	    PANEL_ITEM_X, ATTR_COL (40),
	    PANEL_ITEM_Y, ATTR_ROW (9),
	    PANEL_LABEL_IMAGE, panel_button_image (panel,
	    "NO", 3 , (Pixfont *)NULL ),
	    PANEL_CLIENT_DATA, 0,
	    PANEL_NOTIFY_PROC, yes_no_proc, 0);

	window_fit (panel);
	window_fit (get_arg_frame);
	/* center get_arg_frame on the screen */
	r = (Rect *) window_get ( get_arg_frame, WIN_SCREEN_RECT );
	width = (int) window_get ( get_arg_frame, WIN_WIDTH );
	height = (int) window_get ( get_arg_frame, WIN_HEIGHT );
	left = (r->r_width - width) / 2;
	top = (r->r_height - height) / 2;
	if (left < 0)
		left = 0;
	if (top < 0)
		top = 0;
	(void) window_set (get_arg_frame, WIN_X, left, WIN_Y, top, 0);

	return get_arg_frame;
}


Panel_setting put_data_proc (item, event)
Panel_item item;
Event *event;
{ 
	(void) strcpy (arg_data_buf, (char *) panel_get_value (item));
	args_entered_flag = 1;
	return (panel_text_notify (item, event));
}


/* ARGSUSED */
static void yes_no_proc (item, event)
Panel_item item;
Event *event;
{
	window_return (panel_get (item, PANEL_CLIENT_DATA));
}



static int get_form (form_selector)
int form_selector;
{
	Frame get_args_form1;
	int  answer;
	/* create the frame for entering arguments */
	get_args_form1 = init_get_args_form (form_selector);
	args_entered_flag = 0;
	/* force the user to enter the argument */
	answer = (int) window_loop (get_args_form1);
	/* destroy the get_args_form */
	(void) window_set (get_args_form1 , FRAME_NO_CONFIRM, TRUE, 0);
	(void) window_destroy (get_args_form1);
	return answer;
}


static int get_string_specs ()
{
	Frame get_strings_form;
	int  answer;
	/* create the frame for entering arguments */
	get_strings_form = init_get_strings_form ();
	args_entered_flag = 0;
	/* force the user to enter the argument */
	answer = (int) window_loop (get_strings_form);
	/* destroy the get_args_form */
	(void) window_set (get_strings_form , FRAME_NO_CONFIRM, TRUE, 0);
	(void) window_destroy (get_strings_form);
	return answer;
}


static Frame init_get_args_form (selector)
int selector;
{
	Frame get_args_form1;
	Panel get_args_panel;
	Panel_item at_text[10],match_type[10];
	int left, top, width, height, i;
	Rect *r;
	the_filter_specs.filter_temp_choice = selector;
	the_filter_specs.filter_temp_attr_count = Template_list[selector].attr_count;
	get_args_form1 = window_create ((Frame)0, FRAME, FRAME_SHOW_LABEL, FALSE, 0);
	get_args_panel = window_create (get_args_form1, PANEL, 
	    WIN_ROWS, 20,
	    WIN_COLUMNS, 80, 0);

	(void) panel_create_item (get_args_panel, PANEL_MESSAGE,
	    PANEL_ITEM_X, ATTR_COL (3),
	    PANEL_ITEM_Y, ATTR_ROW (0),
	    PANEL_LABEL_STRING, "message", 0);


	for (i = 0; i < Template_list[selector].attr_count; i++)

	{
		at_text[i] = panel_create_item (get_args_panel, PANEL_TEXT,
		    PANEL_ITEM_X, ATTR_COL (3),
		    PANEL_ITEM_Y, ATTR_ROW (3 + i),
		    PANEL_LABEL_STRING, 
		    Template_list[selector].Temp_attr_pieces[i].print_string,
		    PANEL_VALUE_DISPLAY_LENGTH, 32,
		    PANEL_CLIENT_DATA, i,
		    PANEL_NOTIFY_PROC, put_filter_text_proc, 0);

		match_type[i] = panel_create_item (get_args_panel, PANEL_CYCLE,
		    PANEL_ITEM_X, ATTR_COL (60),
		    PANEL_ITEM_Y, ATTR_ROW (3 + i),
		    PANEL_LABEL_STRING, "match_type",
		    PANEL_CHOICE_STRINGS,"approximate", "equal",
		    "greater or equal",
		    "less than or equal",
		    "substrings", "present", "ignore",0,
		    PANEL_CLIENT_DATA, i,
		    PANEL_NOTIFY_PROC, put_filter_match_proc, 0);

	}

	at_text[i] = panel_create_item (get_args_panel, PANEL_TEXT,
	    PANEL_ITEM_X, ATTR_COL (3),
	    PANEL_ITEM_Y, ATTR_ROW (3 + i),
	    PANEL_LABEL_STRING, 
	    "alternative base object: ",
	    PANEL_VALUE_DISPLAY_LENGTH, 32,
	    PANEL_CLIENT_DATA, i,
	    PANEL_NOTIFY_PROC, put_base_object_string, 0);

	match_type[i] = panel_create_item (get_args_panel, PANEL_CYCLE,
	    PANEL_ITEM_X, ATTR_COL (60),
	    PANEL_ITEM_Y, ATTR_ROW (3 + i),
	    PANEL_LABEL_STRING, "base_select",
	    PANEL_CHOICE_STRINGS, "current position",
	    "specified position",0,
	    PANEL_CLIENT_DATA, i,
	    PANEL_NOTIFY_PROC, put_base_object_select , 0);
	i++;

	match_type[i] = panel_create_item (get_args_panel, PANEL_CYCLE,
	    PANEL_ITEM_X, ATTR_COL (40),
	    PANEL_ITEM_Y, ATTR_ROW (3 + i + 2),
	    PANEL_LABEL_STRING, "DEPTH OF SEARCH",
	    PANEL_CHOICE_STRINGS, "ONE LEVEL",
	    "WHOLE SUBTREE",0,
	    PANEL_CLIENT_DATA, i,
	    PANEL_NOTIFY_PROC, put_search_depth_select , 0);

	i++;

	match_type[i] = panel_create_item (get_args_panel, PANEL_CYCLE,
	    PANEL_ITEM_X, ATTR_COL (40),
	    PANEL_ITEM_Y, ATTR_ROW (3 + i + 2),
	    PANEL_LABEL_STRING, "FILTER TYPE",
	    PANEL_CHOICE_STRINGS,"OR",
	    "AND",0,
	    PANEL_CLIENT_DATA, i,
	    PANEL_NOTIFY_PROC, put_filter_type_select , 0);

	i++;


	(void) panel_create_item (get_args_panel, PANEL_BUTTON,
	    PANEL_ITEM_X, ATTR_COL (20),
	    PANEL_ITEM_Y, ATTR_ROW (3 + i + 2),
	    PANEL_LABEL_IMAGE, panel_button_image (get_args_panel,
	    "YES", 3 , (Pixfont *)NULL ),
	    PANEL_CLIENT_DATA, 1,
	    PANEL_NOTIFY_PROC, yes_no_proc, 0);

	(void) panel_create_item (get_args_panel, PANEL_BUTTON,
	    PANEL_ITEM_X, ATTR_COL (40),
	    PANEL_ITEM_Y, ATTR_ROW (3 + i + 2),
	    PANEL_LABEL_IMAGE, panel_button_image (get_args_panel,
	    "NO", 3 , (Pixfont *)NULL ),
	    PANEL_CLIENT_DATA, 0,
	    PANEL_NOTIFY_PROC, yes_no_proc, 0);
	i++;

	window_fit (get_args_panel);
	window_fit (get_args_form1);
	/* center get_args_form on the screen */
	r = (Rect *) window_get ( get_args_form1, WIN_SCREEN_RECT );
	width = (int) window_get ( get_args_form1, WIN_WIDTH );
	height = (int) window_get ( get_args_form1, WIN_HEIGHT );
	left = (r->r_width - width) / 2;
	top = (r->r_height - height) / 2;
	if (left < 0)
		left = 0;
	if (top < 0)
		top = 0;
	(void) window_set (get_args_form1, WIN_X, left, WIN_Y, top, 0);

	return get_args_form1;
}


static Frame init_get_strings_form ()
{
	Frame get_strings_form;
	Panel get_strings_panel;
    	int left, top, width, height, i=0;
	Rect *r;

	get_strings_form = window_create ((Frame)0, FRAME, FRAME_SHOW_LABEL, FALSE, 0);
	get_strings_panel = window_create (get_strings_form, PANEL, 
	    WIN_ROWS, 10,
	    WIN_COLUMNS, 80, 0);

	(void) panel_create_item (get_strings_panel, PANEL_MESSAGE,
	    PANEL_ITEM_X, ATTR_COL (3),
	    PANEL_ITEM_Y, ATTR_ROW (0),
	    PANEL_LABEL_STRING, "message", 0);



	(void) panel_create_item (get_strings_panel, PANEL_TEXT,
	    PANEL_ITEM_X, ATTR_COL (3),
	    PANEL_ITEM_Y, ATTR_ROW (2),
	    PANEL_LABEL_STRING, "Filter  :",
	    PANEL_VALUE_DISPLAY_LENGTH, 32,
	    PANEL_NOTIFY_PROC, put_filter_string_proc, 0);


	(void) panel_create_item (get_strings_panel, PANEL_TEXT,
	    PANEL_ITEM_X, ATTR_COL (3),
	    PANEL_ITEM_Y, ATTR_ROW (4),
	    PANEL_LABEL_STRING, 
	    "alternative base object: ",
	    PANEL_VALUE_DISPLAY_LENGTH, 32,
	    PANEL_CLIENT_DATA, i,
	    PANEL_NOTIFY_PROC, put_base_object_string_proc, 0);

	(void) panel_create_item (get_strings_panel, PANEL_CYCLE,
	    PANEL_ITEM_X, ATTR_COL (60),
	    PANEL_ITEM_Y, ATTR_ROW (4),
	    PANEL_LABEL_STRING, "base_select",
	    PANEL_CHOICE_STRINGS, "current position",
	    "specified position",0,
	    PANEL_NOTIFY_PROC, put_string_base_object_select_proc , 0);

	(void) panel_create_item (get_strings_panel, PANEL_CYCLE,
	    PANEL_ITEM_X, ATTR_COL (40),
	    PANEL_ITEM_Y, ATTR_ROW (6),
	    PANEL_LABEL_STRING, "DEPTH OF SEARCH",
	    PANEL_CHOICE_STRINGS, "ONE LEVEL",
	    "WHOLE SUBTREE",0,
	    PANEL_NOTIFY_PROC, put_string_search_depth_select , 0);



	(void) panel_create_item (get_strings_panel, PANEL_BUTTON,
	    PANEL_ITEM_X, ATTR_COL (20),
	    PANEL_ITEM_Y, ATTR_ROW (8),
	    PANEL_LABEL_IMAGE, panel_button_image (get_strings_panel,
	    "YES", 3 , (Pixfont *)NULL ),
	    PANEL_CLIENT_DATA, 1,
	    PANEL_NOTIFY_PROC, yes_no_proc, 0);

	(void) panel_create_item (get_strings_panel, PANEL_BUTTON,
	    PANEL_ITEM_X, ATTR_COL (40),
	    PANEL_ITEM_Y, ATTR_ROW (8),
	    PANEL_LABEL_IMAGE, panel_button_image (get_strings_panel,
	    "NO", 3 , (Pixfont *)NULL ),
	    PANEL_CLIENT_DATA, 0,
	    PANEL_NOTIFY_PROC, yes_no_proc, 0);

	window_fit (get_strings_panel);
	window_fit (get_strings_form);
	/* center get_strings_form on the screen */
	r = (Rect *) window_get ( get_strings_form, WIN_SCREEN_RECT );
	width = (int) window_get ( get_strings_form, WIN_WIDTH );
	height = (int) window_get ( get_strings_form, WIN_HEIGHT );
	left = (r->r_width - width) / 2;
	top = (r->r_height - height) / 2;
	if (left < 0)
		left = 0;
	if (top < 0)
		top = 0;
	(void) window_set (get_strings_form, WIN_X, left, WIN_Y, top, 0);

	return get_strings_form;
}


Panel_setting put_filter_text_proc (item, event)
Panel_item item;
Event *event;
{ 
	int offset;
	offset = (int) panel_get (item, PANEL_CLIENT_DATA);
	(void) strcpy (the_filter_specs.filter_temp_entries[offset].attr_string,
	    panel_get_value (item));
	return (panel_text_notify (item, event));
}

Panel_setting put_filter_string_proc (item, event)
Panel_item item;
Event *event;
{   
	(void) strcpy (the_search_data_info.filter_string,
	    panel_get_value (item));
	return (panel_text_notify (item, event));
}

Panel_setting put_base_object_string_proc (item, event)
Panel_item item;
Event *event;
{  
	(void) strcpy (the_search_data_info.base_object_string,
	    panel_get_value (item));
	return (panel_text_notify (item, event));
}


Panel_setting put_filter_type_select (item,value, event)
Panel_item item;
int value;
Event *event;
{
	switch (value) {
	case 0 :  
		the_filter_specs.type = FILTER_OR;
		break;
	case 1 : 
		the_filter_specs.type = FILTER_AND;
		break;
	}
	return (panel_text_notify (item, event));
}



Panel_setting put_base_object_string (item, event)
Panel_item item;
Event *event;
{
	(void) strcpy (the_filter_specs.base_object_string,
	    panel_get_value (item));
	return (panel_text_notify (item, event));
}


Panel_setting put_base_object_select (item,value, event)
Panel_item item;
int value;
Event *event;
{
	switch (value) {
	case 0 :  
		the_filter_specs.base_object_select = CURRENT_POS;
		break;
	case 1 : 
		the_filter_specs.base_object_select = SPECIFIED_POS;
		break;
	}
	return (panel_text_notify (item, event));
}


Panel_setting put_string_base_object_select_proc (item,value, event)
Panel_item item;
int value;
Event *event;
{
	switch (value) {
	case 0 :  
		the_search_data_info.base_object_select = CURRENT_POS;
		break;
	case 1 : 
		the_search_data_info.base_object_select = SPECIFIED_POS;
		break;
	}
	return (panel_text_notify (item, event));
}


Panel_setting put_search_depth_select (item,value, event)
Panel_item item;
int value;
Event *event;
{
	switch (value) {
	case 0 :  
		the_filter_specs.search_subset = SRA_ONELEVEL;
		break;
	case 1 : 
		the_filter_specs.search_subset = SRA_WHOLESUBTREE;
		break;
	}
	return (panel_text_notify (item, event));
}


Panel_setting put_string_search_depth_select (item,value, event)
Panel_item item;
int value;
Event *event;
{
	switch (value) {
	case 0 :  
		the_search_data_info.search_subset = SRA_ONELEVEL;
		break;
	case 1 :  
		the_search_data_info.search_subset = SRA_WHOLESUBTREE;
		break;
	}
	return (panel_text_notify (item, event));
}

/* ARGSUSED */
void put_filter_match_proc (item, value, event)
Panel_item item;
int value;
Event *event;
{
	int offset;
	offset = (int) panel_get (item, PANEL_CLIENT_DATA);
	switch (value) {
	case 0 : 
		the_filter_specs.filter_temp_entries[offset].match_choice  = 
		    FILTERITEM_APPROX;
		break;
	case 1 : 
		the_filter_specs.filter_temp_entries[offset].match_choice  = 
		    FILTERITEM_EQUALITY;
		break;
	case 2 : 
		the_filter_specs.filter_temp_entries[offset].match_choice  = 
		    FILTERITEM_LESSOREQUAL;
		break;
	case 3 : 
		the_filter_specs.filter_temp_entries[offset].match_choice  = 
		    FILTERITEM_GREATEROREQUAL;
		break;
	case 4 : 
		the_filter_specs.filter_temp_entries[offset].match_choice  = 
		    FILTERITEM_SUBSTRINGS;
		break;
	case 5 : 
		the_filter_specs.filter_temp_entries[offset].match_choice  = 
		    FILTERITEM_PRESENT;
		break;
	case 6 : 
		the_filter_specs.filter_temp_entries[offset].match_choice  = 
		    IGNORE;
		break;
	}


}





/* These routines display create and destroy the panel items */
/* which are involved in displaying the current path */

void make_new_path (adn)
DN adn;
{  
	int i,j;
	/* might have to twiddle starting values of i and j */
	DN copy, dnptr;
	DN dn_comp_bit[10];
	DN dn_bit;
	char text_buf[SMALL_BUF];
	PathElementData client_data;
	clear_old_path (0);

	copy = dn_cpy (adn);

	for (dnptr = copy, j = 0 ; dnptr != NULLDN; dnptr = dnptr->dn_parent)
		dn_comp_bit[j++] = dnptr;

	for (i = j ; i != 0; i--)
	{
		get_oc_bit (copy, text_buf);
		dn_bit = dn_cpy (copy);
		get_rdn_bit (dn_comp_bit[(i - 1)], text_buf);
		if ( i != 1 )
			dn_comp_bit[(i - 2)]->dn_parent = NULLDN;
		dn_free (dn_comp_bit[(i - 1)]);
		client_data = (PathElementData) malloc (sizeof (path_element_data));
		client_data->depth = i  ;
		client_data->dn_ptr =  dn_bit;
		current_path_item[(i - 1)] = panel_create_item (control_panel,
		    PANEL_BUTTON,
		    PANEL_ITEM_X, ATTR_COL(1),
		    PANEL_ITEM_Y, ATTR_ROW(i + 3),
		    PANEL_LABEL_STRING, text_buf,
		    PANEL_CLIENT_DATA, client_data,
		    PANEL_SHOW_ITEM,  TRUE,
		    PANEL_EVENT_PROC , handle_path_select_button,
		    0);
		(void) panel_set (current_path_item[(i - 1)], PANEL_PAINT, PANEL_CLEAR, 0);
		bzero (text_buf , SMALL_BUF);
		path_element_count = j;
	}

}


void get_oc_bit (adn, achar_buf)
DN adn;
char achar_buf[SMALL_BUF];
{
	static struct ds_read_arg read_arg =
	{
		default_common_args,
		NULLDN,   /* read_arg DN */
		{       /* entry info selection */
			FALSE,
			NULLATTR,
			EIS_ATTRIBUTESANDVALUES
		}
	};

	struct ds_read_result   result;
	struct DSError          error;

	read_arg.rda_object = adn;
	read_arg.rda_eis.eis_allattributes = FALSE;
	read_arg.rda_eis.eis_select = as_comp_new (AttrT_new ("objectclass"), NULLAV, NULLACL_INFO);
	(void) panel_set(dua_message, PANEL_VALUE, "",0);

	if (ds_read (&read_arg,&error,&result) != DS_OK) {
		/* deal with error */
		(void) panel_set(dua_message, PANEL_VALUE, "read operation failed",0);
	} else 
	{                /* use data */
		(void) as_decode (result.rdr_entry.ent_attr);

		if (result.rdr_entry.ent_attr != NULLATTR) {
			(void) strcat (achar_buf, "  ");
			sunint_print (oc_print, (caddr_t)result.rdr_entry.ent_attr->attr_value, achar_buf);
		}
		entryinfo_comp_free (&result.rdr_entry,0);
	}

}


void get_rdn_bit (adn, achar_buf)
DN adn;
char achar_buf[SMALL_BUF];
{
	DN eptr, trail;
	for (eptr = adn; eptr != NULLDN; eptr = eptr->dn_parent)
		trail = eptr;
	(void) strcat (achar_buf, "   ");
	sunint_print (sunint_dn_comp_print, (caddr_t) trail, achar_buf);
}

void back_to_root ()
{ 
	int i;
	dn = NULLDN;
	clear_old_path (0);
	for ( i = 0; i < display_item_count; i++)
		(void) panel_set (dua_panel_entry[i], PANEL_SHOW_ITEM, FALSE, 0);
}


void clear_old_path (pos)
int pos;
{
	int n ;
	PathElementData client_data;

	if (pos > (path_element_count ))
		(void) panel_set (dua_message, PANEL_VALUE, "element greater than current depth",0);
	else
	{
		for (n = (pos + 1); n < (path_element_count + 1 ); n++)
		{
			client_data =  (PathElementData) panel_get (current_path_item[(n - 1)], PANEL_CLIENT_DATA);
			(void) panel_set (current_path_item[(n - 1)], PANEL_SHOW_ITEM, FALSE,0);
			dn_free (client_data->dn_ptr);
			(void) panel_destroy_item (current_path_item[(n - 1)]);
			current_path_item[(n - 1)] = (Panel_item) NULL;
		}
		path_element_count = pos;
	}
}


photo_start ()
{
	return (0);
}


photo_end ()
{
	return (0);
}

photo_black ()
{
}

photo_white ()
{
}


photo_line_end (line)
bit_string * line;
{
	Pixrect * pix;
	Pixwin *pw;
	static int sy = 20;

	/* the end of a line has been reached */
	/* A bit string is stored in line->dbuf_top */
	pw = canvas_pixwin (read_canvas);
	pix = mem_point (PIC_LINESIZE,1,1,(short*)line->dbuf_top);
	(void) pw_write (pw, 20, sy, PIC_LINESIZE - 20, 1, PIX_SRC,pix,0,0);
	sy++;
}

/* ARGSUSED */
sunint_pictures (ps,picture,format)
PS ps;
char * picture;
int format;
{
	decode_t4 (picture,"photo",0);
	ps_print (ps,"(see sub window)");
}


void    advise (va_alist)
va_dcl
{
	int     code;
	va_list ap;
	extern LLog    *log_dsap;

	va_start (ap);

	code = va_arg (ap, int);

	(void) _ll_log (log_dsap, code, ap);

	va_end (ap);
}

add_entry_info_str  (entryinfo, part_full_buf)
EntryInfo *entryinfo;
char *part_full_buf;
{
	PS aps;

	if ((aps = ps_alloc (str_open)) == NULLPS)
		fatal (-1, "can't ps_alloc in add_entry_info_str");

	if (str_setup (aps, part_full_buf, LOTS, 1) == NOTOK)
		fatal (-1, "can't str_setup in add_entry_info_str");

	(void) as_decode (entryinfo->ent_attr);
	as_print (aps,entryinfo->ent_attr,READOUT);
}


sunint_print  (func, ptr, buf)
int (*func) ();
caddr_t ptr;
char * buf;
{
	PS aps;
	int i;

	i = strlen(buf);
	buf += i;

	if ((aps = ps_alloc (str_open)) == NULLPS)
		fatal (-1, "can't ps_alloc in add_dn_comp_str");

	if (str_setup (aps, buf, LOTS -i, 1) == NOTOK)
		fatal (-1, "can't str_setup in add_dn_comp_str");

	(*func) (aps,ptr,READOUT);
	*aps->ps_ptr = 0;
	ps_free(aps);
}

sunint_dn_comp_print (x,y,z)
/* real dn_comp_print is a macro */
PS x;
DN y;
int z;
{
	if (y != NULLDN)
		rdn_print (x,y->dn_rdn,z);
}


char * sunint_error (err)
struct DSError * err;
{
PS ps;
static char buffer [LOTS];

    if ((ps = ps_alloc (str_open)) == NULLPS) {
	return ("Wierdo error");
    }
    if (str_setup (ps,buffer,LOTS,1) == NOTOK) {
	return ("Wierdo error (2)");
    }
    ds_error (ps,err);

    *ps->ps_ptr = 0;
    return (buffer);
}