ufname.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 1,847 行 · 第 1/3 页
C
1,847 行
filter_free(exact_filter); filter_free(approx_filter); return QERR_bad_value_syntax; } /* Make sure it's a locality object type */ attr_type = AttrT_new("2.5.4.0"); if (make_filter_items(attr_type, "2.5.6.3", &exact_filter->FUFILT->FUFILT->flt_next, &approx_filter->FUFILT->FUFILT->flt_next) != QERR_ok) { filter_free(exact_filter); filter_free(approx_filter); return QERR_bad_value_syntax; } exact_filter->FUFILT->FUFILT->flt_next->flt_next = approx_filter->FUFILT->FUFILT->flt_next->flt_next = NULLFILTER; /* `organizationName' filter item. */ attr_type = AttrT_new("2.5.4.10"); 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->FUFILT, &approx_filter->FUFILT->flt_next->FUFILT) != QERR_ok) { filter_free(exact_filter); filter_free(approx_filter); return QERR_bad_value_syntax; } /* Make sure it's an org object type */ attr_type = AttrT_new("2.5.4.0"); if (make_filter_items(attr_type, "2.5.6.4", &exact_filter->FUFILT->flt_next->FUFILT->flt_next, &approx_filter->FUFILT->flt_next->FUFILT->flt_next) != QERR_ok) { filter_free(exact_filter); filter_free(approx_filter); return QERR_bad_value_syntax; } exact_filter->FUFILT->flt_next->FUFILT->flt_next->flt_next = approx_filter->FUFILT->flt_next->FUFILT->flt_next->flt_next = NULLFILTER; } /* * If `organization' in base object name filter against * `ou' and `localityName'. */ else if (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; /* `ou' filter item. */ attr_type = AttrT_new("2.5.4.11"); 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; } /* `localityName' filter item. */ attr_type = AttrT_new("2.5.4.7"); 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; } exact_filter->FUFILT->flt_next->flt_next = approx_filter->FUFILT->flt_next->flt_next = NULLFILTER; } /* * If none of above and base object name has `locality' filter * on `organizationName'. */ else if (has_loc) { attr_type = AttrT_new("2.5.4.10"); 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; } } } /* * First invoke exact match, then invoke approx match. * Record task invocation for this particular request. * */ for (count = 0; ufnrec->dap_exact_task_ids[count] != NO_TASK && count < MAX_TASKS_PER_REQ; count++) ; if (count == MAX_TASKS_PER_REQ) { filter_free(exact_filter); filter_free(approx_filter); return QERR_internal_limit_reached; } if (_task_invoked(SEARCH_TASK, base_name, ufnrec->request_id, &task_id) != QERR_ok) { filter_free(exact_filter); filter_free(approx_filter); return QERR_internal_limit_reached; } /* Invoke search using exact match. */ search_arg.sra_filter = exact_filter; if (DapSearch(dsap_ad, task_id, &search_arg, &di, ROS_ASYNC) == NOTOK) { filter_free(exact_filter); filter_free(approx_filter); _task_complete(task_id); return QERR_request_failed; } else { ufnrec->exact_task_count++; ufnrec->dap_exact_task_ids[count] = task_id; ufnrec->tasks_sent++; } #ifndef NO_STATS LLOG (log_stat, LLOG_NOTICE, ("EXACT MATCH +%s, task %d, extent %d, val %s", base_name, task_id, search_arg.sra_subset, search_value));#endif if (count == MAX_TASKS_PER_REQ) { filter_free(exact_filter); filter_free(approx_filter); return QERR_internal_limit_reached; } /* * Invoke approx match. * Record task invocation for this particular request. */ if (is_attr_cmp == FALSE) { for (count = 0; ufnrec->dap_approx_task_ids[count] != NO_TASK && count < MAX_TASKS_PER_REQ; count++) ; if (count == MAX_TASKS_PER_REQ) { filter_free(exact_filter); filter_free(approx_filter); return QERR_internal_limit_reached; } if (_task_invoked(SEARCH_TASK, base_name, ufnrec->request_id, &task_id) != QERR_ok) { filter_free(exact_filter); filter_free(approx_filter); return QERR_internal_limit_reached; } search_arg.sra_filter = approx_filter; search_arg.sra_eis.eis_select = get_attrs; if (DapSearch(dsap_ad, task_id, &search_arg, &di, ROS_ASYNC) == NOTOK) { filter_free(exact_filter); filter_free(approx_filter); _task_complete(task_id); return QERR_request_failed; } else { ufnrec->approx_task_count++; ufnrec->dap_approx_task_ids[count] = task_id; ufnrec->tasks_sent++; } #ifndef NO_STATS LLOG (log_stat, LLOG_NOTICE, ("APPROX MATCH +%s, task %d, extent %d, val %s", base_name, task_id, search_arg.sra_subset, search_value));#endif } if (get_attrs != (Attr_Sequence) NULL) as_free(get_attrs); filter_free(exact_filter); filter_free(approx_filter); return QERR_ok;} /* directory_search *//* * - ufname_rec_free() - * Free a ufname_rec structure. * */void ufname_rec_free(record) ufnameRec record;{ if (record == NULLUfnameRec) return; name_part_free(&record->name_parts); free((char *) record);} /* ufname_rec_free *//* * - ufname_result_free() - * * */void ufname_result_free(ufn_result) ufnResults *ufn_result;{ ufnResults result = *ufn_result; if (result == NULLUfnResults) return; error_list_free(&result->errors); dn_list_free(&result->matches); if (result->unresolved_part != NULLCP) free(result->unresolved_part); if (result->resolved_part != NULLCP) free(result->resolved_part); free((char *) result); *ufn_result = NULLUfnResults;} /* ufname_result_free *//* * - name_part_free() - * Free a name part list. * */void name_part_free(name) namePart *name;{ register namePart part = *name; namePart next_part; while (part) { free(part->part_name); if (part->exact_matches != NULLEntryList) dn_list_free(&part->exact_matches); if (part->good_matches != NULLEntryList) dn_list_free(&part->good_matches); if (part->poor_matches != NULLEntryList) dn_list_free(&part->poor_matches); next_part = part->next; free((char *) part); part = next_part; } *name = NULLNamePart;} /* name_part_free *//* * - str2ufname() - * Convert a string encode UFN into a list of name part_names. * */namePart str2ufname(str_ufn) char *str_ufn;{ namePart name_comp = NULLNamePart, new_comp; register char *start, *end; char save; start = str_ufn; while (!isnull(*start)) { while (isspace(*start) && !isnull(*start)) start++; end = start; if (*end++ == '\"') { while (*end != '\"' && !isnull(*end)) end++; if (isnull(*end)) { if (name_comp != NULLNamePart) name_part_free(&name_comp); return NULLNamePart; } } while (*end != ',' && !isnull(*end)) end++; end--; while (isspace(*end)) end--; end++; save = *end; *end = '\0'; if (name_comp == NULLNamePart) { name_comp = name_part_alloc(); name_comp->is_bottom_level = unknown; name_comp->next = NULLNamePart; } else { new_comp = name_part_alloc(); new_comp->next = name_comp; name_comp = new_comp; name_comp->is_bottom_level = no; } name_comp->part_name = copy_string(start); name_comp->is_resolved = FALSE; name_comp->exact_matches = name_comp->good_matches = name_comp->poor_matches = NULLEntryList; name_comp->exact_match_num = name_comp->good_match_num = name_comp->poor_match_num = 0; *end = save; while (*end != ',' && !isnull(*end)) end++; if (!isnull(*end)) end++; while (isspace(*end)) end++; start = end; } return name_comp;} /* str2ufname *//* * - process_ufn_ds_result() - * A ds result bound for a ufn request has been received. Process the * results and update the request record accordingly. If request has * completed indicate this. * */request_state process_ufn_ds_result(request, task_id, ds_result) requestRec request; int task_id; struct DSResult *ds_result;{ DsTask task_rec; ufnameRec ufnrec = request->UFNAME_REC; namePart name_comp, curr_part, part; int *ufn_task_array; QBool is_exact_match_result; QCardinal aindex, hit_count; struct ds_search_result *search_result; task_rec = _get_task_of_id(task_id); /* This shouldn't happen */ if (task_rec == NULLDsTask) return RQ_processing; for (name_comp = ufnrec->name_parts; name_comp->is_resolved == TRUE && name_comp != NULLNamePart; name_comp = name_comp->next) ; /* This shouldn't happen! */ if (name_comp == NULLNamePart) { _task_complete(task_id); return RQ_processing; } /* Check if result comes from a search using exact or approx match. */ for (aindex = 0, ufn_task_array = ufnrec->dap_exact_task_ids; ufn_task_array[aindex] != task_id && aindex < MAX_TASKS_PER_REQ; aindex++) ; /* Not an exact search, so must have been an approx search. */ if (aindex >= MAX_TASKS_PER_REQ) { for (aindex = 0, ufn_task_array = ufnrec->dap_approx_task_ids; ufn_task_array[aindex] != task_id && aindex < MAX_TASKS_PER_REQ; aindex++) ; if (aindex < MAX_TASKS_PER_REQ) is_exact_match_result = FALSE; } else is_exact_match_result = TRUE; /* If not an approx search, then something's wrong! */ if (aindex >= MAX_TASKS_PER_REQ) { _task_complete(task_id); return RQ_processing; } /* Now get the search results. */ search_result = &ds_result->res_sr; correlate_search_results(search_result); /* ######### Have to d this could because of a dsap bug(?) ######### */ search_result->srr_next = NULLSRR; hit_count = 0; if (search_result->CSR_entries != NULLENTRYINFO) { EntryInfo *entry_ptr; register stringCell curr_attr; attrValList got_attrs, curr_av; char *curr_name, *match_str; QBool good_match; char *dn2str(); void get_read_attrs(); /* Decode and add found entry names */ for (entry_ptr = search_result->CSR_entries; entry_ptr != NULLENTRYINFO; entry_ptr = entry_ptr->ent_next) { curr_name = qy_dn2str(entry_ptr->ent_dn); if (!is_exact_match_result) { match_str = name_comp->part_name; if (index(match_str, '=') == NULLCP) { get_read_attrs(entry_ptr->ent_attr, &got_attrs, READOUT); if (got_attrs != NULLAVList) for (curr_av = got_attrs, good_match = FALSE; curr_av != NULLAVList && good_match == FALSE; curr_av = curr_av->next) for (curr_attr = curr_av->val_list; curr_attr != NULLStrCell && good_match == FALSE; curr_attr = curr_attr->next) { if (is_good_match(match_str, curr_attr->string)) good_match = TRUE; } else good_match = FALSE; } else good_match = TRUE; if (good_match == TRUE) { if (dn_list_add(curr_name, &name_comp->good_matches, NULLAttrT)) name_comp->good_match_num++; } else { if ((int)strlen(match_str) > 2 && dn_list_add(curr_name, &name_comp->poor_matches, NULLAttrT)) name_comp->poor_match_num++; } if (got_attrs != NULLAVList) { free_string_seq(&(got_attrs->attr_name)); free_string_seq(&(got_attrs->val_list)); free((char *) got_attrs); got_attrs = NULLAVList; } } else if (dn_list_add(curr_name, &name_comp->good_matches, NULLAttrT)) name_comp->good_match_num++; hit_count++; if (curr_name != NULLCP) free(curr_name); } if (search_result->CSR_limitproblem != LSR_NOLIMITPROBLEM) { QE_error_code limitproblem; switch (search_result->CSR_limitproblem) { case LSR_TIMELIMITEXCEEDED: limitproblem = QERR_time_limit_reached; break; case LSR_SIZELIMITEXCEEDED: limitproblem = QERR_size_limit_reached; break; case LSR_ADMINSIZEEXCEEDED: limitproblem = QERR_admin_limit_reached; break; } add_error_to_request_rec(request, task_rec->baseobject, limitproblem, (struct DSError *) NULL); } } #ifndef NO_STATS LLOG (log_stat, LLOG_NOTICE, ("SEARCH RESULT from +%s, task %d, hits %d", task_rec->baseobject, task_id, hit_count));#endif /* * Remove record of this task */ ufn_task_array[aindex] = NO_TASK; if (is_exact_match_result == TRUE) ufnrec->exact_task_count--; else ufnrec->approx_task_count--; _task_complete(task_id); /* Check the status of this request. */ /* First check if this stage of matching has been completed */ if (ufnrec->exact_task_count == 0 && ufnrec->approx_task_count == 0) { ufnResults results = ufn_res_alloc(); results->tried_intermediate = FALSE; results->match_status = Failed; results->match_num = 0; results->matches = NULLEntryList; results->unresolved_part = results->resolved_part = NULLCP; results->errors = NULLError; results->tasks_sent = ufnrec->tasks_sent; results->tasks_failed = ufnrec->tasks_failed; if (name_comp->exact_match_num > 0 || name_comp->good_match_num > 0) name_comp->is_resolved = TRUE; /* * If no matches found and haven't checked for intermediate level * entries, do so, else continue. * */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?