1 /*
2 * file2buffer.c
3 * (C)1998-2011 by Marc Huber <Marc.Huber@web.de>
4 * All rights reserved.
5 *
6 * $Id: file2buffer.c,v 1.12 2015/03/14 06:11:24 marc Exp marc $
7 *
8 */
9
10 #include "headers.h"
11 #include "misc/tohex.h"
12
13 static const char rcsid[] __attribute__ ((used)) = "$Id: file2buffer.c,v 1.12 2015/03/14 06:11:24 marc Exp marc $";
14
15 /*
16 * This code is somewhat similar to the one found in h_site_checksum.c,
17 * but not compatible enough to be merged.
18 */
19
file2buffer(struct context * ctx,int cur)20 void file2buffer(struct context *ctx, int cur __attribute__ ((unused)))
21 {
22 ssize_t len = 0;
23 DebugIn(DEBUG_BUFFER);
24
25 sigbus_cur = ctx->cfn;
26
27 if (chunk_get(ctx, NULL)) {
28 cleanup_file(ctx, ctx->ffn);
29 cleanup_data(ctx, ctx->dfn);
30 io_sched_pop(ctx->io, ctx);
31 ctx->iomode = IOMODE_dunno;
32 ctx->chunk_start = NULL;
33 ctx->chunk_length = 0;
34 ctx->buffer_filled = 0;
35 reply(ctx, MSG_451_Transfer_incomplete);
36 } else {
37 if (chunk_remaining(ctx)) {
38 len = MIN(ctx->chunk_length, (size_t) bufsize);
39 if (ctx->conversion == CONV_CRC)
40 ctx->checksum.crc32 = crc32_update(ctx->checksum.crc32, (u_char *) ctx->chunk_start, len);
41 else
42 MD5Update(&ctx->checksum.md5context, (u_char *) ctx->chunk_start, len);
43 chunk_release(ctx, len);
44 }
45
46 if (chunk_remaining(ctx))
47 io_sched_renew_proc(ctx->io, ctx, (void *) file2buffer);
48 else {
49 ctx->dbuf = buffer_free_all(ctx->dbuf);
50 ctx->dbufi = buffer_free_all(ctx->dbufi);
51 ctx->dbufi = buffer_get();
52 io_sched_pop(ctx->io, ctx);
53 ctx->iomode = IOMODE_dunno;
54 if (ctx->conversion == CONV_CRC)
55 ctx->dbufi->length =
56 snprintf(ctx->dbufi->buf, ctx->dbufi->size,
57 "%u %llu %s\n", crc32_final(ctx->checksum.crc32, ctx->offset), (unsigned long long) ctx->offset, ctx->filename + ctx->rootlen);
58 else {
59 char digest[16], d[33];
60 MD5Final((u_char *) digest, &ctx->checksum.md5context);
61 tohex((u_char *) digest, 16, d);
62 ctx->dbufi->length = snprintf(ctx->dbufi->buf, ctx->dbufi->size, "%s %s\n", d, ctx->filename + ctx->rootlen);
63 }
64 ctx->offset = 0, ctx->remaining = 0, ctx->conversion = CONV_NONE;
65 if (ctx->dfn > -1 && io_get_cb_o(ctx->io, ctx->dfn) == (void *) buffer2socket)
66 io_set_o(ctx->io, ctx->dfn);
67 cleanup_file(ctx, ctx->ffn);
68 ctx->chunk_start = ctx->dbufi->buf;
69 ctx->chunk_length = ctx->dbufi->length;
70 ctx->buffer_filled = 1;
71 }
72 }
73 DebugOut(DEBUG_BUFFER);
74 }
75