[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: