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