home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
CPM68K
/
68000USQ.LBR
/
USQ.C
< prev
next >
Wrap
Text File
|
2000-06-30
|
11KB
|
410 lines
static char Sccs_Id[] = "@(#)usq.c 1.3 9/4/84 19:57:05";
/* USQ.C CHANGE HISTORY:
* 1.3 Converted to support USG Unix on 68000. Define unix to
* get unix version, cpm to get CP/M-68K version. Geoff Kuenning 9/3/84
* 1.2 Converted to Unix SCCS. Geoff Kuenning 9/3/84
* 1.1 Added WILDEXP. JEC 1/2/84
* 1.0 Converted to CP/M-68K C, Jim Cathey 11-5-83
* Taken from BDS C version 2.0
* 2.0 Added checkurk(), changed credits -CAF 8-14-83
* 1.9 Added wildexp -CAF 6-12-82
* 1.8 Output CPMEOF's while last output sector is partially filled.
* Needed if file was squeezed on a non-CP/M system. -CAF 3-10-82
* 1.7 Added -n to change NL to CRLF when unsqueezing files. Added CPMEOF
* at end of file in case of checksum error detected.
* 1.6 Lengthened permissible length of unsqueezed filename so long **nix
* pathnames won't choke unsqueeze(). -CAF 12-5-81
* 1.5 Break up long lines of introductory text
* -count no longer appends formfeed to preview of each file.
* -fcount (-f10, -F10) does append formfeed.
* 1.4 Add -count option to allow quick inspection of files.
* 1.3 Close inbuff to avoid exceeding maximum number of
* open files. Includes rearranging error exits.
*
* Program to unsqueeze files formed by sq.com
*
* Usage (CPM version):
* USQ item ...
* where ... represents more (optional) items and
* "item" is either:
* drive: to change the output drive
* file input file
* drive:file input file
* -<count> Previewing feature: redirects output
* files to standard output with parity stripped
* and unprintables except CR, LF, TAB and FF
* converted to periods. Limits each file
* to first count lines.
* Defaults to console, but see below how
* to capture all in one file for further
* processing, such as by PIP.
* Count defaults to a very high value.
* No CRC check is performed when previewing.
* Use drive: to cancel this.
*
* -f<count> Same as -count except formfeed
* appended to preview of each file.
* Example: -f10.
*
* -n Change NL to CRLF
*
* If no such items are given on the command line you will be
* prompted for commands (one at a time). An empty command
* terminates the program.
*
* Usage (USG Unix version):
* USQ item ...
* where ... represents more (optional) items and
* "item" is either:
* file input file
* -<count> Previewing feature: redirects output
* files to standard output with parity stripped
* and unprintables except CR, LF, TAB and FF
* converted to periods. Limits each file
* to first count lines.
* Count defaults to a very high value.
* No CRC check is performed when previewing.
* Use -e to cancel this.
*
* -f<count> Same as -<count> except formfeed
* appended to preview of each file.
* Example: -f10.
*
* -u Cancel -<count> or -f<count>.
* -n Change CRLF to NL. Note that this is the EXACT
* opposite of the meaning of this flag in CP/M.
*
* If no such items are given on the command line you will be
* prompted for commands (one at a time). An empty command
* terminates the program.
*
* The unsqueezed file name is recorded in the squeezed file.
*
* Examples (CP/M):
* A>USQ GRUMP.QQQ writes on a:
* A>USQ D:CRAP.XQZ writes on A:
* A>USQ B: D:CRAP.CQM writes on B:
* B>USQ X.AQ C: Y.BQ writes X.?? on B: and Y.?? on C:
*
* Examples (Unix):
* usq grump.qqq writes grump.q?q in current directory
* usq - crap.xqz writes cleaned-up crap to standard output
*/
#ifndef unix /* Make sure *something* is defined */
#define cpm
#endif
#ifdef unix
#include <stdio.h>
#include <ctype.h>
#else
#include <a:stdio.h>
#include <a:ctype.h>
#endif
#include "sqcom.h"
#include "usq.h"
#define VERSION "1.3 9/4/84" /* Version for titling output */
unsigned dispcnt; /* How much of each file to preview */
char ffflag; /* Formfeed separates preview from different files */
char nlmode; /* <>0 if adding/deleting cr's for host system */
#ifdef cpm
#define SENTINEL 055555 /* For catching out-of-memory conditions */
#ifndef PATHLEN
#define PATHLEN 16 /* Maximum length of an input filename */
#endif
#define LONGPATH 257 /* Maximum length of an output filename */
char origname[LONGPATH]; /* Original file name without drive */
unsigned Sentinel; /* be sure this doesn't get munged ! */
#endif
#ifdef unix
#ifndef PATHLEN
#define PATHLEN 512 /* Maximum length of a pathname */
#endif
#define LONGPATH PATHLEN
#endif
short brgetw ();
main(argc, argv)
int argc;
char *argv[];
{
int i,c;
char inparg[PATHLEN]; /* parameter from input */
#ifdef cpm
wildexp(&argc, &argv);
Sentinel = SENTINEL; /* unlikely value */
#endif
nlmode = dispcnt = 0; /* Not in preview or nlmode */
#ifdef cpm
/* Initialize output drive to default drive */
outdrv[0] = '\0';
/* But prepare for a specific drive */
outdrv[1] = ':';
outdrv[2] = '\0'; /* string terminator */
#endif
/* Process the parameters in order */
for(i = 1; i < argc; ++i)
obey(argv[i]);
if(argc < 2) {
fprintf(stderr, "File unsqueezer version %s\n", VERSION);
fprintf(stderr,"Conceived by Richard Greenlaw Modified by Chuck Forsberg et al.\n");
#ifdef cpm
fprintf(stderr, "Accepts redirection and wildcards.\n");
fprintf(stderr, "Usage: usq [-count][-Fcount][-N] [file ...]\n");
fprintf(stderr, "Parameters are from command line or one-at-a-time from standard\n");
fprintf(stderr, "input and are output drives and input file names. Empty to quit.\n");
#endif
#ifdef unix
fprintf(stderr, "Usage: usq [-<count>][-f<count>][-u][-n] [file ...]\n");
fprintf(stderr, "Parameters are from command line or one-at-a-time from standard\n");
fprintf(stderr, "input and are input file names. Empty to quit.\n");
#endif
do {
fprintf(stderr, "\n*");
for(i = 0; i < sizeof (inparg); ++i) {
if((c = getchar()) == EOF)
c = '\n'; /* force empty (exit) command */
if((inparg[i] = c) == '\n') {
inparg[i] = '\0';
break;
}
}
if(inparg[0] != '\0')
obey(inparg);
} while(inparg[0] != '\0');
}
#ifdef cpm
if (Sentinel != SENTINEL)
fprintf(stderr,"Out of memory: translation suspect!\007\n");
#endif
return 0;
}
obey(p)
char *p;
{
char *q;
if(*p == '-') {
if('n' ==tolower(p[1])) {
++nlmode; return;
}
#ifdef unix
if('e' == tolower (p[1])) {
dispcnt = 0; /* cancel previewing */
return;
}
#endif
if(ffflag = (tolower(*(p+1)) == 'f'))
++p;
/* Set number of lines of each file to view */
dispcnt = 65535; /* default */
if(*(p+1))
if((dispcnt = atoi(p + 1)) == 0)
fprintf(stderr, "\nBAD COUNT %s", p + 1);
return;
}
#ifdef cpm
if(*(p + 1) == ':') {
/* Got a drive */
if(isalpha(*p)) {
if(*(p+2) == '\0') {
/* Change output drive */
dispcnt = 0; /* cancel previewing */
printf("\nOutput drive =%s",p);
outdrv[0] = *p;
return;
}
} else {
fprintf(stderr, "\nERROR - Ignoring %s.", p);
return;
}
}
/* Check for ambiguous (wild-card) name */
for(q = p; *q != '\0'; ++q)
if(*q == '*' || *q == '?') {
fprintf(stderr, "\nCan't accept ambiguous name %s.", p);
return;
}
#endif
unsqueeze(p);
}
unsqueeze(infile)
char *infile;
{
FILE *inbuff, *outbuff; /* file buffers */
#ifdef cpm
FILE *fopenb(), *fdopen();
#endif
#ifdef unix
FILE *fopen (), *fdopen ();
#define creatb creat
#define fopenb fopen
#endif
int i, c, ofd;
char cc;
char *p;
unsigned short filecrc; /* checksum */
int numnodes; /* size of decoding tree */
char outfile[LONGPATH]; /* output file name */
unsigned linect; /* count of number of lines previewed */
if((inbuff = fopenb(infile,"r")) == 0) {
fprintf(stderr, "Can't open %s\n", infile);
return;
}
/* Initialization */
linect = 0;
crc = 0;
init_cr();
init_huff();
/* Process header */
if(brgetw (inbuff) != RECOGNIZE) {
fprintf(stderr, "'%s' is not a squeezed file!\n", infile);
goto closein;
}
filecrc = brgetw(inbuff);
/* Get original file name */
#ifdef cpm
p = origname; /* send it to array */
#endif
#ifdef unix
p = outfile;
#endif
do {
*p = getc(inbuff);
} while(*p++ != '\0');
#ifdef cpm
/* Combine with output drive */
outfile[0] = '\0'; /* empty */
strcat(outfile, outdrv); /* drive */
strcat(outfile, origname); /* name */
#endif
printf("\n%s -> %s: ", infile, outfile);
numnodes = brgetw(inbuff);
if(numnodes < 0 || numnodes >= NUMVALS) {
fprintf(stderr, "'%s' has invalid decode tree size.\n", infile);
goto closein;
}
/* Initialize for possible empty tree (SPEOF only) */
dnode[0].children[0] = -(SPEOF + 1);
dnode[0].children[1] = -(SPEOF + 1);
/* Get decoding tree from file */
for(i = 0; i < numnodes; ++i) {
dnode[i].children[0] = brgetw(inbuff);
dnode[i].children[1] = brgetw(inbuff);
}
if(dispcnt) {
/* Use standard output for previewing */
putchar('\n');
while(((c = getcr(inbuff)) != EOF) && (linect < dispcnt)) {
cc = 0x7f & c; /* strip parity */
if((cc < ' ') || (cc > '~'))
/* Unprintable */
switch(cc) {
case '\r': /* return */
/* newline will generate CR-LF */
goto next;
case '\n': /* newline */
++linect;
case '\f': /* formfeed */
case '\t': /* tab */
break;
default:
cc = '.';
}
putchar(cc);
next: ;
}
if(ffflag)
putchar('\f'); /* formfeed */
} else {
/* Create output file */
if((ofd = creatb(outfile, 0755)) == ERROR) {
fprintf(stderr, "Can't create '%s'.\n", outfile);
goto closeall;
}
outbuff = fdopen(ofd,"w");
/* Get translated output bytes and write file */
while((c = getcr(inbuff)) != EOF) {
crc += c;
if(nlmode && c=='\n')
fputc('\r',outbuff);
if((fputc(c, outbuff)) == ERROR) {
fprintf(stderr, "Write error in '%s'.\n", outfile);
goto closeall;
}
}
if(filecrc != crc) {
#ifdef cpm
fputc(CPMEOF, outbuff);
#endif
fprintf(stderr, "ERROR - checksum error in '%s'.\n", outfile);
}
closeall:
/*
* If the last sector is partially filled (this would happen
* iff the file was squeezed on MARC, Unix(TM), MS-DOS or
* similar system which avoids the CP/M EOF crock),
* pad it out with ^Z characters so editors,
* etc. won't choke on it. -CAF 3-10-82
*/
/* while(outbuff._nleft % SECSIZ) /* for BDS C 1.4x only */
/* putc(CPMEOF, &outbuff); */
fflush(outbuff);
fclose(outbuff);
}
closein:
fclose(inbuff);
}
short brgetw(stream)
FILE *stream;
{
/* Get word from stream. Since BDS C is byte reversed and
CP/M-68K isn't, we need to swap every byte.
We don't use 'getw' because it returns 32 bits on a 32-bit machine.
*/
short wordin, wordout;
wordin = (getc (stream) << 8) | (getc (stream) & 0xFF);
swab(&wordin, &wordout, 2);
return wordout;
}