I'm trying to do this exercise for my Operating Systems class: I'm supposed to pass a specific directory through command line to find any files in it pointed by soft links.
This is what I've done:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
int main(int argc, char *argv[])
{
DIR *dir_ptr;
struct dirent *dir_str;
struct stat buf;
struct stat buf2;
if(argc!=2)
{
printf("Error! I need a directory.\n");
exit(-1);
}
if((dir_ptr=opendir(argv[1]))==NULL)
{
printf("Opendir error: %s\n", strerror(errno));
exit(-1);
}
while((dir_str=readdir(dir_ptr))!=NULL)
{
lstat(dir_str->d_name, &buf);
if(S_ISLNK(buf.st_mode))
{
stat(dir_str->d_name, &buf2);
printf("'%s' points to a file of %ld bytes.\n", dir_str->d_name, buf2.st_size);
}
}
closedir(dir_ptr);
exit(0);
}
Now here's my problem: this program just writes to standard output all soft links that point to a file of a certain size. Instead, I need it prints all the files pointed by a soft link. Secondly, strangely this program seems to work only if no directory is required, I mean, getting the current directory with getcwd()
and passing the returned pathname to opendir()
. This one infact doesn't even prints all the soft links in the passed directory.
Thanks in advance! Any help would be much appreciated.
EDIT: Let us assume we have this directory named "my_directory" with these files:
justatext.txt
softlink1 (it points to justatext.txt)
justanothertext.txt
softlink2(it points to justanothertext)
When I pass "my_directory" through command line (./a.out my_directory), I want that the program writes to standard output "justatext.txt" and "justanothertext.txt" because these files in the directory are pointed by softlinks. If I pass this directory to my program, no output is printed.
OK, I think I've solved my problem. Summarizing all the advices in the comments, this is what I did and it seems to work:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
int main(int argc, char *argv[])
{
DIR *dir_ptr;
struct dirent *dir_str;
struct stat buf;
struct stat buf2;
char *buf3;
ssize_t nbyte, bufsize;
int flag=0;
if(argc!=2)
{
printf("Error! I need a directory.\n");
exit(EXIT_FAILURE);
}
if((dir_ptr=opendir(argv[1]))==NULL)
{
printf("Opendir error: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
chdir(argv[1]);
while((dir_str=readdir(dir_ptr))!=NULL)
{
lstat(dir_str->d_name, &buf);
bufsize=buf.st_size+1;
if(buf.st_size==0)
bufsize=PATH_MAX;
buf3=malloc(bufsize);
if(buf3==NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}
nbyte=readlink(dir_str->d_name, buf3, bufsize);
if(S_ISLNK(buf.st_mode))
{
stat(dir_str->d_name, &buf2);
printf("%s is a file of %ld bytes pointed by a symbolic link (%s).\n", buf3, buf2.st_size, dir_str->d_name);
flag+=1;
}
}
if(flag==0)
printf("No files pointed by a syslink found in this directory!\n");
free(buf3);
closedir(dir_ptr);
exit(0);
}
First of all, I used chdir()
in order to change the current directory with the one passed through command line; then I implemented readlink()
to obtain the path name in the symbolic link named as its argument. Also I used exit(EXIT_FAILURE)
to close the program if an error occurs.
I don't know if this is fully correct. Please let me know if it's not so!