* [devel] librpm payload
@ 2005-09-02 20:14 Alexey Tourbin
2005-09-02 21:00 ` Dmitry V. Levin
0 siblings, 1 reply; 9+ messages in thread
From: Alexey Tourbin @ 2005-09-02 20:14 UTC (permalink / raw)
To: devel
[-- Attachment #1: Type: text/plain, Size: 352 bytes --]
Есть ли в librpm API, которое позволяет получить доступ к содержимому
payload без распаковки архива? То есть мне нужна "прозрачная"
распаковка gzdio и доступ к файлам внутри cpio. Задача: считать первые
4096 байтов каждого файла (без распаковки). Скормить считанные байты в
libmagic. То есть определение типа файлов внутри rpm без распаковки.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [devel] librpm payload
2005-09-02 20:14 [devel] librpm payload Alexey Tourbin
@ 2005-09-02 21:00 ` Dmitry V. Levin
2005-09-05 3:43 ` [devel] " Alexey Tourbin
0 siblings, 1 reply; 9+ messages in thread
From: Dmitry V. Levin @ 2005-09-02 21:00 UTC (permalink / raw)
To: ALT Devel discussion list
[-- Attachment #1: Type: text/plain, Size: 781 bytes --]
On Sat, Sep 03, 2005 at 12:14:56AM +0400, Alexey Tourbin wrote:
> Есть ли в librpm API, которое позволяет получить доступ к содержимому
> payload без распаковки архива? То есть мне нужна "прозрачная"
> распаковка gzdio и доступ к файлам внутри cpio. Задача: считать первые
> 4096 байтов каждого файла (без распаковки). Скормить считанные байты в
> libmagic. То есть определение типа файлов внутри rpm без распаковки.
librpmio может предоставить cpio-архив в виде обычного потока, для
которого, кажется, применимы операции типа fsetpos(3). Но поскольку этот
cpio-архив на практике запакован, прозрачной распаковки всё равно не
миновать. Считать первые N байт каждого файла этого cpio-потока librpmio
вряд ли поможет, лучше поискать другие средства.
--
ldv
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* [devel] Re: librpm payload
2005-09-02 21:00 ` Dmitry V. Levin
@ 2005-09-05 3:43 ` Alexey Tourbin
2005-09-05 9:09 ` Sergey Vlasov
2005-09-11 17:06 ` Alexey Tourbin
0 siblings, 2 replies; 9+ messages in thread
From: Alexey Tourbin @ 2005-09-05 3:43 UTC (permalink / raw)
To: ALT Devel discussion list
[-- Attachment #1.1: Type: text/plain, Size: 688 bytes --]
On Sat, Sep 03, 2005 at 01:00:07AM +0400, Dmitry V. Levin wrote:
> librpmio может предоставить cpio-архив в виде обычного потока, для
> которого, кажется, применимы операции типа fsetpos(3). Но поскольку этот
> cpio-архив на практике запакован, прозрачной распаковки всё равно не
> миновать. Считать первые N байт каждого файла этого cpio-потока librpmio
> вряд ли поможет, лучше поискать другие средства.
Как читать поток cpio, я разобрался. Теперь дальше, как парсить cpio?
У него какой-то хитрый padding (см. TODO). Как libmagic подключить --
вроде ясно, magic_buffer().
Что-то такое есть в rpm-4_0-4.0.4/lib/{cpio,fsm}.{c,h}, но им
воспользоваться очень проблемно.
[-- Attachment #1.2: rpmfile.c --]
[-- Type: text/plain, Size: 2349 bytes --]
// gcc -Wall -I/usr/include/rpm rpmfile.c -lrpm -o rpmfile
#include <error.h>
#include <stdlib.h>
#include <string.h>
#include <rpmlib.h>
struct cpio_header
{
char magic[6];
char inode[8];
char mode[8];
char uid[8];
char gid[8];
char nlink[8];
char mtime[8];
char filesize[8];
char dev_major[8];
char dev_minor[8];
char rdev_major[8];
char rdev_minor[8];
char namesize[8];
char checksum[8];
};
int num8(char *s)
{
char c = s[8];
s[8] = 0;
int n = strtoul(s, NULL, 16);
s[8] = c;
return n;
}
FD_t open_payload(const char *fname)
{
FD_t fd = Fopen(fname, "r.ufdio");
if (Ferror(fd))
error(1, 0, "%s: %s", fname, Fstrerror(fd));
Header h; int isSource;
if (rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL))
error(1, 0, "%s: %s", fname, "bad RPM header");
char *method;
if (headerGetEntry(h, RPMTAG_PAYLOADCOMPRESSOR, NULL, (void **) &method, NULL))
method = "gzip";
char *type = "r";
if (strcmp(method, "gzip") == 0)
type = "r.gzdio";
if (strcmp(method, "bzip2") == 0)
type = "r.bzdio";
FD_t zfd = Fdopen(fd, type);
if (Ferror(zfd))
error(1, 0, "%s: %s", fname, Fstrerror(zfd));
if (fd != zfd)
Fclose(fd);
return zfd;
}
void rpmfile(const char *fname)
{
FD_t fd = open_payload(fname);
while (1) {
size_t n;
struct cpio_header h;
n = Fread(&h, sizeof(h), 1, fd);
if (n != 1)
error(1, 0, "%s: %s", fname, "bad cpio header");
if (strncmp(h.magic, "070701", 6))
error(1, 0, "%s: %s", fname, "bad cpio magic");
char path[PATH_MAX];
int len = num8(h.namesize);
n = Fread(path, len, 1, fd);
if (n != 1)
error(1, 0, "%s: %s", fname, "bad cpio namesize");
if (strcmp(path, "TRAILER!!!") == 0)
break;
char buf[4096];
int size = num8(h.filesize);
int toread = (size > sizeof(buf)) ? sizeof(buf) : size;
int toseek = size - toread;
n = 1;
if (toread)
n = Fread(buf, toread, 1, fd);
if (toseek)
n += Fseek(fd, toseek, SEEK_CUR);
if (n != 1)
error(1, 0, "%s: %s", fname, "bad cpio filesize");
int mode = num8(h.mode);
printf("%s\t%s\t0%o\n", fname, path, mode);
/* TODO: zero padded? how do I seek ? */
break;
}
Fclose(fd);
}
int main(int argc, char *argv[])
{
while (--argc > 0)
rpmfile(*++argv);
return 0;
}
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [devel] Re: librpm payload
2005-09-05 3:43 ` [devel] " Alexey Tourbin
@ 2005-09-05 9:09 ` Sergey Vlasov
2005-09-11 17:06 ` Alexey Tourbin
1 sibling, 0 replies; 9+ messages in thread
From: Sergey Vlasov @ 2005-09-05 9:09 UTC (permalink / raw)
To: ALT Devel discussion list
[-- Attachment #1: Type: text/plain, Size: 1203 bytes --]
On Mon, Sep 05, 2005 at 07:43:57AM +0400, Alexey Tourbin wrote:
> On Sat, Sep 03, 2005 at 01:00:07AM +0400, Dmitry V. Levin wrote:
> > librpmio может предоставить cpio-архив в виде обычного потока, для
> > которого, кажется, применимы операции типа fsetpos(3). Но поскольку этот
> > cpio-архив на практике запакован, прозрачной распаковки всё равно не
> > миновать. Считать первые N байт каждого файла этого cpio-потока librpmio
> > вряд ли поможет, лучше поискать другие средства.
>
> Как читать поток cpio, я разобрался. Теперь дальше, как парсить cpio?
Его даже ядро читать умеет (в initramfs) ;)
> У него какой-то хитрый padding (см. TODO). Как libmagic подключить --
> вроде ясно, magic_buffer().
#define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
...
parse_header(collected);
/* тут this_header уже продвинут за struct cpio_header */
next_header = this_header + N_ALIGN(name_len) + body_len;
next_header = (next_header + 3) & ~3;
Правда, после SkipIt (пропуск до позиции next_header) там есть ещё
Reset:
static int __init do_reset(void)
{
while(count && *victim == '\0')
eat(1);
if (count && (this_header & 3))
error("broken padding");
return 1;
}
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* [devel] Re: librpm payload
2005-09-05 3:43 ` [devel] " Alexey Tourbin
2005-09-05 9:09 ` Sergey Vlasov
@ 2005-09-11 17:06 ` Alexey Tourbin
2005-09-11 22:14 ` Dmitry V. Levin
1 sibling, 1 reply; 9+ messages in thread
From: Alexey Tourbin @ 2005-09-11 17:06 UTC (permalink / raw)
To: ALT Devel discussion list
[-- Attachment #1.1: Type: text/plain, Size: 1814 bytes --]
On Mon, Sep 05, 2005 at 07:43:57AM +0400, Alexey Tourbin wrote:
> Как читать поток cpio, я разобрался. Теперь дальше, как парсить cpio?
> У него какой-то хитрый padding (см. TODO). Как libmagic подключить --
> вроде ясно, magic_buffer().
>
> Что-то такое есть в rpm-4_0-4.0.4/lib/{cpio,fsm}.{c,h}, но им
> воспользоваться очень проблемно.
Нет, задолбало на Си писать. Это контрпродуктивно. Можно что-нибудь
сделать, а можно сидеть и пейсать на Си. Ну его в баню.
Написал на шелле, с кешированием для каталогов. Для робота это важно --
очень долго (с распаковкой всех rpm'ов) только один раз будет работать.
$ ./rpmfile -h
Usage:
rpmfile [-h] [*FILE*...] [*DIR*...]
$ ./rpmfile ~/build/repo/i586/RPMS.hasher/qa-robot-0.2-alt1.noarch.rpm
/usr/bin/bugs 100755 Bourne shell script text executable
/usr/bin/csv2tab 100755 perl script text executable
...
$ ./rpmfile ~/build/repo/i586/RPMS.hasher |sort -t$'\t' -k1,1 -u
libsqlite3 /usr/lib/libsqlite3.so.0 120777 symbolic link to `libsqlite3.so.0.8.6'
libsqlite3-devel /usr/include/sqlite3.h 100644 ASCII C program text
...
$
То есть если "дампить" каталог, то впереди добавляется ещё подно поле --
имя пакета. Правильнее было бы добавлять не имя пакета, а собственно
имя файла, но мне сейчас нужнее имя пакета.
А кеширование работает так:
$ rm -rf ~/tmp/tmp
$ mkdir -p ~/tmp/tmp
$ time workdir=~/tmp/tmp ./rpmfile ~/build/repo/i586/RPMS.hasher >/dev/null
workdir=~/tmp/tmp ./rpmfile ~/build/repo/i586/RPMS.hasher > /dev/null 16,70s user 4,81s system 95% cpu 22,606 total
$ time workdir=~/tmp/tmp ./rpmfile ~/build/repo/i586/RPMS.hasher >/dev/null
workdir=~/tmp/tmp ./rpmfile ~/build/repo/i586/RPMS.hasher > /dev/null 1,46s user 0,22s system 99% cpu 1,685 total
$
Трюк с paste(1) -- по моему, красиво. :)
[-- Attachment #1.2: rpmfile --]
[-- Type: text/plain, Size: 1734 bytes --]
#!/bin/sh -ef
export LC_ALL=C
dump_file()
{
rpm -qp --qf '[%{FILENAMES}\t%{FILEMODES:octal}\n]' "$@" >files
if [ -d d ]; then chmod -Rf u+rwX d; rm -rf d; fi
rpm2cpio "$@" |(mkdir d; cd d; cpio -idmu --quiet)
awk -F'\t' '{printf"d/%s\0",$1}' files |xargs -r0 file -b >types
paste files types
}
dump_dir()
{
local d="$1"; shift
packages "$d" >packages
sort -t$'\t' -o packages -u -k1,1 packages
mkdir -p c
while IFS=$'\t' read p v f _; do
b="${f%%.rpm}"
[ -f c/"$b" ] || dump_file "$d/$f" >c/"$b"
awk -v p="$p" '{print p"\t"$0}' c/"$b"
done <packages
}
while getopts h opt; do
case "$opt" in
h) pod2usage --exit=0 "$0"; exit 0 ;;
*) pod2usage --exit=2 "$0"; exit 2 ;;
esac
done
shift "$((OPTIND-1))"
if [ -z "$workdir" ]; then
atexit() { rc=$?; trap - EXIT; rm -rf "$workdir"; exit $rc; }
workdir="$(mktemp -d -t "${0##*/}.XXXXXXXX")"
trap atexit EXIT HUP INT QUIT PIPE TERM
export workdir
fi
if [ -z "$*" ]; then
: ${sisyphus:=/raid/ALT/Sisyphus}
set -- "$sisyphus"/files/i586/RPMS
fi
for arg; do
arg="$(readlink -ev "${arg:?}")"
cd "${workdir:?}"
if [ -f "$arg" ]; then
dump_file "$arg"
else
dump_dir "$arg"
fi
cd -
done
: <<'__EOF__'
=head1 NAME
rpmfile - list file modes and types in RPM packages
=head1 SYNOPSIS
B<rpmfile> [B<-h>] [I<FILE>...] [I<DIR>...]
=head1 AUTHOR
Written by Alexey Tourbin <at@altlinux.org>.
=head1 COPYING
Copyright (c) 2005 Alexey Tourbin, ALT Linux Team.
This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
=head1 SEE ALSO
rpm(8),
rpm2cpio(8),
file(1)
=cut
__EOF__
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [devel] Re: librpm payload
2005-09-11 17:06 ` Alexey Tourbin
@ 2005-09-11 22:14 ` Dmitry V. Levin
2005-09-12 3:48 ` Alexey Tourbin
0 siblings, 1 reply; 9+ messages in thread
From: Dmitry V. Levin @ 2005-09-11 22:14 UTC (permalink / raw)
To: ALT Devel discussion list
[-- Attachment #1: Type: text/plain, Size: 801 bytes --]
On Sun, Sep 11, 2005 at 09:06:44PM +0400, Alexey Tourbin wrote:
> On Mon, Sep 05, 2005 at 07:43:57AM +0400, Alexey Tourbin wrote:
> > Как читать поток cpio, я разобрался. Теперь дальше, как парсить cpio?
> > У него какой-то хитрый padding (см. TODO). Как libmagic подключить --
> > вроде ясно, magic_buffer().
> >
> > Что-то такое есть в rpm-4_0-4.0.4/lib/{cpio,fsm}.{c,h}, но им
> > воспользоваться очень проблемно.
>
> Нет, задолбало на Си писать. Это контрпродуктивно. Можно что-нибудь
> сделать, а можно сидеть и пейсать на Си. Ну его в баню.
>
> Написал на шелле, с кешированием для каталогов. Для робота это важно --
> очень долго (с распаковкой всех rpm'ов) только один раз будет работать.
Да, красиво, мне понравилось. Запакуй куда-нибудь, пожалуйста.
--
ldv
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* [devel] Re: librpm payload
2005-09-11 22:14 ` Dmitry V. Levin
@ 2005-09-12 3:48 ` Alexey Tourbin
2005-09-12 10:28 ` Dmitry V. Levin
0 siblings, 1 reply; 9+ messages in thread
From: Alexey Tourbin @ 2005-09-12 3:48 UTC (permalink / raw)
To: ALT Devel discussion list
[-- Attachment #1: Type: text/plain, Size: 809 bytes --]
On Mon, Sep 12, 2005 at 02:14:10AM +0400, Dmitry V. Levin wrote:
> > Написал на шелле, с кешированием для каталогов. Для робота это важно --
> > очень долго (с распаковкой всех rpm'ов) только один раз будет работать.
>
> Да, красиво, мне понравилось. Запакуй куда-нибудь, пожалуйста.
Посмотрел, что он мне тут ночью сделал. Есть грабли с %ghost файлами,
с неправильными правами доступа на каталог (когда в каталог "не пускают")
и с девайсами. Похоже, придется использовать fakeroot.
Запакую в qa-robot-0.3. Он же использует /usr/bin/packages.
local d="$1"; shift
packages "$d" >packages
sort -t$'\t' -o packages -u -k1,1 packages
while IFS=$'\t' read p v f _; do
Если в каталоге $d есть дупы, то будут из одноименных пакетов будет
обработан только один, с наибольшей версией.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [devel] Re: librpm payload
2005-09-12 3:48 ` Alexey Tourbin
@ 2005-09-12 10:28 ` Dmitry V. Levin
2005-09-13 8:51 ` [devel] rpmfile Alexey Tourbin
0 siblings, 1 reply; 9+ messages in thread
From: Dmitry V. Levin @ 2005-09-12 10:28 UTC (permalink / raw)
To: ALT Devel discussion list
[-- Attachment #1: Type: text/plain, Size: 565 bytes --]
On Mon, Sep 12, 2005 at 07:48:30AM +0400, Alexey Tourbin wrote:
> Посмотрел, что он мне тут ночью сделал. Есть грабли с %ghost файлами,
> с неправильными правами доступа на каталог (когда в каталог "не пускают")
> и с девайсами. Похоже, придется использовать fakeroot.
Когда в каталг не пускают, можно использовать chmod.
[...]
> Если в каталоге $d есть дупы, то будут из одноименных пакетов будет
> обработан только один, с наибольшей версией.
Это не всегда удобно. Может, лучше по дереву на бинарный пакет, чтобы
не пересекались?
--
ldv
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* [devel] rpmfile
2005-09-12 10:28 ` Dmitry V. Levin
@ 2005-09-13 8:51 ` Alexey Tourbin
0 siblings, 0 replies; 9+ messages in thread
From: Alexey Tourbin @ 2005-09-13 8:51 UTC (permalink / raw)
To: ALT Devel discussion list
[-- Attachment #1: Type: text/plain, Size: 1829 bytes --]
On Mon, Sep 12, 2005 at 02:28:57PM +0400, Dmitry V. Levin wrote:
> > Посмотрел, что он мне тут ночью сделал. Есть грабли с %ghost файлами,
> > с неправильными правами доступа на каталог (когда в каталог "не пускают")
> > и с девайсами. Похоже, придется использовать fakeroot.
> Когда в каталг не пускают, можно использовать chmod.
chmod проще всего сделать рекурсивно, но тогда может частично измениться
описание файла, т.к. при чмоде "слетает" suid/sgid. С fakeroot пока
получается лучше всего.
at@solemn ~/.cmdcache 4 $ grep -r setuid rpmfile
rpmfile/i327820s28180m1099489621:/usr/sbin/suexec 104711 setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.18, dynamically linked (uses shared libs), stripped
rpmfile/i275202s28073547m1084879330:/usr/lib/erlang/erts-5.3/src/setuid_socket_wrap.c 100644 ASCII C program text
rpmfile/i328102s346373m1094052150:/usr/sbin/exim-mysql 104711 setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.18, dynamically linked (uses shared libs), stripped
rpmfile/i327778s499335m1093862089:/usr/lib/amanda/dumper 104710 setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.18, dynamically linked (uses shared libs), stripped
rpmfile/i327778s499335m1093862089:/usr/lib/amanda/planner 104710 setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.18, dynamically linked (uses shared libs), stripped
rpmfile/i327778s499335m1093862089:/usr/sbin/amcheck 104710 setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.18, dynamically linked (uses shared libs), stripped
^C
at@solemn ~/.cmdcache 4 $
> Это не всегда удобно. Может, лучше по дереву на бинарный пакет, чтобы
> не пересекались?
Ok.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-09-13 8:51 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-09-02 20:14 [devel] librpm payload Alexey Tourbin
2005-09-02 21:00 ` Dmitry V. Levin
2005-09-05 3:43 ` [devel] " Alexey Tourbin
2005-09-05 9:09 ` Sergey Vlasov
2005-09-11 17:06 ` Alexey Tourbin
2005-09-11 22:14 ` Dmitry V. Levin
2005-09-12 3:48 ` Alexey Tourbin
2005-09-12 10:28 ` Dmitry V. Levin
2005-09-13 8:51 ` [devel] rpmfile Alexey Tourbin
ALT Linux Team development discussions
This inbox may be cloned and mirrored by anyone:
git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
public-inbox-index devel
Example config snippet for mirrors.
Newsgroup available over NNTP:
nntp://lore.altlinux.org/org.altlinux.lists.devel
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git