1 /* ftpd.c Copyright 1992-2000 by Michael Temari All Rights Reserved
3 * ftpd An FTP server program for use with Minix.
5 * Usage: Minix usage: tcpd ftp ftpd
7 * 06/14/92 Tnet Release Michael Temari
8 * 01/15/96 0.30 Michael Temari
9 * 01/25/96 0.90 Michael Temari
10 * 03/17/96 0.91 Michael Temari
11 * 06/27/96 0.92 Michael Temari
12 * 07/02/96 0.93 Michael Temari
13 * 07/15/96 0.94 Michael Temari
14 * 08/27/96 0.95 Michael Temari
15 * 02/09/97 0.96 Michael Temari
16 * 02/10/97 0.97 Michael Temari
17 * 09/25/97 0.98 Michael Temari
18 * 03/10/00 0.99 Michael Temari, <Michael@TemWare.Com>
19 * 12/12/03 1.00 Michael Temari, <Michael@TemWare.Com>
20 * 02/06/05 1.01 Michael Temari, <Michael@TemWare.Com>
21 * 02/12/05 2.00 Michael Temari, <Michael@TemWare.Com>
24 char *FtpdVersion
= "2.00";
26 #include <sys/types.h>
34 #include <net/gen/in.h>
35 #include <net/gen/tcp.h>
42 _PROTOTYPE(static void init
, (void));
43 _PROTOTYPE(static int doHELP
, (char *buff
));
44 _PROTOTYPE(static int doNOOP
, (char *buff
));
45 _PROTOTYPE(static int doUNIMP
, (char *buff
));
46 _PROTOTYPE(static int getline
, (char *line
, int len
));
48 FILE *msgfile
= (FILE *)NULL
;
50 /* The following defines the inactivity timeout in seconds */
51 #define INACTIVITY_TIMEOUT 60*5
53 char *days
[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
54 char *months
[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
55 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
59 int type
, format
, mode
, structure
;
61 int loggedin
, gotuser
, anonymous
;
66 ipaddr_t myipaddr
, rmtipaddr
, dataaddr
;
67 tcpport_t myport
, rmtport
, dataport
;
69 char myhostname
[256], rmthostname
[256];
71 #define FTPD_LOG "/usr/adm/ftpd.log"
72 #define FTPD_MSG "/etc/ftpd_msg"
78 _PROTOTYPE(static int doHELP
, (char *buff
));
79 _PROTOTYPE(int readline
, (char **args
));
80 _PROTOTYPE(void Timeout
, (int sig
));
81 _PROTOTYPE(int main
, (int argc
, char *argv
[]));
85 _PROTOTYPE(int (*func
), (char *buff
));
88 struct commands commands
[] = {
147 /* nothing, nada, zilch... */
148 static int doNOOP(buff
)
151 printf("200 NOOP to you too!\r\n");
156 /* giv'em help, what a USER! */
157 static int doHELP(buff
)
160 struct commands
*cmd
;
165 printf("214-Here is a list of available ftp commands\r\n");
166 printf(" Those with '*' are not yet implemented.\r\n");
169 for(cmd
= commands
; *cmd
->name
!= '\0'; cmd
++) {
170 if(cmd
->func
== doUNIMP
)
174 printf(" %s%c%s", cmd
->name
, star
, space
+ strlen(cmd
->name
));
184 printf("214 That's all the help you get.\r\n");
189 /* not implemented */
190 static int doUNIMP(buff
)
193 printf("502 Command \"%s\" not implemented!\r\n", line
);
198 /* convert line for use */
204 p
= line
+ strlen(line
);
206 if(*p
== '\r' || *p
== '\n' || isspace(*p
))
214 logit("COMMAND", line
);
217 while(*p
&& !isspace(*p
)) {
225 while(*p
&& isspace(*p
))
234 static int getline(line
, len
)
241 /* leave room for at end for null */
244 /* got to be able to put in at least 1 character */
250 s
= read(0, line
, 1);
255 gotcr
= (*line
== '\r');
269 if(getline(line
, sizeof(line
)))
277 /* signal handler for inactivity timeout */
283 printf("421 Inactivity timer expired.\r\n");
287 void logit(type
, parm
)
294 if(logfile
== (FILE *)NULL
)
298 tm
= localtime(&now
);
299 fprintf(logfile
, "%4d%02d%02d%02d%02d%02d ",
303 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
304 fprintf(logfile
, "%s %s %s %s %s\n",
305 rmthostname
, username
, anonymous
? anonpass
: username
, type
, parm
);
309 void showmsg(reply
, filename
)
315 static char mline
[256];
317 if(filename
== (char *)NULL
)
320 mfp
= fopen(filename
, "r");
322 if(mfp
== (FILE *)NULL
)
325 while(fgets(mline
, sizeof(mline
), mfp
) != (char *)NULL
) {
326 pe
= mline
+ strlen(mline
);
328 if(*pe
== '\r' || *pe
== '\n')
332 printf("%s- %s\r\n", reply
, mline
);
335 if(filename
!= (char *)NULL
)
343 struct commands
*cmd
;
352 /* open transfer log file if it exists */
353 if((logfile
= fopen(FTPD_LOG
, "r")) != (FILE *)NULL
) {
355 logfile
= fopen(FTPD_LOG
, "a");
358 /* open login msg file */
359 msgfile
= fopen(FTPD_MSG
, "r");
361 /* Let's initialize some stuff */
364 /* Log the connection */
365 logit("CONNECT", "");
367 /* Tell 'em we are ready */
369 tm
= localtime(&now
);
370 printf("220 FTP service (Ftpd %s) ready on %s at ",
371 FtpdVersion
, myhostname
);
372 printf("%s, %02d %s %d %02d:%02d:%02d %s\r\n", days
[tm
->tm_wday
],
373 tm
->tm_mday
, months
[tm
->tm_mon
], 1900+tm
->tm_year
,
374 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
,
375 tzname
[tm
->tm_isdst
]);
378 /* Loop here getting commands */
380 signal(SIGALRM
, Timeout
);
381 alarm(INACTIVITY_TIMEOUT
);
382 if(readline(&args
) != GOOD
) {
384 printf("221 Control connection closing (EOF).\r\n");
388 for(cmd
= commands
; *cmd
->name
!= '\0'; cmd
++)
389 if(!strcmp(line
, cmd
->name
))
391 if(*cmd
->name
!= '\0')
392 status
= (*cmd
->func
)(args
);
394 printf("500 Command \"%s\" not recognized.\r\n", line
);