mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 08:54:17 +00:00
Upload
Digital Research
This commit is contained in:
752
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/asmlink/ar68.c
Normal file
752
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/asmlink/ar68.c
Normal file
@@ -0,0 +1,752 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
#include "machine.h"
|
||||
#include "iobuf.h"
|
||||
#include "cout.h"
|
||||
|
||||
#define BLKSIZE 512
|
||||
char buff[BLKSIZE]={0};
|
||||
|
||||
/* flags for cp1file*/
|
||||
#define IEVEN 1
|
||||
#define OEVEN 2
|
||||
#define WHDR 4
|
||||
|
||||
#define DIR 0100000
|
||||
#define CHR 040000
|
||||
#define BLK 020000
|
||||
#define ROWN 0400
|
||||
#define WOWN 0200
|
||||
#define XOWN 0100
|
||||
#define RGRP 040
|
||||
#define WGRP 020
|
||||
#define XGRP 010
|
||||
#define ROTH 04
|
||||
#define WOTH 02
|
||||
#define XOTH 01
|
||||
|
||||
#define LIBMAGIC 0177545
|
||||
|
||||
#define LNAMLEN 14
|
||||
struct lib2hdr {
|
||||
char l2fname[LNAMLEN];
|
||||
long l2modti;
|
||||
char l2userid;
|
||||
char l2gid;
|
||||
short l2fimode;
|
||||
long l2fsize;
|
||||
short l2junk;
|
||||
} libhd={0};
|
||||
|
||||
struct {
|
||||
int f_devnum;
|
||||
int f_inum;
|
||||
int f_fimode;
|
||||
char f_nlinks;
|
||||
char f_userid;
|
||||
char f_gid;
|
||||
char f_size0;
|
||||
int f_size1;
|
||||
int f_addr[8];
|
||||
long f_acti;
|
||||
long f_modti;
|
||||
};
|
||||
|
||||
short libmagic LIBMAGIC;
|
||||
|
||||
int rflg=0, dflg=0, xflg=0, tflg=0, vflg=0;
|
||||
int uflg=0;
|
||||
int pflg=0;
|
||||
int areof=0;
|
||||
int arfd=0;
|
||||
int tempfd=0;
|
||||
int aflg=0, bflg=0;
|
||||
int psflg=0;
|
||||
int matchflg=0;
|
||||
char *psname=0;
|
||||
|
||||
char *arname=0,tempname[80]={0,0,0};
|
||||
/************************/
|
||||
#ifdef UNIX /* */
|
||||
char *dname="/tmp/"; /* UNIX */
|
||||
#else /* CP/M and VMS */
|
||||
char *dname=""; /* Disk Name */
|
||||
#endif /************************/
|
||||
#ifdef UNIX /* */
|
||||
char *tname="arXXXXXX"; /* Unix temp file name */
|
||||
#else /* CP/M and VMS */
|
||||
char *tname="ar68.tmp"; /* Temp file name */
|
||||
#endif /************************/
|
||||
|
||||
long lseek();
|
||||
long fixlong();
|
||||
long filesize();
|
||||
int endit();
|
||||
|
||||
int (*docom)()=0;
|
||||
int replace();
|
||||
int delete();
|
||||
int extract();
|
||||
int tell();
|
||||
#ifdef JUNK
|
||||
long mklong();
|
||||
#endif
|
||||
int print();
|
||||
#ifdef VAX
|
||||
struct {
|
||||
short loword;
|
||||
short hiword;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef PDP11
|
||||
struct {
|
||||
short loword;
|
||||
short hiword;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MC68000
|
||||
struct {
|
||||
short hiword;
|
||||
short loword;
|
||||
};
|
||||
#endif
|
||||
|
||||
main(argc,argv)
|
||||
char **argv;
|
||||
{
|
||||
|
||||
register char *p1, *p2;
|
||||
register char **ap;
|
||||
register int i;
|
||||
register long l;
|
||||
register long k;
|
||||
long kk;
|
||||
if(argc < 3) {
|
||||
usage:
|
||||
error("usage: ar68 drtwx[abiv][f d:] [opmod] archive obmod1 [obmod2] ... [>filespec]\n");
|
||||
|
||||
endit();
|
||||
}
|
||||
/* signal(1,endit); */
|
||||
ap = &argv[1];
|
||||
p1 = *ap++;
|
||||
i = argc-3;
|
||||
while(*p1) {
|
||||
switch(*p1++) {
|
||||
|
||||
case 'r':
|
||||
rflg++;
|
||||
docom = replace;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
aflg++;
|
||||
psname = *ap++;
|
||||
i--;
|
||||
break;
|
||||
|
||||
/* These options removed because they don't work!
|
||||
|
||||
case 'b':
|
||||
case 'i':
|
||||
bflg++;
|
||||
i--;
|
||||
psname = *ap++;
|
||||
break;
|
||||
|
||||
*/
|
||||
case 'd':
|
||||
dflg++;
|
||||
docom = delete;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
xflg++;
|
||||
docom = extract;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
tflg++;
|
||||
docom = tell;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
pflg++;
|
||||
docom = print;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
vflg++;
|
||||
break;
|
||||
|
||||
case 'f': /* Drive for temp files */
|
||||
dname = *ap++; /* Set proper disk name */
|
||||
break;
|
||||
default:
|
||||
error("invalid option flag: %c\n",*--p1);
|
||||
endit();
|
||||
}
|
||||
}
|
||||
uflg = rflg+dflg;
|
||||
if((uflg+xflg+tflg+pflg) != 1) {
|
||||
error("one and only one of drtwx flags required\n");
|
||||
endit();
|
||||
}
|
||||
psflg = aflg+bflg;
|
||||
if(psflg > 1) {
|
||||
error("only one of abi flags allowed\n");
|
||||
endit();
|
||||
}
|
||||
strcat (tempname,dname); /* Form 1st part of string */
|
||||
strcat (tempname,tname); /* Add in file name */
|
||||
|
||||
#ifdef UNIX /* For UNIX, make temp file*/
|
||||
mktemp(tempname);
|
||||
#endif
|
||||
|
||||
arname = *ap++;
|
||||
arfd = openar(arname,rflg);
|
||||
if(i==0 && tflg) {
|
||||
listall();
|
||||
endit();
|
||||
}
|
||||
if(i<=0)
|
||||
goto usage;
|
||||
if( xflg == 0 ) {
|
||||
if((tempfd=creat(tempname,0644,1)) < 0) {
|
||||
error("cannot create %s\n",tempname);
|
||||
endit();
|
||||
}
|
||||
if(write(tempfd,&libmagic,sizeof libmagic) != sizeof libmagic)
|
||||
{
|
||||
error("temp file write error\n");
|
||||
endit();
|
||||
}
|
||||
}
|
||||
while(i) {
|
||||
excom(*ap++);
|
||||
i--;
|
||||
}
|
||||
excom(0L); /*end of arg list*/
|
||||
if (xflg == 0)
|
||||
{
|
||||
k = lseek(tempfd,0L,1); /* Fetch file size */
|
||||
#ifndef UNIX
|
||||
l = lseek(tempfd,0L,0); /* Rewind temp file */
|
||||
if (l < 0) /* Error? */
|
||||
{
|
||||
printf("seek error on %s\n",tempname);
|
||||
exit(-1);
|
||||
}
|
||||
#else
|
||||
close(tempfd);
|
||||
if((tempfd=open(tempname,0,1)) < 0)
|
||||
{
|
||||
printf("Cannot re-open %s\n",tempname);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
close(arfd); /* Close input file */
|
||||
unlink(arname); /* Delete the file */
|
||||
arfd=creat(arname,0666,1); /* Create the file again*/
|
||||
if(arfd < 0) /* Error? */
|
||||
{
|
||||
printf("Unable to re-create %s -- archive is in %s\n",
|
||||
arname,tempname);
|
||||
exit(-1);
|
||||
}
|
||||
i = 1; /* Klutz */
|
||||
while (i > 0 && k > 0) /* Copy the file back */
|
||||
{
|
||||
i = (k > BLKSIZE) ? BLKSIZE : k;
|
||||
i = read(tempfd,buff,i);
|
||||
if(i < 0)
|
||||
{
|
||||
printf("Read error on %s\n",tempname);
|
||||
exit(-1);
|
||||
}
|
||||
else if (i > 0)
|
||||
{
|
||||
if(write(arfd,buff,i) != i)
|
||||
{
|
||||
printf("Write error on %s\n",arname);
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
k -= i;
|
||||
}
|
||||
kk = 0;
|
||||
write(arfd,&kk,sizeof(k)); /* Put 0 on end of file */
|
||||
close (tempfd);
|
||||
unlink(tempname);
|
||||
}
|
||||
endit();
|
||||
}
|
||||
|
||||
openar(arp,crfl)
|
||||
char *arp;
|
||||
{
|
||||
|
||||
register i;
|
||||
int ib;
|
||||
|
||||
if((i=open(arp,2,1)) < 0) { /*does not exist*/
|
||||
areof = 1;
|
||||
if((i = creat(arp,0666,1)) < 0)
|
||||
{
|
||||
printf("Cannot Create %s\n",arname);
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
return(i);
|
||||
}
|
||||
if(read(i,&ib,sizeof libmagic) != sizeof libmagic || ib != LIBMAGIC) {
|
||||
notar:
|
||||
error("not archive format: %s\n",arp);
|
||||
endit();
|
||||
}
|
||||
return(i);
|
||||
}
|
||||
|
||||
/* execute one command -- call with filename or 0*/
|
||||
|
||||
excom(ap)
|
||||
char *ap;
|
||||
{
|
||||
|
||||
register char *p;
|
||||
if(p=ap)
|
||||
{
|
||||
if(p[1] == ':') /* CP/M Drive number */
|
||||
p += 2; /* Bump to file name */
|
||||
}
|
||||
if((p) && (matchflg==0)) { /*look thru archive for file name*/
|
||||
while(areof==0 && nextar()) { /*get next ar file header*/
|
||||
if(streq(p,&libhd.l2fname[0]))
|
||||
break;
|
||||
if(psflg && streq(psname,&libhd.l2fname[0])) {
|
||||
break;
|
||||
}
|
||||
skcopy(uflg); /*skip or copy*/
|
||||
}
|
||||
}
|
||||
(*docom)(ap); /*exec requested command*/
|
||||
}
|
||||
|
||||
tell(ap)
|
||||
char *ap;
|
||||
{
|
||||
|
||||
register char *p;
|
||||
register i;
|
||||
register char *p1;
|
||||
|
||||
if(ap==0)
|
||||
endit();
|
||||
if(vflg) { /*long list*/
|
||||
pmode(libhd.l2fimode);
|
||||
printf(" %d/%d %6ld ",libhd.l2userid,libhd.l2gid,
|
||||
libhd.l2fsize);
|
||||
/* p1 = ctime(&libhd.l2modti);
|
||||
p1[24] = '\0';
|
||||
p1 =+ 4;
|
||||
printf(" %s ",p1); */
|
||||
}
|
||||
pfname();
|
||||
skcopy(0);
|
||||
}
|
||||
|
||||
pfname()
|
||||
{
|
||||
printf("%.14s\n",libhd.l2fname);
|
||||
}
|
||||
|
||||
replace(ap)
|
||||
char *ap;
|
||||
{
|
||||
|
||||
register i;
|
||||
int ifd;
|
||||
register long l;
|
||||
register char *p1;
|
||||
|
||||
if( ap == 0 ) {
|
||||
if( bflg && areof == 0 ) {
|
||||
l = -(sizeof libhd);
|
||||
lseek(arfd,l,1);
|
||||
}
|
||||
cprest();
|
||||
return;
|
||||
}
|
||||
if((ifd=open(ap,0,1)) < 0) {
|
||||
error("cannot open %s\n",ap);
|
||||
endit();
|
||||
}
|
||||
if(areof && psflg) {
|
||||
error("%s not in library\n",psname);
|
||||
endit();
|
||||
}
|
||||
if((bflg|aflg) && matchflg==0) { /*copy archive file before appending*/
|
||||
if(aflg)
|
||||
skcopy(1);
|
||||
matchflg++;
|
||||
}
|
||||
p1 = (ap[1] == ':') ? ap + 2 : ap; /* Drive name */
|
||||
copystr(p1,&libhd.l2fname[0],LNAMLEN);
|
||||
if(areof|aflg) {
|
||||
inform('a');
|
||||
}
|
||||
else if(bflg) {
|
||||
inform('i');
|
||||
}
|
||||
else {
|
||||
inform('r');
|
||||
skcopy(0); /*skip old copy*/
|
||||
}
|
||||
p1 = buff;
|
||||
libhd.l2modti = 0;
|
||||
libhd.l2userid = 0;
|
||||
libhd.l2gid = 0;
|
||||
libhd.l2fimode = 0666;
|
||||
libhd.l2fsize = filesize(&ifd,ap);
|
||||
cp1file(ifd,tempfd,WHDR+OEVEN,ap,tempname);
|
||||
close(ifd);
|
||||
}
|
||||
|
||||
struct iobuf ssbuf={0};
|
||||
long filesize(fdp,fname)
|
||||
int *fdp;
|
||||
char *fname;
|
||||
{
|
||||
struct hdr tcout;
|
||||
register long size;
|
||||
register short *p;
|
||||
register int i;
|
||||
|
||||
close(*fdp);
|
||||
if( fopen(fname,&ssbuf,1) < 0 )
|
||||
error("cannot open %s\n",fname);
|
||||
p = &tcout;
|
||||
for( i = 0; i < (sizeof tcout)/2; i++ )
|
||||
*p++ = getw(&ssbuf);
|
||||
close(ssbuf.fildes);
|
||||
if( tcout.ch_magic != MAGIC )
|
||||
error("not object file: %s\n",fname);
|
||||
size = tcout.ch_tsize + tcout.ch_dsize;
|
||||
if( tcout.ch_rlbflg == 0 )
|
||||
size =+ size;
|
||||
size =+ tcout.ch_ssize;
|
||||
if( (*fdp=open(fname,0,1)) < 0 )
|
||||
error("cannot reopen %s\n",fname);
|
||||
size =+ sizeof tcout;
|
||||
#ifndef UNIX
|
||||
size = ((size+3)/4)*4; /*turkey round-up to long for VAX*/
|
||||
#endif
|
||||
return(size);
|
||||
}
|
||||
|
||||
struct { char byt1; char byt2; char byt3; char byt4; };
|
||||
long fixlong(l)
|
||||
long l;
|
||||
{
|
||||
long tl;
|
||||
|
||||
tl.byt1 = l.byt4;
|
||||
tl.byt2 = l.byt3;
|
||||
tl.byt3 = l.byt2;
|
||||
tl.byt4 = l.byt1;
|
||||
return(tl);
|
||||
}
|
||||
fixshort(i)
|
||||
int i;
|
||||
{
|
||||
int ti;
|
||||
|
||||
ti.byt1 = i.byt2;
|
||||
ti.byt2 = i.byt1;
|
||||
}
|
||||
|
||||
delete(ap)
|
||||
char *ap;
|
||||
{
|
||||
|
||||
if(ap==0) {
|
||||
cprest();
|
||||
return;
|
||||
}
|
||||
inform('d');
|
||||
skcopy(0);
|
||||
}
|
||||
|
||||
extract(ap)
|
||||
char *ap;
|
||||
{
|
||||
|
||||
register ofd;
|
||||
register long l;
|
||||
register i;
|
||||
|
||||
if(ckafile(ap))
|
||||
return;
|
||||
if((ofd=creat(ap,0666)) < 0) {
|
||||
error("cannot create %s\n",ap);
|
||||
endit();
|
||||
}
|
||||
inform('x');
|
||||
cp1file(arfd,ofd,IEVEN,arname,ap);
|
||||
close(ofd);
|
||||
}
|
||||
|
||||
print(ap)
|
||||
char *ap;
|
||||
{
|
||||
|
||||
if(ckafile(ap))
|
||||
return;
|
||||
cp1file(arfd,1,IEVEN,arname,"std output");
|
||||
}
|
||||
|
||||
endit()
|
||||
{
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/* list all file in the library*/
|
||||
|
||||
listall()
|
||||
{
|
||||
|
||||
while(nextar()) {
|
||||
tell(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*read next ar file header into libhd*/
|
||||
|
||||
nextar()
|
||||
{
|
||||
|
||||
if( read(arfd,&libhd,sizeof libhd) != sizeof libhd ||
|
||||
libhd.l2fname[0] == '\0' ) {
|
||||
areof++;
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* call with cpflag=0 for skip, cpflag=1 for copy*/
|
||||
skcopy(cpflag)
|
||||
{
|
||||
|
||||
register long l;
|
||||
register int i;
|
||||
|
||||
if(areof)
|
||||
return;
|
||||
l = libhd.l2fsize;
|
||||
if(l&1)
|
||||
l++;
|
||||
if(cpflag) {
|
||||
inform('c');
|
||||
cp1file(arfd,tempfd,WHDR+OEVEN+IEVEN,arname,tempname);
|
||||
}
|
||||
else {
|
||||
if(lseek(arfd,l,1) < 0) {
|
||||
error("seek error on library\n");
|
||||
endit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JUNK
|
||||
char *mktemp(ap)
|
||||
char *ap;
|
||||
{
|
||||
|
||||
register char *p;
|
||||
register i,j;
|
||||
|
||||
/* i = getpid(); /*process id*/
|
||||
/* p = ap;
|
||||
while(*p)
|
||||
p++;
|
||||
for(j=0; j<5; j++) {
|
||||
*--p = ((i&7) + '0');
|
||||
i =>> 3;
|
||||
}
|
||||
*/ return(ap);
|
||||
}
|
||||
#endif
|
||||
|
||||
streq(s1, s2)
|
||||
char *s1, *s2;
|
||||
{
|
||||
register char *p1, *p2;
|
||||
|
||||
p1 = s1;
|
||||
p2 = s2;
|
||||
while(*p1++ == *p2)
|
||||
if(*p2++ == 0)
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int m1[] { 1, ROWN, 'r', '-' };
|
||||
int m2[] { 1, WOWN, 'w', '-' };
|
||||
int m3[] { 1, XOWN, 'x', '-' };
|
||||
int m4[] { 1, RGRP, 'r', '-' };
|
||||
int m5[] { 1, WGRP, 'w', '-' };
|
||||
int m6[] { 1, XGRP, 'x', '-' };
|
||||
int m7[] { 1, ROTH, 'r', '-' };
|
||||
int m8[] { 1, WOTH, 'w', '-' };
|
||||
int m9[] { 1, XOTH, 'x', '-' };
|
||||
|
||||
int *m[] { m1, m2, m3, m4, m5, m6, m7, m8, m9};
|
||||
|
||||
pmode(aflg1)
|
||||
{
|
||||
register int **mp;
|
||||
|
||||
for (mp = &m[0]; mp < &m[9];)
|
||||
select(*mp++,aflg1);
|
||||
}
|
||||
|
||||
select(pairp,flg)
|
||||
int *pairp;
|
||||
int flg;
|
||||
{
|
||||
register int n, *ap, f;
|
||||
|
||||
ap = pairp;
|
||||
f = flg;
|
||||
n = *ap++;
|
||||
while (--n>=0 && (f&*ap++)==0)
|
||||
ap++;
|
||||
putchar(*ap);
|
||||
}
|
||||
|
||||
inform(cc)
|
||||
char cc;
|
||||
{
|
||||
|
||||
if(vflg) {
|
||||
putchar(cc);
|
||||
putchar(' ');
|
||||
pfname();
|
||||
}
|
||||
}
|
||||
|
||||
copystr(ap1,ap2,alen)
|
||||
char *ap1, *ap2;
|
||||
{
|
||||
|
||||
register char *p1, *p2;
|
||||
register len;
|
||||
|
||||
p1 = ap1;
|
||||
p2 = ap2;
|
||||
len = alen;
|
||||
while(len) {
|
||||
if(!(*p2++ = *p1++))
|
||||
break;
|
||||
len--;
|
||||
}
|
||||
while(--len > 0)
|
||||
*p2++ = '\0';
|
||||
}
|
||||
|
||||
#ifdef JUNK
|
||||
long mklong(ai1,ai2)
|
||||
{
|
||||
|
||||
long l;
|
||||
|
||||
l.hiword = ai1;
|
||||
l.loword = ai2;
|
||||
return(l);
|
||||
}
|
||||
#endif
|
||||
|
||||
cprest()
|
||||
{
|
||||
|
||||
while(areof==0 && nextar())
|
||||
skcopy(1); /*copy rest of library*/
|
||||
}
|
||||
|
||||
cp1file(ifd,ofd,aflags,iname,oname)
|
||||
char *iname, *oname;
|
||||
{
|
||||
|
||||
register i;
|
||||
register int j;
|
||||
register long l;
|
||||
register flags;
|
||||
|
||||
flags = aflags;
|
||||
if(flags&WHDR) {
|
||||
if(write(ofd,&libhd,sizeof libhd) != sizeof libhd) {
|
||||
iwrerr:
|
||||
error("write error on %s\n",oname);
|
||||
endit();
|
||||
}
|
||||
}
|
||||
for( l = libhd.l2fsize; l > BLKSIZE; l =- BLKSIZE ) {
|
||||
if((i=read(ifd,buff,BLKSIZE)) != BLKSIZE) {
|
||||
irderr:
|
||||
error("read error on %s\n",iname);
|
||||
endit();
|
||||
}
|
||||
if(write(ofd,buff,BLKSIZE) != BLKSIZE) {
|
||||
goto iwrerr;
|
||||
}
|
||||
}
|
||||
if( l > 0 ) {
|
||||
i = l;
|
||||
if((j=read(ifd,buff,i)) != i)
|
||||
goto irderr;
|
||||
if(flags&OEVEN) {
|
||||
if(i&1) {
|
||||
buff[i] = '\0';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if(write(ofd,buff,i) != i)
|
||||
goto iwrerr;
|
||||
}
|
||||
if(flags&IEVEN)
|
||||
if(l&1)
|
||||
read(ifd,buff,1);
|
||||
}
|
||||
|
||||
ckafile(ap)
|
||||
char *ap;
|
||||
{
|
||||
|
||||
if(ap==0)
|
||||
endit();
|
||||
if(areof) {
|
||||
error("%s not in archive file\n",ap);
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
error(x1,x2,x3,x4,x5,x6)
|
||||
int x1, x2, x3, x4, x5, x6;
|
||||
{
|
||||
printf(x1,x2,x3,x4,x5,x6);
|
||||
if( tempfd ) {
|
||||
close(tempfd);
|
||||
unlink(tempname);
|
||||
}
|
||||
exit();
|
||||
}
|
||||
Reference in New Issue
Block a user