home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
OFFLINE
/
QWKTXT46.ZIP
/
QWKTXT46.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-25
|
14KB
|
467 lines
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <direct.h>
#include <dos.h>
#include <errno.h>
#include <process.h>
#include <stdlib.h>
#include <string.h>
#include "qwktxt46.h"
void _cdecl main(int argc, char **argv)
{
FILE *ifp, *ofp;
int i = 0, j;
int cn, Acc_confs;
char *sp;
char stuff[STUFF_SIZE];
char BBS_name[80];
char BBS_location[80];
char BBS_phone_number[25];
char Packet_date[12];
char Packet_time[9];
char User_name[25];
char temp[25];
char *unavailable = "Not provided.";
char fqpname[81]; /* fully qualified path name */
TotalMsgsInQWK = 0;
MsgsPerConference = 0;
printf("%c[2J",27);
printf("QWK2TXT %s QWK -> TXT converter\n", VERSION);
printf("Public Domain as of %s\n\n", REL_DATE);
if( (argc != 2) && (argc != 3) ) /* check for proper number of args */
{
printf("\n\tusage: qwktxt46 filename.qwk");
printf("\n\t -or- qwktxt46 filename.qwk P|U\n\n");
printf("\n\twhere: filename.qwk is your qwk file");
printf("\n\t P = use PKUNZIP.EXE");
printf("\n\t U = use UNZIP.EXE\n");
printf("\n\tNOTE: ONLY one of P or U may be used and if used, the");
printf("\n\t filename.qwk MUST be in .ZIP format. P or U is");
printf("\n\t not needed if the file is in another archive format.\n\n");
exit(1);
}
zipflag = toupper(argv[2][0]);
printf("Decompressing QWK file...One moment, please...\r");
if(mkdir("QWK$TMP") == -1)
{
printf("\n\tError: Can't create temporary subdirectory QWK$TMP.");
exit(1);
}
arctype = WhichArc(argv[1]);
switch(arctype)
{
case -1:
printf("\n\tFile %s not found.", argv[1]);
exit(1);
break;
case UNKNOWN:
printf("\n\tArchive method of %s is unknown.", argv[1]);
exit(1);
break;
case ARC:
chdir("QWK$TMP");
sprintf(fqpname, "arc x ..\\%s >nul", argv[1]);
break;
case ZOO:
chdir("QWK$TMP");
sprintf(fqpname, "zoo x ..\\%s >nul", argv[1]);
break;
case ARJ:
chdir("QWK$TMP");
sprintf(fqpname, "arj x ..\\%s >nul", argv[1]);
break;
case LHARC:
chdir("QWK$TMP");
sprintf(fqpname, "lharc x ..\\%s >nul", argv[1]);
break;
case LHA:
chdir("QWK$TMP");
sprintf(fqpname, "lha x ..\\%s >nul", argv[1]);
break;
case ZIP:
chdir("QWK$TMP");
if(zipflag == 'P')
sprintf(fqpname, "pkunzip ..\\%s >nul", argv[1]);
else if(zipflag == 'U')
sprintf(fqpname, "unzip ..\\%s >nul", argv[1]);
else
sprintf(fqpname, "pkunzip ..\\%s >nul", argv[1]);
break;
}
system(fqpname); /* decompress the file */
printf(" \n\n");
if ((ifp = fopen("control.dat", "r")) == NULL) /* open control.dat */
{
printf("\n\tRequired file CONTROL.DAT not found.");
exit(1);
}
if(fgets(stuff,STUFF_SIZE,ifp) != NULL) /* get BBS' name */
{
strip(stuff);
strcpy(BBS_name,stuff);
}
if(fgets(stuff,STUFF_SIZE,ifp) != NULL) /* get BBS' city/state */
{
strip(stuff);
if(stuff[0] == 0)
strcpy(BBS_location,unavailable);
else
strcpy(BBS_location,stuff);
}
if(fgets(stuff,STUFF_SIZE,ifp) != NULL) /* get BBS' phone number */
{
strip(stuff);
strcpy(BBS_phone_number,stuff);
}
fgets(stuff, STUFF_SIZE, ifp); /* toss sysop name into bit-bucket */
fgets(stuff, STUFF_SIZE, ifp); /* toss door reg. # and BBS ID too */
if(fgets(stuff,STUFF_SIZE,ifp) != NULL) /* get packet date & time */
{
strip(stuff);
strcpy(temp,stuff);
}
for(i=0; i<10; i++) /* strip packet date from string */
Packet_date[i] = temp[i];
Packet_date[10] = '\0';
for(i=11; i<19; i++) /* strip packet time from string */
Packet_time[i-11] = temp[i];
Packet_time[8] = '\0';
if(fgets(stuff,STUFF_SIZE,ifp) != NULL) /* get user's name */
{
strip(stuff);
strcpy(User_name,stuff);
}
for (i=0; i < 3; i++) /* Skip over Qmail menu filename, */
fgets(stuff, STUFF_SIZE, ifp); /* and two ASCII 0's */
fgets(stuff, STUFF_SIZE, ifp); /* get ASCII value of # of */
strip(stuff); /* conferences available */
Acc_confs = atoi(stuff); /* and convert it to int */
cn = i = 0;
for (;;) /* loop to identify all conferences */
{
if (!fgets(stuff, STUFF_SIZE, ifp))
break;
strip(stuff);
if (stuff[0] == 0)
break;
if (sscanf(stuff, "%d", &i) != 1) /* get conference number */
{ /* and convert to an int */
i = 1;
break;
}
if (!fgets(stuff, STUFF_SIZE, ifp)) /* get conference name */
{
printf("\n\tCorrupted conference name in CONTROL.DAT.");
exit(1);
}
strip(stuff);
confs[cn]._num = i;
confs[cn]._msgs = 0;
strcpy(confs[cn++]._name, byp(stuff));
}
if ((ofp = fopen("messages.txt", "w")) == NULL) /* open output file */
{
printf("\n\tUnable to open MESSAGES.TXT for output.");
exit(1);
}
sep(ofp); /* separate areas */
fprintf(ofp, " BBS Name: %s\n", BBS_name);
fprintf(ofp, " BBS Location: %s\n", BBS_location);
fprintf(ofp, "BBS Phone Number: %s\n", BBS_phone_number);
fprintf(ofp, " Packet Date: %s\n", Packet_date);
fprintf(ofp, " Packet Time: %s\n", Packet_time);
fprintf(ofp, " User Name: %s\n\n", User_name);
fprintf(ofp, "You have access to %d conference%s.\n", Acc_confs,
(Acc_confs == 1) ? "" : "s");
sep(ofp); /* separate info above from actual messages */
printf("Indexing conference: "); /* read *.NDX files and save that info */
for (i = 0; i < cn; i++)
confs[i]._msgs = nummsg(confs[i]._num);
putchar('\r');
for(i=0; i < 30; i++) /* get rid of "Indexing..." message */
putchar(' '); /* (only for aesthetics) */
fclose(ifp); /* finished with CONTROL.DAT so close it */
if ((ifp = fopen("messages.dat", "rb")) == NULL) /* open message packet */
{
printf("Unable to open required file MESSAGES.DAT.");
fclose(ofp);
exit(1);
}
if (readblk(ifp, stuff)) /* read in 1st record with Sparky's copyright */
{ /* abort if we can't read for some reason */
printf("\n\tCan't read Sparkware's copyright message in MESSAGES.DAT.");
fclose(ofp);
exit(1);
}
for (i = 0; i < cn; i++) /* main loop -- do for every conference */
{
printf("\rWorking on Conference %d [%s] ", i, confs[i]._name);
TotalMsgsInQWK += MsgsPerConference;
MsgsPerConference = 0; /* reset variable for next conference */
while (confs[i]._msgs--) /* as long as the conference has messages */
{
if (readhdr(ifp)) /* read the message header or abort if not found */
{
printf("\n\tCan't read message header in MESSAGES.DAT file.");
printf("\n\t\tConference: %d [%s]", i, confs[i]._name);
printf("\n\t\t Message #: %d", confs[i]._msgs);
fclose(ofp);
exit(1);
}
/* keep user's interest up by displaying useless info */
fprintf(ofp, "Conference: %s\n", confs[i]._name);
strncp(stuff, header._msg, 7);
fprintf(ofp, "Message: %u\n", atoi(stuff));
MsgsPerConference += 1; /* increment conference message count */
strncp(stuff, header._from, 25);
strip(stuff);
fprintf(ofp, "From: %s\n", stuff);
strncp(stuff, header._to, 25);
strip(stuff);
fprintf(ofp, "To: %s\t", stuff);
if( strcmp( stuff, User_name) == 0)
{
personal += 1;
if(header._private == 43) /* is message private and unread? */
{ /* flag message as private and personal */
fprintf(ofp, "[RECEIVER ONLY]\n");
}
else
{ /* flag message as public and personal */
fprintf(ofp, "[PUBLIC]\n");
}
}
else
fprintf(ofp, "\n");
strncp(stuff, header._subj, 25);
strip(stuff);
fprintf(ofp, "Subject: %s\n", stuff);
strncp(stuff, header._pass, 12);
strip(stuff);
fprintf(ofp, "Password: %s\n", stuff);
strncp(stuff, header._date, 8);
strncp(&stuff[20], header._time, 5);
fprintf(ofp, "Date: %s %s\n\n", stuff, &stuff[20]);
strncp(stuff, header._count, 6);
j = atoi(stuff); /* get # of 128-byte blocks in message */
while (--j) /* read in each block */
{
if (readblk(ifp, stuff))
{
fclose(ofp);
exit(1);
}
stuff[128] = 0;
if (j == 1)
strip(stuff);
for (sp = stuff; *sp; sp++)
if((unsigned char)*sp == 0xE3) /* if π found, output newline */
fprintf(ofp, "\n");
else
putc(*sp, ofp);
}
sep(ofp);
}
}
fclose(ofp); /* close text file messages.txt */
fclose(ifp); /* close binary file messages.dat */
printf("\n\nTotal Messages in %s: %u\n", argv[1], TotalMsgsInQWK);
system("copy messages.txt .. >nul");
erase("."); /* Erase all files in the temporary */
/* subdirectory - should work with */
/* DOS 3.3 and DOS 5.0 without having */
/* the query from COMMAND.COM */
chdir("..");
rmdir("QWK$TMP");
exit(0);
}
void strip(char *s) /* strip trailing whitespace from string s */
{
char *p;
p = s;
while (*p)
p++;
while (p > s && isspace(*--p))
*p = 0;
}
char *byp(char *s) /* bypass unwanted whitespace from string s */
{
while (isspace(*s))
s++;
return(s);
}
int nummsg(int n) /* Read Index files and process them */
{
FILE *ifp;
int i, j, ch;
char name[20];
char five[5];
sprintf(name, "%03d.ndx", n);
i = 0;
if ((ifp = fopen(name, "rb")) != NULL)
{
printf("%03d\b\b\b", n); /* only show conf # if file is found */
for (;;) /* see how many messages are in this conference */
{
for (j = 0; j < 5; j++)
{
if ((ch = getc(ifp)) == EOF)
ch = 26;
five[j] = ch;
}
for (j = 0; j < 5 && five[j] == 26; j++)
;
if (j == 5)
break;
i++;
}
fclose(ifp);
}
return(i);
}
int readblk(FILE *fp, char *buff)
{
int i, ch;
for (i = 0; i < 128; i++)
if ((ch = getc(fp)) == EOF)
return(1);
else
*buff++ = ch;
return(0);
}
int readhdr(FILE *fp)
{
if ( fread(&header, 1, sizeof(struct hdr), fp) != sizeof(struct hdr) )
return(1);
else
return(0);
}
void strncp(char *d, char *s, int n) /* this was for the CP/M version */
{
while (n-- && (*d++ = *s++))
;
*d = 0;
}
void sep(FILE *fp)
{
int i;
putc('\n',fp);
for (i = 0; i < 70; i++)
putc('-',fp);
putc('\n',fp);
}
void _cdecl erase(char *pathname) /* routine to erase temp files */
{
char tmp[127];
char pattern[127];
int ok;
struct find_t fileinfo;
sprintf(pattern, "%s\\*.*", pathname);
ok = _dos_findfirst(pattern,0,&fileinfo);
if(ok != 0)
return;
while(!ok)
{
sprintf(tmp, "%s\\%s", pathname, fileinfo.name);
unlink(tmp);
ok = _dos_findnext(&fileinfo);
}
}
int WhichArc(char *pName) /* determines compression method used */
{
FILE *afp;
unsigned char archeader[128];
int c, i, n;
memset(archeader, 0, sizeof(archeader));
afp = fopen(pName, "rb");
if (afp == NULL) return -1;
n = fread(archeader, sizeof(unsigned char), sizeof(archeader) - sizeof(unsigned char), afp);
fclose(afp);
if (n <= 0) return -1;
if (n >= 7 && n >= archeader[0] + 2)
{
for (c = 0, i = archeader[0]; i--; c += (archeader+2)[i]);
if ((c & 0x00FF) == archeader[1] &&
archeader[2] == '-' &&
archeader[3] == 'l' &&
archeader[4] == 'h' &&
archeader[6] == '-') return (archeader[5] > '1') ? LHA : LHARC;
}
if (n >= 2)
{
if (archeader[0] == 0x60 && archeader[1] == 0xEA) return ARJ;
if (archeader[0] == 'P' && archeader[1] == 'K') return ZIP;
}
if (n >= 3
&& archeader[0] == 'Z' && archeader[1] == 'O' && archeader[2] == 'O') return ZOO;
if (n >= 25 && archeader[0] == 0x1A) return ARC;
return UNKNOWN;
}