📄 download.c
字号:
download_show_message(download, _("Relaunching download")); if (pthread_create(&download->threads[i], NULL, (void *) &ftp_loop, (void *) (download->pconnections[i])) != 0) proz_die(_("Error: Not enough system resources")); pthread_cond_wait(&download->pconnections[i]->connecting_cond, &download->status_change_mutex); pthread_mutex_unlock(&download->status_change_mutex); } else if (dling_conns_count < download->ftps_info->mirrors[server_pos]. max_simul_connections && (download_query_conns_status_count (download, CONNECTING, download->pconnections[i]->u.host) == 0) && (download_query_conns_status_count (download, LOGGININ, download->pconnections[i]->u.host) == 0)) { /* Make sure this thread has terminated */ pthread_join(download->threads[i], NULL); pthread_mutex_lock(&download->status_change_mutex); download_show_message(download, _("Relaunching download")); if (pthread_create(&download->threads[i], NULL, (void *) &ftp_loop, (void *) (download->pconnections[i])) != 0) proz_die(_("Error: Not enough system resources")); pthread_cond_wait(&download->pconnections[i]->connecting_cond, &download->status_change_mutex); pthread_mutex_unlock(&download->status_change_mutex); } } } break; case CONREJECT: /* * First check if the ftp server did not allow any thread * to login at all, then retry the curent thread */ if (proz_download_all_dls_status(download, CONREJECT) == TRUE) { download_show_message(download, _ ("All connections attempts have been rejected! Retrying connection")); /* Make sure this thread has terminated */ pthread_join(download->threads[i], NULL); if (pthread_create (&download->threads[i], NULL, (void *) &ftp_loop, (void *) (download->pconnections[i])) != 0) proz_die(_("Error: Not enough system resources")); break; } else { int j, usable_server; /*Find any server that is downloading or completed and use it instead */ usable_server = -1; pthread_mutex_lock(&download->status_change_mutex); for (j = 0; j < download->num_connections; j++) { if ((download->pconnections[j]->status == DOWNLOADING || download->pconnections[j]->status == COMPLETED) && j!=i) { usable_server = j; } } pthread_mutex_unlock(&download->status_change_mutex); if (usable_server != -1) { /*We have a server which is DLING */ download_show_message(download, _ ("This server has rejected the connection attempt, so will switch to another server")); /* Make sure this thread has terminated */ pthread_join(download->threads[i], NULL); /*copy url and relaunch */ proz_free_url(&download->pconnections[i]->u, 0); memcpy(&download->pconnections[i]->u, proz_copy_url(&download-> pconnections[usable_server]->u), sizeof(urlinfo)); proz_debug ("Found server %s which is downloading will relaunch based on it", download->pconnections[usable_server]->u.host); /*Relaunch thread */ if (pthread_create (&download->threads[i], NULL, (void *) &ftp_loop, (void *) (download->pconnections[i])) != 0) proz_die(_("Error: Not enough system resources")); } else { /* * Ok so at least there is one download whos connections attempt has not been rejected, * so lets see if it has completed, if so we can relaunch this connection, * as the commonest reason for a ftp login being rejected is because, the * ftp server has a limit on the number of logins permitted from the same * IP address. */ /* * Query the number of threads that are downloading * if it is zero then relaunch this connection */ int server_pos; int dling_conns_count = download_query_conns_status_count(download, DOWNLOADING, download-> pconnections[i]->u.host); server_pos = ftpsearch_get_server_position(download->ftps_info, download->pconnections[i]->u.host); if (dling_conns_count > download->ftps_info->mirrors[server_pos].max_simul_connections) { download->ftps_info->mirrors[server_pos].max_simul_connections = dling_conns_count; break; } if (dling_conns_count == 0 && (download_query_conns_status_count (download, CONNECTING, download->pconnections[i]->u.host) == 0) && (download_query_conns_status_count (download, LOGGININ, download->pconnections[i]->u.host) == 0)) { /* Make sure this thread has terminated */ pthread_join(download->threads[i], NULL); pthread_mutex_lock(&download->status_change_mutex); download_show_message(download, _("Relaunching download")); if (pthread_create(&download->threads[i], NULL, (void *) &ftp_loop, (void *) (download->pconnections[i])) != 0) proz_die(_("Error: Not enough system resources")); pthread_cond_wait(&download->pconnections[i]->connecting_cond, &download->status_change_mutex); pthread_mutex_unlock(&download->status_change_mutex); } else if (dling_conns_count < download->ftps_info->mirrors[server_pos]. max_simul_connections && (download_query_conns_status_count (download, CONNECTING, download->pconnections[i]->u.host) == 0) && (download_query_conns_status_count (download, LOGGININ, download->pconnections[i]->u.host) == 0)) { /* Make sure this thread has terminated */ pthread_join(download->threads[i], NULL); pthread_mutex_lock(&download->status_change_mutex); download_show_message(download, _("Relaunching download")); if (pthread_create(&download->threads[i], NULL, (void *) &ftp_loop, (void *) (download->pconnections[i])) != 0) proz_die(_("Error: Not enough system resources")); pthread_cond_wait(&download->pconnections[i]->connecting_cond, &download->status_change_mutex); pthread_mutex_unlock(&download->status_change_mutex); } } } break; default: break; } } /*bandwith throttling */ download_calc_throttle_factor(download); return DLINPROGRESS;}/****************************************************************************** This will setup a download based on the connection info and the ftpsearch results.******************************************************************************/int proz_download_setup_connections_ftpsearch(download_t * download, connection_t * connection, ftps_request_t * request, int req_connections){ int num_connections, i, num_usable_mirrors = 0; long bytes_per_connection; long bytes_left; FILE *fp; char *out_file; struct stat stat_buf; /*TODO Check for log file and use same number of threads */ download->main_file_size = connection->main_file_size; download->ftps_info = request; num_connections = req_connections; /*Are there any mirrors that are working? */ /**/ if (request->num_mirrors > 0 && request->mirrors[0].status == RESPONSEOK) { /*We should get the info and allocate here */ download->resume_support = TRUE; bytes_per_connection = connection->main_file_size / num_connections; bytes_left = connection->main_file_size % num_connections; /* Get the number of mirros that are within 200% ping speed of the fastest */ for (i = 0; i < request->num_mirrors; i++) { if ((request->mirrors[i].status == RESPONSEOK) && (request->mirrors[i].milli_secs <= (request->mirrors[0].milli_secs + ((request->mirrors[0].milli_secs * 100) / 100)))) num_usable_mirrors++; } proz_debug("usable mirrors = %d", num_usable_mirrors); proz_debug("num_connections = %d", num_connections); download->pconnections = kmalloc(sizeof(connection_t*) * num_connections); download->num_connections = num_connections; for (i = 0; i < num_connections; i++) { urlinfo *url = malloc(sizeof(urlinfo)); char *url_buf; if (i < num_usable_mirrors) { url_buf = malloc(strlen(request->mirrors[i].server_name) + strlen(request->mirrors[i].paths[0].path) + strlen(connection->u.file) + 11 + 1); sprintf(url_buf, "ftp://%s/%s/%s", request->mirrors[i].server_name, request->mirrors[i].paths[0].path, connection->u.file); proz_debug("Target url is %s", url_buf); /*FIXME */ proz_parse_url(url_buf, url, 0); free(url_buf); download->pconnections[i]=proz_connection_init(url, &download->status_change_mutex); } else { int extra_mirror = 0; /*FIXME improve allocation algorithm in this part */ url_buf = malloc(strlen(request->mirrors[extra_mirror].server_name) + strlen(request->mirrors[extra_mirror].paths[0].path) + strlen(connection->u.file) + 11 + 1); sprintf(url_buf, "ftp://%s/%s/%s", request->mirrors[extra_mirror].server_name, request->mirrors[extra_mirror].paths[0].path, connection->u.file); proz_debug("Target url is %s", url_buf); /*FIXME */ proz_parse_url(url_buf, url, 0); free(url_buf); download->pconnections[i]=proz_connection_init(url, &download->status_change_mutex); } download->resume_support = download->pconnections[i]->resume_support = TRUE; memcpy(&download->pconnections[i]->hs, &connection->hs, sizeof(http_stat_t)); out_file=kmalloc(PATH_MAX); snprintf(out_file, PATH_MAX, "%s/%s.prozilla", download->dl_dir, connection->u.file); //First see if the file exists then we dont create a new one else we do if (stat(out_file, &stat_buf) == -1) { /* the call failed */ /* if the error is due to the file not been present then there is no need to do anything..just continue, otherwise return error (-1) */ if (errno == ENOENT) { //File not exists so create it if (! (fp = fopen(out_file, "w+"))) { download_show_message(download, _ ("Unable to open file %s: %s!"), out_file, strerror(errno)); return -1; } } else return -1; } else { //TODO: File exists : so stat it and if it doesnt match file size warna boput it... if (! (fp = fopen(out_file, "r+"))) { download_show_message(download, _ ("Unable to open file %s: %s!"), out_file, strerror(errno)); return -1; } } //TRY setting the offset; if (download->main_file_size != -1) { if(fseek(fp, download->main_file_size, SEEK_SET)!=0) return -1; } /*Make sure all writes go directly to the file */ setvbuf(fp, NULL, _IONBF, 0); download->pconnections[i]->localfile = kmalloc(PATH_MAX); strcpy(out_file, download->pconnections[i]->localfile); download->pconnections[i]->fp=fp; download->pconnections[i]->retry = TRUE; download->pconnections[i]->main_file_size = connection->main_file_size; download->pconnections[i]->orig_remote_startpos = download->pconnections[i]->remote_startpos = i * bytes_per_connection; download->pconnections[i]->remote_endpos = i * bytes_per_connection + bytes_per_connection; //Changing things here..... download->pconnections[i]->local_startpos = download->pconnections[i]->remote_startpos; /*Set the connections message to be download->msg_proc calback */ proz_connection_set_msg_proc(download->pconnections[i], download->msg_proc, download->cb_data); } /* Add the remaining bytes to the last connection */ download->pconnections[--i]->remote_endpos += bytes_left; } else { proz_debug("No mirrors, which were up are found"); download->using_ftpsearch = FALSE; return proz_download_setup_connections_no_ftpsearch(download, connection, req_connections); } download->using_ftpsearch = TRUE; return num_connections;}uerr_t proz_download_get_join_status(download_t *download){ int building_status; pthread_mutex_lock(&download->access_mutex); building_status = download->building; pthread_mutex_unlock(&download->access_mutex); switch(building_status) { case 1: return JOININPROGRESS; case 0: return JOINDONE; case -1: return JOINERR; default: proz_die("Bad building falg in download structure"); }}float proz_download_get_file_build_percentage(download_t *download){ float percent_done; pthread_mutex_lock(&download->access_mutex); percent_done =100; pthread_mutex_unlock(&download->access_mutex); return percent_done;}void proz_download_cancel_joining_thread(download_t * download){ pthread_cancel(download->join_thread); pthread_join(download->join_thread, NULL);}void proz_download_wait_till_end_joining_thread(download_t * download){ pthread_join(download->join_thread, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -