Ignoring symbolic/hard links while scanning through a directory


 
Thread Tools Search this Thread
Top Forums Programming Ignoring symbolic/hard links while scanning through a directory
# 1  
Old 03-02-2005
Ignoring symbolic/hard links while scanning through a directory

Hi,

I am writing a unix system utility that is supposed to scan through a directory, collecting
information about the files and subdirectories. That part is going well.

The tricky part is that some files in the directory are hard links or symbolic links. I am supposed to IGNORE these links. As in, if I reach one, I'm not supposed to gather any information about it.

I understand that hard links have the same inode as the original file.

But I dont understand how I can check if the current file is a hard link or the original file.

Can anyone give me a push in the right direction?

If you're curious, I've included my source code as to give an idea of what my utility does.

/*--------------------------------------------------------------------------
File: dsz.c

Usage: dsz <dirname>

--------------------------------------------------------------------------*/
/********************* Include definitions ***********/
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>

/********************* Global definitions declarations ***********/
#define MAXDIRNAMESZ 150

/* global variables */
int fileNum; /*Keeps track of total Number of Files in the directory*/
int dirNum=0; /*Keeps track of Number of directories in the directory including top*/
int sizeFiles; /*Keeps track of total size of all files found in the directory*/
int fileBlocks;/*Keeps track of total number of bytes of blocks allocated to the files*/
int dirSize;

/************Prototypes*****************/
void scanDirectory(char *);
void printResults();


/*--------------------------------------------------------------------------
Function: main

Description: The main function processes command line arguments and invokes
scanDirectory to scan directory
Output: Main always returns 0

--------------------------------------------------------------------------*/
int main(int argc, char **argv)
{
int argix = 1; /* point to first argument */

if(argc != 2)
{
printf("Usage: fndp <dir1>\n");
return(1);
}

scanDirectory(argv[1]);
printResults();
return(0);
}

/*--------------------------------------------------------------------------
Function: scanDirectory(char *dirname, int prms)

Description: This function traverses the directory searching for links and
large files.

Output: void
--------------------------------------------------------------------------*/
void scanDirectory(char *dirname)
{
DIR *dirpt; /* list of directory contents */
struct dirent *direlm; /* directory element */
struct stat statbuf; /* for stating subdirs and files */
char filedirpath[MAXDIRNAMESZ];


/* open directory file */
dirpt = opendir(dirname);
if(dirpt == NULL)
{
perror(dirname);
return;
}

while( (direlm = readdir( dirpt)) != NULL)
{
if(strcmp(direlm->d_name,".")==0) continue; /* ignore current directory */
if(strcmp(direlm->d_name,"..")==0) continue; /* ignore parent directory */

sprintf(filedirpath,"%s/%s",dirname,direlm->d_name);
if(stat(filedirpath,&statbuf) == -1)
{
perror(filedirpath);
continue; /* go to next */
}
else
{
if (S_ISREG(statbuf.st_mode)) /* regular file */
{
//do processing
//printf("Path:%s\n",filedirpath);
//printf("size:%d\n",statbuf.st_size);
//printf("num of blocks:%d\n",statbuf.st_blocks);
//printf("blocksize:%d\n",statbuf.st_blksize);
sizeFiles = sizeFiles + statbuf.st_size;
fileNum++;
fileBlocks = fileBlocks + (512*statbuf.st_blocks);

}
else if (S_ISDIR(statbuf.st_mode)) /* directory */
{
//do processing
scanDirectory(filedirpath);
dirNum++;
dirSize = dirSize + statbuf.st_blksize;

}
}
}

closedir(dirpt);

}


/*--------------------------------------------------------------------------
Function: printResults()

Description: Prints the results

Output: void
--------------------------------------------------------------------------*/
void printResults() {
printf("Num of Files:%d\n",fileNum);
printf("Size of All Files:%d\n",sizeFiles);
printf("file block size:%d\n",fileBlocks);
printf("Num of Directories:%d\n",dirNum);
printf("directory block size:%d\n",dirSize);
}
# 2  
Old 03-02-2005
If a file has two hard links, both hard links are co-equal and you cannot distinguish which came first. But if the number of links is greater than one, save the inode number in an array. And check that array each time you encounter a file with multiple links. This will let you process each file once and only once.
# 3  
Old 03-02-2005
Quote:
Originally Posted by Perderabo
If a file has two hard links, both hard links are co-equal and you cannot distinguish which came first. But if the number of links is greater than one, save the inode number in an array. And check that array each time you encounter a file with multiple links. This will let you process each file once and only once.
1) The inode number is from the struct dirent and it is of type ino_t. What exactly is ino_t? If my inode number is 25 for example, can I compare an integer to something of type ino_t?

2) Also, is it efficient to do it this way? Because each time I process a file, I have to compare its inode with each value in the array.

Thanks for your reply by the way.
# 4  
Old 03-02-2005
ino_t is ino_t. You're not supposed to care if it's an int or a long or whatever. Just build an array of ino_t. And compare elements of that array to your inode. I would use statbuf.st_ino by the way. If you really can't stand not knowing, take a peek at your include file. It can vary from system to system and I don't know what you're using.

And remember, if statbuf.st_nlink == 1, you can bypass all of the array checking. In most directories most files have only one link. Scanning an in-core array is fast. And fast or not, it's the only way you're going to avoid reprocessing a file with multiple links.
# 5  
Old 03-11-2005
thanks a lot. It works.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Solaris

Symbolic links

Soft link,Hard link brief explanation (1 Reply)
Discussion started by: RAJU KAVATI
1 Replies

2. AIX

List all the soft links and hard links

Hi I'm logged in as root in an aix box Which command will list all the soft links and hard links present in the server ? (2 Replies)
Discussion started by: newtoaixos
2 Replies

3. Solaris

Hard Links and Soft or Sym links

When loooking at files in a directory using ls, how can I tell if I have a hard link or soft link? (11 Replies)
Discussion started by: Harleyrci
11 Replies

4. Shell Programming and Scripting

print summary of directory, and group all symbolic links

I am trying to get a summary of filetypes in a directory, but the total count of symbolic links is not working. I am stuck at the results of the file command. I have used the find command to confirm my expectations, but my bash function is not giving the results I want. Here is my function:... (2 Replies)
Discussion started by: AlphaLexman
2 Replies

5. Windows & DOS: Issues & Discussions

gVim on windows 7 64 constantly overwrites symbolic and even hard links

I use sugarsync to sync my vimrc across computers. I keep the _vimrc file in a syncing folder and in my home folder, I have a symbolic link ~\_vimrc pointing to ~\Synced Docs\_vimrc. On my mac I have a .vimrc symbolic link pointing at the _vimrc file. On the pc side, every time I open the _vimrc... (3 Replies)
Discussion started by: dp88
3 Replies

6. UNIX for Dummies Questions & Answers

Deleting Symbolic and/or Hard links

From what I understand a symbolic link is alot like a shortcut where it points to another file. if the original file is deleted the symbolic link is rendered useless but a symbolic link can be deleted without any problem. A hard link is like a copy of the file itself but pointing to the same... (3 Replies)
Discussion started by: cue
3 Replies

7. UNIX for Dummies Questions & Answers

Symbolic Links

Hi all, I have scoured the entire forum for this but to no avail unfortunately. Basically, I would like to remove my symbolic link from my folder name i.e. foldername -> /a/b/c/d/f where f is indeed a folder. I have tried rmdir but this does not work and in actual fact deletes the... (4 Replies)
Discussion started by: cyberfrog
4 Replies

8. Solaris

symbolic links between servers

Hi Guys... I want to create a link using ln -s for a directory that does not exist on the box. How do I do that? I had some files from Box A directory /d1/u01 and I copied the files across to another Box lets say Box B on directory /d2/u02. Now I want a link so that this path /d1/u01... (2 Replies)
Discussion started by: Phuti
2 Replies

9. AIX

Symbolic Links

I am linking a directory as follows: ln -sf /home/xxx/userid/real_files/* /home/xxx/userid/linked_files This gives me symbolic links for all the files in the real_files directory in the linked_files directory. My question is, if I go and remove a file in the real_files directory and then go... (1 Reply)
Discussion started by: rcarnesiii
1 Replies

10. UNIX for Dummies Questions & Answers

links: (soft, hard? symbolic??) inode

Hi, what is link? and soft link? how about hard one and symbolic link. and inode. i get confuse about this links. could anyone help me with full explainsion? thks Gusla (5 Replies)
Discussion started by: gusla
5 Replies
Login or Register to Ask a Question