📄 sftpcdoc.cpp
字号:
// sftpcdoc.cpp// sftpc's command documentation, in a form suitable for viewing// from sftpc itself, and for generating HTML documents#include "sftpcdoc.h" // this module#include <fstream.h> // ofstream#include <string.h> // strlen, memcpy, etc.#include "xassert.h" // xassert#include "str.h" // string#include "strtokp.h" // StrtokParseAlias const aliases[] = { { "ls", "dir" }, { "list", "dir" }, { "ll", "dir" }, { "delete", "rm" }, { "del", "rm" }, { "rename", "mv" }, { "ren", "mv" }, { "image", "binary" }, { "reset", "sync" }, { "rhelp", "quote help" }, { "system", "quote syst" }, { "size", "quote size" }, { "rstatus", "quote stat" }, { "site", "quote site" }, { "idle", "quote site idle" }, { "umask", "quote site umask" }, { "chmod", "quote site chmod" }, { "chdir", "cd" }, { "cwd", "cd" }, { "nlst", "nlist" }, { "retr", "get" }, { "stor", "put" }, { "?", "help" }, { "'", "quote" }, { "disconnect", "quit" }, { "close", "quit" }, { "exit", "quit" }, { "bye", "quit" }, { "status", "debug dump" }, // not great, but tolerable};int const numAliases = TABLESIZE(aliases);int findAlias(char const *alias){ for (int i=0; i<TABLESIZE(aliases); i++) { if (0==strcmp(aliases[i].alias, alias)) { return i; } } return -1;}Command const commands[] = { { true, "help", "[<command>]", "Basic and per-command help information.", "(no arg): general info\n" "(command): per-command help\n" "commands: list of all commands\n" "aliases: list of all command aliases\n" "crlf: info about CRLF stuff\n", "In the 'help' list, commands listed with a plus (+) have more\n" "info available as 'help <command>'.\n" }, { true, "help", "commands", "Show list of all commands.", "", "" }, { true, "help", "aliases", "Show list of all command aliases.", "", "" }, { false, "debug", "[on|off|1|breaker|dump|binaryAnyway|localCRLF]", "Debugging support.", "(no arg): toggle printing of outgoing FTP commands\n" "on: print outgoing ftp commands\n" "off: don't print outgoing ftp commands (default)\n" "1: toggle diagnostic output level 1\n" "breaker: breakpoint when debugger is attached\n" "dump: print internal state variables\n" "binaryAnyway: toggle binary transfer despite ascii/binary mode\n" "localCRLF: toggle local CRLF convention\n" "localGlobbing: toggle whether we glob locally or remotely\n", "" }, { false, "passive", "[on|off]", "Set whether we use active or passive transfers.", "(no arg): toggle active/passive mode\n" "on: use passive transfers (default)\n" "off: use active transfers\n", "Normally, active transfers are used. This means that, during a\n" "data transfer, the server initiates a connection to the client.\n" "However, under some circumstances (especially when firewalls are\n" "involved), it may be necessary for the client to initiate the\n" "data connection. This is called a 'passive' transfer.\n" }, { true, "ascii", "", "Use text-mode file transfers (see 'help crlf').", "", "" }, { true, "image", "", "Use binary-mode file transfers (see 'help crlf').", "", "" }, { true, "help", "crlf", "Shows information about CRLF issues.", "", "" }, { false, "type", "(i|a)", "Set transfer mode.", "i: binary mode (default)\n" "a: ascii mode\n", "See 'help crlf'.\n" }, { true, "lcd", "", "Change current local working directory.", "", "" }, { false, "lpwd", "", "Print working directory on the local machine.", "", "" }, { false, "prompt", "[on|off]", "Change prompting mode.", "(no arg): toggle prompts for mget/mput\n" "on: turn on prompting\n" "off: turn off prompting (default)\n", "" }, { false, "hash", "[on|off]", "Set whether to print progress characters.", "(no arg): toggle printing of # every 1k transferred\n" "on: turn on hashes\n" "off: turn off hashes (default)\n", "" }, { true, "quit", "", "Exit sftpc", "", "" }, { false, "!", "<command>", "Execute a command on the local machine.", "", "Calls system(3) to execute a shell command\n" }, // -------------- special protocol actions ------------ { false, "sync", "", "Empty FTP response queue.", "", "This is useful only if the server or client gets confused, and\n" "violates the FTP protocol.\n" }, { false, "test", "[active|passive|text|binary|multi]", "Run online self-tests.", "(no arg): all tests, both active and passive\n" "active: all tests, in active mode\n" "passive: all tests, in passive mode\n" "text: text transfers in current active/passive mode\n" "binary: binary transfers in current active/passive mode\n" "multi: multiple-file command tests\n", "" }, { false, "quote", "<raw-ftp-cmd>", "Send an FTP command directly.", "", "No interpretation is done on the command.\n" }, { true, "prot", "[p|t|c]", "Set or get data channel protection level:", "(no arg): print the current protection level\n" "p (private): turn on privacy and integrity protection\n" "t (integrity): turn on just integrity protection\n" "c (clear): turn off protection\n", "Note that this does *not* affect control-channel encryption,\n" "which is always on (unless sftpc was started with the -9 switch).\n" }, // ----------- "ftp"-like protocol actions ------------- { false, "pwd", "", "Print remote current directory (PWD ftp command).", "", "" }, { true, "cd", "[dir]", "Change remote directory (CWD ftp command).", "", "" }, { false, "cdup", "", "Same as 'cd ..' (CDUP ftp command).", "", "" }, { true, "dir", "[directory]", "Remote directory listing (LIST ftp command).", "", "" }, { false, "nlist", "[arg]", "Remote directory listing, with names only.", "", "This issues the NLST ftp command.\n" }, { true, "get", "<remotefile> [localfile]", "Get remote file (GET ftp command).", "", "" }, { true, "put", "<localfile> [remotefile]", "Send local file to remote machine (PUT ftp command).", "", "" }, { false, "mget", "<pattern>", "Multiple-file get; local globbing by default.", "", "" }, { false, "mput", "<pattern>", "Multiple-file put; local globbing (of course).", "", "" }, { false, "mls", "<pattern>", "Multiple-file list.", "", "This command is primarily useful to see what mget will get." }, { false, "mdelete", "<pattern>", "Multiple-file delete.", "", "" }, { false, "mkdir", "<dir>", "Create remote directory (MKD ftp command).", "", "" }, { false, "rmdir", "<dir>", "Remove remote directory (RMD ftp command).", "", "" }, { false, "mv", "<oldName> <newName>", "Rename remote file (RNFR and RNTO ftp commands).", "", "" }, // abort doesn't work because interaction model prevents user // input during data transfer #if 0 { "abort", "", "Abort data transfer (ABOR ftp command).", "", "" }, #endif // 0 { true, "rm", "<filename>", "Delete remote file (DELE ftp command).", "", "" },};int const numCommands = TABLESIZE(commands);int findCommand(char const *cmd){ for (int i=0; i<TABLESIZE(commands); i++) { if (0==strcmp(commands[i].name, cmd)) { return i; } } return -1;}// name and args in 22 charsstring shortCmdName(int i){ char const *n = commands[i].name; int nlen = strlen(n); char const *a = commands[i].args; int alen = strlen(a); // start with all spaces string ret(23); char *r = ret.pchar(); memset(r, ' ', 22); r[22] = 0; // copy name xassert(nlen <= 22); memcpy(r, n, nlen); if (alen == 0) { // done return ret; } if (nlen + alen + 1 > 22) { // use shortened form memcpy(r + nlen + 1, "[...]", 5); } else { // full form memcpy(r + nlen + 1, a, alen); } return ret;}void printCommandList(bool common){ ostream &os = cout; for (int i=0; i<TABLESIZE(commands); i++) { if (commands[i].common != common) { continue; } os << " " << shortCmdName(i); if (commands[i].arglines[0] != 0 || commands[i].desc[0] != 0) { os << " + "; // indicate addl. info via help command } else { os << " - "; // no more info avail. than is displayed here } os << commands[i].blurb << endl; }}// given an ascii string, return one that looks like it, but is// rendered in HTMLstring addHTMLEscapes(char const *str){ // this is, at the moment, fairly incomplete return replace(replace(str, "<", "<"), ">", ">");}void writeHTMLCommands(){ ostream &os = cout; os << "<!-- this block of HTML is generated automatically by\n" " 'sftpc -@', and pasted into sftpc.html by a script -->\n\n"; for (int i=0; i<TABLESIZE(commands); i++) { os << "<p><a name=" << commands[i].name << ">\n" << "<dt><b>" << commands[i].name << "</b> " << addHTMLEscapes(commands[i].args) << "\n</a><dd>\n" << commands[i].blurb << "\n"; // per-argument descs { StrtokParse tok(commands[i].arglines, "\n"); if (tok > 0) { os << "<blockquote>\n"; // blockquote for indentation for (int t=0; t<tok; t++) { os << " " << tok[t] << "<br>\n"; } os << "</blockquote>\n"; } } // command as a whole { StrtokParse tok(commands[i].desc, "\n"); for (int t=0; t<tok; t++) { os << tok[t] << "\n"; } } os << "\n"; } os << "<!-- end of automatically-generated HTML -->\n";}#if 0void entry(){ writeOnlineHelp(); writeHTML();}USUAL_MAIN#endif // 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -