scan a directory to find files in c - c

I'm trying to create a function in c which scans all my path C: \ temp (Windows) to search for a file that I pass (eg test.txt) and each time it finds one return the path to steps another function to write something in the bottom of this file.
I managed to do the function that writes to the file but can not figure out how to do that scans the folder and pass the address of the file found.

#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
void printdir(char *dir, int depth)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if((dp = opendir(dir)) == NULL) {
fprintf(stderr,"cannot open directory: %s\n", dir);
return;
}
chdir(dir);
while((entry = readdir(dp)) != NULL) {
lstat(entry->d_name,&statbuf);
if(S_ISDIR(statbuf.st_mode)) {
/* Found a directory, but ignore . and .. */
if(strcmp(".",entry->d_name) == 0 ||
strcmp("..",entry->d_name) == 0)
continue;
printf("%*s%s/\n",depth,"",entry->d_name);
/* Recurse at a new indent level */
printdir(entry->d_name,depth+4);
}
else printf("%*s%s\n",depth,"",entry->d_name);
}
chdir("..");
closedir(dp);
}
int main()
{
printf("Directory scan of /home:\n");
printdir("/home",0);
printf("done.\n");
exit(0);
}

Use FindFirstFile function. Here's a good example of this function using.

Related

Trying to create code in C that print all directories starting from a root directory passed

EXAMPLE
Imagine I have a directory called Alpha and I want it as root.
Alpha contains: some files and other two directories Beta and Gamma,
Beta contains: some files and another directory called Theta,
Gamma contains: some files,
Theta contains: some files.
INPUT/OUTPUT
Using input as: ./myfind Alpha
I'll want as output:
Alpha
Beta
Gamma
Theta
(I don't care about the order).
MY CODE
I tried with this code but it doesn't work. I'll want to do a recursive function to do it and i can't use POSIX.
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#if !defined(NAME_MAX)
#define NAME_MAX 256
#endif
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "ERROR: Run as ./myfind directory\n");
exit(EXIT_FAILURE);
}
const char *dir = argv[1];
struct stat statbuf;
stat(dir, &statbuf);
if (!S_ISDIR(statbuf.st_mode)) {
fprintf(stderr, "FATAL ERROR: %s IS NOT A DIRECTORY\n", dir);
exit(EXIT_FAILURE);
}
find(dir);
exit(EXIT_SUCCESS);
}
The problem is you change the current directory when you recurse into a subdirectory but you do not change back to the parent directory when returning from the recursive function.
You could add a chdir(".."); at the end of the find function, but it might not work in all cases:
if a directory has more than 2 hard links
if you traverse symbolic links
It is preferable to compute the path of the destination directory for the recursive call to find() by concatenating the passed_dir_name, a / and dir->d_name and avoid changing the current directory.
Here is a modified version of find() for the simplistic approach:
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
chdir("..");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
chdir("..");
}

How to print path of a file properly?

Trying to make a pwd for the c shell. This is what I found on a website and wanted to learn more about it.
I have use debugging printf statements all the way through the program already and it returns the "." instead of the actual dir name all the way through. What am I missing? Why would this be happening?
#include <dirent.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
struct stat stat_buf;
struct dirent *file_info;
ino_t itself_ino; /* holds current folder inode */
ino_t parent_ino; /* holds parent folder inode */
char Current[PATH_MAX]; /* folder name */
char Path[PATH_MAX]; /* holds the full path */
char Slash[PATH_MAX]; /* add / before the folder name */
DIR *dir;
while (1)
{
dir = opendir(".");
if(dir == NULL) {
fprintf(stderr, "cannot get current directory.\n");
exit(-1);
}
/* read the information about the current folder */
file_info = readdir(dir);
lstat(file_info->d_name, &stat_buf);
itself_ino = stat_buf.st_ino;
closedir(dir);
chdir(".."); /* go to parent directory */
dir = opendir(".");
file_info = readdir(dir);
lstat(file_info->d_name, &stat_buf);
parent_ino = stat_buf.st_ino;
if(itself_ino == parent_ino) {
/*closedir(dir);*/
break;
} else {
strcpy(Slash, "/");
strcpy(Current, file_info->d_name);
strcat(Slash, Current); /* add "/" as the first */
strcat(Slash, Path); /* charcter of the directory */
/* check the length of the pathname */
if(strlen(Slash) >= PATH_MAX) {
fprintf(stderr, "Error! Path too long!\n");
exit(0);
}
/* save the full pathname */
strcpy(Path, Slash);
}
closedir(dir);
}
/* print the full path of the current working directory */
printf("%s\n", Path);
return 0;
}
It's just realpath:
if (realpath(".", &Path) == NULL) {
// handle error
}
However maybe you aim at getcwd or get_current_dir_name.
printf("%s\n", get_current_dir_name());

How to move the files from one directory to another in c?

I am creating a project on moving a directory files by creating sub-folders according to their particular type in c. I have made up to creating directories with the help of POSIX library dirent.h for the files having different extension present in the home directory but I don't know how to cut a file from home directory and paste in its particular sub-folder. So please guide me about how can I cut and paste a file from one directory to another in c.
Use rename(DestinationFilepath, SourceFilepath);
For more info check man page http://linux.die.net/man/2/rename
For two different system use cURL library:
http://en.wikipedia.org/wiki/CURL
Code in C:
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
#define DESTINATION_FOLDER "/home/second/"
#define SOURCE_FOLDER "/home/first/"
void printdir()
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
struct tm *tm;
char src_folder[1024];
char dest_folder[1024];
if ((dp = opendir(SOURCE_FOLDER)) == NULL) {
fprintf(stderr,"cannot open directory: %s\n", SOURCE_FOLDER);
return;
}
chdir(SOURCE_FOLDER);
while ((entry = readdir(dp)) != NULL) {
lstat(entry->d_name, &statbuf);
if (!S_ISDIR(statbuf.st_mode)) {
sprintf(src_folder, "%s%s", SOURCE_FOLDER, entry->d_name);
sprintf(dest_folder, "%s%s", DESTINATION_FOLDER, entry->d_name);
printf("%s----------------%s\n", entry->d_name, dest_folder);
rename(src_folder, dest_folder);
}
}
chdir("..");
closedir(dp);
}
int main()
{
while (1) {
printdir();
}
rename("aaa.txt", "/home/second/bbb.txt");
printf("done.\n");
exit(0);
}

C Directory and Subdirectory Recursion

I tried to recursively get all files and folder list.But I can only get subdirectories of documents and inside of them.I can't get the other folders which in inside of subdirectory.
I don't know how to do it recursively.I hope you help me
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <windows.h>
#include <unistd.h>
#include <string.h>
void list(char *a);
void reader(char *path);
int
main (void)
{
DIR *dp;
struct dirent *ep;
dp = opendir ("C:\\Users\\pen\\Documents\\");
if (dp != NULL)
{
while (ep = readdir (dp)){
GetFileAttributes(ep->d_name);
if(FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(ep->d_name))
{
if (strcmp(".",ep->d_name)==0)
continue;
if (strcmp("..",ep->d_name)==0)
continue;
reader(ep->d_name);
}
}
closedir(dp);
}
else
perror ("Couldn't open the directory");
closedir(dp);
system("pause");
return 0;
}
void reader(char *path){
DIR *da;
struct dirent *ef;
da = opendir(path);
while (ef=readdir(da)){
printf ("%s\n",ef->d_name);
if(FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(ef->d_name))
{
if (strcmp(".",ef->d_name)==0)
continue;
if (strcmp("..",ef->d_name)==0)
continue;
reader(ef->d_name);
}
}
closedir(da);
}
1) In reader you need to call closedir(da); after the while loop.
2) every call to reader needs to have the absolute path you need to concatenate path
to ef->d_name and then call reader.
3) also to enable debugging you should call perror after a failed readdir call.

Get only the files included in a directory in c / Ubuntu

I have to create a listing of the files contained inside a specific directory, I have done the code below(part of a bigger programm), but I would like my programm to ignore any possible folders that could be included inside the directory.
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main ()
{
DIR *dirptr;
struct dirent *entry;
dirptr = opendir ("synchedFolder");
if (dirptr != NULL)
{
while (entry = readdir (dirptr))
{
if(strcmp(entry->d_name,"..")!=0 && strcmp(entry->d_name,".")!=0)
puts (entry->d_name);
}
(void) closedir (dirptr);
}
else
perror ("ERROR opening directory");
}
If you want to list only files, but no directories, you have to add the following check:
entry->d_type == DT_REG
or
entry->d_type != DT_DIR
There's stat() and lstat() and the return value for stat. In the latter, look out for the S_ISDIR macro.
Short answer is the dirent structure includes the necessary information:
if ( entry->d_type == DT_REG)
Check stat (or lstat)
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
/* int main (void){ */
int main (int argc, char **argv){
int i,result=0;
struct stat buf;
/* print_S_I_types(); */
for (i=1; i < argc; i++){
if (lstat(argv[i], &buf) < 0) {
fprintf(stderr, "something went wrong with %s, but will continue\n",
argv[i]);
continue;
} else {
if S_ISREG(buf.st_mode){
printf("argv[%d] is normal file\n",i);
}else {
printf("argv[%d] is not normal file\n",i);
}
}
}
return 0;
}
Working code for listing files (without directories):
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
int main()
{
DIR *dir;
struct dirent *ent;
if ((dir = opendir ("/home/images")) != NULL)
{
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL)
{
if(ent->d_type!= DT_DIR)
{
printf ("%s\n", ent->d_name);
}
}
closedir (dir);
}
else
{
/* could not open directory */
perror ("");
return EXIT_FAILURE;
}
}

Resources