?? arj_arcv.c
字號:
#if SFX_LEVEL>=ARJ volume_flag_set=force_volume_flag=1; #else volume_flag_set=1; #endif else volume_flag_set=0; } #endif #if SFX_LEVEL>=ARJ if(file_type==ARJT_CHAPTER&&chapter_number>recent_chapter) recent_chapter=chapter_number; /* ARJSFX/ARJSFXV archives have some limitations, check it here */ if(create_sfx!=SFXCRT_NONE||(sfx_desc_word!=0&&modify_command)) { if(method==4) error(M_INVALID_METHOD_SFX); if(total_chapters>0) error(M_CHAPTER_SFX_CREATION); if(!multivolume_option&&file_type==ARJT_LABEL) error(M_NO_LABELS_IN_SFX); if(!win32_platform&&create_sfx&&!multivolume_option&& ext_hdr_flags>ENCRYPT_GOST256L) error(M_WRONG_ENC_VERSION, ext_hdr_flags); /* ARJSFXJR archives have yet more limitations that need to be checked */ if(create_sfx==SFXCRT_SFXJR||sfx_desc_word==SFXDESC_SFXJR) {#if TARGET==UNIX if(file_type==ARJT_TEXT)#else if(file_type==ARJT_TEXT||lfn_supported!=LFN_NOT_SUPPORTED)#endif error(M_TEXTMODE_LFN_SFXJR); #if defined(HAVE_EAS) if(ea_supported) error(M_TEXTMODE_LFN_SFXJR); #endif /* Check for systems that are hostile to ARJSFXJR */ #if TARGET==DOS if(host_os!=OS) error(M_TEXTMODE_LFN_SFXJR); #elif TARGET!=UNIX if(!test_host_os(host_os)) error(M_TEXTMODE_LFN_SFXJR); #endif if(arj_flags&GARBLED_FLAG) error(M_NO_GARBLE_IN_SFXJR); } } #endif #if SFX_LEVEL>=ARJSFXV /* Reset the extended header buffers for noncontinued files */ if(!(arj_flags&EXTFILE_FLAG)&&cur_header_pos!=main_hdr_offset) { if(eh!=NULL) { eh_release(eh); eh=NULL; valid_ext_hdr=0; } ea_pwd_modifier=password_modifier; } #endif /* Process extended headers, if any */ while((header_id=fget_word(stream))!=0) { #if SFX_LEVEL>=ARJSFXV crc32term=CRC_MASK; if(fread(&id, 1, 1, stream)==0) error(M_CANTREAD); crc32_for_block(&id, 1); valid_ext_hdr=1; /* Skip the extended headers if the file is continued from the previous volume and we haven't caught the beginning */ if((arj_flags&EXTFILE_FLAG)&&eh==NULL) { fseek(stream, (long)header_id+3L, SEEK_CUR); valid_ext_hdr=0; } else { /* Perform early allocation of the extended header block */ if(eh==NULL) eh=eh_alloc(); /* Get the continuation flag */ if(fread(&is_continued, 1, 1, stream)==0) error(M_CANTREAD); crc32_for_block(&is_continued, 1); /* Collect the scattered data */ remainder=header_id-2; tmp_eh=eh_append(eh, id, NULL, remainder); dptr=tmp_eh->raw+(tmp_eh->size-remainder); tmp_eh->flags=is_continued?EH_PROCESSING:EH_UNPROCESSED; while(remainder>0) { fetch_size=min(remainder, sizeof(transfer_buf)); if(fread(transfer_buf, 1, fetch_size, stream)!=fetch_size) error(M_CANTREAD); far_memmove(dptr, transfer_buf, fetch_size); crc32_for_block(transfer_buf, fetch_size); remainder-=fetch_size; dptr+=fetch_size; } if(fget_longword(stream)!=(crc32term^CRC_MASK)) { if(ignore_crc_errors!=ICE_CRC) error(M_BAD_HEADER); else { eh_release(eh); eh=NULL; } } } #else fseek(stream, (long)header_id+4L, SEEK_CUR); #endif } return(1);}#if SFX_LEVEL<=ARJSFX#undef stream#endif#if SFX_LEVEL>=ARJ/* Fill general purpose header fields */static void fill_general_hdr(){ arj_nbr=ARJ_VERSION; arj_x_nbr=ARJ_X_VERSION; if(file_type==ARJT_DIR) arj_x_nbr=ARJ_XD_VERSION; else if(file_type==ARJT_UXSPECIAL) arj_x_nbr=ARJ_XU_VERSION; #if TARGET==DOS host_os=OS; #else host_os=(dos_host==CHO_USE_DOS)?OS_DOS:OS; #endif /* If LFNs are supported, stamp Win95 or WinNT/Win32 OS code */ #if TARGET==DOS if(lfn_supported!=LFN_NOT_SUPPORTED) { host_os=OS_WIN95; if(win32_platform) if(test_for_winnt()) host_os=OS_WINNT; /* Same as OS_WIN32 */ } #endif}/* Fills the basic header */void create_header(int first){ setup_hput(header); hput_byte(first_hdr_size); hput_byte(arj_nbr); hput_byte(arj_x_nbr); if(first&&dos_host==CHO_COMMENT) host_os=OS_DOS; hput_byte(host_os); hput_byte(arj_flags); hput_byte((char)method); hput_byte((char)file_type); hput_byte((!ts_valid(secondary_ftime))?password_modifier:0); if(ts_valid(secondary_ftime)) { hput_longword(ts_native(&secondary_ftime, OS)); garble_ftime=ts_native(&secondary_ftime, OS); } else { garble_ftime=ts_native(&ftime_stamp, host_os); hput_longword(garble_ftime); } hput_longword(compsize); hput_longword(origsize); hput_longword(file_crc); hput_word(entry_pos); hput_word(fm_native(&file_mode, host_os)); hput_byte(ext_flags); hput_byte(chapter_number); if(first) { if(first_hdr_size>=FIRST_HDR_SIZE_V) { hput_byte((char)prot_blocks); hput_byte(arjprot_id); hput_word(0); } } else { if(first_hdr_size<R9_HDR_SIZE) { if(arj_flags&EXTFILE_FLAG) hput_longword(resume_position); } else { hput_longword(resume_position); hput_longword(ts_native(&atime_stamp, host_os)); hput_longword(ts_native(&ctime_stamp, host_os)); hput_longword(0L); } }}/* Walks through the extended header structure, writing the header, advancing the pointers and updating the flags if necessary */static void proc_ext_hdr(unsigned int action){ char transfer_buf[64]; char FAR *dptr; struct ext_hdr FAR *p_eh; unsigned int remainder, fetch_size; char id, cont_id; long cur_capacity; unsigned long rem_size; cur_capacity=ext_hdr_capacity; p_eh=eh; while(cur_capacity>0&&(p_eh=eh_find_pending(p_eh))!=NULL) { rem_size=p_eh->size-p_eh->cur_offset; if((unsigned long)cur_capacity+2<=rem_size) { if(action&EHUF_COMMIT) { p_eh->flags=EH_PROCESSING; p_eh->cur_offset+=ext_hdr_capacity; } remainder=min(cur_capacity, rem_size); cont_id=1; cur_capacity=0; } else { if(action&EHUF_COMMIT) p_eh->flags=EH_FINALIZED; remainder=rem_size; /* ASR fix 15/05/2003 */ /* Take out the ID/length/CRC32 and the data */ cur_capacity-=rem_size+EXT_HDR_OVERHEAD; cont_id=0; } if(action&EHUF_WRITE) { fput_word(remainder+2, aostream); crc32term=CRC_MASK; id=p_eh->tag; fwrite_crc(&id, 1, aostream); fwrite_crc(&cont_id, 1, aostream); dptr=p_eh->raw+p_eh->cur_offset; while(remainder>0) { fetch_size=min(sizeof(transfer_buf), remainder); far_memmove((char FAR *)transfer_buf, dptr, fetch_size); fwrite_crc(transfer_buf, fetch_size, aostream); dptr+=fetch_size; remainder-=fetch_size; } fput_dword(crc32term^CRC_MASK, aostream); } p_eh=p_eh->next; } if(multivolume_option&&p_eh!=NULL&&cur_capacity<=0&&(action&EHUF_SETFLAGS)) volume_flag_set=1; if(action&EHUF_COMMIT) ext_hdr_capacity=cur_capacity;}/* Writes the archive header to the aostream, calculating its CRC */void write_header(){ unsigned long hdr_offset; hdr_offset=ftell(aostream); if(ts_cmp(&ftime_stamp, &ftime_max)>0&&is_file_type(file_type)) ftime_max=ftime_stamp; fput_word(HEADER_ID, aostream); fput_word(basic_hdr_size, aostream); if(fflush(aostream)) error(M_DISK_FULL); if(hdr_offset>last_hdr_offset) last_hdr_offset=hdr_offset; if(file_type!=ARJT_COMMENT&&chapter_number>max_chapter) max_chapter=chapter_number; crc32term=CRC_MASK; fwrite_crc(header, basic_hdr_size, aostream); fput_dword(header_crc=crc32term^CRC_MASK, aostream); /* Store a portion or the entire extended header */ if(eh!=NULL&&hdr_offset!=main_hdr_offset) proc_ext_hdr(EHUF_WRITE|EHUF_SETFLAGS); fput_word(0, aostream);}/* Renames a file in archive. Returns 1 if a header update occured, 0 if not (no filename entered) */int rename_file(){ msg_cprintf(H_HL|H_NFMT, M_CURRENT_FILENAME, filename); msg_cprintf(0, M_ENTER_NEW_FILENAME); read_line(filename, FILENAME_MAX); alltrim(filename); if(filename[0]=='\0') return(0); far_strcpyn(comment, (char FAR *)hdr_comment, COMMENT_MAX); strcpy(hdr_filename, filename); case_path(hdr_filename); entry_pos=split_name(hdr_filename, NULL, NULL); if(translate_path(hdr_filename)) arj_flags|=PATHSYM_FLAG; else arj_flags&=~PATHSYM_FLAG; calc_comment_offset(); far_strcpyn((char FAR *)hdr_comment, comment, COMMENT_MAX); create_header(0); calc_basic_hdr_size(); return(1);}/* Reads a comment from the given file and stores it in the buffer. Supplying a null filename to it will strip the comment (note that null filename is NUL in DOS and /dev/null under UNIX) */static void read_comment(char *buffer, char *name){ FILE *stream; int llen; /* Length of last read line */ if(!strcmp_os(buffer, dev_null)) return; stream=file_open_noarch(name, m_r); while(fgets(buffer, COMMENT_MAX, stream)!=NULL) { if((llen=strlen(buffer))+strlen(tmp_comment)+4>=COMMENT_MAX) break; if(buffer[llen-1]!=LF) buffer[llen-1]=LF; strcat(tmp_comment, buffer); } fclose(stream);}/* A routine to supply comments */int supply_comment(char *cmtname, char *name){ char *tmp_cmtline; int maxlines; int curline; tmp_cmtline=malloc_msg(COMMENT_MAX+1); replicate_comment(); msg_cprintf(H_HL|H_NFMT, M_CURRENT_COMMENT, name); display_comment(comment); /* ASR enhancement -- 09/01/2001 */ if(disable_comment_series&&first_vol_passed) { comment[0]='\0'; calc_basic_hdr_size(); return(1); } /* If the filename given is blank, enter the comment manually */ if(cmtname[0]=='\0') { maxlines=MAX_COMMENT_LINES; msg_cprintf(H_HL|H_NFMT, M_ENTER_COMMENT, maxlines, name); for(curline=0; curline<maxlines; curline++) { msg_cprintf(0, (FMSG *)le_prompt, curline+1); read_line(tmp_cmtline, INPUT_LENGTH); msg_strcpy(strcpy_buf, M_COMMENT_TERMINATOR); if(!stricmp(strcpy_buf, tmp_cmtline)) break; if(curline==0) { tmp_comment[0]='\0'; if(tmp_cmtline[0]==listchar) { if(translate_unix_paths) unix_path_to_dos(tmp_cmtline+1); read_comment(tmp_cmtline, tmp_cmtline+1); } else { strcat(tmp_comment, tmp_cmtline); strcat(tmp_comment, lf); } } else { strcat(tmp_comment, tmp_cmtline); strcat(tmp_comment, lf); } } } else { tmp_comment[0]='\0'; read_comment(tmp_cmtline, cmtname); curline=1; } dump_tmp_comment(); free(tmp_cmtline); if(curline>0) { msg_strcpy(strcpy_buf, M_EMPTY_COMMENT); /* Strip blank comments */ if(!far_strcmp(comment, (char FAR *)strcpy_buf)) comment[0]='\0'; far_strcpyn((char FAR *)hdr_comment, comment, COMMENT_MAX); calc_basic_hdr_size(); return(1); } else return(0);}/* Fills the basic archive header with needed information */void fill_archive_header(){ first_hdr_size=FIRST_HDR_SIZE_V; cur_time_stamp(&ftime_stamp); compsize=ts_native(&ftime_stamp, host_os); if(ts_valid(secondary_ftime)) compsize=ts_native(&secondary_ftime, host_os); file_type=ARJT_COMMENT; method=0; entry_pos=0; origsize=0L; file_crc=0L; fm_store(&file_mode, OS_DOS, 0); host_data=0; ext_flags=0; chapter_number=0; if(chapter_mode!=0) { if(total_chapters==0) chapter_number=total_chapters=1; else chapter_number=total_chapters; } else { if(total_chapters!=0) chapter_number=total_chapters; } arj_flags=0; if(multivolume_option) arj_flags|=VOLUME_FLAG; if(add_command&&lfn_supported!=LFN_NOT_SUPPORTED&&(lfn_mode==LFN_DUAL_EXT||lfn_mode==LFN_DUAL)) arj_flags|=DUAL_NAME_FLAG; if(add_command&&use_ansi_cp) arj_flags|=ANSICP_FLAG; arjprot_id=use_sfxstub?SFXSTUB_FLAG:0; password_modifier=(char)ts_native(&ftime_stamp, OS_SPECIAL); ext_hdr_flags=0; if(garble_enabled) { arj_flags|=GARBLED_FLAG; encryption_applied=1; ext_hdr_flags=ENCRYPT_STD; if(gost_cipher==GOST256) ext_hdr_flags=ENCRYPT_UNK; else if(gost_cipher==GOST40) ext_hdr_flags=ENCRYPT_GOST40; } hdr_filename=&header[first_hdr_size]; split_name(archive_name, NULL, hdr_filename); if(translate_path(hdr_filename)) arj_flags|=PATHSYM_FLAG; calc_comment_offset(); hdr_comment[0]='\0'; fill_general_hdr(); create_header(1); calc_basic_hdr_size();}/* Final header pass: occurs at update of multivolume archives and those containing ARJ SECURITY. The operation variable specifies the action (one of FP_*) to be made. */void final_header(int operation){ unsigned long tmp_resume_position; int tmp_multivolume; /* Indicates that the file is continued on the next volume */ int tmp_cont_prev; /* Indicates that the file is continued from the previous volume */ unsigned long cur_pos; int cur_ext_hdr_flags; int tmp_prot_blocks; tmp_prot_blocks=prot_blocks; tmp_resume_position=resume_position; tmp_cont_prev=continued_prevvolume; tmp_multivolume=mvfile_type; cur_ext_hdr_flags=ext_hdr_flags; cur_pos=ftell(aostream); fseek(aostream, main_hdr_offset, SEEK_SET); read_header(2, aostream, archive_name); fseek(aostream, main_hdr_offset, SEEK_SET); if(operation==FP_SECURITY&&is_registered) { origsize=secured_size; file_crc=arjsec_offset; arj_flags|=SECURED_FLAG; method=2; fm_store(&file_mode, OS_SPECIAL, SECURED_MODE); } else if(operation==FP_PROT) { arj_flags|=PROT_FLAG; prot_blocks=tmp_prot_blocks;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -