File 0002-Add-content-of-lftp-compat-addfiles.patch.patch of Package lftp.10482

From 2b248a384b5489f26c0d920316e20a15a75c678f Mon Sep 17 00:00:00 2001
From: =?utf8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= <tomas.chvatal@gmail.com>
Date: Wed, 28 Feb 2018 19:08:24 +0100
Subject: [PATCH 2/5] Add content of lftp-compat-addfiles.patch

---
 src/CompatMode.cc  |  238 +++++++++++
 src/CompatMode.h   |   28 ++
 src/lftp-wrapper.c | 1177 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1443 insertions(+)
 create mode 100644 src/CompatMode.cc
 create mode 100644 src/CompatMode.h
 create mode 100644 src/lftp-wrapper.c

diff --git a/src/CompatMode.cc b/src/CompatMode.cc
new file mode 100644
index 00000000..718de974
--- /dev/null
+++ b/src/CompatMode.cc
@@ -0,0 +1,238 @@
+/*
+ * compat mode for lftp
+ *
+ * Copyright (c) 2005 by Petr Ostadal (postadal@suse.cz)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <assert.h>
+#include <pwd.h>
+#include "MirrorJob.h"
+#include "CmdExec.h"
+#include "rmJob.h"
+#include "mkdirJob.h"
+#include "ChmodJob.h"
+#include "misc.h"
+#include "plural.h"
+#include "getopt.h"
+#include "FindJob.h"
+#include "url.h"
+#include "CopyJob.h"
+#include "pgetJob.h"
+
+#include "modconfig.h"
+
+#include <fcntl.h>
+#include <termios.h>
+
+#include "xmalloc.h"
+#include "GetPass.h"
+#include "CharReader.h"
+#include "SignalHook.h"
+#include "Job.h"
+
+
+int ascii_mode;
+
+char* GetText(const char *prompt) {
+   static char *oldtext=0;
+   static int tty_fd=-2;
+   static FILE *f=0;
+
+   xfree(oldtext);
+   oldtext=0;
+
+   if(tty_fd==-2)
+   {
+      if(isatty(0))
+	 tty_fd=0;
+      else
+      {
+	 tty_fd=open("/dev/tty",O_RDONLY);
+   	 if(tty_fd!=-1)
+	    fcntl(tty_fd,F_SETFD,FD_CLOEXEC);
+      }
+   }
+   if(tty_fd==-1)
+      return 0;
+
+   if(f==0)
+      f=fdopen(tty_fd,"r");
+   if(f==0)
+      return 0;
+
+   write(tty_fd,prompt,strlen(prompt));
+   oldtext=readline_from_file(fileno(f));
+   return oldtext;
+}
+
+CMD(ascii)
+{
+    ascii_mode = 1;
+    return NULL;
+}
+
+CMD(bin)
+{
+    ascii_mode = 0;
+    return NULL;
+}
+
+CMD(type) 
+{
+    if (parent->args->count() == 2) {
+        if (strcmp(parent->args->getarg(1), "binary") == 0)
+            ascii_mode = 0;
+        else if (strcmp(parent->args->getarg(1), "ascii") == 0)
+            ascii_mode = 1;
+        else
+            parent->eprintf(_("Try `help %s' for more information.\n"), parent->args->a0());
+    } else if (parent->args->count() == 1) {
+        if (ascii_mode)
+            parent->printf("Using ascii mode to transfer files.\n");
+        else
+            parent->printf("Using binary mode to transfer files.\n");
+    }
+    else
+        parent->eprintf(_("Try `help %s' for more information.\n"), parent->args->a0());
+    return NULL;
+}
+
+CMD(user);
+
+CMD(compat_user)
+{
+    char *user;
+
+    if(parent->args->count() == 1) {
+        user = GetText("(username) ");
+        
+        if (!user || strlen(user) == 0) {
+            parent->eprintf(_("Try `help %s' for more information.\n"), parent->args->a0());
+            return NULL;
+        }
+        user = strdup(user);
+        parent->args->Add(user);
+    }
+    
+    return cmd_user(parent);
+}
+
+CMD(compat_open)
+{
+    const char *myname = getlogin();
+    struct passwd *pw;
+    char *name = NULL;
+    char *prompt = NULL;
+    char *cmd;
+    int len = 0;
+    ascii_mode = 0;
+    Job *job;
+    int n;
+    
+    if (parent->args->count() == 3)
+        parent->args->insarg(2, "-p");
+    else if (parent->args->count() != 2) {
+        parent->eprintf(_("Try `help %s' for more information.\n"), parent->args->a0());
+        return NULL;
+    }
+    
+    if (myname == NULL && (pw = getpwuid(getuid())) != NULL)
+        myname = pw->pw_name;
+    if (myname) {
+        len = strlen(myname) + 10;
+        prompt = (char*)malloc(len);
+        if (len <= snprintf(prompt, len, "Name (%s): ", myname))
+            prompt[len - 1] = '\0';
+        name = GetText(prompt);
+        name = strdup(name && strlen(name) > 0 ? name : myname);
+        free(prompt);
+    }
+    else {
+        name = GetText("Name: ");
+        if (name) strdup (name);
+    }
+    
+            
+    if (name != NULL && strlen(name) == 0) {
+        free(name);
+        name = NULL;
+    }
+
+    if (name) {
+        len = strlen(name) + 11;
+        cmd = (char*)malloc(len);
+
+        if (len <= snprintf(cmd, len, "lftp-user %s", name))
+            cmd[len - 1] = '\0';
+
+        parent->PrependCmd(cmd);
+
+        free(name);
+        free(cmd);
+    }
+    job = parent->builtin_open();
+    n = job->Do();
+    
+    return job;
+}
+
+CMD(get);
+
+CMD(compat_get)
+{
+    if (ascii_mode && parent->args->count() > 1)
+        parent->args->insarg(1, "-a");
+    
+    return cmd_get(parent);
+}
+
+CMD(get1);
+
+CMD(compat_get1)
+{
+    if (ascii_mode && parent->args->count() > 1)
+        parent->args->insarg(1, "-a");
+    
+    return cmd_get1(parent);
+}
+
+void module_init()
+{
+    ascii_mode = 0;
+
+    CmdExec::RegisterCompatCommand("user", cmd_compat_user, "user <username> [<pass>]", "send new user information (only for backward compatibility, use lftp-user instead)\n");
+    CmdExec::RegisterCompatCommand("open", cmd_compat_open, "open <site> [<port]", "connect to remote ftp server (only for backward compatibility, use lftp-open instead)\n");
+    
+    CmdExec::RegisterCompatCommand("get", cmd_compat_get);
+    CmdExec::RegisterCompatCommand("mget", cmd_compat_get);
+    CmdExec::RegisterCompatCommand("put", cmd_compat_get);
+    CmdExec::RegisterCompatCommand("mput", cmd_compat_get);
+    CmdExec::RegisterCompatCommand("get1", cmd_compat_get1);
+    
+    
+    CmdExec::RegisterCommand("ascii", cmd_ascii, "ascii", "set ascii transfer type\n");
+    CmdExec::RegisterCommand("binary", cmd_bin, "binary", "set binary transfer type\n");
+    CmdExec::RegisterCommand("type", cmd_type, "type [ascii|binary]", "set file transfer type\n");
+}
diff --git a/src/CompatMode.h b/src/CompatMode.h
new file mode 100644
index 00000000..d9bdc1c5
--- /dev/null
+++ b/src/CompatMode.h
@@ -0,0 +1,28 @@
+/*
+ * lftp and utils
+ *
+ * Copyright (c) 2005 by Petr Ostadal (postadal@suse.cz)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef COMPATMODE_H
+#define COMPATMODE_H
+
+#include "Job.h"
+extern int ascii_mode;
+
+
+#endif //COMPATMODE_H
diff --git a/src/lftp-wrapper.c b/src/lftp-wrapper.c
new file mode 100644
index 00000000..f6bbfdfc
--- /dev/null
+++ b/src/lftp-wrapper.c
@@ -0,0 +1,1177 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (c) 2005 SUSE LINUX Products GmbH, Nuernberg, Germany       *
+ *   Authors: Pavel Nemec  <pnemec@suse.cz>                                *
+ *            Petr Ostadal <postadal@suse.cz>                              *
+ *                                                                         *
+ *   wrapper for ftp                                                       *
+ *  this wraper should provide ftp format of comands for lftp              *
+ *  only noninteractive mode is implemented                                *
+ *                                                                         *
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <string.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <err.h>
+#include <ctype.h>
+
+static void help(void);
+static int strsuftoi(const char *arg);
+static void not_implemented_ignoring(char *what);
+static void add_to_e_script(char *cmd);	/* at to end */
+static void add_to_e_scriptB(char *cmd);	/* at to begin */
+static char *collect_strings(int argc, char **argv);
+char *get_file(char *url_with_file);
+char *get_url(char *url_with_file);
+int haveFile(char *text);
+void printPortWarningMessage(char *port);
+void printPortErrorMessage(char *url, int port);
+
+int isFile(char *url);
+int isFTP(char *url);
+int isHTML(char *url);
+int isHost(char *url);
+int locateChar(char *haystack, char needle);
+int locateCharR(char *haystack, char needle);
+char *convertClasicToFtp(char *url);
+int isWithUsername(char *url);
+int isValidPort(char *port);
+int isPortInUrl(char *url);
+void removeAnonymousUser(char *url);
+
+
+#define BUFSIZE 4096
+#define FTP_PORT 21
+
+#define INSTALLED_COMPAT_MODE_MODULE 1
+#define SSL_NOT_ALLOW 1
+
+#define ANONYMOUS_PREFIX "anonymous@"
+
+#ifdef INSTALLED_COMPAT_MODE_MODULE
+# define LFTP_OPEN "lftp-open"
+# define LFTP_COMPAT_MODE_OPEN "open"
+#else				/* INSTALLED_COMPAT_MODE_MODULE */
+# define LFTP_OPEN "open"
+# define LFTP_COMPAT_MODE_OPEN "open"
+#endif				/* INSTALLED_COMPAT_MODE_MODULE */
+
+static char *binname = NULL;
+static int compat_mode_warning = 1;
+static char e_script[BUFSIZE + 1];
+static char *HTML_URL = "http://";
+static char *FTP_URL = "ftp://";
+static char *FILE_URL = "file://";
+static unsigned int MAX_PORT = 65535;
+static char *std_out = "/dev/stdout";
+
+
+int main(int argc, char *argv[])
+{
+    int ch;
+    int notimplemented;
+    int anonymous = 0; /* 0 not force anonymous login, 1 force anonymous login*/
+    int debug = 0;
+    int verbose = 0;		/* -1=off 0 = NA 1 =on */
+    int force_cache_reload = 0;
+    int autologin = 1;
+    char *ftp_port = NULL;
+    int ftp_port_i=FTP_PORT;
+    int retry_wait = -1;
+    char *end;
+    int restart_auto_fetching = 0;	/* 0 no, 1-yes */
+    char *upload_path = NULL;
+    char *new_argv0 = "lftp";
+    char **new_argv;
+    int iarg = 0;
+    char buf[BUFSIZE + 1];
+    int rate_get = 0, rate_put = 0;
+    int rate_get_incr = -1, rate_put_incr = -1;
+    char *anonymous_pass = NULL;
+    char *env;
+    int passive_mode = -1;
+    int active_fallback = -1;
+    int interactive = 0;
+
+    /*
+     * if 0 using mput/mget, if 1 * using * put/get to supress * local
+     * file * completiotion 
+     */
+    int globing = 0;
+    int showEXE = 0;
+
+    /*
+     * if 0 no redirection, if 1 redirection to file or to /dev/stdout 
+     */
+    int redirect_output = 0;
+    char *output_file = NULL;
+
+    /*
+     * both in lftp and lukemftp is default mode passive, 0 means acitve 
+     */
+    passive_mode = 1;
+
+    /*
+     * terminal 
+     */
+    int is_tty = 0;
+    int i;
+
+
+    e_script[0] = '\0';
+
+    if (!(new_argv = (char **) malloc(sizeof(char *) * (argc + 100))))
+	return -1;
+
+    binname = strrchr(argv[0], '/');
+    if (binname == NULL)
+	binname = argv[0];
+    else
+	binname++;
+
+    if (strcmp(binname, "pftp") == 0) {
+	passive_mode = 1;
+	active_fallback = 0;
+    } else if (strcmp(binname, "gate-ftp") == 0)
+	not_implemented_ignoring("gate_mode");
+
+    /*
+     * environment compatibility 
+     */
+    anonymous_pass = getenv("FTPANONPASS");
+    /*
+     * verbosity
+     */
+    is_tty = isatty(1);
+    if (is_tty == 0)
+	verbose = -1;
+
+    if ((env = getenv("FTPMODE")) != NULL) {
+	if (strcasecmp(env, "passive") == 0) {
+	    passive_mode = 1;
+	    active_fallback = 0;
+	} else if (strcasecmp(env, "active") == 0) {
+	    passive_mode = 0;
+	    active_fallback = 0;
+	} else if (strcasecmp(env, "gate") == 0) {
+	    not_implemented_ignoring
+		("enviroment variable FTPSERVERPORT=gate");
+	} else if (strcasecmp(env, "auto") == 0) {
+	    not_implemented_ignoring
+		("enviroment variable FTPSERVERPORT=auto");
+	} else
+	    warnx("unknown $FTPMODE '%s'; using defaults", env);
+    }
+    while ((ch = getopt(argc, argv, "Aadefhgino:pP:r:RtT:u:vVsx")) != -1) {
+	notimplemented = 0;
+	switch (ch) {
+	case 'A':
+	    /*
+	     * Force active mode ftp. 
+	     */
+	    passive_mode = 0;
+	    break;
+	case 'g':
+	    /*
+	     * Disables file name globbing. 
+	     */
+	    globing = 1;
+	    break;
+	case 'i':
+	    /*
+	     * Turns off interactive prompting during multiple file
+	     * transfers. 
+	     */
+	case 't':
+	    /*
+	     * Enables packet tracing 
+	     */
+	    break;
+	case 'v':
+	    verbose = 1;	/* on */
+	    break;
+	case 'V':
+	    /*
+	     * Disable verbose and progress, overriding the default of
+	     * enabled when output is to a terminal. 
+	     */
+	    verbose = -1;	/* off */
+	    break;
+	case 'a':
+	    anonymous = 1;
+	    break;
+	case 'd':
+	    /*
+	     * Enables debugging. 
+	     */
+	    debug++;
+	    break;
+	case 'f':
+	    /*
+	     * Forces a cache reload for transfers that go through the FTP 
+	     * or HTTP proxies. 
+	     */
+	    force_cache_reload = 1;
+	    break;
+	case 'h':
+	    help();
+	    exit(1);
+
+	case 'n':
+	    /*
+	     * Restrains auto-login upon initial connection 
+	     */
+	    autologin = 0;
+	    break;
+	case 'o':
+	    /*
+	     * When auto-fetching files, save the contents in output 
+	     */
+	    redirect_output = 1;
+	    output_file = optarg;
+	    if (strcmp(output_file, "-") == 0)
+		output_file = std_out;
+
+	    break;
+	case 'p':
+	    /*
+	     * Enable passive mode operation 
+	     */
+	    /*
+	     * deprecated by lukemftp, passive mode is used by default 
+	     */
+	    passive_mode = 1;
+	    break;
+	case 'P':
+	    /*
+	     * Sets the port number to port 
+	     */
+	    ftp_port = optarg;
+	    int tmp_port = isValidPort(ftp_port);
+	    if(tmp_port)ftp_port_i=tmp_port;
+	    break;
+	case 'r':
+	    retry_wait = strtol(optarg, &end, 10);
+
+	    if (retry_wait < 1 || *end != '\0')
+		errx(1, "bad '-r' retry value: %s", optarg);
+	    break;
+	case 'R':
+	    /*
+	     * Restart all non-proxied auto-fetches. 
+	     */
+	    restart_auto_fetching = 1;
+	    break;
+	case 'T':
+	    /*
+	     * Set the maximum transfer rate for direction to maximum
+	     * bytes/second 
+	     */
+	    {
+		int targc = 0;
+		char *targv[5], *oac, *c;
+		int dir = 0, max = 0, incr = -1;
+
+		/*
+		 * look for `dir,max[,incr]' 
+		 */
+		if (!(oac = strdup(optarg)))
+		    return -1;
+
+		while ((c = strsep(&oac, ",")) != NULL) {
+		    if (*c == '\0') {
+			warnx("bad throttle value: %s", optarg);
+			help();
+			/*
+			 * NOTREACHED 
+			 */
+		    }
+		    targv[targc++] = c;
+		    if (targc >= 4)
+			break;
+		}
+
+		if (targc > 3 || targc < 2)
+		    help();
+
+#define	RATE_GET	1
+#define	RATE_PUT	2
+#define	RATE_ALL	(RATE_GET | RATE_PUT)
+
+		if (strcasecmp(targv[0], "all") == 0)
+		    dir = RATE_ALL;
+		else if (strcasecmp(targv[0], "get") == 0)
+		    dir = RATE_GET;
+		else if (strcasecmp(targv[0], "put") == 0)
+		    dir = RATE_PUT;
+		else
+		    help();
+
+		if (targc >= 2)
+		    if ((max = strsuftoi(targv[1])) < 0)
+			help();
+
+		if (targc == 3)
+		    if ((incr = strsuftoi(targv[1])) < 0)
+			help();
+
+
+		if (dir & RATE_GET) {
+		    rate_get = max;
+		    rate_get_incr = incr;
+		}
+
+		if (dir & RATE_PUT) {
+		    rate_put = max;
+		    rate_put_incr = incr;
+		}
+
+		free(oac);
+	    }
+	    break;
+	case 'u':
+	    /*
+	     * Upload files on the command line to url where url is one of 
+	     * the ftp URL types as supported by auto-fetch 
+	     */
+	    upload_path = strdup(optarg);
+	    break;
+	case 's':
+	    /*
+	     * don't display warning message about compatibility mode 
+	     */
+	    compat_mode_warning = 0;
+	    break;
+	case 'x':
+	    showEXE = 1;	/* show exec string */
+	    break;
+	default:
+	    printf("unknown character %c \n", ch);
+	    continue;
+	}
+    }
+    argc -= optind;
+    argv += optind;
+
+    if (compat_mode_warning && (verbose != -1))
+	fprintf(stderr,
+		"Wrapper for lftp to simulate compatibility with lukemftp\n");
+
+    if (getenv("FTPPROMPT"))
+	not_implemented_ignoring("enviroment variable FTPPROMPT");
+
+    if (getenv("FTPRPROMPT"))
+	not_implemented_ignoring("enviroment variable FTPRPROMPT");
+
+    if (getenv("FTPSERVER"))
+	not_implemented_ignoring("enviroment variable FTPSERVER");
+
+    if (getenv("FTPSERVERPORT"))
+	not_implemented_ignoring("enviroment variable FTPSERVERPORT");
+
+    new_argv[iarg++] = strdup(new_argv0);
+
+    if (ftp_port) {
+	new_argv[iarg++] = "-p";
+	new_argv[iarg++] = strdup(ftp_port);
+    }
+    switch (verbose) {
+    case 1:
+	debug += 3;
+	break;
+    case 0:
+	debug = 3;
+	break;
+    case -1:
+    default:
+	debug = 0;
+    }
+
+    if (debug)
+	snprintf(buf, BUFSIZE, "debug %d", debug);
+    else
+	snprintf(buf, BUFSIZE, "debug off");
+
+    buf[BUFSIZE] = '\0';
+    add_to_e_script(buf);
+
+    /*
+     * lukemftp does not support ssl, neither wraper will 
+     */
+    add_to_e_script("set ftp:ssl-allow false");
+    
+    add_to_e_script("set  net:max-retries 1");
+    
+    if (anonymous_pass) {
+	snprintf(buf, BUFSIZE, "set ftp:anon-pass %s", anonymous_pass);
+	buf[BUFSIZE - 1] = '\0';
+	add_to_e_script(buf);
+    }
+
+    if (passive_mode != -1) {
+	snprintf(buf, BUFSIZE, "set ftp:passive-mode %s",
+		 passive_mode ? "on" : "off");
+	buf[BUFSIZE] = '\0';
+	add_to_e_script(buf);
+    }
+
+    if (retry_wait != -1) {
+	snprintf(buf, BUFSIZE,
+		 "set net:reconnect-interval-base %d;"
+		 "set net:reconnect-interval-multiplier 1;"
+		 "set net:reconnect-interval-max %d", retry_wait,
+		 retry_wait);
+	buf[BUFSIZE] = '\0';
+	add_to_e_script(buf);
+    }
+
+    if (rate_put || rate_get) {
+
+	if (rate_get_incr != -1 || rate_put_incr != -1)
+	    not_implemented_ignoring("incremention in -T");
+
+	snprintf(buf, BUFSIZE,
+		 "set net:limit-total-rate %d:%d", rate_get, rate_put);
+
+	buf[BUFSIZE] = '\0';
+	add_to_e_script(buf);
+    }
+    if (!passive_mode) {
+	snprintf(buf, BUFSIZE, "set ftp:passive-mode=true");
+    }
+    if (upload_path) {
+	snprintf(buf, BUFSIZE, LFTP_OPEN " %s", upload_path);
+	buf[BUFSIZE] = '\0';
+	add_to_e_script(buf);
+	interactive = 1;
+	if (argc > 1) {
+	    if (globing) {
+		int i;
+		for (i = 0; i < argc; i++) {
+		    snprintf(buf, BUFSIZE, "put %s", argv[i]);
+		    add_to_e_script(buf);
+		}
+		buf[0] = '\0';	/* not to add it again */
+	    } else {
+		char *buf2 = collect_strings(argc, argv);
+		snprintf(buf, BUFSIZE, "mput %s", buf2);
+		free(buf2);
+	    }
+	} else {
+	    if (argc == 1)
+		snprintf(buf, BUFSIZE, "%s %s", globing ? "put" : "mput",
+			 argv[0]);
+	    else
+		help();		/* nothing to upload */
+	}
+
+	buf[BUFSIZE] = '\0';
+	add_to_e_script(buf);
+    } else if (argc > 0) {	/* another arguments left */
+	char get[100];
+	char open[100];
+
+	/*
+	 * get command 
+	 */
+	if (redirect_output) {
+	    snprintf(get, 100,
+		     (restart_auto_fetching ? "get1 -c -o %s" :
+		      "get1 -o %s"), output_file);
+	} else {
+	    snprintf(get, 100, globing ?
+		     (restart_auto_fetching ? "get -c" : "get") :
+		     (restart_auto_fetching ? "mget -c" : "mget"));
+	}
+
+	for (i = 0; i < argc; i++) {
+	    char *buf2 = argv[i];
+	    char *buf_file = NULL;
+	    char *buf_url = NULL;
+	    int is = haveFile(buf2);
+
+/**	    if (ftp_port == NULL)
+		snprintf(open, 100,
+			 (anonymous
+			  || isWithUsername(buf2) ? LFTP_OPEN :
+			  LFTP_COMPAT_MODE_OPEN));
+	    else
+		snprintf(open, 100, "%s -p %s",
+			 (anonymous
+			  || isWithUsername(buf2) ? LFTP_OPEN :
+			  LFTP_COMPAT_MODE_OPEN), ftp_port);**/
+
+	    int ishtml,isftp,isfile,ishost,isuser; //flags for url
+	    int tmp_port;
+	    ishtml=isHTML(buf2);
+	    isfile=isFile(buf2);
+	    ishost=isHost(buf2);
+	    isftp=isFTP(buf2);
+	    isuser=isWithUsername(buf2);
+	    if (is) {
+		 snprintf(open, 100,isuser ? LFTP_OPEN :
+			  LFTP_COMPAT_MODE_OPEN);
+		/* url to download file with */
+		if (isfile) {	
+		    /* file download is simple, only mget is needed */
+		    snprintf(buf, BUFSIZE, "%s %s", get, buf2);
+		    add_to_e_script(buf);
+		    interactive = 1;
+		    continue;
+		}
+		if( ishtml){ /*similar behaving like ftp but diferent port */
+			if(ftp_port_i==FTP_PORT)/*easy case, no port hacking */
+				snprintf(buf, BUFSIZE, "%s %s", get, buf2);
+			else{   /* complicated one */
+				tmp_port=isPortInUrl(buf2);
+				if(tmp_port==-1) {
+					printPortErrorMessage(buf2,-1); /* will exit */
+					continue;
+				}
+				if(tmp_port)ftp_port_i=tmp_port;
+				buf_file = get_file(buf2);
+				buf_url = get_url(buf2);
+				snprintf(buf, BUFSIZE, "%s %s:%d%s",
+					 get, buf_url, ftp_port_i,
+					 buf_file);
+				add_to_e_script(buf);
+			}
+			snprintf(buf, BUFSIZE, "%s %s", get, buf2);
+			add_to_e_script(buf);
+			interactive = 1;
+			continue;
+		}   
+		if (ishost) {
+			buf2 = convertClasicToFtp(buf2);
+			snprintf(open, 100, LFTP_COMPAT_MODE_OPEN);
+			isftp=1;
+			}
+		if (isftp) {	
+			/* ftp download is litle bit more complicated */
+			buf_file = get_file(buf2);
+			buf_url = get_url(buf2);
+			tmp_port= isPortInUrl(buf2);/* no need to test error message, it is done in get_url() */
+			if(tmp_port)ftp_port_i=tmp_port;
+			snprintf(open, 100, LFTP_OPEN); 
+			snprintf(buf, BUFSIZE, "%s %s:%d; %s %s",
+					 open, buf_url, ftp_port_i, get,
+					 buf_file);
+			add_to_e_script(buf);
+			interactive = 1;
+		} else
+			printf
+			    ("url open/download handling not implemented with %s\n",buf2);
+		interactive = 1;
+	    } else {		/* no file at the end of url, so just open 
+				 * ftp */
+		if (isftp){
+			anonymous = 1;  
+		} else {	
+		     /* [[user@]host [port]] */
+		    if (i < argc - 1) {	/* some arguments left */
+			ftp_port_i = isValidPort(argv[1 + i]);
+		    }
+		}
+		
+		/*if (!strncmp
+		    (buf2, ANONYMOUS_PREFIX, strlen(ANONYMOUS_PREFIX)))
+		    anonymous_offset = strlen(ANONYMOUS_PREFIX);*/
+		snprintf(open, 100,(anonymous || isuser) ? LFTP_OPEN :
+			  LFTP_COMPAT_MODE_OPEN);     
+		buf_file = get_file(buf2); /* directory */ 
+		buf_url = get_url(buf2);
+		tmp_port= isPortInUrl(buf2);/* no need to test error message, it is done in get_url() */
+		if(tmp_port)ftp_port_i=tmp_port;
+		snprintf(buf, BUFSIZE, "%s %s:%d%s", open, buf_url, ftp_port_i, (buf_file==NULL ? "":buf_file));
+		add_to_e_script(buf);
+		interactive = 0;
+		argv += argc;	/* delete comands */
+		argc = 0;
+		break;		/* from FOR loop, because ftp is not able
+				 * to download some file and then open
+				 * url at the end */
+	    }
+	    /*
+	     * if (!autologin) printf("autologin is not implemented
+	     * yet\n"); else { snprintf(buf, BUFSIZE,"open %s", argv[0]);
+	     * buf[BUFSIZE] = '\0'; add_to_e_script(buf); } 
+	     */
+	}
+    }
+
+    if (e_script != NULL && strlen(e_script) > 0) {
+	new_argv[iarg++] = "-e";
+	if (interactive) {
+	    add_to_e_script("exit");
+	}
+	new_argv[iarg++] = e_script;
+    }
+#ifdef INSTALLED_COMPAT_MODE_MODULE
+    add_to_e_scriptB("module compat-mode");
+#endif				/* INSTALLED_COMPAT_MODE_MODULE */
+    new_argv[iarg++] = NULL;
+    if (showEXE) {
+	printf("EXE:");
+	for (i = 0; new_argv[i]; i++)
+	    printf(" %s", new_argv[i]);
+	printf("\n");
+    }
+    execvp(new_argv0, new_argv);
+    return 0;
+}
+
+/**
+  * check if text is in format: (see man ftp) 
+  *   ftp://
+  *   http://
+  *   file:///
+  *   host:path
+  * @param char * text -expecting string end with '\n' 
+  * if yes return 1
+  * if no return 0
+  **/
+int haveFile(char *text)
+{
+    int end = -1;
+    int i = 0, j = 0, k = 0;
+    char *tmp = NULL;
+    tmp = text;
+    /* if is '/' on end, it is directory */ 
+    i = locateCharR(tmp, '/');
+    if(i==strlen(text)) return 0;
+	    
+    if (text == NULL)
+	return 0;
+
+	/**
+	  * Handle this
+	  * [http://[user[:password]@]host[:port]/path]
+	  **/
+    if (isHTML(text)) {
+	tmp += strlen(HTML_URL);
+	end = strlen(tmp);
+	if (strncmp(tmp + end - 1, "/", 1) == 0)
+	    return 0;		/* is directory ! */
+	i = locateCharR(tmp, '/');
+	if (i != end - 1 && i != -1)
+	    return 1;		/* is there any character after /? */
+	else
+	    return 0;
+    }
+
+	/**
+	  * Handle this
+	  * ftp://[user[:password]@]host[:port]/path[/]]
+	  **/
+    if (isFTP(text)) {
+	tmp += strlen(FTP_URL);
+	end = strlen(tmp);
+	if (strncmp(tmp + end - 1, "/", 1) == 0)
+	    return 0;		/* is directory ! */
+	/*
+	 * is there any character after /? 
+	 */
+	i = locateCharR(tmp, '/');
+	return (i != end - 1 && i != -1);
+    }
+
+	/**
+	  * Handle this
+	  * [file:///path]
+	  **/
+    if (isFile(text)) {
+	tmp += strlen(FILE_URL);
+	end = strlen(tmp);
+	if (strncmp(tmp + end - 1, "/", 1) == 0)
+	    return 0;		/* is directory ! */
+	/*
+	 * is there any character after /? 
+	 */
+	i = locateCharR(tmp, '/');
+	return (i != end - 1 && i != -1);
+    }
+
+	/**
+	  * now it could be only host thing
+	  * [user@]host:[path][/]
+	  * [user@][::1]:[path][/]  //ipv6 adress is in bracket!
+	  **/
+
+    end = strlen(tmp);
+    if (strncmp(tmp + end - 1, "/", 1) == 0)
+	return 0;		/* is directory ! */
+    i = locateChar(tmp, '[');
+    j = locateChar(tmp, ':');	/* this will find first characters */
+    k = locateChar(tmp, '@');
+    if (i < k) {		/* there is [ character in name of user */
+	i = locateChar(tmp + k, '[');	/* find another one */
+    }
+    if (i != -1) {		/* ipv6! */
+	i = locateChar(tmp + i, ']');	/* find end of adress */
+	j = locateChar(tmp + i, ':');	/* find colum after end bracket */
+    }
+
+    return j != end - 1 && j != -1 ? 1 : 0;
+}
+
+/**
+  * clasic format is
+  *  [user@]host:[path][/]
+  * will change to
+  * ftp://[user@]host/[path][/]
+  * it will alocate new memory but not free url !
+  * return  char * newurl
+  **/
+char *convertClasicToFtp(char *url)
+{
+    char *change;
+    char *newurl = NULL;
+    if (url == NULL)
+	return url;
+    if ((newurl =
+	 malloc((strlen(url) + strlen(FTP_URL)) * sizeof(char))) == NULL) {
+	printf("convertclasicToFtp, cannot alocate memory\n");
+	exit(1);
+    }
+    sprintf(newurl, "%s%s", FTP_URL, url);
+    change = strstr(newurl + strlen(FTP_URL), ":");
+    change[0] = '/';
+    return newurl;
+}
+
+/**
+  * find file (or directory) at the end of url
+  * return *char file
+  * or null on erorr
+  * it can handle those formats 
+  * ftp://[user[:password]@]host[:port]/path[/]
+  * http://[user[:password]@]host[:port]/path
+  **/
+char *get_file(char *url_with_file)
+{
+    char *reti;
+    char *tmp;
+    int len, file_pos;
+    if (url_with_file == NULL)
+	return 0;
+    tmp = url_with_file;
+    if (isFTP(url_with_file))
+	tmp += strlen(FTP_URL);
+    if (isHTML(url_with_file))
+	tmp += strlen(HTML_URL);
+    len = strlen(tmp);
+    file_pos = locateChar(tmp, '/');
+    if (file_pos == -1)		/* no file */
+	return NULL;
+
+    if ((reti = malloc((len - file_pos) * sizeof(char))) == NULL) {
+	printf
+	    ("function get_file, cannot allocate memmory, returning null\n");
+	return NULL;
+    }
+    strncpy(reti, tmp + file_pos, len - file_pos);
+    return reti;
+}
+
+/**
+  * find url int the url with file, url will be striped by ending '/'
+  * return *char = url;
+  * or null on erorr
+  * it can handle those formats 
+  * file:///path
+  * [user@]host:[path][/]
+  * [user@]host
+  * ftp://[user[:password]@]host[:port]/path[/]
+  * http://[user[:password]@]host[:port]/path
+  **/
+char *get_url(char *url_with_file)
+{
+    char *reti;
+    char *tmp;
+    int len, url_end_pos=-1;
+    if (url_with_file == NULL)
+	return 0;
+    tmp = url_with_file;
+    int isftp = 0, ishtml = 0,ishost=0;
+    if (isFTP(url_with_file)) {
+	tmp += strlen(FTP_URL);
+	isftp = 1;
+    }
+    if (isHTML(url_with_file)) {
+	ishtml = 1;
+	tmp += strlen(HTML_URL);
+    }
+    ishost=isHost(url_with_file);
+    url_end_pos = locateChar(tmp,':'); 
+    if(url_end_pos>locateChar(tmp,'/')) /* localhost/:dir/   case */
+	    url_end_pos = locateChar(tmp,'/');
+    if(url_end_pos==-1)
+	    url_end_pos = locateChar(tmp,'/');
+    if (url_end_pos == -1){		
+	/* no file,  whole url_with_file is valid url or user@url */
+	removeAnonymousUser(url_with_file);
+	return url_with_file; 
+    }
+    else {
+	len = strlen(tmp);
+	int tmpi = strlen(url_with_file)-len; /* offset */ 
+	tmpi += url_end_pos;
+	if ((reti =
+	     malloc(1+tmpi * sizeof(char))) == NULL) {
+	    printf
+		("function get_file, cannot allocate memmory, returning null\n");
+	    return NULL;
+	}
+	strncpy(reti, url_with_file,
+		tmpi);
+	*(reti+tmpi+1)='\0';
+	/* anonymous hack - remove user anonymous, who cause troubles */
+	removeAnonymousUser(reti);
+	/*if (*(reti + len - 1) == '/' || *(reti + len - 1) == ':')
+	    *(reti + len - 1) = '\0';*/
+	return reti;
+    }
+}
+/**
+  * this will check for ANONYMOUS_PREFIX and remove it from url
+  **/
+void removeAnonymousUser(char *url){
+	char *user = strstr(url,ANONYMOUS_PREFIX);
+	int len,url_end_pos;
+	if(user){
+		len = strlen(ANONYMOUS_PREFIX);
+		url_end_pos=strlen(user);
+		strncpy(user, (user+len),url_end_pos-len);
+		*(user+url_end_pos-len)='\0';
+	}
+	return;
+}
+
+/**
+  * return 1 if url begin with FTP_URL string
+  * return 0 otherwise
+  **/
+int isFTP(char *url)
+{
+    return !strncmp(url, FTP_URL, strlen(FTP_URL));
+}
+
+/**
+  * return true if url begin with HTML_URL string
+  * return  otherwise
+  **/
+int isHTML(char *url)
+{
+    return !strncmp(url, HTML_URL, strlen(HTML_URL));
+}
+
+/**
+  * return number of port if char represent valid port
+  * return FTP_PORT otherwise (pftp behaving)
+  * return 0 if there is some raly ugly port (pftp crash on such port)
+  **/
+int isValidPort(char *port)
+{
+    int reti = -1, i;
+    char c;
+    if (port == NULL || strlen(port) >= 6){
+	    printPortWarningMessage(port);
+	    return FTP_PORT;
+    }
+    for (i = 0; i < strlen(port) && reti == -1; i++) {
+	c = *(port + i);
+	if (isdigit((int) c))
+	    continue;
+	else
+	    reti = 0;
+    }
+    if (reti != -1) {		/* strange digit found */
+	return 0;
+    }
+    reti = atoi(port);
+    if(reti > 0 && reti < MAX_PORT){
+	return reti;
+    }
+    printPortWarningMessage(port);
+    return FTP_PORT;
+}
+
+/**
+  * return 1 if url is in format  [user@]host[:port][path][/]
+  * return 0 otherwise
+  * it call isFTP is HTML isFile !!
+  * @todo - not ipv6 [::1] ready
+  **/
+int isHost(char *url)
+{
+    if (url == NULL || isFile(url) || isHTML(url) || isFTP(url))
+	return 0;
+    int at = locateChar(url, '@');
+    if (at == -1)
+	at = 0;
+    int colon = locateChar(url + at, ':');
+    if(colon==-1)
+	    colon=locateChar(url + at, '/');
+    if(colon==-1)
+	    colon=strlen(url);
+    return at>colon? 0 : 1;
+}
+/**
+  * return true if user is included
+  * */
+int isWithUsername(char *url)
+{
+    int i1, i2, i3, i4;
+    if (isFTP(url))
+	url += strlen(FTP_URL);
+
+    i1 = locateChar(url, '@');
+    i2 = locateChar(url, ':');
+    i3 = locateChar(url, '/');
+    i4 = locateChar(url, '[');
+
+    return (i1 != -1 &&
+	    (i2 == -1 || i1 < i2) &&
+	    (i3 == -1 || i1 < i3) && 
+	    (i4 == -1 || i1 < i4));
+}
+
+/**
+  * return 1 if url begin with FILE_URL string
+  * return 0 otherwise
+  **/
+int isFile(char *url)
+{
+    return !strncmp(url, FILE_URL, strlen(FILE_URL));
+}
+
+/**
+  * return position of char in string, start from begin of @haystack
+  * return -1 if char is not found in string
+  **/
+int locateChar(char *haystack, char needle)
+{
+    int reti = -1, size, i;
+    if (!haystack || !needle)
+	return reti;
+    size = strlen(haystack);
+    for (i = 0; i < size && reti == -1; i++) {
+	if (strncmp(haystack + i, &needle, 1) == 0) {
+	    reti = i;
+	}
+    }
+    return reti;
+}
+
+/**
+  * return position of char in string, start from end of @haystack
+  * return -1 if char is not found in string
+  **/
+int locateCharR(char *haystack, char needle)
+{
+    int reti = -1, size, i;
+    if (!haystack || !needle)
+	return reti;
+    size = strlen(haystack);
+    for (i = size-1; i >= 0 && reti == -1; i--) {
+	if (strncmp(haystack + i, &needle, 1) == 0) {
+	    reti = i;
+	}
+    }
+    return reti;
+}
+static void help(void)
+{
+    fprintf(stderr,
+	    /*
+	     * "usage: %s [-AadefginpRtvV] [-o outfile] [-P port] [-r
+	     * retry]\n" 
+	     */
+	    "usage: %s [-adefnpR] [-o outfile] [-P port] [-r retry]\n"
+	    "           [-T dir,max[,inc][[user@]host [port]]] [host:path[/]]\n"
+	    "           [file:///file] [ftp://[user[:pass]@]host[:port]/path[/]]\n"
+	    "           [http://[user[:pass]@]host[:port]/path] [...]\n"
+	    "       %s -u url file [...]\n", binname, binname);
+    exit(1);
+}
+
+/**
+ * Convert the string `arg' to an int, which may have an optional SI suffix
+ * (`b', `k', `m', `g'). Returns the number for success, -1 otherwise.
+ */
+static int strsuftoi(const char *arg)
+{
+    char *c;
+    long val;
+
+    if (!isdigit((unsigned char) arg[0]))
+	return -1;
+
+    val = strtol(arg, &c, 10);
+    if (c != NULL) {
+	if (c[0] != '\0' && c[1] != '\0')
+	    return -1;
+	switch (tolower((unsigned char) c[0])) {
+	case '\0':
+	case 'b':
+	    break;
+	case 'k':
+	    val <<= 10;
+	    break;
+	case 'm':
+	    val <<= 20;
+	    break;
+	case 'g':
+	    val <<= 30;
+	    break;
+	default:
+	    return (-1);
+	}
+    }
+    return val < 0 || val > INT_MAX ? -1 : val;
+}
+
+static void not_implemented_ignoring(char *what)
+{
+    if (compat_mode_warning)
+	fprintf(stderr, "Does not implemented: '%s' (ignoring)\n", what);
+}
+
+/**
+  * this method will add string in char *cmd to END of *e_script, it will also add ';' char to the end
+  **/
+static void add_to_e_script(char *cmd)
+{
+    if (!cmd || strlen(cmd) == 0)
+	return;
+
+    if (strlen(cmd) >= (BUFSIZE - strlen(e_script) - 2)) {
+	warnx("Command line for lftp is too long.");
+	exit(1);
+    }
+    strcat(e_script, cmd);
+    strcat(e_script, ";");
+}
+
+/**
+  * this method will add string in char *cmd to BEGIN of *e_script, it will also add ';' char to the end
+  **/
+static void add_to_e_scriptB(char *cmd)
+{
+    char tmp[BUFSIZE];
+    char *p = tmp;
+    int i;
+    for (i = 0; i < BUFSIZE; i++)
+	tmp[i] = '\0';
+    if (!cmd || strlen(cmd) == 0)
+	return;
+
+    if (strlen(cmd) >= (BUFSIZE - strlen(e_script) - 2)) {
+	warnx("Command line for lftp is too long.");
+	exit(1);
+    }
+    strcpy(p, e_script);
+    strcpy(e_script, cmd);
+    strcat(e_script, ";");
+    strcat(e_script, p);
+}
+
+static char *collect_strings(int argc, char **argv)
+{
+    char *buf;
+    int i, len = 1;
+    len = argc;			/* for space */
+
+    for (i = 0; i < argc; i++)
+	len += strlen(argv[i]);
+
+    if (!(buf = malloc(len))) {
+	warnx("Command line for lftp is too long.");
+	exit(1);
+    }
+    buf[len - 1] = '\0';
+
+    for (i = 0; i < argc; i++) {
+	strcat(buf, " ");
+	strcat(buf, argv[i]);
+    }
+    return buf;
+}
+
+/*
+ * Returns TRUE if address is a IPv6 is given. 
+ */
+int is_ipv6_address(const char *addr)
+{
+    struct addrinfo hints, *res;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_INET6;
+    hints.ai_socktype = SOCK_DGRAM;
+    hints.ai_flags = AI_NUMERICHOST;
+    if (getaddrinfo(addr, "0", &hints, &res) != 0)
+	return 0;
+
+    freeaddrinfo(res);
+    return 1;
+}
+/**
+  * url - url which could contain user, password, ftp/http/local url
+  * Return:
+  * number of port in url if there is some port in url
+  * 0  if there is no port in url
+  * -1 if url is in format when port should be present and no valid port number 
+  * 	is found 
+  **/
+int isPortInUrl(char *url){
+	char *port,*tmp;
+	int position,i;
+	tmp=url;
+	if (isFTP(url))
+		tmp += strlen(FTP_URL);
+	if (isHTML(url))
+		tmp += strlen(HTML_URL);
+	i=locateChar(tmp,'@');
+	if(i!=-1)
+		i=0;
+	position=locateChar(tmp+i,':');
+	i=locateChar(tmp+i,'/');
+	if(position==-1 || position>i )
+		return 0; /* no port */
+	port = tmp+position+1;
+	position = isValidPort(port);
+	if(position==0)
+		printPortErrorMessage(url,position);
+	return position;
+}
+/**
+  * this method will print standard warning error about wrong port and url
+  * this method will exit wrapper !!
+  **/
+void printPortErrorMessage(char *url, int port){
+	fprintf(stderr,"Unknown port `%d' in URL %s\n", port, url);
+	fprintf(stderr,"Invalid URL `%s'\n", url);
+	exit(1);
+}
+/**
+  * this method will print standard warning message about wrong port
+  **/
+void printPortWarningMessage(char *port){
+	fprintf(stderr,"Unknown port `%s', using port %d\n",
+				    port, FTP_PORT);
+}
-- 
2.16.2

openSUSE Build Service is sponsored by