http_file_repair.c

Go to the documentation of this file.
00001 
00033 #include <errno.h>
00034 #include <stdlib.h>
00035 #include <sys/stat.h>
00036 #include <sys/types.h>
00037 #include <fcntl.h>
00038 #include <string.h>
00039 #include <ctype.h>
00040 
00041 #ifdef _MSC_VER
00042 #define _WINSOCKAPI_   /* Prevent inclusion of winsock.h in windows.h */
00043 #include <windows.h>
00044 #include <shellapi.h>
00045 #include <io.h>
00046 #include <direct.h>
00047 #endif
00048 
00049 #include "http_file_repair.h"
00050 
00051 #include "../alclib/alc_session.h"
00052 #include "../alclib/transport.h"
00053 #include "../alclib/alc_rx.h"
00054 #include "../alclib/xor_fec.h"
00055 #include "../alclib/rs_fec.h"
00056 #include "../alclib/null_fec.h"
00057 
00058 #include "uri.h"
00059 #include "mad_md5.h"
00060 #include "mad_zlib.h"
00061 
00062 #ifdef USE_FILE_REPAIR
00063 
00077 int parse_data(chunk_t chunk, file_t *file, trans_obj_t *obj, alc_session_t *s, int openfile) {
00078         
00079         unsigned int sbn = 0;
00080         unsigned int esi = 0;
00081         unsigned short sb_len = 0;
00082         int li;
00083         int i;
00084         int j;
00085         int loop;
00086         int bytes_left;
00087         char *buf = NULL;
00088 
00089 #ifdef USE_OPENSSL
00090         char *md5 = NULL;
00091 #endif
00092 
00093         unsigned long long block_len;
00094         unsigned long long pos;
00095 
00096         uri_t *uri;
00097         char *ptr;
00098         int point;
00099         int ch = '/';
00100         char *tmp = NULL;
00101         char fullpath[MAX_PATH_LENGTH];
00102         char filename[MAX_PATH_LENGTH];
00103         char *filepath = NULL;
00104         char *session_basedir = NULL;
00105         int retcode;
00106 
00107 #ifdef USE_ZLIB
00108 #ifdef _MSC_VER
00109         struct __stat64 file_stats;
00110 #else
00111         struct stat64 file_stats;
00112 #endif
00113 #endif
00114 
00115         trans_block_t *block = NULL;
00116         trans_unit_t *unit = NULL;
00117         trans_unit_t *tu = NULL;
00118         trans_unit_t *next_tu = NULL;
00119 
00120         char *string;
00121 
00122         sbn = 0;
00123         esi = 0;
00124         li = 0;
00125         j = 0;
00126         loop = 1;
00127         bytes_left = chunk.size;
00128         string = chunk.data;
00129 
00130         while(1) {
00131 
00132                 if(bytes_left == 0) {
00133                         break;
00134                 }
00135 
00136                 /* parse length indicator field */
00137                 li = (unsigned char)string[j+1] + (unsigned short)((string[j] << 8) & 0xFF00);
00138                 j += 2;
00139                 bytes_left -= 2;
00140 
00141                 if(file->fec_enc_id == COM_NO_C_FEC_ENC_ID) {
00142                         sbn = (unsigned char)string[j+1] + (unsigned short)((string[j] << 8) & 0xFF00);
00143                         esi = (unsigned char)string[j+3] + (unsigned short)((string[j+2] << 8) & 0xFF00);
00144                         j += 4;
00145                         bytes_left -= 4;
00146                 }
00147                 else if(file->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
00148                         sbn = (unsigned char)string[j+3] + (unsigned short)((string[j+2] << 8) & 0xFF00) +
00149                                 (unsigned int)((string[j+1] << 16) & 0xFF0000) + (unsigned int)((string[j] << 24) & 0xFF000000);
00150                         esi = (unsigned char)string[j+7] + (unsigned short)((string[j+6] << 8) & 0xFF00) +
00151                                 (unsigned int)((string[j+5] << 16) & 0xFF0000) + (unsigned int)((string[j+4] << 24) & 0xFF000000);
00152                         j += 8;
00153                         bytes_left -= 8;
00154                 }
00155                 else if(((file->fec_enc_id == SB_SYS_FEC_ENC_ID) &&
00156                         (file->fec_inst_id == REED_SOL_FEC_INST_ID))) {
00157                                 sbn = (unsigned char)string[j+3] + (unsigned short)((string[j+2] << 8) & 0xFF00) +
00158                                         (unsigned int)((string[j+1] << 16) & 0xFF0000) + (unsigned int)((string[j] << 24) & 0xFF000000);
00159                                 sb_len = (unsigned char)string[j+5] + (unsigned short)((string[j+4] << 8) & 0xFF00);
00160                                 esi = (unsigned char)string[j+7] + (unsigned short)((string[j+6] << 8) & 0xFF00);
00161                                 j += 8;
00162                                 bytes_left -= 8;
00163                 }
00164                 else {
00165                         printf("FEC Encoding %i/%i is not supported!\n", file->fec_enc_id, file->fec_inst_id);
00166                         return -1;
00167                 }
00168 
00169                 for(i = 0; i < li; i++) {
00170 
00171 #ifdef USE_RETRIEVE_UNIT
00172                         /* Retrieve a transport unit from session pool  */
00173                         unit = retrieve_unit(s, file->es_len);
00174 #else
00175                         /* Create transport unit */
00176                         unit = create_units(1);
00177 #endif
00178 
00179                         if(unit == NULL) {
00180                                 return -1;
00181                         }
00182 
00183                         unit->esi = (esi + i);
00184 
00185                         if(bytes_left >= file->es_len) {
00186                                 unit->len = file->es_len;
00187                         }
00188                         else {
00189                                 unit->len = bytes_left;
00190                         }
00191 
00192 #ifndef USE_RETRIEVE_UNIT
00193                         if(!(unit->data = (char*)calloc(unit->len, sizeof(char)))) {
00194                                 printf("Could not alloc memory for transport unit's data!\n");
00195                                 return -1;
00196                         }
00197 #endif
00198 
00199                         memcpy(unit->data, (string + j), unit->len);
00200 
00201                         j += unit->len;
00202                         bytes_left -= unit->len;
00203 
00204                         block = obj->block_list+sbn;
00205 
00206                         if(block->unit_list == NULL) {
00207 
00208                                 block->sbn = sbn;       
00209                                 block->nb_of_rx_units = 0;
00210 
00211                                 if(file->fec_enc_id == COM_NO_C_FEC_ENC_ID) { 
00212 
00213                                         if(sbn < obj->bs->I) {
00214                                                 block->k = obj->bs->A_large;
00215                                         }
00216                                         else {
00217                                                 block->k = obj->bs->A_small;
00218                                         }
00219                                 }
00220                                 else if(((file->fec_enc_id == SB_SYS_FEC_ENC_ID)
00221                                         && (file->fec_inst_id == REED_SOL_FEC_INST_ID))) {
00222 
00223                                                 block->k = sb_len;
00224                                                 block->max_k = file->max_sb_len;
00225                                                 block->max_n = file->max_nb_of_es;
00226                                 }
00227                                 else if(file->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
00228 
00229                                         if(sbn < obj->bs->I) {
00230                                                 block->k = obj->bs->A_large;
00231                                         }
00232                                         else {
00233                                                 block->k = obj->bs->A_small;
00234                                         }
00235 
00236                                         block->max_k = file->max_sb_len;
00237                                 }
00238                         }
00239 
00240                         insert_unit(unit, block, obj);
00241 
00242                         /* if large file mode data symbol is stored in the tmp file */
00243                         if(s->rx_memory_mode == 2) {
00244 
00245 #ifdef _MSC_VER
00246                                 unit->offset = _lseeki64(obj->fd_st, 0, SEEK_END);
00247 #else
00248                                 unit->offset = lseek64(obj->fd_st, 0, SEEK_END);
00249 #endif
00250                                 if(unit->offset == -1) {
00251 #ifdef _MSC_VER
00252                                         printf("lseek error, toi: %I64u\n", obj->toi);
00253 #else
00254                                         printf("lseek error, toi: %llu\n", obj->toi);
00255 #endif
00256                                         fflush(stdout);
00257                                         return -1;
00258                                 }
00259 
00260                                 if(write(obj->fd_st, unit->data, (unsigned int)unit->len) == -1) {
00261 #ifdef _MSC_VER
00262                                         printf("write error, toi: %I64u, sbn: %i\n", obj->toi, sbn);
00263 #else
00264                                         printf("write error, toi: %llu, sbn: %i\n", obj->toi, sbn);
00265 #endif
00266                                         fflush(stdout);
00267                                         return -1;
00268                                 }
00269 
00270                                 free(unit->data);
00271                                 unit->data = NULL;
00272                         }
00273                 }
00274 
00275                 if(s->rx_memory_mode == 1 || s->rx_memory_mode == 2) {
00276 
00277                         if(block_ready_to_decode(block)) {
00278 
00279                                 if(s->rx_memory_mode == 2){
00280 
00281                                         /* We have to restore the data symbols to trans_units from the symbol store tmp file */
00282 
00283                                         next_tu = block->unit_list;
00284 
00285                                         while(next_tu != NULL) {
00286 
00287                                                 tu = next_tu;     
00288 
00289                                                 if(tu->data != NULL) {
00290                                                         next_tu = tu->next; 
00291                                                         continue;
00292                                                 }
00293 #ifdef _MSC_VER
00294                                                 if(_lseeki64(obj->fd_st, tu->offset, SEEK_SET) == -1) {
00295 #else
00296                                                 if(lseek64(obj->fd_st, tu->offset, SEEK_SET) == -1) {
00297 #endif
00298 
00299 #ifdef _MSC_VER
00300                                                         printf("lseek error, toi: %I64u\n", obj->toi);
00301 #else
00302                                                         printf("lseek error, toi: %llu\n", obj->toi);
00303 #endif
00304                                                         fflush(stdout);
00305                                                         return -1;
00306                                                 }
00307                                                 /* let's copy the data symbols from the tmp file to the memory */
00308 
00309                                                 /* Alloc memory for restoring data symbol */
00310 
00311                                                 if(!(tu->data = (char*)calloc(tu->len, sizeof(char)))) { /* rs_fec&xor_fec: 
00312                                                                                                                                                                  trans_unit->len --> eslen */
00313                                                         printf("Could not alloc memory for transport unit's data!\n");
00314                                                         return -1;
00315                                                 }
00316 
00317                                                 if(read(obj->fd_st, tu->data, tu->len) == -1) {
00318 #ifdef _MSC_VER
00319                                                         printf("read error, toi: %I64u, sbn: %i\n", obj->toi, sbn);
00320 #else
00321                                                         printf("read error, toi: %llu, sbn: %i\n", obj->toi, sbn);
00322 #endif
00323                                                         fflush(stdout);
00324                                                         return -1;
00325                                                 }
00326 
00327                                                 next_tu = tu->next;
00328                                         }
00329                                 }
00330 
00331                                 /* decode and save data */
00332                                 if(file->fec_enc_id == COM_NO_C_FEC_ENC_ID) {
00333                                         buf = null_fec_decode_src_block(block, &block_len, file->es_len);
00334                                 }
00335                                 else if(file->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
00336                                         buf = xor_fec_decode_src_block(block, &block_len, file->es_len);
00337                                 }
00338                                 else if(((file->fec_enc_id == SB_SYS_FEC_ENC_ID)
00339                                         && (file->fec_inst_id == REED_SOL_FEC_INST_ID))) {
00340                                                 buf = rs_fec_decode_src_block(block, &block_len, file->es_len);
00341                                 }
00342 
00343                                 if(buf == NULL) {
00344                                         return -1;
00345                                 }
00346 
00347                                 if(block->sbn < obj->bs->I) {
00348                                         pos = ( (unsigned long long)block->sbn * (unsigned long long)obj->bs->A_large *
00349                                                 (unsigned long long)file->es_len );
00350                                 }
00351                                 else {
00352                                         pos = ( ( ( (unsigned long long)obj->bs->I * (unsigned long long)obj->bs->A_large ) +
00353                                                 ( (unsigned long long)block->sbn - (unsigned long long)obj->bs->I )  *
00354                                                 (unsigned long long)obj->bs->A_small ) * (unsigned long long)file->es_len );
00355                                 }
00356 
00357                                 /* We have to check if there is padding in the last source symbol of the last source block */
00358 
00359                                 if(block->sbn == ((obj->bs->N) - 1)) {
00360                                         block_len = (file->transfer_len - (file->es_len * (obj->bs->I * obj->bs->A_large +
00361                                                 (obj->bs->N - obj->bs->I -1) * obj->bs->A_small)));
00362                                 }
00363 
00364                                 /* set correct position */
00365 
00366 #ifdef _MSC_VER
00367                                 if(_lseeki64(obj->fd, pos, SEEK_SET) == -1) {
00368 #else
00369                                 if(lseek64(obj->fd, pos, SEEK_SET) == -1) {
00370 #endif
00371                                         printf("lseek error\n");
00372                                         free(buf);
00373                                         return -1;
00374                                 }
00375 
00376                                 if(write(obj->fd, buf, (unsigned int)block_len) == -1) {
00377                                         printf("write error\n");
00378                                         return -1;
00379                                 }
00380 
00381                                 obj->nb_of_ready_blocks++;
00382 
00383                                 if(s->verbosity > 1) {
00384 #ifdef _MSC_VER
00385                                         printf("%u/%u Source Blocks decoded (TOI=%I64u SBN=%u)\n", obj->nb_of_ready_blocks, obj->bs->N, obj->toi, sbn);
00386 #else
00387                                         printf("%u/%u Source Blocks decoded (TOI=%llu SBN=%u)\n", obj->nb_of_ready_blocks, obj->bs->N, obj->toi, sbn);
00388 #endif
00389                                         fflush(stdout);
00390                                 }
00391 
00392                                 free(buf);
00393 
00394 #ifdef USE_RETRIEVE_UNIT
00395                                 free_units2(block);
00396 #else
00397                                 free_units(block);
00398 #endif
00399 
00400                                 if(object_completed(obj)) {
00401 #ifdef USE_OPENSSL
00402                                         if(file->md5 != NULL) {
00403 
00404                                                 md5 = file_md5(obj->tmp_filename);
00405 
00406                                                 if(md5 == NULL) {
00407 #ifdef _MSC_VER
00408                                                         printf("MD5 check failed (TOI=%I64u)!\n\n", file->toi);
00409 #else
00410                                                         printf("MD5 check failed (TOI=%llu)!\n\n", file->toi);
00411 #endif
00412                                                         fflush(stdout);
00413                                                         remove(obj->tmp_filename);
00414                                                         return -4;
00415                                                 }
00416                                                 else {
00417                                                         if(strcmp(md5, file->md5) != 0) {
00418 #ifdef _MSC_VER
00419                                                                 printf("MD5 check failed (TOI=%I64u)!\n\n", file->toi);
00420 #else
00421                                                                 printf("MD5 check failed (TOI=%llu)!\n\n", file->toi);
00422 #endif
00423                                                                 fflush(stdout);
00424                                                                 remove(obj->tmp_filename);
00425                                                                 free(md5);
00426                                                                 return -4;
00427                                                         }
00428                                                         free(md5);
00429                                                 }
00430                                         }
00431 #endif
00432 
00433 #ifdef USE_ZLIB
00434                                         if(file->encoding != NULL) {
00435                                                 if(strcmp(file->encoding, "gzip") == 0) {
00436 
00437                                                         retcode = file_gzip_uncompress(obj->tmp_filename);
00438 
00439                                                         if(retcode == -1) {
00440                                                                 return -1;
00441                                                         }
00442 
00443                                                         *(obj->tmp_filename + (strlen(obj->tmp_filename) - GZ_SUFFIX_LEN)) = '\0';
00444 
00445 #ifdef _MSC_VER
00446                                                         if(_stat64(obj->tmp_filename, &file_stats) == -1) {
00447 #else
00448                                                         if(stat64(obj->tmp_filename, &file_stats) == -1) {
00449 #endif
00450                                                                 printf("Error: %s is not valid file name\n", obj->tmp_filename);
00451                                                                 fflush(stdout);
00452                                                                 return -1;
00453                                                         }
00454 
00455                                                         if(file_stats.st_size != file->content_len) {
00456                                                                 printf("Error: uncompression failed, file-size not ok.\n");
00457                                                                 fflush(stdout);
00458                                                                 return -1;
00459                                                         }
00460                                                 }
00461                                         }
00462 #endif
00463                                         uri = parse_uri(file->location, (int)strlen(file->location));
00464 
00465                                         filepath = get_uri_host_and_path(uri);
00466 
00467                                         if(!(tmp = (char*)calloc((strlen(filepath) + 1), sizeof(char)))) {
00468                                                 printf("Could not alloc memory for tmp-filepath!\n");
00469                                                 fflush(stdout);
00470                                                 free(filepath);
00471                                                 free_uri(uri);
00472                                                 return -1;
00473                                         }
00474 
00475                                         memcpy(tmp, filepath, strlen(filepath));
00476                                         ptr = strchr(tmp, ch);
00477 
00478                                         session_basedir = get_session_basedir(s->s_id);
00479 
00480                                         memset(fullpath, 0, MAX_PATH_LENGTH);
00481                                         memcpy(fullpath, session_basedir, strlen(session_basedir));
00482 
00483                                         if(ptr != NULL) {
00484 
00485                                                 while(ptr != NULL) {
00486 
00487                                                         point = (int)(ptr - tmp);
00488 
00489                                                         memset(filename, 0, MAX_PATH_LENGTH);                               
00490 #ifdef _MSC_VER
00491                                                         memcpy((fullpath + strlen(fullpath)), "\\", 1);
00492 #else
00493                                                         memcpy((fullpath + strlen(fullpath)), "/", 1);
00494 #endif
00495                                                         memcpy((fullpath + strlen(fullpath)), tmp, point);
00496 
00497                                                         memcpy(filename, (tmp + point + 1), (strlen(tmp) - (point + 1)));
00498 
00499 #ifdef _MSC_VER
00500                                                         if(mkdir(fullpath) < 0) {
00501 #else
00502                                                         if(mkdir(fullpath, S_IRWXU) < 0) {
00503 #endif
00504                                                                 if(errno != EEXIST) {
00505                                                                         printf("mkdir failed: cannot create directory %s (errno=%i)\n", fullpath, errno);
00506                                                                         fflush(stdout);
00507                                                                         free(filepath);
00508                                                                         free_uri(uri);
00509                                                                         return -1;
00510                                                                 }
00511                                                         }
00512 
00513                                                         strcpy(tmp, filename);
00514                                                         ptr = strchr(tmp, ch);
00515                                                 }
00516 #ifdef _MSC_VER
00517                                                 memcpy((fullpath + strlen(fullpath)), "\\", 1);
00518 #else
00519                                                 memcpy((fullpath + strlen(fullpath)), "/", 1);
00520 #endif
00521                                                 memcpy((fullpath + strlen(fullpath)), filename, strlen(filename));
00522                                         }
00523                                         else{
00524 #ifdef _MSC_VER
00525                                                 memcpy((fullpath + strlen(fullpath)), "\\", 1);
00526 #else
00527                                                 memcpy((fullpath + strlen(fullpath)), "/", 1);
00528 #endif
00529                                                 memcpy((fullpath + strlen(fullpath)), filepath, strlen(filepath));
00530                                         }
00531 
00532                                         if(close(obj->fd) == -1) {
00533                                                 printf("close failed, errno: %i\n", errno);
00534                                         }
00535 
00536                                         if(rename(obj->tmp_filename, fullpath) < 0) {
00537 
00538                                                 if(errno == EEXIST) {
00539 
00540                                                         retcode = remove(fullpath);
00541 
00542                                                         if(retcode == -1) {
00543                                                                 printf("remove() error: errno: %i\n", errno);
00544                                                                 fflush(stdout);
00545                                                         }
00546 
00547                                                         if(rename(obj->tmp_filename, fullpath) < 0) {
00548                                                                 printf("rename() error1: %s\n", obj->tmp_filename);
00549                                                                 fflush(stdout);
00550                                                         }
00551                                                 }
00552                                                 else {
00553                                                         printf("rename() error2: %s\n%i\n", obj->tmp_filename, errno);
00554                                                         fflush(stdout);
00555                                                 }
00556                                         }
00557 
00558                                         free(obj->tmp_filename);
00559                                         obj->tmp_filename = NULL;
00560 
00561                                         free(tmp);
00562 
00563                                         if(s->verbosity > 0) {
00564 #ifdef _MSC_VER
00565                                                 printf("File received: %s (TOI=%I64u)\n", file->location, file->toi);
00566 #else
00567                                                 printf("File received: %s (TOI=%llu)\n", file->location, file->toi);
00568 #endif
00569                                                 fflush(stdout);
00570                                         }
00571 
00572                                         free_uri(uri);
00573 
00574 #ifdef _MSC_VER
00575                                         if(openfile) {
00576                                                 ShellExecute(NULL, "Open", fullpath, NULL, NULL, SW_SHOWNORMAL);
00577                                         }
00578 #endif
00579                                         free(filepath);
00580                                 }
00581                         }
00582                 }
00583 
00584                 loop++; 
00585         }
00586 
00587         return 0;
00588 }
00589 
00590 size_t write_to_buffer(void *ptr, size_t size, size_t nmemb, void *a) {
00591   
00592   size_t neededsize;
00593   chunk_t *chunk;
00594   neededsize = size * nmemb;
00595   chunk = (chunk_t*)a;
00596 
00597   chunk->data = (char*)realloc(chunk->data, (chunk->size + neededsize + 1));
00598   
00599   if(chunk->data) {
00600     memcpy(&(chunk->data[chunk->size]), ptr, neededsize);
00601     chunk->size += neededsize;
00602     chunk->data[chunk->size] = 0;
00603   }
00604   else {
00605           return 0;
00606   }
00607   
00608   return neededsize;
00609 }
00610 
00611 char* http_file_repair(flute_receiver_t *receiver, int openfile, int *retval, CURL *curl,
00612                                            char *serviceURI) {
00613 
00614         alc_session_t *s = NULL;
00615         trans_obj_t *obj = NULL;
00616         trans_obj_t *next_obj = NULL;
00617         trans_block_t *block = NULL;
00618         trans_unit_t *unit = NULL;
00619         char esi_table[255]; /* TODO: Max SBL is 255! */
00620         unsigned int i, j;
00621 
00622         char tmp_string[10];
00623         file_t *file = NULL;
00624 
00625         int first_esi;
00626         int tmp_uri_len;
00627 
00628         int counter;
00629         int nb_of_missing_symbols;
00630 
00631         char *sdp_buf = NULL;
00632 
00633         char filename[MAX_PATH_LENGTH];
00634 
00635         CURLcode code;
00636         long response_code;
00637         chunk_t content;
00638         char *content_type;
00639         char query_string[MAX_HTTP_URL_LENGTH];
00640         char errorBuffer[CURL_ERROR_SIZE];
00641         int x;
00642 
00643         code = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
00644 
00645         if(code != CURLE_OK) {
00646                 printf("Failed to set error buffer [%d]\n", code);
00647         *retval = -1;
00648                 return NULL; 
00649         }
00650 
00651         code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_to_buffer);
00652 
00653         if(code != CURLE_OK) {
00654                 printf("Failed to set writer [%s]\n", errorBuffer);
00655         *retval = -1;
00656                 return NULL; 
00657         }
00658 
00659         code = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&content);      
00660 
00661         if(code != CURLE_OK) {
00662                 printf("Failed to set write data [%s]\n", errorBuffer);
00663         *retval = -1;
00664                 return NULL; 
00665         }
00666 
00667         code = curl_easy_setopt(curl, CURLOPT_URL, serviceURI);
00668 
00669         if(code != CURLE_OK) {
00670                 printf("Failed to set URL [%s]\n", errorBuffer);
00671                 *retval = -1;
00672                 return NULL; 
00673         }
00674 
00675         code = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
00676 
00677         if(code != CURLE_OK) {
00678                 printf("Failed to set redirect option [%s]\n", errorBuffer);
00679                 *retval = -1;
00680                 return NULL; 
00681         }
00682 
00683         s = get_alc_session(receiver->s_id);
00684         
00685         /* We should go through the fdt and repair objects which status != 2 with */
00686         /* automatic mode and objects which status is 1 with wild card and file */
00687         /* uri list mode */
00688 
00689         file = receiver->fdt->file_list;
00690 
00691         if(file == NULL) {
00692                 /* This should not happen, because this is already checked in main.c */
00693                 *retval = -1;
00694                 return NULL; 
00695         }
00696 
00697         while(file != NULL) {
00698 
00699                 if((receiver->rx_automatic && file->status != 2) || file->status == 1) {
00700 
00701                         if(receiver->verbosity > 0) {
00702 #ifdef _MSC_VER
00703                                 printf("Repairing TOI: %I64u\n", file->toi);
00704 #else
00705                                 printf("Repairing TOI: %llu\n", file->toi);
00706 #endif
00707                         }
00708 
00709                         memset(query_string, 0, MAX_HTTP_URL_LENGTH);
00710                         strcpy(query_string, "fileURI=");
00711                         strcat(query_string, file->location);
00712 
00713                         tmp_uri_len = strlen(query_string);
00714 
00715                         /* Search the object from the object structure */
00716 
00717                         obj = NULL;
00718 
00719                         next_obj = get_session_obj_list(receiver->s_id);
00720 
00721                         while(next_obj != NULL) {
00722 
00723                                 if(next_obj->toi == file->toi) {
00724                                         obj = next_obj;
00725                                         break;
00726                                 }
00727                                 next_obj = next_obj->next;
00728                         }
00729 
00730                         if(obj == NULL) {
00731 
00732                                 /* We have to create the object structure */
00733 
00734                                 if(receiver->verbosity > 0) {
00735 #ifdef _MSC_VER
00736                                         printf("TOI: %I64u is completely missing.\n", file->toi);
00737 #else           
00738                                         printf("TOI: %llu is completely missing.\n", file->toi);
00739 #endif
00740                                 }
00741 
00742                                 obj = create_object();
00743                                 obj->toi = file->toi;
00744                                 obj->len = file->transfer_len;
00745                                 obj->fec_enc_id = (unsigned char)file->fec_enc_id;
00746                                 obj->fec_inst_id = file->fec_inst_id;
00747                                 obj->es_len = file->es_len;
00748                                 obj->max_sb_len = file->max_sb_len;
00749                                 obj->bs = compute_blocking_structure(file->transfer_len, file->max_sb_len, file->es_len);
00750 
00751                                 if (!(obj->block_list = (trans_block_t*)calloc(obj->bs->N, sizeof(trans_block_t)))) {
00752                                         printf("Could not alloc memory for transport block list!\n");
00753                                         *retval = -1;
00754                                         return NULL;
00755                                 }
00756 
00757                                 memset(filename, 0, MAX_PATH_LENGTH);
00758 
00759                                 if(file->encoding == NULL) {
00760 #ifdef _MSC_VER
00761                                         sprintf(filename, "%s\\%s", get_session_basedir(receiver->s_id), "object_XXXXXX");
00762 #else                 
00763                                         sprintf(filename, "%s/%s", get_session_basedir(receiver->s_id), "object_XXXXXX");
00764 #endif
00765                                         mktemp(filename);
00766                                 }
00767 #ifdef USE_ZLIB
00768                                 else if(strcmp(file->encoding, "gzip") == 0) {
00769 #ifdef _MSC_VER
00770                                         sprintf(filename, "%s\\%s", get_session_basedir(receiver->s_id), "object_XXXXXX");
00771 #else
00772                                         sprintf(filename, "%s/%s", get_session_basedir(receiver->s_id), "object_XXXXXX");
00773 #endif
00774                                         mktemp(filename);
00775                                         strcat(filename, GZ_SUFFIX);
00776                                 }
00777 #endif
00778                                 else {
00779                                         printf("Not supported encoding: %s\n", file->encoding);
00780                                         *retval = -1;
00781                                         return NULL;
00782                                 }
00783 
00784                                 /* Alloc memory for tmp_filename */
00785                                 if(!(obj->tmp_filename = (char*)calloc(strlen(filename)+1, sizeof(char)))) {
00786                                         printf("Could not alloc memory for tmp_filename!\n");
00787                                         *retval = -1;
00788                                         return NULL;
00789                                 }
00790 
00791                                 memcpy(obj->tmp_filename, filename, strlen(filename));
00792 
00793 #ifdef _MSC_VER
00794                                 if((obj->fd = open((const char*)obj->tmp_filename,
00795                                         _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC , _S_IWRITE)) < 0) {
00796 #else
00797                                 if((obj->fd = open(obj->tmp_filename,
00798                                         O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU)) < 0) {
00799 #endif
00800                                                 printf("Error: unable to open file %s\n", obj->tmp_filename);
00801                                                 fflush(stdout);
00802                                                 *retval = -1;
00803                                                 return NULL;
00804                                 }
00805 
00806                                 insert_object(obj, s, 1);
00807                         }
00808                         else {
00809                                 /* Object has been received partly and it is found from the object structure */
00810 
00811                                 block = obj->block_list;
00812 
00813                                 for(j = 0; j < obj->bs->N; j++) {
00814 
00815                                         if(block->nb_of_rx_units != 0 && block_ready_to_decode(block)) {
00816                                                 /* We have a complete block */
00817                                                 block = obj->block_list+(j+1);
00818                                                 continue;
00819                                         }
00820                                         else if(block->nb_of_rx_units == 0) {
00821                                                 /* We have completely missing block */
00822 
00823                                                 strcat(query_string, "&SBN=");
00824                                                 memset(tmp_string, 0, 10);
00825                                                 sprintf(tmp_string, "%i", j);
00826                                                 strcat(query_string, tmp_string);
00827 
00828                                                 if(strlen(query_string) > 200) {
00829 
00830                                                         code = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, query_string);
00831 
00832                                                         if(code != CURLE_OK) {
00833                                                                 printf("Failed to set postfields [%s]\n", errorBuffer);
00834                                                         *retval = -1;
00835                                                                 return NULL;
00836                                                         }
00837 
00838                                                         printf("%s\n", query_string);
00839                                                         
00840                                                         content.data = NULL;
00841                                                         content.size = 0;
00842 
00843                                                         code = curl_easy_perform(curl);
00844 
00845                                                         if(code != CURLE_OK) {
00846                                                                 printf("Failed to get repair data for '%s' [%s]\n", query_string, errorBuffer);
00847                                                                 if(content.data != NULL) {
00848                                                                         free(content.data);
00849                                                                 }
00850                                                                 *retval = -1;
00851                                                                 return NULL;
00852                                                         }
00853 
00854                                                         code = curl_easy_getinfo(curl , CURLINFO_HTTP_CODE , &response_code);
00855 
00856                                                         if(code != CURLE_OK) {
00857                                                                 printf("Failed to get http response code [%s]\n", errorBuffer);
00858                                                                 if(content.data != NULL) {
00859                                                                         free(content.data);
00860                                                                 }
00861                                                                 *retval = -1;
00862                                                                 return NULL;
00863                                                         }
00864 
00865                                                         code = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &content_type);
00866 
00867                                                         if(code != CURLE_OK) {
00868                                                                 printf("Failed to get content type [%s]\n", errorBuffer);
00869                                                                 *retval = -1;
00870                                                                 if(content.data != NULL) {
00871                                                                         free(content.data);
00872                                                                 }
00873                                                                 return NULL;
00874                                                         }
00875 
00876                                                         for(x = 0; x < (int)strlen(content_type); x++) {
00877                                                           content_type[x] = tolower(content_type[x]);
00878                                                         }
00879                                                         
00880                                                         if(response_code == 200) {
00881                                                                 if(strcmp(content_type, "application/simplesymbolcontainer") == 0) {
00882                                                                         if(parse_data(content, file, obj, s, openfile) < 0) {
00883                                                                         }
00884                                                                         free(content.data);
00885                                                                 }
00886                                                                 else  {
00887 
00888                                                                         if(sdp_buf == NULL) {
00889                                                                                 sdp_buf = content.data;
00890                                                                         }
00891                                                                         else {
00892                                                                                 free(content.data);
00893                                                                         }
00894 
00895                                                                         code = curl_easy_setopt(curl, CURLOPT_URL, serviceURI);
00896                                                                         
00897                                                                         if(code != CURLE_OK) {
00898                                                                                 printf("Failed to set URL [%s]\n", errorBuffer);
00899                                                                                 if(content.data != NULL) {
00900                                                                                         free(content.data);
00901                                                                                 }
00902                                                                                 *retval = -1;
00903                                                                                 return NULL; 
00904                                                                         }
00905                                                                 }
00906                                                         }
00907                                                         else {
00908                                                                 printf("Response code [%lu]\n", response_code);
00909                                                                 free(content.data);
00910                                                                 *retval = -1;
00911                                                                 return NULL; 
00912                                                         }
00913 
00914                                                         memset(query_string, 0, MAX_HTTP_URL_LENGTH);
00915                                                         strcpy(query_string, "fileURI=");
00916                                                         strcat(query_string, file->location);
00917                                                 }
00918                                         }
00919                                         else {
00920                                                 /* We have partly missing block */
00921                                                 counter = 0;
00922 
00923                                                 for(i = 0;i < 255; i++) {
00924                                                         esi_table[i] = 0;
00925                                                 }
00926 
00927                                                 if(!block_ready_to_decode(block)) {
00928                                                         unit = block->unit_list;
00929 
00930                                                         while(unit != NULL) {
00931                                                                 esi_table[unit->esi] = 1;
00932                                                                 unit = unit->next;
00933                                                         }
00934 
00935                                                         first_esi = 1;
00936 
00937                                                         /* Now we are fetching only source symbols */
00938                                                         nb_of_missing_symbols = (block->k - block->nb_of_rx_units);
00939 
00940                                                         for(i = 0; i < (int)block->k; i++) {
00941                                                                 if(counter == nb_of_missing_symbols) {
00942                                                                         break;
00943                                                                 }
00944 
00945                                                                 if(esi_table[i] != 1) {
00946                                                                         counter++;
00947 
00948                                                                         if(first_esi) {     
00949                                                                                 memset(tmp_string, 0, 10);
00950                                                                                 strcat(query_string, "&SBN=");
00951                                                                                 sprintf(tmp_string, "%i", block->sbn);
00952                                                                                 strcat(query_string, tmp_string);
00953 
00954                                                                                 memset(tmp_string, 0, 10);
00955                                                                                 strcat(query_string, ";ESI=");
00956                                                                                 sprintf(tmp_string, "%i", i);
00957                                                                                 strcat(query_string, tmp_string);
00958                                                                                 first_esi = 0;
00959                                                                         }
00960                                                                         else {
00961                                                                                 memset(tmp_string, 0, 10);
00962                                                                                 strcat(query_string, ",");
00963                                                                                 sprintf(tmp_string, "%i", i);
00964                                                                                 strcat(query_string, tmp_string);
00965                                                                         }
00966 
00967                                                                         if(strlen(query_string) > 200) {
00968 
00969                                                                                 code = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, query_string);
00970 
00971                                                                                 if(code != CURLE_OK) {
00972                                                                                         printf("Failed to set postfields [%s]\n", errorBuffer);
00973                                                                                 *retval = -1;
00974                                                                                         return NULL;
00975                                                                                 }
00976 
00977                                                                                 printf("%s\n", query_string);
00978                                                                                 
00979                                                                                 content.data = NULL;
00980                                                                                 content.size = 0;
00981 
00982                                                                                 code = curl_easy_perform(curl);
00983 
00984                                                                                 if(code != CURLE_OK) {
00985                                                                                         printf("Failed to get repair data for '%s' [%s]\n", query_string, errorBuffer);
00986                                                                                         if(content.data != NULL) {
00987                                                                                                 free(content.data);
00988                                                                                         }
00989                                                                                         *retval = -1;
00990                                                                                         return NULL;
00991                                                                                 }
00992 
00993                                                                                 code = curl_easy_getinfo(curl , CURLINFO_HTTP_CODE , &response_code);
00994 
00995                                                                                 if(code != CURLE_OK) {
00996                                                                                         printf("Failed to get http response code [%s]\n", errorBuffer);
00997                                                                                         if(content.data != NULL) {
00998                                                                                                 free(content.data);
00999                                                                                         }
01000                                                                                         *retval = -1;
01001                                                                                         return NULL;
01002                                                                                 }
01003 
01004                                                                                 code = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &content_type);
01005 
01006                                                                                 if(code != CURLE_OK) {
01007                                                                                         printf("Failed to get content type [%s]\n", errorBuffer);
01008                                                                                         if(content.data != NULL) {
01009                                                                                                 free(content.data);
01010                                                                                         }
01011                                                                                         *retval = -1;
01012                                                                                         return NULL;
01013                                                                                 }
01014 
01015                                                                                 for(x = 0; x < (int)strlen(content_type); x++) {
01016                                                                                   content_type[x] = tolower(content_type[x]);
01017                                                                                 }
01018 
01019                                                                                 if(response_code == 200) {
01020                                                                                         if(strcmp(content_type, "application/simplesymbolcontainer") == 0) {
01021                                                                                                 if(parse_data(content, file, obj, s, openfile) < 0) {
01022                                                                                                 }
01023                                                                                                 free(content.data);
01024                                                                                         }
01025                                                                                         else  {
01026                                                                                                 if(sdp_buf == NULL) {
01027                                                                                                         sdp_buf = content.data;
01028                                                                                                 }
01029                                                                                                 else {
01030                                                                                                         free(content.data);
01031                                                                                                 }
01032 
01033                                                                                                 code = curl_easy_setopt(curl, CURLOPT_URL, serviceURI);
01034 
01035                                                                                                 if(code != CURLE_OK) {
01036                                                                                                         printf("Failed to set URL [%s]\n", errorBuffer);
01037                                                                                                         if(content.data != NULL) {
01038                                                                                                                 free(content.data);
01039                                                                                                         }
01040                                                                                                         *retval = -1;
01041                                                                                                         return NULL; 
01042                                                                                                 }
01043                                                                                         }
01044                                                                                 }
01045                                                                                 else {
01046                                                                                         printf("Response code [%lu]\n", response_code);
01047                                                                                         free(content.data);
01048                                                                                         *retval = -1;
01049                                                                                         return NULL; 
01050                                                                                 }
01051 
01052                                                                                 memset(query_string, 0, MAX_HTTP_URL_LENGTH);
01053                                                                                 strcpy(query_string, "fileURI=");
01054                                                                                 strcat(query_string, file->location);
01055                                                                                 first_esi = 1;
01056                                                                         }
01057                                                                 }
01058                                                         }
01059                                                 }
01060                                         }
01061                                         block = obj->block_list+(j+1);
01062                                 }
01063                         }
01064                 }
01065 
01066                 code = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, query_string);
01067                 
01068                 if(code != CURLE_OK) {
01069                         printf("Failed to set postfields [%s]\n", errorBuffer);
01070                         *retval = -1;
01071                         return NULL;
01072                 }
01073                 
01074                 printf("%s\n", query_string);
01075 
01076                 content.data = NULL;
01077                 content.size = 0;
01078 
01079                 code = curl_easy_perform(curl);
01080 
01081                 if(code != CURLE_OK) {
01082                         printf("Failed to get repair data for '%s' [%s]\n", query_string, errorBuffer);
01083                         if(content.data != NULL) {
01084                                 free(content.data);
01085                         }
01086                         *retval = -1;
01087                         return NULL;
01088                 }
01089 
01090                 code = curl_easy_getinfo(curl , CURLINFO_HTTP_CODE , &response_code);
01091 
01092                 if(code != CURLE_OK) {
01093                         printf("Failed to get http response code [%s]\n", errorBuffer);
01094                         if(content.data != NULL) {
01095                                 free(content.data);
01096                         }
01097                         *retval = -1;
01098                         return NULL;
01099                 }
01100 
01101                 code = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &content_type);
01102 
01103                 if(code != CURLE_OK) {
01104                         printf("Failed to get content type [%s]\n", errorBuffer);
01105                         if(content.data != NULL) {
01106                                 free(content.data);
01107                         }
01108                         *retval = -1;
01109                         return NULL;
01110                 }
01111 
01112                 for(x = 0; x < (int)strlen(content_type); x++) {
01113                   content_type[x] = tolower(content_type[x]);
01114                 }
01115 
01116                 if(response_code == 200) {
01117                         if(strcmp(content_type, "application/simplesymbolcontainer") == 0) {
01118                                 if(parse_data(content, file, obj, s, openfile) < 0) {
01119                                 }
01120                                 free(content.data);
01121                         }
01122                         else  {
01123 
01124                                 if(sdp_buf == NULL) {
01125                                         sdp_buf = content.data;
01126                                 }
01127                                 else {
01128                                         free(content.data);
01129                                 }
01130 
01131                                 code = curl_easy_setopt(curl, CURLOPT_URL, serviceURI);
01132 
01133                                 if(code != CURLE_OK) {
01134                                         printf("Failed to set URL [%s]\n", errorBuffer);
01135                                         if(content.data != NULL) {
01136                                                 free(content.data);
01137                                         }
01138                                         *retval = -1;
01139                                         return NULL; 
01140                                 }
01141                         }
01142                 }
01143                 else {
01144                         printf("Response code [%lu]\n", response_code);
01145                         free(content.data);
01146                         *retval = -1;
01147                         return NULL; 
01148                 }
01149 
01150                 file = file->next;
01151         }
01152 
01153         *retval = 0;
01154         return sdp_buf;
01155 }
01156 
01157 #endif

Generated on Fri Mar 9 20:08:52 2007 for MAD-FCL by  doxygen 1.5.0