]>
git.proxmox.com Git - mirror_frr.git/blob - lib/defaults.c
2 * FRR switchable defaults.
3 * Copyright (c) 2017-2019 David Lamparter, for NetDEF, Inc.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include "lib/version.h"
23 static char df_version
[128] = FRR_VER_SHORT
, df_profile
[128] = DFLT_NAME
;
24 static struct frr_default
*dflt_first
= NULL
, **dflt_next
= &dflt_first
;
26 /* these are global for all FRR daemons. they have to be, since we write an
27 * integrated config with the same value for all daemons.
29 const char *frr_defaults_profiles
[] = {
35 static int version_value(int ch
)
37 /* non-ASCII shouldn't happen */
38 if (ch
< 0 || ch
>= 128)
41 /* ~foo sorts older than nothing */
47 return 0x100 + tolower(ch
);
49 /* punctuation and digits (and everything else) */
53 int frr_version_cmp(const char *aa
, const char *bb
)
55 const char *apos
= aa
, *bpos
= bb
;
57 /* || is correct, we won't scan past the end of a string since that
58 * doesn't compare equal to anything else */
59 while (apos
[0] || bpos
[0]) {
60 if (isdigit((unsigned char)apos
[0]) &&
61 isdigit((unsigned char)bpos
[0])) {
63 char *aend
= NULL
, *bend
= NULL
;
65 av
= strtoul(apos
, &aend
, 10);
66 bv
= strtoul(bpos
, &bend
, 10);
77 int a
= version_value(*apos
++);
78 int b
= version_value(*bpos
++);
88 static void frr_default_apply_one(struct frr_default
*dflt
, bool check
);
90 void frr_default_add(struct frr_default
*dflt
)
94 dflt_next
= &dflt
->next
;
96 frr_default_apply_one(dflt
, true);
99 static bool frr_match_version(const char *name
, const char *vspec
,
100 const char *version
, bool check
)
103 static const struct spec
{
115 const struct spec
*s
;
118 /* NULL = all versions */
121 for (s
= specs
; s
->str
; s
++)
122 if (!strncmp(s
->str
, vspec
, strlen(s
->str
)))
126 fprintf(stderr
, "invalid version specifier for %s: %s",
128 /* invalid version spec, never matches */
132 vspec
+= strlen(s
->str
);
133 while (isspace((unsigned char)*vspec
))
136 cmp
= frr_version_cmp(version
, vspec
);
137 if (cmp
== s
->dir
|| (s
->eq
&& cmp
== 0))
143 static void frr_default_apply_one(struct frr_default
*dflt
, bool check
)
145 struct frr_default_entry
*entry
= dflt
->entries
;
146 struct frr_default_entry
*dfltentry
= NULL
, *saveentry
= NULL
;
148 for (; entry
->match_version
|| entry
->match_profile
; entry
++) {
149 if (entry
->match_profile
150 && strcmp(entry
->match_profile
, df_profile
))
153 if (!dfltentry
&& frr_match_version(dflt
->name
,
154 entry
->match_version
, df_version
, check
))
156 if (!saveentry
&& frr_match_version(dflt
->name
,
157 entry
->match_version
, FRR_VER_SHORT
, check
))
160 if (dfltentry
&& saveentry
&& !check
)
163 /* found default or arrived at last entry that has NULL,NULL spec */
171 *dflt
->dflt_bool
= dfltentry
->val_bool
;
173 *dflt
->dflt_str
= dfltentry
->val_str
;
175 *dflt
->dflt_long
= dfltentry
->val_long
;
176 if (dflt
->dflt_ulong
)
177 *dflt
->dflt_ulong
= dfltentry
->val_ulong
;
178 if (dflt
->dflt_float
)
179 *dflt
->dflt_float
= dfltentry
->val_float
;
181 *dflt
->save_bool
= saveentry
->val_bool
;
183 *dflt
->save_str
= saveentry
->val_str
;
185 *dflt
->save_long
= saveentry
->val_long
;
186 if (dflt
->save_ulong
)
187 *dflt
->save_ulong
= saveentry
->val_ulong
;
188 if (dflt
->save_float
)
189 *dflt
->save_float
= saveentry
->val_float
;
192 void frr_defaults_apply(void)
194 struct frr_default
*dflt
;
196 for (dflt
= dflt_first
; dflt
; dflt
= dflt
->next
)
197 frr_default_apply_one(dflt
, false);
200 bool frr_defaults_profile_valid(const char *profile
)
204 for (p
= frr_defaults_profiles
; *p
; p
++)
205 if (!strcmp(profile
, *p
))
210 const char *frr_defaults_version(void)
215 const char *frr_defaults_profile(void)
220 void frr_defaults_version_set(const char *version
)
222 strlcpy(df_version
, version
, sizeof(df_version
));
223 frr_defaults_apply();
226 void frr_defaults_profile_set(const char *profile
)
228 strlcpy(df_profile
, profile
, sizeof(df_profile
));
229 frr_defaults_apply();