>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