I need to make an app in linux using C, I need to enter a folder path and copy all the files and subdirectories in a new folder. The problem is when I try to check if the path is to a folder or a file, the program always take the path like a folder, even if it's a file. I don't know what am i doing wrong. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <assert.h>
int main()
{
CopyFile("test3","test4");
return (0);
}
void mkdirRecursive(const char *path, mode_t mode) {
char opath[PATH_MAX];
char *p;
size_t len;
strncpy(opath, path, sizeof(opath));
opath[sizeof(opath) - 1] = '\0';
len = strlen(opath);
if (len == 0)
return;
else if (opath[len - 1] == '/')
opath[len - 1] = '\0';
for(p = opath; *p; p++)
if (*p == '/') {
*p = '\0';
if (access(opath, F_OK))
mkdir(opath, mode);
*p = '/';
}
if (access(opath, F_OK))
mkdir(opath, mode);
}
void CopyFile(char* NumeFisOld, char* NumeFisNew)
{
DIR *dp;
struct dirent *dirp;
struct stat info;
char OldDirPath[255];
char NewDirPath[255];
stat(NumeFisOld,&info);
int status = stat (NumeFisOld, &info);
if (status != 0)
{
fprintf (stderr, "Error, errno = %d\n", errno);
perror("stat error: ");
return;
}
fprintf (stderr, "Error, errno = %d\n", errno);
perror("stat error: ");
if(S_ISREG(info.st_mode))
{
printf("File: File location: %s \n",NumeFisOld);
printf("File: New file location: %s \n",NumeFisNew);
char buffer[65];
int fhRead;
int fhWrite;
unsigned int nbytes=65;
int bytesread;
int byteswritten;
if((fhRead=open(NumeFisOld, O_RDONLY)) ==-1)
{
perror("Eroare la deschiderea fisierului");
exit(1);
}
if((bytesread=read(fhRead,buffer,nbytes))<=0)
perror("Probleme la citirea fisierului");
else
printf("Citeste %u bytes din fisier\n", bytesread);
close(fhRead);
if((fhWrite=open(NumeFisNew,O_WRONLY | O_CREAT,S_IREAD | S_IWRITE)) !=-1)
{
if((byteswritten=write(fhWrite, buffer, sizeof(buffer))) == -1)
perror("Eroare la scriere");
else
printf("A scris %u bytes in fisier\n",byteswritten);
close(fhWrite);
}
}
else if(S_ISDIR(info.st_mode))
{
printf("Folder: File location: %s \n",NumeFisOld);
printf("Folder: New file location: %s \n",NumeFisNew);
dp=opendir(NumeFisOld);
while((dirp=readdir(dp)) != NULL)
{
strcpy(OldDirPath, NumeFisOld);
strcat(OldDirPath,"/");
strcat(OldDirPath,dirp->d_name);
strcpy(NewDirPath, NumeFisNew);
strcat(NewDirPath, "/");
strcat(NewDirPath,dirp->d_name);
DIR* dir = opendir(NewDirPath);
if(dirp->d_name[0]!='.')
{
if (dir)
{
/* Directonry exists. */
CopyFile (OldDirPath,NewDirPath);
printf("Directorul %s exista deja \n",NewDirPath);
closedir(dir);
}
else if (ENOENT == errno)
{
printf("Directorul %s nu exista \n",NewDirPath);
mkdirRecursive(NewDirPath,0755);
CopyFile (OldDirPath,NewDirPath);
/* Directory does not exist. */
}
else
{
printf("Directorul %s nu s-a putut deschide \n",NewDirPath);
/* opendir() failed for some other reason. */
}
}
}
}
}
My logic is that: First I check if the path is a directory, if it is, create it in my new folder(NumeFisNew) and then enter it(NumeFisOld) and repeat for each subdirectory or file in it. If the path is a file, then it should enter in else and copy the file in the path(NumeFisNew).
Edit: Ok, here is the result:
Error, errno = 0
stat error: : Success
Folder: File location: test3
Folder: New file location: test4
Error, errno = 0
stat error: : Success
Folder: File location: test3/test5
Folder: New file location: test4/test5
Directorul test4/test5 exista deja
Error, errno = 0
stat error: : Success
Folder: File location: test3/test4
Folder: New file location: test4/test4
Error, errno = 0
stat error: : Success
File: File location: test3/test4/test2
File: New file location: test4/test4/test2
Citeste 42 bytes din fisier
Directorul test4/test4/test2 exista deja
Directorul test4/test4 exista deja
Error, errno = 21
stat error: : Is a directory
File: File location: test3/test1
File: New file location: test4/test1
Citeste 42 bytes din fisier
Directorul test4/test1 exista deja
If it has File in front, it means it was used from if(S_ISREG) and if it has Folder, it means it was used from if(S_ISDIR). So at least now it recognized that test1 and test2 are files, but it still copied them as folders.
You must switch you control statement: first look if it's a file and after check if it is a dir
if (S_ISREG (info.st_mode))
{
printf ("It's a file\n");
}
else if (S_ISDIR (info.st_mode))
{
printf ("It's a dir\n");
}
Moreover you should take care of stat return value
int status = stat (NumeFisOld, &info);
if (status != 0)
{
fprintf (stderr, "Error, errno = %d\n", errno);
perror("stat error: ");
return;
}