33 |
#include "fildir.h" |
#include "fildir.h" |
34 |
#include <stdlib.h> |
#include <stdlib.h> |
35 |
#include <strings.h> |
#include <strings.h> |
36 |
|
#include <string.h> |
37 |
#include <unistd.h> |
#include <unistd.h> |
38 |
|
|
39 |
|
|
66 |
return strcasecmp((*(DirStruct **)s)->name,(*(DirStruct **)d)->name); |
return strcasecmp((*(DirStruct **)s)->name,(*(DirStruct **)d)->name); |
67 |
} |
} |
68 |
|
|
69 |
/* the qsort implemented into the glibc 2.2.4 is fucked up - it doesn't need |
/* we need to implement a loop with a stack, but I'm too lazy ;-) */ |
|
enough memory, but uses goto and break |
|
|
we need to implement a loop with a stack, but I'm too lazy ;-) */ |
|
70 |
|
|
71 |
void dirQsort(DirStruct **tab, size_t n, int (*fptr)(DirStruct *s, DirStruct *d)) |
void dirQsort(DirStruct **tab, size_t n, int (*fptr)(DirStruct *s, DirStruct *d)) |
72 |
{ |
{ |
113 |
|
|
114 |
/* sorts the dst structure */ |
/* sorts the dst structure */ |
115 |
|
|
116 |
DirStruct *dirSort(DirStruct *dst,int mode) |
DirStruct *dirSort(DirStruct *dst,int mode, int keep_prev) |
117 |
{ |
{ |
118 |
|
|
119 |
/* temporary variable */ |
/* temporary variable */ |
120 |
|
DirStruct *tds=NULL; |
|
DirStruct *tds=NULL; |
|
121 |
|
|
122 |
/* number of inodes */ |
/* number of inodes */ |
|
|
|
123 |
unsigned long c; |
unsigned long c; |
124 |
|
|
125 |
/* helping variable */ |
/* helping variable */ |
|
|
|
126 |
unsigned long i; |
unsigned long i; |
127 |
|
|
128 |
/* all inodes */ |
/* all inodes */ |
|
|
|
129 |
DirStruct **tdsa; |
DirStruct **tdsa; |
130 |
|
|
|
/* idx1: the first directory; idx2: the first file */ |
|
|
|
|
|
unsigned long idx1,idx2; |
|
131 |
int (*compr)(const void *, const void *); |
int (*compr)(const void *, const void *); |
132 |
|
|
133 |
if (dst==NULL) return NULL; |
if (dst==NULL) return NULL; |
134 |
|
|
135 |
/* if there is nothing to sort or we don't need to sort */ |
/* if there is nothing to sort or we don't need to sort */ |
|
|
|
136 |
if ((dst->files_count+dst->dir_count==0) || (mode==SORT_UNSORTED)) return dst; |
if ((dst->files_count+dst->dir_count==0) || (mode==SORT_UNSORTED)) return dst; |
137 |
|
|
|
/* we are selecting the first */ |
|
|
|
|
|
tds=dst->first; |
|
|
|
|
138 |
/* number of inodes */ |
/* number of inodes */ |
139 |
|
c=dst->last->index-dst->index+1; |
|
c=tds->last->index; |
|
|
idx1=2; |
|
140 |
|
|
141 |
/* index of the first file */ |
/* if there is nothing to sort */ |
142 |
|
if (c<2) return dst; |
|
idx2=tds->dir_count+1; |
|
|
|
|
|
/* if there is nothing to sort */ |
|
|
|
|
|
if (c<3) return dst->first; |
|
143 |
|
|
144 |
tdsa=(DirStruct **)xmalloc((c-1)*sizeof(DirStruct)); |
tds=dst; |
145 |
for (i=0;((i<(c-1)) && (tds->next!=NULL));i++) { |
tdsa=(DirStruct **)xmalloc(c*sizeof(DirStruct)); |
146 |
tdsa[i]=tds->next; |
for (i=0;((i<c) && (tds!=NULL));i++) { |
147 |
|
tdsa[i]=tds; |
148 |
tds=tds->next; |
tds=tds->next; |
149 |
} |
} |
150 |
|
if (i!=c) c=i; |
151 |
|
|
152 |
if (mode==SORT_NAME) compr=cmpName; |
if (mode==SORT_NAME) compr=cmpName; |
153 |
else if (mode==SORT_DIR_FIRST) compr=cmpDirFirst; |
else if (mode==SORT_DIR_FIRST) compr=cmpDirFirst; |
154 |
else if (mode==SORT_SIZE) compr=cmpSize; |
else if (mode==SORT_SIZE) compr=cmpSize; |
155 |
qsort(tdsa,c-1,sizeof(*tdsa),compr); |
qsort(tdsa,c,sizeof(*tdsa),compr); |
156 |
|
|
|
tds=dst->first; |
|
157 |
|
|
158 |
/* moving from table to list */ |
/* moving from table to list */ |
159 |
|
|
160 |
for (i=0;i<(c-1);i++) { |
tdsa[0]->index=dst->index; |
161 |
tds->next=tdsa[i]; |
tdsa[0]->last=tdsa[c-1]; |
162 |
tds->next->index=i+2; |
if (keep_prev) { |
163 |
tds->next->prev=tds; |
tdsa[0]->prev=dst->prev; |
164 |
tds=tds->next; |
tdsa[0]->first=dst->first; |
165 |
|
} else { |
166 |
|
tdsa[0]->prev=NULL; |
167 |
|
tdsa[0]->first=tdsa[0]; |
168 |
|
} |
169 |
|
tdsa[c-1]->next=NULL; |
170 |
|
for (i=1;i<c;i++) { |
171 |
|
tds=tdsa[i]; |
172 |
|
tds->prev=tdsa[i-1]; |
173 |
|
tds->prev->next=tdsa[i]; |
174 |
|
tds->index=tds->prev->index+1; |
175 |
|
tds->first=tds->prev->first; |
176 |
|
tds->last=tdsa[c-1]; |
177 |
} |
} |
178 |
dst->first->last=tds; |
tds=tdsa[0]; |
|
tds->next=NULL; |
|
|
|
|
179 |
xfree(tdsa); |
xfree(tdsa); |
180 |
return dst; |
return tds; |
181 |
} |
} |
182 |
|
|
183 |
/* reads the directory content */ |
/* reads the directory content */ |
196 |
unsigned long tindex=1; |
unsigned long tindex=1; |
197 |
|
|
198 |
cat=opendir(dname); |
cat=opendir(dname); |
199 |
/* if we can't read the directory */ |
/* if we can't read the directory |
200 |
|
we create a node */ |
201 |
if (cat==NULL) { |
if (cat==NULL) { |
202 |
tmp=(DirStruct *)xmalloc(DSsize); |
tmp=(DirStruct *)xmalloc(DSsize); |
203 |
if (tmp!=NULL) { |
if (tmp!=NULL) { |
204 |
tmp->name=(char*)xmalloc(3); |
tmp->name=(char*)xmalloc(3); |
205 |
sprintf(tmp->name,".."); |
sprintf(tmp->name,".."); |
206 |
|
tmp->path=NULL; |
207 |
tmp->mode=040755; |
tmp->mode=040755; |
208 |
tmp->dir=1; |
tmp->dir=1; |
209 |
tmp->link=0; |
tmp->link=0; |
221 |
} |
} |
222 |
return tmp; |
return tmp; |
223 |
} |
} |
224 |
|
|
225 |
node=readdir(cat); |
node=readdir(cat); |
226 |
while ((node=readdir(cat))!=NULL) { |
while ((node=readdir(cat))!=NULL) { |
227 |
|
|
228 |
/* we are writing the pointer to the first DirStruct in the list */ |
/* we are writing the pointer to the first DirStruct in the list */ |
|
|
|
229 |
if (tmp2==NULL) { |
if (tmp2==NULL) { |
230 |
tmp=(DirStruct *)xmalloc(DSsize); |
tmp=(DirStruct *)xmalloc(DSsize); |
231 |
if(tmp==NULL) return NULL; |
if(tmp==NULL) return NULL; |
240 |
tmp->next->first=tmp->first; |
tmp->next->first=tmp->first; |
241 |
tmp=tmp->next; |
tmp=tmp->next; |
242 |
} |
} |
243 |
|
|
244 |
|
tmp->path=NULL; |
245 |
tmp->name=NULL; |
tmp->name=NULL; |
246 |
tnsize=strlen(node->d_name)+1; |
tnsize=strlen(node->d_name)+1; |
247 |
tname=(char *)xmalloc(tnsize); |
tname=(char *)xmalloc(tnsize); |
248 |
/*strcpy(tname,node->d_name);*/ |
//strcpy(tname,node->d_name); |
249 |
sprintf(tname,"%s",node->d_name); |
sprintf(tname,"%s",node->d_name); |
250 |
tmp->name=tname; |
tmp->name=tname; |
251 |
tmp->index=tindex++; |
tmp->index=tindex++; |
258 |
else { |
else { |
259 |
tmp->corrupt=FALSE; |
tmp->corrupt=FALSE; |
260 |
tmp->size=stbuf.st_size; |
tmp->size=stbuf.st_size; |
261 |
|
tmp->atime=stbuf.st_atime; |
262 |
|
tmp->mtime=stbuf.st_mtime; |
263 |
|
tmp->ctime=stbuf.st_ctime; |
264 |
tmp->mode=stbuf.st_mode; |
tmp->mode=stbuf.st_mode; |
265 |
tmp->uid=stbuf.st_uid; |
tmp->uid=stbuf.st_uid; |
266 |
tmp->gid=stbuf.st_gid; |
tmp->gid=stbuf.st_gid; |
272 |
tmp->link=S_ISLNK(stbuf.st_mode); |
tmp->link=S_ISLNK(stbuf.st_mode); |
273 |
tmp->size=stbuf.st_size; |
tmp->size=stbuf.st_size; |
274 |
tmp->mode=stbuf.st_mode; |
tmp->mode=stbuf.st_mode; |
275 |
/*if (tmp->corrupt) tmp->mode=stbuf.st_mode&S_IFMT;*/ |
//if (tmp->corrupt) tmp->mode=stbuf.st_mode&S_IFMT; |
276 |
} |
} |
277 |
|
|
278 |
if (tmp->dir) dc++; |
if (tmp->dir) dc++; |
284 |
tmp2->last=tmp; |
tmp2->last=tmp; |
285 |
tmp2->dir_count=--dc; |
tmp2->dir_count=--dc; |
286 |
tmp2->files_count=fc; |
tmp2->files_count=fc; |
287 |
|
|
288 |
|
/* copying dirs count and files count to all nodes */ |
289 |
|
tmp=tmp2; |
290 |
|
while (tmp->next!=NULL) { |
291 |
|
tmp->next->dir_count=tmp->dir_count; |
292 |
|
tmp->next->files_count=tmp->files_count; |
293 |
|
tmp->next->last=tmp->last; |
294 |
|
tmp=tmp->next; |
295 |
|
} |
296 |
|
|
297 |
return tmp2; |
return tmp2; |
298 |
} |
} |
299 |
|
|
300 |
|
/* duplicate DirStruct structure */ |
301 |
|
DirStruct *dirDuplicate(DirStruct *ds) |
302 |
|
{ |
303 |
|
DirStruct *tmp; |
304 |
|
|
305 |
|
tmp=NULL; |
306 |
|
if (ds!=NULL) { |
307 |
|
tmp=(DirStruct *)xmalloc(sizeof(DirStruct)); |
308 |
|
if (tmp!=NULL) { |
309 |
|
tmp->name=strdup(ds->name); |
310 |
|
tmp->path=NULL; |
311 |
|
tmp->mode=ds->mode; |
312 |
|
tmp->dir=ds->dir; |
313 |
|
tmp->link=ds->link; |
314 |
|
tmp->prev=NULL; |
315 |
|
tmp->next=NULL; |
316 |
|
tmp->first=NULL; |
317 |
|
tmp->last=NULL; |
318 |
|
tmp->corrupt=ds->corrupt; |
319 |
|
tmp->exe=ds->exe; |
320 |
|
tmp->index=ds->index; |
321 |
|
tmp->dir_count=0; |
322 |
|
tmp->files_count=0; |
323 |
|
tmp->selected=0; |
324 |
|
tmp->files_count=0; |
325 |
|
tmp->dir_count=0; |
326 |
|
tmp->size=ds->size; |
327 |
|
} |
328 |
|
} |
329 |
|
return tmp; |
330 |
|
} |
331 |
|
|
332 |
|
|
333 |
/* frees the memory used by dst */ |
/* frees the memory used by dst */ |
334 |
|
|
335 |
int dirFree(DirStruct *dst) |
int dirFree(DirStruct *dst) |
337 |
DirStruct *tds; |
DirStruct *tds; |
338 |
|
|
339 |
if (dst!=NULL) { |
if (dst!=NULL) { |
340 |
dst=dst->first; |
//dst=dst->first; |
341 |
while (dst!=NULL) { |
while (dst!=NULL) { |
342 |
tds=dst->next; |
tds=dst->next; |
343 |
xfree(dst->name); |
xfree(dst->name); |
344 |
|
if (dst->path!=NULL) xfree(dst->path); |
345 |
xfree(dst); |
xfree(dst); |
346 |
dst=tds; |
dst=tds; |
347 |
} |
} |
362 |
if (strcmp(name,tmp->name)==0) return tmp; |
if (strcmp(name,tmp->name)==0) return tmp; |
363 |
tmp=tmp->next; |
tmp=tmp->next; |
364 |
} |
} |
365 |
/* fprintf(stderr,"DIRFIND: nie znaleziono %s. skonczono na %s\n",name,tmp->name);*/ |
// fprintf(stderr,"DIRFIND: nie znaleziono %s. skonczono na %s\n",name,tmp->name); |
366 |
} |
} |
367 |
return NULL; |
return NULL; |
368 |
} |
} |
384 |
|
|
385 |
ds=ds->first; |
ds=ds->first; |
386 |
|
|
387 |
/* loop reading files/directories - we need to improve it, including a |
/* loop reading files/directories - we need to improve it */ |
|
realloc, if last > levels * DP_DIR_DEEP_LEVEL */ |
|
388 |
|
|
389 |
do { |
do { |
390 |
ds=ds->next; |
ds=ds->next; |
393 |
|
|
394 |
if (ds==NULL) return 0; |
if (ds==NULL) return 0; |
395 |
if (ds->selected || last) { |
if (ds->selected || last) { |
396 |
|
if (ds->path!=NULL) chdir(ds->path); |
397 |
if ((ds->dir) && (! ds->link)) { |
if ((ds->dir) && (! ds->link)) { |
398 |
(*fptr)(ds,DP_DIRIN); |
(*fptr)(ds,DP_DIRIN); |
399 |
tmp=chdir(ds->name); |
tmp=chdir(ds->name); |
400 |
if (tmp==0) { |
if (tmp==0) { |
401 |
/* fprintf(stderr,"DIRPROCESS: Entered to %s\n",ds->name);*/ |
// fprintf(stderr,"DIRPROCESS: Entered to %s\n",ds->name); |
402 |
subdir=dirSuck("."); |
subdir=dirSuck("."); |
403 |
|
|
404 |
/* we changed the directory */ |
/* we changed the directory */ |
431 |
chdir(".."); |
chdir(".."); |
432 |
dirFree(ds); |
dirFree(ds); |
433 |
ds=dstab[last]; |
ds=dstab[last]; |
434 |
/* fprintf(stderr,"DIRPROCESS: Back from %s\n",ds->name); */ |
// fprintf(stderr,"DIRPROCESS: Back from %s\n",ds->name); |
435 |
(*fptr)(ds,DP_DIROUT); |
(*fptr)(ds,DP_DIROUT); |
436 |
} |
} |
437 |
} while ((ds->next!=NULL) && (! dp_break)); |
} while ((ds->next!=NULL) && (! dp_break)); |