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