no-more-ini-files-20040713
[openafs.git] / src / WINNT / afsd / cm_config.c
index a3ef82f..9c3cc9c 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <afs/param.h>
 #include <afs/stds.h>
+#include <afs/cellconfig.h>
 
 #ifndef DJGPP
 #include <windows.h>
 #include <string.h>
 
 #include "cm_config.h"
+#include <WINNT\afssw.h>
+#ifdef AFS_AFSDB_ENV
+#include "cm_dns.h"
+#include <afs/afsint.h>
+#endif
 
 char AFSConfigKeyName[] =
        "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters";
 
+/* TODO: these should be pulled in from dirpath.h */
+#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
 #define AFS_THISCELL "ThisCell"
+#endif
 #define AFS_CELLSERVDB_UNIX "CellServDB"
 #define AFS_CELLSERVDB_NT "afsdcell.ini"
+#ifndef AFSDIR_CLIENT_ETC_DIRPATH
 #define AFSDIR_CLIENT_ETC_DIRPATH "c:/afs"
+#endif
 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
 #define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
 #ifdef DJGPP
@@ -37,21 +48,55 @@ extern char cm_confDir[];
 extern int errno;
 #endif /* DJGPP */
 #else
-#define AFS_CELLSERVDB AFS_CELLSERVDB_NT
+#define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
 #endif /* DJGPP || WIN95 */
 
+#ifdef DEBUG
+DWORD TraceOption=1;
+
+#define TRACE_OPTION_EVENT 1
+#define ISLOGONTRACE(v) ( ((v) & TRACE_OPTION_EVENT)==TRACE_OPTION_EVENT)
+
+void DebugEvent0_local(char *a) 
+{
+       HANDLE h; char *ptbuf[1];
+       if (!ISLOGONTRACE(TraceOption))
+               return;
+       h = RegisterEventSource(NULL, a);
+       ptbuf[0] = a;
+       ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
+       DeregisterEventSource(h);
+}
+
+#define MAXBUF_ 512
+
+void DebugEvent_local(char *a,char *b,...) 
+{
+       HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
+       va_list marker;
+       if (!ISLOGONTRACE(TraceOption))
+               return;
+       h = RegisterEventSource(NULL, a);
+       va_start(marker,b);
+       _vsnprintf(buf,MAXBUF_,b,marker);
+       ptbuf[0] = buf;
+       ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);\
+       DeregisterEventSource(h);
+       va_end(marker);
+}
+#endif /* DEBUG */
 
 static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
 {
        char *tp;
-        char tc;
-        int sawEquals;
+    char tc;
+    int sawEquals;
        int sawBracket;
         
-        sawEquals = 0;
+    sawEquals = 0;
        sawBracket = 0;
-        for(tp = lineBufferp; *tp; tp++) {
-               tc = *tp;
+    for(tp = lineBufferp; *tp; tp++) {
+        tc = *tp;
 
                if (sawBracket) {
                        if (tc == ']')
@@ -60,33 +105,38 @@ static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
                }
 
                /* comment or line end */
-                if (tc == '#' || tc == '\r' || tc == '\n') break;
+        if (tc == '#' || tc == '\r' || tc == '\n') 
+            break;
 
-               /* square bracket comment -- look for closing delim
-               if (tc == '[') {sawBracket = 1; continue;}
+               /* square bracket comment -- look for closing delim */
+               if (tc == '[') {
+            sawBracket = 1; 
+            continue;
+        }
 
                /* space or tab */
-                if (tc == ' ' || tc == '\t') continue;
+        if (tc == ' ' || tc == '\t') 
+            continue;
 
-                if (tc == '=') {
-                       sawEquals = 1;
-                        continue;
+        if (tc == '=') {
+            sawEquals = 1;
+            continue;
                }
                 
-                /* now we have a real character, put it in the appropriate bucket */
-                if (sawEquals == 0) {
+        /* now we have a real character, put it in the appropriate bucket */
+        if (sawEquals == 0) {
                        *leftp++ = tc;
-                }
-                else {
+        }
+        else {
                        *rightp++ = tc;
-                }
         }
+    }
 
        /* null terminate the strings */
        *leftp = 0;
-        *rightp = 0;
+    *rightp = 0;
 
-        return 0;      /* and return success */
+    return 0;  /* and return success */
 }
 
 /* search for a cell, and either return an error code if we don't find it,
@@ -101,69 +151,72 @@ static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
        cm_configProc_t *procp, void *rockp)
 {
-       char wdir[256];
-        int tlen;
-        FILE *tfilep, *bestp, *tempp;
-        char *tp;
-        char lineBuffer[256];
-        struct hostent *thp;
-        char *valuep;
-        struct sockaddr_in vlSockAddr;
-        int inRightCell;
-        int foundCell;
-        long code;
+       char wdir[257];
+    int tlen;
+    FILE *tfilep = NULL, *bestp, *tempp;
+    char *tp;
+    char lineBuffer[257];
+    struct hostent *thp;
+    char *valuep;
+    struct sockaddr_in vlSockAddr;
+    int inRightCell;
+    int foundCell = 0;
+    long code;
        int tracking = 1, partial = 0;
 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
-       long ip_addr;
-        int c1, c2, c3, c4;
-        char aname[256];
+    char *afsconf_path;
 #endif
-        char *afsconf_path;
-
-       foundCell = 0;
 
 #if !defined(DJGPP)
-       code = GetWindowsDirectory(wdir, sizeof(wdir));
-        if (code == 0 || code > sizeof(wdir)) return -1;
+    strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
 
-       /* add trailing backslash, if required */
-        tlen = strlen(wdir);
-        if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
+    /* add trailing backslash, if required */
+    tlen = strlen(wdir);
+    if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
 #else
-        strcpy(wdir, cm_confDir);
-        strcat(wdir,"/");
+    strcpy(wdir, cm_confDir);
+    strcat(wdir,"/");
 #endif /* !DJGPP */
         
-        strcat(wdir, AFS_CELLSERVDB);
+    strcat(wdir, AFS_CELLSERVDB);
+    tfilep = fopen(wdir, "r");
 
+#if defined(DJGPP) || defined(AFS_WIN95_ENV)
+    if (!tfilep) {
+        /* If we are using DJGPP client, cellservdb will be in afsconf dir. */
+        /* If we are in Win95 here, we are linking with klog etc. and are
+        using DJGPP client even though DJGPP is not defined.  So we still
+        need to check AFSCONF for location. */
+        afsconf_path = getenv("AFSCONF");
+        if (!afsconf_path)
+            strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
+        else
+            strcpy(wdir, afsconf_path);
+        strcat(wdir, "/");
+        strcat(wdir, AFS_CELLSERVDB);
+        /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
         tfilep = fopen(wdir, "r");
-
-        if (!tfilep) {
-          /* If we are using DJGPP client, cellservdb will be in afsconf dir. */
-          /* If we are in Win95 here, we are linking with klog etc. and are
-             using DJGPP client even though DJGPP is not defined.  So we still
-             need to check AFSCONF for location. */
-            afsconf_path = getenv("AFSCONF");
-            if (!afsconf_path)
-               strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
-            else
-               strcpy(wdir, afsconf_path);
-            strcat(wdir, "/");
-            strcat(wdir, AFS_CELLSERVDB_UNIX);
-            /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
-            tfilep = fopen(wdir, "r");
-            if (!tfilep) return -2;
-        }
+        if (!tfilep) return -2;
+    }
+#else
+    /* If we are NT or higher, we don't do DJGPP, So just fail */
+    if ( !tfilep )
+        return -2;
+#endif
 
        bestp = fopen(wdir, "r");
-        
+    
+#ifdef DEBUG
+    DebugEvent_local("AFS- cm_searchfile fopen", "Handle[%x], wdir[%s]", bestp, wdir);
+#endif
+
        /* have we seen the cell line for the guy we're looking for? */
        inRightCell = 0;
        while (1) {
-               tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
-               if (tracking)
+        tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
+        if (tracking)
                        (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
-                if (tp == NULL) {
+        if (tp == NULL) {
                        if (feof(tfilep)) {
                                /* hit EOF */
                                if (partial) {
@@ -184,36 +237,40 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
                                        return (foundCell? 0 : -3);
                                }
                        }
-                }
-                
-                /* turn trailing cr or lf into null */
-                tp = strchr(lineBuffer, '\r');
-                if (tp) *tp = 0;
-                tp = strchr(lineBuffer, '\n');
-                if (tp) *tp = 0;
-                
+        }
+
+        /* turn trailing cr or lf into null */
+        tp = strchr(lineBuffer, '\r');
+        if (tp) *tp = 0;
+        tp = strchr(lineBuffer, '\n');
+        if (tp) *tp = 0;
+
                /* skip blank lines */
-                if (lineBuffer[0] == 0) continue;
+        if (lineBuffer[0] == 0) continue;
 
-                if (lineBuffer[0] == '>') {
+        if (lineBuffer[0] == '>') {
                        /* trim off at white space or '#' chars */
-                        tp = strchr(lineBuffer, ' ');
-                        if (tp) *tp = 0;
-                        tp = strchr(lineBuffer, '\t');
-                        if (tp) *tp = 0;
-                        tp = strchr(lineBuffer, '#');
-                        if (tp) *tp = 0;
+            tp = strchr(lineBuffer, ' ');
+            if (tp) *tp = 0;
+            tp = strchr(lineBuffer, '\t');
+            if (tp) *tp = 0;
+            tp = strchr(lineBuffer, '#');
+            if (tp) *tp = 0;
 
                        /* now see if this is the right cell */
-                       if (stricmp(lineBuffer+1, cellNamep) == 0) {
+            if (stricmp(lineBuffer+1, cellNamep) == 0) {
                                /* found the cell we're looking for */
                                if (newCellNamep)
                                        strcpy(newCellNamep, lineBuffer+1);
-                               inRightCell = 1;
+                inRightCell = 1;
                                tracking = 0;
+#ifdef DEBUG
+                DebugEvent_local("AFS- cm_searchfile is cell", "inRightCell[%x], linebuffer[%s]", 
+                                 inRightCell, lineBuffer);
+#endif
                        }
                        else if (strnicmp(lineBuffer+1, cellNamep,
-                                         strlen(cellNamep)) == 0) {
+                               strlen(cellNamep)) == 0) {
                                /* partial match */
                                if (partial) {  /* ambiguous */
                                        fclose(tfilep);
@@ -226,54 +283,115 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
                                tracking = 0;
                                partial = 1;
                        }
-                        else inRightCell = 0;
-                }
-                else {
+            else inRightCell = 0;
+        }
+        else {
 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
-                       valuep = strchr(lineBuffer, '#');
+            valuep = strchr(lineBuffer, '#');
                        if (valuep == NULL) {
                                fclose(tfilep);
                                fclose(bestp);
                                return -4;
                        }
-                        valuep++;      /* skip the "#" */
+            valuep++;  /* skip the "#" */
+
+            valuep += strspn(valuep, " \t"); /* skip SP & TAB */
+            /* strip spaces and tabs in the end. They should not be there according to CellServDB format
+            so do this just in case                        */
+            while (valuep[strlen(valuep) - 1] == ' ' || valuep[strlen(valuep) - 1] == '\t') 
+                valuep[strlen(valuep) - 1] = '\0';
 
-                        valuep += strspn(valuep, "     "); /* skip SP & TAB */
 #endif /* !DJGPP */
                        if (inRightCell) {
 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
                                /* add the server to the VLDB list */
-                                thp = gethostbyname(valuep);
-                                if (thp) {
+                WSASetLastError(0);
+                thp = gethostbyname(valuep);
+#ifdef DEBUG
+                {
+                    int iErr = WSAGetLastError();
+                    DebugEvent_local("AFS- cm_searchfile inRightCell", 
+                                     "thp[%x], valuep[%s], WSAGetLastError[%d]", 
+                                     thp, valuep, iErr);
+                }
+#endif
+                if (thp) {
                                        memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
-                                               sizeof(long));
-                                        vlSockAddr.sin_family = AF_INET;
-                                        /* sin_port supplied by connection code */
+                            sizeof(long));
+                    vlSockAddr.sin_family = AF_INET;
+                    /* sin_port supplied by connection code */
                                        if (procp)
                                                (*procp)(rockp, &vlSockAddr, valuep);
-                                       foundCell = 1;
+                    foundCell = 1;
                                }
 #else
-                                /* For DJGPP, we will read IP address instead
-                                   of name/comment field */
-                                code = sscanf(lineBuffer, "%d.%d.%d.%d #%s",
-                                              &c1, &c2, &c3, &c4, aname);
-                                tp = (char *) &ip_addr;
-                                *tp++ = c1;
-                                *tp++ = c2;
-                                *tp++ = c3;
-                                *tp++ = c4;
-                                memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
-                                               sizeof(long));
-                                vlSockAddr.sin_family = AF_INET;
-                                /* sin_port supplied by connection code */
-                                if (procp)
-                                  (*procp)(rockp, &vlSockAddr, valuep);
-                                foundCell = 1;
+                thp = 0;
 #endif /* !DJGPP */
-                        }
-                }      /* a vldb line */
-        }              /* while loop processing all lines */
+                if (!thp) {
+                    long ip_addr;
+                                       int c1, c2, c3, c4;
+                                       char aname[241] = "";                    
+                    
+                    /* Since there is no gethostbyname() data 
+                     * available we will read the IP address
+                     * stored in the CellServDB file
+                     */
+                    code = sscanf(lineBuffer, "%d.%d.%d.%d #%s",
+                                   &c1, &c2, &c3, &c4, aname);
+                    tp = (char *) &ip_addr;
+                    *tp++ = c1;
+                    *tp++ = c2;
+                    *tp++ = c3;
+                    *tp++ = c4;
+                    memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
+                            sizeof(long));
+                    vlSockAddr.sin_family = AF_INET;
+                    /* sin_port supplied by connection code */
+                    if (procp)
+                        (*procp)(rockp, &vlSockAddr, valuep);
+                    foundCell = 1;
+                }
+            }
+        }      /* a vldb line */
+    }          /* while loop processing all lines */
+
+    /* if for some unknown reason cell is not found, return negative code (-11) ??? */
+    return (foundCell) ? 0 : -11;
+}
+
+long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
+               cm_configProc_t *procp, void *rockp)
+{
+#ifdef AFS_AFSDB_ENV
+    int rc;
+    int  cellHostAddrs[AFSMAXCELLHOSTS];
+    char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
+    int numServers;
+    int i;
+    struct sockaddr_in vlSockAddr;
+
+#ifdef DEBUG
+    DebugEvent_local("AFS SearchCellDNS-","Doing search for [%s]", cellNamep);
+#endif
+    rc = getAFSServer(cellNamep, cellHostAddrs, cellHostNames, &numServers, ttl);
+    if (rc == 0 && numServers > 0) {     /* found the cell */
+        for (i = 0; i < numServers; i++) {
+            memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
+                   sizeof(long));
+           vlSockAddr.sin_family = AF_INET;
+           /* sin_port supplied by connection code */
+           if (procp)
+          (*procp)(rockp, &vlSockAddr, cellHostNames[i]);
+           if(newCellNamep)
+          strcpy(newCellNamep,cellNamep);
+        }
+        return 0;   /* found cell */
+    }
+    else
+       return -1;  /* not found */
+#else
+       return -1;  /* not found */
+#endif /* AFS_AFSDB_ENV */
 }
 
 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
@@ -292,7 +410,7 @@ long cm_GetRootCellName(char *cellNamep)
        code = RegQueryValueEx(parmKey, "Cell", NULL, NULL,
                                cellNamep, &dummyLen);
        RegCloseKey (parmKey);
-       if (code != ERROR_SUCCESS)
+       if (code != ERROR_SUCCESS || cellNamep[0] == 0)
                return -1;
 
        return 0;
@@ -303,13 +421,13 @@ long cm_GetRootCellName(char *cellNamep)
 {
         FILE *thisCell;
         char thisCellPath[256];
-        char *afsconf_path;
         char *newline;
 
 #ifdef DJGPP
         strcpy(thisCellPath, cm_confDir);
 #else
         /* Win 95 */
+        char *afsconf_path;
         afsconf_path = getenv("AFSCONF");
         if (!afsconf_path)
           strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH);
@@ -338,14 +456,12 @@ long cm_GetRootCellName(char *cellNamep)
 cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
 {
        char wdir[256];
-        long code;
-        long tlen;
-        FILE *tfilep;
-        char *afsconf_path;
+    long code;
+    long tlen;
+    FILE *tfilep;
 
 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
-       code = GetWindowsDirectory(wdir, sizeof(wdir));
-        if (code == 0 || code > sizeof(wdir)) return NULL;
+    strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
         
        /* add trailing backslash, if required */
         tlen = strlen(wdir);
@@ -354,7 +470,7 @@ cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
 #ifdef DJGPP
         strcpy(wdir,cm_confDir);
 #else
-        afsconf_path = getenv("AFSCONF");
+        char *afsconf_path = getenv("AFSCONF");
         if (!afsconf_path)
           strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
         else
@@ -405,7 +521,7 @@ long cm_WriteConfigInt(char *labelp, long value)
                return -1;
 
        code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
-                            &value, sizeof(value));
+                            (LPBYTE)&value, sizeof(value));
        RegCloseKey (parmKey);
        if (code != ERROR_SUCCESS)
                return -1;
@@ -502,54 +618,85 @@ long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
         return 0;
 }
 
-extern long cm_CloseCellFile(cm_configFile_t *filep)
+long cm_CloseCellFile(cm_configFile_t *filep)
 {
        char wdir[256];
-        char sdir[256];
-        long code;
-        long closeCode;
-        int tlen;
-        char *afsconf_path;
-
+    char sdir[256];
+    long code;
+    long closeCode;
+    int tlen;
+#ifdef AFS_WIN95_ENV
+    char *afsconf_path;
+#endif
        closeCode = fclose((FILE *)filep);
 
 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
-       code = GetWindowsDirectory(wdir, sizeof(wdir));
-        if (code == 0 || code > sizeof(wdir)) return NULL;
+    strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
         
        /* add trailing backslash, if required */
-        tlen = strlen(wdir);
-        if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
+    tlen = strlen(wdir);
+    if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
 #else
 #ifdef DJGPP
-        strcpy(wdir,cm_confDir);
+    strcpy(wdir,cm_confDir);
 #else
-        afsconf_path = getenv("AFSCONF");
-        if (!afsconf_path)
-          strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
-        else
-          strcpy(wdir, afsconf_path);
+    afsconf_path = getenv("AFSCONF");
+    if (!afsconf_path)
+        strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
+    else
+        strcpy(wdir, afsconf_path);
 #endif /* !DJGPP */
-        strcat(wdir,"/");
+    strcat(wdir,"/");
 #endif /* DJGPP || WIN95 */
 
-        strcpy(sdir, wdir);
+    strcpy(sdir, wdir);
 
        if (closeCode != 0) {
                /* something went wrong, preserve original database */
-                strcat(wdir, "afsdcel2.ini");
-                unlink(wdir);
-                return closeCode;
-        }
+        strcat(wdir, "afsdcel2.ini");
+        unlink(wdir);
+        return closeCode;
+    }
 
-        strcat(wdir, AFS_CELLSERVDB);
-        strcat(sdir, "afsdcel2.ini");  /* new file */
-        
-        unlink(wdir);                  /* delete old file */
-        
-        code = rename(sdir, wdir);     /* do the rename */
-        
-        if (code) code = errno;
+    strcat(wdir, AFS_CELLSERVDB);
+    strcat(sdir, "afsdcel2.ini");      /* new file */
+
+    unlink(wdir);                      /* delete old file */
+
+    code = rename(sdir, wdir); /* do the rename */
+
+    if (code) 
+        code = errno;
+
+    return code;
+}   
+
+void cm_GetConfigDir(char *dir)
+{
+       char wdir[256];
+    int code;
+    int tlen;
+#ifdef AFS_WIN95_ENV
+    char *afsconf_path;
+#endif
+
+#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
+    strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
         
-        return code;
+       /* add trailing backslash, if required */
+    tlen = strlen(wdir);
+    if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
+#else
+#ifdef DJGPP
+    strcpy(wdir,cm_confDir);
+#else
+    afsconf_path = getenv("AFSCONF");
+    if (!afsconf_path)
+        strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
+    else
+        strcpy(wdir, afsconf_path);
+#endif /* !DJGPP */
+    strcat(wdir,"\\");
+#endif /* DJGPP || WIN95 */
+    strcpy(dir, wdir);
 }