home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
MISC
/
MNLDOS.ZIP
/
src
/
lsttool.c
< prev
next >
Wrap
C/C++ Source or Header
|
2004-07-21
|
13KB
|
439 lines
/* $Id: lsttool.c,v 1.12 2004/07/20 04:29:47 fido Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "makenl.h"
#include "fileutil.h"
#include "crc16.h"
#include "lsttool.h"
#include "msg.h"
#ifdef MALLOC_DEBUG
#include "rmalloc.h"
#endif
#ifdef DMALLOC
#include "dmalloc.h"
#endif
long ARCThreshold = 10000;
long DIFFThreshold = 16666;
char ArcExt[4] = "a"; /* Let's add some default values */
char ArcCopyCmd[20] = "arc a";
char ArcMoveCmd[20] = "arc m";
char ArcOpenCmd[20] = "arc ew";
#if 0
static unsigned int arcparas = 0x4000; /* 256 KBytes */
#endif
static unsigned short DiffCRC;
static char DiffLine[linelength];
static int EditCount;
static int AddLines;
static int dodiffline(int checktop, FILE * oldFILE, FILE * diffFILE);
int makearc(char *filename, int move)
{
char ext[MYMAXEXT];
char name[MYMAXFILE];
char fullpath[MYMAXPATH];
char cmdlinebuf[124];
char arccommand[ARCCMDMAX];
if (filesize(filename) <= ARCThreshold || ARCThreshold == -1)
return 0;
strcpy(fullpath, filename);
myfnsplit(filename, NULL, NULL, name, ext);
if (toupper(ext[0]) == 'D') /* Autogenerated diff - can always be
moved */
{
ext[1] = 'd';
strcpy(arccommand, ArcMoveCmd); /* move instead of add */
}
else
strcpy(arccommand, (move < 1) ? ArcCopyCmd : ArcMoveCmd);
ext[0] = ArcExt[0];
myfnmerge(fullpath, NULL, OutDir, name, ext);
os_filecanonify(fullpath);
os_filecanonify(filename);
fprintf(stdout, "\nCreating archive \"%s\" containing \"%s\"\n",
fullpath, filename);
sprintf(cmdlinebuf, "%s %s", fullpath, filename);
if (os_spawn(arccommand, cmdlinebuf) != 0)
die(0xFD, 1, "Unable to create archive \"%s\"", fullpath);
strcpy(filename, fullpath);
return 1;
}
/* Returns:
1 if list is unchanged,
0 else
*/
int installlist(char *filename, char *extbfr)
{
char *outext;
char *oldstart;
FILE *oldFILE = NULL;
char *tmpstart;
int weeksold = 0;
FILE *tmpFILE = NULL;
int unchanged = 0;
char (*extptr)[MYMAXEXT];
char tmpname[linelength];
char tmpline[linelength];
char oldline[linelength];
for (extptr = OldExtensions; extptr < OldExtensions + 3; extptr++)
{
outext = getext(extbfr, OutFile) ? NULL : *extptr;
myfnmerge(filename, NULL, OutDir, OutFile, outext);
oldFILE = fopen(filename, "r");
if (oldFILE != NULL || extbfr[0] != 0)
break;
weeksold++;
}
swapext(tmpname, filename, "$$$");
if (oldFILE && OutDiff[0] == 0)
{
tmpFILE = fopen(tmpname, "r");
if (!tmpFILE)
die(254, 1, "Unable to open new list \"%s\" for input\n",
tmpname);
if (fgets(tmpline, linelength, tmpFILE)
&& fgets(oldline, linelength, oldFILE)
&& (tmpstart = strrchr(tmpline, ' ')) != NULL
&& (oldstart = strrchr(oldline, ' ')) != NULL)
while (!strcmp(oldstart, tmpstart))
{
tmpstart = fgets(tmpline, linelength, tmpFILE);
oldstart = fgets(oldline, linelength, oldFILE);
if (tmpstart == NULL || oldstart == NULL)
{
unchanged = 1;
break;
}
}
fclose(tmpFILE);
}
if (oldFILE)
fclose(oldFILE);
if (unchanged)
{
unlink(tmpname);
if (extbfr[0] == 0) /* generic filename given */
{
if (weeksold != 0)
{
swapext(tmpname, filename, OldExtensions[0]);
rename(filename, tmpname);
strcpy(filename, tmpname);
}
for (extptr = OldExtensions + weeksold + 1;
extptr < OldExtensions + 3; extptr++)
{
swapext(tmpname, filename, *extptr);
unlink(tmpname);
}
}
fputs("Unchanged output file will NOT be submitted.\n", stdout);
}
else
{
if (weeksold != 0)
swapext(filename, tmpname, OldExtensions[0]);
else
unlink(filename);
rename(tmpname, filename);
}
return unchanged;
}
static int ApplyDiff(FILE * oldFILE, char *diffname, char *outname)
{
int firststatus;
char *crcptr; /* 0x02 */
FILE *outFILE; /* 0x04 */
FILE *diffFILE; /* 0x06 */
unsigned short newcrc; /* 0x08 */
diffFILE = fopen(diffname, "r");
if (!diffFILE)
die(254, 1, "Unable to open %s for input", diffname);
outFILE = fopen(outname, "wb");
if (!outFILE)
die(254, 1, "Unable to create %s", outname);
firststatus = dodiffline(1, oldFILE, diffFILE);
if (firststatus == 0) /* diff fits */
{
/* DiffLine now contains the new header including CRC */
cutspaces(DiffLine);
strcat(DiffLine, "\r\n");
crcptr = DiffLine + strlen(DiffLine);
while (*(--crcptr) != ' ');
getnumber(crcptr + 1, (int *)&newcrc);
fputs(DiffLine, outFILE);
DiffCRC = 0;
while (dodiffline(0, oldFILE, diffFILE) == 0)
{
cutspaces(DiffLine);
strcat(DiffLine, "\r\n");
fputs(DiffLine, outFILE);
DiffCRC = CRC16String(DiffLine, DiffCRC);
}
putc('\x1A', outFILE);
}
fclose(outFILE);
fclose(oldFILE);
fclose(diffFILE);
if (firststatus == -1
|| CRC16DoByte((char)(newcrc & 0xFF),
CRC16DoByte((char)(newcrc >> 8), DiffCRC)) != 0)
{
unlink(outname);
return -1;
}
return 0;
}
static int dodiffline(int checktop, FILE * oldFILE, FILE * diffFILE)
{
char topline[linelength];
if (checktop)
{
EditCount = 0;
if (fgets(topline, linelength, diffFILE) == NULL)
return -1;
}
while (EditCount == 0)
{
if (fgets(DiffLine, linelength, diffFILE) == NULL)
/* return 1 if call fails - -1 if it works */
return 2 * !fgets(DiffLine, linelength, diffFILE) - 1;
getnumber(DiffLine + 1, &EditCount);
switch (DiffLine[0])
{
default:
return -1;
case 'A':
AddLines = 1;
break;
case 'C':
AddLines = 0;
break;
case 'D':
if (EditCount)
do
{
if (fgets(DiffLine, linelength, oldFILE) == NULL)
return -1;
if (checktop)
{
if (strcmp(DiffLine, topline))
return -1;
checktop--;
}
}
while (--EditCount);
break;
}
}
if (fgets(DiffLine, linelength, (AddLines ? diffFILE : oldFILE)) ==
NULL)
return -1;
EditCount--;
return 0;
}
static int searchlistfile(FILE ** someptr, const char *path,
char *foundfile, char *name, char *ext,
int unpackedonly);
/* Returns:
-1 : error
0 : not found
>0 : found, next search for same list should start here
*/
int
openlist(FILE ** listFILEptr, char *filename, char *foundfile, int where,
int mustbenew)
{
int status;
char ext[MYMAXEXT];
char name[MYMAXFILE + MYMAXEXT];
myfnsplit(filename, NULL, NULL, name, ext);
switch (where)
{
default:
return 0;
case SEARCH_UPLOAD:
status =
searchlistfile(listFILEptr, UploadDir, foundfile, name, ext,
0);
if (status == 1)
return SEARCH_MAILFILE;
if (status != 0)
return -1;
/* FALLTHROUGH */
case SEARCH_MAILFILE:
status =
searchlistfile(listFILEptr, MailfileDir, foundfile, name, ext,
0);
if (status == 1)
return SEARCH_UPDATE;
if (status != 0)
return -1;
/* FALLTHROUGH */
case SEARCH_UPDATE:
if (mustbenew)
return 0;
status =
searchlistfile(listFILEptr, UpdateDir, foundfile, name, ext,
1);
if (status == 1)
return SEARCH_MASTER;
if (status != 0)
return -1;
case SEARCH_MASTER:
if (mustbenew)
return 0;
status =
searchlistfile(listFILEptr, MasterDir, foundfile, name, ext,
1);
if (status == 1)
return SEARCH_NOWHERE;
if (status != 0)
return -1;
return 0;
}
}
/* Returns:
-1: error
0: no matching file found
+1: file found and opened */
int
searchlistfile(FILE ** file, const char *path, char *foundfile, char *name,
char *ext, int unpackedonly)
{
struct _filefind f;
char fnamebuf[MYMAXDIR];
char cmdlinebuf[128];
char (*extptr)[MYMAXEXT];
char extbuf[MYMAXEXT];
char *findresult;
int searchwhere;
if (path[0] == 0)
return 0;
while (!(ext[0] == 0 && unpackedonly))
{
myfnmerge(foundfile, NULL, NULL, name, ext[0] ? ext : "*");
findresult = os_findfile(&f, path, foundfile);
if (!findresult)
return 0;
getext(extbuf, findresult);
myfnmerge(foundfile, NULL, path, findresult, NULL);
os_deslashify(foundfile);
if ((ext[0] == 0) && (extbuf[0] == ArcExt[0])) /* ARCed file */
{
myfnmerge(fnamebuf, NULL, path, NULL, NULL);
os_deslashify(fnamebuf);
fprintf(stdout, "Attempting to unpack archive \"%s\"\n",
foundfile);
sprintf(cmdlinebuf, "%s %s", foundfile, fnamebuf);
if (os_spawn(ArcOpenCmd, cmdlinebuf) != 0)
{
fprintf(stderr, "Unable to unpack archive \"%s\". ",
foundfile);
WorkFile = os_file_getname(foundfile);
os_filecanonify(WorkFile);
*file = OpenMSGFile(NotifyAddress, NULL);
if (*file != NULL)
{
fprintf(*file, "Unable to unpack archive \"%s\". ",
WorkFile);
fputs("Please resubmit it.", *file);
CloseMSGFile(1);
}
}
unlink(foundfile);
}
else if (ext[0] == 0 && toupper((unsigned char)extbuf[0]) == 'D') /* DIFFed
file
*/
{
fprintf(stdout, "Attempting to apply difference file \"%s\"\n",
foundfile);
extptr = OldExtensions;
do
{
swapext(findresult, name, *extptr);
searchwhere = SEARCH_UPDATE;
while (searchwhere != 0)
{
searchwhere =
openlist(file, findresult, fnamebuf, searchwhere,
0);
if (searchwhere)
{
myfnmerge(fnamebuf, NULL, path, name,
OldExtensions[0]);
if (ApplyDiff(*file, foundfile, fnamebuf) == 0)
goto out_of_loops;
}
}
extptr++;
}
while (extptr < OldExtensions + 3);
out_of_loops:
unlink(foundfile);
if (searchwhere == 0)
{
fprintf(stdout,
"Unable to apply difference file \"%s\". ",
foundfile);
WorkFile = os_file_getname(foundfile);
os_filecanonify(WorkFile);
*file = OpenMSGFile(NotifyAddress, NULL);
if (*file)
{
fprintf(*file,
"Unable to apply difference file \"%s\". ",
WorkFile);
fputs("Please submit your full update file.", *file);
*file = CloseMSGFile(1);
}
}
}
else
goto justthisfile;
}
for (extptr = OldExtensions; extptr < OldExtensions + 3; extptr++)
{
myfnmerge(foundfile, NULL, NULL, name, *extptr);
if (os_findfile(&f, path, foundfile) != NULL)
{
myfnmerge(foundfile, NULL, path, name, *extptr);
os_deslashify(foundfile);
justthisfile:
*file = fopen(foundfile, "r");
if (!*file)
return -1;
WorkFile = os_file_getname(foundfile);
os_filecanonify(WorkFile);
return 1;
}
}
return 0;
}