📄 arc.c
字号:
allocated = 1024; compressed = (char *)safe_malloc(allocated); offset = 0; space = allocated; while((nbytes = zip_deflate(compressor, compressed + offset, space)) > 0) { offset += nbytes; space -= nbytes; if(space == 0) { space = allocated; allocated += space; compressed = (char *)safe_realloc(compressed, allocated); } } close_deflate_handler(compressor); if(offset == 0) { free(buff); return NULL; } *compressed_size = offset; return compressed;}void *arc_decompress(void *buff, long bufsiz, long *decompressed_size){ InflateHandler decompressor; long allocated, offset, space, nbytes; char *decompressed; compress_buff = (char *)buff; compress_buff_len = bufsiz; decompressor = open_inflate_handler(arc_compress_func, NULL); allocated = 1024; decompressed = (char *)safe_malloc(allocated); offset = 0; space = allocated; while((nbytes = zip_inflate(decompressor, decompressed + offset, space)) > 0) { offset += nbytes; space -= nbytes; if(space == 0) { space = allocated; allocated += space; decompressed = (char *)safe_realloc(decompressed, allocated); } } close_inflate_handler(decompressor); if(offset == 0) { free(buff); return NULL; } *decompressed_size = offset; return decompressed;}void free_archive_files(void){ ArchiveEntryNode *entry, *ecur; ArchiveFileList *acur; while(arc_filelist) { acur = arc_filelist; arc_filelist = arc_filelist->next; entry = acur->entry_list; while(entry) { ecur = entry; entry = entry->next; free_entry_node(ecur); } free(acur->archive_name); free(acur); }}/******************************************************************************* url_arc*****************************************************************************/typedef struct _URL_arc{ char common[sizeof(struct _URL)]; URL instream; long pos, size; int comptype; void *decoder;} URL_arc;static long url_arc_read(URL url, void *buff, long n);static long url_arc_tell(URL url);static void url_arc_close(URL url);static long archiver_read_func(char *buff, long buff_size, void *v){ URL_arc *url; long n; url = (URL_arc *)v; if(url->size < 0) n = buff_size; else { n = url->size - url->pos; if(n > buff_size) n = buff_size; } if(n <= 0) return 0; n = url_read(url->instream, buff, n); if(n <= 0) return n; return n;}URL url_arc_open(char *name){ URL_arc *url; char *base, *p; int len; ArchiveFileList *afl; ArchiveEntryNode *entry; URL instream; if((p = strrchr(name, '#')) == NULL) return NULL; len = p - name; base = new_segment(&arc_buffer, len + 1); memcpy(base, name, len); base[len] = '\0'; base = url_expand_home_dir(base); if((afl = find_arc_filelist(base)) == NULL) afl = regist_archive(base); if(afl == NULL) return NULL; reuse_mblock(&arc_buffer); /* free `base' */ name += len + 1; while(name[0] == '/') name++; /* skip '/'s right after # */ for(entry = afl->entry_list; entry; entry = entry->next) { if(strcasecmp(entry->name, name) == 0) break; } if(entry == NULL) return NULL; if(entry->cache != NULL) instream = url_mem_open((char *)entry->cache + entry->start, entry->compsize, 0); else { if((instream = url_file_open(base)) == NULL) return NULL; url_seek(instream, entry->start, 0); } url = (URL_arc *)alloc_url(sizeof(URL_arc)); if(url == NULL) { url_errno = errno; return NULL; } /* open decoder */ switch(entry->comptype) { case ARCHIVEC_STORED: /* No compression */ case ARCHIVEC_LZHED_LH0: /* -lh0- */ case ARCHIVEC_LZHED_LZ4: /* -lz4- */ url->decoder = NULL; case ARCHIVEC_DEFLATED: /* deflate */ url->decoder = (void *)open_inflate_handler(archiver_read_func, url); if(url->decoder == NULL) { url_arc_close((URL)url); return NULL; } break; case ARCHIVEC_IMPLODED_LIT8: case ARCHIVEC_IMPLODED_LIT4: case ARCHIVEC_IMPLODED_NOLIT8: case ARCHIVEC_IMPLODED_NOLIT4: url->decoder = (void *)open_explode_handler(archiver_read_func, entry->comptype - ARCHIVEC_IMPLODED - 1, entry->compsize, entry->origsize, url); if(url->decoder == NULL) { url_arc_close((URL)url); return NULL; } break; case ARCHIVEC_LZHED_LH1: /* -lh1- */ case ARCHIVEC_LZHED_LH2: /* -lh2- */ case ARCHIVEC_LZHED_LH3: /* -lh3- */ case ARCHIVEC_LZHED_LH4: /* -lh4- */ case ARCHIVEC_LZHED_LH5: /* -lh5- */ case ARCHIVEC_LZHED_LZS: /* -lzs- */ case ARCHIVEC_LZHED_LZ5: /* -lz5- */ case ARCHIVEC_LZHED_LHD: /* -lhd- */ case ARCHIVEC_LZHED_LH6: /* -lh6- */ case ARCHIVEC_LZHED_LH7: /* -lh7- */ url->decoder = (void *)open_unlzh_handler( archiver_read_func, lzh_methods[entry->comptype - ARCHIVEC_LZHED - 1], entry->compsize, entry->origsize, url); if(url->decoder == NULL) { url_arc_close((URL)url); return NULL; } break; default: url_arc_close((URL)url); return NULL; } /* common members */ URLm(url, type) = URL_arc_t; URLm(url, url_read) = url_arc_read; URLm(url, url_gets) = NULL; URLm(url, url_fgetc) = NULL; URLm(url, url_seek) = NULL; URLm(url, url_tell) = url_arc_tell; URLm(url, url_close) = url_arc_close; /* private members */ url->instream = instream; url->pos = 0; url->size = entry->origsize; url->comptype = entry->comptype; return (URL)url;}static long url_arc_read(URL url, void *vp, long bufsiz){ URL_arc *urlp = (URL_arc *)url; long n = 0; int comptype; void *decoder; char *buff = (char *)vp; if(urlp->pos == -1) return 0; comptype = urlp->comptype; decoder = urlp->decoder; switch(comptype) { case ARCHIVEC_STORED: case ARCHIVEC_LZHED_LH0: /* -lh0- */ case ARCHIVEC_LZHED_LZ4: /* -lz4- */ n = archiver_read_func(buff, bufsiz, (void *)urlp); break; case ARCHIVEC_DEFLATED: n = zip_inflate((InflateHandler)decoder, buff, bufsiz); break; case ARCHIVEC_IMPLODED_LIT8: case ARCHIVEC_IMPLODED_LIT4: case ARCHIVEC_IMPLODED_NOLIT8: case ARCHIVEC_IMPLODED_NOLIT4: n = explode((ExplodeHandler)decoder, buff, bufsiz); break; case ARCHIVEC_LZHED_LH1: /* -lh1- */ case ARCHIVEC_LZHED_LH2: /* -lh2- */ case ARCHIVEC_LZHED_LH3: /* -lh3- */ case ARCHIVEC_LZHED_LH4: /* -lh4- */ case ARCHIVEC_LZHED_LH5: /* -lh5- */ case ARCHIVEC_LZHED_LZS: /* -lzs- */ case ARCHIVEC_LZHED_LZ5: /* -lz5- */ case ARCHIVEC_LZHED_LHD: /* -lhd- */ case ARCHIVEC_LZHED_LH6: /* -lh6- */ case ARCHIVEC_LZHED_LH7: /* -lh7- */ n = unlzh((UNLZHHandler)decoder, buff, bufsiz); break; case ARCHIVEC_UU: /* uu encoded */ case ARCHIVEC_B64: /* base64 encoded */ case ARCHIVEC_QS: /* quoted string encoded */ case ARCHIVEC_HQX: /* HQX encoded */ n = url_read((URL)decoder, buff, bufsiz); break; } if(n > 0) urlp->pos += n; return n;}static long url_arc_tell(URL url){ return ((URL_arc *)url)->pos;}static void url_arc_close(URL url){ URL_arc *urlp = (URL_arc *)url; void *decoder; int save_errno = errno; /* 1. close decoder * 2. close decode_stream * 3. free url */ decoder = urlp->decoder; if(decoder != NULL) { switch(urlp->comptype) { case ARCHIVEC_DEFLATED: close_inflate_handler((InflateHandler)decoder); break; case ARCHIVEC_IMPLODED_LIT8: case ARCHIVEC_IMPLODED_LIT4: case ARCHIVEC_IMPLODED_NOLIT8: case ARCHIVEC_IMPLODED_NOLIT4: close_explode_handler((ExplodeHandler)decoder); break; case ARCHIVEC_LZHED_LH1: /* -lh1- */ case ARCHIVEC_LZHED_LH2: /* -lh2- */ case ARCHIVEC_LZHED_LH3: /* -lh3- */ case ARCHIVEC_LZHED_LH4: /* -lh4- */ case ARCHIVEC_LZHED_LH5: /* -lh5- */ case ARCHIVEC_LZHED_LZS: /* -lzs- */ case ARCHIVEC_LZHED_LZ5: /* -lz5- */ case ARCHIVEC_LZHED_LHD: /* -lhd- */ case ARCHIVEC_LZHED_LH6: /* -lh6- */ case ARCHIVEC_LZHED_LH7: /* -lh7- */ close_unlzh_handler((UNLZHHandler)decoder); break; case ARCHIVEC_UU: /* uu encoded */ case ARCHIVEC_B64: /* base64 encoded */ case ARCHIVEC_QS: /* quoted string encoded */ case ARCHIVEC_HQX: /* HQX encoded */ url_close((URL)decoder); break; } } if(urlp->instream != NULL) url_close(urlp->instream); free(urlp); errno = save_errno;}/************** wildmat ***************//* What character marks an inverted character class? */#define NEGATE_CLASS '!'/* Is "*" a common pattern? */#define OPTIMIZE_JUST_STAR/* Do tar(1) matching rules, which ignore a trailing slash? */#undef MATCH_TAR_PATTERN/* Define if case is ignored */#define MATCH_CASE_IGNORE#include <ctype.h>#define TEXT_CASE_CHAR(c) (toupper(c))#define CHAR_CASE_COMP(a, b) (TEXT_CASE_CHAR(a) == TEXT_CASE_CHAR(b))static char *ParseHex(char *p, int *val){ int i, v; *val = 0; for(i = 0; i < 2; i++) { v = *p++; if('0' <= v && v <= '9') v = v - '0'; else if('A' <= v && v <= 'F') v = v - 'A' + 10; else if('a' <= v && v <= 'f') v = v - 'a' + 10; else return NULL; *val = (*val << 4 | v); } return p;}/* * Match text and p, return TRUE, FALSE, or ABORT. */static int DoMatch(char *text, char *p){ register int last; register int matched; register int reverse; for ( ; *p; text++, p++) { if (*text == '\0' && *p != '*') return ABORT; switch (*p) { case '\\': p++; if(*p == 'x') { int c; if((p = ParseHex(++p, &c)) == NULL) return ABORT; if(*text != c) return FALSE; continue; } /* Literal match with following character. */ /* FALLTHROUGH */ default: if (*text != *p) return FALSE; continue; case '?': /* Match anything. */ continue; case '*': while (*++p == '*') /* Consecutive stars act just like one. */ continue; if (*p == '\0') /* Trailing star matches everything. */ return TRUE; while (*text) if ((matched = DoMatch(text++, p)) != FALSE) return matched; return ABORT; case '[': reverse = p[1] == NEGATE_CLASS ? TRUE : FALSE; if (reverse) /* Inverted character class. */ p++; matched = FALSE; if (p[1] == ']' || p[1] == '-') if (*++p == *text) matched = TRUE; for (last = *p; *++p && *p != ']'; last = *p) /* This next line requires a good C compiler. */ if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p) matched = TRUE; if (matched == reverse) return FALSE; continue; } }#ifdef MATCH_TAR_PATTERN if (*text == '/') return TRUE;#endif /* MATCH_TAR_ATTERN */ return *text == '\0';}static int DoCaseMatch(char *text, char *p){ register int last; register int matched; register int reverse; for(; *p; text++, p++) { if(*text == '\0' && *p != '*') return ABORT; switch (*p) { case '\\': p++; if(*p == 'x') { int c; if((p = ParseHex(++p, &c)) == NULL) return ABORT; if(!CHAR_CASE_COMP(*text, c)) return FALSE; continue; } /* Literal match with following character. */ /* FALLTHROUGH */ default: if(!CHAR_CASE_COMP(*text, *p)) return FALSE; continue; case '?': /* Match anything. */ continue; case '*': while(*++p == '*') /* Consecutive stars act just like one. */ continue; if(*p == '\0') /* Trailing star matches everything. */ return TRUE; while(*text) if((matched = DoCaseMatch(text++, p)) != FALSE) return matched; return ABORT; case '[': reverse = p[1] == NEGATE_CLASS ? TRUE : FALSE; if(reverse) /* Inverted character class. */ p++; matched = FALSE; if(p[1] == ']' || p[1] == '-') { if(*++p == *text) matched = TRUE; } for(last = TEXT_CASE_CHAR(*p); *++p && *p != ']'; last = TEXT_CASE_CHAR(*p)) { /* This next line requires a good C compiler. */ if(*p == '-' && p[1] != ']') { p++; if(TEXT_CASE_CHAR(*text) <= TEXT_CASE_CHAR(*p) && TEXT_CASE_CHAR(*text) >= last) matched = TRUE; } else { if(CHAR_CASE_COMP(*text, *p)) matched = TRUE; } } if(matched == reverse) return FALSE; continue; } }#ifdef MATCH_TAR_PATTERN if (*text == '/') return TRUE;#endif /* MATCH_TAR_ATTERN */ return *text == '\0';}/*** User-level routine. Returns TRUE or FALSE.*/int arc_wildmat(char *text, char *p){#ifdef OPTIMIZE_JUST_STAR if (p[0] == '*' && p[1] == '\0') return TRUE;#endif /* OPTIMIZE_JUST_STAR */ return DoMatch(text, p) == TRUE;}int arc_case_wildmat(char *text, char *p){#ifdef OPTIMIZE_JUST_STAR if (p[0] == '*' && p[1] == '\0') return TRUE;#endif /* OPTIMIZE_JUST_STAR */ return DoCaseMatch(text, p) == TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -