1 /*
2  * h_list.c
3  * (C)1998-2011 by Marc Huber <Marc.Huber@web.de>
4  *
5  * $Id: h_list.c,v 1.12 2015/03/14 06:11:25 marc Exp marc $
6  *
7  */
8 
9 #include "headers.h"
10 
11 static const char rcsid[] __attribute__ ((used)) = "$Id: h_list.c,v 1.12 2015/03/14 06:11:25 marc Exp marc $";
12 
13 static void xlist_done(struct context *ctx, int);
14 
xlist(struct context * ctx,char * arg,enum list_mode mode)15 static void xlist(struct context *ctx, char *arg, enum list_mode mode)
16 {
17     DebugIn(DEBUG_COMMAND);
18 
19     if (ctx->transfer_in_progress)
20 	reply(ctx, MSG_501_Transfer_in_progress);
21     else {
22 	ctx->transfer_in_progress = 1;
23 	ctx->conversion = CONV_NONE;
24 	ctx->filename[0] = 0;
25 	ctx->io_offset = 0;
26 	ctx->bytecount = 0;
27 	ctx->filesize = 0;
28 	ctx->outgoing_data = 1;
29 	ctx->ascii_in_buffer = 1;
30 
31 	io_sched_add(ctx->io, ctx, (void *) xlist_done, (time_t) 0, (suseconds_t) 0);
32 	list(ctx, arg, mode);
33     }
34     DebugOut(DEBUG_COMMAND);
35 }
36 
xlist_done(struct context * ctx,int cur)37 static void xlist_done(struct context *ctx, int cur __attribute__ ((unused)))
38 {
39     DebugIn(DEBUG_COMMAND);
40 
41     io_sched_pop(ctx->io, ctx);
42 
43     if (!ctx->dbufi && ctx->list_mode == List_mlsd) {
44 	reply(ctx, MSG_501_No_such_dir);
45 	if (ctx->dfn > -1)
46 	    cleanup_data_reuse(ctx, ctx->dfn);
47 	DebugOut(DEBUG_COMMAND);
48 	return;
49     }
50 
51     if (ctx->dfn < 0) {
52 	connect_port(ctx);
53 	if (ctx->dfn < 0) {
54 	    reply(ctx, MSG_431_Opening_datacon_failed);
55 	    buffer_free_all(ctx->dbuf);
56 	    ctx->dbuf = NULL;
57 	    DebugOut(DEBUG_COMMAND);
58 	    return;
59 	}
60     }
61 
62     if (io_get_cb_i(ctx->io, ctx->dfn) == (void *) accept_data) {
63 	io_set_i(ctx->io, ctx->dfn);
64 	io_clr_o(ctx->io, ctx->dfn);
65 	io_set_cb_e(ctx->io, ctx->dfn, (void *) cleanup_data);
66 	io_set_cb_h(ctx->io, ctx->dfn, (void *) cleanup_data);
67     }
68 
69     if (io_get_cb_o(ctx->io, ctx->dfn) == (void *) buffer2socket) {
70 	/* already connected */
71 	io_clr_cb_i(ctx->io, ctx->dfn);
72 	io_clr_i(ctx->io, ctx->dfn);
73 	io_set_o(ctx->io, ctx->dfn);
74     }
75 
76     if (io_get_cb_o(ctx->io, ctx->dfn) == (void *) buffer2socket || is_connected(ctx->dfn))
77 	replyf(ctx, MSG_125_Starting_dc, "ASCII", ctx->use_tls_d ? "TLS " : "");
78     else
79 	replyf(ctx, MSG_150_Opening_dc, "ASCII", ctx->use_tls_d ? "TLS " : "");
80 
81     DebugOut(DEBUG_COMMAND);
82 }
83 
h_list(struct context * ctx,char * arg)84 void h_list(struct context *ctx, char *arg)
85 {
86     DebugIn(DEBUG_COMMAND);
87     xlist(ctx, arg, List_list);
88     DebugOut(DEBUG_COMMAND);
89 }
90 
h_nlst(struct context * ctx,char * arg)91 void h_nlst(struct context *ctx, char *arg)
92 {
93     DebugIn(DEBUG_COMMAND);
94     xlist(ctx, arg, List_nlst);
95     DebugOut(DEBUG_COMMAND);
96 }
97 
h_mlsd(struct context * ctx,char * arg)98 void h_mlsd(struct context *ctx, char *arg)
99 {
100     DebugIn(DEBUG_COMMAND);
101     xlist(ctx, arg, List_mlsd);
102     DebugOut(DEBUG_COMMAND);
103 }
104