home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
hamradio
/
7plus202.zip
/
7PL2SRC.LZH
/
DECODE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-11
|
16KB
|
569 lines
#include "7plus.h"
#include "globals.h"
/*
*** First decode. If there already are CORs for that file, try correcting
*** afterwards.
***
*/
int control_decode (char *name)
{
int i, cor_exists;
char newname[MAXPATH];
i = cor_exists = 0;
*_ext = EOS;
fnsplit (name, _drive, _dir, _file, _ext);
sprintf (newname, "%s%s%s.cor", _drive, _dir, _file);
if (!test_exist (newname))
cor_exists = 1;
i = decode_file (name, cor_exists);
if ((i == 11 || i == 19) && cor_exists)
return (correct_meta (newname, 1));
return (i);
}
/*
*** decode a file. create error report, if errors detected.
***
***
*/
int decode_file (char *name, int flag)
{
struct m_index index;
FILE *in, *out;
int part, _part, parts, _parts, _parts0;
int c_line, c_line2, f_lines, blocklines;
int defect, rest, length, hcorrupted, ignored;
uint csequence, crc;
long binbytes, _binbytes, lines, rebuilt;
ulong ftimestamp, line;
char rline[81], *p, dummi[20], dummi2[81];
char inpath[MAXFPATH], indexfile[MAXPATH], metafile[MAXPATH];
char filename[13], srcname[MAXPATH], orgname[MAXFNAME];
char orgname2[66], destname[13];
register i, j;
*orgname = EOS;
in = out = NULLFP;
hcorrupted = ignored = 0;
ftimestamp = 0UL;
/* Isolate input-path and filename */
fnsplit (name, _drive, _dir, _file, _ext);
sprintf (inpath, "%s%s", _drive, _dir);
build_DOS_name (_file);
build_DOS_name (_ext);
_file[8] = _ext[3] = EOS;
/* Make up names for the meta- and indexfile */
sprintf (metafile, "%s.7mf", _file);
sprintf (indexfile, "%s.7if", _file);
if (!test_exist (metafile))
{
printf ("\007Metafile '%s' already exists.\n", metafile);
return (19);
}
/* Initialize index-info */
*index.filename = *index.full_name = EOS;
index.length = index.timestamp = 0UL;
index.splitsize = 0;
for (i=0;i<8160;i++)
index.lines_ok[i] = 0;
/* Find out, if it's a splitted file */
parts = 2;
sprintf (srcname, "%s%s.p01", inpath, _file);
if (test_exist (srcname))
{
parts = 1;
sprintf (srcname, "%s%s.7pl", inpath, _file);
if (test_exist (srcname))
{
sprintf (srcname, "%s.7pl/p01", _file);
printf (cant, srcname);
return (2);
}
}
/* Open input file */
in = fopen (srcname, OPEN_READ_BINARY);
/* Set I/O-buffering */
setvbuf (in, NULL, _IOFBF, buflen);
printf ("\n-----------\nDecoding...\n-----------\n\n");
defect = _parts0 = rest = length = 0;
lines = rebuilt = 0L;
/* Loop for number of parts. */
for (part = 1; part < parts +1; part++)
{
if (part == 256)
{
printf ("\007\nMore than 255 parts not allowed. Break.\n");
kill_dest (in, out, metafile);
return (8);
}
/* If more than 1 part, generate filename for messages and handling. */
if (parts == 1)
sprintf (filename, "%s.7pl", _file);
else
sprintf (filename, "%s.p%02x", _file, part);
/* If we're already at part > 1, generate filename for next part. */
if (part != 1)
{
sprintf (srcname, "%s%s", inpath, filename);
if (!(in = fopen (srcname, OPEN_READ_BINARY)))
{
printf ("\007\n'%s': Not found. Break.\n", srcname);
printf ("\nYou must have all parts to be able to decode!\n");
printf (" ===\n");
printf ("Get the missing files and try again.\n");
kill_dest (in, out, metafile);
return (2);
}
setvbuf (in, NULL, _IOFBF, buflen);
}
/* Read, until starting line is found. */
while ((p = my_fgets (rline, 80, in)) != NULL)
{
if (!strncmp (rline, " go_7+. ", 7))
break;
}
/* p == NULL? then no starting line found. File no good. */
if (!p)
{
printf ("\007'%s': 7PLUS-startline ", filename);
printf ("not found. Break.\n");
kill_dest (in, out, metafile);
return (3);
}
if (!mcrc (rline, 0))
rebuild (rline, 1);
/* Check if file went trough 7bit channel */
if (!strstr (rline, "\xb0\xb1"))
{
printf ("\007\n'%s':\nBit 8 has been stripped! Can't decode.\n", filename);
printf ("Please check all settings of your terminal and tnc regarding 8 bit transfer.\n");
printf ("You will have to re-read '%s' from the mailbox\n", filename);
printf ("after having corrected the settings.\n");
kill_dest (in, out, metafile);
return (9);
}
/* Get info from 7PLUS header */
if(sscanf (rline+8, "%d %s %d %s %ld %s %s %s %s %s",
&_part, dummi, &_parts, destname,
&binbytes, dummi, dummi2, dummi, dummi, dummi) != 10)
hcorrupted = 1;
blocklines = get_hex (dummi2);
strlwr (destname); /* Convert to lower case */
/* Set number of lines in this file */
f_lines = blocklines;
if (_part == _parts)
f_lines = (int) (((binbytes + 61) / 62) % blocklines);
if (!f_lines)
f_lines = blocklines;
f_lines--;
if (strlen (dummi) == 5)
if (!mcrc(rline, 0))
hcorrupted = 1;
if (!hcorrupted)
{
if (_part == 1)
{
_parts0 = _parts;
strcpy (index.filename, destname);
index.length = binbytes;
index.splitsize = blocklines;
}
if (_parts0 != _parts || stricmp(index.filename, destname) ||
index.length != binbytes || index.splitsize != blocklines)
hcorrupted = 1;
}
if (hcorrupted)
{
printf ("'%s': Header is corrupted. Can't continue.\n", filename);
kill_dest (in, out, metafile);
return(5);
}
/* If first part, process filename, calculate how many valid binary bytes
are contained in last code line of last part, initialize index-info. */
if (_part == 1)
{
*orgname2 = EOS;
if (dummi[3] == '*')
{
my_fgets (rline, 80, in);
if (!mcrc (rline, 0))
{
printf ("\nExtended Filename corrupted. Using filename from header.\n");
strcpy (orgname2, index.filename);
}
else
sscanf (rline, "/%60[^/]", orgname2);
}
strcpy (orgname, index.filename);
if (extended == '*' && *orgname2)
strncpy (orgname, orgname2, (size_t)(MAXFNAME-1));
strcpy (index.full_name, orgname);
rest = (int) (binbytes % 62);
if (!rest)
rest = 62;
parts = _parts; /* Set number of parts to decode. */
}
/* Current file does not contain expected part */
if (_part != part)
{
printf ("\007'%s': File does not contain part %03d. Break.\n", filename, part);
kill_dest (in, out, metafile);
return (4);
}
/* If first part, open metafile for writing. */
if (part == 1)
{
out = fopen (metafile, OPEN_WRITE_BINARY);
setvbuf (out, NULL, _IOFBF, buflen); /* As always, bufferize */
printf ("File Pt# of# Errors Rebuilt Status\n");
progress (filename, part, parts, 0, 0, "decoding...");
}
c_line2 = -1;
/* Now decode this part */
do
{
/* Get a line from code file */
p = my_fgets (rline, 80, in);
/* If line starts with a space, check if it's the last line */
if (p && *rline == ' ')
if (!strncmp (rline, " stop_7+.", 8))
{
/* Get timespamp */
if (!ftimestamp && strchr (rline, '['))
{
if (!mcrc (rline, 0))
{
progress (filename, part, parts, lines, rebuilt, "### rebuilding a line ###");
rebuild (rline, 2);
progress (filename, part, parts, lines, rebuilt, "decoding...");
}
if (mcrc (rline, 0))
{
char dummy[30];
if (sscanf (rline, " stop_7+. %s [%X]",
dummy, &ftimestamp) != 2)
ftimestamp = 0UL;
}
index.timestamp = ftimestamp;
}
p = NULL; /* Last line, set end indicator */
}
if (p)
{
/* Calculate CRC */
csequence = 0;
for (i=0; i<64; i++)
csequence = crctab[csequence>>8] ^ (((csequence&255)<<8) |
(byte)p[i]);
csequence &= 0x3fff; /* strip calculated CRC to 14 bits */
/* Get crc from code line */
crc_n_lnum (&crc, &c_line, p);
if (csequence != crc)
{
progress (filename, part, parts, lines, rebuilt, "### rebuilding a line ###");
if (!rebuild (p, 0))
{
ignored++; /* Incorrect CRC. Ignore line. */
continue;
}
rebuilt++;
progress (filename, part, parts, lines, rebuilt, "decoding...");
crc_n_lnum (&crc, &c_line, p);
}
/* Number of valid binary bytes in this line. If it's the last line
of the last part, set it to the number precalculated earlier */
length = 62;
if (c_line == f_lines && part == parts)
length = rest;
}
/* If file ends prematurely, set current line number to number of
lines in this part, so that the missing lines can be protocolled. */
if (!p && f_lines != c_line)
c_line = f_lines+1;
/* If current line number is greater than previous one -> ok */
if (c_line > c_line2)
{
/* Difference is greater than 1, then line(s) must be missing. */
if (c_line2 != c_line-1)
{
defect = 1;
/* Loop for number of missing or corrupted lines */
for (i = c_line2+1; i < c_line; i++)
{
progress (filename, part, parts, lines, rebuilt, "decoding...");
lines++; /* Number of missing or corrupted lines. */
length = 62;
if (i == f_lines && part == parts)
length = rest;
line = (long)(part-1)*index.splitsize +i;
index.lines_ok[(int)(line>>4)] += 1U << (uint)(line&15);
/* Write fill-bytes into metafile */
for (j=length;j;j--)
my_putc ( 0, out);
if (length < 62 || i == f_lines)
length = 0;
}
}
decode_n_write (out, rline, length);
c_line2 = c_line; /* Memorize current line number */
}
}
while (p); /* Loop until current code file ends */
progress (filename, part, parts, lines, rebuilt, "decoding...");
fclose (in);
}
progress (filename, part-1, parts, lines, rebuilt, "done...");
index.lines_left = lines;
/* Get size of metafile */
_binbytes = ftell (out);
if (out)
fclose (out);
if (defect) /* write index-file and error report */
w_index_err (&index, 0);
else
{
if (_binbytes == binbytes)
{
test_file (NULLFP, orgname, 1, MAXFNAME-1);
replace (orgname, metafile, ftimestamp);
printf ("\n");
if (autokill)
kill_em (_file, inpath, (parts==1)?"7pl":"p", "cor", "c", "err", "e");
printf ("\nDecoding successful! '%s', %ld bytes.\n",
orgname, binbytes);
return (0);
}
}
printf ("\n");
if (!flag)
{
printf ("\nDecoding of '%s' not successful.\n", orgname);
if (index.lines_left > (index.length/620L))
{
printf ("\nWARNING:\n========\n");
printf ("More than 10%% of all lines are corrupted! Are you sure, your communications\n");
printf ("programm is set correctly to handle 7PLUS files (character conversion ect..)?\n");
printf ("Maybe you didn't get parts of the files because of link failures?\n");
printf ("Of course, the cause may lie with the originating source...\n\n");
}
}
if (_binbytes != binbytes)
{
printf ("\nDecoded file has wrong length! Disk full?\n");
printf ("This error should never have occured.....I hoped...\n");
return (1);
}
else
if (autokill)
kill_em (_file, inpath, (parts==1)?"7pl":"p", NULL, NULL, NULL, NULL);
return (11);
}
/*
***
*** split up longs into 2 * 31 binary bytes and write to file.
***
*/
void decode_n_write (FILE *out, char *p, int length)
{
static ulong after[16], *af;
static int i, j, k;
/* Re-arrange data-characters to 2*8 longs containing 31 bits each.*/
for (i=k=0; i<64; i++)
{
if ((i&3) == 3)
{
after[k] = 0L;
for (j=i;j>(i-4);j--)
after[k] = after[k] * 216L + decode[(byte)p[j]];
k++;
}
}
af = after;
for (i=0; i<2; i++, af+=8)
{
/* Re-arrange to 2*8 longs containing 32 bits.
7th and 15th long only contain 24 valid bits. */
af[0] = (af[0] << 1) | (af[1] >> 30);
af[1] = (af[1] << 2) | (af[2] >> 29);
af[2] = (af[2] << 3) | (af[3] >> 28);
af[3] = (af[3] << 4) | (af[4] >> 27);
af[4] = (af[4] << 5) | (af[5] >> 26);
af[5] = (af[5] << 6) | (af[6] >> 25);
af[6] = (af[6] << 7) | (af[7] >> 24);
af[7] = (af[7] << 8);
for(j=0; j<8; j++)
{
for (k=24;k;k-=8)
{
if (!length)
break;
length--;
my_putc ((int) (af[j] >> k), out);
}
if (j == 7 || !length)
break;
length--;
my_putc ((int) af[j], out);
}
}
}
/*
*** Write indexfile and error report
***
***
*/
void w_index_err (struct m_index *index, int flag)
{
FILE *ifile;
char filename[13];
if (!flag)
{
fnsplit (index->filename, NULL, NULL, filename, NULL);
#ifndef _CHSIZE_OK
strcat (filename, ".7ix");
ifile = fopen (filename, OPEN_WRITE_BINARY);
#else
strcat (filename, ".7mf");
ifile = fopen (filename, OPEN_RANDOM_BINARY);
#endif
write_index (ifile, index, 0);
fclose (ifile);
}
fnsplit (index->filename, NULL, NULL, filename, NULL);
strcat (filename, ".err");
ifile = fopen (filename, OPEN_WRITE_TEXT);
strupr (filename);
fprintf (ifile, " go_text. %s%s", filename, delimit);
strcpy (filename, index->filename);
strupr (filename);
fprintf (ifile, "7PLUS error report: %s %03X", filename, index->splitsize);
if (strcmp (index->full_name, index->filename))
fprintf (ifile, " /%s/", index->full_name);
fprintf (ifile, " %ld%s", index->length, delimit);
write_index (ifile, index, 1);
fprintf (ifile, "[%lX]%s00%s", index->timestamp, delimit, delimit);
fprintf (ifile, "________%s stop_text.%s", delimit, delimit);
if (endstr)
fprintf (ifile, "%s%s", endstr, delimit);
fclose (ifile);
fnsplit (index->filename, NULL, NULL, filename, NULL);
strcat (filename, ".err");
crc_file (filename, "7P", "00\n", 0);
}
/*
*** If an error report has been accidentally erased, it can be recreated
*** using the information in the indexfile, respectively metafile.
*** (depends on _CHSIZE_OK)
*/
int make_new_err (char *name)
{
struct m_index index;
FILE *rfile;
printf ("-----------------------\nRecreating error report\n-----------------------\n\n");
/* Open meta file */
if (!(rfile = fopen (name, OPEN_READ_BINARY)))
{
printf (cant, name);
return (2);
}
/* read index info into struct index */
if (read_index (rfile, &index))
{
printf ("\007Invalid index info.\n");
return (7);
}
fclose (rfile);
w_index_err (&index, 1);
printf ("Error report has been recreated from '%s'.\n", name);
return (0);
}
/*
*** Progress indication
***
***
*/
void progress (char *filename, int part, int of_parts, long errors,
long rebuilt, char *status)
{
printf ("%-12s %3d %3d %6ld %6ld %-30s\r",
filename, part, of_parts, errors, rebuilt, status);
fflush (stdout);
}