/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
* The Regents of the University of California
* All Rights Reserved
*
* University Acknowledgment- Portions of this document are derived from
* software developed by the University of California, Berkeley, and its
* contributors.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* FTP User Program -- Command Routines.
*/
#define FTP_NAMES
#include "ftp_var.h"
static char *mname;
static char *onoff(int bool);
static char *getlevel(int);
/* Prompt for command argument, add to buffer with space separator */
static int
{
(void) printf("Line too long\n");
return (-1);
}
stop_timer();
== NULL) {
reset_timer();
return (-1);
}
/* Flush what didn't fit in the buffer */
;
(void) printf("Line too long\n");
reset_timer();
return (-1);
} else
reset_timer();
return (0);
}
/*
* Connect to peer server and
* auto-login, if possible.
*/
void
{
char *host;
if (connected) {
(void) printf("Already connected to %s, use close first.\n",
hostname);
code = -1;
return;
}
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
code = -1;
return;
}
if (host) {
int overbose;
extern char reply_string[];
connected = 1;
/*
* Set up defaults for FTP.
*/
if (autoauth) {
if (do_auth() && autoencrypt) {
else {
"%s: couldn't enable encryption\n",
argv[0]);
/* unable to encrypt command channel, too! */
}
}
}
if (autologin)
/* if skipsyst is enabled, then don't send SYST command */
if (skipsyst)
return;
if (debug == 0)
verbose = -1;
char *cp, c;
if (cp) {
cp--;
c = *cp;
*cp = '\0';
}
(void) printf("Remote system type is %s.\n",
reply_string+4);
if (cp)
*cp = c;
}
if (overbose)
(void) printf(
"Using %s mode to transfer files.\n",
typename);
} else if (overbose &&
(void) printf(
"Remember to set tenex mode when transfering "
"binary files from this machine.\n");
}
}
}
static struct types {
char *t_name;
char *t_mode;
int t_type;
char *t_arg;
} types[] = {
0
};
/*
* Set transfer type.
*/
void
{
struct types *p;
int comret;
if (argc > 2) {
char *sep;
sep = " ";
if (*sep == ' ')
sep = " | ";
}
(void) printf(" ]\n");
code = -1;
return;
}
if (argc < 2) {
code = 0;
return;
}
break;
if (p->t_name == 0) {
code = -1;
return;
}
else
}
}
/*
* Set binary transfer type.
*/
/*ARGSUSED*/
void
{
}
/*
* Set ascii transfer type.
*/
/*ARGSUSED*/
void
{
}
/*
* Set tenex transfer type.
*/
/*ARGSUSED*/
void
{
}
/*
* Set ebcdic transfer type.
*/
/*ARGSUSED*/
void
{
}
/*
* Set file transfer mode.
*/
/*ARGSUSED*/
void
{
code = -1;
}
/*
* Set file transfer format.
*/
/*ARGSUSED*/
void
{
code = -1;
}
/*
* Set file transfer structure.
*/
/*ARGSUSED*/
void
{
code = -1;
}
/*
* Send a single file.
*/
void
{
char *cmd;
int loc = 0;
char *oldargv1;
if (argc == 2) {
argc++;
loc++;
}
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
if (argc < 3) {
code = -1;
return;
}
makeargv();
}
if (argc < 3)
goto usage;
code = -1;
return;
}
/*
* If "globulize" modifies argv[1], and argv[2] is a copy of
* the old argv[1], make it a copy of the new argv[1].
*/
}
}
}
}
/*ARGSUSED*/
static void
{
int ointer;
(void) printf("\n");
interactive = 1;
}
}
mflag = 0;
}
/*
* Send multiple files.
*/
void
{
int i;
int ointer;
void (*oldintr)();
char *tp;
int len;
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
mflag = 1;
if (proxy) {
if (*cp == 0) {
mflag = 0;
continue;
}
if (mcase) {
while (*tp) {
if ((len =
len = 1;
break;
}
if (!*tp) {
while (*tp) {
MB_CUR_MAX)) <= 0)
len = 1;
*tp2 = 'a' +
*tp2 - 'A';
}
}
*tp2 = 0;
}
}
if (ntflag) {
}
if (mapflag) {
}
interactive = 1;
mflag++;
}
}
}
}
mflag = 0;
return;
}
for (i = 1; i < argc; i++) {
if (!doglob) {
interactive = 1;
mflag++;
}
}
}
continue;
}
if (gargs)
continue;
}
interactive = 1;
mflag++;
}
}
}
}
}
mflag = 0;
}
/*
* Restart transfer at a specific offset.
*/
void
{
if (argc > 2) {
code = -1;
return;
}
if (argc == 2) {
char *endp;
errno = 0;
(void) printf("%s: Invalid offset `%s'\n",
else
restart_point = rp;
}
if (restart_point == 0) {
if (orestart_point == 0)
(void) printf("No restart marker defined\n");
else
(void) printf("Restart marker cleared\n");
} else
(void) printf(
"Restarting at %lld for next get, put or append\n",
}
void
{
}
void
{
}
/*
* Receive one file.
*/
static void
{
int loc = 0;
int len;
if (argc == 2) {
argc++;
/* Only permit !file if two arguments. */
allowpipe = 0;
loc++;
}
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
(void) printf("usage: %s remote-file [ local-file ]\n",
argv[0]);
code = -1;
return;
}
if (argc < 3) {
code = -1;
return;
}
makeargv();
}
if (argc < 3)
goto usage;
code = -1;
return;
}
while (*tp) {
len = 1;
break;
}
if (!*tp) {
while (*tp) {
len = 1;
}
*tp2 = 0;
}
}
}
}
if (restartit) {
code = -1;
return;
}
}
restart_point = 0;
}
/*
* Get multiple files.
*/
void
{
int ointer;
void (*oldintr)();
int need_convert;
int len;
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
mflag = 1;
if (*cp == '\0') {
mflag = 0;
continue;
}
need_convert = 1;
if (mcase) {
while (*tp2 && need_convert) {
/* Need any case convert? */
need_convert = 0;
len = 1;
}
while (need_convert && *tp2) {
/* Convert to lower case */
len = 1;
}
}
if (ntflag) {
}
if (mapflag) {
}
restart_point = 0;
interactive = 1;
mflag++;
}
}
}
}
mflag = 0;
}
static char *
{
static char **args;
char *cp;
if (!mflag) {
if (!doglob) {
} else {
}
}
return (NULL);
}
if (!doglob) {
return (cp);
}
return (NULL);
}
if (doswitch) {
}
if (doswitch) {
}
}
reset_timer();
return (NULL);
}
*cp = '\0';
return (buf);
}
static char *
onoff(int bool)
{
return (bool ? "on" : "off");
}
/*
* Show status.
*/
/*ARGSUSED*/
void
{
int i;
char *levelp;
if (connected)
else
(void) printf("Not connected.\n");
if (!proxy) {
pswitch(1);
if (connected) {
(void) printf("Connected for proxy commands to %s.\n",
hostname);
} else {
(void) printf("No proxy connection.\n");
}
pswitch(0);
}
if (auth_type != AUTHTYPE_NONE)
(void) printf("Authentication type: %s\n",
else
(void) printf("Not authenticated.\n");
(void) printf("Autoauth: %s; Autologin: %s\n",
(void) printf("Control Channel Protection Level: %s\n",
(void) printf("Data Channel Protection Level: %s\n",
(void) printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
(void) printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n",
(void) printf("Case: %s; CR stripping: %s\n",
if (ntflag) {
} else {
(void) printf("Ntrans: off\n");
}
if (mapflag) {
} else {
(void) printf("Nmap: off\n");
}
(void) printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
if (macnum > 0) {
(void) printf("Macros:\n");
for (i = 0; i < macnum; i++) {
}
}
code = 0;
}
/*
* Set beep on cmd completed mode.
*/
/*ARGSUSED*/
void
{
}
/*
* Turn on packet tracing.
*/
/*ARGSUSED*/
void
{
}
/*
* Toggle hash mark printing during transfers.
*/
/*ARGSUSED*/
void
{
if (hash)
(void) printf(".\n");
}
/*
* Turn on printing of server echo's.
*/
/*ARGSUSED*/
void
{
}
/*
* Toggle PORT cmd use before each data connection.
*/
/*ARGSUSED*/
void
{
}
/*
* Turn on interactive prompting
* during mget, mput, and mdelete.
*/
/*ARGSUSED*/
void
{
code = interactive;
}
/*
* Toggle metacharacter interpretation
* on local file names.
*/
/*ARGSUSED*/
void
{
}
/*
* set level of debugging.
*/
void
{
int val;
if (argc > 1) {
if (val < 0) {
code = -1;
return;
}
} else
if (debug)
else
}
/*
* Set current working directory
* on remote machine.
*/
void
{
if (argc < 2) {
0) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
}
/*
* Set current working directory
* on local machine.
*/
void
{
if (argc < 2)
if (argc != 2) {
code = -1;
return;
}
code = -1;
return;
}
code = -1;
return;
}
/*
* Even though chdir may succeed, getcwd may fail if a component
* of the pwd is unreadable. In this case, print the argument to
* chdir as the resultant directory, since we know it succeeded above.
*/
code = 0;
}
/*
* Delete a single file.
*/
void
{
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
}
/*
* Delete multiple files.
*/
void
{
char *cp;
int ointer;
void (*oldintr)();
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
mflag = 1;
if (*cp == '\0') {
mflag = 0;
continue;
}
interactive = 1;
mflag++;
}
}
}
}
mflag = 0;
}
/*
* Rename a remote file.
*/
void
{
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
if (argc < 3) {
code = -1;
return;
}
makeargv();
}
if (argc < 3)
goto usage;
}
/*
* Get a directory listing
* of remote files.
*/
void
{
char *cmd;
if (argc < 2)
if (argc < 3)
if (argc > 3) {
(void) printf("usage: %s remote-directory local-file\n",
argv[0]);
code = -1;
return;
}
if (ls_invokes_NLST) {
"NLST" : "LIST");
} else {
}
code = -1;
return;
}
}
/*
* Get a directory listing
* of multiple remote files.
*/
void
{
int ointer, i;
void (*oldintr)();
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc < 3) {
code = -1;
return;
}
makeargv();
}
if (argc < 3) {
code = -1;
return;
}
code = -1;
return;
}
mflag = 1;
interactive = 1;
mflag ++;
}
}
}
mflag = 0;
}
/*
* Do a shell escape
*/
/*ARGSUSED*/
void
{
int status;
stop_timer();
if (shellstring == NULL)
shellstring = "/bin/sh";
namep = shellstring;
if (argc > 1) {
if (debug) {
altarg);
}
} else {
if (debug) {
}
}
code = -1;
exit(1);
}
if (pid > 0)
;
reset_timer();
perror("Try again later");
code = -1;
} else {
code = 0;
}
}
/*
* Send new user information (re-login)
*/
void
{
int n, aflag = 0;
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc > 4) {
(void) printf("usage: %s username [password] [account]\n",
argv[0]);
code = -1;
return;
}
if (argv[1] == 0) {
(void) printf("access for user (nil) denied\n");
code = -1;
return;
}
if (n == CONTINUE) {
int oldclevel;
if (argc < 3)
/* level may have changed */
}
if (n == CONTINUE) {
if (argc < 4) {
stop_timer();
reset_timer();
}
aflag++;
}
if (n != COMPLETE) {
return;
}
}
}
/*
* Print working directory.
*/
/*ARGSUSED*/
void
{
(void) command("PWD");
}
/*
* Make a directory.
*/
void
{
if (argc < 2) {
0) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
}
/*
* Remove a directory.
*/
void
{
if (argc < 2) {
0) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
}
/*
* Send a line, verbatim, to the remote machine.
*/
void
{
int i, n, len;
if (argc < 2) {
"command line to send") == -1) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
for (i = 2; i < argc; i++) {
argv[i]);
break;
len += n;
}
}
;
}
}
/*
* Send a line, verbatim, to the remote machine as a SITE command.
*/
void
{
int i, n, len;
if (argc < 2) {
"arguments to SITE command") == -1) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
for (i = 2; i < argc; i++) {
argv[i]);
break;
len += n;
}
}
;
}
}
/*
* Ask the other side for help.
*/
void
{
verbose = 1;
}
/*
* Terminate session and exit.
*/
/*ARGSUSED*/
void
{
if (connected)
disconnect(0, NULL);
pswitch(1);
if (connected) {
disconnect(0, NULL);
}
exit(0);
}
/*
* Terminate session, but don't exit.
*/
/*ARGSUSED*/
void
{
extern int data;
if (!connected)
return;
(void) command("QUIT");
if (ctrl_in) {
reset_timer();
}
if (ctrl_out) {
reset_timer();
}
connected = 0;
data = -1;
if (!proxy) {
macnum = 0;
}
goteof = 0;
}
static int
{
if (!interactive)
return (1);
stop_timer();
*line = '\0';
reset_timer();
}
void
{
exit(1);
}
/*
* Glob a local file name specification with
* the expectation of a single return value.
* Can't control multiple values being expanded
* from the expression, we return only the first.
*/
static int
{
char **globbed;
if (!doglob)
return (1);
globerr = "No match";
if (globbed)
return (0);
}
if (globbed) {
if (!*cpp)
return (0);
}
return (1);
}
void
{
if (argc > 1) {
++argv;
--argc;
while (argc > 1) {
--argc;
++argv;
}
} else {
}
}
/*ARGSUSED*/
static void
{
extern int proxy;
if (!proxy) {
pswitch(1);
}
if (connected) {
proxflag = 1;
} else {
proxflag = 0;
}
pswitch(0);
}
void
{
void (*oldintr)();
struct cmd *c;
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc < 2) {
code = -1;
return;
}
if (c == (struct cmd *)-1) {
(void) printf("?Ambiguous command\n");
code = -1;
return;
}
if (c == 0) {
(void) printf("?Invalid command\n");
code = -1;
return;
}
if (!c->c_proxy) {
(void) printf("?Invalid proxy command\n");
code = -1;
return;
}
code = -1;
return;
}
pswitch(1);
(void) printf("Not connected\n");
pswitch(0);
code = -1;
return;
}
if (connected) {
proxflag = 1;
} else {
proxflag = 0;
}
pswitch(0);
}
/*ARGSUSED*/
void
{
}
/*ARGSUSED*/
void
{
}
void
{
if (argc == 1) {
ntflag = 0;
(void) printf("Ntrans off.\n");
return;
}
ntflag++;
if (argc == 2) {
ntout[0] = '\0';
return;
}
}
static char *
{
;
found = 0;
for (i = 0; *(ntin + i) && i < 16; i++) {
found++;
if (i < ostop) {
}
break;
}
}
if (!found) {
}
}
*cp2 = '\0';
return (new);
}
void
{
char *cp;
if (argc == 1) {
mapflag = 0;
(void) printf("Nmap off.\n");
return;
}
if (argc < 3) {
code = -1;
return;
}
makeargv();
}
if (argc < 3) {
code = -1;
return;
}
mapflag = 1;
code = 1;
if (proxy) {
while (*++cp == ' ')
/* NULL */;
}
*cp = '\0';
while (*++cp == ' ')
/* NULL */;
}
static char *
{
for (i = 0; i < 9; ++i) {
toks[i] = 0;
}
len1 = 1;
}
len2 = 1;
}
switch (wc2) {
case '\\':
len2 = 1;
}
match = 0;
break;
case '$':
if ((len2 =
len2 = 1;
}
while (*cp1) {
cp1, MB_CUR_MAX)) <= 0) {
wc1 =
(unsigned char)*cp1;
len1 = 1;
}
break;
}
else
}
cp2++; /* Consume the digit */
if (wc2)
break;
}
/* intentional drop through */
default:
match = 0;
break;
}
}
*cp1 = '\0';
while (*cp2) {
match = 0;
switch (*cp2) {
case '\\':
cp2++;
if (*cp2) {
len2 = 1;
}
break;
case '[':
LOOP:
cp2++;
if (*++cp2 == '0') {
while (*cp3) {
}
match = 1;
}
match = 1;
}
} else {
if (*cp2 == '\\') {
cp2++;
continue;
}
if (*++cp2 == '0') {
while (*cp3)
continue;
}
while (cp3 !=
}
continue;
}
if (*cp2) {
if ((len2 =
0) {
len2 = 1;
}
}
}
if (!*cp2) {
(void) printf(
"nmap: unbalanced brackets\n");
return (name);
}
match = 1;
}
if (match) {
cp2++;
}
0)
len2 = 1;
}
if (!*cp2) {
(void) printf(
"nmap: unbalanced brackets\n");
return (name);
}
cp2++;
break;
}
switch (*++cp2) {
case ',':
goto LOOP;
case ']':
break;
default:
cp2--;
goto LOOP;
}
cp2++;
break;
case '$':
if (*++cp2 == '0') {
while (*cp3) {
}
}
}
cp2++;
break;
}
/* intentional drop through */
default:
len2 = 1;
break;
}
}
*cp1 = '\0';
if (!*new) {
return (name);
}
return (new);
}
/*ARGSUSED*/
void
{
}
/*ARGSUSED*/
void
{
}
/*ARGSUSED*/
void
{
code = passivemode;
}
void
{
if (argc > 2) {
code = -1;
return;
}
if (argc == 2) {
int window;
char *endp;
errno = 0;
(void) printf("%s: Invalid size `%s'\n",
else
}
if (tcpwindowsize == 0) {
if (owindowsize == 0)
(void) printf("No TCP window size defined\n");
else
(void) printf("TCP window size cleared\n");
} else
}
/* change directory to parent directory */
/*ARGSUSED*/
void
{
(void) command("CDUP");
}
void
{
char *tmp;
int c;
if (macnum == 16) {
(void) printf("Limit of 16 macros have already been defined\n");
code = -1;
return;
}
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc != 2) {
code = -1;
return;
}
if (interactive) {
(void) printf("Enter macro line by line, terminating "
"it with a null line\n");
}
if (macnum == 0) {
} else {
}
(void) printf("macdef:end of file encountered\n");
code = -1;
return;
}
if ((*tmp = c) == '\n') {
code = 0;
return;
}
code = 0;
return;
}
*tmp = '\0';
}
tmp++;
}
for (;;) {
/* NULL */;
(void) printf(
"Macro not defined - 4k buffer exceeded\n");
code = -1;
return;
}
}
}
/*
* The p_name strings are for the getlevel and setlevel commands.
* protnames[] array of strings.
*/
static struct levels {
char *p_name;
char *p_mode;
int p_level;
} levels[] = {
};
/*
* Return a pointer to a string which is the readable version of the
* protection level, or NULL if the input level is not found.
*/
static char *
{
struct levels *p;
;
}
static char *plevel[] = {
"protect",
"",
};
/*
* Set control channel protection level.
*/
void
{
struct levels *p;
char *levelp;
int comret;
if (argc > 2) {
char *sep;
sep = " ";
if (*sep == ' ')
sep = " | ";
}
(void) printf(" ]\n");
code = -1;
return;
}
if (argc < 2) {
(void) printf("Using %s protection level for commands.\n",
code = 0;
return;
}
break;
if (p->p_name == 0) {
code = -1;
return;
}
if (auth_type == AUTHTYPE_NONE) {
(void) printf("Cannot set protection level to %s\n",
argv[1]);
return;
}
return;
}
(void) printf("Control channel protection level set to %s.\n",
p->p_name);
}
/*
* Set data channel protection level.
*/
void
{
struct levels *p;
int comret;
if (argc != 2) {
char *sep;
sep = " ";
if (*sep == ' ')
sep = " | ";
}
(void) printf(" ]\n");
code = -1;
return;
}
break;
if (p->p_name == 0) {
code = -1;
return;
}
if (auth_type == AUTHTYPE_NONE) {
(void) printf("Cannot set protection level to %s\n",
argv[1]);
return;
}
/* Start with a PBSZ of 1 meg */
}
/*
* Set clear command protection level.
*/
/* VARARGS */
void
{
}
/*
* Set clear data protection level.
*/
/* VARARGS */
void
{
}
/*
* Set safe data protection level.
*/
/* VARARGS */
void
{
}
/*
* Set private data protection level.
*/
/* VARARGS */
void
{
}
/*
* Set mechanism type
*/
void
{
if (argc < 2) {
code = -1;
return;
}
makeargv();
}
if (argc != 2) {
code = -1;
return;
}
(void) printf("%s: %s: not a valid security mechanism\n",
code = -1;
return;
} else {
code = 0;
return;
}
}