как распаковать файл в памяти (c программированием)? - PullRequest
4 голосов
/ 12 октября 2009

Позвольте мне объяснить, что я пытаюсь понять:

У меня есть зашифрованный файл tar. Я могу расшифровать его в памяти, но, очевидно, я не могу записать расшифрованные данные обратно на жесткий диск в виде реального файла. Дешифрованные данные структурированы как буфер char * в памяти; как распаковать его в памяти?

Я не могу найти ответ в библиотеке libtar. Я также пытался распаковать его с execlp("tar", "tar", "-xvO", (void*)0). Но это не сработало, как я думал.

Кто-нибудь может дать мне подсказку о лучшем решении? Спасибо!

Ответы [ 5 ]

8 голосов
/ 12 октября 2009

Я подозреваю, что libtar - это ответ.

Используя libtar, вы можете указать свои собственные функции для открытия / закрытия, чтения и записи. С справочной страницы:

int tar_open(TAR **t, char *pathname, tartype_t *type, int oflags,
             int mode, int options);

Функция tar_open() открывает файл архива tar, соответствующий имя файла с помощью аргумента pathname. Аргумент oflags должен быть либо O_RDONLY, либо O_WRONLY.

Аргумент type определяет методы доступа для данного файла. тип. Структура tartype_t имеет члены с именами openfunc(), closefunc(), readfunc() и writefunc(), которые являются указателями на функции для открытия, закрытие, чтение и запись файла соответственно. Если тип NULL, тип файла по умолчанию - обычный файл, а стандарт open(), Используются функции close(), read() и write().

7 голосов
/ 12 октября 2009

Я сделал пример, как читать содержимое файла из tar-памяти в памяти. Функция is_file_in_tar() возвращает позицию length и start в файле name d, если он хранится в tar:

#include <stdio.h> 
#include <fcntl.h> 
#include <string.h> 
#include <sys/mman.h> 

struct tar {
  char name[100];   char _unused[24];
  char size[12];    char _padding[376];
} *tar;

int is_file_in_tar( struct tar *tar, char *name, char **start, int *length ){
  for( ; tar->name[0]; tar+=1+(*length+511)/512 ){
    sscanf( tar->size, "%o", length);
    if( !strcmp(tar->name,name) ){ *start = (char*)(tar+1); return 1; }
  }
  return 0;
}

int main(){
  int fd=open( "libtar-1.2.11.tar", O_RDONLY );
  tar=mmap(NULL, 808960, PROT_READ, MAP_PRIVATE, fd, 0);

  char *start; int length; char name[]="libtar-1.2.11/TODO";
  if( is_file_in_tar(tar,name,&start,&length) ) printf("%.*s",length,start);
}
2 голосов
/ 14 июня 2011

Я сделал для этого с этим кодом. Попробуй!

FILE*fp;
if( fp = popen("/bin/tar -xv -C /target/dir", "w") )
{
    fwrite(tar_buffer,1,tar_size,fp);
    pclose(fp);
    printf("Untar End %d Save file\n", tar_size);

}
2 голосов
/ 12 октября 2009

Вы можете запустить утилиту tar, перенаправленную на стандартный вывод. (tar --to-stdout). Вы должны запустить его, используя forkpty() или popen(), чтобы прочитать вывод.

0 голосов
/ 12 октября 2009

Просто распакуйте tmpfs в памяти, используя обычную операцию распаковки.

...