Skip to content

Instantly share code, notes, and snippets.

@iambriccardo
Created April 18, 2020 16:08
Show Gist options
  • Select an option

  • Save iambriccardo/1656b5fdee950aaebeb00368e8ca2552 to your computer and use it in GitHub Desktop.

Select an option

Save iambriccardo/1656b5fdee950aaebeb00368e8ca2552 to your computer and use it in GitHub Desktop.
#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