⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arj_arcv.c

📁 open arj source
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * $Id: arj_arcv.c,v 1.12 2004/02/20 23:18:59 andrew_belov Exp $ * --------------------------------------------------------------------------- * Archive management routines  are stored here (all these have  nothing to do * neither with commands nor with the "user" part). * */#include "arj.h"DEBUGHDR(__FILE__)                      /* Debug information block */#define MAX_COMMENT_LINES         25    /* As stated in the documentation */#define SECURED_MODE            0x78    /* file_mode of ARJ SECURITY headers *//* Ways of processing for the extended header structure */#define EHUF_WRITE            0x0001    /* Write the header */#define EHUF_COMMIT           0x0002    /* Advance the pointer(s) */#define EHUF_SETFLAGS         0x0004    /* Set the volume flag *//* * Local variables */static char *tmp_comment=NULL;          /* Temporary comment storage */static char *tmp_hptr;                  /* Pointer to parts of header */static char arjdisp_default[]="arjdisp" EXE_EXTENSION;  /* External display module */#if SFX_LEVEL>=ARJSFXVstatic unsigned char ea_pwd_modifier;   /* For garbled EAs */static char arjprot_id;                 /* Identifies ARJ-PROTECT block in the                                           main header */#endif/* A table of permissions for binary/text files */#if SFX_LEVEL>=ARJstatic char *read_perms[]={m_rb, m_r};  /* For encoding only */#endif#if SFX_LEVEL>=ARJSFXVstatic char *sim_perms[]={m_rbp, m_rp};#endifstatic char *write_perms[]={m_wb, m_w};/* Index file IDs */#if SFX_LEVEL>=ARJstatic char idxid_fault[]="?";#endif/* * A set of macros and functions to read the header *//* These macros read and write a byte from the header */#define setup_hget(ptr) (tmp_hptr=(ptr))#define setup_hput(ptr) (tmp_hptr=(ptr))#define hget_byte() (*(tmp_hptr++)&0xFF)#define hput_byte(c) (*(tmp_hptr++)=(char) (c))/* Reads two bytes from the header, incrementing the pointer */static unsigned int hget_word(){ unsigned int result; result=mget_word(tmp_hptr); tmp_hptr+=sizeof(short); return result;}/* Reads four bytes from the header, incrementing the pointer */static unsigned long hget_longword(){ unsigned long result; result=mget_dword(tmp_hptr); tmp_hptr+=sizeof(unsigned long); return result;}#if SFX_LEVEL>=ARJ/* Writes two bytes to the header, incrementing the pointer */static void hput_word(unsigned int w){ mput_word(w,tmp_hptr);  tmp_hptr+=sizeof(unsigned short);}/* Writes four bytes to the header, incrementing the pointer */static void hput_longword(unsigned long l){ mput_dword(l,tmp_hptr); tmp_hptr+=sizeof(unsigned long);}/* Calculates and stores the basic header size */static void calc_basic_hdr_size(){ basic_hdr_size=(unsigned int)first_hdr_size+strlen(hdr_filename)+1+                strlen(hdr_comment)+1;}#endif#if SFX_LEVEL>=ARJSFXV/* Calculates and stores the offset of comment within a preallocated header */static void calc_comment_offset(){ hdr_comment=&header[(int)first_hdr_size+strlen(hdr_filename)+1];}#endif#if SFX_LEVEL>=ARJ/* Allocates near memory for a temporary comment image, and copies the comment   to this area. */static void replicate_comment(){ tmp_comment=malloc_msg(COMMENT_MAX); far_strcpy((char FAR *)tmp_comment, comment);}/* Removes the temporary comment from memory, copying its contents to original   comment storage area (the one in the FAR memory). */static void dump_tmp_comment(){ if(tmp_comment!=NULL) {  far_strcpy(comment, (char FAR *)tmp_comment);  free(tmp_comment); }}/* Returns 1 if the given type is a file type, not a comment */static int is_file_type(int t){ return((t==ARJT_BINARY||t==ARJT_TEXT||t==ARJT_DIR||file_type==ARJT_UXSPECIAL||t==ARJT_LABEL)?1:0);}#endif/* Finds archive header, returning its offset within file, or -1 if it can't   be located. search_all is used to search through the entire file. */long find_header(int search_all, FILE *stream){ long end_pos; long tmp_pos; int id;  tmp_pos=ftell(stream); #if SFX_LEVEL>=ARJSFXV  if(archive_size==0L)  {   fseek(stream, 0L, SEEK_END);   archive_size=ftell(stream)-2L;   #if SFX_LEVEL<=ARJSFXV    fseek(stream, tmp_pos, SEEK_SET);   #endif  }  end_pos=archive_size;  if(!search_all)  {   if(end_pos>=HSLIMIT_ARJ)    end_pos=HSLIMIT_ARJ;  } while(tmp_pos<end_pos) #else while(tmp_pos<HSLIMIT_ARJSFX) #endif {  fseek(stream, tmp_pos, SEEK_SET);  id=fget_byte(stream);  #if SFX_LEVEL>=ARJSFXV  while(tmp_pos<end_pos)  #else  while(tmp_pos<HSLIMIT_ARJSFX)  #endif  {   if(id==HEADER_ID_LO)   {    if((id=fget_byte(stream))==HEADER_ID_HI)     break;   }   else    id=fget_byte(stream);   tmp_pos++;  }  #if SFX_LEVEL>=ARJSFXV   if(tmp_pos>=end_pos)    return(-1);  #endif  if((basic_hdr_size=fget_word(stream))<=HEADERSIZE_MAX)  {   crc32term=CRC_MASK;   fread_crc(header, basic_hdr_size, stream);  #if SFX_LEVEL>=ARJ   if(fget_longword(stream)==(crc32term^CRC_MASK)||ignore_crc_errors==ICE_CRC)  #else   if(fget_longword(stream)==(crc32term^CRC_MASK))  #endif   {    fseek(stream, tmp_pos, SEEK_SET);    return(tmp_pos);   }  }  tmp_pos++; } return(-1);}#if SFX_LEVEL>=ARJ/* Displays a header error */static void display_hdr_error_proc(FMSG *errmsg, char *name, unsigned int l){ #ifdef DEBUG  debug_report(dbg_cur_file, l, 'V'); #endif if(!ignore_archive_errors)  error(errmsg, name); msg_cprintf(0, errmsg, name); nputlf();}#define display_hdr_error(errmsg, name) display_hdr_error_proc(errmsg, name, __LINE__)#else#define display_hdr_error(errmsg, dptr) error(errmsg, dptr)#endif/* Checks size of compressed files for abnormal effects (e.g. size<0) */static int check_file_size(){ return((long)origsize<0||(long)compsize<0);}/* Reads an archive or file header (<name> is archive filename just for user   interface, and first, when == 0, specifies that the archive header is being   read). Returns 0 if the end of archive has been reached. */#if SFX_LEVEL>=ARJSFXVint read_header(int first, FILE *stream, char *name)#elseint read_header(int first)#define stream aistream#endif{ unsigned short header_id; #if SFX_LEVEL>=ARJSFXV  char id;                              /* Extended header identifier */  char is_continued;  struct ext_hdr FAR *tmp_eh;  unsigned int remainder, fetch_size;  char FAR *dptr;  char transfer_buf[64]; #endif #if SFX_LEVEL>=ARJSFXV  flush_kbd();  if(ignore_crc_errors!=ICE_NONE)  {   if(ignore_crc_errors==ICE_FORMAT)    /* Allow malformed header signatures */   {    cur_header_pos=ftell(stream);    if((header_id=fget_word(stream))==HEADER_ID)    {     if((basic_hdr_size=fget_word(stream))==0)      return(0);    }    fseek(stream, cur_header_pos, SEEK_SET);   }   if(find_header(1, stream)<0L)   {    display_hdr_error(M_BAD_HEADER, NULL);    return(0);   }  }  cur_header_pos=ftell(stream); #endif /* Strictly check the header ID */ if((header_id=fget_word(stream))!=HEADER_ID) { #if SFX_LEVEL>=ARJSFXV  if(first!=0)   display_hdr_error(M_NOT_ARJ_ARCHIVE, name);  else #endif   display_hdr_error(M_BAD_HEADER, NULL);  return(0); } if((basic_hdr_size=fget_word(stream))==0)  return(0); if(basic_hdr_size>HEADERSIZE_MAX) {  display_hdr_error(M_BAD_HEADER, NULL);  return(0); } crc32term=CRC_MASK; fread_crc(header, basic_hdr_size, stream); if((header_crc=fget_longword(stream))!=(crc32term^CRC_MASK)) {  display_hdr_error(M_HEADER_CRC_ERROR, NULL);  #if SFX_LEVEL>=ARJSFXV   return(0);  #endif } setup_hget(header); first_hdr_size=hget_byte(); arj_nbr=hget_byte(); arj_x_nbr=hget_byte(); host_os=hget_byte(); arj_flags=hget_byte(); method=hget_byte(); file_type=hget_byte(); password_modifier=hget_byte(); ts_store(&ftime_stamp, host_os, hget_longword()); compsize=hget_longword(); origsize=hget_longword(); file_crc=hget_longword(); entry_pos=hget_word(); fm_store(&file_mode, host_os, hget_word()); #if SFX_LEVEL>=ARJSFXV  /* Before v 2.50, we could only read host data here. With the introduction of     chapter archives, chapter numbers are stored in this field. NOTE: it will     be wise to check that the compressor's version (arj_nbr) is >= 7 ... */  ext_flags=hget_byte();  chapter_number=hget_byte();  #if SFX_LEVEL>=ARJ   if(modify_command&&ts_cmp(&ftime_stamp, &ftime_max)>0&&is_file_type(file_type))    ftime_max=ftime_stamp;  #else   if(ts_cmp(&ftime_stamp, &ftime_max)>0&&file_type!=ARJT_COMMENT)    ftime_max=ftime_stamp;  #endif  resume_position=0L;  continued_prevvolume=0;  /* v 2.62+ - reset ext. timestamps */  ts_store(&atime_stamp, OS_SPECIAL, 0L);  if(first)  {   arjprot_id=0;   #if SFX_LEVEL>=ARJ    prot_blocks=0;   #endif   if(first_hdr_size>=FIRST_HDR_SIZE_V)   {    #if SFX_LEVEL>=ARJ     prot_blocks=hget_byte();    #else     hget_byte();    #endif    arjprot_id=hget_byte();    hget_word();    if(arjprot_id&SFXSTUB_FLAG)     use_sfxstub=1;   }  }  else  {   if(first_hdr_size<R9_HDR_SIZE)   {    if(arj_flags&EXTFILE_FLAG)    {     resume_position=hget_longword();     continued_prevvolume=1;     mvfile_type=file_type;    }   }   else                                  /* v 2.62+ - resume position is stored                                             anyway, atime/ctime follows it. */   {    resume_position=hget_longword();    if(arj_flags&EXTFILE_FLAG)    {     continued_prevvolume=1;     mvfile_type=file_type;    }    ts_store(&atime_stamp, host_os, hget_longword());    ts_store(&ctime_stamp, host_os, hget_longword());    hget_longword();                     /* Reserved in revision 9 headers */   }  } #endif if(check_file_size())  display_hdr_error(M_BAD_HEADER, NULL); #if SFX_LEVEL>=ARJSFXV  file_garbled=(arj_flags&GARBLED_FLAG)?1:0;  garble_ftime=ts_native(&ftime_stamp, host_os); #endif hdr_filename=&header[first_hdr_size]; /* To conserve space, the calc_comment_offset() is placed in-line */ #if SFX_LEVEL>=ARJSFXV  calc_comment_offset(); #else  hdr_comment=&header[(int)first_hdr_size+strlen(hdr_filename)+1]; #endif #if SFX_LEVEL>=ARJSFXV  far_strcpyn((char FAR *)filename, (char FAR *)hdr_filename, FILENAME_MAX);  far_strcpyn(comment, (char FAR *)hdr_comment, COMMENT_MAX); #else  strncpy(filename, hdr_filename, FILENAME_MAX);  strncpy(comment, hdr_comment, COMMENT_MAX); #endif if(first==0&&lfn_supported==LFN_SUPPORTED&&dual_name) {  #if SFX_LEVEL>=ARJSFXV   far_strcpyn((char FAR *)filename, (char FAR *)hdr_comment, FILENAME_MAX);   far_strcpyn(comment, (char FAR *)hdr_filename, COMMENT_MAX);  #else   strncpy(filename, hdr_comment, FILENAME_MAX);   strncpy(comment, hdr_filename, COMMENT_MAX);  #endif } filename[FILENAME_MAX-1]='\0'; comment[COMMENT_MAX-1]='\0';#if SFX_LEVEL>=ARJSFXV if(!test_host_os((int)host_os)&&file_type==ARJT_TEXT)#else if(!test_host_os((int)host_os))#endif  to_7bit(filename); if(arj_flags&PATHSYM_FLAG)  name_to_hdr(filename); if(test_host_os((int)host_os))  #if SFX_LEVEL>=ARJSFXV   entry_pos=split_name(filename, NULL, NULL);  #else   entry_pos=split_name(filename);  #endif #if SFX_LEVEL<=ARJSFX  list_adapted_name=filename+entry_pos; #endif #if SFX_LEVEL>=ARJ  /* Convert the comment to 7 bits if the host OS is unknown to us */  if(!test_host_os(host_os))  {   replicate_comment();   to_7bit(tmp_comment);   dump_tmp_comment();  } #elif SFX_LEVEL==ARJSFX  if(!test_host_os(host_os))   to_7bit(comment);                    /* The advantage of NEAR memory... */ #endif #if SFX_LEVEL>=ARJ  /* This was a stub initially, and, anyway, is no longer applicable     -- ASR 16/02/2001 */  /* ftime_stamp=import_timestamp(ftime_stamp); */ #endif #if SFX_LEVEL<=ARJSFX  file_garbled=(arj_flags&GARBLED_FLAG)?1:0; #endif if(first!=0) {  #if SFX_LEVEL>=ARJ   if(arj_flags&GARBLED_FLAG)    encryption_applied=1;  #endif  #if SFX_LEVEL>=ARJSFXV   continued_nextvolume=(arj_flags&VOLUME_FLAG)?1:0;  #endif  if(arj_flags&SECURED_FLAG)  {   security_state=ARJSEC_SECURED;   #if SFX_LEVEL>=ARJ    secured_size=origsize;   #endif   arjsec_offset=file_crc;  }  #if SFX_LEVEL>=ARJSFXV   ext_hdr_flags=ext_flags&0x0F;        /* Mask only the currently supported                                           values */  #endif  if(arj_flags&DUAL_NAME_FLAG)   dual_name=1;  #if SFX_LEVEL>=ARJSFXV   if(arj_flags&ANSICP_FLAG)    ansi_codepage=1;   #if SFX_LEVEL>=ARJ    if(arj_flags&PROT_FLAG)     arjprot_tail=1;    /* Chapter-archive specific processing */    if(first==1&&chapter_number>0)    {     if(add_command&&current_chapter<=CHAPTERS_MAX)     {      chapter_number++;      comment_entries++;     }     if(!first_vol_passed)      total_chapters=chapter_number;     else      chapter_number=total_chapters;     if(total_chapters>CHAPTERS_MAX)      error(M_TOO_MANY_CHAPTERS, CHAPTERS_MAX);    }   #endif  #endif } #if SFX_LEVEL>=ARJSFXV  else  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -