📄 cmds.c
字号:
#ifdef HAVE_VSNPRINTF
len = (size_t) vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
va_end(ap);
buf[sizeof(buf) - 1] = '\0';
#else
(void) vsprintf(buf, fmt, ap);
va_end(ap);
len = strlen(buf);
#endif
buf[len] = '\0';
Trace(9, "%s\n", buf);
for (; len < padlim; len++)
buf[len] = ' ';
buf[len] = '\0';
#if 0
(void) fprintf(stdout, "\r%s", buf);
#else
(void) fprintf(stdout, "%s\r", buf);
#endif
(void) fflush(stdout);
} /* OpenMsg */
static void
NcFTPOpenPrintResponseProc(const FTPCIPtr cipUNUSED, ResponsePtr rp)
{
gUnusedArg = (cipUNUSED != NULL);
if ((rp->printMode & kResponseNoPrint) != 0)
return;
#if 0
if (rp->code == 331) /* Skip: "331 User name okay, need password." */
return;
#else
/* This is only used to print errors. */
if (rp->code < 400)
return;
#endif
PrintResp(&rp->msg);
} /* NcFTPOpenPrintResponseProc */
static void
NcFTPOnConnectMessageProc(const FTPCIPtr cipUNUSED, ResponsePtr rp)
{
gUnusedArg = (cipUNUSED != NULL);
(void) printf("\n");
PrintResp(&rp->msg);
OpenMsg("Logging in...");
} /* NcFTPOnConnectMessageProc */
static void
NcFTPOnLoginMessageProc(const FTPCIPtr cipUNUSED, ResponsePtr rp)
{
gUnusedArg = (cipUNUSED != NULL);
(void) printf("\n");
PrintResp(&rp->msg);
OpenMsg("Logging in...");
} /* NcFTPOnLoginMessageProc */
static void
NcFTPRedialStatusProc(const FTPCIPtr cipUNUSED, int mode, int val)
{
gUnusedArg = (cipUNUSED != NULL);
if (mode == kRedialStatusDialing) {
if (val > 0) {
OpenMsg("Redialing (try %d)...", val);
sleep(1); /* Give time for message to stay */
}
} else if (mode == kRedialStatusSleeping) {
OpenMsg("Sleeping %d seconds...", val);
}
} /* NcFTPRedialStatusProc */
static void
NcFTPGetPassphraseProc(const FTPCIPtr cip, LineListPtr pwPrompt, char *pass, size_t dsize)
{
LinePtr lp;
(void) printf("\nPassword requested by %s for user \"%s\".\n\n",
cip->host,
cip->user
);
for (lp = pwPrompt->first; lp != NULL; lp = lp->next) {
(void) printf(" %s\n", lp->line);
}
(void) printf("\n");
(void) gl_getpass("Password: ", pass, (int) dsize);
} /* NcFTPGetPassphraseProc */
/* Attempts to establish a new FTP connection to a remote host. */
int
DoOpen(void)
{
int result;
char ipstr[128];
char ohost[128];
#ifdef SIGALRM
sigproc_t osigalrm;
#endif
char prompt[256];
if (gConn.firewallType == kFirewallNotInUse) {
(void) STRNCPY(ohost, gConn.host);
OpenMsg("Resolving %s...", ohost);
if ((gLoadedBm != 0) && (gBm.lastIP[0] != '\0')) {
result = GetHostByName(ipstr, sizeof(ipstr), ohost, 3);
if (result < 0) {
(void) STRNCPY(ipstr, gBm.lastIP);
result = 0;
} else {
result = GetHostByName(ipstr, sizeof(ipstr), ohost, 7);
}
} else {
result = GetHostByName(ipstr, sizeof(ipstr), ohost, 10);
}
if (result < 0) {
(void) printf("\n");
(void) printf("Unknown host \"%s\".\n", ohost);
return (-1);
}
(void) STRNCPY(gConn.host, ipstr);
OpenMsg("Connecting to %s...", ipstr);
} else {
OpenMsg("Connecting to %s via %s...", gConn.host, gConn.firewallHost);
Trace(0, "Fw: %s Type: %d User: %s Pass: %s Port: %u\n",
gConn.firewallHost,
gConn.firewallType,
gConn.firewallUser,
(gConn.firewallPass[0] == '\0') ? "(none)" : "********",
gConn.firewallPort
);
Trace(0, "FwExceptions: %s\n", gFirewallExceptionList);
if (strchr(gLib.ourHostName, '.') == NULL) {
Trace(0, "NOTE: Your domain name could not be detected.\n");
if (gConn.firewallType != kFirewallNotInUse) {
Trace(0, " Make sure you manually add your domain name to firewall-exception-list.\n");
}
}
}
if (gConn.firewallPass[0] == '\0') {
switch (gConn.firewallType) {
case kFirewallNotInUse:
break;
case kFirewallUserAtSite:
break;
case kFirewallLoginThenUserAtSite:
case kFirewallSiteSite:
case kFirewallOpenSite:
case kFirewallUserAtUserPassAtPass:
case kFirewallFwuAtSiteFwpUserPass:
case kFirewallUserAtSiteFwuPassFwp:
(void) printf("\n");
(void) STRNCPY(prompt, "Password for firewall user \"");
(void) STRNCAT(prompt, gConn.firewallUser);
(void) STRNCAT(prompt, "\" at ");
(void) STRNCAT(prompt, gConn.firewallHost);
(void) STRNCAT(prompt, ": ");
(void) gl_getpass(prompt, gConn.firewallPass, sizeof(gConn.firewallPass));
break;
}
}
if ((gConn.user[0] != '\0') && (strcmp(gConn.user, "anonymous") != 0) && (strcmp(gConn.user, "ftp") != 0)) {
gConn.passphraseProc = NcFTPGetPassphraseProc;
}
/* Register our callbacks. */
gConn.printResponseProc = NcFTPOpenPrintResponseProc;
gConn.onConnectMsgProc = NcFTPOnConnectMessageProc;
gConn.onLoginMsgProc = NcFTPOnLoginMessageProc;
gConn.redialStatusProc = NcFTPRedialStatusProc;
#ifdef SIGALRM
osigalrm = NcSignal(SIGALRM, (FTPSigProc) SIG_IGN);
result = FTPOpenHost(&gConn);
(void) NcSignal(SIGALRM, osigalrm);
#else
result = FTPOpenHost(&gConn);
#endif
if (gConn.firewallType == kFirewallNotInUse)
(void) STRNCPY(gConn.host, ohost); /* Put it back. */
if (result >= 0) {
(void) time(&gBm.lastCall);
LogOpen(gConn.host);
OpenMsg("Logged in to %s.", gConn.host);
(void) printf("\n");
/* Remove callback. */
gConn.printResponseProc = 0;
/* Need to note what our "root" was before we change it. */
if (gConn.startingWorkingDirectory == NULL) {
(void) STRNCPY(gRemoteCWD, "/"); /* Guess! */
} else {
(void) STRNCPY(gRemoteCWD, gConn.startingWorkingDirectory);
}
(void) STRNCPY(gStartDir, gRemoteCWD);
/* If the bookmark specified a remote directory, change to it now. */
if ((gLoadedBm != 0) && (gBm.dir[0] != '\0')) {
result = Chdirs(&gConn, gBm.dir);
if (result < 0) {
FTPPerror(&gConn, result, kErrCWDFailed, "Could not chdir to previous directory", gBm.dir);
}
Trace(-1, "Current remote directory is %s.\n", gRemoteCWD);
}
/* If the bookmark specified a local directory, change to it now. */
if ((gLoadedBm != 0) && (gBm.ldir[0] != '\0')) {
(void) chdir(gBm.ldir);
(void) STRNCPY(gPrevLocalCWD, gLocalCWD);
if (FTPGetLocalCWD(gLocalCWD, sizeof(gLocalCWD)) != NULL) {
Trace(-1, "Current local directory is %s.\n", gLocalCWD);
}
}
/* Identify the FTP client type to the server. Most don't understand this yet. */
if (gConn.hasCLNT != kCommandNotAvailable)
(void) FTPCmd(&gConn, "CLNT NcFTP %.5s %s", gVersion + 11, gOS);
return (0);
} else {
FTPPerror(&gConn, result, 0, "Could not open host", gConn.host);
}
/* Remove callback. */
gConn.printResponseProc = 0;
(void) printf("\n");
return (-1);
} /* Open */
/* Chooses a new remote system to connect to, and attempts to establish
* a new FTP connection. This function is in charge of collecting the
* information needed to do the open, and then doing it.
*/
void
OpenCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
{
int c;
int opts = 0;
int uOptInd = 0;
int n;
int rc;
char url[256];
char urlfile[128];
int directoryURL = 0;
LineList cdlist;
LinePtr lp;
char prompt[256];
ARGSUSED(gUnusedArg);
FlushLsCache();
CloseHost();
gLoadedBm = 0;
InitConnectionInfo();
/* Need to find the host argument first. */
GetoptReset();
while ((c = Getopt(argc, argv, "aP:u:p:J:rd:g:")) > 0) switch(c) {
case 'u':
uOptInd = gOptInd + 1;
opts++;
break;
default:
opts++;
}
if (gOptInd < argc) {
(void) STRNCPY(gConn.host, argv[gOptInd]);
(void) STRNCPY(url, argv[gOptInd]);
} else if (uOptInd > argc) {
/* Special hack for v2.4.2 compatibility */
(void) STRNCPY(gConn.host, argv[argc - 1]);
(void) STRNCPY(url, argv[argc - 1]);
} else {
/* No host arg */
if (opts > 0) {
PrintCmdUsage(cmdp);
} else if (RunBookmarkEditor(gConn.host, sizeof(gConn.host)) == 0) {
if (gConn.host[0] != '\0') {
gLoadedBm = 1;
/* okay, now fall through */
} else {
return;
}
} else if (PrintHosts() <= 0) {
(void) printf("You haven't bookmarked any FTP sites.\n");
(void) printf("Before closing a site, you can use the \"bookmark\" command to save the current\nhost and directory for next time.\n");
return;
} else {
(void) printf("\nTo use a bookmark, use the \"open\" command with the name of the bookmark.\n");
return;
}
}
InitLineList(&cdlist);
if (GetBookmark(gConn.host, &gBm) >= 0) {
gLoadedBm = 1;
(void) STRNCPY(gConn.host, gBm.name);
(void) STRNCPY(gConn.user, gBm.user);
(void) STRNCPY(gConn.pass, gBm.pass);
(void) STRNCPY(gConn.acct, gBm.acct);
gConn.hasSIZE = gBm.hasSIZE;
gConn.hasMDTM = gBm.hasMDTM;
gConn.hasUTIME = gBm.hasUTIME;
gConn.port = gBm.port;
/* Note: Version 3 only goes off of the
* global "gDataPortMode" setting instead of
* setting the dataPortMode on a per-site
* basis.
*/
gConn.hasPASV = gBm.hasPASV;
} else {
SetBookmarkDefaults(&gBm);
memcpy(&gTmpURLConn, &gConn, sizeof(gTmpURLConn));
rc = DecodeDirectoryURL(&gTmpURLConn, url, &cdlist, urlfile, sizeof(urlfile));
if (rc == kMalformedURL) {
(void) fprintf(stdout, "Malformed URL: %s\n", url);
DisposeLineListContents(&cdlist);
return;
} else if (rc == kNotURL) {
directoryURL = 0;
} else {
/* It was a URL. */
if (urlfile[0] != '\0') {
/* It was obviously not a directory */
(void) fprintf(stdout, "Use ncftpget or ncftpput to handle file URLs.\n");
DisposeLineListContents(&cdlist);
return;
}
memcpy(&gConn, &gTmpURLConn, sizeof(gConn));
directoryURL = 1;
}
}
if (MayUseFirewall(gConn.host, gFirewallType, gFirewallExceptionList) != 0) {
gConn.firewallType = gFirewallType;
(void) STRNCPY(gConn.firewallHost, gFirewallHost);
(void) STRNCPY(gConn.firewallUser, gFirewallUser);
(void) STRNCPY(gConn.firewallPass, gFirewallPass);
gConn.firewallPort = gFirewallPort;
}
GetoptReset();
while ((c = Getopt(argc, argv, "aP:u:p:J:j:rd:g:")) > 0) switch(c) {
case 'J':
case 'j':
(void) STRNCPY(gConn.acct, gOptArg);
break;
case 'a':
(void) STRNCPY(gConn.user, "anonymous");
(void) STRNCPY(gConn.pass, "");
(void) STRNCPY(gConn.acct, "");
break;
case 'P':
gConn.port = atoi(gOptArg);
break;
case 'u':
if (uOptInd <= argc)
(void) STRNCPY(gConn.user, gOptArg);
break;
case 'p':
(void) STRNCPY(gConn.pass, gOptArg); /* Don't recommend doing this! */
break;
case 'r':
/* redial is on by default */
break;
case 'g':
n = atoi(gOptArg);
gConn.maxDials = n;
break;
case 'd':
n = atoi(gOptArg);
if (n >= 10)
gConn.redialDelay = n;
break;
default:
PrintCmdUsage(cmdp);
DisposeLineListContents(&cdlist);
return;
}
if (uOptInd > argc) {
(void) STRNCPY(prompt, "Username at ");
(void) STRNCAT(prompt, gConn.host);
(void) STRNCAT(prompt, ": ");
(void) gl_getpass(prompt, gConn.user, sizeof(gConn.user));
}
rc = DoOpen();
if ((rc >= 0) && (directoryURL != 0)) {
for (lp = cdlist.first; lp != NULL; lp = lp->next) {
rc = FTPChdir(&gConn, lp->line);
if (rc != kNoErr) {
FTPPerror(&gConn, rc, kErrCWDFailed, "Could not chdir to", lp->line);
break;
}
}
rc = FTPGetCWD(&gConn, gRemoteCWD, sizeof(gRemoteCWD));
if (rc != kNoErr) {
FTPPerror(&gConn, rc, kErrPWDFailed, NULL, NULL);
} else {
(void) printf("Current remote directory is %s.\n", gRemoteCWD);
}
}
DisposeLineListContents(&cdlist);
} /* OpenCmd */
/* View a remote file through the users $PAGER. */
void
PageCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
{
int result;
int i;
FILE *volatile stream;
#if defined(WIN32) || defined(_WINDOWS)
#else
int sj;
vsigproc_t osigpipe, osigint;
#endif
ARGSUSED(gUnusedArg);
stream = OpenPager();
if (stream == NULL) {
return;
}
#if defined(WIN32) || defined(_WINDOWS)
#else
#ifdef HAVE_SIGSETJMP
osigpipe = osigint = (sigproc_t) 0;
sj = sigsetjmp(gCancelJmp, 1);
#else /* HAVE_SIGSETJMP */
osigpipe = osigint = (sigproc_t) 0;
sj = setjmp(gCancelJmp);
#endif /* HAVE_SIGSETJMP */
if (sj != 0) {
/* Caught a signal. */
(void) NcSignal(SIGPIPE, (FTPSigProc) SIG_IGN);
ClosePager(stream);
(void) NcSignal(SIGPIPE, osigpipe);
(void) NcSignal(SIGINT, osigint);
(void) fprintf(stderr, "Canceled.\n");
Trace(0, "Canceled because of signal %d.\n", gGotSig);
gMayCancelJmp = 0;
return;
} else {
osigpipe = NcSignal(SIGPIPE, Cancel);
osigint = NcSignal(SIGINT, Cancel);
gMayCancelJmp = 1;
}
#endif
for (i=1; i<argc; i++) {
result = FTPGetOneFile2(&gConn, argv[i], NULL, kTypeAscii, fileno(stream), kResumeNo, kAppendNo);
if (result < 0) {
if (errno != EPIPE) {
ClosePager(stream);
stream = NULL;
FTPPerror(&gConn, result, kErrCouldNotStartDataTransfer, argv[0], argv[i]);
}
break;
}
}
#if defined(WIN32) || defined(_WINDOWS)
ClosePager(stream);
#else
(void) NcSignal(SIGPIPE, (FTPSigProc) SIG_IGN);
ClosePager(stream);
(void) NcSignal(SIGPIPE, osigpipe);
(void) NcSignal(SIGINT, osigint);
#endif
gMayCancelJmp = 0;
} /* PageCmd */
static int
NcFTPConfirmResumeUploadProc(
const char *volatile localpath,
volatile longest_int localsize,
volatile time_t localmtime,
const char *volatile *remotepath,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -