2013-07-21 2 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을, 나는 - 반복 처리를 다시거야 표준화되지 않은 형식. 올바른 파일 형식을 알 수있는 유일한 방법은 (a) 다른 질문에서 제공 한 문서 링크를 연구하고 (b) 보관 파일의 샘플을 분석하여 형식이 해당 문서에 부합하는지 여부를 결정하는 것입니다 네가 가진대로. 파일 형식이 유사하지만 동일하지 않을 가능성이 있습니다. 그런 다음 차이점이 무엇인지 알아 내야합니다. 일단 그렇게하면 자신 만의 파일 형식 문서를 만들고 그 파일 형식으로 작업하십시오.

은 또한 첫 주 단계는 디버깅 간단한 대합니다 (od -c 명령 여기에 도움이된다, 또는 사이드 - "ar에 의해 생성 된 내 프로그램에 해당하는 생성 무엇을 비교한다. 그들은 어떻게 왜? 다르다" 바이 사이드 뷰어).

몇 가지 포인트 :

  • 마법의 헤더 캐릭터 라인 ("!<arch>\n"가)뿐만 아니라 모든 레코드의 시작 부분에, 파일의 시작에 간다.
  • ar_hdr 구조의 모든 필드는 공백으로 채워지고 null로 끝나는 문자열이 아닙니다.
  • 필요에 따라 심볼 테이블을 업데이트하고 심볼 테이블을 업데이트하고 전체 파일을 다시 쓸 준비가되어 있지 않으면 파일 이름이 15자를 초과하지 않아야합니다.
  • 각 파일 이름은 즉시 / 문자가 와야합니다 (널에 의해 올 수 없습니다. 또, 공간을 가득 필드의 나머지.)
  • 당신은 결코 ar_hdr 구조의 ar_fmag 필드를 초기화하지있어 . 이것은 특정 값으로 초기화되어야합니다.
  • 헤더를 작성한 후에는 파일의 실제 내용을 작성해야합니다.
  • 일부 참조는 파일 내용이 기록 될 때 짝수 바이트를 작성해야한다는 것을 나타냅니다. 파일 크기가 홀수 인 경우 \n을 패딩으로 추가해야합니다 (헤더에 기록 된 파일 크기는 패딩 바이트를 포함하도록 증가되지 않습니다).