www.pudn.com > tvctrl.rar > etcfile.c


#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
  
#include "tvmisc.h"  
  
#ifndef TRUE  
#define TRUE 1  
#endif  
  
#ifndef FALSE  
#define FALSE 0  
#endif  
  
#ifndef BOOL  
#define BOOL int  
#endif  
  
static int etcf_LocateSection(FILE* fp, const char* pSection, FILE* bak_fp) ;  
static int etcf_LocateKeyValue(FILE* fp, const char* pKey,   
                               BOOL bCurSection, char* pValue, int iLen,  
                               FILE* bak_fp, char* nextSection) ;  
static int etcf_CopyAndLocate (FILE* etc_fp, FILE* tmp_fp,   
                const char* pSection, const char* pKey, char* tempSection) ;  
static int etcf_FileCopy (FILE* sf, FILE* df) ;  
  
/****************************** ETC file support ******************************/  
// This function locate the specified section in the etc file.  
static int etcf_LocateSection(FILE* fp, const char* pSection, FILE* bak_fp)  
{  
    char szBuff[ETC_MAXLINE + 1];  
    char* current;  
    char* tail;  
  
    while (TRUE) {  
        if (!fgets(szBuff, ETC_MAXLINE, fp)) {  
            if (feof (fp))  
                return ETC_SECTIONNOTFOUND;  
            else  
                return ETC_FILEIOFAILED;  
        }  
        else if (bak_fp && fputs (szBuff, bak_fp) == EOF)  
            return ETC_FILEIOFAILED;  
          
        current = szBuff;  
  
        while (*current == ' ' ||  *current == '\t') current++;   
  
        if (*current == ';' || *current == '#') continue;  
  
        if (*current++ == '[')   
            while (*current == ' ' ||  *current == '\t') current ++;  
        else  
            continue;  
  
        // Locate the tail.  
        tail = current;  
        while (*tail != ']' && *tail != '\n' &&  
              *tail != ';' && *tail != '#' && *tail != '\0')  
              tail++;  
        *tail = '\0';  
        while (*tail == ' ' || *tail == '\t') {  
            *tail = '\0';  
            tail--;   
        }  
              
        if (strcmp (current, pSection) == 0)  
            return ETC_OK;   
    }  
  
    return ETC_SECTIONNOTFOUND;  
}  
  
// This function locate the specified key in the etc file.  
static int etcf_LocateKeyValue(FILE* fp, const char* pKey,   
                               BOOL bCurSection, char* pValue, int iLen,  
                               FILE* bak_fp, char* nextSection)  
{  
    char szBuff[ETC_MAXLINE + 1 + 1];  
    char* current;  
    char* tail;  
    char* value;  
  
    while (TRUE) {  
        if (!fgets(szBuff, ETC_MAXLINE, fp))  
            return ETC_FILEIOFAILED;  
        if (szBuff [strlen (szBuff) - 1] == '\n')  
            szBuff [strlen (szBuff) - 1] = '\0';  
        current = szBuff;  
  
        while (*current == ' ' ||  *current == '\t') current++;   
  
        if (*current == ';' || *current == '#') continue;  
  
        if (*current == '[') {  
            if (bCurSection) {  
                strcpy (nextSection, current);  
                return ETC_KEYNOTFOUND;   
            }  
            else  
                continue;  
        }  
  
        tail = current;  
        while (*tail != '=' && *tail != '\n' &&  
              *tail != ';' && *tail != '#' && *tail != '\0')  
              tail++;  
  
        value = tail + 1;  
        if (*tail != '=')  
            *value = '\0';   
  
        *tail-- = '\0';  
        while (*tail == ' ' || *tail == '\t') {  
            *tail = '\0';  
            tail--;   
        }  
              
        if (strcmp (current, pKey) == 0) {  
            tail = value;  
            while (*tail != '\n' && *tail != '\0') tail++;  
            *tail = '\0';   
  
            if (pValue)  
                strncpy (pValue, value, iLen);  
  
            return ETC_OK;   
        }  
        else if (bak_fp && *current != '\0')  
            fprintf (bak_fp, "%s=%s\n", current, value);  
    }  
  
    return ETC_KEYNOTFOUND;  
}  
  
/* Function: GetValueFromIniFile(const char* pEtcFile, const char* pSection,  
 *                               const char* pKey, char* pValue, int iLen);  
 * Parameter:  
 *     pEtcFile: etc file path name.  
 *     pSection: Section name.  
 *     pKey:     Key name.  
 *     pValue:   The buffer will store the value of the key.  
 *     iLen:     The max length of value string.  
 * Return:  
 *     int               meaning  
 *     ETC_FILENOTFOUND           The etc file not found.   
 *     ETC_SECTIONNOTFOUND        The section is not found.   
 *     ETC_EKYNOTFOUND        The Key is not found.  
 *     ETC_OK            OK.  
 */  
int GetValueFromIniFile(const char* pEtcFile, const char* pSection,  
                               const char* pKey, char* pValue, int iLen)  
{  
    FILE* fp;  
    char tempSection [ETC_MAXLINE + 2];  
  
    if (!(fp = fopen(pEtcFile, "r")))  
         return ETC_FILENOTFOUND;  
  
    if (pSection)  
         if (etcf_LocateSection (fp, pSection, NULL) != ETC_OK) {  
             fclose (fp);  
             return ETC_SECTIONNOTFOUND;  
         }  
  
    if (etcf_LocateKeyValue (fp, pKey, pSection != NULL,   
                pValue, iLen, NULL, tempSection) != ETC_OK) {  
         fclose (fp);  
         return ETC_KEYNOTFOUND;  
    }  
  
    fclose (fp);  
    return ETC_OK;  
}  
  
/* Function: GetIntValueFromEtcFile(const char* pEtcFile, const char* pSection,  
 *                               const char* pKey);  
 * Parameter:  
 *     pEtcFile: etc file path name.  
 *     pSection: Section name.  
 *     pKey:     Key name.  
 * Return:  
 *     int                      meaning  
 *     ETC_FILENOTFOUND             The etc file not found.   
 *     ETC_SECTIONNOTFOUND          The section is not found.   
 *     ETC_EKYNOTFOUND              The Key is not found.  
 *     ETC_OK                       OK.  
 */  
int GetIntValueFromIniFile(const char* pEtcFile, const char* pSection,  
                               const char* pKey, int* value)  
{  
    int ret;  
    char szBuff [51];  
  
    ret = GetValueFromIniFile (pEtcFile, pSection, pKey, szBuff, 50);  
    if (ret < 0)  
        return ret;  
  
    *value = strtol (szBuff, NULL, 0);  
    if ((*value == LONG_MIN || *value == LONG_MAX) && errno == ERANGE)  
        return ETC_INTCONV;  
  
    return ETC_OK;  
}  
  
static int etcf_CopyAndLocate (FILE* etc_fp, FILE* tmp_fp,   
                const char* pSection, const char* pKey, char* tempSection)  
{  
    if (pSection && etcf_LocateSection (etc_fp, pSection, tmp_fp) != ETC_OK)  
        return ETC_SECTIONNOTFOUND;  
  
    if (etcf_LocateKeyValue (etc_fp, pKey, pSection != NULL,   
                NULL, 0, tmp_fp, tempSection) != ETC_OK)  
        return ETC_KEYNOTFOUND;  
  
    return ETC_OK;  
}  
  
static int etcf_FileCopy (FILE* sf, FILE* df)  
{  
    char line [ETC_MAXLINE + 1];  
      
    while (fgets (line, ETC_MAXLINE + 1, sf) != NULL)  
        if (fputs (line, df) == EOF) {  
            return ETC_FILEIOFAILED;  
        }  
  
    return ETC_OK;  
}  
  
/* Function: SetValueToEtcFile(const char* pEtcFile, const char* pSection,  
 *                               const char* pKey, char* pValue);  
 * Parameter:  
 *     pEtcFile: etc file path name.  
 *     pSection: Section name.  
 *     pKey:     Key name.  
 *     pValue:   Value.  
 * Return:  
 *     int                      meaning  
 *     ETC_FILENOTFOUND         The etc file not found.  
 *     ETC_TMPFILEFAILED        Create tmp file failure.  
 *     ETC_OK                   OK.  
 */  
int SetValueToIniFile (const char* pEtcFile, const char* pSection,  
                               const char* pKey, char* pValue)  
{  
    FILE* etc_fp;  
    FILE* tmp_fp;  
    int rc;  
    char tempSection [ETC_MAXLINE + 2];  
  
    if ((tmp_fp = tmpfile ()) == NULL)  
        return ETC_TMPFILEFAILED;  
  
    if (!(etc_fp = fopen (pEtcFile, "r+"))) {  
        fclose (tmp_fp);  
        if (!(etc_fp = fopen (pEtcFile, "w")))  
            return ETC_FILEIOFAILED;  
        fprintf (etc_fp, "[%s]\n", pSection);  
        fprintf (etc_fp, "%s=%s\n", pKey, pValue);  
        fclose (etc_fp);  
        return ETC_OK;  
    }  
  
    switch (etcf_CopyAndLocate (etc_fp, tmp_fp, pSection, pKey, tempSection)) {  
    case ETC_SECTIONNOTFOUND:  
        fprintf (tmp_fp, "\n[%s]\n", pSection);  
        fprintf (tmp_fp, "%s=%s\n", pKey, pValue);  
        break;  
      
    case ETC_KEYNOTFOUND:  
        fprintf (tmp_fp, "%s=%s\n\n", pKey, pValue);  
        fprintf (tmp_fp, "%s\n", tempSection);  
    break;  
  
    default:  
        fprintf (tmp_fp, "%s=%s\n", pKey, pValue);  
        break;  
    }  
  
    if ((rc = etcf_FileCopy (etc_fp, tmp_fp)) != ETC_OK)  
        goto error;  
      
    // replace etc content with tmp file content  
    // truncate etc content first  
    fclose (etc_fp);  
    if (!(etc_fp = fopen (pEtcFile, "w")))  
        return ETC_FILEIOFAILED;  
      
    rewind (tmp_fp);  
    rc = etcf_FileCopy (tmp_fp, etc_fp);  
  
error:  
    fclose (etc_fp);  
    fclose (tmp_fp);  
    return rc;  
}