/* reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * Pack/Unpack cpk archive files * * Copyright (C) 1989-2002 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "version.h" #define max(a, b) (a > b) ? a : b #define min(a, b) (a < b) ? a : b #define programname "uncpk" #define progversion "v0.2.1" #define author "Written by André Fachat" #define copyright "Copyright (C) 1997-2002 André Fachat." FILE *fp; char name[100]; char *s; void usage(FILE *fp) { fprintf(fp, "Usage: %s [OPTION]... [FILE]...\n" "Manage c64 cpk archives\n" "\n" " c create an archive\n" " a add a file to an archive\n" " x extract archive\n" " l list contents of archive\n" " v verbose output\n" " --version output version information and exit\n" " --help display this help and exit\n", programname); } int list=0,verbose=0,add=0,create=0; int main(int argc, char *argv[]) { int i,c,c2,fileok, nc; size_t n,n2; FILE *fp,*fpo=NULL; if (argc <= 1) { usage(stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, author, copyright); exit(0); } if(strchr(argv[1],(int)'l')) { list=1; } if(strchr(argv[1],(int)'v')) { verbose=1; } if(strchr(argv[1],(int)'a')) { add=1; } if(strchr(argv[1],(int)'c')) { create=1; } if(add||create) { if (argc <= 3) { usage(stderr); exit(1); } if(add) { fpo=fopen(argv[2],"ab"); } else if(create) { fpo=fopen(argv[2],"wb"); } if(fpo) { if(!add) fputc(1,fpo); /* Version Byte */ for(i=3;i=4 || c==0xf7) { n2=min(255,n); fprintf(fpo,"\xf7%c%c",(char)n2,(char)c); n-=n2; } else { fputc(c,fpo); n--; } } c=c2; } fclose(fp); fputc(0xf7,fpo); fputc(0,fpo); } else { fprintf(stderr,"Couldn't open file '%s' for reading!",argv[i]); } } fclose(fpo); } else { fprintf(stderr,"Couldn't open file '%s' for writing!",argv[1]); } } else { if (argc != 3) { usage(stderr); exit(1); } fp=fopen(argv[2],"rb"); if(fp){ if(fgetc(fp)==1){ do{ /* read name */ i=0; while((c=fgetc(fp))){ if(c==EOF) break; name[i++]=c; } name[i++]='\0'; if(!c){ /* end of archive ? */ while((s=strchr(name,'/'))) *s=':'; if(verbose+list) printf("%s\n",name); if(!list) { fpo=fopen(name,"wb"); if(!fpo) { fprintf(stderr,"Couldn't open output file %s !\n",name); } } fileok=0; while((c=fgetc(fp))!=EOF){ /* test if 'compressed' */ if(c==0xf7){ nc=fgetc(fp); if(!nc) { fileok=1; break; } c=fgetc(fp); if(fpo) { /* extract */ if(nc!=EOF && c!=EOF) { nc &= 255; while(nc--) { fputc(c,fpo); } } } } else { if(fpo) { fputc(c,fpo); } } } if(fpo) { fclose(fpo); fpo=NULL; } if(!fileok) { fprintf(stderr,"Unexpected end of file!\n"); } } } while(c!=EOF); } else fprintf(stderr,"Wrong Version!\n"); fclose(fp); } else { fprintf(stderr,"File %s not found!\n",argv[1]); } } return(0); }