home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
cvt304.zip
/
CVT.C
next >
Wrap
Text File
|
2002-08-24
|
25KB
|
901 lines
/****************************************************************************/
/* */
/* Convert one or more files from Unix format (LF) to DOS format (CR/LF) */
/* */
/* Note: Wildcards are supported and files are updated in place. */
/* */
/* This work is released into the public domain by the author. */
/* */
/* */
/* 08/02/92 Bob Withers Program originally complete. */
/* */
/* 09/24/92 Bob Withers Added search subdirs feature. */
/* */
/* 10/02/93 Bob Withers Added multiple format conversion. */
/* */
/* 07/20/94 Bob Withers Converted to Unix style dir routines */
/* and tested code under Unix SVR3.2 */
/* */
/* 08/23/94 Bob Withers Added Ctrl-Z to tests for valid text */
/* files. Ctrl-Z at end of DOS files */
/* was causing them to be treated as */
/* binary. Also, remove Ctrl-Z when */
/* converting from DOS. */
/* */
/* 12/26/95 Bob Withers Added #ifdef checks for NEED_STRERROR */
/* per Dale DePriest daled@cadence.com. */
/* Added -8 switch to permit conversion */
/* of files with char values > 127 per */
/* Stefan Witzel switzel@gwdg.de. */
/* */
/* 02/19/96 Bob Withers Force filenames to uppercase if not */
/* running on Unix. This will allow */
/* all matches to be found under NT which */
/* treats file access as case insensitive */
/* but may return names in mixed case. */
/* */
/* 02/21/96 Bob Withers Corrected error in recursive directory */
/* processing that prevented it from */
/* working properly. Fixed bug in alloc */
/* of memory to store directory names. */
/* Added general purpose Err() function */
/* to handle display of terminal errors. */
/* */
/****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef UNIX
#include <unistd.h>
#include <malloc.h>
#include <dirent.h>
#define READ_BIN "r"
#define WRITE_BIN "w"
#define PATH_SEP '/'
#define PATH_SEP_STR "/"
#define ANSI_C 0
#else
#include "dirent.h"
#include <ctype.h>
#define READ_BIN "rb"
#define WRITE_BIN "wb"
#define PATH_SEP '\\'
#define PATH_SEP_STR "\\"
#define ANSI_C 1
#endif
#if ANSI_C
#define USE_PROTO 1
#define PROTO(x) x
#include <stdarg.h>
#else
#define USE_PROTO 0
#define PROTO(x) ()
#include <varargs.h>
#endif
#include "regexp.h"
#if USE_PROTO
#include <stdlib.h>
#else
extern int errno;
#endif
#ifndef FILENAME_MAX
#define FILENAME_MAX 128
#endif
#define CTRL_Z 0x1a
#define FILTYP_DOS 0
#define FILTYP_MAC 1
#define FILTYP_UNIX 2
#define FILTYP_BINARY 3
#define FILTYP_VAX 4
static int ChkFileType PROTO((FILE *pFile));
static int ConvertFiles PROTO((char *pPath, int bOrigCall));
static int CopyFile PROTO((char *pszSrcFile, char *pszDestFile));
static void Err PROTO((int nLine, int nErrNo, char *pszFmt, ...));
static int ProcFileByType PROTO((FILE *pInFile, char *pszInName,
char *pszShortName));
static int ProcessFile PROTO((FILE *pInFile, int nFilTyp,
char *pszInName));
static void Usage PROTO((void));
static int WildCardPath PROTO((char *pPath, char *pszInName,
char *pszRegExp, struct stat *pST));
static void WriteChar PROTO((int c, FILE *pOutFile));
#ifdef NEED_STRERROR
static char * strerror PROTO((int nErr));
#endif
static int nSelCnt = 0;
static int nFileCnt = 0;
static int nCharLimit = 127;
static int bSearchSubDirs = 0;
static int bChkType = 0;
static int bToDos = 0;
static int bToUnix = 0;
static int bToMac = 0;
static int bToVax = 0;
#if USE_PROTO
int main(int argc, char **argv)
#else
int main(argc, argv)
int argc;
char **argv;
#endif
{
register int i, j;
auto int nFirstArg = 1;
for (i = 1; i < argc; ++i)
{
if (!('-' == argv[i][0] || '/' == argv[i][0]))
break;
++nFirstArg;
for (j = 1; argv[i][j]; ++j)
{
switch (argv[i][j])
{
case 's':
case 'S':
++bSearchSubDirs;
break;
case 'c':
case 'C':
++bChkType;
break;
case '8':
nCharLimit = 255;
break;
case 'm':
case 'M':
++bToMac;
break;
case 'd':
case 'D':
++bToDos;
break;
case 'u':
case 'U':
++bToUnix;
break;
case 'v':
case 'V':
++bToVax;
break;
default:
printf("\nUnknown switch %c\n", argv[i][j]);
break;
}
}
}
if (argc - nFirstArg < 1)
{
Usage();
return(0);
}
if (1 != (bChkType + bToMac + bToDos + bToUnix + bToVax))
Err(__LINE__, 0, "\nInvalid switch combination, only one of c,m,u,d,v\n");
if (!bChkType)
{
printf("\nConvert files to ");
if (bToDos)
printf("Dos format\n");
else
{
if (bToUnix)
printf("Unix format\n");
else
{
if (bToVax)
printf("Vax format\n");
else
printf("Mac format\n");
}
}
}
for (i = nFirstArg; i < argc; ++i)
{
if (ConvertFiles(argv[i], 1))
exit(1);
}
printf("\n\n%d file%s selected, %d converted.\n",
nSelCnt, 1 == nSelCnt ? "" : "s", nFileCnt);
return(0);
}
#define DIRNAME_ARRAY_INCR 10
#if USE_PROTO
static int ConvertFiles(char *pPath, int bOrigCall)
#else
static int ConvertFiles(pPath, bOrigCall)
char *pPath;
int bOrigCall;
#endif
{
auto FILE * pInFile;
auto char * p;
auto int len;
auto int bSearchDir = 0;
static regexp * pRegExp;
static struct stat st;
static char szPath[FILENAME_MAX];
static char szInName[FILENAME_MAX];
static char szRegExp[FILENAME_MAX];
strcpy(szInName, pPath);
bSearchDir = WildCardPath(pPath, szPath, szRegExp, &st);
if (bSearchDir)
{
auto DIR * pDir;
auto struct dirent * pDirEnt;
auto int nCurDirCnt = 0;
auto int nMaxDirCnt = 0;
auto char ** pDirNames = NULL;
static int nOrigPathLen;
strcat(szPath, PATH_SEP_STR);
pDir = opendir(szPath);
if (NULL == pDir)
Err(__LINE__, 0, "\nError, unable to open directory %s\n", szPath);
if (bOrigCall)
{
nOrigPathLen = strlen(szPath) - 1;
pRegExp = regcomp(szRegExp);
if (NULL == pRegExp)
{
Err(__LINE__, 0, "\nError compiling regular expression %s\n",
szRegExp);
}
}
while (NULL != (pDirEnt = readdir(pDir)))
{
if (0 == strcmp(pDirEnt->d_name, ".")
||
0 == strcmp(pDirEnt->d_name, ".."))
{
continue;
}
#ifndef UNIX
strupr(pDirEnt->d_name);
#endif
strcpy(szInName, szPath);
strcat(szInName, pDirEnt->d_name);
if (0 != stat(szInName, &st))
Err(__LINE__, errno, "\nstat failed on %s", szInName);
if (st.st_mode & S_IFDIR)
{
if (!bSearchSubDirs)
continue;
if (nCurDirCnt >= nMaxDirCnt)
{
nMaxDirCnt += DIRNAME_ARRAY_INCR;
len = nMaxDirCnt * sizeof(*pDirNames);
if (NULL == pDirNames)
pDirNames = malloc(len);
else
pDirNames = realloc(pDirNames, len);
if (NULL == pDirNames)
{
closedir(pDir);
Err(__LINE__, 0, "Error - out of memory");
}
}
p = strdup(pDirEnt->d_name);
if (p)
pDirNames[nCurDirCnt++] = p;
else
Err(__LINE__, 0, "Out of memory");
continue;
}
if (regexec(pRegExp, pDirEnt->d_name))
{
p = szInName + nOrigPathLen + 1;
if (!bChkType)
printf("\nConverting %-16s\t", p);
pInFile = fopen(szInName, READ_BIN);
if (NULL == pInFile)
{
closedir(pDir);
Err(__LINE__, errno, "Error - unable to open %s", szInName);
}
ProcFileByType(pInFile, szInName, p);
}
}
closedir(pDir);
if (nCurDirCnt > 0)
{
p = strdup(szPath);
if (NULL == p)
Err(__LINE__, 0, "Out of memory");
for (len = 0; len < nCurDirCnt; ++len)
{
strcpy(szInName, p);
strcat(szInName, pDirNames[len]);
free(pDirNames[len]);
if (ConvertFiles(szInName, 0))
return(1);
}
free(p);
}
if (bOrigCall)
free(pRegExp);
if (pDirNames)
free(pDirNames);
}
else
{
pInFile = fopen(szInName, READ_BIN);
if (NULL == pInFile)
Err(__LINE__, errno, "Error, unable to open %s", szInName);
p = strrchr(szInName, PATH_SEP);
if (NULL == p)
p = szInName;
else
++p;
if (!bChkType)
printf("\nConverting %-16s\t", p);
ProcFileByType(pInFile, szInName, p);
}
return(0);
}
#if USE_PROTO
static int WildCardPath(char *pPath, char *pszInName,
char *pszRegExp, struct stat *pST)
#else
static int WildCardPath(pPath, pszInName, pszRegExp, pST)
char *pPath;
char *pszInName;
char *pszRegExp;
struct stat *pST;
#endif
{
register char * p;
auto char szWrk[2];
szWrk[1] = '\0';
strcpy(pszInName, pPath);
if (0 == stat(pszInName, pST))
{
if (pST->st_mode & S_IFDIR)
{
strcpy(pszRegExp, ".*");
return(1);
}
}
p = strrchr(pszInName, PATH_SEP);
if (NULL == p)
{
p = pszInName;
while (*p)
{
if ('?' == *p || '*' == *p)
break;
++p;
}
if (*p)
{
p = pPath;
strcpy(pszInName, ".");
}
else
return(0);
}
else
{
*p++ = '\0';
}
strcpy(pszRegExp, "^");
while (*p)
{
if ('.' == *p)
{
strcat(pszRegExp, "\\.");
}
else
{
if ('*' == *p)
{
strcat(pszRegExp, ".*");
}
else
{
#ifdef UNIX
szWrk[0] = *p;
#else
szWrk[0] = toupper(*p);
#endif
strcat(pszRegExp, szWrk);
}
}
++p;
}
strcat(pszRegExp, "$");
return(1);
}
#if USE_PROTO
static int ProcFileByType(FILE *pInFile, char *pszInName, char *pszShortName)
#else
static int ProcFileByType(pInFile, pszInName, pszShortName)
FILE *pInFile;
char *pszInName;
char *pszShortName;
#endif
{
++nSelCnt;
switch (ChkFileType(pInFile))
{
case FILTYP_MAC:
if (bChkType)
{
fclose(pInFile);
printf("\nFile %-16s\ttype is Mac", pszShortName);
}
else
{
if (bToMac)
{
fclose(pInFile);
printf("already Mac format");
}
else
{
ProcessFile(pInFile, FILTYP_MAC, pszInName);
printf("from Mac");
}
}
break;
case FILTYP_DOS:
if (bChkType)
{
fclose(pInFile);
printf("\nFile %-16s\ttype is Dos", pszShortName);
}
else
{
if (bToDos)
{
fclose(pInFile);
printf("already Dos format");
}
else
{
ProcessFile(pInFile, FILTYP_DOS, pszInName);
printf("from Dos");
}
}
break;
case FILTYP_UNIX:
if (bChkType)
{
printf("\nFile %-16s\ttype is Unix", pszShortName);
fclose(pInFile);
}
else
{
if (bToUnix)
{
fclose(pInFile);
printf("already Unix format");
}
else
{
ProcessFile(pInFile, FILTYP_UNIX, pszInName);
printf("from Unix");
}
}
break;
case FILTYP_VAX:
if (bChkType)
{
printf("\nFile %-16s\ttype is Vax", pszShortName);
fclose(pInFile);
}
else
{
if (bToVax)
{
fclose(pInFile);
printf("already Vax format");
}
else
{
ProcessFile(pInFile, FILTYP_VAX, pszInName);
printf("from Vax");
}
}
break;
default:
fclose(pInFile);
if (bChkType)
printf("\nFile %-16s\ttype is Binary", pszShortName);
else
printf("skipped, binary file");
break;
}
return(0);
}
#if USE_PROTO
static int ProcessFile(FILE *pInFile, int nFilTyp, char *pszInName)
#else
static int ProcessFile(pInFile, nFilTyp, pszInName)
FILE *pInFile;
int nFilTyp;
char *pszInName;
#endif
{
register int c;
auto FILE * pOutFile;
auto char szOutName[L_tmpnam];
tmpnam(szOutName);
pOutFile = fopen(szOutName, WRITE_BIN);
if (NULL == pOutFile)
Err(__LINE__, errno, "Error, unable to open temp file %s", szOutName);
while (EOF != (c = fgetc(pInFile)))
{
switch (nFilTyp)
{
case FILTYP_DOS:
if (bToUnix && ('\r' == c || CTRL_Z == c))
continue;
if (bToMac && ('\n' == c || CTRL_Z == c))
continue;
if (bToVax)
{
if (CTRL_Z == c)
continue;
if ('\n' == c)
WriteChar('\r', pOutFile);
}
WriteChar(c, pOutFile);
break;
case FILTYP_MAC:
if ('\r' == c)
{
c = '\n';
if (bToVax)
{
WriteChar('\r', pOutFile);
WriteChar('\r', pOutFile);
}
}
if ('\n' == c && bToDos)
WriteChar('\r', pOutFile);
WriteChar(c, pOutFile);
break;
case FILTYP_UNIX:
if ('\n' == c)
{
if (bToMac)
c = '\r';
else
{
if (bToDos)
WriteChar('\r', pOutFile);
else
{
if (bToVax)
{
WriteChar('\r', pOutFile);
WriteChar('\r', pOutFile);
}
}
}
}
WriteChar(c, pOutFile);
break;
case FILTYP_VAX:
if ('\r' == c)
continue;
if ('\n' == c)
{
if (bToMac)
c = '\r';
else
{
if (bToDos)
WriteChar('\r', pOutFile);
}
}
WriteChar(c, pOutFile);
break;
}
}
fclose(pInFile);
fclose(pOutFile);
if (CopyFile(szOutName, pszInName))
exit(1);
unlink(szOutName);
++nFileCnt;
return(0);
}
#if USE_PROTO
static void WriteChar(int c, FILE *pOutFile)
#else
static void WriteChar(c, pOutFile)
int c;
FILE *pOutFile;
#endif
{
if (EOF == fputc(c, pOutFile))
Err(__LINE__, errno, "Error, can't write to temp output file\n");
return;
}
#if USE_PROTO
static int CopyFile(char *pszSrcFile, char *pszDestFile)
#else
static int CopyFile(pszSrcFile, pszDestFile)
char *pszSrcFile;
char *pszDestFile;
#endif
{
auto size_t Len;
auto FILE * pIn;
auto FILE * pOut;
static char Buf[4096];
pIn = fopen(pszSrcFile, READ_BIN);
if (NULL == pIn)
Err(__LINE__, errno, "Error, unable to open file %s", pszSrcFile);
pOut = fopen(pszDestFile, WRITE_BIN);
if (NULL == pOut)
{
fclose(pIn);
Err(__LINE__, errno, "Error, unable to open file %s", pszDestFile);
}
Len = fread(Buf, sizeof(Buf[0]), sizeof(Buf), pIn);
while (Len > 0)
{
if (Len != fwrite(Buf, sizeof(Buf[0]), Len, pOut))
{
fclose(pIn);
fclose(pOut);
Err(__LINE__, errno, "Error writing output - disk full??");
}
if (Len < sizeof(Buf))
break;
Len = fread(Buf, sizeof(Buf[0]), sizeof(Buf), pIn);
}
if (ferror(pIn))
{
perror("\nError while copying temp file ");
fclose(pIn);
fclose(pOut);
return(1);
}
fclose(pIn);
fclose(pOut);
return(0);
}
#if USE_PROTO
static int ChkFileType(FILE *pFile)
#else
static int ChkFileType(pFile)
FILE *pFile;
#endif
{
auto size_t i;
auto size_t siz;
auto int nCR = 0;
auto int nLF = 0;
static unsigned char buf[1024];
siz = fread(buf, 1, sizeof(buf), pFile);
fseek(pFile, 0L, SEEK_SET);
if (0 == siz)
return(FILTYP_BINARY);
for (i = 0; i < siz; ++i)
{
switch (buf[i])
{
case '\r':
++nCR;
break;
case '\n':
++nLF;
break;
case '\t':
case 11:
case 12:
case CTRL_Z:
break;
default:
if (buf[i] < ' ' || (int) buf[i] > nCharLimit)
return(FILTYP_BINARY);
break;
}
}
if (0 == nCR && nLF)
return(FILTYP_UNIX);
if (0 == nLF && nCR)
return(FILTYP_MAC);
if (nCR > nLF + 1)
return(FILTYP_VAX);
return(FILTYP_DOS);
}
#if USE_PROTO
static void Usage(void)
#else
static void Usage()
#endif
{
printf("\nCVT - Convert source file to Dos/Mac/Unix/Vax format V3.04");
#ifdef UNIX
printf("\n Bob Withers, 10/02/93\n");
#else
printf("\n Bob Withers, 10/02/93 [as of %s]\n", __DATE__);
#endif
printf("\nUsage: CVT [-s] -cdmuv file1 file2 ... fileN");
printf("\n -s ==> Search subdirectories");
printf("\n -c ==> Check filetypes and display");
printf("\n -8 ==> Allow chars > 127 in converted files");
printf("\n -d ==> Convert to DOS format");
printf("\n -m ==> Convert to MAC format");
printf("\n -u ==> Convert to Unix format");
printf("\n -v ==> Convert to Vax format");
printf("\n Select 1 of c,d,m,u,v only");
printf("\n Wildcards are permitted.");
printf("\n Files are overwritten with converted version.\n");
return;
}
#if USE_PROTO
static void Err(int nLine, int nErrNo, char *pszFmt, ...)
#else
static void Err(va_alist)
va_dcl
#endif
{
#if USE_PROTO
auto va_list ap;
va_start(ap, pszFmt);
#else
auto int nLine;
auto int nErrNo;
auto char * pszFmt;
auto va_list ap;
va_start(ap);
nLine = va_arg(ap, int);
nErrNo = va_arg(ap, int);
pszFmt = va_arg(ap, char *);
#endif
printf("\nLine %d: ", nLine);
vprintf(pszFmt, ap);
va_end(ap);
printf("\n");
if (nErrNo)
printf("Error %d: %s\n", nErrNo, strerror(nErrNo));
exit(1);
}
#ifdef NEED_STRERROR
#if USE_PROTO
static char *strerror(int nErr)
#else
static char *strerror(nErr)
int nErr;
#endif
{
extern int sys_nerr;
extern char * sys_errlist[];
if (nErr < sys_nerr)
return(sys_errlist[nErr]);
return("");
}
#endif