#include "fixlib.h"
#include <sys/stat.h>
#if defined( HAVE_MMAP_FILE )
#include <sys/mman.h>
#define BAD_ADDR ((void*)-1)
#endif
#ifndef SEPARATE_FIX_PROC
#include "server.h"
#endif
static const char program_id[] = "fixincl version 1.1";
static const char z_std_preamble[] =
"/* DO NOT EDIT THIS FILE.\n\n\
It has been auto-edited by fixincludes from:\n\n\
\t\"%s/%s\"\n\n\
This had to be done to correct non-standard usages in the\n\
original, manufacturer supplied header file. */\n\n";
int find_base_len = 0;
typedef enum {
VERB_SILENT = 0,
VERB_FIXES,
VERB_APPLIES,
VERB_PROGRESS,
VERB_TESTS,
VERB_EVERYTHING
} te_verbose;
te_verbose verbose_level = VERB_PROGRESS;
int have_tty = 0;
#define VLEVEL(l) ((unsigned int) verbose_level >= (unsigned int) l)
#define NOT_SILENT VLEVEL(VERB_FIXES)
pid_t process_chain_head = (pid_t) -1;
char* pz_curr_file;
char* pz_curr_data;
char* pz_temp_file;
t_bool curr_data_mapped;
int data_map_fd;
size_t data_map_size;
size_t ttl_data_size = 0;
#ifdef DO_STATS
int process_ct = 0;
int apply_ct = 0;
int fixed_ct = 0;
int altered_ct = 0;
#endif
const char incl_quote_pat[] = "^[ \t]*#[ \t]*include[ \t]*\"[^/]";
tSCC z_fork_err[] = "Error %d (%s) starting filter process for %s\n";
regex_t incl_quote_re;
static void do_version (void) ATTRIBUTE_NORETURN;
char *load_file (const char *);
void run_compiles (void);
void initialize (int argc, char** argv);
void process (void);
#include "fixincl.x"
extern int main (int, char **);
int
main (int argc, char** argv)
{
char *file_name_buf;
initialize ( argc, argv );
have_tty = isatty (fileno (stderr));
file_name_buf = load_file_data (stdin);
freopen ("/dev/null", "r", stdin);
if (file_name_buf == (char *) NULL)
{
fputs ("No file names listed for fixing\n", stderr);
exit (EXIT_FAILURE);
}
for (;;)
{
char* pz_end;
while (ISSPACE (*file_name_buf)) file_name_buf++;
while ((file_name_buf[0] == '.') && (file_name_buf[1] == '/'))
file_name_buf += 2;
if (*file_name_buf == NUL)
break;
pz_curr_file = file_name_buf;
pz_end = strchr( pz_curr_file, '\n' );
if (pz_end == (char*)NULL)
pz_end = file_name_buf = pz_curr_file + strlen (pz_curr_file);
else
file_name_buf = pz_end + 1;
while ((pz_end > pz_curr_file) && ISSPACE( pz_end[-1])) pz_end--;
if ((pz_curr_file == pz_end) || (*pz_curr_file == '#'))
continue;
*pz_end = NUL;
process ();
}
#ifdef DO_STATS
if (VLEVEL( VERB_PROGRESS )) {
tSCC zFmt[] =
"\
Processed %5d files containing %d bytes \n\
Applying %5d fixes to %d files\n\
Altering %5d of them\n";
fprintf (stderr, zFmt, process_ct, ttl_data_size, apply_ct,
fixed_ct, altered_ct);
}
#endif
# ifdef SEPARATE_FIX_PROC
unlink( pz_temp_file );
# endif
exit (EXIT_SUCCESS);
}
static void
do_version (void)
{
static const char zFmt[] = "echo '%s'";
char zBuf[ 1024 ];
run_compiles ();
sprintf (zBuf, zFmt, program_id);
#ifndef SEPARATE_FIX_PROC
puts (zBuf + 5);
exit (strcmp (run_shell (zBuf), program_id));
#else
exit (system (zBuf));
#endif
}
void
initialize ( int argc, char** argv )
{
xmalloc_set_program_name (argv[0]);
switch (argc)
{
case 1:
break;
case 2:
if (strcmp (argv[1], "-v") == 0)
do_version ();
if (freopen (argv[1], "r", stdin) == (FILE*)NULL)
{
fprintf (stderr, "Error %d (%s) reopening %s as stdin\n",
errno, xstrerror (errno), argv[1] );
exit (EXIT_FAILURE);
}
break;
default:
fputs ("fixincl ERROR: too many command line arguments\n", stderr);
exit (EXIT_FAILURE);
}
#ifdef SIGCHLD
signal (SIGCHLD, SIG_DFL);
#endif
initialize_opts ();
if (ISDIGIT ( *pz_verbose ))
verbose_level = (te_verbose)atoi( pz_verbose );
else
switch (*pz_verbose) {
case 's':
case 'S':
verbose_level = VERB_SILENT; break;
case 'f':
case 'F':
verbose_level = VERB_FIXES; break;
case 'a':
case 'A':
verbose_level = VERB_APPLIES; break;
default:
case 'p':
case 'P':
verbose_level = VERB_PROGRESS; break;
case 't':
case 'T':
verbose_level = VERB_TESTS; break;
case 'e':
case 'E':
verbose_level = VERB_EVERYTHING; break;
}
if (verbose_level >= VERB_EVERYTHING) {
verbose_level = VERB_EVERYTHING;
fputs ("fixinc verbosity: EVERYTHING\n", stderr);
}
while ((pz_find_base[0] == '.') && (pz_find_base[1] == '/'))
pz_find_base += 2;
if ((pz_find_base[0] != '.') || (pz_find_base[1] != NUL))
find_base_len = strlen( pz_find_base );
run_compiles ();
# ifdef SEPARATE_FIX_PROC
pz_temp_file = tempnam( NULL, "fxinc" );
# endif
signal (SIGQUIT, SIG_IGN);
signal (SIGIOT, SIG_IGN);
signal (SIGPIPE, SIG_IGN);
signal (SIGALRM, SIG_IGN);
signal (SIGTERM, SIG_IGN);
}
char *
load_file ( const char* fname )
{
struct stat stbf;
char* res;
if (stat (fname, &stbf) != 0)
{
if (NOT_SILENT)
fprintf (stderr, "error %d (%s) stat-ing %s\n",
errno, xstrerror (errno), fname );
return (char *) NULL;
}
if (stbf.st_size == 0)
return (char*)NULL;
data_map_size = stbf.st_size+1;
data_map_fd = open (fname, O_RDONLY);
ttl_data_size += data_map_size-1;
if (data_map_fd < 0)
{
if (NOT_SILENT)
fprintf (stderr, "error %d (%s) opening %s for read\n",
errno, xstrerror (errno), fname);
return (char*)NULL;
}
#ifdef HAVE_MMAP_FILE
curr_data_mapped = BOOL_TRUE;
if ((stbf.st_size & (getpagesize()-1)) == 0)
res = (char*)BAD_ADDR;
else
res = (char*)mmap ((void*)NULL, data_map_size, PROT_READ,
MAP_PRIVATE, data_map_fd, 0);
if (res == (char*)BAD_ADDR)
#endif
{
FILE* fp = fdopen (data_map_fd, "r");
curr_data_mapped = BOOL_FALSE;
res = load_file_data (fp);
fclose (fp);
}
return res;
}
static int
machine_matches( tFixDesc* p_fixd )
{
# ifndef SEPARATE_FIX_PROC
tSCC case_fmt[] = "case %s in\n";
tSCC esac_fmt[] =
" )\n echo %s ;;\n* ) echo %s ;;\nesac";
tSCC skip[] = "skip";
tSCC run[] = "run";
const char **papz_machs = p_fixd->papz_machs;
char *pz;
const char *pz_sep = "";
tCC *pz_if_true;
tCC *pz_if_false;
char cmd_buf[ MACH_LIST_SIZE_LIMIT ];
sprintf (cmd_buf, case_fmt, pz_machine);
pz = cmd_buf + strlen (cmd_buf);
if (p_fixd->fd_flags & FD_MACH_IFNOT)
{
pz_if_true = skip;
pz_if_false = run;
}
else
{
pz_if_true = run;
pz_if_false = skip;
}
for (;;)
{
const char* pz_mach = *(papz_machs++);
if (pz_mach == (const char*) NULL)
break;
sprintf (pz, "%s%s", pz_sep, pz_mach);
pz += strlen (pz);
pz_sep = " | \\\n";
}
sprintf (pz, esac_fmt, pz_if_true, pz_if_false);
{
int skip;
pz = run_shell (cmd_buf);
skip = (*pz == 's');
free ( (void*)pz );
if (skip)
{
p_fixd->fd_flags |= FD_SKIP_TEST;
return BOOL_FALSE;
}
}
return BOOL_TRUE;
# else
const char **papz_machs = p_fixd->papz_machs;
int invert = (p_fixd->fd_flags & FD_MACH_IFNOT) != 0;
for (;;)
{
const char* pz_mach = *(papz_machs++);
if (pz_mach == (const char*) NULL)
break;
if (strstr (pz_mach, "dos") != NULL && !invert)
return BOOL_TRUE;
}
p_fixd->fd_flags |= FD_SKIP_TEST;
return BOOL_FALSE;
# endif
}
void
run_compiles (void)
{
tFixDesc *p_fixd = fixDescList;
int fix_ct = FIX_COUNT;
regex_t *p_re = xcalloc (REGEX_COUNT, sizeof (regex_t));
memset (&incl_quote_re, '\0', sizeof (regex_t));
compile_re (incl_quote_pat, &incl_quote_re, 1,
"quoted include", "run_compiles");
if (pz_machine && ((*pz_machine == '\0') || (*pz_machine == '*')))
pz_machine = (char*)NULL;
do
{
tTestDesc *p_test = p_fixd->p_test_desc;
int test_ct = p_fixd->test_ct;
if ( (pz_machine != NULL)
&& (p_fixd->papz_machs != (const char**) NULL)
&& ! machine_matches (p_fixd) )
continue;
while (--test_ct >= 0)
{
switch (p_test->type)
{
case TT_EGREP:
case TT_NEGREP:
p_test->p_test_regex = p_re++;
compile_re (p_test->pz_test_text, p_test->p_test_regex, 0,
"select test", p_fixd->fix_name);
default: break;
}
p_test++;
}
}
while (p_fixd++, --fix_ct > 0);
}
#if defined(S_IRUSR) && defined(S_IWUSR) && \
defined(S_IRGRP) && defined(S_IROTH)
# define S_IRALL (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#else
# define S_IRALL 0644
#endif
#if defined(S_IRWXU) && defined(S_IRGRP) && defined(S_IXGRP) && \
defined(S_IROTH) && defined(S_IXOTH)
# define S_DIRALL (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
#else
# define S_DIRALL 0755
#endif
static FILE *
create_file (void)
{
int fd;
FILE *pf;
char fname[MAXPATHLEN];
sprintf (fname, "%s/%s", pz_dest_dir, pz_curr_file + find_base_len);
fd = open (fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRALL);
if ((fd < 0) && (errno == ENOENT))
{
char *pz_dir = strchr (fname + 1, '/');
struct stat stbf;
while (pz_dir != (char *) NULL)
{
*pz_dir = NUL;
if (stat (fname, &stbf) < 0)
{
#ifdef _WIN32
mkdir (fname);
#else
mkdir (fname, S_IFDIR | S_DIRALL);
#endif
}
*pz_dir = '/';
pz_dir = strchr (pz_dir + 1, '/');
}
fd = open (fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRALL);
}
if (fd < 0)
{
fprintf (stderr, "Error %d (%s) creating %s\n",
errno, xstrerror (errno), fname);
exit (EXIT_FAILURE);
}
if (NOT_SILENT)
fprintf (stderr, "Fixed: %s\n", pz_curr_file);
pf = fdopen (fd, "w");
fprintf (pf, z_std_preamble,
(pz_machine == NULL)
? "fixinc/tests/inc"
: pz_input_dir,
pz_curr_file);
return pf;
}
#ifndef SEPARATE_FIX_PROC
static int
test_test (tTestDesc* p_test, char* pz_test_file)
{
tSCC cmd_fmt[] =
"file=%s\n\
if ( test %s ) > /dev/null 2>&1\n\
then echo TRUE\n\
else echo FALSE\n\
fi";
char *pz_res;
int res;
static char cmd_buf[4096];
sprintf (cmd_buf, cmd_fmt, pz_test_file, p_test->pz_test_text);
pz_res = run_shell (cmd_buf);
switch (*pz_res) {
case 'T':
res = APPLY_FIX;
break;
case 'F':
res = SKIP_FIX;
break;
default:
fprintf (stderr, "Script yielded bogus result of `%s':\n%s\n\n",
pz_res, cmd_buf );
res = SKIP_FIX;
}
free ((void *) pz_res);
return res;
}
#else
#define test_test(t,tf) SKIP_FIX
#endif
static int
egrep_test (char* pz_data, tTestDesc* p_test)
{
#ifdef DEBUG
if (p_test->p_test_regex == 0)
fprintf (stderr, "fixincl ERROR RE not compiled: `%s'\n",
p_test->pz_test_text);
#endif
if (xregexec (p_test->p_test_regex, pz_data, 0, 0, 0) == 0)
return APPLY_FIX;
return SKIP_FIX;
}
static int
quoted_file_exists (const char* pz_src_path,
const char* pz_file_path,
const char* pz_file)
{
char z[ MAXPATHLEN ];
char* pz;
sprintf (z, "%s/%s/", pz_src_path, pz_file_path);
pz = z + strlen ( z );
for (;;) {
char ch = *pz_file++;
if (! ISGRAPH( ch ))
return 0;
if (ch == '"')
break;
*pz++ = ch;
}
*pz = '\0';
{
struct stat s;
if (stat (z, &s) != 0)
return 0;
return S_ISREG( s.st_mode );
}
}
static void
extract_quoted_files (char* pz_data,
const char* pz_fixed_file,
regmatch_t* p_re_match)
{
char *pz_dir_end = strrchr (pz_fixed_file, '/');
char *pz_incl_quot = pz_data;
if (VLEVEL( VERB_APPLIES ))
fprintf (stderr, "Quoted includes in %s\n", pz_fixed_file);
if (pz_dir_end == (char *) NULL)
pz_fixed_file = ".";
else
*pz_dir_end = '\0';
for (;;)
{
pz_incl_quot += p_re_match->rm_so;
while (*pz_incl_quot != '"')
pz_incl_quot++;
if (quoted_file_exists (pz_src_dir, pz_fixed_file, pz_incl_quot))
{
printf ("%s %s/", pz_src_dir, pz_fixed_file);
pz_dir_end = pz_incl_quot;
while (*pz_incl_quot != '"')
putc (*pz_incl_quot++, stdout);
printf (" %s/%s/", pz_dest_dir, pz_fixed_file);
while (*pz_dir_end != '"')
putc (*pz_dir_end++, stdout);
putc ('\n', stdout);
}
if (xregexec (&incl_quote_re, pz_incl_quot, 1, p_re_match, 0) != 0)
break;
}
}
#ifndef SEPARATE_FIX_PROC
static int
internal_fix (int read_fd, tFixDesc* p_fixd)
{
int fd[2];
if (pipe( fd ) != 0)
{
fprintf (stderr, "Error %d on pipe(2) call\n", errno );
exit (EXIT_FAILURE);
}
for (;;)
{
pid_t childid = fork();
switch (childid)
{
case -1:
break;
case 0:
close (fd[0]);
goto do_child_task;
default:
close (read_fd);
close (fd[1]);
return fd[0];
}
fprintf (stderr, z_fork_err, errno, xstrerror (errno),
p_fixd->fix_name);
{
static int failCt = 0;
if ((errno != EAGAIN) || (++failCt > 10))
exit (EXIT_FAILURE);
sleep (1);
}
} do_child_task:;
close (STDIN_FILENO);
close (STDOUT_FILENO);
UNLOAD_DATA();
dup2 (fd[1], STDOUT_FILENO);
dup2 (read_fd, STDIN_FILENO);
apply_fix (p_fixd, pz_curr_file);
exit (0);
}
#endif
#ifdef SEPARATE_FIX_PROC
static void
fix_with_system (tFixDesc* p_fixd,
tCC* pz_fix_file,
tCC* pz_file_source,
tCC* pz_temp_file)
{
char* pz_cmd;
char* pz_scan;
size_t argsize;
if (p_fixd->fd_flags & FD_SUBROUTINE)
{
static const char z_applyfix_prog[] =
"/../fixincludes/applyfix" EXE_EXT;
struct stat buf;
argsize = 32
+ strlen (pz_orig_dir)
+ sizeof (z_applyfix_prog)
+ strlen (pz_fix_file)
+ strlen (pz_file_source)
+ strlen (pz_temp_file);
pz_cmd = xmalloc (argsize);
strcpy (pz_cmd, pz_orig_dir);
pz_scan = pz_cmd + strlen (pz_orig_dir);
strcpy (pz_scan, z_applyfix_prog);
if (stat (pz_cmd, &buf) == -1)
{
strcpy (pz_scan, "/..");
strcpy (pz_scan+3, z_applyfix_prog);
}
pz_scan += strlen (pz_scan);
sprintf (pz_scan, " %ld '%s' '%s' '%s'", p_fixd - fixDescList,
pz_fix_file, pz_file_source, pz_temp_file);
}
else
{
size_t parg_size;
#ifdef __MSDOS__
tSCC z_cmd_fmt[] = " '%s' | cat > '%s'";
#else
tSCC z_cmd_fmt[] = " %s > %sX ; rm -f %s; mv -f %sX %s";
#endif
tCC** ppArgs = p_fixd->patch_args;
argsize = sizeof( z_cmd_fmt ) + strlen( pz_temp_file )
+ strlen( pz_file_source );
parg_size = argsize;
for (;;)
{
tCC* p_arg = *(ppArgs++);
if (p_arg == NULL)
break;
argsize += 24 + strlen( p_arg );
}
pz_scan = pz_cmd = xmalloc (argsize);
parg_size = argsize - parg_size;
ppArgs = p_fixd->patch_args;
{
tCC* pArg = *(ppArgs++);
for (;;)
{
char ch = *(pArg++);
if (ch == NUL)
break;
*(pz_scan++) = ch;
}
}
for (;;)
{
tCC* pArg = *(ppArgs++);
char* pz_scan_save;
if (pArg == NULL)
break;
*(pz_scan++) = ' ';
pz_scan = make_raw_shell_str( pz_scan_save = pz_scan, pArg,
parg_size - (pz_scan - pz_cmd) );
while (pz_scan == (char*)NULL)
{
size_t already_filled = pz_scan_save - pz_cmd;
pz_cmd = xrealloc (pz_cmd, argsize += 100);
pz_scan_save = pz_scan = pz_cmd + already_filled;
parg_size += 100;
pz_scan = make_raw_shell_str( pz_scan, pArg,
parg_size - (pz_scan - pz_cmd) );
}
}
#ifdef __MSDOS__
sprintf (pz_scan, z_cmd_fmt, pz_file_source, pz_temp_file );
#else
sprintf (pz_scan, z_cmd_fmt, pz_file_source, pz_temp_file,
pz_temp_file, pz_temp_file, pz_temp_file);
#endif
}
system( pz_cmd );
free( (void*)pz_cmd );
}
#else
static int
start_fixer (int read_fd, tFixDesc* p_fixd, char* pz_fix_file)
{
tCC* pz_cmd_save;
char* pz_cmd;
if ((p_fixd->fd_flags & FD_SUBROUTINE) != 0)
return internal_fix (read_fd, p_fixd);
if ((p_fixd->fd_flags & FD_SHELL_SCRIPT) == 0)
{
pz_cmd = NULL;
pz_cmd_save = NULL;
}
else
{
tSCC z_cmd_fmt[] = "file='%s'\n%s";
pz_cmd = xmalloc (strlen (p_fixd->patch_args[2])
+ sizeof (z_cmd_fmt) + strlen (pz_fix_file));
sprintf (pz_cmd, z_cmd_fmt, pz_fix_file, p_fixd->patch_args[2]);
pz_cmd_save = p_fixd->patch_args[2];
p_fixd->patch_args[2] = pz_cmd;
}
for (;;)
{
static int failCt = 0;
int fd;
fd = chain_open (read_fd,
(tCC **) p_fixd->patch_args,
(process_chain_head == -1)
? &process_chain_head : (pid_t *) NULL);
if (fd != -1)
{
read_fd = fd;
break;
}
fprintf (stderr, z_fork_err, errno, xstrerror (errno),
p_fixd->fix_name);
if ((errno != EAGAIN) || (++failCt > 10))
exit (EXIT_FAILURE);
sleep (1);
}
if (pz_cmd != (char*)NULL)
{
free ((void*)pz_cmd);
p_fixd->patch_args[2] = pz_cmd_save;
}
return read_fd;
}
#endif
static t_bool
fix_applies (tFixDesc* p_fixd)
{
const char *pz_fname = pz_curr_file;
const char *pz_scan = p_fixd->file_list;
int test_ct;
tTestDesc *p_test;
# ifdef SEPARATE_FIX_PROC
if (p_fixd->fd_flags & (FD_SHELL_SCRIPT | FD_SKIP_TEST))
return BOOL_FALSE;
# else
if (p_fixd->fd_flags & FD_SKIP_TEST)
return BOOL_FALSE;
# endif
if (pz_scan != (char *) NULL)
{
size_t name_len;
while ((pz_fname[0] == '.') && (pz_fname[1] == '/'))
pz_fname += 2;
name_len = strlen (pz_fname);
for (;;)
{
pz_scan = strstr (pz_scan + 1, pz_fname);
if (pz_scan == (char *) NULL)
return BOOL_FALSE;
if ((pz_scan[-1] == '|') && (pz_scan[name_len] == '|'))
break;
}
}
for (p_test = p_fixd->p_test_desc, test_ct = p_fixd->test_ct;
test_ct-- > 0;
p_test++)
{
switch (p_test->type)
{
case TT_TEST:
if (test_test (p_test, pz_curr_file) != APPLY_FIX) {
#ifdef DEBUG
if (VLEVEL( VERB_EVERYTHING ))
fprintf (stderr, z_failed, "TEST", p_fixd->fix_name,
pz_fname, p_fixd->test_ct - test_ct);
#endif
return BOOL_FALSE;
}
break;
case TT_EGREP:
if (egrep_test (pz_curr_data, p_test) != APPLY_FIX) {
#ifdef DEBUG
if (VLEVEL( VERB_EVERYTHING ))
fprintf (stderr, z_failed, "EGREP", p_fixd->fix_name,
pz_fname, p_fixd->test_ct - test_ct);
#endif
return BOOL_FALSE;
}
break;
case TT_NEGREP:
if (egrep_test (pz_curr_data, p_test) == APPLY_FIX) {
#ifdef DEBUG
if (VLEVEL( VERB_EVERYTHING ))
fprintf (stderr, z_failed, "NEGREP", p_fixd->fix_name,
pz_fname, p_fixd->test_ct - test_ct);
#endif
return BOOL_FALSE;
}
break;
case TT_FUNCTION:
if (run_test (p_test->pz_test_text, pz_curr_file, pz_curr_data)
!= APPLY_FIX) {
#ifdef DEBUG
if (VLEVEL( VERB_EVERYTHING ))
fprintf (stderr, z_failed, "FTEST", p_fixd->fix_name,
pz_fname, p_fixd->test_ct - test_ct);
#endif
return BOOL_FALSE;
}
break;
}
}
return BOOL_TRUE;
}
static void
write_replacement (tFixDesc* p_fixd)
{
const char* pz_text = p_fixd->patch_args[0];
if ((pz_text == (char*)NULL) || (*pz_text == NUL))
return;
{
FILE* out_fp = create_file ();
fputs (pz_text, out_fp);
fclose (out_fp);
}
}
static void
test_for_changes (int read_fd)
{
FILE *in_fp = fdopen (read_fd, "r");
FILE *out_fp = (FILE *) NULL;
unsigned char *pz_cmp = (unsigned char*)pz_curr_data;
#ifdef DO_STATS
fixed_ct++;
#endif
for (;;)
{
int ch;
ch = getc (in_fp);
if (ch == EOF)
break;
ch &= 0xFF;
if (out_fp != (FILE *) NULL)
putc (ch, out_fp);
else if (ch != *pz_cmp)
{
out_fp = create_file ();
#ifdef DO_STATS
altered_ct++;
#endif
if ((char*)pz_cmp != pz_curr_data)
fwrite (pz_curr_data, (size_t)((char*)pz_cmp - pz_curr_data),
1, out_fp);
putc (ch, out_fp);
}
else
pz_cmp++;
}
if (out_fp != (FILE *) NULL)
{
regmatch_t match;
fclose (out_fp);
if (xregexec (&incl_quote_re, pz_curr_data, 1, &match, 0) == 0)
extract_quoted_files (pz_curr_data, pz_curr_file, &match);
}
fclose (in_fp);
close (read_fd);
}
void
process (void)
{
tFixDesc *p_fixd = fixDescList;
int todo_ct = FIX_COUNT;
int read_fd = -1;
# ifndef SEPARATE_FIX_PROC
int num_children = 0;
# else
char* pz_file_source = pz_curr_file;
# endif
if (access (pz_curr_file, R_OK) != 0)
{
int erno = errno;
fprintf (stderr, "Cannot access %s from %s\n\terror %d (%s)\n",
pz_curr_file, getcwd ((char *) NULL, MAXPATHLEN),
erno, xstrerror (erno));
return;
}
pz_curr_data = load_file (pz_curr_file);
if (pz_curr_data == (char *) NULL)
return;
#ifdef DO_STATS
process_ct++;
#endif
if (VLEVEL( VERB_PROGRESS ) && have_tty)
fprintf (stderr, "%6lu %-50s \r",
(unsigned long) data_map_size, pz_curr_file);
# ifndef SEPARATE_FIX_PROC
process_chain_head = NOPROCESS;
for (; todo_ct > 0; p_fixd++, todo_ct--)
{
if (! fix_applies (p_fixd))
continue;
if (VLEVEL( VERB_APPLIES ))
fprintf (stderr, "Applying %-24s to %s\n",
p_fixd->fix_name, pz_curr_file);
if (p_fixd->fd_flags & FD_REPLACEMENT)
{
write_replacement (p_fixd);
UNLOAD_DATA();
return;
}
if (read_fd == -1)
{
read_fd = open (pz_curr_file, O_RDONLY);
if (read_fd < 0)
{
fprintf (stderr, "Error %d (%s) opening %s\n", errno,
xstrerror (errno), pz_curr_file);
exit (EXIT_FAILURE);
}
fflush (stdout);
}
read_fd = start_fixer (read_fd, p_fixd, pz_curr_file);
num_children++;
}
if (read_fd >= 0)
{
test_for_changes (read_fd);
#ifdef DO_STATS
apply_ct += num_children;
#endif
do {
wait ((int *) NULL);
} while (--num_children > 0);
}
# else
for (; todo_ct > 0; p_fixd++, todo_ct--)
{
if (! fix_applies (p_fixd))
continue;
if (VLEVEL( VERB_APPLIES ))
fprintf (stderr, "Applying %-24s to %s\n",
p_fixd->fix_name, pz_curr_file);
if (p_fixd->fd_flags & FD_REPLACEMENT)
{
write_replacement (p_fixd);
UNLOAD_DATA();
return;
}
fix_with_system (p_fixd, pz_curr_file, pz_file_source, pz_temp_file);
pz_file_source = pz_temp_file;
}
read_fd = open (pz_temp_file, O_RDONLY);
if (read_fd < 0)
{
if (errno != ENOENT)
fprintf (stderr, "error %d (%s) opening output (%s) for read\n",
errno, xstrerror (errno), pz_temp_file);
}
else
{
test_for_changes (read_fd);
close (read_fd);
unlink (pz_temp_file);
}
# endif
UNLOAD_DATA();
}