I'm trying to delete files from a specifc folder. My deleteFile() function only deletes on its home folder, not on /tmp folder which is what I need. I tried the same approach as my displayDIR() function to change directory but I can't figure out how to make it work. I use cygwin as compiler.
void deleteFile() {
int status;
char filetodelete[25];
printf("\n \t **Delete File**\n");
displayDIR();
printf("\n\tChoose the name of the file to delete:\t");
scanf("%s", filetodelete);
status = remove(filetodelete);
if( status == 0 )
printf("%s file deleted successfully.\n", filetodelete);
else {
printf("\n\tUnable to delete the file");
perror("\n\tError");
}
}
void displayDIR() {
DIR *d;
struct dirent *dir;
d = opendir("C:/cygwin/tmp");
if (d) {
while ((dir = readdir(d)) != NULL)
printf("\t\t\t%s\n", dir->d_name);
closedir(d);
}
}
You need to include the folder path in the argument to remove():
char fullpath[40] = "C:/cygwin/tmp/";
strcat(fullpath, filetodelete);
status = remove(fullpath);
Related
I am trying to read a given directory filePath and get the names of all non folder files into a array of strings. So the issue that I need solved is how to specifically not get folder type files but also get all the other file type names and store them into the string array. Later I plan to use threads to read these individual files as well, but I need to be able to store the files names properly. The code that I am currently using is below. It should also be noted that this code is being executed by a child process from the fork() command, but I am not sure if that is relevant to the issue anyway. Any help would be appreciated. Thanks.
Example:
In the Home/Documents there are 4 files: hello.txt something.dat folder1 something2.dat
My string array should have the values hello.txt, something.dat, and something2.dat
Note: It is okay for me not to do the files as a I go through the directory as the files themselves are not going to be changed at all content wise.
//char* directory is an absolute filePath to the directory
void getFilesFromDirectory(char* directory, pid_t process)
{
int index =0;
DIR *dir;
struct dirent *ent;
//Can hold only 500 valid files in the folder
char *stringArray[500];
if ((dir = opendir (directory)) != NULL)
{
while ((ent = readdir (dir)) != NULL)
{
strcpy(stringArray[index],ent->d_name);
index++;
}
closedir (dir);
}
else
{
/* could not open directory */
perror ("");
}
//Everything Below is not related to the problem. Just what I am using it for.
pthread_t threadArray[index];
pthread_t senderThread;
//thread_param_t parameterSender;
thread_param_t paramterArray[index];
sem_init(&empty,0,bufferSize);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
//parameterSender.listItem = listHead;
pthread_create(&senderThread, NULL, senderFunction, NULL);
//int threadCounter = 0;
for(int i =0; i<index; i++)
{
paramterArray[i].fileLocation = strcat(directory, stringArray[i]);
pthread_create(&threadArray[i], NULL, threadFunction, paramterArray + i);
}
}
You could check stringArray for files without "." and set this pointer to Null. (There are files missing)
A better option is this:
#include <stdio.h>
#include <dirent.h>
int main()
{
DIR *folder;
struct dirent *entry;
int files = 0;
folder = opendir(".");
if(folder == NULL)
{
perror("Unable to read directory");
return(1);
}
printf("debug\n");
while( (entry=readdir(folder)) )
{
files++;
printf("File %3d: %s :: %s\n",
files,
entry->d_name,
(entry->d_type == DT_DIR)?"Directory" : "File"
);
}
closedir(folder);
return(0);
}
I'm trying to copy directory contents to another directory
but I'm having a problem with writing to the second directory without using sprintf; Any suggestions?
void Copying(char *folder1, char *folder2) {
DIR *s1, *s2;
struct dirent *dep;
if ((s1 = opendir(folder1)) == NULL) {
printf("Error\n");
return;
}
if ((s2 = opendir(folder2)) == NULL) {
printf("Error \n");
return;
}
while ((dep = readdir(s1)) != NULL) {
//write(s2 , dep->d_name , sizeof(dep) ) ; // <-
}
closedir(s1);
closedir(s2);
return;
}
This approach won't work. Directory handles are not writable.
If you want to copy the contents of a directory, you will need to copy each file, directory, and link in the source directory individually. To copy each file, you will need to create a new file in the target directory and write the contents of the source file into it.
In my program stat is only working for a current directory. Can any one please help me with this.
even though I am passing parameter from main it is only working for current directory.
and source path is good it is printing correct path which I have passed from the main.
DIR *dr;
struct dirent *cur;
struct stat fi;
long int total_size = 0;
dr = opendir(source);
char *name;
printf("%s\n\n\n", source);
if (!(dr))
{
perror("opendir()");
return(1);
}
while (cur = readdir(dr))
{
if(cur->d_name[0] != '.')
{
if(stat(cur->d_name, &fi) == -1)
{
printf("error \n\n");
}
else
{
printf("%s ",cur->d_name);
printf("%ld ",fi.st_blocks);
total_size = total_size + fi.st_blocks;
}
}
}
printf("\n\ntotal_size = %ld \n", total_size);
printf("\n\n\n");
return 0;
}
cur->d_name only contains the file name.
to get a 'stat()' outside the current directory,
need to prefix with the path string.
Also need to check if the returned struct from readdir()
is a file or a sub directory.
The main problem is that stat expects a file path but d_name is just the file name. You can find a working example of how to use stat with d_name here
I am working on a simple project to implement "ls -R" from scratch. Whenever I run what I have, my program just keeps searching the root directory over and over again. What am I doing wrong?
void lsR(char dirName[]) {
/*
The recursive function call.
*/
DIR *dir;
struct dirent *directory;
struct stat fileStat;
char type;
char **nameList[MAX_RECURSIVE_FILES];
struct passwd *user;
int count = 0;
int i = 0;
printf("\n");
printf("./%s :\n", dirName);
printf("\n");
if ((dir = opendir(dirName)) == NULL) {
perror("opendir error:");
return;
}
while ((directory = readdir(dir)) != NULL) {
if (stat(directory->d_name, &fileStat) < 0) {
perror("fstat error:");
return;
}
if (fileStat.st_uid == 1) {
continue;
}
user = getpwuid(fileStat.st_uid);
printf("%s ", directory->d_name);
fileType(&fileStat, &type);
if ((type == 'd') && (count < MAX_RECURSIVE_FILES)) {
nameList[count] = malloc(sizeof(char)*MAX_STRING_LENGTH);
strncpy(nameList[count++], directory->d_name, MAX_STRING_LENGTH);
}
}
closedir(dir);
printf("\n");
for (i=0; i<count; i++) {
printf("Calling lsR on: %s\n", nameList[i]);
lsR(nameList[i]);
}
}
When it executes, I get the following output:
"./. :
., .., ... all other files in my current working directory ....
./. :
., .., ... all other files in my current working directory...
"
Among the list of files in the current directory you've noticed . and .. The first one is a hardlink to the current directory and the second one to the parent directory. So when you recurse through your dir entries you will want to skip those two. Otherwise the first directory you will recurse into will be ., in other words the directory you've just gone through.
This is the reason of your program current behavior, but once you fix that you will run into the issue lurker mentioned in his answer.
Additional notes :
Are you sure about the char **nameList[MAX_RECURSIVE_FILES]; variable? Seems to me you want an array of char * not an array of char **.
Are you aware you can use the S_ISDIR macro on the st_mode field of your stat struct, in order to check that the current file is not a directory instead of your custom function?
You need to include the path relative to your program's current directory. Each nameList element will need to be dirName + "/" + directory->d_name.
If you started out calling lsR on the local directory, ./foo and foo has directory named bar under it, then to open bar you need to open ./foo/bar since your program is running from the directory represented by ..
I want to retrieve all the files, directories and subdirectories contained within a given path, recursively. But I have a problem when my code reaches the second level (a directory within a directory): instead of opening the inner directory to search its contents, it throws an error. Here is what I have done:
void getFile(char *path)
{
DIR *dir;
struct dirent *ent;
if ((dir = opendir(path)) != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir(dir)) != NULL) {
if((strcmp(ent->d_name,"..") != 0) && (strcmp(ent->d_name,".") != 0)){
printf ("%s", ent->d_name);
if(ent->d_type == DT_DIR){
printf("/\n");
getFile(ent->d_name);
}
else{
printf("\n");
}
} // end of if condition
} // end of while loop
closedir (dir);
}
Use the ftw(3) library function to recursively walk a file tree. It is quite standard.
You may also look into nftw and the MUSL libc source code for it. It is quite readable.
When you recursively call getFile you only call it with the only the name of the directory you just read. It's not the full path, which is what you need. You have to manage that yourself.
Something like this:
if(ent->d_type == DT_DIR)
{
if ((strlen(path) + strlen(ent->d_name) + 1) > PATH_MAX)
{
printf("Path to long\n");
return;
}
char fullpath[PATH_MAX + 1];
strcpy(fullpath, path);
strcat(fullpath, "/");
strcat(fullpath, ent->d_name); // corrected
getFile(fullpath);
}