1106792Sobrien/* $Id: lukemftpd.h,v 1.20 2002/05/23 02:43:58 lukem Exp $ */
279968Sobrien
3106792Sobrien#define	FTPD_VERSION	"lukemftpd 1.2 beta 2"
479968Sobrien
579968Sobrien#include "config.h"
679968Sobrien
779968Sobrien#include <sys/types.h>
879968Sobrien#include <sys/param.h>
979968Sobrien#include <sys/ioctl.h>
1079968Sobrien#include <sys/socket.h>
1179968Sobrien#include <sys/stat.h>
1279968Sobrien#include <sys/wait.h>
1379968Sobrien#if HAVE_SYS_SYSMACROS_H
1479968Sobrien# include <sys/sysmacros.h>
1579968Sobrien#endif
1679968Sobrien
1779968Sobrien#include <netinet/in.h>
1879968Sobrien#include <netinet/in_systm.h>
1979968Sobrien#include <netinet/ip.h>
2079968Sobrien
2179968Sobrien#if HAVE_FTP_NAMES
2279968Sobrien# include <arpa/ftp.h>
2379968Sobrien#else
2479968Sobrien# include "arpaftp.h"
2579968Sobrien#endif
2679968Sobrien#include <arpa/inet.h>
2779968Sobrien
2879968Sobrien#include <ctype.h>
2979968Sobrien#include <errno.h>
3079968Sobrien#include <fcntl.h>
3179968Sobrien#include <grp.h>
3279968Sobrien#include <limits.h>
3379968Sobrien#include <locale.h>
3479968Sobrien#include <netdb.h>
3579968Sobrien#include <pwd.h>
3679968Sobrien#include <setjmp.h>
3779968Sobrien#include <signal.h>
3879968Sobrien#include <stdarg.h>
3979968Sobrien#include <stddef.h>
4079968Sobrien#include <stdio.h>
4179968Sobrien#include <stdlib.h>
4279968Sobrien#include <string.h>
4379968Sobrien#include <syslog.h>
4479968Sobrien#include <termios.h>
4579968Sobrien#include <unistd.h>
4679968Sobrien#include <utmp.h>
4779968Sobrien
4879968Sobrien#if HAVE_DIRENT_H
4979968Sobrien# include <dirent.h>
5079968Sobrien#else
5179968Sobrien# define dirent direct
5279968Sobrien# if HAVE_SYS_NDIR_H
5379968Sobrien#  include <sys/ndir.h>
5479968Sobrien# endif
5579968Sobrien# if HAVE_SYS_DIR_H
5679968Sobrien#  include <sys/dir.h>
5779968Sobrien# endif
5879968Sobrien# if HAVE_NDIR_H
5979968Sobrien#  include <ndir.h>
6079968Sobrien# endif
6179968Sobrien#endif
6279968Sobrien
6379968Sobrien#if TIME_WITH_SYS_TIME
6479968Sobrien# include <sys/time.h>
6579968Sobrien# include <time.h>
6679968Sobrien#else
6779968Sobrien# if HAVE_SYS_TIME_H
6879968Sobrien#  include <sys/time.h>
6979968Sobrien# else
7079968Sobrien#  include <time.h>
7179968Sobrien# endif
7279968Sobrien#endif
7379968Sobrien
7479968Sobrien#if HAVE_ERR_H
7579968Sobrien# include <err.h>
7679968Sobrien#endif
7779968Sobrien
7879968Sobrien#if HAVE_WORKING_GLOB
7979968Sobrien# include <glob.h>
8079968Sobrien#else
8179968Sobrien# include "ftpglob.h"
8279968Sobrien#endif
8379968Sobrien
84106792Sobrien#if HAVE_FNM_CASEFOLD
85106792Sobrien# include <fnmatch.h>
86106792Sobrien#else
87106792Sobrien# include "ftpfnmatch.h"
88106792Sobrien#endif
89106792Sobrien
9079968Sobrien#if HAVE_PATHS_H
9179968Sobrien# include <paths.h>
9279968Sobrien#endif
9379968Sobrien#ifndef	_PATH_BSHELL
9479968Sobrien#define	_PATH_BSHELL	"/bin/sh"
9579968Sobrien#endif
9679968Sobrien#ifndef	_PATH_CSHELL
9779968Sobrien#define	_PATH_CSHELL	"/bin/csh"
9879968Sobrien#endif
9979968Sobrien#ifndef	_PATH_SHELLS
10079968Sobrien#define	_PATH_SHELLS	"/etc/shells"
10179968Sobrien#endif
10279968Sobrien#ifndef	_PATH_DEVNULL
10379968Sobrien#define	_PATH_DEVNULL	"/dev/null"
10479968Sobrien#endif
10579968Sobrien#ifndef	_PATH_NOLOGIN
10679968Sobrien#define	_PATH_NOLOGIN	"/etc/nologin"
10779968Sobrien#endif
10879968Sobrien
10979968Sobrien#ifndef FTPD_LOGTYPE
11079968Sobrien# ifdef LOG_FTP
11179968Sobrien#  define FTPD_LOGTYPE	LOG_FTP
11279968Sobrien# else
11379968Sobrien#  define FTPD_LOGTYPE	LOG_DAEMON
11479968Sobrien# endif
11579968Sobrien#endif
11679968Sobrien
11779968Sobrien#ifndef LOG_AUTHPRIV
11879968Sobrien# ifdef LOG_AUTH
11979968Sobrien#  define LOG_AUTHPRIV	LOG_AUTH
12079968Sobrien# else
12179968Sobrien#  define LOG_AUTHPRIV	LOG_DAEMON
12279968Sobrien# endif
12379968Sobrien#endif
12479968Sobrien
12579968Sobrientypedef struct _stringlist {
12679968Sobrien	char	**sl_str;
12779968Sobrien	size_t	  sl_max;
12879968Sobrien	size_t	  sl_cur;
12979968Sobrien} StringList;
13079968Sobrien
13179968SobrienStringList *sl_init(void);
13279968Sobrienint	 sl_add(StringList *, char *);
13379968Sobrienvoid	 sl_free(StringList *, int);
13479968Sobrienchar	*sl_find(StringList *, char *);
13579968Sobrien
13679968Sobrien#if HAVE_FTS_H
13779968Sobrien# include <fts.h>
13879968Sobrien#else
13979968Sobrien# include "ftpfts.h"
14079968Sobrien#endif
14179968Sobrien
14279968Sobrien#if HAVE_UTIL_H
14379968Sobrien# include <util.h>
14479968Sobrien#endif
14579968Sobrien
14679968Sobrien#if HAVE_LIBUTIL_H
14779968Sobrien# include <libutil.h>
14879968Sobrien#endif
14979968Sobrien
15079968Sobrien#if ! HAVE_IN_PORT_T
15179968Sobrientypedef unsigned short in_port_t;
15279968Sobrien#endif
15379968Sobrien
15479968Sobrien#if ! HAVE_SOCKLEN_T
15579968Sobrientypedef unsigned int socklen_t;
15679968Sobrien#endif
15779968Sobrien
15879968Sobrien#if HAVE_AF_INET6 && HAVE_SOCKADDR_IN6
15979968Sobrien# define INET6
16079968Sobrien#endif
16179968Sobrien
16279968Sobrien
16379968Sobrien#if ! HAVE_RFC2553_NETDB
16479968Sobrien
16579968Sobrien				/* RFC 2553 */
16679968Sobrien#undef	EAI_ADDRFAMILY
16779968Sobrien#define	EAI_ADDRFAMILY	 1	/* address family for hostname not supported */
16879968Sobrien#undef	EAI_AGAIN
16979968Sobrien#define	EAI_AGAIN	 2	/* temporary failure in name resolution */
17079968Sobrien#undef	EAI_BADFLAGS
17179968Sobrien#define	EAI_BADFLAGS	 3	/* invalid value for ai_flags */
17279968Sobrien#undef	EAI_FAIL
17379968Sobrien#define	EAI_FAIL	 4	/* non-recoverable failure in name resolution */
17479968Sobrien#undef	EAI_FAMILY
17579968Sobrien#define	EAI_FAMILY	 5	/* ai_family not supported */
17679968Sobrien#undef	EAI_MEMORY
17779968Sobrien#define	EAI_MEMORY	 6	/* memory allocation failure */
17879968Sobrien#undef	EAI_NODATA
17979968Sobrien#define	EAI_NODATA	 7	/* no address associated with hostname */
18079968Sobrien#undef	EAI_NONAME
18179968Sobrien#define	EAI_NONAME	 8	/* hostname nor servname provided, or not known */
18279968Sobrien#undef	EAI_SERVICE
18379968Sobrien#define	EAI_SERVICE	 9	/* servname not supported for ai_socktype */
18479968Sobrien#undef	EAI_SOCKTYPE
18579968Sobrien#define	EAI_SOCKTYPE	10	/* ai_socktype not supported */
18679968Sobrien#undef	EAI_SYSTEM
18779968Sobrien#define	EAI_SYSTEM	11	/* system error returned in errno */
18879968Sobrien
18979968Sobrien				/* KAME extensions? */
19079968Sobrien#undef	EAI_BADHINTS
19179968Sobrien#define	EAI_BADHINTS	12
19279968Sobrien#undef	EAI_PROTOCOL
19379968Sobrien#define	EAI_PROTOCOL	13
19479968Sobrien#undef	EAI_MAX
19579968Sobrien#define	EAI_MAX		14
19679968Sobrien
19779968Sobrien				/* RFC 2553 */
19879968Sobrien#undef	NI_MAXHOST
19979968Sobrien#define	NI_MAXHOST	1025
20079968Sobrien#undef	NI_MAXSERV
20179968Sobrien#define	NI_MAXSERV	32
20279968Sobrien
20379968Sobrien#undef	NI_NOFQDN
20479968Sobrien#define	NI_NOFQDN	0x00000001
20579968Sobrien#undef	NI_NUMERICHOST
20679968Sobrien#define	NI_NUMERICHOST	0x00000002
20779968Sobrien#undef	NI_NAMEREQD
20879968Sobrien#define	NI_NAMEREQD	0x00000004
20979968Sobrien#undef	NI_NUMERICSERV
21079968Sobrien#define	NI_NUMERICSERV	0x00000008
21179968Sobrien#undef	NI_DGRAM
21279968Sobrien#define	NI_DGRAM	0x00000010
21379968Sobrien
21479968Sobrien				/* RFC 2553 */
21579968Sobrien#undef	AI_PASSIVE
21679968Sobrien#define	AI_PASSIVE	0x00000001 /* get address to use bind() */
21779968Sobrien#undef	AI_CANONNAME
21879968Sobrien#define	AI_CANONNAME	0x00000002 /* fill ai_canonname */
21979968Sobrien
22079968Sobrien				/* KAME extensions ? */
22179968Sobrien#undef	AI_NUMERICHOST
22279968Sobrien#define	AI_NUMERICHOST	0x00000004 /* prevent name resolution */
22379968Sobrien#undef	AI_MASK
22479968Sobrien#define	AI_MASK		(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
22579968Sobrien
22679968Sobrien				/* RFC 2553 */
22779968Sobrien#undef	AI_ALL
22879968Sobrien#define	AI_ALL		0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
22979968Sobrien#undef	AI_V4MAPPED_CFG
23079968Sobrien#define	AI_V4MAPPED_CFG	0x00000200 /* accept IPv4-mapped if kernel supports */
23179968Sobrien#undef	AI_ADDRCONFIG
23279968Sobrien#define	AI_ADDRCONFIG	0x00000400 /* only if any address is assigned */
23379968Sobrien#undef	AI_V4MAPPED
23479968Sobrien#define	AI_V4MAPPED	0x00000800 /* accept IPv4-mapped IPv6 address */
23579968Sobrien
23679968Sobrien#endif /* ! HAVE_RFC2553_NETDB */
23779968Sobrien
23879968Sobrien
23979968Sobrien#if ! HAVE_RFC2553_NETDB && ! HAVE_ADDRINFO
24079968Sobrien
24179968Sobrienstruct addrinfo {
24279968Sobrien	int	ai_flags;	/* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
24379968Sobrien	int	ai_family;	/* PF_xxx */
24479968Sobrien	int	ai_socktype;	/* SOCK_xxx */
24579968Sobrien	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
24679968Sobrien	size_t	ai_addrlen;	/* length of ai_addr */
24779968Sobrien	char	*ai_canonname;	/* canonical name for hostname */
24879968Sobrien	struct sockaddr *ai_addr;	/* binary address */
24979968Sobrien	struct addrinfo *ai_next;	/* next structure in linked list */
25079968Sobrien};
25179968Sobrien
25279968Sobrienint	getaddrinfo(const char *, const char *,
25379968Sobrien	    const struct addrinfo *, struct addrinfo **);
25479968Sobrienint	getnameinfo(const struct sockaddr *, socklen_t, char *,
25579968Sobrien	    size_t, char *, size_t, int);
25679968Sobrienvoid	freeaddrinfo(struct addrinfo *);
25779968Sobrienchar	*gai_strerror(int);
25879968Sobrien
25979968Sobrien#endif /* ! HAVE_RFC2553_NETDB && ! HAVE_ADDRINFO */
26079968Sobrien
26179968Sobrien
26279968Sobrien#if ! HAVE_D_NAMLEN
26379968Sobrien# define DIRENT_MISSING_D_NAMLEN
26479968Sobrien#endif
26579968Sobrien
26679968Sobrien#if ! HAVE_CRYPT_D
26779968Sobrienchar	*crypt(const char *, const char *);
26879968Sobrien#endif
26979968Sobrien
27079968Sobrien#if ! HAVE_FCLOSE_D
27179968Sobrienint	fclose(FILE *);
27279968Sobrien#endif
27379968Sobrien
27479968Sobrien#if ! HAVE_OPTARG_D
27579968Sobrienextern char	*optarg;
27679968Sobrien#endif
27779968Sobrien
27879968Sobrien#if ! HAVE_OPTIND_D
27979968Sobrienextern int	optind;
28079968Sobrien#endif
28179968Sobrien
28279968Sobrien#if ! HAVE_PCLOSE_D
28379968Sobrienint	pclose(FILE *);
28479968Sobrien#endif
28579968Sobrien
28679968Sobrien#if ! HAVE_ERR
28779968Sobrienvoid	err(int, const char *, ...);
28879968Sobrienvoid	errx(int, const char *, ...);
28979968Sobrienvoid	warn(const char *, ...);
29079968Sobrienvoid	warnx(const char *, ...);
29179968Sobrien#endif
29279968Sobrien
29379968Sobrien#if ! HAVE_FGETLN
29479968Sobrienchar	*fgetln(FILE *, size_t *);
29579968Sobrien#endif
29679968Sobrien
29779968Sobrien#if ! HAVE_FPARSELN
29879968Sobrien# define FPARSELN_UNESCESC	0x01
29979968Sobrien# define FPARSELN_UNESCCONT	0x02
30079968Sobrien# define FPARSELN_UNESCCOMM	0x04
30179968Sobrien# define FPARSELN_UNESCREST	0x08
30279968Sobrien# define FPARSELN_UNESCALL	0x0f
30379968Sobrienchar	*fparseln(FILE *, size_t *, size_t *, const char[3], int);
30479968Sobrien#endif
30579968Sobrien
30679968Sobrien#if ! HAVE_GETUSERSHELL || ! HAVE_GETUSERSHELL_D
30779968Sobrienchar	*getusershell(void);
30879968Sobrienvoid	setusershell(void);
30979968Sobrienvoid	endusershell(void);
31079968Sobrien#endif
31179968Sobrien
31279968Sobrien#if ! HAVE_INET_NTOP
31379968Sobrienconst char *inet_ntop(int, const void *, char *, size_t);
31479968Sobrien#endif
31579968Sobrien
31679968Sobrien#if ! HAVE_INET_PTON
31779968Sobrienint	inet_pton(int, const char *, void *);
31879968Sobrien#endif
31979968Sobrien
32079968Sobrien#if ! HAVE_MKSTEMP
32179968Sobrienint	mkstemp(const char *);
32279968Sobrien#endif
32379968Sobrien
32479968Sobrien#if ! HAVE_SNPRINTF
32579968Sobrienint	snprintf(char *, size_t, const char *, ...);
32679968Sobrien#endif
32779968Sobrien
32879968Sobrien#if ! HAVE_STRDUP
32979968Sobrienchar	*strdup(const char *);
33079968Sobrien#endif
33179968Sobrien
33279968Sobrien#if ! HAVE_STRERROR
33379968Sobrienchar	*strerror(int);
33479968Sobrien#endif
33579968Sobrien
33679968Sobrien#if HAVE_QUAD_SUPPORT
33779968Sobrien# if ! HAVE_STRTOLL && HAVE_LONG_LONG
33879968Sobrienlong long strtoll(const char *, char **, int);
33979968Sobrien#  if ! defined(QUAD_MIN)
34079968Sobrien#   define QUAD_MIN	(-0x7fffffffffffffffL-1)
34179968Sobrien#  endif
34279968Sobrien#  if ! defined(QUAD_MAX)
34379968Sobrien#   define QUAD_MAX	(0x7fffffffffffffffL)
34479968Sobrien#  endif
34579968Sobrien# endif
34679968Sobrien#else	/* ! HAVE_QUAD_SUPPORT */
34779968Sobrien# define NO_LONG_LONG	1
34879968Sobrien#endif	/* ! HAVE_QUAD_SUPPORT */
34979968Sobrien
35079968Sobrien#if ! HAVE_STRLCAT
35179968Sobriensize_t	strlcat(char *, const char *, size_t);
35279968Sobrien#endif
35379968Sobrien
35479968Sobrien#if ! HAVE_STRLCPY
35579968Sobriensize_t	strlcpy(char *, const char *, size_t);
35679968Sobrien#endif
35779968Sobrien
35879968Sobrien#if ! HAVE_STRMODE
35979968Sobrienvoid	strmode(mode_t, char *);
36079968Sobrien#endif
36179968Sobrien
36279968Sobrien#if ! HAVE_STRSEP
36379968Sobrienchar	*strsep(char **, const char *);
36479968Sobrien#endif
36579968Sobrien
36679968Sobrien#if ! HAVE_USER_FROM_UID
36779968Sobrienconst char *user_from_uid(uid_t, int);
36879968Sobrienconst char *group_from_gid(gid_t, int);
36979968Sobrien#endif
37079968Sobrien
37179968Sobrien#if ! HAVE_VSYSLOG
37279968Sobrienvoid	vsyslog(int level, const char *, va_list);
37379968Sobrien#endif
37479968Sobrien
37579968Sobrien
37679968Sobrien#if ! defined(MIN)
37779968Sobrien# define MIN(a, b)	((a) < (b) ? (a) : (b))
37879968Sobrien#endif
37979968Sobrien#if ! defined(MAX)
38079968Sobrien# define MAX(a, b)	((a) < (b) ? (b) : (a))
38179968Sobrien#endif
38279968Sobrien
38379968Sobrien#if ! defined(timersub)
38479968Sobrien# define timersub(tvp, uvp, vvp)					\
38579968Sobrien	do {								\
38679968Sobrien		(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
38779968Sobrien		(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;	\
38879968Sobrien		if ((vvp)->tv_usec < 0) {				\
38979968Sobrien			(vvp)->tv_sec--;				\
39079968Sobrien			(vvp)->tv_usec += 1000000;			\
39179968Sobrien		}							\
39279968Sobrien	} while (0)
39379968Sobrien#endif
39479968Sobrien
39579968Sobrien#if ! defined(S_ISLNK)
39679968Sobrien# define S_ISLNK(m)	((m & S_IFMT) == S_IFLNK)
39779968Sobrien#endif
39879968Sobrien
39979968Sobrien#define	DAYSPERNYEAR	365
40079968Sobrien#define SECSPERDAY	86400
40179968Sobrien#define TM_YEAR_BASE	1900
402