Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / mbk / mbk_sys.c
1 /*
2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - Département ASIM
4 * Universite Pierre et Marie Curie
5 *
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail support : mailto:alliance-support@asim.lip6.fr
8 *
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Library General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * Alliance VLSI CAD System is distributed in the hope that it will be
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with the GNU C Library; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 /*
25 * Purpose : system dependant functions
26 * Date : 06/03/92
27 * Author : Frederic Petrot <Frederic.Petrot@lip6.fr>
28 * Modified by Czo <Olivier.Sirol@lip6.fr> 1997,98
29 */
30
31 #ident "$Id: mbk_sys.c,v 1.69 2008/09/22 14:34:15 anthony Exp $"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/wait.h>
39 #include <string.h>
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <regex.h>
43 #include <dirent.h>
44 #include <time.h>
45 #include <pthread.h>
46
47 // zinaps: to compute the memory consumed
48 /*
49 #ifdef Linux
50 #include <asm/page.h>
51 #endif
52 */
53
54 #ifdef Solaris
55 #define _STRUCTURED_PROC 1
56 #include <sys/procfs.h>
57 #endif
58
59 #include AVT_H
60 #include MUT_H
61 #include "mbk_sys.h"
62
63 #ifdef MALLOC_HISTOGRAM
64 #undef mbkalloc
65 #undef mbkfree
66 #undef mbkrealloc
67 #undef malloc
68 #undef free
69 #undef realloc
70 #endif
71
72 #ifdef Darwin
73 #include <sys/sysctl.h>
74 #include <mach/task.h>
75 #include <mach/mach_init.h>
76 #include <mach/shared_memory_server.h>
77 #endif
78
79
80 #define VFORKMAXTRY 100
81
82 static char filename[BUFSIZ];
83 char MBKFOPEN_NAME[BUFSIZ];
84 char MBKFOPEN_FILTER;
85 autoackchld_list *HEAD_AUTOACKCHLD=NULL;
86 autoackchld_list *HEAD_AUTOACKCHLD_FREE=NULL;
87 int STAT_AUTOACKCHLD;
88
89 it* MBK_TAB_FILE_ACCES=NULL;
90
91 long mbkalloc_stat = 0; /* statistics on maximun allocated memory */
92
93 void *mbkalloc(nbytes)
94 size_t nbytes;
95 {
96 void *pt;
97
98 mbkalloc_stat += nbytes;
99 if (!(pt = malloc(nbytes))) {
100 avt_errmsg (MBK_ERRMSG, "045", AVT_FATAL,(unsigned long)nbytes,mbkprocessmemoryusage()/(unsigned long)1024);
101 }
102 return pt;
103 }
104
105 void *mbkrealloc(pt, nbytes)
106 void *pt;
107 unsigned int nbytes;
108 {
109
110 mbkalloc_stat += nbytes;
111 if (!(pt = realloc(pt, nbytes))) {
112 avt_errmsg (MBK_ERRMSG, "046", AVT_FATAL);
113 }
114 return pt;
115 }
116
117 void mbkfree(ptr)
118 void *ptr;
119 {
120 #ifdef lint
121 (void)free((char *)ptr);
122 #else
123 (void)free(ptr); /* lint makes a mistake here : expects (char *) */
124 #endif
125 }
126
127 /* file opening :
128 defines the strategy used for searching and opening file in the
129 mbk environement. */
130 FILE* mbkfopen( name, extension, mode )
131 char *name;
132 char *extension;
133 char *mode;
134 {
135 return mbkfopen_ext( name, extension, mode, 0, 1 );
136 }
137
138 FILE* mbkfopen_ext( name, extension, mode, access, allowcompress )
139 char *name;
140 char *extension;
141 char *mode;
142 char access;
143 char allowcompress;
144 {
145 FILE *ptf;
146 int ln, le, i, j;
147
148 // Check name contain extension
149 if( extension ) {
150 ln = strlen( name );
151 le = strlen( extension );
152 for( i=ln-1, j=le-1 ; i>=0 && j>=0 && name[i] == extension[j] ; i--, j-- );
153 if( name[i] == '.' )
154 extension = NULL;
155 }
156
157 ptf = mbkfopentrace( name, extension, mode, access, allowcompress );
158
159 avt_log( LOGFILEACCESS, 1,
160 "open( \"%s\", \"%s\", \"%s\" ) -> %s [%s]\n",
161 name,
162 extension ? extension : "",
163 mode,
164 ptf ? MBKFOPEN_NAME : "FAILED",
165 mbk_getfileacces( ptf ) == MBK_FILE_STD ? "STD" : "LFS"
166 );
167 return( ptf );
168 }
169
170 void mbkfopen_infos( in, filename, name, extension, mode )
171 FILE *in;
172 char *filename;
173 char *name;
174 char *extension;
175 char *mode;
176 {
177 avt_log( LOGFILEACCESS, 2,
178 "%s : %s, (%s,%s,%s)\n",
179 in ? "ok" : "FAILED",
180 filename,
181 name,
182 extension ? extension : "",
183 mode
184 );
185 }
186
187 /*******************************************************************************
188
189 Fonctions d'accès aux fichiers en 32 ou en 64 bits dans un environnement 32
190 bits.
191
192 Informations :
193
194 En écriture, le mode 64 est toujours utilisé.
195
196 En lecture, si la taille du fichier est inférieure à MBK_LIMIT_USELARGEFILE,
197 le mode 32 bits est utilisé, sinon, c'est le mode 64.
198 Pour savoir en quel mode a été ouvert un fichier, il faut utiliser
199 mbk_getfileacces, qui renvoit MBK_FILE_STD ou MBK_FILE_LFS.
200 Lorsque le programme est compilé en 64 bits, le mode MBK_FILE_STD est toujours
201 utilisé puisque les fonctions de base accèdent en mode natif à des fichiers
202 en 64bits.
203 MBK_OFFSET_STD et MBK_OFFSET_LFS sont les types qui permettent de stocker les
204 offsets, selon le mode renvoyer par mbk_getfileacces(). L'objet MBK_OFFSET_STD
205 est stockable dans un long.
206
207 Fonctions de positionnement dans un fichier.
208
209 mbkftell() et mbkfseek() permettent d'appeller les fonctions fseek et ftell sans
210 se soucier du mode d'acces au fichier. Les offsets étant de taille variable, ils
211 sont passés par pointeur. Le type MBK_OFFSET_MAX est un type qui permet de
212 stocker n'importe quelle taille d'offset.
213
214 *******************************************************************************/
215
216 void mbk_setfileacces( FILE *file, char acces )
217 {
218 if( !file ) return;
219
220 if( ! MBK_TAB_FILE_ACCES )
221 MBK_TAB_FILE_ACCES = addit( 10 );
222
223 setititem( MBK_TAB_FILE_ACCES, fileno( file ), (long)acces );
224 }
225
226 char mbk_getfileacces( FILE *file )
227 {
228 if( !file || !MBK_TAB_FILE_ACCES ) return 0;
229 return (char)getititem( MBK_TAB_FILE_ACCES, fileno( file ) );
230 }
231
232 // Renvoie 1 en cas de succès, 0 en cas d'echec.
233 int mbkftell( FILE *file, MBK_OFFSET_MAX *offset )
234 {
235 int r=1;
236 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
237 if( mbk_getfileacces( file ) == MBK_FILE_STD ) {
238 *((MBK_OFFSET_STD*)offset) = ftell( file );
239 if( *((MBK_OFFSET_STD*)offset) == (MBK_OFFSET_STD)-1 )
240 r = 0;
241 }
242 else {
243 *((MBK_OFFSET_LFS*)offset) = ftello64( file );
244 if( *((MBK_OFFSET_LFS*)offset) == (MBK_OFFSET_LFS)-1 )
245 r = 0;
246 }
247 #else
248 *((MBK_OFFSET_STD*)offset) = ftell( file );
249 if( *((MBK_OFFSET_STD*)offset) == (MBK_OFFSET_STD)-1 )
250 r = 0;
251 #endif
252
253 return r;
254 }
255
256 // Renvoie 1 en cas de succès, 0 en cas d'echec.
257 int mbkfseek( FILE *file, MBK_OFFSET_MAX *offset, int whence )
258 {
259 int r;
260 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
261 if( mbk_getfileacces( file ) == MBK_FILE_STD )
262 r = fseek( file, *((MBK_OFFSET_STD*)offset), whence );
263 else
264 r = fseeko64( file, *((MBK_OFFSET_LFS*)offset), whence );
265 #else
266 r = fseek( file, *((MBK_OFFSET_STD*)offset), whence );
267 #endif
268
269 if( r<0 )
270 return 0;
271 return 1;
272 }
273
274 long long unsigned mbk_getfilesize( char *name )
275 {
276 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
277 struct stat64 infos;
278 int r;
279
280 r=stat64( name, &infos );
281 if( r==-1) return 0;
282 return (long long unsigned) infos.st_size;
283 #else
284 struct stat infos;
285 int r;
286
287 r=stat( name, &infos );
288 if( r==-1) {
289 if( errno == EOVERFLOW ) {
290 avt_errmsg (MBK_ERRMSG, "047", AVT_FATAL, name);
291 }
292 return 0;
293 }
294 return (long long unsigned) infos.st_size;
295 #endif
296 }
297
298 FILE *mbksysfopen( char *name, char *mode, char access )
299 {
300 FILE *file;
301
302 if( strchr(mode,'w')!=NULL || strchr(mode,'a')!=NULL) {
303 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
304 switch( access ) {
305 case MBK_FILE_LFS :
306 case 0:
307 file = fopen64( name, mode );
308 mbk_setfileacces( file, MBK_FILE_LFS );
309 break;
310 case MBK_FILE_STD :
311 file = fopen( name, mode );
312 mbk_setfileacces( file, MBK_FILE_STD );
313 break;
314 default:
315 avt_errmsg (MBK_ERRMSG, "048", AVT_FATAL);
316 }
317 #else
318 file = fopen( name, mode );
319 mbk_setfileacces( file, MBK_FILE_STD );
320 #endif
321 }
322 else {
323 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
324 if( access == 0 ) {
325 if( mbk_getfilesize( filename ) > MBK_LIMIT_USELARGEFILE ) {
326 file = fopen64( name, mode );
327 mbk_setfileacces( file, MBK_FILE_LFS );
328 }
329 else {
330 file = fopen( name, mode );
331 mbk_setfileacces( file, MBK_FILE_STD );
332 }
333 }
334 else {
335 if( access == MBK_FILE_LFS ) {
336 file = fopen64( name, mode );
337 mbk_setfileacces( file, MBK_FILE_LFS );
338 }
339 else {
340 file = fopen( name, mode );
341 mbk_setfileacces( file, MBK_FILE_STD );
342 }
343 }
344 #else
345 file = fopen( name, mode );
346 mbk_setfileacces( file, MBK_FILE_STD );
347 #endif
348 }
349
350 access=0;
351 return file;
352 }
353
354 /******************************************************************************/
355
356 // Ouvre un fichier. Le nom UNIX de ce fichier est stocké dans la variable
357 // global MBKFOPEN_NAME.
358
359 FILE *mbkfopentrace(name, extension, mode, access, allowcompress)
360 char *name, *extension, *mode;
361 char access, allowcompress ;
362 {
363 FILE *in;
364 FILE *infilter;
365 int i;
366 char suffix[512], suffixfilter[512] ;
367 char filenamefilter[BUFSIZE];
368 char *prefixlist[64];
369 char local ;
370
371 if (!CATA_LIB || !WORK_LIB)
372 mbkenv(); /* not done yet */
373
374 if( *mode != 'r' && *mode !='w' && *mode !='a') {
375 fflush( stdout );
376 fprintf( stderr,
377 "Fatal error in mbkfopentrace() : unknown mode %s\n",
378 mode
379 );
380 EXIT(1);
381 }
382
383 if( *mode == 'w' || *mode == 'a' || mode[1] == 'l' )
384 local = 1 ;
385 else
386 local = 0 ;
387
388 if (*mode == 'a') allowcompress=0;
389
390 // Le tableau prefixlist contient la liste des répertoires où acceder les
391 // fichiers.
392
393 if( name[0]=='/' ) {
394 prefixlist[0]="";
395 prefixlist[1]=NULL;
396 }
397 else {
398 prefixlist[0] = WORK_LIB;
399 if( local == 1 ) {
400 prefixlist[1] = NULL;
401 }
402 else {
403 i=0;
404 while (CATA_LIB[i]) {
405 prefixlist[i+1] = CATA_LIB[i];
406 i++;
407 }
408 prefixlist[i+1] = NULL;
409 }
410 }
411
412 // Accès aux fichiers
413 i=0;
414 while( prefixlist[i] ) {
415
416 if( extension )
417 sprintf( suffix, ".%s", extension );
418 else
419 suffix[0]='\0';
420
421 if( ( ( OUT_FILTER && *mode == 'w' ) || ( IN_FILTER && *mode == 'r' ))
422 && FILTER_SFX && allowcompress )
423 sprintf( suffixfilter, "%s", FILTER_SFX );
424 else
425 suffixfilter[0]='\0';
426
427 if (strcmp(prefixlist[i],"")!=0)
428 {
429 sprintf( filename, "%s/%s%s", prefixlist[i], name, suffix );
430 sprintf( filenamefilter, "%s/%s%s%s", prefixlist[i],
431 name,
432 suffix,
433 suffixfilter
434 );
435 }
436 else
437 {
438 sprintf( filename, "%s%s", name, suffix );
439 sprintf( filenamefilter, "%s%s%s", name,
440 suffix,
441 suffixfilter
442 );
443 }
444
445 if (V_STR_TAB[__AVT_EXCLUDE_COMPRESSION].VALUE!=NULL && *mode=='w')
446 {
447 char buf[1024];
448 char *c, *tok;
449 strcpy(buf, V_STR_TAB[__AVT_EXCLUDE_COMPRESSION].VALUE);
450 tok=strtok_r(buf, " ", &c);
451 while (tok!=NULL)
452 {
453 if (mbk_TestREGEX(filename, tok))
454 {
455 suffixfilter[0]='\0';
456 break;
457 }
458 tok=strtok_r(NULL, " ", &c);
459 }
460 }
461
462 // Stratégies différentes selon le mode d'ouverture :
463 // Ecriture : le format preféré est le compressé, l'autre est effacé
464 // Lecture : le format préféré est le non compressé, l'autre est ignoré
465
466 if( *mode == 'r' ) {
467
468 in = mbksysfopen( filename, "r", access );
469 mbkfopen_infos( in, filename, name, extension, mode );
470
471 if( suffixfilter[0] ) {
472 infilter = mbkpopen( filenamefilter, IN_FILTER, 'r' );
473 mbkfopen_infos( infilter, filenamefilter, name, extension, mode );
474 }
475 else
476 infilter = NULL;
477
478 if( in && infilter ) {
479 avt_errmsg (MBK_ERRMSG, "049", AVT_WARNING, filename, filenamefilter);
480 fclose( infilter );
481 infilter = NULL;
482 }
483 }
484 else if ( *mode == 'w' || *mode == 'a') {
485
486 if( suffixfilter[0] ) {
487 infilter = mbkpopen( filenamefilter, OUT_FILTER, 'w' );
488 mbkfopen_infos( infilter, filenamefilter, name, extension, mode );
489 in = mbksysfopen( filename, "r", access );
490 mbkfopen_infos( in, filename, name, extension, mode );
491 }
492 else {
493 infilter = NULL;
494 in = mbksysfopen( filename, *mode == 'a'?"a":"w", access );
495 mbkfopen_infos( in, filename, name, extension, mode );
496 }
497
498 if( in && infilter ) {
499 avt_errmsg (MBK_ERRMSG, "050", AVT_WARNING, filenamefilter, filename);
500 fclose( in );
501 unlink( filename );
502 in = NULL;
503 }
504 }
505
506 if( infilter ) {
507 strcpy( MBKFOPEN_NAME, filenamefilter );
508 MBKFOPEN_FILTER = YES;
509 return( infilter );
510 }
511
512 if( in ) {
513 strcpy( MBKFOPEN_NAME, filename );
514 MBKFOPEN_FILTER = NO;
515 return( in );
516 }
517
518 i++;
519 }
520 return( NULL );
521 }
522
523 /* unlink :
524 ensures that only files in the working library may be erased. */
525 int mbkunlink(name, extension)
526 char *name, *extension;
527 {
528 if (!CATA_LIB || !WORK_LIB)
529 mbkenv(); /* not done yet */
530
531 if (extension) /* if extension is null, no dot is required */
532 (void)sprintf(filename, "%s/%s.%s", WORK_LIB, name, extension);
533 else
534 (void)sprintf(filename, "%s/%s", WORK_LIB, name);
535
536 return unlink(filename);
537 }
538
539 /* filepath :
540 find the complete path of file from mbkfopen point of view. */
541 char *filepath(name, extension)
542 char *name, *extension;
543 {
544 FILE *in;
545 int i ,ln ,le ,j ;
546
547 if (!CATA_LIB || !WORK_LIB)
548 mbkenv(); /* not done yet */
549
550 if( extension ) {
551 ln = strlen( name );
552 le = strlen( extension );
553 for( i=ln-1, j=le-1 ; i>=0 && j>=0 && name[i] == extension[j] ; i--, j-- );
554 if( name[i] == '.' )
555 extension = NULL;
556 }
557
558
559 if (*name == '/') {
560 if( extension ) sprintf(filename, "%s.%s", name, extension);
561 else sprintf(filename, "%s", name);
562
563 if ((in = mbksysfopen(filename, READ_TEXT, 0))) {
564 fclose(in);
565 return filename;
566 }
567
568 if( FILTER_SFX && IN_FILTER ) {
569 if( extension ) sprintf(filename, "%s.%s%s", name, extension, FILTER_SFX);
570 else sprintf(filename, "%s%s", name, FILTER_SFX);
571
572 if ((in = mbksysfopen(filename, READ_TEXT, 0))) {
573 fclose(in);
574 return filename;
575 }
576 }
577 return NULL;
578 }
579
580 if (extension) /* if extension is null, no dot is required */
581 (void)sprintf(filename, "%s/%s.%s", WORK_LIB, name, extension );
582 else
583 (void)sprintf(filename, "%s/%s", WORK_LIB, name );
584
585 if ((in = mbksysfopen(filename, READ_TEXT, 0))) {
586 (void)fclose(in);
587 return filename;
588 }
589
590 if( FILTER_SFX && IN_FILTER )
591 {
592 if (extension) /* if extension is null, no dot is required */
593 (void)sprintf(filename, "%s/%s.%s%s", WORK_LIB, name, extension, FILTER_SFX );
594 else
595 (void)sprintf(filename, "%s/%s%s", WORK_LIB, name, FILTER_SFX );
596
597 if ((in = mbksysfopen(filename, READ_TEXT, 0))) {
598 (void)fclose(in);
599 return filename;
600 }
601 }
602
603
604 i = 0;
605 while (CATA_LIB[i]) {
606 if (extension) /* if extension is null, no dot is required */
607 (void)sprintf(filename, "%s/%s.%s", CATA_LIB[i], name, extension );
608 else
609 (void)sprintf(filename, "%s/%s", CATA_LIB[i], name );
610
611 if ((in = mbksysfopen(filename, READ_TEXT, 0))) {
612 (void)fclose(in);
613 return filename;
614 }
615
616 if( FILTER_SFX && IN_FILTER )
617 {
618 if (extension) /* if extension is null, no dot is required */
619 (void)sprintf(filename, "%s/%s.%s%s", CATA_LIB[i], name, extension, FILTER_SFX );
620 else
621 (void)sprintf(filename, "%s/%s%s", CATA_LIB[i], name, FILTER_SFX );
622
623 if ((in = mbksysfopen(filename, READ_TEXT, 0))) {
624 (void)fclose(in);
625 return filename;
626 }
627 }
628 i++;
629 }
630 return NULL;
631 }
632
633 #if 0
634 /* process state :
635 this gives some information on allocated memory, time spend, and so on. */
636 void mbkps()
637 {
638 #include <sys/time.h>
639 #include <sys/resource.h>
640 struct rusage rusage;
641 static int pagesize;
642 extern long mbkalloc_stat;
643 static int times;
644
645 if (!times)
646 pagesize = getpagesize() / 1024;
647 (void)getrusage(RUSAGE_SELF, &rusage);
648 (void)fprintf(stdout, "mbk stats : %d call\n", ++times);
649 (void)fprintf(stdout, "user time : %ld sec\n",
650 rusage.ru_utime.tv_sec);
651 (void)fprintf(stdout, "system time : %d sec\n",
652 rusage.ru_stime.tv_usec);
653 (void)fprintf(stdout, "real size : %ld k\n",
654 rusage.ru_maxrss * pagesize);
655 (void)fprintf(stdout, "mbkalloc peak size : %ld k\n",
656 mbkalloc_stat / 1024);
657 (void)fprintf(stdout, "mallinfo size : %ld k\n",
658 mallinfo().arena / 1024);
659 }
660 #endif
661
662 /* mbkpopen : open a pipe with a filter, return a FILE*
663 * Gregoire.Avot
664 */
665
666 FILE* mbkpopen( char *nom, char *filter, char mode )
667 {
668 int ptf[2];
669 static int fic;
670 int pid;
671 FILE *file;
672 char **argv;
673 int i;
674 int errfile ;
675
676 if( mode == 'w' )
677 fic = open( nom,
678 O_WRONLY|O_CREAT|O_TRUNC,
679 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
680 );
681 else
682 fic = open( nom, O_RDONLY );
683
684 if( fic == -1 )
685 return( NULL );
686
687 if( pipe( ptf ) == -1 )
688 {
689 fflush( stdout );
690 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" )\n", nom );
691 perror( "pipe() ");
692 EXIT(1);
693 }
694
695 argv = decompfilter( filter );
696
697 i=1 ;
698 do {
699 pid = vfork();
700 if( pid == -1 ) {
701 perror( "vfork() " );
702 if( i<VFORKMAXTRY ) {
703 fflush( stdout );
704 printf( "vfork() #%d attempt failed. wait a few moment...\n", i );
705 sleep( 6 );
706 }
707 }
708 i++;
709 }
710 while( pid == -1 && i <= VFORKMAXTRY );
711
712 if( pid == -1 )
713 {
714 fflush( stdout );
715 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" )\n", nom );
716 printf( "Memory usage : %ldKb\n", mbkprocessmemoryusage()/1024 );
717 EXIT(1);
718 }
719
720 if( pid == 0 )
721 {
722 /* fils */
723 fflush( stdout );
724
725 if( argv == NULL )
726 {
727 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
728 fprintf( stderr, "Bad filter.\n" );
729 EXIT(1);
730 }
731
732 if( mode == 'w' )
733 {
734 if( dup2( ptf[0], 0 ) == -1 )
735 {
736 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
737 perror( "dup2( ptf[0], 0 ) ");
738 EXIT(1);
739 }
740
741 if( dup2( fic, 1 ) == -1 )
742 {
743 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
744 perror( "dup2( fic, 1 ) ");
745 EXIT(1);
746 }
747 }
748 else
749 {
750 if( dup2( ptf[1], 1 ) == -1 )
751 {
752 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
753 perror( "dup2( ptf[1], 1 ) ");
754 EXIT(1);
755 }
756
757 if( dup2( fic, 0 ) == -1 )
758 {
759 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
760 perror( "dup2( fic, 0 ) ");
761 EXIT(1);
762 }
763 }
764
765 if( close( fic ) == -1 )
766 {
767 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
768 perror( "close( fic ) ");
769 EXIT(1);
770 }
771
772 if( close( ptf[1] ) == -1 )
773 {
774 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
775 perror( "close( ptf[1] ) ");
776 EXIT(1);
777 }
778
779 if( close( ptf[0] ) == -1 )
780 {
781 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
782 perror( "close( ptf[0] ) ");
783 EXIT(1);
784 }
785
786 if( V_BOOL_TAB[ __MBK_FILTER_MASK_ERROR ].VALUE ) {
787 errfile = open( "/dev/null", 0 );
788 if( errfile < 0 ) {
789 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
790 perror( "open(\"/dev/null\",0) " );
791 EXIT(1);
792 }
793 if( dup2( errfile, 2 ) == -1 )
794 {
795 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
796 perror( "dup2( errfile, 2 ) ");
797 EXIT(1);
798 }
799 if( close( errfile ) == -1 )
800 {
801 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
802 perror( "close( errfile ) ");
803 EXIT(1);
804 }
805 }
806
807 if( execvp( argv[0], &(argv[1]) ) == -1 )
808 {
809 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
810 perror( "execvp " );
811 EXIT(1);
812 }
813 }
814
815 for( i=0 ; argv[i] ; i++ )
816 mbkfree( argv[i] );
817 mbkfree( argv );
818
819 mbksetautoackchld( pid );
820 close( fic );
821
822 if( mode == 'w' )
823 {
824 if( close( ptf[0] ) == -1 )
825 {
826 fflush( stdout );
827 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom );
828 perror( "close( ptf[0] ) ");
829 EXIT(1);
830 }
831
832 file = fdopen( ptf[1], "w" );
833 if( file == NULL )
834 {
835 fflush( stdout );
836 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom );
837 perror( "fdopen( ptf[1], \"w\" ) ");
838 EXIT(1);
839 }
840 }
841 else
842 {
843 if( close( ptf[1] ) == -1 )
844 {
845 fflush( stdout );
846 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom );
847 perror( "close( ptf[1] ) ");
848 EXIT(1);
849 }
850
851 file = fdopen( ptf[0], "r" );
852 if( file == NULL )
853 {
854 fflush( stdout );
855 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom );
856 perror( "fdopen( ptf[0], \"r\" ) ");
857 EXIT(1);
858 }
859 }
860
861 return( file );
862 }
863
864 char **decompfilter( char *filter )
865 {
866 int pos;
867 int i;
868 char *pt;
869 char *fullpath;
870 char *argv0;
871 char *argvn;
872 chain_list *head;
873 chain_list *scan;
874 int nbarg;
875 char **ret;
876
877 /* remove trailing space */
878 for( pos = 0 ; filter[pos] == ' ' && filter[pos] != 0 ; pos++ );
879 if( filter[pos] == 0 )
880 return( NULL );
881
882 /* The full path to binairie */
883 for( i = pos ; filter[i] != ' ' && filter[i] != 0 ; i++ );
884 fullpath = (char*)mbkalloc( sizeof(char) * ( i-pos+1 ) );
885 strncpy( fullpath, filter+pos, i-pos );
886 fullpath[i-pos] = 0;
887 pos = i;
888
889 /* The binairie himself */
890 pt = strrchr( fullpath, '/' );
891 argv0 = (char*)mbkalloc( sizeof( char ) * (strlen( fullpath ) + 1) );
892 if( pt == NULL )
893 strcpy( argv0, fullpath );
894 else
895 strcpy( argv0, pt+sizeof(char) );
896
897 /* The arguments */
898 head = NULL;
899 nbarg=2;
900
901 do
902 {
903 for( ; filter[pos] == ' ' && filter[pos] != 0 ; pos++ );
904 if( filter[pos] == 0 )
905 break;
906
907 for( i = pos ; filter[i] != ' ' && filter[i] != 0 ; i++ );
908 argvn = (char*)mbkalloc( sizeof( char ) * ( i-pos+1 ) );
909 strncpy( argvn, filter+pos, i-pos );
910 argvn[i-pos] = 0;
911 pos = i;
912 head = addchain( head, argvn );
913 nbarg++;
914 }
915 while( 1 );
916
917 head = reverse( head );
918
919 ret = (char**)mbkalloc( sizeof(char*) * (nbarg+1) );
920
921 ret[0] = fullpath;
922 ret[1] = argv0;
923
924 for( scan = head, pos=2 ; scan ; scan = scan->NEXT, pos++ )
925 ret[pos] = scan->DATA;
926 ret[pos] = NULL;
927
928 freechain( head );
929
930 return( ret );
931 }
932
933 void mbkackchld( int sig )
934 {
935 int status;
936 autoackchld_list *scanauto, *prevauto, *nextauto;
937
938 /* Le handlert d'interruption SIGCHLD. Il doit avoir été configuré pour ne
939 * pas être interrompu par lui même. */
940
941 if( sig != SIGCHLD )
942 {
943 fflush( stdout );
944 fprintf( stderr,
945 "*** mbk warning : call of mbkackchld with signal %d\n",
946 (int)sig
947 );
948 return;
949 }
950
951 for( scanauto = HEAD_AUTOACKCHLD, prevauto=NULL ;
952 scanauto ;
953 scanauto = nextauto
954 )
955 {
956 nextauto = scanauto->NEXT;
957 if( waitpid(scanauto->PID, &status, WNOHANG) == scanauto->PID )
958 {
959 if( prevauto )
960 prevauto->NEXT = scanauto->NEXT;
961 else
962 HEAD_AUTOACKCHLD = scanauto->NEXT;
963 mbkfreeautoackchld( scanauto );
964 }
965 else prevauto = scanauto ;
966 }
967 }
968
969 autoackchld_list* mbkgetautoackchld( void )
970 {
971 autoackchld_list *new;
972
973 if( ! HEAD_AUTOACKCHLD_FREE )
974 {
975 fflush( stdout );
976 fprintf( stderr,
977 "\n*** mbk ERROR : Not enought free slot in mbkgetautoackchld().\n"
978 );
979 EXIT(1);
980 }
981
982 new = HEAD_AUTOACKCHLD_FREE ;
983 HEAD_AUTOACKCHLD_FREE = HEAD_AUTOACKCHLD_FREE->NEXT ;
984
985 STAT_AUTOACKCHLD++;
986 return( new );
987 }
988
989 void mbkfreeautoackchld( autoackchld_list *bloc )
990 {
991 bloc->NEXT = HEAD_AUTOACKCHLD_FREE ;
992 HEAD_AUTOACKCHLD_FREE = bloc ;
993 STAT_AUTOACKCHLD--;
994 }
995
996 void mbkinitautoackchld( void )
997 {
998 autoackchld_list *bloc;
999 int n;
1000
1001 bloc=(autoackchld_list*)mbkalloc( sizeof( autoackchld_list ) * ENDCHLD_MAX );
1002 n = AUTOACKCHLD_MAX - 1;
1003 bloc[n].NEXT = NULL ;
1004 while( n > 0 )
1005 {
1006 n-- ;
1007 bloc[n].NEXT = &( bloc[n+1] );
1008 }
1009 HEAD_AUTOACKCHLD_FREE = &(bloc[0]);
1010 STAT_AUTOACKCHLD=0;
1011 }
1012
1013 void mbksetautoackchld( int pid )
1014 {
1015 autoackchld_list *new;
1016 sigset_t set;
1017 int status;
1018
1019 /* Fonction utilisateur : on met dans la liste HEAD_AUTOACKCHLD un numéro de
1020 * pid. Dès qu'un processus fils se termine ave ce pid, il sera
1021 * automatiquement supprimé. */
1022
1023 /* Dans le déroulement normal du programme, on touche ici à des structures
1024 * qui sont modifiées par le handler SIGCHLD. On évite de mettre le bazard en
1025 * blindant le morceau de code. */
1026
1027 sigemptyset( &set );
1028 sigaddset( &set, SIGCHLD );
1029 sigprocmask( SIG_BLOCK, &set, NULL );
1030
1031 if( waitpid( pid, &status, WNOHANG ) == 0 ) /* pas deja termine */
1032 {
1033 /* On ne voudra jamais savoir ce qu'est devenu le processus fils pid. On le
1034 * met dans la liste des processus à acquiter automatiquement */
1035 new = mbkgetautoackchld();
1036 new->PID = pid;
1037 new->NEXT = HEAD_AUTOACKCHLD ;
1038 HEAD_AUTOACKCHLD = new ;
1039 }
1040 sigprocmask( SIG_UNBLOCK, &set, NULL );
1041 }
1042
1043 unsigned long mbkprocessmemoryusage()
1044 {
1045 #ifdef Linux
1046 char temp[100];
1047 pid_t pid;
1048 FILE *f;
1049 int cnt;
1050 unsigned long size;
1051 pid=getpid();
1052 sprintf(temp,"/proc/%d/stat",pid);
1053 if ((f=fopen(temp,"rt"))==NULL) return (unsigned long)sbrk(0);
1054 for (cnt=1;cnt<=23;cnt++) fscanf(f,"%s",temp);
1055 size=strtoul(temp,NULL,10);
1056 fclose(f);
1057 return size;
1058 #endif
1059
1060 #ifdef Solaris
1061 unsigned long total;
1062 char file[255];
1063 int f;
1064
1065 sprintf( file, "/proc/%d/as", (int)getpid());
1066 f = open( file, O_RDONLY );
1067 if( f < 0 ) return (unsigned long)sbrk(0);
1068
1069 total = (unsigned long )lseek( f, 0, SEEK_END );
1070 close( f );
1071
1072 return total;
1073 #endif
1074
1075 #ifdef Darwin
1076 struct task_basic_info t_info;
1077 mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
1078 task_t task = MACH_PORT_NULL;
1079
1080 if (task_for_pid(current_task(), getpid(), &task) == KERN_SUCCESS) {
1081 task_info(task, TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
1082 return (unsigned long)(t_info.virtual_size - SHARED_TEXT_REGION_SIZE - SHARED_DATA_REGION_SIZE);
1083 }
1084 #endif
1085 return 0;
1086 }
1087
1088 char *mbkIsLofigExt(char *filename, char *ext)
1089 {
1090 char *c;
1091 c=&filename[strlen(filename)-1];
1092 while (c!=filename && *c!='.') c--;
1093 if (c==filename) return NULL;
1094 if (strcmp(c+1,ext)==0) return c;
1095 if (FILTER_SFX!=NULL)
1096 {
1097 char temp[20];
1098 c--;
1099 while (c!=filename && *c!='.') c--;
1100 if (c==filename) return NULL;
1101 sprintf(temp,".%s%s",ext,FILTER_SFX);
1102 if (strcmp(c,temp)==0) return c;
1103 }
1104 return 0;
1105 }
1106
1107 static int done=0;
1108 static char *ext[]={"","","","al","spi","hns","fdn","vhd","vlg","v","vst"};
1109
1110 static void setext()
1111 {
1112 char *c;
1113 if (!done)
1114 {
1115 char *SPI_SFX="spi", *VHD_SFX="vhd", *VLG_SFX="vlg";
1116 if ((c=V_STR_TAB[__MBK_SPI_SUFFIX].VALUE)!=NULL) SPI_SFX=c;
1117 if ((c=V_STR_TAB[__MVL_FILE_SUFFIX].VALUE)!=NULL) VHD_SFX=c;
1118 if ((c=V_STR_TAB[__MGL_FILE_SUFFIX].VALUE)!=NULL) VLG_SFX=c;
1119 ext[0]=SPI_SFX;
1120 ext[1]=VHD_SFX;
1121 ext[2]=VLG_SFX;
1122 done=1;
1123 }
1124 }
1125
1126 char *mbkFileIsLofig(char *filename)
1127 {
1128 unsigned int i;
1129 char *c;
1130 setext();
1131 for (i=0;i<sizeof(ext)/sizeof(*ext); i++)
1132 if ((c=mbkIsLofigExt(filename, ext[i]))!=NULL) return c;
1133 return NULL;
1134 }
1135
1136
1137 /****************************************************************************/
1138 /*{{{ Pipe functions */
1139 /* */
1140 /* author : Antony PinTo (anto) */
1141 /* */
1142 /* 8 january 2004 : anto creation */
1143 /* */
1144 /****************************************************************************/
1145 /*{{{ mbkpprint() */
1146 /* */
1147 /* write into a pipe */
1148 /* */
1149 /****************************************************************************/
1150 int mbkpprint(int fildes, void *data, int size)
1151 {
1152 ssize_t writen, remaining;
1153
1154 remaining = (ssize_t)size;
1155 writen = 0;
1156
1157 while (remaining)
1158 {
1159 writen += write(fildes,(char*)data+writen,remaining);
1160 if (writen < 0)
1161 break;
1162 remaining = size - writen;
1163 }
1164
1165 return (writen == (ssize_t)size);
1166 }
1167
1168 /*}}}************************************************************************/
1169 /*{{{ mbkpscan() */
1170 /* */
1171 /* read a pipe */
1172 /* */
1173 /****************************************************************************/
1174 int mbkpscan(int fildes, void *data, int size)
1175 {
1176 ssize_t readen, remaining, this_time;
1177
1178 remaining = (ssize_t)size;
1179 readen = 0;
1180
1181 while (remaining)
1182 {
1183 this_time = read(fildes,(char*)data+readen,remaining);
1184 readen += this_time;
1185 if (readen < 0)
1186 break;
1187 remaining = size - readen;
1188 }
1189
1190 return (readen == (ssize_t)size);
1191 }
1192
1193 /*}}}************************************************************************/
1194 /*{{{ mbkpcreate() */
1195 /* */
1196 /* forks and create the communication pipes */
1197 /* */
1198 /* return the result of fork() */
1199 /* */
1200 /****************************************************************************/
1201 pid_t mbkpcreate(int *file_des_write, int *file_des_read)
1202 {
1203 pid_t son_id;
1204 int server_to_client[2];
1205 int client_to_server[2];
1206
1207 pipe(server_to_client);
1208 pipe(client_to_server);
1209
1210 switch ((son_id = fork()))
1211 {
1212 case -1 :
1213 *file_des_write = 0;
1214 *file_des_read = 0;
1215 break;
1216 case 0 : // son is the client
1217 *file_des_write = client_to_server[1];
1218 *file_des_read = server_to_client[0];
1219 break;
1220 default : // father is the server
1221 *file_des_write = server_to_client[1];
1222 *file_des_read = client_to_server[0];
1223 break;
1224 }
1225
1226 return son_id;
1227 }
1228
1229 /*}}}************************************************************************/
1230 /*}}}************************************************************************/
1231 /*{{{ Test if come from gdb */
1232 /****************************************************************************/
1233 /*{{{ isGdb() */
1234 /* */
1235 /* */
1236 /****************************************************************************/
1237 static inline
1238 int isGdb(char *name)
1239 {
1240 return !strncmp("gdb",name,3);
1241 }
1242
1243 /*}}}************************************************************************/
1244 /*{{{ mbk_whoAmI() */
1245 /* */
1246 /* fill the buffer name with the process name */
1247 /* */
1248 /****************************************************************************/
1249 #ifdef Linux
1250 char *mbk_whoAmI(pid_t pd, char *name)
1251 {
1252 char buf[1024], *p;
1253 int fd;
1254 int len;
1255 char *res;
1256 char *q;
1257
1258 res = (char*)-1;
1259
1260 sprintf(buf,"/proc/%d/stat",(int)pd);
1261
1262 if ((fd = open(buf,O_RDONLY)) >= 0)
1263 {
1264 len = read(fd, buf, sizeof(buf)-1);
1265 buf[len] = '\0';
1266 p = buf;
1267 p = strchr(p,'(')+1;
1268 q = strrchr(p,')');
1269 len = q-p;
1270 if (len >= (signed)sizeof(name))
1271 len = sizeof(name)-1;
1272 memcpy(name,p,len);
1273 name[len] = 0;
1274 res = name;
1275 close(fd);
1276 }
1277 return res;
1278 }
1279 #endif
1280
1281 #ifdef Solaris
1282 char *mbk_whoAmI(pid_t pd, char *name)
1283 {
1284 char buf[1024], *p;
1285 int fd;
1286 int len;
1287 char *res;
1288
1289 psinfo_t curproc;
1290
1291 res = (char*)-1;
1292
1293 sprintf(buf,"/proc/%d/psinfo",(int)pd);
1294
1295 if ((fd = open(buf,O_RDONLY)) >= 0)
1296 {
1297 if ((read(fd,&curproc,sizeof(psinfo_t))) == sizeof(psinfo_t))
1298 {
1299 p = curproc.pr_fname;
1300 len = strlen(p);
1301 memcpy(name,p,len);
1302 name[len] = 0;
1303 res = name;
1304 }
1305 close(fd);
1306 }
1307 return res;
1308 }
1309 #endif
1310
1311 #ifdef Darwin
1312 char *mbk_whoAmI(pid_t pd, char *name)
1313 {
1314 int mib[4];
1315 size_t len = sizeof(struct kinfo_proc);
1316 struct kinfo_proc kp;
1317
1318 mib[0] = CTL_KERN;
1319 mib[1] = KERN_PROC;
1320 mib[2] = KERN_PROC_PID;
1321 mib[3] = pd;
1322 if (sysctl(mib, 4, &kp, &len, NULL, 0) == 0) {
1323 strcpy(name, kp.kp_proc.p_comm);
1324 }
1325 else strcpy(name, "unknown");
1326
1327 return name;
1328 }
1329 #endif
1330
1331 #ifdef Win32
1332 char *mbk_whoAmI(pid_t pd, char *name)
1333 {
1334 /* TODO */
1335 strcpy(name, "unknown");
1336
1337 return name;
1338 }
1339 #endif
1340
1341 /*}}}************************************************************************/
1342 /*{{{ mbk_whoAmILong() */
1343 /* */
1344 /* fill the buffer name with the process name */
1345 /* */
1346 /****************************************************************************/
1347 #ifdef Linux
1348 char *mbk_whoAmILong(pid_t pd, char *name)
1349 {
1350 char buf[1024];
1351 int fd;
1352 int len, done;
1353 char *res;
1354 int i;
1355 char buf2[1024];
1356 res = (char*)-1;
1357
1358 sprintf(buf,"/proc/%d/exe",(int)pd);
1359 len = readlink(buf,buf2,sizeof(buf));
1360 buf2[len] = '\0';
1361
1362 sprintf(buf,"/proc/%d/cmdline",(int)pd);
1363 if ((fd = open(buf,O_RDONLY)) >= 0)
1364 {
1365 done = 0;
1366 len = read(fd, buf, sizeof(buf)-1);
1367 for (i = 0; i < len; i ++)
1368 if (buf[i] == '\0')
1369 {
1370 if (!done)
1371 done = i;
1372 buf[i] = ' ';
1373 }
1374 buf[len] = '\0';
1375 close(fd);
1376 }
1377 sprintf(name,"%s %s",buf2,buf + done + 1);
1378
1379 return res;
1380 }
1381 #endif
1382
1383 #ifdef Solaris
1384 char *mbk_whoAmILong(pid_t pd, char *name)
1385 {
1386 char buf[1024];
1387 int fd;
1388 int len, done;
1389 char *res;
1390 char *p, *env, *tt, *strtok;
1391 psinfo_t curproc;
1392 struct stat st;
1393
1394 res = (char*)-1;
1395
1396 sprintf(buf,"/proc/%d/psinfo",(int)pd);
1397 if ((fd = open(buf,O_RDONLY)) >= 0)
1398 {
1399 done = 0;
1400 if ((read(fd,&curproc,sizeof(psinfo_t))) == sizeof(psinfo_t))
1401 {
1402 p = curproc.pr_psargs;
1403 if (p[0] != '/')
1404 if ((env = getenv("PATH")))
1405 while (!done)
1406 {
1407 strtok = strtok_r(env,":",&tt);
1408 env = NULL;
1409 sprintf(name,"%s/%s",strtok,curproc.pr_fname);
1410 if (!stat(name,&st) && (st.st_mode & (S_IROTH | S_IXOTH)))
1411 {
1412 sprintf(name,"%s/%s",strtok,curproc.pr_psargs);
1413 done = 1;
1414 }
1415
1416 if (tt)
1417 tt[-1] = ':';
1418 else
1419 done = 2;
1420 }
1421
1422 if (done != 1)
1423 {
1424 len = strlen(p);
1425 memcpy(name,p,len);
1426 name[len] = 0;
1427 }
1428 }
1429 res = name;
1430 close(fd);
1431 }
1432
1433 return res;
1434 }
1435 #endif
1436
1437 #ifdef Darwin
1438 char *mbk_whoAmILong(pid_t pd, char *name)
1439 {
1440 int mib[4];
1441 size_t len = sizeof(struct kinfo_proc);
1442 struct kinfo_proc kp;
1443
1444 mib[0] = CTL_KERN;
1445 mib[1] = KERN_PROC;
1446 mib[2] = KERN_PROC_PID;
1447 mib[3] = pd;
1448 if (sysctl(mib, 4, &kp, &len, NULL, 0) == 0) {
1449 strcpy(name, kp.kp_proc.p_comm);
1450 }
1451 else strcpy(name, "unknown");
1452
1453 return name;
1454 }
1455 #endif
1456
1457 #ifdef Win32
1458 char *mbk_whoAmILong(pid_t pd, char *name)
1459 {
1460 /* TODO */
1461 strcpy(name, "unknown");
1462
1463 return name;
1464 }
1465 #endif
1466 /*}}}************************************************************************/
1467 /*}}}************************************************************************/
1468
1469 chain_list *BuildFileList(char *name, chain_list *regx, int once)
1470 {
1471 DIR *dp;
1472 struct dirent *ep;
1473 char buf[1024], *regxname, buf0[1024];
1474 char str[3];
1475 int i;
1476 chain_list *cl = NULL, *ch, *oncelist=NULL;
1477 /* regex_t regular_expression;
1478 regmatch_t pmatch[1];*/
1479 char **catal;
1480 char *mycatal[]={"", NULL};
1481 struct stat st;
1482 char save_sensi;
1483
1484 save_sensi=CASE_SENSITIVE;
1485 CASE_SENSITIVE='Y';
1486
1487 strcpy(str," ");
1488 while (regx!=NULL)
1489 {
1490 regxname=(char *)regx->DATA;
1491 if (name!=NULL)
1492 {
1493 strcpy(buf,"");
1494 for (i=0; regxname[i]!='\0'; i++)
1495 {
1496 str[0]=regxname[i];
1497 if (regxname[i]=='$') strcat(buf, name);
1498 else strcat(buf, str);
1499 }
1500 }
1501 else
1502 strcpy(buf, regxname);
1503
1504 if ((regxname=strrchr(buf, '/'))==NULL)
1505 {
1506 catal=CATA_LIB;
1507 regxname=buf;
1508 }
1509 else
1510 {
1511 catal=mycatal;
1512 *regxname='\0';
1513 mycatal[0]=buf;
1514 regxname++;
1515 }
1516
1517 for (i=0; catal[i]!=NULL; i++)
1518 {
1519 dp = opendir(catal[i]);
1520 if (dp != NULL)
1521 {
1522 while ((ep = readdir(dp)) != NULL)
1523 {
1524 if (mbk_TestREGEX(ep->d_name, regxname))
1525 {
1526 if (once)
1527 {
1528 for (ch=oncelist; ch!=NULL && strcmp((char *)ch->DATA, ep->d_name)!=0; ch=ch->NEXT) ;
1529 if (ch!=NULL) continue;
1530 }
1531 sprintf(buf0, "%s/%s",catal[i],ep->d_name);
1532
1533 if (stat(buf0, &st)!=ENOENT && !S_ISDIR(st.st_mode))
1534 {
1535 for (ch=cl; ch!=NULL && strcmp((char *)ch->DATA, buf0)!=0; ch=ch->NEXT);
1536 if (ch==NULL)
1537 {
1538 cl=addchain(cl, mbkstrdup(buf0));
1539 if (once) oncelist=addchain(oncelist, mbkstrdup(ep->d_name));
1540 }
1541 }
1542 }
1543 }
1544 closedir(dp);
1545 }
1546 }
1547 regx=regx->NEXT;
1548 }
1549
1550 CASE_SENSITIVE=save_sensi;
1551
1552 for (ch=oncelist; ch!=NULL; ch=ch->NEXT)
1553 mbkfree(ch->DATA);
1554 freechain(oncelist);
1555
1556 return reverse(cl);
1557 }
1558
1559 #undef mbk_DisplayProgress
1560
1561 void mbk_DisplayProgress(long *TM, char *mes, int cur, int tot, char mode)
1562 {
1563 long tmp;
1564
1565 if (!isatty (fileno(stdout))) return;
1566 if (mode=='e' || *TM!=(tmp=time(NULL)))
1567 {
1568 *TM=tmp;
1569 if (mode=='%')
1570 fprintf(stdout, "\r%s[%3.2f%%]", mes, (cur*100.0)/tot);
1571 else
1572 fprintf(stdout, "\r%s[%07d/%07d]", mes, cur, tot);
1573 if (mode=='e') fprintf(stdout, "\n");
1574 fflush(stdout);
1575 }
1576 }
1577
1578 void mbk_sem_init(mbk_sem_t *sm, int value)
1579 {
1580 sm->nb=value;
1581 pthread_mutex_init(&sm->mutex, NULL);
1582 pthread_cond_init(&sm->cond, NULL);
1583 }
1584
1585 void mbk_sem_destroy(mbk_sem_t *sm)
1586 {
1587 pthread_mutex_destroy(&sm->mutex);
1588 pthread_cond_destroy(&sm->cond);
1589 }
1590
1591 void mbk_sem_wait(mbk_sem_t *sm)
1592 {
1593 int rc;
1594 pthread_mutex_lock(&sm->mutex);
1595 while (sm->nb<=0) pthread_cond_wait(&sm->cond, &sm->mutex);
1596 sm->nb--;
1597 pthread_mutex_unlock(&sm->mutex);
1598 }
1599
1600 void mbk_sem_post(mbk_sem_t *sm)
1601 {
1602 pthread_mutex_lock(&sm->mutex);
1603 sm->nb++;
1604 pthread_mutex_unlock(&sm->mutex);
1605 pthread_cond_signal(&sm->cond);
1606 }