>From b1a788a5ad423e4db960d15d604b8909d2e7155a Mon Sep 17 00:00:00 2001 From: illusionoflife 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 +#include "netrc.h" +#include +#include +#include +#include +#include +#include +#include +#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 +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 +#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 +#include +#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 +#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 +#include +#include +#include +#include +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 -- 1.7.12