diff options
Diffstat (limited to 'genisoimage/stream.c')
-rw-r--r-- | genisoimage/stream.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/genisoimage/stream.c b/genisoimage/stream.c new file mode 100644 index 0000000..f59c1e3 --- /dev/null +++ b/genisoimage/stream.c @@ -0,0 +1,272 @@ +/* + * This file has been modified for the cdrkit suite. + * + * The behaviour and appearence of the program code below can differ to a major + * extent from the version distributed by the original author(s). + * + * For details, see Changelog file distributed with the cdrkit package. If you + * received this file from another source then ask the distributing person for + * a log of modifications. + * + */ + +/* @(#)stream.c 1.3 04/03/04 Copyright 2002-2003 J. Schilling */ +/* Parts from @(#)stream.c 1.9 07/02/17 Copyright 2002-2007 J. Schilling */ +/* + * ISO-9660 stream (pipe) file module for genisoimage + * + * Copyright (c) 2002-2003 J. Schilling + * Implemented after an idea from M.H. Voase + */ +/* + * This program is free software; 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; see the file COPYING. If not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include "iso9660.h" + +static int size_str_file(int starting_extent); +static int size_str_dir(int starting_extent); +static int size_str_path(int starting_extent); + +static int gen_str_path(void); + +static int write_str_file(FILE *outfile); +static int write_str_dir(FILE *outfile); +static int write_str_path(FILE *outfile); + +extern struct directory *root; +extern unsigned int session_start; +extern int stream_media_size; +extern char *stream_filename; +extern time_t begun; +extern int volume_sequence_number; + +static unsigned int avail_extent; +static unsigned int stream_extent; +static unsigned int stream_size; +static unsigned int stream_pad; +static char *l_path; +static char *m_path; +static struct iso_directory_record s_dir; +static int stream_finished = 0; + +/* + * Compute the size of the file + */ +static int +size_str_file(int starting_extent) +{ + int n; +extern int dopad; + + stream_extent = last_extent; /* Start of stream file content */ + + avail_extent = stream_media_size; + n = last_extent; /* Room for FS blocks before file */ + n += 1; /* Room for the directory block */ + stream_pad = 0; + if (n < 50) { + stream_pad = 50 - n; + n = 50; /* Make net. size easy to compute */ + } + if (dopad) + n += 150; /* Room for final padding */ + avail_extent -= n; + + last_extent += avail_extent + stream_pad; + + return (0); +} + +/* + * The size of the directory record - one sector + */ +static int +size_str_dir(int starting_extent) +{ + root->extent = last_extent; + last_extent += 1; + return (0); +} + +/* + * The size of the path tables - two sectors + */ +static int +size_str_path(int starting_extent) +{ + path_table[0] = starting_extent; + path_table[1] = 0; + path_table[2] = path_table[0] + 1; + path_table[3] = 0; + last_extent += 2 * 1; + return (0); +} + +/* + * Generate the path table data + */ +static int +gen_str_path() +{ + /* + * Basically add the root directory entry + */ + l_path = (char *)e_malloc(SECTOR_SIZE); + m_path = (char *)e_malloc(SECTOR_SIZE); + memset(l_path, 0, SECTOR_SIZE); + memset(m_path, 0, SECTOR_SIZE); + l_path[0] = 1; + m_path[0] = 1; + set_731(l_path + 2, root->extent); + set_732(m_path + 2, root->extent); + set_721(l_path + 6, 1); + set_722(m_path + 6, 1); + l_path[8] = '\0'; l_path[9] = '\0'; + m_path[8] = '\0'; m_path[9] = '\0'; + return (0); +} + +/* + * Write the file content + */ +static int +write_str_file(FILE *outfile) +{ + unsigned int idx = 0; + unsigned int iso_blocks; + int count; + char *buf; + + buf = e_malloc(SECTOR_SIZE); + stream_size = 0; + while ((idx + SECTOR_SIZE) < (avail_extent * SECTOR_SIZE)) { + memset(buf, 0, SECTOR_SIZE); + count = fread(buf, 1, SECTOR_SIZE, stdin); + if (count <= 0) { + stream_finished = 1; + break; + } + idx += count; + jtwrite(buf, count, 1, 0, FALSE); + xfwrite(buf, count, 1, outfile, 0, FALSE); + } + + stream_size = idx; + iso_blocks = ISO_BLOCKS(idx); + memset(buf, 0, SECTOR_SIZE); + if (SECTOR_SIZE * iso_blocks - idx) + { + jtwrite(buf, SECTOR_SIZE * iso_blocks - idx, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE * iso_blocks - idx, 1, outfile, 0, FALSE); + } + /* + * If we didn't fill the available area, pad to directory block + */ + for (count = 0; count < (avail_extent - iso_blocks); count++) + { + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE); + } + for (count = 0; count < stream_pad; count++) + { + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE); + } + + last_extent_written += avail_extent + stream_pad; + return (0); +} + +/* + * Generate and write the directory record data + */ +static int +write_str_dir(FILE *outfile) +{ + int to_write; + char *buf; + + buf = e_malloc(SECTOR_SIZE); memset(buf, 0, SECTOR_SIZE); + memset(&s_dir, 0, sizeof (struct iso_directory_record)); + s_dir.length[0] = 34; /* BAD: Hardcoded - Will fix, MHV */ + s_dir.ext_attr_length[0] = 0; + set_733((char *)s_dir.extent, root->extent); + set_733((char *)s_dir.size, SECTOR_SIZE); + iso9660_date(s_dir.date, begun); + s_dir.flags[0] = ISO_DIRECTORY; + s_dir.file_unit_size[0] = 0; + s_dir.interleave[0] = 0; + set_723((char *)s_dir.volume_sequence_number, volume_sequence_number); + s_dir.name_len[0] = 1; + s_dir.name[0] = 0; /* "." */ + jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, 0, FALSE); + xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE); + s_dir.name[0] = 1; /* ".." */ + jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, 0, FALSE); + xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE); + memset(&s_dir, 0, sizeof (struct iso_directory_record)); + s_dir.length[0] = 34 + strlen(stream_filename); + s_dir.ext_attr_length[0] = 0; + set_733((char *) s_dir.extent, stream_extent); + set_733((char *) s_dir.size, stream_size); + iso9660_date(s_dir.date, begun); + s_dir.flags[0] = 0; + s_dir.file_unit_size[0] = 0; + set_723((char *)s_dir.volume_sequence_number, volume_sequence_number); + s_dir.name_len[0] = strlen(stream_filename); + memcpy(s_dir.name, stream_filename, s_dir.name_len[0]); + jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + + s_dir.name_len[0], 1, 0, FALSE); + xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + + s_dir.name_len[0], 1, outfile, 0, FALSE); + + /* + * This calc is: 2 single char directory entries (34) + an additional entry + * with filename length stream_filename + round up for even lenght count + */ + to_write = (s_dir.name_len[0] % 2) ? 0 : 1; + jtwrite(buf, SECTOR_SIZE - ((3 * 34) + s_dir.name_len[0]) + + to_write, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE - ((3 * 34) + s_dir.name_len[0]) + + to_write, 1, outfile, 0, FALSE); + free(buf); + last_extent_written++; + return (0); +} + +/* + * Generate the path table data + */ +static int +write_str_path(FILE *outfile) +{ + jtwrite(l_path, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(l_path, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + jtwrite(m_path, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(m_path, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + free(l_path); + free(m_path); + path_table_l = NULL; + path_table_m = NULL; + return (0); +} + +struct output_fragment strfile_desc = { NULL, size_str_file, NULL, write_str_file, "Stream File" }; +struct output_fragment strdir_desc = { NULL, size_str_dir, NULL, write_str_dir, "Stream File Directory" }; +struct output_fragment strpath_desc = { NULL, size_str_path, gen_str_path, write_str_path, "Stream File Path table" }; |