Add functions psl_latest() and psl_dist_filename()

Also add a new ./configure function to set a distribution wide
PSL file used by psl_latest(): --with-psl-distfile
If possible that filename should point to a DAFSA PSL file that
becomes updated regularly.
This commit is contained in:
Tim Rühsen 2016-12-05 14:48:49 +01:00
parent deabd4a546
commit ff29f13d8f
6 changed files with 110 additions and 2 deletions

View File

@ -243,6 +243,11 @@ else
TESTS_INFO="Valgrind testing not enabled"
fi
# Check for distribution-wide PSL file
AC_ARG_WITH(psl-distfile,
AC_HELP_STRING([--with-psl-distfile=[PATH]], [path to distribution-wide PSL file]),
PSL_DISTFILE=$withval AC_SUBST(PSL_DISTFILE))
# Check for custom PSL file
AC_ARG_WITH(psl-file,
AC_HELP_STRING([--with-psl-file=[PATH]], [path to PSL file]),
@ -283,6 +288,7 @@ AC_MSG_NOTICE([Summary of build options:
Libs: ${LIBS}
Runtime: ${enable_runtime}
Builtin: ${enable_builtin}
PSL Dist File: ${PSL_DISTFILE}
PSL File: ${PSL_FILE}
PSL Test File: ${PSL_TESTFILE}
Tests: ${TESTS_INFO}

View File

@ -13,6 +13,7 @@ psl_error_t
psl_ctx_t
psl_load_file
psl_load_fp
psl_latest
psl_builtin
psl_free
psl_is_public_suffix
@ -27,6 +28,7 @@ psl_builtin_sha1sum
psl_builtin_filename
psl_builtin_outdated
psl_is_cookie_domain_acceptable
psl_dist_filename
psl_get_version
psl_check_version_number
psl_str_to_utf8lower

View File

@ -91,6 +91,10 @@ psl_ctx_t *
const psl_ctx_t *
psl_builtin(void);
/* retrieves most recent PSL data */
psl_ctx_t *
psl_latest(const char *fname);
/* checks whether domain is a public suffix or not */
int
psl_is_public_suffix(const psl_ctx_t *psl, const char *domain);
@ -139,6 +143,10 @@ const char *
const char *
psl_builtin_filename(void);
/* returns name of distribution PSL data file */
const char *
psl_dist_filename(void);
/* returns library version string */
const char *
psl_get_version(void);

View File

@ -7,7 +7,7 @@ CLEANFILES = suffixes_dafsa.c
lib_LTLIBRARIES = libpsl.la
libpsl_la_SOURCES = psl.c lookup_string_in_fixed_set.c
libpsl_la_CPPFLAGS = -I$(top_srcdir)/include
libpsl_la_CPPFLAGS = -I$(top_srcdir)/include -DPSL_DISTFILE=\"$(PSL_DISTFILE)\"
# include ABI version information
libpsl_la_LDFLAGS = -version-info $(LIBPSL_SO_VERSION)
if WITH_LIBICU

View File

@ -176,6 +176,12 @@ struct _psl_ctx_st {
static const psl_ctx_t
_builtin_psl;
#ifdef PSL_DISTFILE
static const char _psl_dist_filename[] = PSL_DISTFILE;
#else
static const char _psl_dist_filename[] = "";
#endif
static _psl_vector_t *_vector_alloc(int max, int (*cmp)(const _psl_entry_t **, const _psl_entry_t **))
{
_psl_vector_t *v;
@ -1416,6 +1422,23 @@ int psl_builtin_outdated(void)
return 0;
}
/**
* psl_dist_filename:
*
* This function returns the file name of the distribution/system PSL data file.
* This file will be considered by psl_latest().
*
* Return the filename that is set by ./configure --with-psl-distfile, or an empty string.
*
* Returns: String containing a PSL file name or an empty string.
*
* Since: 0.16
*/
const char *psl_dist_filename(void)
{
return _psl_dist_filename;
}
/**
* psl_get_version:
*
@ -1741,3 +1764,70 @@ out:
return ret;
}
/* if file is newer than the builtin data, insert it reverse sorted by mtime */
static int _insert_file(const char *fname, const char **psl_fname, time_t *psl_mtime, int n)
{
struct stat st;
int it;
if (fname && *fname && stat(fname, &st) == 0 && st.st_mtime > _psl_file_time) {
/* add file name and mtime to end of array */
psl_fname[n] = fname;
psl_mtime[n++] = st.st_mtime;
/* move the new entry to it's correct position */
for (it = n - 2; it >= 0 && st.st_mtime > psl_mtime[it]; it--) {
psl_fname[it + 1] = psl_fname[it];
psl_mtime[it + 1] = psl_mtime[it];
psl_fname[it] = fname;
psl_mtime[it] = st.st_mtime;
}
}
return n;
}
/**
* psl_latest:
* @fname: Name of PSL file or %NULL
*
* This function loads the the latest available PSL data from either
* - @fname (application specific filename, may be %NULL)
* - location specified during built-time (filename from ./configure --with-psl-distfile)
* - built-in PSL data (generated from ./configure --with-psl-file)
* - location of built-in data (filename from ./configure --with-psl-file)
*
* If none of the above is available, the function returns %NULL.
*
* To free the allocated resources, call psl_free().
*
* Returns: Pointer to a PSL context or %NULL on failure.
*
* Since: 0.16
*/
psl_ctx_t *psl_latest(const char *fname)
{
psl_ctx_t *psl;
const char *psl_fname[3];
time_t psl_mtime[3];
int it, ntimes;
psl_fname[0] = NULL; /* silence gcc 6.2 false warning */
/* create array of PSL files reverse sorted by mtime (latest first) */
ntimes = _insert_file(fname, psl_fname, psl_mtime, 0);
ntimes = _insert_file(_psl_filename, psl_fname, psl_mtime, ntimes);
ntimes = _insert_file(_psl_dist_filename, psl_fname, psl_mtime, ntimes);
/* load PSL data from the latest file, falling back to the second recent, ... */
for (psl = NULL, it = 0; it < ntimes; it++) {
if (psl_mtime[it] > _psl_file_time)
if ((psl = psl_load_file(psl_fname[it])))
break;
}
/* if file loading failed or there is no file newer than the builtin data,
* then return the builtin data. */
return psl ? psl : (psl_ctx_t *) psl_builtin();
}

View File

@ -72,7 +72,7 @@ int main(int argc, const char *const *argv)
{
int mode = 1;
const char *const *arg, *psl_file = NULL, *cookie_domain = NULL;
psl_ctx_t *psl = (psl_ctx_t *) psl_builtin();
psl_ctx_t *psl = (psl_ctx_t *) psl_latest(NULL);
/* set current locale according to the environment variables */
#include <locale.h>
@ -197,6 +197,8 @@ int main(int argc, const char *const *argv)
printf("%s: %d\n", *arg, psl_is_cookie_domain_acceptable(psl, *arg, cookie_domain));
}
else if (mode == 99) {
printf("dist filename: %s\n", psl_dist_filename());
if (psl && psl != psl_builtin()) {
printf("suffixes: %d\n", psl_suffix_count(psl));
printf("exceptions: %d\n", psl_suffix_exception_count(psl));