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