// // Programmer: Stef // Last Modified: Tue Aug 31 22:34:27 GMT+0700 1999 // $Smake: cc -ansi -m486 -O -o %b %f -lg++ && strip %b // $Smake-linux: g++ -ansi -m486 -O3 -o %b %f && strip %b // // // Original idea from Craig Stuart Sapp // Modified by Stef to support input of filenames from STDIN // And to ignore Binary Files // // Description: Utility program to convert text files between // UNIX newlines and DOS linefeed + newlines // // Unix uses the character 0x0a to start a new line // while DOS uses two characters: 0x0d 0x0a // // Options are: // -u make the file Unix/MAC conformant // -d make the file DOS conformant // -f force it to process binary files // -l read a list of files from STDIN // // Multiple files can be processed at once on the command line // #include #include #include #include #include #include // Added By Stef #define MAX_PATH 256 void exit_usage(const char* command); int translate_to_unix(istream& in, ostream& out); int translate_to_dos(istream& in, ostream& out); void process_file(const char* filename); // Globals char g_cMode; // Current Mode bool g_bForce; // Force Binary Mode bool g_nRet; // ErrorLevel Return value int main(int argc, char* argv[]) { // Sanity Syntax Check if (argc < 2) exit_usage(argv[0]); if (argv[1][0] != '-' && argv[1][0] != '/') exit_usage(argv[0]); // Set Defaults g_cMode = '\0'; g_bForce = false; g_nRet = 0; bool bStdIn = true; // Should we read from STDIN bool bFiles = false; // Read Files (not data) from STDIN // Process Arguments for(int nCnt = 1; nCnt < argc; nCnt++) { // Is it a parameter? if(argv[nCnt][0] == '-' || argv[nCnt][0] == '/') { switch(argv[nCnt][1]) { case 'u': case 'd': g_cMode = argv[nCnt][1]; break; case 'l': bFiles = true; break; case 'f': g_bForce = true; break; default: break; } continue; } // If no mode set yet then syntax prob if(g_cMode == '\0') exit_usage(argv[0]); // Don't read from StdIn bStdIn = false; process_file(argv[nCnt]); } if(bStdIn) { // Read file list from stin if(bFiles) { char szBuff[MAX_PATH]; while(!cin.eof()) { // Get a line cin.get(szBuff, MAX_PATH, '\n'); cin.get(); // Process it if there's something if(strlen(szBuff)) process_file(szBuff); } } else // Just process the stdin raw process_file(NULL); } return g_nRet; } //////////////////////////////// // // process_file void process_file(const char* filename) { char fileTemp[MAX_PATH]; // Backup Filename int nRet = 0; // Return Value // If filename is NULL means stdin -> stdout (below) if(filename) { // Construct Backup File Name strcpy(fileTemp, filename); strcat(fileTemp, "._x"); strcat(fileTemp, &g_cMode); // If it exists dump it remove(fileTemp); // Rename original to backup if(rename(filename, fileTemp)) { cerr << "Error: "; perror(filename); g_nRet++; return; } // Open original file fstream infile(fileTemp, ios::in | ios::binary | ios::nocreate); if (!infile) { cerr << "Error: cannot find file " << fileTemp << endl; g_nRet++; return; } // Open output file fstream outfile(filename, ios::out | ios::binary); if (!outfile) { cerr << "Error: cannot write to file: " << filename << endl; g_nRet++; return; } // Translate File if (g_cMode == 'd') nRet = translate_to_dos(infile, outfile); else if (g_cMode == 'u') nRet = translate_to_unix(infile, outfile); // Clean Up infile.close(); outfile.close(); // If errors then move everything back if(nRet) { remove(filename); rename(fileTemp, filename); } } // stdin -> stdout else { if (g_cMode == 'd') nRet = translate_to_dos(cin, cout); else if (g_cMode == 'u') nRet = translate_to_unix(cin, cout); } // Put file name at end of conversion error message if(nRet) { g_nRet++; cerr << filename << endl; } } ////////////////////////////// // // translate_to_dos // int translate_to_dos(istream& in, ostream& out) { char szBuff[1024]; // Read at most 1K at a time int nLen = 0; // Length of current line while (!in.eof()) { in.getline(szBuff, 1024); nLen = strlen(szBuff); // Check for Binary characters for now that's ASCII 0 - 31 // excluding \n \r \t if(!g_bForce) { char* psz = szBuff; for(; psz < szBuff + nLen; psz++) { if(psz[0] < 0x20 && psz[0] > -1 && psz[0] != '\n' && psz[0] != '\t' && psz[0] != '\r') { cerr << "Error: File is Binary: "; // process_file puts filename return 1; } } } // Remove Line ending if(szBuff[nLen - 1] == 0x0a) nLen--; if(szBuff[nLen - 1] == 0x0d) nLen--; out.write(szBuff, nLen); if (in.eof()) break; // Add DOS ending out.put((char)0x0d); out.put((char)0x0a); } return 0; } ////////////////////////////// // // translate_to_unix // int translate_to_unix(istream& in, ostream& out) { char szBuff[1024]; // Read at most 1K at a time int nLen = 0; // Length of current line while (!in.eof()) { in.getline(szBuff, 1024); nLen = strlen(szBuff); // Check for Binary characters for now that's ASCII 0 - 31 // excluding \n \r \t if(!g_bForce) { char* psz = szBuff; for(; psz < szBuff + nLen; psz++) { if(psz[0] < 0x20 && psz[0] > -1 && psz[0] != '\n' && psz[0] != '\t' && psz[0] != '\r') { cerr << "Error: File is Binary: "; // process_file puts filename return 1; } } } // Remove ending if(szBuff[nLen - 1] == 0x0a) nLen--; if(szBuff[nLen - 1] == 0x0d) nLen--; out.write(szBuff, nLen); if (in.eof()) break; // Add Unix Ending out.put((char)0x0a); } return 0; } ////////////////////////////// // // exit_usage // void exit_usage(const char* commandName) { cout << endl; cout << "Usage: " << commandName << " option filename[s]" << endl; cout << " Converts ascii files to either unix or dos format" << endl; cout << " If no file parameters reads from stdin" << endl; cout << endl; cout << " Options: " << endl; cout << " -u = convert to unix format (newline)" << endl; cout << " -d = convert to dos format (linefeed + newline)" << endl; cout << " -f = force conversion even if binary found" << endl; cout << " -l = read a list of filenames from stdin" << endl; cout << endl; cout << endl; exit(1); }