/** * Process a directory, listing each file and descending recursively into its * subdirectories. * * \param real_path Real path to the directory. * \param dir_name Directory name, the last component of its path. * \returns A newly allocated xmlNodePtr. */ xmlNodePtr directory_proc(const gchar *real_path, const gchar *dir_name) { xmlNodePtr dir_node; GDir *dir; gchar *dir_name_utf8; /* create directory node */ dir_node = xmlNewNode(NULL, "directory"); dir_name_utf8 = g_filename_to_utf8(dir_name, -1, NULL, NULL, NULL); xmlNewProp(dir_node, "name", dir_name_utf8); /* open directory */ dir = g_dir_open(real_path, 0, NULL); if (dir != NULL) { /* g_dir_open() succeeded */ const gchar *entry; log_info("Processing \"%s\"...", real_path); /* visit each directory entry */ while ((entry = g_dir_read_name(dir)) != NULL) { gchar *full_name = g_build_filename(real_path, entry, NULL); if (g_file_test(full_name, G_FILE_TEST_IS_DIR)) { xmlNodePtr subdir_node = directory_proc(full_name, entry); if (subdir_node != NULL) xmlAddChild(dir_node, subdir_node); } else if (g_file_test(full_name, G_FILE_TEST_IS_REGULAR)) { xmlNodePtr file_node = file_proc(full_name, entry); if (file_node != NULL) xmlAddChild(dir_node, file_node); } g_free(full_name); } g_dir_close(dir); } else { /* g_dir_open() returned NULL */ xmlNodePtr comment = xmlNewComment("error opening directory"); xmlAddChild(dir_node, comment); g_warning("%s: %s", real_path, g_strerror(errno)); } g_free(dir_name_utf8); /* free UTF-8 converted filename */ return dir_node; }
void ScanDirectoryFiles(char *basedir, int (* file_proc)(char *pathname, /* (const) */ void *user_val), void *user_val) { char baselen; URL dir; static int depth = 0; static int stop_flag; /* Stop scanning if true */ static int error_disp; /* Whether error is displayed or not */ static char pathbuf[MAXPATH]; /* pathname buffer */ if(depth == 0) /* Initialize variables at first recursive */ { stop_flag = 0; error_disp = 0; strcpy(pathbuf, basedir); } else if(depth > SCANDIR_MAX_DEPTH) /* Avoid infinite recursive */ { if(!error_disp) { /* Display this message at once */ ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "%s: Directory is too deep", basedir); error_disp = 1; } return; /* Skip scanning this directory */ } directory_form(pathbuf); baselen = strlen(pathbuf); if(baselen > sizeof(pathbuf) - 16) { /* Ignore too long file name */ return; } if((dir = url_dir_open(pathbuf)) == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: Can't open directory", pathbuf); return; } if(file_proc(pathbuf, user_val)) { stop_flag = 1; /* Terminate */ return; } while(!stop_flag && url_gets(dir, pathbuf + baselen, sizeof(pathbuf) - baselen - 1)) { if(strcmp(pathbuf + baselen, ".") == 0 || strcmp(pathbuf + baselen, "..") == 0) continue; if(file_proc(pathbuf, user_val)) { stop_flag = 1; /* Terminate */ break; } if(is_directory(pathbuf)) { /* into subdirectory */ depth++; ScanDirectoryFiles(pathbuf, file_proc, user_val); depth--; } } url_close(dir); }