1 /*
2 * h_size.c
3 * (C)1998-2011 by Marc Huber <Marc.Huber@web.de>
4 * All rights reserved.
5 *
6 * $Id: h_size.c,v 1.12 2015/03/14 06:11:26 marc Exp marc $
7 *
8 */
9
10 #include "headers.h"
11
12 static const char rcsid[] __attribute__ ((used)) = "$Id: h_size.c,v 1.12 2015/03/14 06:11:26 marc Exp marc $";
13
getasciisize(struct context * ctx,int cur)14 static void getasciisize(struct context *ctx, int cur __attribute__ ((unused)))
15 {
16 DebugIn(DEBUG_BUFFER);
17
18 sigbus_cur = ctx->cfn;
19 if (chunk_get(ctx, NULL)) {
20 reply(ctx, MSG_451_Internal_error);
21 goto bye;
22 } else {
23 if (chunk_remaining(ctx)) {
24 char lastchar = ctx->lastchar;
25 char *u = ctx->chunk_start;
26 size_t len = MIN(ctx->chunk_length, (size_t) bufsize);
27 char *ul = u + len;
28
29 for (; u < ul; lastchar = *u++)
30 if (*u == '\n' && lastchar != '\r')
31 ctx->bytecount++;
32
33 ctx->lastchar = lastchar;
34 ctx->bytecount += len;
35 chunk_release(ctx, len);
36 }
37
38 if (chunk_remaining(ctx))
39 io_sched_renew_proc(ctx->io, ctx, (void *) getasciisize);
40 else {
41 replyf(ctx, "213 %llu\r\n", (unsigned long long) ctx->bytecount);
42 bye:
43 ctx->lastchar = 0, ctx->bytecount = 0;
44 io_sched_pop(ctx->io, ctx);
45 cleanup_file(ctx, ctx->ffn);
46 ctx->dbufi = buffer_free_all(ctx->dbufi);
47 }
48 }
49
50 DebugOut(DEBUG_BUFFER);
51 }
52
h_size(struct context * ctx,char * arg)53 void h_size(struct context *ctx, char *arg)
54 {
55 char *t;
56 struct stat st;
57
58 DebugIn(DEBUG_COMMAND);
59
60 if (ctx->use_ascii && ctx->ffn > -1)
61 reply(ctx, MSG_452_Command_not_during_transfers);
62 else if (!((t = buildpath(ctx, arg)) && !pickystat(ctx, &st, t)))
63 reply(ctx, MSG_550_No_such_file_or_directory);
64 else if (!S_ISREG(st.st_mode))
65 reply(ctx, MSG_550_Not_plain_file);
66 else if (ctx->use_ascii && acl_binary_only(ctx, arg, t))
67 reply(ctx, MSG_504_size_no_ascii);
68 else if (ctx->use_ascii && ctx->ascii_size_limit > -1 && ctx->ascii_size_limit < st.st_size)
69 reply(ctx, MSG_504_size_ascii_exceeded);
70 else if (ctx->use_ascii && ((ctx->ffn = open(t, O_RDONLY | O_LARGEFILE)) > -1)) {
71 fcntl(ctx->ffn, F_SETFD, FD_CLOEXEC);
72 ctx->iomode_fixed = 0;
73 io_sched_add(ctx->io, ctx, (void *) getasciisize, 0, 0);
74 #ifdef WITH_MMAP
75 if (use_mmap)
76 ctx->iomode = IOMODE_mmap;
77 else
78 #endif
79 ctx->iomode = IOMODE_read, ctx->iomode_fixed = 1;
80 ctx->offset = 0;
81 ctx->remaining = st.st_size;
82 ctx->bytecount = 0;
83 ctx->quota_update_on_close = 0;
84 } else if (!ctx->use_ascii)
85 replyf(ctx, "213 %llu\r\n", (unsigned long long) st.st_size);
86 else
87 reply(ctx, MSG_550_No_such_file_or_directory);
88
89 DebugOut(DEBUG_COMMAND);
90 }
91