Annotation of 43BSDReno/contrib/isode-beta/dsap/common/guide.c, revision 1.1.1.1

1.1       root        1: /* guide.c - Search Guide handling */
                      2: 
                      3: #ifndef lint
                      4: static char *rcsid = "$Header: /f/osi/dsap/common/RCS/guide.c,v 7.0 89/11/23 21:42:17 mrose Rel $";
                      5: #endif
                      6: 
                      7: /*
                      8:  * $Header: /f/osi/dsap/common/RCS/guide.c,v 7.0 89/11/23 21:42:17 mrose Rel $
                      9:  *
                     10:  *
                     11:  * $Log:       guide.c,v $
                     12:  * Revision 7.0  89/11/23  21:42:17  mrose
                     13:  * Release 6.0
                     14:  * 
                     15:  */
                     16: 
                     17: /*
                     18:  *                                NOTICE
                     19:  *
                     20:  *    Acquisition, use, and distribution of this module and related
                     21:  *    materials are subject to the restrictions of a license agreement.
                     22:  *    Consult the Preface in the User's Manual for the full terms of
                     23:  *    this agreement.
                     24:  *
                     25:  */
                     26: 
                     27: /*
                     28:        SYNTAX: 
                     29:                Guide ::= [<objectclass> '#'] <Criteria>
                     30:                Criteria ::= CriteriaItem | CriteriaSet | '!' Criteria
                     31:                CrtieriaSet ::= ['('] Criteria '@' CriteriaSet [')'] |
                     32:                                ['('] Criteria '|' CriteriaSet [')']
                     33:                CriteriaItem ::= ['('] <attributetype> '$' <matchType> [')']
                     34:                matchType ::= "EQ" | "SUBSTR" | "GE" | "LE" | "APPROX"
                     35:        
                     36:        EXAMPLES:
                     37: 
                     38:                Person # commonName $ APPROX
                     39:                ( organization $ EQ ) @ (commonName $ SUBSTR)
                     40:                ( organization $ EQ ) @ ((commonName $ SUBSTR) | (commonName $ EQ))
                     41: 
                     42:        NOTE:
                     43:                Use of @ for "and" as '&' get filtered out earlier!!!
                     44: */
                     45: 
                     46: /* LINTLIBRARY */
                     47: 
                     48: #include "quipu/util.h"
                     49: #include "quipu/attrvalue.h"
                     50: #include "cmd_srch.h"
                     51: 
                     52: static Criteria_free (arg)
                     53: struct Criteria *arg;
                     54: {
                     55:        struct Criteria *parm = arg;
                     56: 
                     57:        if (parm == NULL)
                     58:                return;
                     59: 
                     60:        switch (parm -> offset) {
                     61:        case Criteria_type:
                     62:                if (parm -> un.type)
                     63:                        free_CriteriaItem (parm -> un.type),
                     64:                            parm -> un.type = NULL;
                     65:                break;
                     66: 
                     67:        case Criteria_and:
                     68:        case Criteria_or:
                     69:                {
                     70:                        struct and_or_set *and_or_set;
                     71: 
                     72:                        for (and_or_set = parm -> un.and_or; and_or_set;) {
                     73:                                struct and_or_set *f_and_or_set = and_or_set -> and_or_next;
                     74: 
                     75:                                if (and_or_set -> and_or_comp)
                     76:                                        Criteria_free (and_or_set -> and_or_comp),
                     77:                                            and_or_set -> and_or_comp = NULL;
                     78: 
                     79:                                if (and_or_set)
                     80:                                        free ((char *) and_or_set);
                     81:                                and_or_set = f_and_or_set;
                     82:                        }
                     83: 
                     84:                        parm -> un.and_or = NULL;
                     85:                }
                     86:                break;
                     87: 
                     88:        case Criteria_not:
                     89:                if (parm -> un.not)
                     90:                        Criteria_free (parm -> un.not),
                     91:                            parm -> un.not = NULL;
                     92:                break;
                     93:        }
                     94: 
                     95:        free ((char *) arg);
                     96: }
                     97: 
                     98: static free_CriteriaItem (arg)
                     99: struct CriteriaItem *arg;
                    100: {
                    101:        struct CriteriaItem *parm = arg;
                    102: 
                    103:        if (parm == NULL)
                    104:                return;
                    105: 
                    106:        free ((char *) arg);
                    107: }
                    108: 
                    109: 
                    110: static guidefree (arg)
                    111: struct Guide * arg;
                    112: {
                    113:        if (arg == NULL)
                    114:                return;
                    115: 
                    116:        if (arg->objectClass)
                    117:                oid_free (arg->objectClass);
                    118: 
                    119:        Criteria_free (arg->criteria);
                    120: 
                    121:        free ((char *)arg);
                    122: }
                    123: 
                    124: static struct CriteriaItem * CriteriaItem_cpy (arg)
                    125: struct CriteriaItem *arg;
                    126: {
                    127:        struct CriteriaItem *parm = arg;
                    128:        struct CriteriaItem *res;
                    129: 
                    130:        if (parm == NULL)
                    131:                return NULL;
                    132: 
                    133:        res = (struct CriteriaItem *) smalloc (sizeof(struct CriteriaItem));
                    134: 
                    135:        res->offset = parm->offset;
                    136:        res->attrib = AttrT_cpy (parm->attrib);
                    137: 
                    138:        return (res);
                    139: }
                    140: 
                    141: 
                    142: static struct Criteria * Criteria_cpy (a)
                    143: struct Criteria * a;
                    144: {
                    145: struct Criteria *b;
                    146: 
                    147:        if (a == NULL)
                    148:                return NULL;
                    149: 
                    150:        b = (struct Criteria *) smalloc (sizeof(struct Criteria));
                    151:        b-> offset = a->offset;
                    152: 
                    153:        switch (a -> offset) {
                    154:        case Criteria_type:
                    155:                b->un.type = CriteriaItem_cpy (a->un.type);
                    156:                break;
                    157: 
                    158:        case Criteria_and:
                    159:        case Criteria_or:
                    160:                {
                    161:                        struct and_or_set *and_or_set;
                    162:                        struct and_or_set *ao_res = (struct and_or_set *)NULL;
                    163:                        struct and_or_set *ao_tmp;
                    164: 
                    165:                        ao_tmp = ao_res; /* OK lint ? */
                    166: 
                    167:                        for (and_or_set = a -> un.and_or; and_or_set; and_or_set = and_or_set->and_or_next) {
                    168:                                struct and_or_set *tmp;
                    169: 
                    170:                                tmp = (struct and_or_set *) smalloc (sizeof(struct and_or_set));
                    171:                                tmp->and_or_comp = Criteria_cpy(and_or_set->and_or_comp);
                    172:                                tmp->and_or_next = (struct and_or_set *)NULL;
                    173:                                if (ao_res == ((struct and_or_set *)NULL))
                    174:                                        ao_res = tmp;
                    175:                                else 
                    176:                                        ao_tmp->and_or_next = tmp;
                    177:                                ao_tmp = tmp;
                    178:                        }
                    179: 
                    180:                        b->un.and_or = ao_res;
                    181:                }
                    182:                break;
                    183: 
                    184:        case Criteria_not:
                    185:                b->un.not = Criteria_cpy (a->un.not);
                    186:                break;
                    187:        }
                    188: 
                    189:        return (b);             
                    190: }
                    191: 
                    192: static struct Guide * guidecpy (a)
                    193: struct Guide * a;
                    194: {
                    195: struct Guide * b;
                    196: 
                    197:        b = (struct Guide * ) smalloc (sizeof(struct Guide));   
                    198: 
                    199:        if (a->objectClass) 
                    200:                b->objectClass = oid_cpy (a->objectClass);
                    201:        else
                    202:                b->objectClass = NULLOID;
                    203: 
                    204:        b->criteria = Criteria_cpy (a->criteria);
                    205: 
                    206:        return (b);
                    207: }
                    208: 
                    209: #define NOCHOICE 255
                    210: 
                    211: static CMD_TABLE guide_tab [] = {
                    212:        "EQ",           choice_equality,
                    213:        "SUBSTR",       choice_substrings,
                    214:        "GE",           choice_greaterOrEqual,
                    215:        "LE",           choice_lessOrEqual,
                    216:        "APPROX",       choice_approximateMatch,
                    217:        0,              NOCHOICE
                    218: };
                    219:        
                    220: static struct CriteriaItem *  CriteriaItem_parse (str)
                    221: char * str;
                    222: {
                    223: struct CriteriaItem * res;
                    224: char * ptr;
                    225:        if ((str == NULLCP) || (*str == 0))
                    226:                return ((struct CriteriaItem *) NULL);
                    227: 
                    228:        res = (struct CriteriaItem *) smalloc (sizeof(struct CriteriaItem));
                    229: 
                    230:        if ((ptr = index (str,'$')) == NULLCP) {
                    231:                parse_error ("Seperator missing in CriteriaItem %s",str);
                    232:                return ((struct CriteriaItem *) NULL);
                    233:        }
                    234:        *ptr-- = 0;
                    235:        if (isspace (*ptr))
                    236:                *ptr = 0;
                    237:        ptr++;
                    238:        if ((res -> attrib = AttrT_new (str)) == NULLAttrT) {
                    239:                parse_error ("Unknown attribute type in CriteriaItem %s",str);
                    240:                return ((struct CriteriaItem *) NULL);
                    241:        }
                    242:        *ptr++ = '$';
                    243: 
                    244:        if ((res -> offset = cmd_srch(SkipSpace(ptr),guide_tab)) == NOCHOICE) {
                    245:                parse_error ("Unknown search type in CriteriaItem %s",ptr);
                    246:                return ((struct CriteriaItem *) NULL);
                    247:        }
                    248: 
                    249:        return (res);
                    250: 
                    251: }
                    252: 
                    253: 
                    254: 
                    255: static getop (str, ch)
                    256: char           *str,
                    257:                *ch;
                    258: {
                    259:        int             i,
                    260:                        bracket = 0;
                    261: 
                    262:        for (i = 0; i < strlen (str); i++) {
                    263:                if (bracket == 0 && (str[i] == '@' || str[i] == '|')) {
                    264:                        *ch = str[i];
                    265:                        return (i);
                    266:                }
                    267:                if (str[i] == '(')
                    268:                        ++bracket;
                    269:                if (str[i] == ')')
                    270:                        --bracket;
                    271:                if (bracket < 0) {
                    272:                        parse_error ("Too many close brackets",NULLCP);
                    273:                        return (-2);
                    274:                }
                    275:        }
                    276:        return (-1);
                    277: }
                    278: 
                    279: 
                    280: static struct Criteria * Criteria_parse (str)
                    281: char           *str;
                    282: {
                    283:        int             gotit,
                    284:                        bracketed;
                    285:        char            ch,
                    286:                        och = '\0';
                    287:        char *          TidyString();
                    288:        struct Criteria *  result;
                    289: 
                    290:        struct and_or_set  * ao = (struct and_or_set *)NULL;
                    291:        struct and_or_set  * ao_ptr;
                    292: 
                    293:        result = (struct Criteria *) smalloc (sizeof(struct Criteria));
                    294: 
                    295:        str = TidyString (str);
                    296: 
                    297:        /* Got a multiple-component string for parsing */
                    298: 
                    299:        do {
                    300:                bracketed = FALSE;
                    301:                if ((gotit = getop (str, &ch)) == -2)
                    302:                        return ((struct Criteria *)NULL);
                    303: 
                    304:                if (gotit < 0) {/* Match an open bracket. */
                    305:                        if (*str == '(')
                    306:                                if (str[strlen (str) - 1] == ')') {
                    307:                                        str[strlen (str) - 1] = '\0';
                    308:                                        ++str;
                    309:                                        bracketed = TRUE;
                    310:                                } else {
                    311:                                        parse_error ("Too many open brackets",NULLCP);
                    312:                                        return ((struct Criteria *)NULL);
                    313:                                }
                    314: 
                    315:                        if (och == '\0') {
                    316:                                if (bracketed == TRUE) {
                    317:                                        gotit = 0;      /* Stop 'while' loop
                    318:                                                         * falling */
                    319:                                        continue;       /* Parse the internals */
                    320:                                } else
                    321:                                        break;  /* Single item only */
                    322:                        } else
                    323:                                ch = och;       /* Use last operation */
                    324:                }
                    325:                if (och == '\0')/* Remember last operation */
                    326:                        och = ch;
                    327:                else if (och != ch) {
                    328:                        parse_error ("Can't Mix Operations.",NULLCP);
                    329:                        return ((struct Criteria *)NULL);
                    330:                }
                    331:                if (gotit >= 0) /* If got an op, make it null */
                    332:                        str[gotit] = '\0';
                    333:                /* Recurse on the 'first' string */
                    334:                ao_ptr = (struct and_or_set*) smalloc (sizeof(struct and_or_set));
                    335:                if ((ao_ptr->and_or_comp = Criteria_parse (str)) == (struct Criteria *)NULL)
                    336:                        return ((struct Criteria *)NULL);
                    337: 
                    338:                ao_ptr->and_or_next = (struct and_or_set*) NULL;
                    339:                if (ao != (struct and_or_set *)NULL)
                    340:                        ao_ptr->and_or_next = ao;
                    341:                ao = ao_ptr;
                    342:                str += gotit + 1;
                    343: 
                    344:                if (gotit >= 0) {       /* Match an and symbol */
                    345:                        if (och == '@') {
                    346:                                result->offset = Criteria_and;
                    347:                        } else {/* Match an or symbol */
                    348:                                result->offset = Criteria_or;
                    349:                        }
                    350:                }
                    351:                result->un.and_or = ao;
                    352:        }
                    353:        while (gotit >= 0);
                    354:        if (och == '\0') {
                    355:                if (*str == '!') {      /* Match a not symbol */
                    356:                        result->offset = Criteria_not;
                    357:                        if ((result->un.not = Criteria_parse (str + 1)) == (struct Criteria *)NULL)
                    358:                                return ((struct Criteria *)NULL);
                    359:                } else {
                    360:                        result->offset = Criteria_type;
                    361:                        if ((result->un.type = CriteriaItem_parse(str)) == (struct CriteriaItem *)NULL)
                    362:                                return ((struct Criteria *)NULL);
                    363:                }
                    364:        }
                    365:        return (result);
                    366: }
                    367: 
                    368: static struct Guide * guideparse (str)
                    369: char *str;
                    370: {
                    371: char *ptr;
                    372: struct Guide * res;
                    373:        
                    374:        res = (struct Guide *) smalloc (sizeof (struct Guide));
                    375: 
                    376:        if ((ptr = index (str,'#')) != NULLCP) {
                    377:                *ptr-- = 0;
                    378:                if (isspace (*ptr))
                    379:                        *ptr = 0;
                    380:                ptr++;
                    381:                if (( res->objectClass = name2oid(str)) == NULLOID) {
                    382:                        parse_error ("Unknown class in Guide %s",str);
                    383:                        return ((struct Guide *)NULL);
                    384:                }
                    385:                res->objectClass = oid_cpy (res->objectClass);
                    386:                *ptr++ = '#';
                    387:                str = ptr;
                    388:        }
                    389: 
                    390:        if ((res->criteria = Criteria_parse (SkipSpace(str))) == (struct Criteria *)NULL)
                    391:                return ((struct Guide *)NULL);
                    392: 
                    393:        return (res);
                    394: }
                    395: 
                    396: 
                    397: static CriteriaItem_print(ps,parm,format)
                    398: PS ps;
                    399: struct CriteriaItem * parm;
                    400: int format;
                    401: {
                    402: char *ptr;
                    403: 
                    404:        if (parm == NULL)
                    405:                return;
                    406: 
                    407:        if ((ptr = rcmd_srch ((int)parm->offset,guide_tab)) == NULLCP)
                    408:                ptr = "UNKNOWN !!!";
                    409: 
                    410:        if (format == READOUT) {
                    411:                ps_printf (ps,"%s on ",ptr);
                    412:                AttrT_print (ps,parm->attrib,EDBOUT);
                    413:        } else {
                    414:                AttrT_print (ps,parm->attrib,format);
                    415:                ps_printf (ps,"$%s",ptr);
                    416:        }
                    417: 
                    418:        
                    419: }
                    420: 
                    421: 
                    422: static Criteria_print (ps,a,format)
                    423: PS ps;
                    424: struct Criteria * a;
                    425: int format;
                    426: {
                    427: char * sep;
                    428: 
                    429:        if (format == READOUT)  
                    430:                sep = " OR ";
                    431:        else
                    432:                sep = "|";
                    433: 
                    434:        if (a == NULL)
                    435:                return;
                    436: 
                    437:        switch (a -> offset) {
                    438:        case Criteria_type:
                    439:                CriteriaItem_print (ps,a->un.type,format);
                    440:                break;
                    441:        case Criteria_and:
                    442:                if (format == READOUT)
                    443:                        sep = " AND ";
                    444:                else
                    445:                        sep = "@";
                    446:        case Criteria_or:
                    447:                {
                    448:                        struct and_or_set *and_or_set;
                    449:                        char * tmp = NULLCP;
                    450: 
                    451:                        for (and_or_set = a -> un.and_or; and_or_set; and_or_set = and_or_set->and_or_next) {
                    452:                                if (tmp != NULLCP)
                    453:                                        ps_print (ps,tmp);
                    454:                                ps_print (ps,"(");
                    455:                                Criteria_print(ps,and_or_set->and_or_comp,format);
                    456:                                ps_print (ps,")");
                    457:                                tmp = sep;
                    458:                        }
                    459:                }
                    460:                break;
                    461: 
                    462:        case Criteria_not:
                    463:                if (format == READOUT)
                    464:                        ps_print (ps,"NOT ");
                    465:                else
                    466:                        ps_print (ps,"!");
                    467:                ps_print (ps,"(");
                    468:                Criteria_print (ps,a->un.not,format);
                    469:                ps_print (ps,")");
                    470:                break;
                    471:        }
                    472: }
                    473: 
                    474: static guideprint (ps,a,format)
                    475: PS ps;
                    476: struct Guide * a;
                    477: int format;
                    478: {
                    479:        if (a->objectClass) {
                    480:                if (format == READOUT) {
                    481:                        ps_print (ps,"Class: ");
                    482:                        oidprint (ps,a->objectClass,format);
                    483:                        ps_print (ps,", search for: ");
                    484:                } else {
                    485:                        oidprint (ps,a->objectClass,format);
                    486:                        ps_print (ps,"#");
                    487:                }
                    488:        } 
                    489: 
                    490:        Criteria_print (ps,a->criteria,format);
                    491:                
                    492: }
                    493: 
                    494: static PE guideenc (m)
                    495: struct Guide * m;
                    496: {
                    497:        PE ret_pe;
                    498: 
                    499:        (void) encode_SA_Guide (&ret_pe,0,0,NULLCP,m);
                    500: 
                    501:        return (ret_pe);
                    502: }
                    503: 
                    504: static struct Guide * guidedec (pe)
                    505: PE pe;
                    506: {
                    507:        struct Guide * m;
                    508: 
                    509:        if (decode_SA_Guide (pe,1,NULLIP,NULLVP,&m) == NOTOK)
                    510:                return ((struct Guide *) NULL);
                    511: 
                    512:        if (decode_Criteria (m->criteria) == NOTOK)
                    513:                return ((struct Guide *) NULL);
                    514: 
                    515:        return (m);
                    516: }
                    517: 
                    518: static decode_Criteria (m)
                    519: struct Criteria * m;
                    520: {
                    521: int result;
                    522: 
                    523:        switch (m -> offset) {
                    524:        case Criteria_type:
                    525:                result = decode_CriteriaItem (m -> un.type);
                    526:                break;
                    527: 
                    528:        case Criteria_and:
                    529:        case Criteria_or:
                    530:                {
                    531:                        struct and_or_set *and_or_set;
                    532: 
                    533:                        result = OK;
                    534:                        for (and_or_set = m -> un.and_or; and_or_set;) {
                    535:                                struct and_or_set *f_and_or_set = and_or_set -> and_or_next;
                    536:                                if (decode_Criteria (and_or_set -> and_or_comp) == NOTOK)
                    537:                                        result = NOTOK;
                    538:                                and_or_set = f_and_or_set;
                    539:                        }
                    540: 
                    541:                }
                    542:                break;
                    543: 
                    544:        case Criteria_not:
                    545:                result = decode_Criteria (m -> un.not);
                    546:                break;
                    547:        }
                    548: 
                    549:        return (result);
                    550: }
                    551: 
                    552: static decode_CriteriaItem (m)
                    553: struct CriteriaItem *m;
                    554: {
                    555: 
                    556:        if (m == NULL)
                    557:                return OK;
                    558: 
                    559:        return OK;
                    560: }
                    561: 
                    562: static criteriaItem_cmp (a,b)
                    563: struct CriteriaItem *a,*b;
                    564: {
                    565: 
                    566:        if (a == NULL)
                    567:                return (b==NULL ? 0 : -1);
                    568:        if (b == NULL)
                    569:                return (1);
                    570: 
                    571:        if (a->offset != b->offset)
                    572:                return (a->offset>b->offset ? 1 : -1);
                    573: 
                    574:        return (AttrT_cmp (a->attrib,b->attrib));
                    575: }
                    576: 
                    577: static criteria_cmp(a,b)
                    578: struct Criteria * a, *b;
                    579: {
                    580: int result;
                    581: 
                    582:        if (a==NULL)
                    583:                return(b==NULL ? 0 : -1);
                    584:        if (b==NULL)
                    585:                return(1);
                    586: 
                    587:        if (a->offset != b->offset)
                    588:                return (a->offset > b->offset ? 1 : -1);
                    589: 
                    590:        switch (a -> offset) {
                    591:        case Criteria_type:
                    592:                return (criteriaItem_cmp (a->un.type, b->un.type));
                    593: 
                    594:        case Criteria_and:
                    595:        case Criteria_or:
                    596:                {
                    597:                        struct and_or_set *a_set;
                    598:                        struct and_or_set *b_set;
                    599: 
                    600:                        for (a_set = a->un.and_or; a_set ; a_set = a_set->and_or_next) {
                    601:                           for (b_set = b->un.and_or; b_set ; b_set = b_set->and_or_next) {
                    602:                                if ((result=criteria_cmp (a_set -> and_or_comp,b_set->and_or_comp)) == 0) 
                    603:                                        break;
                    604:                           }
                    605:                           if (result != 0)
                    606:                                return (1);
                    607:                        }
                    608:                        for (b_set = b->un.and_or; b_set ; b_set = b_set->and_or_next) {
                    609:                           for (a_set = a->un.and_or; a_set ; a_set = a_set->and_or_next) {
                    610:                                if ((result=criteria_cmp (a_set -> and_or_comp,b_set->and_or_comp)) == 0) 
                    611:                                        break;
                    612:                           }
                    613:                           if (result != 0)
                    614:                                return (-1);
                    615:                        }
                    616:                        return (0);
                    617: 
                    618:                }
                    619: 
                    620:        case Criteria_not:
                    621:                result = criteria_cmp (a->un.not,b->un.not);
                    622:                break;
                    623:        }
                    624: 
                    625:        return (result);
                    626: }
                    627: 
                    628: static guidecmp (a,b)
                    629: struct Guide *a, *b;
                    630: {
                    631: int i;
                    632:        if (a == (struct Guide *)NULL)
                    633:                if (b == (struct Guide *)NULL)
                    634:                        return (0);
                    635:                else 
                    636:                        return (1);
                    637: 
                    638:        if (b==(struct Guide *)NULL)
                    639:                return (-1);
                    640: 
                    641:        if ((i=oid_cmp(a->objectClass,b->objectClass)) == 0)
                    642:                return (criteria_cmp(a->criteria,b->criteria));
                    643: 
                    644:        return (i);
                    645: }
                    646: 
                    647: guide_syntax ()
                    648: {
                    649:        (void) add_attribute_syntax ("Guide",
                    650:            (IFP) guideenc,     (IFP) guidedec,
                    651:            (IFP) guideparse,guideprint,
                    652:            (IFP) guidecpy,     guidecmp,
                    653:            guidefree,  NULLCP,
                    654:            NULLIFP,    TRUE);
                    655: 
                    656: }
                    657: 

unix.superglobalmegacorp.com

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