?? ftpcmd_y.txt
字號:
/* $OpenBSD: ftpcmd.y,v 1.50 2008/06/30 12:03:51 ragge Exp $ */
/* $NetBSD: ftpcmd.y,v 1.7 1996/04/08 19:03:11 jtc Exp $ */
/*
* Copyright (c) 1985, 1988, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. 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.
*
* @(#)ftpcmd.y 8.3 (Berkeley) 4/6/94
*/
/*
* Grammar for FTP commands.
* See RFC 959.
*/
%{
#ifndef lint
#if 0
static const char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
#else
static const char rcsid[] =
"$OpenBSD: ftpcmd.y,v 1.50 2008/06/30 12:03:51 ragge Exp $";
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/ftp.h>
#include <ctype.h>
#include <errno.h>
#include <glob.h>
#include <pwd.h>
#include <signal.h>
#include <tzfile.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <netdb.h>
#include "monitor.h"
#include "extern.h"
extern union sockunion 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[];
extern int portcheck;
extern union sockunion his_addr;
extern int umaskchange;
off_t restart_point;
static int cmd_type;
static int cmd_form;
static int cmd_bytesz;
static int state;
static int quit;
char cbuf[512];
char *fromname;
%}
%union {
int i;
char *s;
}
%token
A B C E F I
L N P R S T
SP CRLF COMMA ALL
USER PASS ACCT REIN QUIT PORT
PASV TYPE STRU MODE RETR STOR
APPE MLFL MAIL MSND MSOM MSAM
MRSQ MRCP ALLO REST RNFR RNTO
ABOR DELE CWD LIST NLST SITE
STAT HELP NOOP MKD RMD PWD
CDUP STOU SMNT SYST SIZE MDTM
LPRT LPSV EPRT EPSV
UMASK IDLE CHMOD
LEXERR
%token <s> STRING
%token <i> NUMBER
%type <i> check_login check_login_epsvall octal_number byte_size
%type <i> struct_code mode_code type_code form_code
%type <s> pathstring pathname password username
%type <i> host_port host_long_port4 host_long_port6
%start cmd_list
%%
cmd_list
: /* empty */
| cmd_list cmd
{
if (fromname) {
free(fromname);
fromname = NULL;
}
restart_point = (off_t) 0;
}
| cmd_list rcmd
;
cmd
: USER SP username CRLF
{
monitor_user($3);
free($3);
}
| PASS SP password CRLF
{
quit = monitor_pass($3);
memset($3, 0, strlen($3));
free($3);
/* Terminate unprivileged pre-auth slave */
if (quit)
_exit(0);
}
| PORT check_login_epsvall SP host_port CRLF
{
if ($2) {
if ($4) {
usedefault = 1;
reply(500,
"Illegal PORT rejected (range errors).");
} else if (portcheck &&
ntohs(data_dest.su_sin.sin_port) < IPPORT_RESERVED) {
usedefault = 1;
reply(500,
"Illegal PORT rejected (reserved port).");
} else if (portcheck &&
memcmp(&data_dest.su_sin.sin_addr,
&his_addr.su_sin.sin_addr,
sizeof data_dest.su_sin.sin_addr)) {
usedefault = 1;
reply(500,
"Illegal PORT rejected (address wrong).");
} else {
usedefault = 0;
if (pdata >= 0) {
(void) close(pdata);
pdata = -1;
}
reply(200, "PORT command successful.");
}
}
}
| LPRT check_login_epsvall SP host_long_port4 CRLF
{
if ($2) {
/* reject invalid host_long_port4 */
if ($4) {
reply(500,
"Illegal LPRT command rejected");
usedefault = 1;
} else {
usedefault = 0;
if (pdata >= 0) {
(void) close(pdata);
pdata = -1;
}
reply(200, "LPRT command successful.");
}
}
}
| LPRT check_login_epsvall SP host_long_port6 CRLF
{
if ($2) {
/* reject invalid host_long_port6 */
if ($4) {
reply(500,
"Illegal LPRT command rejected");
usedefault = 1;
} else {
usedefault = 0;
if (pdata >= 0) {
(void) close(pdata);
pdata = -1;
}
reply(200, "LPRT command successful.");
}
}
}
| EPRT check_login_epsvall SP STRING CRLF
{
if ($2)
extended_port($4);
free($4);
}
| PASV check_login_epsvall CRLF
{
if ($2)
passive();
}
| LPSV check_login_epsvall CRLF
{
if ($2)
long_passive("LPSV", PF_UNSPEC);
}
| EPSV check_login SP NUMBER CRLF
{
if ($2)
long_passive("EPSV", epsvproto2af($4));
}
| EPSV check_login SP ALL CRLF
{
if ($2) {
reply(200, "EPSV ALL command successful.");
epsvall++;
}
}
| EPSV check_login CRLF
{
if ($2)
long_passive("EPSV", PF_UNSPEC);
}
| TYPE check_login SP type_code CRLF
{
if ($2) {
switch (cmd_type) {
case TYPE_A:
if (cmd_form == FORM_N) {
reply(200, "Type set to A.");
type = cmd_type;
form = cmd_form;
} else
reply(504, "Form must be N.");
break;
case TYPE_E:
reply(504, "Type E not implemented.");
break;
case TYPE_I:
reply(200, "Type set to I.");
type = cmd_type;
break;
case TYPE_L:
if (cmd_bytesz == 8) {
reply(200,
"Type set to L (byte size 8).");
type = cmd_type;
} else
reply(504, "Byte size must be 8.");
}
}
}
| STRU check_login SP struct_code CRLF
{
if ($2) {
switch ($4) {
case STRU_F:
reply(200, "STRU F ok.");
break;
default:
reply(504, "Unimplemented STRU type.");
}
}
}
| MODE check_login SP mode_code CRLF
{
if ($2) {
switch ($4) {
case MODE_S:
reply(200, "MODE S ok.");
break;
default:
reply(502, "Unimplemented MODE type.");
}
}
}
| ALLO check_login SP NUMBER CRLF
{
if ($2) {
reply(202, "ALLO command ignored.");
}
}
| ALLO check_login SP NUMBER SP R SP NUMBER CRLF
{
if ($2) {
reply(202, "ALLO command ignored.");
}
}
| RETR check_login SP pathname CRLF
{
if ($2 && $4 != NULL)
retrieve(NULL, $4);
if ($4 != NULL)
free($4);
}
| STOR check_login SP pathname CRLF
{
if ($2 && $4 != NULL)
store($4, "w", 0);
if ($4 != NULL)
free($4);
}
| APPE check_login SP pathname CRLF
{
if ($2 && $4 != NULL)
store($4, "a", 0);
if ($4 != NULL)
free($4);
}
| NLST check_login CRLF
{
if ($2)
send_file_list(".");
}
| NLST check_login SP STRING CRLF
{
if ($2 && $4 != NULL)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -