#ifndef lint static char *rcsid = "$Header: /Pluto/Pluto2/src/local/X500/xd/pod/RCS/filt.c,v 1.7 90/05/18 12:11:51 emsrdsm Exp Locker: emsrdsm $"; #endif /* * $Header: /Pluto/Pluto2/src/local/X500/xd/pod/RCS/filt.c,v 1.7 90/05/18 12:11:51 emsrdsm Exp Locker: emsrdsm $ */ #include <string.h> #include <malloc.h> #include <ctype.h> #include "quipu/util.h" #include "quipu/common.h" #include "quipu/entry.h" #include "filt.h" #include "y.tab.h" extern unsigned int curr_filt; extern unsigned int filt_num; extern unsigned int typeindx; extern filt_struct *filt_arr[]; extern char *filtvalue[]; extern char *filttype[]; extern char *default_arr[]; extern char mvalue[]; void tprint(), cleartext(); void make_type(name_val, filt) char * name_val; filt_struct * filt; { filttype[curr_filt] = strdup(name_val); filt_arr[curr_filt] = filt; } filt_struct *make_item_filter(oid, match, value) char *oid; int match; char *value; { register filt_struct * filt = (filt_struct *) malloc(sizeof(filt_struct)); filt->flt_type = ITEM; filt->next = 0; filt->fu_cont.item.fi_type = match; filt->fu_cont.item.stroid = (char *) malloc((unsigned) (strlen(oid) + 1)); (void) strcpy(filt->fu_cont.item.stroid, oid); if (*value == '*') filt->fu_cont.item.name = (char *) 0; else { filt->fu_cont.item.name = (char *) malloc((unsigned) (strlen(value) + 1)); (void) strcpy(filt->fu_cont.item.name, value); } return filt; } filt_struct *link_filters(filt1, filt2) filt_struct *filt1; filt_struct *filt2; { filt1->next = filt2; return filt1; } filt_struct *make_parent_filter(filt_type, filt1, filt2, filt3) int filt_type; filt_struct * filt1; filt_struct * filt2; filt_struct * filt3; { filt_struct * parent = (filt_struct *) malloc(sizeof(filt_struct)); switch (filt_type) { case NOT: parent->flt_type = NOT; parent->fu_cont.sub_filt = filt1; parent->next = 0; break; case AND: parent->flt_type = AND; parent->fu_cont.sub_filt = filt1; filt1->next = filt2; filt2->next = filt3; parent->next = 0; break; default: parent->flt_type = OR; parent->fu_cont.sub_filt = filt1; filt1->next = filt2; filt2->next = filt3; parent->next = 0; break; } return parent; } Filter make_attr_filter() { int match_type; char attr_name[1024], attr_val[1024], sub_val_initial[1024], sub_val_final[1024], sub_val_any[1024]; register char *end, *start, *next; char save; Filter rfilt, sfilt = filter_alloc(); sfilt->flt_type = FILTER_ITEM; sfilt->flt_next = NULLFILTER; sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY; sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = NULLAttrV; sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = NULLAttrT; if (end = index(mvalue, '~')) match_type = APPROX; else if (end = index(mvalue, '*')) match_type = SUBSTRING; else match_type = EQUAL; start = mvalue; while (isspace(*start) && *start != '\0') start++; end = start; while (!isspace(*end) && *end != '=' && *end != '~' && *end != '*' && *end != '\0') end++; save = *end; *end = '\0'; (void) strcpy(attr_name, start); *end = save; if (attr_name [0] == '\0') { cleartext(); tprint ("Error: Cannot search, invalid syntax on filter '%s'.\n", mvalue); filter_free(sfilt); return NULLFILTER; } start = end + 1; if (match_type != SUBSTRING) { while (!isalnum(*start) && *start != '\0') start++; end = start; while (*end != '\0') end++; while (!isalnum(*end) && end > start) end--; if (*end != '\0') end++; save = *end; *end = '\0'; (void) strcpy(attr_val, start); *end = save; if (attr_val[0] == '\0') { cleartext(); tprint ("Error: Cannot search, invalid syntax on filter '%s'.\n", mvalue); filter_free(sfilt); return NULLFILTER; } } else { while (!isalnum(*start) && *start != '*' && *start != '\0') start++; if (*start == '\0') { cleartext(); tprint ("Error: Cannot search, invalid syntax on filter '%s'.\n", mvalue); filter_free(sfilt); return NULLFILTER; } if (*start == '*') { sub_val_initial[0] = '*'; ++start; while (isspace(*start) && *start != '\0') start++; if (*start == '\0' || !isalnum(*start)) { cleartext(); tprint ("Error: Cannot search, invalid syntax on filter '%s'.\n", mvalue); filter_free(sfilt); return NULLFILTER; } end = start; while (isalnum(*end) && *end != '\0') end++; if (*end == '\0') { (void) strcpy (sub_val_final, start); sub_val_any[0] = '*'; } else { next = end; while (*next != '*' && *next != '\0') next++; if (*next == '*') { sub_val_final[0] = '*'; save = *end; *end = '\0'; (void) strcpy(sub_val_any, start); *end = save; } else { sub_val_any[0] = '*'; save = *end; *end = '\0'; (void) strcpy(sub_val_final, start); *end = save; } } } else if (isalnum(*start)) { end = start; while (!isspace(*end) && *end != '\0') end++; if (*end == '\0') { cleartext(); tprint ("Error: Cannot search, invalid syntax on filter '%s'.\n", mvalue); filter_free(sfilt); return NULLFILTER; } save = *end; *end = '\0'; if (index ((char *) (end + 1), '*') == NULLCP) { cleartext(); tprint ("Error: Cannot search, invalid syntax on filter '%s'.\n", mvalue); filter_free(sfilt); return NULLFILTER; } else { (void) strcpy(sub_val_initial, start); sub_val_any[0] = sub_val_final[0] = '*'; } } } switch (match_type) { case APPROX: case EQUAL: sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = AttrT_new(attr_name); if (match_type == EQUAL) sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY; else sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_APPROX; if (!sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type || sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type->oa_syntax == 0) { cleartext(); tprint ("Error: Cannot search, invalid attribute type '%s'.\n", attr_name); rfilt = sfilt->flt_next; sfilt->flt_next = NULLFILTER; filter_free(sfilt); return NULLFILTER; } if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = str2AttrV(attr_val, sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> oa_syntax)) == NULL) { cleartext(); tprint ("Error: Cannot search, invalid value '%s' for attribute type '%s'.\n", attr_val, attr_name); filter_free(sfilt); return NULLFILTER; } return sfilt; case SUBSTRING: sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_SUBSTRINGS; sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_initial = NULLAV; sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_final = NULLAV; sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any = NULLAV; sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_type = AttrT_new(attr_name); if (!sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type || sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type->oa_syntax == 0) { cleartext(); tprint ("Error: Cannot search, invalid attribute type '%s'.\n", attr_name); filter_free(sfilt); return NULLFILTER; } if (sub_val_initial[0] != '*') if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_initial = avs_comp_new(str2AttrV(sub_val_initial, sfilt->flt_un.flt_un_item.fi_un. fi_un_substrings.fi_sub_type-> oa_syntax))) == NULLAV) { cleartext(); tprint ("Error: Cannot search, invalid value '%s' for attribute type '%s'.\n", sub_val_initial, attr_name); filter_free(sfilt); return NULLFILTER; } if (sub_val_any[0] != '*') if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any = avs_comp_new(str2AttrV(sub_val_any, sfilt->flt_un.flt_un_item.fi_un. fi_un_substrings.fi_sub_type-> oa_syntax))) == NULLAV) { cleartext(); tprint ("Error: Cannot search, invalid value '%s' for attribute type '%s'.\n", sub_val_any, attr_name); filter_free(sfilt); return NULLFILTER; } if (sub_val_final[0] != '*') if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_final = avs_comp_new(str2AttrV(sub_val_final, sfilt->flt_un.flt_un_item.fi_un. fi_un_substrings.fi_sub_type-> oa_syntax))) == NULLAV) { cleartext(); tprint ("Error: Cannot search, invalid value '%s' for attribute type '%s'.\n", sub_val_final, attr_name); filter_free(sfilt); return NULLFILTER; } return sfilt; default: return NULLFILTER; } } Filter make_filter(filt) filt_struct *filt; { int type; char svalue[1024]; Filter rfilt, sfilt = filter_alloc(); if (!filt) return NULLFILTER; if (index(mvalue, '=')) return make_attr_filter(); switch(filt->flt_type) { case ITEM: sfilt->flt_type = FILTER_ITEM; sfilt->flt_next = make_filter(filt->next); (void) strcpy(svalue, (filt->fu_cont.item.name? filt->fu_cont.item.name: mvalue)); type = filt->fu_cont.item.fi_type; switch(type) { case APPROX: case EQUAL: sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = AttrT_new(filt->fu_cont.item.stroid); if (!sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type || sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> oa_syntax == 0) { rfilt = sfilt->flt_next; sfilt->flt_next = NULLFILTER; filter_free(sfilt); return rfilt; } if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = str2AttrV(svalue, sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> oa_syntax)) == NULL) { rfilt = sfilt->flt_next; sfilt->flt_next = NULLFILTER; filter_free(sfilt); return rfilt; } if (type == EQUAL) sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY; else sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_APPROX; break; case SUBSTRING: sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_SUBSTRINGS; sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_type = AttrT_new(filt->fu_cont.item.stroid); if (!sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type || sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> oa_syntax == 0) { rfilt = sfilt->flt_next; sfilt->flt_next = NULLFILTER; filter_free(sfilt); return rfilt; } sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_initial = NULLAV; sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_final = NULLAV; sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any = avs_comp_new(str2AttrV(svalue, sfilt->flt_un.flt_un_item.fi_un. fi_un_substrings.fi_sub_type-> oa_syntax)); if (sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any == NULL) { rfilt = sfilt->flt_next; sfilt->flt_next = NULLFILTER; filter_free(sfilt); return rfilt; } break; default: sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_APPROX; break; } return sfilt; case AND: sfilt->flt_type = FILTER_AND; sfilt->flt_un.flt_un_filter = make_filter(filt->fu_cont.sub_filt); sfilt->flt_next = make_filter(filt->next); return sfilt; case OR: sfilt->flt_type = FILTER_OR; sfilt->flt_un.flt_un_filter = make_filter(filt->fu_cont.sub_filt); sfilt->flt_next = make_filter(filt->next); return sfilt; case NOT: sfilt->flt_type = FILTER_NOT; sfilt->flt_next = make_filter(filt->next); sfilt->flt_un.flt_un_filter = make_filter(filt->fu_cont.sub_filt); return sfilt; default: return NULLFILTER; } } void free_filt(filt) filt_struct *filt; { if (filt) { free_filt(filt->next); if (filt->flt_type = ITEM) { free(filt->fu_cont.item.stroid); if (filt->fu_cont.item.name) free(filt->fu_cont.item.name); } else free_filt(filt->fu_cont.sub_filt); free((char *) filt); } else return; }