1 /***************************************************************************
2 *
3 * $Header: /usr/local/cvsroot/utils/ytree/readtree.c,v 1.13 2000/07/13 18:26:06 werner Exp $
4 *
5 * Funktionen zum Lesen des Dateibaumes
6 *
7 ***************************************************************************/
8
9
10 #include "ytree.h"
11
12
13
14 static void UnReadSubTree(DirEntry *dir_entry);
15
16
17
18 /* Dateibaum lesen: path = "Root"-Pfad
19 * dir_entry wird von der Funktion gefuellt
20 */
21
22
ReadTree(DirEntry * dir_entry,char * path,int depth)23 int ReadTree(DirEntry *dir_entry, char *path, int depth)
24 {
25 DIR *dir;
26 struct stat stat_struct;
27 struct dirent *dirent;
28 char new_path[PATH_LENGTH + 1];
29 DirEntry first_dir_entry;
30 DirEntry *des_ptr;
31 DirEntry *den_ptr;
32 FileEntry first_file_entry;
33 FileEntry *fes_ptr;
34 FileEntry *fen_ptr;
35 int file_count;
36
37
38 /* dir_entry initialisieren */
39 /*--------------------------*/
40
41 dir_entry->file = NULL;
42 /*
43 dir_entry->next = NULL;
44 dir_entry->prev = NULL;
45 */
46 dir_entry->sub_tree = NULL;
47 dir_entry->total_bytes = 0L;
48 dir_entry->matching_bytes = 0L;
49 dir_entry->tagged_bytes = 0L;
50 dir_entry->total_files = 0;
51 dir_entry->matching_files = 0;
52 dir_entry->tagged_files = 0;
53 dir_entry->access_denied = FALSE;
54 dir_entry->start_file = 0;
55 dir_entry->cursor_pos = 0;
56 dir_entry->global_flag = FALSE;
57 dir_entry->login_flag = FALSE;
58 dir_entry->big_window = FALSE;
59 dir_entry->not_scanned = FALSE;
60
61 if( S_ISBLK( dir_entry->stat_struct.st_mode ) )
62 return( 0 ); /* Block-Device */
63
64 if( depth < 0 )
65 {
66 if( dir_entry->up_tree )
67 {
68 dir_entry->up_tree->not_scanned = TRUE;
69 return( 1 );
70 }
71 }
72
73 statistic.disk_total_directories++;
74
75 if( ( dir = opendir( path ) ) == NULL )
76 {
77 dir_entry->access_denied = TRUE;
78 return( 1 );
79 }
80
81 first_dir_entry.prev = NULL;
82 first_dir_entry.next = NULL;
83 *first_dir_entry.name = '\0';
84 first_file_entry.next = NULL;
85 fes_ptr = &first_file_entry;
86
87 file_count = 0;
88 while( ( dirent = readdir( dir ) ) != NULL )
89 {
90 if( !strcmp( dirent->d_name, "." ) || !strcmp( dirent->d_name, ".." ) )
91 continue;
92
93 if( EscapeKeyPressed() )
94 {
95 Quit(); /* Abfrage ob ytree verlassen werden soll */
96 }
97
98 if( ( file_count++ % 100 ) == 0 ) {
99 DisplayDiskStatistic();
100 doupdate();
101 }
102
103
104 (void) strcpy( new_path, path );
105 if( strcmp( new_path, FILE_SEPARATOR_STRING ) )
106 (void) strcat( new_path, FILE_SEPARATOR_STRING );
107 (void) strcat( new_path, dirent->d_name );
108
109 if( STAT_( new_path, &stat_struct ) )
110 {
111 if( errno == EACCES ) continue;
112 (void) sprintf( message, "Stat failed on*%s*IGNORED", new_path );
113 ERROR_MSG( message );
114 continue;
115 }
116
117 if( S_ISDIR( stat_struct.st_mode ) )
118 {
119 /* Directory-Entry */
120 /*-----------------*/
121
122 if( ( den_ptr = (DirEntry *)
123 malloc( sizeof( DirEntry ) + strlen( dirent->d_name ) )
124 ) == NULL )
125 {
126 ERROR_MSG( "Malloc Failed*ABORT" );
127 exit( 1 );
128 }
129
130 den_ptr->up_tree = dir_entry;
131
132 (void) strcpy( den_ptr->name, dirent->d_name );
133
134 (void) memcpy( &den_ptr->stat_struct,
135 &stat_struct,
136 sizeof( stat_struct )
137 );
138 den_ptr->prev = den_ptr->next = NULL;
139
140 (void) ReadTree( den_ptr, new_path, depth - 1);
141
142 /* Sortieren durch direktes Einfuegen */
143 /*------------------------------------*/
144
145 for( des_ptr = &first_dir_entry; des_ptr; des_ptr = des_ptr->next )
146 {
147 if( strcmp( des_ptr->name, den_ptr->name ) > 0 )
148 {
149 /* des-Element ist groesser */
150 /*--------------------------*/
151
152 den_ptr->next = des_ptr;
153 den_ptr->prev = des_ptr->prev;
154 des_ptr->prev->next = den_ptr;
155 des_ptr->prev = den_ptr;
156 break;
157 }
158
159 if( des_ptr->next == NULL )
160 {
161 /* Ende der Liste erreicht; ==> einfuegen */
162 /*----------------------------------------*/
163
164 den_ptr->prev = des_ptr;
165 den_ptr->next = des_ptr->next;
166 des_ptr->next = den_ptr;
167 break;
168 }
169 }
170 }
171 else
172 {
173 /* File-Entry */
174 /*------------*/
175
176 int n;
177 char link_path[PATH_LENGTH + 1];
178
179 /* Test, ob Eintrag Symbolischer Link ist */
180 /*----------------------------------------*/
181
182 n = 0; *link_path = '\0';
183
184 if( S_ISLNK( stat_struct.st_mode ) )
185 {
186 /* Ja, symbolischer Name wird an "echten" Namen angehaengt */
187 /*---------------------------------------------------------*/
188
189 if( ( n = readlink( new_path, link_path, sizeof( link_path ) ) ) == -1 )
190 {
191 (void) strcpy( link_path, "unknown" );
192 n = strlen( link_path );
193 }
194 link_path[n] = '\0';
195
196 if( ( fen_ptr = (FileEntry *)
197 malloc( sizeof( FileEntry ) +
198 strlen( dirent->d_name ) +
199 n + 1 )
200 ) == NULL )
201 {
202 ERROR_MSG( "Malloc Failed*ABORT" );
203 exit( 1 );
204 }
205
206 (void) strcpy( fen_ptr->name, dirent->d_name );
207 (void) strcpy( &fen_ptr->name[strlen(fen_ptr->name) + 1],
208 link_path );
209 }
210 else
211 {
212 if( ( fen_ptr = (FileEntry *)
213 malloc( sizeof( FileEntry ) + strlen( dirent->d_name ) )
214 ) == NULL )
215 {
216 ERROR_MSG( "Malloc Failed*ABORT" );
217 exit( 1 );
218 }
219
220 (void) strcpy( fen_ptr->name, dirent->d_name );
221 }
222
223 fen_ptr->next = NULL;
224 fen_ptr->prev = NULL;
225 fen_ptr->tagged = FALSE;
226
227 (void) memcpy( &fen_ptr->stat_struct,
228 &stat_struct,
229 sizeof( stat_struct )
230 );
231
232 fen_ptr->dir_entry = dir_entry;
233 fes_ptr->next = fen_ptr;
234 fen_ptr->prev = fes_ptr;
235 fes_ptr = fen_ptr;
236 dir_entry->total_files++;
237 dir_entry->total_bytes += stat_struct.st_size;
238 statistic.disk_total_files++;
239 statistic.disk_total_bytes += stat_struct.st_size;
240 }
241 }
242
243 (void) closedir( dir );
244
245 if( first_file_entry.next ) first_file_entry.next->prev = NULL;
246 if( first_dir_entry.next ) first_dir_entry.next->prev = NULL;
247
248 dir_entry->file = first_file_entry.next;
249 dir_entry->sub_tree = first_dir_entry.next;
250
251 DisplayDiskStatistic();
252 doupdate();
253
254 return( 0 );
255 }
256
257
258
UnReadTree(DirEntry * dir_entry)259 void UnReadTree(DirEntry *dir_entry)
260 {
261 FileEntry *fe_ptr, *next_fe_ptr;
262
263 if( dir_entry == statistic.tree )
264 {
265 MESSAGE( "Can't delete ROOT" );
266 }
267 else
268 {
269 for( fe_ptr=dir_entry->file; fe_ptr; fe_ptr=next_fe_ptr )
270 {
271 next_fe_ptr = fe_ptr->next;
272 RemoveFile( fe_ptr );
273 }
274 if( dir_entry->sub_tree )
275 {
276 UnReadSubTree( dir_entry->sub_tree );
277 }
278 statistic.disk_total_directories--;
279 (void) GetAvailBytes( &statistic.disk_space );
280 DisplayDiskStatistic();
281 doupdate();
282 }
283 }
284
285
UnReadSubTree(DirEntry * dir_entry)286 static void UnReadSubTree(DirEntry *dir_entry)
287 {
288 DirEntry *de_ptr, *next_de_ptr;
289 FileEntry *fe_ptr, *next_fe_ptr;
290
291 for( de_ptr = dir_entry; de_ptr; de_ptr = next_de_ptr )
292 {
293 next_de_ptr = de_ptr->next;
294
295 for( fe_ptr=de_ptr->file; fe_ptr; fe_ptr=next_fe_ptr )
296 {
297 next_fe_ptr = fe_ptr->next;
298 RemoveFile( fe_ptr );
299 }
300
301 if( de_ptr->sub_tree )
302 {
303 UnReadSubTree( de_ptr->sub_tree );
304 }
305
306 if( !de_ptr->up_tree->not_scanned )
307 statistic.disk_total_directories--;
308
309 if( de_ptr->prev ) de_ptr->prev->next = de_ptr->next;
310 else de_ptr->up_tree->sub_tree = de_ptr->next;
311 if( de_ptr->next ) de_ptr->next->prev = de_ptr->prev;
312
313 free( de_ptr );
314 }
315 }
316
317