]> git.sesse.net Git - betaftpd/blob - ftpd.c
Updated documentation to tell that root can't FTP anymore.
[betaftpd] / ftpd.c
1 /*  ftpd.c: BetaFTPD main
2     Copyright (C) 1999-2000 Steinar H. Gunderson
3
4     This program is is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License, version 2 if the
6     License as published by the Free Software Foundation.
7
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12
13     You should have received a copy of the GNU General Public License
14     along with this program; if not, write to the Free Software
15     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18 /*
19  * Special note: this file has been overwritten by another (0-byte) file, been
20  * through the dead, and restored (with the help of dd, grep, gpm, vi and less)
21  * with a sucess rate of 99.9%. Show it a little respect -- don't add junk
22  * to it. :-)
23  */
24
25 #define _GNU_SOURCE
26
27 #if HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #if HAVE_SYS_TYPES_H
32 #include <sys/types.h>
33 #endif
34
35 #if HAVE_ERRNO_H
36 #include <errno.h>
37 #endif
38
39 #if HAVE_STROPTS_H
40 #include <stropts.h>
41 #endif
42
43 #if HAVE_SYS_CONF_H
44 #include <sys/conf.h>
45 #endif
46
47 #if HAVE_FCNTL_H
48 #include <fcntl.h>
49 #endif
50
51 #if HAVE_STDIO_H
52 #include <stdio.h>
53 #endif
54
55 #if HAVE_ASSERT_H
56 #include <assert.h>
57 #endif
58
59 #if HAVE_STRING_H
60 #include <string.h>
61 #endif
62
63 #if HAVE_STRINGS_H
64 #include <strings.h>
65 #endif
66
67 #if HAVE_STDARG_H
68 #include <stdarg.h>
69 #endif
70
71 #if HAVE_STDLIB_H
72 #include <stdlib.h>
73 #endif
74
75 #if HAVE_UNISTD_H
76 #include <unistd.h>
77 #endif
78
79 #if HAVE_NETINET_IN_H
80 #include <netinet/in.h>
81 #endif
82
83 #if HAVE_ARPA_INET_H
84 #include <arpa/inet.h>
85 #endif
86
87 #if HAVE_SYS_STAT_H
88 #include <sys/stat.h>
89 #endif
90
91 #if HAVE_SYS_SOCKET_H
92 #include <sys/socket.h>
93 #endif
94
95 #if HAVE_SYS_IOCTL_H
96 #include <sys/ioctl.h>
97 #endif
98
99 #if HAVE_NETINET_IN_SYSTM_H
100 #include <netinet/in_systm.h>
101 #endif
102
103 #if HAVE_NETINET_IP_H
104 #include <netinet/ip.h>
105 #endif
106
107 #if HAVE_NETINET_TCP_H
108 #include <netinet/tcp.h>
109 #endif
110
111 #if HAVE_LINUX_SOCKET_H
112 #include <linux/socket.h>
113 #endif
114
115 #if HAVE_MMAP
116 #include <sys/mman.h>
117 #endif
118
119 #if HAVE_TIME_H
120 #include <time.h>
121 #endif
122
123 #if HAVE_SYS_TIME_H
124 #include <sys/time.h>
125 #endif
126
127 #if HAVE_SYS_TIME_H
128 #include <sys/time.h>
129 #endif
130
131 #if HAVE_SYS_FILIO_H
132 #include <sys/filio.h>
133 #endif
134
135 #if HAVE_NETDB_H
136 #include <netdb.h>
137 #endif
138
139 #if HAVE_SIGNAL_H
140 #include <signal.h>
141 #endif
142
143 #if HAVE_GLOB_H
144 #include <glob.h>
145 #endif
146
147 #if HAVE_SYS_SIGNAL_H
148 #include <sys/signal.h>
149 #endif
150
151 #if HAVE_SYS_POLL_H
152 #include <sys/poll.h>
153 #endif
154
155 #if HAVE_SYS_SENDFILE_H
156 #include <sys/sendfile.h>
157 #endif
158
159 /*
160  * <linux/socket.h> does not export this to glibc2 systems, and it isn't
161  * always defined anywhere else.
162  */
163 #if !defined(TCP_CORK) && defined(__linux__)
164 #define TCP_CORK 3
165 #endif
166
167 #include <ftpd.h>
168 #include <cmds.h>
169
170 #if WANT_ASCII
171 #include <ascii.h>
172 #endif
173
174 /* Debug printing -- remove before 0.0.8 final */
175 #if 1
176 #define DPRINT(s)
177 #else
178 #define DPRINT(s) printf s 
179 #endif
180
181 #ifndef MAP_FAILED
182 #define MAP_FAILED -1
183 #endif
184
185 struct conn *first_conn = NULL;
186 struct ftran *first_ftran = NULL;
187 #if WANT_DCACHE
188 struct dcache *first_dcache = NULL;
189 #endif
190
191 #if HAVE_POLL
192 unsigned int highest_fds = 0;
193
194 #define FD_MAX 1024
195 #define fds_send fds
196 struct pollfd fds[FD_MAX];
197
198 #define MAXCLIENTS FD_MAX
199 #else
200 fd_set master_fds, master_send_fds;
201 #define MAXCLIENTS FD_SETSIZE
202 #endif
203
204 #if WANT_XFERLOG
205 FILE *xferlog = NULL;
206 #endif
207
208 /*
209  * This variable specifies if it's soon time to check for timed out
210  * clients, and timed out directory listing cache entries. It is
211  * set to 1 by a signal handler every minute, and set to 0 when the
212  * checking has been performed.
213  */
214 int time_to_check = 1;
215
216 #ifndef HAVE_SPRINTF
217 /*
218  * snprintf():  snprintf() replacement for systems that miss it. Note
219  *              that this implementation does _not_ necessarily protect
220  *              against all buffer overflows. Get a real snprintf() in
221  *              your C library. That being said, the 8k limit is
222  *              substantially larger than any other string in BetaFTPD,
223  *              which should make such an attack harder.
224  */
225 int snprintf(char *str, size_t n, const char *format, ...)
226 {
227         char buf[8192];
228         va_list args;
229         int err;
230
231         va_start(args, format);
232         err = vsprintf(buf, format, args);
233         va_end(args);
234
235         buf[(int)n] = 0;
236         strcpy(str, buf);
237
238         return err;
239 }
240 #endif
241
242 #ifndef HAVE_VSNPRINTF
243 /*
244  * vsnprintf:   vsnprintf() replacement for systems that miss it. Please
245  *              see snprintf (above) for more information.
246  */
247 int vsnprintf(char *str, size_t n, const char *format, va_list ap)
248 {
249         char buf[8192];
250         int err;
251
252         err = vsprintf(buf, format, ap);
253         buf[(int)n] = 0;
254         strcpy(str, buf);
255         return err;
256 }
257 #endif
258
259 /*
260  * add_fd():    Add an fd to the set we monitor. Return 0 on success.
261  *              This code is shared between poll() and select() versions.
262  */
263 int add_fd(const int fd, const int events)
264 {
265         DPRINT(("add_fd(%d, %x)\n", fd, events));
266 #if HAVE_POLL
267         if (fd >= FD_MAX) {
268                 printf("add_fd(%d, %x): failed\n", fd, events);
269                 return E2BIG;
270         }
271
272         fds[fd].fd = fd;
273         fds[fd].events = events;
274         if (highest_fds < fd) 
275                 highest_fds = fd;
276 #else 
277         if (fd >= FD_SETSIZE)
278                 return E2BIG;
279         if (events & POLLIN)
280                 FD_SET(fd, &master_fds);
281         if (events & POLLOUT)
282                 FD_SET(fd, &master_send_fds);
283 #endif
284         return 0;
285 }
286
287 /*
288  * del_fd():    Close and remove an fd from the set(s) we monitor. (See also add_fd().)
289  */
290 void del_fd(const int fd)
291 {
292         DPRINT(("del_fd(%d)\n", fd));
293 #if HAVE_POLL
294         if (fd >= FD_MAX)
295                 return;
296
297         fds[fd].fd = -1;
298         fds[fd].events = 0;
299
300         /* Reduce poll()'s workload by not making it watch past end of array */
301         while ((highest_fds > 0) && (fds[highest_fds].fd == -1))
302                 highest_fds--;
303 #else 
304         if (fd >= FD_SETSIZE)
305                 return;
306         FD_CLR(fd, &master_fds);
307         FD_CLR(fd, &master_send_fds);
308 #endif
309
310         close(fd);
311 }
312
313 #if 0
314 void list_clients()
315 {
316         struct conn *c = first_conn;
317         printf("list_clients:\n");
318         while (c && c->next_conn) {
319                 c = c->next_conn;
320                 printf("list_clients: fd %d\n", c->sock);
321         }
322 }
323 #endif
324
325 /*
326  * add_to_linked_list():
327  *              Inserts an element (conn, ftran or dcache) into its linked list.
328  *              The list is placed at the beginning, right after the (bogus)
329  *              first element of the list.
330  */
331 void add_to_linked_list(struct list_element * const first,
332                         struct list_element * const elem)
333 {
334         elem->prev = first;
335
336         if (first) {
337                 elem->next = first->next;
338                 if (elem->next) elem->next->prev = elem;
339                 first->next = elem;
340         } else {
341                 /* this is the bogus head of the list */
342                 elem->next = NULL;
343         }
344 }
345
346 /*
347  * remove_from_linked_list():
348  *              Removes an element (conn, ftran or dcache) from its linked list,
349  *              then frees it.
350  */
351 void remove_from_linked_list(struct list_element * const elem)
352 {
353         if (elem->prev != NULL) elem->prev->next = elem->next;
354         if (elem->next != NULL) elem->next->prev = elem->prev;
355         free(elem);
356 }
357
358 /*
359  * alloc_new_conn():
360  *              Allocates a new control connection (type `struct conn'),
361  *              initializes it, and adds it to the linked list. The connection
362  *              operates on the socket SOCK.
363  */
364 struct conn *alloc_new_conn(const int sock)
365 {
366         const unsigned int one = 1;
367         struct conn *c = (struct conn *)(malloc(sizeof(struct conn)));
368         DPRINT(("alloc_new_conn(%d)\n", sock));
369
370         if (c == NULL) return c;
371
372         if (sock != -1) {
373                 ioctl(sock, FIONBIO, &one);
374                 if (add_fd(sock, POLLIN) != 0) {
375                         /* temp unavail */
376                         send(sock, "230 Server too busy, please try again later.\r\n", 46, 0);
377                         close(sock);
378                         return NULL;
379                 }
380
381                 add_to_linked_list((struct list_element *)first_conn,
382                                    (struct list_element *)c);
383         } else {
384                 /* this is the bogus head of the list */
385                 c->next_conn = NULL;
386                 c->prev_conn = NULL;
387         }
388
389         c->transfer = NULL;
390         c->sock = sock;
391         c->buf_len = c->auth = c->rest_pos = 0;
392 #if WANT_ASCII
393         c->ascii_mode = 0;
394 #endif
395
396         /*
397          * equals:
398          * strcpy(c->curr_dir, "/");
399          * strcpy(c->last_cmd, "");
400          * strcpy(c->rename_from, "")
401          */
402         c->curr_dir[0] = '/';
403 #if WANT_FULLSCREEN
404         c->curr_dir[1] = c->last_cmd[0] = c->rename_from[0] = '\0';
405 #else
406         c->curr_dir[1] = c->rename_from[0] = '\0';
407 #endif
408
409         time(&(c->last_transfer));
410
411         /*list_clients();*/
412
413         return c;
414 }
415
416 /*
417  * alloc_new_ftran():
418  *              Allocates a new data connection (type `struct ftran'), and
419  *              adds it to the linked list. The connection operates on the
420  *              socket SOCK, and has the control connection C as its parent.
421  */
422 struct ftran *alloc_new_ftran(const int sock, const struct conn * const c)
423 {
424         struct ftran *f = (struct ftran *)(malloc(sizeof(struct ftran)));
425
426         if (f == NULL) return f;
427         if (c == NULL) {
428                 /* this is the bogus head of the list */
429                 f->next_ftran = NULL;
430                 f->prev_ftran = NULL;
431         } else {
432                 add_to_linked_list((struct list_element *)first_ftran,
433                                    (struct list_element *)f);
434         }
435
436 #if HAVE_MMAP
437         f->file_data = NULL;
438 #endif
439         f->owner = (struct conn * const)c;
440         f->sock = sock;
441         f->state = 0;
442         f->local_file = -1;
443
444 #if WANT_DCACHE
445         f->dir_cache = NULL;
446 #endif
447
448         f->dir_listing = 0;
449         return f;
450 }
451
452 #if WANT_DCACHE
453 /*
454  * alloc_new_dcache():
455  *              Allocates a new directory cache entry (type `struct dcache'),
456  *              and adds it to the linked list.
457  */
458 struct dcache *alloc_new_dcache()
459 {
460         struct dcache *d = (struct dcache *)(malloc(sizeof(struct dcache)));
461
462         if (d == NULL) return d;
463
464         d->use_count = 0;
465         d->last_used = 0;
466         strcpy(d->dir_name, "");
467         d->dir_data = NULL;
468
469         add_to_linked_list((struct list_element *)first_dcache,
470                            (struct list_element *)d);
471
472         return d;
473 }
474 #endif
475
476 /*
477  * destroy_conn():
478  *              Destroy a control connection, remove it from the linked
479  *              list, and clean up after it.
480  */
481 void destroy_conn(struct conn * const c)
482 {
483         DPRINT(("destroy_conn:\n"));
484         if (c == NULL) return;
485         del_fd(c->sock);
486
487         destroy_ftran(c->transfer);
488         remove_from_linked_list((struct list_element *)c);
489
490         DPRINT(("destroy_conn done.\n"));
491 }
492
493 /*
494  * destroy_ftran():
495  *              Destroy a data connection, remove it from the linked list,
496  *              and clean up after it.
497  *
498  *              For some reason, TCP_CORK (Linux 2.2.x-only) doesn't flush
499  *              even _after_ the socket is closed, so we zero it just before
500  *              closing. We also zero just before sending the last packet,
501  *              as it seems to be needed on some systems.
502  *
503  *              If you wonder why I check for `defined(SOL_TCP)' and don't
504  *              provide an alternative, see the comments on init_file_transfer().
505  */
506 void destroy_ftran(struct ftran * const f)
507 {
508         const unsigned int zero = 0;
509
510         if (f == NULL) return;
511 #if defined(TCP_CORK) && defined(SOL_TCP)
512         setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&zero, sizeof(zero));
513 #endif
514         del_fd(f->sock);
515
516 #if WANT_DCACHE
517         if (f->dir_cache) {
518                 time(&(f->dir_cache->last_used));
519                 f->dir_cache->use_count--;
520                 f->dir_cache = NULL;
521         } else
522 #endif
523 #if HAVE_MMAP
524                 if (f->file_data) {
525                         if (f->dir_listing) {
526                                 free(f->file_data);
527                                 f->file_data = NULL;
528                         } else {
529                                 munmap(f->file_data, f->size);
530                         }
531                 }
532
533         if (!f->dir_listing)
534 #endif
535                 if (f->local_file != -1) close(f->local_file);
536
537 #if !HAVE_MMAP
538         if (f->dir_listing) unlink(f->filename);
539 #endif
540
541         f->owner->transfer = NULL;
542
543 #if WANT_DCACHE
544         if (f->dir_cache != NULL) f->dir_cache->use_count--;
545 #endif
546
547         remove_from_linked_list((struct list_element *)f);
548 }
549
550 #if WANT_DCACHE
551 /*
552  * destroy_dcache():
553  *              Destroy a directory listing cache entry, remove it from the
554  *              linked list, and clean up after it.
555  *
556  *              If you free a cache entry that is in use (use_count > 0),
557  *              BetaFTPD will most likely crash (later). The thing you're supposed
558  *              to do when you're done with a dcache entry, is to decrement
559  *              its use_count, and let the timeout functions do the destroying
560  *              when it's time to do so.
561  */
562 void destroy_dcache(struct dcache * const d)
563 {
564         if (d == NULL) return;
565
566         if (d->dir_data != NULL) free(d->dir_data);
567         remove_from_linked_list((struct list_element *)d);
568 }
569 #endif
570
571 /*
572  * process_all_clients():
573  *              Processes all the control connections in active_clients
574  *              (normally returned from a select(), there are at max
575  *              NUM_AC active connections in the set), sending them
576  *              through to the command parser if a command has been
577  *              entered.
578  */
579 #if HAVE_POLL
580 int process_all_clients(const int num_ac)
581 #else
582 int process_all_clients(const fd_set * const active_clients, const int num_ac)
583 #endif
584 {
585         struct conn *c = NULL, *next = first_conn->next_conn;
586         int checked_through = 0;
587
588         DPRINT(("process_all_clients: num_ac %d\n", num_ac));
589
590         /* run through the linked list */
591         while (next != NULL && checked_through < num_ac) {
592                 int bytes_avail;
593
594                 c = next;
595                 next = c->next_conn;
596 #if HAVE_POLL
597                 if (fds[c->sock].revents & (POLLERR|POLLHUP|POLLNVAL)) {
598                         destroy_conn(c);
599                         continue;
600                 }
601                 if (!fds[c->sock].revents & POLLIN) {
602                         continue;
603                 }
604                 DPRINT(("process_all_clients: fd %d has POLLIN set\n", c->sock));
605 #else
606                 if (!FD_ISSET(c->sock, active_clients)) {
607                         continue;
608                 }
609 #endif
610
611                 checked_through++;
612
613                 bytes_avail = recv(c->sock, c->recv_buf + c->buf_len,
614                                    255 - c->buf_len, 0);
615                 if (bytes_avail <= 0) {
616                         /*
617                          * select() has already told us there's something about
618                          * this socket, so if we get a return value of zero, the
619                          * client has closed the socket. If we get a return value
620                          * of -1 (error), we close the socket ourselves.
621                          *
622                          * Just to be safe, we include this code for poll() as
623                          * well.
624                          */
625                         destroy_conn(c);
626                         continue;
627                 }
628
629                 /* overrun = disconnect */
630                 if (c->buf_len + bytes_avail > 254) {
631                         numeric(c, 503, "Buffer overrun; disconnecting.");
632                         destroy_conn(c);
633                         continue;
634                 }
635
636                 c->buf_len += bytes_avail;
637                 parse_command(c);
638         }
639         return checked_through;
640 }
641
642 /*
643  * process_all_sendfiles():
644  *              Sends data to all clients that are ready to receive it.
645  *              Also checks for data connections that are newly-connected,
646  *              and handler xferlog entries for the files that are finished.
647  */
648 #if HAVE_POLL
649 int process_all_sendfiles(const int num_ac)
650 #else
651 int process_all_sendfiles(fd_set * const active_clients, const int num_ac)
652 #endif
653 {
654         struct ftran *f = NULL, *next = first_ftran->next_ftran;
655         int checked_through = 0;
656         struct sockaddr tempaddr;
657         int tempaddr_len = sizeof(tempaddr);
658  
659         while (next != NULL && checked_through < num_ac) {
660                 f = next;
661                 next = f->next_ftran;
662
663 #if HAVE_POLL
664                 if (fds[f->sock].revents & (POLLHUP|POLLERR|POLLNVAL)) {
665                         destroy_ftran(f);
666                         continue;
667                 }
668 #endif
669
670                 /* state = 2: incoming PASV, state >3: send file */
671 #if HAVE_POLL
672                 if ((f->state < 2) || (f->state == 3) ||  (fds[f->sock].revents & (POLLIN|POLLOUT)) == 0) {
673 #else
674                 if ((f->state < 2) || (f->state == 3) || !FD_ISSET(f->sock, active_clients)) {
675 #endif
676                         continue;
677                 }
678
679                 checked_through++;
680
681 #if HAVE_POLL
682                 /* Nothing is needed for the poll() version? */
683 #else
684                 FD_CLR(f->sock, active_clients);
685 #endif
686
687                 if (f->state == 2) {            /* incoming PASV */
688                         const unsigned int one = 1;
689                         const int tempsock = accept(f->sock, (struct sockaddr *)&tempaddr,
690                                                         &tempaddr_len);
691
692                         del_fd(f->sock);
693
694                         if (tempsock == -1) {
695                                 destroy_ftran(f);
696                                 continue;
697                         }
698
699                         f->sock = tempsock;
700                         ioctl(f->sock, FIONBIO, &one);
701                         init_file_transfer(f);
702 #if WANT_UPLOAD
703                         if (f->upload) continue;
704 #endif
705                 }
706                 if (f->state < 5) {
707                         init_file_transfer(f);
708 #if WANT_UPLOAD
709                         if (f->upload) continue;
710 #endif
711                 }
712
713                 /* for download, we send the first packets right away */
714 #if WANT_UPLOAD
715                 if (f->upload) {
716                         if (do_upload(f)) continue;
717                 } else
718 #endif
719                         if (do_download(f)) continue;
720
721                 /* do_{upload,download} returned 0, the transfer is complete */
722                 numeric(f->owner, 226, "Transfer complete.");
723                 time(&(f->owner->last_transfer));
724
725 #if WANT_XFERLOG
726                 if (!f->dir_listing) {
727                         write_xferlog(f);
728                 }
729 #endif
730
731                 destroy_ftran(f);
732 #if WANT_FULLSCREEN
733                 update_display(first_conn);
734 #endif
735         }
736
737         return checked_through;
738 }
739
740 #if WANT_UPLOAD
741 int do_upload(struct ftran *f)
742 {
743         char upload_buf[16384];
744         int avail, size;
745 #if WANT_ASCII
746         /* keep buffer size small in ascii transfers 
747            to prevent process stalling while filtering
748            data on slower computers */
749
750         /* 
751          * This isn't a big problem, since we won't get
752          * packets this big anyway, the biggest I've seen
753          * was 12kB on 100mbit (but that was from a Windows
754          * machine), so I've reduced the buffer from 64 kB
755          * to 16 kB :-) --Steinar
756          */
757         const int maxlen = (f->ascii_mode == 1) ? 4096 : 16384;
758 #else
759         const int maxlen = 16384;
760 #endif
761
762         errno = 0;
763         size = recv(f->sock, upload_buf, maxlen, 0);
764         if (size >= 0) {
765                 f->pos += size;
766         }
767 #if WANT_ASCII
768         if (size > 0 && f->ascii_mode == 1) {
769                 size = ascii_uploadfilter(upload_buf, size);
770         }
771 #endif
772         if (size > 0 && (write(f->local_file, upload_buf, size) == size)) {
773                 return 1;
774         } else if (size == -1) {
775                 /* don't write xferlog... or? */
776                 numeric(f->owner, 426, strerror(errno));
777                 destroy_ftran(f);
778                 return 1;
779         }
780         return 0;
781
782 #endif
783
784 int do_download(struct ftran *f)
785 {
786 #if defined(TCP_CORK) && defined(SOL_TCP)
787         unsigned int zero = 0;
788 #endif
789         char *sendfrom_buf;
790         int bytes_to_send;
791         int more_to_send = 0;
792
793 #if !HAVE_MMAP
794         char buf[MAX_BLOCK_SIZE];
795 #endif
796 #if WANT_ASCII
797         char buf2[MAX_BLOCK_SIZE * 2];
798 #endif
799         int size;
800
801 #if HAVE_LINUX_SENDFILE
802         /*
803          * We handle the optimal case first, which is sendfile().
804          * Here we use a rather simplified sending `algorithm',
805          * leaving most of the quirks to the system calls.
806          */
807         if (f->dir_listing == 0
808 #if WANT_UPLOAD
809                 && f->upload == 0
810 #endif
811         ) {
812                 int err;
813                 size = f->size - f->pos;
814
815                 if (size > f->block_size) size = f->block_size;
816                 if (size < 0) size = 0;
817
818 #ifdef TCP_CORK
819                 if (size != f->block_size) {
820                         setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&zero, sizeof(zero));
821                 }       
822 #endif
823
824                 err = sendfile(f->sock, f->local_file, &f->pos, size);
825                 return (f->pos < f->size) && (err > -1);
826         }
827 #endif
828
829 #if HAVE_MMAP
830         size = f->size - f->pos;
831
832         if (size > f->block_size) size = f->block_size;
833         if (size < 0) size = 0;
834
835         bytes_to_send = size;
836         sendfrom_buf = f->file_data + f->pos;
837 #else
838         bytes_to_send = read(f->local_file, buf, f->block_size);
839         sendfrom_buf = buf;
840 #endif
841
842         if (bytes_to_send == f->block_size) more_to_send = 1;
843
844 #if WANT_ASCII
845         if (f->ascii_mode == 1) {
846                 bytes_to_send = ascii_downloadfilter(sendfrom_buf,
847                                                      buf2, bytes_to_send);
848                 sendfrom_buf = buf2;
849         }
850 #endif /* WANT_ASCII */
851
852 #if defined(TCP_CORK) && defined(SOL_TCP)
853         /* if we believe this is the last packet, unset TCP_CORK */
854         if (more_to_send == 0) {
855                 setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&zero, sizeof(zero));
856         }
857 #endif
858
859         size = send(f->sock, sendfrom_buf, bytes_to_send, 0);
860         if (size < bytes_to_send) more_to_send = 1;
861
862 #if WANT_ASCII
863         if (f->ascii_mode == 1 && size < bytes_to_send && size > 0) {
864                 size = ascii_findlength(sendfrom_buf, size);
865         }
866 #endif
867
868 #if HAVE_MMAP
869         if (size > 0) f->pos += size;
870 #endif
871
872         return more_to_send;
873 }
874
875 #if WANT_XFERLOG
876 void write_xferlog(struct ftran *f)
877 {
878         char temp[256];
879         time_t now = time(NULL);
880         struct tm *t = localtime(&now);
881
882         if (xferlog == NULL) return;
883
884         strftime(temp, 256, "%a %b %d %H:%M:%S %Y", t);
885 #if WANT_UPLOAD
886         fprintf(xferlog, "%s %u %s %lu %s b _ %c a %s ftp 0 * \n",
887 #else
888         fprintf(xferlog, "%s %u %s %lu %s b _ o a %s ftp 0 *\n",
889 #endif
890                 temp, (int)(difftime(now, f->tran_start)),
891                 inet_ntoa(f->sin.sin_addr), f->size,
892                 f->filename,
893 #if WANT_UPLOAD
894                 (f->upload) ? 'i' : 'o',
895 #endif
896                 f->owner->username);
897         fflush(xferlog);
898
899 #if 0
900         /* vim needs this to work properly :-( */
901         )
902 #endif
903 }
904 #endif
905
906 #if 0
907 /* Reallocate the buggers constantly */
908 void screw_clients()
909 {
910         struct conn *c = first_conn;
911         int maxloops = MAXCLIENTS;
912
913         while (c && c->next_conn) {
914                 struct conn *temp = malloc(sizeof(*temp));
915                 if (!temp) break;
916                 *temp = *(c->next_conn);
917                 if (temp->transfer) temp->transfer->owner = temp;
918                 memset(c->next_conn, 0, sizeof(struct conn));
919                 free(c->next_conn);
920                 temp->prev_conn = c;
921                 c->next_conn = temp;
922                 c = c->next_conn;
923                 maxloops--;
924                 assert(maxloops > 0);
925         }
926 }
927 #endif
928
929 /*
930  * main():      Main function. Does the initialization, and contains
931  *              the main server loop. Takes no command-line arguments
932  *              (see README for justification).
933  */
934 int main(void)
935 {
936         int server_sock;
937
938 #if HAVE_POLL
939         /* the sets are declared globally if we use poll() */
940 #else
941         fd_set fds, fds_send;
942 #endif
943
944         /*setlinebuf(stdout);*/
945         setvbuf(stdout, (char *)NULL, _IOLBF, 0); 
946
947         signal(SIGPIPE, SIG_IGN);
948
949         printf("BetaFTPD version %s, Copyright (C) 1999-2000 Steinar H. Gunderson\n", VERSION);
950         puts("BetaFTPD comes with ABSOLUTELY NO WARRANTY; for details see the file");
951         puts("COPYING. This is free software, and you are welcome to redistribute it");
952         puts("under certain conditions; again see the file COPYING for details.");
953         puts("");
954
955         /* we don't need stdin */
956         close(0);
957
958 #if HAVE_POLL
959         {
960                 int i;
961                 for (i = 0; i < FD_MAX; i++) {
962                         fds[i].fd = -1;
963                         fds[i].events = 0;
964                 }
965         }
966 #else
967         FD_ZERO(&master_fds);
968         FD_ZERO(&master_send_fds);
969 #endif
970
971         server_sock = create_server_socket();
972
973 #if WANT_FULLSCREEN
974         printf("%cc", (char)27);        /* reset and clear the screen */
975 #endif
976
977         /* init dummy first connection */
978         first_conn = alloc_new_conn(-1);
979         first_ftran = alloc_new_ftran(0, NULL);
980 #if WANT_DCACHE
981         first_dcache = alloc_new_dcache();
982 #endif
983
984 #if WANT_XFERLOG
985 #if WANT_NONROOT
986 #warning No xferlog support for nonroot yet
987 #else
988         /* open xferlog */
989         xferlog = fopen("/var/log/xferlog", "r+");
990         if (xferlog == NULL) xferlog = fopen("/usr/adm/xferlog", "r+");
991
992         if (xferlog != NULL) {
993                  fseek(xferlog, 0L, SEEK_END);
994         }
995 #endif
996 #endif
997
998 #if WANT_FORK
999         switch (fork()) {
1000         case -1:
1001                 perror("fork()");
1002                 puts("fork() failed, exiting");
1003                 exit(0);
1004         case 0:
1005                 break;
1006         default:
1007                 puts("BetaFTPD forked into the background");
1008                 exit(0);
1009         }
1010 #else
1011         puts("BetaFTPD active");
1012 #endif
1013
1014         /* set timeout alarm here (after the fork) */
1015         alarm(60);
1016         signal(SIGALRM, handle_alarm);
1017
1018         for ( ;; ) {
1019                 int i;
1020 #ifndef HAVE_POLL
1021                 struct timeval timeout;
1022 #endif
1023
1024                 /*screw_clients();       //look for memory errors */
1025
1026 #if WANT_FULLSCREEN
1027                 update_display(first_conn);
1028 #endif
1029
1030 #if HAVE_POLL
1031                 i = poll(fds, highest_fds + 1, 60000);
1032                 DPRINT(("poll returns %d\n", i));
1033 #if 0
1034                 {
1035                         int j;
1036                         for (j=0; j<=highest_fds; j++) {
1037                                 if (fds[j].revents) printf("fds[%d].fd %d, .revents %x\n", j, fds[j].fd, fds[j].revents);
1038                         }
1039                 }
1040 #endif
1041 #else
1042                 /* reset fds (gets changed by select()) */
1043                 fds = master_fds;
1044                 fds_send = master_send_fds;
1045
1046                 /*
1047                  * wait up to 60 secs for any activity 
1048                  */
1049                 timeout.tv_sec = 60;
1050                 timeout.tv_usec = 0;
1051
1052                 i = select(FD_SETSIZE, &fds, &fds_send, NULL, &timeout);
1053 #endif
1054
1055                 if (i == -1) {
1056                         if (errno == EBADF) {
1057 #if !HAVE_POLL
1058                                 /* don't like this, but we have to */
1059                                 clear_bad_fds(&server_sock);
1060 #endif
1061                         } else if (errno != EINTR) {
1062 #if HAVE_POLL
1063                                 perror("poll()");
1064 #else
1065                                 perror("select()");
1066 #endif
1067                                 continue;
1068                         }
1069                 }
1070
1071 #if HAVE_POLL
1072                 /* fix an invalid server socket */
1073                 if (fds[server_sock].revents & POLLERR) {
1074                         del_fd(server_sock);
1075                         server_sock = create_server_socket();
1076                 }
1077 #endif
1078
1079                 /* remove any timed out sockets */
1080                 if (time_to_check) {
1081                         time_out_sockets();
1082 #if WANT_DCACHE
1083                         time_out_dcache();
1084 #endif
1085                         time_to_check = 0;
1086                 }
1087
1088                 if (i <= 0) continue;
1089
1090 #if HAVE_POLL
1091                 i -= process_all_sendfiles(i);
1092                 process_all_clients(i);
1093 #else
1094                 /* sends are given highest `priority' */
1095                 i -= process_all_sendfiles(&fds_send, i);
1096
1097                 /* incoming PASV connections and uploads */
1098                 i -= process_all_sendfiles(&fds, i);
1099
1100                 /*
1101                  * check the incoming PASV connections first, so
1102                  * process_all_clients() won't be confused.
1103                  */ 
1104                 process_all_clients(&fds, i);
1105 #endif
1106
1107 #if HAVE_POLL
1108                 if (fds[server_sock].revents & POLLIN) {
1109 #else
1110                 if (FD_ISSET(server_sock, &fds)) {
1111 #endif
1112                         accept_new_client(&server_sock);
1113                         i--;
1114                 }
1115         }
1116 }
1117
1118 /*
1119  * accept_new_client():
1120  *              Open a socket for the new client, say hello and put it in
1121  *              among the others.
1122  */
1123 void accept_new_client(int * const server_sock)
1124 {
1125         struct sockaddr_in tempaddr;
1126         int tempaddr_len = sizeof(tempaddr);
1127         const int tempsock = accept(*server_sock, (struct sockaddr *)&tempaddr, &tempaddr_len);
1128
1129         static int num_err = 0;
1130
1131         if (tempsock < 0) {
1132 #ifndef WANT_FORK
1133                 perror("accept()");
1134 #endif
1135                 close(tempsock);
1136                 if ((errno == EBADF || errno == EPIPE) && ++num_err >= 3) {
1137                         del_fd(*server_sock);
1138                         *server_sock = create_server_socket();
1139                 }
1140         } else {
1141                 struct conn * const c = alloc_new_conn(tempsock);
1142                 num_err = 0;
1143                 if (c != NULL) {
1144                         numeric(c, 220, "BetaFTPD " VERSION " ready.");
1145 #if WANT_STAT
1146                         memcpy(&(c->addr), &tempaddr, sizeof(struct sockaddr));
1147 #endif
1148                 }
1149         }
1150 }
1151
1152 /*
1153  * time_out_sockets():
1154  *              Times out any socket that has not had any transfer
1155  *              in the last 15 minutes (delay not customizable by FTP
1156  *              user -- you must change it in ftpd.h).
1157  *
1158  *              Note that RFC959 explicitly states that there are no
1159  *              `spontaneous' error replies, yet we have to do it to
1160  *              get the message through at all.
1161  *
1162  *              If we check this list for every accept() call, it's
1163  *              actually eating a lot of CPU time, so we only check
1164  *              it every minute. We used to do a time() call here,
1165  *              but we've changed to do use an alarm() call and set
1166  *              the time_to_check_flag in the SIGALRM handler.
1167  */
1168 RETSIGTYPE handle_alarm(int signum)
1169 {
1170         time_to_check = 1;
1171         alarm(60);
1172
1173         /* for libc5 */
1174         signal(SIGALRM, handle_alarm);
1175 }
1176
1177 void time_out_sockets()
1178 {
1179         struct conn *c = NULL, *next = first_conn->next_conn;
1180         time_t now = time(NULL);  
1181
1182         /* run through the linked list */
1183         while (next != NULL) {
1184                 c = next;
1185                 next = c->next_conn;
1186
1187                 if ((c->transfer == NULL || c->transfer->state != 5) &&
1188                     (now - c->last_transfer > TIMEOUT_SECS)) {
1189                         /* RFC violation? */
1190                         numeric(c, 421, "Timeout (%u minutes): Closing control connection.", TIMEOUT_SECS/60);
1191                         destroy_conn(c);
1192                 }
1193         }
1194 }
1195
1196 #if WANT_DCACHE
1197 /*
1198  * time_out_dcache():
1199  *              Time out expired directory listing cache entries.
1200  *              Uses much of the same code as time_out_sockets().
1201  */
1202 void time_out_dcache()
1203 {
1204         struct dcache *d = NULL, *next = first_dcache->next_dcache;
1205         time_t now = time(NULL);        
1206
1207         /* run through the linked list */
1208         while (next != NULL) {
1209                 d = next;
1210                 next = d->next_dcache;
1211
1212                 if (d->use_count == 0 && (now - d->last_used > 900)) {
1213                         destroy_dcache(d);
1214                 }
1215         }
1216 }
1217 #endif
1218
1219 /*
1220  * remove_bytes():
1221  *              Remove some bytes from the incoming buffer. This gives
1222  *              room for new data on the control connection, and should
1223  *              be called when the code has finished using the data.
1224  *              (This is done automatically for all commands, so you
1225  *              normally need not worry about it.)
1226  */
1227 void remove_bytes(struct conn * const c, const int num)
1228 {
1229         if (c->buf_len <= num) {
1230                 c->buf_len = 0;
1231         } else {
1232                 c->buf_len -= num;
1233                 memmove(c->recv_buf, c->recv_buf + num, c->buf_len);
1234         }
1235 }
1236
1237 /*
1238  * numeric():   Sends a numeric FTP reply to the client. Note that
1239  *              you can use this command much the same way as you
1240  *              would use a printf() (with all the normal %s, %d,
1241  *              etc.), since it actually uses printf() internally.
1242  */
1243 void numeric(struct conn * const c, const int numeric, const char * const format, ...)
1244 {
1245         char buf[256], fmt[256];
1246         va_list args;
1247         int i, err;
1248
1249         snprintf(fmt, 256, "%03u %s\r\n", numeric, format);
1250
1251         va_start(args, format);
1252         i = vsnprintf(buf, 256, fmt, args);
1253         va_end(args);
1254
1255         DPRINT((buf));
1256         err = send(c->sock, buf, i, 0);
1257         if (err == -1 && errno == EPIPE) {
1258                 destroy_conn(c);
1259         }
1260 }
1261
1262 /*
1263  * init_file_transfer():
1264  *              Initiate a data connection for sending. This does not open
1265  *              any files etc., just does whatever is needed for the socket,
1266  *              if needed. It does, however, send the 150 reply to the client,
1267  *              and mmap()s if needed.
1268  *
1269  *              Linux systems (others?) define SOL_TCP right away, which saves us
1270  *              some grief and code size. Perhaps using getprotoent() is the `right'
1271  *              way, but it's bigger :-) (Optionally, we could figure it out at
1272  *              configure time, of course...)
1273  *
1274  *              For optimal speed, we use the Linux 2.2.x-only TCP_CORK flag if
1275  *              possible. Note that this is only defined in the first `arm' --
1276  *              we silently assume that Linux is the only OS supporting this
1277  *              flag. This might be an over-generalization, but I it looks like
1278  *              we'll have to depend on it other places as well, so we might
1279  *              just as well be evil here.
1280  */
1281 void init_file_transfer(struct ftran * const f)
1282 {
1283         struct linger ling;
1284         struct conn * const c = f->owner;
1285         const int mode = IPTOS_THROUGHPUT, zero = 0, one = 1;
1286         struct stat buf;
1287         int events;
1288
1289 #ifdef SOL_TCP
1290         /* we want max throughput */
1291         setsockopt(f->sock, SOL_IP, IP_TOS, (void *)&mode, sizeof(mode));
1292         setsockopt(f->sock, SOL_TCP, TCP_NODELAY, (void *)&zero, sizeof(zero));
1293 #ifdef TCP_CORK
1294         setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&one, sizeof(one));
1295 #endif
1296 #else
1297         /* should these pointers be freed afterwards? */
1298         {
1299                 getprotoent();  /* legal? */
1300                 {
1301                         const struct protoent * const pe_ip  = getprotobyname("ip");
1302                         const struct protoent * const pe_tcp = getprotobyname("tcp");
1303                         setsockopt(f->sock, pe_ip->p_proto, IP_TOS, (void *)&mode, sizeof(mode));
1304                         setsockopt(f->sock, pe_tcp->p_proto, TCP_NODELAY, (void *)&zero, sizeof(zero));
1305                 }
1306                 endprotoent();
1307         }
1308 #endif
1309
1310         if (f->dir_listing) {
1311                 f->block_size = MAX_BLOCK_SIZE;
1312         } else {
1313 #if WANT_ASCII
1314                 f->ascii_mode = f->owner->ascii_mode;
1315 #endif
1316
1317                 /* find the preferred block size */
1318                 f->block_size = MAX_BLOCK_SIZE;
1319                 if (fstat(f->local_file, &buf) != -1 &&
1320                     buf.st_blksize < MAX_BLOCK_SIZE) {
1321                         f->block_size = buf.st_blksize;
1322                 }
1323         }
1324
1325         f->state = 5;
1326
1327         events = POLLOUT;
1328 #if WANT_UPLOAD
1329         if (f->upload) {
1330                 events = POLLIN;
1331         }
1332 #endif /* WANT_UPLOAD */
1333
1334         TRAP_ERROR(add_fd(f->sock, events), 500, return);
1335
1336         ling.l_onoff = 0;
1337         ling.l_linger = 0;
1338         setsockopt(f->sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
1339
1340 #if !HAVE_POLL && WANT_UPLOAD
1341         /*
1342          * if we let an upload socket stay in master_send_fds, we would
1343          * get data that would fool us into closing the socket... (sigh)
1344          */
1345         if (f->upload) {
1346                 FD_CLR(f->sock, &master_send_fds);
1347                 FD_SET(f->sock, &master_fds);
1348         }
1349 #endif
1350
1351         time(&(f->owner->last_transfer));
1352         
1353         if (f->dir_listing) {
1354                 /* include size? */
1355                 numeric(f->owner, 150, "Opening ASCII mode data connection for directory listing.");
1356         } else {
1357                 /*
1358                  * slightly kludged -- perhaps we should kill the second arm,
1359                  * at the expense of code size? Or perhaps we could collapse
1360                  * the two possible replies into one?
1361                  */
1362 #if WANT_ASCII
1363                 if (f->ascii_mode
1364 #if WANT_UPLOAD
1365                         || f->upload
1366 #endif /* WANT_UPLOAD */
1367                 ) {
1368                         numeric(f->owner, 150, "Opening %s mode data connection for '%s'",
1369                                 (f->ascii_mode) ? "ASCII" : "BINARY", f->filename);
1370                 } else {
1371                         numeric(f->owner, 150, "Opening %s mode data connection for '%s' (%u bytes)",
1372                                 (f->ascii_mode) ? "ASCII" : "BINARY", f->filename,
1373                                 f->size); 
1374                 }
1375 #else /* !WANT_ASCII */
1376 #if WANT_UPLOAD
1377                 if (f->upload) {
1378                         numeric(f->owner, 150, "Opening BINARY mode data connection for '%s'", f->filename);
1379                 } else
1380 #endif /* WANT_UPLOAD */
1381                         numeric(f->owner, 150, "Opening BINARY mode data connection for '%s' (%u bytes)", f->filename, f->size);
1382 #endif /* !WANT_ASCII */
1383         }
1384
1385         /*
1386          * This section _could_ in theory be more optimized, but it's
1387          * much easier this way, and hopefully, the compiler will be
1388          * intelligent enough to optimize most of this away. The idea
1389          * is, some modes _require_ use of mmap (or not). The preferred
1390          * thing is using mmap() when we don't have sendfile(), and not
1391          * using mmap() when we have sendfile().
1392          */
1393 #if HAVE_MMAP
1394         if (f->dir_listing == 0) {
1395 #if HAVE_LINUX_SENDFILE
1396                 int do_mmap = 0;
1397 #else
1398                 int do_mmap = 1;
1399 #endif
1400 #if WANT_ASCII
1401                 if (f->ascii_mode == 1) do_mmap = 1;
1402 #endif
1403 #if WANT_UPLOAD
1404                 if (f->upload == 1) do_mmap = 0;
1405 #endif
1406  
1407                 if (do_mmap == 1) {
1408                         f->file_data = mmap(NULL, f->size, PROT_READ, MAP_SHARED, f->local_file, 0);
1409                         if (f->file_data == MAP_FAILED) f->file_data = NULL;
1410                 } else {
1411                         f->file_data = NULL;
1412                 }
1413                 f->pos = f->owner->rest_pos;
1414         }
1415 #else /* !HAVE_MMAP */
1416         lseek(f->local_file, f->owner->rest_pos, SEEK_SET);
1417 #endif
1418 }
1419
1420 /*
1421  * create_server_socket():
1422  *              Create and bind a server socket, that we can use to
1423  *              listen to new clients on.
1424  */
1425 int create_server_socket()
1426 {
1427         int server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1428         const unsigned int one = 1;
1429         struct sockaddr_in addr;
1430         int err;
1431         
1432         /*
1433          * In the `perfect' world, if an address was in use, we could
1434          * just wait for the kernel to clear everything up, and everybody
1435          * would be happy. But when you just found out your server socket
1436          * was invalid, it has to be `re-made', and 3000 users are trying
1437          * to access your fileserver, I think it's nice that it comes
1438          * up right away... hence this option.
1439          */
1440         setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1441         ioctl(server_sock, FIONBIO, &one);      /* just in case */
1442
1443         addr.sin_family = AF_INET;
1444         addr.sin_addr.s_addr = INADDR_ANY;
1445         addr.sin_port = htons(FTP_PORT);
1446
1447         do {
1448                 err = bind(server_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr));
1449
1450                 if (err == -1) {
1451                         perror("bind()");
1452                 
1453                         /* try to recover from recoverable errors... */
1454                         if (errno == ENOMEM || errno == EADDRINUSE) {
1455                                 puts("Waiting 1 sec before trying again...");
1456                                 sleep(1);
1457                         } else {
1458                                 puts("Giving up.");
1459                                 exit(1); 
1460                         }
1461                 }
1462         } while (err == -1);
1463
1464         listen(server_sock, 20);
1465
1466         err = add_fd(server_sock, POLLIN);
1467         if (err) {
1468                 perror("add_fd");
1469                 return -1;
1470         }
1471
1472         return server_sock;
1473 }
1474
1475 #if !HAVE_POLL
1476 /*
1477  * clear_bad_fds():
1478  *              Try to find invalid socket descriptors, and clean them.
1479  *              The methods used are rather UGLY, but I can't think of
1480  *              any good way of checking e.g. server_sock without
1481  *              doing anything to it :-(
1482  *
1483  *              poll() is able to do this in a much cleaner way, which 
1484  *              we use if we use poll(). That checking isn't done here,
1485  *              though.
1486  */
1487 void clear_bad_fds(int * const server_sock)
1488 {
1489         {
1490                 fd_set fds;
1491                 struct timeval tv = { 0, 0 };
1492
1493                 FD_ZERO(&fds);
1494                 FD_SET(*server_sock, &fds); 
1495                 if (select(*server_sock, &fds, NULL, NULL, &tv) == -1) {
1496                         FD_CLR(*server_sock, &master_fds);
1497                         close(*server_sock);
1498                         *server_sock = create_server_socket();
1499                 }
1500         }
1501
1502         /* could do this (conn, ftran) in any order */
1503         {
1504                 struct conn *c = NULL, *next = first_conn->next_conn;
1505         
1506                 /* run through the linked list */
1507                 while (next != NULL) {
1508                         char buf[1];
1509
1510                         c = next;
1511                         next = c->next_conn;
1512
1513                         if (read(c->sock, &buf, 0) == -1 &&
1514                             errno == EBADF) {
1515                                 destroy_conn(c);
1516                         }
1517                 }
1518         }
1519
1520         {
1521                 struct ftran *f = NULL, *next = first_ftran->next_ftran;
1522         
1523                 while (next != NULL) {
1524                         char buf[1];
1525
1526                         f = next;
1527                         next = f->next_ftran;
1528
1529                         if (read(f->sock, &buf, 0) == -1 &&
1530                             errno == EBADF) {
1531                                 destroy_ftran(f);
1532                         }
1533                 }
1534         }       
1535 }
1536 #endif
1537
1538 #if WANT_MESSAGE
1539 /*
1540  * dump_file(): Dumps a file on the control connection. Used for
1541  *              welcome messages and the likes. Note that outbuf
1542  *              is so big, to prevent any crashing from users creating
1543  *              weird .message files (like 1024 LFs)...
1544  */
1545 void dump_file(struct conn * const c, const int num, const char * const filename)
1546 {
1547         char buf[1024], outbuf[8192];
1548         char *ptr = outbuf + 4;
1549         int i, j = -1;
1550
1551         const int dumpfile = open(filename, O_RDONLY);
1552         if (dumpfile == -1) return;
1553
1554         i = read(dumpfile, buf, 1024);
1555         if (i <= 0) {
1556                 close(dumpfile);
1557                 return;
1558         }
1559
1560         sprintf(outbuf, "%03u-", num);
1561         while (++j < i) {
1562                 *ptr++ = buf[j];
1563                 if (buf[j] == '\n') {
1564                         sprintf(ptr, "%03u-", num);
1565                         ptr += 4;
1566                 }
1567         }
1568         *ptr++ = '\n';
1569
1570         send(c->sock, outbuf, ptr - outbuf, 0);
1571         close(dumpfile);
1572 }
1573
1574
1575 /*
1576  * list_readme():
1577  *              Lists all README file in the current (ie. OS current)
1578  *              directory, in a 250- message.
1579  */
1580 void list_readmes(struct conn * const c)
1581 {
1582         glob_t pglob;
1583         const time_t now = time(NULL);
1584         int i;
1585
1586         if (glob("README*", 0, NULL, &pglob) == 0) {
1587                 for (i = 0; i < pglob.gl_pathc; i++) {
1588                         const char * const temp = pglob.gl_pathv[i];
1589                         struct stat buf;
1590                         char str[2048];
1591
1592                         char *tm;
1593
1594                         if (stat(temp, &buf) == -1) continue;
1595
1596                         /* remove trailing LF */
1597                         tm = ctime(&buf.st_mtime);
1598                         tm[strlen(tm) - 1] = 0;
1599
1600                         sprintf(str, "250-Please read the file %s\r\n"
1601                                      "250-\tIt was last modified %s - %ld days ago\r\n",
1602                                 temp, tm,
1603                                 (now - buf.st_mtime) / 86400);
1604                         send(c->sock, str, strlen(str), 0);
1605                 }
1606                 globfree(&pglob);
1607         }       
1608 }
1609 #endif
1610