Reputation: 103
Can anybody spot what I am missing here? This block of code is supposed to recursively access directories and store the directory path and the path of the files in it. It will fprintf() a true if the file is a directory and a false if the file is not a directory. Weird part is that the printf routine for fileName works fine but when its time to fprintf fileName to a file, it just prints a newline where its supposed to print fileName.
/* List the files in "dir_name". */
static void listDir(const char *dirName)
{
DIR *dir;
/*
* Open the directory specified by "dirName".
*/
dir = opendir(dirName);
/*
* Check it was opened.
*/
if (!dir) {
fprintf(stderr, "Cannot open directory '%s': %s\n",
dirName, strerror(errno));
exit(EXIT_FAILURE);
}
while (1) {
struct dirent *entry;
const char *dir_name;
/*
* "Readdir" gets subsequent entries from "d".
*/
entry = readdir(dir);
if (!entry) {
/*
* There are no more entries in this directory, so break out of the while loop.
*/
break;
}
dir_name = entry->d_name;
char fileName[PATH_MAX];
// Assign fileName to path if the file is not a directory
if (entry->d_type != DT_DIR) {
if (strcmp(dirName, "/") != 0) {
snprintf(fileName, PATH_MAX,
"%s/%s", dirName, dir_name);
} else {
snprintf(fileName, PATH_MAX,
"%s%s", dirName, dir_name);
}
}
/* Access directory and leave out /. and /.. in the process
*/
if (entry->d_type == DT_DIR) {
/*
* Check that the directory is not "d" or d's parent.
*/
if (strcmp(dir_name, "..") != 0 && strcmp(dir_name, ".") != 0) {
int path_length;
char path[PATH_MAX], indexPath[PATH_MAX];
if (strcmp(dirName, "/") != 0) {
path_length = snprintf(path, PATH_MAX,
"%s/%s", dirName, dir_name);
} else {
path_length = snprintf(path, PATH_MAX,
"%s%s", dirName, dir_name);
}
strcpy(indexPath, path);
strcat(indexPath, "/masterIndex.db");
FILE *fp;
if ((fp = fopen(indexPath, "a")) == NULL) {
printf("Cannot open file\n");
return;
}
printf("File: %s\n (TRUE)\n", path);
printf("File: %s\n (FALSE)\n", fileName); // This routine prints fileName correctly
fprintf(fp, "%s\n", path);
fprintf(fp, "%s\n", "true");
fprintf(fp, "%s\n", fileName); // This routine prints a newline where fileName is supposed to be
fprintf(fp, "%s\n", "false");
fclose(fp);
// Activate this for screw ups
/*
char command[PATH_MAX];
strcpy(command, "cd ");
strcat(command, path);
strcat(command, " && rm abc *.finderDB .DS_Store");
printf("%s\n", command);
system(command);*/
if (path_length >= PATH_MAX) {
fprintf(stderr, "Path length has gotten too long.\n");
exit(EXIT_FAILURE);
}
/*
* Recursively call "list_dir" with the new path.
*/
listDir(path);
}
}
}
/*
* After going through all the entries, close the directory.
*/
if (closedir(dir)) {
fprintf(stderr, "Could not close '%s': %s\n",
dirName, strerror(errno));
exit(EXIT_FAILURE);
}
}
Upvotes: 1
Views: 265
Reputation: 103
Here's the working code I managed to fix. Still have no idea what the bug was but this should work on POSIX systems. Not sure about Windows. Thanks to alk for the initialization suggestion, xtof for chidir() (which i have still not implemented yet) and twalberg for explaining what chdir() does.
/* List the files in "dir_name". */
static void listDir(const char *dirName)
{
DIR *dir;
/*
* Open the directory specified by "dirName".
*/
dir = opendir(dirName);
/*
* Check it was opened.
*/
if (!dir) {
fprintf(stderr, "Cannot open directory '%s': %s\n",
dirName, strerror(errno));
exit(EXIT_FAILURE);
}
while (1) {
struct dirent *entry;
const char *dir_name;
/*
* "Readdir" gets subsequent entries from "d".
*/
entry = readdir(dir);
if (!entry) {
/*
* There are no more entries in this directory, so break out of the while loop.
*/
break;
}
dir_name = entry->d_name;
if (entry->d_type != DT_DIR) {
char fileName[PATH_MAX] = "", indexPath[PATH_MAX] = "";
if (strcmp(dirName, "/") != 0) {
sprintf(fileName, "%s/%s", dirName, dir_name);
} else {
sprintf(fileName, "%s%s", dirName, dir_name);
}
strcpy(indexPath, dirName);
strcat(indexPath, "/masterIndex.db");
// We don't want to include masterIndex.db in the index list right?
if (strcmp(indexPath, fileName) != 0) {
FILE *fp;
fp = fopen(indexPath, "a");
if (fp == NULL) {
printf("Cannot open file\n");
}
printf("File: %s\n (FALSE)\n", fileName);
fprintf(fp, "%s\n", fileName);
fprintf(fp, "%s\n", "false");
fclose(fp);
}
}
/*
* See if "entry" is a subdirectory of "dir".
*/
if (entry->d_type == DT_DIR) {
/*
* Check that the directory is not "d" or d's parent.
*/
if (strcmp(dir_name, "..") != 0 && strcmp(dir_name, ".") != 0
&& strcmp(dir_name, "tmp") != 0
&& strcmp(dir_name, "Jarvis") != 0) {
int path_length;
char path[PATH_MAX] = "", indexPath[PATH_MAX] = "";
if (strcmp(dirName, "/") != 0) {
path_length = sprintf(path,
"%s/%s", dirName, dir_name);
} else {
path_length = sprintf(path, "%s%s", dirName, dir_name);
}
strcpy(indexPath, path);
strcat(indexPath, "/masterIndex.db");
FILE *fp;
fp = fopen(indexPath, "a");
if (fp == NULL) {
printf("Cannot open file\n");
}
printf("File: %s\n (TRUE)\n", path);
fprintf(fp, "%s\n", path);
fprintf(fp, "%s\n", "true");
fclose(fp);
// Activate this for screw ups
/*
char command[PATH_MAX];
strcpy(command, "cd ");
strcat(command, path);
strcat(command, " && rm abc *.finderDB .DS_Store");
printf("%s\n", command);
system(command); */
if (path_length >= PATH_MAX) {
fprintf(stderr, "Path length has gotten too long.\n");
exit(EXIT_FAILURE);
}
/*
* Recursively call "list_dir" with the new path.
*/
listDir(path);
}
}
}
/*
* After going through all the entries, close the directory.
*/
if (closedir(dir)) {
fprintf(stderr, "Could not close '%s': %s\n",
dirName, strerror(errno));
exit(EXIT_FAILURE);
}
}
Upvotes: 0
Reputation: 70971
Your are missing to initialise fileName
here:
char fileName[PATH_MAX];
Mod the line like this:
char fileName[PATH_MAX] = "";
Not doing so could lead to access the unintialised variable, which is Undefined Behaviour and could lead to anything more or less rational or irrational.
Upvotes: 1
Reputation: 883
system("cd any_path")
won't have any effect on the calling process; use chdir()
instead..
Upvotes: 1