/***************************************************************************** DOS style copy command for the commodore 128, CP/M 3+ mode While tested on the C-128, should work on any cp/m system. 4/29/99 - Ken Mauro (main program, except where otherwise noted) ******************************************************************************/ #define BUFSIZE 16384 /* from stdio */ #define C80 1 /* compiler type: softworks C80 */ #ifdef C80 #define NULL 0 #define EOF -1 #include "printf.c" #else #include "stdio.h" #include "stdlib.h" #endif main(argc,argv) int argc; char *argv[]; { unsigned int tbytes; /* handles counts up to 65535 bytes */ int u1,u2; char d1,d2; int c,i,j,n,t,f1,f2; int len,len1,len2,len3,ret; int next,last,usr,drv,echo,diag; char u[8],d[8],tmp[20],src[20],dest[20]; char du1[8],du2[8],buf[BUFSIZE+1]; static char space[]={" "}; /* must be 17 spaces*/ echo = 1; diag = 0; command(&argc, &argv); /* manually expand cmdline args */ /* ansi compilers handle internally*/ /* i=0; while(i1 ){ if(argc >2 ){ printf(" \n"); next = 1; last = argc-1; /*usr = bdos(32,0);*/ /* diag only: force default user# */ usr = bdos(32,255); drv = bdos(0x19,255); drv+=65; /* 97;*/ sprintf(u,"%u",usr); sprintf(d,"%c",drv); strcpy(tmp,argv[1]); len = instr(tmp,':'); if(len > 0){ tmp[len]=0; c=tmp[len-1]; if( c <= '9') sprintf( du1,"%s%s%c%c",tmp,d,':', 0 ); if(c>='A' && len>1 ) sprintf( du1,"%s%c%c",tmp,':', 0 ); if(c>='A' && len==1 ) sprintf( du1,"%s%s%c%c",u,tmp,':', 0 ); } else sprintf( du1,"%s%s%c%c",u,d,':',0); len1=strlen(du1); strcpy(tmp,argv[last]); len = instr(tmp,':'); if(len > 0){ tmp[len]=0; c=tmp[len-1]; if( c <= '9') sprintf( du2,"%s%s%c%c",tmp,d,':', 0 ); if(c>='A' && len>1 ) sprintf( du2,"%s%c%c",tmp,':', 0 ); if(c>='A' && len==1 ) sprintf( du2,"%s%s%c%c",u,tmp,':', 0 ); } else sprintf( du2,"%s%s%c%c",u,d,':',0); len2=strlen(du2); len = len1; ret=instr(argv[1],':'); if(ret > 0) len1=ret+1; else len1=0; ret=instr(argv[2],':'); if(ret > 0) len2=ret+1; else len2=0; u1=atoi(du1); u2=atoi(du1); /*===========================================================================*/ while(next++ < last ){ strcpy(src,du1); strcpy(tmp,argv[next-1]); strcat(src,&tmp[len1]); if(argc>3){ strcpy(dest,du2); strcpy(tmp,argv[next-1]); strcat(dest,&tmp[len2]); } else{ strcpy(dest,du2); if(argv[2][len2]==0){ strcpy(tmp,argv[1]); strcat(dest,&tmp[len1]); } else{ strcpy(tmp,argv[2]); strcat(dest,&tmp[len2]); } } len=strlen(src); len3=strlen(dest); /*printf("%s%s%s \n",src, &space[len], dest);*/ printf("%s%s%s ",src, &space[len], dest); if( strcmp(src,dest) == 0 ){ error("Source and destination are the same."); } tbytes=0; ret=instr(src,':'); if((f1=fopen(&src[ret-1],"r" )) == -1) error("Invalid Source."); ret=instr(dest,':'); if((f2=fopen(&dest[ret-1],"w")) == -1) error("Invalid Destination."); bdos(32,u1); while( (n=read(f1,buf,BUFSIZE)) > 0 ) { bdos(32,u2); if(write(f2,buf,n)!=n) error("Write Error or Disk full."); tbytes += n; /*if(echo)printf("%u bytes \r",tbytes);*/ bdos(32,u1); } fclose(f2); fclose(f1); if(echo)printf("%s%6u bytes \n", &space[len3], tbytes); /* if( (c=bdos(6,254)) >0 ) ctrlbrk(); */ } /* end of while copy loop */ bdos(32,usr); /* get our default user area back */ printf("%u file(s) copied. \n", next-2 ); } else error("You must supply a source and destination."); } else { printf(" Program: COPY80.COM v1.1 CP/M \n"); printf(" Author : Ken Mauro \n"); printf(" Date...: Mar 1, 1999 \n"); printf(" Purpose: Dos style copy \n"); printf(" Usage..: copy UD:src UD:dest \n"); printf(" Bufsiz : %u bytes \n",BUFSIZE); } } /* =============================== END MAIN ================================ */ instr(a,b) char *a, *b; { int i; i=0; while( a[i++] != 0 ) { if( a[i] == b ) return(i); } return(0); } error(s) char *s; { printf(" %s \n",s); exit(1); } /* ctrlbrk(c) int c; { c=bdos(6,255); if (c=3){ printf("*interrupted* \n"); exit(1); } } */ /* command: expand wild cards in the command line. (7/25/83) * * usage: command(&argc, &argv) modifies argc and argv as necessary * uses sbrk to create the new arg list * NOTE: requires makfcb() and bdos() from file stdlib.c. When used * with a linker and stdlib.rel, remove the #include stdlib.c. * * Written by Dr. Jim Gillogly; Modified for CP/M by Walt Bilofsky. */ #define MAXFILES 255 /* max number of expanded files */ #define FNSIZE 15 /* filename: 2(A:)+8+1+3+null */ int COMnf,*COMfn,COMc,*COMv; char *COMarg,*COMs; static expand(); command(argcp,argvp) int *argcp,*argvp; { int f_alloc[MAXFILES]; COMfn = f_alloc; COMc = *argcp; COMv = *argvp; COMfn[0] = *COMv++; /* Don't expand first one */ COMnf = 1; for (COMarg = *COMv; --COMc; COMarg = *++COMv) { for (COMs = COMarg; *COMs; COMs++) if (*COMs == '?' || *COMs == '*') { expand(); goto contn; /* expand each name at most once */ } COMfn[COMnf++] = COMarg; /* no expansion */ contn:; } *argcp = COMnf; COMfn[COMnf++] = -1; COMv = *argvp = sbrk(2 * COMnf); while (COMnf--) COMv[COMnf] = COMfn[COMnf]; } static expand() { char fcb[36]; static char *p,*q; static int i,flg; makfcb(COMarg,fcb); if (fcb[0] == -1) fcb[0] = '?'; /* Check for all users */ for (i = flg = 1; i <= 11; ++i) { /* Expand *'s */ if (i == 9) flg = 1; if (fcb[i] == '*') flg = 0; if (flg == 0) fcb[i] = '?'; } flg = 17; bdos(26,0x80); /* Make sure DMA address OK */ while ((i = bdos(flg,fcb)) != -1) { COMfn[COMnf++] = q = sbrk(FNSIZE); if (COMnf >= MAXFILES-1) { for (p = "Too many file names.\n"; putchar(*p++); ); exit(0); } p = 0x81 + i * 32; /* Where to find dir. record */ if (COMarg[1] == ':' && COMarg[0] != '?') { *q++ = COMarg[0]; *q++ = ':'; } for (i = 12; --i; ) { if (i == 3) *q++ = '.'; if ((*q = *p++ & 0177) != ' ') ++q; } *q = 0; flg = 18; } } #include "stdlib.c" /* remove if using L80.COM & *.rel files */