• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

extra/H07-Apr-2020-141108

nls/H03-May-2022-12494

sample/H03-Mar-2019-4640

GNUmakefileH A D06-Aug-2011600 3519

Makefile.objH A D01-Mar-20202.8 KiB9059

accept_control.cH A D14-Mar-20154.3 KiB190149

accept_data.cH A D14-Mar-20155.2 KiB210150

auth.cH A D14-Mar-20157.6 KiB278221

buffer2socket.cH A D14-Mar-20159.6 KiB358299

bug.cH A D14-Mar-20151.5 KiB6245

chunk.cH A D14-Mar-20153 KiB11192

cleanup.cH A D14-Mar-20158.2 KiB363283

conf.cH A D02-Mar-202043.8 KiB1,7081,544

control2socket.cH A D14-Mar-20151.3 KiB5135

conversions.cH A D14-Mar-20151.7 KiB8162

defaults.hH A D18-Jul-20111.5 KiB4342

file2buffer.cH A D14-Mar-20152.3 KiB7555

foobar.cH A D14-Mar-20158.4 KiB379299

foobar.hH A D23-Jul-2011658 2615

glob.cH A D14-Mar-20153.4 KiB158131

glob.hH A D23-Jul-2011386 218

h_abor.cH A D14-Mar-2015759 3117

h_auth.cH A D14-Mar-20154.4 KiB170139

h_ccc.cH A D14-Mar-20151.4 KiB5938

h_cwd.cH A D14-Mar-20152 KiB7454

h_dele.cH A D14-Mar-2015630 2814

h_esta.cH A D14-Mar-20151.8 KiB7650

h_feat.cH A D14-Mar-20155.1 KiB220176

h_help.cH A D14-Mar-20152.7 KiB10783

h_host.cH A D14-Mar-2015749 3313

h_lang.cH A D14-Mar-2015672 3519

h_list.cH A D14-Mar-20152.5 KiB10478

h_mdtm.cH A D14-Mar-2015774 3319

h_mff.cH A D14-Mar-20153.3 KiB145111

h_mfmt.cH A D14-Mar-20151.4 KiB6443

h_mkd.cH A D14-Mar-2015724 2914

h_mode.cH A D14-Mar-2015742 3519

h_noop.cH A D14-Mar-2015698 2815

h_pass.cH A D14-Mar-2015536 2613

h_pasv.cH A D14-Mar-20153.6 KiB147108

h_pbsz.cH A D14-Mar-2015658 3116

h_port.cH A D14-Mar-20151.9 KiB8762

h_prot.cH A D14-Mar-2015769 3723

h_pwd.cH A D14-Mar-2015521 218

h_quit.cH A D14-Mar-2015746 2814

h_rang.cH A D14-Mar-20151.1 KiB4227

h_rein.cH A D14-Mar-20152.6 KiB10679

h_rest.cH A D14-Mar-2015619 2813

h_retr.cH A D14-Mar-20154.3 KiB148113

h_rmd.cH A D14-Mar-2015651 2913

h_rnfr.cH A D14-Mar-2015973 3922

h_rnto.cH A D14-Mar-2015838 3719

h_site_checksum.cH A D14-Mar-20158 KiB315265

h_site_chmod.cH A D14-Mar-20152.4 KiB128104

h_site_group.cH A D14-Mar-2015888 3720

h_site_groups.cH A D14-Mar-2015715 3215

h_site_id.cH A D14-Mar-2015810 3315

h_site_idle.cH A D14-Mar-20151,008 3823

h_site_umask.cH A D14-Mar-2015548 2610

h_size.cH A D14-Mar-20152.5 KiB9170

h_stat.cH A D14-Mar-20152.3 KiB8463

h_stor.cH A D07-Jun-20196.3 KiB265210

h_syst.cH A D14-Mar-2015938 4629

h_type.cH A D14-Mar-2015652 3014

h_user.cH A D14-Mar-2015874 4426

headers.hH A D29-Feb-202022.9 KiB780668

ident_buffer2socket.cH A D14-Mar-2015890 3418

ident_connect_out.cH A D14-Mar-20151.5 KiB6342

ident_connected.cH A D14-Mar-2015943 3415

ident_socket2buffer.cH A D14-Mar-20151.8 KiB7755

list.cH A D14-Mar-201516.5 KiB685542

log.cH A D14-Mar-20154.9 KiB191169

main.cH A D14-Mar-20153.5 KiB160112

messages.cH A D14-Mar-201526.3 KiB944936

messages.hH A D30-Jul-201119.1 KiB468462

parse.cH A D14-Mar-20154.7 KiB187151

path.cH A D01-Mar-20203.5 KiB148116

pcre_rewrite.cH A D05-Mar-20204.7 KiB207168

pickystat.cH A D14-Mar-20152.6 KiB11782

quota.cH A D14-Mar-20151.8 KiB9062

readcmd.cH A D31-Mar-20194.9 KiB202143

readme.cH A D14-Mar-20153.9 KiB152113

reply.cH A D14-Mar-20152.3 KiB10773

sig_bus.cH A D14-Mar-2015947 4026

signals.cH A D14-Mar-20151 KiB5033

socket2buffer.cH A D14-Mar-20155.7 KiB228193

ssl_verify.cH A D14-Mar-20153.6 KiB12493

structs.cH A D14-Mar-20151.1 KiB3824

readme.c

1 /*
2  * readme.c
3  *
4  * (C)1998-2011 by Marc Huber <Marc.Huber@web.de>
5  * All rights reserved.
6  *
7  * $Id: readme.c,v 1.11 2015/03/14 06:11:27 marc Exp marc $
8  *
9  */
10 
11 #include "headers.h"
12 
13 static const char rcsid[] __attribute__ ((used)) = "$Id: readme.c,v 1.11 2015/03/14 06:11:27 marc Exp marc $";
14 
15 #define VD_SIZE 32		/* good enough for the cyclic buffer */
16 
17 struct visited_dirs {
18     int size;
19     int current;
20     struct {
21 	long dev;
22 	long ino;
23     } cyc[VD_SIZE];
24 };
25 
dir_visited(struct context * ctx,struct stat * st)26 static int dir_visited(struct context *ctx, struct stat *st)
27 {
28     int i = 0;
29 
30     if (!ctx->visited_dirs)
31 	ctx->visited_dirs = Xcalloc(1, sizeof(struct visited_dirs));
32     else
33 	for (i = 0; i < ctx->visited_dirs->size; i++)
34 	    if (ctx->visited_dirs->cyc[i].ino == (long) st->st_ino && ctx->visited_dirs->cyc[i].dev == (long) st->st_dev)
35 		return -1;
36 
37     ctx->visited_dirs->cyc[ctx->visited_dirs->current].dev = (long) st->st_dev;
38     ctx->visited_dirs->cyc[ctx->visited_dirs->current].ino = (long) st->st_ino;
39 
40     if (ctx->visited_dirs->size < VD_SIZE)
41 	ctx->visited_dirs->size++;
42 
43     if (++ctx->visited_dirs->current == VD_SIZE)
44 	ctx->visited_dirs->current = 0;
45 
46     return 0;
47 }
48 
file2control(struct context * ctx,char * arg,char * file)49 void file2control(struct context *ctx, char *arg, char *file)
50 {
51     Debug((DEBUG_PROC, "+ %s (%s)\n", __func__, file ? file : "(NULL)"));
52 
53     if (file && ctx->multiline_banners) {
54 	int i = -1;
55 	struct stat st;
56 	int is_banner = file == ctx->welcome || file == ctx->banner || file == ctx->goodbye;
57 	char form[PATH_MAX + 1], path[PATH_MAX + 1];
58 	char *l, *t, llang[10];
59 
60 	if (!is_banner && ctx->readme_once && (!pickystat(ctx, &st, ctx->cwd)) && dir_visited(ctx, &st)) {
61 	    Debug((DEBUG_PROC, "already visited\n"));
62 	    DebugOut(DEBUG_PROC);
63 	    return;
64 	}
65 
66 	l = llang, t = lang[ctx->lang];
67 	*l++ = '-';
68 	while (*t)
69 	    *l++ = tolower((int) *t++);
70 	*l = 0;
71 
72 	if ((sizeof(form) <= (size_t) snprintf(form, sizeof(form), "%s/%s", (is_banner || file[0] == '/')
73 					       ? "" : ctx->cwd, file)) || (sizeof(path) <= (size_t) snprintf(path, sizeof(path), form, llang))) {
74 	    DebugOut(DEBUG_PROC);
75 	    return;
76 	}
77 
78 	if (is_banner) {
79 	    i = open(path, O_RDONLY);
80 	    if (i < 0 && strstr(form, "%s")) {
81 		if (sizeof(path) <= (size_t) snprintf(path, sizeof(path), form, "")) {
82 		    DebugOut(DEBUG_PROC);
83 		    return;
84 		}
85 		i = open(path, O_RDONLY);
86 	    }
87 	} else {
88 	    if (((pickystat(ctx, &st, path) || (i = open(path, O_RDONLY)) < 0)) && strstr(form, "%s")) {
89 		if (sizeof(path) <= (size_t) snprintf(path, sizeof(path), form, "")) {
90 		    DebugOut(DEBUG_PROC);
91 		    return;
92 		}
93 		if (!pickystat(ctx, &st, path))
94 		    i = open(path, O_RDONLY);
95 	    }
96 
97 	    if (i > -1 && ctx->readme_notify) {
98 		long days_ago = (io_now.tv_sec - st.st_mtime) / 86400;
99 		char tb[2 * PATH_MAX];
100 		close(i);
101 
102 		replyf(ctx, "%s-", arg);
103 		replyf(ctx, MSG_Readme_notify_1, file);
104 
105 		strftime(tb, sizeof(tb), MSG_Readme_notify_2, localtime(&st.st_mtime));
106 		replyf(ctx, "%s-%s", arg, tb);
107 
108 		if (days_ago == 1)
109 		    reply(ctx, MSG_Readme_notify_31);
110 		else
111 		    replyf(ctx, MSG_Readme_notify_3n, days_ago);
112 
113 		DebugOut(DEBUG_PROC);
114 		return;
115 	    }
116 	}
117 
118 	if (i > -1) {
119 	    char tbuf[BUFSIZE];
120 	    char *lineend, *linestart = NULL;
121 	    size_t offset = 0;
122 	    ssize_t inlength;
123 
124 	    while ((inlength = read(i, tbuf + offset, sizeof(tbuf) - 1 - offset)) > 0) {
125 		inlength += offset;
126 		tbuf[inlength] = 0;
127 		linestart = tbuf;
128 		while ((lineend = strchr(linestart, '\n'))) {
129 		    *lineend = 0;
130 		    chomp(linestart);
131 		    replyf(ctx, "%s-%s\r\n", arg, cook(ctx, linestart, NULL, NULL, 0));
132 		    linestart = lineend + 1;
133 		}
134 #ifdef README_LOOP
135 /*
136  * Don't allow arbitrary sized README files. Noone's able or willing to
137  * read thousands of lines rushing by. BUFSIZE is our upper limit. For
138  * unlimited file sizes, #define README_LOOP. Yes, that could be made
139  * a configuration option. No, I don't think it makes sense.
140  */
141 		if ((offset = tbuf + inlength - linestart))
142 		    memmove(tbuf, linestart, offset);
143 		else
144 #endif
145 		    break;
146 	    }
147 	    close(i);
148 	}
149     }
150     DebugOut(DEBUG_PROC);
151 }
152