mirror of
https://github.com/pygos/pkg-utils.git
synced 2024-05-21 13:46:13 +02:00
Compare commits
39 commits
Author | SHA1 | Date | |
---|---|---|---|
David Oberhollenzer | 2ba65d6cfa | ||
David Oberhollenzer | 80f298de55 | ||
David Oberhollenzer | 4a7b1d3b3c | ||
David Oberhollenzer | a632656a60 | ||
David Oberhollenzer | ec1020ffc6 | ||
David Oberhollenzer | 6d053ff213 | ||
David Oberhollenzer | f426e4ef91 | ||
David Oberhollenzer | e08c819606 | ||
David Oberhollenzer | ba034260d4 | ||
David Oberhollenzer | ab753a402f | ||
David Oberhollenzer | f95f02f6be | ||
David Oberhollenzer | 5df2d5f730 | ||
David Oberhollenzer | ed6841ed17 | ||
David Oberhollenzer | 7a70868fcd | ||
David Oberhollenzer | 5f0ee09c83 | ||
David Oberhollenzer | 75e169d06a | ||
David Oberhollenzer | 9402492c16 | ||
David Oberhollenzer | 377596f37e | ||
David Oberhollenzer | 33997bdb9e | ||
David Oberhollenzer | 00db5541e9 | ||
David Oberhollenzer | 96d4d353d4 | ||
David Oberhollenzer | b30e912e97 | ||
David Oberhollenzer | 576491eae6 | ||
David Oberhollenzer | ac8e457c96 | ||
David Oberhollenzer | 214a5e917e | ||
David Oberhollenzer | e123eaf433 | ||
David Oberhollenzer | f80e4e8d29 | ||
David Oberhollenzer | 26b3683f7a | ||
David Oberhollenzer | 765c836c3d | ||
David Oberhollenzer | d94bd8ff17 | ||
David Oberhollenzer | cd79a4fccf | ||
David Oberhollenzer | eadeee25d9 | ||
David Oberhollenzer | 025ab1007b | ||
David Oberhollenzer | db25ddc108 | ||
David Oberhollenzer | 858779e42c | ||
David Oberhollenzer | c78dc2255f | ||
David Oberhollenzer | aa6bbf2ef4 | ||
David Oberhollenzer | 6cfd9a37bf | ||
David Oberhollenzer | 1205ca0f3b |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -18,3 +18,4 @@ config.h
|
|||
*.a
|
||||
*~
|
||||
pkg
|
||||
pkg2sqfs
|
||||
|
|
|
@ -11,7 +11,7 @@ Building this package produces a program called `pkg` that can:
|
|||
* dump the contents and meta data of such an archive for inspection.
|
||||
* install an archive and all its dependencies recursively, in topological
|
||||
order, to a specified root directory.
|
||||
* generate file listings from archives in formats suitable for `mksquashfs`
|
||||
* generate file listings from archives in formats suitable for `gensquashfs`
|
||||
and Linux `CONFIG_INITRAMFS_SOURCE`.
|
||||
* work out a build order for source packages given information on what source
|
||||
packages provide what binary packages and what binary packages they need in
|
||||
|
|
17
configure.ac
17
configure.ac
|
@ -1,5 +1,5 @@
|
|||
AC_PREREQ([2.60])
|
||||
AC_INIT([pkgtool], [0.3], [goliath@infraroot.at], pkgtool)
|
||||
AC_INIT([pkgtool], [0.4.2], [goliath@infraroot.at], pkgtool)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE([foreign dist-xz subdir-objects])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
@ -39,6 +39,21 @@ UL_WARN_ADD([-pedantic])
|
|||
|
||||
AC_SUBST([WARN_CFLAGS])
|
||||
|
||||
##### configuration options #####
|
||||
|
||||
AC_DEFINE([REPODIR], ["./"], [Default package repository directory])
|
||||
AC_DEFINE([INSTALLROOT], ["./"], [Default package installation root])
|
||||
|
||||
AC_ARG_WITH([repo-dir],
|
||||
[AS_HELP_STRING([--with-repo-dir],
|
||||
[Set the default package repository directory])],
|
||||
[AC_DEFINE_UNQUOTED([REPODIR], "$withval")])
|
||||
|
||||
AC_ARG_WITH([install-root],
|
||||
[AS_HELP_STRING([--with-install-root],
|
||||
[Set the default package installation directory])],
|
||||
[AC_DEFINE_UNQUOTED([INSTALLROOT], "$withval")])
|
||||
|
||||
##### search for dependencies #####
|
||||
|
||||
have_zlib="no"
|
||||
|
|
|
@ -105,14 +105,10 @@ table of contents contains an entry with the following common structure:
|
|||
|
||||
0 1 2 3
|
||||
+-------+-------+-------+-------+
|
||||
0 | mode |
|
||||
0 | mode | user id |
|
||||
+-------+-------+-------+-------+
|
||||
1 | user id |
|
||||
1 | group id | path length |
|
||||
+-------+-------+-------+-------+
|
||||
2 | group id |
|
||||
+-------+-------+-------+-------+
|
||||
3 | path length |
|
||||
+---------------+
|
||||
|
||||
The mode field contains standard UNIX permissions. The user ID and group ID
|
||||
fields contain the numeric IDs of the user and group respectively that own
|
||||
|
@ -142,8 +138,6 @@ On the bit level, the mode field is structured as follows:
|
|||
| +------------------------- set UID bit
|
||||
+----------------------------- file type
|
||||
|
||||
The upper 16 bit of the mode filed must be set to zero.
|
||||
|
||||
Currently, the following file types are supported:
|
||||
|
||||
* `S_IFCHR` with a value of 2. The entry defines a character device.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "pkgformat.h"
|
||||
#include "pkg/pkgformat.h"
|
||||
|
||||
typedef struct compressor_stream_t {
|
||||
ssize_t (*write)(struct compressor_stream_t *stream, const uint8_t *in,
|
||||
|
@ -24,21 +24,14 @@ typedef struct compressor_t {
|
|||
const char *name;
|
||||
PKG_COMPRESSION id;
|
||||
|
||||
compressor_stream_t *(*compression_stream)(struct compressor_t *cmp);
|
||||
compressor_stream_t *(*compression_stream)(struct compressor_t *cmp,
|
||||
void *options);
|
||||
|
||||
compressor_stream_t *(*uncompression_stream)(struct compressor_t *cmp);
|
||||
} compressor_t;
|
||||
|
||||
void compressor_register(compressor_t *compressor);
|
||||
|
||||
compressor_t *compressor_by_name(const char *name);
|
||||
|
||||
compressor_t *compressor_by_id(PKG_COMPRESSION id);
|
||||
|
||||
#define REGISTER_COMPRESSOR(compressor) \
|
||||
static void __attribute__((constructor)) register_##compressor(void) \
|
||||
{ \
|
||||
compressor_register((compressor_t *)&compressor); \
|
||||
}
|
||||
|
||||
#endif /* COMPRESSOR_H */
|
|
@ -31,7 +31,6 @@ typedef struct image_entry_t {
|
|||
|
||||
typedef enum {
|
||||
TOC_FORMAT_PRETTY = 0,
|
||||
TOC_FORMAT_SQFS = 1,
|
||||
TOC_FORMAT_INITRD = 2,
|
||||
TOC_FORMAT_PKG = 3,
|
||||
} TOC_FORMAT;
|
||||
|
|
|
@ -36,10 +36,9 @@ typedef struct {
|
|||
} record_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t mode;
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
|
||||
uint16_t mode;
|
||||
uint16_t uid;
|
||||
uint16_t gid;
|
||||
uint16_t path_length;
|
||||
/* uint8_t path[]; */
|
||||
} toc_entry_t;
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
#ifndef DEPGRAPH_H
|
||||
#define DEPGRAPH_H
|
||||
#ifndef PKGLIST_H
|
||||
#define PKGLIST_H
|
||||
|
||||
struct pkg_dep_node {
|
||||
char *name;
|
||||
|
@ -30,4 +30,4 @@ int collect_dependencies(int repofd, struct pkg_dep_list *list);
|
|||
|
||||
int sort_by_dependencies(struct pkg_dep_list *list);
|
||||
|
||||
#endif /* DEPGRAPH_H */
|
||||
#endif /* PKGLIST_H */
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "comp/compressor.h"
|
||||
#include "pkgformat.h"
|
||||
#include "compressor.h"
|
||||
|
||||
typedef struct pkg_writer_t pkg_writer_t;
|
||||
|
|
@ -9,4 +9,30 @@ libfilelist_a_SOURCES = lib/filelist/dump_toc.c lib/filelist/image_entry.c
|
|||
libfilelist_a_SOURCES += lib/filelist/image_entry_sort.c
|
||||
libfilelist_a_SOURCES += include/filelist/image_entry.h
|
||||
|
||||
noinst_LIBRARIES += libutil.a libfilelist.a
|
||||
libcomp_a_SOURCES = lib/comp/compressor.c lib/comp/none.c
|
||||
libcomp_a_SOURCES += include/comp/compressor.h lib/comp/internal.h
|
||||
libcomp_a_CFLAGS = $(AM_CFLAGS)
|
||||
libcomp_a_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
|
||||
if WITH_ZLIB
|
||||
libcomp_a_SOURCES += lib/comp/zlib.c
|
||||
|
||||
libcomp_a_CFLAGS += $(ZLIB_CFLAGS)
|
||||
libcomp_a_CPPFLAGS += -DWITH_ZLIB
|
||||
endif
|
||||
|
||||
if WITH_LZMA
|
||||
libcomp_a_SOURCES += lib/comp/lzma.c
|
||||
|
||||
libcomp_a_CFLAGS += $(XZ_CFLAGS)
|
||||
libcomp_a_CPPFLAGS += -DWITH_LZMA
|
||||
endif
|
||||
|
||||
libpkg_a_SOURCES = include/pkg/pkgformat.h include/pkg/pkgreader.h
|
||||
libpkg_a_SOURCES += include/pkg/pkgio.h include/pkg/pkgwriter.h
|
||||
libpkg_a_SOURCES += include/pkg/pkglist.h
|
||||
libpkg_a_SOURCES += lib/pkg/pkgreader.c lib/pkg/pkgwriter.c
|
||||
libpkg_a_SOURCES += lib/pkg/pkg_unpack.c lib/pkg/pkgio_rd_image_entry.c
|
||||
libpkg_a_SOURCES += lib/pkg/collect.c lib/pkg/pkglist.c lib/pkg/tsort.c
|
||||
|
||||
noinst_LIBRARIES += libutil.a libfilelist.a libcomp.a libpkg.a
|
||||
|
|
39
lib/comp/compressor.c
Normal file
39
lib/comp/compressor.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
#include <string.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
static compressor_t *compressors[] = {
|
||||
[PKG_COMPRESSION_NONE] = &comp_none,
|
||||
#ifdef WITH_ZLIB
|
||||
[PKG_COMPRESSION_ZLIB] = &comp_zlib,
|
||||
#endif
|
||||
#ifdef WITH_LZMA
|
||||
[PKG_COMPRESSION_LZMA] = &comp_lzma,
|
||||
#endif
|
||||
};
|
||||
|
||||
compressor_t *compressor_by_name(const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(compressors) / sizeof(compressors[0]); ++i) {
|
||||
if (compressors[i] == NULL)
|
||||
continue;
|
||||
if (strcmp(compressors[i]->name, name) == 0)
|
||||
return compressors[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
compressor_t *compressor_by_id(PKG_COMPRESSION id)
|
||||
{
|
||||
if ((int)id < 0)
|
||||
return NULL;
|
||||
|
||||
if ((size_t)id >= sizeof(compressors) / sizeof(compressors[0]))
|
||||
return NULL;
|
||||
|
||||
return compressors[id];
|
||||
}
|
11
lib/comp/internal.h
Normal file
11
lib/comp/internal.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
#ifndef INTERNAL_H
|
||||
#define INTERNAL_H
|
||||
|
||||
#include "comp/compressor.h"
|
||||
|
||||
extern compressor_t comp_lzma;
|
||||
extern compressor_t comp_none;
|
||||
extern compressor_t comp_zlib;
|
||||
|
||||
#endif /* INTERNAL_H */
|
|
@ -5,7 +5,7 @@
|
|||
#include <stdio.h>
|
||||
#include <lzma.h>
|
||||
|
||||
#include "compressor.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define CHUNK_SIZE 16384
|
||||
|
||||
|
@ -17,6 +17,7 @@ typedef struct {
|
|||
int used;
|
||||
bool eof;
|
||||
bool error;
|
||||
size_t dict_size;
|
||||
} lzma_stream_t;
|
||||
|
||||
static ssize_t lzma_write(compressor_stream_t *base,
|
||||
|
@ -100,7 +101,7 @@ static void lzma_destroy(compressor_stream_t *base)
|
|||
free(lzma);
|
||||
}
|
||||
|
||||
static compressor_stream_t *create_stream(bool compress)
|
||||
static compressor_stream_t *create_stream(bool compress, size_t dict_size)
|
||||
{
|
||||
lzma_stream_t *lzma = calloc(1, sizeof(*lzma));
|
||||
compressor_stream_t *base;
|
||||
|
@ -113,6 +114,7 @@ static compressor_stream_t *create_stream(bool compress)
|
|||
}
|
||||
|
||||
lzma->action = LZMA_RUN;
|
||||
lzma->dict_size = dict_size;
|
||||
|
||||
base = (compressor_stream_t *)lzma;
|
||||
base->write = lzma_write;
|
||||
|
@ -126,6 +128,9 @@ static compressor_stream_t *create_stream(bool compress)
|
|||
if (lzma_lzma_preset(&opt_lzma2, LZMA_PRESET_DEFAULT))
|
||||
goto fail;
|
||||
|
||||
if (dict_size)
|
||||
opt_lzma2.dict_size = dict_size;
|
||||
|
||||
filters[0].id = LZMA_FILTER_LZMA2;
|
||||
filters[0].options = &opt_lzma2;
|
||||
|
||||
|
@ -148,23 +153,21 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static compressor_stream_t *lzma_compress(compressor_t *cmp)
|
||||
static compressor_stream_t *lzma_compress(compressor_t *cmp, void *options)
|
||||
{
|
||||
(void)cmp;
|
||||
return create_stream(true);
|
||||
return create_stream(true, options == NULL ? 0 : *((size_t *)options));
|
||||
}
|
||||
|
||||
static compressor_stream_t *lzma_uncompress(compressor_t *cmp)
|
||||
{
|
||||
(void)cmp;
|
||||
return create_stream(false);
|
||||
return create_stream(false, 0);
|
||||
}
|
||||
|
||||
static compressor_t lzma = {
|
||||
compressor_t comp_lzma = {
|
||||
.name = "lzma",
|
||||
.id = PKG_COMPRESSION_LZMA,
|
||||
.compression_stream = lzma_compress,
|
||||
.uncompression_stream = lzma_uncompress,
|
||||
};
|
||||
|
||||
REGISTER_COMPRESSOR(lzma)
|
|
@ -4,7 +4,7 @@
|
|||
#include <stdio.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "compressor.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define CHUNK_SIZE 16384
|
||||
|
||||
|
@ -62,11 +62,12 @@ static void dummy_destroy(compressor_stream_t *base)
|
|||
free(base);
|
||||
}
|
||||
|
||||
static compressor_stream_t *create_dummy_stream(compressor_t *cmp)
|
||||
static compressor_stream_t *create_dummy_stream(compressor_t *cmp,
|
||||
void *options)
|
||||
{
|
||||
dummy_stream_t *dummy = calloc(1, sizeof(*dummy));
|
||||
compressor_stream_t *base;
|
||||
(void)cmp;
|
||||
(void)cmp; (void)options;
|
||||
|
||||
if (dummy == NULL) {
|
||||
perror("creating dummy compressor stream");
|
||||
|
@ -81,11 +82,14 @@ static compressor_stream_t *create_dummy_stream(compressor_t *cmp)
|
|||
return base;
|
||||
}
|
||||
|
||||
static compressor_t none = {
|
||||
static compressor_stream_t *create_dummy_uncompressor(compressor_t *cmp)
|
||||
{
|
||||
return create_dummy_stream(cmp, NULL);
|
||||
}
|
||||
|
||||
compressor_t comp_none = {
|
||||
.name = "none",
|
||||
.id = PKG_COMPRESSION_NONE,
|
||||
.compression_stream = create_dummy_stream,
|
||||
.uncompression_stream = create_dummy_stream,
|
||||
.uncompression_stream = create_dummy_uncompressor,
|
||||
};
|
||||
|
||||
REGISTER_COMPRESSOR(none)
|
|
@ -5,7 +5,7 @@
|
|||
#include <stdio.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "compressor.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define CHUNK_SIZE 16384
|
||||
|
||||
|
@ -147,9 +147,9 @@ static compressor_stream_t *create_stream(bool compress)
|
|||
return base;
|
||||
}
|
||||
|
||||
static compressor_stream_t *zlib_compress(compressor_t *cmp)
|
||||
static compressor_stream_t *zlib_compress(compressor_t *cmp, void *options)
|
||||
{
|
||||
(void)cmp;
|
||||
(void)cmp; (void)options;
|
||||
return create_stream(true);
|
||||
}
|
||||
|
||||
|
@ -159,11 +159,9 @@ static compressor_stream_t *zlib_uncompress(compressor_t *cmp)
|
|||
return create_stream(false);
|
||||
}
|
||||
|
||||
static compressor_t zlib = {
|
||||
compressor_t comp_zlib = {
|
||||
.name = "zlib",
|
||||
.id = PKG_COMPRESSION_ZLIB,
|
||||
.compression_stream = zlib_compress,
|
||||
.uncompression_stream = zlib_uncompress,
|
||||
};
|
||||
|
||||
REGISTER_COMPRESSOR(zlib)
|
|
@ -55,40 +55,6 @@ fail_type:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int print_sqfs(image_entry_t *ent, const char *root)
|
||||
{
|
||||
mode_t mode = ent->mode & (~S_IFMT);
|
||||
(void)root;
|
||||
|
||||
switch (ent->mode & S_IFMT) {
|
||||
case S_IFCHR:
|
||||
printf("%s c %o %u %u %u %u\n", ent->name, mode,
|
||||
(unsigned int)ent->uid, (unsigned int)ent->gid,
|
||||
major(ent->data.device.devno),
|
||||
minor(ent->data.device.devno));
|
||||
break;
|
||||
case S_IFBLK:
|
||||
printf("%s b %o %u %u %u %u\n", ent->name, mode,
|
||||
(unsigned int)ent->uid, (unsigned int)ent->gid,
|
||||
major(ent->data.device.devno),
|
||||
minor(ent->data.device.devno));
|
||||
break;
|
||||
case S_IFLNK:
|
||||
mode = 0777;
|
||||
/* fall-through */
|
||||
case S_IFDIR:
|
||||
case S_IFREG:
|
||||
printf("%s m %o %u %u\n", ent->name, mode,
|
||||
(unsigned int)ent->uid, (unsigned int)ent->gid);
|
||||
break;
|
||||
default:
|
||||
fputs("unknown file type in table of contents\n", stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_initrd(image_entry_t *ent, const char *root)
|
||||
{
|
||||
mode_t mode = ent->mode & (~S_IFMT);
|
||||
|
@ -156,7 +122,7 @@ static int print_pkg(image_entry_t *ent, const char *root)
|
|||
return -1;
|
||||
}
|
||||
|
||||
printf(" %s 0%o %u %u ", ent->name, mode,
|
||||
printf(" \"%s\" 0%o %u %u ", ent->name, mode,
|
||||
(unsigned int)ent->uid, (unsigned int)ent->gid);
|
||||
|
||||
switch (ent->mode & S_IFMT) {
|
||||
|
@ -186,7 +152,6 @@ static int print_pkg(image_entry_t *ent, const char *root)
|
|||
|
||||
static print_fun_t printers[] = {
|
||||
[TOC_FORMAT_PRETTY] = print_pretty,
|
||||
[TOC_FORMAT_SQFS] = print_sqfs,
|
||||
[TOC_FORMAT_INITRD] = print_initrd,
|
||||
[TOC_FORMAT_PKG] = print_pkg,
|
||||
};
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
static int compare_ent(image_entry_t *a, image_entry_t *b)
|
||||
{
|
||||
int diff;
|
||||
|
||||
/* directories < .. < symlinks < devices < .. < files */
|
||||
switch (a->mode & S_IFMT) {
|
||||
case S_IFDIR:
|
||||
|
@ -31,7 +33,8 @@ static int compare_ent(image_entry_t *a, image_entry_t *b)
|
|||
return -1;
|
||||
}
|
||||
out_len:
|
||||
return (int)strlen(a->name) - (int)strlen(b->name);
|
||||
diff = (int)strlen(a->name) - (int)strlen(b->name);
|
||||
return diff ? diff : strcmp(a->name, b->name);
|
||||
out_fsize:
|
||||
if (a->data.file.size > b->data.file.size)
|
||||
return 1;
|
||||
|
@ -65,6 +68,34 @@ static image_entry_t *insert_sorted(image_entry_t *list, image_entry_t *ent)
|
|||
return list;
|
||||
}
|
||||
|
||||
static void remove_duplicates(image_entry_t *list)
|
||||
{
|
||||
image_entry_t *it = list, *old;
|
||||
int equal;
|
||||
|
||||
if (it == NULL)
|
||||
return;
|
||||
|
||||
while (it->next != NULL) {
|
||||
equal = 0;
|
||||
|
||||
if (S_ISDIR(it->mode) && S_ISDIR(it->next->mode)) {
|
||||
equal = (strcmp(it->name, it->next->name) == 0);
|
||||
equal = equal && (it->mode == it->next->mode);
|
||||
equal = equal && (it->uid == it->next->uid);
|
||||
equal = equal && (it->gid == it->next->gid);
|
||||
}
|
||||
|
||||
if (equal) {
|
||||
old = it->next;
|
||||
it->next = old->next;
|
||||
image_entry_free(old);
|
||||
} else {
|
||||
it = it->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image_entry_t *image_entry_sort(image_entry_t *list)
|
||||
{
|
||||
image_entry_t *sorted = NULL, *ent;
|
||||
|
@ -76,5 +107,7 @@ image_entry_t *image_entry_sort(image_entry_t *list)
|
|||
sorted = insert_sorted(sorted, ent);
|
||||
}
|
||||
|
||||
remove_duplicates(sorted);
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pkgreader.h"
|
||||
#include "depgraph.h"
|
||||
#include "pkg/pkgreader.h"
|
||||
#include "pkg/pkglist.h"
|
||||
|
||||
int collect_dependencies(int repofd, struct pkg_dep_list *list)
|
||||
{
|
|
@ -8,7 +8,7 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "pkgio.h"
|
||||
#include "pkg/pkgio.h"
|
||||
#include "util/util.h"
|
||||
|
||||
static int create_hierarchy(int dirfd, image_entry_t *list, int flags)
|
|
@ -4,7 +4,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pkgio.h"
|
||||
#include "pkg/pkgio.h"
|
||||
#include "util/util.h"
|
||||
|
||||
static int read_extra(pkg_reader_t *pkg, image_entry_t *ent)
|
|
@ -3,7 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "depgraph.h"
|
||||
#include "pkg/pkglist.h"
|
||||
|
||||
struct pkg_dep_node *append_pkg(struct pkg_dep_list *list, const char *name)
|
||||
{
|
|
@ -8,9 +8,9 @@
|
|||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "comp/compressor.h"
|
||||
#include "util/util.h"
|
||||
#include "pkgreader.h"
|
||||
#include "compressor.h"
|
||||
#include "pkg/pkgreader.h"
|
||||
|
||||
struct pkg_reader_t {
|
||||
int fd;
|
||||
|
@ -235,26 +235,29 @@ record_t *pkg_reader_current_record_header(pkg_reader_t *rd)
|
|||
|
||||
ssize_t pkg_reader_read_payload(pkg_reader_t *rd, void *out, size_t size)
|
||||
{
|
||||
ssize_t ret;
|
||||
ssize_t ret, total = 0;
|
||||
|
||||
do {
|
||||
if (rd->have_error)
|
||||
return -1;
|
||||
|
||||
if (rd->have_eof || rd->offset_raw == rd->current.raw_size)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
if (prefetch_compressed(rd))
|
||||
return -1;
|
||||
|
||||
if (size >= (rd->current.raw_size - rd->offset_raw))
|
||||
rd->stream->flush(rd->stream);
|
||||
|
||||
ret = rd->stream->read(rd->stream, out, size);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
rd->offset_raw += ret;
|
||||
return ret;
|
||||
out = (char *)out + ret;
|
||||
size -= ret;
|
||||
total += ret;
|
||||
} while (size > 0);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int pkg_reader_rewind(pkg_reader_t *rd)
|
|
@ -6,7 +6,7 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "pkgwriter.h"
|
||||
#include "pkg/pkgwriter.h"
|
||||
#include "util/util.h"
|
||||
|
||||
struct pkg_writer_t {
|
||||
|
@ -96,7 +96,7 @@ pkg_writer_t *pkg_writer_open(const char *path, bool force)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
wr->stream = cmp->compression_stream(cmp);
|
||||
wr->stream = cmp->compression_stream(cmp, NULL);
|
||||
if (wr->stream == NULL) {
|
||||
fputs("error creating compressor stream for package header\n",
|
||||
stderr);
|
||||
|
@ -153,7 +153,7 @@ int pkg_writer_start_record(pkg_writer_t *wr, uint32_t magic,
|
|||
if (write_header(wr))
|
||||
return -1;
|
||||
|
||||
wr->stream = cmp->compression_stream(cmp);
|
||||
wr->stream = cmp->compression_stream(cmp, NULL);
|
||||
if (wr->stream == NULL)
|
||||
return -1;
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "depgraph.h"
|
||||
#include "pkg/pkglist.h"
|
||||
|
||||
static void remove_dependency(struct pkg_dep_list *list,
|
||||
struct pkg_dep_node *pkg)
|
|
@ -1,13 +1,8 @@
|
|||
pkg_SOURCES = include/pkgformat.h include/pkgreader.h include/pkgio.h
|
||||
pkg_SOURCES += include/compressor.h include/command.h include/pkgwriter.h
|
||||
pkg_SOURCES += include/depgraph.h
|
||||
pkg_SOURCES += main/pkg.c main/compressor.c main/command.c main/pkgreader.c
|
||||
pkg_SOURCES += main/pkgwriter.c main/pkgio_rd_image_entry.c main/pkg_unpack.c
|
||||
pkg_SOURCES += main/depgraph/collect.c main/depgraph/pkglist.c
|
||||
pkg_SOURCES += main/depgraph/tsort.c
|
||||
pkg_SOURCES = main/command.h main/pkg.c main/command.c
|
||||
|
||||
pkg_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/main
|
||||
pkg_CFLAGS = $(AM_CFLAGS)
|
||||
pkg_LDADD = libutil.a libfilelist.a
|
||||
pkg_LDADD = libpkg.a libutil.a libfilelist.a libcomp.a
|
||||
|
||||
##### commands #####
|
||||
|
||||
|
@ -40,24 +35,12 @@ pkg_SOURCES += main/cmd/unpack.c
|
|||
pkg_SOURCES += main/cmd/help.c
|
||||
|
||||
##### compressors #####
|
||||
|
||||
# dummy compressor
|
||||
pkg_SOURCES += main/compressors/none.c
|
||||
|
||||
# zlib compressor
|
||||
if WITH_ZLIB
|
||||
pkg_SOURCES += main/compressors/zlib.c
|
||||
|
||||
pkg_CFLAGS += $(ZLIB_CFLAGS)
|
||||
pkg_LDADD += $(ZLIB_LIBS)
|
||||
endif
|
||||
|
||||
# lzma compressor
|
||||
if WITH_LZMA
|
||||
pkg_SOURCES += main/compressors/lzma.c
|
||||
|
||||
pkg_CFLAGS += $(XZ_CFLAGS)
|
||||
pkg_LDADD += $(XZ_LIBS)
|
||||
endif
|
||||
|
||||
if WITH_ZLIB
|
||||
pkg_LDADD += $(ZLIB_LIBS)
|
||||
endif
|
||||
|
||||
bin_PROGRAMS += pkg
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "depgraph.h"
|
||||
#include "pkg/pkglist.h"
|
||||
#include "command.h"
|
||||
#include "config.h"
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
{ "no-dependencies", no_argument, NULL, 'd' },
|
||||
|
@ -37,7 +38,7 @@ static void print_dot_graph(struct pkg_dep_list *list)
|
|||
|
||||
static int cmd_depgraph(int argc, char **argv)
|
||||
{
|
||||
int i, repofd = AT_FDCWD, ret = EXIT_FAILURE;
|
||||
int i, repofd = -1, ret = EXIT_FAILURE;
|
||||
struct pkg_dep_list list;
|
||||
bool resolve_deps = true;
|
||||
|
||||
|
@ -53,7 +54,7 @@ static int cmd_depgraph(int argc, char **argv)
|
|||
resolve_deps = false;
|
||||
break;
|
||||
case 'R':
|
||||
if (repofd != AT_FDCWD) {
|
||||
if (repofd != -1) {
|
||||
fputs("repo specified more than once\n",
|
||||
stderr);
|
||||
tell_read_help(argv[0]);
|
||||
|
@ -71,6 +72,14 @@ static int cmd_depgraph(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (repofd == -1) {
|
||||
repofd = open(REPODIR, O_RDONLY | O_DIRECTORY);
|
||||
if (repofd < 0) {
|
||||
perror(REPODIR);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = optind; i < argc; ++i) {
|
||||
if (append_pkg(&list, argv[i]) == NULL)
|
||||
goto out;
|
||||
|
@ -84,7 +93,7 @@ static int cmd_depgraph(int argc, char **argv)
|
|||
print_dot_graph(&list);
|
||||
ret = EXIT_SUCCESS;
|
||||
out:
|
||||
if (repofd != AT_FDCWD)
|
||||
if (repofd != -1)
|
||||
close(repofd);
|
||||
pkg_list_cleanup(&list);
|
||||
return ret;
|
||||
|
@ -101,6 +110,7 @@ static command_t depgraph = {
|
|||
"Possible options:\n"
|
||||
" --repo-dir, -R <path> Specify the input repository path to fetch the\n"
|
||||
" packages from.\n"
|
||||
" If not set, defaults to " REPODIR ".\n"
|
||||
" --no-dependencies, -d Do not resolve dependencies, only process the\n"
|
||||
" packages listed on the command line.\n",
|
||||
.run_cmd = cmd_depgraph,
|
||||
|
|
|
@ -27,9 +27,7 @@ static int cmd_dump(int argc, char **argv)
|
|||
switch (i) {
|
||||
case 'l':
|
||||
flags |= DUMP_TOC;
|
||||
if (strcmp(optarg, "sqfs") == 0) {
|
||||
format = TOC_FORMAT_SQFS;
|
||||
} else if (strcmp(optarg, "initrd") == 0) {
|
||||
if (strcmp(optarg, "initrd") == 0) {
|
||||
format = TOC_FORMAT_INITRD;
|
||||
} else if (strcmp(optarg, "pkg") == 0) {
|
||||
format = TOC_FORMAT_PKG;
|
||||
|
@ -108,10 +106,6 @@ static command_t dump = {
|
|||
" If \"detail\" is specified, a human readable,\n"
|
||||
" pretty printed format with details is used.\n"
|
||||
"\n"
|
||||
" If \"sqfs\" is specified, a squashfs pseudo\n"
|
||||
" file is genareated for setting permissions\n"
|
||||
" bits and ownership appropriately.\n"
|
||||
"\n"
|
||||
" If \"initrd\" is specified, the format of\n"
|
||||
" Linux gen_init_cpio is produced.\n"
|
||||
"\n"
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
|
||||
#include "filelist/image_entry.h"
|
||||
|
||||
#include "pkgformat.h"
|
||||
#include "pkgreader.h"
|
||||
#include "pkg/pkgformat.h"
|
||||
#include "pkg/pkgreader.h"
|
||||
#include "pkg/pkgio.h"
|
||||
|
||||
#include "command.h"
|
||||
#include "pkgio.h"
|
||||
|
||||
typedef enum {
|
||||
DUMP_TOC = 0x01,
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "pkg/pkglist.h"
|
||||
#include "pkg/pkgio.h"
|
||||
#include "util/util.h"
|
||||
#include "depgraph.h"
|
||||
#include "command.h"
|
||||
#include "pkgio.h"
|
||||
#include "config.h"
|
||||
|
||||
enum {
|
||||
INSTALL_MODE_INSTALL = 0,
|
||||
|
@ -95,8 +96,8 @@ static int list_files(int repofd, const char *rootdir, TOC_FORMAT format,
|
|||
|
||||
static int cmd_install(int argc, char **argv)
|
||||
{
|
||||
int i, rootfd = AT_FDCWD, repofd = AT_FDCWD, flags = 0;
|
||||
int ret = EXIT_FAILURE, mode = INSTALL_MODE_INSTALL;
|
||||
int i, rootfd = -1, repofd = -1, flags = 0;
|
||||
TOC_FORMAT format = TOC_FORMAT_PRETTY;
|
||||
const char *rootdir = NULL;
|
||||
struct pkg_dep_list list;
|
||||
|
@ -118,9 +119,7 @@ static int cmd_install(int argc, char **argv)
|
|||
break;
|
||||
case 'l':
|
||||
mode = INSTALL_MODE_LIST_FILES;
|
||||
if (strcmp(optarg, "sqfs") == 0) {
|
||||
format = TOC_FORMAT_SQFS;
|
||||
} else if (strcmp(optarg, "initrd") == 0) {
|
||||
if (strcmp(optarg, "initrd") == 0) {
|
||||
format = TOC_FORMAT_INITRD;
|
||||
} else if (strcmp(optarg, "pkg") == 0) {
|
||||
format = TOC_FORMAT_PKG;
|
||||
|
@ -133,7 +132,7 @@ static int cmd_install(int argc, char **argv)
|
|||
}
|
||||
break;
|
||||
case 'R':
|
||||
if (repofd != AT_FDCWD) {
|
||||
if (repofd != -1) {
|
||||
fputs("repo specified more than once\n",
|
||||
stderr);
|
||||
tell_read_help(argv[0]);
|
||||
|
@ -146,7 +145,7 @@ static int cmd_install(int argc, char **argv)
|
|||
}
|
||||
break;
|
||||
case 'r':
|
||||
if (rootfd != AT_FDCWD) {
|
||||
if (rootfd != -1) {
|
||||
fputs("root specified more than once\n",
|
||||
stderr);
|
||||
tell_read_help(argv[0]);
|
||||
|
@ -182,6 +181,22 @@ static int cmd_install(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (repofd == -1) {
|
||||
repofd = open(REPODIR, O_RDONLY | O_DIRECTORY);
|
||||
if (repofd < 0) {
|
||||
perror(REPODIR);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (rootfd == -1) {
|
||||
rootfd = open(INSTALLROOT, O_RDONLY | O_DIRECTORY);
|
||||
if (rootfd < 0) {
|
||||
perror(INSTALLROOT);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = optind; i < argc; ++i) {
|
||||
if (append_pkg(&list, argv[i]) == NULL)
|
||||
goto out;
|
||||
|
@ -211,9 +226,9 @@ static int cmd_install(int argc, char **argv)
|
|||
|
||||
ret = EXIT_SUCCESS;
|
||||
out:
|
||||
if (rootfd != AT_FDCWD)
|
||||
if (rootfd != -1)
|
||||
close(rootfd);
|
||||
if (repofd != AT_FDCWD)
|
||||
if (repofd != -1)
|
||||
close(repofd);
|
||||
pkg_list_cleanup(&list);
|
||||
return ret;
|
||||
|
@ -231,11 +246,12 @@ static command_t install = {
|
|||
"Possible options:\n"
|
||||
" --repo-dir, -R <path> Specify the input repository path to fetch the\n"
|
||||
" packages from.\n"
|
||||
" --root, -r <path> A root directory to unpack the package. Default\n"
|
||||
" if not set is the current working directory.\n"
|
||||
" If not set, defaults to " REPODIR ".\n"
|
||||
" --root, -r <path> A root directory to unpack the package.\n"
|
||||
" If not set, defaults to " INSTALLROOT ".\n"
|
||||
" --no-chown, -o Do not change ownership of the extracted data.\n"
|
||||
" Keep the uid/gid of the user who runs the \n"
|
||||
" program."
|
||||
" program.\n"
|
||||
" --no-chmod, -m Do not change permission flags of the extarcted\n"
|
||||
" data. Use 0644 for all files and 0755 for all\n"
|
||||
" directories.\n"
|
||||
|
@ -252,10 +268,6 @@ static command_t install = {
|
|||
" If \"detail\" is specified, a human readable,\n"
|
||||
" pretty printed format with details is used.\n"
|
||||
"\n"
|
||||
" If \"sqfs\" is specified, a squashfs pseudo\n"
|
||||
" file is genareated for setting permissions bits\n"
|
||||
" and ownership appropriately.\n"
|
||||
"\n"
|
||||
" If \"initrd\" is specified, the format of Linux\n"
|
||||
" gen_init_cpio is produced.\n",
|
||||
.run_cmd = cmd_install,
|
||||
|
|
|
@ -13,6 +13,22 @@ static void oom(const char *filename, size_t linenum)
|
|||
input_file_complain(filename, linenum, "out of memory");
|
||||
}
|
||||
|
||||
static void unescape_name(char *name)
|
||||
{
|
||||
char *dst = name, *src = name + 1;
|
||||
|
||||
while (*src != '"' && *src != '\0') {
|
||||
if (src[0] == '\\' && (src[1] == '\\' || src[1] == '"')) {
|
||||
*(dst++) = src[1];
|
||||
src += 2;
|
||||
} else {
|
||||
*(dst++) = *(src++);
|
||||
}
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
static image_entry_t *filelist_mkentry(char *line, const char *filename,
|
||||
size_t linenum, mode_t filetype)
|
||||
{
|
||||
|
@ -27,8 +43,23 @@ static image_entry_t *filelist_mkentry(char *line, const char *filename,
|
|||
}
|
||||
|
||||
/* name */
|
||||
if (*line == '"') {
|
||||
for (i = 1; line[i] != '"' && line[i] != '\0'; ++i) {
|
||||
if (line[i] == '\\' &&
|
||||
(line[i + 1] == '\\' || line[i + 1] == '"')) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if (line[i++] != '"') {
|
||||
input_file_complain(filename, linenum,
|
||||
"missing \" after file name");
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; !isspace(line[i]) && line[i] != '\0'; ++i)
|
||||
;
|
||||
}
|
||||
|
||||
if (!isspace(line[i])) {
|
||||
input_file_complain(filename, linenum,
|
||||
|
@ -43,6 +74,10 @@ static image_entry_t *filelist_mkentry(char *line, const char *filename,
|
|||
}
|
||||
|
||||
memcpy(ent->name, line, i);
|
||||
|
||||
if (ent->name[0] == '"')
|
||||
unescape_name(ent->name);
|
||||
|
||||
if (canonicalize_name(ent->name)) {
|
||||
input_file_complain(filename, linenum, "invalid file name");
|
||||
goto fail;
|
||||
|
|
|
@ -65,9 +65,7 @@ static int cmd_pack(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (repodir == NULL) {
|
||||
fputs("missing argument: repository directory\n", stderr);
|
||||
tell_read_help(argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
repodir = REPODIR;
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
|
@ -117,6 +115,7 @@ static command_t pack = {
|
|||
" --file-list, -l <path> Specify a file containing a list of input files.\n"
|
||||
" --repo-dir, -r <path> Specify the output repository path to store the\n"
|
||||
" package in.\n"
|
||||
" If not set, defaults to " REPODIR ".\n"
|
||||
" --description, -d <path> Specify a file containing a description of the\n"
|
||||
" package, including information such as package\n"
|
||||
" dependencies, the actual package name, etc.\n"
|
||||
|
|
|
@ -21,10 +21,11 @@
|
|||
|
||||
#include "filelist/image_entry.h"
|
||||
|
||||
#include "compressor.h"
|
||||
#include "pkgformat.h"
|
||||
#include "pkgwriter.h"
|
||||
#include "comp/compressor.h"
|
||||
#include "pkg/pkgformat.h"
|
||||
#include "pkg/pkgwriter.h"
|
||||
#include "command.h"
|
||||
#include "config.h"
|
||||
|
||||
typedef struct dependency_t {
|
||||
struct dependency_t *next;
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#include "util/util.h"
|
||||
|
||||
#include "pkgreader.h"
|
||||
#include "pkg/pkgreader.h"
|
||||
#include "pkg/pkgio.h"
|
||||
#include "command.h"
|
||||
#include "pkgio.h"
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
{ "root", required_argument, NULL, 'r' },
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
#include <string.h>
|
||||
|
||||
#include "compressor.h"
|
||||
|
||||
static compressor_t *list = NULL;
|
||||
|
||||
void compressor_register(compressor_t *compressor)
|
||||
{
|
||||
compressor->next = list;
|
||||
list = compressor;
|
||||
}
|
||||
|
||||
compressor_t *compressor_by_name(const char *name)
|
||||
{
|
||||
compressor_t *it = list;
|
||||
|
||||
while (it != NULL && strcmp(it->name, name) != 0)
|
||||
it = it->next;
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
compressor_t *compressor_by_id(PKG_COMPRESSION id)
|
||||
{
|
||||
compressor_t *it = list;
|
||||
|
||||
while (it != NULL && it->id != id)
|
||||
it = it->next;
|
||||
|
||||
return it;
|
||||
}
|
Loading…
Reference in a new issue