ufname.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 1,847 行 · 第 1/3 页

C
1,847
字号
#ifndef lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/quipu/uips/doog/query/RCS/ufname.c,v 9.0 1992/06/16 12:45:27 isode Rel $";#endif/* $Header: /xtel/isode/isode/others/quipu/uips/doog/query/RCS/ufname.c,v 9.0 1992/06/16 12:45:27 isode Rel $ *//* * $Log: ufname.c,v $ * Revision 9.0  1992/06/16  12:45:27  isode * Release 8.0 * *//*****************************************************************************  ufname.c -*****************************************************************************/#include <ctype.h>#include "types.h"#include "ufname.h"#include "request.h"#include "error.h"#include "util.h"#include "ds_tasks.h"#include "ds_util.h"#include "quipu/ds_search.h"#include "quipu/dap2.h"#include "quipu/name.h"extern int dsap_ad;extern int next_task_id;#ifndef NO_STATSextern LLog    *log_stat;#endifstatic QE_error_code process_ufn_search();static QE_error_code directory_search();static QBool follow_path();searchPath ufnpaths = NULLSearchPath;/* * - get_ufn_status() - * * */ufnStatus get_ufn_status(request_id)     QCardinal request_id;{  (void) _get_request_of_id(request_id);  return NULLUfnStatus;  } /* get_ufn_status *//* * - get_ufn_results() - * Copy and return results for the identified ufn request, then delete all * records for that request. * */ufnResults get_ufn_results(id)     QCardinal id;{  requestRec ufn_request = _get_request_of_id(id);  ufnameRec ufnrec;  ufnResults results;  ufnrec = ufn_request->UFNAME_REC;  results = ufnrec->results;  results->tasks_sent = ufnrec->tasks_sent;  results->tasks_failed = ufnrec->tasks_failed;  ufnrec->results = NULLUfnResults;  return results;} /* get_ufn_results *//* * - do_ufn_resolve() - * Initiate a UFN search. * */QE_error_code do_ufn_resolve(baseobjects, ufname, is_leaf, id_ptr)     entryList baseobjects;     namePart ufname;     known is_leaf;     QCardinal *id_ptr;{  ufnameRec new_request;  namePart root_part, tmp_part;  entryList path;  requestRec request;  int name_part_count;  /* Record request invocation */  (void) _request_invoked(UFNAME, id_ptr);  request = _get_request_of_id(*id_ptr);  new_request = request->UFNAME_REC;  new_request->name_parts = ufname;  new_request->tasks_sent = new_request->tasks_failed = 0;  for (tmp_part = ufname, name_part_count = 1;       tmp_part->next != NULLNamePart;       tmp_part = tmp_part->next, name_part_count++)    ;    tmp_part->is_bottom_level = is_leaf;      if (baseobjects != NULLEntryList)    {      QCardinal base_object_num;      root_part = name_part_alloc();      root_part->next = ufname;            root_part->good_matches = root_part->poor_matches = NULLEntryList;      root_part->good_match_num = root_part->exact_match_num = 0;      root_part->part_name = NULLCP;      root_part->is_resolved = TRUE;      root_part->is_bottom_level = no;      root_part->exact_matches = baseobjects;      for (base_object_num = 0;	   baseobjects != NULLEntryList;	   baseobjects = baseobjects->next, base_object_num++)	;            root_part->exact_match_num = base_object_num;      new_request->name_parts = root_part;    }  else    {      path = new_request->path = get_ufn_path(name_part_count);      root_part = name_part_alloc();      root_part->next = ufname;            root_part->good_matches =	root_part->poor_matches =	  root_part->exact_matches = NULLEntryList;      root_part->good_match_num = 0;      root_part->part_name = NULLCP;      root_part->is_resolved = TRUE;      root_part->is_bottom_level = no;            (void) dn_list_add(path == NULLEntryList? "" : path->string_dn,			 &root_part->exact_matches,			 NULLAttrT);      new_request->path = new_request->path->next;      root_part->exact_match_num = 1;      new_request->name_parts = root_part;    }  new_request->request_id = *id_ptr;  new_request->results = NULLUfnResults;  return process_ufn_search(new_request);} /* do_ufn_resolve *//* * - process_ufn_search() - * Do/continue a UFN search. Uses requestRec to determine the stage that * the search has reached, and then proceeds accordingly. *		 * If search not yet started do an appropriate ds_search against the given base * object. * * If the given name is only partially resolved, search against the list * of partial names resolved thus far. * */static QE_error_code process_ufn_search(ufnrec)     ufnameRec ufnrec;{  namePart name_comp, prev_comp;  entryList resolved_names;  QE_error_code search_status;  requestRec request;  /* If ds searches outstanding, then do nothing. */  if (ufnrec->exact_task_count > 0 || ufnrec->approx_task_count > 0)    return QERR_ok;  /* Find out how far the search has gone. */  for (name_comp = ufnrec->name_parts, prev_comp = NULLNamePart;        name_comp != NULLNamePart && name_comp->is_resolved == TRUE;       prev_comp = name_comp, name_comp = name_comp->next)    ;  request = _get_request_of_id(ufnrec->request_id);  if (prev_comp == NULLNamePart)    {      /* If no name part_names yet resolved search against root object. */      if ((search_status = directory_search(NULLCP, name_comp, ufnrec))	  != QERR_ok)	{	  add_error_to_request_rec(request,				   NULLCP,				   search_status,				   (struct DSError *) NULL);	  return search_status;	}    }  else    {      /* Else search against all resolved names. If no exact matches, use	 good matches. If no good matches use poor matches.	 Return partial matches if match number exceeds limit */            if (prev_comp->exact_match_num > 0)	resolved_names = prev_comp->exact_matches;      else if (prev_comp->good_match_num > 0)	resolved_names = prev_comp->good_matches;      else if (prev_comp->poor_match_num > 0)	resolved_names = prev_comp->poor_matches;      else	return QERR_nothing_found;            while (resolved_names != NULLEntryList)	{	  if ((search_status =	       directory_search(resolved_names->string_dn, name_comp, ufnrec))	      != QERR_ok)	    return search_status;	  resolved_names = resolved_names->next;	}    }    return QERR_ok;} /* process_ufn_search *//* * * * */request_state continue_ufn_search(good_matches, request_id)     entryList good_matches;     QCardinal request_id;{  namePart last_part, first_real_part;  ufnameRec ufnrec;  requestRec request;  ufnResults results;  QCardinal good_match_num;  entryList curr_match;  request = _get_request_of_id(request_id);  ufnrec = request->UFNAME_REC;  for (last_part = ufnrec->name_parts->next;       last_part->poor_matches != NULLEntryList &&       last_part->good_matches == NULLEntryList &&       last_part->exact_matches == NULLEntryList &&       last_part != NULLNamePart;       last_part = last_part->next)    ;  if (last_part == NULLNamePart)    return RQ_error_returned;  else    {      for (good_match_num = 0, curr_match = good_matches;	   curr_match != NULLEntryList;	   curr_match = curr_match->next, good_match_num++)	;      if (good_match_num == 0)	{	  first_real_part = ufnrec->name_parts->next;	  	  if (first_real_part->is_resolved != TRUE)	    {	      if (ufnrec->path != NULLEntryList)		if (follow_path(ufnrec) == TRUE)		  {		    ufnrec->results = NULLUfnResults;		    return RQ_processing;		  }	      results = ufnrec->results = ufn_res_alloc();	      	      results->match_status = Failed;	      results->tried_intermediate = TRUE;	      	      results->resolved_part = results->unresolved_part = NULLCP;	      results->tasks_sent = ufnrec->tasks_sent;	      results->tasks_failed = ufnrec->tasks_failed;	      results->match_num = 0;	      results->matches = NULLEntryList;	      results->errors = request->errors;	      request->errors = NULLError;	    }	  else	    {	      ufnrec->results = NULLUfnResults;	      return RQ_processing;	    }	}            last_part->good_match_num = good_match_num;      last_part->good_matches = good_matches;      last_part->is_resolved = TRUE;      if (process_ufn_search(ufnrec) != QERR_ok)	return RQ_error_returned;      else	return RQ_processing;    }} /* continue_ufn_search *//* * - directory_search() - * Compose and invoke a X500 search. * */static QE_error_code directory_search(base_name, purp_name_comp, ufnrec)     char *base_name;     namePart purp_name_comp;     ufnameRec ufnrec;{  struct ds_search_arg search_arg;  struct DAPindication di;  DN base_dn;  AttributeType attr_type;  QBool is_attr_cmp = FALSE;  char *str_oid,       *start,       *end,       *search_value;  QCardinal level_count;  QBool has_org = FALSE, has_loc = FALSE, has_org_unit = FALSE;  Filter exact_filter, approx_filter;  Attr_Sequence get_attrs = (Attr_Sequence) NULL;  int task_id, count;  char *TidyString();  if (purp_name_comp->next == NULLNamePart &&      purp_name_comp->is_bottom_level == no)    return QERR_nothing_found;  if (purp_name_comp->is_bottom_level == might_not)    purp_name_comp->is_bottom_level = no;  /* Make a DN struct from given string object name.     If not valid then return an error. */  if (base_name == NULLCP || isnull(*base_name)) base_dn = NULLDN;  else if ((base_dn = str2dn(base_name)) == NULLDN) return QERR_bad_name;  /* `Analyse' the string dn. */  start = end = base_name;  level_count = 0;  if (base_dn != NULLDN)    while (1)      {	end = index(start, '=');		*end = '\0';	if ((attr_type = AttrT_new(start)) == NULLAttrT) return QERR_bad_name;	*end = '=';		/* Need the string oid of the base type. */	str_oid = attr_type->oa_ot.ot_stroid;		if (lexequ(str_oid, "2.5.4.7") == 0) has_loc = TRUE;	else if (lexequ(str_oid, "2.5.4.11") == 0) has_org_unit = TRUE;	else if (lexequ(str_oid, "2.5.4.10") == 0) has_org = TRUE;		level_count++;		if ((start = index(end, '@')) == NULLCP) break;	end = ++start;      }    /* Implace search parameters. */  (void) get_default_service(&search_arg.sra_common);  search_arg.sra_common.ca_servicecontrol.svc_options =    search_arg.sra_common.ca_servicecontrol.svc_options | SVC_OPT_PREFERCHAIN;  search_arg.sra_common.ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;  search_arg.sra_common.ca_servicecontrol.svc_sizelimit = 10;  search_arg.sra_baseobject = base_dn;  /* Don't want any attributes back. */  search_arg.sra_eis.eis_allattributes = FALSE;  /* Approx search will ask for some attributes back */  search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;  search_arg.sra_eis.eis_select = NULL;  /* Search dereferences alias entries. */  search_arg.sra_searchaliases = TRUE;  if (level_count >= 2 && has_org == TRUE)    search_arg.sra_subset = SRA_WHOLESUBTREE;  else    search_arg.sra_subset = SRA_ONELEVEL;  /* Make search filters for exact and approx matches. */  search_value = TidyString(purp_name_comp->part_name);  /* If a type is given, make appropriate filters. */  if (index(search_value, '=') != NULLCP)    {      is_attr_cmp = TRUE;      if (make_typed_filter_items(search_value, &exact_filter, &approx_filter)	  != QERR_ok)	  return QERR_bad_value_syntax;    }  /*   * If base object == root, can only search for a country.   */  else if (base_dn == NULLDN)    {      if ((int)strlen(search_value) > 2)	{	  attr_type = AttrT_new("0.9.2342.19200300.99.1.8");	  get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO);	  if (make_filter_items(attr_type,				search_value,				&exact_filter,				&approx_filter) != QERR_ok)	    return QERR_bad_value_syntax;	}      else	{	  exact_filter = filter_alloc();	  approx_filter = filter_alloc();	  	  approx_filter->flt_next = exact_filter->flt_next = NULLFILTER;	  exact_filter->flt_type = approx_filter->flt_type = FILTER_OR;	  	  attr_type = AttrT_new("2.5.4.6");	  get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO);	  if (make_filter_items(attr_type,				search_value,				&exact_filter->FUFILT,				&approx_filter->FUFILT) != QERR_ok)	    {	      filter_free(exact_filter);	      filter_free(approx_filter);	      attr_type = AttrT_new("0.9.2342.19200300.99.1.8");	      get_attrs = as_merge(get_attrs,				   as_comp_new(attr_type,					       NULLAV,					       NULLACL_INFO));	      if (make_filter_items(attr_type,				    search_value,				    &exact_filter,				    &approx_filter) != QERR_ok)		{		  return QERR_bad_value_syntax;		}	    }	  else	    {	      attr_type = AttrT_new("0.9.2342.19200300.99.1.8");	      get_attrs = as_merge(get_attrs,				   as_comp_new(attr_type,					       NULLAV,					       NULLACL_INFO));	      if (make_filter_items(attr_type,				    search_value,				    &exact_filter->FUFILT->flt_next,				    &approx_filter->FUFILT->flt_next)		  != QERR_ok)		{		  filter_free(exact_filter);		  filter_free(approx_filter);		  		  return QERR_bad_value_syntax;		}	    }	}    }  /*   * Check for `bottom level' case first so search    * against `cn', `sn' and `uid'. Get the `cn' and `uid' attrs back.   */  else if (purp_name_comp->is_bottom_level == unknown &&	   level_count >= 2 &&	   has_org == TRUE)    {      search_arg.sra_common.ca_servicecontrol.svc_sizelimit = 20;            exact_filter = filter_alloc();      approx_filter = filter_alloc();            approx_filter->flt_next = exact_filter->flt_next = NULLFILTER;      exact_filter->flt_type = approx_filter->flt_type = FILTER_OR;            /* `cn' filter item. */      attr_type = AttrT_new("2.5.4.3");      get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO);         if (make_filter_items(attr_type,			    search_value,			    &exact_filter->FUFILT,			    &approx_filter->FUFILT) != QERR_ok)	{	  filter_free(exact_filter);	  filter_free(approx_filter);	  	  return QERR_bad_value_syntax;	}            /* `sn' filter item. */      attr_type = AttrT_new("2.5.4.4");      if (make_filter_items(attr_type,			    search_value,			    &exact_filter->FUFILT->flt_next, 			    &approx_filter->FUFILT->flt_next) != QERR_ok)	{	  filter_free(exact_filter);	  filter_free(approx_filter);	  	  return QERR_bad_value_syntax;	}      exact_filter->FUFILT->flt_next->flt_next = NULLFILTER;      approx_filter->FUFILT->flt_next->flt_next = NULLFILTER;    }  /*   * Otherwise do an intermediate search.   */  else    {      /*       * If `organizationalUnit' in base object name filter on `ou'.       */      search_arg.sra_subset = SRA_ONELEVEL;            if (has_org_unit)	{	  attr_type = AttrT_new("2.5.4.11");	  /* Get back the 'ou' attrs */	  get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO);	  if (make_filter_items(attr_type,				search_value,				&exact_filter,				&approx_filter) != QERR_ok)	    {	      return QERR_bad_value_syntax;	    }	}      /*       * If no `locality' or `organization' in base object name search       * filter on `locality' or `organization'.       */      else if (!has_loc && !has_org)	{	  exact_filter = filter_alloc();	  approx_filter = filter_alloc();	  	  approx_filter->flt_next = exact_filter->flt_next = NULLFILTER;	  exact_filter->flt_type = approx_filter->flt_type = FILTER_OR;	  	  exact_filter->FUFILT = filter_alloc();	  approx_filter->FUFILT = filter_alloc();	  	  exact_filter->FUFILT->flt_next = filter_alloc();	  approx_filter->FUFILT->flt_next = filter_alloc();	  	  approx_filter->FUFILT->flt_next->flt_next =	    exact_filter->FUFILT->flt_next->flt_next = 	      approx_filter->flt_next =		exact_filter->flt_next = NULLFILTER;	  	  exact_filter->FUFILT->flt_type =	    approx_filter->FUFILT->flt_type =	      exact_filter->FUFILT->flt_next->flt_type =		approx_filter->FUFILT->flt_next->flt_type = FILTER_AND;	  	  /* `localityName' filter. */	  attr_type = AttrT_new("2.5.4.7");	  get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO);	  if (make_filter_items(attr_type,				search_value,				&exact_filter->FUFILT->FUFILT,				&approx_filter->FUFILT->FUFILT) != QERR_ok)	    {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?