Browse Source

Fixed obsolete lines, free joliet tree, added public functions

master
Mario Danic 15 years ago
parent
commit
9746b5b273
  1. 6
      libisofs/ecma119.c
  2. 377
      libisofs/file.c
  3. 110
      libisofs/file.h
  4. 15
      libisofs/joliet.c
  5. 11
      libisofs/joliet.h
  6. 71
      libisofs/libisofs.h
  7. 44
      libisofs/tree.c
  8. 13
      libisofs/tree.h

6
libisofs/ecma119.c

@ -316,7 +316,6 @@ ecma119_target_new(struct iso_volset *volset,
t->dirlist = calloc(1, sizeof(void*) * t->dirlist_len);
t->pathlist = calloc(1, sizeof(void*) * t->dirlist_len);
//t->filelist = calloc(1, sizeof(void*) * t->filelist_len);
/* fill out the pathlist */
t->pathlist[0] = t->root;
@ -365,8 +364,6 @@ ecma119_target_new(struct iso_volset *volset,
t->curfile = 0;
}
calc_file_pos(t, t->root);
//if (t->joliet)
// joliet_update_file_pos (t, t->joliet_root);
if (t->rockridge) {
susp_finalize(t, t->root);
@ -772,13 +769,14 @@ bs_free_data(struct burn_source *bs)
ecma119_tree_free(t->root);
iso_file_table_clear(t->file_table);
//FIXME free joliet tree
free(t->dirlist);
free(t->pathlist);
free(t->dirlist_joliet);
free(t->pathlist_joliet);
free(t->filelist);
free(t->state_data);
if (t->joliet)
joliet_tree_free(t->joliet_root);
if (t->state_files.fd)
fclose(t->state_files.fd);
}

377
libisofs/file.c

@ -185,380 +185,3 @@ iso_file_table_lookup(struct iso_file_table *ft, struct iso_tree_node_file *f)
return NULL;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "file.h"
#include "tree.h"
//TODO: refactor both hash and this hash table into a single one!!
struct iso_file *
iso_file_new(struct iso_tree_node_file *f)
{
struct iso_file *file = calloc(1, sizeof(struct iso_file));
file->path = f->path; /*TODO strdup? it needs to be free on clear then */
file->size = f->node.attrib.st_size;
file->nlink = 1;
file->real_dev = f->node.attrib.st_dev;
file->real_ino = f->node.attrib.st_ino;
file->sort_weight = f->sort_weight;
return file;
}
static unsigned int
iso_file_table_hash(const char *path)
{
unsigned int hash_num=0;
const char *c;
c=path;
while(*c)
hash_num = (hash_num << 15) + (hash_num << 3) + (hash_num >> 3) + *c++;
return hash_num % FILE_HASH_NODES;
}
static inline unsigned int
iso_file_table_hash_inode(dev_t dev, ino_t ino)
{
return (dev ^ ino) % FILE_HASH_NODES;
}
struct iso_file_table*
iso_file_table_new(int cache_inodes)
{
struct iso_file_table *table = calloc(1, sizeof(struct iso_file_table));
table->cache_inodes = cache_inodes;
return table;
}
static struct iso_file_hash_node *
iso_file_table_node_new(struct iso_file *file)
{
struct iso_file_hash_node *node;
node = calloc(1, sizeof(struct iso_file_hash_node) );
node->file = file;
return node;
}
static void
iso_file_table_node_free(struct iso_file_hash_node *node)
{
free(node->file);
free(node);
}
void
iso_file_table_clear(struct iso_file_table *ft)
{
int i;
for (i=0; i < FILE_HASH_NODES; i++) {
struct iso_file_hash_node *node;
node=ft->table[i];
if (!node)
continue;
ft->table[i] = NULL;
do {
struct iso_file_hash_node *next;
next = node->next;
iso_file_table_node_free(node);
node = next;
} while (node);
}
}
/**
* return 0 if equal, != 0 if not
*/
static int
iso_table_compare_files(struct iso_file_table *ft,
struct iso_file *f1, struct iso_file *f2)
{
if (ft->cache_inodes) {
return (f1->real_dev != f2->real_dev) || (f1->real_ino != f2->real_ino);
} else {
return strcmp(f1->path, f2->path);
}
}
int
iso_file_table_add_file(struct iso_file_table *ft, struct iso_file *f)
{
struct iso_file_hash_node *node;
unsigned int hash_num;
/* find the hash number */
if (ft->cache_inodes)
hash_num = iso_file_table_hash_inode(f->real_dev, f->real_ino);
else
hash_num = iso_file_table_hash(f->path);
/* insert it */
node = ft->table[hash_num];
/* unfortunately, we can't safely consider that a file
* won't be twice in the hash table so make sure it
* doesn't already exists */
if (!node) {
ft->table[hash_num]=iso_file_table_node_new(f);
ft->count++;
return 1;
}
/* if it's already in, we don't do anything */
if (!iso_table_compare_files(ft, f, node->file))
return 0;
while (node->next) {
node = node->next;
/* if it's already in, we don't do anything */
if (!iso_table_compare_files(ft, f, node->file))
return 0;
}
node->next = iso_file_table_node_new(f);
ft->count++;
return 1;
}
struct iso_file *
iso_file_table_lookup(struct iso_file_table *ft, struct iso_tree_node_file *f)
{
struct iso_file_hash_node *node;
unsigned int hash_num;
int equal;
/* find the hash number */
if ( ft->cache_inodes )
hash_num = iso_file_table_hash_inode(f->node.attrib.st_dev,
f->node.attrib.st_ino);
else
hash_num = iso_file_table_hash(f->path);
node = ft->table[hash_num];
if (!node)
return NULL;
equal = ft->cache_inodes ?
((f->node.attrib.st_dev == node->file->real_dev)
&& (f->node.attrib.st_ino == node->file->real_ino))
: !strcmp(f->path, node->file->path);
if (equal)
return node->file;
while (node->next) {
node = node->next;
equal = ft->cache_inodes ?
((f->node.attrib.st_dev == node->file->real_dev)
&& (f->node.attrib.st_ino == node->file->real_ino))
: !strcmp(f->path, node->file->path);
if (equal)
return node->file;
}
return NULL;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "file.h"
#include "tree.h"
//TODO: refactor both hash and this hash table into a single one!!
struct iso_file *
iso_file_new(struct iso_tree_node_file *f)
{
struct iso_file *file = calloc(1, sizeof(struct iso_file));
file->path = f->path; /*TODO strdup? it needs to be free on clear then */
file->size = f->node.attrib.st_size;
file->nlink = 1;
file->real_dev = f->node.attrib.st_dev;
file->real_ino = f->node.attrib.st_ino;
file->sort_weight = f->sort_weight;
return file;
}
static unsigned int
iso_file_table_hash(const char *path)
{
unsigned int hash_num=0;
const char *c;
c=path;
while(*c)
hash_num = (hash_num << 15) + (hash_num << 3) + (hash_num >> 3) + *c++;
return hash_num % FILE_HASH_NODES;
}
static inline unsigned int
iso_file_table_hash_inode(dev_t dev, ino_t ino)
{
return (dev ^ ino) % FILE_HASH_NODES;
}
struct iso_file_table*
iso_file_table_new(int cache_inodes)
{
struct iso_file_table *table = calloc(1, sizeof(struct iso_file_table));
table->cache_inodes = cache_inodes;
return table;
}
static struct iso_file_hash_node *
iso_file_table_node_new(struct iso_file *file)
{
struct iso_file_hash_node *node;
node = calloc(1, sizeof(struct iso_file_hash_node) );
node->file = file;
return node;
}
static void
iso_file_table_node_free(struct iso_file_hash_node *node)
{
free(node->file);
free(node);
}
void
iso_file_table_clear(struct iso_file_table *ft)
{
int i;
for (i=0; i < FILE_HASH_NODES; i++) {
struct iso_file_hash_node *node;
node=ft->table[i];
if (!node)
continue;
ft->table[i] = NULL;
do {
struct iso_file_hash_node *next;
next = node->next;
iso_file_table_node_free(node);
node = next;
} while (node);
}
}
/**
* return 0 if equal, != 0 if not
*/
static int
iso_table_compare_files(struct iso_file_table *ft,
struct iso_file *f1, struct iso_file *f2)
{
if (ft->cache_inodes) {
return (f1->real_dev != f2->real_dev) || (f1->real_ino != f2->real_ino);
} else {
return strcmp(f1->path, f2->path);
}
}
int
iso_file_table_add_file(struct iso_file_table *ft, struct iso_file *f)
{
struct iso_file_hash_node *node;
unsigned int hash_num;
/* find the hash number */
if (ft->cache_inodes)
hash_num = iso_file_table_hash_inode(f->real_dev, f->real_ino);
else
hash_num = iso_file_table_hash(f->path);
/* insert it */
node = ft->table[hash_num];
/* unfortunately, we can't safely consider that a file
* won't be twice in the hash table so make sure it
* doesn't already exists */
if (!node) {
ft->table[hash_num]=iso_file_table_node_new(f);
ft->count++;
return 1;
}
/* if it's already in, we don't do anything */
if (!iso_table_compare_files(ft, f, node->file))
return 0;
while (node->next) {
node = node->next;
/* if it's already in, we don't do anything */
if (!iso_table_compare_files(ft, f, node->file))
return 0;
}
node->next = iso_file_table_node_new(f);
ft->count++;
return 1;
}
struct iso_file *
iso_file_table_lookup(struct iso_file_table *ft, struct iso_tree_node_file *f)
{
struct iso_file_hash_node *node;
unsigned int hash_num;
int equal;
/* find the hash number */
if ( ft->cache_inodes )
hash_num = iso_file_table_hash_inode(f->node.attrib.st_dev,
f->node.attrib.st_ino);
else
hash_num = iso_file_table_hash(f->path);
node = ft->table[hash_num];
if (!node)
return NULL;
equal = ft->cache_inodes ?
((f->node.attrib.st_dev == node->file->real_dev)
&& (f->node.attrib.st_ino == node->file->real_ino))
: !strcmp(f->path, node->file->path);
if (equal)
return node->file;
while (node->next) {
node = node->next;
equal = ft->cache_inodes ?
((f->node.attrib.st_dev == node->file->real_dev)
&& (f->node.attrib.st_ino == node->file->real_ino))
: !strcmp(f->path, node->file->path);
if (equal)
return node->file;
}
return NULL;
}

110
libisofs/file.h

@ -53,113 +53,3 @@ struct iso_file *iso_file_table_lookup(struct iso_file_table *ft,
struct iso_tree_node_file *f);
#endif /*FILE_H_*/
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* vim: set noet ts=8 sts=8 sw=8 : */
/**
* \file file.h
*
* Declare the structs to keep track of the files to be written into image.
*
*/
#ifndef FILE_H_
#define FILE_H_
#define FILE_HASH_NODES 2048
struct iso_file {
char *path;
off_t size; /**< size of this file */
ino_t ino; /**< This will be the inode number on CD of the file (RR) */
nlink_t nlink; /**< Number of hard links of the file on CD (RR) */
size_t block; /**< Block where this file is to be written on image */
dev_t real_dev;
ino_t real_ino; /**< for lookup by inode caching */
int sort_weight;
};
struct iso_file_hash_node {
struct iso_file_hash_node *next;
struct iso_file *file;
};
struct iso_file_table {
struct iso_file_hash_node *table[FILE_HASH_NODES];
size_t count;
int cache_inodes; /**< 1 to index by inode number */
};
struct iso_tree_node_file;
struct iso_file *iso_file_new(struct iso_tree_node_file*);
struct iso_file_table *iso_file_table_new(int cache_inodes);
/**
* Clear a hash table. All iso_file structs stored will also be freed,
* but not the path of each iso_file
*/
void iso_file_table_clear(struct iso_file_table *ft);
int iso_file_table_add_file(struct iso_file_table *ft, struct iso_file *f);
struct iso_file *iso_file_table_lookup(struct iso_file_table *ft,
struct iso_tree_node_file *f);
#endif /*FILE_H_*/
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* vim: set noet ts=8 sts=8 sw=8 : */
/**
* \file file.h
*
* Declare the structs to keep track of the files to be written into image.
*
*/
#ifndef FILE_H_
#define FILE_H_
#define FILE_HASH_NODES 2048
struct iso_file {
char *path;
off_t size; /**< size of this file */
ino_t ino; /**< This will be the inode number on CD of the file (RR) */
nlink_t nlink; /**< Number of hard links of the file on CD (RR) */
size_t block; /**< Block where this file is to be written on image */
dev_t real_dev;
ino_t real_ino; /**< for lookup by inode caching */
int sort_weight;
};
struct iso_file_hash_node {
struct iso_file_hash_node *next;
struct iso_file *file;
};
struct iso_file_table {
struct iso_file_hash_node *table[FILE_HASH_NODES];
size_t count;
int cache_inodes; /**< 1 to index by inode number */
};
struct iso_tree_node_file;
struct iso_file *iso_file_new(struct iso_tree_node_file*);
struct iso_file_table *iso_file_table_new(int cache_inodes);
/**
* Clear a hash table. All iso_file structs stored will also be freed,
* but not the path of each iso_file
*/
void iso_file_table_clear(struct iso_file_table *ft);
int iso_file_table_add_file(struct iso_file_table *ft, struct iso_file *f);
struct iso_file *iso_file_table_lookup(struct iso_file_table *ft,
struct iso_tree_node_file *f);
#endif /*FILE_H_*/

15
libisofs/joliet.c

@ -191,6 +191,21 @@ joliet_tree_create(struct ecma119_write_target *t,
return root;
}
void
joliet_tree_free(struct joliet_tree_node *root)
{
size_t i;
if (root->type == JOLIET_DIR) {
for (i=0; i < root->info.dir.nchildren; i++) {
joliet_tree_free(root->info.dir.children[i]);
}
free(root->info.dir.children);
}
free(root->name);
free(root);
}
/* ugh. this is mostly C&P */
static void
write_path_table(struct ecma119_write_target *t,

11
libisofs/joliet.h

@ -33,11 +33,8 @@ struct joliet_tree_node
{
uint16_t *name; /**< In UCS-2BE. */
size_t dirent_len;
//size_t len;??
/*size_t block;*/
struct joliet_tree_node *parent;
/* struct iso_tree_node *iso_self; */
struct ecma119_write_target *target;
int type;
@ -67,14 +64,6 @@ joliet_calc_dir_size(struct ecma119_write_target *t, struct joliet_tree_node*);
void
joliet_calc_dir_pos(struct ecma119_write_target *t, struct joliet_tree_node*);
/**
* Update the position of each file in the joliet hierarchy (to be called
* AFTER the file positions in the iso tree have been set).
* TODO not needed, block info is kept away in hash table
*/
//void
//joliet_update_file_pos(struct ecma119_write_target *t, struct joliet_tree_node*);
/**
* Calculate the size of the joliet path table and fill in the list of
* directories.

71
libisofs/libisofs.h

@ -12,6 +12,8 @@
#ifndef LIBISO_LIBISOFS_H
#define LIBISO_LIBISOFS_H
#include <sys/types.h>
/* #include <libburn.h> */
struct burn_source;
@ -45,6 +47,11 @@ enum ecma119_extension_flag {
ECMA119_JOLIET = (1<<1)
};
enum hide_node_flag {
LIBISO_HIDE_ON_RR = 1 << 0,
LIBISO_HIDE_ON_JOLIET = 1 << 1
};
/**
* This will hold the error code for some functions, if them fail.
*/
@ -282,23 +289,6 @@ struct iso_tree_node *iso_tree_add_node(struct iso_tree_node_dir *parent,
struct iso_tree_node_dir *iso_tree_radd_dir(struct iso_tree_node_dir *parent,
const char *path, struct iso_tree_radd_dir_behavior *behavior);
//struct iso_tree_node *iso_tree_radd_dir(struct iso_tree_node *parent,
// const char *path);
/**
* Creates a new, empty directory on the volume.
*
* \pre \p parent is NULL or is a directory.
* \pre \p name is unique among the children and files belonging to \p parent.
* Also, it doesn't contain '/' characters.
*
* \post \p parent contains a child directory whose name is \p name and whose
* POSIX attributes are the same as \p parent's.
* \return a pointer to the newly created directory.
*/
/*struct iso_tree_node *iso_tree_add_new_dir(struct iso_tree_node *parent,
const char *name);*/
/**
* Set the name of a tree node (using the current locale).
*/
@ -306,9 +296,56 @@ void iso_tree_node_set_name(struct iso_tree_node *node, const char *name);
/**
* Set if the node will be hidden in RR/ISO tree, Joliet tree or both.
*
* If the file is setted as hidden in one tree, it won't be included there, so
* it won't be visible in a OS accessing CD using that tree. For example,
* GNU/Linux systems access to Rock Ridge / ISO9960 tree in order to see
* what is recorded on CD, while MS Windows make use of the Joliet tree. If a
* file is hidden only in Joliet, it won't be visible in Windows systems,
* while still visible in Linux.
*
* If a file is hidden in both trees, it won't be written to image.
*
* \param node The node that is to be hidden.
* \param hide_attrs hide_node_flag's to set the trees in which file
* will be hidden.
*/
void iso_tree_node_set_hidden(struct iso_tree_node *node, int hide_attrs);
/**
* Set the group id for the node. This attribute is only useful when
* Rock Ridge extensions are enabled.
*/
void iso_tree_node_set_gid(struct iso_tree_node *node, gid_t gid);
/**
* Set the user id for the node. This attribute is only useful when
* Rock Ridge extensions are enabled.
*/
void iso_tree_node_set_uid(struct iso_tree_node *node, uid_t uid);
/**
* Set the permissions for the node. This attribute is only useful when
* Rock Ridge extensions are enabled.
*
* \param mode bitmask with the permissions of the node, as specified
* in 'man 2 stat'. The file type bitfields will be ignored,
* only file permissions will be modified.
*/
void iso_tree_node_set_permissions(struct iso_tree_node *node, mode_t mode);
/**
* Sets the order in which a node will be written on image. High weihted files
* will be written first, so in a disc them will be written near the center.
*
* \param node The node which weight will be changed. If it's a dir, this
* function will change the weight of all its children. For nodes
* other that dirs or regular files, this function has no effect.
* \param w The weight as a integer number, the greater this value is, the
* closer from the begining of image the file will be written.
*/
void iso_tree_node_set_sort_weight(struct iso_tree_node *node, int w);
/**
* Recursively print a directory to stdout.
* \param spaces The initial number of spaces on the left. Set to 0 if you

44
libisofs/tree.c

@ -146,9 +146,51 @@ iso_tree_node_set_name(struct iso_tree_node *node, const char *name)
void
iso_tree_node_set_hidden(struct iso_tree_node *node, int hide_attrs)
{
assert(node);
node->hide_flags = hide_attrs;
}
void
iso_tree_node_set_gid(struct iso_tree_node *node, gid_t gid)
{
assert(node);
node->attrib.st_gid = gid;
}
void
iso_tree_node_set_uid(struct iso_tree_node *node, uid_t uid)
{
assert(node);
node->attrib.st_uid = uid;
}
void
iso_tree_node_set_permissions(struct iso_tree_node *node, mode_t mode)
{
assert(node);
node->attrib.st_mode = (node->attrib.st_mode & S_IFMT) |
(mode & ~S_IFMT);
}
void
iso_tree_node_set_sort_weight(struct iso_tree_node *node, int w)
{
assert(node);
if ( ISO_ISDIR(node) ) {
size_t i;
struct iso_tree_node_dir *dir;
dir = (struct iso_tree_node_dir *) node;
for (i=0; i < dir->nchildren; i++) {
iso_tree_node_set_sort_weight(dir->children[i], w);
}
free(dir->children);
} else if ( ISO_ISREG(node) ) {
struct iso_tree_node_file *file;
file = (struct iso_tree_node_file *) node;
file->sort_weight = w;
}
}
struct iso_tree_node*
iso_tree_add_node(struct iso_tree_node_dir *parent,
const char *path)
@ -261,7 +303,7 @@ iso_tree_radd_dir_aux(struct iso_tree_node_dir *parent, const char *path,
strcmp(ent->d_name, "..") == 0)
continue;
//check if path already finished in '/'
//TODO check if path already finished in '/'
sprintf(child, "%s/%s", path, ent->d_name);
/* see if this child is excluded. */

13
libisofs/tree.h

@ -31,11 +31,6 @@
// * iso_tree_add_new_XXX. */
//};
enum hide_node {
LIBISO_HIDE_ON_RR = 1 << 0,
LIBISO_HIDE_ON_JOLIET = 1 << 1
};
/**
* This tells us where to read the data from a file. Either we read from the
* local filesystem or we just point to the block on a previous session.
@ -54,7 +49,6 @@ enum hide_node {
*/
struct iso_tree_node
{
/*struct iso_volume *volume; TODO not needed? */
struct iso_tree_node_dir *parent;
char *name;
struct stat attrib; /**< The POSIX attributes of this node as
@ -62,13 +56,6 @@ struct iso_tree_node
int hide_flags; /**< If the node is to be hidden in RR/ISO or
* Joilet tree */
/*size_t block;*/ /**< The block at which this file will
* reside on disk. We store this here as
* well as in the various mangled trees
* because many different trees might point
* to the same file and they need to share the
* block location. */
};
/**

Loading…
Cancel
Save