📄 main.c
字号:
/* * Let's check and see the status of each connection */ switch (connections[i].status) { /*fixme */ case MAXTRYS: die("Connection %d has been tried %d time(s) and has failed. " "Aborting!", i + 1, rt.try_attempts); break; case LOGINFAIL: /*shit we have been kicked out, is this the firs time*/ if( connections[i].ftp_login_reject_start==0) connections[i].ftp_login_reject_start=time(0); /* * First check if the ftp server did not allow any thread * to login at all, then retry the curent thread */ if (all_dls_failed_login(connections, rt.num_connections) == TRUE) { /* * Well the FTP server has disallowed all the connections * login attempts...so we will continue to retry this thread */ message("All logins rejected! Retrying connection"); /* * make sure this thread has terminated */ pthread_join(threads[i], NULL); /* * Relaunch it */ connections[i].status = IDLE; if (pthread_create(&threads[i], NULL, (void *) &ftp_loop, (void *) (&connections[i])) != 0) die("Error: Not enough system resources to create thread!\n"); break; } else { /* * Ok so at least there is one download whos login 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 dling_conns_count = query_downloading_conns_count(connections, rt.num_connections); if (dling_conns_count == 0 && (query_connecting_conns_count (connections, rt.num_connections) == 0) && (query_logging_conns_count (connections, rt.num_connections) == 0)) { /* * make sure this thread has terminated */ pthread_join(threads[i], NULL); /* * Relaunch it */ connections[i].status = IDLE; pthread_mutex_lock(&status_change_mutex); if (pthread_create(&threads[i], NULL, (void *) &ftp_loop, (void *) (&connections[i])) != 0) die("Error: Not enough system resources to create thread!\n"); pthread_cond_wait(&connecting_cond, &status_change_mutex); pthread_mutex_unlock(&status_change_mutex); break; } else { if (dling_conns_count > max_simul_conns) { max_simul_conns = dling_conns_count; break; } if ((dling_conns_count < max_simul_conns) && (query_connecting_conns_count (connections, rt.num_connections) == 0) && (query_logging_conns_count (connections, rt.num_connections) == 0)) { /* * make sure this thread has terminated */ pthread_join(threads[i], NULL); /* * Relaunch it */ connections[i].status = IDLE; pthread_mutex_lock(&status_change_mutex); if (pthread_create(&threads[i], NULL, (void *) &ftp_loop, (void *) (&connections[i])) != 0) die("Error: Not enough system resources to create thread!\n"); pthread_cond_wait(&connecting_cond, &status_change_mutex); pthread_mutex_unlock(&status_change_mutex); break; } /* Or else is it time to retry again, ie to check and see whether a user disconnected :-) */ if(time(0)>= connections[i].ftp_login_reject_start+RETRY_LOGIN_TIME) { /* try loggin in again */ /* * make sure this thread has terminated */ pthread_join(threads[i], NULL); /* * Relaunch it */ connections[i].status = IDLE; pthread_mutex_lock(&status_change_mutex); if (pthread_create(&threads[i], NULL, (void *) &ftp_loop, (void *) (&connections[i])) != 0) die("Error: Not enough system resources to create thread!\n"); pthread_cond_wait(&connecting_cond, &status_change_mutex); pthread_mutex_unlock(&status_change_mutex); break; } } } break; case CONREJECT: /* * First check if the ftp server did not allow any thread * to connect at all, then retry the curent thread */ if (all_dls_connect_rejected(connections, rt.num_connections) == TRUE) { message("FTP server rejected all the connections!" "Retrying conection"); /* * make sure this thread has terminated */ pthread_join(threads[i], NULL); /* * Relaunch it */ connections[i].status = IDLE; if (pthread_create(&threads[i], NULL, (void *) &ftp_loop, (void *) (&connections[i])) != 0) die("Error: Not enough system resources to create thread!\n"); break; } else { /* * Ok so at least there is one download who's connection 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 connection request * being rejected is because, the ftp server has a limit on the number of * connection requests permitted from the same IP address. */ /* * Query the number of threads that are downloading * if it is zero then relaunch this connection */ int dling_conns_count = query_downloading_conns_count(connections, rt.num_connections); if ((dling_conns_count == 0) && (query_connecting_conns_count (connections, rt.num_connections) == 0) && (query_logging_conns_count (connections, rt.num_connections) == 0)) { /* * make sure this thread has terminated */ pthread_join(threads[i], NULL); /* * Relaunch it */ connections[i].status = IDLE; pthread_mutex_lock(&status_change_mutex); if (pthread_create(&threads[i], NULL, (void *) &ftp_loop, (void *) (&connections[i])) != 0) die("Error: Not enough system resources to create thread!\n"); pthread_cond_wait(&connecting_cond, &status_change_mutex); pthread_mutex_unlock(&status_change_mutex); break; } else { if (dling_conns_count > max_simul_conns) { max_simul_conns = dling_conns_count; break; } if ((dling_conns_count < max_simul_conns) && (query_connecting_conns_count (connections, rt.num_connections) == 0) && (query_logging_conns_count (connections, rt.num_connections) == 0)) { /* * make sure this thread has terminated */ pthread_join(threads[i], NULL); /* * Relaunch it */ connections[i].status = IDLE; pthread_mutex_lock(&status_change_mutex); if (pthread_create(&threads[i], NULL, (void *) &ftp_loop, (void *) (&connections[i])) != 0) die("Error: Not enough system resources to create thread!\n"); pthread_cond_wait(&connecting_cond, &status_change_mutex); pthread_mutex_unlock(&status_change_mutex); break; } } } break; case LOCALFATAL: die("A local error occured in connection %d, aborting...\n", i + 1); break; default: break; } } pthread_mutex_lock(&compute_throttle_mutex); calc_throttle_factor(connections, rt.num_connections); pthread_mutex_unlock(&compute_throttle_mutex);}/* * terminates the running threads */void terminate_threads(pthread_t * threads, int num_threads){ int i; for (i = 0; i < num_threads; i++) { pthread_cancel(threads[i]); } for (i = 0; i < num_threads; i++) { pthread_join(threads[i], NULL); }}/* * This function will check for the target file and if it is present will ask * the user what action he/she wishes to do */int query_overwrite_target(char *fname){ char buffer[MAXPATHLEN + 1]; struct stat st_buf; int ret; char *p_file; /* get the prefixed name */ p_file = get_prefixed_file(fname); ret = stat(p_file, &st_buf); if (ret == -1) { if (errno == ENOENT) return 0; else return -1; } /* * The File exists, ask the user what to do */ do { ret = curses_query_user_input ("Warning: The file %s already exists!\nWould you like" " to (A)bort, (B)ack it up, (O)verwrite it?", p_file); } while (ret != 'O' && ret != 'A' && ret != 'B'); switch (ret) { case 'O': if (unlink(p_file) != 0) { if (errno == ENOENT) { /* * somehow the file which was supposed to be overwritten * does not seem to exist??? anyway return since it is, * not a problem */ return 0; } else { die("Error while trying to delete %s :", p_file, strerror(errno)); } } break; case 'A': die("OK, aborting..."); break; case 'B': snprintf(buffer, sizeof(buffer), "%s~", p_file); message("Backing up %s to %s", p_file, buffer); debug_prz("Backing up %s to %s", p_file, buffer); if (rename(p_file, buffer) == -1) { if (errno == ENOENT) { /* * somehow the file which was supposed to be backed up * does not seem to exist??? Anyway return since it is, * not a problem */ return 0; } else { die("Error trying to rename %s to %s : %s", p_file, buffer, strerror(errno)); } } break; } return 0;}/* If the logfile is present then it indicates that the previous download * has not been completed */void query_resume_old_download(urlinfo * u){ int ret; if (u->resume_support == TRUE) { do { ret = curses_query_user_input ("Warning: Previous incomplete download of %s detected!\n" "Would you like to (A)bort, (R)esume it, (O)verwrite it?", u->file); } while (ret != 'A' && ret != 'R' && ret != 'O'); } else { do { ret = curses_query_user_input ("Warning: Previous incomplete download of %s detected!\n" "The Server does not support resuming so would you like to (A)bort, (O)verwrite it?", u->file); } while (ret != 'A' && ret != 'O'); } switch (ret) { case 'A': die("OK, aborting..."); break; case 'R': /* * turn the resume mode on */ rt.run_mode = RESUME; break; case 'O': delete_file_portions(u); break; } return;}/* Message: calls the appropriate routine to display the msg */void message(const char *args, ...){ char p[MAX_MSG_SIZE]; va_list vp; va_start(vp, args); vsnprintf(p, sizeof(p), args, vp); va_end(vp); switch (rt.display_mode) { case DISPLAY_CURSES: curses_message(p); break;#ifdef HAVE_GTK case DISPLAY_GTK: gtk_message(p); break;#endif default: die("Unsupported display mode"); }}/* Deletes any downloaded file portions if present. * It determines the number of file portions by checking for * a logfile and reading the number of conenctions from it. * If the logfile is not present then it assumes that there are 4 portions */void delete_file_portions(urlinfo * u){ logfile lf; int ret; int i; int num_connections = 0; char buffer[MAXPATHLEN]; memset(&lf, 0, sizeof(logfile)); ret = log_logfile_exists(u); if (ret == -1) { /* * Something wrong hapenned
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -