home *** CD-ROM | disk | FTP | other *** search
- /*
- * File tree.c - scan directory tree and build memory structures 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 <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <errno.h>
-
- #ifndef VMS
- #ifndef AMIGA
- #include <unistd.h>
- #ifndef __QNX__
- #include <sys/sysmacros.h>
- #endif
- #endif
- #endif
-
- #include "mkisofs.h"
- #include "iso9660.h"
-
- #ifndef AMIGA
- #include <sys/stat.h>
- #endif
-
- #ifdef AMIGA
- #include <exec/memory.h>
- #ifdef LATTICE
- #include <proto/exec.h>
- #endif
- #if defined(__GNUC__) || defined(AZTEC_C)
- #include <clib/exec_protos.h>
- #endif
- #endif
-
- #include "exclude.h"
-
- #ifdef VMS
- #define S_ISLNK(m) (0)
- #define S_ISSOCK(m) (0)
- #define S_ISFIFO(m) (0)
- #else
- #ifndef S_ISLNK
- #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
- #endif
- #ifndef S_ISSOCK
- #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
- #endif
- #endif
-
- #ifdef __svr4__
- extern char * strdup(const char *);
- #endif
-
- static unsigned char symlink_buff[256];
-
- extern int verbose;
-
- struct stat fstatbuf = {0,}; /* We use this for the artificial entries we create */
-
- struct stat root_statbuf = {0, }; /* Stat buffer for root directory */
-
- struct directory * reloc_dir = NULL;
-
- unsigned long pr_dir_count = 0;
- unsigned long pr_file_count = 0;
-
- void FDECL1(sort_n_finish, struct directory *, this_dir)
- {
- struct directory_entry *s_entry, *s_entry1;
- time_t current_time;
- struct directory_entry * table;
- int count;
- int new_reclen;
- char * c;
- int tablesize = 0;
- char newname[15], rootname[15];
-
- /* Here we can take the opportunity to toss duplicate entries from the
- directory. */
-
- table = NULL;
-
- if(fstatbuf.st_ctime == 0){
- time (¤t_time);
- fstatbuf.st_uid = 0;
- fstatbuf.st_gid = 0;
- fstatbuf.st_ctime = current_time;
- fstatbuf.st_mtime = current_time;
- fstatbuf.st_atime = current_time;
- };
-
- flush_file_hash();
- s_entry = this_dir->contents;
- while(s_entry){
-
- /* First assume no conflict, and handle this case */
-
- if(!(s_entry1 = find_file_hash(s_entry->isorec.iso_name))){
- add_file_hash(s_entry);
- s_entry = s_entry->next;
- continue;
- };
-
- if (!convert_filenames) {
- fprintf (stderr, "Duplicate filename: %s\n", s_entry->isorec.iso_name);
- fprintf (stderr, "Filenames must be shorter than 30 characters!\n");
- exit (1);
- }
-
- if (s_entry->isorec.name_len[0] == 1 &&
- s_entry->isorec.iso_name[0] < 2) {
- fprintf (stderr, "Fatal error: duplicate dot or dotdot entry.\n");
- exit (1);
- }
-
- if(s_entry1 == s_entry){
- fprintf(stderr,"Fatal goof\n");
- exit(1);
- };
- /* OK, handle the conflicts. Try substitute names until we come
- up with a winner */
- strcpy(rootname, s_entry->isorec.iso_name);
- c = strchr(rootname, '.');
- if (c) *c = 0;
- count = 0;
- while(count < 1000){
- sprintf(newname,"%s.%3.3d%s", rootname, count,
- (s_entry->isorec.flags[0] == 2 ? "" : ";1"));
- if(!find_file_hash(newname)) break;
- count++;
- };
- if(count >= 1000){
- fprintf(stderr,"Unable to generate unique name for file %s\n", s_entry->name);
- exit(1);
- };
-
- /* OK, now we have a good replacement name. Now decide which one
- of these two beasts should get the name changed */
-
- if(s_entry->priority < s_entry1->priority) {
- fprintf(stderr,"Using %s for %s/%s (%s)\n", newname, this_dir->whole_name, s_entry->name, s_entry1->name);
- s_entry->isorec.name_len[0] = strlen(newname);
- new_reclen = ISO_REC_SIZE + strlen(newname);
- if(use_RockRidge) {
- if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
- new_reclen += s_entry->rr_attr_size;
- };
- if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
- s_entry->isorec.length[0] = new_reclen;
- s_entry->isorec.iso_name = strdup (newname);
- } else {
- delete_file_hash(s_entry1);
- fprintf(stderr,"Using %s for %s/%s (%s)\n", newname, this_dir->whole_name, s_entry1->name, s_entry->name);
- s_entry1->isorec.name_len[0] = strlen(newname);
- new_reclen = ISO_REC_SIZE + strlen(newname);
- if(use_RockRidge) {
- if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
- new_reclen += s_entry1->rr_attr_size;
- };
- if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
- s_entry1->isorec.length[0] = new_reclen;
- s_entry1->isorec.iso_name = strdup (newname);
- add_file_hash(s_entry1);
- };
- add_file_hash(s_entry);
- s_entry = s_entry->next;
- };
-
- if(generate_tables && !find_file_hash("TRANS.TBL;1") && (reloc_dir != this_dir)){
- /* First we need to figure out how big this table is */
- for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){
- if(strcmp(s_entry->name, ".") == 0 ||
- strcmp(s_entry->name, "..") == 0) continue;
- if(s_entry->table) tablesize += 35 + strlen(s_entry->table);
- };
- table = (struct directory_entry *)
- malloc(sizeof (struct directory_entry));
- memset(table, 0, sizeof(struct directory_entry));
- table->table = NULL;
- table->next = this_dir->contents;
- this_dir->contents = table;
-
- table->filedir = root;
- table->isorec.flags[0] = 0;
- table->priority = 32768;
- iso9660_date(table->isorec.date, current_time);
- #ifdef AMIGA
- table->is_a_table = 1;
- #else
- table->inode = TABLE_INODE;
- table->dev = UNCACHED_DEVICE;
- #endif
- set_723(table->isorec.volume_sequence_number, 1);
- set_733(table->isorec.size, tablesize);
- table->size = tablesize;
- table->filedir = this_dir;
- table->name = strdup("<translation table>");
- table->table = (char *) malloc(ROUND_UP(tablesize));
- memset(table->table, 0, ROUND_UP(tablesize));
- iso9660_file_length ("TRANS.TBL;1", table, 1);
-
- if(use_RockRidge){
- fstatbuf.st_mode = 0444 | S_IFREG;
- fstatbuf.st_nlink = 1;
- generate_rock_ridge_attributes("",
- "TRANS.TBL", table,
- &fstatbuf, &fstatbuf, 0);
- };
- };
-
- for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){
- new_reclen = strlen (s_entry->isorec.iso_name);
-
- if(s_entry->isorec.flags[0] == 2){
- if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) {
- /* path_table_size += new_reclen + sizeof(struct iso_path_table) - 1; */
- path_table_size += new_reclen + 8;
- if (new_reclen & 1) path_table_size++;
- } else {
- new_reclen = 1;
- if (this_dir == root && strlen(s_entry->name) == 1)
- /* path_table_size += sizeof(struct iso_path_table); */
- path_table_size += 9;
- }
- };
- if(path_table_size & 1) path_table_size++; /* For odd lengths we pad */
- s_entry->isorec.name_len[0] = new_reclen;
-
- new_reclen += ISO_REC_SIZE;
-
- if (new_reclen & 1)
- new_reclen++;
- if(use_RockRidge){
- new_reclen += s_entry->rr_attr_size;
-
- if (new_reclen & 1)
- new_reclen++;
- };
- if(new_reclen > 0xff) {
- fprintf(stderr,"Fatal error - RR overflow for file %s\n",
- s_entry->name);
- exit(1);
- };
- s_entry->isorec.length[0] = new_reclen;
- };
-
- sort_directory(&this_dir->contents);
-
- if(table){
- char buffer[1024];
- count = 0;
- for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){
- if(s_entry == table) continue;
- if(!s_entry->table) continue;
- if(strcmp(s_entry->name, ".") == 0 ||
- strcmp(s_entry->name, "..") == 0) continue;
-
- sprintf(buffer,"%c %-34s%s",s_entry->table[0],
- s_entry->isorec.iso_name, s_entry->table+1);
- memcpy(table->table + count, buffer, strlen(buffer));
- count += strlen(buffer);
- free(s_entry->table);
- s_entry->table = NULL;
- };
- if(count != tablesize) {
- fprintf(stderr,"Translation table size mismatch %d %d\n",
- count, tablesize);
- exit(1);
- };
- };
-
- /* Now go through the directory and figure out how large this one will be.
- Do not split a directory entry across a sector boundary */
-
- s_entry = this_dir->contents;
- while(s_entry){
- new_reclen = s_entry->isorec.length[0];
- if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE)
- this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) &
- ~(SECTOR_SIZE - 1);
- this_dir->size += new_reclen;
- s_entry = s_entry->next;
- }
- }
-
- static void generate_reloc_directory(void)
- {
- int new_reclen;
- time_t current_time;
- struct directory_entry *s_entry;
-
- /* Create an entry for our internal tree */
- time (¤t_time);
- reloc_dir = (struct directory *)
- malloc(sizeof(struct directory));
- memset(reloc_dir, 0, sizeof(struct directory));
- reloc_dir->parent = root;
- reloc_dir->next = root->subdir;
- root->subdir = reloc_dir;
- reloc_dir->depth = 1;
- reloc_dir->whole_name = strdup("./rr_moved");
- reloc_dir->de_name = strdup("rr_moved");
- reloc_dir->extent = 0;
-
- new_reclen = strlen(reloc_dir->de_name);
-
- /* Now create an actual directory entry */
- s_entry = (struct directory_entry *)
- malloc(sizeof (struct directory_entry));
- memset(s_entry, 0, sizeof(struct directory_entry));
- s_entry->next = root->contents;
- reloc_dir->self = s_entry;
-
- root->contents = s_entry;
- root->contents->name = strdup(reloc_dir->de_name);
- root->contents->filedir = root;
- root->contents->isorec.flags[0] = 2;
- root->contents->priority = 32768;
- iso9660_date(root->contents->isorec.date, current_time);
- #ifdef AMIGA
- root->contents->is_a_table = 0;
- #else
- root->contents->inode = UNCACHED_INODE;
- root->contents->dev = UNCACHED_DEVICE;
- #endif
- set_723(root->contents->isorec.volume_sequence_number, 1);
- iso9660_file_length (reloc_dir->de_name, root->contents, 1);
-
- if(use_RockRidge){
- fstatbuf.st_mode = 0555 | S_IFDIR;
- fstatbuf.st_nlink = 2;
- generate_rock_ridge_attributes("",
- "rr_moved", s_entry,
- &fstatbuf, &fstatbuf, 0);
- };
-
- /* Now create the . and .. entries in rr_moved */
- /* Now create an actual directory entry */
- s_entry = (struct directory_entry *)
- malloc(sizeof (struct directory_entry));
- memcpy(s_entry, root->contents,
- sizeof(struct directory_entry));
- s_entry->name = strdup(".");
- iso9660_file_length (".", s_entry, 1);
-
- #ifdef AMIGA
- s_entry->is_a_table = 0;
- #endif
-
- s_entry->filedir = reloc_dir;
- reloc_dir->contents = s_entry;
-
- if(use_RockRidge){
- fstatbuf.st_mode = 0555 | S_IFDIR;
- fstatbuf.st_nlink = 2;
- generate_rock_ridge_attributes("",
- ".", s_entry,
- &fstatbuf, &fstatbuf, 0);
- };
-
- s_entry = (struct directory_entry *)
- malloc(sizeof (struct directory_entry));
- memcpy(s_entry, root->contents,
- sizeof(struct directory_entry));
- #ifdef AMIGA
- s_entry->is_a_table = 0;
- #endif
- s_entry->name = strdup("..");
- iso9660_file_length ("..", s_entry, 1);
- s_entry->filedir = root;
- reloc_dir->contents->next = s_entry;
- reloc_dir->contents->next->next = NULL;
- if(use_RockRidge){
- fstatbuf.st_mode = 0555 | S_IFDIR;
- fstatbuf.st_nlink = 2;
- generate_rock_ridge_attributes("",
- "..", s_entry,
- &root_statbuf, &root_statbuf, 0);
- };
- }
-
- static void FDECL1(increment_nlink, struct directory_entry *, s_entry){
- char * pnt;
- int len, nlink;
-
- pnt = s_entry->rr_attributes;
- len = s_entry->rr_attr_size;
- while(len){
- if(pnt[0] == 'P' && pnt[1] == 'X') {
- nlink = get_733(pnt+12);
- set_733(pnt+12, nlink+1);
- break;
- };
- len -= pnt[2];
- pnt += pnt[2];
- };
- }
-
- void finish_cl_pl_entries(){
- struct directory_entry *s_entry, *s_entry1;
- struct directory * d_entry;
-
- s_entry = reloc_dir->contents;
- s_entry = s_entry->next->next; /* Skip past . and .. */
- for(; s_entry; s_entry = s_entry->next){
- d_entry = reloc_dir->subdir;
- while(d_entry){
- if(d_entry->self == s_entry) break;
- d_entry = d_entry->next;
- };
- if(!d_entry){
- fprintf(stderr,"Unable to locate directory parent\n");
- exit(1);
- };
-
- /* First fix the PL pointer in the directory in the rr_reloc dir */
- s_entry1 = d_entry->contents->next;
- set_733(s_entry1->rr_attributes + s_entry1->rr_attr_size - 8,
- s_entry->filedir->extent);
-
- /* Now fix the CL pointer */
- s_entry1 = s_entry->parent_rec;
-
- set_733(s_entry1->rr_attributes + s_entry1->rr_attr_size - 8,
- d_entry->extent);
-
- s_entry->filedir = reloc_dir; /* Now we can fix this */
- }
- /* Next we need to modify the NLINK terms in the assorted root directory records
- to account for the presence of the RR_MOVED directory */
-
- increment_nlink(root->self);
- increment_nlink(root->self->next);
- d_entry = root->subdir;
- while(d_entry){
- increment_nlink(d_entry->contents->next);
- d_entry = d_entry->next;
- };
- }
- /*
- * This function scans the directory tree, looking for files, and it makes
- * note of everything that is found. We also begin to construct the ISO9660
- * directory entries, so that we can determine how large each directory is.
- */
-
- int
- FDECL2(scan_directory_tree,char *, path, struct directory_entry *, de){
- DIR * current_dir;
- char whole_path[1024];
- #ifdef AMIGA
- char amiga_path[1024];
- #endif
- struct dirent * d_entry;
- struct directory_entry *s_entry, *s_entry1;
- struct directory * this_dir, *next_brother, *parent;
- struct stat statbuf, lstatbuf;
- int status;
- char * cpnt;
- #ifdef AMIGA
- char * cpnt2;
- #endif
- int deep_flag;
-
- current_dir = opendir(path);
- if(!current_dir) {
- fprintf(stderr,"Unable to open directory %s\n", path);
- de->isorec.flags[0] &= ~2; /* Mark as not a directory */
- return 0;
- };
-
- parent = de->filedir;
- /* Set up the struct for the current directory, and insert it into the
- tree */
-
- this_dir = (struct directory *) malloc(sizeof(struct directory));
- this_dir->next = NULL;
- this_dir->subdir = NULL;
- this_dir->self = de;
- this_dir->contents = NULL;
- this_dir->whole_name = strdup(path);
- cpnt = strrchr(this_dir->whole_name, '/');
- #ifdef AMIGA
- if ((cpnt2 = strchr (this_dir->whole_name, ':')) && cpnt < cpnt2)
- cpnt = cpnt2;
- #endif
- if(cpnt)
- this_dir->de_name = cpnt + 1;
- else
- this_dir->de_name = strdup (path);
- this_dir->size = 0;
- this_dir->extent = 0;
-
- if (verbose)
- fprintf (stderr, "%s\n", path);
-
- if(!parent || parent == root){
- if (!root) {
- root = this_dir; /* First time through for root directory only */
- root->depth = 0;
- root->parent = root;
- } else {
- this_dir->depth = 1;
- if(!root->subdir)
- root->subdir = this_dir;
- else {
- next_brother = root->subdir;
- while(next_brother->next) next_brother = next_brother->next;
- next_brother->next = this_dir;
- };
- this_dir->parent = parent;
- };
- } else {
- /* Come through here for normal traversal of tree */
- #ifdef DEBUG
- fprintf(stderr,"%s(%d) ", path, this_dir->depth);
- #endif
- if(!inhibit_relocation && parent->depth > 6) {
- fprintf(stderr,"Directories too deep %s\n", path);
- exit(1);
- };
-
- this_dir->parent = parent;
- this_dir->depth = parent->depth + 1;
-
- if(!parent->subdir)
- parent->subdir = this_dir;
- else {
- next_brother = parent->subdir;
- while(next_brother->next) next_brother = next_brother->next;
- next_brother->next = this_dir;
- };
- };
-
- /* Now we scan the directory itself, and look at what is inside of it. */
-
- while(1==1){
-
- d_entry = readdir(current_dir);
- if(!d_entry) break;
-
- /* OK, got a valid entry */
-
- /* If we do not want all files, then pitch the backups. */
- if(!all_files){
- if(strchr(d_entry->d_name,'~')) continue;
- if(strchr(d_entry->d_name,'#')) continue;
- };
-
- if(strlen(path)+strlen(d_entry->d_name) + 2 > sizeof(whole_path)){
- fprintf(stderr, "Overflow of stat buffer\n");
- exit(1);
- };
-
- /* Generate the complete ASCII path for this file */
- strcpy(whole_path, path);
- #ifdef AMIGA
- if(whole_path[strlen(whole_path)-1] != '/' &&
- whole_path[strlen(whole_path)-1] != ':') strcat(whole_path, "/");
- #else
- if(whole_path[strlen(whole_path)-1] != '/') strcat(whole_path, "/");
- #endif
- strcat(whole_path, d_entry->d_name);
-
- /* Should we exclude this file? */
- if (is_excluded(whole_path)) {
- if (verbose) {
- fprintf(stderr, "Excluded: %s\n",whole_path);
- }
- continue;
- }
-
- if (verbose >= 2) fprintf(stderr, "%s\n",whole_path);
-
- #ifdef AMIGA
- strcpy (amiga_path, whole_path);
- #ifndef __GNUC__
- remove_dot_files (amiga_path);
- #endif
-
- status = stat(amiga_path, &statbuf);
- lstatbuf = statbuf;
- #else
- status = stat(whole_path, &statbuf);
- lstat(whole_path, &lstatbuf);
- #endif
-
- if(this_dir == root && strcmp(d_entry->d_name, ".") == 0)
- root_statbuf = statbuf; /* Save this for later on */
-
- /* We do this to make sure that the root entries are consistent */
- if(this_dir == root && strcmp(d_entry->d_name, "..") == 0) {
- statbuf = root_statbuf;
- lstatbuf = root_statbuf;
- };
-
- #ifndef AMIGA
- if(S_ISLNK(lstatbuf.st_mode)){
-
- /* Here we decide how to handle the symbolic links. Here we
- handle the general case - if we are not following links or there is an
- error, then we must change something. If RR is in use, it is easy, we
- let RR describe the file. If not, then we punt the file. */
-
- if((status || !follow_links)){
- if(use_RockRidge){
- status = 0;
- statbuf.st_size = 0;
- statbuf.st_ino = UNCACHED_INODE;
- statbuf.st_dev = UNCACHED_DEVICE;
- statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
- } else {
- if(follow_links) fprintf(stderr,
- "Unable to stat file %s - ignoring and continuing.\n",
- whole_path);
- else fprintf(stderr,
- "Symlink %s ignored - continuing.\n",
- whole_path);
- continue; /* Non Rock Ridge discs - ignore all symlinks */
- };
- }
-
- /* Here we handle a different kind of case. Here we have a symlink,
- but we want to follow symlinks. If we run across a directory loop,
- then we need to pretend that we are not following symlinks for this file.
- If this is the first time we have seen this, then make this seem
- as if there was no symlink there in the first place */
-
- else if(strcmp(d_entry->d_name, ".") &&
- strcmp(d_entry->d_name, "..")) {
- if(find_directory_hash(statbuf.st_dev, statbuf.st_ino)){
- fprintf(stderr, "Infinite loop detected (%s)\n", whole_path);
- if(!use_RockRidge) continue;
- statbuf.st_size = 0;
- statbuf.st_ino = UNCACHED_INODE;
- statbuf.st_dev = UNCACHED_DEVICE;
- statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
- } else {
- lstatbuf = statbuf;
- add_directory_hash(statbuf.st_dev, statbuf.st_ino);
- };
- };
- };
- #endif
-
- #ifdef AMIGA
- if(S_ISREG(lstatbuf.st_mode) && !(S_IRUSR & lstatbuf.st_mode)) {
- #else
- if(S_ISREG(lstatbuf.st_mode) && (status = access(whole_path, R_OK))){
- #endif
- fprintf(stderr, "File %s is not readable (errno = %d) - ignoring\n",
- whole_path, errno);
- continue;
- }
-
- #ifndef AMIGA
- /* Add this so that we can detect directory loops with hard links.
- If we are set up to follow symlinks, then we skip this checking. */
- if(!follow_links && S_ISDIR(lstatbuf.st_mode) && strcmp(d_entry->d_name, ".") &&
- strcmp(d_entry->d_name, "..")) {
- if(find_directory_hash(statbuf.st_dev, statbuf.st_ino)) {
- fprintf(stderr,"Directory loop - fatal goof (%s %x %d).\n",
- whole_path, statbuf.st_dev, statbuf.st_ino);
- exit(1);
- };
- add_directory_hash(statbuf.st_dev, statbuf.st_ino);
- };
- #endif
-
- if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) &&
- #ifndef AMIGA
- !S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode) &&
- #endif
- !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) &&
- !S_ISDIR(lstatbuf.st_mode)) {
- fprintf(stderr,"Unknown file type %s - ignoring and continuing.\n",
- whole_path);
- continue;
- };
-
- /* Who knows what trash this is - ignore and continue */
-
- if(status) {
- fprintf(stderr,
- "Unable to stat file %s - ignoring and continuing.\n",
- whole_path);
- continue;
- };
-
- s_entry = (struct directory_entry *)
- malloc_forever(sizeof (struct directory_entry));
- s_entry->next = this_dir->contents;
- this_dir->contents = s_entry;
- deep_flag = 0;
- s_entry->table = NULL;
-
- s_entry->name = strdup(d_entry->d_name);
-
- s_entry->filedir = this_dir;
- s_entry->isorec.flags[0] = 0;
- s_entry->isorec.ext_attr_length[0] = 0;
- iso9660_date(s_entry->isorec.date, statbuf.st_ctime);
- s_entry->isorec.file_unit_size[0] = 0;
- s_entry->isorec.interleave[0] = 0;
- #ifdef AMIGA
- s_entry->is_a_table = 0;
- #endif
- if(parent && parent == reloc_dir && strcmp(d_entry->d_name, "..") == 0){
- #ifndef AMIGA
- s_entry->inode = UNCACHED_INODE;
- s_entry->dev = UNCACHED_DEVICE;
- #endif
- deep_flag = NEED_PL;
- } else {
- #ifndef AMIGA
- s_entry->inode = statbuf.st_ino;
- s_entry->dev = statbuf.st_dev;
- #endif
- };
- set_723(s_entry->isorec.volume_sequence_number, 1);
- iso9660_file_length(d_entry->d_name, s_entry, S_ISDIR(statbuf.st_mode));
- s_entry->rr_attr_size = 0;
- s_entry->rr_attributes = NULL;
-
- /* Directories are assigned sizes later on */
- if (!S_ISDIR(statbuf.st_mode)) {
- set_733(s_entry->isorec.size, statbuf.st_size);
-
- if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) ||
- #ifndef AMIGA
- S_ISFIFO(lstatbuf.st_mode) || S_ISSOCK(lstatbuf.st_mode) ||
- #endif
- S_ISLNK(lstatbuf.st_mode))
- s_entry->size = 0;
- else
- s_entry->size = statbuf.st_size;
- pr_file_count++;
- } else {
- s_entry->isorec.flags[0] = 2;
- if (strcmp(d_entry->d_name,".") && strcmp(d_entry->d_name,".."))
- pr_dir_count++;
- }
-
- if (!inhibit_relocation &&
- strcmp(d_entry->d_name,".") && strcmp(d_entry->d_name,"..") &&
- S_ISDIR(statbuf.st_mode) && this_dir->depth > 6){
- if(!reloc_dir) generate_reloc_directory();
-
- s_entry1 = (struct directory_entry *)
- malloc(sizeof (struct directory_entry));
- memcpy(s_entry1, this_dir->contents,
- sizeof(struct directory_entry));
- s_entry1->table = NULL;
- s_entry1->name = strdup(this_dir->contents->name);
- s_entry1->next = reloc_dir->contents;
- reloc_dir->contents = s_entry1;
- s_entry1->priority = 32768;
- s_entry1->parent_rec = this_dir->contents;
-
- deep_flag = NEED_RE;
-
- if(use_RockRidge) {
- generate_rock_ridge_attributes(whole_path,
- d_entry->d_name, s_entry1,
- &statbuf, &lstatbuf, deep_flag);
- };
-
- deep_flag = 0;
-
- /* We need to set this temporarily so that the parent to this is correctly
- determined. */
- s_entry1->filedir = reloc_dir;
- scan_directory_tree(whole_path, s_entry1);
- s_entry1->filedir = this_dir;
-
- statbuf.st_size = 0;
- statbuf.st_mode &= 0777;
- set_733(s_entry->isorec.size, 0);
- s_entry->size = 0;
- s_entry->isorec.flags[0] = 0;
- #ifdef AMIGA
- s_entry->is_a_table = 0;
- #else
- s_entry->inode = UNCACHED_INODE;
- #endif
- deep_flag = NEED_CL;
- };
-
- if(generate_tables && strcmp(s_entry->name, ".") && strcmp(s_entry->name, "..")) {
- char buffer[2048];
- switch(lstatbuf.st_mode & S_IFMT){
- case S_IFDIR:
- sprintf(buffer,"D\t%s\n",
- s_entry->name);
- break;
- #ifndef AMIGA
- #ifndef VMS
- case S_IFBLK:
- sprintf(buffer,"B\t%s\t%d %d\n",
- s_entry->name,
- major(statbuf.st_rdev), minor(statbuf.st_rdev));
- break;
- case S_IFIFO:
- sprintf(buffer,"P\t%s\n",
- s_entry->name);
- break;
- case S_IFCHR:
- sprintf(buffer,"C\t%s\t%d %d\n",
- s_entry->name,
- major(statbuf.st_rdev), minor(statbuf.st_rdev));
- break;
- case S_IFLNK:
- readlink(whole_path, symlink_buff, sizeof(symlink_buff));
- sprintf(buffer,"L\t%s\t%s\n",
- s_entry->name, symlink_buff);
- break;
- case S_IFSOCK:
- sprintf(buffer,"S\t%s\n",
- s_entry->name);
- break;
- #endif
- #endif
- case S_IFREG:
- default:
- sprintf(buffer,"F\t%s\n",
- s_entry->name);
- break;
- };
- s_entry->table = strdup(buffer);
- };
-
- if(S_ISDIR(statbuf.st_mode)){
- int dflag;
- if (strcmp(d_entry->d_name,".") && strcmp(d_entry->d_name,"..")) {
- /* shall filenames in this directory be converted? */
- if (is_included_conv (whole_path)) {
- convert_filenames = 1;
- dflag = scan_directory_tree(whole_path, s_entry);
- convert_filenames = 0;
- } else
- dflag = scan_directory_tree(whole_path, s_entry);
-
- /* If unable to scan directory, mark this as a non-directory */
- if(!dflag)
- lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG;
- }
- };
-
- if(use_RockRidge && this_dir == root && strcmp(s_entry->name, ".") == 0)
- deep_flag |= NEED_CE | NEED_SP; /* For extension record */
-
- /* Now figure out how much room this file will take in the directory */
-
- if(use_RockRidge) {
- generate_rock_ridge_attributes(whole_path,
- d_entry->d_name, s_entry,
- &statbuf, &lstatbuf, deep_flag);
-
- }
- }
- closedir(current_dir);
- sort_n_finish(this_dir);
-
- #ifdef AMIGA
- if (progress_indicator) {
- printf ("Scanning tree; %lu directories, %lu files; free mem: %lu \r",
- pr_dir_count, pr_file_count, AvailMem (MEMF_ANY));
- fflush (stdout);
- }
- #endif
-
- return 1;
- }
-
-
- void FDECL2(generate_iso9660_directories, struct directory *, node, FILE*, outfile){
- struct directory * dpnt;
-
- dpnt = node;
-
- while (dpnt){
- generate_one_directory(dpnt, outfile);
- if(dpnt->subdir) generate_iso9660_directories(dpnt->subdir, outfile);
- dpnt = dpnt->next;
- };
- }
-
- void FDECL1(dump_tree, struct directory *, node){
- struct directory * dpnt;
-
- dpnt = node;
-
- while (dpnt){
- fprintf(stderr,"%4d %5d %s\n",dpnt->extent, dpnt->size, dpnt->de_name);
- if(dpnt->subdir) dump_tree(dpnt->subdir);
- dpnt = dpnt->next;
- };
- }
-
-