2013-07-21 4 views
0

Я пытаюсь добавить новый член файла с форматом ar_hdr и поместить его сразу после последнего элемента в архиве. Мой код компилируется, но когда я хочу просмотреть имя файла с помощью команды ar -t, у меня появилось сообщение об ошибке: ar: hello.a: Недопустимый тип файла или формат. Может кто-то взглянуть на мой код и дать мне несколько советов о том, как его исправить? Благодарю.«Недопустимый тип файла или формат»

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <sys/utsname.h> 
#include <ctype.h> 
#include <string.h> 
#include <ar.h> 

#define BLOCKSIZE 1 

int main (int argc, char **argv) 
{ 
    char *archive = argv[1]; 
    char *read_file = argv[2]; 

    int in_fd; 
    int out_fd; 

    char title[] = ARMAG; //constant define in ar.h 
    char buf[BLOCKSIZE]; 

    int num_read; 
    int num_written; 

    struct stat stat_file; 
    struct ar_hdr my_ar; 

    //open read_file (i.e., text file) 
    if (stat(read_file, &stat_file) == -1){ 
     perror("Error in Stat"); 
     exit(-1); 
    } 

    //assign file info to struct dhr (my_ar)  
    sprintf(my_ar.ar_name, "%s", read_file); 
    sprintf(my_ar.ar_date, "%ld", stat_file.st_mtimespec.tv_sec); 
    sprintf(my_ar.ar_uid, "%i", stat_file.st_uid); 
    sprintf(my_ar.ar_gid, "%i", stat_file.st_gid); 
    sprintf(my_ar.ar_mode, "%o", stat_file.st_mode) ; 
    sprintf(my_ar.ar_size, "%lld", stat_file.st_size) ; 


    //0666 - open archive 
    out_fd = open(archive, O_CREAT | O_WRONLY | O_APPEND, 0666); 
    if (out_fd == -1) { 
     perror("Canot open/create output file"); 
     exit(-1); 
    } 

    //write my_ar to archive 
    num_written = write(out_fd, title, sizeof(title)); 
    num_written = write(out_fd, &my_ar, sizeof(my_ar)); 


    printf("\n"); 

    return 0; 
} 
+0

Возможно, это связано с тем, что не задано член структуры 'ar_fmag' (см. Http://docs.oracle.com/cd/E19082-01/819-2242/ar.h-3head/index.html) - У меня нет опыта работы с 'ar', так что это предположение. Также было бы полезно проанализировать выходной файл с 'od', чтобы проверить, что байты, как вы ожидаете. – imp25

ответ

0

title должен появиться только один раз в файле, в самом начале. Если вы добавляете файл в архив, вам просто нужно написать ar_hdr для нового файла, за которым следует содержимое файла.

Поэтому вам нужно проверить, существует ли файл уже существует. Если это не так, и вы создаете новый архив, вам нужно сначала написать title. Если он существует, пропустите этот шаг. Так как вы открываете файл в режиме добавления, вы можете сказать, является ли это новый файл с помощью lseek():

off_t curpos = lseek(out_fd, SEEK_CUR, 0); // Get current position 
if (curpos == 0) { // At beginning, it must be a new file 
    num_written = write(out_fd, ARMAG, SARMAG); 
} 
+0

Благодарим вас за помощь. Я добавил, что вы предложили, и добавил содержимое файла после ar_hdr, но я все равно получаю ту же ошибку. Я отправлю свои новые вопросы. – user2203774

0

user2203774, я собираюсь повторно итерация: Вы работаете с плохо документированным файлом формат не стандартизован. Единственный способ узнать правильный формат файла - (а) изучить ссылки документации, которые я дал в вашем другом вопросе, и (б) проанализировать выборку архивных файлов, которые у вас есть, чтобы определить, соответствует ли формат такой документации как у вас. Вероятность того, что формат файла будет похож, но не идентичен. ТОГДА, вам нужно выяснить, каковы различия. Как только вы это сделаете, создайте свой собственный документ формата файла и отработайте его.

также отметить, что первый и самый простой отладки шаг «сравнить то, что моя программа генерируется с эквивалентом, как генерируется ar. Чем они отличаются? Почему?» (команда od -c полезно здесь, или бок- в стороннем представлении).

Несколько точек:

  • Строка заголовка магии ("!<arch>\n") идет только в начале файла, а не в начале каждой записи.
  • Все поля в структуре ar_hdr заполнены пробелами, а не являются строки с нулевым символом.
  • Если вы не готовы обновить таблицу символов (включая добавление одного, если необходимо) и переписать весь файл, вы должны убедиться, что ваши имена не превышают пятнадцати символов.
  • Каждое имя файла должно быть немедленно следует / характера (которые не должны быть с последующим нулем. Опять же, остальные поля заполняются пробелами.)
  • Вы никогда не инициализирует ar_fmag поле ar_hdr структуры , Это нужно инициализировать до определенного значения.
  • После того как вы напишите заголовок, вам нужно написать фактическое содержимое файла.
  • Некоторые ссылки указывают, что при записи содержимого файла вы должны записать четное количество байтов. Если размер файла является нечетным числом, в качестве отступов должен быть добавлен один \n (а размер файла, записанный в заголовке, не увеличивается, чтобы включать в себя заполняющий байт).
Смежные вопросы