Logo Search packages:      
Sourcecode: xa version File versions  Download package

uncpk.c

/* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#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<argc;i++) {
           if(verbose) printf("%s\n",argv[i]);
           fp=fopen(argv[i],"rb");
           if(fp) {
             while((s=strchr(argv[i],':'))) *s='/';
             fprintf(fpo,"%s",argv[i]);
             fputc(0,fpo);
             c=fgetc(fp);
             while(c!=EOF) {
             n=1;
               while((c2=fgetc(fp))==c) {
               n++;
             }
             while(n) {
               if(n>=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);
}

Generated by  Doxygen 1.6.0   Back to index