File:  [CSRG BSD Unix] / 43BSDReno / contrib / isode-beta / quipu / dish / fred.c
Revision 1.1: download - view: text, annotated - select for diffs
Tue Apr 24 16:12:56 2018 UTC (8 years, 1 month ago) by root
CVS tags: MAIN, HEAD
Initial revision

/* fred.c - DiSH support for FrED */

#ifndef	lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/quipu/dish/fred.c,v 1.1 2018/04/24 16:12:56 root Exp $";
#endif

/* 
 * $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/quipu/dish/fred.c,v 1.1 2018/04/24 16:12:56 root Exp $
 *
 *
 * $Log: fred.c,v $
 * Revision 1.1  2018/04/24 16:12:56  root
 * Initial revision
 *
 * Revision 7.6  90/07/09  14:47:11  mrose
 * sync
 * 
 * Revision 7.5  90/04/18  08:49:40  mrose
 * 6.2
 * 
 * Revision 7.4  90/03/15  11:18:27  mrose
 * quipu-sync
 * 
 * Revision 7.3  90/01/11  18:37:38  mrose
 * real-sync
 * 
 * Revision 7.2  89/12/19  16:21:03  mrose
 * sync
 * 
 * Revision 7.1  89/11/26  14:25:47  mrose
 * sync
 * 
 * Revision 7.0  89/11/23  22:20:08  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 <ctype.h>
#include <stdio.h>
#include "quipu/ds_search.h"
#include "quipu/entry.h"


#define	OPT	(!frompipe || rps -> ps_byteno == 0 ? opt : rps)
#define	RPS	(!frompipe || opt -> ps_byteno == 0 ? rps : opt)
extern	char	frompipe;
extern	PS	opt, rps;


char		fred_flag;
char		fred_expand;
char		fred_long;
char		fred_phone;
char		fred_sequence;
char		fred_subdisplay;


static	int	dsa_status;

struct dn_seq *dm2dn_seq ();

Entry	fredentry ();


struct dn_seq *dn_seq_push ();

/*    FRED BACK-END */

int	call_fred (argc, argv)
int	argc;
char  **argv;
{
    if (argc < 2)
	goto usage;

    if (test_arg (argv[1], "-dm2dn", 5)) {
	int	seqno;
	register struct dn_seq *dlist,
			       *dp;

	if (argc != 3)
	    goto usage;

	if ((dlist = dm2dn_seq (argv[2])) == NULLDNSEQ) {
	    if (dsa_status == OK)
		ps_printf (OPT, "Unable to resolve domain.\n");
	    return;
	}

	for (dp = dlist; dp; dp = dp -> dns_next) {
	    if (seqno = add_sequence (dp -> dns_dn))
		ps_printf (RPS, "%-3d ", seqno);
	    dn_print (RPS, dp -> dns_dn, RDNOUT);
	    ps_printf (RPS, "\n");
	}

	dn_seq_free (dlist);
	return;
    }

    if (test_arg (argv[1], "-ufn", 3)) {
	if (argc < 3)
	    goto usage;

	do_ufn_match (argc - 2, argv + 2);
	return;
    }

usage: ;
    Usage (argv[0]);
}

/*  */

#define	ADOMAIN	"associatedDomain"

static	int	dlevel = 0;

struct dn_seq *dm2dn_seq_aux ();


static struct dn_seq *dm2dn_seq (dm)
char   *dm;
{
    register char *dp;

    for (dp = dm; *dp; dp++)
	if (isupper (*dp))
	    *dp = tolower (*dp);

    dlevel = 0;
    dsa_status = OK;

    return dm2dn_seq_aux (dm, NULLDN, NULLDNSEQ);
}

/*  */

static struct dn_seq *dm2dn_seq_aux (dm, dn, dlist)
char   *dm;
DN	dn;
struct dn_seq *dlist;
{
    register char   *dp;
    register CommonArgs *ca;
    struct ds_search_arg search_arg;
    register struct ds_search_arg *sa = &search_arg;
    struct ds_search_result search_result;
    register struct ds_search_result *sr = &search_result;
    struct DSError error;
    register struct DSError *se = &error;

    bzero ((char *) sa, sizeof *sa);

			    /* perhaps later initialize this from user, etc. */
    ca = &sa -> sra_common;
    ca -> ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;
    ca -> ca_servicecontrol.svc_prio = SVC_PRIO_LOW;
    ca -> ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;
    ca -> ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;
    ca -> ca_servicecontrol.svc_scopeofreferral = SVC_REFSCOPE_NONE;

    sa -> sra_baseobject = dn;
    sa -> sra_subset = SRA_ONELEVEL;
    sa -> sra_searchaliases = FALSE;

    dp = dm;
    for (;;) {
	int	    i;
	EntryInfo  *ptr;
	register filter *fi;
	register AttributeType at;

	if ((dsa_status = rebind ()) != OK)
	    return dlist;

	if ((i = strlen (dp)) < dlevel)
	    break;

	sa -> sra_filter = fi = filter_alloc ();

	bzero ((char *) fi, sizeof *fi);
	fi -> flt_type = FILTER_ITEM;
	fi -> FUITEM.fi_type = FILTERITEM_EQUALITY;
	if ((fi -> FUITEM.UNAVA.ava_type = at = AttrT_new (ADOMAIN)) == NULL)
	    fatal (-100, "associatedDomain: invalid attribute type");
	fi -> FUITEM.UNAVA.ava_value =
	    str2AttrV (dp, at -> oa_syntax);

	while (ds_search (sa, se, sr) != DS_OK) {
	    if (dish_error (OPT, se) == 0) {
		dsa_status = NOTOK;
		goto free_filter;
	    }

	    sa -> sra_baseobject =
			    se -> ERR_REFERRAL.DSE_ref_candidates -> cr_name;
	}

	if (sr -> srr_correlated != TRUE)
	    correlate_search_results (sr);

	if (sr -> CSR_entries == NULLENTRYINFO) {
	    filter_free (sa -> sra_filter);
	    if (dp = index (dp, '.'))
		dp++;
	    if (dp == NULL)
		break;
	    continue;
	}

	if (i > dlevel) {
	    dlevel = i;
	    if (dlist)
		dn_seq_free (dlist), dlist = NULLDNSEQ;
	}

	if (i == dlevel)
	    for (ptr = sr -> CSR_entries; ptr; ptr = ptr -> ent_next) {
		struct dn_seq *dprev = dlist;

		dlist = dm2dn_seq_aux (dm, ptr -> ent_dn, dlist);

		if (dprev == dlist)
		    dlist = dn_seq_push (ptr -> ent_dn, dlist);
		else
		    if (i < dlevel)
			break;
	    }

	entryinfo_free (sr -> CSR_entries, 0);
free_filter: ;
	filter_free (sa -> sra_filter);
	break;
    }

    return dlist;
}

/*    UFN SUPPORT */

extern	char	ufn_notify;


static struct dn_seq *interact (dns, dn, s)
struct dn_seq *dns;
DN	dn;
char   *s;
{
    int	    i,
	    j;
    char   *bp,
	    buffer[BUFSIZ];
    struct dn_seq *result = NULL,
		  *ptr;
    static PS    nps = NULL;

    if (dns == NULL)
	return NULL;
    if (nps == NULLPS
	    && ((nps = ps_alloc (str_open)) == NULLPS
	            || str_setup (nps, NULLCP, 0, 0) == NOTOK)) {
	if (nps)
	    ps_free (nps);
	return dns;
    }

    i = 0;
    for (ptr = dns; ptr; ptr = ptr -> dns_next)
	i++;

    if (i == 1)
	return dns;

    bp = buffer;
    if (i > 10) {
	(void) sprintf (bp,
			"%d imprecise matches for '%s', select from them [y/n] ? ",
			i, s);
	if (!yesno (buffer)) {
	    dn_seq_free (dns);
	    return NULLDNSEQ;
	}

	*bp = NULL;
    }
    else
	(void) sprintf (bp,
			"Please select from the following %d match%s for '%s':\n",
			i, i != 1 ? "es" : "", s);

    dns_sort (&dns, i);

    j = 1;
    for (bp += strlen (buffer); dns; bp = buffer) {
	ps_print (nps, "  ");
	ufn_dn_print_aux (nps, dns -> dns_dn, dn, 0);
	ps_print (nps, " [y/n] ? ");
	ps_print (nps, " ");
	*--nps -> ps_ptr = NULL, nps -> ps_cnt++;

	(void) strcpy (bp, nps -> ps_base);

	nps -> ps_ptr = nps -> ps_base, nps -> ps_cnt = nps -> ps_bufsiz;

	if (yesno (buffer)) {
	    struct dn_seq *newdns = dn_seq_alloc ();

	    newdns -> dns_next = result;
	    newdns -> dns_dn = dn_cpy (dns -> dns_dn);
	    result = newdns;
	    dns = dns -> dns_next;
	}
	else {
	    struct dn_seq *tmp = dns;

	    dns = dns -> dns_next;
	    tmp -> dns_next = NULL;
	    dn_seq_free (tmp);
	}

	if ((j++ % 10) == 0 && dns) {
	    (void) sprintf (buffer, "Continue (%d more) [y/n] ? ", i - j + 1);
	    if (!yesno (buffer))
		break;
	}
    }

    return result;
}

/*  */

static	int	dns_compar (a, b)
struct dn_seq **a,
	      **b;
{
    int	    i;
    DN	    adn,
	    bdn;

    for (adn = (*a) -> dns_dn; adn -> dn_parent; adn = adn -> dn_parent)
	continue;
    for (bdn = (*b) -> dns_dn; bdn -> dn_parent; bdn = bdn -> dn_parent)
	continue;

    i = rdn_cmp (adn -> dn_rdn, bdn -> dn_rdn);
    return (i == (-1) || i == 1 ? i : 0);
}


static int	dns_sort (dns, i)
struct dn_seq **dns;
int	i;
{
    register struct dn_seq *ptr;

    if (i == 0)
	for (ptr = *dns; ptr; ptr = ptr -> dns_next)
	    i++;

    if (i > 1) {
	struct dn_seq **base,
		      **bp,
		      **ep;

	if (base = (struct dn_seq **) malloc ((unsigned) (i * sizeof *base))) {
	    ep = base;
	    for (ptr = *dns; ptr; ptr = ptr -> dns_next)
		*ep++ = ptr;

	    qsort ((char *) base, i, sizeof *base, dns_compar);

	    bp = base;
	    ptr = *dns = *bp++;
	    while (bp < ep) {
		ptr -> dns_next = *bp;
		ptr = *bp++;
	    }
	    ptr -> dns_next = NULL;

	    free ((char *) base);
	}
    }
}

/*  */

static	do_ufn_match (n, vec)
int	n;
char  **vec;
{
    int	    i;
    struct dn_seq *dns = NULL;
    register struct dn_seq *ptr;

    if (ufn_init () == FALSE) {
	ps_printf (OPT, "UFN initialization fails.\n");
	return;
    }

    if (rebind () != OK)
	return;

    ufn_notify = !frompipe;
    if (!ufn_match (n, vec, interact, &dns, (struct _envlist *) 0)) {
	ps_printf (OPT, "Unable to resolve name.\n");
	return;
    }

    if (dns == NULL) {
	ps_printf (OPT, "Search failed to find anything.\n");
	return;
    }

    i = 0;
    for (ptr = dns; ptr; ptr = ptr -> dns_next)
	i++;

    fred_long = i == 1; 
    fred_expand = fred_subdisplay = FALSE;
    fred_sequence = TRUE;

    if (i > 1) {
	ps_printf (RPS, "%d matches found.\n", i);
	(void) ps_flush (RPS);

	dns_sort (&dns, i);
    }

    for (ptr = dns; ptr; ptr = ptr -> dns_next) {
	normalize_dn (&ptr -> dns_dn);
	(void) add_sequence (ptr -> dns_dn);
    }
    for (i = 0, ptr = dns; ptr; ptr = ptr -> dns_next, i++) {
	if (i > 0)
	    (void) ps_flush (RPS);

	 (void) showfred (ptr -> dns_dn, fred_long, fred_subdisplay);
    }

    dn_seq_free (dns);
}

/*  */

normalize_dn (ptr)
DN     *ptr;
{
    register DN	    dn,
		    dn2,
		   *dp;
    register Entry wp;

    for (dn = *ptr, dp = &dn -> dn_parent; *dp; dp = &((*dp) -> dn_parent)) {
	dn2 = *dp, *dp = NULLDN;
	if ((wp = fredentry (dn, TRUE)) == NULLENTRY)
	    break;
	*dp = dn2;

	if (wp -> e_alias) {
	    *dp = NULLDN;
	    dn_append (dn = dn_cpy (wp -> e_alias), dn2);
	    dn_free (*ptr), *ptr = dn;
	    dp = &dn -> dn_parent;
	}
    }
}

/*    SHOWENTRY SUPPORT */

#include "quipu/list.h"
#include "quipu/read.h"

/*  */

static AttributeType t_mbox = NULLAttrT;
static AttributeType t_phone = NULLAttrT;
static AttributeType t_modtime = NULLAttrT;
static AttributeType t_modwhom = NULLAttrT;
static AttributeType t_postal = NULLAttrT;
static AttributeType t_title = NULLAttrT;
static AttributeType t_photo = NULLAttrT;

extern int postal_indent;
extern int ufn_indent;

static struct template {
    char   *t_name;
    char   *t_prefix;

    int	    t_level;

    AttributeType t_at;    
} default_template[] = {
    "title",				NULL,
		0, NULL,
    "documentTitle",			NULL,
		0, NULL,
#define	LEVEL_POSTAL	0
    "organizationName", 		NULL,
		0, NULL,
    "organizationalUnitName",		NULL,
		0, NULL,
	"roomNumber",			"  Room ",
		0, NULL,
	"streetAddress",		"  ",
		0, NULL,
	"postOfficeBox",		"  POB ",
		0, NULL,
	"physicalDeliveryOfficeName",	"  ",
		0, NULL,
	"stateOrProvinceName",		"  ",
		0, NULL,
	"postalCode", 			"  ",
		0, NULL,

    "postalAddress",			NULL,
		1, NULL,
    "documentAuthor",			"Author: ",
		1, NULL,

    "registeredAddress",		"Registered Address: ",
		2, NULL,
    "documentVersion",			"Version of: ",
		2, NULL,
    
    "telephoneNumber",			"Telephone: ",
		3, NULL,
    "mobileTelephoneNumber",		"Mobile:    ",
		3, NULL,
    "pagerTelephoneNumber",		"Pager:     ",
		3, NULL,
    "facsimileTelephoneNumber",		"FAX:       ",
		3, NULL,
    "telexNumber",			"Telex:     ",
		3, NULL,
    "teletexTerminalIdentifier",	"Teletex:   ",
		3, NULL,
    "x121Address",			"X.121:     ",
		3, NULL,
    "internationaliSDNNumber",		"ISDN:      ",
		3, NULL,
    "presentationAddress",		"OSI:       ",
		3, NULL,

#define	LEVEL_MBOX	4
    "rfc822Mailbox",			"  Mailbox: ",
		4, NULL,
        "otherMailbox",			"  ",
		4, NULL,
	"textEncodedORaddress",		"  ",
		4, NULL,

    "destinationIndicator",		"Destination Indicator:     ",
		5, NULL,
    "preferredDeliveryMethod",		"Preferred Delivery Method: ",
		5, NULL,
    "supportedApplicationContext",      "Supports:  ",
		5, NULL,

    "description",			NULL,
		6, NULL,

    "info",				"Information: ",
		7, NULL,
    "businessCategory",			"Business:    ",
		7, NULL,
    "userClass",			"User Class:  ",
		7, NULL,
    "localityName",			"Locality:    ",
    		7, NULL,
    "documentLocation",			"Location:    ",
		7, NULL,

    "aliasedObjectName",		"Alias to:  ",
		8, NULL,
    "roleOccupant",			"Occupant:  ",
		8, NULL,
    "seeAlso",				"See Also:  ",
		8, NULL,
    "secretary",			"Secretary: ",
		8, NULL,
    "manager",				"Manager:   ",
		8, NULL,

    "homePostalAddress",		"Home Address: ",
		9, NULL,
    "homePhone",			"Home Phone:   ",
		9, NULL,
    "favouriteDrink",			"Drinks:       ",
		9, NULL,
    "photo",				"Picture:      ",
		9, NULL,

    NULL
};


/*  */

showfred (mydn, islong, subdisplay)
DN	mydn;
char	islong,
	subdisplay;
{
    int	    didtime,
	    haspost,
	    level,
	    nchild,
	    pos,
	    seqno;
    register struct template *t;
    register Attr_Sequence eptr;
    register AV_Sequence avs,
			 avp;
    AttributeType rdn_at,
		  inf_at;
    AttributeValue rdn_av;
    Entry	myentry = fredentry (mydn = dn_cpy (mydn), islong);
    PS	    ps = NULLPS;
    RDN	    myrdn;
    static int once_only = 0;

    if (once_only == 0) {
	once_only++;

	t_mbox = AttrT_new ("rfc822Mailbox");
	t_phone = AttrT_new ("telephoneNumber");
	t_modtime = AttrT_new ("lastModifiedTime");
	t_modwhom = AttrT_new ("lastModifiedBy");
	t_postal = AttrT_new ("postalAddress");
	t_title = AttrT_new ("title");
	t_photo = AttrT_new ("photo");

	for (t = default_template; t -> t_name; t++)
	    t -> t_at = AttrT_new (t -> t_name);
    }

    pos = RPS -> ps_byteno;

    seqno = fred_sequence ? add_sequence (mydn) : 0;
    if (islong == FALSE) {
	if (seqno)
	    ps_printf (RPS, "%3d. ", seqno);
	else
	    ps_printf (RPS, "     ");
    }

    if (mydn) {
	register DN	adn;
	register RDN	rdn;


	if (islong == FALSE) {
	    ufn_dn_print_aux (RPS, mydn, NULLDN, 0);
	    goto ufn_short;
	}
	for (adn = mydn; adn -> dn_parent; adn = adn -> dn_parent)
	    continue;
	myrdn = adn -> dn_rdn;
	rdn_at = myrdn -> rdn_at, rdn_av = &myrdn -> rdn_av;
	AttrV_print (RPS, rdn_av, EDBOUT);
	for (rdn = myrdn -> rdn_next; rdn; rdn = rdn -> rdn_next) {
	    ps_print (RPS, " + ");
	    AttrV_print (RPS, &rdn -> rdn_av, EDBOUT);
	}
    }
    else {
	myrdn = NULLRDN, rdn_at = NULLAttrT, rdn_av = NULLAttrV;
	ps_print (RPS, "@");
    }

    if (islong == TRUE && seqno)
	ps_printf (RPS, " (%d)", seqno);

    if ((pos += 52 - RPS -> ps_byteno) <= 0)
	pos = 1;

    inf_at = NULLAttrT;
    if (myentry) {
	for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
	    if (!fred_phone && AttrT_cmp (eptr -> attr_type, t_mbox) == 0) {
		inf_at = t_mbox;

		if (avs = eptr -> attr_value) {
		    ps_printf (RPS, "%*s", pos, "");
		    showfredattr (&avs -> avseq_av);
		}
		break;
	    }
	    else
		if (AttrT_cmp (eptr -> attr_type, t_phone) == 0) {
		    inf_at = t_phone;
		    avp = eptr -> attr_value;
		}

	if (inf_at == t_phone && avp) {
	    ps_printf (RPS, "%*s", pos, "");
	    showfredattr (&avp -> avseq_av);
	}
    }

ufn_short: ;
    ps_print (RPS, "\n");

    if (myentry == NULLENTRY)
	goto out;
    if (islong == FALSE)
	goto children;

   for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
	if (AttrT_cmp (eptr -> attr_type, t_photo) == 0) {
	    if (eptr -> attr_value) {
		if (rdn_av
		        && (ps = ps_alloc (str_open)) != NULLPS
		        && str_setup (ps, NULLCP, 0, 0) != NOTOK) {
		    register RDN rdn;

		    AttrV_print (ps, rdn_av, EDBOUT);
		    for (rdn = myrdn -> rdn_next; rdn; rdn = rdn -> rdn_next) {
			ps_print (ps, "/");
			AttrV_print (ps, &rdn -> rdn_av, EDBOUT);
		    }
		    ps_print (ps, " ");
		    *--ps -> ps_ptr = NULL, ps -> ps_cnt++;
		    (void) setenv ("RDN", ps -> ps_base);
		}
		else
		    (void) setenv ("RDN", "Photo");
	    }
	    break;
	}

    level = 0;
    for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
	if (AttrT_cmp (eptr -> attr_type, rdn_at) == 0) {
	    for (avp = eptr -> attr_value; avp; avp = avp -> avseq_next)
		if (AttrV_cmp (&avp -> avseq_av, rdn_av)) {
		    ps_print (RPS, "     aka: ");
		    showfredattr (&avp -> avseq_av);
		    ps_print (RPS, "\n");
		    level++;
		}

	    break;
	}

    haspost = 0;
    for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
	if (AttrT_cmp (eptr -> attr_type, t_postal) == 0) {
	    if (eptr -> attr_value)
		haspost = 1;
	}
    ps_print (RPS, "\n");

    level = -1;
    for (t = default_template; t -> t_name; t++) {
	if (AttrT_cmp (t -> t_at, rdn_at) == 0)
	    continue;

	for (eptr = myentry -> e_attributes;
	         eptr;
	         eptr = eptr -> attr_link)
	    if (AttrT_cmp (eptr -> attr_type, t -> t_at) == 0) {
		int	i;

		if (AttrT_cmp (eptr -> attr_type, inf_at) == 0
		        && (avs = eptr -> attr_value)
		        && !avs -> avseq_next)
		    continue;

		if (haspost
			&& t -> t_level == LEVEL_POSTAL
			&& AttrT_cmp (eptr -> attr_type, t_title)) {
		    level = t -> t_level + 1;
		    continue;
		}

		if (t -> t_level != level) {
		    if (level >= 0)
			ps_print (RPS, "\n");
		    if ((level = t -> t_level) == LEVEL_MBOX)
			ps_print (RPS, "Mailbox information:\n");
		}
		
		if (t -> t_prefix) {
		    i = strlen (t -> t_prefix);
		    ps_printf (RPS, "%s", t -> t_prefix);
		}
		else
		    i = 0;

		if (avs = eptr -> attr_value) {
		    postal_indent = i;
		    ufn_indent = postal_indent + 2;
		    showfredattr (&avs -> avseq_av);
		    ps_print (RPS, "\n");
		    for (avp = avs -> avseq_next;
			     avp;
			     avp = avp -> avseq_next) {
			if (t -> t_prefix)
			    ps_printf (RPS, "%*s", i, "");
			else
			    ps_print (RPS, "\n");

			showfredattr (&avp -> avseq_av);

			ps_print (RPS, "\n");
		    }
		}
		else
		    ps_print (RPS, "no value?!?\n");

		break;
	    }
    }

    ufn_indent = (sizeof "Modified: " - 1) + 2;
    if (mydn) {
	ps_print (RPS, "\nName:     ");
	ufn_dn_print_aux (RPS, mydn, NULLDN, 1);
	if (seqno)
	    ps_printf (RPS, " (%d)", seqno);
    }

    ps_print (RPS, "\n");

    didtime = 0;
    for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
	if (AttrT_cmp (eptr -> attr_type, t_modtime) == 0) {
	    if (avs = eptr -> attr_value) {
		ps_print (RPS, "Modified: ");
		showfredattr (&avs -> avseq_av);
		ps_print (RPS, "\n");

		didtime = 1;
	    }
	    break;
	}
    if (didtime)
	for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
	    if (AttrT_cmp (eptr -> attr_type, t_modwhom) == 0) {
		if ((avs = eptr -> attr_value)
			&& dn_cmp ((DN) avs -> avseq_av.av_struct, mydn)) {
		    ps_print (RPS, "      by: ");
		    showfredattr (&avs -> avseq_av);
		    ps_print (RPS, "\n");
		}
		break;
	    }

children: ;
    nchild = 0;
    if (subdisplay) {
	struct ds_list_arg list_arg;
	struct ds_list_result list_result;
	struct DSError list_error;
	struct list_cache *ptr;

	(void) ps_flush (RPS);

	(void) service_control (OPT, 0, NULLVP, &list_arg.lsa_common);
	list_arg.lsa_common.ca_servicecontrol.svc_options |=
						SVC_OPT_DONTDEREFERENCEALIAS;

	if (ptr = find_list_cache (list_arg.lsa_object = mydn,
				   SVC_NOSIZELIMIT)) {
	    if (ptr -> list_subs)
		nchild = fred_children (mydn, ptr -> list_subs,
					ptr -> list_problem);

	    goto out;
	}

	if (rebind () != OK)
	    goto out;

	if (ds_list (&list_arg, &list_error, &list_result) != DS_OK) {
	    ds_error (RPS, &list_error);
	    goto out;
	}

	if (list_result.lsr_subordinates)
	    nchild = fred_children (mydn, list_result.lsr_subordinates,
			   list_result.lsr_limitproblem);

	cache_list (list_result.lsr_subordinates, list_result.lsr_limitproblem,
		    mydn, SVC_NOSIZELIMIT);
	subords_free (list_result.lsr_subordinates);
    }

out: ;
    if (mydn)
	dn_free (mydn);
    if (ps)
	ps_free (ps);
    postal_indent = -1;
    ufn_indent = -1;

    return nchild;
}

/*  */

static	fred_children (parentdn, ptr, prob)
DN	parentdn;
register struct subordinate *ptr;
int	prob;
{
    int	    i,
	    nchild;
    register struct subordinate *qtr;
    register DN	adn,
		newdn;

    newdn = dn_comp_new (rdn_comp_new (NULLAttrT, NULLAttrV));
    if (adn = dn_cpy (parentdn))
	dn_append (adn, newdn);
    else
	adn = newdn;

    i = 0;
    for (qtr = ptr; qtr; qtr = qtr -> sub_next)
	i++;
    nchild = i;

    if (i > 0)
	ps_printf (RPS, "%d child%s.\n-----\n", i, i != 1 ? "ren" : "");

    for (i = 0; ptr; ptr = ptr -> sub_next, i++) {
	rdn_free (newdn -> dn_rdn);
	dn_comp_fill (newdn, rdn_cpy (ptr -> sub_rdn));
	(void) add_sequence (adn);

	(void) showfred (adn, 0, FALSE);
    }

    dn_free (adn);

    if (prob != LSR_NOLIMITPROBLEM)
	ps_print (RPS, "(Limit problem)\n");

    return nchild;
}


/*  */

static showfredattr (av)
register AttributeValue av;
{
    int	    seqno;
    static int once_only = 0;
    static int s_dn;

    if (once_only == 0) {
	once_only++;

	s_dn = str2syntax ("DN");
    }

    if (av -> av_syntax == s_dn) {
	ufn_dn_print_aux (RPS, (DN) av -> av_struct, NULLDN, 1);

	if (fred_sequence && (seqno = add_sequence ((DN) av -> av_struct)))
	    ps_printf (RPS, " (%d)", seqno);
    }
    else
	AttrV_print (RPS, av, READOUT);
}

/*  */

static  Entry fredentry (adn, islong)
DN	adn;
char	islong;
{
    register Entry newentry;

    struct ds_read_arg read_arg;
    struct ds_read_result read_result;
    struct DSError read_error;
    
    if (adn == NULLDN)
	return NULLENTRY;

    if ((newentry = local_find_entry (read_arg.rda_object = adn,
				      FALSE)) == NULLENTRY
	    || !newentry -> e_lock
	    || (islong && !newentry -> e_complete)) {
	if (rebind () != OK)
	    return newentry;

	(void) service_control (OPT, 0, NULLVP, &read_arg.rda_common);
	read_arg.rda_common.ca_servicecontrol.svc_options |=
						SVC_OPT_DONTDEREFERENCEALIAS;
	read_arg.rda_eis.eis_infotypes = TRUE;
	read_arg.rda_eis.eis_allattributes = TRUE;
	read_arg.rda_eis.eis_select = NULLATTR;

	if (ds_read (&read_arg, &read_error, &read_result) != DS_OK) {
#ifdef	notdef
	    ds_error (RPS, &read_error);
#endif
	    return newentry;
	}

	cache_entry (&read_result.rdr_entry,
		     read_arg.rda_eis.eis_allattributes,
		     read_arg.rda_eis.eis_infotypes);

	entryinfo_comp_free (&read_result.rdr_entry, 0);

	newentry = local_find_entry (adn, FALSE);
    }

    return newentry;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.