2007-12-15 12:13:49 +00:00
|
|
|
/*
|
|
|
|
* 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 "filesrc.h"
|
|
|
|
#include "error.h"
|
|
|
|
#include "node.h"
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2007-12-16 18:10:47 +00:00
|
|
|
|
|
|
|
/* tdestroy is a GNU specific function */
|
|
|
|
#define __USE_GNU
|
2007-12-15 12:13:49 +00:00
|
|
|
#include <search.h>
|
|
|
|
|
|
|
|
static
|
|
|
|
int comp_iso_file_src(const void *n1, const void *n2)
|
|
|
|
{
|
|
|
|
const IsoFileSrc *f1, *f2;
|
|
|
|
f1 = (const IsoFileSrc *)n1;
|
|
|
|
f2 = (const IsoFileSrc *)n2;
|
|
|
|
|
|
|
|
if (f1->fs_id < f2->fs_id) {
|
|
|
|
return -1;
|
|
|
|
} else if (f1->fs_id > f2->fs_id) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
/* files belong to the same fs */
|
|
|
|
if (f1->dev_id > f2->dev_id) {
|
|
|
|
return -1;
|
|
|
|
} else if (f1->dev_id < f2->dev_id) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
/* files belong to same device in same fs */
|
2007-12-15 15:48:50 +00:00
|
|
|
return (f1->ino_id < f2->ino_id) ? -1 :
|
|
|
|
(f1->ino_id > f2->ino_id) ? 1 : 0;
|
2007-12-15 12:13:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
|
|
|
{
|
|
|
|
int res;
|
|
|
|
IsoStream *stream;
|
|
|
|
IsoFileSrc *fsrc;
|
|
|
|
unsigned int fs_id;
|
|
|
|
dev_t dev_id;
|
|
|
|
ino_t ino_id;
|
|
|
|
off_t size;
|
|
|
|
|
|
|
|
if (img == NULL || file == NULL || src == NULL) {
|
|
|
|
return ISO_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream = file->stream;
|
|
|
|
res = stream->get_id(stream, &fs_id, &dev_id, &ino_id);
|
|
|
|
if (res < 0) {
|
|
|
|
return res;
|
|
|
|
} else if (res == 0) {
|
|
|
|
// TODO this corresponds to Stream that cannot provide a valid id
|
|
|
|
// Not implemented for now
|
|
|
|
return ISO_ERROR;
|
|
|
|
} else {
|
2007-12-15 15:48:50 +00:00
|
|
|
IsoFileSrc **inserted;
|
2007-12-15 12:13:49 +00:00
|
|
|
|
|
|
|
size = stream->get_size(stream);
|
|
|
|
if (size == (off_t)-1) {
|
|
|
|
return ISO_FILE_ERROR;
|
|
|
|
}
|
|
|
|
|
2007-12-17 19:47:53 +00:00
|
|
|
/* Files > 4GB not supported yet, they need ISO level 3 */
|
|
|
|
if (size > (off_t)0xffffffff) {
|
|
|
|
return ISO_FILE_TOO_BIG;
|
|
|
|
}
|
|
|
|
|
2007-12-15 12:13:49 +00:00
|
|
|
fsrc = malloc(sizeof(IsoFileSrc));
|
|
|
|
if (fsrc == NULL) {
|
|
|
|
return ISO_MEM_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fill key and other atts */
|
|
|
|
fsrc->fs_id = fs_id;
|
|
|
|
fsrc->dev_id = dev_id;
|
|
|
|
fsrc->ino_id = ino_id;
|
|
|
|
fsrc->prev_img = file->msblock ? 1 : 0;
|
|
|
|
fsrc->block = file->msblock;
|
|
|
|
fsrc->size = size;
|
|
|
|
fsrc->sort_weight = file->sort_weight;
|
|
|
|
fsrc->stream = file->stream;
|
|
|
|
|
|
|
|
/* insert the filesrc in the tree */
|
2007-12-15 15:48:50 +00:00
|
|
|
inserted = tsearch(fsrc, &(img->file_srcs), comp_iso_file_src);
|
2007-12-15 12:13:49 +00:00
|
|
|
if (inserted == NULL) {
|
|
|
|
free(fsrc);
|
|
|
|
return ISO_MEM_ERROR;
|
2007-12-15 15:48:50 +00:00
|
|
|
} else if (*inserted == fsrc) {
|
2007-12-15 12:13:49 +00:00
|
|
|
/* the file was inserted */
|
|
|
|
img->file_count++;
|
|
|
|
} else {
|
|
|
|
/* the file was already on the tree */
|
|
|
|
free(fsrc);
|
|
|
|
}
|
2007-12-15 15:48:50 +00:00
|
|
|
*src = *inserted;
|
2007-12-15 12:13:49 +00:00
|
|
|
}
|
|
|
|
return ISO_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-12-16 18:10:47 +00:00
|
|
|
void free_node(void *nodep)
|
|
|
|
{
|
|
|
|
/* nothing to do */
|
|
|
|
}
|
|
|
|
|
|
|
|
void iso_file_src_free(Ecma119Image *img)
|
|
|
|
{
|
2007-12-17 22:22:19 +00:00
|
|
|
if (img->file_srcs != NULL) {
|
|
|
|
tdestroy(img->file_srcs, free_node);
|
|
|
|
}
|
2007-12-16 18:10:47 +00:00
|
|
|
}
|