|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T u
Length: 18290 (0x4772)
Types: TextFile
Names: »ufn_parse.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Chans/dirlist/ufn_parse.c«
/* ufn_parse.c - user-friendly name resolution */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/dirlist/RCS/ufn_parse.c,v 5.0 90/09/20 15:46:23 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Chans/dirlist/RCS/ufn_parse.c,v 5.0 90/09/20 15:46:23 pp Exp Locker: pp $
*
* $Log: ufn_parse.c,v $
* Revision 5.0 90/09/20 15:46:23 pp
* rcsforce : 5.0 public release
*
*/
/*
* 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 "ufn.h"
#include <isode/tailor.h>
#include <isode/quipu/list.h>
#include <isode/quipu/ds_search.h>
#include <isode/quipu/connection.h> /* ds_search uses di_block - include this for lint !!! */
#include <isode/quipu/dua.h>
char ufn_notify = FALSE;
extern char PY_pepy[];
#define NOTIFY(x) if (ufn_notify) (void) printf x, (void) putchar('\n'); else ;
AttributeType at_OrgUnit;
AttributeType at_Organisation;
AttributeType at_Locality;
AttributeType at_CountryName;
AttributeType at_FriendlyCountryName;
AttributeType at_CommonName;
AttributeType at_Surname;
AttributeType at_Userid;
AttributeType at_ObjectClass;
Attr_Sequence ufnas = NULL;
extern LLog * log_dsap;
extern Filter strfilter ();
extern Filter ocfilter ();
extern Filter joinfilter ();
DNS DNS_append (a,b)
DNS a, b;
{
DNS c;
if (a == NULLDNS)
return b;
for (c=a; c->dns_next != NULLDNS; c=c->dns_next)
; /* Nothing */
c->dns_next = b;
return a;
}
static Attr_Sequence read (base)
DN base;
{
Entry ptr;
if ((ptr = local_find_entry (base,FALSE)) != NULLENTRY)
return (ptr->e_attributes);
(void) printf ("You need the bug fix to libquipu.a !!!\n");
return NULLATTR;
}
static char exact_match (dn,s)
DN dn;
char * s;
{
RDN rdn;
for (; dn->dn_parent != NULLDN; dn=dn->dn_parent)
; /* Nothing */
for (rdn = dn->dn_rdn; rdn != NULLRDN; rdn=rdn->rdn_next) {
if (sub_string (rdn->rdn_av.av_syntax)
&& (lexequ((char *)rdn->rdn_av.av_struct,s) == 0))
return TRUE;
}
return FALSE;
}
static char good_match (dn,s)
DN dn;
char * s;
{
Attr_Sequence as;
AV_Sequence avs;
for (as = read(dn); as != NULLATTR; as=as->attr_link)
for (avs=as->attr_value; avs!= NULLAV; avs=avs->avseq_next)
if (sub_string (avs->avseq_av.av_syntax)
&& (lexequ((char *)avs->avseq_av.av_struct,s) == 0))
return TRUE;
return FALSE;
}
dnSelect (s,dlist,interact,el)
char * s;
DNS *dlist;
DNS (* interact) ();
DNS el;
{
DNS exact = NULLDNS;
DNS good = NULLDNS;
DNS bad = NULLDNS;
DNS tmp, next = NULLDNS;
if ((dlist == (DNS *)NULL) || (*dlist == NULLDNS))
return 2;
for (tmp= *dlist; tmp != NULLDNS; tmp=next) {
next = tmp->dns_next;
if (exact_match(tmp->dns_dn,s)) {
tmp->dns_next = exact;
exact = tmp;
} else if (good_match(tmp->dns_dn,s)) {
tmp->dns_next = good;
good = tmp;
} else {
tmp->dns_next = bad;
bad = tmp;
}
}
if (exact) {
NOTIFY (("Found exact match(es) for '%s'",s));
*dlist = exact;
dn_seq_free (good);
dn_seq_free (bad);
return TRUE;
}
if (good) {
NOTIFY (("Found good match(es) for '%s'",s));
*dlist = good;
dn_seq_free (bad);
return TRUE;
}
good = (*interact)(bad,el->dns_dn,s);
*dlist = good;
if (good != NULLDNS)
return TRUE;
else
return 2; /* back track allowed ! */
}
ufn_search (base, subtree, filt, res, s, interact, el)
DN base;
char subtree;
Filter filt;
DNS * res;
char * s;
DNS (* interact) ();
DNS el;
{
struct ds_search_arg search_arg;
static struct ds_search_result result;
struct DSError err;
static CommonArgs ca = default_common_args;
EntryInfo * ptr;
DNS newdns, r = NULLDNS;
search_arg.sra_baseobject = base;
search_arg.sra_filter = filt;
if (subtree)
search_arg.sra_subset = SRA_WHOLESUBTREE;
else
search_arg.sra_subset = SRA_ONELEVEL;
search_arg.sra_searchaliases = TRUE;
search_arg.sra_common = ca; /* struct copy */
search_arg.sra_eis.eis_infotypes = TRUE;
search_arg.sra_eis.eis_allattributes = FALSE;
search_arg.sra_eis.eis_select = ufnas;
#ifdef DEBUG
if (ufn_notify == 2)
print_search (base, subtree, filt);
#endif
if (ds_search (&search_arg, &err, &result) != DS_OK) {
log_ds_error (&err);
NOTIFY (("DAP Search returned an error"))
ds_error_free (&err);
filter_free (filt);
return FALSE;
}
filter_free (filt);
correlate_search_results (&result);
if ( (result.CSR_limitproblem != LSR_NOLIMITPROBLEM) || (result.CSR_cr != NULLCONTINUATIONREF)) {
if ( ! result.CSR_entries) {
NOTIFY (("Search returned partial results"))
return FALSE;
}
NOTIFY (("Continuing with partial results !"));
}
for (ptr = result.CSR_entries; ptr != NULLENTRYINFO; ptr=ptr->ent_next) {
cache_entry (ptr,FALSE,TRUE);
newdns = dn_seq_alloc();
newdns->dns_next = r;
newdns->dns_dn = dn_cpy (ptr->ent_dn);
r = newdns;
}
*res = r;
return dnSelect (s,res,interact,el);
}
static rootSearch (s,interact,el,result)
char * s;
DNS (* interact) ();
DNS el;
DNS * result;
{
Filter filt, filta, filtb, filtc, filtd, filte, filtf;
if (strlen (s) == 2) {
filta = strfilter (at_CountryName,s,FILTERITEM_EQUALITY);
filtb = strfilter (at_FriendlyCountryName,s,FILTERITEM_EQUALITY);
filtc = strfilter (at_Organisation,s,FILTERITEM_EQUALITY);
filtb->flt_next = filta;
filtc->flt_next = filtb;
filt = joinfilter (filtc, FILTER_OR);
return ufn_search (NULLDN,FALSE,filt,result,s,interact,el);
} else {
filta = strfilter (at_FriendlyCountryName,s,FILTERITEM_SUBSTRINGS);
filtb = strfilter (at_FriendlyCountryName,s,FILTERITEM_APPROX);
filtc = strfilter (at_Organisation,s,FILTERITEM_SUBSTRINGS);
filtd = strfilter (at_Organisation,s,FILTERITEM_APPROX);
filte = strfilter (at_Locality,s,FILTERITEM_SUBSTRINGS);
filtf = strfilter (at_Locality,s,FILTERITEM_APPROX);
filtb->flt_next = filta;
filtc->flt_next = filtb;
filtd->flt_next = filtc;
filte->flt_next = filtd;
filtf->flt_next = filte;
filt = joinfilter (filtf, FILTER_OR);
return ufn_search (NULLDN,FALSE,filt,result,s,interact,el);
}
}
static char present (d,t)
DN d;
AttributeType t;
{
for (; d != NULLDN; d=d->dn_parent)
if (AttrT_cmp (&(d->dn_rdn->rdn_at),t) == 0)
return TRUE;
return FALSE; /* More work ... */
}
static intSearch (base,s,interact,el,result)
DN base;
char * s;
DNS (* interact) ();
DNS el;
DNS * result;
{
Filter filt, filta, filtb, filtc, filtd, filte, filtf, filtg, filth;
if ( present (base,at_OrgUnit) ) {
filta = strfilter (at_OrgUnit,s,FILTERITEM_APPROX);
filtb = strfilter (at_OrgUnit,s,FILTERITEM_SUBSTRINGS);
filtb->flt_next = filta;
filt = joinfilter (filtb, FILTER_OR);
if ((filte = ocfilter ("OrganizationalUnit")) == NULLFILTER)
return FALSE;
filte->flt_next = filt;
filtf = joinfilter (filte, FILTER_AND);
return ufn_search (base,FALSE,filtf,result,s,interact,el);
} else if ( present (base,at_Organisation) ) {
filta = strfilter (at_OrgUnit,s,FILTERITEM_APPROX);
filtb = strfilter (at_OrgUnit,s,FILTERITEM_SUBSTRINGS);
filtc = strfilter (at_Locality,s,FILTERITEM_APPROX);
filtd = strfilter (at_Locality,s,FILTERITEM_SUBSTRINGS);
filtb->flt_next = filta;
filtc->flt_next = filtb;
filtd->flt_next = filtc;
filt = joinfilter (filtd, FILTER_OR);
if ((filte = ocfilter ("OrganizationalUnit")) == NULLFILTER)
return FALSE;
if ((filth = ocfilter ("Locality")) == NULLFILTER)
return FALSE;
filth->flt_next = filte;
filtg = joinfilter (filth, FILTER_OR);
filtg->flt_next = filt;
filtf = joinfilter (filtg, FILTER_AND);
return ufn_search (base,FALSE,filtf,result,s,interact,el);
} else if ( present (base,at_Locality) ) {
filta = strfilter (at_Organisation,s,FILTERITEM_APPROX);
filtb = strfilter (at_Organisation,s,FILTERITEM_SUBSTRINGS);
filtb->flt_next = filta;
filt = joinfilter (filtb, FILTER_OR);
if ((filte = ocfilter ("Organization")) == NULLFILTER)
return FALSE;
filte->flt_next = filt;
filtf = joinfilter (filte, FILTER_AND);
return ufn_search (base,FALSE,filtf,result,s,interact,el);
} else {
filta = strfilter (at_Organisation,s,FILTERITEM_APPROX);
filtb = strfilter (at_Organisation,s,FILTERITEM_SUBSTRINGS);
filtc = strfilter (at_Locality,s,FILTERITEM_APPROX);
filtd = strfilter (at_Locality,s,FILTERITEM_SUBSTRINGS);
filtb->flt_next = filta;
filtc->flt_next = filtb;
filtd->flt_next = filtc;
filt = joinfilter (filtd, FILTER_OR);
if ((filte = ocfilter ("Organization")) == NULLFILTER)
return FALSE;
if ((filth = ocfilter ("Locality")) == NULLFILTER)
return FALSE;
filth->flt_next = filte;
filtg = joinfilter (filth, FILTER_OR);
filtg->flt_next = filt;
filtf = joinfilter (filtg, FILTER_AND);
return ufn_search (base,FALSE,filtf,result,s,interact,el);
}
}
static leafSearch (base,s,subtree,interact,el,result)
DN base;
char * s;
char subtree;
DNS (* interact) ();
DNS el;
DNS * result;
{
Filter filt, filta, filtb, filtc, filtd, filte, filtf;
filta = strfilter (at_CommonName,s,FILTERITEM_APPROX);
filtb = strfilter (at_CommonName,s,FILTERITEM_SUBSTRINGS);
filtc = strfilter (at_Surname,s,FILTERITEM_APPROX);
filtd = strfilter (at_Surname,s,FILTERITEM_SUBSTRINGS);
filte = strfilter (at_Userid,s,FILTERITEM_APPROX);
filtf = strfilter (at_Userid,s,FILTERITEM_SUBSTRINGS);
filtb->flt_next = filta;
filtc->flt_next = filtb;
filtd->flt_next = filtc;
filte->flt_next = filtd;
filtf->flt_next = filte;
filt = joinfilter (filtf, FILTER_OR);
return ufn_search (base,subtree,filt,result,s,interact,el);
}
static keyedSearch (base,t,v,interact,el,result)
DN base;
char * t, *v;
DNS (* interact) ();
DNS el;
DNS * result;
{
Filter filt, filta, filtb;
AttributeType at;
if ((at = AttrT_new (t)) == NULLAttrT) {
NOTIFY (("Invalid Key !"));
return FALSE;
}
if ( ! sub_string (at->at_table->oa_syntax)) {
NOTIFY (("String types only !"));
return FALSE;
}
filta = strfilter (at,v,FILTERITEM_SUBSTRINGS);
filtb = strfilter (at,v,FILTERITEM_APPROX);
filtb->flt_next = filta;
filt = joinfilter (filtb, FILTER_OR);
if (base && base->dn_parent)
return ufn_search (base,TRUE,filt,result,v,interact,el);
else
return ufn_search (base,FALSE,filt,result,v,interact,el);
}
static purportedMatch(base,c,v,interact,el,result)
DN base;
int c;
char ** v;
DNS (* interact) ();
DNS el;
DNS * result;
{
char * s = v[c-1];
DNS root, x, new = NULLDNS;
char * ptr;
int matches;
if (c == 1) {
if ((ptr = index (s,'=')) != NULLCP) {
*ptr++ = 0;
matches = keyedSearch (base,SkipSpace(s),SkipSpace(ptr),interact,el,result);
*(--ptr) = '=';
return matches;
} else if (base == NULLDN) {
matches = rootSearch(s,interact,el,result);
if (*result != NULLDNS)
return matches;
else if (matches == TRUE)
return TRUE;
else
return leafSearch (base,s,FALSE,interact,el,result);
} else if (base->dn_parent == NULLDN) {
/* length == 1 */
matches = intSearch (base,s,interact,el,result);
if (*result != NULLDNS)
return matches;
else if (matches == TRUE)
return TRUE;
else
return leafSearch (base,s,FALSE,interact,el,result);
} else {
matches = leafSearch (base,s,TRUE,interact,el,result);
if (*result != NULLDNS)
return matches;
else if (matches == TRUE)
return TRUE;
else
return intSearch (base,s,interact,el,result);
}
}
if ((ptr = index (s,'=')) != NULLCP) {
*ptr++ = 0;
if ( ! (matches = keyedSearch (base,SkipSpace(s),SkipSpace(ptr),interact,el,&root))) {
*(--ptr) = '=';
return FALSE;
}
*(--ptr) = '=';
} else if (base == NULLDN) {
if ( ! (matches = rootSearch (s,interact,el,&root)))
return FALSE;
} else {
if ( ! (matches = intSearch (base,s,interact,el,&root)))
return FALSE;
}
for (x = root; x != NULLDNS; x = x->dns_next) {
if (purportedMatch (x->dns_dn, c-1, v,interact,el,&new)) {
if (new != NULLDNS)
*result = DNS_append (*result,new);
} else
return FALSE;
}
return matches;
}
static envMatch (c,v,el,interact,result)
int c;
char ** v;
DNS el;
DNS (* interact) ();
DNS * result;
{
int res;
if (el == NULLDNS)
return TRUE;
if ( ! ( res = purportedMatch(el->dns_dn,c,v,interact,el,result)))
return FALSE;
if (*result != NULLDNS)
return res;
if (res == TRUE)
return TRUE;
return envMatch(c,v,el->dns_next,interact,result);
}
static friendlyMatch_aux (c,v,el,interact,result)
int c;
char ** v;
envlist el;
DNS (* interact) ();
DNS * result;
{
if (el == NULLEL)
return TRUE;
if ( ( c <= el->Upper) && (c >= el->Lower) )
return envMatch (c,v,el->Dns,interact,result);
return (friendlyMatch_aux (c,v,el->Next,interact,result));
}
envlist read_envlist()
{
char * home, *p, *ptr;
char ufnrc [LINESIZE];
char * def;
char buffer [LINESIZE];
envlist env, top = NULLEL, trail = NULLEL;
DNS dtail = NULLDNS;
FILE * file;
DN dn;
int i = 0;
extern char * TidyString ();
if (home = getenv ("UFNRC"))
(void) strcpy (ufnrc, home);
else
if (home = getenv ("HOME"))
(void) sprintf (ufnrc, "%s/.ufnrc", home);
else
(void) strcpy (ufnrc, "./.ufnrc");
if ((file = fopen (ufnrc,"r")) == 0) {
def = isodefile("ufnrc",0);
if ((file = fopen(def,"r")) == 0) {
(void) sprintf (PY_pepy,"Can't open '%s' or '%s'",ufnrc,def);
return NULLEL;
}
}
while (fgets (buffer, LINESIZE, file) != 0) {
i++;
p = buffer;
if (( *p == '#') || (*p == '\0') || (*p == '\n'))
continue; /* ignore comments and blanks */
if (isspace (*p)) {
/* part of current environment */
if (!dtail) {
(void) sprintf (PY_pepy, "Unexpected blank at start of line %d",i);
(void) fclose (file);
return NULLEL;
}
p = TidyString(p);
if (*p == '-')
dn = NULLDN;
else if ((dn = str2dn (p)) == NULLDN) {
(void) sprintf (PY_pepy, "Bad DN in environment file line %d",i);
(void) fclose (file);
return NULLEL;
}
dtail->dns_next = dn_seq_alloc();
dtail = dtail->dns_next;
dtail->dns_next = NULLDNS;
dtail->dns_dn = dn;
continue;
}
p = TidyString (p);
if ((ptr = index (p,':')) == NULLCP) {
(void) sprintf (PY_pepy, "':' missing in environment file line %d",i);
(void) fclose (file);
return NULLEL;
}
*ptr++ = 0;
ptr = SkipSpace (ptr);
if (*ptr == '-')
dn = NULLDN;
else if ((dn = str2dn (ptr)) == NULLDN) {
(void) sprintf (PY_pepy, "Bad DN in environment file line %d",i);
(void) fclose (file);
return NULLEL;
}
env = (envlist) smalloc (sizeof (*env));
dtail = env->Dns = dn_seq_alloc();
dtail->dns_next = NULLDNS;
dtail->dns_dn = dn;
env->Next = NULLEL;
if (top == NULLEL)
top = env;
else
trail->Next = env;
trail = env;
if ((ptr = index (p,',')) != NULLCP) {
*ptr++ = 0;
ptr = SkipSpace(ptr);
if (*ptr == '+')
env->Upper = 32767; /* ~= infinity */
else
env->Upper = atoi (ptr); /* how to test error ? */
} else
env->Upper = 0;
p = SkipSpace(p);
env->Lower = atoi (p); /* how to test error ? */
if ( ! env->Upper)
env->Upper = env->Lower;
}
(void) fclose (file);
return top;
}
ufn_match (c,v,interact,result,el)
int c;
char ** v;
DNS (* interact) ();
DNS * result;
envlist el;
{
static int inited = FALSE;
if ( (!ufnas) && !(inited = ufn_init()))
return inited;
PY_pepy[0] = NULL;
if (el == NULLEL) {
if ((el = read_envlist ()) == NULLEL) {
(void) sprintf (PY_pepy,"Can't read environment");
return 0;
}
}
return (friendlyMatch_aux (c,v,el,interact,result));
}
ufn_init ()
{
Attr_Sequence as;
int result = TRUE;
if (ufnas)
return result;
if ((at_ObjectClass = AttrT_new ("ObjectClass")) == NULLAttrT) {
result = FALSE;
LLOG (log_dsap,LLOG_EXCEPTIONS,("ObjectClass attribute unknown"));
}
if ((at_OrgUnit = AttrT_new ("ou")) == NULLAttrT) {
result = FALSE;
LLOG (log_dsap,LLOG_EXCEPTIONS,("ou attribute unknown"));
}
if ((at_Organisation = AttrT_new ("o")) == NULLAttrT) {
result = FALSE;
LLOG (log_dsap,LLOG_EXCEPTIONS,("o attribute unknown"));
}
if ((at_Locality = AttrT_new ("l")) == NULLAttrT) {
result = FALSE;
LLOG (log_dsap,LLOG_EXCEPTIONS,("l attribute unknown"));
}
if ((at_CountryName = AttrT_new ("c")) == NULLAttrT) {
result = FALSE;
LLOG (log_dsap,LLOG_EXCEPTIONS,("c attribute unknown"));
}
if ((at_FriendlyCountryName = AttrT_new ("FriendlyCountryName")) == NULLAttrT) {
result = FALSE;
LLOG (log_dsap,LLOG_EXCEPTIONS,("FriendlyCountryName attribute unknown"));
}
if ((at_CommonName = AttrT_new (CN_OID)) == NULLAttrT) {
result = FALSE;
LLOG (log_dsap,LLOG_EXCEPTIONS,("cn attribute unknown"));
}
if ((at_Surname = AttrT_new ("sn")) == NULLAttrT) {
result = FALSE;
LLOG (log_dsap,LLOG_EXCEPTIONS,("sn attribute unknown"));
}
if ((at_Userid = AttrT_new ("uid")) == NULLAttrT) {
result = FALSE;
LLOG (log_dsap,LLOG_EXCEPTIONS,("uid attribute unknown"));
}
ufnas = as_comp_new (at_OrgUnit,NULLAV,NULLACL_INFO);
as = as_comp_new (at_Organisation,NULLAV,NULLACL_INFO);
ufnas = as_merge (ufnas,as);
as = as_comp_new (at_Locality,NULLAV,NULLACL_INFO);
ufnas = as_merge (ufnas,as);
as = as_comp_new (at_CountryName,NULLAV,NULLACL_INFO);
ufnas = as_merge (ufnas,as);
as = as_comp_new (at_FriendlyCountryName,NULLAV,NULLACL_INFO);
ufnas = as_merge (ufnas,as);
as = as_comp_new (at_CommonName,NULLAV,NULLACL_INFO);
ufnas = as_merge (ufnas,as);
as = as_comp_new (at_Surname,NULLAV,NULLACL_INFO);
ufnas = as_merge (ufnas,as);
as = as_comp_new (at_Userid,NULLAV,NULLACL_INFO);
ufnas = as_merge (ufnas,as);
return result;
}
#ifdef DEBUG
static print_search (dn, subtree, fi)
DN dn;
char subtree;
Filter fi;
{
static PS nps = NULLPS;
if (nps == NULLPS) {
if ((nps = ps_alloc (std_open)) == NULL) {
(void) fprintf (stderr, "ps_alloc(std_open): you lose\n");
return;
}
if (std_setup (nps, stdout) == NOTOK) {
(void) fprintf (stderr, "std_setup(stdout): you lose\n");
ps_free (nps);
nps = NULL;
return;
}
}
ps_printf (nps, "search starting at @");
dn_print (nps, dn, EDBOUT);
ps_printf (nps, "(%s) for ", subtree ? "subtree" : "singlelevel");
print_filter (nps, fi, 0);
ps_print (nps, "\n\n");
(void) ps_flush (nps);
}
#endif