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); } } }
static void gcf_create(){ char *gcf_name=HREnextArg(); if (gcf_name==NULL) { Abort("missing <gcf archive> argument"); } archive_t arch=arch_gcf_create(raf_unistd(gcf_name),blocksize,blocksize*blockcount,0,1); char*file; while((file=HREnextArg())){ if (is_a_file(file)){ stream_t is=file_input(file); stream_t os=arch_write_apply(arch,file,SSMcall(compression_policy,file)); 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); } else { Abort("cannot add %s because it is not a file",file); } } arch_close(&arch); }
static int copy_item(void*arg,int id,char*name){ (void)id; copy_context_t ctx=(copy_context_t)arg; Warning(info,"copying %s",name); char*compression=ctx->encode?ctx->encode(name):NULL; Warning(debug,"compression method is %s",compression); stream_t is=arch_read(ctx->src,name,ctx->decode); stream_t os=arch_write(ctx->dst,name,compression,1); char buf[ctx->bs]; for(;;){ int len=stream_read_max(is,buf,ctx->bs); if (len) stream_write(os,buf,len); if(len<ctx->bs) break; } stream_close(&is); stream_close(&os); return 0; }
static int copy_item(void*arg,int id,const char*name){ (void)id; copy_context_t ctx=(copy_context_t)arg; Print(info,"copying %s",name); char*compression=SSMcall(ctx->encode,name); Print(debug,"compression method is %s",compression); stream_t is=arch_read(ctx->src,(char*)name); stream_t os=arch_write_apply(ctx->dst,(char*)name,compression); char buf[ctx->bs]; for(;;){ int len=stream_read_max(is,buf,ctx->bs); if (len) stream_write(os,buf,len); if(len<ctx->bs) break; } stream_close(&is); stream_close(&os); return 0; }
static size_t gzip_read_max(stream_t stream,void*buf,size_t count){ stream->rd.next_out=buf; stream->rd.avail_out=count; int res; do { if (stream->rd.avail_in==0){ stream->rd.next_in=stream->rd_buf; stream->rd.avail_in=stream_read_max(stream->s,stream->rd_buf,stream->bufsize); } if (stream->compress){ res=inflate(&stream->rd, Z_NO_FLUSH); } else { res=deflate(&stream->rd, Z_NO_FLUSH); } if(res!=Z_OK && res!=Z_STREAM_END){ Abort("compression error %d %s",res,zError(res)); } } while(stream->rd.avail_out && res!=Z_STREAM_END); return (count-stream->rd.avail_out); }
static void gcf_decompress(){ char*source; char target[LTSMIN_PATHNAME_MAX]; while((source=HREnextArg())){ if (has_extension(source,".gzf")){ strncpy(target,source,strlen(source)-4); target[strlen(source)-4]=0; stream_t is=file_input(source); stream_t os=file_output(target); char *code=DSreadSA(is); is=stream_add_code(is,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 (has_extension(source,".gcf")||has_extension(source,".zip")){ strncpy(target,source,strlen(source)-4); target[strlen(source)-4]=0; archive_t arch_in; if (has_extension(source,".gcf")){ arch_in=arch_gcf_read(raf_unistd(source)); } else { arch_in=arch_zip_read(source,blocksize); } archive_t arch_out=arch_dir_create(target,blocksize,force?DELETE_ALL:DELETE_NONE); archive_copy(arch_in,arch_out,NULL,blocksize,NULL); arch_close(&arch_in); arch_close(&arch_out); if (!keep) recursive_erase(source); } else { Abort("source %s does not have known extension",source); } } }