home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 9
/
FreshFishVol9-CD2.bin
/
bbs
/
disk
/
mkisofs-1.00.7.lha
/
mkisofs
/
write.c
< prev
Wrap
C/C++ Source or Header
|
1994-12-18
|
27KB
|
920 lines
/*
* Program write.c - dump memory structures to file for iso9660 filesystem.
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
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; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h>
#include <stdlib.h>
#include "mkisofs.h"
#include "iso9660.h"
#include <time.h>
#include <errno.h>
#ifdef AMIGA
#include <exec/memory.h>
#ifdef LATTICE
#include <proto/utility.h>
#include <proto/exec.h>
#include <proto/dos.h>
#endif
#if defined(__GNUC__) || defined(AZTEC_C)
#include <clib/utility_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#endif
#endif
#ifndef AMIGA
#include <ctype.h>
#endif
#ifdef __svr4__
extern char * strdup(const char *);
#endif
/* Max number of sectors we will write at one time */
#define NSECT 16
/* Counters for statistics */
static int table_size = 0;
static int total_dir_size = 0;
static int rockridge_size = 0;
static struct directory ** pathlist;
static next_path_index = 1;
/* Used to fill in some of the information in the volume descriptor. */
static struct tm *local;
/* Location and length of extent of cdtv.tm file: */
static unsigned long cdtv_trademark_extent = 0;
static unsigned long cdtv_trademark_length = 0;
/* Routines to actually write the disc. We write sequentially so that
we could write a tape, or write the disc directly */
#define FILL_SPACE(X) memset(vol_desc.X, ' ', sizeof(vol_desc.X))
#define FILL_NULL(X) memset(vol_desc.X, 0, sizeof(vol_desc.X))
void FDECL2(set_721, char *, pnt, unsigned int, i){
pnt[0] = i & 0xff;
pnt[1] = (i >> 8) & 0xff;
}
void FDECL2(set_722, char *, pnt, unsigned int, i){
pnt[0] = (i >> 8) & 0xff;
pnt[1] = i & 0xff;
}
void FDECL2(set_723, char *, pnt, unsigned int, i){
pnt[3] = pnt[0] = i & 0xff;
pnt[2] = pnt[1] = (i >> 8) & 0xff;
}
void FDECL2(set_731, char *, pnt, unsigned int, i){
pnt[0] = i & 0xff;
pnt[1] = (i >> 8) & 0xff;
pnt[2] = (i >> 16) & 0xff;
pnt[3] = (i >> 24) & 0xff;
}
void FDECL2(set_732, char *, pnt, unsigned int, i){
pnt[3] = i & 0xff;
pnt[2] = (i >> 8) & 0xff;
pnt[1] = (i >> 16) & 0xff;
pnt[0] = (i >> 24) & 0xff;
}
int FDECL1(get_733, char *, p){
return ((p[0] & 0xff)
| ((p[1] & 0xff) << 8)
| ((p[2] & 0xff) << 16)
| ((p[3] & 0xff) << 24));
}
void FDECL2(set_733, char *, pnt, unsigned int, i){
pnt[7] = pnt[0] = i & 0xff;
pnt[6] = pnt[1] = (i >> 8) & 0xff;
pnt[5] = pnt[2] = (i >> 16) & 0xff;
pnt[4] = pnt[3] = (i >> 24) & 0xff;
}
static int xfwrite(void * buffer, int count, int size, FILE * file)
{
if (fwrite(buffer, count, size, file) == size) return size;
fprintf(stderr,"cannot write raw file\n");
exit(1);
}
#define DEFERRED_CHUNK_SIZE 65000
static struct directory_entry **deferred = NULL;
static unsigned int deferred_count = 0;
static unsigned int deferred_size = 0;
static struct directory_entry * sort_dir;
static unsigned int last_extent_written =0;
static struct iso_primary_descriptor vol_desc;
static path_table_index;
/* We recursively walk through all of the directories and assign extent
numbers to them. We have already assigned extent numbers to everything that
goes in front of them */
void FDECL1(assign_directory_addresses, struct directory *, node){
struct directory * dpnt;
int dir_size;
static unsigned long cnt = 0;
dpnt = node;
while (dpnt){
cnt++;
dpnt->extent = last_extent;
dpnt->path_index = next_path_index++;
dir_size = (dpnt->size + (SECTOR_SIZE - 1)) >> 11;
last_extent += dir_size;
if(dpnt->subdir) assign_directory_addresses(dpnt->subdir);
dpnt = dpnt->next;
};
#ifdef AMIGA
if (progress_indicator) {
printf ("Assigning addresses for directories (%d%% complete);"
" free mem: %lu \r",
pr_dir_count ? (int)(((cnt-1)*100)/pr_dir_count) : 100,
AvailMem (MEMF_ANY));
fflush (stdout);
}
#endif
}
static void FDECL3(write_one_file, char *, filename, unsigned int, size, FILE *, outfile){
FILE * infile;
#ifdef AMIGA
#ifdef LATTICE
__far static char buffer[SECTOR_SIZE * NSECT];
#else
static char buffer[SECTOR_SIZE * NSECT];
#endif
#else
char buffer[SECTOR_SIZE * NSECT];
#endif
int use;
int remain;
if ((infile = fopen(filename, "rb")) == NULL) {
#ifdef sun
fprintf(stderr, "cannot open %s: (%d)\n", filename, errno);
#else
fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
#endif
exit(1);
}
remain = size;
while(remain > 0){
use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain);
use = ROUND_UP(use); /* Round up to nearest sector boundary */
memset(buffer, 0, use);
if (fread(buffer, 1, use, infile) == 0) {
fprintf(stderr,"cannot read from %s\n",filename);
exit(1);
}
xfwrite(buffer, 1, use, outfile);
last_extent_written += use/SECTOR_SIZE;
if(verbose && (last_extent_written % 1000) < use/SECTOR_SIZE) {
fprintf(stderr,"%d..", last_extent_written);
#ifdef AMIGA
fflush (stderr);
#endif
}
remain -= use;
};
fclose(infile);
}
static void FDECL1(write_files, FILE *, outfile){
unsigned int i;
for (i=0; i<deferred_count; i++) {
#ifdef AMIGA
if (progress_indicator &&
((i&31) == 0 || i+1 == deferred_count)) {
printf ("Writing files (%d%% complete); free mem: %lu \r",
(int) ((100*(i+1))/deferred_count),
AvailMem (MEMF_ANY));
fflush (stdout);
}
#endif
#ifdef AMIGA
if(deferred[i]->is_a_table) {
#else
if(deferred[i]->inode == TABLE_INODE) {
#endif
xfwrite(deferred[i]->table, 1, ROUND_UP(deferred[i]->size),
outfile);
table_size += deferred[i]->size;
} else {
static char whole_path[1024];
strcpy (whole_path, deferred[i]->filedir->whole_name);
#ifdef AMIGA
if(strlen(whole_path) && whole_path[strlen(whole_path)-1] != ':')
strcat(whole_path, "/");
#else
if(strlen(whole_path)) strcat(whole_path, "/");
#endif
strcat (whole_path, deferred[i]->name);
write_one_file(whole_path, deferred[i]->size, outfile);
};
};
if (progress_indicator)
putchar ('\n');
}
/* compare strings of unsigned char: */
#ifdef AMIGA
typedef unsigned char UChar;
static int stringcmp (UChar *str1, UChar *str2)
{
for (;;) {
register unsigned char a = *str1++;
register unsigned char b = *str2++;
if (a < b)
return -1;
if (a > b)
return 1;
if (a == 0)
return 0;
}
}
#endif
int FDECL2(compare_dirs, const struct directory_entry **, r, const struct directory_entry **, l) {
static char left[40];
static char right[40];
char *cp;
strcpy (left, (*l)->isorec.iso_name);
strcpy (right, (*r)->isorec.iso_name);
if (((*l)->isorec.flags[0] & 2) == 0) {
if ((cp = strrchr (left, ';')) != 0) {
*cp = 0;
}
}
if (((*r)->isorec.flags[0] & 2) == 0) {
if ((cp = strrchr (right, ';')) != 0) {
*cp = 0;
}
}
#ifdef AMIGA
return stringcmp(right, left);
#else
return strcmp(right, left);
#endif
}
void FDECL1(sort_directory, struct directory_entry **, sort_dir){
int dcount = 0;
int i, len;
struct directory_entry * s_entry;
struct directory_entry ** sortlist;
s_entry = *sort_dir;
while(s_entry){
dcount++;
s_entry = s_entry->next;
};
/* OK, now we know how many there are. Build a vector for sorting. */
sortlist = (struct directory_entry **)
malloc(sizeof(struct directory_entry *) * dcount);
dcount = 0;
s_entry = *sort_dir;
while(s_entry){
sortlist[dcount] = s_entry;
len = s_entry->iso