good work, but it seems you haven't copyright assignment to the FSF for wget, I will send you a separate email.
Cheers, Giuseppe illusionoflife <[email protected]> writes: > Hello again. Sorry, was short on time, and it tooked me time to > learn flex and bison. > > So, this is beta version of patch, that reimplement netrc parsing and cleanup > some utility functions. All kind of constructive critic are welcome. I am not > finished with tests and integration, but to give community idea. I would like > to acent attention on `auth_free` function. Why gl_list operates on const > pointers? I already asked on gnulib list. I did my best to make code clean > and > simple, no-more, then 20 lines function, but probably I missed portability > issues. > -- > Best regards, illusionoflife. > This mail is for mailing lists. > For private, responce-warrantied > mail use [email protected]. > > > > From b1a788a5ad423e4db960d15d604b8909d2e7155a Mon Sep 17 00:00:00 2001 > From: illusionoflife <[email protected]> > Date: Mon, 24 Sep 2012 16:25:56 +0400 > Subject: [PATCH] Rewrite netrc code. Implement libwget. > > Implement netrc parsing via flex/bison. Moved `home_dir` > function to libwget, cleaned up code. > Not integrated in yet. > --- > Makefile.am | 2 +- > bootstrap | 8 ++-- > check/Makefile.am | 3 ++ > check/check_netrc.c | 4 ++ > check/netrc-1.sh | 2 + > check/netrc-2.sh | 2 + > configure.ac | 14 +++--- > libwget/Makefile.am | 8 ++++ > libwget/netrc.c | 115 > +++++++++++++++++++++++++++++++++++++++++++++++ > libwget/netrc.h | 12 +++++ > libwget/netrc_grammar.y | 67 +++++++++++++++++++++++++++ > libwget/netrc_tokenize.l | 43 ++++++++++++++++++ > libwget/utility.c | 64 ++++++++++++++++++++++++++ > libwget/utility.h | 6 +++ > 14 files changed, 338 insertions(+), 12 deletions(-) > create mode 100644 check/Makefile.am > create mode 100644 check/check_netrc.c > create mode 100755 check/netrc-1.sh > create mode 100755 check/netrc-2.sh > create mode 100644 libwget/Makefile.am > create mode 100644 libwget/netrc.c > create mode 100644 libwget/netrc.h > create mode 100644 libwget/netrc_grammar.y > create mode 100644 libwget/netrc_tokenize.l > create mode 100644 libwget/utility.c > create mode 100644 libwget/utility.h > mode change 100644 => 100755 tests/Test-auth-retcode.px > > diff --git a/Makefile.am b/Makefile.am > index 7a500ba..f21edaf 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -41,7 +41,7 @@ distuninstallcheck_listfiles = find . -type f | \ > ACLOCAL_AMFLAGS = -I m4 > > # subdirectories in the distribution > -SUBDIRS = lib src doc po tests util > +SUBDIRS = lib libwget src doc po tests check util > > EXTRA_DIST = ChangeLog.README MAILING-LIST \ > msdos/ChangeLog msdos/config.h msdos/Makefile.DJ \ > diff --git a/bootstrap b/bootstrap > index e3e270b..0d409dc 100755 > --- a/bootstrap > +++ b/bootstrap > @@ -109,9 +109,6 @@ die() { warn_ "$@"; exit 1; } > # Name of the Makefile.am > gnulib_mk=gnulib.mk > > -# List of gnulib modules needed. > -gnulib_modules= > - > # Any gnulib files needed that are not in modules. > gnulib_files= > > @@ -845,7 +842,8 @@ if test $with_gettext = yes || test $use_libtool = 1; then > rm -f $tempbase.0 $tempbase.1 > trap - 1 2 13 15 > fi > - > +# List of gnulib modules needed. > +gnulib_modules+="list xlist array-list" > # Import from gnulib. > > gnulib_tool_options="\ > @@ -866,7 +864,7 @@ if test $use_libtool = 1; then > *) gnulib_tool_options="$gnulib_tool_options --libtool" ;; > esac > fi > -echo "$0: $gnulib_tool $gnulib_tool_options --import ..." > +echo "$0: $gnulib_tool $gnulib_tool_options --import ... $gnulib_modules" > $gnulib_tool $gnulib_tool_options --import $gnulib_modules && > > for file in $gnulib_files; do > diff --git a/check/Makefile.am b/check/Makefile.am > new file mode 100644 > index 0000000..faa6eef > --- /dev/null > +++ b/check/Makefile.am > @@ -0,0 +1,3 @@ > +check_PROGRAMS = check_netrc > +TESTS= > +TESTS += netrc-1.sh netrc-2.sh > diff --git a/check/check_netrc.c b/check/check_netrc.c > new file mode 100644 > index 0000000..ed4563e > --- /dev/null > +++ b/check/check_netrc.c > @@ -0,0 +1,4 @@ > +int main(int argc, char **argv) > +{ > + return 0; > +} > diff --git a/check/netrc-1.sh b/check/netrc-1.sh > new file mode 100755 > index 0000000..20d602b > --- /dev/null > +++ b/check/netrc-1.sh > @@ -0,0 +1,2 @@ > +#!/usr/bin/env bash > + > diff --git a/check/netrc-2.sh b/check/netrc-2.sh > new file mode 100755 > index 0000000..20d602b > --- /dev/null > +++ b/check/netrc-2.sh > @@ -0,0 +1,2 @@ > +#!/usr/bin/env bash > + > diff --git a/configure.ac b/configure.ac > index 873c3c9..c227e34 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -49,7 +49,6 @@ dnl > dnl Automake setup > dnl > AM_INIT_AUTOMAKE([1.9]) > - > dnl > dnl Get cannonical host > dnl > @@ -102,6 +101,8 @@ AC_PROG_CC > AM_PROG_CC_C_O > AC_AIX > > +AM_PROG_LEX > +AC_PROG_YACC > gl_EARLY > > dnl > @@ -192,7 +193,8 @@ AC_CHECK_TYPES(sig_atomic_t, [], [], [ > > # gnulib > gl_INIT > - > +gl_XALLOC > +dnl gl_LIST > dnl > dnl Checks for library functions. > dnl > @@ -257,7 +259,7 @@ AS_IF([test x"$with_ssl" = xopenssl], [ > case $host_os in > *mingw32* ) > dnl prefer link to openssl dlls if possible. if not then fallback on > static libs. if not then error > - > + > AC_CHECK_LIB(eay32, EVP_MD_CTX_init) > if test x"$ac_cv_lib_eay32_EVP_MD_CTX_init" != xno > then > @@ -269,7 +271,7 @@ AS_IF([test x"$with_ssl" = xopenssl], [ > AC_DEFINE([HAVE_LIBSSL32], [1], [Define to 1 if you have the > `ssl32' library (-lssl32).]) > ], > AC_MSG_ERROR([openssl not found: shared lib eay32 found but ssl32 > not found])) > - > + > else > LIBS+=' -lgdi32' > dnl fallback and test static libs > @@ -544,7 +546,7 @@ AC_CHECK_HEADER(pcre.h, > ]) > ) > > - > + > dnl Needed by src/Makefile.am > AM_CONDITIONAL([IRI_IS_ENABLED], [test "X$iri" != "Xno"]) > > @@ -554,6 +556,6 @@ dnl Create output > dnl > AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile util/Makefile > po/Makefile.in tests/Makefile tests/WgetTest.pm > - lib/Makefile]) > + lib/Makefile libwget/Makefile check/Makefile]) > AC_CONFIG_HEADERS([src/config.h]) > AC_OUTPUT > diff --git a/libwget/Makefile.am b/libwget/Makefile.am > new file mode 100644 > index 0000000..a9a5202 > --- /dev/null > +++ b/libwget/Makefile.am > @@ -0,0 +1,8 @@ > +AM_YFLAGS = -d -pnetrc_yy > +AM_LFLAGS = -o lex.yy.c -Pnetrc_yy > +AM_CFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir) > + > + > +lib_LIBRARIES = libwget.a > +libwget_a_SOURCES = netrc_grammar.y netrc_tokenize.l netrc.c utility.h > utility.c > +libwget_a_LIBADD= $(top_builddir)/lib/libgnu.a > diff --git a/libwget/netrc.c b/libwget/netrc.c > new file mode 100644 > index 0000000..7f68a3e > --- /dev/null > +++ b/libwget/netrc.c > @@ -0,0 +1,115 @@ > +#include <config.h> > +#include "netrc.h" > +#include <assert.h> > +#include <stdio.h> > +#include <string.h> > +#include <stdlib.h> > +#include <gl_xlist.h> > +#include <gl_array_list.h> > +#include <libwget/utility.h> > +#include "netrc_grammar.h" > + > +#define NETRC_DEFAULT_FILENAME ".netrc" > +extern FILE *netrc_yyin; > +typedef struct netrc_info { > +} netrc_info; > + > +static inline void > +auth_strassign (const struct auth *src, const char **login, const char **pwd) > +{ > + *login = src->login; > + *pwd = src->pwd; > +} > + > +static inline void > +auth_free(const void *ptr) > +{ > + struct auth *ath = (struct auth *) ptr; > + > + free(ath->login); > + free(ath->pwd); > + free(ath->host); > + free(ath); > +} > +#if defined __VMS > +/* Simplicity over perfomance */ > +static char * > +netrc_default_filepath(void) > +{ > + return xstrdup("SYS$LOGIN:.netrc" NETRC_DEFAULT_FILENAME); > +} > +#else > +static char * > +netrc_default_filepath(void) > +{ > + char *home = home_dir(); > + char *path = xzalloc(strlen(home)+1+strlen(NETRC_DEFAULT_FILENAME)+1); > + sprintf(path, "%s/%s", home, NETRC_DEFAULT_FILENAME); > + free(home); > +} > +#endif > + > +netrc_info* > +netrc_parse_default() > +{ > + char *path = netrc_default_filepath(); > + netrc_info *info = netrc_parse(path); > + free(path); > + return info; > +} > + > +netrc_info * > +netrc_parse(const char *path) > +{ > + gl_list_t list = gl_list_create_empty(GL_ARRAY_LIST, > + NULL, NULL, auth_free, true); > + > + if (path) { > + netrc_yyin = fopen(path, "r"); > + if (netrc_yyin) > + { > + netrc_yyparse(list); > + fclose(netrc_yyin); > + } > + } > + /* gl_list_t is actually pointer, so I can do this */ > + return (netrc_info *) list; > +} > + > +void > +netrc_search(const netrc_info *info, const char *host, > + const char **login, const char **pwd, bool use_default) > +{ > + gl_list_t list = (gl_list_t) info; > + gl_list_iterator_t it = gl_list_iterator(list); > + const void *current_voidptr; > + > + *login = *pwd = NULL; > + while (gl_list_iterator_next (&it, ¤t_voidptr, NULL)) > + { > + const struct auth *current = current_voidptr; > + if (current->host) { > + if (!strcmp(current->host, host)) { > + auth_strassign(current, login, pwd); > + break; > + } > + } else { /* current->host == NULL */ > + if (use_default) /* No break, because default is only one and last */ > + auth_strassign(current, login, pwd); > + } > + } > + gl_list_iterator_free(&it); > +} > + > +void > +netrc_free(netrc_info *info) > +{ > + gl_list_t list = (gl_list_t) info; > + > + gl_list_free(list); > +} > + > +int main() > +{ > + return 0; > +} > diff --git a/libwget/netrc.h b/libwget/netrc.h > new file mode 100644 > index 0000000..49a7ae8 > --- /dev/null > +++ b/libwget/netrc.h > @@ -0,0 +1,12 @@ > +#ifndef NETRC_H > +#define NETRC_H > +#include <stdbool.h> > +typedef struct netrc_info netrc_info; > +netrc_info* netrc_parse(const char *path); > +netrc_info* netrc_parse_default(); > +void netrc_search(const netrc_info *info, const char *host, const char > **login, > + const char **pwd, bool use_default); > +void netrc_free(netrc_info *); > + > + > +#endif > diff --git a/libwget/netrc_grammar.y b/libwget/netrc_grammar.y > new file mode 100644 > index 0000000..7abe5eb > --- /dev/null > +++ b/libwget/netrc_grammar.y > @@ -0,0 +1,67 @@ > + /* Into generated header */ > +%code requires { > +#include <config.h> > +#define YYSTYPE char * > +#include "gl_xlist.h" > +#include "xalloc.h" > + > +/* Last `auth' in list with host=NULL is > + * default account */ > +struct auth { > + char *host; > + char *login; > + char *pwd; > +}; > +} > + /* To the top of C file */ > +%code top { > +#include <stdio.h> > +#include <string.h> > +#include "netrc_grammar.h" > +} > + > +%code { > +static void > +netrc_yyerror(gl_list_t parsearg, char const *s) > +{ > + puts("Warning: incorrect netrc file. Made best efford"); > +} > +static struct auth* > +auth_xalloc(char *host, char *login, char *pwd) > +{ > + struct auth *ath = xmalloc(sizeof(struct auth)); > + > + ath->host = host; > + ath->login = login; > + ath->pwd = pwd; > + > + return ath; > +} > +int > +netrc_yywrap() > +{ > + return 1; > +} > +} > + > +%parse-param{gl_list_t list} > +%token TOKMACHINE TOKLOGIN TOKPASSWORD TOKVALUE TOKDEFAULT TOKMACDEF > +%% > +input: auths macdefs > +auths: /* empty */ | auth auths | authdefault > +macdefs: /* empty */| macdef macdefs > +values: TOKVALUE| TOKVALUE values > +macdef: TOKMACDEF values > + > +authdefault: TOKDEFAULT TOKLOGIN TOKVALUE > + TOKPASSWORD TOKVALUE > +{ > + gl_list_add_last(list, auth_xalloc(NULL, $3, $5)); > +} > + > +auth: TOKMACHINE TOKVALUE > + TOKLOGIN TOKVALUE > + TOKPASSWORD TOKVALUE > +{ > + gl_list_add_last(list, auth_xalloc($2, $4, $6)); > +}; > diff --git a/libwget/netrc_tokenize.l b/libwget/netrc_tokenize.l > new file mode 100644 > index 0000000..796feb3 > --- /dev/null > +++ b/libwget/netrc_tokenize.l > @@ -0,0 +1,43 @@ > +%{ > +#include <config.h> > +#include "netrc_grammar.h" > +#include "xalloc.h" > +#include "assert.h" > +/* @str have at least opening and closing quote */ > +static char * > +strdup_unescaped (const char *str) > +{ > + unsigned int len = strlen (str); > + unsigned int index; > + unsigned int res_index = 0; > + char *res = xmalloc (len - 1); /* Little memory overhead from simplity > */ > + char q = str[0]; > + assert(len >= 2); > + /* Exclude quotes -- last and first symbol */ > + for (index = 1; index < len - 1; ++index) > + { > + /* Skip backslash, that escapes quote or another backslash */ > + if (str[index] == '\\' && > + (str[index + 1] == q || str[index + 1] == '\\')) > + index++; > + res[res_index++] = str[index]; > + } > + res[res_index] = '\0'; > + return res; > +} > + > +%} > +qstring \"(\\.|[^\\"])*\" > +astring \'(\\.|[^\\'])*\' > +bstring [[:alpha:][:punct:][:digit:]]+ > +string {qstring}|{astring} > +%% > +machine return TOKMACHINE; > +login return TOKLOGIN; > +password return TOKPASSWORD; > +default return TOKDEFAULT; > +macdef return TOKMACDEF; > +{string} {netrc_yylval = xstrdup_unescaped(netrc_yytext); return > TOKVALUE;} > +{bstring} {netrc_yylval = xstrdup(netrc_yytext); return TOKVALUE;} > +. > +%% > diff --git a/libwget/utility.c b/libwget/utility.c > new file mode 100644 > index 0000000..aaab272 > --- /dev/null > +++ b/libwget/utility.c > @@ -0,0 +1,64 @@ > +#include "utility.h" > +#include <config.h> > +#include <assert.h> > +#include <xalloc.h> > +#include <stdlib.h> > +#include <pwd.h> > +static char get_separator(const char *path) > +{ > + const char *p = path; > + > + while (p) { > + if (*p == '/') /* djgpp */ > + return '/'; > + else if (*p == '\\') /* others */ > + return '\\'; > + p++; > + } > + assert(0 && "No separator found"); > +} > + > +#if defined (MSDOS) > +extern const char *_w32_get_argv0 (void); /* in libwatt.a/pcconfig.c */ > +/* Under MSDOS, if $HOME isn't defined, use the directory where > + `wget.exe' resides. */ > +static char * > +noenv_homedir(void) > +{ > + const char *argv0 = _w32_get_argv0 (); > + const char *last_sep; > + char *home; > + > + last_sep = strrchr(argv0, get_separator(argv0)); > + home = strndup(last_sep - argv0); > + > + return home; > +} > +#elseif defined(WINDOWS) > +extern char* ws_mypath(void); > +static char * > +noenv_homedir(void) > +{ > + return xstrdup(ws_mypath()); > +} > +#else /* POSIX-like */ > +static char* > +noenv_homedir(void) > +{ > + const struct passwd *pwd = getpwuid (getuid ()); > + if (pwd && pwd->pw_dir) > + return xstrdup(pwd->pw_dir); > + else > + return NULL; > +} > +#endif /*noenv_homedir */ > + > +char * > +home_dir (void) > +{ > + char *home; > + if (home = getenv ("HOME")) > + return xstrdup(home); > + else > + return noenv_homedir(); > +} > diff --git a/libwget/utility.h b/libwget/utility.h > new file mode 100644 > index 0000000..cdd71f9 > --- /dev/null > +++ b/libwget/utility.h > @@ -0,0 +1,6 @@ > +#ifndef UTILITY_H > +#define UTILITY_H > + > +char *home_dir(void); > + > +#endif > diff --git a/tests/Test-auth-retcode.px b/tests/Test-auth-retcode.px > old mode 100644 > new mode 100755
