/**************************************************************************************************
$Header: /pub/cvsroot/yencode/src/support.c,v 1.10 2002/03/15 05:59:02 bboy Exp $
Copyright (C) 2002 Don Moore <bboy@bboy.net>
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: */
syntax highlighted by Code2HTML, v. 0.9.1