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, &current_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
-- 
1.7.12

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to