Logo Search packages:      
Sourcecode: psqlodbc version File versions

gpps.c

/*-------
 * GetPrivateProfileString()
 *
 * approximate implementation of
 * Windows NT System Services version of GetPrivateProfileString()
 * probably doesn't handle the NULL key for section name or value key
 * correctly also, doesn't provide Microsoft backwards compatability
 * wrt TAB characters in the value string
 *
 * Microsoft terminates value
 * at the first TAB, but I couldn't discover what the behavior should
 * be regarding TABS in quoted strings so, I treat tabs like any other
 * characters
 *
 * NO comments following value string separated by a TAB
 * are allowed (that is an anachronism anyway)
 * Added code to search for ODBC_INI file in users home directory on
 * Unix
 *-------
 */

#include "config.h"
#if !defined(WIN32) && !defined(WITH_UNIXODBC) && !defined(WITH_IODBC)

#include "gpps.h"

#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <pwd.h>

#include <sys/types.h>
#include <string.h>
#include "misc.h"
#include "dlg_specific.h"

#ifndef TRUE
#define TRUE      ((BOOL)1)
#endif
#ifndef FALSE
#define FALSE     ((BOOL)0)
#endif

#ifndef ODBCINSTDIR
#error "ODBCINSTDIR must be defined to compile this file"
#endif


/*
 * theIniFileName is searched for in:
 *    $HOME/theIniFileName
 *    theIniFileName
 *    ODBCINSTDIR/ODBCINST_INI
 */
DWORD
GetPrivateProfileString(const char *theSection, /* section name */
                                    const char *theKey,           /* search key name */
                                    const char *theDefault, /* default value if not
                                                                         * found */
                                    char *theReturnBuffer,  /* return value stored
                                                                         * here */
                                    size_t theReturnBufferLength, /* byte length of return
                                                                                     * buffer */
                                    const char *theIniFileName)         /* pathname of ini file
                                                                                     * to search */
{
      char        buf[MAXPGPATH];
      char     *ptr = 0;
      FILE     *aFile = 0;
      size_t            aLength;
      char        aLine[2048];
      char     *aValue;
      char     *aStart;
      char     *aString;
      size_t            aLineLength;
      size_t            aReturnLength = 0;
      BOOL        aSectionFound = FALSE;
      BOOL        aKeyFound = FALSE;

      ptr = (char *) getpwuid(getuid());  /* get user info */

      if (ptr == NULL || (((struct passwd *) ptr)->pw_dir) == NULL || *(((struct passwd *) ptr)->pw_dir) == '\0')
            ptr = "/home";
      else
            ptr = ((struct passwd *) ptr)->pw_dir;    /* get user home dir */

      /*
       * If it can't be opened because the paths are too long, then skip it,
       * don't just truncate the path string...  The truncated path might
       * accidently be an existing file.  The default value will be returned
       * instead.
       */
      if (MAXPGPATH - 1 >= strlen(ptr) + 1 + strlen(theIniFileName))
      {
            sprintf(buf, "%s/%s", ptr, theIniFileName);
            aFile = (FILE *) fopen(buf, PG_BINARY_R);
      }

      /*
       * This code makes it so that a file in the users home dir overrides a
       * the "default" file as passed in
       */
      if (!aFile)
      {
            aFile = (FILE *) fopen(theIniFileName, PG_BINARY_R);
            if (!aFile)
                  aFile = (FILE *) fopen(ODBCINSTDIR "/" ODBCINST_INI, PG_BINARY_R);
      }

      aLength = (theDefault == NULL) ? 0 : strlen(theDefault);

      if (theReturnBufferLength == 0 || theReturnBuffer == NULL)
      {
            if (aFile)
                  fclose(aFile);
            return 0;
      }

      if (aFile == NULL)
      {
            /* no ini file specified, return the default */
            ++aLength;                    /* room for NULL char */
            aLength = theReturnBufferLength < aLength ?
                  theReturnBufferLength : aLength;
            strncpy(theReturnBuffer, theDefault, aLength);
            theReturnBuffer[aLength - 1] = '\0';
            return aLength - 1;
      }

      while (fgets(aLine, sizeof(aLine), aFile) != NULL)
      {
            aLineLength = strlen(aLine);
            /* strip final '\n' */
            if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
                  aLine[aLineLength - 1] = '\0';
            switch (*aLine)
            {
                  case ' ':               /* blank line */
                  case ';':               /* comment line */
                        continue;
                        break;

                  case '[':               /* section marker */
                        if ((aString = strchr(aLine, ']')))
                        {
                              aStart = aLine + 1;
                              aString--;
                              while (isspace((unsigned char) *aStart))
                                    aStart++;
                              while (isspace((unsigned char) *aString))
                                    aString--;
                              *(aString + 1) = '\0';

                              /* accept as matched if NULL key or exact match */
                              if (!theSection || !strcmp(aStart, theSection))
                                    aSectionFound = TRUE;
                              else
                                    aSectionFound = FALSE;
                        }
                        break;

                  default:

                        /* try to match value keys if in proper section */
                        if (aSectionFound)
                        {
                              /* try to match requested key */
                              if ((aString = aValue = strchr(aLine, '=')))
                              {
                                    *aValue = '\0';
                                    ++aValue;

                                    /* strip leading blanks in value field */
                                    while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
                                          *aValue++ = '\0';
                                    if (aValue >= aLine + sizeof(aLine))
                                          aValue = "";
                              }
                              else
                                    aValue = "";

                              aStart = aLine;
                              while (isspace((unsigned char) *aStart))
                                    aStart++;

                              /* strip trailing blanks from key */
                              if (aString)
                              {
                                    while (--aString >= aStart && *aString == ' ')
                                          *aString = '\0';
                              }

                              /* see if key is matched */
                              if (theKey == NULL || !strcmp(theKey, aStart))
                              {
                                    /* matched -- first, terminate value part */
                                    aKeyFound = TRUE;
                                    aLength = strlen(aValue);

                                    /* remove trailing blanks from aValue if any */
                                    aString = aValue + aLength - 1;

                                    while (--aString > aValue && *aString == ' ')
                                    {
                                          *aString = '\0';
                                          --aLength;
                                    }

                                    /* unquote value if quoted */
                                    if (aLength >= 2 && aValue[0] == '"' &&
                                          aValue[aLength - 1] == '"')
                                    {
                                          /* string quoted with double quotes */

                                          aValue[aLength - 1] = '\0';
                                          ++aValue;
                                          aLength -= 2;
                                    }
                                    else
                                    {
                                          /* single quotes allowed also... */
                                          if (aLength >= 2 && aValue[0] == '\'' &&
                                                aValue[aLength - 1] == '\'')
                                          {
                                                aValue[aLength - 1] = '\0';
                                                ++aValue;
                                                aLength -= 2;
                                          }
                                    }

                                    /* compute maximum length copyable */
                                    aLineLength = (aLength <
                                    theReturnBufferLength - aReturnLength) ? aLength :
                                          theReturnBufferLength - aReturnLength;

                                    /* do the copy to return buffer */
                                    if (aLineLength)
                                    {
                                          strncpy(&theReturnBuffer[aReturnLength],
                                                      aValue, aLineLength);
                                          aReturnLength += aLineLength;
                                          if (aReturnLength < theReturnBufferLength)
                                          {
                                                theReturnBuffer[aReturnLength] = '\0';
                                                ++aReturnLength;
                                          }
                                    }
                                    if (aFile)
                                    {
                                          fclose(aFile);
                                          aFile = NULL;
                                    }
                                    return aReturnLength > 0 ? aReturnLength - 1 : 0;
                              }
                        }
                        break;
            }
      }

      if (aFile)
            fclose(aFile);

      if (!aKeyFound)
      {
            /* key wasn't found return default */
            ++aLength;                    /* room for NULL char */
            aLength = theReturnBufferLength < aLength ?
                  theReturnBufferLength : aLength;
            strncpy(theReturnBuffer, theDefault, aLength);
            theReturnBuffer[aLength - 1] = '\0';
            aReturnLength = aLength - 1;
      }
      return aReturnLength > 0 ? aReturnLength - 1 : 0;
}


DWORD
WritePrivateProfileString(const char *theSection,           /* section name */
                                      const char *theKey,   /* write key name */
                                      const char *theBuffer,            /* input buffer */
                                      const char *theIniFileName) /* pathname of ini file
                                                                                     * to write */
{
      return 0;
}


#if NOT_USED
/*
 * Ok. What the hell's the default behaviour for a null input buffer, and null
 * section name. For now if either are null I ignore the request, until
 * I find out different.
 */
DWORD
WritePrivateProfileString(char *theSection,           /* section name */
                                      char *theKey, /* write key name */
                                      char *theBuffer,            /* input buffer */
                                      char *theIniFileName) /* pathname of ini file to
                                                                         * write */
{
      char        buf[MAXPGPATH];
      char     *ptr = 0;
      FILE     *aFile = 0;
      size_t            aLength;
      char        aLine[2048];
      char     *aValue;
      char     *aString;
      size_t            aLineLength;
      size_t            aReturnLength = 0;

      BOOL        aSectionFound = FALSE;
      BOOL        keyFound = FALSE;
      int               j = 0;

      /* If this isn't correct processing we'll change it later  */
      if (theSection == NULL || theKey == NULL || theBuffer == NULL ||
            theIniFileName == NULL)
            return 0;

      aLength = strlen(theBuffer);
      if (aLength == 0)
            return 0;

      j = strlen(theIniFileName) + 1;
      ptr = (char *) getpwuid(getuid());  /* get user info */

      if (ptr == NULL)
      {
            if (MAXPGPATH - 1 < j)
                  theIniFileName[MAXPGPATH - 1] = '\0';

            sprintf(buf, "%s", theIniFileName);
      }
      ptr = ((struct passwd *) ptr)->pw_dir;          /* get user home dir */
      if (ptr == NULL || *ptr == '\0')
            ptr = "/home";

      /*
       * This doesn't make it so we find an ini file but allows normal
       * processing to continue further on down. The likelihood is that the
       * file won't be found and thus the default value will be returned.
       */
      if (MAXPGPATH - 1 < strlen(ptr) + j)
      {
            if (MAXPGPATH - 1 < strlen(ptr))
                  ptr[MAXPGPATH - 1] = '\0';
            else
                  theIniFileName[MAXPGPATH - 1 - strlen(ptr)] = '\0';
      }

      sprintf(buf, "%s/%s", ptr, theIniFileName);

      /*
       * This code makes it so that a file in the users home dir overrides a
       * the "default" file as passed in
       */
      aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
      if (!aFile)
      {
            sprintf(buf, "%s", theIniFileName);
            aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
            if (!aFile)
                  return 0;
      }

      aLength = strlen(theBuffer);

      /*
       * We have to search for theKey, because if it already exists we have
       * to overwrite it. If it doesn't exist we just write a new line to
       * the file.
       */
      while (fgets(aLine, sizeof(aLine), aFile) != NULL)
      {
            aLineLength = strlen(aLine);
            /* strip final '\n' */
            if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
                  aLine[aLineLength - 1] = '\0';
            switch (*aLine)
            {
                  case ' ':               /* blank line */
                  case ';':               /* comment line */
                        continue;
                        break;

                  case '[':               /* section marker */
                        if ((aString = strchr(aLine, ']')))
                        {
                              *aString = '\0';

                              /* accept as matched if key exact match */

                              if (!strcmp(aLine + 1, theSection))
                                    aSectionFound = TRUE;
                        }
                        break;

                  default:
                        /* try to match value keys if in proper section */
                        if (aSectionFound)
                        {
                              /* try to match requested key */

                              if ((aString = aValue = strchr(aLine, '=')))
                              {
                                    *aValue = '\0';
                                    ++aValue;

                                    /* strip leading blanks in value field */
                                    while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
                                          *aValue++ = '\0';
                                    if (aValue >= aLine + sizeof(aLine))
                                          aValue = "";
                              }
                              else
                                    aValue = "";

                              /* strip trailing blanks from key */
                              if (aString)
                              {
                                    while (--aString >= aLine && *aString == ' ')
                                          *aString = '\0';
                              }

                              /* see if key is matched */
                              if (!strcmp(theKey, aLine))
                              {
                                    keyFound = TRUE;
                                    /* matched -- first, terminate value part */

                                    /* overwrite current value */
                                    fseek(aFile, -aLineLength, SEEK_CUR);
                                    /* overwrite key and value */
                                    sprintf(aLine, "%s = %s\n", theKey, theBuffer);
                                    fputs(aLine, aFile);
                              }
                        }
            }
            break;
      }
}

if (!keyFound)
{                                               /* theKey wasn't in file so  */
      if (aFile)
            fclose(aFile);

      return aReturnLength > 0 ? aReturnLength - 1 : 0;
}
#endif   /* NOT_USED */

#endif   /* not WIN32 */

Generated by  Doxygen 1.6.0   Back to index