//**************************************************************************** // fotplib.cpp // Contains functions for handling one-time pad (OTP) files. // // Notice // Copyright ©1995-97, David R. Tribble. // // This source code is copyrighted. Distribution of this source code is // granted, provided that this copyright notice remains attached to the // source code, and that adequate acknowledgement is given to the // original author. // // History // 0.01 1995-05-03 dtribble. // First cut. // 1.00 1995-05-08 dtribble. // Works. // 1.01 1995-06-27 dtribble. // Renamed "fotplib.h" to "fotplib.hpp". // Identification #define ID_TITLE "FOTP" #define ID_DATE "1995-06-27" #define ID_VERS "1.01" #define ID_FILE __FILE__ #define ID_AUTH "David R. Tribble" #define ID_COMP __DATE__ " " __TIME__ static const char copyright[] = "Copyright ©1995-97, " ID_AUTH "."; static const char id[] = "@(#) " ID_DATE " " ID_VERS " " ID_FILE; static const char id_compile[] = "[" ID_TITLE " " ID_VERS ", " ID_DATE "] <" ID_COMP ">"; // System includes #include #include #include #include // Local includes #include "osdefs.h" #include "debug.h" #include "fotplib.hpp" #if !DEBUG #undef DL #define DL(e) (0) #endif //---------------------------------------------------------------------------- // otp_file::otp_file() // Constructor: Initialize OTP file control info. otp_file::otp_file() { // Init control info init(); } //---------------------------------------------------------------------------- // otp_file::otp_file() // Constructor: Initialize OTP file control info for file named `fname'. otp_file::otp_file(const char *fname) { int err; // Init control info init(); // Open file err = open(fname); } //---------------------------------------------------------------------------- // otp_file::~otp_file() // Destructor: Close OTP file control info. otp_file::~otp_file() { int err; // Close file err = close(); // Clear OTP control struct o_magic = ~OTP_MAGIC; o_vers = ~OTP_VERS; } //---------------------------------------------------------------------------- // otp_file::init() // Initialize OTP file control info. void otp_file::init() { // Init control info o_magic = OTP_MAGIC; o_vers = OTP_VERS; } //---------------------------------------------------------------------------- // otp_file::open() // Open OTP file with name `fname'. int otp_file::open(const char *fname) { int err; // Check args if (fname == NULL) { err = EFAULT; goto fail; } if (fname[0] == '\0') { err = EINVAL; goto fail; } // Init OTP control struct init(); o_fname = strdup(fname); o_off = 0; // Open OTP file o_fp = fopen(fname, "rb"); if (o_fp == NULL) { // Can't open/read file err = errno; goto fail; } return 0; fail: // Failure, clean up if (o_fp != NULL) { fclose(o_fp); o_fp = NULL; } if (o_fname != NULL) { free((char *) o_fname); o_fname = NULL; } errno = err; return -1; } //---------------------------------------------------------------------------- // otp_file::close() // Close OTP file. // // Caveats // This OTP file must have been previously opened by otp_file::open(). int otp_file::close() { // Check this file if (o_magic != OTP_MAGIC) { errno = EINVAL; return -1; } if (o_vers/100 != OTP_VERS/100) { errno = EINVAL; return -1; } // Close the file if (o_fp != NULL) { fclose(o_fp); o_fp = NULL; } else errno = EBADF; // Deallocate stuff if (o_fname != NULL) { free((char *) o_fname); o_fname = NULL; } // Clear OTP control struct memset(o_data, 0, sizeof(o_data)); return 0; } //---------------------------------------------------------------------------- // otp_file::seek() // Reposition the OTP file pointer to byte number `off'. // // Caveats // This OTP file must have been previously opened by otp_file::open(). int otp_file::seek(long off) { int err; int b; int cnt; // Check this file if (o_magic != OTP_MAGIC) { errno = EINVAL; return -1; } if (o_vers/100 != OTP_VERS/100) { errno = EINVAL; return -1; } if (o_fp == NULL) { errno = EBADF; return -1; } // Seek to new file position if (fseek(o_fp, off, SEEK_SET) != 0) { // Can't seek, errno is set return -1; } // Save current position o_off = ftell(o_fp); return 0; } //---------------------------------------------------------------------------- // otp_file::readblk() // Read the next data block from the OTP file. // // Caveats // This OTP file must have been previously opened by otp_file::open(). int otp_file::readblk() { int err; int b; int cnt; // Check this file if (o_magic != OTP_MAGIC) { errno = EINVAL; return -1; } if (o_vers/100 != OTP_VERS/100) { errno = EINVAL; return -1; } if (o_fp == NULL) { errno = EBADF; return -1; } // Read a block of data for (cnt = 0; cnt < sizeof(o_data); cnt++) { retry: // Read a single data byte b = getc(o_fp); // Check for end of file if (b == EOF) { // End of file, wrap around to start of file rewind(o_fp); // Read a new byte b = getc(o_fp); if (b == EOF) { // File is empty, or contains only zero bytes err = ENOENT; goto fail; } } // Check for suitable data byte if (b == 0x00) goto retry; // Add data byte to data block o_data[cnt] = b; } // Get current file position o_off = ftell(o_fp); return 0; fail: // Failure errno = err; return 0; } // End fotplib.cpp