|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
* lftp - file transfer program
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* Copyright (c) 1996-2017 by Alexander V. Lukyanov (lav@yars.free.net)
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8f70b4 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8f70b4 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
8f70b4 |
* (at your option) any later version.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
8f70b4 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8f70b4 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8f70b4 |
* GNU General Public License for more details.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
8f70b4 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include <config.h>
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "modconfig.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "trio.h"
|
|
Packit |
8f70b4 |
#include <unistd.h>
|
|
Packit |
8f70b4 |
#include <errno.h>
|
|
Packit |
8f70b4 |
#include <ctype.h>
|
|
Packit |
8f70b4 |
#include <pwd.h>
|
|
Packit |
8f70b4 |
#include <sys/types.h>
|
|
Packit |
8f70b4 |
#include <sys/stat.h>
|
|
Packit |
8f70b4 |
#include <sys/wait.h>
|
|
Packit |
8f70b4 |
#include <fcntl.h>
|
|
Packit |
8f70b4 |
#include <assert.h>
|
|
Packit |
8f70b4 |
#ifdef HAVE_DLFCN_H
|
|
Packit |
8f70b4 |
# include <dlfcn.h>
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
#include <mbswidth.h>
|
|
Packit |
8f70b4 |
#include <human.h>
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "CmdExec.h"
|
|
Packit |
8f70b4 |
#include "GetJob.h"
|
|
Packit |
8f70b4 |
#include "CatJob.h"
|
|
Packit |
8f70b4 |
#include "LsCache.h"
|
|
Packit |
8f70b4 |
#include "mgetJob.h"
|
|
Packit |
8f70b4 |
#include "mkdirJob.h"
|
|
Packit |
8f70b4 |
#include "rmJob.h"
|
|
Packit |
8f70b4 |
#include "SysCmdJob.h"
|
|
Packit |
8f70b4 |
#include "mvJob.h"
|
|
Packit |
8f70b4 |
#include "pgetJob.h"
|
|
Packit |
8f70b4 |
#include "SleepJob.h"
|
|
Packit |
8f70b4 |
#include "FindJob.h"
|
|
Packit |
8f70b4 |
#include "FindJobDu.h"
|
|
Packit |
8f70b4 |
#include "ChmodJob.h"
|
|
Packit |
8f70b4 |
#include "CopyJob.h"
|
|
Packit |
8f70b4 |
#include "OutputJob.h"
|
|
Packit |
8f70b4 |
#include "echoJob.h"
|
|
Packit |
8f70b4 |
#include "EditJob.h"
|
|
Packit |
8f70b4 |
#include "mmvJob.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "misc.h"
|
|
Packit |
8f70b4 |
#include "alias.h"
|
|
Packit |
8f70b4 |
#include "netrc.h"
|
|
Packit |
8f70b4 |
#include "url.h"
|
|
Packit |
8f70b4 |
#include "GetPass.h"
|
|
Packit |
8f70b4 |
#include "SignalHook.h"
|
|
Packit |
8f70b4 |
#include "FileFeeder.h"
|
|
Packit |
8f70b4 |
#include "bookmark.h"
|
|
Packit |
8f70b4 |
#include "log.h"
|
|
Packit |
8f70b4 |
#include "module.h"
|
|
Packit |
8f70b4 |
#include "FileCopy.h"
|
|
Packit |
8f70b4 |
#include "DummyProto.h"
|
|
Packit |
8f70b4 |
#include "QueueFeeder.h"
|
|
Packit |
8f70b4 |
#include "lftp_rl.h"
|
|
Packit |
8f70b4 |
#include "FileSetOutput.h"
|
|
Packit |
8f70b4 |
#include "PatternSet.h"
|
|
Packit |
8f70b4 |
#include "LocalDir.h"
|
|
Packit |
8f70b4 |
#include "ConnectionSlot.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "configmake.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
History cwd_history;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(alias); CMD(anon); CMD(at); CMD(bookmark); CMD(cache); CMD(cat);
|
|
Packit |
8f70b4 |
CMD(cd); CMD(chmod); CMD(close); CMD(cls); CMD(command); CMD(debug);
|
|
Packit |
8f70b4 |
CMD(du); CMD(echo); CMD(edit); CMD(eval); CMD(exit); CMD(find); CMD(get);
|
|
Packit |
8f70b4 |
CMD(get1); CMD(glob); CMD(help); CMD(jobs); CMD(kill); CMD(lcd); CMD(lftp);
|
|
Packit |
8f70b4 |
CMD(ln); CMD(local); CMD(lpwd); CMD(ls); CMD(mirror); CMD(mkdir);
|
|
Packit |
8f70b4 |
CMD(module); CMD(mrm); CMD(mv); CMD(open); CMD(pwd); CMD(queue);
|
|
Packit |
8f70b4 |
CMD(repeat); CMD(rm); CMD(scache); CMD(set); CMD(shell); CMD(sleep);
|
|
Packit |
8f70b4 |
CMD(slot); CMD(source); CMD(subsh); CMD(suspend); CMD(tasks); CMD(torrent);
|
|
Packit |
8f70b4 |
CMD(user); CMD(ver); CMD(wait); CMD(empty); CMD(notempty); CMD(true);
|
|
Packit |
8f70b4 |
CMD(false); CMD(mmv);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#define HELP_IN_MODULE "m"
|
|
Packit |
8f70b4 |
#define ALIAS_FOR(cmd) cmd_##cmd,0,#cmd
|
|
Packit |
8f70b4 |
#define ALIAS_FOR2(a,cmd) cmd_##cmd,0,a
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#ifdef MODULE_CMD_MIRROR
|
|
Packit |
8f70b4 |
# define cmd_mirror 0
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
#ifdef MODULE_CMD_SLEEP
|
|
Packit |
8f70b4 |
# define cmd_sleep 0
|
|
Packit |
8f70b4 |
# define cmd_at 0
|
|
Packit |
8f70b4 |
# define cmd_repeat 0
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
#ifdef MODULE_CMD_TORRENT
|
|
Packit |
8f70b4 |
# define cmd_torrent 0
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum { DEFAULT_DEBUG_LEVEL=9 };
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const struct CmdExec::cmd_rec CmdExec::static_cmd_table[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"!", cmd_shell, N_("!<shell-command>"),
|
|
Packit |
8f70b4 |
N_("Launch shell or shell command\n")},
|
|
Packit |
8f70b4 |
{"(", cmd_subsh, N_("(commands)"),
|
|
Packit |
8f70b4 |
N_("Group commands together to be executed as one command\n"
|
|
Packit |
8f70b4 |
"You can launch such a group in background\n")},
|
|
Packit |
8f70b4 |
{"?", ALIAS_FOR(help)},
|
|
Packit |
8f70b4 |
{"alias", cmd_alias, N_("alias [<name> [<value>]]"),
|
|
Packit |
8f70b4 |
N_("Define or undefine alias <name>. If <value> omitted,\n"
|
|
Packit |
8f70b4 |
"the alias is undefined, else is takes the value <value>.\n"
|
|
Packit |
8f70b4 |
"If no argument is given the current aliases are listed.\n")},
|
|
Packit |
8f70b4 |
{"anon", cmd_anon, 0,
|
|
Packit |
8f70b4 |
N_("anon - login anonymously (by default)\n")},
|
|
Packit |
8f70b4 |
{"at", cmd_at, 0, HELP_IN_MODULE},
|
|
Packit |
8f70b4 |
{"bookmark",cmd_bookmark,N_("bookmark [SUBCMD]"),
|
|
Packit |
8f70b4 |
N_("bookmark command controls bookmarks\n\n"
|
|
Packit |
8f70b4 |
"The following subcommands are recognized:\n"
|
|
Packit |
8f70b4 |
" add <name> [<loc>] - add current place or given location to bookmarks\n"
|
|
Packit |
8f70b4 |
" and bind to given name\n"
|
|
Packit |
8f70b4 |
" del <name> - remove bookmark with the name\n"
|
|
Packit |
8f70b4 |
" edit - start editor on bookmarks file\n"
|
|
Packit |
8f70b4 |
" import <type> - import foreign bookmarks\n"
|
|
Packit |
8f70b4 |
" list - list bookmarks (default)\n")},
|
|
Packit |
8f70b4 |
{"bye", ALIAS_FOR(exit)},
|
|
Packit |
8f70b4 |
{"cache", cmd_cache, N_("cache [SUBCMD]"),
|
|
Packit |
8f70b4 |
N_("cache command controls local memory cache\n\n"
|
|
Packit |
8f70b4 |
"The following subcommands are recognized:\n"
|
|
Packit |
8f70b4 |
" stat - print cache status (default)\n"
|
|
Packit |
8f70b4 |
" on|off - turn on/off caching\n"
|
|
Packit |
8f70b4 |
" flush - flush cache\n"
|
|
Packit |
8f70b4 |
" size <lim> - set memory limit\n"
|
|
Packit |
8f70b4 |
" expire <Nx> - set cache expiration time to N seconds (x=s)\n"
|
|
Packit |
8f70b4 |
" minutes (x=m) hours (x=h) or days (x=d)\n")},
|
|
Packit |
8f70b4 |
{"cat", cmd_cat, N_("cat [-b] <files>"),
|
|
Packit |
8f70b4 |
N_("cat - output remote files to stdout (can be redirected)\n"
|
|
Packit |
8f70b4 |
" -b use binary mode (ascii is the default)\n")},
|
|
Packit |
8f70b4 |
{"cd", cmd_cd, N_("cd <rdir>"),
|
|
Packit |
8f70b4 |
N_("Change current remote directory to <rdir>. The previous remote directory\n"
|
|
Packit |
8f70b4 |
"is stored as `-'. You can do `cd -' to change the directory back.\n"
|
|
Packit |
8f70b4 |
"The previous directory for each site is also stored on disk, so you can\n"
|
|
Packit |
8f70b4 |
"do `open site; cd -' even after lftp restart.\n")},
|
|
Packit |
8f70b4 |
{"chmod", cmd_chmod, N_("chmod [OPTS] mode file..."),
|
|
Packit |
8f70b4 |
N_("Change the mode of each FILE to MODE.\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
" -c, --changes - like verbose but report only when a change is made\n"
|
|
Packit |
8f70b4 |
" -f, --quiet - suppress most error messages\n"
|
|
Packit |
8f70b4 |
" -v, --verbose - output a diagnostic for every file processed\n"
|
|
Packit |
8f70b4 |
" -R, --recursive - change files and directories recursively\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
"MODE can be an octal number or symbolic mode (see chmod(1))\n")},
|
|
Packit |
8f70b4 |
{"close", cmd_close, "close [-a]",
|
|
Packit |
8f70b4 |
N_("Close idle connections. By default only with current server.\n"
|
|
Packit |
8f70b4 |
" -a close idle connections with all servers\n")},
|
|
Packit |
8f70b4 |
{"cls", cmd_cls, N_("[re]cls [opts] [path/][pattern]"),
|
|
Packit |
8f70b4 |
N_("List remote files. You can redirect output of this command to file\n"
|
|
Packit |
8f70b4 |
"or via pipe to external command.\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
/* note: I've tried to keep options which are likely to be always
|
|
Packit |
8f70b4 |
* turned on (via cmd:cls-default, etc) capital, to leave lowercase
|
|
Packit |
8f70b4 |
* available for options more commonly used manually. -s/-S is an
|
|
Packit |
8f70b4 |
* exception; they both seem to be options used manually, so I made
|
|
Packit |
8f70b4 |
* them align with GNU ls options. */
|
|
Packit |
8f70b4 |
" -1 - single-column output\n"
|
|
Packit |
8f70b4 |
" -a, --all - show dot files\n"
|
|
Packit |
8f70b4 |
" -B, --basename - show basename of files only\n"
|
|
Packit |
8f70b4 |
" --block-size=SIZ - use SIZ-byte blocks\n"
|
|
Packit |
8f70b4 |
" -d, --directory - list directory entries instead of contents\n"
|
|
Packit |
8f70b4 |
" -F, --classify - append indicator (one of /@) to entries\n"
|
|
Packit |
8f70b4 |
" -h, --human-readable - print sizes in human readable format (e.g., 1K)\n"
|
|
Packit |
8f70b4 |
" --si - likewise, but use powers of 1000 not 1024\n"
|
|
Packit |
8f70b4 |
" -k, --kilobytes - like --block-size=1024\n"
|
|
Packit |
8f70b4 |
" -l, --long - use a long listing format\n"
|
|
Packit |
8f70b4 |
" -q, --quiet - don't show status\n"
|
|
Packit |
8f70b4 |
" -s, --size - print size of each file\n"
|
|
Packit |
8f70b4 |
" --filesize - if printing size, only print size for files\n"
|
|
Packit |
8f70b4 |
" -i, --nocase - case-insensitive pattern matching\n"
|
|
Packit |
8f70b4 |
" -I, --sortnocase - sort names case-insensitively\n"
|
|
Packit |
8f70b4 |
" -D, --dirsfirst - list directories first\n"
|
|
Packit |
8f70b4 |
" --sort=OPT - \"name\", \"size\", \"date\"\n"
|
|
Packit |
8f70b4 |
" -S - sort by file size\n"
|
|
Packit |
8f70b4 |
" --user, --group, --perms, --date, --linkcount, --links\n"
|
|
Packit |
8f70b4 |
" - show individual fields\n"
|
|
Packit |
8f70b4 |
" --time-style=STYLE - use specified time format\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
"By default, cls output is cached, to see new listing use `recls' or\n"
|
|
Packit |
8f70b4 |
"`cache flush'.\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
"The variables cls-default and cls-completion-default can be used to\n"
|
|
Packit |
8f70b4 |
"specify defaults for cls listings and completion listings, respectively.\n"
|
|
Packit |
8f70b4 |
"For example, to make completion listings show file sizes, set\n"
|
|
Packit |
8f70b4 |
"cls-completion-default to \"-s\".\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
/* FIXME: poorly worded. another explanation of --filesize: if a person
|
|
Packit |
8f70b4 |
* wants to only see file sizes for files (not dirs) when he uses -s,
|
|
Packit |
8f70b4 |
* add --filesize; it won't have any effect unless -s is also used, so
|
|
Packit |
8f70b4 |
* it can be enabled all the time. (that's also poorly worded, and too
|
|
Packit |
8f70b4 |
* long.) */
|
|
Packit |
8f70b4 |
"Tips: Use --filesize with -D to pack the listing better. If you don't\n"
|
|
Packit |
8f70b4 |
"always want to see file sizes, --filesize in cls-default will affect the\n"
|
|
Packit |
8f70b4 |
"-s flag on the commandline as well. Add `-i' to cls-completion-default\n"
|
|
Packit |
8f70b4 |
"to make filename completion case-insensitive.\n"
|
|
Packit |
8f70b4 |
)},
|
|
Packit |
8f70b4 |
{"connect", ALIAS_FOR(open)},
|
|
Packit |
8f70b4 |
{"command", cmd_command},
|
|
Packit |
8f70b4 |
{"debug", cmd_debug, N_("debug [OPTS] [<level>|off]"),
|
|
Packit |
8f70b4 |
N_("Set debug level to given value or turn debug off completely.\n"
|
|
Packit |
8f70b4 |
" -o <file> redirect debug output to the file\n"
|
|
Packit |
8f70b4 |
" -c show message context\n"
|
|
Packit |
8f70b4 |
" -p show PID\n"
|
|
Packit |
8f70b4 |
" -t show timestamps\n")},
|
|
Packit |
8f70b4 |
{"du", cmd_du, N_("du [options] <dirs>"),
|
|
Packit |
8f70b4 |
N_("Summarize disk usage.\n"
|
|
Packit |
8f70b4 |
" -a, --all write counts for all files, not just directories\n"
|
|
Packit |
8f70b4 |
" --block-size=SIZ use SIZ-byte blocks\n"
|
|
Packit |
8f70b4 |
" -b, --bytes print size in bytes\n"
|
|
Packit |
8f70b4 |
" -c, --total produce a grand total\n"
|
|
Packit |
8f70b4 |
" -d, --max-depth=N print the total for a directory (or file, with --all)\n"
|
|
Packit |
8f70b4 |
" only if it is N or fewer levels below the command\n"
|
|
Packit |
8f70b4 |
" line argument; --max-depth=0 is the same as\n"
|
|
Packit |
8f70b4 |
" --summarize\n"
|
|
Packit |
8f70b4 |
" -F, --files print number of files instead of sizes\n"
|
|
Packit |
8f70b4 |
" -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\n"
|
|
Packit |
8f70b4 |
" -H, --si likewise, but use powers of 1000 not 1024\n"
|
|
Packit |
8f70b4 |
" -k, --kilobytes like --block-size=1024\n"
|
|
Packit |
8f70b4 |
" -m, --megabytes like --block-size=1048576\n"
|
|
Packit |
8f70b4 |
" -S, --separate-dirs do not include size of subdirectories\n"
|
|
Packit |
8f70b4 |
" -s, --summarize display only a total for each argument\n"
|
|
Packit |
8f70b4 |
" --exclude=PAT exclude files that match PAT\n")},
|
|
Packit |
8f70b4 |
{"echo", cmd_echo, 0},
|
|
Packit |
8f70b4 |
{"edit", cmd_edit, N_("edit [OPTS] <file>"),
|
|
Packit |
8f70b4 |
N_("Retrieve remote file to a temporary location, run a local editor on it\n"
|
|
Packit |
8f70b4 |
"and upload the file back if changed.\n"
|
|
Packit |
8f70b4 |
" -k keep the temporary file\n"
|
|
Packit |
8f70b4 |
" -o <temp> explicit temporary file location\n")},
|
|
Packit |
8f70b4 |
{"eval", cmd_eval, 0},
|
|
Packit |
8f70b4 |
{"exit", cmd_exit, N_("exit [|bg]"),
|
|
Packit |
8f70b4 |
N_("exit - exit from lftp or move to background if jobs are active\n\n"
|
|
Packit |
8f70b4 |
"If no jobs active, the code is passed to operating system as lftp\n"
|
|
Packit |
8f70b4 |
"termination status. If omitted, exit code of last command is used.\n"
|
|
Packit |
8f70b4 |
"`bg' forces moving to background if cmd:move-background is false.\n")},
|
|
Packit |
8f70b4 |
{"fg", ALIAS_FOR(wait)},
|
|
Packit |
8f70b4 |
{"find", cmd_find,0,
|
|
Packit |
8f70b4 |
N_("Usage: find [OPTS] [directory]\n"
|
|
Packit |
8f70b4 |
"Print contents of specified directory or current directory recursively.\n"
|
|
Packit |
8f70b4 |
"Directories in the list are marked with trailing slash.\n"
|
|
Packit |
8f70b4 |
"You can redirect output of this command.\n"
|
|
Packit |
8f70b4 |
" -d, --maxdepth=LEVELS Descend at most LEVELS of directories.\n")},
|
|
Packit |
8f70b4 |
{"get", cmd_get, N_("get [OPTS] <rfile> [-o <lfile>]"),
|
|
Packit |
8f70b4 |
N_("Retrieve remote file <rfile> and store it to local file <lfile>.\n"
|
|
Packit |
8f70b4 |
" -o <lfile> specifies local file name (default - basename of rfile)\n"
|
|
Packit |
8f70b4 |
" -c continue, resume transfer\n"
|
|
Packit |
8f70b4 |
" -E delete remote files after successful transfer\n"
|
|
Packit |
8f70b4 |
" -a use ascii mode (binary is the default)\n"
|
|
Packit |
8f70b4 |
" -O <base> specifies base directory or URL where files should be placed\n")},
|
|
Packit |
8f70b4 |
{"get1", cmd_get1, 0,0},
|
|
Packit |
8f70b4 |
{"glob", cmd_glob, N_("glob [OPTS] <cmd> <args>"),
|
|
Packit |
8f70b4 |
N_(
|
|
Packit |
8f70b4 |
"Expand wildcards and run specified command.\n"
|
|
Packit |
8f70b4 |
"Options can be used to expand wildcards to list of files, directories,\n"
|
|
Packit |
8f70b4 |
"or both types. Type selection is not very reliable and depends on server.\n"
|
|
Packit |
8f70b4 |
"If entry type cannot be determined, it will be included in the list.\n"
|
|
Packit |
8f70b4 |
" -f plain files (default)\n"
|
|
Packit |
8f70b4 |
" -d directories\n"
|
|
Packit |
8f70b4 |
" -a all types\n"
|
|
Packit |
8f70b4 |
" --exist return zero exit code when the patterns expand to non-empty list\n"
|
|
Packit |
8f70b4 |
" --not-exist return zero exit code when the patterns expand to an empty list\n")},
|
|
Packit |
8f70b4 |
{"help", cmd_help, N_("help [<cmd>]"),
|
|
Packit |
8f70b4 |
N_("Print help for command <cmd>, or list of available commands\n")},
|
|
Packit |
8f70b4 |
{"jobs", cmd_jobs, "jobs [-v] [<job_no...>]",
|
|
Packit |
8f70b4 |
N_("List running jobs. -v means verbose, several -v can be specified.\n"
|
|
Packit |
8f70b4 |
"If <job_no> is specified, only list a job with that number.\n")},
|
|
Packit |
8f70b4 |
{"kill", cmd_kill, N_("kill all|<job_no>"),
|
|
Packit |
8f70b4 |
N_("Delete specified job with <job_no> or all jobs\n")},
|
|
Packit |
8f70b4 |
{"lcd", cmd_lcd, N_("lcd <ldir>"),
|
|
Packit |
8f70b4 |
N_("Change current local directory to <ldir>. The previous local directory\n"
|
|
Packit |
8f70b4 |
"is stored as `-'. You can do `lcd -' to change the directory back.\n")},
|
|
Packit |
8f70b4 |
{"lftp", cmd_lftp, N_("lftp [OPTS] <site>"),
|
|
Packit |
8f70b4 |
N_("`lftp' is the first command executed by lftp after rc files\n"
|
|
Packit |
8f70b4 |
" -f <file> execute commands from the file and exit\n"
|
|
Packit |
8f70b4 |
" -c <cmd> execute the commands and exit\n"
|
|
Packit |
8f70b4 |
" --norc don't execute rc files from the home directory\n"
|
|
Packit |
8f70b4 |
" --help print this help and exit\n"
|
|
Packit |
8f70b4 |
" --version print lftp version and exit\n"
|
|
Packit |
8f70b4 |
"Other options are the same as in `open' command:\n"
|
|
Packit |
8f70b4 |
" -e <cmd> execute the command just after selecting\n"
|
|
Packit |
8f70b4 |
" -u <user>[,<pass>] use the user/password for authentication\n"
|
|
Packit |
8f70b4 |
" -p <port> use the port for connection\n"
|
|
Packit |
8f70b4 |
" -s <slot> assign the connection to this slot\n"
|
|
Packit |
8f70b4 |
" -d switch on debugging mode\n"
|
|
Packit |
8f70b4 |
" <site> host name, URL or bookmark name\n")},
|
|
Packit |
8f70b4 |
{"ln", cmd_ln, N_("ln [-s] <file1> <file2>"),
|
|
Packit |
8f70b4 |
N_("Link <file1> to <file2>\n")},
|
|
Packit |
8f70b4 |
{"lpwd", cmd_lpwd},
|
|
Packit |
8f70b4 |
{"local", cmd_local},
|
|
Packit |
8f70b4 |
{"login", ALIAS_FOR(user)},
|
|
Packit |
8f70b4 |
{"ls", cmd_ls, N_("ls [<args>]"),
|
|
Packit |
8f70b4 |
N_("List remote files. You can redirect output of this command to file\n"
|
|
Packit |
8f70b4 |
"or via pipe to external command.\n"
|
|
Packit |
8f70b4 |
"By default, ls output is cached, to see new listing use `rels' or\n"
|
|
Packit |
8f70b4 |
"`cache flush'.\n"
|
|
Packit |
8f70b4 |
"See also `help cls'.\n")},
|
|
Packit |
8f70b4 |
{"mget", cmd_get, N_("mget [OPTS] <files>"),
|
|
Packit |
8f70b4 |
N_("Gets selected files with expanded wildcards\n"
|
|
Packit |
8f70b4 |
" -c continue, resume transfer\n"
|
|
Packit |
8f70b4 |
" -d create directories the same as in file names and get the\n"
|
|
Packit |
8f70b4 |
" files into them instead of current directory\n"
|
|
Packit |
8f70b4 |
" -E delete remote files after successful transfer\n"
|
|
Packit |
8f70b4 |
" -a use ascii mode (binary is the default)\n"
|
|
Packit |
8f70b4 |
" -O <base> specifies base directory or URL where files should be placed\n")},
|
|
Packit |
8f70b4 |
{"mirror", cmd_mirror, N_("mirror [OPTS] [remote [local]]"), HELP_IN_MODULE},
|
|
Packit |
8f70b4 |
{"mkdir", cmd_mkdir, N_("mkdir [OPTS] <dirs>"),
|
|
Packit |
8f70b4 |
N_("Make remote directories\n"
|
|
Packit |
8f70b4 |
" -p make all levels of path\n"
|
|
Packit |
8f70b4 |
" -f be quiet, suppress messages\n")},
|
|
Packit |
8f70b4 |
{"module", cmd_module, N_("module name [args]"),
|
|
Packit |
8f70b4 |
N_("Load module (shared object). The module should contain function\n"
|
|
Packit |
8f70b4 |
" void module_init(int argc,const char *const *argv)\n"
|
|
Packit |
8f70b4 |
"If name contains a slash, then the module is searched in current\n"
|
|
Packit |
8f70b4 |
"directory, otherwise in directories specified by setting module:path.\n")},
|
|
Packit |
8f70b4 |
{"more", cmd_cat, N_("more <files>"),
|
|
Packit |
8f70b4 |
N_("Same as `cat <files> | more'. if PAGER is set, it is used as filter\n")},
|
|
Packit |
8f70b4 |
{"mput", cmd_get, N_("mput [OPTS] <files>"),
|
|
Packit |
8f70b4 |
N_("Upload files with wildcard expansion\n"
|
|
Packit |
8f70b4 |
" -c continue, reput\n"
|
|
Packit |
8f70b4 |
" -d create directories the same as in file names and put the\n"
|
|
Packit |
8f70b4 |
" files into them instead of current directory\n"
|
|
Packit |
8f70b4 |
" -E delete local files after successful transfer (dangerous)\n"
|
|
Packit |
8f70b4 |
" -a use ascii mode (binary is the default)\n"
|
|
Packit |
8f70b4 |
" -O <base> specifies base directory or URL where files should be placed\n")},
|
|
Packit |
8f70b4 |
{"mrm", cmd_mrm, N_("mrm <files>"),
|
|
Packit |
8f70b4 |
N_("Removes specified files with wildcard expansion\n")},
|
|
Packit |
8f70b4 |
{"mv", cmd_mv, N_("mv <file1> <file2>"),
|
|
Packit |
8f70b4 |
N_("Rename <file1> to <file2>\n")},
|
|
Packit |
8f70b4 |
{"mmv", cmd_mmv, N_("mmv [OPTS] <files> <target-dir>"),
|
|
Packit |
8f70b4 |
N_("Move <files> to <target-directory> with wildcard expansion\n"
|
|
Packit |
8f70b4 |
" -O <dir> specifies the target directory (alternative way)\n")},
|
|
Packit |
8f70b4 |
{"nlist", cmd_ls, N_("[re]nlist [<args>]"),
|
|
Packit |
8f70b4 |
N_("List remote file names.\n"
|
|
Packit |
8f70b4 |
"By default, nlist output is cached, to see new listing use `renlist' or\n"
|
|
Packit |
8f70b4 |
"`cache flush'.\n")},
|
|
Packit |
8f70b4 |
{"open", cmd_open, N_("open [OPTS] <site>"),
|
|
Packit |
8f70b4 |
N_("Select a server, URL or bookmark\n"
|
|
Packit |
8f70b4 |
" -e <cmd> execute the command just after selecting\n"
|
|
Packit |
8f70b4 |
" -u <user>[,<pass>] use the user/password for authentication\n"
|
|
Packit |
8f70b4 |
" -p <port> use the port for connection\n"
|
|
Packit |
8f70b4 |
" -s <slot> assign the connection to this slot\n"
|
|
Packit |
8f70b4 |
" -d switch on debugging mode\n"
|
|
Packit |
8f70b4 |
" <site> host name, URL or bookmark name\n")},
|
|
Packit |
8f70b4 |
{"pget", cmd_get, N_("pget [OPTS] <rfile> [-o <lfile>]"),
|
|
Packit |
8f70b4 |
N_("Gets the specified file using several connections. This can speed up transfer,\n"
|
|
Packit |
8f70b4 |
"but loads the net heavily impacting other users. Use only if you really\n"
|
|
Packit |
8f70b4 |
"have to transfer the file ASAP.\n"
|
|
Packit |
8f70b4 |
"\nOptions:\n"
|
|
Packit |
8f70b4 |
" -c continue transfer. Requires <lfile>.lftp-pget-status file.\n"
|
|
Packit |
8f70b4 |
" -n <maxconn> set maximum number of connections (default is is taken from\n"
|
|
Packit |
8f70b4 |
" pget:default-n setting)\n"
|
|
Packit |
8f70b4 |
" -O <base> specifies base directory where files should be placed\n")},
|
|
Packit |
8f70b4 |
{"put", cmd_get, N_("put [OPTS] <lfile> [-o <rfile>]"),
|
|
Packit |
8f70b4 |
N_("Upload <lfile> with remote name <rfile>.\n"
|
|
Packit |
8f70b4 |
" -o <rfile> specifies remote file name (default - basename of lfile)\n"
|
|
Packit |
8f70b4 |
" -c continue, reput\n"
|
|
Packit |
8f70b4 |
" it requires permission to overwrite remote files\n"
|
|
Packit |
8f70b4 |
" -E delete local files after successful transfer (dangerous)\n"
|
|
Packit |
8f70b4 |
" -a use ascii mode (binary is the default)\n"
|
|
Packit |
8f70b4 |
" -O <base> specifies base directory or URL where files should be placed\n")},
|
|
Packit |
8f70b4 |
{"pwd", cmd_pwd, "pwd [-p]",
|
|
Packit |
8f70b4 |
N_("Print current remote URL.\n"
|
|
Packit |
8f70b4 |
" -p show password\n")},
|
|
Packit |
8f70b4 |
{"queue", cmd_queue, N_("queue [OPTS] [<cmd>]"),
|
|
Packit |
8f70b4 |
N_("\n"
|
|
Packit |
8f70b4 |
" queue [-n num] <command>\n\n"
|
|
Packit |
8f70b4 |
"Add the command to queue for current site. Each site has its own command\n"
|
|
Packit |
8f70b4 |
"queue. `-n' adds the command before the given item in the queue. It is\n"
|
|
Packit |
8f70b4 |
"possible to queue up a running job by using command `queue wait <jobno>'.\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
" queue --delete|-d [index or wildcard expression]\n\n"
|
|
Packit |
8f70b4 |
"Delete one or more items from the queue. If no argument is given, the last\n"
|
|
Packit |
8f70b4 |
"entry in the queue is deleted.\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
" queue --move|-m <index or wildcard expression> [index]\n\n"
|
|
Packit |
8f70b4 |
"Move the given items before the given queue index, or to the end if no\n"
|
|
Packit |
8f70b4 |
"destination is given.\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
"Options:\n"
|
|
Packit |
8f70b4 |
" -q Be quiet.\n"
|
|
Packit |
8f70b4 |
" -v Be verbose.\n"
|
|
Packit |
8f70b4 |
" -Q Output in a format that can be used to re-queue.\n"
|
|
Packit |
8f70b4 |
" Useful with --delete.\n"
|
|
Packit |
8f70b4 |
)},
|
|
Packit |
8f70b4 |
{"quit", ALIAS_FOR(exit)},
|
|
Packit |
8f70b4 |
{"quote", cmd_ls, N_("quote <cmd>"),
|
|
Packit |
8f70b4 |
N_("Send the command uninterpreted. Use with caution - it can lead to\n"
|
|
Packit |
8f70b4 |
"unknown remote state and thus will cause reconnect. You cannot\n"
|
|
Packit |
8f70b4 |
"be sure that any change of remote state because of quoted command\n"
|
|
Packit |
8f70b4 |
"is solid - it can be reset by reconnect at any time.\n")},
|
|
Packit |
8f70b4 |
{"recls", cmd_cls, 0,
|
|
Packit |
8f70b4 |
N_("recls [<args>]\n"
|
|
Packit |
8f70b4 |
"Same as `cls', but don't look in cache\n")},
|
|
Packit |
8f70b4 |
{"reget", cmd_get, 0,
|
|
Packit |
8f70b4 |
N_("Usage: reget [OPTS] <rfile> [-o <lfile>]\n"
|
|
Packit |
8f70b4 |
"Same as `get -c'\n")},
|
|
Packit |
8f70b4 |
{"rels", cmd_ls, 0,
|
|
Packit |
8f70b4 |
N_("Usage: rels [<args>]\n"
|
|
Packit |
8f70b4 |
"Same as `ls', but don't look in cache\n")},
|
|
Packit |
8f70b4 |
{"renlist", cmd_ls, 0,
|
|
Packit |
8f70b4 |
N_("Usage: renlist [<args>]\n"
|
|
Packit |
8f70b4 |
"Same as `nlist', but don't look in cache\n")},
|
|
Packit |
8f70b4 |
{"repeat", cmd_repeat, N_("repeat [OPTS] [delay] [command]"), HELP_IN_MODULE},
|
|
Packit |
8f70b4 |
{"reput", cmd_get, 0,
|
|
Packit |
8f70b4 |
N_("Usage: reput <lfile> [-o <rfile>]\n"
|
|
Packit |
8f70b4 |
"Same as `put -c'\n")},
|
|
Packit |
8f70b4 |
{"rm", cmd_rm, N_("rm [-r] [-f] <files>"),
|
|
Packit |
8f70b4 |
N_("Remove remote files\n"
|
|
Packit |
8f70b4 |
" -r recursive directory removal, be careful\n"
|
|
Packit |
8f70b4 |
" -f work quietly\n")},
|
|
Packit |
8f70b4 |
{"rmdir", cmd_rm, N_("rmdir [-f] <dirs>"),
|
|
Packit |
8f70b4 |
N_("Remove remote directories\n")},
|
|
Packit |
8f70b4 |
{"scache", cmd_scache, N_("scache [<session_no>]"),
|
|
Packit |
8f70b4 |
N_("List cached sessions or switch to specified session number\n")},
|
|
Packit |
8f70b4 |
{"set", cmd_set, N_("set [OPT] [ [<val>]]"),
|
|
Packit |
8f70b4 |
N_("Set variable to given value. If the value is omitted, unset the variable.\n"
|
|
Packit |
8f70b4 |
"Variable name has format ``name/closure'', where closure can specify\n"
|
|
Packit |
8f70b4 |
"exact application of the setting. See lftp(1) for details.\n"
|
|
Packit |
8f70b4 |
"If set is called with no variable then only altered settings are listed.\n"
|
|
Packit |
8f70b4 |
"It can be changed by options:\n"
|
|
Packit |
8f70b4 |
" -a list all settings, including default values\n"
|
|
Packit |
8f70b4 |
" -d list only default values, not necessary current ones\n")},
|
|
Packit |
8f70b4 |
{"shell", ALIAS_FOR2("!",shell)},
|
|
Packit |
8f70b4 |
{"site", cmd_ls, N_("site <site-cmd>"),
|
|
Packit |
8f70b4 |
N_("Execute site command <site_cmd> and output the result\n"
|
|
Packit |
8f70b4 |
"You can redirect its output\n")},
|
|
Packit |
8f70b4 |
{"sleep", cmd_sleep, 0, HELP_IN_MODULE},
|
|
Packit |
8f70b4 |
{"slot", cmd_slot, 0,
|
|
Packit |
8f70b4 |
N_("Usage: slot [<label>]\n"
|
|
Packit |
8f70b4 |
"List assigned slots.\n"
|
|
Packit |
8f70b4 |
"If <label> is specified, switch to the slot named <label>.\n")},
|
|
Packit |
8f70b4 |
{"source", cmd_source, N_("source <file>"),
|
|
Packit |
8f70b4 |
N_("Execute commands recorded in file <file>\n")},
|
|
Packit |
8f70b4 |
{"suspend", cmd_suspend},
|
|
Packit |
8f70b4 |
{"torrent", cmd_torrent, N_("torrent [OPTS] <file|URL>..."), HELP_IN_MODULE},
|
|
Packit |
8f70b4 |
{"user", cmd_user, N_("user <user|URL> [<pass>]"),
|
|
Packit |
8f70b4 |
N_("Use specified info for remote login. If you specify URL, the password\n"
|
|
Packit |
8f70b4 |
"will be cached for future usage.\n")},
|
|
Packit |
8f70b4 |
{"version", cmd_ver, 0,
|
|
Packit |
8f70b4 |
N_("Shows lftp version\n")},
|
|
Packit |
8f70b4 |
{"wait", cmd_wait, N_("wait [<jobno>]"),
|
|
Packit |
8f70b4 |
N_("Wait for specified job to terminate. If jobno is omitted, wait\n"
|
|
Packit |
8f70b4 |
"for last backgrounded job.\n")},
|
|
Packit |
8f70b4 |
{"zcat", cmd_cat, N_("zcat <files>"),
|
|
Packit |
8f70b4 |
N_("Same as cat, but filter each file through zcat\n")},
|
|
Packit |
8f70b4 |
{"zmore", cmd_cat, N_("zmore <files>"),
|
|
Packit |
8f70b4 |
N_("Same as more, but filter each file through zcat\n")},
|
|
Packit |
8f70b4 |
{"bzcat", cmd_cat, 0,
|
|
Packit |
8f70b4 |
N_("Same as cat, but filter each file through bzcat\n")},
|
|
Packit |
8f70b4 |
{"bzmore", cmd_cat, 0,
|
|
Packit |
8f70b4 |
N_("Same as more, but filter each file through bzcat\n")},
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
{".tasks", cmd_tasks, 0,0},
|
|
Packit |
8f70b4 |
{".empty", cmd_empty, 0,0},
|
|
Packit |
8f70b4 |
{".notempty",cmd_notempty,0,0},
|
|
Packit |
8f70b4 |
{".true", cmd_true, 0,0},
|
|
Packit |
8f70b4 |
{".false", cmd_false, 0,0},
|
|
Packit |
8f70b4 |
{".mplist", cmd_ls, 0,0},
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
const int CmdExec::static_cmd_table_length=sizeof(static_cmd_table)/sizeof(static_cmd_table[0]);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#define charcasecmp(a,b) (tolower((unsigned char)(a))-tolower((unsigned char)(b)))
|
|
Packit |
8f70b4 |
// returns:
|
|
Packit |
8f70b4 |
// 0 - no match
|
|
Packit |
8f70b4 |
// 1 - found, if *res==0 then ambiguous
|
|
Packit |
8f70b4 |
static
|
|
Packit |
8f70b4 |
int find_command(const char *unprec_name,const char * const *names,
|
|
Packit |
8f70b4 |
const char **res)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *match=0;
|
|
Packit |
8f70b4 |
for( ; *names; names++)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *s,*u;
|
|
Packit |
8f70b4 |
for(s=*names,u=unprec_name; *s && !charcasecmp(*u,*s); s++,u++)
|
|
Packit |
8f70b4 |
;
|
|
Packit |
8f70b4 |
if(*s && !*u)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(match)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
*res=0;
|
|
Packit |
8f70b4 |
return 1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
match=*names;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!*s && !*u)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
*res=*names;
|
|
Packit |
8f70b4 |
return 1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(match)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
*res=match;
|
|
Packit |
8f70b4 |
return 1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
*res=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Job *CmdExec::builtin_lcd()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->count()==1)
|
|
Packit |
8f70b4 |
args->Append("~");
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(args->count()!=2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s local-dir\n"),args->getarg(0));
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *cd_to=args->getarg(1);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!strcmp(cd_to,"-"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(old_lcwd)
|
|
Packit |
8f70b4 |
cd_to=old_lcwd;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
cd_to=expand_home_relative(cd_to);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(RestoreCWD()==-1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(cd_to[0]!='/')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("No current local directory, use absolute path.\n");
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int res=chdir(cd_to);
|
|
Packit |
8f70b4 |
if(res==-1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
perror(cd_to);
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
old_lcwd.set(cwd->GetName());
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
SaveCWD();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *name=cwd->GetName();
|
|
Packit |
8f70b4 |
if(interactive)
|
|
Packit |
8f70b4 |
eprintf(_("lcd ok, local cwd=%s\n"),name?name:"?");
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Job *CmdExec::builtin_cd()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->count()==1)
|
|
Packit |
8f70b4 |
args->Append("~");
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool is_file=false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(args->count()!=2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// xgettext:c-format
|
|
Packit |
8f70b4 |
eprintf(_("Usage: cd remote-dir\n"));
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *dir=args->getarg(1);
|
|
Packit |
8f70b4 |
const char *url=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!strcmp(dir,"-"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
dir=cwd_history.Lookup(session);
|
|
Packit |
8f70b4 |
if(!dir)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: no old directory for this site\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
args->setarg(1,dir); // for status line
|
|
Packit |
8f70b4 |
dir=args->getarg(1);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool dir_needs_slash=false;
|
|
Packit |
8f70b4 |
if(url::is_url(dir))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
ParsedURL u(dir,true);
|
|
Packit |
8f70b4 |
FileAccess *new_session=FileAccess::New(&u);
|
|
Packit |
8f70b4 |
bool same_site=session->SameSiteAs(new_session);
|
|
Packit |
8f70b4 |
Delete(new_session);
|
|
Packit |
8f70b4 |
if(!same_site)
|
|
Packit |
8f70b4 |
return builtin_open();
|
|
Packit |
8f70b4 |
url=dir;
|
|
Packit |
8f70b4 |
dir=alloca_strdup(u.path);
|
|
Packit |
8f70b4 |
dir_needs_slash=url::dir_needs_trailing_slash(u.proto);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
dir_needs_slash=url::dir_needs_trailing_slash(session->GetProto());
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(dir_needs_slash)
|
|
Packit |
8f70b4 |
is_file=(last_char(dir)!='/');
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int cache_is_dir=FileAccess::cache->IsDirectory(session,dir);
|
|
Packit |
8f70b4 |
if(cache_is_dir==1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(is_file && dir_needs_slash && last_char(dir)!='/')
|
|
Packit |
8f70b4 |
dir=xstring::get_tmp(dir).append('/');
|
|
Packit |
8f70b4 |
is_file=false;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(cache_is_dir==0)
|
|
Packit |
8f70b4 |
is_file=true;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
old_cwd=session->GetCwd();
|
|
Packit |
8f70b4 |
FileAccess::Path new_cwd(old_cwd);
|
|
Packit |
8f70b4 |
new_cwd.Change(dir,is_file);
|
|
Packit |
8f70b4 |
if(url)
|
|
Packit |
8f70b4 |
new_cwd.SetURL(url);
|
|
Packit |
8f70b4 |
if(!verify_path || background
|
|
Packit |
8f70b4 |
|| (!verify_path_cached && cache_is_dir==1))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
cwd_history.Set(session,old_cwd);
|
|
Packit |
8f70b4 |
session->SetCwd(new_cwd);
|
|
Packit |
8f70b4 |
if(slot)
|
|
Packit |
8f70b4 |
ConnectionSlot::SetCwd(slot,new_cwd);
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
session->PathVerify(new_cwd);
|
|
Packit |
8f70b4 |
session->Roll();
|
|
Packit |
8f70b4 |
builtin=BUILTIN_CD;
|
|
Packit |
8f70b4 |
return this;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Job *CmdExec::builtin_exit()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
bool detach=ResMgr::QueryBool("cmd:move-background-detach",0);
|
|
Packit |
8f70b4 |
bool bg=false;
|
|
Packit |
8f70b4 |
bool kill=false;
|
|
Packit |
8f70b4 |
int code=prev_exit_code;
|
|
Packit |
8f70b4 |
CmdExec *exec=this;
|
|
Packit |
8f70b4 |
const char *a;
|
|
Packit |
8f70b4 |
args->rewind();
|
|
Packit |
8f70b4 |
while((a=args->getnext())!=0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!strcmp(a,"bg"))
|
|
Packit |
8f70b4 |
bg=true;
|
|
Packit |
8f70b4 |
if(!strcmp(a,"top") || !strcmp(a,"bg"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(top)
|
|
Packit |
8f70b4 |
exec=top.get_non_const();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcmp(a,"parent"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(parent_exec)
|
|
Packit |
8f70b4 |
exec=parent_exec;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcmp(a,"kill"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
kill=true;
|
|
Packit |
8f70b4 |
bg=false;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(sscanf(a,"%i",&code)!=1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [<exit_code>]\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
// Note: one job is this CmdExec.
|
|
Packit |
8f70b4 |
if(!bg && exec->top_level
|
|
Packit |
8f70b4 |
&& !ResMgr::QueryBool("cmd:move-background",0) && NumberOfChildrenJobs()>0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_(
|
|
Packit |
8f70b4 |
"There are running jobs and `cmd:move-background' is not set.\n"
|
|
Packit |
8f70b4 |
"Use `exit bg' to force moving to background or `kill all' to terminate jobs.\n"
|
|
Packit |
8f70b4 |
));
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!detach && Job::NumberOfChildrenJobs()==0)
|
|
Packit |
8f70b4 |
detach=true;
|
|
Packit |
8f70b4 |
if(kill)
|
|
Packit |
8f70b4 |
Job::KillAll();
|
|
Packit |
8f70b4 |
if(detach) {
|
|
Packit |
8f70b4 |
for(CmdExec *e=this; e!=exec; e=e->parent_exec)
|
|
Packit |
8f70b4 |
e->Exit(code);
|
|
Packit |
8f70b4 |
exec->Exit(code);
|
|
Packit |
8f70b4 |
} else {
|
|
Packit |
8f70b4 |
int loc=0;
|
|
Packit |
8f70b4 |
exec->SetAutoTerminateInBackground(true);
|
|
Packit |
8f70b4 |
eprintf(_(
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
"lftp now tricks the shell to move it to background process group.\n"
|
|
Packit |
8f70b4 |
"lftp continues to run in the background despite the `Stopped' message.\n"
|
|
Packit |
8f70b4 |
"lftp will automatically terminate when all jobs are finished.\n"
|
|
Packit |
8f70b4 |
"Use `fg' shell command to return to lftp if it is still running.\n"
|
|
Packit |
8f70b4 |
));
|
|
Packit |
8f70b4 |
// trick the shell
|
|
Packit |
8f70b4 |
switch(pid_t pid=fork()) {
|
|
Packit |
8f70b4 |
case 0: // child
|
|
Packit |
8f70b4 |
sleep(1); // wait for the parent to stop (is there a safer way?)
|
|
Packit |
8f70b4 |
::kill(getppid(),SIGCONT);
|
|
Packit |
8f70b4 |
_exit(0);
|
|
Packit |
8f70b4 |
default: // parent
|
|
Packit |
8f70b4 |
raise(SIGSTOP);
|
|
Packit |
8f70b4 |
waitpid(pid,&loc,0); // clean-up
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case -1:
|
|
Packit |
8f70b4 |
exec->Exit(code);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
exit_code=code;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void CmdExec::Exit(int code)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
while(feeder)
|
|
Packit |
8f70b4 |
RemoveFeeder();
|
|
Packit |
8f70b4 |
cmd_buf.Empty();
|
|
Packit |
8f70b4 |
if(interactive)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
ListDoneJobs();
|
|
Packit |
8f70b4 |
BuryDoneJobs();
|
|
Packit |
8f70b4 |
if(FindJob(last_bg)==0)
|
|
Packit |
8f70b4 |
last_bg=-1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
exit_code=prev_exit_code=code;
|
|
Packit |
8f70b4 |
return;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void CmdExec::enable_debug(const char *opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int level=DEFAULT_DEBUG_LEVEL;
|
|
Packit |
8f70b4 |
if(opt && isdigit((unsigned char)opt[0]))
|
|
Packit |
8f70b4 |
level=atoi(opt);
|
|
Packit |
8f70b4 |
const char *c="debug";
|
|
Packit |
8f70b4 |
ResMgr::Set("log:enabled",c,"yes");
|
|
Packit |
8f70b4 |
ResMgr::Set("log:level",c,xstring::format("%d",level));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CmdFeeder *lftp_feeder=0;
|
|
Packit |
8f70b4 |
Job *CmdExec::builtin_lftp()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int c;
|
|
Packit |
8f70b4 |
xstring cmd;
|
|
Packit |
8f70b4 |
xstring rc;
|
|
Packit |
8f70b4 |
ArgV open("open");
|
|
Packit |
8f70b4 |
open.Add("--lftp");
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum {
|
|
Packit |
8f70b4 |
OPT_USER,
|
|
Packit |
8f70b4 |
OPT_PASSWORD,
|
|
Packit |
8f70b4 |
OPT_ENV_PASSWORD,
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
static struct option lftp_options[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"help",no_argument,0,'h'},
|
|
Packit |
8f70b4 |
{"version",no_argument,0,'v'},
|
|
Packit |
8f70b4 |
{"debug",optional_argument,0,'d'},
|
|
Packit |
8f70b4 |
{"rcfile",required_argument,0,'r'},
|
|
Packit |
8f70b4 |
// other options are for "open" command
|
|
Packit |
8f70b4 |
{"port",required_argument,0,'p'},
|
|
Packit |
8f70b4 |
{"user",required_argument,0,OPT_USER},
|
|
Packit |
8f70b4 |
{"password",required_argument,0,OPT_PASSWORD},
|
|
Packit |
8f70b4 |
{"env-password",no_argument,0,OPT_ENV_PASSWORD},
|
|
Packit |
8f70b4 |
{"execute",required_argument,0,'e'},
|
|
Packit |
8f70b4 |
{"no-bookmark",no_argument,0,'B'},
|
|
Packit |
8f70b4 |
{"slot",required_argument,0,'s'},
|
|
Packit |
8f70b4 |
{0,0,0,0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
while((c=args->getopt_long("+f:c:vhdu:p:e:s:B",lftp_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(c)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('h'):
|
|
Packit |
8f70b4 |
cmd.set("help lftp;");
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('v'):
|
|
Packit |
8f70b4 |
cmd.set("version;");
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('f'):
|
|
Packit |
8f70b4 |
cmd.set("source ");
|
|
Packit |
8f70b4 |
cmd.append_quoted(optarg);
|
|
Packit |
8f70b4 |
cmd.append(';');
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('c'):
|
|
Packit |
8f70b4 |
args->CombineCmdTo(cmd,args->getindex()-1).append("\n\n");
|
|
Packit |
8f70b4 |
args->seek(args->count());
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('d'):
|
|
Packit |
8f70b4 |
enable_debug(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('r'):
|
|
Packit |
8f70b4 |
rc.append("&&source ").append_quoted(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// "open" command options are passed along
|
|
Packit |
8f70b4 |
case('s'):
|
|
Packit |
8f70b4 |
open.Add("-s");
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('p'):
|
|
Packit |
8f70b4 |
open.Add("-p").Add(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('u'):
|
|
Packit |
8f70b4 |
open.Add("-u").Add(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case(OPT_USER):
|
|
Packit |
8f70b4 |
open.Add("--user").Add(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case(OPT_PASSWORD):
|
|
Packit |
8f70b4 |
open.Add("--password").Add(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case(OPT_ENV_PASSWORD):
|
|
Packit |
8f70b4 |
open.Add("--env-password");
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('e'):
|
|
Packit |
8f70b4 |
open.Add("-e").Add(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('B'):
|
|
Packit |
8f70b4 |
open.Add("-B");
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
eprintf(_("Try `%s --help' for more information\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
for(const char *arg=args->getcurr(); arg; arg=args->getnext())
|
|
Packit |
8f70b4 |
open.Add(arg);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// feeder should be set before PrependCmd
|
|
Packit |
8f70b4 |
if(!cmd && lftp_feeder) // no feeder and no commands
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
SetCmdFeeder(lftp_feeder);
|
|
Packit |
8f70b4 |
lftp_feeder=0;
|
|
Packit |
8f70b4 |
FeedCmd("||command exit\n"); // if the command fails, quit
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// prepended commands are executed in reverse order: rc, cmd, open
|
|
Packit |
8f70b4 |
if(open.count()>2) {
|
|
Packit |
8f70b4 |
if(cmd) {
|
|
Packit |
8f70b4 |
eprintf(_("%s: -c, -f, -v, -h conflict with other `open' options and arguments\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
xstring_ca open_cmd(open.CombineQuoted());
|
|
Packit |
8f70b4 |
PrependCmd(open_cmd);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(cmd)
|
|
Packit |
8f70b4 |
PrependCmd(cmd);
|
|
Packit |
8f70b4 |
if(rc)
|
|
Packit |
8f70b4 |
PrependCmd(rc);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Job *CmdExec::builtin_open()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
ReuseSavedSession();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *port=NULL;
|
|
Packit |
8f70b4 |
const char *host=NULL;
|
|
Packit |
8f70b4 |
const char *path=NULL;
|
|
Packit |
8f70b4 |
const char *user=NULL;
|
|
Packit |
8f70b4 |
const char *pass=NULL;
|
|
Packit |
8f70b4 |
int c;
|
|
Packit |
8f70b4 |
NetRC::Entry *nrc=0;
|
|
Packit |
8f70b4 |
char *cmd_to_exec=0;
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
bool insecure=false;
|
|
Packit |
8f70b4 |
bool no_bm=false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum {
|
|
Packit |
8f70b4 |
OPT_USER,
|
|
Packit |
8f70b4 |
OPT_PASSWORD,
|
|
Packit |
8f70b4 |
OPT_ENV_PASSWORD,
|
|
Packit |
8f70b4 |
OPT_LFTP,
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
static struct option open_options[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"port",required_argument,0,'p'},
|
|
Packit |
8f70b4 |
{"user",required_argument,0,OPT_USER},
|
|
Packit |
8f70b4 |
{"password",required_argument,0,OPT_PASSWORD},
|
|
Packit |
8f70b4 |
{"env-password",no_argument,0,OPT_ENV_PASSWORD},
|
|
Packit |
8f70b4 |
{"execute",required_argument,0,'e'},
|
|
Packit |
8f70b4 |
{"debug",optional_argument,0,'d'},
|
|
Packit |
8f70b4 |
{"no-bookmark",no_argument,0,'B'},
|
|
Packit |
8f70b4 |
{"slot",required_argument,0,'s'},
|
|
Packit |
8f70b4 |
{"lftp",no_argument,0,OPT_LFTP},
|
|
Packit |
8f70b4 |
{0,0,0,0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
while((c=args->getopt_long("u:p:e:s:dB",open_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(c)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('s'):
|
|
Packit |
8f70b4 |
if (*optarg) ChangeSlot(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('p'):
|
|
Packit |
8f70b4 |
port=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('u'):
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
user=optarg;
|
|
Packit |
8f70b4 |
char *sep=strchr(optarg,',');
|
|
Packit |
8f70b4 |
if(sep==NULL)
|
|
Packit |
8f70b4 |
sep=strchr(optarg,' ');
|
|
Packit |
8f70b4 |
if(sep==NULL)
|
|
Packit |
8f70b4 |
sep=strchr(optarg,':');
|
|
Packit |
8f70b4 |
if(sep==NULL)
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
*sep=0;
|
|
Packit |
8f70b4 |
pass=sep+1;
|
|
Packit |
8f70b4 |
insecure=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
case(OPT_USER):
|
|
Packit |
8f70b4 |
user=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case(OPT_PASSWORD):
|
|
Packit |
8f70b4 |
pass=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case(OPT_ENV_PASSWORD):
|
|
Packit |
8f70b4 |
pass=getenv("LFTP_PASSWORD");
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('d'):
|
|
Packit |
8f70b4 |
enable_debug(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('e'):
|
|
Packit |
8f70b4 |
cmd_to_exec=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('B'):
|
|
Packit |
8f70b4 |
no_bm=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case(OPT_LFTP):
|
|
Packit |
8f70b4 |
op="lftp";
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [-e cmd] [-p port] [-u user[,pass]] <host|url>\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(optind<args->count())
|
|
Packit |
8f70b4 |
host=args->getarg(optind++);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Ref<ParsedURL> url;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *bm=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(cmd_to_exec)
|
|
Packit |
8f70b4 |
PrependCmd(cmd_to_exec);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!no_bm && host && (bm=lftp_bookmarks.Lookup(host))!=0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring& cmd=xstring::get_tmp("open -B ");
|
|
Packit |
8f70b4 |
if(user)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
cmd.append("--user ").append_quoted(user);
|
|
Packit |
8f70b4 |
if(pass)
|
|
Packit |
8f70b4 |
cmd.append(" --password ").append_quoted(pass);
|
|
Packit |
8f70b4 |
cmd.append(' ');
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(port)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
cmd.append("-p ");
|
|
Packit |
8f70b4 |
cmd.append_quoted(port);
|
|
Packit |
8f70b4 |
cmd.append(' ');
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
cmd.append(bm);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(background)
|
|
Packit |
8f70b4 |
cmd.append(" &\n");
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
cmd.append(";\n");
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
PrependCmd(cmd);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(host && host[0])
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
url=new ParsedURL(host);
|
|
Packit |
8f70b4 |
bool no_proto=(!url->proto);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(no_proto && url->host)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *p=ResMgr::Query("cmd:default-protocol",url->host);
|
|
Packit |
8f70b4 |
if(!p)
|
|
Packit |
8f70b4 |
p="ftp";
|
|
Packit |
8f70b4 |
url=new ParsedURL(xstring::format("%s://%s",p,host));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(user || port)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(user)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
url->user.set(user);
|
|
Packit |
8f70b4 |
url->pass.set(pass);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(port)
|
|
Packit |
8f70b4 |
url->port.set(port);
|
|
Packit |
8f70b4 |
xstring_ca host1(url->Combine());
|
|
Packit |
8f70b4 |
url=new ParsedURL(host1);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const ParsedURL &uc=*url;
|
|
Packit |
8f70b4 |
if(uc.host && uc.host[0] && uc.proto)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
cwd_history.Set(session,session->GetCwd());
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(uc.user && !user)
|
|
Packit |
8f70b4 |
user=uc.user;
|
|
Packit |
8f70b4 |
if(uc.pass && !pass)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
pass=uc.pass;
|
|
Packit |
8f70b4 |
insecure=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
host=uc.host;
|
|
Packit |
8f70b4 |
if(uc.port && !port)
|
|
Packit |
8f70b4 |
port=uc.port;
|
|
Packit |
8f70b4 |
if(uc.path && !path)
|
|
Packit |
8f70b4 |
path=uc.path;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileAccess *new_session=FileAccess::New(uc.proto,host,port);
|
|
Packit |
8f70b4 |
if(!new_session)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s: %s%s\n",op,uc.proto.get(),
|
|
Packit |
8f70b4 |
_(" - not supported protocol"));
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
saved_session=session.borrow();
|
|
Packit |
8f70b4 |
ChangeSession(new_session);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// user gets substituted only if no proto is specified.
|
|
Packit |
8f70b4 |
if(!pass && (user || no_proto))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
nrc=NetRC::LookupHost(host,user);
|
|
Packit |
8f70b4 |
if(nrc)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!user)
|
|
Packit |
8f70b4 |
ProtoLog::LogNote(3,"using user `%s' and password from ~/.netrc",nrc->user.get());
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
ProtoLog::LogNote(3,"using password from ~/.netrc");
|
|
Packit |
8f70b4 |
user=nrc->user;
|
|
Packit |
8f70b4 |
pass=nrc->pass;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(host && !host[0])
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
ChangeSession(new DummyProto);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(host && host[0] && session->GetHostName()==0)
|
|
Packit |
8f70b4 |
session->Connect(host,port);
|
|
Packit |
8f70b4 |
if(user && *session->GetProto())
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!pass)
|
|
Packit |
8f70b4 |
pass=GetPass(_("Password: "));
|
|
Packit |
8f70b4 |
if(!pass)
|
|
Packit |
8f70b4 |
eprintf(_("%s: GetPass() failed -- assume anonymous login\n"),
|
|
Packit |
8f70b4 |
args->getarg(0));
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
session->Login(user,pass);
|
|
Packit |
8f70b4 |
// assume the new password is the correct one.
|
|
Packit |
8f70b4 |
session->SetPasswordGlobal(pass);
|
|
Packit |
8f70b4 |
session->InsecurePassword(insecure && !no_bm);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(host && host[0])
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(verify_host && !background)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
session->ConnectVerify();
|
|
Packit |
8f70b4 |
builtin=BUILTIN_OPEN;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(nrc)
|
|
Packit |
8f70b4 |
delete nrc;
|
|
Packit |
8f70b4 |
} // !bookmark
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(path)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *old=cwd_history.Lookup(session);
|
|
Packit |
8f70b4 |
if(old)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
bool is_file=false;
|
|
Packit |
8f70b4 |
const char *old_url=0;
|
|
Packit |
8f70b4 |
if(url::is_url(old))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
ParsedURL u(old,true);
|
|
Packit |
8f70b4 |
old_url=old;
|
|
Packit |
8f70b4 |
old=alloca_strdup(u.path);
|
|
Packit |
8f70b4 |
if(url::dir_needs_trailing_slash(u.proto))
|
|
Packit |
8f70b4 |
is_file=(last_char(old)!='/');
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(url::dir_needs_trailing_slash(session->GetProto()))
|
|
Packit |
8f70b4 |
is_file=(last_char(old)!='/');
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
session->SetCwd(FileAccess::Path(old,is_file,old_url));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *cd_arg=(url && url->orig_url)?url->orig_url.get():path;
|
|
Packit |
8f70b4 |
xstring& s=xstring::get_tmp("&& cd ");
|
|
Packit |
8f70b4 |
s.append_quoted(cd_arg);
|
|
Packit |
8f70b4 |
if(background)
|
|
Packit |
8f70b4 |
s.append('&';;
|
|
Packit |
8f70b4 |
s.append('\n');
|
|
Packit |
8f70b4 |
PrependCmd(s);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(slot)
|
|
Packit |
8f70b4 |
ConnectionSlot::Set(slot,session);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Reconfig(0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(builtin==BUILTIN_OPEN)
|
|
Packit |
8f70b4 |
return this;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
ReuseSavedSession();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Job *CmdExec::builtin_restart()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
builtin=BUILTIN_EXEC_RESTART;
|
|
Packit |
8f70b4 |
return this;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Job *CmdExec::builtin_glob()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
GlobURL::type_select glob_type=GlobURL::FILES_ONLY;
|
|
Packit |
8f70b4 |
const char *cmd=0;
|
|
Packit |
8f70b4 |
bool nullglob=false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static struct option glob_options[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"exist",no_argument,0,'e'},
|
|
Packit |
8f70b4 |
{"not-exist",no_argument,0,'E'},
|
|
Packit |
8f70b4 |
{0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
while((opt=args->getopt_long("+adf",glob_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('a'):
|
|
Packit |
8f70b4 |
glob_type=GlobURL::ALL;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('d'):
|
|
Packit |
8f70b4 |
glob_type=GlobURL::DIRS_ONLY;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('f'):
|
|
Packit |
8f70b4 |
glob_type=GlobURL::FILES_ONLY;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('e'):
|
|
Packit |
8f70b4 |
cmd=".notempty";
|
|
Packit |
8f70b4 |
nullglob=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('E'):
|
|
Packit |
8f70b4 |
cmd=".empty";
|
|
Packit |
8f70b4 |
nullglob=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
while(args->getindex()>1)
|
|
Packit |
8f70b4 |
args->delarg(1); // remove options.
|
|
Packit |
8f70b4 |
if(cmd)
|
|
Packit |
8f70b4 |
args->insarg(1,cmd);
|
|
Packit |
8f70b4 |
if(args->count()<2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [OPTS] command args...\n"),op);
|
|
Packit |
8f70b4 |
RevertToSavedSession();
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
assert(args_glob==0 && glob==0);
|
|
Packit |
8f70b4 |
args_glob=new ArgV();
|
|
Packit |
8f70b4 |
args->rewind();
|
|
Packit |
8f70b4 |
args_glob->Append(args->getnext());
|
|
Packit |
8f70b4 |
const char *pat=args->getnext();
|
|
Packit |
8f70b4 |
if(!pat)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
args_glob=0;
|
|
Packit |
8f70b4 |
args->rewind();
|
|
Packit |
8f70b4 |
RevertToSavedSession();
|
|
Packit |
8f70b4 |
return cmd_command(this);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
glob=new GlobURL(session,pat,glob_type);
|
|
Packit |
8f70b4 |
if(nullglob)
|
|
Packit |
8f70b4 |
glob->NullGlob();
|
|
Packit |
8f70b4 |
builtin=BUILTIN_GLOB;
|
|
Packit |
8f70b4 |
return this;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Job *CmdExec::builtin_queue()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
static struct option queue_options[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"move",required_argument,0,'m'},
|
|
Packit |
8f70b4 |
{"delete",no_argument,0,'d'},
|
|
Packit |
8f70b4 |
{"quiet",no_argument,0,'q'},
|
|
Packit |
8f70b4 |
{"verbose",no_argument,0,'v'},
|
|
Packit |
8f70b4 |
{"queue",required_argument,0,'Q'},
|
|
Packit |
8f70b4 |
{0,0,0,0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
enum { ins, del, move } mode = ins;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *arg = NULL;
|
|
Packit |
8f70b4 |
/* position to insert at (ins only) */
|
|
Packit |
8f70b4 |
int pos = -1; /* default to the end */
|
|
Packit |
8f70b4 |
int verbose = -1; /* default */
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
while((opt=args->getopt_long("+dm:n:qvQw",queue_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case 'n':
|
|
Packit |
8f70b4 |
/* Actually, sending pos == -1 will work, but it'll put the
|
|
Packit |
8f70b4 |
* job at the end; it's confusing for "-n 0" to mean "put
|
|
Packit |
8f70b4 |
* it at the end", and that's the default anyway, so disallow
|
|
Packit |
8f70b4 |
* it. */
|
|
Packit |
8f70b4 |
if(!isdigit((unsigned char)optarg[0]) || atoi(optarg) == 0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: -n: positive number expected. "), args->a0());
|
|
Packit |
8f70b4 |
goto err;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
/* make offsets match the jobs output (starting at 1) */
|
|
Packit |
8f70b4 |
pos = atoi(optarg) - 1;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case 'm':
|
|
Packit |
8f70b4 |
mode = move;
|
|
Packit |
8f70b4 |
arg = optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case 'd':
|
|
Packit |
8f70b4 |
mode = del;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case 'q':
|
|
Packit |
8f70b4 |
verbose = 0;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case 'v':
|
|
Packit |
8f70b4 |
verbose = 2;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case 'Q':
|
|
Packit |
8f70b4 |
verbose = QueueFeeder::PrintRequeue;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case '?':
|
|
Packit |
8f70b4 |
err:
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(verbose == -1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(mode == ins || mode == move)
|
|
Packit |
8f70b4 |
verbose = 0;
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
verbose = 1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const int args_remaining = args->count() - args->getindex();
|
|
Packit |
8f70b4 |
switch(mode) {
|
|
Packit |
8f70b4 |
case ins: {
|
|
Packit |
8f70b4 |
CmdExec *queue=GetQueue(false);
|
|
Packit |
8f70b4 |
if(args_remaining==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!queue)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(verbose)
|
|
Packit |
8f70b4 |
printf(_("Created a stopped queue.\n"));
|
|
Packit |
8f70b4 |
queue=GetQueue(true);
|
|
Packit |
8f70b4 |
queue->Suspend();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring& buf=xstring::get_tmp("");
|
|
Packit |
8f70b4 |
queue->FormatStatus(buf,2,"");
|
|
Packit |
8f70b4 |
printf("%s",buf.get());
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!queue)
|
|
Packit |
8f70b4 |
queue=GetQueue(true);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring_ca cmd(args->CombineCmd(args->getindex()));
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!strcasecmp(cmd,"stop"))
|
|
Packit |
8f70b4 |
queue->Suspend();
|
|
Packit |
8f70b4 |
else if(!strcasecmp(cmd,"start"))
|
|
Packit |
8f70b4 |
queue->Resume();
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
queue->queue_feeder->QueueCmd(cmd, session->GetCwd(),
|
|
Packit |
8f70b4 |
cwd?cwd->GetName():0, pos, verbose);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
last_bg=queue->jobno;
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case del: {
|
|
Packit |
8f70b4 |
/* Accept:
|
|
Packit |
8f70b4 |
* queue -d (delete the last job)
|
|
Packit |
8f70b4 |
* queue -d 1 (delete entry 1)
|
|
Packit |
8f70b4 |
* queue -d "get" (delete all *get*)
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* We want an optional argument, but don't use getopt ::, since
|
|
Packit |
8f70b4 |
* that'll disallow the space between arguments, which we want. */
|
|
Packit |
8f70b4 |
arg = args->getarg(args->getindex());
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CmdExec *queue=GetQueue(false);
|
|
Packit |
8f70b4 |
if(!queue) {
|
|
Packit |
8f70b4 |
eprintf(_("%s: No queue is active.\n"), args->a0());
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!arg)
|
|
Packit |
8f70b4 |
exit_code=!queue->queue_feeder->DelJob(-1, verbose); /* delete the last job */
|
|
Packit |
8f70b4 |
else if(atoi(arg) != 0)
|
|
Packit |
8f70b4 |
exit_code=!queue->queue_feeder->DelJob(atoi(arg)-1, verbose);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
exit_code=!queue->queue_feeder->DelJob(arg, verbose);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case move: {
|
|
Packit |
8f70b4 |
/* Accept:
|
|
Packit |
8f70b4 |
* queue -m 1 2 (move entry 1 to position 2)
|
|
Packit |
8f70b4 |
* queue -m "*get*" 1
|
|
Packit |
8f70b4 |
* queue -m 3 (move entry 3 to the end) */
|
|
Packit |
8f70b4 |
const char *a1 = args->getarg(args->getindex());
|
|
Packit |
8f70b4 |
if(a1 && !isdigit((unsigned char)a1[0])) {
|
|
Packit |
8f70b4 |
eprintf(_("%s: -m: Number expected as second argument. "), args->a0());
|
|
Packit |
8f70b4 |
goto err;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
/* default to moving to the end */
|
|
Packit |
8f70b4 |
int to = a1? atoi(a1)-1:-1;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CmdExec *queue=GetQueue(false);
|
|
Packit |
8f70b4 |
if(!queue) {
|
|
Packit |
8f70b4 |
eprintf(_("%s: No queue is active.\n"), args->a0());
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(atoi(arg) != 0) {
|
|
Packit |
8f70b4 |
exit_code=!queue->queue_feeder->MoveJob(atoi(arg)-1, to, verbose);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exit_code=!queue->queue_feeder->MoveJob(arg, to, verbose);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// below are only non-builtin commands
|
|
Packit |
8f70b4 |
#define args (parent->args)
|
|
Packit |
8f70b4 |
#define exit_code (parent->exit_code)
|
|
Packit |
8f70b4 |
#define output (parent->output)
|
|
Packit |
8f70b4 |
#define session (parent->session)
|
|
Packit |
8f70b4 |
#define eprintf parent->eprintf
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(lcd)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return parent->builtin_lcd();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(ls)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
bool nlist=false;
|
|
Packit |
8f70b4 |
bool re=false;
|
|
Packit |
8f70b4 |
int mode=FA::LIST;
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
bool ascii=true;
|
|
Packit |
8f70b4 |
if(strstr(op,"nlist"))
|
|
Packit |
8f70b4 |
nlist=true;
|
|
Packit |
8f70b4 |
if(!strncmp(op,"re",2))
|
|
Packit |
8f70b4 |
re=true;
|
|
Packit |
8f70b4 |
if(!strcmp(op,"quote") || !strcmp(op,"site"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->count()<=1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s <cmd>\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
nlist=true;
|
|
Packit |
8f70b4 |
ascii=false;
|
|
Packit |
8f70b4 |
mode=FA::QUOTE_CMD;
|
|
Packit |
8f70b4 |
if(!strcmp(op,"site"))
|
|
Packit |
8f70b4 |
args->insarg(1,"SITE");
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcmp(op,".mplist")) {
|
|
Packit |
8f70b4 |
nlist=true;
|
|
Packit |
8f70b4 |
mode=FA::MP_LIST;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring_ca a(args->Combine(nlist?1:0));
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *var_ls=ResMgr::Query("cmd:ls-default",session->GetConnectURL(FA::NO_PATH));
|
|
Packit |
8f70b4 |
if(!nlist && args->count()==1 && var_ls[0])
|
|
Packit |
8f70b4 |
args->Append(var_ls);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool no_status=(!output || output->usesfd(1));
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileCopyPeer *src_peer=0;
|
|
Packit |
8f70b4 |
if(!nlist)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FileCopyPeerDirList *dir_list=new FileCopyPeerDirList(session->Clone(),args.borrow());
|
|
Packit |
8f70b4 |
dir_list->UseColor(ResMgr::QueryTriBool("color:use-color",0,(!output && isatty(1))));
|
|
Packit |
8f70b4 |
src_peer=dir_list;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
src_peer=new FileCopyPeerFA(session->Clone(),a,mode);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(re)
|
|
Packit |
8f70b4 |
src_peer->NoCache();
|
|
Packit |
8f70b4 |
src_peer->SetDate(NO_DATE);
|
|
Packit |
8f70b4 |
src_peer->SetSize(NO_SIZE);
|
|
Packit |
8f70b4 |
FileCopyPeer *dst_peer=new FileCopyPeerFDStream(output.borrow(),FileCopyPeer::PUT);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileCopy *c=FileCopy::New(src_peer,dst_peer,false);
|
|
Packit |
8f70b4 |
c->DontCopyDate();
|
|
Packit |
8f70b4 |
c->LineBuffered();
|
|
Packit |
8f70b4 |
if(ascii)
|
|
Packit |
8f70b4 |
c->Ascii();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CopyJob *j=new CopyJob(c,a,op);
|
|
Packit |
8f70b4 |
if(no_status)
|
|
Packit |
8f70b4 |
j->NoStatusOnWrite();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/* this seems to belong here more than in FileSetOutput.cc ... */
|
|
Packit |
8f70b4 |
const char *FileSetOutput::parse_argv(const Ref<ArgV>& a)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
enum {
|
|
Packit |
8f70b4 |
OPT_BLOCK_SIZE,
|
|
Packit |
8f70b4 |
OPT_DATE,
|
|
Packit |
8f70b4 |
OPT_FILESIZE,
|
|
Packit |
8f70b4 |
OPT_GROUP,
|
|
Packit |
8f70b4 |
OPT_LINKCOUNT,
|
|
Packit |
8f70b4 |
OPT_LINKS,
|
|
Packit |
8f70b4 |
OPT_PERMS,
|
|
Packit |
8f70b4 |
OPT_SI,
|
|
Packit |
8f70b4 |
OPT_SORT,
|
|
Packit |
8f70b4 |
OPT_TIME_STYLE,
|
|
Packit |
8f70b4 |
OPT_USER
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
static struct option cls_options[] = {
|
|
Packit |
8f70b4 |
{"all",no_argument,0,'a'},
|
|
Packit |
8f70b4 |
{"basename",no_argument,0,'B'},
|
|
Packit |
8f70b4 |
{"directory",no_argument,0,'d'},
|
|
Packit |
8f70b4 |
{"human-readable",no_argument,0,'h'},
|
|
Packit |
8f70b4 |
{"block-size",required_argument,0,OPT_BLOCK_SIZE},
|
|
Packit |
8f70b4 |
{"si",no_argument,0,OPT_SI},
|
|
Packit |
8f70b4 |
{"classify",no_argument,0,'F'},
|
|
Packit |
8f70b4 |
{"long",no_argument,0,'l'},
|
|
Packit |
8f70b4 |
{"quiet",no_argument,0,'q'},
|
|
Packit |
8f70b4 |
{"size",no_argument,0,'s'}, /* show size */
|
|
Packit |
8f70b4 |
{"filesize",no_argument,0,OPT_FILESIZE}, /* for files only */
|
|
Packit |
8f70b4 |
{"nocase",no_argument,0,'i'},
|
|
Packit |
8f70b4 |
{"sortnocase",no_argument,0,'I'},
|
|
Packit |
8f70b4 |
{"dirsfirst",no_argument,0,'D'},
|
|
Packit |
8f70b4 |
{"time-style",required_argument,0,OPT_TIME_STYLE},
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
{"sort",required_argument,0,OPT_SORT},
|
|
Packit |
8f70b4 |
{"reverse",no_argument,0,'r'},
|
|
Packit |
8f70b4 |
{"user",no_argument,0,OPT_USER},
|
|
Packit |
8f70b4 |
{"group",no_argument,0,OPT_GROUP},
|
|
Packit |
8f70b4 |
{"perms",no_argument,0,OPT_PERMS},
|
|
Packit |
8f70b4 |
{"date",no_argument,0,OPT_DATE},
|
|
Packit |
8f70b4 |
{"linkcount",no_argument,0,OPT_LINKCOUNT},
|
|
Packit |
8f70b4 |
{"links",no_argument,0,OPT_LINKS},
|
|
Packit |
8f70b4 |
{0,0,0,0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *time_style=ResMgr::Query("cmd:time-style",0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
while((opt=a->getopt_long(":a1BdFhiklqsDISrt", cls_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt) {
|
|
Packit |
8f70b4 |
case OPT_SORT:
|
|
Packit |
8f70b4 |
if(!strcasecmp(optarg, "name")) sort = FileSet::BYNAME;
|
|
Packit |
8f70b4 |
else if(!strcasecmp(optarg, "size")) sort = FileSet::BYSIZE;
|
|
Packit |
8f70b4 |
else if(!strcasecmp(optarg, "date")) sort = FileSet::BYDATE;
|
|
Packit |
8f70b4 |
else if(!strcasecmp(optarg, "time")) sort = FileSet::BYDATE;
|
|
Packit |
8f70b4 |
else return _("invalid argument for `--sort'");
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_FILESIZE:
|
|
Packit |
8f70b4 |
size_filesonly = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_USER:
|
|
Packit |
8f70b4 |
mode |= USER;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_GROUP:
|
|
Packit |
8f70b4 |
mode |= GROUP;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_PERMS:
|
|
Packit |
8f70b4 |
mode |= PERMS;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_DATE:
|
|
Packit |
8f70b4 |
mode |= DATE;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_LINKCOUNT:
|
|
Packit |
8f70b4 |
mode |= NLINKS;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_LINKS:
|
|
Packit |
8f70b4 |
mode |= LINKS;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_SI:
|
|
Packit |
8f70b4 |
output_block_size = 1;
|
|
Packit |
8f70b4 |
human_opts=human_autoscale|human_SI;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_BLOCK_SIZE:
|
|
Packit |
8f70b4 |
output_block_size = atoi(optarg);
|
|
Packit |
8f70b4 |
if(output_block_size == 0)
|
|
Packit |
8f70b4 |
return _("invalid block size");
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('a'):
|
|
Packit |
8f70b4 |
showdots = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('1'):
|
|
Packit |
8f70b4 |
single_column = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('B'):
|
|
Packit |
8f70b4 |
basenames = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('d'):
|
|
Packit |
8f70b4 |
list_directories = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('h'):
|
|
Packit |
8f70b4 |
output_block_size = 1;
|
|
Packit |
8f70b4 |
human_opts=human_autoscale|human_SI|human_base_1024;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('l'):
|
|
Packit |
8f70b4 |
long_list();
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('i'):
|
|
Packit |
8f70b4 |
patterns_casefold = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('k'):
|
|
Packit |
8f70b4 |
output_block_size = 1024;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('F'):
|
|
Packit |
8f70b4 |
classify=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('q'):
|
|
Packit |
8f70b4 |
quiet = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('s'):
|
|
Packit |
8f70b4 |
mode |= FileSetOutput::SIZE;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('D'):
|
|
Packit |
8f70b4 |
sort_dirs_first = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('I'):
|
|
Packit |
8f70b4 |
sort_casefold = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('S'):
|
|
Packit |
8f70b4 |
sort = FileSet::BYSIZE;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('t'):
|
|
Packit |
8f70b4 |
sort = FileSet::BYDATE;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('r'):
|
|
Packit |
8f70b4 |
sort_reverse = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_TIME_STYLE:
|
|
Packit |
8f70b4 |
time_style=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
default:
|
|
Packit |
8f70b4 |
return a->getopt_error_message(opt);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
time_fmt.set(0);
|
|
Packit |
8f70b4 |
if(time_style && time_style[0]) {
|
|
Packit |
8f70b4 |
if (mode & DATE)
|
|
Packit |
8f70b4 |
need_exact_time=ResMgr::QueryBool("cmd:cls-exact-time",0);
|
|
Packit |
8f70b4 |
if(time_style[0]=='+')
|
|
Packit |
8f70b4 |
time_fmt.set(time_style+1);
|
|
Packit |
8f70b4 |
else if(!strcmp(time_style,"full-iso"))
|
|
Packit |
8f70b4 |
// time_fmt.set("%Y-%m-%d %H:%M:%S.%N %z"); // %N and %z are GNU extensions
|
|
Packit |
8f70b4 |
time_fmt.set("%Y-%m-%d %H:%M:%S");
|
|
Packit |
8f70b4 |
else if(!strcmp(time_style,"long-iso"))
|
|
Packit |
8f70b4 |
time_fmt.set("%Y-%m-%d %H:%M");
|
|
Packit |
8f70b4 |
else if(!strcmp(time_style,"iso"))
|
|
Packit |
8f70b4 |
time_fmt.set("%Y-%m-%d \n%m-%d %H:%M");
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
time_fmt.set(time_style);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// remove parsed options.
|
|
Packit |
8f70b4 |
while(a->getindex()>1)
|
|
Packit |
8f70b4 |
a->delarg(1);
|
|
Packit |
8f70b4 |
a->rewind();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return NULL;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(cls)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
bool re=false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
JobRef<OutputJob> out(new OutputJob(output.borrow(), args->a0()));
|
|
Packit |
8f70b4 |
Ref<FileSetOutput> fso(new FileSetOutput);
|
|
Packit |
8f70b4 |
fso->config(out);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!strncmp(op,"re",2))
|
|
Packit |
8f70b4 |
re=true;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
fso->parse_res(ResMgr::Query("cmd:cls-default", 0));
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(const char *err = fso->parse_argv(args)) {
|
|
Packit |
8f70b4 |
eprintf("%s: %s\n", op, err);
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
clsJob *j = new clsJob(session->Clone(), args.borrow(), fso.borrow(), out.borrow());
|
|
Packit |
8f70b4 |
if(re)
|
|
Packit |
8f70b4 |
j->UseCache(false);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(cat)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
bool ascii=false;
|
|
Packit |
8f70b4 |
bool auto_ascii=true;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
while((opt=args->getopt("+bau"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('a'):
|
|
Packit |
8f70b4 |
ascii=true;
|
|
Packit |
8f70b4 |
auto_ascii=false;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('b'):
|
|
Packit |
8f70b4 |
ascii=false;
|
|
Packit |
8f70b4 |
auto_ascii=false;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
while(args->getindex()>1)
|
|
Packit |
8f70b4 |
args->delarg(1);
|
|
Packit |
8f70b4 |
args->rewind();
|
|
Packit |
8f70b4 |
if(args->count()<=1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [OPTS] files...\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
OutputJob *out=new OutputJob(output.borrow(), args->a0());
|
|
Packit |
8f70b4 |
CatJob *j=new CatJob(session->Clone(),out,args.borrow());
|
|
Packit |
8f70b4 |
if(!auto_ascii)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(ascii)
|
|
Packit |
8f70b4 |
j->Ascii();
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
j->Binary();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(get)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
static struct option get_options[] = {
|
|
Packit |
8f70b4 |
{"continue",no_argument,0,'c'},
|
|
Packit |
8f70b4 |
{"Remove-source-files",no_argument,0,'E'},
|
|
Packit |
8f70b4 |
{"remove-target",no_argument,0,'e'},
|
|
Packit |
8f70b4 |
{"ascii",no_argument,0,'a'},
|
|
Packit |
8f70b4 |
{"target-directory",required_argument,0,'O'},
|
|
Packit |
8f70b4 |
{"destination-directory",required_argument,0,'O'},
|
|
Packit |
8f70b4 |
{"quiet",no_argument,0,'q'},
|
|
Packit |
8f70b4 |
{"parallel",optional_argument,0,'P'},
|
|
Packit |
8f70b4 |
{"use-pget-n",optional_argument,0,'n'},
|
|
Packit |
8f70b4 |
{"glob",no_argument,0,256+'g'},
|
|
Packit |
8f70b4 |
{"reverse",no_argument,0,256+'R'},
|
|
Packit |
8f70b4 |
{0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
const char *opts="+cEeaO:qP";
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
bool cont=false;
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
Ref<ArgV> get_args(new ArgV(op));
|
|
Packit |
8f70b4 |
int n_conn=1;
|
|
Packit |
8f70b4 |
int parallel=0;
|
|
Packit |
8f70b4 |
bool del=false;
|
|
Packit |
8f70b4 |
bool del_target=false;
|
|
Packit |
8f70b4 |
bool ascii=false;
|
|
Packit |
8f70b4 |
bool glob=false;
|
|
Packit |
8f70b4 |
bool make_dirs=false;
|
|
Packit |
8f70b4 |
bool reverse=false;
|
|
Packit |
8f70b4 |
bool quiet=false;
|
|
Packit |
8f70b4 |
const char *output_dir=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!strncmp(op,"re",2))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
cont=true;
|
|
Packit |
8f70b4 |
opts="+EaO:qP:";
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strcmp(op,"pget"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
opts="+n:ceO:q";
|
|
Packit |
8f70b4 |
n_conn=0; // default, which means to take pget:default-n
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcmp(op,"put") || !strcmp(op,"reput"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
reverse=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcmp(op,"mget") || !strcmp(op,"mput"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
glob=true;
|
|
Packit |
8f70b4 |
opts="cEeadO:qP:";
|
|
Packit |
8f70b4 |
reverse=(op[1]=='p');
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!reverse)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *od=ResMgr::Query("xfer:destination-directory",session->GetHostName());
|
|
Packit |
8f70b4 |
if(od && *od)
|
|
Packit |
8f70b4 |
output_dir=od;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
while((opt=args->getopt_long(opts,get_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('c'):
|
|
Packit |
8f70b4 |
cont=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('n'):
|
|
Packit |
8f70b4 |
if(optarg) {
|
|
Packit |
8f70b4 |
if(!isdigit((unsigned char)optarg[0]))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s: Number expected. "),"-n",op);
|
|
Packit |
8f70b4 |
goto err;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
n_conn=atoi(optarg);
|
|
Packit |
8f70b4 |
} else
|
|
Packit |
8f70b4 |
n_conn=3;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('E'):
|
|
Packit |
8f70b4 |
del=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('e'):
|
|
Packit |
8f70b4 |
del_target=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('a'):
|
|
Packit |
8f70b4 |
ascii=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('d'):
|
|
Packit |
8f70b4 |
make_dirs=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('O'):
|
|
Packit |
8f70b4 |
output_dir=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('q'):
|
|
Packit |
8f70b4 |
quiet=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('P'):
|
|
Packit |
8f70b4 |
if(optarg) {
|
|
Packit |
8f70b4 |
if(!isdigit((unsigned char)optarg[0]))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s: Number expected. "),"-P",op);
|
|
Packit |
8f70b4 |
goto err;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
parallel=atoi(optarg);
|
|
Packit |
8f70b4 |
} else
|
|
Packit |
8f70b4 |
parallel=3;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case(256+'R'):
|
|
Packit |
8f70b4 |
reverse=!reverse;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case(256+'g'):
|
|
Packit |
8f70b4 |
glob=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
err:
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(cont && del_target) {
|
|
Packit |
8f70b4 |
eprintf(_("%s: --continue conflicts with --remove-target.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
JobRef<GetJob> j;
|
|
Packit |
8f70b4 |
if(glob)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->getcurr()==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
file_name_missed:
|
|
Packit |
8f70b4 |
// xgettext:c-format
|
|
Packit |
8f70b4 |
eprintf(_("File name missed. "));
|
|
Packit |
8f70b4 |
goto err;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
mgetJob *mj=new mgetJob(session->Clone(),args,cont,make_dirs);
|
|
Packit |
8f70b4 |
if(output_dir)
|
|
Packit |
8f70b4 |
mj->OutputDir(output_dir);
|
|
Packit |
8f70b4 |
j=mj;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
args->back();
|
|
Packit |
8f70b4 |
const char *a=args->getnext();
|
|
Packit |
8f70b4 |
if(a==0)
|
|
Packit |
8f70b4 |
goto file_name_missed;
|
|
Packit |
8f70b4 |
while(a)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *src=a;
|
|
Packit |
8f70b4 |
const char *dst=0;
|
|
Packit |
8f70b4 |
a=args->getnext();
|
|
Packit |
8f70b4 |
if(a && !strcmp(a,"-o"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
dst=args->getnext();
|
|
Packit |
8f70b4 |
a=args->getnext();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(reverse)
|
|
Packit |
8f70b4 |
src=expand_home_relative(src);
|
|
Packit |
8f70b4 |
dst=output_file_name(src,dst,!reverse,output_dir,false);
|
|
Packit |
8f70b4 |
get_args->Append(src);
|
|
Packit |
8f70b4 |
get_args->Append(dst);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
j=new GetJob(session->Clone(),get_args.borrow(),cont);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(reverse)
|
|
Packit |
8f70b4 |
j->Reverse();
|
|
Packit |
8f70b4 |
if(del)
|
|
Packit |
8f70b4 |
j->DeleteFiles();
|
|
Packit |
8f70b4 |
if(del_target)
|
|
Packit |
8f70b4 |
j->RemoveTargetFirst();
|
|
Packit |
8f70b4 |
if(ascii)
|
|
Packit |
8f70b4 |
j->Ascii();
|
|
Packit |
8f70b4 |
if(n_conn!=1)
|
|
Packit |
8f70b4 |
j->SetCopyJobCreator(new pCopyJobCreator(n_conn));
|
|
Packit |
8f70b4 |
if(parallel>0)
|
|
Packit |
8f70b4 |
j->SetParallel(parallel);
|
|
Packit |
8f70b4 |
j->Quiet(quiet);
|
|
Packit |
8f70b4 |
return j.borrow();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(edit)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
/* Download specified remote file into a temporary local file; run an
|
|
Packit |
8f70b4 |
* editor on it and upload the file back if changed. Remove the temp file. */
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
xstring temp_file;
|
|
Packit |
8f70b4 |
bool keep_temp=false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
while((opt=args->getopt("ok"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('o'):
|
|
Packit |
8f70b4 |
temp_file.set(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('k'):
|
|
Packit |
8f70b4 |
keep_temp=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
err:
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
args->rewind();
|
|
Packit |
8f70b4 |
if(args->count()<=1) {
|
|
Packit |
8f70b4 |
eprintf(_("File name missed. "));
|
|
Packit |
8f70b4 |
goto err;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *file=args->getarg(1);
|
|
Packit |
8f70b4 |
if(!temp_file) {
|
|
Packit |
8f70b4 |
ParsedURL u(file);
|
|
Packit |
8f70b4 |
temp_file.set(basename_ptr(u.proto?u.path.get():file));
|
|
Packit |
8f70b4 |
// make temp file name by substituting node name and PID after the first dot.
|
|
Packit |
8f70b4 |
xstring temp_str;
|
|
Packit |
8f70b4 |
temp_str.setf("%s-%u.",get_nodename(),(unsigned)getpid());
|
|
Packit |
8f70b4 |
int point=temp_file.instr('.');
|
|
Packit |
8f70b4 |
temp_file.set_substr(point>=0?point+1:0,0,temp_str);
|
|
Packit |
8f70b4 |
temp_file.set_substr(0,0,"/");
|
|
Packit |
8f70b4 |
xstring temp_dir(dir_file(get_lftp_cache_dir(),"edit"));
|
|
Packit |
8f70b4 |
mkdir(temp_dir,0700);
|
|
Packit |
8f70b4 |
temp_file.set_substr(0,0,temp_dir);
|
|
Packit |
8f70b4 |
if(access(temp_file,F_OK)!=-1)
|
|
Packit |
8f70b4 |
keep_temp=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
EditJob *j=new EditJob(session->Clone(),file,temp_file);
|
|
Packit |
8f70b4 |
j->KeepTempFile(keep_temp);
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(shell)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
Job *j;
|
|
Packit |
8f70b4 |
if(args->count()<=1)
|
|
Packit |
8f70b4 |
j=new SysCmdJob(0);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_ca a(args->Combine(1));
|
|
Packit |
8f70b4 |
j=new SysCmdJob(a);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(mrm)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
args->setarg(0,"glob");
|
|
Packit |
8f70b4 |
args->insarg(1,"rm");
|
|
Packit |
8f70b4 |
return parent->builtin_restart();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
CMD(rm)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
bool recursive=false;
|
|
Packit |
8f70b4 |
bool silent=false;
|
|
Packit |
8f70b4 |
const char *opts="+rf";
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool rmdir = false;
|
|
Packit |
8f70b4 |
if(!strcmp(args->a0(),"rmdir"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
rmdir = true;
|
|
Packit |
8f70b4 |
opts="+f";
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
while((opt=args->getopt(opts))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('r'):
|
|
Packit |
8f70b4 |
recursive=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('f'):
|
|
Packit |
8f70b4 |
silent=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
print_usage:
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s %s[-f] files...\n"),args->a0(), rmdir? "":"[-r] ");
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(args->getcurr()==0)
|
|
Packit |
8f70b4 |
goto print_usage;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
rmJob *j=new rmJob(session->Clone(),args.borrow());
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(recursive)
|
|
Packit |
8f70b4 |
j->Recurse();
|
|
Packit |
8f70b4 |
if(rmdir)
|
|
Packit |
8f70b4 |
j->Rmdir();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(silent)
|
|
Packit |
8f70b4 |
j->BeQuiet();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
CMD(mkdir)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return new mkdirJob(session->Clone(),args.borrow());
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#ifndef O_ASCII
|
|
Packit |
8f70b4 |
# define O_ASCII 0
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(source)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
bool e=false;
|
|
Packit |
8f70b4 |
while((opt=args->getopt("+e"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('e'):
|
|
Packit |
8f70b4 |
e=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
usage:
|
|
Packit |
8f70b4 |
// xgettext:c-format
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [-e] <file|command>\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(args->getindex()>=args->count())
|
|
Packit |
8f70b4 |
goto usage;
|
|
Packit |
8f70b4 |
FDStream *f=0;
|
|
Packit |
8f70b4 |
if(e)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_ca cmd(args->Combine(args->getindex()));
|
|
Packit |
8f70b4 |
f=new InputFilter(cmd);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
f=new FileStream(args->getarg(1),O_RDONLY|O_ASCII);
|
|
Packit |
8f70b4 |
// try to open the file to return error code if failed, as FileFeeder
|
|
Packit |
8f70b4 |
// cannot feed error codes.
|
|
Packit |
8f70b4 |
if(f->getfd()==-1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(f->error())
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
fprintf(stderr,"%s: %s\n",args->a0(),f->error_text.get());
|
|
Packit |
8f70b4 |
delete f;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
parent->SetCmdFeeder(new FileFeeder(f));
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(jobs)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
int v=1;
|
|
Packit |
8f70b4 |
bool recursion=true;
|
|
Packit |
8f70b4 |
while((opt=args->getopt("+vr"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('v'):
|
|
Packit |
8f70b4 |
v++;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('r'):
|
|
Packit |
8f70b4 |
recursion=false;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
// xgettext:c-format
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [-v] [-v] ...\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
args->back();
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
const char *arg=args->getnext();
|
|
Packit |
8f70b4 |
xstring s("");
|
|
Packit |
8f70b4 |
if(!arg) {
|
|
Packit |
8f70b4 |
parent->top->FormatJobs(s,v);
|
|
Packit |
8f70b4 |
} else {
|
|
Packit |
8f70b4 |
for(; arg; arg=args->getnext()) {
|
|
Packit |
8f70b4 |
if(!isdigit((unsigned char)*arg)) {
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s - not a number\n"),op,arg);
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
int n=atoi(arg);
|
|
Packit |
8f70b4 |
Job *j=parent->FindJob(n);
|
|
Packit |
8f70b4 |
if(!j) {
|
|
Packit |
8f70b4 |
eprintf(_("%s: %d - no such job\n"),op,n);
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(recursion)
|
|
Packit |
8f70b4 |
j->FormatOneJobRecursively(s,v);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
j->FormatOneJob(s,v);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(exit_code)
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
OutputJob *out=new OutputJob(output.borrow(), args->a0());
|
|
Packit |
8f70b4 |
Job *j=new echoJob(s,s.length(),out);
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(cd)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return parent->builtin_cd();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(pwd)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
int flags=0;
|
|
Packit |
8f70b4 |
while((opt=args->getopt("p"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('p'):
|
|
Packit |
8f70b4 |
flags|=FA::WITH_PASSWORD;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
// xgettext:c-format
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [-p]\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *url_c=session->GetConnectURL(flags);
|
|
Packit |
8f70b4 |
char *url=alloca_strdup(url_c);
|
|
Packit |
8f70b4 |
int len=strlen(url_c);
|
|
Packit |
8f70b4 |
url[len++]='\n'; // replaces \0
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
OutputJob *out=new OutputJob(output.borrow(), args->a0());
|
|
Packit |
8f70b4 |
Job *j=new echoJob(url,len,out);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(exit)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return parent->builtin_exit();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(debug)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
int new_dlevel=DEFAULT_DEBUG_LEVEL;
|
|
Packit |
8f70b4 |
const char *debug_file_name=0;
|
|
Packit |
8f70b4 |
bool enabled=true;
|
|
Packit |
8f70b4 |
bool show_pid=false;
|
|
Packit |
8f70b4 |
bool show_time=false;
|
|
Packit |
8f70b4 |
bool show_context=false;
|
|
Packit |
8f70b4 |
int trunc=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
while((opt=args->getopt("To:ptc"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('T'):
|
|
Packit |
8f70b4 |
trunc=O_TRUNC;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('o'):
|
|
Packit |
8f70b4 |
debug_file_name=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'p':
|
|
Packit |
8f70b4 |
show_pid=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 't':
|
|
Packit |
8f70b4 |
show_time=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'c':
|
|
Packit |
8f70b4 |
show_context=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *a=args->getcurr();
|
|
Packit |
8f70b4 |
if(a)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!strcasecmp(a,"off"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
enabled=false;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
new_dlevel=atoi(a);
|
|
Packit |
8f70b4 |
if(new_dlevel<0)
|
|
Packit |
8f70b4 |
new_dlevel=0;
|
|
Packit |
8f70b4 |
enabled=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(debug_file_name && trunc)
|
|
Packit |
8f70b4 |
truncate(debug_file_name,0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *c="debug";
|
|
Packit |
8f70b4 |
ResMgr::Set("log:file",c,debug_file_name?debug_file_name:"");
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
ResMgr::Set("log:enabled",c,enabled?"yes":"no");
|
|
Packit |
8f70b4 |
if(enabled)
|
|
Packit |
8f70b4 |
ResMgr::Set("log:level",c,xstring::format("%d",new_dlevel));
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
ResMgr::Set("log:show-pid",c,show_pid?"yes":"no");
|
|
Packit |
8f70b4 |
ResMgr::Set("log:show-time",c,show_time?"yes":"no");
|
|
Packit |
8f70b4 |
ResMgr::Set("log:show-ctx",c,show_context?"yes":"no");
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#if 0
|
|
Packit |
8f70b4 |
if(interactive)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(enabled)
|
|
Packit |
8f70b4 |
printf(_("debug level is %d, output goes to %s\n"),new_dlevel,
|
|
Packit |
8f70b4 |
debug_file_name?debug_file_name:"<stderr>");
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
printf(_("debug is off\n"));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(user)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->count()<2 || args->count()>3)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s <user|URL> [<pass>]\n"),args->getarg(0));
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *user=args->getarg(1);
|
|
Packit |
8f70b4 |
const char *pass=args->getarg(2);
|
|
Packit |
8f70b4 |
bool insecure=(pass!=0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
ParsedURL u(user,true);
|
|
Packit |
8f70b4 |
if(u.proto && !u.user)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(u.proto && u.user && u.pass)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
pass=u.pass;
|
|
Packit |
8f70b4 |
insecure=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!pass)
|
|
Packit |
8f70b4 |
pass=GetPass(_("Password: "));
|
|
Packit |
8f70b4 |
if(!pass)
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(u.proto && u.user)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FA *s=FA::New(&u,false);
|
|
Packit |
8f70b4 |
if(s)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
s->SetPasswordGlobal(pass);
|
|
Packit |
8f70b4 |
s->InsecurePassword(insecure);
|
|
Packit |
8f70b4 |
SessionPool::Reuse(s);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s: %s%s\n",args->a0(),u.proto.get(),
|
|
Packit |
8f70b4 |
_(" - not supported protocol"));
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
session->Login(args->getarg(1),0);
|
|
Packit |
8f70b4 |
session->SetPasswordGlobal(pass);
|
|
Packit |
8f70b4 |
session->InsecurePassword(insecure);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
CMD(anon)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
session->AnonymousLogin();
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(lftp)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return parent->builtin_lftp();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(open)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return parent->builtin_open();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(kill)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int n;
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
if(args->count()<2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
#if 0 // too dangerous to kill last job. Better require explicit number.
|
|
Packit |
8f70b4 |
n=parent->last_bg;
|
|
Packit |
8f70b4 |
if(n==-1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: no current job\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
printf("%s %d\n",op,n);
|
|
Packit |
8f70b4 |
if(Job::Running(n))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
parent->Kill(n);
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
eprintf(_("%s: %d - no such job\n"),op,n);
|
|
Packit |
8f70b4 |
#else
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s <jobno> ... | all\n"),args->getarg(0));
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strcasecmp(args->getarg(1),"all"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
parent->KillAll();
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
args->rewind();
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
for(;;)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *arg=args->getnext();
|
|
Packit |
8f70b4 |
if(arg==0)
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
if(!isdigit((unsigned char)arg[0]))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s - not a number\n"),op,arg);
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
n=atoi(arg);
|
|
Packit |
8f70b4 |
if(Job::Running(n))
|
|
Packit |
8f70b4 |
parent->Kill(n);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %d - no such job\n"),op,n);
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(set)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
bool with_defaults=false;
|
|
Packit |
8f70b4 |
bool only_defaults=false;
|
|
Packit |
8f70b4 |
int c;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
while((c=args->getopt("+ad"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(c)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case 'a':
|
|
Packit |
8f70b4 |
with_defaults=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'd':
|
|
Packit |
8f70b4 |
only_defaults=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
default:
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
args->back();
|
|
Packit |
8f70b4 |
const char *ac=args->getnext();
|
|
Packit |
8f70b4 |
if(ac==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_ca s(ResMgr::Format(with_defaults,only_defaults));
|
|
Packit |
8f70b4 |
OutputJob *out=new OutputJob(output.borrow(), args->a0());
|
|
Packit |
8f70b4 |
Job *j=new echoJob(s,out);
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
char *a=alloca_strdup(ac);
|
|
Packit |
8f70b4 |
char *sl=strchr(a,'/');
|
|
Packit |
8f70b4 |
char *closure=0;
|
|
Packit |
8f70b4 |
if(sl)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
*sl=0;
|
|
Packit |
8f70b4 |
closure=sl+1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const ResType *type;
|
|
Packit |
8f70b4 |
// find type of given variable
|
|
Packit |
8f70b4 |
const char *msg=ResMgr::FindVar(a,&type);
|
|
Packit |
8f70b4 |
if(msg)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s. Use `set -a' to look at all variables.\n"),a,msg);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
args->getnext();
|
|
Packit |
8f70b4 |
xstring_ca val(args->getcurr()==0?0:args->Combine(args->getindex()));
|
|
Packit |
8f70b4 |
msg=ResMgr::Set(a,closure,val);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(msg)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s: %s.\n",val.get(),msg);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(alias)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->count()<2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_ca list(Alias::Format());
|
|
Packit |
8f70b4 |
OutputJob *out=new OutputJob(output.borrow(), args->a0());
|
|
Packit |
8f70b4 |
Job *j=new echoJob(list,out);
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(args->count()==2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
Alias::Del(args->getarg(1));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_ca val(args->Combine(2));
|
|
Packit |
8f70b4 |
Alias::Add(args->getarg(1),val);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(wait)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
if(args->count()>2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [<jobno>]\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
int n=-1;
|
|
Packit |
8f70b4 |
const char *jn=args->getnext();
|
|
Packit |
8f70b4 |
if(jn)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!strcasecmp(jn,"all"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
parent->WaitForAllChildren();
|
|
Packit |
8f70b4 |
parent->AllWaitingFg();
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!isdigit((unsigned char)jn[0]))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s - not a number\n"),op,jn);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
n=atoi(jn);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(n==-1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
n=parent->last_bg;
|
|
Packit |
8f70b4 |
if(n==-1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: no current job\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
printf("%s %d\n",op,n);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
Job *j=parent->FindJob(n);
|
|
Packit |
8f70b4 |
if(j==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %d - no such job\n"),op,n);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(Job::FindWhoWaitsFor(j)!=0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: some other job waits for job %d\n"),op,n);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(j->Job::CheckForWaitLoop(parent))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: wait loop detected\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
j->SetParent(0);
|
|
Packit |
8f70b4 |
j->Bg();
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(subsh)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
CmdExec *e=new CmdExec(parent);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *c=args->getarg(1);
|
|
Packit |
8f70b4 |
e->FeedCmd(c);
|
|
Packit |
8f70b4 |
e->FeedCmd("\n");
|
|
Packit |
8f70b4 |
e->cmdline.vset("(",c,")",NULL);
|
|
Packit |
8f70b4 |
return e;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(mmv)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
static const struct option mmv_opts[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"target-directory",required_argument,0,'O'},
|
|
Packit |
8f70b4 |
{"destination-directory",required_argument,0,'O'},
|
|
Packit |
8f70b4 |
{"remove-target-first",no_argument,0,'e'},
|
|
Packit |
8f70b4 |
{0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool remove_target=false;
|
|
Packit |
8f70b4 |
const char *target_dir=0;
|
|
Packit |
8f70b4 |
args->rewind();
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
while((opt=args->getopt_long("eO:t:",mmv_opts,0))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('e'):
|
|
Packit |
8f70b4 |
remove_target=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('t'):
|
|
Packit |
8f70b4 |
case('O'):
|
|
Packit |
8f70b4 |
target_dir=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
help:
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!target_dir && args->count()>=3) {
|
|
Packit |
8f70b4 |
target_dir=args->getarg(args->count()-1);
|
|
Packit |
8f70b4 |
target_dir=alloca_strdup(target_dir);
|
|
Packit |
8f70b4 |
args->delarg(args->count()-1);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!target_dir || args->getindex()>=args->count()) {
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [OPTS] <files> <target-dir>\n"),args->a0());
|
|
Packit |
8f70b4 |
goto help;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
mmvJob *j=new mmvJob(session->Clone(),args,target_dir,FA::RENAME);
|
|
Packit |
8f70b4 |
if(remove_target)
|
|
Packit |
8f70b4 |
j->RemoveTargetFirst();
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(mv)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->count()!=3
|
|
Packit |
8f70b4 |
|| (args->count()==3 && last_char(args->getarg(2))=='/'))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
args->setarg(0,"mmv");
|
|
Packit |
8f70b4 |
return cmd_mmv(parent);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
Job *j=new mvJob(session->Clone(),args->getarg(1),args->getarg(2));
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(ln)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FA::open_mode m=FA::LINK;
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
int c;
|
|
Packit |
8f70b4 |
while((c=args->getopt("+s"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(c)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case 's':
|
|
Packit |
8f70b4 |
m=FA::SYMLINK;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
default:
|
|
Packit |
8f70b4 |
error:
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
args->back();
|
|
Packit |
8f70b4 |
const char *file1=args->getnext();
|
|
Packit |
8f70b4 |
const char *file2=args->getnext();
|
|
Packit |
8f70b4 |
if(!file1 || !file2)
|
|
Packit |
8f70b4 |
goto error;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return new mvJob(session->Clone(),file1,file2,m);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *const cache_subcmd[]={
|
|
Packit |
8f70b4 |
"status","flush","on","off","size","expire",
|
|
Packit |
8f70b4 |
NULL
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(cache) // cache control
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->getnext();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!op)
|
|
Packit |
8f70b4 |
op="status";
|
|
Packit |
8f70b4 |
else if(!find_command(op,cache_subcmd,&op))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// xgettext:c-format
|
|
Packit |
8f70b4 |
eprintf(_("Invalid command. "));
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!op)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// xgettext:c-format
|
|
Packit |
8f70b4 |
eprintf(_("Ambiguous command. "));
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
if(!op || !strcasecmp(op,"status"))
|
|
Packit |
8f70b4 |
FileAccess::cache->List();
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"flush"))
|
|
Packit |
8f70b4 |
FileAccess::cache->Flush();
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"on"))
|
|
Packit |
8f70b4 |
ResMgr::Set("cache:enable",0,"yes");
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"off"))
|
|
Packit |
8f70b4 |
ResMgr::Set("cache:enable",0,"no");
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"size"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
op=args->getnext();
|
|
Packit |
8f70b4 |
if(!op)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: Operand missed for size\n"),args->a0());
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *err=ResMgr::Set("cache:size",0,op);
|
|
Packit |
8f70b4 |
if(err)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s: %s: %s\n",args->a0(),op,err);
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"expire"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
op=args->getnext();
|
|
Packit |
8f70b4 |
if(!op)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: Operand missed for `expire'\n"),args->a0());
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *err=ResMgr::Set("cache:expire",0,op);
|
|
Packit |
8f70b4 |
if(err)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s: %s: %s\n",args->a0(),op,err);
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(scache)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->count()==1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
SessionPool::Print(stdout);
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *a=args->getarg(1);
|
|
Packit |
8f70b4 |
if(!isdigit((unsigned char)a[0]))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s - not a number\n"),args->a0(),a);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
FileAccess *new_session=SessionPool::GetSession(atoi(a));
|
|
Packit |
8f70b4 |
if(new_session==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s - no such cached session. Use `scache' to look at session list.\n"),args->a0(),a);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
parent->ChangeSession(new_session);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool CmdExec::print_cmd_help(const char *cmd)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const cmd_rec *c;
|
|
Packit |
8f70b4 |
int part=find_cmd(cmd,&c);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(part==1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(c->creator==0 || !xstrcmp(c->long_desc,HELP_IN_MODULE)) {
|
|
Packit |
8f70b4 |
// try to load the module which can have a help text
|
|
Packit |
8f70b4 |
if(load_cmd_module(c->name))
|
|
Packit |
8f70b4 |
find_cmd(c->name,&c);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(c->long_desc==0 && c->short_desc==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
printf(_("Sorry, no help for %s\n"),cmd);
|
|
Packit |
8f70b4 |
return true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(c->short_desc==0 && !strchr(c->long_desc,' '))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
printf(_("%s is a built-in alias for %s\n"),cmd,c->long_desc);
|
|
Packit |
8f70b4 |
print_cmd_help(c->long_desc);
|
|
Packit |
8f70b4 |
return true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(c->short_desc)
|
|
Packit |
8f70b4 |
printf(_("Usage: %s\n"),_(c->short_desc));
|
|
Packit |
8f70b4 |
if(c->long_desc)
|
|
Packit |
8f70b4 |
printf("%s",_(c->long_desc));
|
|
Packit |
8f70b4 |
return true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *a=Alias::Find(cmd);
|
|
Packit |
8f70b4 |
if(a)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
printf(_("%s is an alias to `%s'\n"),cmd,a);
|
|
Packit |
8f70b4 |
return true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(part==0)
|
|
Packit |
8f70b4 |
printf(_("No such command `%s'. Use `help' to see available commands.\n"),cmd);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
printf(_("Ambiguous command `%s'. Use `help' to see available commands.\n"),cmd);
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void CmdExec::print_cmd_index()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int i=0;
|
|
Packit |
8f70b4 |
const cmd_rec *cmd_table=dyn_cmd_table?dyn_cmd_table.get():static_cmd_table;
|
|
Packit |
8f70b4 |
const int count=dyn_cmd_table?dyn_cmd_table.count():static_cmd_table_length;
|
|
Packit |
8f70b4 |
int width=fd_width(1);
|
|
Packit |
8f70b4 |
int pos=0;
|
|
Packit |
8f70b4 |
const int align=37;
|
|
Packit |
8f70b4 |
const int first_align=4;
|
|
Packit |
8f70b4 |
while(i
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
while(i
|
|
Packit |
8f70b4 |
i++;
|
|
Packit |
8f70b4 |
if(i>=count)
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
const char *c1=gettext(cmd_table[i].short_desc);
|
|
Packit |
8f70b4 |
i++;
|
|
Packit |
8f70b4 |
int w1=mbswidth(c1,0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int pad=0;
|
|
Packit |
8f70b4 |
if(pos
|
|
Packit |
8f70b4 |
pad=first_align-pos;
|
|
Packit |
8f70b4 |
else if(pos>first_align)
|
|
Packit |
8f70b4 |
pad=align-(pos-first_align)%align;
|
|
Packit |
8f70b4 |
if(pos>first_align && pos+pad+w1>=width) {
|
|
Packit |
8f70b4 |
printf("\n");
|
|
Packit |
8f70b4 |
pos=0;
|
|
Packit |
8f70b4 |
pad=first_align;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
printf("%*s%s",pad,"",c1);
|
|
Packit |
8f70b4 |
pos+=pad+w1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(pos>0)
|
|
Packit |
8f70b4 |
printf("\n");
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(help)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->count()>1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
for(;;)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *cmd=args->getnext();
|
|
Packit |
8f70b4 |
if(cmd==0)
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
if(!parent->print_cmd_help(cmd))
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
parent->print_cmd_index();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(ver)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
printf(
|
|
Packit |
8f70b4 |
_("LFTP | Version %s | Copyright (c) 1996-%d Alexander V. Lukyanov\n"),VERSION,2017);
|
|
Packit |
8f70b4 |
printf("\n");
|
|
Packit |
8f70b4 |
printf(
|
|
Packit |
8f70b4 |
_("LFTP is free software: you can redistribute it and/or modify\n"
|
|
Packit |
8f70b4 |
"it under the terms of the GNU General Public License as published by\n"
|
|
Packit |
8f70b4 |
"the Free Software Foundation, either version 3 of the License, or\n"
|
|
Packit |
8f70b4 |
"(at your option) any later version.\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
"This program is distributed in the hope that it will be useful,\n"
|
|
Packit |
8f70b4 |
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
|
Packit |
8f70b4 |
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
|
Packit |
8f70b4 |
"GNU General Public License for more details.\n"
|
|
Packit |
8f70b4 |
"\n"
|
|
Packit |
8f70b4 |
"You should have received a copy of the GNU General Public License\n"
|
|
Packit |
8f70b4 |
"along with LFTP. If not, see <http://www.gnu.org/licenses/>.\n"));
|
|
Packit |
8f70b4 |
printf("\n");
|
|
Packit |
8f70b4 |
printf(
|
|
Packit |
8f70b4 |
_("Send bug reports and questions to the mailing list <%s>.\n"),"lftp@uniyar.ac.ru");
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#if defined(HAVE_DLOPEN) && defined(RTLD_DEFAULT)
|
|
Packit |
8f70b4 |
/* Show some of loaded libraries. Modules can load those libraries on
|
|
Packit |
8f70b4 |
demand so use dlsym to avoid linking with them just for showing version. */
|
|
Packit |
8f70b4 |
printf("\n");
|
|
Packit |
8f70b4 |
const char *msg=_("Libraries used: ");
|
|
Packit |
8f70b4 |
int mbflags=0;
|
|
Packit |
8f70b4 |
int col=mbswidth(msg,mbflags);
|
|
Packit |
8f70b4 |
int width=parent->status_line?parent->status_line->GetWidth():80;
|
|
Packit |
8f70b4 |
printf("%s",msg);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
struct VersionInfo
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *lib_name;
|
|
Packit |
8f70b4 |
const char *symbol;
|
|
Packit |
8f70b4 |
enum type_t { STRING_PTR, FUNC0, INT8_8 } type;
|
|
Packit |
8f70b4 |
const char *skip_prefix;
|
|
Packit |
8f70b4 |
typedef const char *(*func0)(void *);
|
|
Packit |
8f70b4 |
const char *query() const
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int v;
|
|
Packit |
8f70b4 |
void *sym_ptr=dlsym(RTLD_DEFAULT,symbol);
|
|
Packit |
8f70b4 |
if(!sym_ptr)
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
const char *str=0;
|
|
Packit |
8f70b4 |
switch(type)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case STRING_PTR:
|
|
Packit |
8f70b4 |
str=*(const char**)sym_ptr;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case FUNC0:
|
|
Packit |
8f70b4 |
str=((func0)sym_ptr)(NULL);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case INT8_8:
|
|
Packit |
8f70b4 |
v=*(int*)sym_ptr;
|
|
Packit |
8f70b4 |
str=xstring::format("%d.%d",(v>>8)&255,v&255);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!str)
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
if(skip_prefix && !strncmp(str,skip_prefix,strlen(skip_prefix)))
|
|
Packit |
8f70b4 |
str+=strlen(skip_prefix);
|
|
Packit |
8f70b4 |
return str;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
static const libs[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"Expat", "XML_ExpatVersion", VersionInfo::FUNC0, "expat_"},
|
|
Packit |
8f70b4 |
{"GnuTLS", "gnutls_check_version", VersionInfo::FUNC0, 0},
|
|
Packit |
8f70b4 |
{"idn2", "idn2_check_version", VersionInfo::FUNC0, 0},
|
|
Packit |
8f70b4 |
{"libiconv", "_libiconv_version", VersionInfo::INT8_8, 0},
|
|
Packit |
8f70b4 |
{"OpenSSL", "SSL_version_str", VersionInfo::STRING_PTR,"OpenSSL "},
|
|
Packit |
8f70b4 |
{"Readline", "rl_library_version", VersionInfo::STRING_PTR,0},
|
|
Packit |
8f70b4 |
{"zlib", "zlibVersion", VersionInfo::FUNC0, 0},
|
|
Packit |
8f70b4 |
{0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool need_comma=false;
|
|
Packit |
8f70b4 |
for(const VersionInfo *scan=libs; scan->lib_name; scan++)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *v=scan->query();
|
|
Packit |
8f70b4 |
if(!v)
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
char buf[256];
|
|
Packit |
8f70b4 |
snprintf(buf,sizeof(buf),", %s %s",scan->lib_name,v);
|
|
Packit |
8f70b4 |
int skip=need_comma?0:2;
|
|
Packit |
8f70b4 |
int w=mbswidth(buf+skip,mbflags);
|
|
Packit |
8f70b4 |
if(col+w>=width && need_comma)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
buf[1]='\n';
|
|
Packit |
8f70b4 |
col=w-2;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
col+=w;
|
|
Packit |
8f70b4 |
printf("%s",buf+skip);
|
|
Packit |
8f70b4 |
need_comma=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
printf("\n");
|
|
Packit |
8f70b4 |
#endif // HAVE_DLOPEN
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(close)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
bool all=false;
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
while((opt=args->getopt("a"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('a'):
|
|
Packit |
8f70b4 |
all=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(all)
|
|
Packit |
8f70b4 |
session->CleanupAll();
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
session->Cleanup();
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char * const bookmark_subcmd[]=
|
|
Packit |
8f70b4 |
{"add","delete","list","list-p","edit","import",0};
|
|
Packit |
8f70b4 |
static ResDecl res_save_passwords
|
|
Packit |
8f70b4 |
("bmk:save-passwords","no",ResMgr::BoolValidate,0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(bookmark)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->getnext();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!op)
|
|
Packit |
8f70b4 |
op="list";
|
|
Packit |
8f70b4 |
else if(!find_command(op,bookmark_subcmd,&op))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// xgettext:c-format
|
|
Packit |
8f70b4 |
eprintf(_("Invalid command. "));
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!op)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// xgettext:c-format
|
|
Packit |
8f70b4 |
eprintf(_("Ambiguous command. "));
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!strcasecmp(op,"list") || !strcasecmp(op,"list-p"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_ca list(op[4]?lftp_bookmarks.Format():lftp_bookmarks.FormatHidePasswords());
|
|
Packit |
8f70b4 |
OutputJob *out=new OutputJob(output.borrow(), args->a0());
|
|
Packit |
8f70b4 |
Job *j=new echoJob(list,out);
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"add"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *key=args->getnext();
|
|
Packit |
8f70b4 |
if(key==0 || key[0]==0)
|
|
Packit |
8f70b4 |
eprintf(_("%s: bookmark name required\n"),args->a0());
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *value=args->getnext();
|
|
Packit |
8f70b4 |
int flags=0;
|
|
Packit |
8f70b4 |
if(res_save_passwords.QueryBool(session->GetHostName()))
|
|
Packit |
8f70b4 |
flags|=session->WITH_PASSWORD;
|
|
Packit |
8f70b4 |
if(value==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
value=session->GetConnectURL(flags);
|
|
Packit |
8f70b4 |
// encode some more characters, special to CmdExec parser.
|
|
Packit |
8f70b4 |
value=url::encode(value,"&;|\"'\\");
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(value==0 || value[0]==0)
|
|
Packit |
8f70b4 |
value="\"\"";
|
|
Packit |
8f70b4 |
if(strchr(key,' ') || strchr(key,'\t'))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: spaces in bookmark name are not allowed\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
lftp_bookmarks.Add(key,value);
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"delete"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *key=args->getnext();
|
|
Packit |
8f70b4 |
if(key==0 || key[0]==0)
|
|
Packit |
8f70b4 |
eprintf(_("%s: bookmark name required\n"),args->a0());
|
|
Packit |
8f70b4 |
else if(lftp_bookmarks.Lookup(key)==0)
|
|
Packit |
8f70b4 |
eprintf(_("%s: no such bookmark `%s'\n"),args->a0(),key);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
lftp_bookmarks.Remove(key);
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"edit"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
lftp_bookmarks.Remove(""); // force bookmark file creation
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring cmd0("exec ${EDITOR:-vi} ");
|
|
Packit |
8f70b4 |
cmd0.append(shell_encode(lftp_bookmarks.GetFilePath()));
|
|
Packit |
8f70b4 |
xstring cmd1("/bin/sh -c ");
|
|
Packit |
8f70b4 |
cmd1.append(shell_encode(cmd0));
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
parent->PrependCmd(xstring::get_tmp("shell ").append_quoted(cmd1));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"import"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
op=args->getnext();
|
|
Packit |
8f70b4 |
if(!op)
|
|
Packit |
8f70b4 |
eprintf(_("%s: import type required (netscape,ncftp)\n"),args->a0());
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
parent->PrependCmd(xstring::cat("shell " PKGDATADIR "/import-",op,"\n",NULL));
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"load"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
lftp_bookmarks.UserLoad();
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strcasecmp(op,"save"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
lftp_bookmarks.UserSave();
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(echo)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring s;
|
|
Packit |
8f70b4 |
args->CombineTo(s,1);
|
|
Packit |
8f70b4 |
if(args->count()>1 && !strcmp(args->getarg(1),"-n"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(s.length()<=3)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
s.set_substr(0,3,"");
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
s.append('\n');
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
OutputJob *out=new OutputJob(output.borrow(), args->a0());
|
|
Packit |
8f70b4 |
Job *j=new echoJob(s,s.length(),out);
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(suspend)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
kill(getpid(),SIGSTOP);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(find)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
static struct option find_options[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"maxdepth",required_argument,0,'d'},
|
|
Packit |
8f70b4 |
{"ls",no_argument,0,'l'},
|
|
Packit |
8f70b4 |
{0,0,0,0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
int maxdepth = -1;
|
|
Packit |
8f70b4 |
bool long_listing=false;
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
while((opt=args->getopt_long("+d:l",find_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case 'd':
|
|
Packit |
8f70b4 |
if(!isdigit((unsigned char)*optarg))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s - not a number\n"),op,optarg);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
maxdepth = atoi(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'l':
|
|
Packit |
8f70b4 |
long_listing=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case '?':
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [-d #] dir\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!args->getcurr())
|
|
Packit |
8f70b4 |
args->Append(".");
|
|
Packit |
8f70b4 |
FinderJob_List *j=new class FinderJob_List(session->Clone(),args.borrow(),output.borrow());
|
|
Packit |
8f70b4 |
j->set_maxdepth(maxdepth);
|
|
Packit |
8f70b4 |
j->DoLongListing(long_listing);
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(du)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
enum {
|
|
Packit |
8f70b4 |
OPT_BLOCK_SIZE,
|
|
Packit |
8f70b4 |
OPT_EXCLUDE
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
static struct option du_options[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"all",no_argument,0,'a'},
|
|
Packit |
8f70b4 |
/* alias: both GNU-like max-depth and lftp-like maxdepth;
|
|
Packit |
8f70b4 |
* only document one of them. */
|
|
Packit |
8f70b4 |
{"bytes",no_argument,0,'b'},
|
|
Packit |
8f70b4 |
{"block-size",required_argument,0,OPT_BLOCK_SIZE},
|
|
Packit |
8f70b4 |
{"maxdepth",required_argument,0,'d'},
|
|
Packit |
8f70b4 |
{"total",no_argument,0,'c'},
|
|
Packit |
8f70b4 |
{"max-depth",required_argument,0,'d'},
|
|
Packit |
8f70b4 |
{"files",no_argument,0,'F'},
|
|
Packit |
8f70b4 |
{"human-readable",no_argument,0,'h'},
|
|
Packit |
8f70b4 |
{"si",no_argument,0,'H'},
|
|
Packit |
8f70b4 |
{"kilobytes",required_argument,0,'k'},
|
|
Packit |
8f70b4 |
{"megabytes",required_argument,0,'m'},
|
|
Packit |
8f70b4 |
{"separate-dirs",no_argument,0,'S'},
|
|
Packit |
8f70b4 |
{"summarize",no_argument,0,'s'},
|
|
Packit |
8f70b4 |
{"exclude",required_argument,0,OPT_EXCLUDE},
|
|
Packit |
8f70b4 |
{0,0,0,0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
int maxdepth = -1;
|
|
Packit |
8f70b4 |
bool max_depth_specified = false;
|
|
Packit |
8f70b4 |
int blocksize = 1024;
|
|
Packit |
8f70b4 |
bool separate_dirs = false;
|
|
Packit |
8f70b4 |
bool summarize_only = false;
|
|
Packit |
8f70b4 |
bool print_totals=false;
|
|
Packit |
8f70b4 |
bool all_files=false;
|
|
Packit |
8f70b4 |
bool file_count=false;
|
|
Packit |
8f70b4 |
Ref<PatternSet> exclude;
|
|
Packit |
8f70b4 |
int human_opts=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
while((opt=args->getopt_long("+abcd:FhHkmsS",du_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case 'a':
|
|
Packit |
8f70b4 |
all_files=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'b':
|
|
Packit |
8f70b4 |
blocksize = 1;
|
|
Packit |
8f70b4 |
human_opts = 0;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'c':
|
|
Packit |
8f70b4 |
print_totals=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'd':
|
|
Packit |
8f70b4 |
if(!isdigit((unsigned char)*optarg))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: %s - not a number\n"),op,optarg);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
maxdepth = atoi(optarg);
|
|
Packit |
8f70b4 |
max_depth_specified = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'F':
|
|
Packit |
8f70b4 |
file_count=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'h':
|
|
Packit |
8f70b4 |
human_opts |= human_autoscale|human_SI|human_base_1024;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'H':
|
|
Packit |
8f70b4 |
human_opts |= human_autoscale|human_SI;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'k': /* the default; here for completeness */
|
|
Packit |
8f70b4 |
blocksize = 1024;
|
|
Packit |
8f70b4 |
human_opts = 0;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'm':
|
|
Packit |
8f70b4 |
blocksize = 1024*1024;
|
|
Packit |
8f70b4 |
human_opts = 0;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 's':
|
|
Packit |
8f70b4 |
summarize_only = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'S':
|
|
Packit |
8f70b4 |
separate_dirs = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_BLOCK_SIZE:
|
|
Packit |
8f70b4 |
blocksize = atoi(optarg);
|
|
Packit |
8f70b4 |
if(blocksize == 0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: invalid block size `%s'\n"),op,optarg);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case OPT_EXCLUDE:
|
|
Packit |
8f70b4 |
if(!exclude)
|
|
Packit |
8f70b4 |
exclude=new PatternSet();
|
|
Packit |
8f70b4 |
exclude->Add(PatternSet::EXCLUDE,new PatternSet::Glob(optarg));
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case '?':
|
|
Packit |
8f70b4 |
default:
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [options] <dirs>\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if (summarize_only && max_depth_specified && maxdepth == 0)
|
|
Packit |
8f70b4 |
eprintf(_("%s: warning: summarizing is the same as using --max-depth=0\n"), op);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if (summarize_only && max_depth_specified && maxdepth != 0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: summarizing conflicts with --max-depth=%i\n"), op, maxdepth);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/* It doesn't really make sense to show all files when doing a file count.
|
|
Packit |
8f70b4 |
* We might have -a in an alias as defaults, so let's just silently turn
|
|
Packit |
8f70b4 |
* it off. (I'm not sure if we should do this for summarize_only and
|
|
Packit |
8f70b4 |
* max_depth_specified, too.) */
|
|
Packit |
8f70b4 |
if (file_count && all_files)
|
|
Packit |
8f70b4 |
all_files=false;
|
|
Packit |
8f70b4 |
if (file_count)
|
|
Packit |
8f70b4 |
blocksize=1;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if (summarize_only)
|
|
Packit |
8f70b4 |
maxdepth = 0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!args->getcurr())
|
|
Packit |
8f70b4 |
args->Append(".");
|
|
Packit |
8f70b4 |
FinderJob_Du *j=new class FinderJob_Du(session->Clone(),args.borrow(),output.borrow());
|
|
Packit |
8f70b4 |
j->PrintDepth(maxdepth);
|
|
Packit |
8f70b4 |
j->SetBlockSize(blocksize,human_opts);
|
|
Packit |
8f70b4 |
if(print_totals)
|
|
Packit |
8f70b4 |
j->PrintTotals();
|
|
Packit |
8f70b4 |
if(all_files)
|
|
Packit |
8f70b4 |
j->AllFiles();
|
|
Packit |
8f70b4 |
if(separate_dirs)
|
|
Packit |
8f70b4 |
j->SeparateDirs();
|
|
Packit |
8f70b4 |
if(file_count)
|
|
Packit |
8f70b4 |
j->FileCount();
|
|
Packit |
8f70b4 |
/* if separate_dirs is on, then there's no point in traversing past
|
|
Packit |
8f70b4 |
* max_print_depth at all */
|
|
Packit |
8f70b4 |
if(separate_dirs && maxdepth != -1)
|
|
Packit |
8f70b4 |
j->set_maxdepth(maxdepth);
|
|
Packit |
8f70b4 |
if(exclude)
|
|
Packit |
8f70b4 |
j->SetExclude(exclude.borrow());
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(command)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(args->count()<2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s command args...\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
args->delarg(0);
|
|
Packit |
8f70b4 |
return parent->builtin_restart();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(module)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
if(args->count()<2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s module [args...]\n"),args->a0());
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void *map=module_load(args->getarg(1),args->count()-1,args->GetV()+1);
|
|
Packit |
8f70b4 |
if(map==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s\n",module_error_message());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(lpwd)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!parent->cwd)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s: %s\n",args->a0(),_("cannot get current directory"));
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *name=parent->cwd->GetName();
|
|
Packit |
8f70b4 |
const char *buf=xstring::cat(name?name:"?","\n",NULL);
|
|
Packit |
8f70b4 |
Job *j=new echoJob(buf,new OutputJob(output.borrow(), args->a0()));
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(local)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return parent->builtin_local();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(glob)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return parent->builtin_glob();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(chmod)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
ChmodJob::verbosity verbose = ChmodJob::V_NONE;
|
|
Packit |
8f70b4 |
bool recurse = false, quiet = false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static struct option chmod_options[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"verbose",no_argument,0,'v'},
|
|
Packit |
8f70b4 |
{"changes",no_argument,0,'c'},
|
|
Packit |
8f70b4 |
{"recursive",no_argument,0,'R'},
|
|
Packit |
8f70b4 |
{"silent",no_argument,0,'f'},
|
|
Packit |
8f70b4 |
{"quiet",no_argument,0,'f'},
|
|
Packit |
8f70b4 |
{0,0,0,0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
int modeind = 0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
while((opt=args->getopt_long("vcRfrwxXstugoa,+-=",chmod_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case 'r': case 'w': case 'x':
|
|
Packit |
8f70b4 |
case 'X': case 's': case 't':
|
|
Packit |
8f70b4 |
case 'u': case 'g': case 'o':
|
|
Packit |
8f70b4 |
case 'a':
|
|
Packit |
8f70b4 |
case ',':
|
|
Packit |
8f70b4 |
case '+': case '=':
|
|
Packit |
8f70b4 |
modeind = optind?optind-1:1;
|
|
Packit |
8f70b4 |
break; /* mode string that begins with - */
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case 'v':
|
|
Packit |
8f70b4 |
verbose=ChmodJob::V_ALL;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'c':
|
|
Packit |
8f70b4 |
verbose=ChmodJob::V_CHANGES;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'R':
|
|
Packit |
8f70b4 |
recurse = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'f':
|
|
Packit |
8f70b4 |
quiet = true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
case '?':
|
|
Packit |
8f70b4 |
usage:
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [OPTS] mode file...\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(modeind == 0)
|
|
Packit |
8f70b4 |
modeind = args->getindex();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *arg = args->getarg(modeind);
|
|
Packit |
8f70b4 |
if(!arg)
|
|
Packit |
8f70b4 |
goto usage;
|
|
Packit |
8f70b4 |
arg = alloca_strdup(arg);
|
|
Packit |
8f70b4 |
args->delarg(modeind);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!args->getcurr())
|
|
Packit |
8f70b4 |
goto usage;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
mode_change *m = mode_compile(arg);
|
|
Packit |
8f70b4 |
if(!m)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("invalid mode string: %s\n"), arg);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
ChmodJob *j=new ChmodJob(session->Clone(),args.borrow());
|
|
Packit |
8f70b4 |
j->SetVerbosity(verbose);
|
|
Packit |
8f70b4 |
j->SetMode(m);
|
|
Packit |
8f70b4 |
if(quiet)
|
|
Packit |
8f70b4 |
j->BeQuiet(); /* does not affect messages from Verbosity */
|
|
Packit |
8f70b4 |
if(recurse)
|
|
Packit |
8f70b4 |
j->Recurse();
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(queue)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return parent->builtin_queue();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(get1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
static struct option get1_options[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"ascii",no_argument,0,'a'},
|
|
Packit |
8f70b4 |
{"source-region",required_argument,0,256+'r'},
|
|
Packit |
8f70b4 |
{"target-position",required_argument,0,256+'R'},
|
|
Packit |
8f70b4 |
{"continue",no_argument,0,'c'},
|
|
Packit |
8f70b4 |
{"output",required_argument,0,'o'},
|
|
Packit |
8f70b4 |
{"remove-source-later",no_argument,0,'E'},
|
|
Packit |
8f70b4 |
{"remove-target-first",no_argument,0,'e'},
|
|
Packit |
8f70b4 |
{"make-target-dir",no_argument,0,'d'},
|
|
Packit |
8f70b4 |
{"quiet",no_argument,0,'q'},
|
|
Packit |
8f70b4 |
{0,0,0,0}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
const char *src=0;
|
|
Packit |
8f70b4 |
const char *dst=0;
|
|
Packit |
8f70b4 |
bool cont=false;
|
|
Packit |
8f70b4 |
bool ascii=false;
|
|
Packit |
8f70b4 |
bool quiet=false;
|
|
Packit |
8f70b4 |
bool do_mkdir=false;
|
|
Packit |
8f70b4 |
long long source_region_begin=0,source_region_end=FILE_END;
|
|
Packit |
8f70b4 |
long long target_region_begin=0,target_region_end=FILE_END;
|
|
Packit |
8f70b4 |
int n,p;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
while((opt=args->getopt_long("arco:d",get1_options))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case 'c':
|
|
Packit |
8f70b4 |
cont=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'a':
|
|
Packit |
8f70b4 |
ascii=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'o':
|
|
Packit |
8f70b4 |
dst=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 256+'r':
|
|
Packit |
8f70b4 |
source_region_end=FILE_END;
|
|
Packit |
8f70b4 |
n=sscanf(optarg,"%lld%n-%lld",&source_region_begin,&p,&source_region_end);
|
|
Packit |
8f70b4 |
if(n<1 || (n==1 && (optarg[p] && (optarg[p]!='-' || optarg[p+1]))))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s\n",_("Invalid range format. Format is min-max, e.g. 10-20."));
|
|
Packit |
8f70b4 |
goto usage;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 256+'R':
|
|
Packit |
8f70b4 |
target_region_end=FILE_END;
|
|
Packit |
8f70b4 |
n=sscanf(optarg,"%lld",&target_region_begin);
|
|
Packit |
8f70b4 |
if(n<1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s\n",_("Invalid range format. Format is min-max, e.g. 10-20."));
|
|
Packit |
8f70b4 |
goto usage;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('q'):
|
|
Packit |
8f70b4 |
quiet=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('d'):
|
|
Packit |
8f70b4 |
do_mkdir=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case '?':
|
|
Packit |
8f70b4 |
usage:
|
|
Packit |
8f70b4 |
eprintf(_("Usage: %s [OPTS] file\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
src=args->getcurr();
|
|
Packit |
8f70b4 |
if(src==0)
|
|
Packit |
8f70b4 |
goto usage;
|
|
Packit |
8f70b4 |
if(args->getnext()!=0)
|
|
Packit |
8f70b4 |
goto usage;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool auto_rename=false;
|
|
Packit |
8f70b4 |
if(dst==0 || dst[0]==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
dst=basename_ptr(src);
|
|
Packit |
8f70b4 |
auto_rename=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(last_char(dst)=='/' && basename_ptr(dst)[0]!='/')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *bn=basename_ptr(src);
|
|
Packit |
8f70b4 |
if(bn[0]!='/')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
dst=xstring::get_tmp(dst).append(bn);
|
|
Packit |
8f70b4 |
auto_rename=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
ParsedURL dst_url(dst,true);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(dst_url.proto==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
dst=expand_home_relative(dst);
|
|
Packit |
8f70b4 |
// check if dst is a directory.
|
|
Packit |
8f70b4 |
struct stat st;
|
|
Packit |
8f70b4 |
if(stat(dst,&st)!=-1)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(S_ISDIR(st.st_mode))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *slash=strrchr(src,'/');
|
|
Packit |
8f70b4 |
if(slash)
|
|
Packit |
8f70b4 |
slash++;
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
slash=src;
|
|
Packit |
8f70b4 |
dst=xstring::cat(dst,"/",slash,NULL);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
dst=alloca_strdup(dst); // save tmp xstring
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileCopyPeer *src_peer=0;
|
|
Packit |
8f70b4 |
FileCopyPeer *dst_peer=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
src_peer=FileCopyPeerFA::New(session->Clone(),src,FA::RETRIEVE);
|
|
Packit |
8f70b4 |
if(!cont && (source_region_begin>0 || source_region_end!=FILE_END))
|
|
Packit |
8f70b4 |
src_peer->SetRange(source_region_begin,source_region_end);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(dst_url.proto==0)
|
|
Packit |
8f70b4 |
dst_peer=FileCopyPeerFDStream::NewPut(dst,cont||target_region_begin>0);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
dst_peer=new FileCopyPeerFA(&dst_url,FA::STORE);
|
|
Packit |
8f70b4 |
dst_peer->AutoRename(auto_rename && ResMgr::QueryBool("xfer:auto-rename",0));
|
|
Packit |
8f70b4 |
if(!cont && (target_region_begin>0 || target_region_end!=FILE_END))
|
|
Packit |
8f70b4 |
dst_peer->SetRange(target_region_begin,target_region_end);
|
|
Packit |
8f70b4 |
if(do_mkdir)
|
|
Packit |
8f70b4 |
dst_peer->MakeTargetDir();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileCopy *c=FileCopy::New(src_peer,dst_peer,cont);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(ascii)
|
|
Packit |
8f70b4 |
c->Ascii();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CopyJob *cj=new CopyJob(c,src,args->a0());
|
|
Packit |
8f70b4 |
cj->Quiet(quiet);
|
|
Packit |
8f70b4 |
return cj;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(slot)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *n=args->getarg(1);
|
|
Packit |
8f70b4 |
if(n)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
parent->ChangeSlot(n);
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_ca slots(ConnectionSlot::Format());
|
|
Packit |
8f70b4 |
Job *j=new echoJob(slots,new OutputJob(output.borrow(),args->a0()));
|
|
Packit |
8f70b4 |
return j;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(tasks)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
printf("task_count=%d\n",SMTask::TaskCount());
|
|
Packit |
8f70b4 |
SMTask::PrintTasks();
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(empty)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
exit_code=(args->count()>1 ? 1 : 0);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
CMD(notempty)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
exit_code=(args->count()>1 ? 0 : 1);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
CMD(true)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
CMD(false)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
exit_code=1;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
CMD(eval)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
const char *fmt=0;
|
|
Packit |
8f70b4 |
const char *op=args->getarg(0);
|
|
Packit |
8f70b4 |
while((opt=args->getopt("+f:"))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case 'f':
|
|
Packit |
8f70b4 |
fmt=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
default:
|
|
Packit |
8f70b4 |
eprintf(_("Try `%s --help' for more information\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
int base=optind;
|
|
Packit |
8f70b4 |
xstring cmd;
|
|
Packit |
8f70b4 |
if(!fmt)
|
|
Packit |
8f70b4 |
args->CombineTo(cmd,optind);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
while(*fmt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(*fmt=='\\' && (fmt[1]=='$' || fmt[1]=='\\'))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
cmd.append(fmt[1]);
|
|
Packit |
8f70b4 |
fmt+=2;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(*fmt=='$' && fmt[1]>='0' && fmt[1]<='9')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int n=fmt[1]-'0';
|
|
Packit |
8f70b4 |
if(n+base<args->count())
|
|
Packit |
8f70b4 |
cmd.append(args->getarg(n+base));
|
|
Packit |
8f70b4 |
fmt+=2;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(*fmt=='$' && fmt[1]=='@')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_ca c(args->CombineQuoted(base));
|
|
Packit |
8f70b4 |
cmd.append(c);
|
|
Packit |
8f70b4 |
fmt+=2;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(*fmt=='$' && fmt[1]=='$')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
cmd.appendf("%d",(int)getpid());
|
|
Packit |
8f70b4 |
fmt+=2;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
cmd.append(*fmt++);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
cmd.append(";\n\n");
|
|
Packit |
8f70b4 |
parent->PrependCmd(cmd);
|
|
Packit |
8f70b4 |
exit_code=parent->prev_exit_code;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|