mirror of
https://github.com/ericonr/util-linux.git
synced 2024-04-21 09:12:35 -05:00
Add support for libeconf
This commit is contained in:
parent
eabcbfc449
commit
9e584ff324
27
configure.ac
27
configure.ac
@ -2232,6 +2232,31 @@ AS_IF([test "x$with_smack" = xyes], [
|
|||||||
AC_DEFINE([HAVE_SMACK], [1], [Add SMACK support])
|
AC_DEFINE([HAVE_SMACK], [1], [Add SMACK support])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AC_ARG_WITH([econf],
|
||||||
|
AS_HELP_STRING([--without-econf], [do not use libeconf]),
|
||||||
|
[], [with_econf=check]
|
||||||
|
)
|
||||||
|
|
||||||
|
have_econf=no
|
||||||
|
AS_IF([test "x$with_econf" != xno], [
|
||||||
|
# new version -- all libsystemd-* libs merged into libsystemd
|
||||||
|
PKG_CHECK_MODULES([ECONF], [libeconf], [have_econf=yes], [have_econf=no])
|
||||||
|
AS_CASE([$with_econf:$have_econf],
|
||||||
|
[yes:no],
|
||||||
|
[AC_MSG_ERROR([libeconf expected but libeconf not found])],
|
||||||
|
[*:yes],
|
||||||
|
AC_DEFINE([HAVE_LIBECONF], [1], [Define if libeconf is available])
|
||||||
|
)
|
||||||
|
])
|
||||||
|
AM_CONDITIONAL([HAVE_ECONF], [test "x$have_econf" = xyes])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([vendordir],
|
||||||
|
AS_HELP_STRING([--enable-vendordir=DIR], [Direcotry for istribution provided configuration files]),,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
AC_SUBST([vendordir], [$enable_vendordir])
|
||||||
|
AM_CONDITIONAL([HAVE_VENDORDIR], [test "x$enable_vendordir" != x])
|
||||||
|
|
||||||
|
|
||||||
AC_ARG_WITH([bashcompletiondir],
|
AC_ARG_WITH([bashcompletiondir],
|
||||||
AS_HELP_STRING([--with-bashcompletiondir=DIR], [Bash completions directory]),
|
AS_HELP_STRING([--with-bashcompletiondir=DIR], [Bash completions directory]),
|
||||||
@ -2461,6 +2486,7 @@ AC_MSG_RESULT([
|
|||||||
usrbin_execdir: ${usrbin_execdir}
|
usrbin_execdir: ${usrbin_execdir}
|
||||||
usrsbin_execdir: ${usrsbin_execdir}
|
usrsbin_execdir: ${usrsbin_execdir}
|
||||||
usrlib_execdir: ${usrlib_execdir}
|
usrlib_execdir: ${usrlib_execdir}
|
||||||
|
vendordir: ${enable_vendordir}
|
||||||
|
|
||||||
compiler: ${CC}
|
compiler: ${CC}
|
||||||
cflags: ${CFLAGS}
|
cflags: ${CFLAGS}
|
||||||
@ -2476,6 +2502,7 @@ AC_MSG_RESULT([
|
|||||||
Bash completions: ${with_bashcompletiondir}
|
Bash completions: ${with_bashcompletiondir}
|
||||||
Systemd support: ${have_systemd}
|
Systemd support: ${have_systemd}
|
||||||
Systemd unitdir: ${with_systemdsystemunitdir}
|
Systemd unitdir: ${with_systemdsystemunitdir}
|
||||||
|
libeconf support: ${have_econf}
|
||||||
Btrfs support: ${have_btrfs}
|
Btrfs support: ${have_btrfs}
|
||||||
Wide-char support: ${build_widechar}
|
Wide-char support: ${build_widechar}
|
||||||
|
|
||||||
|
@ -44,6 +44,9 @@ login_SOURCES = \
|
|||||||
login-utils/logindefs.c \
|
login-utils/logindefs.c \
|
||||||
login-utils/logindefs.h
|
login-utils/logindefs.h
|
||||||
login_LDADD = $(LDADD) libcommon.la -lpam
|
login_LDADD = $(LDADD) libcommon.la -lpam
|
||||||
|
if HAVE_VENDORDIR
|
||||||
|
login_CFLAGS = $(AM_CFLAGS) -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
|
||||||
|
endif
|
||||||
if HAVE_LINUXPAM
|
if HAVE_LINUXPAM
|
||||||
login_LDADD += -lpam_misc
|
login_LDADD += -lpam_misc
|
||||||
endif
|
endif
|
||||||
@ -53,6 +56,9 @@ endif
|
|||||||
if HAVE_SELINUX
|
if HAVE_SELINUX
|
||||||
login_LDADD += -lselinux
|
login_LDADD += -lselinux
|
||||||
endif
|
endif
|
||||||
|
if HAVE_ECONF
|
||||||
|
login_LDADD += -leconf
|
||||||
|
endif
|
||||||
endif # BUILD_LOGIN
|
endif # BUILD_LOGIN
|
||||||
|
|
||||||
|
|
||||||
@ -121,8 +127,14 @@ chfn_SOURCES = \
|
|||||||
login-utils/logindefs.h \
|
login-utils/logindefs.h \
|
||||||
$(chfn_chsh_sources)
|
$(chfn_chsh_sources)
|
||||||
chfn_CFLAGS = $(chfn_chsh_cflags)
|
chfn_CFLAGS = $(chfn_chsh_cflags)
|
||||||
|
if HAVE_VENDORDIR
|
||||||
|
chfn_CFLAGS += -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
|
||||||
|
endif
|
||||||
chfn_LDFLAGS = $(chfn_chsh_ldflags)
|
chfn_LDFLAGS = $(chfn_chsh_ldflags)
|
||||||
chfn_LDADD = $(LDADD) $(chfn_chsh_ldadd)
|
chfn_LDADD = $(LDADD) $(chfn_chsh_ldadd)
|
||||||
|
if HAVE_ECONF
|
||||||
|
chfn_LDADD += -leconf
|
||||||
|
endif
|
||||||
|
|
||||||
chsh_SOURCES = login-utils/chsh.c $(chfn_chsh_sources)
|
chsh_SOURCES = login-utils/chsh.c $(chfn_chsh_sources)
|
||||||
chsh_CFLAGS = $(chfn_chsh_cflags)
|
chsh_CFLAGS = $(chfn_chsh_cflags)
|
||||||
@ -141,6 +153,9 @@ su_SOURCES = \
|
|||||||
login-utils/logindefs.c \
|
login-utils/logindefs.c \
|
||||||
login-utils/logindefs.h
|
login-utils/logindefs.h
|
||||||
su_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS)
|
su_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS)
|
||||||
|
if HAVE_VENDORDIR
|
||||||
|
su_CFLAGS += -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
|
||||||
|
endif
|
||||||
su_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
|
su_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
|
||||||
su_LDADD = $(LDADD) libcommon.la -lpam
|
su_LDADD = $(LDADD) libcommon.la -lpam
|
||||||
if HAVE_LINUXPAM
|
if HAVE_LINUXPAM
|
||||||
@ -149,6 +164,9 @@ endif
|
|||||||
if HAVE_UTIL
|
if HAVE_UTIL
|
||||||
su_LDADD += -lutil
|
su_LDADD += -lutil
|
||||||
endif
|
endif
|
||||||
|
if HAVE_ECONF
|
||||||
|
su_LDADD += -leconf
|
||||||
|
endif
|
||||||
endif # BUILD_SU
|
endif # BUILD_SU
|
||||||
|
|
||||||
|
|
||||||
@ -168,6 +186,12 @@ endif
|
|||||||
if HAVE_UTIL
|
if HAVE_UTIL
|
||||||
runuser_LDADD += -lutil
|
runuser_LDADD += -lutil
|
||||||
endif
|
endif
|
||||||
|
if HAVE_ECONF
|
||||||
|
runuser_LDADD += -leconf
|
||||||
|
endif
|
||||||
|
if HAVE_VENDORDIR
|
||||||
|
runuser_CFLAGS = $(AM_CFLAGS) -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
|
||||||
|
endif
|
||||||
endif # BUILD_RUNUSER
|
endif # BUILD_RUNUSER
|
||||||
|
|
||||||
|
|
||||||
@ -192,6 +216,9 @@ lslogins_SOURCES = \
|
|||||||
login-utils/logindefs.h
|
login-utils/logindefs.h
|
||||||
lslogins_LDADD = $(LDADD) libcommon.la libsmartcols.la
|
lslogins_LDADD = $(LDADD) libcommon.la libsmartcols.la
|
||||||
lslogins_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir)
|
lslogins_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir)
|
||||||
|
if HAVE_VENDORDIR
|
||||||
|
lslogins_CFLAGS += -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
|
||||||
|
endif
|
||||||
if HAVE_SELINUX
|
if HAVE_SELINUX
|
||||||
lslogins_LDADD += -lselinux
|
lslogins_LDADD += -lselinux
|
||||||
endif
|
endif
|
||||||
@ -199,6 +226,9 @@ if HAVE_SYSTEMD
|
|||||||
lslogins_LDADD += $(SYSTEMD_LIBS) $(SYSTEMD_JOURNAL_LIBS)
|
lslogins_LDADD += $(SYSTEMD_LIBS) $(SYSTEMD_JOURNAL_LIBS)
|
||||||
lslogins_CFLAGS += $(SYSTEMD_CFLAGS) $(SYSTEMD_JOURNAL_CFLAGS)
|
lslogins_CFLAGS += $(SYSTEMD_CFLAGS) $(SYSTEMD_JOURNAL_CFLAGS)
|
||||||
endif
|
endif
|
||||||
|
if HAVE_ECONF
|
||||||
|
lslogins_LDADD += -leconf
|
||||||
|
endif
|
||||||
endif # BUILD_LSLOGINS
|
endif # BUILD_LSLOGINS
|
||||||
|
|
||||||
if BUILD_VIPW
|
if BUILD_VIPW
|
||||||
@ -231,6 +261,12 @@ test_logindefs_SOURCES = \
|
|||||||
login-utils/logindefs.c \
|
login-utils/logindefs.c \
|
||||||
login-utils/logindefs.h
|
login-utils/logindefs.h
|
||||||
test_logindefs_CPPFLAGS = -DTEST_PROGRAM $(AM_CPPFLAGS)
|
test_logindefs_CPPFLAGS = -DTEST_PROGRAM $(AM_CPPFLAGS)
|
||||||
|
if HAVE_VENDORDIR
|
||||||
|
test_logindefs_CPPFLAGS += -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
|
||||||
|
endif
|
||||||
|
if HAVE_ECONF
|
||||||
|
test_logindefs_LDADD = -leconf
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
install-exec-hook:
|
install-exec-hook:
|
||||||
|
@ -38,6 +38,18 @@
|
|||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void (*logindefs_loader)(void *) = NULL;
|
||||||
|
static void *logindefs_loader_data = NULL;
|
||||||
|
|
||||||
|
void logindefs_set_loader(void (*loader)(void *data), void *data)
|
||||||
|
{
|
||||||
|
logindefs_loader = loader;
|
||||||
|
logindefs_loader_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_LIBECONF
|
||||||
|
|
||||||
struct item {
|
struct item {
|
||||||
char *name; /* name of the option. */
|
char *name; /* name of the option. */
|
||||||
char *value; /* value of the option. */
|
char *value; /* value of the option. */
|
||||||
@ -48,9 +60,6 @@ struct item {
|
|||||||
|
|
||||||
static struct item *list = NULL;
|
static struct item *list = NULL;
|
||||||
|
|
||||||
static void (*logindefs_loader)(void *) = NULL;
|
|
||||||
static void *logindefs_loader_data = NULL;
|
|
||||||
|
|
||||||
void free_getlogindefs_data(void)
|
void free_getlogindefs_data(void)
|
||||||
{
|
{
|
||||||
struct item *ptr;
|
struct item *ptr;
|
||||||
@ -145,12 +154,6 @@ void logindefs_load_file(const char *filename)
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logindefs_set_loader(void (*loader)(void *data), void *data)
|
|
||||||
{
|
|
||||||
logindefs_loader = loader;
|
|
||||||
logindefs_loader_data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void load_defaults(void)
|
static void load_defaults(void)
|
||||||
{
|
{
|
||||||
if (logindefs_loader)
|
if (logindefs_loader)
|
||||||
@ -232,6 +235,156 @@ const char *getlogindefs_str(const char *name, const char *dflt)
|
|||||||
return ptr->value;
|
return ptr->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <libeconf.h>
|
||||||
|
|
||||||
|
static econf_file *file = NULL;
|
||||||
|
|
||||||
|
void free_getlogindefs_data(void)
|
||||||
|
{
|
||||||
|
econf_free (file);
|
||||||
|
file = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef VENDORDIR
|
||||||
|
#define VENDORDIR NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void load_defaults(void)
|
||||||
|
{
|
||||||
|
econf_err error;
|
||||||
|
|
||||||
|
if (file != NULL)
|
||||||
|
free_getlogindefs_data();
|
||||||
|
|
||||||
|
if ((error = econf_readDirs(&file, VENDORDIR, "/etc",
|
||||||
|
"login", "defs", "= \t", "#")))
|
||||||
|
syslog(LOG_NOTICE, _("Error reading login.defs: %s"),
|
||||||
|
econf_errString(error));
|
||||||
|
|
||||||
|
if (logindefs_loader)
|
||||||
|
logindefs_loader(logindefs_loader_data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void logindefs_load_file(const char *filename)
|
||||||
|
{
|
||||||
|
econf_file *file_l, *file_m;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
logindefs_loader = NULL; /* No recursion */
|
||||||
|
|
||||||
|
#if HAVE_VENDORDIR
|
||||||
|
if (asprintf (&path, VENDORDIR"/%s", filename) == -1)
|
||||||
|
return;
|
||||||
|
if (!econf_readFile(&file_l, path, "= \t", "#")) {
|
||||||
|
if (file == NULL)
|
||||||
|
file = file_l;
|
||||||
|
else if (!econf_mergeFiles(&file_m, file, file_l)) {
|
||||||
|
econf_free(file);
|
||||||
|
file = file_m;
|
||||||
|
econf_free(file_l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free (path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (asprintf (&path, "/etc/%s", filename) == -1)
|
||||||
|
return;
|
||||||
|
if (!econf_readFile(&file_l, path, "= \t", "#")) {
|
||||||
|
if (file == NULL)
|
||||||
|
file = file_l;
|
||||||
|
else if (!econf_mergeFiles(&file_m, file, file_l)) {
|
||||||
|
econf_free(file);
|
||||||
|
file = file_m;
|
||||||
|
econf_free(file_l);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Try original filename, could be relative */
|
||||||
|
if (!econf_readFile(&file_l, filename, "= \t", "#")) {
|
||||||
|
if (file == NULL)
|
||||||
|
file = file_l;
|
||||||
|
else if (!econf_mergeFiles(&file_m, file, file_l)) {
|
||||||
|
econf_free(file);
|
||||||
|
file = file_m;
|
||||||
|
econf_free(file_l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getlogindefs_bool(const char *name, int dflt)
|
||||||
|
{
|
||||||
|
bool value;
|
||||||
|
econf_err error;
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
load_defaults();
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
return dflt;
|
||||||
|
|
||||||
|
if ((error = econf_getBoolValue(file, NULL, name, &value))) {
|
||||||
|
if (error != ECONF_NOKEY)
|
||||||
|
syslog(LOG_NOTICE, _("couldn't fetch %s: %s"), name,
|
||||||
|
econf_errString(error));
|
||||||
|
return dflt;
|
||||||
|
}
|
||||||
|
if (value == true)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long getlogindefs_num(const char *name, unsigned long dflt)
|
||||||
|
{
|
||||||
|
unsigned long value;
|
||||||
|
econf_err error;
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
load_defaults();
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
return dflt;
|
||||||
|
|
||||||
|
if ((error = econf_getUInt64Value(file, NULL, name, &value))) {
|
||||||
|
if (error != ECONF_NOKEY)
|
||||||
|
syslog(LOG_NOTICE, _("couldn't fetch %s: %s"), name,
|
||||||
|
econf_errString(error));
|
||||||
|
return dflt;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* @dflt if @name not found
|
||||||
|
* "" (empty string) if found, but value not defined
|
||||||
|
* "string" if found
|
||||||
|
*/
|
||||||
|
const char *getlogindefs_str(const char *name, const char *dflt)
|
||||||
|
{
|
||||||
|
char *value;
|
||||||
|
econf_err error;
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
load_defaults();
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
return dflt;
|
||||||
|
|
||||||
|
if ((error = econf_getStringValue(file, NULL, name, &value))) {
|
||||||
|
if (error != ECONF_NOKEY)
|
||||||
|
syslog(LOG_NOTICE, _("couldn't fetch %s: %s"), name,
|
||||||
|
econf_errString(error));
|
||||||
|
return dflt;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_LIBECONF */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For compatibility with shadow-utils we have to support additional
|
* For compatibility with shadow-utils we have to support additional
|
||||||
* syntax for environment variables in login.defs(5) file. The standard
|
* syntax for environment variables in login.defs(5) file. The standard
|
||||||
@ -283,7 +436,6 @@ int effective_access(const char *path, int mode)
|
|||||||
return fd == -1 ? -1 : 0;
|
return fd == -1 ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the per-account or the global hush-login setting.
|
* Check the per-account or the global hush-login setting.
|
||||||
*
|
*
|
||||||
@ -412,12 +564,33 @@ int main(int argc, char *argv[])
|
|||||||
logindefs_load_file(argv[1]);
|
logindefs_load_file(argv[1]);
|
||||||
|
|
||||||
if (argc != 4) { /* list all */
|
if (argc != 4) { /* list all */
|
||||||
|
#ifdef HAVE_LIBECONF
|
||||||
|
econf_err error;
|
||||||
|
size_t key_number;
|
||||||
|
char **keys;
|
||||||
|
|
||||||
|
if ((error = econf_getKeys(file, NULL, &key_number, &keys)))
|
||||||
|
errx(EXIT_FAILURE, "Couldn't list all keys: %s",
|
||||||
|
econf_errString(error));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < key_number; i++) {
|
||||||
|
char *value = NULL;
|
||||||
|
|
||||||
|
econf_getStringValue(file, NULL, keys[i], &value);
|
||||||
|
printf ("%s: $%s: '%s'\n", "logindefs.data",
|
||||||
|
keys[i], value);
|
||||||
|
}
|
||||||
|
|
||||||
|
econf_free (keys);
|
||||||
|
econf_free (file);
|
||||||
|
|
||||||
|
#else
|
||||||
struct item *ptr;
|
struct item *ptr;
|
||||||
|
|
||||||
for (ptr = list; ptr; ptr = ptr->next)
|
for (ptr = list; ptr; ptr = ptr->next)
|
||||||
printf("%s: $%s: '%s'\n", ptr->path, ptr->name,
|
printf("%s: $%s: '%s'\n", ptr->path, ptr->name,
|
||||||
ptr->value);
|
ptr->value);
|
||||||
|
#endif
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,8 +90,13 @@ UL_DEBUG_DEFINE_MASKNAMES(su) = UL_DEBUG_EMPTY_MASKNAMES;
|
|||||||
#define PAM_SRVNAME_RUNUSER "runuser"
|
#define PAM_SRVNAME_RUNUSER "runuser"
|
||||||
#define PAM_SRVNAME_RUNUSER_L "runuser-l"
|
#define PAM_SRVNAME_RUNUSER_L "runuser-l"
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBECONF
|
||||||
|
#define _PATH_LOGINDEFS_SU "default/su"
|
||||||
|
#define _PATH_LOGINDEFS_RUNUSER "default/runuser"
|
||||||
|
#else
|
||||||
#define _PATH_LOGINDEFS_SU "/etc/default/su"
|
#define _PATH_LOGINDEFS_SU "/etc/default/su"
|
||||||
#define _PATH_LOGINDEFS_RUNUSER "/etc/default/runuser"
|
#define _PATH_LOGINDEFS_RUNUSER "/etc/default/runuser"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define is_pam_failure(_rc) ((_rc) != PAM_SUCCESS)
|
#define is_pam_failure(_rc) ((_rc) != PAM_SUCCESS)
|
||||||
|
|
||||||
@ -1231,7 +1236,9 @@ static void load_config(void *data)
|
|||||||
struct su_context *su = (struct su_context *) data;
|
struct su_context *su = (struct su_context *) data;
|
||||||
|
|
||||||
DBG(MISC, ul_debug("loading logindefs"));
|
DBG(MISC, ul_debug("loading logindefs"));
|
||||||
|
#ifndef HAVE_LIBECONF
|
||||||
logindefs_load_file(_PATH_LOGINDEFS);
|
logindefs_load_file(_PATH_LOGINDEFS);
|
||||||
|
#endif
|
||||||
logindefs_load_file(su->runuser ? _PATH_LOGINDEFS_RUNUSER : _PATH_LOGINDEFS_SU);
|
logindefs_load_file(su->runuser ? _PATH_LOGINDEFS_RUNUSER : _PATH_LOGINDEFS_SU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user