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
/
ENTERPRS
/
CPM
/
UTILS
/
A
/
CPMSHAR.LBR
/
SHAR.CQ
/
SHAR.C
Wrap
Text File
|
2000-06-30
|
14KB
|
556 lines
/*
* Shar puts readable text files together in a package
*
* from which they are easy to extract.
*
* v 860716 M. Kersenbrock (tektronix!copper!michaelk) for Z80-CPM
* - enhanced usage message
*
* v 860712 D. Wecker for ULTRIX and the AMIGA
* - stripped down.. does patterns but no directories
* - added a -u (unshar) switch
*/
#define CPM
#ifdef CPM
#include "c:stdio.h"
#include "c:fcntl.h"
#else
#include <stdio.h>
#endif
#ifdef CPM
#define void int
#define fputc putc
extern char *getenv(),*malloc(),*index(),*rindex();
int cpmversion;
#endif
#ifdef AMIGA
#include <exec/types.h>
extern char *getenv(),*scdir(),*malloc(),*index();
#endif
#ifdef ULTRIX
#include <sys/types.h>
extern char *getenv(),*scdir(),*malloc(),*index();
#endif
#ifdef VMS
#include <types.h>
extern char *getenv(),*scdir(),*malloc();
#endif
#define BADCH ((int)'?')
#define EMSG ""
#define tell(s) {fputs(*nargv,stderr);fputs((s),stderr);fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);}
#define rescanopts() (optind = 1)
int optind = 1, /* index into parent argv vector */
optopt; /* character checked for validity */
long fsize; /* length of file */
char *optarg; /* argument associated with option */
char *sav[100]; /* saved file names */
int savind; /* save index */
/* OPTIONS */
int Verbose = 0; /* provide append/extract feedback */
int Basename = 0; /* extract into basenames */
int Count = 0; /* count characters to check transfer */
char *Delim = "SHAR_EOF"; /* put after each file */
char Filter[100] = "cat"; /* used to extract archived files */
char *Prefix = NULL; /* line prefix to avoid funny chars */
int UnShar = 0; /* do we unshar an input file? */
char Usage1[] =
"\nSHAR: Create/extract file archive for extraction by /bin/sh (normally).\n\
\n\
usage: shar [-u archive] [[-a] [-p prefix]\
[-d delim] [-bcv] files > archive]\n\
\n\
where: -a all the options (v,c,b,-pXX)\n";
char Usage2[] =
" -b extract absolute paths into current directory\n\
-c check filesizes on extraction\n\
-d use this EOF delimiter instead of SHAR_EOF\n";
char Usage3[] =
" -p use this as prefix to each line in archived files\n\
-u unshar <archive>\n\
-v verbose on extraction, incl. echoing filesizes\n";
#define SED "sed 's/^%s//'" /* used to remove prefix from lines */
#ifdef CPM
#define OPTSTRING "U:AP:D:BCV"
#else
#define OPTSTRING "u:ap:d:bcv"
#endif
#ifdef VMS
char *index(s,c)
char *s;
char c;
{
while (*s != 0 && *s != c) s++;
if (*s == 0 && *s != c) s = 0;
return(s);
}
#endif
int header(ppchFiles)
char *ppchFiles[];
{
extern char *ctime();
register int i;
auto long clock;
register char **ppchList;
char *pchOrg;
char *pchName;
register int problems = 0;
pchOrg = getenv("ORGANIZATION");
pchName = getenv("NAME");
puts("#\tThis is a shell archive.");
puts("#\tRemove everything above and including the cut line.");
puts("#\tThen run the rest of the file through sh.");
puts("#----cut here-----cut here-----cut here-----cut here----#");
puts("#!/bin/sh");
puts("# shar: Shell Archiver");
puts("#\tRun the following text with /bin/sh to create:");
for (ppchList = ppchFiles; *ppchList; ++ppchList)
printf("#\t%s\n", *ppchList);
#ifdef CPM
if (cpmversion >= 0x30) {
#endif
(void) time(& clock);
printf("# This archive created: %s", ctime(&clock));
#ifdef CPM
}
#endif
if (pchName)
printf("# By:\t%s (%s)\n", pchName,
pchOrg ? pchOrg : "Dave Wecker Midnight Hacks");
return(0);
}
int archive(input, output)
char *input, *output;
{
auto char line[BUFSIZ];
register FILE *ioptr;
if (ioptr = fopen(input, "r")) {
printf("%s << \\%s > %s\n", Filter, Delim, output);
while(fgets(line, BUFSIZ, ioptr)) {
if (Prefix) fputs(Prefix, stdout);
fputs(line, stdout);
if (Count) fsize += strlen(line);
}
puts(Delim);
(void) fclose(ioptr);
return(0);
}
else {
fprintf(stderr, "shar: Can't open '%s'\n", input);
return(1);
}
}
void shar(file)
char *file;
{
register char *basefile;
basefile = file;
if (!strcmp(file, "."))
return;
fsize = 0;
if (Basename) {
while(*basefile)
basefile++; /* go to end of name */
while(basefile > file && *(basefile-1) != '/')
basefile--;
}
if (Verbose) printf("echo shar: extracting %s\n", basefile);
if (archive(file, basefile)) exit(66);
if (Count) {
printf("if test %ld -ne \"`wc -c %s`\"\n",fsize,basefile);
printf("then\necho shar: error transmitting %s ",basefile);
printf("'(should have been %ld characters)'\nfi\n",fsize);
}
}
int main(argc, argv)
int argc;
char **argv;
{
auto char *ppchFiles[256];
register int C;
register char **ppchList = ppchFiles;
register int errflg = 0;
#ifdef CPM
cpmversion = (bdoshl(0x0c,0) & 0xff);
#endif
while(EOF != (C = getopt(argc, argv, OPTSTRING))) {
#ifdef CPM
switch(isupper(C) ? tolower(C) : C ) {
#else
switch(C) {
#endif
case 'v':
Verbose++;
break;
case 'c':
Count++;
break;
case 'b':
Basename++;
break;
case 'd':
Delim = optarg;
break;
case 'a': /* all the options */
optarg = "XX";
Verbose++;
Count++;
Basename++;
/* fall through to set prefix */
case 'p':
(void) sprintf(Filter, SED, Prefix = optarg);
break;
case 'u':
UnShar++;
dounshar(optarg);
break;
default:
errflg++;
}
}
if (UnShar) exit(0);
C = getarg(argc, argv);
if (errflg || EOF == C) {
if (EOF == C)
fprintf(stderr, "shar: No input files\n");
fprintf(stderr, "%s%s%s", Usage1, Usage2, Usage3);
exit(1);
}
savind = 0;
do {
if (getpat(optarg)) exit(2);
}
while (EOF != (C = getarg(argc, argv)));
sav[savind] = 0;
header(sav);
for (ppchList = sav; *ppchList; ++ppchList) {
#ifdef CPM
strlower(*ppchList);
#endif
shar(*ppchList);
}
puts("#\tEnd of shell archive");
puts("exit 0");
exit(0);
}
getpat(pattern)
char *pattern;
{
register char *ptr;
int temp;
#ifdef AMIGA
while (ptr = scdir(pattern)) {
#else
ptr = pattern;
{
#endif
sav[savind] = malloc(strlen(ptr)+1);
strcpy(sav[savind++],ptr);
#ifdef CPM
temp = open(ptr,O_RDONLY);
if (temp == -1) {
#else
if (access(ptr,4)) {
#endif
printf("No read access for file: %s\n",ptr);
return(-1);
}
#ifdef CPM
close(temp);
#endif
}
return(0);
}
/*
* get option letter from argument vector
*/
int
getopt(nargc, nargv, ostr)
int nargc;
char **nargv, *ostr;
{
register char *oli; /* option letter list index */
static char *place = EMSG; /* option letter processing */
if(!*place) { /* update scanning pointer */
if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place)
return(EOF);
if (*place == '-') { /* found "--" */
++optind;
return EOF;
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
if(!*place) ++optind;
tell(": illegal option -- ");
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) { /* no white space */
optarg = place;
}
else {
if (nargc <= ++optind) { /* no arg */
place = EMSG;
tell(": option requires an argument -- ");
}
else {
optarg = nargv[optind]; /* white space */
}
}
place = EMSG;
++optind;
}
return(optopt); /* dump back option letter */
}
int
getarg(nargc, nargv)
int nargc;
char **nargv;
{
if (nargc <= optind) {
optarg = (char *) 0;
return EOF;
}
else {
optarg = nargv[optind++];
return 0;
}
}
dounshar(ArcNam)
char *ArcNam;
{
register int i,j;
register FILE *inptr,*outptr;
auto char line[BUFSIZ];
int DirNum = -1;
int Prefix = 0;
char Dirs[5][40],FilNam[128],Delim[40],ScrStr[128];
char *ptr;
if (!(inptr = fopen(ArcNam,"r"))) {
fprintf(stderr,"shar: Can't open archive '%s'\n", ArcNam);
return;
}
while (fgets(line,BUFSIZ,inptr)) {
if (strncmp(line,"sed ",4) == 0) {
Prefix = 0;
if (!(ptr = index(line,'/'))) goto getfil;
if (*++ptr == '^') ++ptr;
while (*ptr++ != '/') Prefix++;
goto getfil;
}
else if (strncmp(line,"cat ",4) == 0) {
Prefix = 0;
;
getfil:
#ifdef VMS
strcpy(FilNam,"[");
#else
FilNam[0] = 0;
#endif
for (i = 0; i <= DirNum; i++) {
#ifdef VMS
strcat(FilNam,".");
strcat(FilNam,Dirs[i]);
#else
strcat(FilNam,Dirs[i]);
strcat(FilNam,"/");
#endif
}
#ifdef VMS
strcat(FilNam,"]");
#endif
getshpar(line,">",ScrStr);
strcat(FilNam,ScrStr);
#ifdef CPM
tocpmformat(FilNam); /* tweek format as needed */
#endif
getshpar(line,"<<",Delim);
fprintf(stderr,"Creating %s ...",FilNam);
outptr = fopen(FilNam,"w");
while (fgets(line,BUFSIZ,inptr)) {
if (strncmp(line,Delim,strlen(Delim)) == 0) break;
if (outptr) fputs(&line[Prefix],outptr);
}
if (outptr) {
fclose(outptr);
fprintf(stderr,"...done\n");
}
else fprintf(stderr,"...error in creating file\n");
}
else if (strncmp(line,"mkdir ",6) == 0) {
sprintf(stderr,"Need to make directory: %s\n",&line[6]);
}
else if (strncmp(line,"chdir ",6) == 0) {
if (line[6] == '.' && line[7] == '.') DirNum--;
else strcpy(Dirs[++DirNum],&line[6]);
if (DirNum < -1) DirNum = -1;
}
else if (strncmp(line,"cd ",3) == 0) {
if (line[3] == '.' && line[4] == '.') DirNum--;
else strcpy(Dirs[++DirNum],&line[3]);
if (DirNum < -1) DirNum = -1;
}
}
fclose(inptr);
}
getshpar(line,sea,par)
char *line,*sea,*par;
{
register int i,j,k;
register char *scr1,*scr2;
while (*line) {
scr1 = line;
scr2 = sea;
while (*scr1 && *scr2 && *scr1 == *scr2) {
scr1++;
scr2++;
}
if (*scr2 == 0) {
if (*scr1 == 0) {
*par = 0;
return;
}
while ( *scr1 == ' ' || *scr1 == '\t' ||
*scr1 == '\\' || *scr1 == '\'' || *scr1 == '"') scr1++;
while ( *scr1 != 0 && *scr1 != ' ' && *scr1 != '\t' &&
*scr1 != '\\' && *scr1 != '\'' && *scr1 != '"' &&
*scr1 != '\n' && *scr1 != '\r') *par++ = *scr1++;
*par = 0;
return;
}
line++;
}
*par = 0;
}
#ifdef CPM
tocpmformat(filename)
char *filename;
{
char buffer[100];
char extension[100];
register char *temp;
int mod = 0;
strcpy(buffer,filename);
/*
* Make sure we get rid of any pathnames
*/
if ((temp=rindex(buffer,'/')) != 0) {
strcpy(buffer,(char *)((temp-buffer)+filename+1));
mod = 1;
}
if (strlen(filename) <= 8) {
if (mod != 0) {
strcpy(filename,buffer);
}
return(0);
}
/*
* If it already is in "CPM" format we'll check if we need
* to truncate the front filename part.
*/
if ((temp=index(buffer,'.')) != 0 ) {
if ((temp-buffer) < 8) {
if (mod != 0) {
strcpy(filename,buffer);
}
return(0);
}
else {
strcpy(extension,temp);
strcpy(&buffer[8],extension);
buffer[12] = '\0';
strcpy(filename,buffer);
return(1);
}
}
/*
* OK, filename is longer than can be handled, and it doesnt have
* a filetype "." marker already. We will put one in to minimize
* truncation.
*/
strcpy(extension,&buffer[8]);
buffer[8] = '.';
strcpy(&buffer[9],extension);
buffer[12] = '\0';
strcpy(filename,buffer);
return(2);
}
strlower(string)
char *string;
{
register char *pointer;
char c;
for (pointer = string ; (c=*pointer) != '\0' ; pointer++ ) {
if (isupper(c))
*pointer = tolower(c);
}
}
#endif