Version 0.0

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@387 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Unknown User d91-jda
1996-04-08 22:51:40 +00:00
parent fae6f2292a
commit 7686c38ea0
47 changed files with 3872 additions and 360 deletions

38
appl/ftp/Makefile.in Normal file
View File

@@ -0,0 +1,38 @@
#
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SHELL = /bin/sh
CC = @CC@
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
INSTALL = @INSTALL@
prefix = @prefix@
exec_prefix = $(prefix)
libdir = $(exec_prefix)/lib
SUBDIRS=common ftp ftpd
all:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) all); done
install:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) install); done
clean cleandir:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) clean); done
distclean:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) distclean); done
rm -f Makefile config.status config.cache config.log config.h *~
rm -rf CVS

13
appl/ftp/acconfig.h Normal file
View File

@@ -0,0 +1,13 @@
@TOP@
@BOTTOM@
#ifdef __STDC__
#define RCSID(msg) static const char *rcsid[] = { (char *)rcsid, "@(#)" msg }
#else
#define RCSID(msg) static char *rcsid[] = { (char *)rcsid, msg }
#endif
#define WTMP_PATH "/var/adm/wtmp"

View File

@@ -0,0 +1,41 @@
#
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SHELL = /bin/sh
CC = @CC@
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
INSTALL = @INSTALL@
prefix = @prefix@
exec_prefix = $(prefix)
libdir = $(exec_prefix)/lib
ATHENA = /usr/athena
libcommon_OBJS = base64.o glob.o @LIBOBJS@
all: libcommon.a
.c.o:
$(CC) -c $(CFLAGS) -I. -I.. -I$(ATHENA)/include $(DEFS) $<
libcommon.a: $(libcommon_OBJS)
ar cr libcommon.a $(libcommon_OBJS)
ranlib libcommon.a
install:
clean cleandir:
rm -f *~ *.o ftp core \#*
distclean:
rm -f Makefile
rm -rf CVS

107
appl/ftp/common/base64.c Normal file
View File

@@ -0,0 +1,107 @@
#include <stdlib.h>
#include <string.h>
#include "base64.h"
static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static int pos(char c)
{
char *p;
for(p = base64; *p; p++)
if(*p == c)
return p - base64;
return -1;
}
int base64_encode(const void *data, int size, char **str)
{
char *s, *p;
int i;
int c;
unsigned char *q;
p = s = (char*)malloc(size*4/3+4);
q = (unsigned char*)data;
i=0;
for(i = 0; i < size;){
c=q[i++];
c*=256;
if(i < size)
c+=q[i];
i++;
c*=256;
if(i < size)
c+=q[i];
i++;
p[0]=base64[(c&0x00fc0000) >> 18];
p[1]=base64[(c&0x0003f000) >> 12];
p[2]=base64[(c&0x00000fc0) >> 6];
p[3]=base64[(c&0x0000003f) >> 0];
if(i > size)
p[3]='=';
if(i > size+1)
p[2]='=';
p+=4;
}
*p=0;
*str = s;
return strlen(s);
}
int base64_decode(const char *str, void *data)
{
const char *p;
unsigned char *q;
int c;
int x;
int done = 0;
q=(unsigned char*)data;
for(p=str; *p && !done; p+=4){
x = pos(p[0]);
if(x >= 0)
c = x;
else{
done = 3;
break;
}
c*=64;
x = pos(p[1]);
if(x >= 0)
c += x;
else
return -1;
c*=64;
if(p[2] == '=')
done++;
else{
x = pos(p[2]);
if(x >= 0)
c += x;
else
return -1;
}
c*=64;
if(p[3] == '=')
done++;
else{
if(done)
return -1;
x = pos(p[3]);
if(x >= 0)
c += x;
else
return -1;
}
if(done < 3)
*q++=(c&0x00ff0000)>>16;
if(done < 2)
*q++=(c&0x0000ff00)>>8;
if(done < 1)
*q++=(c&0x000000ff)>>0;
}
return q - (unsigned char*)data;
}

7
appl/ftp/common/base64.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef _BASE64_H_
#define _BASE64_H_
int base64_encode(const void *data, int size, char **str);
int base64_decode(const char *str, void *data);
#endif

16
appl/ftp/common/common.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef __MISSING_H__
#define __MISSING_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdarg.h>
#include "vsyslog.h"
#include "err.h"
#include "base64.h"
#endif /* __MISSING_H__ */

16
appl/ftp/common/err.c Normal file
View File

@@ -0,0 +1,16 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h"
RCSID("$Id$");
void
err(int eval, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
verr(eval, fmt, ap);
va_end(ap);
}

21
appl/ftp/common/err.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef __ERR_H__
#define __ERR_H__
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
extern char *__progname;
void verr(int eval, const char *fmt, va_list ap);
void err(int eval, const char *fmt, ...);
void verrx(int eval, const char *fmt, va_list ap);
void errx(int eval, const char *fmt, ...);
void vwarn(const char *fmt, va_list ap);
void warn(const char *fmt, ...);
void vwarnx(const char *fmt, va_list ap);
void warnx(const char *fmt, ...);
#endif /* __ERR_H__ */

16
appl/ftp/common/errx.c Normal file
View File

@@ -0,0 +1,16 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h"
RCSID("$Id$");
void
errx(int eval, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
verrx(eval, fmt, ap);
va_end(ap);
}

853
appl/ftp/common/glob.c Normal file
View File

@@ -0,0 +1,853 @@
/* $NetBSD: glob.c,v 1.5 1995/02/27 04:13:35 cgd Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
#else
static char rcsid[] = "$NetBSD: glob.c,v 1.5 1995/02/27 04:13:35 cgd Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
/*
* glob(3) -- a superset of the one defined in POSIX 1003.2.
*
* The [!...] convention to negate a range is supported (SysV, Posix, ksh).
*
* Optional extra services, controlled by flags not defined by POSIX:
*
* GLOB_QUOTE:
* Escaping convention: \ inhibits any special meaning the following
* character might have (except \ at end of string is retained).
* GLOB_MAGCHAR:
* Set in gl_flags if pattern contained a globbing character.
* GLOB_NOMAGIC:
* Same as GLOB_NOCHECK, but it will only append pattern if it did
* not contain any magic characters. [Used in csh style globbing]
* GLOB_ALTDIRFUNC:
* Use alternately specified directory access functions.
* GLOB_TILDE:
* expand ~user/foo to the /home/dir/of/user/foo
* GLOB_BRACE:
* expand {1,2}{a,b} to 1a 1b 2a 2b
* gl_matchc:
* Number of matches in the current invocation of glob.
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "glob.h"
#define DOLLAR '$'
#define DOT '.'
#define EOS '\0'
#define LBRACKET '['
#define NOT '!'
#define QUESTION '?'
#define QUOTE '\\'
#define RANGE '-'
#define RBRACKET ']'
#define SEP '/'
#define STAR '*'
#define TILDE '~'
#define UNDERSCORE '_'
#define LBRACE '{'
#define RBRACE '}'
#define SLASH '/'
#define COMMA ','
#ifndef DEBUG
#define M_QUOTE 0x8000
#define M_PROTECT 0x4000
#define M_MASK 0xffff
#define M_ASCII 0x00ff
typedef u_short Char;
#else
#define M_QUOTE 0x80
#define M_PROTECT 0x40
#define M_MASK 0xff
#define M_ASCII 0x7f
typedef char Char;
#endif
#define CHAR(c) ((Char)((c)&M_ASCII))
#define META(c) ((Char)((c)|M_QUOTE))
#define M_ALL META('*')
#define M_END META(']')
#define M_NOT META('!')
#define M_ONE META('?')
#define M_RNG META('-')
#define M_SET META('[')
#define ismeta(c) (((c)&M_QUOTE) != 0)
static int compare __P((const void *, const void *));
static void g_Ctoc __P((const Char *, char *));
static int g_lstat __P((Char *, struct stat *, glob_t *));
static DIR *g_opendir __P((Char *, glob_t *));
static Char *g_strchr __P((Char *, int));
#ifdef notdef
static Char *g_strcat __P((Char *, const Char *));
#endif
static int g_stat __P((Char *, struct stat *, glob_t *));
static int glob0 __P((const Char *, glob_t *));
static int glob1 __P((Char *, glob_t *));
static int glob2 __P((Char *, Char *, Char *, glob_t *));
static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
static int globextend __P((const Char *, glob_t *));
static const Char * globtilde __P((const Char *, Char *, glob_t *));
static int globexp1 __P((const Char *, glob_t *));
static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
static int match __P((Char *, Char *, Char *));
#ifdef DEBUG
static void qprintf __P((const char *, Char *));
#endif
int
glob(pattern, flags, errfunc, pglob)
const char *pattern;
int flags, (*errfunc) __P((const char *, int));
glob_t *pglob;
{
const u_char *patnext;
int c;
Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
patnext = (u_char *) pattern;
if (!(flags & GLOB_APPEND)) {
pglob->gl_pathc = 0;
pglob->gl_pathv = NULL;
if (!(flags & GLOB_DOOFFS))
pglob->gl_offs = 0;
}
pglob->gl_flags = flags & ~GLOB_MAGCHAR;
pglob->gl_errfunc = errfunc;
pglob->gl_matchc = 0;
bufnext = patbuf;
bufend = bufnext + MAXPATHLEN;
if (flags & GLOB_QUOTE) {
/* Protect the quoted characters. */
while (bufnext < bufend && (c = *patnext++) != EOS)
if (c == QUOTE) {
if ((c = *patnext++) == EOS) {
c = QUOTE;
--patnext;
}
*bufnext++ = c | M_PROTECT;
}
else
*bufnext++ = c;
}
else
while (bufnext < bufend && (c = *patnext++) != EOS)
*bufnext++ = c;
*bufnext = EOS;
if (flags & GLOB_BRACE)
return globexp1(patbuf, pglob);
else
return glob0(patbuf, pglob);
}
/*
* Expand recursively a glob {} pattern. When there is no more expansion
* invoke the standard globbing routine to glob the rest of the magic
* characters
*/
static int globexp1(pattern, pglob)
const Char *pattern;
glob_t *pglob;
{
const Char* ptr = pattern;
int rv;
/* Protect a single {}, for find(1), like csh */
if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
return glob0(pattern, pglob);
while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
if (!globexp2(ptr, pattern, pglob, &rv))
return rv;
return glob0(pattern, pglob);
}
/*
* Recursive brace globbing helper. Tries to expand a single brace.
* If it succeeds then it invokes globexp1 with the new pattern.
* If it fails then it tries to glob the rest of the pattern and returns.
*/
static int globexp2(ptr, pattern, pglob, rv)
const Char *ptr, *pattern;
glob_t *pglob;
int *rv;
{
int i;
Char *lm, *ls;
const Char *pe, *pm, *pl;
Char patbuf[MAXPATHLEN + 1];
/* copy part up to the brace */
for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
continue;
ls = lm;
/* Find the balanced brace */
for (i = 0, pe = ++ptr; *pe; pe++)
if (*pe == LBRACKET) {
/* Ignore everything between [] */
for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
continue;
if (*pe == EOS) {
/*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
pe = pm;
}
}
else if (*pe == LBRACE)
i++;
else if (*pe == RBRACE) {
if (i == 0)
break;
i--;
}
/* Non matching braces; just glob the pattern */
if (i != 0 || *pe == EOS) {
*rv = glob0(patbuf, pglob);
return 0;
}
for (i = 0, pl = pm = ptr; pm <= pe; pm++)
switch (*pm) {
case LBRACKET:
/* Ignore everything between [] */
for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
continue;
if (*pm == EOS) {
/*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
pm = pl;
}
break;
case LBRACE:
i++;
break;
case RBRACE:
if (i) {
i--;
break;
}
/* FALLTHROUGH */
case COMMA:
if (i && *pm == COMMA)
break;
else {
/* Append the current string */
for (lm = ls; (pl < pm); *lm++ = *pl++)
continue;
/*
* Append the rest of the pattern after the
* closing brace
*/
for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
continue;
/* Expand the current pattern */
#ifdef DEBUG
qprintf("globexp2:", patbuf);
#endif
*rv = globexp1(patbuf, pglob);
/* move after the comma, to the next string */
pl = pm + 1;
}
break;
default:
break;
}
*rv = 0;
return 0;
}
/*
* expand tilde from the passwd file.
*/
static const Char *
globtilde(pattern, patbuf, pglob)
const Char *pattern;
Char *patbuf;
glob_t *pglob;
{
struct passwd *pwd;
char *h;
const Char *p;
Char *b;
if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
return pattern;
/* Copy up to the end of the string or / */
for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH;
*h++ = *p++)
continue;
*h = EOS;
if (((char *) patbuf)[0] == EOS) {
/*
* handle a plain ~ or ~/ by expanding $HOME
* first and then trying the password file
*/
if ((h = getenv("HOME")) == NULL) {
if ((pwd = getpwuid(getuid())) == NULL)
return pattern;
else
h = pwd->pw_dir;
}
}
else {
/*
* Expand a ~user
*/
if ((pwd = getpwnam((char*) patbuf)) == NULL)
return pattern;
else
h = pwd->pw_dir;
}
/* Copy the home directory */
for (b = patbuf; *h; *b++ = *h++)
continue;
/* Append the rest of the pattern */
while ((*b++ = *p++) != EOS)
continue;
return patbuf;
}
/*
* The main glob() routine: compiles the pattern (optionally processing
* quotes), calls glob1() to do the real pattern matching, and finally
* sorts the list (unless unsorted operation is requested). Returns 0
* if things went well, nonzero if errors occurred. It is not an error
* to find no matches.
*/
static int
glob0(pattern, pglob)
const Char *pattern;
glob_t *pglob;
{
const Char *qpatnext;
int c, err, oldpathc;
Char *bufnext, patbuf[MAXPATHLEN+1];
qpatnext = globtilde(pattern, patbuf, pglob);
oldpathc = pglob->gl_pathc;
bufnext = patbuf;
/* We don't need to check for buffer overflow any more. */
while ((c = *qpatnext++) != EOS) {
switch (c) {
case LBRACKET:
c = *qpatnext;
if (c == NOT)
++qpatnext;
if (*qpatnext == EOS ||
g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
*bufnext++ = LBRACKET;
if (c == NOT)
--qpatnext;
break;
}
*bufnext++ = M_SET;
if (c == NOT)
*bufnext++ = M_NOT;
c = *qpatnext++;
do {
*bufnext++ = CHAR(c);
if (*qpatnext == RANGE &&
(c = qpatnext[1]) != RBRACKET) {
*bufnext++ = M_RNG;
*bufnext++ = CHAR(c);
qpatnext += 2;
}
} while ((c = *qpatnext++) != RBRACKET);
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_END;
break;
case QUESTION:
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_ONE;
break;
case STAR:
pglob->gl_flags |= GLOB_MAGCHAR;
/* collapse adjacent stars to one,
* to avoid exponential behavior
*/
if (bufnext == patbuf || bufnext[-1] != M_ALL)
*bufnext++ = M_ALL;
break;
default:
*bufnext++ = CHAR(c);
break;
}
}
*bufnext = EOS;
#ifdef DEBUG
qprintf("glob0:", patbuf);
#endif
if ((err = glob1(patbuf, pglob)) != 0)
return(err);
/*
* If there was no match we are going to append the pattern
* if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
* and the pattern did not contain any magic characters
* GLOB_NOMAGIC is there just for compatibility with csh.
*/
if (pglob->gl_pathc == oldpathc &&
((pglob->gl_flags & GLOB_NOCHECK) ||
((pglob->gl_flags & GLOB_NOMAGIC) &&
!(pglob->gl_flags & GLOB_MAGCHAR))))
return(globextend(pattern, pglob));
else if (!(pglob->gl_flags & GLOB_NOSORT))
qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
pglob->gl_pathc - oldpathc, sizeof(char *), compare);
return(0);
}
static int
compare(p, q)
const void *p, *q;
{
return(strcmp(*(char **)p, *(char **)q));
}
static int
glob1(pattern, pglob)
Char *pattern;
glob_t *pglob;
{
Char pathbuf[MAXPATHLEN+1];
/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
if (*pattern == EOS)
return(0);
return(glob2(pathbuf, pathbuf, pattern, pglob));
}
/*
* The functions glob2 and glob3 are mutually recursive; there is one level
* of recursion for each segment in the pattern that contains one or more
* meta characters.
*/
static int
glob2(pathbuf, pathend, pattern, pglob)
Char *pathbuf, *pathend, *pattern;
glob_t *pglob;
{
struct stat sb;
Char *p, *q;
int anymeta;
/*
* Loop over pattern segments until end of pattern or until
* segment with meta character found.
*/
for (anymeta = 0;;) {
if (*pattern == EOS) { /* End of pattern? */
*pathend = EOS;
if (g_lstat(pathbuf, &sb, pglob))
return(0);
if (((pglob->gl_flags & GLOB_MARK) &&
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
|| (S_ISLNK(sb.st_mode) &&
(g_stat(pathbuf, &sb, pglob) == 0) &&
S_ISDIR(sb.st_mode)))) {
*pathend++ = SEP;
*pathend = EOS;
}
++pglob->gl_matchc;
return(globextend(pathbuf, pglob));
}
/* Find end of next segment, copy tentatively to pathend. */
q = pathend;
p = pattern;
while (*p != EOS && *p != SEP) {
if (ismeta(*p))
anymeta = 1;
*q++ = *p++;
}
if (!anymeta) { /* No expansion, do next segment. */
pathend = q;
pattern = p;
while (*pattern == SEP)
*pathend++ = *pattern++;
} else /* Need expansion, recurse. */
return(glob3(pathbuf, pathend, pattern, p, pglob));
}
/* NOTREACHED */
}
static int
glob3(pathbuf, pathend, pattern, restpattern, pglob)
Char *pathbuf, *pathend, *pattern, *restpattern;
glob_t *pglob;
{
register struct dirent *dp;
DIR *dirp;
int err;
char buf[MAXPATHLEN];
/*
* The readdirfunc declaration can't be prototyped, because it is
* assigned, below, to two functions which are prototyped in glob.h
* and dirent.h as taking pointers to differently typed opaque
* structures.
*/
struct dirent *(*readdirfunc)();
*pathend = EOS;
errno = 0;
if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
/* TODO: don't call for ENOENT or ENOTDIR? */
if (pglob->gl_errfunc) {
g_Ctoc(pathbuf, buf);
if (pglob->gl_errfunc(buf, errno) ||
pglob->gl_flags & GLOB_ERR)
return (GLOB_ABEND);
}
return(0);
}
err = 0;
/* Search directory for matching names. */
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
readdirfunc = pglob->gl_readdir;
else
readdirfunc = readdir;
while ((dp = (*readdirfunc)(dirp))) {
register u_char *sc;
register Char *dc;
/* Initial DOT must be matched literally. */
if (dp->d_name[0] == DOT && *pattern != DOT)
continue;
for (sc = (u_char *) dp->d_name, dc = pathend;
(*dc++ = *sc++) != EOS;)
continue;
if (!match(pathend, pattern, restpattern)) {
*pathend = EOS;
continue;
}
err = glob2(pathbuf, --dc, restpattern, pglob);
if (err)
break;
}
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
(*pglob->gl_closedir)(dirp);
else
closedir(dirp);
return(err);
}
/*
* Extend the gl_pathv member of a glob_t structure to accomodate a new item,
* add the new item, and update gl_pathc.
*
* This assumes the BSD realloc, which only copies the block when its size
* crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
* behavior.
*
* Return 0 if new item added, error code if memory couldn't be allocated.
*
* Invariant of the glob_t structure:
* Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
* gl_pathv points to (gl_offs + gl_pathc + 1) items.
*/
static int
globextend(path, pglob)
const Char *path;
glob_t *pglob;
{
register char **pathv;
register int i;
u_int newsize;
char *copy;
const Char *p;
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
pathv = pglob->gl_pathv ?
realloc((char *)pglob->gl_pathv, newsize) :
malloc(newsize);
if (pathv == NULL)
return(GLOB_NOSPACE);
if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
/* first time around -- clear initial gl_offs items */
pathv += pglob->gl_offs;
for (i = pglob->gl_offs; --i >= 0; )
*--pathv = NULL;
}
pglob->gl_pathv = pathv;
for (p = path; *p++;)
continue;
if ((copy = malloc(p - path)) != NULL) {
g_Ctoc(path, copy);
pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
}
pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
return(copy == NULL ? GLOB_NOSPACE : 0);
}
/*
* pattern matching function for filenames. Each occurrence of the *
* pattern causes a recursion level.
*/
static int
match(name, pat, patend)
register Char *name, *pat, *patend;
{
int ok, negate_range;
Char c, k;
while (pat < patend) {
c = *pat++;
switch (c & M_MASK) {
case M_ALL:
if (pat == patend)
return(1);
do
if (match(name, pat, patend))
return(1);
while (*name++ != EOS);
return(0);
case M_ONE:
if (*name++ == EOS)
return(0);
break;
case M_SET:
ok = 0;
if ((k = *name++) == EOS)
return(0);
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
++pat;
while (((c = *pat++) & M_MASK) != M_END)
if ((*pat & M_MASK) == M_RNG) {
if (c <= k && k <= pat[1])
ok = 1;
pat += 2;
} else if (c == k)
ok = 1;
if (ok == negate_range)
return(0);
break;
default:
if (*name++ != c)
return(0);
break;
}
}
return(*name == EOS);
}
/* Free allocated data belonging to a glob_t structure. */
void
globfree(pglob)
glob_t *pglob;
{
register int i;
register char **pp;
if (pglob->gl_pathv != NULL) {
pp = pglob->gl_pathv + pglob->gl_offs;
for (i = pglob->gl_pathc; i--; ++pp)
if (*pp)
free(*pp);
free(pglob->gl_pathv);
}
}
static DIR *
g_opendir(str, pglob)
register Char *str;
glob_t *pglob;
{
char buf[MAXPATHLEN];
if (!*str)
strcpy(buf, ".");
else
g_Ctoc(str, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_opendir)(buf));
return(opendir(buf));
}
static int
g_lstat(fn, sb, pglob)
register Char *fn;
struct stat *sb;
glob_t *pglob;
{
char buf[MAXPATHLEN];
g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_lstat)(buf, sb));
return(lstat(buf, sb));
}
static int
g_stat(fn, sb, pglob)
register Char *fn;
struct stat *sb;
glob_t *pglob;
{
char buf[MAXPATHLEN];
g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_stat)(buf, sb));
return(stat(buf, sb));
}
static Char *
g_strchr(str, ch)
Char *str;
int ch;
{
do {
if (*str == ch)
return (str);
} while (*str++);
return (NULL);
}
#ifdef notdef
static Char *
g_strcat(dst, src)
Char *dst;
const Char* src;
{
Char *sdst = dst;
while (*dst++)
continue;
--dst;
while((*dst++ = *src++) != EOS)
continue;
return (sdst);
}
#endif
static void
g_Ctoc(str, buf)
register const Char *str;
char *buf;
{
register char *dc;
for (dc = buf; (*dc++ = *str++) != EOS;)
continue;
}
#ifdef DEBUG
static void
qprintf(str, s)
const char *str;
register Char *s;
{
register Char *p;
(void)printf("%s:\n", str);
for (p = s; *p; p++)
(void)printf("%c", CHAR(*p));
(void)printf("\n");
for (p = s; *p; p++)
(void)printf("%c", *p & M_PROTECT ? '"' : ' ');
(void)printf("\n");
for (p = s; *p; p++)
(void)printf("%c", ismeta(*p) ? '_' : ' ');
(void)printf("\n");
}
#endif

90
appl/ftp/common/glob.h Normal file
View File

@@ -0,0 +1,90 @@
/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* 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.
*
* @(#)glob.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _GLOB_H_
#define _GLOB_H_
#ifndef __P
#define __P(protos) protos
#endif
struct stat;
typedef struct {
int gl_pathc; /* Count of total paths so far. */
int gl_matchc; /* Count of paths matching pattern. */
int gl_offs; /* Reserved at beginning of gl_pathv. */
int gl_flags; /* Copy of flags parameter to glob. */
char **gl_pathv; /* List of paths matching pattern. */
/* Copy of errfunc parameter to glob. */
int (*gl_errfunc) __P((const char *, int));
/*
* Alternate filesystem access methods for glob; replacement
* versions of closedir(3), readdir(3), opendir(3), stat(2)
* and lstat(2).
*/
void (*gl_closedir) __P((void *));
struct dirent *(*gl_readdir) __P((void *));
void *(*gl_opendir) __P((const char *));
int (*gl_lstat) __P((const char *, struct stat *));
int (*gl_stat) __P((const char *, struct stat *));
} glob_t;
#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
#define GLOB_ERR 0x0004 /* Return on error. */
#define GLOB_MARK 0x0008 /* Append / to matching directories. */
#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
#define GLOB_NOSORT 0x0020 /* Don't sort. */
#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
#define GLOB_NOSPACE (-1) /* Malloc call failed. */
#define GLOB_ABEND (-2) /* Unignored error. */
int glob __P((const char *, int, int (*)(const char *, int), glob_t *));
void globfree __P((glob_t *));
#endif /* !_GLOB_H_ */

View File

@@ -0,0 +1,26 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef HAVE_HSTRERROR
#include <stdio.h>
#include <netdb.h>
static char *msg[] = {
"No error",
"Authoritative Answer Host not found",
"Non-Authoritive Host not found, or SERVERFAIL",
"Non recoverable errors, FORMERR, REFUSED, NOTIMP",
"Valid name, no data record of requested type"
};
char *hstrerror(int herr)
{
if(herr >= 0 && herr <= 4)
return msg[herr];
return "Error number out of range (hstrerror)";
}
#endif

View File

@@ -0,0 +1,23 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <netinet/in.h>
#include <netdb.h>
RCSID("$Id$");
int inet_aton(char *cp, struct in_addr *adr)
{
int a, b, c, d;
if(sscanf(cp, "%d.%d.%d.%d", &a, &b, &c, &d) != 4)
return 0;
if(a < 0 || a > 255 ||
b < 0 || b > 255 ||
c < 0 || c > 255 ||
d < 0 || d > 255)
return 0;
adr->s_addr = htonl((a << 24) | (b << 16) | (c << 8) | d);
return 1;
}

View File

@@ -0,0 +1,13 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <krb.h>
RCSID("$Id$");
const char *
krb_get_err_text(int n)
{
return krb_err_txt[n];
}

33
appl/ftp/common/memmove.c Normal file
View File

@@ -0,0 +1,33 @@
/*
* memmove for systems that doesn't have it
*
* $Id$
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
RCSID("$Id$");
void* memmove(void *s1, const void *s2, size_t n)
{
char *s=(char*)s2, *d=(char*)s1;
if(d > s){
s+=n-1;
d+=n-1;
while(n){
*d--=*s--;
n--;
}
}else if(d < s)
while(n){
*d++=*s++;
n--;
}
return s1;
}

View File

@@ -0,0 +1,18 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdarg.h>
RCSID("$Id$");
int snprintf(char *s, int n, char *fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
ret = vsprintf(s, fmt, ap);
va_end(ap);
return ret;
}

22
appl/ftp/common/verr.c Normal file
View File

@@ -0,0 +1,22 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h"
RCSID("$Id$");
void
verr(int eval, const char *fmt, va_list ap)
{
int sverrno;
sverrno = errno;
fprintf(stderr, "%s: ", __progname);
if (fmt != NULL) {
vfprintf(stderr, fmt, ap);
fprintf(stderr, ": ");
}
fprintf(stderr, "%s\n", strerror(sverrno));
exit(eval);
}

17
appl/ftp/common/verrx.c Normal file
View File

@@ -0,0 +1,17 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h"
RCSID("$Id$");
void
verrx(int eval, const char *fmt, va_list ap)
{
fprintf(stderr, "%s: ", __progname);
if (fmt != NULL)
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
exit(eval);
}

17
appl/ftp/common/vsyslog.c Normal file
View File

@@ -0,0 +1,17 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef HAVE_VSYSLOG
#include <syslog.h>
#include <stdarg.h>
void vsyslog(int pri, const char *fmt, va_list ap)
{
char buf[10240];
vsprintf(buf, fmt, ap);
syslog(pri, buf);
}
#endif

View File

@@ -0,0 +1,8 @@
#ifndef __VSYSLOG_H__
#define __VSYSLOG_H__
#ifndef HAVE_VSYSLOG
void vsyslog(int pri, const char *fmt, ...);
#endif
#endif /* __VSYSLOG_H__ */

21
appl/ftp/common/vwarn.c Normal file
View File

@@ -0,0 +1,21 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h"
RCSID("$Id$");
void
vwarn(const char *fmt, va_list ap)
{
int sverrno;
sverrno = errno;
fprintf(stderr, "%s: ", __progname);
if (fmt != NULL) {
vfprintf(stderr, fmt, ap);
fprintf(stderr, ": ");
}
fprintf(stderr, "%s\n", strerror(sverrno));
}

16
appl/ftp/common/vwarnx.c Normal file
View File

@@ -0,0 +1,16 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h"
RCSID("$Id$");
void
vwarnx(const char *fmt, va_list ap)
{
fprintf(stderr, "%s: ", __progname);
if (fmt != NULL)
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
}

16
appl/ftp/common/warn.c Normal file
View File

@@ -0,0 +1,16 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h"
RCSID("$Id$");
void
warn(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vwarn(fmt, ap);
va_end(ap);
}

16
appl/ftp/common/warnx.c Normal file
View File

@@ -0,0 +1,16 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h"
RCSID("$Id$");
void
warnx(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vwarnx(fmt, ap);
va_end(ap);
}

30
appl/ftp/configure.in Normal file
View File

@@ -0,0 +1,30 @@
#
# configure script for kftp
#
# $Id$
#
AC_INIT(ftp/main.c)
AC_CONFIG_HEADER(config.h)
# This may be overridden using --prefix=/usr to configure
AC_PREFIX_DEFAULT(/usr/athena)
AC_PROG_CC
AC_PROG_RANLIB
AC_PROG_CPP
AC_SUBST(CFLAGS)dnl
AC_SUBST(LDFLAGS)dnl
AC_CHECK_HEADERS(sys/select.h paths.h)
AC_CHECK_LIB(socket, socket)
AC_CHECK_LIB(nsl, gethostbyname)
AC_CHECK_LIB(krb, krb_mk_req)
AC_REPLACE_FUNCS(errx hstrerror inet_aton krb_get_err_text memmove snprintf vsyslog verrx vwarn vwarnx warn warnx)
AC_OUTPUT(Makefile common/Makefile ftp/Makefile ftpd/Makefile)

View File

@@ -1,13 +0,0 @@
CC=cc -std1
#CC=gcc
CFLAGS=-g -DHAVE_CONFIG_H -I.. -I../libmissing -I$(ATHENA)/include -I.
ATHENA = /usr/athena
ftp_OBJS = cmds.o cmdtab.o ftp.o main.o ruserpass.o domacro.o globals.o
ftp: $(ftp_OBJS)
$(CC) -o ftp $(ftp_OBJS) ../libmissing/libmissing.a -L$(ATHENA)/lib -lkrb -ldes
clean:
rm -f *~ *.o core ftpd ftpcmd.c \#*

41
appl/ftp/ftp/Makefile.in Normal file
View File

@@ -0,0 +1,41 @@
#
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SHELL = /bin/sh
CC = @CC@
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
LIBS = @LIBS@
INSTALL = @INSTALL@
prefix = @prefix@
exec_prefix = $(prefix)
libdir = $(exec_prefix)/lib
ATHENA = /usr/athena
ftp_OBJS = cmds.o cmdtab.o ftp.o main.o ruserpass.o domacro.o globals.o
all: ftp
.c.o:
$(CC) -c $(CFLAGS) -I.. -I$(srcdir)/.. -I../common -I$(srcdir)/../common -I$(ATHENA)/include $(DEFS) $<
install:
ftp: $(ftp_OBJS) ../common/libcommon.a
$(CC) -o ftp $(ftp_OBJS) ../common/libcommon.a -L$(ATHENA)/lib -lkrb -ldes $(LIBS)
clean cleandir:
rm -f *~ *.o core ftpd ftpcmd.c \#*
distclean:
rm -f Makefile
rm -rf CVS

View File

@@ -38,7 +38,9 @@
#include <setjmp.h>
#include <stdlib.h>
#include <sys/time.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifndef __P
#ifdef __STDC__
@@ -60,7 +62,7 @@ void cdup __P((int, char **));
void changetype __P((int, int));
void cmdabort __P((int));
void cmdscanner __P((int));
int command __((char *fmt, ...));
int command __P((char *fmt, ...));
int confirm __P((char *, char *));
FILE *dataconn __P((char *));
void delete __P((int, char **));

View File

@@ -35,6 +35,8 @@
#include "ftp_locl.h"
struct sockaddr_in hisctladdr;
struct sockaddr_in data_addr;
int data = -1;
@@ -157,6 +159,77 @@ bad:
return ((char *)0);
}
#include <des.h>
#include <krb.h>
int krb4_auth = 0;
KTEXT_ST krb4_adat;
static des_cblock key;
static des_key_schedule schedule;
int do_auth(char *service, char *host)
{
int ret;
CREDENTIALS cred;
char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ];
strcpy(sname, service);
strcpy(inst, krb_get_phost(host));
strcpy(realm, krb_realmofhost(host));
ret = krb_mk_req(&krb4_adat, sname, inst, realm, 0);
if(ret)
return ret;
strcpy(sname, service);
strcpy(inst, krb_get_phost(host));
strcpy(realm, krb_realmofhost(host));
ret = krb_get_cred(sname, inst, realm, &cred);
memmove(&key, &cred.session, sizeof(des_cblock));
des_key_sched(&key, schedule);
memset(&cred, 0, sizeof(cred));
return ret;
}
int do_klogin(char *host)
{
int ret;
char *phost;
char *p, *q;
int len;
char *serv = "ftp";
char adat[1024];
MSG_DAT msg_data;
int checksum;
ret = command("AUTH KERBEROS_V4");
if(ret == CONTINUE){
ret = do_auth("ftp", host);
if(ret == KDC_PR_UNKNOWN)
ret = do_auth("rcmd", host);
if(ret)
return ret;
base64_encode(krb4_adat.dat, krb4_adat.length, &p);
ret = command("ADAT %s", p);
free(p);
if(ret == COMPLETE){
p = strstr(reply_string, "ADAT=");
if(p){
p+=5;
for(q = p; isalnum(*q) || strchr("/+=", *q); q++);
*q = 0;
len = base64_decode(p, adat);
ret = krb_rd_safe(adat, len, &key,
&hisctladdr, &myctladdr, &msg_data);
memmove(&checksum, msg_data.app_data, 4);
checksum = ntohl(checksum);
}
krb4_auth = 1;
return 0;
}
}
return -1;
}
int
login(char *host)
{
@@ -189,6 +262,9 @@ login(char *host)
else
user = tmp;
}
if(strcmp(user, "ftp") && strcmp(user, "anonymous")){
do_klogin(host);
}
n = command("USER %s", user);
if (n == CONTINUE) {
if (pass == NULL)
@@ -230,6 +306,69 @@ cmdabort(int sig)
longjmp(ptabort,1);
}
int krb4_write_enc(FILE *F, char *fmt, va_list ap)
{
int len;
char *p;
char buf[1024];
char enc[1024];
vsprintf(buf, fmt, ap);
len = krb_mk_priv(buf, enc, strlen(buf), schedule, &key,
&myctladdr, &hisctladdr);
base64_encode(enc, len, &p);
fprintf(F, "ENC %s", p);
return 0;
}
int krb4_read_msg(char *s, int priv)
{
int len;
int ret;
char buf[1024];
MSG_DAT m;
int code;
len = base64_decode(s + 4, buf);
if(priv)
ret = krb_rd_priv(buf, len, schedule, &key,
&hisctladdr, &myctladdr, &m);
else
ret = krb_rd_safe(buf, len, &key, &myctladdr, &hisctladdr, &m);
if(ret){
fprintf(stderr, "%s\n", krb_get_err_text(ret));
return -1;
}
m.app_data[m.app_length] = 0;
if(m.app_data[3] == '-')
code = 0;
else
sscanf((char*)m.app_data, "%d", &code);
strncpy(s, (char*)m.app_data, strlen((char*)m.app_data));
s[m.app_length] = 0;
len = strlen(s);
if(s[len-1] == '\n')
s[len-1] = 0;
return code;
}
int
krb4_read_mic(char *s)
{
return krb4_read_msg(s, 0);
}
int
krb4_read_enc(char *s)
{
return krb4_read_msg(s, 1);
}
int
command(char *fmt, ...)
{
@@ -252,7 +391,10 @@ command(char *fmt, ...)
printf("PASS XXXX");
else
vfprintf(stdout, fmt, ap);
vfprintf(cout, fmt, ap);
if(krb4_auth)
krb4_write_enc(cout, fmt, ap);
else
vfprintf(cout, fmt, ap);
va_end(ap);
if(debug){
printf("\n");
@@ -270,6 +412,93 @@ command(char *fmt, ...)
char reply_string[BUFSIZ]; /* last line of previous reply */
int
getreply(int expecteof)
{
char *p;
int c;
struct sigaction sa, osa;
char buf[1024];
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = cmdabort;
sigaction(SIGINT, &sa, &osa);
p = buf;
while(1){
c = getc(cin);
switch(c){
case EOF:
if (expecteof) {
sigaction(SIGINT,&osa, NULL);
code = 221;
return 0;
}
lostpeer(0);
if (verbose) {
printf("421 Service not available, remote server has closed connection\n");
fflush(stdout);
}
code = 421;
return (4);
break;
case IAC:
c = getc(cin);
if(c == WILL || c == WONT)
fprintf(cout, "%c%c%c", IAC, DONT, getc(cin));
if(c == DO || c == DONT)
fprintf(cout, "%c%c%c", IAC, WONT, getc(cin));
continue;
case '\n':
*p++ = 0;
if(isdigit(buf[0])){
sscanf(buf, "%d", &code);
if(code == 631){
krb4_read_mic(buf);
sscanf(buf, "%d", &code);
fprintf(stdout, "S:");
} else if(code == 632){
krb4_read_enc(buf);
sscanf(buf, "%d", &code);
fprintf(stdout, "P:");
}else if(code == 633){
fprintf(stdout, "Confidentiality is meaningless:/n");
}else if(krb4_auth)
fprintf(stdout, "!!"); /* clear text */
fprintf(stdout, "%s\n", buf);
if(buf[3] == ' '){
strcpy(reply_string, buf);
if (code < 200)
cpend = 0;
sigaction(SIGINT, &osa, NULL);
if (code == 421)
lostpeer(0);
#if 0
if (abrtflag &&
osa.sa_handler != cmdabort &&
osa.sa_handler != SIG_IGN)
osa.sa_handler(SIGINT);
#endif
return code / 100;
}
}else{
if(krb4_auth)
fprintf(stdout, "!!");
fprintf(stdout, "%s\n", buf);
}
p = buf;
continue;
default:
*p++ = c;
}
}
}
#if 0
int
getreply(int expecteof)
{
@@ -360,6 +589,16 @@ getreply(int expecteof)
continue;
}
*cp = '\0';
if(krb4_auth){
if(code == 631)
krb4_read_mic(reply_string);
else
krb4_read_enc(reply_string);
n = code / 100 + '0';
}
if (n != '1')
cpend = 0;
(void) signal(SIGINT,oldintr);
@@ -370,6 +609,7 @@ getreply(int expecteof)
return (n - '0');
}
}
#endif
int
empty(struct fd_set *mask, int sec)
@@ -1109,8 +1349,8 @@ ptransfer(char *direction, long int bytes,
long bs;
if (verbose) {
td.tv_sec = t0->tv_sec - t1->tv_sec;
td.tv_usec = t0->tv_usec - t1->tv_usec;
td.tv_sec = t1->tv_sec - t0->tv_sec;
td.tv_usec = t1->tv_usec - t0->tv_usec;
if(td.tv_usec < 0){
td.tv_sec--;
td.tv_usec += 1000000;

41
appl/ftp/ftp/ftp_locl.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef __FTP_LOCL_H__
#define __FTP_LOCL_H__
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <arpa/ftp.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <errno.h>
#include <ctype.h>
#include <glob.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "extern.h"
#include "common.h"
#include "ftp_var.h"
#include "pathnames.h"
#if defined(__sun__) && !defined(__svr4)
int fclose(FILE*);
int pclose(FILE*);
extern int optind;
#endif
#endif /* __FTP_LOCL_H__ */

View File

@@ -35,7 +35,13 @@
* @(#)pathnames.h 8.1 (Berkeley) 6/6/93
*/
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#undef _PATH_TMP
#define _PATH_TMP "/tmp/ftpXXXXXX"
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif

View File

@@ -1,21 +0,0 @@
# $NetBSD: Makefile,v 1.12 1995/04/11 02:44:45 cgd Exp $
# @(#)Makefile 8.2 (Berkeley) 4/4/94
PROG= ftpd
CFLAGS+=-DHASSETPROCTITLE -DSKEY
SRCS= ftpd.c ftpcmd.c logwtmp.c popen.c
MAN= ftpd.8
CLEANFILES+=ftpcmd.c y.tab.h
.PATH: ${.CURDIR}/../../usr.bin/ftp ${.CURDIR}/../../usr.bin/login
LDADD+= -lcrypt -lskey
DPADD+= ${LIBCRYPT} ${LIBSKEY}
.if defined(KERBEROS)
SRCS+= klogin.c
CFLAGS+= -DKERBEROS
LDADD+= -lkrb -ldes
DPADD+= ${LIBKRB} ${LIBDES}
.endif
.include <bsd.prog.mk>

45
appl/ftp/ftpd/Makefile.in Normal file
View File

@@ -0,0 +1,45 @@
#
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SHELL = /bin/sh
CC = @CC@
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
INSTALL = @INSTALL@
prefix = @prefix@
exec_prefix = $(prefix)
libdir = $(exec_prefix)/lib
ATHENA = /usr/athena
ftpd_OBJS = ftpd.o ftpcmd.o logwtmp.o popen.o auth.o krb4.o
all: ftpd
.c.o:
$(CC) -c $(CFLAGS) -I.. -I$(srcdir)/.. -I../common -I$(srcdir)/../common -I$(ATHENA)/include $(DEFS) $<
install:
ftpd: $(ftpd_OBJS) ../common/libcommon.a
$(CC) -o ftpd $(ftpd_OBJS) ../common/libcommon.a -L$(ATHENA)/lib -lkrb -ldes
ftpcmd.c: ftpcmd.y
$(YACC) $(YFLAGS) $<
chmod a-w y.tab.c
mv -f y.tab.c ftpcmd.c
clean cleandir:
rm -f *~ *.o core ftpd ftpcmd.c \#*
distclean:
rm -f Makefile
rm -rf CVS

131
appl/ftp/ftpd/auth.c Normal file
View File

@@ -0,0 +1,131 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include "extern.h"
#include "krb4.h"
#include "auth.h"
static struct at auth_types [] = {
{ "KERBEROS_V4", krb4_auth, krb4_adat, krb4_pbsz, krb4_prot, krb4_ccc,
krb4_mic, krb4_conf, krb4_enc, krb4_userok, krb4_vprintf },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
struct at *ct;
int data_protection;
int buffer_size;
int auth_complete;
void auth_init(void)
{
}
char *ftp_command;
int prot_level;
void new_ftp_command(char *command)
{
ftp_command = command;
}
void delete_ftp_command(void)
{
if(ftp_command){
free(ftp_command);
ftp_command = NULL;
}
}
void auth(char *auth)
{
for(ct=auth_types; ct->name; ct++){
if(!strcmp(auth, ct->name)){
ct->auth(auth);
return;
}
}
reply(504, "%s is not a known security mechanism", auth);
}
void adat(char *auth)
{
if(ct)
ct->adat(auth);
else
reply(503, "Error, error");
}
void pbsz(int size)
{
if(ct)
ct->pbsz(size);
else
reply(503, "Error, error");
}
void prot(char *pl)
{
if(ct)
ct->prot(pl);
else
reply(503, "Error, error");
}
void ccc(void)
{
if(ct)
ct->ccc();
else
reply(503, "Error, error");
}
void mic(char *msg)
{
prot_level = prot_safe;
if(ct)
ct->mic(msg);
else
reply(500, "Command unrecognized");
}
void conf(char *msg)
{
prot_level = prot_confidential;
if(ct)
ct->conf(msg);
else
reply(500, "Command unrecognized");
}
void enc(char *msg)
{
prot_level = prot_private;
if(ct)
ct->enc(msg);
else
reply(500, "Command unrecognized");
}
void auth_vprintf(const char *fmt, va_list ap)
{
if(ct && auth_complete && prot_level){
ct->vprintf(fmt, ap);
}else
vprintf(fmt, ap);
}
void auth_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
auth_vprintf(fmt, ap);
va_end(ap);
}

49
appl/ftp/ftpd/auth.h Normal file
View File

@@ -0,0 +1,49 @@
#ifndef _AUTH_H_
#define _AUTH_H_
#include <stdarg.h>
struct at {
char *name;
int (*auth)(char*);
int (*adat)(char*);
int (*pbsz)(int);
int (*prot)(char*);
int (*ccc)(void);
int (*mic)(char*);
int (*conf)(char*);
int (*enc)(char*);
int (*userok)(char*);
int (*vprintf)(const char*, va_list);
};
struct at *ct;
enum protection_levels {
prot_clear, prot_safe, prot_confidential, prot_private
};
extern char *ftp_command;
extern int prot_level;
int data_protection;
int buffer_size;
int auth_complete;
void auth_init(void);
void auth(char*);
void adat(char*);
void pbsz(int);
void prot(char*);
void ccc(void);
void mic(char*);
void conf(char*);
void enc(char*);
void auth_vprintf(const char *fmt, va_list ap);
void auth_printf(const char *fmt, ...);
void new_ftp_command(char *command);
#endif /* _AUTH_H_ */

115
appl/ftp/ftpd/commands.c Normal file
View File

@@ -0,0 +1,115 @@
enum form_code { form_code_N, form_code_T, form_code_C };
enum type_code { type_code_A, type_code_E, type_code_I, type_code_L };
enum structure_code { structure_code_F, structure_code_R, structure_code_P };
enum mode_code { mode_code_S, mode_code_B, mode_code_C };
enum prot_code { prot_code_C, prot_code_S, prot_code_E, prot_code_P };
struct ftp_commands{
char *name;
int (*user)(char *username);
int (*pass)(char *password);
int (*acct)(char *account);
int (*cwd)(char *pathname);
int (*auth)(char *mechanism_name);
int (*adat)(char *base64data);
int (*pbsz)(int buffer_size);
int (*prot)(int protection_code);
int (*ccc)(void);
int (*mic)(char *command);
int (*conf)(char *command);
int (*enc)(char *command);
int (*cdup)(void);
int (*smnt)(char *pathname);
int (*quit)(void);
int (*rein)(void);
int (*port)(char *host_port);
int (*pasv)(void);
int (*type)(int type_code, int form_code);
int (*stru)(int structure_code);
int (*mode)(int mode_code);
int (*retr)(char *pathname);
int (*stor)(char *pathname);
int (*stou)(void);
int (*appe)(char *pathname);
int (*allo)(int decimal_integer, char r, int decimal_integer);
int (*rest)(char *marker);
int (*rnfr)(char *pathname);
int (*rnto)(char *pathname);
int (*abor)(void);
int (*dele)(char *pathname);
int (*rmd)(char *pathname);
int (*mkd)(char *pathname);
int (*pwd)(void);
int (*list)(char *pathname);
int (*nlst)(char *pathname);
int (*site)(char *string);
int (*syst)(void);
int (*stat)(char *pathname);
int (*help)(char *string);
int (*noop)(void);
int (*reply)(int code, char *msg);
int (*lreply)(int code, char *msg);
};
struct ftp_commands commands [] = {
{
"noauth",
user, pass, acct, cwd,
NULL, /* AUTH */
NULL, /* ADAT */
NULL, /* PBSZ */
NULL, /* PROT */
NULL, /* CCC */
NULL, /* MIC */
NULL, /* CONF */
NULL, /* ENC */
cdup, smnt, quit, rein, port, pasv, type, stru, mode, retr, stor,
stou, appe, allo, rest, rnfr, rnto, abor, dele, rmd, mkd, pwd, list,
nlst, site, syst, stat, help, noop,
reply, lreply
}
{
"KERBEROS_V4",
krb4_user, krb4_pass, krb4_acct, NULL, krb4_auth, krb4_adat,
};
<username> ::= <string>
<password> ::= <string>
<account-information> ::= <string>
<string> ::= <char> | <char><string>
<char> ::= any of the 128 ASCII characters except <CR> and
<LF>
<marker> ::= <pr-string>
<pr-string> ::= <pr-char> | <pr-char><pr-string>
<pr-char> ::= printable characters, any
ASCII code 33 through 126
<byte-size> ::= <number>
<host-port> ::= <host-number>,<port-number>
<host-number> ::= <number>,<number>,<number>,<number>
<port-number> ::= <number>,<number>
<number> ::= any decimal integer 1 through 255
<form-code> ::= N | T | C
<type-code> ::= A [<sp> <form-code>]
| E [<sp> <form-code>]
| I
| L <sp> <byte-size>
<structure-code> ::= F | R | P
<mode-code> ::= S | B | C
<pathname> ::= <string>
<decimal-integer> ::= any decimal integer

View File

@@ -35,33 +35,72 @@
* @(#)extern.h 8.2 (Berkeley) 4/4/94
*/
void blkfree __P((char **));
char **copyblk __P((char **));
void cwd __P((char *));
void delete __P((char *));
void dologout __P((int));
void fatal __P((char *));
int ftpd_pclose __P((FILE *));
FILE *ftpd_popen __P((char *, char *));
char *getline __P((char *, int, FILE *));
void logwtmp __P((char *, char *, char *));
void lreply __P((int, const char *, ...));
void makedir __P((char *));
void nack __P((char *));
void pass __P((char *));
void passive __P((void));
void perror_reply __P((int, char *));
void pwd __P((void));
void removedir __P((char *));
void renamecmd __P((char *, char *));
char *renamefrom __P((char *));
void reply __P((int, const char *, ...));
void retrieve __P((char *, char *));
void send_file_list __P((char *));
void setproctitle __P((const char *, ...));
void statcmd __P((void));
void statfilecmd __P((char *));
void store __P((char *, char *, int));
void upper __P((char *));
void user __P((char *));
void yyerror __P((char *));
#ifndef _EXTERN_H_
#define _EXTERN_H_
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdarg.h>
#include <setjmp.h>
#include <pwd.h>
void blkfree(char **);
char **copyblk(char **);
void cwd(char *);
void delete(char *);
void dologout(int);
void fatal(char *);
int ftpd_pclose(FILE *);
FILE *ftpd_popen(char *, char *);
char *getline(char *, int);
void logwtmp(char *, char *, char *);
void lreply(int, const char *, ...);
void makedir(char *);
void nack(char *);
void pass(char *);
void passive(void);
void perror_reply(int, char *);
void pwd(void);
void removedir(char *);
void renamecmd(char *, char *);
char *renamefrom(char *);
void reply(int, const char *, ...);
void retrieve(char *, char *);
void send_file_list(char *);
void setproctitle(const char *, ...);
void statcmd(void);
void statfilecmd(char *);
void store(char *, char *, int);
void upper(char *);
void user(char *);
void yyerror(char *);
extern struct sockaddr_in ctrl_addr, his_addr;
extern char hostname[];
extern struct sockaddr_in data_dest;
extern int logged_in;
extern struct passwd *pw;
extern int guest;
extern int logging;
extern int type;
extern int oobflag;
extern off_t file_size;
extern off_t byte_count;
extern jmp_buf urgcatch;
extern int form;
extern int debug;
extern int timeout;
extern int maxtimeout;
extern int pdata;
extern char hostname[], remotehost[];
extern char proctitle[];
extern int usedefault;
extern int transflag;
extern char tmpline[];
#endif /* _EXTERN_H_ */

View File

@@ -71,23 +71,7 @@ static char rcsid[] = "$NetBSD: ftpcmd.y,v 1.6 1995/06/03 22:46:45 mycroft Exp $
#include <unistd.h>
#include "extern.h"
extern struct sockaddr_in data_dest;
extern int logged_in;
extern struct passwd *pw;
extern int guest;
extern int logging;
extern int type;
extern int form;
extern int debug;
extern int timeout;
extern int maxtimeout;
extern int pdata;
extern char hostname[], remotehost[];
extern char proctitle[];
extern int usedefault;
extern int transflag;
extern char tmpline[];
#include "auth.h"
off_t restart_point;
@@ -120,6 +104,9 @@ char *fromname;
UMASK IDLE CHMOD
AUTH ADAT PROT PBSZ CCC MIC
CONF ENC
LEXERR
%token <s> STRING
@@ -149,6 +136,43 @@ cmd
user($3);
free($3);
}
| AUTH SP STRING CRLF
{
auth($3);
free($3);
}
| ADAT SP STRING CRLF
{
adat($3);
free($3);
}
| PBSZ SP NUMBER CRLF
{
pbsz($3);
}
| PROT SP STRING CRLF
{
prot($3);
}
| CCC CRLF
{
ccc();
}
| MIC SP STRING CRLF
{
mic($3);
free($3);
}
| CONF SP STRING CRLF
{
conf($3);
free($3);
}
| ENC SP STRING CRLF
{
enc($3);
free($3);
}
| PASS SP password CRLF
{
pass($3);
@@ -288,8 +312,15 @@ cmd
}
| STAT CRLF
{
statcmd();
}
if(oobflag){
if (file_size != (off_t) -1)
reply(213, "Status: %ld of %ld bytes transferred",
byte_count, file_size);
else
reply(213, "Status: %ld bytes transferred", byte_count);
}else
statcmd();
}
| DELE check_login SP pathname CRLF
{
if ($2 && $4 != NULL)
@@ -310,7 +341,13 @@ cmd
}
| ABOR CRLF
{
reply(225, "ABOR command successful.");
if(oobflag){
reply(426, "Transfer aborted. Data connection closed.");
reply(226, "Abort successful");
oobflag = 0;
longjmp(urgcatch, 1);
}else
reply(225, "ABOR command successful.");
}
| CWD check_login CRLF
{
@@ -531,7 +568,7 @@ rcmd
{
fromname = (char *) 0;
restart_point = $3; /* XXX $3 is only "int" */
reply(350, "Restarting at %qd. %s", restart_point,
reply(350, "Restarting at %ld. %s", restart_point,
"Send STORE or RETRIEVE to initiate transfer.");
}
;
@@ -558,7 +595,6 @@ host_port
{
char *a, *p;
data_dest.sin_len = sizeof(struct sockaddr_in);
data_dest.sin_family = AF_INET;
p = (char *)&data_dest.sin_port;
p[0] = $9; p[1] = $11;
@@ -717,11 +753,15 @@ octal_number
check_login
: /* empty */
{
if(auth_complete && prot_level == prot_clear){
reply(533, "Command protection level denied for paranoid reasons.");
$$ = 0;
}else
if (logged_in)
$$ = 1;
$$ = 1;
else {
reply(530, "Please login with USER and PASS.");
$$ = 0;
reply(530, "Please login with USER and PASS.");
$$ = 0;
}
}
;
@@ -796,6 +836,17 @@ struct tab cmdtab[] = { /* In order defined in RFC 765 */
{ "STOU", STOU, STR1, 1, "<sp> file-name" },
{ "SIZE", SIZE, OSTR, 1, "<sp> path-name" },
{ "MDTM", MDTM, OSTR, 1, "<sp> path-name" },
/* extensions from draft-ietf-cat-ftpsec-08 */
{ "AUTH", AUTH, STR1, 1, "<sp> auth-type" },
{ "ADAT", ADAT, STR1, 1, "<sp> auth-data" },
{ "PBSZ", PBSZ, ARGS, 1, "<sp> buffer-size" },
{ "PROT", PROT, ARGS, 1, "<sp> prot-level" },
{ "CCC", CCC, ARGS, 1, "" },
{ "MIC", MIC, STR1, 1, "<sp> integrity command" },
{ "CONF", CONF, STR1, 1, "<sp> confidentiality command" },
{ "ENC", ENC, STR1, 1, "<sp> privacy command" },
{ NULL, 0, 0, 0, 0 }
};
@@ -833,43 +884,38 @@ lookup(p, cmd)
* getline - a hacked up version of fgets to ignore TELNET escape codes.
*/
char *
getline(s, n, iop)
char *s;
int n;
FILE *iop;
getline(char *s, int n)
{
int c;
register char *cs;
cs = s;
/* tmpline may contain saved command from urgent mode interruption */
for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
*cs++ = tmpline[c];
if (tmpline[c] == '\n') {
*cs++ = '\0';
if (debug)
syslog(LOG_DEBUG, "command: %s", s);
tmpline[0] = '\0';
return(s);
}
if (c == 0)
tmpline[0] = '\0';
if(ftp_command){
strncpy(s, ftp_command, n);
if (debug)
syslog(LOG_DEBUG, "command: %s", s);
#if 0
fprintf(stderr, "%s\n", s);
#endif
return s;
}
while ((c = getc(iop)) != EOF) {
prot_level = prot_clear;
while ((c = getc(stdin)) != EOF) {
c &= 0377;
if (c == IAC) {
if ((c = getc(iop)) != EOF) {
if ((c = getc(stdin)) != EOF) {
c &= 0377;
switch (c) {
case WILL:
case WONT:
c = getc(iop);
c = getc(stdin);
printf("%c%c%c", IAC, DONT, 0377&c);
(void) fflush(stdout);
continue;
case DO:
case DONT:
c = getc(iop);
c = getc(stdin);
printf("%c%c%c", IAC, WONT, 0377&c);
(void) fflush(stdout);
continue;
@@ -905,6 +951,9 @@ getline(s, n, iop)
syslog(LOG_DEBUG, "command: %.*s", len, s);
}
}
#if 0
fprintf(stderr, "%s\n", s);
#endif
return (s);
}
@@ -936,7 +985,7 @@ yylex()
case CMD:
(void) signal(SIGALRM, toolong);
(void) alarm((unsigned) timeout);
if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
if (getline(cbuf, sizeof(cbuf)-1) == NULL) {
reply(221, "You could at least say goodbye.");
dologout(0);
}
@@ -1171,6 +1220,7 @@ help(ctab, s)
struct tab *c;
int width, NCMDS;
char *type;
char buf[1024];
if (ctab == sitetab)
type = "SITE ";
@@ -1196,22 +1246,21 @@ help(ctab, s)
columns = 1;
lines = (NCMDS + columns - 1) / columns;
for (i = 0; i < lines; i++) {
printf(" ");
for (j = 0; j < columns; j++) {
c = ctab + j * lines + i;
printf("%s%c", c->name,
c->implemented ? ' ' : '*');
if (c + lines >= &ctab[NCMDS])
break;
w = strlen(c->name) + 1;
while (w < width) {
putchar(' ');
w++;
}
sprintf(buf, " ");
for (j = 0; j < columns; j++) {
c = ctab + j * lines + i;
sprintf(buf + strlen(buf), "%s%c", c->name,
c->implemented ? ' ' : '*');
if (c + lines >= &ctab[NCMDS])
break;
w = strlen(c->name) + 1;
while (w < width) {
strcat(buf, " ");
w++;
}
printf("\r\n");
}
lreply(214, buf);
}
(void) fflush(stdout);
reply(214, "Direct comments to ftp-bugs@%s.", hostname);
return;
}
@@ -1265,7 +1314,7 @@ sizecmd(filename)
}
(void) fclose(fin);
reply(213, "%qd", count);
reply(213, "%ld", count);
break; }
default:
reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);

View File

@@ -47,6 +47,10 @@ static char rcsid[] = "$NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $"
#endif
#endif /* not lint */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/*
* FTP server.
*/
@@ -67,7 +71,6 @@ static char rcsid[] = "$NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $"
#include <ctype.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
@@ -82,14 +85,19 @@ static char rcsid[] = "$NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $"
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <grp.h>
#include <stdarg.h>
#include "pathnames.h"
#include "extern.h"
#include "common.h"
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#include "auth.h"
#ifndef LOG_FTP
#define LOG_FTP LOG_DAEMON
#endif
static char version[] = "Version 6.00";
@@ -105,6 +113,7 @@ struct sockaddr_in pasv_addr;
int data;
jmp_buf errcatch, urgcatch;
int oobflag;
int logged_in;
struct passwd *pw;
int debug;
@@ -119,7 +128,7 @@ int stru; /* avoid C keyword */
int mode;
int usedefault = 1; /* for data transfers */
int pdata = -1; /* for passive mode */
sig_atomic_t transflag;
int transflag;
off_t file_size;
off_t byte_count;
#if !defined(CMASK) || CMASK == 0
@@ -127,7 +136,7 @@ off_t byte_count;
#define CMASK 027
#endif
int defumask = CMASK; /* default umask value */
char tmpline[7];
char tmpline[10240];
char hostname[MAXHOSTNAMELEN];
char remotehost[MAXHOSTNAMELEN];
static char ttyline[20];
@@ -138,6 +147,19 @@ int notickets = 1;
char *krbtkfile_env = NULL;
#endif
char *getusershell(void);
int endusershell(void);
int setusershell(void);
#ifdef sun
extern char *optarg;
extern int optind, opterr;
int fclose(FILE*);
char* crypt(char*, char*);
char* getwd(char*);
#endif
/*
* Timeout intervals for retrying connections
* to hosts that don't accept PORT cmds. This
@@ -168,7 +190,7 @@ char proctitle[BUFSIZ]; /* initial part of title */
syslog(LOG_INFO,"%s %s%s", cmd, \
*(file) == '/' ? "" : curdir(), file); \
else \
syslog(LOG_INFO, "%s %s%s = %qd bytes", \
syslog(LOG_INFO, "%s %s%s = %ld bytes", \
cmd, (*(file) == '/') ? "" : curdir(), file, cnt); \
}
@@ -177,19 +199,16 @@ static void myoob __P((int));
static int checkuser __P((char *, char *));
static FILE *dataconn __P((char *, off_t, char *));
static void dolog __P((struct sockaddr_in *));
static char *curdir __P((void));
static void end_login __P((void));
static FILE *getdatasock __P((char *));
static char *gunique __P((char *));
static void lostconn __P((int));
static int receive_data __P((FILE *, FILE *));
static void send_data __P((FILE *, FILE *, off_t));
static struct passwd *
sgetpwnam __P((char *));
static char *sgetsave __P((char *));
static struct passwd * sgetpwnam __P((char *));
static char *
curdir()
curdir(void)
{
static char path[MAXPATHLEN+1+1]; /* path + '/' + '\0' */
@@ -201,16 +220,46 @@ curdir()
return (guest ? path+1 : path);
}
#ifndef LINE_MAX
#define LINE_MAX 1024
#endif
static void gurka(void)
{
int s, t;
struct sockaddr_in sa;
int one = 1;
s = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
memset(&sa, 0, sizeof(sa));
sa.sin_port = htons(21);
sa.sin_addr.s_addr = INADDR_ANY;
bind(s, (struct sockaddr*)&sa, sizeof(sa));
listen(s, 5);
t = accept(s, NULL, 0);
close(s);
dup2(t, 0);
dup2(t, 1);
if(t > 2)
close(t);
}
#ifndef HAVE___PROGNAME
char *__progname = "ftpd";
#endif
int
main(argc, argv, envp)
int argc;
char *argv[];
char **envp;
main(int argc, char **argv, char **envp)
{
int addrlen, ch, on = 1, tos;
char *cp, line[LINE_MAX];
FILE *fd;
gurka();
/*
* LOG_NDELAY sets up the logging connection immediately,
* necessary for anonymous ftp's that chroot and can't do it later.
@@ -276,16 +325,18 @@ main(argc, argv, envp)
break;
default:
warnx("unknown flag -%c ignored", optopt);
warnx("unknown flag -%c ignored", argv[optind-1][0]);
break;
}
}
(void) freopen(_PATH_DEVNULL, "w", stderr);
/* (void) freopen(_PATH_DEVNULL, "w", stderr); */
(void) signal(SIGPIPE, lostconn);
(void) signal(SIGCHLD, SIG_IGN);
if ((long)signal(SIGURG, myoob) < 0)
syslog(LOG_ERR, "signal: %m");
auth_init();
/* Try to handle urgent data inline */
#ifdef SO_OOBINLINE
if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0)
@@ -338,8 +389,7 @@ main(argc, argv, envp)
}
static void
lostconn(signo)
int signo;
lostconn(int signo)
{
if (debug)
@@ -351,8 +401,7 @@ lostconn(signo)
* Helper function for sgetpwnam().
*/
static char *
sgetsave(s)
char *s;
sgetsave(char *s)
{
char *new = malloc((unsigned) strlen(s) + 1);
@@ -371,8 +420,7 @@ sgetsave(s)
* (e.g., globbing).
*/
static struct passwd *
sgetpwnam(name)
char *name;
sgetpwnam(char *name)
{
static struct passwd save;
struct passwd *p;
@@ -411,8 +459,7 @@ static char curname[10]; /* current USER name */
* _PATH_FTPUSERS to allow people such as root and uucp to be avoided.
*/
void
user(name)
char *name;
user(char *name)
{
char *cp, *shell;
@@ -473,9 +520,12 @@ user(name)
myskey ? myskey : "error getting challenge", name);
} else
#endif
reply(331, "Password required for %s.", name);
askpasswd = 1;
if(ct)
ct->userok(name);
else{
reply(331, "Password required for %s.", name);
askpasswd = 1;
}
/*
* Delay before reading passwd after first failed
* attempt to slow down passwd-guessing programs.
@@ -488,9 +538,7 @@ user(name)
* Check if a user is in the file "fname"
*/
static int
checkuser(fname, name)
char *fname;
char *name;
checkuser(char *fname, char *name)
{
FILE *fd;
int found = 0;
@@ -512,12 +560,95 @@ checkuser(fname, name)
return (found);
}
int do_login(int code, char *passwd)
{
FILE *fd;
login_attempts = 0; /* this time successful */
if (setegid((gid_t)pw->pw_gid) < 0) {
reply(550, "Can't set gid.");
return -1;
}
(void) initgroups(pw->pw_name, pw->pw_gid);
/* open wtmp before chroot */
logwtmp(ttyline, pw->pw_name, remotehost);
logged_in = 1;
dochroot = checkuser(_PATH_FTPCHROOT, pw->pw_name);
if (guest) {
/*
* We MUST do a chdir() after the chroot. Otherwise
* the old current directory will be accessible as "."
* outside the new root!
*/
if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
reply(550, "Can't set guest privileges.");
return -1;
}
} else if (dochroot) {
if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
reply(550, "Can't change root.");
return -1;
}
} else if (chdir(pw->pw_dir) < 0) {
if (chdir("/") < 0) {
reply(530, "User %s: can't change directory to %s.",
pw->pw_name, pw->pw_dir);
return -1;
} else
lreply(code, "No directory! Logging in with home=/");
}
if (seteuid((uid_t)pw->pw_uid) < 0) {
reply(550, "Can't set uid.");
return -1;
}
/*
* Display a login message, if it exists.
* N.B. reply(code,) must follow the message.
*/
if ((fd = fopen(_PATH_FTPLOGINMESG, "r")) != NULL) {
char *cp, line[LINE_MAX];
while (fgets(line, sizeof(line), fd) != NULL) {
if ((cp = strchr(line, '\n')) != NULL)
*cp = '\0';
lreply(code, "%s", line);
}
}
if (guest) {
reply(code, "Guest login ok, access restrictions apply.");
#ifdef HASSETPROCTITLE
snprintf(proctitle, sizeof(proctitle),
"%s: anonymous/%.*s", remotehost,
sizeof(proctitle) - sizeof(remotehost) -
sizeof(": anonymous/"), passwd);
setproctitle(proctitle);
#endif /* HASSETPROCTITLE */
if (logging)
syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
remotehost, passwd);
} else {
reply(code, "User %s logged in.", pw->pw_name);
#ifdef HASSETPROCTITLE
snprintf(proctitle, sizeof(proctitle),
"%s: %s", remotehost, pw->pw_name);
setproctitle(proctitle);
#endif /* HASSETPROCTITLE */
if (logging)
syslog(LOG_INFO, "FTP LOGIN FROM %s as %s",
remotehost, pw->pw_name);
}
(void) umask(defumask);
return 0;
}
/*
* Terminate login as previous user, if any, resetting state;
* used when USER command is given or login fails.
*/
static void
end_login()
end_login(void)
{
(void) seteuid((uid_t)0);
@@ -530,11 +661,14 @@ end_login()
}
void
pass(passwd)
char *passwd;
pass(char *passwd)
{
int rval;
FILE *fd;
/* some clients insists on sending a password */
if (logged_in && askpasswd == 0){
reply(230, "Dumpucko!");
return;
}
if (logged_in || askpasswd == 0) {
reply(503, "Login with USER first.");
@@ -588,93 +722,16 @@ skip:
return;
}
}
login_attempts = 0; /* this time successful */
if (setegid((gid_t)pw->pw_gid) < 0) {
reply(550, "Can't set gid.");
return;
}
(void) initgroups(pw->pw_name, pw->pw_gid);
/* open wtmp before chroot */
logwtmp(ttyline, pw->pw_name, remotehost);
logged_in = 1;
dochroot = checkuser(_PATH_FTPCHROOT, pw->pw_name);
if (guest) {
/*
* We MUST do a chdir() after the chroot. Otherwise
* the old current directory will be accessible as "."
* outside the new root!
*/
if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
reply(550, "Can't set guest privileges.");
goto bad;
}
} else if (dochroot) {
if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
reply(550, "Can't change root.");
goto bad;
}
} else if (chdir(pw->pw_dir) < 0) {
if (chdir("/") < 0) {
reply(530, "User %s: can't change directory to %s.",
pw->pw_name, pw->pw_dir);
goto bad;
} else
lreply(230, "No directory! Logging in with home=/");
}
if (seteuid((uid_t)pw->pw_uid) < 0) {
reply(550, "Can't set uid.");
goto bad;
}
/*
* Display a login message, if it exists.
* N.B. reply(230,) must follow the message.
*/
if ((fd = fopen(_PATH_FTPLOGINMESG, "r")) != NULL) {
char *cp, line[LINE_MAX];
while (fgets(line, sizeof(line), fd) != NULL) {
if ((cp = strchr(line, '\n')) != NULL)
*cp = '\0';
lreply(230, "%s", line);
}
(void) fflush(stdout);
(void) fclose(fd);
}
if (guest) {
reply(230, "Guest login ok, access restrictions apply.");
#ifdef HASSETPROCTITLE
snprintf(proctitle, sizeof(proctitle),
"%s: anonymous/%.*s", remotehost,
sizeof(proctitle) - sizeof(remotehost) -
sizeof(": anonymous/"), passwd);
setproctitle(proctitle);
#endif /* HASSETPROCTITLE */
if (logging)
syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
remotehost, passwd);
} else {
reply(230, "User %s logged in.", pw->pw_name);
#ifdef HASSETPROCTITLE
snprintf(proctitle, sizeof(proctitle),
"%s: %s", remotehost, pw->pw_name);
setproctitle(proctitle);
#endif /* HASSETPROCTITLE */
if (logging)
syslog(LOG_INFO, "FTP LOGIN FROM %s as %s",
remotehost, pw->pw_name);
}
(void) umask(defumask);
return;
if(!do_login(230, passwd))
return;
bad:
/* Forget all about it... */
end_login();
}
void
retrieve(cmd, name)
char *cmd, *name;
retrieve(char *cmd, char *name)
{
FILE *fin, *dout;
struct stat st;
@@ -720,7 +777,7 @@ retrieve(cmd, name)
if (c == '\n')
i++;
}
} else if (lseek(fileno(fin), restart_point, L_SET) < 0) {
} else if (lseek(fileno(fin), restart_point, SEEK_SET) < 0) {
perror_reply(550, name);
goto done;
}
@@ -739,9 +796,7 @@ done:
}
void
store(name, mode, unique)
char *name, *mode;
int unique;
store(char *name, char *mode, int unique)
{
FILE *fout, *din;
struct stat st;
@@ -783,11 +838,11 @@ store(name, mode, unique)
* because we are changing from reading to
* writing.
*/
if (fseek(fout, 0L, L_INCR) < 0) {
if (fseek(fout, 0L, SEEK_CUR) < 0) {
perror_reply(550, name);
goto done;
}
} else if (lseek(fileno(fout), restart_point, L_SET) < 0) {
} else if (lseek(fileno(fout), restart_point, SEEK_SET) < 0) {
perror_reply(550, name);
goto done;
}
@@ -811,8 +866,7 @@ done:
}
static FILE *
getdatasock(mode)
char *mode;
getdatasock(char *mode)
{
int on = 1, s, t, tries;
@@ -826,7 +880,6 @@ getdatasock(mode)
(char *) &on, sizeof(on)) < 0)
goto bad;
/* anchor socket to avoid multi-homing problems */
data_source.sin_len = sizeof(struct sockaddr_in);
data_source.sin_family = AF_INET;
data_source.sin_addr = ctrl_addr.sin_addr;
for (tries = 1; ; tries++) {
@@ -854,10 +907,7 @@ bad:
}
static FILE *
dataconn(name, size, mode)
char *name;
off_t size;
char *mode;
dataconn(char *name, off_t size, char *mode)
{
char sizebuf[32];
FILE *file;
@@ -866,7 +916,7 @@ dataconn(name, size, mode)
file_size = size;
byte_count = 0;
if (size != (off_t) -1)
(void) sprintf(sizebuf, " (%qd bytes)", size);
(void) sprintf(sizebuf, " (%ld bytes)", size);
else
(void) strcpy(sizebuf, "");
if (pdata >= 0) {
@@ -932,9 +982,7 @@ dataconn(name, size, mode)
* NB: Form isn't handled.
*/
static void
send_data(instr, outstr, blksize)
FILE *instr, *outstr;
off_t blksize;
send_data(FILE *instr, FILE *outstr, off_t blksize)
{
int c, cnt, filefd, netfd;
char *buf;
@@ -1009,8 +1057,7 @@ file_err:
* N.B.: Form isn't handled.
*/
static int
receive_data(instr, outstr)
FILE *instr, *outstr;
receive_data(FILE *instr, FILE *outstr)
{
int c;
int cnt, bare_lfs = 0;
@@ -1088,8 +1135,7 @@ file_err:
}
void
statfilecmd(filename)
char *filename;
statfilecmd(char *filename)
{
FILE *fin;
int c;
@@ -1120,8 +1166,9 @@ statfilecmd(filename)
}
void
statcmd()
statcmd(void)
{
#if 0
struct sockaddr_in *sin;
u_char *a, *p;
@@ -1169,12 +1216,12 @@ printaddr:
#undef UC
} else
printf(" No data connection\r\n");
#endif
reply(211, "End of status");
}
void
fatal(s)
char *s;
fatal(char *s)
{
reply(451, "Error in server: %s\n", s);
@@ -1183,69 +1230,52 @@ fatal(s)
/* NOTREACHED */
}
void
#if __STDC__
reply(int n, const char *fmt, ...)
#else
reply(n, fmt, va_alist)
int n;
char *fmt;
va_dcl
#endif
static void
int_reply(int n, char *c, const char *fmt, va_list ap)
{
va_list ap;
#if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
(void)printf("%d ", n);
(void)vprintf(fmt, ap);
(void)printf("\r\n");
(void)fflush(stdout);
if (debug) {
syslog(LOG_DEBUG, "<--- %d ", n);
vsyslog(LOG_DEBUG, fmt, ap);
}
char buf[10240];
char *p;
p=buf;
sprintf(p, "%d%s", n, c);
p+=strlen(p);
vsprintf(p, fmt, ap);
p+=strlen(p);
sprintf(p, "\r\n");
p+=strlen(p);
auth_printf("%s", buf);
fflush(stdout);
if (debug)
syslog(LOG_DEBUG, "<--- %s- ", buf);
}
void
#if __STDC__
lreply(int n, const char *fmt, ...)
#else
lreply(n, fmt, va_alist)
int n;
char *fmt;
va_dcl
#endif
reply(int n, const char *fmt, ...)
{
va_list ap;
#if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
(void)printf("%d- ", n);
(void)vprintf(fmt, ap);
(void)printf("\r\n");
(void)fflush(stdout);
if (debug) {
syslog(LOG_DEBUG, "<--- %d- ", n);
vsyslog(LOG_DEBUG, fmt, ap);
}
va_list ap;
va_start(ap, fmt);
int_reply(n, " ", fmt, ap);
delete_ftp_command();
va_end(ap);
}
void
lreply(int n, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
int_reply(n, "-", fmt, ap);
va_end(ap);
}
static void
ack(s)
char *s;
ack(char *s)
{
reply(250, "%s command successful.", s);
}
void
nack(s)
char *s;
nack(char *s)
{
reply(502, "%s command not implemented.", s);
@@ -1253,8 +1283,7 @@ nack(s)
/* ARGSUSED */
void
yyerror(s)
char *s;
yyerror(char *s)
{
char *cp;
@@ -1264,8 +1293,7 @@ yyerror(s)
}
void
delete(name)
char *name;
delete(char *name)
{
struct stat st;
@@ -1290,8 +1318,7 @@ done:
}
void
cwd(path)
char *path;
cwd(char *path)
{
if (chdir(path) < 0)
@@ -1301,8 +1328,7 @@ cwd(path)
}
void
makedir(name)
char *name;
makedir(char *name)
{
LOGCMD("mkdir", name);
@@ -1313,8 +1339,7 @@ makedir(name)
}
void
removedir(name)
char *name;
removedir(char *name)
{
LOGCMD("rmdir", name);
@@ -1325,7 +1350,7 @@ removedir(name)
}
void
pwd()
pwd(void)
{
char path[MAXPATHLEN + 1];
@@ -1336,8 +1361,7 @@ pwd()
}
char *
renamefrom(name)
char *name;
renamefrom(char *name)
{
struct stat st;
@@ -1350,8 +1374,7 @@ renamefrom(name)
}
void
renamecmd(from, to)
char *from, *to;
renamecmd(char *from, char *to)
{
LOGCMD2("rename", from, to);
@@ -1362,8 +1385,7 @@ renamecmd(from, to)
}
static void
dolog(sin)
struct sockaddr_in *sin;
dolog(struct sockaddr_in *sin)
{
struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr,
sizeof(struct in_addr), AF_INET);
@@ -1387,8 +1409,7 @@ dolog(sin)
* and exit with supplied status.
*/
void
dologout(status)
int status;
dologout(int status)
{
if (logged_in) {
@@ -1403,17 +1424,29 @@ dologout(status)
_exit(status);
}
void abor(void)
{
}
static void
myoob(signo)
int signo;
myoob(int signo)
{
char *cp;
/* only process if transfer occurring */
if (!transflag)
return;
oobflag = 1;
yyparse();
oobflag = 0;
/* hopefully this will work. this way we can send commands to
yyparse() from other sources than stdin */
#if 0
cp = tmpline;
if (getline(cp, 7, stdin) == NULL) {
if (getline(cp, 7) == NULL) {
reply(221, "You could at least say goodbye.");
dologout(0);
}
@@ -1426,11 +1459,12 @@ myoob(signo)
}
if (strcmp(cp, "STAT\r\n") == 0) {
if (file_size != (off_t) -1)
reply(213, "Status: %qd of %qd bytes transferred",
reply(213, "Status: %ld of %ld bytes transferred",
byte_count, file_size);
else
reply(213, "Status: %qd bytes transferred", byte_count);
reply(213, "Status: %ld bytes transferred", byte_count);
}
#endif
}
/*
@@ -1440,7 +1474,7 @@ myoob(signo)
* with Rick Adams on 25 Jan 89.
*/
void
passive()
passive(void)
{
int len;
char *p, *a;
@@ -1485,8 +1519,7 @@ pasv_error:
* Generates failure reply on error.
*/
static char *
gunique(local)
char *local;
gunique(char *local)
{
static char new[MAXPATHLEN];
struct stat st;
@@ -1518,9 +1551,7 @@ gunique(local)
* Format and send reply containing system error number.
*/
void
perror_reply(code, string)
int code;
char *string;
perror_reply(int code, char *string)
{
reply(code, "%s: %s.", string, strerror(errno));
@@ -1532,8 +1563,7 @@ static char *onefile[] = {
};
void
send_file_list(whichf)
char *whichf;
send_file_list(char *whichf)
{
struct stat st;
DIR *dirp = NULL;

195
appl/ftp/ftpd/krb4.c Normal file
View File

@@ -0,0 +1,195 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <krb.h>
#include "base64.h"
#include "extern.h"
#include "auth.h"
static AUTH_DAT auth_dat;
static des_key_schedule schedule;
int krb4_auth(char *auth)
{
auth_complete = 0;
reply(334, "Using authentication type %s; ADAT must follow", auth);
return 0;
}
int krb4_adat(char *auth)
{
KTEXT_ST tkt;
char *p;
int kerror;
u_int32_t cs;
char msg[35]; /* size of encrypted block */
int len;
char inst[INST_SZ];
memset(&tkt, 0, sizeof(tkt));
tkt.length = base64_decode(auth, tkt.dat);
strcpy(inst, "*");
kerror = krb_rd_req(&tkt, "ftp", inst, 0, &auth_dat, "");
if(kerror == RD_AP_UNDEC){
strcpy(inst, "*");
kerror = krb_rd_req(&tkt, "rcmd", inst, 0, &auth_dat, "");
}
des_key_sched(&auth_dat.session, schedule);
if(kerror != RD_AP_OK){
reply(535, "%s", krb_err_txt[kerror]);
return 1;
}
cs = htonl(auth_dat.checksum + 1);
len = krb_mk_safe((u_char*)&cs, (u_char*)msg, sizeof(cs),
&auth_dat.session, &ctrl_addr, &his_addr);
base64_encode((unsigned char*)msg, len, &p);
reply(235, "ADAT=%s", p);
auth_complete = 1;
free(p);
return 0;
}
int krb4_pbsz(int size)
{
buffer_size = size;
reply(200, "OK");
return 0;
}
int krb4_prot(char *type)
{
if(!strcmp(type, "C")){
data_protection = prot_clear;
}else if(!strcmp(type, "S")){
data_protection = prot_safe;
}else if(!strcmp(type, "E")){
data_protection = prot_confidential;
}else if(!strcmp(type, "P")){
data_protection = prot_private;
}else{
reply(504, "Unrecognized protection level");
return 1;
}
reply(200, "OK");
return 0;
}
int krb4_ccc(void)
{
reply(500, "Gurka");
return 1;
}
int krb4_mic(char *msg)
{
char *cmd = (char*)malloc(strlen(msg));
int len;
int kerror;
MSG_DAT m_data;
char *p;
char tmp[1024];
unsigned char enc[1024];
len = base64_decode(msg, cmd);
kerror = krb_rd_safe(cmd, len, &auth_dat.session,
&ctrl_addr, &his_addr, &m_data);
sprintf(tmp, "%.*s\r\n", m_data.app_length, m_data.app_data);
new_ftp_command(strdup(tmp));
free(cmd);
return 0;
}
int krb4_conf(char *msg)
{
char tmp[1024];
unsigned char enc[1024];
int len;
char *p;
sprintf(tmp, "%d %s\r\n", 536,
"Requested PROT level not supported by mechanism");
len = krb_mk_safe((u_char*)tmp, (u_char*)enc, strlen(tmp), &auth_dat.session,
&ctrl_addr, &his_addr);
if(len > 0){
base64_encode(enc, len, &p);
fprintf(stdout, "631 %s\r\n", p);
free(p);
}
return 1;
}
int krb4_enc(char *msg)
{
char *cmd = (char*)malloc(strlen(msg));
int len;
int kerror;
MSG_DAT m_data;
char *p;
char tmp[1024];
unsigned char enc[1024];
len = base64_decode(msg, cmd);
kerror = krb_rd_priv(cmd, len, schedule, &auth_dat.session,
&ctrl_addr, &his_addr, &m_data);
sprintf(tmp, "%.*s\r\n", m_data.app_length, m_data.app_data);
new_ftp_command(strdup(tmp));
free(cmd);
return 0;
}
int krb4_userok(char *name)
{
if(!kuserok(&auth_dat, name)){
do_login(232, name);
}else{
reply(530, "User %s access denied.", name);
}
return 0;
}
int krb4_vprintf(const char *fmt, va_list ap)
{
char buf[10240];
char *p;
char *enc;
int code;
int len;
vsprintf(buf, fmt, ap);
enc = malloc(strlen(buf) + 31);
if(prot_level == prot_safe){
len = krb_mk_safe((u_char*)buf, (u_char*)enc, strlen(buf), &auth_dat.session,
&ctrl_addr, &his_addr);
code = 631;
}else if(prot_level == prot_private){
len = krb_mk_priv((u_char*)buf, (u_char*)enc, strlen(buf), schedule,
&auth_dat.session, &ctrl_addr, &his_addr);
code = 632;
}else{
len = 0; /* XXX */
code = 631;
}
base64_encode(enc, len, &p);
fprintf(stdout, "%d %s\r\n", code, p);
free(enc);
free(p);
return 0;
}

17
appl/ftp/ftpd/krb4.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef _KRB4_H_
#define _KRB4_H_
#include <stdarg.h>
extern int krb4_auth(char * auth);
extern int krb4_adat(char * auth);
extern int krb4_pbsz(int size);
extern int krb4_prot(char * type);
extern int krb4_ccc(void );
extern int krb4_mic(char * msg);
extern int krb4_conf(char * msg);
extern int krb4_enc(char * msg);
extern int krb4_userok(char *name);
extern int krb4_vprintf(const char *fmt, va_list ap);
#endif /* _KRB4_H_ */

View File

@@ -42,6 +42,10 @@ static char rcsid[] = "$NetBSD: logwtmp.c,v 1.4 1995/04/11 02:44:58 cgd Exp $";
#endif
#endif /* not lint */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
@@ -61,13 +65,12 @@ static int fd = -1;
* after login, but before logout).
*/
void
logwtmp(line, name, host)
char *line, *name, *host;
logwtmp(char *line, char *name, char *host)
{
struct utmp ut;
struct stat buf;
if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
if (fd < 0 && (fd = open(WTMP_PATH, O_WRONLY|O_APPEND, 0)) < 0)
return;
if (fstat(fd, &buf) == 0) {
(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));

View File

@@ -35,7 +35,21 @@
* @(#)pathnames.h 8.1 (Berkeley) 6/4/93
*/
#ifdef HAVE_PATH_H
#include <paths.h>
#endif
#ifndef _PATH_DEVNULL
#define _PATH_DEVNULL "/dev/null"
#endif
#ifndef _PATH_NOLOGIN
#define _PATH_NOLOGIN "/etc/nologin"
#endif
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif
#define _PATH_FTPUSERS "/etc/ftpusers"
#define _PATH_FTPCHROOT "/etc/ftpchroot"

View File

@@ -45,6 +45,10 @@ static char rcsid[] = "$NetBSD: popen.c,v 1.5 1995/04/11 02:45:00 cgd Exp $";
#endif
#endif /* not lint */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/wait.h>
@@ -67,15 +71,14 @@ static int *pids;
static int fds;
FILE *
ftpd_popen(program, type)
char *program, *type;
ftpd_popen(char *program, char *type)
{
char *cp;
FILE *iop;
int argc, gargc, pdes[2], pid;
char **pop, *argv[100], *gargv[1000];
if (*type != 'r' && *type != 'w' || type[1])
if (strcmp(type, "r") && strcmp(type, "w"))
return (NULL);
if (!pids) {
@@ -151,10 +154,9 @@ pfree: for (argc = 1; gargv[argc] != NULL; argc++)
}
int
ftpd_pclose(iop)
FILE *iop;
ftpd_pclose(FILE *iop)
{
int fdes, omask, status;
int fdes, status;
pid_t pid;
sigset_t sigset, osigset;

853
lib/roken/glob.c Normal file
View File

@@ -0,0 +1,853 @@
/* $NetBSD: glob.c,v 1.5 1995/02/27 04:13:35 cgd Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
#else
static char rcsid[] = "$NetBSD: glob.c,v 1.5 1995/02/27 04:13:35 cgd Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
/*
* glob(3) -- a superset of the one defined in POSIX 1003.2.
*
* The [!...] convention to negate a range is supported (SysV, Posix, ksh).
*
* Optional extra services, controlled by flags not defined by POSIX:
*
* GLOB_QUOTE:
* Escaping convention: \ inhibits any special meaning the following
* character might have (except \ at end of string is retained).
* GLOB_MAGCHAR:
* Set in gl_flags if pattern contained a globbing character.
* GLOB_NOMAGIC:
* Same as GLOB_NOCHECK, but it will only append pattern if it did
* not contain any magic characters. [Used in csh style globbing]
* GLOB_ALTDIRFUNC:
* Use alternately specified directory access functions.
* GLOB_TILDE:
* expand ~user/foo to the /home/dir/of/user/foo
* GLOB_BRACE:
* expand {1,2}{a,b} to 1a 1b 2a 2b
* gl_matchc:
* Number of matches in the current invocation of glob.
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "glob.h"
#define DOLLAR '$'
#define DOT '.'
#define EOS '\0'
#define LBRACKET '['
#define NOT '!'
#define QUESTION '?'
#define QUOTE '\\'
#define RANGE '-'
#define RBRACKET ']'
#define SEP '/'
#define STAR '*'
#define TILDE '~'
#define UNDERSCORE '_'
#define LBRACE '{'
#define RBRACE '}'
#define SLASH '/'
#define COMMA ','
#ifndef DEBUG
#define M_QUOTE 0x8000
#define M_PROTECT 0x4000
#define M_MASK 0xffff
#define M_ASCII 0x00ff
typedef u_short Char;
#else
#define M_QUOTE 0x80
#define M_PROTECT 0x40
#define M_MASK 0xff
#define M_ASCII 0x7f
typedef char Char;
#endif
#define CHAR(c) ((Char)((c)&M_ASCII))
#define META(c) ((Char)((c)|M_QUOTE))
#define M_ALL META('*')
#define M_END META(']')
#define M_NOT META('!')
#define M_ONE META('?')
#define M_RNG META('-')
#define M_SET META('[')
#define ismeta(c) (((c)&M_QUOTE) != 0)
static int compare __P((const void *, const void *));
static void g_Ctoc __P((const Char *, char *));
static int g_lstat __P((Char *, struct stat *, glob_t *));
static DIR *g_opendir __P((Char *, glob_t *));
static Char *g_strchr __P((Char *, int));
#ifdef notdef
static Char *g_strcat __P((Char *, const Char *));
#endif
static int g_stat __P((Char *, struct stat *, glob_t *));
static int glob0 __P((const Char *, glob_t *));
static int glob1 __P((Char *, glob_t *));
static int glob2 __P((Char *, Char *, Char *, glob_t *));
static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
static int globextend __P((const Char *, glob_t *));
static const Char * globtilde __P((const Char *, Char *, glob_t *));
static int globexp1 __P((const Char *, glob_t *));
static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
static int match __P((Char *, Char *, Char *));
#ifdef DEBUG
static void qprintf __P((const char *, Char *));
#endif
int
glob(pattern, flags, errfunc, pglob)
const char *pattern;
int flags, (*errfunc) __P((const char *, int));
glob_t *pglob;
{
const u_char *patnext;
int c;
Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
patnext = (u_char *) pattern;
if (!(flags & GLOB_APPEND)) {
pglob->gl_pathc = 0;
pglob->gl_pathv = NULL;
if (!(flags & GLOB_DOOFFS))
pglob->gl_offs = 0;
}
pglob->gl_flags = flags & ~GLOB_MAGCHAR;
pglob->gl_errfunc = errfunc;
pglob->gl_matchc = 0;
bufnext = patbuf;
bufend = bufnext + MAXPATHLEN;
if (flags & GLOB_QUOTE) {
/* Protect the quoted characters. */
while (bufnext < bufend && (c = *patnext++) != EOS)
if (c == QUOTE) {
if ((c = *patnext++) == EOS) {
c = QUOTE;
--patnext;
}
*bufnext++ = c | M_PROTECT;
}
else
*bufnext++ = c;
}
else
while (bufnext < bufend && (c = *patnext++) != EOS)
*bufnext++ = c;
*bufnext = EOS;
if (flags & GLOB_BRACE)
return globexp1(patbuf, pglob);
else
return glob0(patbuf, pglob);
}
/*
* Expand recursively a glob {} pattern. When there is no more expansion
* invoke the standard globbing routine to glob the rest of the magic
* characters
*/
static int globexp1(pattern, pglob)
const Char *pattern;
glob_t *pglob;
{
const Char* ptr = pattern;
int rv;
/* Protect a single {}, for find(1), like csh */
if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
return glob0(pattern, pglob);
while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
if (!globexp2(ptr, pattern, pglob, &rv))
return rv;
return glob0(pattern, pglob);
}
/*
* Recursive brace globbing helper. Tries to expand a single brace.
* If it succeeds then it invokes globexp1 with the new pattern.
* If it fails then it tries to glob the rest of the pattern and returns.
*/
static int globexp2(ptr, pattern, pglob, rv)
const Char *ptr, *pattern;
glob_t *pglob;
int *rv;
{
int i;
Char *lm, *ls;
const Char *pe, *pm, *pl;
Char patbuf[MAXPATHLEN + 1];
/* copy part up to the brace */
for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
continue;
ls = lm;
/* Find the balanced brace */
for (i = 0, pe = ++ptr; *pe; pe++)
if (*pe == LBRACKET) {
/* Ignore everything between [] */
for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
continue;
if (*pe == EOS) {
/*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
pe = pm;
}
}
else if (*pe == LBRACE)
i++;
else if (*pe == RBRACE) {
if (i == 0)
break;
i--;
}
/* Non matching braces; just glob the pattern */
if (i != 0 || *pe == EOS) {
*rv = glob0(patbuf, pglob);
return 0;
}
for (i = 0, pl = pm = ptr; pm <= pe; pm++)
switch (*pm) {
case LBRACKET:
/* Ignore everything between [] */
for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
continue;
if (*pm == EOS) {
/*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
pm = pl;
}
break;
case LBRACE:
i++;
break;
case RBRACE:
if (i) {
i--;
break;
}
/* FALLTHROUGH */
case COMMA:
if (i && *pm == COMMA)
break;
else {
/* Append the current string */
for (lm = ls; (pl < pm); *lm++ = *pl++)
continue;
/*
* Append the rest of the pattern after the
* closing brace
*/
for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
continue;
/* Expand the current pattern */
#ifdef DEBUG
qprintf("globexp2:", patbuf);
#endif
*rv = globexp1(patbuf, pglob);
/* move after the comma, to the next string */
pl = pm + 1;
}
break;
default:
break;
}
*rv = 0;
return 0;
}
/*
* expand tilde from the passwd file.
*/
static const Char *
globtilde(pattern, patbuf, pglob)
const Char *pattern;
Char *patbuf;
glob_t *pglob;
{
struct passwd *pwd;
char *h;
const Char *p;
Char *b;
if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
return pattern;
/* Copy up to the end of the string or / */
for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH;
*h++ = *p++)
continue;
*h = EOS;
if (((char *) patbuf)[0] == EOS) {
/*
* handle a plain ~ or ~/ by expanding $HOME
* first and then trying the password file
*/
if ((h = getenv("HOME")) == NULL) {
if ((pwd = getpwuid(getuid())) == NULL)
return pattern;
else
h = pwd->pw_dir;
}
}
else {
/*
* Expand a ~user
*/
if ((pwd = getpwnam((char*) patbuf)) == NULL)
return pattern;
else
h = pwd->pw_dir;
}
/* Copy the home directory */
for (b = patbuf; *h; *b++ = *h++)
continue;
/* Append the rest of the pattern */
while ((*b++ = *p++) != EOS)
continue;
return patbuf;
}
/*
* The main glob() routine: compiles the pattern (optionally processing
* quotes), calls glob1() to do the real pattern matching, and finally
* sorts the list (unless unsorted operation is requested). Returns 0
* if things went well, nonzero if errors occurred. It is not an error
* to find no matches.
*/
static int
glob0(pattern, pglob)
const Char *pattern;
glob_t *pglob;
{
const Char *qpatnext;
int c, err, oldpathc;
Char *bufnext, patbuf[MAXPATHLEN+1];
qpatnext = globtilde(pattern, patbuf, pglob);
oldpathc = pglob->gl_pathc;
bufnext = patbuf;
/* We don't need to check for buffer overflow any more. */
while ((c = *qpatnext++) != EOS) {
switch (c) {
case LBRACKET:
c = *qpatnext;
if (c == NOT)
++qpatnext;
if (*qpatnext == EOS ||
g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
*bufnext++ = LBRACKET;
if (c == NOT)
--qpatnext;
break;
}
*bufnext++ = M_SET;
if (c == NOT)
*bufnext++ = M_NOT;
c = *qpatnext++;
do {
*bufnext++ = CHAR(c);
if (*qpatnext == RANGE &&
(c = qpatnext[1]) != RBRACKET) {
*bufnext++ = M_RNG;
*bufnext++ = CHAR(c);
qpatnext += 2;
}
} while ((c = *qpatnext++) != RBRACKET);
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_END;
break;
case QUESTION:
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_ONE;
break;
case STAR:
pglob->gl_flags |= GLOB_MAGCHAR;
/* collapse adjacent stars to one,
* to avoid exponential behavior
*/
if (bufnext == patbuf || bufnext[-1] != M_ALL)
*bufnext++ = M_ALL;
break;
default:
*bufnext++ = CHAR(c);
break;
}
}
*bufnext = EOS;
#ifdef DEBUG
qprintf("glob0:", patbuf);
#endif
if ((err = glob1(patbuf, pglob)) != 0)
return(err);
/*
* If there was no match we are going to append the pattern
* if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
* and the pattern did not contain any magic characters
* GLOB_NOMAGIC is there just for compatibility with csh.
*/
if (pglob->gl_pathc == oldpathc &&
((pglob->gl_flags & GLOB_NOCHECK) ||
((pglob->gl_flags & GLOB_NOMAGIC) &&
!(pglob->gl_flags & GLOB_MAGCHAR))))
return(globextend(pattern, pglob));
else if (!(pglob->gl_flags & GLOB_NOSORT))
qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
pglob->gl_pathc - oldpathc, sizeof(char *), compare);
return(0);
}
static int
compare(p, q)
const void *p, *q;
{
return(strcmp(*(char **)p, *(char **)q));
}
static int
glob1(pattern, pglob)
Char *pattern;
glob_t *pglob;
{
Char pathbuf[MAXPATHLEN+1];
/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
if (*pattern == EOS)
return(0);
return(glob2(pathbuf, pathbuf, pattern, pglob));
}
/*
* The functions glob2 and glob3 are mutually recursive; there is one level
* of recursion for each segment in the pattern that contains one or more
* meta characters.
*/
static int
glob2(pathbuf, pathend, pattern, pglob)
Char *pathbuf, *pathend, *pattern;
glob_t *pglob;
{
struct stat sb;
Char *p, *q;
int anymeta;
/*
* Loop over pattern segments until end of pattern or until
* segment with meta character found.
*/
for (anymeta = 0;;) {
if (*pattern == EOS) { /* End of pattern? */
*pathend = EOS;
if (g_lstat(pathbuf, &sb, pglob))
return(0);
if (((pglob->gl_flags & GLOB_MARK) &&
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
|| (S_ISLNK(sb.st_mode) &&
(g_stat(pathbuf, &sb, pglob) == 0) &&
S_ISDIR(sb.st_mode)))) {
*pathend++ = SEP;
*pathend = EOS;
}
++pglob->gl_matchc;
return(globextend(pathbuf, pglob));
}
/* Find end of next segment, copy tentatively to pathend. */
q = pathend;
p = pattern;
while (*p != EOS && *p != SEP) {
if (ismeta(*p))
anymeta = 1;
*q++ = *p++;
}
if (!anymeta) { /* No expansion, do next segment. */
pathend = q;
pattern = p;
while (*pattern == SEP)
*pathend++ = *pattern++;
} else /* Need expansion, recurse. */
return(glob3(pathbuf, pathend, pattern, p, pglob));
}
/* NOTREACHED */
}
static int
glob3(pathbuf, pathend, pattern, restpattern, pglob)
Char *pathbuf, *pathend, *pattern, *restpattern;
glob_t *pglob;
{
register struct dirent *dp;
DIR *dirp;
int err;
char buf[MAXPATHLEN];
/*
* The readdirfunc declaration can't be prototyped, because it is
* assigned, below, to two functions which are prototyped in glob.h
* and dirent.h as taking pointers to differently typed opaque
* structures.
*/
struct dirent *(*readdirfunc)();
*pathend = EOS;
errno = 0;
if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
/* TODO: don't call for ENOENT or ENOTDIR? */
if (pglob->gl_errfunc) {
g_Ctoc(pathbuf, buf);
if (pglob->gl_errfunc(buf, errno) ||
pglob->gl_flags & GLOB_ERR)
return (GLOB_ABEND);
}
return(0);
}
err = 0;
/* Search directory for matching names. */
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
readdirfunc = pglob->gl_readdir;
else
readdirfunc = readdir;
while ((dp = (*readdirfunc)(dirp))) {
register u_char *sc;
register Char *dc;
/* Initial DOT must be matched literally. */
if (dp->d_name[0] == DOT && *pattern != DOT)
continue;
for (sc = (u_char *) dp->d_name, dc = pathend;
(*dc++ = *sc++) != EOS;)
continue;
if (!match(pathend, pattern, restpattern)) {
*pathend = EOS;
continue;
}
err = glob2(pathbuf, --dc, restpattern, pglob);
if (err)
break;
}
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
(*pglob->gl_closedir)(dirp);
else
closedir(dirp);
return(err);
}
/*
* Extend the gl_pathv member of a glob_t structure to accomodate a new item,
* add the new item, and update gl_pathc.
*
* This assumes the BSD realloc, which only copies the block when its size
* crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
* behavior.
*
* Return 0 if new item added, error code if memory couldn't be allocated.
*
* Invariant of the glob_t structure:
* Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
* gl_pathv points to (gl_offs + gl_pathc + 1) items.
*/
static int
globextend(path, pglob)
const Char *path;
glob_t *pglob;
{
register char **pathv;
register int i;
u_int newsize;
char *copy;
const Char *p;
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
pathv = pglob->gl_pathv ?
realloc((char *)pglob->gl_pathv, newsize) :
malloc(newsize);
if (pathv == NULL)
return(GLOB_NOSPACE);
if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
/* first time around -- clear initial gl_offs items */
pathv += pglob->gl_offs;
for (i = pglob->gl_offs; --i >= 0; )
*--pathv = NULL;
}
pglob->gl_pathv = pathv;
for (p = path; *p++;)
continue;
if ((copy = malloc(p - path)) != NULL) {
g_Ctoc(path, copy);
pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
}
pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
return(copy == NULL ? GLOB_NOSPACE : 0);
}
/*
* pattern matching function for filenames. Each occurrence of the *
* pattern causes a recursion level.
*/
static int
match(name, pat, patend)
register Char *name, *pat, *patend;
{
int ok, negate_range;
Char c, k;
while (pat < patend) {
c = *pat++;
switch (c & M_MASK) {
case M_ALL:
if (pat == patend)
return(1);
do
if (match(name, pat, patend))
return(1);
while (*name++ != EOS);
return(0);
case M_ONE:
if (*name++ == EOS)
return(0);
break;
case M_SET:
ok = 0;
if ((k = *name++) == EOS)
return(0);
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
++pat;
while (((c = *pat++) & M_MASK) != M_END)
if ((*pat & M_MASK) == M_RNG) {
if (c <= k && k <= pat[1])
ok = 1;
pat += 2;
} else if (c == k)
ok = 1;
if (ok == negate_range)
return(0);
break;
default:
if (*name++ != c)
return(0);
break;
}
}
return(*name == EOS);
}
/* Free allocated data belonging to a glob_t structure. */
void
globfree(pglob)
glob_t *pglob;
{
register int i;
register char **pp;
if (pglob->gl_pathv != NULL) {
pp = pglob->gl_pathv + pglob->gl_offs;
for (i = pglob->gl_pathc; i--; ++pp)
if (*pp)
free(*pp);
free(pglob->gl_pathv);
}
}
static DIR *
g_opendir(str, pglob)
register Char *str;
glob_t *pglob;
{
char buf[MAXPATHLEN];
if (!*str)
strcpy(buf, ".");
else
g_Ctoc(str, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_opendir)(buf));
return(opendir(buf));
}
static int
g_lstat(fn, sb, pglob)
register Char *fn;
struct stat *sb;
glob_t *pglob;
{
char buf[MAXPATHLEN];
g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_lstat)(buf, sb));
return(lstat(buf, sb));
}
static int
g_stat(fn, sb, pglob)
register Char *fn;
struct stat *sb;
glob_t *pglob;
{
char buf[MAXPATHLEN];
g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_stat)(buf, sb));
return(stat(buf, sb));
}
static Char *
g_strchr(str, ch)
Char *str;
int ch;
{
do {
if (*str == ch)
return (str);
} while (*str++);
return (NULL);
}
#ifdef notdef
static Char *
g_strcat(dst, src)
Char *dst;
const Char* src;
{
Char *sdst = dst;
while (*dst++)
continue;
--dst;
while((*dst++ = *src++) != EOS)
continue;
return (sdst);
}
#endif
static void
g_Ctoc(str, buf)
register const Char *str;
char *buf;
{
register char *dc;
for (dc = buf; (*dc++ = *str++) != EOS;)
continue;
}
#ifdef DEBUG
static void
qprintf(str, s)
const char *str;
register Char *s;
{
register Char *p;
(void)printf("%s:\n", str);
for (p = s; *p; p++)
(void)printf("%c", CHAR(*p));
(void)printf("\n");
for (p = s; *p; p++)
(void)printf("%c", *p & M_PROTECT ? '"' : ' ');
(void)printf("\n");
for (p = s; *p; p++)
(void)printf("%c", ismeta(*p) ? '_' : ' ');
(void)printf("\n");
}
#endif

90
lib/roken/glob.h Normal file
View File

@@ -0,0 +1,90 @@
/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* 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.
*
* @(#)glob.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _GLOB_H_
#define _GLOB_H_
#ifndef __P
#define __P(protos) protos
#endif
struct stat;
typedef struct {
int gl_pathc; /* Count of total paths so far. */
int gl_matchc; /* Count of paths matching pattern. */
int gl_offs; /* Reserved at beginning of gl_pathv. */
int gl_flags; /* Copy of flags parameter to glob. */
char **gl_pathv; /* List of paths matching pattern. */
/* Copy of errfunc parameter to glob. */
int (*gl_errfunc) __P((const char *, int));
/*
* Alternate filesystem access methods for glob; replacement
* versions of closedir(3), readdir(3), opendir(3), stat(2)
* and lstat(2).
*/
void (*gl_closedir) __P((void *));
struct dirent *(*gl_readdir) __P((void *));
void *(*gl_opendir) __P((const char *));
int (*gl_lstat) __P((const char *, struct stat *));
int (*gl_stat) __P((const char *, struct stat *));
} glob_t;
#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
#define GLOB_ERR 0x0004 /* Return on error. */
#define GLOB_MARK 0x0008 /* Append / to matching directories. */
#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
#define GLOB_NOSORT 0x0020 /* Don't sort. */
#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
#define GLOB_NOSPACE (-1) /* Malloc call failed. */
#define GLOB_ABEND (-2) /* Unignored error. */
int glob __P((const char *, int, int (*)(const char *, int), glob_t *));
void globfree __P((glob_t *));
#endif /* !_GLOB_H_ */

90
lib/roken/glob.hin Normal file
View File

@@ -0,0 +1,90 @@
/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* 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.
*
* @(#)glob.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _GLOB_H_
#define _GLOB_H_
#ifndef __P
#define __P(protos) protos
#endif
struct stat;
typedef struct {
int gl_pathc; /* Count of total paths so far. */
int gl_matchc; /* Count of paths matching pattern. */
int gl_offs; /* Reserved at beginning of gl_pathv. */
int gl_flags; /* Copy of flags parameter to glob. */
char **gl_pathv; /* List of paths matching pattern. */
/* Copy of errfunc parameter to glob. */
int (*gl_errfunc) __P((const char *, int));
/*
* Alternate filesystem access methods for glob; replacement
* versions of closedir(3), readdir(3), opendir(3), stat(2)
* and lstat(2).
*/
void (*gl_closedir) __P((void *));
struct dirent *(*gl_readdir) __P((void *));
void *(*gl_opendir) __P((const char *));
int (*gl_lstat) __P((const char *, struct stat *));
int (*gl_stat) __P((const char *, struct stat *));
} glob_t;
#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
#define GLOB_ERR 0x0004 /* Return on error. */
#define GLOB_MARK 0x0008 /* Append / to matching directories. */
#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
#define GLOB_NOSORT 0x0020 /* Don't sort. */
#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
#define GLOB_NOSPACE (-1) /* Malloc call failed. */
#define GLOB_ABEND (-2) /* Unignored error. */
int glob __P((const char *, int, int (*)(const char *, int), glob_t *));
void globfree __P((glob_t *));
#endif /* !_GLOB_H_ */