1283514Sarybchik/*	$NetBSD: extern.h,v 1.66 2022/04/17 21:24:53 andvar Exp $	*/
2283514Sarybchik
3283514Sarybchik/*-
4283514Sarybchik * Copyright (c) 1992, 1993
5283514Sarybchik *	The Regents of the University of California.  All rights reserved.
6283514Sarybchik *
7283514Sarybchik * Redistribution and use in source and binary forms, with or without
8283514Sarybchik * modification, are permitted provided that the following conditions
9283514Sarybchik * are met:
10283514Sarybchik * 1. Redistributions of source code must retain the above copyright
11283514Sarybchik *    notice, this list of conditions and the following disclaimer.
12283514Sarybchik * 2. Redistributions in binary form must reproduce the above copyright
13283514Sarybchik *    notice, this list of conditions and the following disclaimer in the
14283514Sarybchik *    documentation and/or other materials provided with the distribution.
15283514Sarybchik * 3. Neither the name of the University nor the names of its contributors
16283514Sarybchik *    may be used to endorse or promote products derived from this software
17283514Sarybchik *    without specific prior written permission.
18283514Sarybchik *
19283514Sarybchik * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20283514Sarybchik * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21283514Sarybchik * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22283514Sarybchik * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23283514Sarybchik * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24283514Sarybchik * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25283514Sarybchik * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26283514Sarybchik * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27283514Sarybchik * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28283514Sarybchik * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29283514Sarybchik * SUCH DAMAGE.
30283514Sarybchik *
31283514Sarybchik *	@(#)extern.h	8.2 (Berkeley) 4/4/94
32283514Sarybchik */
33283514Sarybchik
34283514Sarybchik/*-
35283514Sarybchik * Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
36283514Sarybchik * All rights reserved.
37283514Sarybchik *
38283514Sarybchik * This code is derived from software contributed to The NetBSD Foundation
39283514Sarybchik * by Luke Mewburn.
40283514Sarybchik *
41293764Sarybchik * Redistribution and use in source and binary forms, with or without
42283514Sarybchik * modification, are permitted provided that the following conditions
43283514Sarybchik * are met:
44293764Sarybchik * 1. Redistributions of source code must retain the above copyright
45293764Sarybchik *    notice, this list of conditions and the following disclaimer.
46283514Sarybchik * 2. Redistributions in binary form must reproduce the above copyright
47283514Sarybchik *    notice, this list of conditions and the following disclaimer in the
48293764Sarybchik *    documentation and/or other materials provided with the distribution.
49293764Sarybchik *
50283514Sarybchik * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
51283514Sarybchik * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
52283514Sarybchik * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53293764Sarybchik * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
54293764Sarybchik * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55283514Sarybchik * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56283514Sarybchik * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57293764Sarybchik * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58283514Sarybchik * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59283514Sarybchik * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60283514Sarybchik * POSSIBILITY OF SUCH DAMAGE.
61283514Sarybchik */
62283514Sarybchik
63283514Sarybchik/*
64293764Sarybchik * Copyright (C) 1997 and 1998 WIDE Project.
65293764Sarybchik * All rights reserved.
66283514Sarybchik *
67283514Sarybchik * Redistribution and use in source and binary forms, with or without
68293764Sarybchik * modification, are permitted provided that the following conditions
69283514Sarybchik * are met:
70283514Sarybchik * 1. Redistributions of source code must retain the above copyright
71283514Sarybchik *    notice, this list of conditions and the following disclaimer.
72283514Sarybchik * 2. Redistributions in binary form must reproduce the above copyright
73283514Sarybchik *    notice, this list of conditions and the following disclaimer in the
74283514Sarybchik *    documentation and/or other materials provided with the distribution.
75293764Sarybchik * 3. Neither the name of the project nor the names of its contributors
76293764Sarybchik *    may be used to endorse or promote products derived from this software
77283514Sarybchik *    without specific prior written permission.
78283514Sarybchik *
79283514Sarybchik * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
80293764Sarybchik * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
81283514Sarybchik * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
82283514Sarybchik * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
83283514Sarybchik * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
84293764Sarybchik * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
85293764Sarybchik * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
86283514Sarybchik * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
87283514Sarybchik * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
88293764Sarybchik * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
89283514Sarybchik * SUCH DAMAGE.
90283514Sarybchik */
91283514Sarybchik
92293764Sarybchik#ifdef NO_LONG_LONG
93293764Sarybchik# define LLF		"%ld"
94283514Sarybchik# define LLFP(x)	"%" x "ld"
95283514Sarybchik# define LLT		long
96293764Sarybchik# define ULLF		"%lu"
97283514Sarybchik# define ULLFP(x)	"%" x "lu"
98283514Sarybchik# define ULLT		unsigned long
99283514Sarybchik# define STRTOLL(x,y,z)	strtol(x,y,z)
100293764Sarybchik# define LLTMIN		LONG_MIN
101293764Sarybchik# define LLTMAX		LONG_MAX
102283514Sarybchik#else
103283514Sarybchik# define LLF		"%lld"
104293764Sarybchik# define LLFP(x)	"%" x "lld"
105293764Sarybchik# define LLT		long long
106283514Sarybchik# define ULLF		"%llu"
107283514Sarybchik# define ULLFP(x)	"%" x "llu"
108283514Sarybchik# define ULLT		unsigned long long
109293764Sarybchik# define STRTOLL(x,y,z)	strtoll(x,y,z)
110293764Sarybchik# define LLTMIN		LLONG_MIN
111283514Sarybchik# define LLTMAX		LLONG_MAX
112283514Sarybchik#endif
113293764Sarybchik
114293764Sarybchik#define FTP_BUFLEN	512
115283514Sarybchik
116283514Sarybchikvoid	abor(void);
117291436Sarybchikvoid	closedataconn(FILE *);
118293764Sarybchikchar   *conffilename(const char *);
119283514Sarybchikvoid	count_users(void);
120283514Sarybchikvoid	cprintf(FILE *, const char *, ...)
121291436Sarybchik	    __printflike(2, 3);
122293764Sarybchikvoid	cwd(const char *);
123283514SarybchikFILE   *dataconn(const char *, off_t, const char *);
124293764Sarybchikvoid	delete(const char *);
125293764Sarybchikint	display_file(const char *, int);
126283514Sarybchikconst char **do_conversion(const char *);
127283514Sarybchik__dead void	dologout(int);
128283514Sarybchik__dead void	fatal(const char *);
129283514Sarybchikvoid	feat(void);
130283514Sarybchikvoid	format_path(char *, const char *);
131283514Sarybchikint	ftpd_pclose(FILE *);
132283514SarybchikFILE   *ftpd_popen(const char *[], const char *, int);
133283514Sarybchikint	get_line(char *, int, FILE *);
134283514Sarybchikvoid	init_curclass(void);
135283514Sarybchikvoid	logxfer(const char *, off_t, const char *, const char *,
136283514Sarybchik	    const struct timeval *, const char *);
137283514Sarybchikstruct tab *lookup(struct tab *, const char *);
138283514Sarybchikvoid	makedir(const char *);
139283514Sarybchikvoid	mlsd(const char *);
140283514Sarybchikvoid	mlst(const char *);
141283514Sarybchikvoid	opts(const char *);
142283514Sarybchikvoid	parse_conf(const char *);
143283514Sarybchikvoid	pass(const char *);
144283514Sarybchikvoid	passive(void);
145283514Sarybchikint	lpsvproto2af(int);
146283514Sarybchikint	af2lpsvproto(int);
147283514Sarybchikint	epsvproto2af(int);
148283514Sarybchikint	af2epsvproto(int);
149283514Sarybchikvoid	long_passive(const char *, int);
150293764Sarybchikint	extended_port(const char *);
151283514Sarybchikvoid	epsv_protounsupp(const char *);
152293764Sarybchikvoid	perror_reply(int, const char *);
153283514Sarybchikvoid	pwd(void);
154283514Sarybchikvoid	removedir(const char *);
155283514Sarybchikvoid	renamecmd(const char *, const char *);
156283514Sarybchikchar   *renamefrom(const char *);
157293764Sarybchikvoid	reply(int, const char *, ...)
158283514Sarybchik	    __printflike(2, 3);
159283514Sarybchikvoid	retrieve(const char *[], const char *);
160283514Sarybchikvoid	send_file_list(const char *);
161283514Sarybchikvoid	show_chdir_messages(int);
162291436Sarybchikvoid	sizecmd(const char *);
163283514Sarybchikvoid	statcmd(void);
164283514Sarybchikvoid	statfilecmd(const char *);
165283514Sarybchikvoid	statxfer(void);
166283514Sarybchikvoid	store(const char *, const char *, int);
167283514Sarybchikvoid	user(const char *);
168293764Sarybchikchar   *ftpd_strdup(const char *);
169283514Sarybchikvoid	yyerror(const char *);
170283514Sarybchik
171293764Sarybchik#ifdef SUPPORT_UTMP
172293764Sarybchikstruct utmp;
173283514Sarybchik
174293764Sarybchikvoid	ftpd_initwtmp(void);
175293764Sarybchikvoid	ftpd_logwtmp(const char *, const char *, const char *);
176293764Sarybchikvoid	ftpd_login(const struct utmp *);
177283514Sarybchikint	ftpd_logout(const char *);
178283514Sarybchik#endif
179283514Sarybchik
180291436Sarybchik#ifdef SUPPORT_UTMPX
181283514Sarybchikstruct utmpx;
182283514Sarybchikstruct sockinet;
183283514Sarybchik
184283514Sarybchikvoid	ftpd_initwtmpx(void);
185293764Sarybchikvoid	ftpd_logwtmpx(const char *, const char *, const char *,
186283514Sarybchik    struct sockinet *, int, int);
187283514Sarybchikvoid	ftpd_loginx(const struct utmpx *);
188283514Sarybchikint	ftpd_logoutx(const char *, int, int);
189283514Sarybchik#endif
190283514Sarybchik
191291436Sarybchik#include <netinet/in.h>
192283514Sarybchik
193283514Sarybchik#if defined(__NetBSD__)
194283514Sarybchik# define HAVE_SETPROCTITLE		1
195283514Sarybchik# define HAVE_STRUCT_SOCKADDR_SA_LEN	1
196283514Sarybchik# define HAVE_SOCKADDR_SNPRINTF		1
197283514Sarybchik#endif
198283514Sarybchik
199283514Sarybchikstruct sockinet {
200283514Sarybchik	union sockunion {
201283514Sarybchik		struct sockaddr_in  su_sin;
202283514Sarybchik#ifdef INET6
203293764Sarybchik		struct sockaddr_in6 su_sin6;
204283514Sarybchik#endif
205293764Sarybchik	} si_su;
206283514Sarybchik#if !defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
207283514Sarybchik	int	si_len;
208283514Sarybchik#endif
209283514Sarybchik};
210283514Sarybchik
211283514Sarybchik#if !defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
212283514Sarybchik# define su_len		si_len
213283514Sarybchik#else
214283514Sarybchik# define su_len		si_su.su_sin.sin_len
215283514Sarybchik#endif
216283514Sarybchik#define su_addr		si_su.su_sin.sin_addr
217283514Sarybchik#define su_family	si_su.su_sin.sin_family
218283514Sarybchik#define su_port		si_su.su_sin.sin_port
219283514Sarybchik#ifdef INET6
220283514Sarybchik# define su_6addr	si_su.su_sin6.sin6_addr
221283514Sarybchik# define su_scope_id	si_su.su_sin6.sin6_scope_id
222283514Sarybchik#endif
223283514Sarybchik
224283514Sarybchikstruct tab {
225283514Sarybchik	const char	*name;
226283514Sarybchik	short	 	token;
227283514Sarybchik	short	 	state;
228283514Sarybchik	short	 	flags;	/* 1 if command implemented, 2 if has options,
229283514Sarybchik				   4 if can occur OOB */
230283514Sarybchik	const char	*help;
231283514Sarybchik	char		*options;
232283514Sarybchik};
233283514Sarybchik
234283514Sarybchikstruct ftpconv {
235283514Sarybchik	struct ftpconv	*next;
236283514Sarybchik	char 		*suffix;	/* Suffix of requested name */
237283514Sarybchik	char		*types;		/* Valid file types */
238283514Sarybchik	char		*disable;	/* File to disable conversions */
239283514Sarybchik	char		*command;	/* Command to do the conversion */
240283514Sarybchik};
241283514Sarybchik
242283514Sarybchiktypedef enum {
243283514Sarybchik	CLASS_GUEST,
244283514Sarybchik	CLASS_CHROOT,
245283514Sarybchik	CLASS_REAL
246283514Sarybchik} class_ft;
247283514Sarybchik
248283514Sarybchiktypedef enum {
249283514Sarybchik	FLAG_checkportcmd =	1<<0,	/* Check port commands */
250283514Sarybchik	FLAG_denyquick =	1<<1,	/* Check ftpusers(5) before PASS */
251283514Sarybchik	FLAG_hidesymlinks =	1<<2,	/* For symbolic links, list the file
252283514Sarybchik					   or directory the link references
253283514Sarybchik					   rather than the link itself */
254283514Sarybchik	FLAG_modify =		1<<3,	/* Allow CHMOD, DELE, MKD, RMD, RNFR,
255283514Sarybchik					   UMASK */
256283514Sarybchik	FLAG_passive =		1<<4,	/* Allow PASV mode */
257283514Sarybchik	FLAG_private =		1<<5,	/* Don't publish class info in STAT */
258283514Sarybchik	FLAG_sanenames =	1<<6,	/* Restrict names of uploaded files */
259283514Sarybchik	FLAG_upload =		1<<7,	/* As per modify, but also allow
260283514Sarybchik					   APPE, STOR, STOU */
261283514Sarybchik} classflag_t;
262283514Sarybchik
263283514Sarybchik#define CURCLASS_FLAGS_SET(x)	(curclass.flags |=  (FLAG_ ## x))
264283514Sarybchik#define CURCLASS_FLAGS_CLR(x)	(curclass.flags &= ~(FLAG_ ## x))
265283514Sarybchik#define CURCLASS_FLAGS_ISSET(x)	(curclass.flags &   (FLAG_ ## x))
266283514Sarybchik
267283514Sarybchikstruct ftpclass {
268283514Sarybchik	struct sockinet	 advertise;	/* PASV address to advertise as */
269283514Sarybchik	char		*chroot;	/* Directory to chroot(2) to at login */
270283514Sarybchik	char		*classname;	/* Current class */
271283514Sarybchik	struct ftpconv	*conversions;	/* List of conversions */
272283514Sarybchik	char		*display;	/* File to display upon chdir */
273283514Sarybchik	char		*homedir;	/* Directory to chdir(2) to at login */
274283514Sarybchik	classflag_t	 flags;		/* Flags; see classflag_t above */
275283514Sarybchik	LLT		 limit;		/* Max connections (-1 = unlimited) */
276283514Sarybchik	char		*limitfile;	/* File to display if limit reached */
277283514Sarybchik	LLT		 maxfilesize;	/* Maximum file size of uploads */
278283514Sarybchik	LLT		 maxrateget;	/* Maximum get transfer rate throttle */
279283514Sarybchik	LLT		 maxrateput;	/* Maximum put transfer rate throttle */
280283514Sarybchik	LLT		 maxtimeout;	/* Maximum permitted timeout */
281283514Sarybchik	char		*motd;		/* MotD file to display after login */
282283514Sarybchik	char		*notify;	/* Files to notify about upon chdir */
283283514Sarybchik	LLT		 portmin;	/* Minimum port for passive mode */
284283514Sarybchik	LLT		 portmax;	/* Maximum port for passive mode */
285283514Sarybchik	LLT		 rateget;	/* Get (RETR) transfer rate throttle */
286283514Sarybchik	LLT		 rateput;	/* Put (STOR) transfer rate throttle */
287283514Sarybchik	LLT		 timeout;	/* Default timeout */
288283514Sarybchik	class_ft	 type;		/* Class type */
289283514Sarybchik	mode_t		 umask;		/* Umask to use */
290283514Sarybchik	LLT		 mmapsize;	/* mmap window size */
291283514Sarybchik	LLT		 readsize;	/* data read size */
292283514Sarybchik	LLT		 writesize;	/* data write size */
293283514Sarybchik	LLT		 recvbufsize;	/* SO_RCVBUF size */
294283514Sarybchik	LLT		 sendbufsize;	/* SO_SNDBUF size */
295283514Sarybchik	LLT		 sendlowat;	/* SO_SNDLOWAT size */
296283514Sarybchik};
297283514Sarybchik
298283514Sarybchik__dead extern void		ftp_loop(void);
299283514Sarybchikextern void		ftp_handle_line(char *);
300283514Sarybchik
301283514Sarybchik#ifndef	GLOBAL
302283514Sarybchik#define	GLOBAL	extern
303283514Sarybchik#endif
304293764Sarybchik
305293764Sarybchik
306283514SarybchikGLOBAL	struct sockinet ctrl_addr;
307283514SarybchikGLOBAL	struct sockinet	data_dest;
308283514SarybchikGLOBAL	struct sockinet	data_source;
309283514SarybchikGLOBAL	struct sockinet	his_addr;
310283514SarybchikGLOBAL	struct sockinet	pasv_addr;
311283514SarybchikGLOBAL	int		connections;
312283514SarybchikGLOBAL	struct ftpclass	curclass;
313283514SarybchikGLOBAL	int		ftpd_debug;
314291436SarybchikGLOBAL	char		*emailaddr;
315283514SarybchikGLOBAL	int		form;
316283514SarybchikGLOBAL	int		gidcount;	/* number of entries in gidlist[] */
317283514SarybchikGLOBAL	gid_t		*gidlist;
318283514SarybchikGLOBAL	int		hasyyerrored;
319283514SarybchikGLOBAL	char		hostname[MAXHOSTNAMELEN+1];
320291436SarybchikGLOBAL	char		homedir[MAXPATHLEN];
321283514Sarybchik#ifdef KERBEROS5
322283514SarybchikGLOBAL	krb5_context	kcontext;
323283514Sarybchik#endif
324293764SarybchikGLOBAL	int		logged_in;
325283514SarybchikGLOBAL	int		logging;
326283514SarybchikGLOBAL	int		pdata;			/* for passive mode */
327283514Sarybchik#if defined(HAVE_SETPROCTITLE)
328283514SarybchikGLOBAL	char		proctitle[BUFSIZ];	/* initial part of title */
329291436Sarybchik#endif
330283514SarybchikGLOBAL	struct passwd  *pw;
331283514SarybchikGLOBAL	int		quietmessages;
332283514SarybchikGLOBAL	char		remotehost[MAXHOSTNAMELEN+1];
333283514SarybchikGLOBAL	char		remoteloghost[2 * MAXHOSTNAMELEN + 4];
334283514SarybchikGLOBAL	off_t		restart_point;
335283514SarybchikGLOBAL	char		tmpline[FTP_BUFLEN];
336283514SarybchikGLOBAL	int		type;
337283514SarybchikGLOBAL	int		usedefault;		/* for data transfers */
338283514SarybchikGLOBAL	const char     *version;
339283514SarybchikGLOBAL	int		is_oob;
340283514Sarybchik
341283514Sarybchik						/* total file data bytes */
342283514SarybchikGLOBAL	off_t		total_data_in,  total_data_out,  total_data;
343283514Sarybchik						/* total number of data files */
344283514SarybchikGLOBAL	off_t		total_files_in, total_files_out, total_files;
345283514Sarybchik						/* total bytes */
346283514SarybchikGLOBAL	off_t		total_bytes_in, total_bytes_out, total_bytes;
347283514Sarybchik						/* total number of xfers */
348283514SarybchikGLOBAL	off_t		total_xfers_in, total_xfers_out, total_xfers;
349283514Sarybchik
350283514Sarybchikextern	struct tab	cmdtab[];
351283514Sarybchik
352283514Sarybchik#define	INTERNAL_LS	"/bin/ls"
353293764Sarybchik
354293764Sarybchik
355283514Sarybchik#define CMD_IMPLEMENTED(x)	((x)->flags != 0)
356283514Sarybchik#define CMD_HAS_OPTIONS(x)	((x)->flags & 0x2)
357283514Sarybchik#define CMD_OOB(x)		((x)->flags & 0x4)
358283514Sarybchik
359283514Sarybchik#define	CPUTC(c, f)	do { \
360283514Sarybchik				putc(c, f); total_bytes++; total_bytes_out++; \
361283514Sarybchik			} while (0)
362283514Sarybchik
363283514Sarybchik#define CURCLASSTYPE	curclass.type == CLASS_GUEST  ? "GUEST"  : \
364283514Sarybchik			curclass.type == CLASS_CHROOT ? "CHROOT" : \
365283514Sarybchik			curclass.type == CLASS_REAL   ? "REAL"   : \
366283514Sarybchik			"<unknown>"
367283514Sarybchik
368283514Sarybchik#define ISDOTDIR(x)	(x[0] == '.' && x[1] == '\0')
369283514Sarybchik#define ISDOTDOTDIR(x)	(x[0] == '.' && x[1] == '.' && x[2] == '\0')
370283514Sarybchik
371283514Sarybchik#define EMPTYSTR(p)	((p) == NULL || *(p) == '\0')
372283514Sarybchik#define NEXTWORD(P, W)	do { \
373283514Sarybchik				(W) = strsep(&(P), " \t"); \
374283514Sarybchik			} while ((W) != NULL && *(W) == '\0')
375283514Sarybchik#define PLURAL(s)	((s) == 1 ? "" : "s")
376291436Sarybchik#define REASSIGN(X,Y)	do { if (X) free(X); (X)=(Y); } while (/*CONSTCOND*/0)
377283514Sarybchik
378283514Sarybchik#ifndef IPPORT_ANONMAX
379283514Sarybchik# define IPPORT_ANONMAX	65535
380283514Sarybchik#endif
381283514Sarybchik