int main(int argc, char *argv[]){ char*gcf_name; archive_t gcf=NULL; RTinitPopt(&argc,&argv,options,1,-1,&gcf_name,NULL,"([-c] <gcf> (<dir>|<file>)*) | (-x <gcf> [<dir>|<pattern>])", "Tool for creating and extracting GCF archives\n\nOptions"); compression_policy_compile(policy); if (operation==GCF_EXTRACT) { char *out_name=RTinitNextArg(); archive_t dir; if(out_name){ if(RTinitNextArg()){ Fatal(1,error,"extraction uses gcf -x <gcf> [<dir>|<pattern>]"); } if (strstr(out_name,"%s")) { dir=arch_fmt(out_name,file_input,file_output,blocksize); } else { dir=arch_dir_create(out_name,blocksize,force?DELETE_ALL:DELETE_NONE); } } else { dir=arch_dir_open(".",blocksize); } if (is_a_dir(gcf_name)){ gcf=arch_dir_open(gcf_name,blocksize); } else { gcf=arch_gcf_read(raf_unistd(gcf_name)); } archive_copy(gcf,"auto",dir,NULL,blocksize); arch_close(&dir); arch_close(&gcf); } else { if (operation==GCF_FILE){ gcf=arch_gcf_create(raf_unistd(gcf_name),blocksize,blocksize*blockcount,0,1); } else { gcf=arch_dir_create(gcf_name,blocksize,force?DELETE_ALL:DELETE_NONE); } for(;;){ char *input_name=RTinitNextArg(); if (!input_name) break; if (is_a_dir(input_name)){ Warning(info,"copying contents of %s",input_name); archive_t dir=arch_dir_open(input_name,blocksize); archive_copy(dir,NULL,gcf,get_compression,blocksize); arch_close(&dir); } else { Warning(info,"copying %s",input_name); stream_t is=file_input(input_name); stream_t os=arch_write(gcf,input_name,get_compression(input_name),1); char buf[blocksize]; for(;;){ int len=stream_read_max(is,buf,blocksize); if (len) stream_write(os,buf,len); if(len<blocksize) break; } stream_close(&is); stream_close(&os); } } arch_close(&gcf); } }
static void gcf_compress(){ char*source; char target[LTSMIN_PATHNAME_MAX]; while((source=HREnextArg())){ if (is_a_file(source)){ sprintf(target,"%s.gzf",source); stream_t is=file_input(source); stream_t os=file_output(target); char *code=SSMcall(compression_policy,source); DSwriteS(os,code); os=stream_add_code(os,code); char buf[blocksize]; for(;;){ int len=stream_read_max(is,buf,blocksize); if (len) stream_write(os,buf,len); if(len<blocksize) break; } stream_close(&is); stream_close(&os); if (!keep) recursive_erase(source); } else if (is_a_dir(source)){ sprintf(target,"%s.gcf",source); archive_t arch_in=arch_dir_open(source,blocksize); archive_t arch_out=arch_gcf_create(raf_unistd(target),blocksize,blocksize*blockcount,0,1); archive_copy(arch_in,arch_out,compression_policy,blocksize,NULL); arch_close(&arch_in); arch_close(&arch_out); if (!keep) recursive_erase(source); } else { Abort("source %s is neither a file nor a directory",source); } } }
void lts_read(char *name,lts_t lts){ int format=lts_guess_format(name); switch(format){ case LTS_GCF: case LTS_DIR: { archive_t archive=format==LTS_DIR?arch_dir_open(name,65536):arch_gcf_read(raf_unistd(name)); stream_t ds=arch_read(archive,"info"); int magic=DSreadS32(ds); DSclose(&ds); if (magic==31) { // DIR in .dir lts_read_dir(archive,lts); arch_close(&archive); return; } else { // VEC in .dir arch_close(&archive); break; } } case LTS_TRA: lts_read_tra(name,lts); return; case LTS_IMCA: Abort("no read support for imca"); default: break; } lts_file_t src=lts_file_open(name); int segments=lts_file_get_segments(src); lts_type_t ltstype=lts_file_get_type(src); if (lts->ltstype==NULL){ lts_set_sig(lts,ltstype); } else { Print(info,"** warning ** omitting signature check"); } lts_file_t dst=lts_writer(lts,segments,src); int T=lts_type_get_type_count(ltstype); for(int i=0;i<T;i++){ if (lts->values[i]) lts_file_set_table(src,i,lts->values[i]); } lts_file_copy(src,dst); lts_file_close(src); lts_file_close(dst); }
static void gcf_extract(){ char *gcf_name=HREnextArg(); if (gcf_name==NULL) { Abort("missing <gcf archive> argument"); } archive_t arch=arch_gcf_read(raf_unistd(gcf_name)); archive_t dir; if (outputdir) { dir=arch_dir_create(outputdir,blocksize,force?DELETE_ALL:DELETE_NONE); } else { dir=arch_dir_open(".",blocksize); } char*pattern=HREnextArg(); do { archive_copy(arch,dir,NULL,blocksize,pattern); } while((pattern=HREnextArg())); arch_close(&dir); arch_close(&arch); }