/* * store.c, SJ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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]; 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; fd = open(filename, O_RDONLY); if(fd == -1) return ret; if(len == 0){ if(fstat(fd, &st)) return ret; len = st.st_size; } gettimeofday(&tv1, &tz); addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); if(addr == MAP_FAILED) return ret; dstlen = compressBound(len); z = malloc(dstlen); if(z == NULL){ munmap(addr, len); return ret; } rc = compress(z, &dstlen, (const Bytef *)addr, len); gettimeofday(&tv2, &tz); sdata->__compress += tvdiff(tv2, tv1); munmap(addr, len); 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); /* 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); } if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: trying to store %d bytes for %s", sdata->ttmpfile, len, filename); 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'; mkdir(s, 0750); *p2 = '/'; mkdir(s, 0750); *p1 = '/'; mkdir(s, 0770); } *p0 = '/'; fd = open(s, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP); 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; }