2005-11-21 23:55:56 +00:00
|
|
|
/*
|
|
|
|
*
|
2006-09-15 14:55:39 +00:00
|
|
|
* (c) 2005 Laurent Vivier <Laurent@lvivier.info>
|
2005-11-21 23:55:56 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2005-11-22 23:11:42 +00:00
|
|
|
#include <stdio.h>
|
2005-11-21 23:55:56 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "libstream.h"
|
2005-11-26 08:53:02 +00:00
|
|
|
#ifdef FLOPPY_SUPPORT
|
2005-11-21 23:55:56 +00:00
|
|
|
#include <libfloppy.h>
|
2005-11-26 08:53:02 +00:00
|
|
|
#endif
|
|
|
|
#ifdef SCSI_SUPPORT
|
2005-11-21 23:55:56 +00:00
|
|
|
#include <libscsi.h>
|
2005-11-26 08:53:02 +00:00
|
|
|
#endif
|
|
|
|
#ifdef BLOCK_SUPPORT
|
2005-11-21 23:55:56 +00:00
|
|
|
#include <libblock.h>
|
2005-11-26 08:53:02 +00:00
|
|
|
#endif
|
|
|
|
#ifdef CONTAINER_SUPPORT
|
2005-11-21 23:55:56 +00:00
|
|
|
#include <libcontainer.h>
|
2005-11-26 08:53:02 +00:00
|
|
|
#endif
|
|
|
|
#ifdef ISO9660_SUPPORT
|
2005-11-21 23:55:56 +00:00
|
|
|
#include <libiso9660.h>
|
2005-11-26 08:53:02 +00:00
|
|
|
#endif
|
2008-04-12 22:27:13 +00:00
|
|
|
#ifdef EXT2_SUPPORT
|
|
|
|
#include <libext2.h>
|
|
|
|
#endif
|
2007-10-10 21:13:35 +00:00
|
|
|
#ifdef MAP_SUPPORT
|
|
|
|
#include <libmap.h>
|
|
|
|
#endif
|
2005-11-21 23:55:56 +00:00
|
|
|
|
2008-04-20 16:07:24 +00:00
|
|
|
stream_init_t fs_init[] = {
|
|
|
|
#ifdef EXT2_SUPPORT
|
|
|
|
[fs_EXT2] = ext2_init,
|
|
|
|
#endif
|
|
|
|
#ifdef ISO9660_SUPPORT
|
|
|
|
[fs_ISO9660] = iso9660_init,
|
|
|
|
#endif
|
|
|
|
#ifdef CONTAINER_SUPPORT
|
|
|
|
[fs_CONTAINER] = container_init,
|
|
|
|
#endif
|
|
|
|
#ifdef BLOCK_SUPPORT
|
|
|
|
[fs_BLOCK] = block_init,
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2005-11-21 23:55:56 +00:00
|
|
|
static char* get_fs(char *path, fs_t *fs)
|
|
|
|
{
|
|
|
|
if (strncmp("block:", path, 6) == 0)
|
|
|
|
{
|
|
|
|
*fs = fs_BLOCK;
|
|
|
|
return path + 6;
|
2005-11-26 08:53:02 +00:00
|
|
|
}
|
|
|
|
if (strncmp("container:", path, 10) == 0)
|
2005-11-21 23:55:56 +00:00
|
|
|
{
|
|
|
|
*fs = fs_CONTAINER;
|
|
|
|
return path + 10;
|
2005-11-26 08:53:02 +00:00
|
|
|
}
|
|
|
|
if (strncmp("iso9660:", path, 8) == 0)
|
2005-11-21 23:55:56 +00:00
|
|
|
{
|
|
|
|
*fs = fs_ISO9660;
|
|
|
|
return path + 8;
|
|
|
|
}
|
2008-04-12 22:27:13 +00:00
|
|
|
if (strncmp("ext2:", path, 8) == 0)
|
|
|
|
{
|
|
|
|
*fs = fs_EXT2;
|
|
|
|
return path + 8;
|
|
|
|
}
|
2005-11-21 23:55:56 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *get_device(char* path,
|
|
|
|
device_t *device, int *unit, int* partition)
|
|
|
|
{
|
|
|
|
int nb;
|
|
|
|
|
|
|
|
if (*path != '(')
|
|
|
|
return NULL;
|
|
|
|
path++;
|
|
|
|
|
|
|
|
if (strncmp("fd", path, 2) == 0) {
|
|
|
|
*device = device_FLOPPY;
|
|
|
|
path += 2;
|
|
|
|
} else if (strncmp("sd", path, 2) == 0) {
|
|
|
|
*device = device_SCSI;
|
|
|
|
path += 2;
|
|
|
|
} else
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
nb = 0;
|
|
|
|
while ( (*path >= '0') && (*path <= '9') ) {
|
|
|
|
nb = (nb * 10) + (*path - '0');
|
|
|
|
path++;
|
|
|
|
}
|
|
|
|
*unit = nb;
|
|
|
|
|
|
|
|
*partition = -1;
|
|
|
|
if ( (*path == 0) || (*path == ')') )
|
|
|
|
{
|
|
|
|
path++;
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*path != ',')
|
|
|
|
return NULL;
|
|
|
|
path++;
|
|
|
|
|
|
|
|
nb = 0;
|
|
|
|
while ( (*path >= '0') && (*path <= '9') ) {
|
|
|
|
nb = (nb * 10) + (*path - '0');
|
|
|
|
path++;
|
|
|
|
}
|
|
|
|
*partition = nb;
|
|
|
|
if ( (*path == 0) || (*path == ')') )
|
|
|
|
{
|
|
|
|
path++;
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream_t *stream_open(char *dev)
|
|
|
|
{
|
|
|
|
stream_t *stream;
|
|
|
|
fs_t fs;
|
|
|
|
device_t device;
|
|
|
|
int unit, partition;
|
|
|
|
char *current;
|
|
|
|
|
|
|
|
current = get_fs(dev, &fs);
|
|
|
|
if (current == NULL)
|
2005-11-22 23:11:42 +00:00
|
|
|
{
|
|
|
|
printf("Cannot identify given filesystem\n");
|
2005-11-21 23:55:56 +00:00
|
|
|
return NULL;
|
2005-11-22 23:11:42 +00:00
|
|
|
}
|
2005-11-21 23:55:56 +00:00
|
|
|
current = get_device(current, &device, &unit, &partition);
|
|
|
|
if (current == NULL)
|
2005-11-22 23:11:42 +00:00
|
|
|
{
|
|
|
|
printf("Cannot identify given device\n");
|
2005-11-21 23:55:56 +00:00
|
|
|
return NULL;
|
2005-11-22 23:11:42 +00:00
|
|
|
}
|
2005-11-21 23:55:56 +00:00
|
|
|
|
|
|
|
stream = (stream_t*)malloc(sizeof(stream_t));
|
|
|
|
|
2007-11-02 22:11:28 +00:00
|
|
|
stream->fs_id = fs,
|
|
|
|
stream->device_id = device;
|
|
|
|
stream->unit = unit;
|
|
|
|
stream->partition = partition;
|
|
|
|
|
2005-11-21 23:55:56 +00:00
|
|
|
switch(device)
|
|
|
|
{
|
2005-11-26 08:53:02 +00:00
|
|
|
#ifdef FLOPPY_SUPPORT
|
2005-11-21 23:55:56 +00:00
|
|
|
case device_FLOPPY:
|
|
|
|
if (partition != -1)
|
|
|
|
{
|
|
|
|
free(stream);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
stream->device.data = floppy_open(unit);
|
|
|
|
if (stream->device.data == NULL)
|
|
|
|
{
|
|
|
|
free(stream);
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-11-26 08:53:02 +00:00
|
|
|
stream->device.read_sector =
|
|
|
|
(stream_read_sector_t)floppy_read_sector;
|
2005-11-21 23:55:56 +00:00
|
|
|
stream->device.close = (stream_close_t)floppy_close;
|
2005-11-26 08:53:02 +00:00
|
|
|
stream->device.get_blocksize =
|
|
|
|
(stream_get_blocksize_t)floppy_get_blocksize;
|
2005-11-21 23:55:56 +00:00
|
|
|
break;
|
2005-11-26 08:53:02 +00:00
|
|
|
#endif /* FLOPPY_SUPPORT */
|
2005-11-21 23:55:56 +00:00
|
|
|
|
2005-11-26 08:53:02 +00:00
|
|
|
#ifdef SCSI_SUPPORT
|
2005-11-21 23:55:56 +00:00
|
|
|
case device_SCSI:
|
|
|
|
stream->device.data = scsi_open(unit);
|
|
|
|
if (stream->device.data == NULL)
|
|
|
|
{
|
|
|
|
free(stream);
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-11-26 08:53:02 +00:00
|
|
|
stream->device.read_sector =
|
|
|
|
(stream_read_sector_t)scsi_read_sector;
|
2005-11-21 23:55:56 +00:00
|
|
|
stream->device.close = (stream_close_t)scsi_close;
|
2005-11-26 08:53:02 +00:00
|
|
|
stream->device.get_blocksize =
|
|
|
|
(stream_get_blocksize_t)scsi_get_blocksize;
|
2005-11-21 23:55:56 +00:00
|
|
|
break;
|
2005-11-26 08:53:02 +00:00
|
|
|
#endif /* SCSI_SUPPORT */
|
|
|
|
|
2005-11-21 23:55:56 +00:00
|
|
|
default:
|
|
|
|
free(stream);
|
2005-11-26 08:53:02 +00:00
|
|
|
return NULL;
|
2005-11-21 23:55:56 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-10-10 21:13:35 +00:00
|
|
|
if (partition != -1)
|
|
|
|
{
|
|
|
|
#ifdef MAP_SUPPORT
|
2008-04-20 16:07:24 +00:00
|
|
|
if (map_init(&stream->device, partition) == -1)
|
2007-10-22 23:13:23 +00:00
|
|
|
{
|
2007-11-01 21:18:45 +00:00
|
|
|
printf("Cannot open map\n");
|
2008-04-20 16:07:24 +00:00
|
|
|
stream->device.close(stream->volume);
|
2007-10-22 23:13:23 +00:00
|
|
|
free(stream);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#else
|
2007-11-01 21:18:45 +00:00
|
|
|
stream->device.close(stream->device.data);
|
2007-10-10 21:13:35 +00:00
|
|
|
free(stream);
|
|
|
|
return NULL;
|
2007-10-22 23:13:23 +00:00
|
|
|
#endif /* MAP_SUPPORT */
|
2007-10-10 21:13:35 +00:00
|
|
|
}
|
|
|
|
|
2008-04-20 16:07:24 +00:00
|
|
|
if (fs >= fs_LAST || fs_init[fs](&stream->device, &stream->fs) == -1)
|
2005-11-21 23:55:56 +00:00
|
|
|
{
|
2008-04-20 16:07:24 +00:00
|
|
|
stream->device.close(stream->device.data);
|
|
|
|
free(stream);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
stream->volume = stream->fs.mount(&stream->device);
|
|
|
|
if (stream->volume == NULL) {
|
|
|
|
stream->device.close(stream->device.data);
|
|
|
|
free(stream);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
stream->file = stream->fs.open(stream->volume, current);
|
|
|
|
if (stream->file == NULL) {
|
|
|
|
stream->fs.umount(stream->volume);
|
|
|
|
stream->device.close(stream->device.data);
|
|
|
|
free(stream);
|
|
|
|
return NULL;
|
2005-11-21 23:55:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
}
|