~ubuntu-branches/debian/sid/ntp/sid

« back to all changes in this revision

Viewing changes to sntp/libopts/configfile.c

  • Committer: Package Import Robot
  • Author(s): Peter Eisentraut
  • Date: 2012-02-27 13:55:56 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20120227135556-dkx4mkod5trl5bgt
Tags: 1:4.2.6.p5+dfsg-1
* New upstream release (closes: #644673)
* Updated instructions on generating autotools.patch
* Updated standards version

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
2
 * \file configfile.c
3
3
 *
4
 
 *  Time-stamp:      "2010-12-16 14:03:06 bkorb"
 
4
 *  Time-stamp:      "2011-04-06 09:31:24 bkorb"
5
5
 *
6
6
 *  configuration/rc/ini file handling.
7
7
 *
8
8
 *  This file is part of AutoOpts, a companion to AutoGen.
9
9
 *  AutoOpts is free software.
10
 
 *  AutoOpts is Copyright (c) 1992-2010 by Bruce Korb - all rights reserved
 
10
 *  AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
11
11
 *
12
12
 *  AutoOpts is available under any one of two licenses.  The license
13
13
 *  in use must be one of these two and the choice is under the control
51
51
static char *
52
52
handle_section(tOptions * pOpts, char * pzText);
53
53
 
 
54
static int
 
55
parse_xml_encoding(char ** ppz);
 
56
 
 
57
static char *
 
58
trim_xml_text(char * pztxt, char const * pznm, tOptionLoadMode mode);
 
59
 
 
60
static void
 
61
cook_xml_text(char * pzData);
 
62
 
54
63
static char *
55
64
handle_struct(tOptions * pOpts, tOptState * pOS, char * pzText, int dir);
56
65
 
653
662
    size_t name_len = strlen(pOpts->pzProgName);
654
663
 
655
664
    memcpy(ttl, ttlfmt, sizeof(ttlfmt) - 1);
656
 
    strcpy(ttl + sizeof(ttlfmt) - 1, zCfgProg);
 
665
    memcpy(ttl + sizeof(ttlfmt) - 1, zCfgProg, ttl_len - (sizeof(ttlfmt) - 1));
657
666
 
658
667
    do  {
659
668
        while (IS_WHITESPACE_CHAR(*++pzText))  ;
709
718
    return pzText;
710
719
}
711
720
 
 
721
/**
 
722
 * parse XML encodings
 
723
 */
 
724
static int
 
725
parse_xml_encoding(char ** ppz)
 
726
{
 
727
#   define XMLTABLE             \
 
728
        _xmlNm_(amp,   '&')     \
 
729
        _xmlNm_(lt,    '<')     \
 
730
        _xmlNm_(gt,    '>')     \
 
731
        _xmlNm_(ff,    '\f')    \
 
732
        _xmlNm_(ht,    '\t')    \
 
733
        _xmlNm_(cr,    '\r')    \
 
734
        _xmlNm_(vt,    '\v')    \
 
735
        _xmlNm_(bel,   '\a')    \
 
736
        _xmlNm_(nl,    '\n')    \
 
737
        _xmlNm_(space, ' ')     \
 
738
        _xmlNm_(quot,  '"')     \
 
739
        _xmlNm_(apos,  '\'')
 
740
 
 
741
    static struct {
 
742
        char const * const  nm_str;
 
743
        unsigned short      nm_len;
 
744
        short               nm_val;
 
745
    } const xml_names[] = {
 
746
#   define _xmlNm_(_n, _v) { #_n ";", sizeof(#_n), _v },
 
747
        XMLTABLE
 
748
#   undef  _xmlNm_
 
749
#   undef XMLTABLE
 
750
    };
 
751
 
 
752
    static int const nm_ct = sizeof(xml_names) / sizeof(xml_names[0]);
 
753
    int    base = 10;
 
754
 
 
755
    char * pz = *ppz;
 
756
 
 
757
    if (*pz == '#') {
 
758
        pz++;
 
759
        goto parse_number;
 
760
    }
 
761
 
 
762
    if (IS_DEC_DIGIT_CHAR(*pz)) {
 
763
        unsigned long v;
 
764
 
 
765
    parse_number:
 
766
        switch (*pz) {
 
767
        case 'x': case 'X':
 
768
            /*
 
769
             * Some forms specify hex with:  &#xNN;
 
770
             */
 
771
            base = 16;
 
772
            pz++;
 
773
            break;
 
774
 
 
775
        case '0':
 
776
            /*
 
777
             *  &#0022; is hex and &#22; is decimal.  Cool.
 
778
             *  Ya gotta love it.
 
779
             */
 
780
            if (pz[1] == '0')
 
781
                base = 16;
 
782
            break;
 
783
        }
 
784
 
 
785
        v = strtoul(pz, &pz, base);
 
786
        if ((*pz != ';') || (v > 0x7F))
 
787
            return NUL;
 
788
        *ppz = pz + 1;
 
789
        return (int)v;
 
790
    }
 
791
 
 
792
    {
 
793
        int ix = 0;
 
794
        do  {
 
795
            if (strncmp(pz, xml_names[ix].nm_str, xml_names[ix].nm_len)
 
796
                == 0) {
 
797
                *ppz = pz + xml_names[ix].nm_len;
 
798
                return xml_names[ix].nm_val;
 
799
            }
 
800
        } while (++ix < nm_ct);
 
801
    }
 
802
 
 
803
    return NUL;
 
804
}
 
805
 
 
806
/**
 
807
 * Find the end marker for the named section of XML.
 
808
 * Trim that text there, trimming trailing white space for all modes
 
809
 * except for OPTION_LOAD_UNCOOKED.
 
810
 */
 
811
static char *
 
812
trim_xml_text(char * pztxt, char const * pznm, tOptionLoadMode mode)
 
813
{
 
814
    static char const fmt[] = "</%s>";
 
815
    char   z[64], *pz = z;
 
816
    size_t len = strlen(pznm) + sizeof(fmt) - 2 /* for %s */;
 
817
 
 
818
    if (len > sizeof(z))
 
819
        pz = AGALOC(len, "scan name");
 
820
 
 
821
    sprintf(pz, fmt, pznm);
 
822
    *pztxt = ' ';
 
823
    pztxt = strstr(pztxt, pz);
 
824
    if (pz != z) AGFREE(pz);
 
825
 
 
826
    if (pztxt == NULL)
 
827
        return pztxt;
 
828
 
 
829
    if (mode != OPTION_LOAD_UNCOOKED)
 
830
        while (IS_WHITESPACE_CHAR(pztxt[-1]))   len++, pztxt--;
 
831
 
 
832
    *pztxt = NUL;
 
833
    return pztxt + len - 1 /* for NUL byte */;
 
834
}
 
835
 
 
836
/**
 
837
 */
 
838
static void
 
839
cook_xml_text(char * pzData)
 
840
{
 
841
    char * pzs = pzData;
 
842
    char * pzd = pzData;
 
843
    char   bf[4];
 
844
    bf[2] = NUL;
 
845
 
 
846
    for (;;) {
 
847
        int ch = ((int)*(pzs++)) & 0xFF;
 
848
        switch (ch) {
 
849
        case NUL:
 
850
            *pzd = NUL;
 
851
            return;
 
852
 
 
853
        case '&':
 
854
            *(pzd++) = \
 
855
                ch = parse_xml_encoding(&pzs);
 
856
            if (ch == NUL)
 
857
                return;
 
858
            break;
 
859
 
 
860
        case '%':
 
861
            bf[0] = *(pzs++);
 
862
            bf[1] = *(pzs++);
 
863
            if ((bf[0] == NUL) || (bf[1] == NUL)) {
 
864
                *pzd = NUL;
 
865
                return;
 
866
            }
 
867
 
 
868
            ch = strtoul(bf, NULL, 16);
 
869
            /* FALLTHROUGH */
 
870
 
 
871
        default:
 
872
            *(pzd++) = ch;
 
873
        }
 
874
    }
 
875
}
712
876
 
713
877
/**
714
878
 *  "pzText" points to a '<' character, followed by an alpha.
763
927
     */
764
928
    *pcNulPoint = NUL;
765
929
    pzData = ++pzText;
766
 
 
767
 
    /*
768
 
     *  Find the end of the option text and NUL terminate it
769
 
     */
770
 
    {
771
 
        char   z[64], *pz = z;
772
 
        size_t len = strlen(pzName) + 4;
773
 
        if (len > sizeof(z))
774
 
            pz = AGALOC(len, "scan name");
775
 
 
776
 
        sprintf(pz, "</%s>", pzName);
777
 
        *pzText = ' ';
778
 
        pzText = strstr(pzText, pz);
779
 
        if (pz != z) AGFREE(pz);
780
 
 
781
 
        if (pzText == NULL)
782
 
            return pzText;
783
 
 
784
 
        *pzText = NUL;
785
 
 
786
 
        pzText += len-1;
787
 
    }
 
930
    pzText = trim_xml_text(pzText, pzName, mode);
 
931
    if (pzText == NULL)
 
932
        return pzText;
788
933
 
789
934
    /*
790
935
     *  Rejoin the name and value for parsing by "loadOptionLine()".
793
938
    memset(pcNulPoint, ' ', pzData - pcNulPoint);
794
939
 
795
940
    /*
796
 
     *  If we are getting a "string" value, the process the XML-ish
797
 
     *  %XX hex characters.
 
941
     *  If we are getting a "string" value that is to be cooked,
 
942
     *  then process the XML-ish &xx; XML-ish and %XX hex characters.
798
943
     */
799
 
    if (valu.valType == OPARG_TYPE_STRING) {
800
 
        char * pzSrc = pzData;
801
 
        char * pzDst = pzData;
802
 
        char bf[4];
803
 
        bf[2] = NUL;
804
 
 
805
 
        for (;;) {
806
 
            int ch = ((int)*(pzSrc++)) & 0xFF;
807
 
            switch (ch) {
808
 
            case NUL: goto string_fixup_done;
809
 
 
810
 
            case '%':
811
 
                bf[0] = *(pzSrc++);
812
 
                bf[1] = *(pzSrc++);
813
 
                if ((bf[0] == NUL) || (bf[1] == NUL))
814
 
                    goto string_fixup_done;
815
 
                ch = strtoul(bf, NULL, 16);
816
 
                /* FALLTHROUGH */
817
 
 
818
 
            default:
819
 
                *(pzDst++) = ch;
820
 
            }
821
 
        } string_fixup_done:;
822
 
        *pzDst = NUL;
823
 
    }
 
944
    if (  (valu.valType == OPARG_TYPE_STRING)
 
945
       && (mode == OPTION_LOAD_COOKED))
 
946
        cook_xml_text(pzData);
824
947
 
825
948
    /*
826
949
     *  "pzName" points to what looks like text for one option/configurable.
903
1026
 
904
1027
        if (S_ISDIR(StatBuf.st_mode)) {
905
1028
            size_t len = strlen(zFileName);
906
 
            char* pz;
 
1029
            size_t nln = strlen(pOpts->pzRcName) + 1;
 
1030
            char * pz  = zFileName + len;
907
1031
 
908
 
            if (len + 1 + strlen(pOpts->pzRcName) >= sizeof(zFileName))
 
1032
            if (len + 1 + nln >= sizeof(zFileName))
909
1033
                continue;
910
1034
 
911
 
            pz = zFileName + len;
912
1035
            if (pz[-1] != DIRCH)
913
1036
                *(pz++) = DIRCH;
914
 
            strcpy(pz, pOpts->pzRcName);
 
1037
            memcpy(pz, pOpts->pzRcName, nln);
915
1038
        }
916
1039
 
917
1040
        file_preset(pOpts, zFileName, inc);
1239
1362
       && (  (pOpts->structVersion > OPTIONS_STRUCT_VERSION  )
1240
1363
          || (pOpts->structVersion < OPTIONS_MINIMUM_VERSION )
1241
1364
       )  )  {
 
1365
        static char const aover[] =
 
1366
            __STR(AO_CURRENT)":"__STR(AO_REVISION)":"__STR(AO_AGE)"\n";
1242
1367
 
1243
1368
        fprintf(stderr, zAO_Err, pzProgram, NUM_TO_VER(pOpts->structVersion));
1244
1369
        if (pOpts->structVersion > OPTIONS_STRUCT_VERSION )
1246
1371
        else
1247
1372
            fputs(zAO_Sml, stderr);
1248
1373
 
1249
 
        fputs(ShellAsString(AO_CURRENT)  ":"
1250
 
              ShellAsString(AO_REVISION) ":"
1251
 
              ShellAsString(AO_AGE)      "\n", stderr);
 
1374
        fwrite(aover, sizeof(aover) - 1, 1, stderr);
1252
1375
        return FAILURE;
1253
1376
    }
1254
1377