/** * @file dat2pl1.c * @brief Convert EBCDIC to ASCII for NSSDC PSPG-00472 * @author Yukio Yamamoto * @date 2013/04/03 */ #include #include #define SIZE_HEADER 2 #define SIZE_BUF 2000 #define SIZE_CODE 3 #define RECORD_LENGTH 80 /* * Notice: * It appears that CCSID EBCDIC-US was adoped. * See RFC 1345: Character Mnemonics & Character Sets */ char ebcdic[16][16][SIZE_CODE] = { {"NU","SH","SX","EX","ET","EQ","AK","BL","BS","HT","LF","VT","FF","CR","SO","SI"}, {"DL","D1","D2","D3","D4","NK","SY","EB","CN","EM","SB","EC","FS","GS","RS","US"}, {"??","??","??","??","??","??","??","??","??","??","??","??","??","??","??","??"}, {"??","??","??","??","??","??","??","??","??","??","??","??","??","??","??","??"}, {" ","??","??","??","??","??","??","??","??","??","Ct",". ","< ","( ","+ ","| "}, {"& ","??","??","??","??","??","??","??","??","??","! ","$ ","* ",") ","; ","^ "}, {"- ","/ ","??","??","??","??","??","??","??","??","BB",", ","% ","_ ","> ","? "}, {"??","??","??","??","??","??","??","??","??","'!",": ","# ","@ ","' ","= ","\" "}, {"??","a ","b ","c ","d ","e ","f ","g ","h ","i ","??","??","??","??","??","??"}, {"??","j ","k ","l ","m ","n ","o ","p ","q ","r ","??","??","??","??","??","??"}, {"??","~ ","s ","t ","u ","v ","w ","x ","y ","z ","??","??","??","??","??","??"}, {"??","??","??","??","??","??","??","??","??","??","??","??","??","??","??","??"}, {"{ ","A ","B ","C ","D ","E ","F ","G ","H ","I ","??","??","??","??","??","??"}, {"} ","J ","K ","L ","M ","N ","O ","P ","Q ","R ","??","??","??","??","??","??"}, {"\\ ","??","S ","T ","U ","V ","W ","X ","Y ","Z ","??","??","??","??","??","??"}, {"0 ","1 ","2 ","3 ","4 ","5 ","6 ","7 ","8 ","9 ","??","??","??","??","??","DT"}, }; char ebcdic2ascii(unsigned char c) { int high = c >> 4; int low = c & 0x0f; char* code = ebcdic[high][low]; if (high < 4) { return ' '; } if (code[1] != ' ') { return ' '; } return code[0]; } int main(int argc, char** argv) { FILE* f; unsigned char header[SIZE_HEADER]; unsigned char buf[SIZE_BUF]; size_t r, size; int i; int ret = EXIT_SUCCESS; f = fopen(argv[1], "rb"); if (f == NULL) { fprintf(stderr, "no such file: %s\n", argv[1]); ret = EXIT_FAILURE; goto finish; } while ((r = fread(header, sizeof(char), SIZE_HEADER, f)) > 0) { if (r != SIZE_HEADER) { fprintf(stderr, "invalid format\n"); ret = EXIT_FAILURE; goto finish; } size = header[0]; size = (size << 8) + header[1]; if (size > SIZE_BUF) { fprintf(stderr, "data size exceeds buffer size %zd\n", size); ret = EXIT_FAILURE; goto finish; } if ((r = fread(buf, sizeof(char), size, f)) > 0) { if (size != r) { fprintf(stderr, "warning: data might be terminated\n"); } for(i = 0; i < r; ++i) { putchar(ebcdic2ascii(buf[i])); if (i % RECORD_LENGTH == (RECORD_LENGTH - 1)) { putchar('\n'); } } } } finish: if (f) { fclose(f); } return ret; }