static char sccsid
[] = "@(#)main.c 4.8 (Berkeley) %G%";
* FTP User Program -- Command Interface.
char homedir
[MAXPATHLEN
];
sp
= getservbyname("ftp", "tcp");
fprintf(stderr
, "ftp: ftp/tcp: unknown service\n");
while (argc
> 0 && **argv
== '-') {
for (cp
= *argv
+ 1; *cp
; cp
++)
"ftp: %c: unknown option\n", *cp
);
fromatty
= isatty(fileno(stdin
));
* Set up defaults for FTP.
strcpy(typename
, "ascii"), type
= TYPE_A
;
strcpy(formname
, "non-print"), form
= FORM_N
;
strcpy(modename
, "stream"), mode
= MODE_S
;
strcpy(structname
, "file"), stru
= STRU_F
;
strcpy(bytename
, "8"), bytesize
= 8;
* Set up the home directory in case we're globbing.
pw
= getpwnam(getlogin());
strcpy(home
, pw
->pw_dir
);
signal(SIGPIPE
, lostpeer
);
setpeer(argc
+ 1, argv
- 1);
top
= setjmp(toplevel
) == 0;
signal(SIGPIPE
, lostpeer
);
shutdown(fileno(cout
), 1+1);
s
= rindex(filename
, '/');
extern struct cmd cmdtab
[];
if (c
== (struct cmd
*)-1) {
printf("?Ambiguous command\n");
printf("?Invalid command\n");
if (c
->c_conn
&& !connected
) {
printf ("Not connected.\n");
(*c
->c_handler
)(margc
, margv
);
if (c
->c_handler
!= help
)
register struct cmd
*c
, *found
;
register int nmatches
, longest
;
for (c
= cmdtab
; p
= c
->c_name
; c
++) {
for (q
= name
; *q
== *p
++; q
++)
if (*q
== 0) /* exact match? */
if (!*q
) { /* the name was a prefix */
if (q
- name
> longest
) {
} else if (q
- name
== longest
)
return ((struct cmd
*)-1);
* Slice a string up into argc/argv.
stringbase
= line
; /* scan from first of buffer */
argbase
= argbuf
; /* store from first of buffer */
while (*argp
++ = slurpstring())
* Parse string into argbuf;
* implemented with FSM to
* handle quoting and strings
register char *sb
= stringbase
;
register char *ap
= argbase
;
char *tmp
= argbase
; /* will return this if token found */
if (*sb
== '!') { /* recognize ! as a token for shell */
goto OUT
; /* end of token */
sb
++; goto S2
; /* slurp next character */
sb
++; goto S3
; /* slurp quoted string */
*ap
++ = *sb
++; /* add character to token */
argbase
= ap
; /* update storage pointer */
stringbase
= sb
; /* update scan pointer */
#define HELPINDENT (sizeof ("directory"))
* Call each command handler with argc == 0 and argv[0] == name.
int columns
, width
= 0, lines
;
printf("Commands may be abbreviated. Commands are:\n\n");
for (c
= cmdtab
; c
< &cmdtab
[NCMDS
]; c
++) {
int len
= strlen(c
->c_name
);
width
= (width
+ 8) &~ 7;
lines
= (NCMDS
+ columns
- 1) / columns
;
for (i
= 0; i
< lines
; i
++) {
for (j
= 0; j
< columns
; j
++) {
c
= cmdtab
+ j
* lines
+ i
;
if (c
+ lines
>= &cmdtab
[NCMDS
]) {
if (c
== (struct cmd
*)-1)
printf("?Ambiguous help command %s\n", arg
);
else if (c
== (struct cmd
*)0)
printf("?Invalid help command %s\n", arg
);
printf("%-*s\t%s\n", HELPINDENT
,
* Call routine with argc, argv set from args (terminated by 0).
for (argc
= 0, argp
= &args
; *argp
++ != 0; argc
++)