ftpcmd.y revision 67dbe2be0c0f1e2eb428b89088bb5667e8f0b9f6
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/****************************************************************************
Copyright (c) 1999,2000,2001 WU-FTPD Development Group.
All rights reserved.
Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994
The Regents of the University of California.
Portions Copyright (c) 1993, 1994 Washington University in Saint Louis.
Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.
Portions Copyright (c) 1989 Massachusetts Institute of Technology.
Portions Copyright (c) 1998 Sendmail, Inc.
Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman.
Portions Copyright (c) 1997 by Stan Barber.
Portions Copyright (c) 1997 by Kent Landfield.
Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
Free Software Foundation, Inc.
Use and distribution of this software and its source code are governed
by the terms and conditions of the WU-FTPD Software License ("LICENSE").
If you did not receive a copy of the license, it may be obtained online
$Id: ftpcmd.y,v 1.27.2.2 2001/11/29 17:01:38 wuftpd Exp $
****************************************************************************/
/*
* Grammar for FTP commands.
* See RFC 959.
*/
%{
#include "config.h"
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <ctype.h>
#include <pwd.h>
#include <setjmp.h>
#ifdef HAVE_SYS_SYSLOG_H
#endif
#include <syslog.h>
#endif
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <alloca.h>
#include "extensions.h"
#include "pathnames.h"
#include "proto.h"
static int pbsz_command_issued = 0;
char *cur_auth_type = NULL;
extern char *protnames[];
#endif /* defined(USE_TLS) || defined(USE_GSS) */
#if defined(USE_GSS)
#include "gssutil.h"
extern gss_info_t gss_info;
#endif /* defined(USE_GSS) */
extern int dolreplies;
#ifndef INTERNAL_LS
extern char ls_long[];
extern char ls_short[];
#endif
extern struct SOCKSTORAGE data_dest;
extern struct SOCKSTORAGE his_addr;
extern int logged_in;
extern int anonymous;
extern int logging;
extern int log_commands;
extern int log_security;
extern int type;
extern int form;
extern int debug;
extern unsigned int timeout_idle;
extern unsigned int timeout_maxidle;
extern int pdata;
extern char remoteaddr[];
extern char chroot_path[];
extern char proctitle[];
extern char *globerr;
extern int usedefault;
extern int transflag;
extern char tmpline[];
extern int data;
extern int errno;
extern char *home;
int yyerrorcalled;
extern char *strunames[];
extern char *typenames[];
extern char *modenames[];
extern char *formnames[];
extern int restricted_user; /* global flag indicating if user is restricted to home directory */
#ifdef TRANSFER_COUNT
extern off_t data_count_total;
extern off_t byte_count_total;
extern off_t byte_count_in;
extern int file_count_total;
extern int xfer_count_total;
#endif
extern int retrieve_is_data;
#ifdef VIRTUAL
extern int virtual_mode;
extern int virtual_ftpaccess;
extern char virtual_email[];
#endif
#ifdef IGNORE_NOOP
static int alarm_running = 0;
#endif
static unsigned short cliport = 0;
static int cmd_type;
static int cmd_form;
static int cmd_bytesz;
char *fromname;
#ifndef L_FORMAT /* Autoconf detects this... */
#define L_FORMAT "qd"
#else
#ifdef _AIX42
#define L_FORMAT "lld"
#else
#ifdef SOLARIS_2
#define L_FORMAT "ld"
#else
#define L_FORMAT "d"
#endif
#endif
#endif
#endif
#ifdef INET6
extern int epsv_all;
int lport_error;
#endif
/* Debian linux bison fix: moved this up, added forward decls */
struct tab {
char *name;
short token;
short state;
short implemented; /* 1 if command is implemented */
char *help;
};
static void toolong(int);
int yylex(void);
static char *nullstr = "(null)";
extern int pasv_allowed(const char *remoteaddr);
extern int port_allowed(const char *remoteaddr);
%}
A B C E F I
L N P R S T
%union {
char *String;
int Number;
}
%%
cmd_list: /* empty */
= {
if (fromname) {
}
restart_point = 0;
}
;
= {
user($3);
if (log_commands)
free($3);
}
= {
if (log_commands)
if (anonymous)
else
pass($3);
free($3);
}
= {
if (log_commands)
/* H* port fix, part B: admonish the twit.
Also require login before PORT works */
if ($2) {
#ifndef DISABLE_PORT
#ifdef INET6
if (epsv_all) {
goto prt_done;
}
#endif
usedefault = 0;
if (pdata >= 0) {
pdata = -1;
}
}
else {
#endif /* DISABLE_PORT */
usedefault = 1;
#ifndef DISABLE_PORT
}
#endif
}
}
= {
#ifdef INET6
if (log_commands)
#ifndef DISABLE_PORT
int proto;
unsigned short port;
if (epsv_all) {
goto eprt_done;
}
d = *((char *)$4);
if ((d < 33) || (d > 126)) {
goto eprt_done;
}
if (d == '%')
"%%%1$c%%d%%%1$c%%%2$d[^%%%1$c]%%%1$c%%hu%%%1$c",
d, INET6_ADDRSTRLEN);
else
"%1$c%%d%1$c%%%2$d[^%1$c]%1$c%%hu%1$c",
d, INET6_ADDRSTRLEN);
goto eprt_done;
}
switch (proto) {
case 1:
break;
case 2:
break;
default:
goto eprt_done;
}
!= 1) {
goto eprt_done;
}
usedefault = 0;
if (pdata >= 0) {
pdata = -1;
}
}
else {
#endif /* DISABLE_PORT */
usedefault = 1;
$4, remoteident);
#ifndef DISABLE_PORT
}
#endif
}
if ($4 != NULL)
free($4);
#endif /* INET6 */
}
= {
#ifdef INET6
if (log_commands)
if ($2) {
#ifndef DISABLE_PORT
if (lport_error)
goto lprt_done;
usedefault = 0;
if (pdata >= 0) {
pdata = -1;
}
}
else {
#endif /* DISABLE_PORT */
usedefault = 1;
#ifndef DISABLE_PORT
}
#endif
}
#endif /* INET6 */
}
= {
/* Require login for PASV, too. This actually fixes a bug -- telnet to an
unfixed wu-ftpd and type PASV first off, and it crashes! */
if (log_commands)
if ($2)
#if (defined (DISABLE_PORT) || !defined (DISABLE_PASV))
#ifdef INET6
if (epsv_all)
else
#endif
#else
#endif
}
= {
#ifdef INET6
if (log_commands)
if ($2)
#if (defined (DISABLE_PORT) || !defined (DISABLE_PASV))
#else
#endif
#endif /* INET6 */
}
= {
#ifdef INET6
if (log_commands)
#if (defined (DISABLE_PORT) || !defined (DISABLE_PASV))
epsv_all = 1;
}
else {
int af;
char *endp;
if (*endp)
else {
/* Not allowed to specify address family 0 */
if (af == 0)
af = -1;
}
}
#else
#endif
if ($4 != NULL)
free($4);
#endif /* INET6 */
}
= {
#ifdef INET6
if (log_commands)
if ($2)
#if (defined (DISABLE_PORT) || !defined (DISABLE_PASV))
if (epsv_all)
else
#else
#endif
#endif /* INET6 */
}
= {
if (log_commands)
if ($2)
switch (cmd_type) {
case TYPE_A:
}
else
break;
case TYPE_E:
break;
case TYPE_I:
break;
case TYPE_L:
#if NBBY == 8
if (cmd_bytesz == 8) {
reply(200,
"Type set to L (byte size 8).");
}
else
#else /* NBBY == 8 */
#endif /* NBBY == 8 */
}
}
= {
if (log_commands)
if ($2)
switch ($4) {
case STRU_F:
break;
default:
}
}
= {
if (log_commands)
if ($2)
switch ($4) {
case MODE_S:
break;
default:
}
}
= {
if (log_commands)
if ($2)
}
= {
if (log_commands)
if ($2)
}
= {
if (log_commands)
retrieve_is_data = 1;
}
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
send_file_list("");
}
= {
if (log_commands)
send_file_list($4);
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
retrieve_is_data = 0;
#ifndef INTERNAL_LS
if (anonymous && dolreplies)
else
#else
#endif
}
}
= {
if (log_commands)
retrieve_is_data = 0;
#ifndef INTERNAL_LS
if (anonymous && dolreplies)
else
#else
ls($4, 0);
#endif
}
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
statfilecmd($4);
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
if ($2)
statcmd();
}
= {
if (log_commands)
delete($4);
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
if (fromname) {
}
else {
}
}
if ($4)
free($4);
}
= {
if (log_commands)
if ($2)
}
= {
if (log_commands)
}
= {
if (log_commands)
cwd($4);
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
if ($2)
}
= {
register char *cp = (char *) $4;
if (log_commands)
if ($2)
if (*cp == ' ')
cp++;
if (*cp)
else
}
else
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
if ($2)
}
= {
if (log_commands)
makedir($4);
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
removedir($4);
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
if ($2)
pwd();
}
= {
if (log_commands)
if ($2)
if (!test_restriction(".."))
cwd("..");
else
ack("CWD");
}
= {
if (log_commands)
if ($2)
}
= {
if (log_commands)
if ($2)
if ($6 != NULL)
free($6);
}
= {
if (log_commands)
if ($2) {
}
}
= {
int ok = 1;
if (log_commands)
if ($2) {
/* check for umask permission */
if (type_match(ARG1))
if (*ARG0 == 'n')
ok = 0;
}
if (ok && !restricted_user) {
if (($6 < 0) || ($6 > 0777)) {
}
else {
}
}
else
}
}
= {
if (log_commands)
if ($2 && $8) {
/* check for chmod permission */
if (type_match(ARG1))
if (anonymous) {
if (*ARG0 == 'y')
ok = 1;
}
else if (*ARG0 == 'n')
ok = 0;
}
if (ok) {
#ifdef UNRESTRICTED_CHMOD
#else
if (($6 < 0) || ($6 > 0777))
reply(501,
"CHMOD: Mode value must be between 0 and 0777");
#endif
else {
char path[MAXPATHLEN];
if (log_security)
if (anonymous) {
}
else {
remoteident, path);
}
}
}
else
}
if ($8 != NULL)
free($8);
}
= {
if (log_commands)
if ($2)
reply(200,
"Current IDLE time limit is %d seconds; max %d",
}
= {
if (log_commands)
if ($2)
reply(501,
"Maximum IDLE time must be between 30 and %d seconds",
}
else {
timeout_idle = $6;
}
}
= {
#ifndef NO_PRIVATE
if (log_commands)
priv_group($6);
free($6);
#endif /* !NO_PRIVATE */
}
= {
#ifndef NO_PRIVATE
if (log_commands)
priv_gpass($6);
free($6);
#endif /* !NO_PRIVATE */
}
= {
#ifndef NO_PRIVATE
if (log_commands)
if (!restricted_user && $2)
#endif /* !NO_PRIVATE */
}
= {
if (log_commands)
#ifdef SITE_NEWER
#else
#endif
free($6);
}
= {
if (log_commands)
CHECKNULL($8));
#ifdef SITE_NEWER
#else
#endif
free($6);
if ($8)
free($8);
}
= {
if (log_commands)
#ifdef SITE_NEWER
#else
#endif
free($6);
}
= {
if (log_commands)
CHECKNULL($8));
#ifdef SITE_NEWER
#else
#endif
free($6);
if ($8)
free($8);
}
= {
/* this is just for backward compatibility since we
* thought of INDEX before we thought of EXEC
*/
char buf[MAXPATHLEN];
}
}
if ($6 != NULL)
free($6);
}
= {
(void) site_exec((char *) $6);
}
if ($6 != NULL)
free($6);
}
= {
char *default_filename = "ftp";
if (log_commands)
}
= {
if (log_commands)
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
if ($2)
#ifdef BSD
#else
#endif /* BSD */
}
/*
* SIZE is not in RFC959, but Postel has blessed it and
* it will be in the updated RFC.
*
* Return size of file in a format suitable for
* using with RESTART (we just count bytes).
*/
= {
if (log_commands)
sizecmd($4);
}
if ($4 != NULL)
free($4);
}
/*
* MDTM is not in RFC959, but Postel has blessed it and
* it will be in the updated RFC.
*
* Return modification time of file as an ISO 3307
* style time. E.g. YYYYMMDDHHMMSS or YYYYMMDDHHMMSS.xxx
* where xxx is the fractional second (of any precision,
* not necessarily 3 digits)
*/
= {
if (log_commands)
$4);
}
else {
register struct tm *t;
reply(213,
"%04d%02d%02d%02d%02d%02d",
}
}
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
#ifdef TRANSFER_COUNT
if (logged_in) {
lreply(221, "You have transferred %" L_FORMAT " bytes in %d files.", data_count_total, file_count_total);
lreply(221, "Total traffic for this session was %" L_FORMAT " bytes in %d transfers.", byte_count_total, xfer_count_total);
}
#endif /* TRANSFER_COUNT */
dologout(0);
}
= {
}
;
= {
if (log_commands)
if ($2)
restart_point = 0;
if (fromname) {
}
}
free($4);
}
= {
if (log_commands)
char *endp;
if (fromname) {
}
errno = 0;
#if _FILE_OFFSET_BITS == 64
#else
#endif
". Send STORE or RETRIEVE to initiate transfer.",
}
else {
restart_point = 0;
}
}
if ($4 != NULL)
free($4);
}
= {
if (log_commands)
if ($2)
}
= {
if (log_commands)
if ($2)
alias($6);
if ($6 != NULL)
free($6);
}
= {
if (log_commands)
if ($2)
print_groups();
}
= {
if (log_commands)
if ($2)
cdpath();
}
= {
if (log_commands)
SetCheckMethod($6);
if ($6 != NULL)
free($6);
}
= {
if (log_commands)
if ($2)
}
= {
if (log_commands)
CheckSum($6);
if ($6 != NULL)
free($6);
}
= {
if (log_commands)
if ($2)
}
= {
if (log_commands)
{
int sz = 0;
#if defined(USE_GSS)
#else
#endif /* defined(USE_GSS) */
pbsz_command_issued = 1;
}
#endif /* defined(USE_TLS) || defined(USE_GSS) */
if ($3 != NULL)
free((char *)$3);
}
= {
register char *cp = (char *) $3;
if (log_commands)
/* convert to UPPER case as per RFC 2228 */
while (*cp) {
cp++;
}
#if defined(USE_GSS)
if (cur_auth_type != NULL) {
} else {
}
} else
#endif /* defined(USE_GSS) */
{
/*
* Previous auth_type did not work, clear the string.
*/
if (cur_auth_type != NULL) {
}
}
#endif /* !(defined(USE_TLS)) && !defined(USE_GSS) */
if ($3 != NULL)
free((char *)$3);
}
= {
if (log_commands)
{
if (!pbsz_command_issued) {
} else {
switch ($3) {
case PROT_P:
#if defined(USE_GSS)
#endif /* defined(USE_GSS) */
break;
case PROT_C:
#if defined(USE_GSS)
#endif /* defined(USE_GSS) */
break;
case PROT_E:
break;
case PROT_S:
#if defined(USE_GSS)
#endif /* defined(USE_GSS) */
break;
default:
}
#if defined(USE_GSS)
#endif /* defined(USE_GSS) */
}
}
#endif /* !(defined(USE_TLS) && !defined(USE_GSS)) */
}
= {
#if defined(USE_GSS)
if (log_commands)
} else
(void) gss_adat((char *)$3);
#endif
if ($3 != NULL)
free((char *)$3);
}
= {
#if defined(USE_GSS)
if (log_commands)
ccc();
#endif /* defined(USE_GSS) */
}
;
;
password: /* empty */
= {
$$ = (char *) malloc(1);
$$[0] = '\0';
}
| STRING
;
;
= {
register char *a, *p;
a = (char *) &cliaddr;
a[0] = $1;
a[1] = $3;
a[2] = $5;
a[3] = $7;
p = (char *) &cliport;
p[0] = $9;
p[1] = $11;
}
;
= {
#ifdef INET6
char *a, *p;
struct sockaddr_in6 *data_dest_sin6;
lport_error = 0;
if (epsv_all) {
lport_error = 1;
goto lport_done6;
}
if ($1 != 6) {
lport_error = 1;
goto lport_done6;
}
if (($3 != 16) || ($37 != 2)) {
lport_error = 1;
goto lport_done6;
}
a = (char *)&data_dest_sin6->sin6_addr;
a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11;
a[4] = $13; a[5] = $15; a[6] = $17; a[7] = $19;
a[8] = $21; a[9] = $23; a[10] = $25; a[11] = $27;
a[12] = $29; a[13] = $31; a[14] = $33; a[15] = $35;
p = (char *)&data_dest_sin6->sin6_port;
p[0] = $39; p[1] = $41;
#endif /* INET6 */
}
= {
#ifdef INET6
char *a, *p;
struct sockaddr_in *data_dest_sin;
lport_error = 0;
if (epsv_all) {
lport_error = 1;
goto lport_done4;
}
if ($1 != 4) {
lport_error = 1;
goto lport_done4;
}
if (($3 != 4) || ($13 != 2)) {
lport_error = 1;
goto lport_done4;
}
a = (char *)&data_dest_sin->sin_addr;
a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11;
p = (char *)&data_dest_sin->sin_port;
p[0] = $15; p[1] = $17;
#endif /* INET6 */
}
;
form_code: N
= {
$$ = FORM_N;
}
| T
= {
$$ = FORM_T;
}
| C
= {
$$ = FORM_C;
}
;
type_code: A
= {
}
= {
cmd_form = $3;
}
| E
= {
}
= {
cmd_form = $3;
}
| I
= {
}
| L
= {
cmd_bytesz = NBBY;
}
= {
cmd_bytesz = $3;
}
/* this is for a bug in the BBN ftp */
| L byte_size
= {
cmd_bytesz = $2;
}
;
prot_code: C
= {
#if defined(USE_GSS)
$$ = PROT_C;
#endif
}
| P
= {
#if defined(USE_GSS)
$$ = PROT_P;
#endif
}
| S
= {
#if defined(USE_GSS)
$$ = PROT_S;
#endif
}
| E
= {
#if defined(USE_GSS)
$$ = PROT_E;
#endif
}
;
struct_code: F
= {
$$ = STRU_F;
}
| R
= {
$$ = STRU_R;
}
| P
= {
$$ = STRU_P;
}
;
mode_code: S
= {
$$ = MODE_S;
}
| B
= {
$$ = MODE_B;
}
| C
= {
$$ = MODE_C;
}
;
= {
/*
* Problem: this production is used for all pathname
* processing, but only gives a 550 error reply.
* This is a valid reply in some cases but not in others.
*/
/*
* This remaps the root so it is appearently at the user's home
*/
char **globlist;
if (t == NULL) {
$$ = NULL;
}
else {
t[0] = '~';
t[1] = '\0';
if (globerr) {
$$ = NULL;
if (globlist) {
}
}
$$ = *globlist;
}
else {
if (globlist) {
}
$$ = NULL;
}
free(t);
}
free($1);
}
char **globlist;
if (globerr) {
$$ = NULL;
if (globlist) {
}
}
$$ = *globlist;
}
else {
if (globlist) {
}
$$ = NULL;
}
free($1);
}
else
$$ = $1;
}
;
;
;
= {
/*
* Convert a number that was read as decimal number
* to what it would be if it had been read as octal.
*/
dec = $1;
multby = 1;
ret = 0;
while (dec) {
if (digit > 7) {
ret = -1;
break;
}
multby *= 8;
dec /= 10;
}
$$ = ret;
}
;
check_login: /* empty */
= {
if (logged_in)
$$ = 1;
else {
if (log_commands)
$$ = 0;
yyerrorcalled = 1;
}
}
;
%%
#define CMD 0 /* beginning of command */
{ /* In order defined in RFC 765 */
#ifdef INET6
#endif
#if defined(USE_GSS)
#endif
#endif /* defined(USE_TLS) || defined(USE_GSS) */
{NULL, 0, 0, 0, 0}
};
{
{NULL, 0, 0, 0, 0}
};
{
return (p);
return (0);
}
/*
* getline - a hacked up version of fgets to ignore TELNET escape codes.
*/
{
register int c;
register char *cs;
char *passtxt = "PASS password\r\n";
cs = s;
/* tmpline may contain saved command from urgent mode interruption */
for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
if (tmpline[c] == '\n') {
*cs++ = '\0';
if (debug) {
else
}
tmpline[0] = '\0';
return (s);
}
if (c == 0)
tmpline[0] = '\0';
}
#ifdef TRANSFER_COUNT
#endif
c &= 0377;
if (c == IAC) {
#ifdef TRANSFER_COUNT
#endif
c &= 0377;
switch (c) {
case WILL:
case WONT:
#ifdef TRANSFER_COUNT
#endif
continue;
case DO:
case DONT:
#ifdef TRANSFER_COUNT
#endif
continue;
case IAC:
break;
default:
continue; /* ignore command */
}
}
}
*cs++ = c;
if (--n <= 0 || c == '\n')
break;
}
goto retry;
return (NULL);
}
*cs++ = '\0';
#if defined(USE_GSS)
if (IS_GSSAUTH(cur_auth_type) &&
s = sec_decode_command(s);
} else if (IS_GSSAUTH(cur_auth_type) &&
if (debug)
*s = '\0';
return(s);
}
#endif /* USE_GSS */
if (debug) {
else
}
return (s);
}
static void toolong(int a) /* signal that caused this function to be called */
{
reply(421,
"Timeout (%d seconds): closing control connection.", timeout_idle);
if (logging) {
"User %s timed out after %d seconds at %.24s",
}
dologout(1);
}
int yylex(void)
{
register struct tab *p;
int n;
char c = '\0';
extern time_t limit_time;
extern time_t login_time;
for (;;) {
switch (state) {
case CMD:
yyerrorcalled = 0;
if (is_shutdown(!logged_in, 0) != 0) {
dologout(0);
}
dologout(0);
}
#ifdef IGNORE_NOOP
if (!alarm_running) {
(void) alarm((unsigned) timeout_idle);
alarm_running = 1;
}
#else
(void) alarm((unsigned) timeout_idle);
#endif
(void) alarm(0);
dologout(0);
}
#ifndef IGNORE_NOOP
(void) alarm(0);
#endif
*cp++ = '\n';
*cp = '\0';
}
if (cpos == 0)
cpos = 4;
#ifdef IGNORE_NOOP
(void) alarm(0);
alarm_running = 0;
}
#endif
*cp = '\0';
if (cp)
*cp = '\n';
}
if (p != 0) {
if (p->implemented == 0) {
/* NOTREACHED */
}
return (p->token);
}
break;
case SITECMD:
cpos++;
return (SP);
}
if (p != 0) {
#ifndef PARANOID /* what GOOD is SITE *, anyways?! _H */
if (p->implemented == 0) {
#else
if (1) {
#endif /* PARANOID */
/* NOTREACHED */
}
return (p->token);
}
break;
case OSTR:
return (CRLF);
}
/* FALLTHROUGH */
case STR1:
case ZSTR1:
cpos++;
else
++state;
return (SP);
}
break;
case ZSTR2:
return (CRLF);
}
/* FALLTHROUGH */
case STR2:
cpos += n - 1;
/*
* Make sure the string is nonempty and \n terminated.
*/
return (STRING);
}
break;
case NSTR:
cpos++;
return (SP);
}
return (NUMBER);
}
goto dostr1;
case STR3:
cpos++;
return (SP);
}
c = *cp2;
*cp2 = '\0';
}
cpos += n;
/*
* Make sure the string is nonempty and SP terminated.
*/
return (STRING);
}
break;
case ARGS:
return (NUMBER);
}
case '\n':
return (CRLF);
case ' ':
return (SP);
case ',':
return (COMMA);
case 'A':
case 'a':
return (A);
case 'B':
case 'b':
return (B);
case 'C':
case 'c':
return (C);
case 'E':
case 'e':
return (E);
case 'F':
case 'f':
return (F);
case 'I':
case 'i':
return (I);
case 'L':
case 'l':
return (L);
case 'N':
case 'n':
return (N);
case 'P':
case 'p':
return (P);
case 'R':
case 'r':
return (R);
case 'S':
case 's':
return (S);
case 'T':
case 't':
return (T);
}
break;
default:
fatal("Unknown state in scanner.");
}
if (yyerrorcalled == 0) {
*cp = '\0';
if (logged_in)
else
}
}
}
void upper(char *s)
{
while (*s != '\0') {
if (islower(*s))
*s = toupper(*s);
s++;
}
}
char *copy(char *s)
{
char *p;
p = strdup(s);
if (p == NULL)
fatal("Ran out of memory.");
return (p);
}
{
struct tab *c;
char *type;
type = "SITE ";
else
type = "";
NCMDS++;
}
if (s == 0) {
register size_t i, j, w;
type, "(* =>'s unimplemented)");
if (columns == 0)
columns = 1;
for (i = 0; i < lines; i++) {
for (j = 0; j < columns; j++) {
ptr += w;
break;
while (w < width) {
*(ptr++) = ' ';
w++;
}
}
*ptr = '\0';
}
#ifdef VIRTUAL
else
#endif
else
return;
}
upper(s);
return;
}
if (c->implemented)
else
}
{
switch (type) {
case TYPE_L:
case TYPE_I:{
else
break;
}
case TYPE_A:{
register int c;
return;
}
return;
}
count = 0;
if (c == '\n') /* will get expanded to \r\n */
count++;
count++;
}
break;
}
default:
}
}
{
#ifdef PARANOID
#else
char buf[MAXPATHLEN];
/* sanitize the command-string */
if (sp == 0) {
}
else {
}
if (isupper(*t)) {
*t = tolower(*t);
}
}
/* build the command */
return;
if (!cmdf) {
if (log_commands)
}
else {
int lines = 0;
int maxlines = 0;
int maxfound = 0;
int defmaxlines = 20;
int which;
(void) acl_getclass(class);
if (ARG1)
maxfound = 1;
}
}
else
}
if (!maxfound)
if (maxlines <= 0)
++lines;
break;
}
}
if (log_commands)
}
#endif /* PARANOID */
}
void alias(char *s)
{
if (s != (char *) NULL) {
return;
}
return;
}
}
void cdpath(void)
{
}
void print_groups(void)
{
int ngroups;
int maxgrp;
return;
}
ngroups--;
}