Check-in [92a0e45fc6]
Overview
Comment:Updated man pages. Updated lc_process_files() to work.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 92a0e45fc625c5d24b3d55c1ed1978e5976543e6
User & Date: rkeene on 2004-10-26 13:19:56
Other Links: manifest | tags
Context
2004-10-28
21:11
Fixed command line processing and added argument re-ordering. Also, added a global variable lc_optind to indicate where we were in the argv array. check-in: 9d733cc5a2 user: rkeene tags: trunk
2004-10-26
13:19
Updated man pages. Updated lc_process_files() to work. check-in: 92a0e45fc6 user: rkeene tags: trunk
2004-10-24
14:26
Lots of improvements to libconfig: We now process the command line arguments ourselves rather than using getopt(). We now process Apache-style config files. Began work on documentation. Many more bug fixes check-in: 6a0a10a0ab user: rkeene tags: trunk
Changes

Modified build/list-chkfiles.sh from [5b504920a7] to [ebf22f9f71].

1
2
3
4
5
6
7
8
9

10



#! /bin/sh

for file in *.[ch]; do
	if [ "${file}" = "compat.h" ]; then continue; fi
	if [ "${file}" = "config.h" ]; then continue; fi
	if [ "${file}" = "win32.h" ]; then continue; fi
	filelist="${filelist} ${file}"
done


grep ' HAVE_.*_H$' ${filelist} | sed 's@.*HAVE_\(.*_H\)@\1@;s@_H$@.h@;s@_@/@g' | dd conv=lcase 2>/dev/null | grep -v '^config.h$' | sort -u












>
|
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#! /bin/sh

for file in *.[ch]; do
	if [ "${file}" = "compat.h" ]; then continue; fi
	if [ "${file}" = "config.h" ]; then continue; fi
	if [ "${file}" = "win32.h" ]; then continue; fi
	filelist="${filelist} ${file}"
done

(
	grep ' HAVE_.*_H$' ${filelist} | sed 's@.*HAVE_\(.*_H\)@\1@;s@_H$@.h@;s@_@/@g' | dd conv=lcase 2>/dev/null | grep -v '^config.h$'
	echo 'time.h'
	echo 'sys/time.h'
) | sort -u

Modified config.h.in from [813c28c85f] to [543f408fb5].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* config.h.in.  Generated from configure.in by autoheader.  */

/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H

/* Define to 1 if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H

/* Define to 1 if you have the `getopt' function. */
#undef HAVE_GETOPT

/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define to 1 if you have the <libintl.h> header file. */
#undef HAVE_LIBINTL_H

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H

/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H









|
<
<
<
|




|
|

|
|







1
2
3
4
5
6
7
8
9



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* config.h.in.  Generated from configure.in by autoheader.  */

/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H

/* Define to 1 if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H

/* Define to 1 if you have the `getpwuid' function. */



#undef HAVE_GETPWUID

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

/* Define to 1 if you have the <pwd.h> header file. */
#undef HAVE_PWD_H

/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H

/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H

Modified configure from [3e2a72d1bf] to [b7be557787].

3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081









for ac_header in ctype.h dirent.h libintl.h stdio.h stdlib.h string.h strings.h sys/stat.h sys/types.h unistd.h getopt.h time.h sys/time.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
  echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
  echo $ECHO_N "(cached) $ECHO_C" >&6







|
<
<







3065
3066
3067
3068
3069
3070
3071
3072


3073
3074
3075
3076
3077
3078
3079







for ac_header in ctype.h dirent.h pwd.h stdio.h stdlib.h string.h sys/stat.h sys/time.h sys/types.h time.h unistd.h


do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
  echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
15356
15357
15358
15359
15360
15361
15362
15363
15364
15365
15366
15367
15368
15369
15370
15371
			FOUND=1
			break
		fi
	done




for ac_func in getopt strsep
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
if eval "test \"\${$as_ac_var+set}\" = set"; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else







<
|







15354
15355
15356
15357
15358
15359
15360

15361
15362
15363
15364
15365
15366
15367
15368
			FOUND=1
			break
		fi
	done




for ac_func in strsep
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
if eval "test \"\${$as_ac_var+set}\" = set"; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
15468
15469
15470
15471
15472
15473
15474






































































































15475
15476
15477
15478
15479
15480
15481
  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
esac

fi
done












































































































for ac_header in windows.h windowsx.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







15465
15466
15467
15468
15469
15470
15471
15472
15473
15474
15475
15476
15477
15478
15479
15480
15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497
15498
15499
15500
15501
15502
15503
15504
15505
15506
15507
15508
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518
15519
15520
15521
15522
15523
15524
15525
15526
15527
15528
15529
15530
15531
15532
15533
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
esac

fi
done



for ac_func in getpwuid
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
if eval "test \"\${$as_ac_var+set}\" = set"; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
#define $ac_func innocuous_$ac_func

/* System header to define __stub macros and hopefully few prototypes,
    which can conflict with char $ac_func (); below.
    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
    <limits.h> exists even on freestanding compilers.  */

#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif

#undef $ac_func

/* Override any gcc2 internal prototype to avoid an error.  */
#ifdef __cplusplus
extern "C"
{
#endif
/* We use char because int might match the return type of a gcc2
   builtin and then its argument prototype would still apply.  */
char $ac_func ();
/* The GNU C library defines this for functions which it implements
    to always fail with ENOSYS.  Some functions are actually named
    something starting with __ and the normal name is an alias.  */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
char (*f) () = $ac_func;
#endif
#ifdef __cplusplus
}
#endif

int
main ()
{
return f != $ac_func;
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest$ac_exeext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  eval "$as_ac_var=yes"
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

eval "$as_ac_var=no"
fi
rm -f conftest.err conftest.$ac_objext \
      conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
if test `eval echo '${'$as_ac_var'}'` = yes; then
  cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF

fi
done





for ac_header in windows.h windowsx.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`

Modified configure.in from [769589dcb9] to [4423e690ac].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
AC_REVISION($Revision $)
AC_INIT(libconfig, 0.0.2)
AC_CONFIG_HEADER(config.h)

dnl Checks for programs.
AC_PROG_CC
AC_PROG_MAKE_SET
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_RANLIB
AC_AIX
AC_CHECK_TOOL(AR, ar, true)
AC_GNU_SOURCE

AC_CHECK_HEADERS(ctype.h dirent.h libintl.h stdio.h stdlib.h string.h strings.h sys/stat.h sys/types.h unistd.h time.h sys/time.h)
AC_HEADER_TIME

DC_DO_TYPE(uint64_t, unsigned, 8)
DC_DO_TYPE(int64_t, signed, 8)
DC_DO_TYPE(uint32_t, unsigned, 4)
DC_DO_TYPE(int32_t, signed, 4)
DC_DO_TYPE(uint16_t, unsigned, 2)
DC_DO_TYPE(int16_t, signed, 2)

AC_REPLACE_FUNCS(strsep)


dnl Checks for Win32 specific things.
DC_DO_WIN32

DC_GET_SHOBJFLAGS

AC_OUTPUT(Makefile lc_geterrno.3 lc_process.3 lc_register_var.3 lc_geterrstr.3 lc_register_callback.3)

|












|










>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
AC_REVISION($Revision $)
AC_INIT(libconfig, 0.0.3)
AC_CONFIG_HEADER(config.h)

dnl Checks for programs.
AC_PROG_CC
AC_PROG_MAKE_SET
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_RANLIB
AC_AIX
AC_CHECK_TOOL(AR, ar, true)
AC_GNU_SOURCE

AC_CHECK_HEADERS(ctype.h dirent.h pwd.h stdio.h stdlib.h string.h sys/stat.h sys/time.h sys/types.h time.h unistd.h)
AC_HEADER_TIME

DC_DO_TYPE(uint64_t, unsigned, 8)
DC_DO_TYPE(int64_t, signed, 8)
DC_DO_TYPE(uint32_t, unsigned, 4)
DC_DO_TYPE(int32_t, signed, 4)
DC_DO_TYPE(uint16_t, unsigned, 2)
DC_DO_TYPE(int16_t, signed, 2)

AC_REPLACE_FUNCS(strsep)
AC_CHECK_FUNCS(getpwuid)

dnl Checks for Win32 specific things.
DC_DO_WIN32

DC_GET_SHOBJFLAGS

AC_OUTPUT(Makefile lc_geterrno.3 lc_process.3 lc_register_var.3 lc_geterrstr.3 lc_register_callback.3)

Modified lc_register_callback.3.in from [da39a3ee5e] to [57f2b8a256].











































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
.TH LC_REGISTER_CALLBACK 3 "25 Oct 04" "@PACKAGE_STRING@"
.SH NAME
lc_register_callback \- Register a function for callback in config processing.

.SH SYNOPSIS
.B #include <libconfig.h>
.sp
.BI "int lc_register_callback(const char *" var ", char " opt ", lc_var_type_t " type ", int (*callback)(const char *, const char *, const char *, const char *, lc_flags_t, void *), void *" extra);

.SH DESCRIPTION
The
.B lc_register_callback
function registers a function to be called when
.IR var
is encounted in a configuration file, command line, or environment variable.
The parameters are as follows:
.TP
.IR "const char *var"
.RS
The
.IR var
parameter indicates the name of the variable to register for a callback when encountered in a configuration file, the environment, or as a long option.  The
.IR var
may be prefixed with "*." to indicate that the object can occur in any section or subsection.
.RE

.TP
.IR "const char opt"
.RS
The
.IR opt
parameter indicates the single charectar short option to use from the command line to invoke the register callback.  A value of 0 indicates that no short option is acceptable.
.RE

.TP
.IR "lc_var_type_t type"
.RS
The
.IR type
parameter indicates the type of values that are acceptable for this callback.  Currently only LC_VAR_NONE is acceptable, since callbacks may not have values (though they may have arguments).
.RE

.TP
.IR "int (*callback)(...)"
.RS
The
.IR callback
parameter indicates the name of the function to invoke when the above parameters are met.  The specified function should take 6 parameters, see below for more information.  This value may not be NULL.
.RE

.TP
.IR "void *extra"
.RS
The
.IR extra
parameter is a pointer that can be used to pass data to the callback upon invocation, it will not be mangled or examined by any function.
.RE

The arguments to the function specified as
.IR callback
are as follows:
.TP
.I "const char *shortvar"
.RS
The
.I shortvar
parameter is the local variable name, provided as a convience.  It is the portion of the variable name after the first "dot" (.) in the fully qualified variable name.  The "dot" (.) value in the fully qualified variable name indicates a section or subsection that the variable belongs to.
This may be
.B NULL
if the
.IR var
parameter to
.BI lc_register_callback (3)
was
.B NULL
too.
.RE
.TP
.I "const char *var"
.RS
The
.I var
parameter is the fully qualified variable name.  It includes in the prefix any sections and subsections that contain this variable.
This may be
.B NULL
if the
.IR var
parameter to
.BI lc_register_callback (3)
was
.B NULL
too.
.RE
.TP
.I "const char *arguments"
.RS
The
.I arguments
parameter provides the arguments passed to the variable, currently only sections may have arguments.
This may be
.B NULL
if there were no arguments specified, or if arguments were not applicable.
.RE
.TP
.I "const char *value"
.RS
The
.I value
parameter provides the value of the variable specified.
This may be
.B NULL
if no value was specified.  Values are required if the
.IR type
parameter to
.BI lc_register_callback (3)
was not specified as one of LC_VAR_NONE, LC_VAR_SECTION, LC_VAR_SECTIONSTART, or LC_VAR_SECTIONEND.
.RE
.TP
.I "lc_flags_t flags"
.RS
The flags parameter provides information about the type of command being called.  The valid values are:
.IP LC_FLAGS_VAR
To indicate a regular variable in a configuration file.
.IP LC_FLAGS_CMDLINE
To indicate a command line option has been used to invoke this option.
.IP LC_FLAGS_SECTIONSTART
To indicate that this command represents the beginning of a section.
.IP LC_FLAGS_SECTIONEND
To indicate that this command represents the end of a section.
.RE
.TP
.I "void *extra"
.RS
The
.I extra
parameter is just a copy of the
.IR extra
parameter passed to
.BI lc_register_callback (3)
when the callback was registered.
.RE

The
.IR callback
function should return one of three values:
.TP
LC_CBRET_IGNORESECTION
Returning LC_CBRET_IGNORESECTION from a callback that begins a section causes the entire section to be ignored without generating an error.
.TP
LC_CBRET_OKAY
Returning LC_CBRET_OKAY from a callback indicates that all went well and further processing may continue.
.TP
LC_CBRET_ERROR
Returnning LC_CBRET_ERROR from a callback indicates that the command failed for some reason, the error will be passed back down the chain back to the
.BI lc_process (3)
call that began processing the configuration data.  If LC_CBRET_ERROR is returned from a callback that begins a section, the entire section is ignored.


 "RETURN VALUE"
On success 0 is returned, otherwise -1 is returned.

.SH EXAMPLE
.nf
#include <libconfig.h>
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>

int callback_ifmodule(const char *shortvar, const char *var,
                      const char *arguments, const char *value,
                      lc_flags_t flags, void *extra) {
	if (flags == LC_FLAGS_SECTIONEND) {
		return(LC_CBRET_OKAY);
	}

	if (flags != LC_FLAGS_SECTIONSTART) {
		fprintf(stderr, "IfModule can only be used as a \\
		        section.\\n");
		return(LC_CBRET_ERROR);
	}
	if (arguments == NULL) {
		fprintf(stderr, "You must specify an argument to \\
		        IfModule.\\n");
		return(LC_CBRET_ERROR);
	}

	printf("IfModule %s\\n", arguments);

	if (strcasecmp(arguments, "MyModule") == 0) {
		return(LC_CBRET_IGNORESECTION);
	}

	return(LC_CBRET_OKAY);
}

int main(int argc, char **argv) {
	int lc_rc_ret = 0, lc_p_ret;

	lc_rc_ret = lc_register_callback("*.IfModule", 0, LC_VAR_NONE,
	                                 callback_ifmodule, NULL);

	if (lc_rc_ret != 0) {
		fprintf(stderr, "Error registering callback.\\n");
		return(EXIT_FAILURE);
	}

	lc_p_ret = lc_process(argc, argv, "example", LC_CONF_APACHE,
	                      NULL);
	if (lc_p_ret != 0) {
		fprintf(stderr, "Error processing configuration: \\
		        %s\\n", lc_geterrstr());
		return(EXIT_FAILURE);
	}

	return(EXIT_SUCCESS);
}
.fi

.SH ERRORS
.TP
.B ENOMEM
Memory could not be allocated to create the needed internal structures.

.SH "SEE ALSO"
.BR lc_register_var (3),
.BR lc_geterrno (3),
.BR lc_geterrstr (3),
.BR lc_process (3),
.BR lc_register_var (3)

Modified libconfig.c from [09c6afb854] to [683ee83d44].

15
16
17
18
19
20
21
















22
23
24
25
26
27
28
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif

















struct lc_varhandler_st *varhandlers = NULL;
lc_err_t lc_errno = LC_ERR_NONE;

static int lc_process_var_string(void *data, const char *value) {
	char **dataval;








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_PWD_H
#include <pwd.h>
#endif

struct lc_varhandler_st *varhandlers = NULL;
lc_err_t lc_errno = LC_ERR_NONE;

static int lc_process_var_string(void *data, const char *value) {
	char **dataval;

415
416
417
418
419
420
421









422
423
424
425
426
427
428
					continue;
				}
			} else if (strcasecmp(handler->var, var) != 0) {
				/* Exact (case-insensitive comparison) failed. */
				continue;
			}
		}










		return(lc_handle(handler, var, varargs, value, flags));
	}

	return(-1);
}








>
>
>
>
>
>
>
>
>







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
					continue;
				}
			} else if (strcasecmp(handler->var, var) != 0) {
				/* Exact (case-insensitive comparison) failed. */
				continue;
			}
		}

		if (value == NULL &&
		    handler->type != LC_VAR_NONE &&
		    handler->type != LC_VAR_SECTION &&
		    handler->type != LC_VAR_SECTIONSTART &&
		    handler->type != LC_VAR_SECTIONEND) {
			lc_errno = LC_ERR_BADFORMAT;
			break;
		}

		return(lc_handle(handler, var, varargs, value, flags));
	}

	return(-1);
}

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509




































































510
511
512
513
514
515
516
	newhandler->_next = varhandlers;

	varhandlers = newhandler;

	return(0);
}

int lc_process(int argc, char **argv, const char *appname, lc_conf_type_t type, const char *extra) {
	int retval = 0, chkretval = 0;

	/* XXX Handle config files.  need to handle this in a loop of config files... */
	switch (type) {
		case LC_CONF_SECTION:
			chkretval = lc_process_conf_section(appname, extra);
			break;
		case LC_CONF_APACHE:
			chkretval = lc_process_conf_apache(appname, extra);
			break;
		case LC_CONF_COLON:
			chkretval = lc_process_conf_colon(appname, extra);
			break;
		case LC_CONF_EQUAL:
			chkretval = lc_process_conf_equal(appname, extra);
			break;
		case LC_CONF_SPACE:
			chkretval = lc_process_conf_space(appname, extra);
			break;
		case LC_CONF_XML:
			chkretval = lc_process_conf_xml(appname, extra);
			break;
		default:
			chkretval = -1;
			lc_errno = LC_ERR_INVDATA;
			break;
	}





































































	if (chkretval < 0) {
		retval = -1;
	}

	/* Handle environment variables.*/
	chkretval = lc_process_environment(appname);
	if (chkretval < 0) {







|
|

<


|


|


|


|


|


|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







499
500
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
	newhandler->_next = varhandlers;

	varhandlers = newhandler;

	return(0);
}

static int lc_process_file(const char *appname, const char *pathname, lc_conf_type_t type) {
	int chkretval = 0;


	switch (type) {
		case LC_CONF_SECTION:
			chkretval = lc_process_conf_section(appname, pathname);
			break;
		case LC_CONF_APACHE:
			chkretval = lc_process_conf_apache(appname, pathname);
			break;
		case LC_CONF_COLON:
			chkretval = lc_process_conf_colon(appname, pathname);
			break;
		case LC_CONF_EQUAL:
			chkretval = lc_process_conf_equal(appname, pathname);
			break;
		case LC_CONF_SPACE:
			chkretval = lc_process_conf_space(appname, pathname);
			break;
		case LC_CONF_XML:
			chkretval = lc_process_conf_xml(appname, pathname);
			break;
		default:
			chkretval = -1;
			lc_errno = LC_ERR_INVDATA;
			break;
	}

	return(chkretval);
}

static int lc_process_files(const char *appname, lc_conf_type_t type, const char *extraconfig) {
	struct passwd *pwinfo = NULL;
	char configfiles[3][13][512] = {{{0}}};
	char *configfile = NULL;
	char *homedir = NULL;
	int configsetidx = 0, configidx = 0;
	int chkretval = 0, retval = 0;

	snprintf(configfiles[0][0], sizeof(**configfiles) - 1, "/etc/%s.cfg", appname);
	snprintf(configfiles[0][1], sizeof(**configfiles) - 1, "/etc/%s.conf", appname);
	snprintf(configfiles[0][2], sizeof(**configfiles) - 1, "/etc/%s/%s.cfg", appname, appname);
	snprintf(configfiles[0][3], sizeof(**configfiles) - 1, "/etc/%s/%s.conf", appname, appname);
	snprintf(configfiles[0][4], sizeof(**configfiles) - 1, "/usr/etc/%s.cfg", appname);
	snprintf(configfiles[0][5], sizeof(**configfiles) - 1, "/usr/etc/%s.conf", appname);
	snprintf(configfiles[0][6], sizeof(**configfiles) - 1, "/usr/etc/%s/%s.cfg", appname, appname);
	snprintf(configfiles[0][7], sizeof(**configfiles) - 1, "/usr/etc/%s/%s.conf", appname, appname);
	snprintf(configfiles[0][8], sizeof(**configfiles) - 1, "/usr/local/etc/%s.cfg", appname);
	snprintf(configfiles[0][9], sizeof(**configfiles) - 1, "/usr/local/etc/%s.conf", appname);
	snprintf(configfiles[0][10], sizeof(**configfiles) - 1, "/usr/local/etc/%s/%s.cfg", appname, appname);
	snprintf(configfiles[0][11], sizeof(**configfiles) - 1, "/usr/local/etc/%s/%s.conf", appname, appname);
	snprintf(configfiles[1][0], sizeof(**configfiles) - 1, "%s", extraconfig);
	if (getuid() != 0) {
		homedir = getenv("HOME");
		if (homedir == NULL) {
			pwinfo = getpwuid(getuid());
			if (pwinfo != NULL) {
				homedir = pwinfo->pw_dir;
			}
		}
		if (homedir != NULL) {
			if (strcmp(homedir, "/") != 0 && access(homedir, R_OK|W_OK|X_OK) == 0) {
				snprintf(configfiles[2][0], sizeof(**configfiles) - 1, "%s/.%src", homedir, appname);
				snprintf(configfiles[2][1], sizeof(**configfiles) - 1, "%s/.%s.cfg", homedir, appname);
				snprintf(configfiles[2][2], sizeof(**configfiles) - 1, "%s/.%s.conf", homedir, appname);
				snprintf(configfiles[2][3], sizeof(**configfiles) - 1, "%s/.%s/%s.cfg", homedir, appname, appname);
				snprintf(configfiles[2][4], sizeof(**configfiles) - 1, "%s/.%s/%s.conf", homedir, appname, appname);
				snprintf(configfiles[2][5], sizeof(**configfiles) - 1, "%s/.%s/config", homedir, appname);
			}
		}
	}

	for (configsetidx = 0; configsetidx < 3; configsetidx++) {
		for (configidx = 0; configidx < 13; configidx++) {
			configfile = configfiles[configsetidx][configidx];
			if (configfile[0] == '\0') {
				break;
			}
			if (access(configfile, R_OK) == 0) {
				chkretval = lc_process_file(appname, configfile, type);
				if (chkretval < 0) {
					retval = -1;
				}
				break;
			}
		}
	}

	return(retval);
}

int lc_process(int argc, char **argv, const char *appname, lc_conf_type_t type, const char *extra) {
	int retval = 0, chkretval = 0;

	/* Handle config files. */
	chkretval = lc_process_files(appname, type, extra);
	if (chkretval < 0) {
		retval = -1;
	}

	/* Handle environment variables.*/
	chkretval = lc_process_environment(appname);
	if (chkretval < 0) {
558
559
560
561
562
563
564



565
566
567
568
569
570
571
572
573
			break;
		case LC_ERR_CANTOPEN:
			retval = "Can't open file.";
			break;
		case LC_ERR_CALLBACK:
			retval = "Error return from application handler.";
			break;



	}

	lc_errno = LC_ERR_NONE;

	if (retval != NULL) {
		return(retval);
	}
	return("Unknown error");
}







>
>
>









650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
			break;
		case LC_ERR_CANTOPEN:
			retval = "Can't open file.";
			break;
		case LC_ERR_CALLBACK:
			retval = "Error return from application handler.";
			break;
		case LC_ERR_ENOMEM:
			retval = "Insuffcient memory.";
			break;
	}

	lc_errno = LC_ERR_NONE;

	if (retval != NULL) {
		return(retval);
	}
	return("Unknown error");
}

Modified libconfig.h.in from [a63e3c406d] to [e6a141a35f].

51
52
53
54
55
56
57

58
59
60
61
62
63
64
        LC_ERR_NONE,
        LC_ERR_INVCMD,
        LC_ERR_INVSECTION,
        LC_ERR_INVDATA,
        LC_ERR_BADFORMAT,
        LC_ERR_CANTOPEN,
        LC_ERR_CALLBACK,

} lc_err_t;

__BLANK_LINE__

int lc_process(int argc, char **argv, const char *appname, lc_conf_type_t type, const char *extra);
int lc_register_callback(const char *var, char opt, lc_var_type_t type, int (*callback)(const char *, const char *, const char *, const char *, lc_flags_t, void *), void *extra);
int lc_register_var(const char *var, lc_var_type_t type, void *data, char opt);







>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
        LC_ERR_NONE,
        LC_ERR_INVCMD,
        LC_ERR_INVSECTION,
        LC_ERR_INVDATA,
        LC_ERR_BADFORMAT,
        LC_ERR_CANTOPEN,
        LC_ERR_CALLBACK,
	LC_ERR_ENOMEM
} lc_err_t;

__BLANK_LINE__

int lc_process(int argc, char **argv, const char *appname, lc_conf_type_t type, const char *extra);
int lc_register_callback(const char *var, char opt, lc_var_type_t type, int (*callback)(const char *, const char *, const char *, const char *, lc_flags_t, void *), void *extra);
int lc_register_var(const char *var, lc_var_type_t type, void *data, char opt);

Modified test-lc.c from [9386f962de] to [8d667bd176].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "compat.h"
#include "libconfig.h"

int help_cmd(const char *partarg, const char *arg, const char *argarg, const char *val, lc_flags_t flags, void *extra) {
	printf("Usage info goes here\n");
	printf("\n");

	exit(EXIT_FAILURE);
}
int sally_cmd(const char *partarg, const char *arg, const char *argarg, const char *val, lc_flags_t flags, void *extra) {
	PRINTERR_D("%s sets value: \"%s\" (flags=%i)", arg, val, flags);
	return(0);
}

int cmd_ifmodule(const char *partarg, const char *arg, const char *argarg, const char *val, lc_flags_t flags, void *extra) {
	if (flags == LC_FLAGS_SECTIONEND) {
		return(LC_CBRET_OKAY);
	}
	if (flags != LC_FLAGS_SECTIONSTART) {
		PRINTERR("IfModule can only be used as a section.");
		return(LC_CBRET_ERROR);
	}
	if (argarg == NULL) {
		PRINTERR("You must specify an argument to IfModule.");
		return(LC_CBRET_ERROR);
	}

	SPOTVAR_S(arg);
	SPOTVAR_S(argarg);
	return(LC_CBRET_IGNORESECTION);
}

int main(int argc, char **argv) {
	char *joeval = NULL;
	long long xval = -1;
	int onoff = -1;










|
















<
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
#include "compat.h"
#include "libconfig.h"

int help_cmd(const char *partarg, const char *arg, const char *argarg, const char *val, lc_flags_t flags, void *extra) {
	printf("Usage info goes here\n");
	printf("\n");

	exit(EXIT_FAILURE);
}
int sally_cmd(const char *partarg, const char *arg, const char *argarg, const char *val, lc_flags_t flags, void *extra) {
	PRINTERR("%s sets value: \"%s\" (flags=%i)", arg, val, flags);
	return(0);
}

int cmd_ifmodule(const char *partarg, const char *arg, const char *argarg, const char *val, lc_flags_t flags, void *extra) {
	if (flags == LC_FLAGS_SECTIONEND) {
		return(LC_CBRET_OKAY);
	}
	if (flags != LC_FLAGS_SECTIONSTART) {
		PRINTERR("IfModule can only be used as a section.");
		return(LC_CBRET_ERROR);
	}
	if (argarg == NULL) {
		PRINTERR("You must specify an argument to IfModule.");
		return(LC_CBRET_ERROR);
	}


	PRINTERR("IfModule (%s)", argarg);
	return(LC_CBRET_IGNORESECTION);
}

int main(int argc, char **argv) {
	char *joeval = NULL;
	long long xval = -1;
	int onoff = -1;