首先下载下嵌入式linux服务器资源,linux-ftpd-0.17.tar.gz
下面我们将开始制作嵌入式linux下ftp服务器
1、解压资源
tar xvzf linux-ftpd-0.17.tar.gz
2、修改configure文件
vi configure,内容如下:
#!/bin/sh
#
# This file was generated by confgen version 2.
# Do not edit.
#
PREFIX='/usr'
#EXECPREFIX='$PREFIX'
INSTALLROOT=''
BINMODE='755'
#DAEMONMODE='$BINMODE'
MANMODE='644'
while [ x$1 != x ]; do case $1 in
--help)
cat <<EOF
Usage: configure [options]
--help Show this message
--with-debug Enable debugging
--without-shadow Disable shadow password support
--prefix=path Prefix for location of files [/usr]
--exec-prefix=path Location for arch-depedent files [prefix]
--installroot=root Top of filesystem tree to install in [/]
--binmode=mode Mode for binaries [755]
--daemonmode=mode Mode for daemon binaries [same as binmode]
--manmode=mode Mode for manual pages [644]
--with-c-compiler=cc Program for compiling C source [guessed]
EOF
exit 0;;
--verbose) ;;
--quiet) ;;
--subdir) . ../configure.defs;;
--with-debug|--debug) DEBUG=1;;
--prefix=*) PREFIX=`echo $1 | sed 's/^[^=]*=//'` ;;
--exec-prefix=*) EXECPREFIX=`echo $1 | sed 's/^[^=]*=//'` ;;
--installroot=*) INSTALLROOT=`echo $1 | sed 's/^[^=]*=//'` ;;
--binmode=*) BINMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
--daemonmode=*) DAEMONMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
--manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
--with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;;
--without-shadow|--disable-shadow) WITHOUT_SHADOW=1;;
*) echo "Unrecognized option: $1"; exit 1;;
esac
shift
done
上面我们能够清晰的看见configure的各个参数及作用,这里我不详细介绍各个参数的作用,这里我们如果想将ftpd服务器移植到嵌入式linux操作系统中,需要关注的主要是三个参数,分别是:prefix,installroot,with-c-compiler,其中prefix为installroot(文件系统根目录)目录下的具体目录,这里为什么需要将其与intallroot变量分开,主要是因为后续安装ftpd服务器时需要传递几个文件,所以需要根文件系统传递几个参数。
prefix:这里的值我们不用修改,一般ftpd被安装到文件系统目录下的/usr/sbin中
intallroot:文件系统的根目录,这里设置为/XXX/rootfs
with-c-compiler:交叉编译器的选择,嵌入式linux肯定是arm-linux-gcc,(在传递交叉编译工具时,如果文件中这样添加WITH-C-COMPILER='arm-linux-gcc',好像会报错,所
以我没直接在文件中传递这个参数,希望有大神能指点下为什么)
这是我们运行./configure --with-c-compiler=arm-linux-gcc尝试配置下,结果出现如下信息:
Directories: /usr/sbin /usr/man
Checking if C compiler works... no
Compiler arm-linux-gcc does not exist or cannot compile C; try another.
分析发现,我们传递的arm-linux-gcc出错,可是我的arm-linux-gcc编译内核都没问题,应该不会少文件,估计时configure文件内有错误,打开configure文件,找到错误信息
比对发现:
$CC __conftest.c -o __conftest || exit 1
./__conftest || exit 1
./__conftest肯定不能再linux下运行啊,所以果断将该文件中的./__conftest全部删除,总共8处。
继续运行./configure --with-c-compiler=arm-linux-gcc,这次输出信息Ok:
Directories: /usr/sbin /usr/man
Checking if C compiler works... yes
Checking if arm-linux-gcc accepts gcc warnings... yes
Checking if arm-linux-gcc accepts -O2... yes
Checking for yacc... bison -y
Checking for BSD signal semantics... yes
Checking for shadow... yes
Checking for crypt... -lcrypt
Checking for socklen_t... yes
Checking for snprintf declaration... ok
Checking for snprintf implementation... ok
Generating MCONFIG...
3、接下来我们开始编译
make,结果还是报错,
ftpcmd.y:108: error: array type has incomplete element type
ftpcmd.y:109: error: array type has incomplete element type
ftpcmd.y: In function 'yylex':
ftpcmd.y:1055: warning: cast discards qualifiers from pointer target type
ftpcmd.y:1081: warning: cast discards qualifiers from pointer target type
make[1]: *** [ftpcmd.o] Error 1
make[1]: Leaving directory `/GT2440/linux-ftpd-0.17/ftpd'
查看出错文件,vim ftpd/ftpcmd.y
发现这块应该是tab结构体定义文件,将该文件中822行开始的结构体定义放到代码前面,ok。
1 /*
2 * Copyright (c) 1985, 1988, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)ftpcmd.y 8.3 (Berkeley) 4/6/94
34 * NetBSD: ftpcmd.y,v 1.7 1996/04/08 19:03:11 jtc Exp
35 * OpenBSD: ftpcmd.y,v 1.16 1998/05/22 06:46:09 deraadt Exp
36 */
37
38 /*
39 * Grammar for FTP commands.
40 * See RFC 959.
41 */
42
43 %{
44
45 char ftpcmd_rcsid[] =
46 "$Id: ftpcmd.y,v 1.11 1999/10/09 02:32:12 dholland Exp $";
47
48 #include <sys/param.h>
49 #include <sys/socket.h>
50 #include <sys/stat.h>
51
52 #include <netinet/in.h>
53 #include <arpa/ftp.h>
54
55 #include <ctype.h>
56 #include <errno.h>
57 #include <glob.h>
58 #include <pwd.h>
59 #include <setjmp.h>
60 #include <signal.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 #include <syslog.h>
65 #include <time.h>
66 #include <unistd.h>
67
68 #ifndef __linux__
69 #include <tzfile.h>
70 #else
71 #define TM_YEAR_BASE 1900
72 #endif
73
74 #include "extern.h"
75
76 extern struct sockaddr_in data_dest;
77 extern int logged_in;
78 extern struct passwd *pw;
79 extern int guest;
80 extern int logging;
81 extern int type;
82 extern int form;
83 extern int debug;
84 extern int timeout;
85 extern int maxtimeout;
86 extern int pdata;
87 extern char hostname[], remotehost[];
88 extern char proctitle[];
89 extern int usedefault;
90 extern int transflag;
91 extern char tmpline[];
92 extern int portcheck;
93 extern struct sockaddr_in his_addr;
94
95 off_t restart_point;
96
97 static int cmd_type;
98 static int cmd_form;
99 static int cmd_bytesz;
100 char cbuf[512];
101 char *fromname;
102
103 struct tab;
104 static int yylex __P((void));
105 static void sizecmd __P((char *));
106 static void help __P((struct tab *, char *));
107 %}
108
109 %union {
110 int i;
111 char *s;
112 }
113
114 %token
115 A B C E F I
116 L N P R S T
117
118 SP CRLF COMMA
119
120 USER PASS ACCT REIN QUIT PORT
121 PASV TYPE STRU MODE RETR STOR
122 APPE MLFL MAIL MSND MSOM MSAM
123 MRSQ MRCP ALLO REST RNFR RNTO
124 ABOR DELE CWD LIST NLST SITE
125 STAT HELP NOOP MKD RMD PWD
126 CDUP STOU SMNT SYST SIZE MDTM
127
128 UMASK IDLE CHMOD
129
130 LEXERR
131
132 %token <s> STRING
133 %token <i> NUMBER
134
135 %type <i> check_login octal_number byte_size
136 %type <i> struct_code mode_code type_code form_code
137 %type <s> pathstring pathname password username
138 %type <i> host_port
139
140 %start cmd_list
141
142 %{
143 extern jmp_buf errcatch;
144
145 #define CMD 0 /* beginning of command */
146 #define ARGS 1 /* expect miscellaneous arguments */
147 #define STR1 2 /* expect SP followed by STRING */
148 #define STR2 3 /* expect STRING */
149 #define OSTR 4 /* optional SP then STRING */
150 #define ZSTR1 5 /* SP then optional STRING */
151 #define ZSTR2 6 /* optional STRING after SP */
152 #define SITECMD 7 /* SITE command */
153 #define NSTR 8 /* Number followed by a string */
154
155 struct tab {
156 const char *name;
157 short token;
158 short state;
159 short implemented; /* 1 if command is implemented */
160 const char *help;
161 };
162
163 struct tab cmdtab[] = { /* In order defined in RFC 765 */
164 { "USER", USER, STR1, 1, "<sp> username" },
165 { "PASS", PASS, ZSTR1, 1, "<sp> password" },
166 { "ACCT", ACCT, STR1, 0, "(specify account)" },
167 { "SMNT", SMNT, ARGS, 0, "(structure mount)" },
168 { "REIN", REIN, ARGS, 0, "(reinitialize server state)" },
169 { "QUIT", QUIT, ARGS, 1, "(terminate service)", },
170 { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" },
171 { "PASV", PASV, ARGS, 1, "(set server in passive mode)" },
172 { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" },
173 { "STRU", STRU, ARGS, 1, "(specify file structure)" },
174 { "MODE", MODE, ARGS, 1, "(specify transfer mode)" },
175 { "RETR", RETR, STR1, 1, "<sp> file-name" },
176 { "STOR", STOR, STR1, 1, "<sp> file-name" },
177 { "APPE", APPE, STR1, 1, "<sp> file-name" },
178 { "MLFL", MLFL, OSTR, 0, "(mail file)" },
179 { "MAIL", MAIL, OSTR, 0, "(mail to user)" },
180 { "MSND", MSND, OSTR, 0, "(mail send to terminal)" },
181 { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" },
182 { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" },
183 { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" },
184 { "MRCP", MRCP, STR1, 0, "(mail recipient)" },
185 { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" },
186 { "REST", REST, ARGS, 1, "<sp> offset (restart command)" },
187 { "RNFR", RNFR, STR1, 1, "<sp> file-name" },
188 { "RNTO", RNTO, STR1, 1, "<sp> file-name" },
189 { "ABOR", ABOR, ARGS, 1, "(abort operation)" },
190 { "DELE", DELE, STR1, 1, "<sp> file-name" },
191 { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
192 { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
193 { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" },
194 { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" },
195 { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" },
196 { "SYST", SYST, ARGS, 1, "(get type of operating system)" },
197 { "STAT", STAT, OSTR, 1, "[ <sp> path-name ]" },
198 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
199 { "NOOP", NOOP, ARGS, 1, "" },
200 { "MKD", MKD, STR1, 1, "<sp> path-name" },
201 { "XMKD", MKD, STR1, 1, "<sp> path-name" },
202 { "RMD", RMD, STR1, 1, "<sp> path-name" },
203 { "XRMD", RMD, STR1, 1, "<sp> path-name" },
204 { "PWD", PWD, ARGS, 1, "(return current directory)" },
205 { "XPWD", PWD, ARGS, 1, "(return current directory)" },
206 { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" },
207 { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" },
208 { "STOU", STOU, STR1, 1, "<sp> file-name" },
209 { "SIZE", SIZE, OSTR, 1, "<sp> path-name" },
210 { "MDTM", MDTM, OSTR, 1, "<sp> path-name" },
211 { NULL, 0, 0, 0, 0 }
212 };
213
214 struct tab sitetab[] = {
215 { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
216 { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
217 { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
218 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
219 { NULL, 0, 0, 0, 0 }
220 };
221 extern struct tab cmdtab[];
222 extern struct tab sitetab[];
223
224 %}
重新编译,没有错误
4、安装ftpd,直接将ftpd拷贝到根文件系统目录下的/usr/sbin中,然后配置启动文件
在etc目录下的init.d/rcS文件中,添加如下内容:
# These are standard services.
#
ftpstreamtcpnowaitroot/usr/sbin/ftpd/usr/sbin/ftpd
#telnetstreamtcpnowaitroot/usr/sbin/telnetd/usr/sbin/telnetd -i
修改/etc/passwd文件,添加如下内容:
root::0:0:root:/:/bin/sh
ftp::14:50:FTP User:/var/ftp:
bin:*:1:1:bin:/bin:
daemon:*:2:2:daemon:/sbin:
nobody:*:99:99:Nobody:/:
plg:$1$wwtsqwnk$sWaEJGcJFTqaCW18sbUK7/:502:502:Linux User,,,:/home/plg:/bin/sh
但是,发现启动ftp服务后,需要挺长时间才能登陆上。因此推荐大家还是使用vsftpd-2.3.4,感觉比ftpd好用。
VSftpd-2.3.4使用:http://blog.csdn.net/alan00000/article/details/7194702