I'm currently working on a problem that is a C program to allow me to keep directories in sync. The jist of it is:
- If a file is in Directory A and not in Directory B, copy the file to Directory B.
- If the file is in both Directory A and Directory B, copy the newest version of the file to the Directory with the oldest.
- If a file is in Directory B but not Directory A, delete the file.
I was having issues getting the full path of the files I need to open and delete. So I decided to use the C function chdir(path).
I am able to create a new file and remove the files, but for some reason, the data in the file is not copied even after opening two file streams to do so and I'm not sure why. The code is definitely messy, but I can't figure out where I'm going wrong. Insight would be appreciated. I am new to C and dealing with buffers and memory management is something I'm not quite good at just yet. Any ideas?
#include "csapp.h"
#include <stdio.h>
#include <dirent.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
// prototypes
bool inOtherDir(char*, char*);
void copyFile(char*, char*, char*, char*);
int isNewer(char*, char*, char*, char*);
int main(int argc, char **argv ) {
// variables
struct dirent *dirone;
struct dirent *dirtwo;
char* dirAPath = argv[1]; // this will be used for absolute paths
char* dirBPath = argv[2];
char cwd[256];
char* cwdptr = cwd;
// get the CWD for use later
if(getcwd(cwd, sizeof(cwd)) == NULL) {
perror("getcwd() error()");
return 1;
}
// Testing
// printf("CWD is: %s\n", cwd);
if (argc < 3) {
printf("Not enough arguments provided, please provide two directories.\n");
return 1;
}
// open directory a
DIR *ptrone = opendir(argv[1]);
// open directory b
DIR *ptrtwo = opendir(argv[2]);
if (ptrone == NULL || ptrtwo == NULL) {
printf("Could not open directory\n");
return 1;
}
printf("Checking Sync Status: \n");
// Open the directory and check to see if the file is a regular file
// if it is regular, then do work on it based on if its in the other
// directory or not.
while ((dirone = readdir(ptrone)) != NULL) {
if (dirone->d_type == DT_REG) {
if(inOtherDir(dirone->d_name, argv[2])) {
printf("File %s is in both directories.\n", dirone->d_name);
} else {
printf("File %s is in Directory A but not Directory B.\n", dirone->d_name);
printf("Copying %s in Directory A to Directory B.\n",dirone->d_name);
copyFile(dirone->d_name,dirAPath, dirBPath,cwdptr);
}
}
}
// check for files only in directory B, then delete them
while ((dirtwo = readdir(ptrtwo)) != NULL) {
if (dirtwo->d_type == DT_REG) {
if(inOtherDir(dirtwo->d_name, argv[1])) {
printf("File %s is in both directories.\n", dirtwo->d_name);
} else {
printf("File %s will be removed from the directory.\n",dirtwo->d_name);
chdir(dirBPath);
remove(dirtwo->d_name);
chdir(cwd);
}
}
}
closedir(ptrone);
closedir(ptrtwo);
return 0;
}
// Look through the directory to see if the same file is in there returns
// true if the file is in that directory and returns false if not.
bool inOtherDir(char* filename, char* direct) {
struct dirent *buf;
DIR *directory = opendir(direct);
if(directory == NULL) {
printf("Could not open directory.");
exit(1);
}
while((buf = readdir(directory)) != NULL) {
if ((strcmp(filename, buf->d_name)) == 0) {
return true;
}
}
closedir(directory);
return false;
}
// Copies the file from one directory to the other
void copyFile(char* filename, char* directory_from,char* directory_to, char* cwd) {
FILE *file, *copyfile;
char c;
chdir(directory_from);
file = fopen(filename,"r");
if(file == NULL) {
printf("Cannot open the file %s in copyFile.\n", filename);
}
chdir(cwd);
chdir(directory_to);
copyfile = fopen(filename, "w+");
if(copyfile == NULL) {
printf("Cannot open copy of the file %s in copyFile.\n", filename);
}
c = fgetc(file);
while(c != EOF){
fputc(c, copyfile);
c = fgetc(file);
}
printf("Contents copied successfully.\n");
fclose(file);
fclose(copyfile);
chdir(cwd);
return;
}