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

📄 gbx_archive.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
字号:
/***************************************************************************  archive.c  The archive management routines  (c) 2000-2004 Beno� Minisini <gambas@users.sourceforge.net>  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 1, or (at your option)  any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __GBX_ARCHIVE_C#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include "gb_common.h"#include "gb_common_swap.h"#include "gb_error.h"#include "gbx_value.h"#include "gb_limit.h"#include "gb_magic.h"#include "gb_alloc.h"#include "gbx_string.h"#include "gbx_regexp.h"#include "gbx_exec.h"#include "gbx_list.h"#include "gbx_project.h"#include "gbx_archive.h"/*PRIVATE int arch_fd = -1;PRIVATE ARCH_HEADER arch_header;PRIVATE char *arch_string;PRIVATE ARCH_SYMBOL *arch_symbol;*/PUBLIC ARCHIVE *ARCHIVE_main = NULL;PUBLIC ARCHIVE *ARCHIVE_last = NULL;PRIVATE char *arch_pattern = NULL;PRIVATE long arch_index = 0;PRIVATE ARCHIVE *arch_dir = NULL;PRIVATE ARCHIVE *_arch_list = NULL;static bool _swap;PRIVATE void arch_error(const char *msg){  if (msg == NULL)    THROW(E_ARCH, strerror(errno));  else    THROW(E_ARCH, msg);}PRIVATE void set_pos(ARCHIVE *arch, long pos){  if (lseek(arch->fd, pos, SEEK_SET) < 0)    arch_error(NULL);}PRIVATE void read_at(ARCHIVE *arch, long pos, void *buf, long len){  set_pos(arch, pos);  if (read(arch->fd, buf, len) != len)    arch_error(NULL);}PUBLIC void ARCH_create(const char *path){  ARCHIVE *arch;  long len;  int i;  long pos;  /*fprintf(stderr, "Using archive: %s\n", path);*/  ALLOC_ZERO(&arch, sizeof(ARCHIVE), "ARCH_create");  LIST_insert(&_arch_list, arch, &arch->list);  arch->fd = open(path, O_RDONLY);  if (arch->fd < 0)    THROW(E_OPEN, path, strerror(errno));  /* Lecture de l'ent�e */  read_at(arch, 32, &arch->header, sizeof(ARCH_HEADER));  _swap = arch->header.magic != ARCH_MAGIC;  if (_swap)  {  	fprintf(stderr, "gbx: Swapping archive\n");  	SWAP_longs((long *)&arch->header, 6);	}  /* Lecture des cha�es */  len = arch->header.pos_table - arch->header.pos_string;  if (len <= 0)    arch_error("corrupted header");  ALLOC(&arch->string, len, "ARCH_init");  read_at(arch, arch->header.pos_string, arch->string, len);  /* Lecture de la table */  len = arch->header.n_symbol * sizeof(ARCH_SYMBOL);  if (len <= 0)    arch_error("corrupted header");  ALLOC(&arch->symbol, len, "ARCH_init");  read_at(arch, arch->header.pos_table, arch->symbol, len);  /* Relocation des cha�es */  pos = 0;  for (i = 0; i < arch->header.n_symbol; i++)  {    if (_swap)    {    	SWAP_short((short *)&arch->symbol[i].sym.sort);    	SWAP_short((short *)&arch->symbol[i].sym.len);			SWAP_long(&arch->symbol[i].pos);			SWAP_long(&arch->symbol[i].len);    }    arch->symbol[i].sym.name = &arch->string[pos];    pos += arch->symbol[i].sym.len;  }}PUBLIC void ARCH_delete(ARCHIVE *arch){  LIST_remove(&_arch_list, arch, &arch->list);  FREE(&arch->string, "ARCH_delete");  FREE(&arch->symbol, "ARCH_delete");  close(arch->fd);  FREE(&arch, "ARCH_delete");}PUBLIC void ARCH_init(const char *path){  ARCH_create(path);  ARCHIVE_main = _arch_list;}PUBLIC void ARCH_exit(void){  while (_arch_list)    ARCH_delete(_arch_list);  STRING_free(&arch_pattern);}PUBLIC void ARCH_add(const char *path){  const char *arch_path;  struct stat info;  char *name;  if (FILE_is_relative(path))  {    arch_path = FILE_cat(FILE_get_dir(PROJECT_path), path, NULL);    if (stat(arch_path, &info) == 0)    {      if (S_ISDIR(info.st_mode))      {        STRING_new(&name, FILE_get_name(arch_path), 0);        arch_path = FILE_cat(arch_path, name, NULL);        STRING_free(&name);      }    }    else      arch_path = FILE_cat(PROJECT_exec_path, "bin", path, NULL);  }  else    arch_path = path;  if (stat(arch_path, &info) != 0)    THROW(E_LIBRARY, path, "File not found");  ARCH_create(arch_path);}PRIVATE bool ARCH_current(ARCHIVE **parch){  ARCHIVE *arch = NULL;  /*if (!CP) && EXEC_arch)    arch = _arch_list;*/  if (CP)    arch = (ARCHIVE *)CP->belong;  if (!arch)    arch = _arch_list;  *parch = arch;  return arch != NULL;}PUBLIC bool ARCH_get(const char *path, int len_path, ARCH_FIND *find){  long index;  ARCH_SYMBOL *sym;  ARCHIVE *arch;  if (!ARCH_current(&arch))    return TRUE;  if (len_path <= 0)    len_path = strlen(path);  if (len_path == 0)    return TRUE;  for(;;)  {    SYMBOL_find(arch->symbol, arch->header.n_symbol, sizeof(ARCH_SYMBOL), TF_NORMAL, path, len_path, 0, &index);    if (index != NO_SYMBOL)      break;    arch = arch->list.next;    if (!arch)      return TRUE;  }  sym = &arch->symbol[index];  find->sym = sym;  find->pos = find->sym->pos;  find->len = sym->len;  find->arch = arch;  ARCHIVE_last = arch;  return FALSE;}PUBLIC bool ARCH_exist(const char *path){  ARCH_FIND find;  return (!ARCH_get(path, 0, &find));}PUBLIC void ARCH_stat(const char *path, FILE_STAT *info){  ARCH_FIND find;  struct stat buf;  if (!ARCH_get(path, 0, &find))    THROW_SYSTEM(ENOENT, path);  fstat(find.arch->fd, &buf);  info->type = GB_STAT_FILE;  info->mode = 0400;  info->size = find.len;  info->atime = (long)buf.st_mtime;  info->mtime = (long)buf.st_mtime;  info->ctime = (long)buf.st_mtime;  info->hidden = (*FILE_get_name(path) == '.');  info->uid = buf.st_uid;  info->gid = buf.st_gid;}PUBLIC boolean ARCH_read(ARCHIVE *arch, long pos, void *buffer, long len){  if (lseek(arch->fd, pos, SEEK_SET) < 0)    return TRUE;  if (read(arch->fd, buffer, len) != len)    return TRUE;  return FALSE;}PUBLIC void ARCH_dir_first(const char *path, const char *pattern){  if (pattern == NULL)    pattern = "*";  path = FILE_cat(path, pattern, NULL);  if (arch_pattern)    STRING_free(&arch_pattern);  STRING_new(&arch_pattern, path, FILE_buffer_length());  arch_index = 0;  arch_dir = _arch_list;}PUBLIC bool ARCH_dir_next(char **name, long *len){  SYMBOL *sym;  /*if (arch_fd < 0)    return FILE_dir_next(name, len);*/  if (!arch_dir)    return TRUE;  for(;;)  {    if (arch_index >= arch_dir->header.n_symbol)    {      arch_dir = arch_dir->list.next;      if (!arch_dir)        return TRUE;      else      {        arch_index = 0;        continue;      }    }    sym = (SYMBOL *)&arch_dir->symbol[arch_index];    sym = (SYMBOL *)&arch_dir->symbol[sym->sort];    if (arch_pattern == NULL)      break;    arch_index++;    if (REGEXP_match(arch_pattern, STRING_length(arch_pattern), sym->name, sym->len))      break;  }  *name = sym->name;  *len = sym->len;  return FALSE;}

⌨️ 快捷键说明

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