/************************************************************************************************** $Header: /pub/cvsroot/yencode/src/support.c,v 1.10 2002/03/15 05:59:02 bboy Exp $ Copyright (C) 2002 Don Moore 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **************************************************************************************************/ #include "y.h" extern int opt_overwrite; extern int opt_line_length; extern size_t opt_multipart_size; extern int opt_keep_paths; /* Strip paths from filenames? */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ YENCODE_AND_WRITE_BUFFER Writes a buffer to a file, encoding as it goes. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void yencode_and_write_buffer(FILE *out, const char *filename, const unsigned char *buf, size_t buflen) { crc32_t crc; register size_t ct; register int linect = 0; register unsigned char c; fprintf(out, "=ybegin line=%d size=%u name=%s\r\n", opt_line_length, buflen, filename); CRC_START(crc); for (ct = 0; ct < buflen; ct++) { c = buf[ct]; CRC_UPDATE(crc, c); c = YENCODE(c); if (YSHOULD_ESCAPE(c,linect,opt_line_length)) { fputc(c, out); c = YESCAPE(c); linect++; } fputc(c, out); linect++; if (linect >= opt_line_length) { fputc('\r', out); fputc('\n', out); linect = 0; } } if (linect) { fputc('\r', out); fputc('\n', out); } CRC_FINISH(crc); fprintf(out, "=yend size=%u crc32=%08x\r\n", buflen, crc); } /*--- yencode_and_write_buffer() ----------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ YENCFILE_DEFAULT_FILENAME If no filename was specified, this sets a default based on the first item in the YENCFILE. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ char * yencfile_default_filename(const char *filename, const char *default_filename, const char *extension) { static char outfile[PATH_MAX]; char name[PATH_MAX], *c; if (filename) strncpy(name, filename, sizeof(name)-1); else { strncpy(name, default_filename, sizeof(name)-1); if ((c = strrchr(name, '.'))) // Strip short extension if (c > (name + strlen(name)) - 6) *c = '\0'; } snprintf(outfile, sizeof(outfile), "%s%s", name, extension); return (outfile); } /*--- yencfile_default_filename() ---------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SFV_CONSTRUCT Constructs the SFV file data. Returns a buffer containing the data. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ unsigned char * sfv_construct(YENCFILE **y, int ysize) { unsigned char *buf = NULL; /* Output buffer */ time_t now = time(NULL); /* Current time */ char timebuf[80]; /* Buffer for date/time string */ const struct tm *tm; /* Broken down time */ int ct; /* Current position in `y' */ struct stat st; /* File info for input file */ tm = gmtime(&now); strftime(timebuf, sizeof(timebuf)-1, "%Y-%m-%d at %H:%M.%S %Z", tm); sdprintf(&buf, "; Generated by WIN-SFV32 v1.1a (%s %s for %s) on %s\r\n;\r\n", PACKAGE, VERSION, SYSTYPE && strlen(SYSTYPE) ? SYSTYPE : "Unknown OS", timebuf); for (ct = 0; ct < ysize; ct++) /* Output file sizes etc in comments */ if (!YSUPPORT_IS_SPECIAL(y[ct]->file_type) && y[ct]->ok && !stat(y[ct]->input_filename, &st)) { tm = gmtime(&st.st_mtime); strftime(timebuf, sizeof(timebuf)-1, "%H:%M.%S %Y-%m-%d", tm); sdprintf(&buf, "; %12lu %s %s\r\n", (unsigned long)st.st_size, timebuf, STRIP_PATH(y[ct]->input_filename)); } for (ct = 0; ct < ysize; ct++) /* Output checksums */ if (!YSUPPORT_IS_SPECIAL(y[ct]->file_type) && y[ct]->ok) sdprintf(&buf, "%s %08X\r\n", STRIP_PATH(y[ct]->input_filename), y[ct]->crc); return (buf); } /*--- sfv_construct() ---------------------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SFV_CREATE Creates an SFV file for the specified file set. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void sfv_create(const char *filename, YENCFILE **y, int ysize, const char *output_dir) { char *outbase, outfile[PATH_MAX]; /* Name of output file */ FILE *fp; /* Output file pointer */ unsigned char *buf = NULL; /* Output buffer */ outbase = yencfile_default_filename(filename, STRIP_PATH(y[0]->input_filename), ".sfv"); if (output_dir) snprintf(outfile, sizeof(outfile), "%s/%s.ync", output_dir, outbase); else snprintf(outfile, sizeof(outfile), "%s.ync", outbase); if (!(fp = open_output_file(outfile, opt_overwrite, NULL))) return; buf = sfv_construct(y, ysize); yencode_and_write_buffer(fp, outbase, buf, strlen(buf)); fclose(fp); free(buf); usermsg(NULL, outfile, 0, 0, _("SFV file created OK"), NULL); } /*--- sfv_create() ------------------------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CRC_CONSTRUCT Constructs the CRC file data. Returns a buffer containing the data. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ unsigned char * crc_construct(YENCFILE **y, int ysize) { unsigned char *buf = NULL; /* Output buffer */ int ct; /* Current position in `y' */ for (ct = 0; ct < ysize; ct++) /* Output checksums */ if (!YSUPPORT_IS_SPECIAL(y[ct]->file_type) && y[ct]->ok) sdprintf(&buf, "%s -- %08X\r\n", STRIP_PATH(y[ct]->input_filename), y[ct]->crc); return (buf); } /*--- crc_construct() ---------------------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CRC_CREATE Creates a CRC file for the specified file set. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void crc_create(const char *filename, YENCFILE **y, int ysize, const char *output_dir) { char *outbase, outfile[PATH_MAX]; /* Name of output file */ FILE *fp; /* Output file pointer */ unsigned char *buf = NULL; /* Output buffer */ outbase = yencfile_default_filename(filename, STRIP_PATH(y[0]->input_filename), ".crc"); if (output_dir) snprintf(outfile, sizeof(outfile), "%s/%s.ync", output_dir, outbase); else snprintf(outfile, sizeof(outfile), "%s.ync", outbase); if (!(fp = open_output_file(outfile, opt_overwrite, NULL))) return; buf = crc_construct(y, ysize); yencode_and_write_buffer(fp, outbase, buf, strlen(buf)); fclose(fp); free(buf); usermsg(NULL, outfile, 0, 0, _("CRC file created OK"), NULL); } /*--- crc_create() ------------------------------------------------------------------------------*/ /* vi:set ts=3: */