mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-09-11 14:54:54 +00:00
895 lines
20 KiB
C
895 lines
20 KiB
C
/*
|
|
* udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
|
|
* and Apple (CR).
|
|
*
|
|
* Routines common to both the Unix and Apple IIgs versions.
|
|
*
|
|
* $Id: common.c,v 1.9 1996/02/04 01:34:26 gdr Exp $
|
|
*
|
|
* Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
|
|
*/
|
|
|
|
#ifdef GNO
|
|
#pragma noroot
|
|
#endif
|
|
|
|
#include "common.h"
|
|
extern char *strdup(const char *);
|
|
|
|
/*
|
|
* convert_gs() ... convert files to use CR as EOL
|
|
*
|
|
* Inputs:
|
|
* FILE *infile File to read from
|
|
* FILE *outfile File to write to
|
|
*
|
|
* Outputs:
|
|
* None
|
|
*/
|
|
|
|
void convert_gs(FILE *infile, FILE *outfile) {
|
|
unsigned char a;
|
|
unsigned char *in_bufpos;
|
|
unsigned char *out_bufpos;
|
|
unsigned char *in_bufend;
|
|
unsigned char *out_bufend;
|
|
size_t file_remain;
|
|
|
|
in_bufpos = in_buffer;
|
|
out_bufpos = out_buffer;
|
|
|
|
(void) fseek(infile,0L,SEEK_END);
|
|
file_remain = ftell(infile);
|
|
rewind(infile);
|
|
|
|
in_bufend = in_buffer + my_fread(infile,BUFFERSIZE);
|
|
out_bufend = out_buffer + BUFFERSIZE;
|
|
|
|
while (file_remain != 0) {
|
|
a = *in_bufpos;
|
|
in_bufpos++;
|
|
|
|
if (in_bufpos >= in_bufend) {
|
|
file_remain -= in_bufend - in_buffer;
|
|
in_bufend = in_buffer + my_fread(infile,BUFFERSIZE);
|
|
in_bufpos = in_buffer;
|
|
}
|
|
|
|
if(a == LF) {
|
|
*out_bufpos = CR;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
} else if(a == CR) {
|
|
*out_bufpos = CR;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
|
|
if (*in_bufpos == LF && file_remain != 0) {
|
|
in_bufpos++;
|
|
|
|
if (in_bufpos >= in_bufend) {
|
|
file_remain -= in_bufend - in_buffer;
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
in_bufpos = in_buffer;
|
|
}
|
|
}
|
|
} else {
|
|
*out_bufpos = a;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
}
|
|
}
|
|
/* Check for remainder in output buffer */
|
|
if (out_bufpos != out_buffer)
|
|
my_fwrite(out_buffer,outfile,(int)(out_bufpos - out_buffer));
|
|
}
|
|
|
|
/*
|
|
* convert_messy() ... convert files to use CR/LF as EOL
|
|
*
|
|
* Inputs:
|
|
* FILE *infile File to read from
|
|
* FILE *outfile File to write to
|
|
*
|
|
* Outputs:
|
|
* None
|
|
*/
|
|
|
|
void convert_messy (FILE *infile, FILE *outfile) {
|
|
unsigned char a;
|
|
unsigned char *in_bufpos;
|
|
unsigned char *out_bufpos;
|
|
unsigned char *in_bufend;
|
|
unsigned char *out_bufend;
|
|
size_t file_remain;
|
|
|
|
in_bufpos = in_buffer;
|
|
out_bufpos = out_buffer;
|
|
|
|
(void) fseek(infile,0L,SEEK_END);
|
|
file_remain = ftell(infile);
|
|
rewind(infile);
|
|
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
out_bufend = out_buffer + BUFFERSIZE;
|
|
|
|
while (file_remain != 0) {
|
|
a = *in_bufpos;
|
|
in_bufpos++;
|
|
|
|
if (in_bufpos >= in_bufend) {
|
|
file_remain -= in_bufend - in_buffer;
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
in_bufpos = in_buffer;
|
|
}
|
|
|
|
if(a == LF) {
|
|
*out_bufpos = CR;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
|
|
*out_bufpos = LF;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
} else if(a == CR) {
|
|
*out_bufpos = CR;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
|
|
*out_bufpos = LF;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
|
|
if (*in_bufpos == LF && file_remain != 0) {
|
|
in_bufpos++;
|
|
|
|
if (in_bufpos >= in_bufend) {
|
|
file_remain -= in_bufend - in_buffer;
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
in_bufpos = in_buffer;
|
|
}
|
|
}
|
|
} else {
|
|
*out_bufpos = a;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
}
|
|
}
|
|
/* Check for remainder in output buffer */
|
|
if (out_bufpos != out_buffer)
|
|
my_fwrite(out_buffer,outfile,(int)(out_bufpos - out_buffer));
|
|
}
|
|
|
|
/*
|
|
* convert_tunix() ... convert files to use LF as EOL
|
|
*
|
|
* Inputs:
|
|
* FILE *infile File to read from
|
|
* FILE *outfile File to write to
|
|
*
|
|
* Outputs:
|
|
* None
|
|
*/
|
|
|
|
void convert_tunix (FILE *infile, FILE *outfile) {
|
|
unsigned char a;
|
|
unsigned char *in_bufpos;
|
|
unsigned char *out_bufpos;
|
|
unsigned char *in_bufend;
|
|
unsigned char *out_bufend;
|
|
size_t file_remain;
|
|
|
|
in_bufpos = in_buffer;
|
|
out_bufpos = out_buffer;
|
|
|
|
(void) fseek(infile,0L,SEEK_END);
|
|
file_remain = ftell(infile);
|
|
rewind(infile);
|
|
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
out_bufend = out_buffer + BUFFERSIZE;
|
|
|
|
while (file_remain != 0) {
|
|
a = *in_bufpos;
|
|
in_bufpos++;
|
|
|
|
if (in_bufpos >= in_bufend) {
|
|
file_remain -= in_bufend - in_buffer;
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
in_bufpos = in_buffer;
|
|
}
|
|
|
|
if(a == CR) {
|
|
*out_bufpos = LF;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
|
|
if (*in_bufpos == LF && file_remain != 0) {
|
|
in_bufpos++;
|
|
|
|
if (in_bufpos >= in_bufend) {
|
|
file_remain -= in_bufend - in_buffer;
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
in_bufpos = in_buffer;
|
|
}
|
|
}
|
|
} else {
|
|
*out_bufpos = a;
|
|
out_bufpos++;
|
|
if (out_bufpos == out_bufend) {
|
|
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
|
out_bufpos = out_buffer;
|
|
}
|
|
}
|
|
}
|
|
/* Check for remainder in output buffer */
|
|
if (out_bufpos != out_buffer)
|
|
my_fwrite(out_buffer,outfile,(int)(out_bufpos - out_buffer));
|
|
}
|
|
|
|
/*
|
|
* convert_fast_gs() ... convert files to use CR as EOL
|
|
* Do not care about differing EOL chars in the same file,
|
|
* do not allow '\0' bytes, and replace in-vitro if possible.
|
|
*
|
|
* Inputs:
|
|
* FILE *infile File to read from
|
|
* FILE *outfile File to write to
|
|
*
|
|
* Outputs:
|
|
* int FALSE if no conversion took place, TRUE otherwise
|
|
*/
|
|
|
|
int convert_fast_gs(FILE *infile, FILE *outfile) {
|
|
unsigned char a;
|
|
unsigned char *in_bufpos;
|
|
unsigned char *in_bufend;
|
|
size_t file_remain;
|
|
enum file_format infile_type;
|
|
|
|
in_bufpos = in_buffer;
|
|
|
|
(void) fseek(infile,0L,SEEK_END);
|
|
file_remain = ftell(infile);
|
|
rewind(infile);
|
|
|
|
in_bufend = in_buffer + my_fread(infile,BUFFERSIZE);
|
|
*in_bufend = '\0';
|
|
|
|
infile_type = get_file_format (in_buffer);
|
|
|
|
switch (infile_type) {
|
|
case apple:
|
|
if (verbose)
|
|
printf("%s: %s is already in Apple format, skipping.\n",
|
|
program_name,current_file);
|
|
return (FALSE);
|
|
break;
|
|
|
|
case tunix:
|
|
/* Replace "in-vitro", so out_buffer isn't used */
|
|
while (file_remain != 0) {
|
|
a = *in_bufpos;
|
|
if (a == LF)
|
|
*in_bufpos++ = CR;
|
|
else if (a == '\0') { /* End of buffer reached */
|
|
|
|
/* Write changed buffer out */
|
|
my_fwrite(in_buffer,outfile,(int)(in_bufend - in_buffer));
|
|
|
|
/* And reload it */
|
|
file_remain -= in_bufend - in_buffer;
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
*in_bufend = '\0';
|
|
in_bufpos = in_buffer;
|
|
} else in_bufpos++;
|
|
}
|
|
return (TRUE);
|
|
break;
|
|
|
|
case dos:
|
|
/* This I couldn't speed up, so use the existing thing */
|
|
convert_gs (infile, outfile);
|
|
return (TRUE);
|
|
break;
|
|
|
|
case binary:
|
|
return (FALSE);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr,"%s: Fatal internal error\n",program_name);
|
|
exit (EXIT_FAILURE);
|
|
break;
|
|
} /* switch */
|
|
}
|
|
|
|
/*
|
|
* convert_fast_messy() ... convert files to use CR/LF as EOL
|
|
* Just check if it's already in DOS format.
|
|
*
|
|
* Inputs:
|
|
* FILE *infile File to read from
|
|
* FILE *outfile File to write to
|
|
*
|
|
* Outputs:
|
|
* int FALSE if no conversion took place, TRUE otherwise
|
|
*/
|
|
|
|
int convert_fast_messy (FILE *infile, FILE *outfile) {
|
|
unsigned char *in_bufend;
|
|
enum file_format infile_type;
|
|
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
*in_bufend = '\0';
|
|
|
|
infile_type = get_file_format (in_buffer);
|
|
|
|
switch (infile_type) {
|
|
case dos:
|
|
if (verbose)
|
|
printf("%s: %s is already in MS-DOS format, skipping.\n",
|
|
program_name,current_file);
|
|
return (FALSE);
|
|
break;
|
|
|
|
case tunix: /* drop through */
|
|
case apple:
|
|
/* Wasn't able to speed this up, call old routine */
|
|
convert_messy (infile, outfile);
|
|
return (TRUE);
|
|
break;
|
|
|
|
case binary:
|
|
return (FALSE);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr,"%s: Fatal internal error\n",program_name);
|
|
exit (EXIT_FAILURE);
|
|
break;
|
|
} /* switch */
|
|
}
|
|
|
|
/*
|
|
* convert_fast_tunix() ... convert files to use LF as EOL
|
|
* Do not care about differing EOL chars in the same file,
|
|
* do not allow '\0' bytes, and replace in-vitro if possible.
|
|
*
|
|
* Inputs:
|
|
* FILE *infile File to read from
|
|
* FILE *outfile File to write to
|
|
*
|
|
* Outputs:
|
|
* int FALSE if no conversion took place, TRUE otherwise
|
|
*/
|
|
|
|
int convert_fast_tunix (FILE *infile, FILE *outfile) {
|
|
unsigned char a;
|
|
unsigned char *in_bufpos;
|
|
unsigned char *in_bufend;
|
|
size_t file_remain;
|
|
enum file_format infile_type;
|
|
|
|
in_bufpos = in_buffer;
|
|
|
|
(void) fseek(infile,0L,SEEK_END);
|
|
file_remain = ftell(infile);
|
|
rewind(infile);
|
|
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
*in_bufend = '\0';
|
|
|
|
infile_type = get_file_format (in_buffer);
|
|
|
|
switch (infile_type) {
|
|
case tunix:
|
|
if (verbose)
|
|
printf("%s: %s is already in Unix format, skipping.\n",
|
|
program_name,current_file);
|
|
return (FALSE);
|
|
break;
|
|
|
|
case apple:
|
|
/* Replace "in-vitro", so out_buffer isn't used */
|
|
while (file_remain != 0) {
|
|
a = *in_bufpos;
|
|
if (a == CR)
|
|
*in_bufpos++ = LF;
|
|
else if (a == '\0'){ /* End of buffer reached */
|
|
|
|
/* Write changed buffer out */
|
|
my_fwrite(in_buffer,outfile,(int)(in_bufend - in_buffer));
|
|
|
|
/* And reload */
|
|
file_remain -= in_bufend - in_buffer;
|
|
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
|
*in_bufend = '\0';
|
|
in_bufpos = in_buffer;
|
|
} else in_bufpos++;
|
|
}
|
|
return (TRUE);
|
|
break;
|
|
|
|
case dos:
|
|
/* Couldn't speed it up, so use old routine */
|
|
convert_tunix (infile, outfile);
|
|
return (TRUE);
|
|
break;
|
|
|
|
case binary:
|
|
return (FALSE);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr,"%s: Fatal internal error\n", program_name);
|
|
exit (EXIT_FAILURE);
|
|
break;
|
|
} /* switch */
|
|
}
|
|
|
|
/*
|
|
* get_file_format() ... look at a buffer and find out what the EOL
|
|
* character is. If no EOL character is found, print an error message
|
|
* and exit.
|
|
*
|
|
* Inputs:
|
|
* unsigned char *buffer Buffer to search through, terminated
|
|
* by '\0'.
|
|
*
|
|
* Output:
|
|
* enum file_format tunix, dos, apple, or binary
|
|
*/
|
|
|
|
enum file_format get_file_format (unsigned char *buffer) {
|
|
unsigned char c;
|
|
enum file_format result = unknown;
|
|
|
|
while ((c = *buffer++) != '\0') {
|
|
if (c == LF) {
|
|
result = tunix;
|
|
break;
|
|
} else if (c == CR) {
|
|
if (*buffer == LF)
|
|
result = dos;
|
|
else
|
|
result = apple;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (result == unknown) {
|
|
if (verbose)
|
|
printf("%s: No EOL found on the first %d bytes "
|
|
"of %s. Might be a binary file. File skipped\n",
|
|
program_name,BUFFERSIZE, current_file);
|
|
result = binary;
|
|
}
|
|
|
|
return (result);
|
|
}
|
|
|
|
/*
|
|
* tryopen() ... try to open a file, exit if unsuccesful
|
|
*
|
|
* Inputs:
|
|
* char *name Name of file to be opened
|
|
* char *mode Mode string for fopen() call
|
|
*
|
|
* Output:
|
|
* FILE * File identifier of successful fopen()
|
|
*/
|
|
|
|
FILE *tryopen (char *name, char *mode) {
|
|
FILE *tmp;
|
|
|
|
if ((tmp = fopen(name,mode)) == NULL) {
|
|
fprintf(stderr,"%s: Unable to open file %s\n",program_name, name);
|
|
exit (EXIT_FAILURE);
|
|
} else
|
|
return (tmp);
|
|
}
|
|
|
|
/*
|
|
* my_fread() ... read data into global buffer and exit if I fail
|
|
*
|
|
* Inputs:
|
|
* FILE *infile File to read from
|
|
* int howmuch Number of bytes to read
|
|
*
|
|
* Output:
|
|
* int Number of bytes actually read
|
|
*/
|
|
|
|
int my_fread(FILE *infile, int howmuch) {
|
|
int result;
|
|
|
|
result = (int)fread(in_buffer, 1, howmuch, infile);
|
|
if (ferror(infile)) {
|
|
fprintf(stderr,"%s: Error while reading data\n",program_name);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
return (result);
|
|
}
|
|
|
|
/*
|
|
* my_fwrite() ... write data from global buffer to file
|
|
*
|
|
* Inputs:
|
|
* unsigned char *buffer Buffer to write out
|
|
* FILE *outfile File to write to
|
|
* int howmuch Number of bytes to write
|
|
*
|
|
* Output:
|
|
* None
|
|
*/
|
|
|
|
void my_fwrite (unsigned char *buffer, FILE *outfile, int howmuch) {
|
|
fwrite(buffer, 1, howmuch, outfile);
|
|
if (ferror(outfile)) {
|
|
fprintf(stderr,"%s: Error while writing data\n",program_name);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* cleanup() ... called in case of an exit(). Frees memory I allocated.
|
|
*
|
|
* Inputs:
|
|
* None
|
|
*
|
|
* Output:
|
|
* None
|
|
*/
|
|
|
|
void cleanup (void) {
|
|
char **p;
|
|
|
|
free (program_name);
|
|
free (current_file);
|
|
free (in_buffer);
|
|
free (out_buffer);
|
|
free (tempfile);
|
|
if (pathList) {
|
|
p = pathList;
|
|
while(*p) free(*p++);
|
|
free (pathList);
|
|
}
|
|
|
|
if (tempfile)
|
|
remove (tempfile);
|
|
}
|
|
|
|
/*
|
|
* usage() ... print out a usage string gotten from udluse.c
|
|
*
|
|
* Inputs:
|
|
* None
|
|
*
|
|
* Outputs:
|
|
* None
|
|
*/
|
|
|
|
void usage (void) {
|
|
extern char use1[]; /* from udluse.c */
|
|
#ifdef GNO
|
|
extern char use2[];
|
|
#endif
|
|
|
|
fprintf(stderr,"%s",use1);
|
|
#ifdef GNO
|
|
if(!needsgno())
|
|
fprintf(stderr,"%s",use2);
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* build_file_list() build the list of files to process
|
|
*
|
|
* Precondition:
|
|
* file is the file name to be added to the pathList
|
|
* recurse if non-zero, directories will be recursed
|
|
*
|
|
* Postcondition:
|
|
* pathList will be a NULL-terminated array of strings. Each
|
|
* string is a partial pathname (relative to rootdir) of a file
|
|
* to convert.
|
|
*
|
|
* Note: This is a recursive routine that uses up (3 * sizeof(char *))
|
|
* bytes of stack with each level of subdirectories.
|
|
*/
|
|
|
|
|
|
void build_file_list(char *file, short recurse) {
|
|
char *thisdir;
|
|
DIR *dir;
|
|
struct dirent *entry;
|
|
|
|
#ifdef __DJGPP__ /* chdir() doesn't accept dir names ending in '\\' */
|
|
if(file[strlen(file)-1] == '\\')
|
|
file[strlen(file)-1] = '/';
|
|
#endif
|
|
|
|
/* check for stack overflow */
|
|
recursionDepth++;
|
|
#ifdef OVERFLOW_CHECK
|
|
if ((recursionDepth * BYTES_PER_DEPTH + BASESIZE) > STACKSIZE) {
|
|
fprintf(stderr,"%s: Exceeded permitted nesting depth (%d levels)\n"
|
|
"Aborted.\n",program_name,recursionDepth);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
#endif
|
|
|
|
if (stat(file,&tstat)!=0) {
|
|
fprintf(stderr,"%s: Couldn't stat %s. File skipped\n",program_name,file);
|
|
--recursionDepth;
|
|
return;
|
|
}
|
|
|
|
if (recurse && S_ISDIR(tstat.st_mode)) {
|
|
char tstr[2];
|
|
|
|
/*
|
|
* It is a directory. recurse through it.
|
|
*/
|
|
|
|
/* save our state */
|
|
tstr[0] = dirbrk;
|
|
tstr[1] = '\0';
|
|
if (*currentDirectory) {
|
|
thisdir = strdup(currentDirectory);
|
|
} else {
|
|
thisdir = malloc(1);
|
|
if (thisdir != NULL) *thisdir='\0';
|
|
}
|
|
if (thisdir == NULL) {
|
|
perror("Couldn't duplicate current directory");
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
if (*currentDirectory) strcat(currentDirectory,tstr);
|
|
strcat(currentDirectory,file);
|
|
if (currentDirectory[strlen(currentDirectory)-1] == dirbrk)
|
|
currentDirectory[strlen(currentDirectory)-1] = '\0';
|
|
|
|
/* recurse */
|
|
if ((dir = opendir(file)) == NULL) {
|
|
fprintf(stderr,"%s: Couldn't open %s. Directory skipped.\n",
|
|
program_name,currentDirectory);
|
|
} else {
|
|
if (chdir(file) !=0) {
|
|
fprintf(stderr,"couldn't cd to %s\n",currentDirectory);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
#ifdef READDIR_RETURNS_DOT
|
|
entry = readdir(dir); /* for "." */
|
|
entry = readdir(dir); /* for ".." */
|
|
#endif
|
|
|
|
while ((entry = readdir(dir))!=NULL) {
|
|
/* ignore hidden files */
|
|
#ifdef BROKEN_DIRENT_STRUCT
|
|
if (*(entry->d_name)!='.') build_file_list((entry->d_name)-2,1);
|
|
#else
|
|
if (*(entry->d_name)!='.') build_file_list(entry->d_name,1);
|
|
#endif
|
|
}
|
|
|
|
if (*thisdir) {
|
|
if ((chdir(rootdir)!=0) || (chdir(thisdir)!=0)) {
|
|
fprintf(stderr,"couldn't cd to %s\n",thisdir);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
} else {
|
|
if (chdir(rootdir)!=0) {
|
|
fprintf(stderr,"couldn't cd to calling directory\n");
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/* restore our state */
|
|
strcpy(currentDirectory,thisdir);
|
|
free(thisdir);
|
|
|
|
} else if (S_ISREG(tstat.st_mode)) {
|
|
|
|
/* It is a normal file. Add it to the pathList */
|
|
add_to_pathList(currentDirectory, file);
|
|
}
|
|
|
|
--recursionDepth;
|
|
return;
|
|
}
|
|
|
|
void add_to_pathList(char *thisdir, char *file) {
|
|
char **p;
|
|
|
|
/* expand the pathList if necessary */
|
|
if (pathSlotsUsed >= pathSlots) {
|
|
pathSlots += PATHLIST_QUANTUM;
|
|
#if BROKEN_REALLOC
|
|
if ((pathList==NULL) &&
|
|
((pathList = malloc((pathSlots+1) * sizeof(char *)))==NULL)) {
|
|
fprintf(stderr,"%s: Couldn't expand pathList\n",program_name);
|
|
exit (EXIT_FAILURE);
|
|
} else {
|
|
if ((p = realloc(pathList, (pathSlots+1) * sizeof(char *)))==NULL) {
|
|
fprintf(stderr,"%s: Couldn't expand pathList\n",program_name);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
pathList = p;
|
|
}
|
|
#else
|
|
if ((p = realloc(pathList,(pathSlots+1) * sizeof(char *)))==NULL) {
|
|
fprintf(stderr,"%s: Couldn't expand pathList\n",program_name);
|
|
exit (EXIT_FAILURE);
|
|
} else pathList = p;
|
|
#endif
|
|
}
|
|
|
|
/* add in the current directory and filename to the pathList */
|
|
pathList[pathSlotsUsed] = malloc(strlen(thisdir)+strlen(file)+2);
|
|
if (pathList[pathSlotsUsed] == NULL) {
|
|
fprintf(stderr,"%s: Couldn't duplicate filename %s%c%s\n",program_name,
|
|
thisdir,dirbrk,file);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
if (*thisdir) {
|
|
sprintf(pathList[pathSlotsUsed],"%s%c%s",thisdir,dirbrk,file);
|
|
} else {
|
|
strcpy(pathList[pathSlotsUsed],file);
|
|
}
|
|
pathSlotsUsed++;
|
|
pathList[pathSlotsUsed] = NULL;
|
|
return;
|
|
}
|
|
|
|
/* Mktemp() construct a unique file name
|
|
*
|
|
* This routine is slightly different than the Unix standard one,
|
|
* thus the capitalization.
|
|
*
|
|
* Inputs:
|
|
* base Template to construct the name upon. It should
|
|
* be in the format "nameXXXXXX" where all "X" are replaced
|
|
* in such a way that the resulting name is unique. There
|
|
* should be at least one, at most 15 "X" in the base name.
|
|
* base may contain a full or partial path.
|
|
*
|
|
* Outputs:
|
|
* Mktemp() returns a pointer to a dynamically allocated string
|
|
* containing a unique file name.
|
|
*
|
|
*/
|
|
|
|
char *Mktemp(const char *base)
|
|
{
|
|
static char id[16] = "AAAAAAAAAAAAAAA";
|
|
char *p1,*p2,*st;
|
|
|
|
if ((st = malloc(strlen(base) + 1)) == NULL)
|
|
{
|
|
fprintf(stderr,"%s: memory allocation failure\n", program_name);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
st = strcpy(st,base);
|
|
|
|
if (*st == '\0')
|
|
{
|
|
free (st);
|
|
if ((st = strdup("TXXXXXXX")) == NULL)
|
|
{
|
|
fprintf(stderr,"%s: memory allocation failure\n", program_name);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
/* Replace all "X" with part of ID string */
|
|
for(p1 = st + strlen(st) - 1,p2 = &id[14];
|
|
p1 >= st && p2 >= id && *p1 == 'X';
|
|
p1--,p2--)
|
|
*p1 = *p2;
|
|
|
|
/* Update ID string to "count" one further */
|
|
for(p1 = &id[14];p1 >= id;)
|
|
if(*p1 == 'Z')
|
|
{
|
|
*p1 = 'A';
|
|
p1--;
|
|
} else {
|
|
*p1 += 1;
|
|
break;
|
|
}
|
|
|
|
/* Make sure the file name does not already exist */
|
|
#ifdef GNO
|
|
if (needsgno() == TRUE) {
|
|
#endif
|
|
if (stat(st,&tstat) == 0)
|
|
{
|
|
free (st);
|
|
st = Mktemp (base);
|
|
}
|
|
#ifdef GNO
|
|
} else { /* ORCA/Shell doesn't like stat one little bit */
|
|
FILE *fp;
|
|
if ((fp = fopen(st,"r")) != NULL)
|
|
{
|
|
fclose(fp);
|
|
free (st);
|
|
st = Mktemp (base);
|
|
} else if ((fp = fopen(st,"a")) == NULL) {
|
|
free(st);
|
|
st = Mktemp (base);
|
|
} else {
|
|
fclose(fp);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return st;
|
|
}
|
|
|
|
/* get_path() ... extract path from filename
|
|
*
|
|
* Inputs:
|
|
* name A file name containing a full, partial or no path.
|
|
*
|
|
* Outputs:
|
|
* Pointer to a string in static memory containing the path
|
|
* to the given file, or an empty string if "name" contained
|
|
* no path. The string can hold MAXPATHLEN characters.
|
|
*/
|
|
|
|
char *get_path (const char *name)
|
|
{
|
|
int i;
|
|
|
|
strcpy(filebuffer, name);
|
|
|
|
for (i = (int)strlen(filebuffer) - 1; i > 0 && filebuffer[i] != dirbrk; i--)
|
|
; /* empty loop to find end of path in name */
|
|
|
|
if (i != 0)
|
|
++i;
|
|
filebuffer[i] = '\0';
|
|
return filebuffer;
|
|
}
|
|
|
|
/* End Of File */
|