Initial support for low level ECMA-119 tree.
This only adds the tree creation functions, no sorting and name mangling yet. Only plain ECMA-119 supported for now, nor RR, relaxed restrictions, etc.. This also adds a little test program.
This commit is contained in:
parent
aa312cf7d7
commit
40b27dbacc
@ -27,3 +27,4 @@ test/test
|
|||||||
demo/lsl
|
demo/lsl
|
||||||
demo/cat
|
demo/cat
|
||||||
demo/tree
|
demo/tree
|
||||||
|
demo/ecma119tree
|
||||||
|
12
Makefile.am
12
Makefile.am
@ -31,7 +31,10 @@ src_libisofs_la_SOURCES = \
|
|||||||
src/util.c \
|
src/util.c \
|
||||||
src/filesrc.h \
|
src/filesrc.h \
|
||||||
src/filesrc.c \
|
src/filesrc.c \
|
||||||
src/ecma119.h
|
src/ecma119.h \
|
||||||
|
src/ecma119.c \
|
||||||
|
src/ecma119_tree.h \
|
||||||
|
src/ecma119_tree.c
|
||||||
libinclude_HEADERS = \
|
libinclude_HEADERS = \
|
||||||
src/libisofs.h
|
src/libisofs.h
|
||||||
|
|
||||||
@ -41,7 +44,8 @@ libinclude_HEADERS = \
|
|||||||
noinst_PROGRAMS = \
|
noinst_PROGRAMS = \
|
||||||
demo/lsl \
|
demo/lsl \
|
||||||
demo/cat \
|
demo/cat \
|
||||||
demo/tree
|
demo/tree \
|
||||||
|
demo/ecma119tree
|
||||||
|
|
||||||
demo_lsl_CPPFLAGS = -Isrc
|
demo_lsl_CPPFLAGS = -Isrc
|
||||||
demo_lsl_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
demo_lsl_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
||||||
@ -55,6 +59,10 @@ demo_tree_CPPFLAGS = -Isrc
|
|||||||
demo_tree_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
demo_tree_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
||||||
demo_tree_SOURCES = demo/tree.c
|
demo_tree_SOURCES = demo/tree.c
|
||||||
|
|
||||||
|
demo_ecma119tree_CPPFLAGS = -Isrc
|
||||||
|
demo_ecma119tree_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
||||||
|
demo_ecma119tree_SOURCES = demo/ecma119_tree.c
|
||||||
|
|
||||||
|
|
||||||
## Build unit test
|
## Build unit test
|
||||||
|
|
||||||
|
111
demo/ecma119_tree.c
Normal file
111
demo/ecma119_tree.c
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Little program that imports a directory to iso image, generates the
|
||||||
|
* ecma119 low level tree and prints it.
|
||||||
|
* Note that this is not an API example, but a little program for test
|
||||||
|
* purposes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libisofs.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
#include "ecma119_tree.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_permissions(mode_t mode)
|
||||||
|
{
|
||||||
|
char perm[10];
|
||||||
|
|
||||||
|
//TODO suid, sticky...
|
||||||
|
|
||||||
|
perm[9] = '\0';
|
||||||
|
perm[8] = mode & S_IXOTH ? 'x' : '-';
|
||||||
|
perm[7] = mode & S_IWOTH ? 'w' : '-';
|
||||||
|
perm[6] = mode & S_IROTH ? 'r' : '-';
|
||||||
|
perm[5] = mode & S_IXGRP ? 'x' : '-';
|
||||||
|
perm[4] = mode & S_IWGRP ? 'w' : '-';
|
||||||
|
perm[3] = mode & S_IRGRP ? 'r' : '-';
|
||||||
|
perm[2] = mode & S_IXUSR ? 'x' : '-';
|
||||||
|
perm[1] = mode & S_IWUSR ? 'w' : '-';
|
||||||
|
perm[0] = mode & S_IRUSR ? 'r' : '-';
|
||||||
|
printf("[%s]",perm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_dir(Ecma119Node *dir, int level)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char sp[level * 2 + 1];
|
||||||
|
|
||||||
|
for (i = 0; i < level * 2; i += 2) {
|
||||||
|
sp[i] = '|';
|
||||||
|
sp[i+1] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
sp[level * 2-1] = '-';
|
||||||
|
sp[level * 2] = '\0';
|
||||||
|
|
||||||
|
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||||
|
Ecma119Node *child = dir->info.dir.children[i];
|
||||||
|
|
||||||
|
if (child->type == ECMA119_DIR) {
|
||||||
|
printf("%s+[D] ", sp);
|
||||||
|
print_permissions(iso_node_get_permissions(child->node));
|
||||||
|
printf(" %s\n", child->iso_name);
|
||||||
|
print_dir(child, level+1);
|
||||||
|
} else if (child->type == ECMA119_FILE) {
|
||||||
|
printf("%s-[F] ", sp);
|
||||||
|
print_permissions(iso_node_get_permissions(child->node));
|
||||||
|
printf(" %s {%p}\n", child->iso_name, (void*)child->info.file);
|
||||||
|
} else {
|
||||||
|
printf("%s-[????] ", sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
IsoImage *image;
|
||||||
|
Ecma119Image *ecma119;
|
||||||
|
Ecma119Node *tree;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
printf ("You need to specify a valid path\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = iso_image_new("volume_id", &image);
|
||||||
|
if (result < 0) {
|
||||||
|
printf ("Error creating image\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
iso_image_set_msgs_severities(image, "NEVER", "ALL", "");
|
||||||
|
|
||||||
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[1]);
|
||||||
|
if (result < 0) {
|
||||||
|
printf ("Error adding directory %d\n", result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma119 = calloc(1, sizeof(Ecma119Image));
|
||||||
|
ecma119->iso_level = 1;
|
||||||
|
|
||||||
|
/* create low level tree */
|
||||||
|
result = ecma119_tree_create(ecma119, (IsoNode*)iso_image_get_root(image), &tree);
|
||||||
|
if (result < 0) {
|
||||||
|
printf ("Error creating ecma-119 tree: %d\n", result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("================= ECMA-119 TREE =================\n");
|
||||||
|
print_dir(tree, 0);
|
||||||
|
printf("\n\n");
|
||||||
|
|
||||||
|
ecma119_node_free(tree);
|
||||||
|
iso_image_unref(image);
|
||||||
|
return 0;
|
||||||
|
}
|
@ -59,6 +59,7 @@ print_file_src(IsoFileSource *file)
|
|||||||
file->lstat(file, &info);
|
file->lstat(file, &info);
|
||||||
print_type(info.st_mode);
|
print_type(info.st_mode);
|
||||||
print_permissions(info.st_mode);
|
print_permissions(info.st_mode);
|
||||||
|
printf(" {%ld,%ld} ", (long)info.st_dev, (long)info.st_ino);
|
||||||
name = file->get_name(file);
|
name = file->get_name(file);
|
||||||
printf(" %s", name);
|
printf(" %s", name);
|
||||||
free(name);
|
free(name);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Little program that reads an existing ISO image and prints its
|
* Little program that import a directory and prints the resulting iso tree.
|
||||||
* contents to stdout.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
9
src/ecma119.c
Normal file
9
src/ecma119.c
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
*
|
||||||
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation. See COPYING file for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ecma119.h"
|
@ -10,9 +10,11 @@
|
|||||||
#define LIBISO_ECMA119_H_
|
#define LIBISO_ECMA119_H_
|
||||||
|
|
||||||
typedef struct ecma119_image Ecma119Image;
|
typedef struct ecma119_image Ecma119Image;
|
||||||
|
typedef struct ecma119_node Ecma119Node;
|
||||||
typedef struct Iso_File_Src IsoFileSrc;
|
typedef struct Iso_File_Src IsoFileSrc;
|
||||||
|
|
||||||
struct ecma119_image {
|
struct ecma119_image {
|
||||||
|
Ecma119Node *root;
|
||||||
|
|
||||||
unsigned int iso_level:2;
|
unsigned int iso_level:2;
|
||||||
|
|
||||||
|
243
src/ecma119_tree.c
Normal file
243
src/ecma119_tree.c
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
*
|
||||||
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation. See COPYING file for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ecma119_tree.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "node.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "filesrc.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static
|
||||||
|
int set_iso_name(Ecma119Image *img, IsoNode *iso, Ecma119Node *node)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *ascii_name;
|
||||||
|
|
||||||
|
if (iso->name == NULL) {
|
||||||
|
/* it is not necessarily an error, it can be the root */
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO add support for other input charset
|
||||||
|
ret = str2ascii("UTF-8", iso->name, &ascii_name);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO add support for relaxed constraints
|
||||||
|
if (iso->type == LIBISO_DIR) {
|
||||||
|
if (img->iso_level == 1) {
|
||||||
|
iso_dirid(ascii_name, 8);
|
||||||
|
} else {
|
||||||
|
iso_dirid(ascii_name, 31);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (img->iso_level == 1) {
|
||||||
|
iso_1_fileid(ascii_name);
|
||||||
|
} else {
|
||||||
|
iso_2_fileid(ascii_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node->iso_name = ascii_name;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int create_ecma119_node(Ecma119Image *img, IsoNode *iso, Ecma119Node **node)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Ecma119Node *ecma;
|
||||||
|
|
||||||
|
ecma = calloc(1, sizeof(Ecma119Node));
|
||||||
|
if (ecma == NULL) {
|
||||||
|
return ISO_MEM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = set_iso_name(img, iso, ecma);
|
||||||
|
if (ret < 0) {
|
||||||
|
free(ecma);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* take a ref to the IsoNode */
|
||||||
|
ecma->node = iso;
|
||||||
|
iso_node_ref(iso);
|
||||||
|
|
||||||
|
// TODO what to do with full name? For now, not a problem, as we
|
||||||
|
// haven't support for charset conversion. However, one we had it,
|
||||||
|
// we need to choose whether to do it here (consumes more memory)
|
||||||
|
// or on writting
|
||||||
|
*node = ecma;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ECMA-119 node representing a directory from a iso directory
|
||||||
|
* node.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Ecma119Node **children;
|
||||||
|
|
||||||
|
children = calloc(1, sizeof(void*) * iso->nchildren);
|
||||||
|
if (children == NULL) {
|
||||||
|
return ISO_MEM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = create_ecma119_node(img, (IsoNode*)iso, node);
|
||||||
|
if (ret < 0) {
|
||||||
|
free(children);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
(*node)->type = ECMA119_DIR;
|
||||||
|
(*node)->info.dir.nchildren = 0;
|
||||||
|
(*node)->info.dir.children = children;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ECMA-119 node representing a regular file from a iso file
|
||||||
|
* node.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
IsoFileSrc *src;
|
||||||
|
|
||||||
|
ret = iso_file_src_create(img, iso, &src);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = create_ecma119_node(img, (IsoNode*)iso, node);
|
||||||
|
if (ret < 0) {
|
||||||
|
/*
|
||||||
|
* the src doesn't need to be freed, it is free together with
|
||||||
|
* the Ecma119Image
|
||||||
|
*/
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
(*node)->type = ECMA119_FILE;
|
||||||
|
(*node)->info.file = src;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecma119_node_free(Ecma119Node *node)
|
||||||
|
{
|
||||||
|
if (node->type == ECMA119_DIR) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < node->info.dir.nchildren; i++) {
|
||||||
|
ecma119_node_free(node->info.dir.children[i]);
|
||||||
|
}
|
||||||
|
free(node->info.dir.children);
|
||||||
|
}
|
||||||
|
free(node->iso_name);
|
||||||
|
iso_node_unref(node->node);
|
||||||
|
//TODO? free(node->name);
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* 1 success, 0 node ignored, < 0 error
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Ecma119Node *node;
|
||||||
|
|
||||||
|
if (image == NULL || iso == NULL || tree == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iso->hidden & LIBISO_HIDE_ON_RR) {
|
||||||
|
/* file will be ignored */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(iso->type) {
|
||||||
|
case LIBISO_FILE:
|
||||||
|
ret = create_file(image, (IsoFile*)iso, &node);
|
||||||
|
break;
|
||||||
|
case LIBISO_SYMLINK:
|
||||||
|
//TODO only supported with RR
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case LIBISO_SPECIAL:
|
||||||
|
//TODO only supported with RR
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case LIBISO_BOOT:
|
||||||
|
//TODO
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case LIBISO_DIR:
|
||||||
|
{
|
||||||
|
IsoNode *pos;
|
||||||
|
IsoDir *dir = (IsoDir*)iso;
|
||||||
|
ret = create_dir(image, dir, &node);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
pos = dir->children;
|
||||||
|
while (pos) {
|
||||||
|
Ecma119Node *child;
|
||||||
|
ret = create_tree(image, pos, &child);
|
||||||
|
if (ret < 0) {
|
||||||
|
/* error */
|
||||||
|
ecma119_node_free(node);
|
||||||
|
return ret;
|
||||||
|
} else if (ret == ISO_SUCCESS) {
|
||||||
|
/* add child to this node */
|
||||||
|
int nchildren = node->info.dir.nchildren++;
|
||||||
|
node->info.dir.children[nchildren] = child;
|
||||||
|
child->parent = node;
|
||||||
|
}
|
||||||
|
pos = pos->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* should never happen */
|
||||||
|
return ISO_ERROR;
|
||||||
|
}
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*tree = node;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ecma119_tree_create(Ecma119Image *img, IsoNode *iso, Ecma119Node **tree)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = create_tree(img, iso, tree);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO
|
||||||
|
* - take care about dirs whose level is over 8
|
||||||
|
* - sort files in dir
|
||||||
|
* - mangle names
|
||||||
|
*/
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
68
src/ecma119_tree.h
Normal file
68
src/ecma119_tree.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
*
|
||||||
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation. See COPYING file for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBISO_ECMA119_TREE_H_
|
||||||
|
#define LIBISO_ECMA119_TREE_H_
|
||||||
|
|
||||||
|
#include "libisofs.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
|
||||||
|
enum ecma119_node_type {
|
||||||
|
ECMA119_FILE,
|
||||||
|
ECMA119_DIR
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Struct with info about a node representing a tree
|
||||||
|
*/
|
||||||
|
struct ecma119_dir_info {
|
||||||
|
/* Block where the directory entries will be written on image */
|
||||||
|
size_t block;
|
||||||
|
|
||||||
|
size_t nchildren;
|
||||||
|
Ecma119Node **children;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A node for a tree containing all the information necessary for writing
|
||||||
|
* an ISO9660 volume.
|
||||||
|
*/
|
||||||
|
struct ecma119_node
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Name in ASCII, conforming to selected ISO level.
|
||||||
|
* Version number is not include, it is added on the fly
|
||||||
|
*/
|
||||||
|
char *iso_name;
|
||||||
|
|
||||||
|
// TODO mmm, is this needed?
|
||||||
|
// or should we compute charset translation on-the-fly?
|
||||||
|
//char *name; /**< full name, in output charset (UTF-8 for now) */
|
||||||
|
|
||||||
|
Ecma119Node *parent;
|
||||||
|
|
||||||
|
IsoNode *node; /*< reference to the iso node */
|
||||||
|
|
||||||
|
enum ecma119_node_type type; /**< file, symlink, directory or placeholder */
|
||||||
|
union {
|
||||||
|
IsoFileSrc *file;
|
||||||
|
struct ecma119_dir_info dir;
|
||||||
|
} info;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int ecma119_tree_create(Ecma119Image *img, IsoNode *iso, Ecma119Node **tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free an Ecma119Node, and its children if node is a dir
|
||||||
|
*/
|
||||||
|
void ecma119_node_free(Ecma119Node *node);
|
||||||
|
|
||||||
|
#endif /*LIBISO_ECMA119_TREE_H_*/
|
Loading…
Reference in New Issue
Block a user