Created
April 18, 2020 16:08
-
-
Save iambriccardo/1656b5fdee950aaebeb00368e8ca2552 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <unistd.h> | |
| #include <stdlib.h> | |
| #include <pthread.h> | |
| #include <dirent.h> | |
| #include "fcopy.h" | |
| #include <string.h> | |
| /* MACROS */ | |
| #define MAX_MP3_TRANSFER 100 | |
| #define MAX_PARALLEL_DOWNLOADS 3 | |
| #define AVAILABLE_MP3_FILES 4 | |
| /* STRUCTS */ | |
| struct thread_args { | |
| int thread_index; | |
| char *path_from; | |
| char *path_to; | |
| } typedef pthread_args; | |
| struct thread_status { | |
| time_t starting_time; | |
| time_t ending_time; | |
| } typedef pthread_status; | |
| /* GLOBAL VARIABLES */ | |
| char *available_mp3_files[AVAILABLE_MP3_FILES] = { | |
| "http://www.gutenberg.org/files/10246/10246-m/10246-m-001.mp3", | |
| "http://www.gutenberg.org/files/10179/10179-m/10179-m-001.mp3", | |
| "http://www.gutenberg.org/files/10306/10306-m/10306-m-001.mp3", | |
| "http://www.gutenberg.org/files/10177/10177-m/10177-m-001.mp3" | |
| }; | |
| pthread_status mp3_transfer_pthreads_statuses[MAX_MP3_TRANSFER]; | |
| /* FUNCTIONS PROTOTYPES */ | |
| char *concat(const char *s1, const char *s2); | |
| void print_available_mp3_files(); | |
| int get_all_mp3_file_names(char **mp3_file_names, int size); | |
| void download_mp3_files(); | |
| void *async_mp3_copy(void *args); | |
| void copy_mp3_files_to_folder(char *folder_name); | |
| /* ENTRYPOINT */ | |
| int main() { | |
| download_mp3_files(); | |
| copy_mp3_files_to_folder("./mp3/"); | |
| return 0; | |
| } | |
| /* FUNCTIONS IMPLEMENTATIONS */ | |
| char *concat(const char *s1, const char *s2) { | |
| char *result = malloc(strlen(s1) + strlen(s2) + 1); | |
| strcpy(result, s1); | |
| strcat(result, s2); | |
| return result; | |
| } | |
| void print_available_mp3_files() { | |
| for (int i = 0; i < AVAILABLE_MP3_FILES; i++) { | |
| printf("Press %i for the audio file -> %s\n", i, available_mp3_files[i]); | |
| } | |
| } | |
| int get_all_mp3_file_names(char **mp3_file_names, int size) { | |
| int j = 0; | |
| DIR *directory; | |
| char *file_name, *extension; | |
| int comparison_result; | |
| struct dirent *dir; | |
| directory = opendir("."); | |
| if (directory) { | |
| while (j < size && (dir = readdir(directory)) != NULL) { | |
| file_name = strtok(dir->d_name, "."); | |
| extension = strtok(NULL, "."); | |
| if (extension != NULL) { | |
| comparison_result = strcmp(extension, "mp3"); | |
| if (comparison_result == 0) { | |
| mp3_file_names[j] = concat(file_name, concat(".", extension)); | |
| j++; | |
| } | |
| } | |
| } | |
| } | |
| closedir(directory); | |
| return j; | |
| } | |
| void download_mp3_files() { | |
| pid_t pids[MAX_PARALLEL_DOWNLOADS]; | |
| int i = 0; | |
| while (i < MAX_PARALLEL_DOWNLOADS) { | |
| int file_index; | |
| printf("Choose the file from the list:\n"); | |
| print_available_mp3_files(); | |
| scanf("%i", &file_index); | |
| if (file_index >= 0 && file_index < AVAILABLE_MP3_FILES) { | |
| pids[i] = fork(); | |
| if (pids[i] == 0) { | |
| printf("Downloading file %s...\n", available_mp3_files[file_index]); | |
| execlp("curl", "curl", "-Os", available_mp3_files[file_index], NULL); | |
| } else if (pids[i] < 0) { | |
| printf("Error while forking.\n"); | |
| exit(0); | |
| } else if (pids[i] > 0) { | |
| i++; | |
| } | |
| } else { | |
| break; | |
| } | |
| } | |
| for (int j = 0; j < i; j++) { | |
| printf("Waiting for the download to finish...\n"); | |
| wait(&pids[j]); | |
| } | |
| } | |
| void *async_mp3_copy(void *args) { | |
| time_t start_time = time(NULL); | |
| fcopy(((pthread_args *) args)->path_from, ((pthread_args *) args)->path_to); | |
| time_t end_time = time(NULL); | |
| pthread_status status = {start_time, end_time}; | |
| mp3_transfer_pthreads_statuses[((pthread_args *) args)->thread_index] = status; | |
| return NULL; | |
| } | |
| void copy_mp3_files_to_folder(char *folder_name) { | |
| char *mp3_file_names[MAX_MP3_TRANSFER]; | |
| int mp3_files_found = get_all_mp3_file_names(mp3_file_names, MAX_MP3_TRANSFER); | |
| pthread_t tids[mp3_files_found]; | |
| for (int i = 0; i < mp3_files_found; i++) { | |
| pthread_attr_t attr; | |
| pthread_attr_init(&attr); | |
| pthread_args *args = (pthread_args *) malloc(sizeof(pthread_args)); | |
| args->thread_index = i; | |
| args->path_from = mp3_file_names[i]; | |
| args->path_to = concat(folder_name, mp3_file_names[i]); | |
| pthread_create(&tids[i], &attr, async_mp3_copy, args); | |
| } | |
| for (int i = 0; i < mp3_files_found; i++) { | |
| pthread_join(tids[i], NULL); | |
| printf("Copy of %s into folder %s lasted from %i to %i\n", mp3_file_names[i], folder_name, | |
| mp3_transfer_pthreads_statuses[i].starting_time, mp3_transfer_pthreads_statuses[i].ending_time); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment