📄 xencode.c
字号:
/* V2.11-26.Feb.97~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XENCODE.C ~~~~~~~~~ Description: ~~~~~~~~~~~~ Program to convert binary files into ASCII file(s), in order to allow transmission via electronic mail. It follows the de-facto standard of the public-domain program uuencode.c, but adding the capability of automatically break a file pottencially too long for transmission in some networks (e.g., BITNET only allows 64k-byte long files). The encoded file will be decoded by xdecode.c or any other compatible with uudecode.c; using the former, the reconstruction of the file encoded by xencode.c will be automatic (in the case that file truncation happened); using the latter, reconstruction will have to be manual. The uuencode.c's basic algorithm is to access the file char-wisely (char-by-char), to transform the chars (0..255) read into printable ASCII chars but adding some error detection capabilities: reads 45 chars from the file (possibly except in the last "block" read from file, if the file size is not multiple of 45, i.e., filesize % 45 != 0.), codes the number of chars read and put into the file;then codes the samples, making 3 chars into 4, and then converting them to readable ASCII chars. The encoding function is ENC(c) = (((c) & 077) + ' ') The standard implies also that a header and a tail are added to the file. The header, for uuencode.c, is the word "begin", followed by the file's access mode (in octal) and the original file name. The tail is just the word "end", followed by a carriage return (necessarily). The extension here implemented just add some more information to the header: the continuation file's name. This way, if no continuation file name is found in header, the program assumes that the presently open file is the last one. In this version the CRC is calculated and saved incrementally to the end of the xencoded file (right after the "end" line). Incrementally means that, when a file is broken in parts, at the end of each part, it will be printed the CRC from the beginning of the file upto that part. Three CRCs are printed: CCITT, XMODEM and ARC. The CRC module is based on the implementation posted on the comp.sources.unix by Mark G. Mendel. NOTE1: because some operating systems have short maximum file names (for example, DOS only allows 8-char-long file names and 3-byte-long file extensions), it is advidsable to use destination names as short as possible, in order to prevent file overwriting. NOTE2: when encoding ASCII files (e.g. postscript figures or docs) in a DOS file system, it is advisable to use the option "-t", rather than the default binary option. This may cause a problem when decoding the file in a Unix machine, because DOS line termination is the pair CR+LF, while in Unix it is only LF. Option "-t" provides a proper encoding of the original file. Usage: ~~~~~~ $ xencode [-options] [InpFile [OutFile [BlockSize]]] where: InpFile is the name of the file to be encoded; if not specified, stdin is assumed; OutFile is the name with the encoded data; if not specified, stdout is assumed; BlockSize is the block size, almost in kbytes; if not specified, MAX_LONG is assumed, what implies no fragmentation of encoded file; the "almost" above means that, due to 1k (ie, 1024) not being a multiple of 45, the final file's size will be adjusted to the greatest multiple of 45 smaller than the file's size (in bytes). Options: ~~~~~~~~ -t ............ interpret the input file/pipe as ASCII, rather than binary (the default). -b ............ interpret the input file/pipe as binary (default). -q ............ do not produce information text header Example: $ xencode speech.dat speech.uue 10 ~~~~~~~~ If speech.dat is 103424 bytes long, this will convert it into 11 (ASCII) files, each being 14336 bytes long, named speech.uue,speech01.uue, ... , speech10.uue. The size of the last one will in general be smaller than the other files (because in general the file length is not an integer multiple of 45, the "magic number" used by the uuencode algorithm). Variables: ~~~~~~~~~~ in input file; out output file; blk block size; Exit values: ~~~~~~~~~~~~ -1 Wrong parameters 0 Success (all but VAX/VMS) 1 Success (only VAX/VMS) 2 Error opening input file 3 Error opening output file 4 Error in block size specs Compilation under: ~~~~~~~~~~~~~~~~~~ TurboC: tcc xencode MS-C: cl xencode VAX-C: cc xencode link xencode SunOS: cc -o xencode xencode.c Gnu-C: gcc -o xencode xencode.c Author: Simao Ferraz de Campos Neto -- CPqD/Telebras ~~~~~~~ <tdsimao@venus.cpqd.ansp.br> History: ~~~~~~~~ 01.Aug.91 1.00 1st version to UGST <tdsimao@cpqd.ansp.br> 27.Aug.91 1.10 1024 changed by 1024l in line that calculates the number of bytes per .uue file, in the case of partition of encoded file into several pieces. <tdsimao@cpqd.ansp.br> 05.Jun.92 1.20 Added function to put text information on uuencoded file and parts on the total number of parts and how they shall be named. <tdsimao@cpqd.ansp.br> 21.Jul.93 1.30 Strips path from file name for the output file. <tdsimao@cpqd.ansp.br> 25.Sep.93 2.00 Calculate CRC for the input file and save it, incrementally for each part. Included "-t" option for safe encoding of text files. <tdsimao@cpqd.ansp.br> 23.May.95 2.01 Added \n\n before %XENCODE-INFO, to avoid problems with some e-mailers. <simao@ctd.comsat.com> 25.Sep.95 2.10 Encoded file does not have ' ' but '`' instead. Cleaned for better compilation. Added extra header instruction message when original file is .ZIP. Added option for having user's email in message instead of my email (coordinated with the makefile). Max filesizes specified in command line now reflect the size of the output file parts, not the chuncks of the input file (an old bug corrected!) <simao@ctd.comsat.com> 26.Feb.97 2.11 Added command line option to supress printing text header on how to uudecode, etc. <simao>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*//* Version number for XENCODE */#define XENCODE 211/* General includes */#include "ugstdemo.h" /* UGST demo macros - the 1st include */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>/* System-dependent includes */#if defined(VMS)#include types#include stat#else#include <sys/types.h>#include <sys/stat.h>#endif/* DEFINITION FOR SMART PROTOTYPES */#ifndef ARGS#if defined(MSDOS) || defined(VMS)#define ARGS(x) x#else /* Unix: no parameters in prototype! */#define ARGS(x) ()#endif#endif /* ARGS *//* General defines */#define MAX_LONG 2147483647#define NO 0#define YES 1/* Defines for CRC routine */#define W 16 /* CRC width */#define WTYPE unsigned short /* Basic data type */#define B 8 /* the number of bits per char */#ifndef USER_NAME#define USER_NAME (char *)NULL /* "<simao@ctd.comsat.com>" OR your user name */#endif/* Local function prototypes */void display_usage ARGS((void));int encode ARGS((FILE *in, FILE *out, long charno));int fr ARGS((FILE *fd, char *buf, int cnt));int get_mode ARGS((FILE *fp));char *get_extension ARGS((char *ext, char *full_name, int max_length));char *get_root ARGS((char *root, char *full_name));char *xcode_index ARGS((register char *sp, register char c));int outenc ARGS((char *p, FILE * f));void put_info ARGS((FILE * out, char *ori_file, char *root, char *ext, char mode, int filno));WTYPE updcrc ARGS((WTYPE icrc, unsigned char *icp, int icnt, WTYPE *crctab, char swapped));/* ENC is the basic 1 character encoding function to make a char printing */char c_global;#define ENC(c) ((c_global=(((c) & 077) + ' '))==' '?'`':c_global)/* Macros related to crc calculations */#define get_ccitt_crc(crc,buf,n) updcrc(crc, buf, n, crctab_ccitt, 0)#define get_arc_crc(crc,buf,n) updcrc(crc, buf, n, crctab_arc, 1)#define get_xmodem_crc(crc,buf,n) updcrc(crc, buf, n, crctab_xmodem, 1)/* Global variables related to crc calculations */WTYPE crc_a = 0, crc_c = 0, crc_x = 0;int init_crc_a = 0L, init_crc_c = -1L, init_crc_x = 0L;/* ================================================== */int main(argc, argv) int argc; char *argv[];{ FILE *in, *out; long blk = MAX_LONG; int filno, i; int input_is_file = YES; int output_is_file = YES; char root[120], ext[5], src[120], this_file[120], next_file[120]; char *get_root(), *get_extension(), mode_is_binary = YES, quiet=0; struct stat inpfil;#ifdef VMS static char mrs[15] = "mrs=512"; /* for correct mrs in VMS environment */#endif /* Check if 1st par. is an option */ while (argc > 1 && argv[1][0] == '-' && strlen(argv[1]) > 1) if (strcmp(argv[1], "-t") == 0) { /* set mode as text */ mode_is_binary = 0; /* Move argv over the option to the next argument */ argc--; argv++; } else if (strcmp(argv[1], "-b") == 0) { /* set mode as binary */ mode_is_binary = 1; /* Move argv over the option to the next argument */ argv++; argc--; } else if (strcmp(argv[1], "-q") == 0) { /* Don't print progress indicator */ quiet = 1; /* Move argv over the option to the next argument */ argv++; argc--; } else if (strcmp(argv[1], "-?") == 0 || strstr(argv[1], "-help")) { /* Print help */ display_usage(); } else { fprintf(stderr, "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]); display_usage(); } /* Check arguments ... */ if (argc > 3) /* , then block size specified */ { blk = atol(argv[3]) * 1024l; blk -= blk % 45; /* blk is in bytes */ argc--; if (blk == 0) HARAKIRI("Bad max.size for encoded file was specified! \n", 4); } /* If 3 arguments, then output file specified */ if (argc > 2) { argc--; } else { out = stdout; /* output is not a file, but the std. output */ output_is_file = NO; } /* If 2 arguments, then input file specified */ if (argc > 1) { strcpy(src, argv[1]); if (mode_is_binary) in = fopen(src, RB); else in = fopen(src, RT); if (in == NULL) KILL(src, 2); argc--; } else { in = stdin; /* input is not a file, but the std. input */ input_is_file = NO; } /* Warns wrong usage */ if (argc != 1) display_usage(); /* Finds out the number of files to generate, filno */ if (input_is_file) { long tmp = blk * 3/4; fstat(fileno(in), &inpfil); /* Stat structure */ filno = inpfil.st_size / tmp; /* Number of files; */ if (inpfil.st_size % tmp != 0) /* Add one to avoid truncation */ filno++; } else filno = 1; /* only one file will be generated */ /* Remove path from input file name */ get_root(root, src); get_extension(ext, src, 4); strcpy(src, root); strcat(src, ext); /* Print info on screen when not a pipe/redirection */ if (output_is_file) { /* Displays blocking information */ if (filno > 1) { fprintf(stderr, " Input file will be broken"); fprintf(stderr, " in %3d files ", filno); fprintf(stderr, " of %ld bytes each.\n", blk); } /* Get the root of the file name (ie, name w/o extension) */ get_root(root, argv[2]); /* Get file name's extension */ get_extension(ext, argv[2], 4); /* Initializes this_file with the given output file name */ /* PS: this is the FIRST file; srips off the path! */ strcpy(this_file, root); strcat(this_file, ext); /* tell something ... */ if (input_is_file) fprintf(stderr, " Encoding %s into ", src); } /* Initialize crc calculations */ crc_a = init_crc_a; crc_c = init_crc_c; crc_x = init_crc_x; /* Process input file saving in blocks, as specified */ for (i = 0; i < filno; i++) { /* Mounts the next output file name, if any */ if (i < filno - 1 && output_is_file) { sprintf(next_file, "%s%02d%s\0", root, i + 1, ext); } else strcpy(next_file, "\0"); /* no next file! */ /* Opens output file */ if (output_is_file)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -