suggestions for my file backup app (for linux)
I just got to working code with my first program dealing with the unix file system. all it does is accept a command line path to a directory, and a path to the directory where the files will be copied. it then copies all the files and folders to the new folder. so if you wanted to backup the folder "/home/user/files" into "/home/user/old" you would use:
./backup /home/user/files /home/user/files/old
and the program will copy the content os "files" to a new folder "old~BACKUP".
I would just like some people to look it over and make some suggestions as to what it good/bad because I know better than anyone that it could use improvement.
thanks, and here is the code
EDIT: I know that some parts of the code are rather cryptic, such as when multiple calls to strcat, i am aware of this but this is the only way i thought of doing (at first).
EDIT #2: Ahhh, posted too quick. I already found a problem, when trying to backup a folder within a folder, my calls to create another instance of backup (would that be considered recursive if i used the system() call?) fail because there is no path to the backup executable in the other folders. I think I could get around it by editing path files on my machine but how could I get it to work in a portable way?
EDIT #3: Last one i swear! I can run the program fine if the executable is in the /usr/bin directory, which is in most peoples PATHs, so is that the best way to use the program? Or is there another way to get around this so that the program can be run from anywhere?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define SIZE 75
struct dir_path
{
char *orig;
char *new;
};
char *create_dir(char *orig, char *new);
char *backup(char *filepath, char *dirpath, char *name);
int main(int argc, char *argv[])
{
char new[SIZE], *orig, *temp;
DIR *directory = NULL;
struct dirent *entry;
struct dir_path *dir = malloc(sizeof(struct dir_path));
orig = malloc(SIZE);
temp = malloc(SIZE);
memset(new, '\0', SIZE);
memset(temp, '\0', SIZE);
memset(orig, '\0', SIZE);
if (argc != 3) {
printf("USAGE: ./backup <source dir> <dest dir>\n");
exit(EXIT_FAILURE);
}
dir->orig = argv[1];
dir->new = argv[2];
if ((directory = opendir(dir->orig)) == NULL) {
perror("opendir");
exit(EXIT_FAILURE);
}
dir->new = create_dir(argv[1], argv[2]);
sprintf(new, "%s", dir->new);
sprintf(orig, "%s", dir->orig);
sprintf(temp, "%s", dir->orig);
while (errno = 0, (entry = readdir(directory)) != NULL) {
if ((strcmp(entry->d_name,".") == 0) || (strcmp(entry->d_name,"..") == 0))
continue;
/* concatenates path string */
strcat(temp, "/");
strcat(temp, entry->d_name);
/* calls backup function to copy directory files */
backup(temp, new, entry->d_name);
memset(temp, '\0', SIZE);
sprintf(temp, "%s", dir->orig);
}
closedir(directory);
free(dir);
return 0;
}
/* creates a directory in the parent directory of PATH */
/* directory name is <PATH>~BACKUP */
char *create_dir(char *orig, char *newdir)
{
char *path = malloc(SIZE),
*new = malloc(SIZE);
sprintf(path, "%s", orig);
sprintf(new, "%s", newdir);
chdir(newdir);
new = strcat(new, "~BACKUP");
if (mkdir(new, 0755) == -1) {
perror("mkdir");
exit(EXIT_FAILURE);
}
chdir(orig);
return new;
}
char *backup(char *filepath, char *newdir, char *name)
{
int fd, newfile, b_read, b_written, i, k=0;
char buf[4096], *temp = malloc(SIZE),
*new = malloc(SIZE),
*dirname = malloc(SIZE);
/* form dest path */
memset(new, '\0', SIZE);
sprintf(new, "%s", newdir);
strcat(new, "/");
strcat(new, name);
fprintf(stderr, "Saving...%s\n", new);
if ((fd = open(filepath, O_RDONLY)) == -1)
perror("open");
if ((b_read = read(fd, buf, sizeof(buf))) == -1) {
perror("read");
if (errno == EISDIR) { /* path is a directory */
sprintf(temp, "%s", "./backup ");
strcat(temp, filepath);
i = SIZE;
while (filepath[--i] != '/')
continue;
while (filepath[++i] != '\0')
dirname[k++] = filepath[i];
strcat(temp, " ");
strcat(temp, newdir);
strcat(temp, "/");
strcat(temp, dirname);
system(temp);
}
} else {
printf("bytes read: %d\n", b_read);
if ((newfile = open(new, O_RDWR | O_CREAT, 0755)) == -1) {
perror("open");
}
if ((b_written = write(newfile, buf, b_read)) == -1) {
perror("write");
}
printf("bytes written: %d\n", b_written);
}
close(fd);
close(newfile);
return new;
}