📄 gbc_archive.c
字号:
/*************************************************************************** archive.c The GAMBAS Archiver (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 __GBC_ARCHIVE_C#include <stdlib.h>#include <string.h>#include <stdio.h>#include <fcntl.h>#include <errno.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include "gb_common.h"#include "gb_error.h"#include "gb_str.h"#include "gb_file.h"#include "gb_magic.h"#include "gbc_archive.h"#include "gb_common_swap_temp.h"/*#define DEBUG*/PUBLIC char *ARCH_project;PUBLIC char *ARCH_project_name;PUBLIC char *ARCH_output;PUBLIC boolean ARCH_verbose = FALSE;PUBLIC boolean ARCH_swap = FALSE;PRIVATE int arch_dir_pos;PRIVATE TABLE *arch_table;PRIVATE FILE *arch_file = NULL;PRIVATE char arch_buffer[4096];PRIVATE long pos_start;PRIVATE void write_long(ulong val){ if (ARCH_swap) SWAP_long((long *)&val); if (fwrite(&val, sizeof(ulong), 1, arch_file) < 1) THROW("Write error");}PRIVATE void write_short(ushort val){ if (ARCH_swap) SWAP_short((short *)&val); if (fwrite(&val, sizeof(ushort), 1, arch_file) < 1) THROW("Write error");}PRIVATE long get_pos(void){ return ftell(arch_file);}PRIVATE void write_long_at(long pos, ulong val){ long old_pos = get_pos(); fseek(arch_file, pos, SEEK_SET); write_long(val); fseek(arch_file, old_pos, SEEK_SET);}PRIVATE void write_string(const char *str, int len){ if (fwrite(str, sizeof(char), len, arch_file) < len) THROW("Write error");}PRIVATE void make_executable(void){ struct stat info; if (stat(ARCH_output, &info) == 0) if (chmod(ARCH_output, info.st_mode | S_IXUSR | S_IXGRP | S_IXOTH) == 0) return; THROW("Cannot make executable: &1", strerror(errno));}PUBLIC void ARCH_define_project(const char *project){ char *name; char *dir; if (project == NULL) project = FILE_get_current_dir(); chdir(project); dir = STR_copy(FILE_get_current_dir()); arch_dir_pos = strlen(dir) + 1; ARCH_project = STR_copy(FILE_cat(dir, ".project", NULL)); name = STR_copy(FILE_get_name(dir)); /*ARCH_project_name = STR_copy(FILE_set_ext(name, NULL));*/ ARCH_project_name = STR_copy(name); ARCH_output = STR_copy(FILE_cat(dir, ARCH_project_name, NULL)); STR_free(name); STR_free(dir);}PUBLIC void ARCH_init(void){ TABLE_create(&arch_table, sizeof(ARCH_SYMBOL), TF_NORMAL); arch_file = fopen(ARCH_output, "w"); if (arch_file == NULL) THROW("Cannot create temporary archive file: &1", ARCH_output); fprintf(arch_file, "#!/usr/bin/gbx -x\n"); while (get_pos() < 31) fprintf(arch_file, " "); fprintf(arch_file, "\n"); write_long(ARCH_MAGIC); write_long(ARCH_VERSION); pos_start = get_pos(); write_long(0); write_long(0); write_long(0); write_long(0); write_long_at(pos_start, get_pos());}PUBLIC void ARCH_exit(void){ int i; ARCH_SYMBOL *sym; long pos_str; /* �riture des cha�es */ write_long_at(pos_start + sizeof(long), get_pos()); pos_str = 0; for (i = 0; i < TABLE_count(arch_table); i++) { sym = (ARCH_SYMBOL *)TABLE_get_symbol_sort(arch_table, i); write_string(sym->symbol.name, sym->symbol.len); } /* �riture de la table des symboles */ write_long_at(pos_start + sizeof(long) * 2, get_pos()); write_long_at(pos_start + sizeof(long) * 3, TABLE_count(arch_table)); for (i = 0; i < TABLE_count(arch_table); i++) { sym = (ARCH_SYMBOL *)TABLE_get_symbol_sort(arch_table, i); write_short((ushort)i); write_short(sym->symbol.len); write_long(pos_str); write_long(sym->pos); write_long(sym->len); pos_str += sym->symbol.len; } /* fermeture du fichier */ fclose(arch_file); make_executable(); /* on lib�e tout */ for (i = 0; i < TABLE_count(arch_table); i++) STR_free(TABLE_get_symbol(arch_table, i)->name); TABLE_delete(&arch_table); STR_free(ARCH_output); STR_free(ARCH_project); STR_free(ARCH_project_name);}PUBLIC void ARCH_add_file(const char *path){ char *rel_path; ARCH_SYMBOL *sym; FILE *file; struct stat info; long len, len_read; rel_path = STR_copy(&path[arch_dir_pos]); TABLE_add_symbol(arch_table, rel_path, strlen(rel_path), (SYMBOL **)&sym, NULL); sym->pos = get_pos(); file = fopen(path, "r"); if (file == NULL) THROW("Cannot open file '&1'", path); fstat(fileno(file), &info); sym->len = info.st_size; len = sym->len; while (len > 0) { len_read = fread(arch_buffer, 1, sizeof(arch_buffer), file); if (len_read > 0) fwrite(arch_buffer, 1, len_read, arch_file); if (len_read < sizeof(arch_buffer)) { if (ferror(file)) THROW("Cannot read file '&1': &2", path, strerror(errno)); else break; } } fclose(file); if (ARCH_verbose) printf("Adding file %s (%ld bytes)\n", rel_path, sym->len);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -