piler/src/store.c

144 lines
2.9 KiB
C
Raw Normal View History

2011-11-14 15:57:52 +01:00
/*
* store.c, SJ
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <syslog.h>
#include <piler.h>
#include <zlib.h>
#include <openssl/blowfish.h>
#include <openssl/evp.h>
2011-11-19 21:25:44 +01:00
int store_file(struct session_data *sdata, char *filename, int startpos, int len, struct __config *cfg){
int ret=0, rc, fd, n;
char *addr, *p, *p0, *p1, *p2, s[SMALLBUFSIZE];
2011-11-14 15:57:52 +01:00
struct stat st;
Bytef *z=NULL;
uLongf dstlen;
EVP_CIPHER_CTX ctx;
unsigned char *outbuf=NULL;
int outlen, tmplen;
struct timezone tz;
struct timeval tv1, tv2;
2011-11-19 21:25:44 +01:00
fd = open(filename, O_RDONLY);
2011-11-14 15:57:52 +01:00
if(fd == -1) return ret;
2011-11-19 21:25:44 +01:00
if(len == 0){
if(fstat(fd, &st)) return ret;
len = st.st_size;
}
2011-11-14 15:57:52 +01:00
gettimeofday(&tv1, &tz);
2011-11-19 21:25:44 +01:00
addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
2011-11-14 15:57:52 +01:00
close(fd);
if(addr == MAP_FAILED) return ret;
dstlen = compressBound(len);
z = malloc(dstlen);
if(z == NULL){
2011-11-19 21:25:44 +01:00
munmap(addr, len);
2011-11-14 15:57:52 +01:00
return ret;
}
rc = compress(z, &dstlen, (const Bytef *)addr, len);
gettimeofday(&tv2, &tz);
sdata->__compress += tvdiff(tv2, tv1);
2011-11-19 21:25:44 +01:00
munmap(addr, len);
2011-11-14 15:57:52 +01:00
if(rc != Z_OK) goto ENDE;
gettimeofday(&tv1, &tz);
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, cfg->key, cfg->iv);
outbuf = malloc(dstlen + EVP_MAX_BLOCK_LENGTH);
if(outbuf == NULL) goto ENDE;
if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, z, dstlen)) goto ENDE;
if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen)) goto ENDE;
outlen += tmplen;
EVP_CIPHER_CTX_cleanup(&ctx);
gettimeofday(&tv2, &tz);
sdata->__encrypt += tvdiff(tv2, tv1);
2011-11-19 21:25:44 +01:00
/* create a filename in the store based on piler_id */
p = strchr(filename, '.');
if(p) *p = '\0';
snprintf(s, sizeof(s)-1, "%s/%c%c/%c%c/%c%c/%s", cfg->queuedir, filename[RND_STR_LEN-6], filename[RND_STR_LEN-5], filename[RND_STR_LEN-4], filename[RND_STR_LEN-3], filename[RND_STR_LEN-2], filename[RND_STR_LEN-1], filename);
if(p){
*p = '.';
strncat(s, p, sizeof(s)-1);
}
2011-11-14 15:57:52 +01:00
2011-11-19 21:25:44 +01:00
if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: trying to store %d bytes for %s", sdata->ttmpfile, len, filename);
2011-11-14 15:57:52 +01:00
p0 = strrchr(s, '/'); if(!p0) goto ENDE;
*p0 = '\0';
if(stat(s, &st)){
p1 = strrchr(s, '/'); if(!p1) goto ENDE;
*p1 = '\0';
p2 = strrchr(s, '/'); if(!p2) goto ENDE;
*p2 = '\0';
2011-11-19 21:25:44 +01:00
mkdir(s, 0750);
2011-11-14 15:57:52 +01:00
*p2 = '/';
2011-11-19 21:25:44 +01:00
mkdir(s, 0750);
2011-11-14 15:57:52 +01:00
*p1 = '/';
2011-11-19 21:25:44 +01:00
mkdir(s, 0770);
2011-11-14 15:57:52 +01:00
}
*p0 = '/';
2011-11-19 21:25:44 +01:00
fd = open(s, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP);
2011-11-14 15:57:52 +01:00
if(fd == -1) goto ENDE;
n = write(fd, outbuf, outlen);
if(n == outlen){
ret = 1;
}
fsync(fd);
close(fd);
if(ret == 0){
unlink(s);
}
ENDE:
if(outbuf) free(outbuf);
if(z) free(z);
return ret;
}