2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)stream.c 1.3 04/03/04 Copyright 2002-2003 J. Schilling */
14 /* Parts from @(#)stream.c 1.9 07/02/17 Copyright 2002-2007 J. Schilling */
16 * ISO-9660 stream (pipe) file module for genisoimage
18 * Copyright (c) 2002-2003 J. Schilling
19 * Implemented after an idea from M.H. Voase
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License version 2
24 * as published by the Free Software Foundation.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License along with
32 * this program; see the file COPYING. If not, write to the Free Software
33 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 #include "genisoimage.h"
40 static int size_str_file(int starting_extent);
41 static int size_str_dir(int starting_extent);
42 static int size_str_path(int starting_extent);
44 static int gen_str_path(void);
46 static int write_str_file(FILE *outfile);
47 static int write_str_dir(FILE *outfile);
48 static int write_str_path(FILE *outfile);
50 extern struct directory *root;
51 extern unsigned int session_start;
52 extern int stream_media_size;
53 extern char *stream_filename;
55 extern int volume_sequence_number;
57 static unsigned int avail_extent;
58 static unsigned int stream_extent;
59 static unsigned int stream_size;
60 static unsigned int stream_pad;
63 static struct iso_directory_record s_dir;
64 static int stream_finished = 0;
67 * Compute the size of the file
70 size_str_file(int starting_extent)
75 stream_extent = last_extent; /* Start of stream file content */
77 avail_extent = stream_media_size;
78 n = last_extent; /* Room for FS blocks before file */
79 n += 1; /* Room for the directory block */
83 n = 50; /* Make net. size easy to compute */
86 n += 150; /* Room for final padding */
89 last_extent += avail_extent + stream_pad;
95 * The size of the directory record - one sector
98 size_str_dir(int starting_extent)
100 root->extent = last_extent;
106 * The size of the path tables - two sectors
109 size_str_path(int starting_extent)
111 path_table[0] = starting_extent;
113 path_table[2] = path_table[0] + 1;
115 last_extent += 2 * 1;
120 * Generate the path table data
126 * Basically add the root directory entry
128 l_path = (char *)e_malloc(SECTOR_SIZE);
129 m_path = (char *)e_malloc(SECTOR_SIZE);
130 memset(l_path, 0, SECTOR_SIZE);
131 memset(m_path, 0, SECTOR_SIZE);
134 set_731(l_path + 2, root->extent);
135 set_732(m_path + 2, root->extent);
136 set_721(l_path + 6, 1);
137 set_722(m_path + 6, 1);
138 l_path[8] = '\0'; l_path[9] = '\0';
139 m_path[8] = '\0'; m_path[9] = '\0';
144 * Write the file content
147 write_str_file(FILE *outfile)
149 unsigned int idx = 0;
150 unsigned int iso_blocks;
154 buf = e_malloc(SECTOR_SIZE);
156 while ((idx + SECTOR_SIZE) < (avail_extent * SECTOR_SIZE)) {
157 memset(buf, 0, SECTOR_SIZE);
158 count = fread(buf, 1, SECTOR_SIZE, stdin);
164 jtwrite(buf, count, 1, 0, FALSE);
165 xfwrite(buf, count, 1, outfile, 0, FALSE);
169 iso_blocks = ISO_BLOCKS(idx);
170 memset(buf, 0, SECTOR_SIZE);
171 if (SECTOR_SIZE * iso_blocks - idx)
173 jtwrite(buf, SECTOR_SIZE * iso_blocks - idx, 1, 0, FALSE);
174 xfwrite(buf, SECTOR_SIZE * iso_blocks - idx, 1, outfile, 0, FALSE);
177 * If we didn't fill the available area, pad to directory block
179 for (count = 0; count < (avail_extent - iso_blocks); count++)
181 jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
182 xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE);
184 for (count = 0; count < stream_pad; count++)
186 jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE);
187 xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE);
190 last_extent_written += avail_extent + stream_pad;
195 * Generate and write the directory record data
198 write_str_dir(FILE *outfile)
203 buf = e_malloc(SECTOR_SIZE); memset(buf, 0, SECTOR_SIZE);
204 memset(&s_dir, 0, sizeof (struct iso_directory_record));
205 s_dir.length[0] = 34; /* BAD: Hardcoded - Will fix, MHV */
206 s_dir.ext_attr_length[0] = 0;
207 set_733((char *)s_dir.extent, root->extent);
208 set_733((char *)s_dir.size, SECTOR_SIZE);
209 iso9660_date(s_dir.date, begun);
210 s_dir.flags[0] = ISO_DIRECTORY;
211 s_dir.file_unit_size[0] = 0;
212 s_dir.interleave[0] = 0;
213 set_723((char *)s_dir.volume_sequence_number, volume_sequence_number);
214 s_dir.name_len[0] = 1;
215 s_dir.name[0] = 0; /* "." */
216 jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, 0, FALSE);
217 xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE);
218 s_dir.name[0] = 1; /* ".." */
219 jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, 0, FALSE);
220 xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE);
221 memset(&s_dir, 0, sizeof (struct iso_directory_record));
222 s_dir.length[0] = 34 + strlen(stream_filename);
223 s_dir.ext_attr_length[0] = 0;
224 set_733((char *) s_dir.extent, stream_extent);
225 set_733((char *) s_dir.size, stream_size);
226 iso9660_date(s_dir.date, begun);
228 s_dir.file_unit_size[0] = 0;
229 set_723((char *)s_dir.volume_sequence_number, volume_sequence_number);
230 s_dir.name_len[0] = strlen(stream_filename);
231 memcpy(s_dir.name, stream_filename, s_dir.name_len[0]);
232 jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0])
233 + s_dir.name_len[0], 1, 0, FALSE);
234 xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0])
235 + s_dir.name_len[0], 1, outfile, 0, FALSE);
238 * This calc is: 2 single char directory entries (34) + an additional entry
239 * with filename length stream_filename + round up for even lenght count
241 to_write = (s_dir.name_len[0] % 2) ? 0 : 1;
242 jtwrite(buf, SECTOR_SIZE - ((3 * 34) + s_dir.name_len[0]) +
243 to_write, 1, 0, FALSE);
244 xfwrite(buf, SECTOR_SIZE - ((3 * 34) + s_dir.name_len[0]) +
245 to_write, 1, outfile, 0, FALSE);
247 last_extent_written++;
252 * Generate the path table data
255 write_str_path(FILE *outfile)
257 jtwrite(l_path, SECTOR_SIZE, 1, 0, FALSE);
258 xfwrite(l_path, SECTOR_SIZE, 1, outfile, 0, FALSE);
259 last_extent_written++;
260 jtwrite(m_path, SECTOR_SIZE, 1, 0, FALSE);
261 xfwrite(m_path, SECTOR_SIZE, 1, outfile, 0, FALSE);
262 last_extent_written++;
270 struct output_fragment strfile_desc = { NULL, size_str_file, NULL, write_str_file, "Stream File" };
271 struct output_fragment strdir_desc = { NULL, size_str_dir, NULL, write_str_dir, "Stream File Directory" };
272 struct output_fragment strpath_desc = { NULL, size_str_path, gen_str_path, write_str_path, "Stream File Path table" };