diff options
author | Mark Eichin <eichin@mit.edu> | 1996-01-14 08:33:16 +0000 |
---|---|---|
committer | Mark Eichin <eichin@mit.edu> | 1996-01-14 08:33:16 +0000 |
commit | 4233c6f3143639f164290a00eb0ffe720a32b9bc (patch) | |
tree | 11e611f0bdc83991fc573882148217df9f1db53d /src/appl/gssftp/ftp/main.c | |
parent | 347ed3cc833b7d119f51f82c78aafe9e420073af (diff) | |
download | krb5-4233c6f3143639f164290a00eb0ffe720a32b9bc.tar.gz krb5-4233c6f3143639f164290a00eb0ffe720a32b9bc.tar.xz krb5-4233c6f3143639f164290a00eb0ffe720a32b9bc.zip |
Cygnus implementation of GSSAPI-based ftp client and server.
See README.gssftp for history and details.
Bugs, comments to <eichin@cygnus.com>. Be sure to forward any changes
made at MIT as well.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7312 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/appl/gssftp/ftp/main.c')
-rw-r--r-- | src/appl/gssftp/ftp/main.c | 553 |
1 files changed, 553 insertions, 0 deletions
diff --git a/src/appl/gssftp/ftp/main.c b/src/appl/gssftp/ftp/main.c new file mode 100644 index 0000000000..4a6d88f54f --- /dev/null +++ b/src/appl/gssftp/ftp/main.c @@ -0,0 +1,553 @@ +/* + * Copyright (c) 1985, 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\ + All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)main.c 5.18 (Berkeley) 3/1/91"; +#endif /* not lint */ + +/* + * FTP User Program -- Command Interface. + */ +#include <stdio.h> +#include "ftp_var.h" +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/types.h> + +#include <arpa/ftp.h> + +#include <signal.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> +#include <netdb.h> +#include <pwd.h> + +#define sig_t my_sig_t +#define sigtype krb5_sigtype +typedef sigtype (*sig_t)(); + +uid_t getuid(); +sigtype intr(), lostpeer(); +extern char *home; +char *getlogin(); +#ifdef KERBEROS +#include <krb.h> +struct servent staticsp; +extern char realm[]; +#endif /* KERBEROS */ + +main(argc, argv) + char *argv[]; +{ + register char *cp; + int top; + struct passwd *pw = NULL; + char homedir[MAXPATHLEN]; + + sp = getservbyname("ftp", "tcp"); + if (sp == 0) { + fprintf(stderr, "ftp: ftp/tcp: unknown service\n"); + exit(1); + } +#ifdef KERBEROS +/* GDM need to static sp so that the information is not lost + when kerberos calls getservbyname */ + memcpy(&staticsp,sp,sizeof(struct servent)); + sp = &staticsp; +#endif /* KERBEROS */ + doglob = 1; + interactive = 1; + autologin = 1; + argc--, argv++; + while (argc > 0 && **argv == '-') { + for (cp = *argv + 1; *cp; cp++) + switch (*cp) { + + case 'd': + options |= SO_DEBUG; + debug++; + break; + +#ifdef KERBEROS + case 'k': + if (*++cp != '\0') + strncpy(realm, ++cp, REALM_SZ); + else if (argc > 1) { + argc--, argv++; + strncpy(realm, *argv, REALM_SZ); + } + else + fprintf(stderr, "ftp: -k expects arguments\n"); + goto nextopt; +#endif + + case 'v': + verbose++; + break; + + case 't': + trace++; + break; + + case 'i': + interactive = 0; + break; + + case 'n': + autologin = 0; + break; + + case 'g': + doglob = 0; + break; + + default: + fprintf(stdout, + "ftp: %c: unknown option\n", *cp); + exit(1); + } + nextopt: + argc--, argv++; + } + fromatty = isatty(fileno(stdin)); + if (fromatty) + verbose++; + cpend = 0; /* no pending replies */ + proxy = 0; /* proxy not active */ +#ifndef NO_PASSIVE_MODE + passivemode = 1; /* passive mode active */ +#endif + crflag = 1; /* strip c.r. on ascii gets */ + sendport = -1; /* not using ports */ + /* + * Set up the home directory in case we're globbing. + */ + cp = getlogin(); + if (cp != NULL) { + pw = getpwnam(cp); + } + if (pw == NULL) + pw = getpwuid(getuid()); + if (pw != NULL) { + home = homedir; + (void) strcpy(home, pw->pw_dir); + } + if (argc > 0) { + if (setjmp(toplevel)) + exit(0); + (void) signal(SIGINT, intr); + (void) signal(SIGPIPE, lostpeer); + setpeer(argc + 1, argv - 1); + } + top = setjmp(toplevel) == 0; + if (top) { + (void) signal(SIGINT, intr); + (void) signal(SIGPIPE, lostpeer); + } + for (;;) { + cmdscanner(top); + top = 1; + } +} + +sigtype +intr(sig) + int sig; +{ + + longjmp(toplevel, 1); +} + +sigtype +lostpeer(sig) + int sig; +{ + extern FILE *cout; + extern int data; + extern char *auth_type; + extern int level; + + if (connected) { + if (cout != NULL) { + (void) shutdown(fileno(cout), 1+1); + (void) fclose(cout); + cout = NULL; + } + if (data >= 0) { + (void) shutdown(data, 1+1); + (void) close(data); + data = -1; + } + connected = 0; + auth_type = NULL; + level = PROT_C; + } + pswitch(1); + if (connected) { + if (cout != NULL) { + (void) shutdown(fileno(cout), 1+1); + (void) fclose(cout); + cout = NULL; + } + connected = 0; + auth_type = NULL; + level = PROT_C; + } + proxflag = 0; + pswitch(0); +} + +/*char * +tail(filename) + char *filename; +{ + register char *s; + + while (*filename) { + s = strrchr(filename, '/'); + if (s == NULL) + break; + if (s[1]) + return (s + 1); + *s = '\0'; + } + return (filename); +} +*/ +/* + * Command parser. + */ +cmdscanner(top) + int top; +{ + register struct cmd *c; + register int l; + struct cmd *getcmd(); + extern int help(); + + if (!top) + (void) putchar('\n'); + for (;;) { + if (fromatty) { + printf("ftp> "); + (void) fflush(stdout); + } + if (fgets(line, sizeof line, stdin) == NULL) + quit(); + l = strlen(line); + if (l == 0) + break; + if (line[--l] == '\n') { + if (l == 0) + break; + line[l] = '\0'; + } else if (l == sizeof(line) - 2) { + printf("sorry, input line too long\n"); + while ((l = getchar()) != '\n' && l != EOF) + /* void */; + break; + } /* else it was a line without a newline */ + makeargv(); + if (margc == 0) { + continue; + } + c = getcmd(margv[0]); + if (c == (struct cmd *)-1) { + printf("?Ambiguous command\n"); + continue; + } + if (c == 0) { + printf("?Invalid command\n"); + continue; + } + if (c->c_conn && !connected) { + printf("Not connected.\n"); + continue; + } + (*c->c_handler)(margc, margv); + if (bell && c->c_bell) + (void) putchar('\007'); + if (c->c_handler != help) + break; + } + (void) signal(SIGINT, intr); + (void) signal(SIGPIPE, lostpeer); +} + +struct cmd * +getcmd(name) + register char *name; +{ + extern struct cmd cmdtab[]; + register char *p, *q; + register struct cmd *c, *found; + register int nmatches, longest; + + longest = 0; + nmatches = 0; + found = 0; + for (c = cmdtab; p = c->c_name; c++) { + for (q = name; *q == *p++; q++) + if (*q == 0) /* exact match? */ + return (c); + if (!*q) { /* the name was a prefix */ + if (q - name > longest) { + longest = q - name; + nmatches = 1; + found = c; + } else if (q - name == longest) + nmatches++; + } + } + if (nmatches > 1) + return ((struct cmd *)-1); + return (found); +} + +/* + * Slice a string up into argc/argv. + */ + +int slrflag; + +makeargv() +{ + char **argp; + char *slurpstring(); + + margc = 0; + argp = margv; + stringbase = line; /* scan from first of buffer */ + argbase = argbuf; /* store from first of buffer */ + slrflag = 0; + while (*argp++ = slurpstring()) + margc++; +} + +/* + * Parse string into argbuf; + * implemented with FSM to + * handle quoting and strings + */ +char * +slurpstring() +{ + int got_one = 0; + register char *sb = stringbase; + register char *ap = argbase; + char *tmp = argbase; /* will return this if token found */ + + if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */ + switch (slrflag) { /* and $ as token for macro invoke */ + case 0: + slrflag++; + stringbase++; + return ((*sb == '!') ? "!" : "$"); + /* NOTREACHED */ + case 1: + slrflag++; + altarg = stringbase; + break; + default: + break; + } + } + +S0: + switch (*sb) { + + case '\0': + goto OUT; + + case ' ': + case '\t': + sb++; goto S0; + + default: + switch (slrflag) { + case 0: + slrflag++; + break; + case 1: + slrflag++; + altarg = sb; + break; + default: + break; + } + goto S1; + } + +S1: + switch (*sb) { + + case ' ': + case '\t': + case '\0': + goto OUT; /* end of token */ + + case '\\': + sb++; goto S2; /* slurp next character */ + + case '"': + sb++; goto S3; /* slurp quoted string */ + + default: + *ap++ = *sb++; /* add character to token */ + got_one = 1; + goto S1; + } + +S2: + switch (*sb) { + + case '\0': + goto OUT; + + default: + *ap++ = *sb++; + got_one = 1; + goto S1; + } + +S3: + switch (*sb) { + + case '\0': + goto OUT; + + case '"': + sb++; goto S1; + + default: + *ap++ = *sb++; + got_one = 1; + goto S3; + } + +OUT: + if (got_one) + *ap++ = '\0'; + argbase = ap; /* update storage pointer */ + stringbase = sb; /* update scan pointer */ + if (got_one) { + return(tmp); + } + switch (slrflag) { + case 0: + slrflag++; + break; + case 1: + slrflag++; + altarg = (char *) 0; + break; + default: + break; + } + return((char *)0); +} + +#define HELPINDENT (sizeof ("directory")) + +/* + * Help command. + * Call each command handler with argc == 0 and argv[0] == name. + */ +help(argc, argv) + int argc; + char *argv[]; +{ + extern struct cmd cmdtab[]; + register struct cmd *c; + + if (argc == 1) { + register int i, j, w, k; + int columns, width = 0, lines; + extern int NCMDS; + + printf("Commands may be abbreviated. Commands are:\n\n"); + for (c = cmdtab; c < &cmdtab[NCMDS]; c++) { + int len = strlen(c->c_name); + + if (len > width) + width = len; + } + width = (width + 8) &~ 7; + columns = 80 / width; + if (columns == 0) + columns = 1; + lines = (NCMDS + columns - 1) / columns; + for (i = 0; i < lines; i++) { + for (j = 0; j < columns; j++) { + c = cmdtab + j * lines + i; + if (c->c_name && (!proxy || c->c_proxy)) { + printf("%s", c->c_name); + } + else if (c->c_name) { + for (k=0; k < strlen(c->c_name); k++) { + (void) putchar(' '); + } + } + if (c + lines >= &cmdtab[NCMDS]) { + printf("\n"); + break; + } + w = strlen(c->c_name); + while (w < width) { + w = (w + 8) &~ 7; + (void) putchar('\t'); + } + } + } + return; + } + while (--argc > 0) { + register char *arg; + arg = *++argv; + c = getcmd(arg); + 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); + else + printf("%-*s\t%s\n", HELPINDENT, + c->c_name, c->c_help); + } +} |