Index: libabac/abac_pl_yap.c
===================================================================
--- libabac/abac_pl_yap.c	(revision e95d652a2cd6131b110bcb0e946047818f4fe954)
+++ libabac/abac_pl_yap.c	(revision e95d652a2cd6131b110bcb0e946047818f4fe954)
@@ -0,0 +1,288 @@
+
+/* copied from abac_graph.c 
+   implementation of the low level using
+   yap prolog
+*/
+
+#include <err.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <Yap/YapInterface.h>
+
+#include "abac_pl.h"
+#include "abac_pl_yap.h"
+
+#include "abac_list.h"
+#include "abac_util.h"
+
+#include "uthash.h"
+
+static int _insert_clause(char*);
+static void _show_yap_db(char*);
+
+extern char *abac_cn_with_role(abac_role_t *);
+
+// pl
+struct _abac_pl_t {
+    FILE *fptr;
+    char *fname;
+    char *yap_certs;
+};
+
+/**
+ * Create a new yap structure.
+ */
+abac_pl_t *abac_pl_new(void) {
+
+    if (YAP_FastInit(NULL) == YAP_BOOT_ERROR)
+        YAP_Exit(1);
+
+    if (YAP_RunGoal(YAP_MkAtomTerm(YAP_LookupAtom("source")))) {
+        printf("calling source..\n");
+        } else {
+        printf("calling source failed..\n");
+        YAP_Exit(1);
+    }
+    abac_pl_t *pl = abac_xmalloc(sizeof(abac_pl_t));
+    pl->fptr=NULL;
+    pl->fname=NULL;
+    pl->yap_certs=NULL;
+    return pl;
+}
+
+/**
+ * Add a credential to the credential pl.
+ */
+int abac_pl_add_credential(abac_pl_t *pl, abac_credential_t *cred)
+{
+    int rc=0;
+    char *str = abac_credential_clause(cred);
+    if (str != NULL) {
+        rc=_insert_clause(str);
+    }
+    _show_yap_db("calling within abac_pl_add_credential");
+    return rc;
+}
+
+static int _insert_clause(char *cstr)
+{
+    int ret=ABAC_CERT_SUCCESS;
+    YAP_Term *eterm;
+    YAP_Term goalArgs=YAP_ReadBuffer(cstr, eterm);
+    char *tmp=YAP_CompileClause(goalArgs);
+    if (tmp!=NULL) { /* something is wrong */
+        printf("error: result of compile clause (%s)\n", tmp);
+        ret=ABAC_CERT_BAD_YAP;
+    }
+    return ret;
+}
+
+static void _show_yap_db(char *msg)
+{
+    char lstr[]="listing";
+    YAP_Term *eterm;
+
+    YAP_Term goal=YAP_ReadBuffer(lstr, eterm);
+    printf("calling listing..from(%s) \n",msg);
+    int rc =YAP_RunGoal( goal );
+    if (rc) {
+        printf("listing ok.. \n");
+    } else {
+        printf("listing's rc is bad.. \n");
+        YAP_Exit(1);
+    }
+}
+
+static void _set_dbg(abac_pl_t *pl)
+{
+    char *fname=strdup( "/tmp/abac_yap-XXXXXX.pl" );
+    int fd = mkstemps( pl->fname, 3 );
+    if ( fd == -1) {
+        printf("Couldn't get a valid temp name %s\n", fname);
+        free((void*)fname);
+        YAP_Exit(1);
+    }
+    FILE *fptr = fdopen(fd, "w");
+    if (fptr == NULL) {
+        printf("Couldn't open %s for writing\n", fname);
+        free((void*)fname);
+        YAP_Exit(1);
+    }
+    pl->fptr=fptr;
+    pl->fname=fname;
+}
+
+static abac_list_t *_linked_query(abac_pl_t *pl, abac_role_t* role, abac_role_t* role_prin )
+{
+    abac_list_t *cred_list = abac_list_new();
+    return cred_list;
+}
+
+static abac_list_t *_intersect_query(abac_pl_t *pl, abac_role_t* role, abac_role_t* role_prin )
+{
+    abac_list_t *cred_list = abac_list_new();
+    return cred_list;
+}
+
+
+/* cases,
+     ['str']
+     ['str1','str2']
+     ([] is not possible, and don't care)
+*/
+static void _credentials_from_string(abac_list_t *credentials,char *slist) {
+    char *cptr=slist; /* current ptr */
+    char *sptr; /* string ptr */
+    char *ptr;
+    int len=strlen(ptr);
+    char *string;
+    abac_credential_t *cred=NULL;
+
+    /* find first [' */  
+    ptr=strstr(cptr,"['");
+    if(ptr == NULL) 
+         return;
+    cptr=ptr+2;
+    sptr=cptr;
+    while (1) {
+        /* find next ',' or '] */
+        ptr=strstr(cptr,"','");
+        if(ptr!=NULL) {
+             cptr=ptr+3;
+             len=ptr-sptr;
+             string=strndup(sptr,len);
+             printf("string found(%s)\n", string); 
+             cred=abac_credential_lookup(string);
+             if(cred) {
+                 abac_list_add(credentials, abac_credential_dup(cred));
+                 } else {
+                 printf("BAD BAD BAD\n");
+             }
+             sptr=cptr;
+             } else {
+             ptr=strstr(cptr,"']");
+             if(ptr!=NULL) {
+                 len=ptr-sptr;
+                 string=strndup(sptr,len);
+                 printf("last string found(%s)\n", string); 
+                 cred=abac_credential_lookup(string);
+                 if(cred) {
+                     abac_list_add(credentials, abac_credential_dup(cred));
+                     } else {
+                     printf("BAD BAD BAD\n");
+                 }
+                 break;
+             }
+        }
+    }
+}
+
+/* 2 types 
+      acme.buys_rocket <- coyote 
+      acme.buys_rocket <- acme.preferred_customer  -- NOT DONE YET */
+static abac_list_t *_query(abac_pl_t *pl, abac_role_t* role, abac_role_t* role_prin )
+{
+    YAP_Term *eterm;
+    YAP_Term arg[3];
+    char tmp[1000];
+    abac_list_t *cred_list = NULL;
+
+    char *cn_prin=abac_cn_with_role(role_prin);
+    char *cn_role=abac_cn_with_role(role);
+
+    if(abac_role_role_name(role_prin)!=NULL) {
+        printf("NOT YET DONE, role_prin is B.R !!!\n");
+        YAP_Exit(1);
+    }
+
+    if (cn_prin == NULL || cn_role == NULL) {
+        printf("fail, query's call got bad roles.. \n");
+        YAP_Exit(1);
+    }
+    sprintf(tmp,"role(%s,%s)", cn_role, abac_role_role_name(role));
+    arg[0]=YAP_MkAtomTerm(YAP_LookupAtom(cn_prin));
+    arg[1]=YAP_ReadBuffer(tmp,eterm);
+    arg[2]=YAP_MkVarTerm();
+    YAP_Atom f = YAP_LookupAtom("isMember");
+    YAP_Functor func = YAP_MkFunctor(f, 3);
+    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
+    int rc =YAP_RunGoal( goal );
+    if (rc) {
+        cred_list = abac_list_new();
+        printf("success, query call ok.. \n");
+        YAP_WriteBuffer(arg[2], tmp, 1000,YAP_WRITE_HANDLE_VARS);
+        printf("    answer : %s(%d)\n", tmp, strlen(tmp));
+        /* this is returned as ['string1','string2'] */
+        _credentials_from_string(cred_list,tmp); 
+        while (YAP_RestartGoal()) {
+            printf("another success\n");
+            YAP_WriteBuffer(arg[2], tmp, 1000,YAP_WRITE_HANDLE_VARS);
+            printf("    answer : %s\n", tmp);
+            _credentials_from_string(cred_list,tmp); 
+        }
+    } else {
+        printf("fail, query's call is bad.. \n");
+        YAP_Exit(1);
+    }
+    return cred_list;
+}
+
+/**
+ * Make a query into prolog db
+--role acme.preferred_customer --principal coyote
+--role acme.prefer_customer.buy_rockets --principlal coyote
+ */
+abac_list_t *abac_pl_query(abac_pl_t *pl, char *role_name, char *principal)
+{
+    abac_role_t *role = abac_role_from_string(role_name);
+    abac_role_t *prin_role = abac_role_from_string(principal);
+    char *query_clause = NULL;
+    abac_list_t *ret=NULL;
+
+    // give up on bogus roles
+    if (role == NULL || prin_role == NULL) {
+        free(role);
+        free(prin_role);
+        return NULL;
+    }
+
+    /* should be using yacc */
+/* if role->prereqs != NULL (&) */
+    if (abac_role_is_intersection(role)) {
+/* XXX */
+        ret=_intersect_query(pl,role,prin_role);
+    /* prin.role.role1 */
+    } else if( abac_role_linked_role(role) ) {
+/* XXX */
+        ret=_linked_query(pl,role,prin_role);
+    } else {  /* prin.role,  */
+        ret=_query(pl,role,prin_role);
+    }
+
+    return ret;
+}
+
+/**
+ * Get all the credentials (attribute/issuer cert pairs) from prolog
+ * (which returns in string form)
+ */
+abac_list_t *abac_pl_credentials(abac_pl_t *pl) {
+    abac_list_t *credentials = abac_list_new();
+    /* fix up a stream to stream the credentials from prolog engine */
+    return credentials;
+}
+
+void abac_pl_free(abac_pl_t *pl) {
+    if(pl->fptr) {
+        fflush(pl->fptr);
+        free(pl->fptr);
+    }
+    if(pl->fname) {
+        unlink(pl->fname);
+        free(pl->fname);
+    }
+    free(pl);
+}
+
