File: directory.c

package info (click to toggle)
swish++ 1.1b3-3
  • links: PTS
  • area: main
  • in suites: slink
  • size: 416 kB
  • ctags: 409
  • sloc: ansic: 2,842; makefile: 247; sh: 48
file content (113 lines) | stat: -rw-r--r-- 3,017 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
**	SWISH++
**	directory.c
**
**	Copyright (C) 1998  Paul J. Lucas
**
**	This program is free software; you can redistribute it and/or modify
**	it under the terms of the GNU General Public License as published by
**	the Free Software Foundation; either version 2 of the License, or
**	(at your option) any later version.
** 
**	This program is distributed in the hope that it will be useful,
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**	GNU General Public License for more details.
** 
**	You should have received a copy of the GNU General Public License
**	along with this program; if not, write to the Free Software
**	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

// standard
#include <dirent.h>
#include <iostream.h>
#include <queue>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>

// local
#include "directory.h"
#include "fake_ansi.h"

#ifndef	PJL_NO_NAMESPACES
using namespace std;
#endif

extern int	verbosity;

extern void	do_file( char const *file_name );

bool		follow_symbolic_links;
struct stat	stat_buf;			// somplace to do a stat(2) in

//*****************************************************************************
//
// SYNOPSIS
//
	void do_directory( char const *dir_name )
//
// DESCRIPTION
//
//	Call do_file() for every file in the given directory; it will queue
//	subdirectories encountered that do no start with '.' and call
//	do_directory() on them.  It will not follow symbolic links unless the
//	-l command-line option was given.
//
//	This function uses a queue and recurses only once so as not to have
//	too many directories open concurrently.  This has the effect of
//	indexing in a breadth-first order rather than depth-first.
//
// PARAMETERS
//
//	dir_name	The full path of the directory of the files and
//			subdirectories to index.
//
//*****************************************************************************
{
	typedef queue< string > dir_queue_type;
	static dir_queue_type dir_queue;
	static int recursion;

	if ( is_symbolic_link( dir_name ) && !follow_symbolic_links )
		return;

	DIR *dir_p;
	if ( !( dir_p = ::opendir( dir_name ) ) )	// can't open: skip
		return;

	if ( verbosity > 1 ) {
		if ( verbosity > 2 ) cout << '\n';
		cout << dir_name;
		if ( verbosity > 2 ) cout << ':';
		cout << '\n';
	}

	string const dir_string( dir_name );

	struct dirent const *dir_ent;
	while ( dir_ent = ::readdir( dir_p ) ) {
		if ( *dir_ent->d_name == '.' )		// skip dot files
			continue;
		string const path( dir_string + '/' + dir_ent->d_name );
		if ( is_directory( path ) )
			dir_queue.push( path );
		else
			do_file( path.c_str() );
	}

	::closedir( dir_p );
	if ( recursion )
		return;

	////////// Do all subdirectories //////////////////////////////////////

	while ( !dir_queue.empty() ) {
		dir_queue_type::value_type dir_name = dir_queue.front();
		dir_queue.pop();
		++recursion;
		do_directory( dir_name.c_str() );
		--recursion;
	}
}