Files
ModManager/src/file.c
T
2022-10-05 08:35:10 +02:00

122 lines
2.6 KiB
C

#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <glib.h>
#include "file.h"
static u_int32_t countSetBits(u_int32_t n) {
// base case
if (n == 0)
return 0;
else
// if last bit set add 1 else add 0
return (n & 1) + countSetBits(n >> 1);
}
//TODO: add interruption support
//simplest way to copy a file in c(linux)
int copy(const char * path, const char * dest, u_int32_t flags) {
int flagCount = countSetBits(flags);
if(flagCount > 3) {
fprintf(stderr, "Invalid flags for cp command\n");
return -1;
}
//flags + cp + path + dest
const char * args[flagCount + 4];
args[0] = "/bin/cp";
args[1] = path;
args[2] = dest;
int argIndex = 3;
if(flags & CP_LINK) {
args[argIndex] = "--link";
argIndex += 1;
}
if(flags & CP_RECURSIVE) {
args[argIndex] = "-r";
argIndex += 1;
}
if(flags & CP_NO_TARGET_DIR) {
args[argIndex] = "-T";
argIndex += 1;
}
args[argIndex] = NULL;
int pid = fork();
if(pid == 0) {
//discard the const. since we are in a fork we don't care.
execv("/bin/cp", (char **)args);
return 0;
} else {
int returnValue;
waitpid(pid, &returnValue, 0);
return returnValue;
}
}
int delete(const char * path, bool recursive) {
int pid = fork();
if(pid == 0) {
if(recursive) {
execl("/bin/rm", "/bin/rm", "-r", path, NULL);
} else {
execl("/bin/rm", "/bin/rm", path, NULL);
}
return 0;
} else {
int returnValue;
waitpid(pid, &returnValue, 0);
return returnValue;
}
}
int move(const char * source, const char * destination) {
int pid = fork();
if(pid == 0) {
execl("/bin/mv", "/bin/mv", source, destination, NULL);
return 0;
} else {
int returnValue;
waitpid(pid, &returnValue, 0);
return returnValue;
}
}
//rename a folder and all subfolder and files to lowercase
//TODO: error handling
void casefold(const char * folder) {
DIR * d = opendir(folder);
struct dirent *dir;
if (d) {
while ((dir = readdir(d)) != NULL) {
//removes .. & . from the list
if(strcmp(dir->d_name, "..") != 0 && strcmp(dir->d_name, ".") != 0) {
//only look at ascii and hope for the best.
gchar * file = g_build_path("/", folder, dir->d_name, NULL);
gchar * destinationName = g_ascii_strdown(dir->d_name, -1);
gchar * destination = g_build_path("/", folder,destinationName, NULL);
int result = move(file, destination);
if(result != EXIT_SUCCESS) {
fprintf(stderr, "Move failed: %s => %s \n", dir->d_name, destinationName);
}
g_free(destinationName);
g_free(destination);
if(dir->d_type == DT_DIR) {
casefold(file);
}
g_free(file);
}
}
closedir(d);
}
}