ARCHIVE_WRITE(3) | FreeBSD Library Functions Manual | ARCHIVE_WRITE(3) |
名称
archive_write — アーカイブを作成するための関数ライブラリ
ストリーミングアーカイブライブラリ (libarchive, -larchive)書式
#include < archive.h>解説
これらの関数は、ストリーミングアーカイブファイルを作成するための完全な API を提供します。一般的なプロセスは、最初に、 struct archive オブジェクトを作成して、任意の必要なオプションを設定し、アーカイブを初期化し、エントリを追加し、次に、アーカイブをクローズして、すべてのリソースを解放します。アーカイブオブジェクトを作成する
archive_write_new(3) を参照してください。アーカイブを書き込むためには、最初に archive_write_new() から初期化された struct archive オブジェクトを取得しなければなりません。
フィルタとフォーマットを有効にし、ブロックサイズとパディングを設定する
archive_write_filter(3), archive_write_format(3) と archive_write_blocksize(3) を参照してください。次に、様々な archive_write_set_XXX() 関数で希望の操作のために、このオブジェクトを修正することができます。特に、対応する圧縮とフォーマットサポートを有効にする適切な archive_write_add_XXX() と archive_write_set_XXX() 関数を呼び出す必要があります。
設定オプション
archive_read_set_options(3) を参照してください。アーカイブをオープンする
archive_write_open(3) を参照してください。いったん、 struct archive オブジェクトを準備したなら、実際にアーカイブをオープンし、書き込みのために準備するためには、 archive_write_open() を呼び出します。この関数のいくつかの変異型があります。最も基本的なものは、利用者が、アーカイブからのバイトのブロックを提供することができるいくつかの関数へのポインタを提供することを期待しています。利用者がファイル名、ファイル記述子、 FILE * オブジェクトまたはアーカイブデータを書き込むメモリのブロックを指定することができる便利な方法があります。
アーカイブを生成する
archive_write_header(3) と archive_write_data(3) を参照してください。個別のアーカイブエントリは、次の 3 つのステップのプロセスで書き込まれます: 最初に新しいエントリに関する情報がある struct archive_entry 構造体を初期化します。最低でも、エントリのパス名を設定し、オブジェクトのタイプを指定する有効な st_mode フィールドがある struct stat とオブジェクトのデータ部分のサイズを指定する st_size フィールドを提供するべきです。
リソースを解放する
archive_write_free(3) を参照してください。すべてのエントリが書き込まれた後に、すべてのリソースを解放するために archive_write_free() 関数を使用します。
使用例
次のスケッチ (概略) は、ライブラリの基本的な使用法を説明しています。この例では、コールバック関数は、標準の open(2), write(2) と close(2) システムコールを囲むような単純なラッパです。
#ifdef __linux__ #define _FILE_OFFSET_BITS 64 #endif #include <sys/stat.h> #include <archive.h> #include <archive_entry.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> struct mydata { const char *name; int fd; }; int myopen(struct archive *a, void *client_data) { struct mydata *mydata = client_data; mydata->fd = open(mydata->name, O_WRONLY | O_CREAT, 0644); if (mydata->fd >= 0) return (ARCHIVE_OK); else return (ARCHIVE_FATAL); } ssize_t mywrite(struct archive *a, void *client_data, const void *buff, size_t n) { struct mydata *mydata = client_data; return (write(mydata->fd, buff, n)); } int myclose(struct archive *a, void *client_data) { struct mydata *mydata = client_data; if (mydata->fd > 0) close(mydata->fd); return (0); } void write_archive(const char *outname, const char **filename) { struct mydata *mydata = malloc(sizeof(struct mydata)); struct archive *a; struct archive_entry *entry; struct stat st; char buff[8192]; int len; int fd; a = archive_write_new(); mydata->name = outname; archive_write_add_filter_gzip(a); archive_write_set_format_ustar(a); archive_write_open(a, mydata, myopen, mywrite, myclose); while (*filename) { stat(*filename, &st); entry = archive_entry_new(); archive_entry_copy_stat(entry, &st); archive_entry_set_pathname(entry, *filename); archive_write_header(a, entry); if ((fd = open(*filename, O_RDONLY)) != -1) { len = read(fd, buff, sizeof(buff)); while ( len > 0 ) { archive_write_data(a, buff, len); len = read(fd, buff, sizeof(buff)); } close(fd); } archive_entry_free(entry); filename++; } archive_write_free(a); } int main(int argc, const char **argv) { const char *outname; argv++; outname = argv++; write_archive(outname, argv); return 0; }
歴史
libarchive ライブラリは、 FreeBSD 5.3 ではじめて登場しました。作者
libarchive ライブラリは、 <kientzle@acm.org>によって書かれました。バグ
あるプログラムがこのライブラリによって書き込まれたアーカイブを拒絶する歴史的な tar 実装には、多くの独特のバグがあります。例えば、いくつかの歴史的な実装は、不正確にヘッダチェックサムを計算して、その結果、有効なアーカイブを拒絶します。 GNU tar は、pax 交換形式を完全にサポートしていません。いくつかの古い tar 実装は、特定のフィールド終端を要求します。デフォルトの pax 交換形式は、歴史的な tar 制限の大部分を取り除き、ベンダ定義の拡張のために一般的なキー/値の属性機能を提供します。 POSIX の 1 つの手落ちは、大きいデバイス番号のための標準の属性を提供することの失敗です。このライブラリは、後方互換性の ustar ヘッダによってサポートされる範囲を超えるデバイス番号のために“SCHILY.devminor”と“SCHILY.devmajor”を使用します。これらのキーは、Joerg Schilling の star アーカイバと互換性があります。他の実装は、これらのキーを認識しないかもしれません、その結果、このライブラリによって作成されたアーカイブから大きなデバイス番号でデバイスノードを正しく復旧することができないでしょう。
February 2, 2012 | FreeBSD |