Re: virtual fs ?
Sergey, Thu, Nov 27, 2003 16:47:37 +0100:
> Здравствуйте Все.
>
> Вопрос не по Дебиану конкретно, а по Линуксу вообще...
> Существуют ли средства, позволяющие создавать образы сд, содержащие
> только описания файлов - имя, тип, размер, путь, возможно права?
> Чтобы не хранить все это на винте, но иметь возможность поиска по
> всем имеющимся сд.
> Можно конечно сделать find /cdrom > file.txt , но это имхо как-то
find /cdrom -print0 | xargs -0 ls -dfl > cdrom.lst
советую давать имена этим файлам поосмысленнее, чем cdrom.lst.
Иначе потом бесполезно что-либо искать.
> криво... В общем, хочется не изобретать велосипед, а использовать
> проверенные решения...
а есть они?
Если делать нечего, можно скопировать атрибуты и размер (если файловая
система дырявые(sparse) файлы поддерживает: ext2/3, reiser, xfs, jfs).
Если чего-нить вроде фата - убери ftruncate.
Расширеные атрибуты не копируются, сам делай.
Например, вот так:
$ find /cdrom -exec cpattr '{}' './{}' \;
/*
* cpattr
* cc -o cpattr cpattr.c
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <fcntl.h>
#include <utime.h>
#include <errno.h>
#include <string.h>
int mkp(const char *path, unsigned long mode)
{
const char* p = strchr(path, '/');
char* part = (char*)malloc(strlen(path) + 1);
while ( p )
{
if ( p - path )
{
struct stat st;
strncpy(part, path, p - path)[p - path] = 0;
if ( stat(part, &st) < 0 )
{
if ( mkdir(part, mode) < 0 )
{
free(part);
return -1;
}
}
else if ( !S_ISDIR(st.st_mode) )
{
free(part);
errno = EINVAL;
return -1;
}
}
while ( *p && '/' == *p )
++p;
const char* next = strchr(p, '/');
p = next ? next: (*p ? p + strlen(p): 0);
}
free(part);
return 0;
}
int cpattr(const char* in, const char* out)
{
struct stat st;
struct utimbuf ut;
if ( lstat(in, &st) < 0 )
{
perror(in);
return 1;
}
if ( S_ISDIR(st.st_mode) )
{
if ( mkp(out, st.st_mode & 0777) < 0 )
{
perror(out);
return 2;
}
chown(out, st.st_uid, st.st_gid);
/* delay utimes. */
return 0;
}
unlink(out);
if ( S_ISLNK(st.st_mode) )
{
static char buf[PATH_MAX+1];
int n = readlink(in, buf, sizeof(buf) - 1);
if ( n < 0 )
{
perror(out);
return 2;
}
buf[n] = '\0';
if ( symlink(buf, out) < 0 )
{
perror(out);
return 2;
}
lchown(out, st.st_uid, st.st_gid);
chmod(out, st.st_mode & 0777);
}
if ( S_ISREG(st.st_mode) )
{
int fo = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0200);
if ( fo < 0 )
{
perror(out);
return 2;
}
ftruncate(fo, st.st_size);
fchown(fo, st.st_uid, st.st_gid);
fchmod(fo, st.st_mode & 0777);
close(fo);
}
#define DEVMASK (S_IFIFO|S_IFSOCK|S_IFCHR|S_IFBLK)
else if ( st.st_mode & DEVMASK )
{
if ( mknod(out, st.st_mode & (DEVMASK|0777), st.st_dev) < 0 )
{
perror(out);
return 2;
}
chown(out, st.st_uid, st.st_gid);
}
ut.actime = st.st_atime;
ut.modtime = st.st_mtime;
utime(out, &ut);
return 0;
}
int main(int argc, char* argv[])
{
umask(0);
return cpattr(argv[1], argv[2]);
}
Reply to: