Index: /branches/rel10_ifa/psModules/src/config/pmConfig.c
===================================================================
--- /branches/rel10_ifa/psModules/src/config/pmConfig.c	(revision 6753)
+++ /branches/rel10_ifa/psModules/src/config/pmConfig.c	(revision 6754)
@@ -3,6 +3,6 @@
  *  @author PAP, IfA
  *
- *  @version $Revision: 1.7.4.7 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-03-30 20:08:30 $
+ *  @version $Revision: 1.7.4.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-04-01 03:00:23 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -13,9 +13,13 @@
 #include <unistd.h>
 #include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include "pslib.h"
 #include "pmConfig.h"
 
-#define PS_SITE "PS_SITE"               // Name of the environment variable containing the site config file
-#define PS_DEFAULT_SITE "ipprc.config"  // Default site config file
+#define PS_SITE "PS_SITE"         // Name of the environment variable containing the site config file
+#define PS_DEFAULT_SITE ".ipprc"  // Default site config file
+
+static psArray *configPath = NULL;
 
 static void configFree(pmConfig *config)
@@ -57,19 +61,69 @@
     const char *description)            // Description of file
 {
+    char *realName = NULL;
     unsigned int numBadLines = 0;
+    struct stat filestat;
 
     psLogMsg(__func__, PS_LOG_INFO, "Loading %s configuration from file %s\n",
              description, name);
-    *config = psMetadataConfigParse(NULL, &numBadLines, name, true);
+
+    uid_t uid = getuid();
+    gid_t gid = getgid();
+
+    // we try: name, path[0]/name, path[1]/name, ...
+    // find the first existing entry in the path (starting with the bare name)
+    realName = psStringCopy (name);
+    psTrace (__func__, 5, "trying %s\n", realName);
+
+    int status = stat (realName, &filestat);
+    if (status == 0) {
+        if ((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR))
+            goto found;
+        if ((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP))
+            goto found;
+        if (filestat.st_mode & S_IROTH)
+            goto found;
+    }
+    psFree (realName);
+
+    if (configPath == NULL) {
+        psError(PS_ERR_IO, false, "Cannot find %s configuration file in path\n", description);
+        return false;
+    }
+
+    for (int i = 0; i < configPath->n; i++) {
+        realName = psStringCopy (configPath->data[i]);
+        psStringAppend (&realName, "/%s", name);
+        psTrace (__func__, 5, "trying %s\n", realName);
+
+        status = stat (realName, &filestat);
+        if (status == 0) {
+            if ((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR))
+                goto found;
+            if ((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP))
+                goto found;
+            if (filestat.st_mode & S_IROTH)
+                goto found;
+        }
+        psFree (realName);
+    }
+
+    psError(PS_ERR_IO, false, "Cannot find %s configuration file in path\n", description);
+    return false;
+
+found:
+    *config = psMetadataConfigParse(NULL, &numBadLines, realName, true);
     if (numBadLines > 0) {
         psLogMsg(__func__, PS_LOG_WARN, "%d bad lines in %s configuration file (%s)\n",
-                 description, name);
+                 description, realName);
     }
     if (!*config) {
         psError(PS_ERR_IO, false, "Unable to read %s configuration from %s\n",
-                description, name);
+                description, realName);
+        psFree (realName);
         return false;
     }
 
+    psFree (realName);
     return true;
 }
@@ -115,5 +169,5 @@
                      "-site command-line switch provided without the required filename --- ignored.\n");
         } else {
-            siteName = argv[argNum];
+            siteName = psStringCopy(argv[argNum]);
             psArgumentRemove(argNum, argc, argv);
         }
@@ -124,4 +178,7 @@
     if (!siteName) {
         siteName = getenv(PS_SITE);
+        if (siteName) {
+            siteName = psStringCopy (siteName);
+        }
     }
 
@@ -129,12 +186,12 @@
     // Last chance is ~/.ipprc
     //
-    bool cleanupSiteName = false; // Do I have to psFree siteName?
     if (!siteName) {
-        siteName = psStringCopy(PS_DEFAULT_SITE);
-        cleanupSiteName = true;
-    }
-
-    //
-    // We have the connfiguration filename; now we read and parse the config
+        char *home = getenv("HOME");
+        siteName = psStringCopy(home);
+        psStringAppend(&siteName, "/%s", PS_DEFAULT_SITE);
+    }
+
+
+    // We have the configuration filename; now we read and parse the config
     // file and store in psMetadata struct site.
     //
@@ -144,10 +201,18 @@
         return NULL;
     }
-    if (cleanupSiteName) {
-        psFree(siteName);
-    }
-
-
-    //
+    psFree(siteName);
+
+    // define the config-file search path (configPath)
+    if (configPath) {
+        psFree (configPath);
+        configPath = NULL;
+    }
+    char *path = psMetadataLookupStr(NULL, config->site, "PATH");
+    if (path) {
+        psList *list = psStringSplit(path, ":");
+        configPath = psListToArray(list);
+        psFree (list);
+    }
+
     // Next, we do a similar thing for the camera configuration file.  The
     // file is read and parsed into psMetadata struct "camera".
@@ -350,4 +415,6 @@
                             )
 {
+    psMetadata *testFormat;
+
     assert(format);
     assert(camera);
@@ -374,11 +441,21 @@
         }
         psTrace(__func__, 5, "Reading camera format for %s...\n", formatsItem->name);
-        unsigned int badLines = 0;  // Number of bad lines in reading camera configuration
+        // unsigned int badLines = 0;  // Number of bad lines in reading camera configuration
         // Format to test against what we've got
-        psMetadata *testFormat = psMetadataConfigParse(NULL, &badLines, formatsItem->data.V, true);
+
+        if (!readConfig(&testFormat, formatsItem->data.V, formatsItem->name)) {
+            psLogMsg(__func__, PS_LOG_WARN, "trouble reading reading camera format %s\n", formatsItem->name);
+            psFree(testFormat);
+            continue;
+        }
+
+        # if (0)
+            psMetadata *testFormat = psMetadataConfigParse(NULL, &badLines, formatsItem->data.V, true);
         if (badLines > 0) {
             psLogMsg(__func__, PS_LOG_WARN, "%d bad lines encountered while reading camera"
                      "format %s\n", badLines, formatsItem->name);
         }
+        # endif
+
         if (pmConfigValidateCameraFormat(testFormat, header)) {
             if (!*format) {
@@ -408,4 +485,5 @@
     psMetadata *format = NULL;          // The winning format
     bool mdok = false;                  // Metadata lookup status
+    psMetadata *testCamera = NULL;
 
     // If we don't know what sort of camera we have, we try all that we know
@@ -430,11 +508,21 @@
 
             psTrace(__func__, 5, "Reading camera configuration for %s...\n", camerasItem->name);
-            unsigned int badLines = 0;  // Number of bad lines in reading camera configuration
+            // unsigned int badLines = 0;  // Number of bad lines in reading camera configuration
             // Camera to test against what we've got:
-            psMetadata *testCamera = psMetadataConfigParse(NULL, &badLines, camerasItem->data.V, true);
+
+            if (!readConfig(&testCamera, camerasItem->data.V, camerasItem->name)) {
+                psLogMsg(__func__, PS_LOG_WARN, "trouble reading reading camera configuration %s\n", camerasItem->name);
+                psFree(testCamera);
+                continue;
+            }
+
+            # if (0)
+                psMetadata *testCamera = psMetadataConfigParse(NULL, &badLines, camerasItem->data.V, true);
             if (badLines > 0) {
                 psLogMsg(__func__, PS_LOG_WARN, "%d bad lines encountered while reading camera"
                          "configuration %s\n", badLines, camerasItem->name);
             }
+            # endif
+
             if (! testCamera) {
                 psLogMsg(__func__, PS_LOG_WARN, "Unable to interpret camera configuration for %s (%s) --- "
