| 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)); |