Index: libabac/abac.c
===================================================================
--- libabac/abac.c	(revision 472161887a4822e907c5e9d23bd1a4a0ec6f950b)
+++ libabac/abac.c	(revision bec30b5ab9c079bfa792531837b13442d03db10c)
@@ -3,5 +3,8 @@
 #include <assert.h>
 #include <err.h>
-#include <glob.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
 
 #include "abac.h"
@@ -11,5 +14,11 @@
 #include "abac_verifier.h"
 
+int debug=0;
+abac_id_cert_t **abac_context_principals(abac_context_t *ctx);
+void abac_context_id_credentials_free(abac_id_cert_t **id_credentials);
+
 struct _abac_context_t {
+/* list of principal id credentials, abac_id_cert_t */
+    abac_list_t *id_certs;
     abac_graph_t *graph;
 };
@@ -45,4 +54,5 @@
     abac_context_t *ctx = abac_xmalloc(sizeof(abac_context_t));
     ctx->graph = abac_graph_new();
+    ctx->id_certs=abac_list_new();
     return ctx;
 }
@@ -53,7 +63,13 @@
 abac_context_t *abac_context_dup(abac_context_t *ctx) {
     assert(ctx != NULL);
-
+   
     abac_context_t *dup = abac_xmalloc(sizeof(abac_context_t));
     dup->graph = abac_graph_dup(ctx->graph);
+    dup->id_certs=abac_list_new();
+
+    abac_id_cert_t *id_cert;
+    abac_list_foreach(ctx->id_certs, id_cert,
+        abac_list_add(dup->id_certs, abac_id_cert_dup(id_cert));
+    );
 
     return dup;
@@ -67,4 +83,10 @@
 
     abac_graph_free(ctx->graph);
+
+    abac_id_cert_t *id_cert;
+    abac_list_foreach(ctx->id_certs, id_cert,
+        abac_id_cert_free(id_cert);
+    );
+    abac_list_free(ctx->id_certs);
     free(ctx);
 }
@@ -75,5 +97,5 @@
 int abac_context_load_id_file(abac_context_t *ctx, char *filename) {
     assert(ctx != NULL); assert(filename != NULL);
-    return abac_verifier_load_id_file(filename);
+    return abac_verifier_load_id_file(ctx->id_certs,filename);
 }
 
@@ -83,5 +105,5 @@
 int abac_context_load_id_chunk(abac_context_t *ctx, abac_chunk_t cert_chunk) {
     assert(ctx != NULL);
-    return abac_verifier_load_id_chunk(cert_chunk);
+    return abac_verifier_load_id_chunk(ctx->id_certs,cert_chunk);
 }
 
@@ -96,5 +118,5 @@
     assert(ctx != NULL); assert(filename != NULL);
 
-    ret = abac_verifier_load_attribute_cert_file(filename, cred_list);
+    ret = abac_verifier_load_attribute_cert_file(ctx->id_certs, filename, cred_list);
 
     if (ret == ABAC_CERT_SUCCESS) {
@@ -122,5 +144,5 @@
     assert(ctx != NULL);
 
-    ret = abac_verifier_load_attribute_cert_chunk(cert_chunk, cred_list);
+    ret = abac_verifier_load_attribute_cert_chunk(ctx->id_certs, cert_chunk, cred_list);
     if (ret == ABAC_CERT_SUCCESS) {
         int size = abac_list_size(cred_list);
@@ -141,43 +163,38 @@
 #define ATTR_PAT "/*_attr.xml"
 
+static int is_regular_file(char *filename)
+{
+   struct stat sb;
+   if(stat(filename,&sb) == -1)
+       return 0;
+   if((sb.st_mode & S_IFMT) == S_IFREG)
+       return 1;
+   return 0;
+}
+
 /**
  * Load a directory full of certs.
  */
 void abac_context_load_directory(abac_context_t *ctx, char *path) {
-    char *glob_pat;
-    glob_t glob_buf;
-    int i, ret;
-
-    assert(ctx != NULL); assert(path != NULL);
-
-    int dirlen = strlen(path);
-    glob_pat = abac_xmalloc(dirlen + sizeof(ID_PAT));
-    memcpy(glob_pat, path, dirlen);
-
-    // first load ID certs
-    memcpy(glob_pat + dirlen, ID_PAT, sizeof(ID_PAT));
-    glob(glob_pat, GLOB_BRACE, NULL, &glob_buf); // TODO check for error
-    for (i = 0; i < glob_buf.gl_pathc; ++i) {
-        char *cert_file = glob_buf.gl_pathv[i];
-
-        ret = abac_context_load_id_file(ctx, cert_file);
-        if (ret != ABAC_CERT_SUCCESS)
-            warnx("Couldn't load ID cert %s", cert_file);
-    }
-    globfree(&glob_buf);
-
-    // then load attr certs
-    memcpy(glob_pat + dirlen, ATTR_PAT, sizeof(ATTR_PAT));
-    glob(glob_pat, 0, NULL, &glob_buf); // TODO check for error
-    for (i = 0; i < glob_buf.gl_pathc; ++i) {
-        char *cert_file = glob_buf.gl_pathv[i];
-
-        ret = abac_context_load_attribute_file(ctx, cert_file);
-        if (ret != ABAC_CERT_SUCCESS)
-            warnx("Couldn't load attribute cert %s", cert_file);
-    }
-    globfree(&glob_buf);
-
-    free(glob_pat);
+    DIR *dp;
+    struct dirent *ep;
+     
+    dp = opendir (path);
+    if (dp != NULL) {
+        while (ep = readdir (dp)) {
+            if(is_regular_file(ep->d_name)) {
+                int ret = abac_context_load_id_file(ctx, ep->d_name);
+                if (ret == ABAC_CERT_SUCCESS) {
+                    if(debug) fprintf(stderr,"abac_context_load_directory, found an id %s\n",ep->d_name);
+                    continue;
+                }
+                ret = abac_context_load_attribute_file(ctx, ep->d_name);
+                if (ret == ABAC_CERT_SUCCESS) {
+                    if(debug) fprintf(stderr,"abac_context_load_directory, found an attr %s\n",ep->d_name);
+                }
+            }
+        }
+        (void) closedir (dp);
+    } else fprintf(stderr, "abac_load_directory, Couldn't open the directory\n");
 }
 
@@ -247,4 +264,5 @@
 }
 
+
 /**
  * A NULL-terminated array of all the credentials in the context.
@@ -267,6 +285,43 @@
     abac_list_free(cred_list);
 
+    if(debug) {
+        abac_id_cert_t **ilist=abac_context_principals(ctx);
+        abac_id_cert_t *cert;
+        if (ilist != NULL)
+            for (i = 0; ilist[i] != NULL; ++i) {
+                cert = ilist[i];
+                printf("id[%d] %s\n",i, abac_id_cert_keyid(cert));
+            }
+        abac_context_id_credentials_free(ilist);
+    }
+
     return credentials;
 }
+
+/**
+ * A NULL-terminated array of all the principals in the context.
+ */
+abac_id_cert_t **abac_context_principals(abac_context_t *ctx)
+{
+    abac_id_cert_t **principals = NULL, *cur;
+    assert(ctx != NULL);
+
+    int size = abac_list_size(ctx->id_certs);
+
+    // make the array (leave space to NULL terminate it)
+    //      n.b., even if the list is empty, we still return an array that
+    //            only contains the NULL terminator
+    principals = abac_xmalloc(sizeof(abac_id_cert_t *) * (size + 1));
+    int i = 0;
+    abac_id_cert_t *id_cert;
+    abac_list_foreach(ctx->id_certs, id_cert,
+        principals[i]=abac_id_cert_dup(id_cert);
+        i++;
+    );
+    principals[i] = NULL;
+
+    return principals;
+}
+
 
 /**
@@ -283,2 +338,19 @@
     free(credentials);
 }
+
+/**
+ * Frees a NULL-terminated list of id credentials 
+ */
+void abac_context_id_credentials_free(abac_id_cert_t **id_credentials) {
+    int i;
+
+    if (id_credentials == NULL)
+        return;
+
+    for (i = 0; id_credentials[i] != NULL; ++i) {
+        abac_id_cert_free(id_credentials[i]);
+    }
+    free(id_credentials);
+}
+
+
