📄 receiver.c
字号:
/* $Author: peltotas $ $Date: 2006/03/14 12:01:00 $ $Revision: 1.8 $ *//* * MAD-FLUTELIB: Implementation of FLUTE protocol. * Copyright (c) 2003-2006 TUT - Tampere University of Technology * main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.fi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "flute_inc.h"/* * This function receives file identified with TOI. * * Params: int s_id: Session identifier, * char *filepath: Pointer to files path string, used when creating file and storing data to it, * ULONGLONG/unsigned long long toi: Transport Object Identifier for desired file, * ULONGLONG\unsigned long long file_len: Length of file, * char *md5: MD5 checksum for the file, * int rx_memory_mode: Receiver memory consumption mode, * char *encoding: Content-Encoding algorithm for file, * int verbosity:. * * Return: int: Different values (1, 0, -1, -2, -3, -4) depending on how function ends * */int recvfile(int s_id, char *filepath,#ifdef WIN32 ULONGLONG toi, ULONGLONG file_len,#else unsigned long long toi, unsigned long long file_len,#endif char *md5, int rx_memory_mode, char *encoding, int verbosity) { #ifdef USE_ZLIB char *uncompr_buf = NULL; #ifdef WIN32 ULONGLONG uncompr_buflen = 0;#else unsigned long long uncompr_buflen = 0;#endif #endif unsigned char fdt_cont_enc_algo = 0; int fdt_instance_id = 0; struct stat file_stats; #ifdef WIN32 ULONGLONG recvbytes = 0;#else unsigned long long recvbytes = 0;#endif char *buf = NULL; int fd; char *ptr; int point; int ch = '/'; int i = 0; int j; char *tmp = NULL; char fullpath[MAX_PATH]; char filename[MAX_PATH]; char tmp_filename[MAX_PATH]; char *tmp_file_name; int retcode = 0; int retval; #ifdef USE_OPENSSL char *md5_digest = NULL;#endif char* session_basedir = get_session_basedir(s_id); if(filepath != NULL) { if(verbosity > 0) { #ifdef WIN32 printf("Receiving file: %s (TOI=%I64u)\n", filepath, toi);#else printf("Receiving file: %s (TOI=%llu)\n", filepath, toi);#endif fflush(stdout); } for(j = 0; j < (int)strlen(filepath); j++) { if(*(filepath + j) == '\\') { *(filepath + j) = '/'; } } } else { if(verbosity > 0) {#ifdef WIN32 printf("Receiving object: TOI=%I64u\n", toi);#else printf("Receiving object: TOI=%llu\n", toi);#endif fflush(stdout); } } if(toi == FDT_TOI) { buf = fdt_recv(s_id, &recvbytes, &retcode, &fdt_cont_enc_algo, &fdt_instance_id); if(buf == NULL) { return retcode; } /* open tmp file */ memset(tmp_filename, 0, MAX_PATH); #ifdef WIN32 sprintf(tmp_filename, "%s\\object%I64u", session_basedir, toi);#else sprintf(tmp_filename, "%s/object%llu", session_basedir, toi);#endif#ifdef WIN32 if((fd = open((const char*)tmp_filename, _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC , _S_IWRITE)) < 0) {#else if((fd = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU)) < 0) {#endif printf("Error: unable to open file %s\n", tmp_filename); fflush(stdout); return MEM_ERROR; } if(fdt_cont_enc_algo == 0) { /* write buf to tmp file */ if(write(fd, buf, (unsigned int)recvbytes) == -1) {#ifdef WIN32 printf("write error, toi: %I64u\n", toi);#else printf("write error, toi: %llu\n", toi);#endif fflush(stdout); free(buf); close(fd); return MEM_ERROR; } free(buf); }#ifdef USE_ZLIB else if(fdt_cont_enc_algo == ZLIB) { uncompr_buf = buffer_zlib_uncompress(buf, recvbytes, &uncompr_buflen); if(uncompr_buf == NULL) { free(buf); return -1; } free(buf); /* write uncompr_buf to tmp file */ if(write(fd, uncompr_buf, (unsigned int)uncompr_buflen) == -1) {#ifdef WIN32 printf("write error, toi: %I64u\n", toi);#else printf("write error, toi: %llu\n", toi);#endif fflush(stdout); free(uncompr_buf); close(fd); return MEM_ERROR; } free(uncompr_buf); }#endif close(fd); } else { if(rx_memory_mode == 1) { tmp_file_name = alc_recv3(s_id, &toi, &retcode); if(tmp_file_name == NULL) { return retcode; } memset(tmp_filename, 0, MAX_PATH); memcpy(tmp_filename, tmp_file_name, strlen(tmp_file_name)); free(tmp_file_name); } else if(rx_memory_mode == 2) { printf("-b:2 option is not supported with object mode\n"); fflush(stdout); return -1; } else { buf = alc_recv(s_id, toi, &recvbytes, &retcode); if(buf == NULL) { return retcode; } /* open tmp file */ memset(tmp_filename, 0, MAX_PATH); if(encoding == NULL) {#ifdef WIN32 sprintf(tmp_filename, "%s\\object%I64u", session_basedir, toi);#else sprintf(tmp_filename, "%s/object%llu", session_basedir, toi);#endif }#ifdef USE_ZLIB else if(strcmp(encoding, "gzip") == 0) {#ifdef WIN32 sprintf(tmp_filename, "%s\\object%I64u%s", session_basedir, toi, GZ_SUFFIX);#else sprintf(tmp_filename, "%s/object%llu%s", session_basedir, toi, GZ_SUFFIX);#endif }#endif else if(strcmp(encoding, "pad") == 0) {#ifdef WIN32 sprintf(tmp_filename, "%s\\object%I64u%s", session_basedir, toi, PAD_SUFFIX);#else sprintf(tmp_filename, "%s/object%llu%s", session_basedir, toi, PAD_SUFFIX);#endif }#ifdef WIN32 if((fd = open((const char*)tmp_filename, _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC , _S_IWRITE)) < 0) {#else if((fd = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU)) < 0) {#endif printf("Error: unable to open file %s\n", tmp_filename); fflush(stdout); return MEM_ERROR; } /* write buffer to tmp file */ if(write(fd, buf, (unsigned int)recvbytes) == -1) {#ifdef WIN32 printf("write error, toi: %I64u\n", toi);#else printf("write error, toi: %llu\n", toi);#endif fflush(stdout); free(buf); close(fd); return MEM_ERROR; } free(buf); close(fd); } #ifdef USE_OPENSSL if(md5 != NULL) { md5_digest = file_md5(tmp_filename); if(md5_digest == NULL) { printf("MD5 check failed!\n"); fflush(stdout); remove(tmp_filename); return -4; } else{ if(strcmp(md5, md5_digest) != 0) { printf("MD5 check failed!\n"); fflush(stdout); remove(tmp_filename); free(md5_digest); return -4; } free(md5_digest); } }#endif if(encoding != NULL) { if(strcmp(encoding, "pad") == 0) { retcode = padding_decoder(tmp_filename, (int)file_len); if(retcode == -1) { return -1; } *(tmp_filename + (strlen(tmp_filename) - PAD_SUFFIX_LEN)) = '\0'; if(file_len != 0) { if(stat(tmp_filename, &file_stats) == -1) { printf("Error: %s is not valid file name\n", tmp_filename); fflush(stdout); return -1; } if(file_stats.st_size != file_len) { printf("Error: padding decoding failed\n"); remove(tmp_filename); fflush(stdout); return -1; } } }#ifdef USE_ZLIB else if(strcmp(encoding, "gzip") == 0) { retcode = file_gzip_uncompress(tmp_filename); if(retcode == -1) { return -1; } *(tmp_filename + (strlen(tmp_filename) - GZ_SUFFIX_LEN)) = '\0'; if(file_len != 0) { if(stat(tmp_filename, &file_stats) == -1) { printf("Error: %s is not valid file name\n", tmp_filename); fflush(stdout); return -1; } if(file_stats.st_size != file_len) { printf("Error: uncompression failed\n"); remove(tmp_filename); fflush(stdout); return -1; } } }#endif } } if(filepath == NULL) { if(verbosity > 0) { #ifdef WIN32 printf("Object received: TOI=%I64u\n", toi);#else printf("Object received: TOI=%llu\n", toi);#endif fflush(stdout); } return 1; } if(!(tmp = (char*)calloc((strlen(filepath) + 1), sizeof(char)))) { printf("Could not alloc memory for tmp (filepath)!\n"); fflush(stdout); return -1; } memcpy(tmp, filepath, strlen(filepath)); ptr = strchr(tmp, ch); memset(fullpath, 0, MAX_PATH); memcpy(fullpath, session_basedir, strlen(session_basedir)); if(ptr != NULL) { while(ptr != NULL) { i++; point = (int)(ptr - tmp); memset(filename, 0, MAX_PATH); #ifdef WIN32 memcpy((fullpath + strlen(fullpath)), "\\", 1);#else memcpy((fullpath + strlen(fullpath)), "/", 1);#endif memcpy((fullpath + strlen(fullpath)), tmp, point); memcpy(filename, (tmp + point + 1), (strlen(tmp) - (point + 1))); #ifdef WIN32 if(mkdir(fullpath) < 0) { #else if(mkdir(fullpath, S_IRWXU) < 0) {#endif if(errno != EEXIST) { printf("mkdir failed: cannot create directory %s (errno=%i)\n", fullpath, errno); fflush(stdout); if(toi == FDT_TOI) {#ifdef USE_ZLIB if(fdt_cont_enc_algo == ZLIB) { free(uncompr_buf); } else { free(buf); }#else free(buf);#endif } free(tmp); return -1; } } strcpy(tmp, filename); ptr = strchr(tmp, ch); }#ifdef WIN32 memcpy((fullpath + strlen(fullpath)), "\\", 1);#else memcpy((fullpath + strlen(fullpath)), "/", 1);#endif memcpy((fullpath + strlen(fullpath)), filename, strlen(filename)); } else{#ifdef WIN32 memcpy((fullpath + strlen(fullpath)), "\\", 1);#else memcpy((fullpath + strlen(fullpath)), "/", 1);#endif memcpy((fullpath + strlen(fullpath)), filepath, strlen(filepath)); } if(rename(tmp_filename, fullpath) < 0) { if(errno == EEXIST) { retval = remove(fullpath); if(retval == -1) { printf("errno: %i\n", errno); } if(rename(tmp_filename, fullpath) < 0) { printf("rename() error1\n"); } } else { printf("rename() error2\n"); } } free(tmp); if(verbosity > 0) {#ifdef WIN32 printf("File received: %s (TOI=%I64u)\n", filepath, toi);#else printf("File received: %s (TOI=%llu)\n", filepath, toi);#endif fflush(stdout); } return 1;}/* * This function receives files defined in an FDT file using alc_recv2() or alc_recv3() function. * * Params: fdt_t *fdt: Pointer to FDT structure, * int s_id: Session identifier, * int rx_memory_mode: Receiver memory consumtion mode, * int accept_expired_files: Accept Expired files, * char *filetoken: Pointer to wilc card token, * int openfile: Open file automatically (1 = yes, 0 = no) [only in Windows], * int verbosity:. * * Return: int: Different values (1, 0, -1, -2, -3) depending on how function ends * */int fdtbasedrecv(fdt_t *fdt, int s_id, int rx_memory_mode, int accept_expired_files, char *filetoken, int openfile, int verbosity) { file_t *file = NULL; file_t *next_file = NULL; uri_t *uri = NULL; time_t systime; #ifdef WIN32 ULONGLONG curr_time; ULONGLONG toi; ULONGLONG toi_len;#else unsigned long long curr_time; unsigned long long toi; unsigned long long toi_len;#endif char *ptr = NULL; int point; int ch = '/'; int i; char *tmp = NULL; char fullpath[MAX_PATH]; char filename[MAX_PATH]; char *filepath = NULL; bool is_all_files_received; bool is_printed = false; bool any_files_received = false; int retcode; int retval; #ifdef USE_OPENSSL char *md5= NULL;#endif unsigned char content_enc_algo = 0; struct stat file_stats; char* session_basedir = NULL; /* rx_memory_mode == 1 || 2 */ char *tmp_file_name; /* rx_memory_mode == 0 */ char *buf = NULL; int fd; char tmp_filename[MAX_PATH]; session_basedir = get_session_basedir(s_id); while(1) { if(get_session_state(s_id) == SExiting) { return -2; } else if(get_session_state(s_id) == STxStopped) { return -3; } is_all_files_received = true; time(&systime); curr_time = systime + 2208988800U; next_file = fdt->file_list; while(next_file != NULL) { file = next_file; if(((file->expires < curr_time) && (!accept_expired_files))) { if(file->next != NULL) { file->next->prev = file->prev; } if(file->prev != NULL) { file->prev->next = file->next; } if(file == fdt->file_list) { fdt->file_list = file->next; } if(file->encoding != NULL) { free(file->encoding); } if(file->location != NULL) { free(file->location); } if(file->md5 != NULL) { free(file->md5); } if(file->type != NULL) { free(file->type); } next_file = file->next; free(file); continue; } if(((filetoken == NULL) || (strstr(file->location, filetoken) != NULL))) { if(file->is_downloaded != 2) { is_all_files_received = false; is_printed = false; } if(file->is_downloaded == 2) { any_files_received = true; } } next_file = file->next; } i = 0; retcode = 0; toi = 0; if(rx_memory_mode == 0) { toi_len = 0; } if(is_all_files_received) { if(fdt->complete) { if(any_files_received) { if(verbosity > 0) { printf("All files received\n"); fflush(stdout); } } else { if(verbosity > 0) { printf("No wanted files in the session\n"); fflush(stdout); } } return 1; } else { if(((!is_printed) && (any_files_received))) { if(verbosity > 0) { printf("All files received, waiting for new files\n"); fflush(stdout); } is_printed = true; } #ifdef WIN32 Sleep(1);#else usleep(1000);#endif continue; } } if(rx_memory_mode == 1 || rx_memory_mode == 2) { tmp_file_name = alc_recv3(s_id, &toi, &retcode); if(tmp_file_name == NULL) { return retcode; } memset(tmp_filename, 0, MAX_PATH); memcpy(tmp_filename, tmp_file_name, strlen(tmp_file_name)); free(tmp_file_name); next_file = fdt->file_list; /* Find correct file structure, to get the file->location for file creation purpose */ while(next_file != NULL) { file = next_file; if(file->toi == toi) { file->is_downloaded = 2; break; } next_file = file->next; } } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -