Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
SUSE:SLE-15-SP2:GA
lftp
0002-Add-content-of-lftp-compat-addfiles.patch....
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0002-Add-content-of-lftp-compat-addfiles.patch.patch of Package lftp
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
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor