/* * newlinelib.c * Used for determining and converting newline formats. * * History: * Developed 970714 for use in creating automatic file format changing in Samba. * * Copyright (c) 1997 David R. Harris. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #include #include #include #include "newlinelib.h" /******************************************************************************/ /******************************************************************************/ /* Function to determine a file format */ int findFileFormat( int readFile ) { int countBigLoop; int counter = 0; int numCount = NLL_FFF_FIRSTREAD; char buff[NLL_BUFFSIZE]; int buffNextChar = 1; int buffNumChars = 0; int numLF = 0; int numBinary = 0; int numCRLF = 0; char thisChar = 0; char lastChar; /* Loop for levels of counting */ for( countBigLoop = 0 ; countBigLoop <= 1 ; countBigLoop++ ) { /* Loop for the characters to read */ for( ; counter < numCount ; counter++ ) { /* Get another buf full of chars if needed */ if ( buffNextChar >= buffNumChars ) { /* Get anothe buf full */ buffNumChars = read(readFile, buff, (size_t)sizeof(buff)); buffNextChar = 0; /* Handle a possible EOF */ if( buffNumChars == 0 ) break; } /* Get the character */ lastChar = thisChar; thisChar = buff[buffNextChar++]; /* Do the counting */ if( (int)(unsigned char)thisChar == 10 ) numLF++; if( (int)(unsigned char)thisChar == 10 && lastChar == 13 ) numCRLF++; if( ( (int)(unsigned char)thisChar <= 31 && (int)(unsigned char)thisChar != 13 && (int)(unsigned char)thisChar != 10 ) || ( (int)(unsigned char)thisChar >= 128 ) ) numBinary++; } /* If for two ways to decide, can defer or can't */ if ( countBigLoop == 0 && buffNumChars != 0 ) { /* Determine what type of file this is */ if ( numBinary >= (int)( (float)(counter + 1) * 0.30 ) ) return BINARY; if ( numBinary <= (int)( (float)(counter + 1) * 0.10 ) ) { if ( (numLF - numCRLF) >= ( numCRLF * 2 ) ) return ASCII_UNIX; if ( numCRLF >= ( (numLF - numCRLF) * 2 ) ) return ASCII_DOS; } /* Can't defer descision */ } else { /* Determine what type of file this is */ if ( numBinary >= (int)( (float)(counter + 1) * 0.15 ) ) return BINARY; if ( (numLF - numCRLF) >= numCRLF ) { return ASCII_UNIX; } else { return ASCII_DOS; } } /* Looks like we defered the descision, count some more */ numCount = NLL_FFF_SECONDREAD; } } /******************************************************************************/ /******************************************************************************/ /* Function to convert UNIX files into DOS files */ int convertUnixToDos( int readFile, int writeFile ) { char buff[NLL_BUFFSIZE]; int buffThisChar = 0; int buffNumChars = 0; int buffBeginNextWrite = 1; /* Loop for chunks */ while ( 1 ) { /* Get another buf full of chars if needed */ if ( buffThisChar >= buffNumChars ) { /* Write the last part of the current buff */ write(writeFile, buff + buffBeginNextWrite, (size_t) (buffThisChar - buffBeginNextWrite)); /* Go get a new buff of chars */ buffNumChars = read(readFile, buff, (size_t)sizeof(buff)); buffThisChar = 0; buffBeginNextWrite = 0; /* Handle an EOF */ if( buffNumChars == 0 ) break; } /* If we found a LF */ if ( (int)(unsigned char)buff[buffThisChar] == 10 ) { /* Print the last buff with a CR */ buff[buffThisChar] = (char)(unsigned char)13; write(writeFile, buff + buffBeginNextWrite, (size_t) (buffThisChar - buffBeginNextWrite + 1)); buffBeginNextWrite = buffThisChar; /* Set up the next write to print the LF */ buff[buffThisChar] = (char)(unsigned char)10; } /* Move on to the next char */ buffThisChar++; } return 0; } /******************************************************************************/ /******************************************************************************/ /* Function to convert DOS files into UNIX files */ /* * Actually, this just removes all CR's instead of converting all CRLF's into * CR's. Therefor, if there is a lone CR around it will get deleted. I don't * really feel that this is a bug, because lone CR's are a mistake. * - David Harris 7/17/97 */ int convertDosToUnix( int readFile, int writeFile ) { char buff[NLL_BUFFSIZE]; int buffThisChar = 0; int buffNumChars = 0; int buffBeginNextWrite = 1; /* Loop for chunks */ while ( 1 ) { /* Get another buf full of chars if needed */ if ( buffThisChar >= buffNumChars ) { /* Write the last part of the current buff */ write(writeFile, buff + buffBeginNextWrite, (size_t) (buffThisChar - buffBeginNextWrite)); /* Go get a new buff of chars */ buffNumChars = read(readFile, buff, (size_t)sizeof(buff)); buffThisChar = 0; buffBeginNextWrite = 0; /* Handle an EOF */ if( buffNumChars == 0 ) break; } /* If we found a CR */ if ( (int)(unsigned char)buff[buffThisChar] == 13 ) { /* Print the last buff without the CR */ write(writeFile, buff + buffBeginNextWrite, (size_t) (buffThisChar - buffBeginNextWrite)); buffBeginNextWrite = buffThisChar + 1; } /* Move on to the next char */ buffThisChar++; } return 0; } /******************************************************************************/ /******************************************************************************/ /* Don't convert, just copy */ int convertNone( int readFile, int writeFile ) { char buff[NLL_BUFFSIZE]; int buffNumChars = 0; /* Loop for chunks */ while ( 1 ) { /* Go get a new buff of chars */ buffNumChars = read(readFile, buff, (size_t)sizeof(buff)); /* Handle an EOF */ if( buffNumChars == 0 ) { break; } /* Write out the current buff */ write(writeFile, buff, (size_t)buffNumChars); } return 0; }