home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 49
/
Amiga_Dream_49.iso
/
beos
/
utils
/
mkisofs-1.000
/
mkisofs-1.11-beos
/
files.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-04-09
|
8KB
|
363 lines
/*
* File files.c - Handle ADD_FILES related stuff.
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. */
/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */
static char rcsid[] ="$Id: files.c,v 1.5 1997/04/10 03:32:24 eric Rel $";
#include <errno.h>
#include "mkisofs.h"
#include <stdlib.h>
#include <ctype.h>
#ifdef ADD_FILES
struct file_adds {
char *name;
struct file_adds *child;
struct file_adds *next;
int add_count;
int used;
union diru {
/*
* XXX Struct dirent is not guaranteed to be any size on a POSIX
* XXX compliant system.
* XXX We need to allocate enough space here, to allow the hacky
* XXX code in tree.c made by Ross Biro biro@yggdrasil.com
* XXX to work on operating systems other than Linux :-(
* XXX Changes made by Joerg Schilling joerg@schily.isdn.cs.tu-berlin.de
* XXX to prevent core dumps on Solaris.
* XXX Space allocated:
* XXX 1024 bytes == NAME_MAX
* XXX + 2 bytes for directory record length
* XXX + 2*8 bytes for inode number & offset (64 for future exp)
*/
struct dirent de;
char dspace[NAME_MAX+2+2*8];
} du;
struct {
char *path;
char *name;
} *adds;
};
extern struct file_adds *root_file_adds;
/*
* FIXME(eric) - the file adding code really doesn't work very well
* at all. We should differentiate between adding directories, and adding
* single files, as adding a full directory affects how we should be
* searching for things. Ideally what we should do is make two passes
* through the local filesystem - one to figure out what trees we need
* to scan (and merge in any additions at that point), and the second to
* actually fill out each structure with the appropriate contents.
*
*
*/
struct file_adds *root_file_adds = NULL;
void
FDECL2(add_one_file, char *, addpath, char *, path )
{
char *cp;
char *name;
struct file_adds *f;
struct file_adds *tmp;
f = root_file_adds;
tmp = NULL;
name = strrchr (addpath, PATH_SEPARATOR);
if (name == NULL) {
name = addpath;
} else {
name++;
}
cp = strtok (addpath, SPATH_SEPARATOR);
while (cp != NULL && strcmp (name, cp)) {
if (f == NULL) {
root_file_adds = e_malloc (sizeof *root_file_adds);
f=root_file_adds;
f->name = NULL;
f->child = NULL;
f->next = NULL;
f->add_count = 0;
f->adds = NULL;
f->used = 0;
}
if (f->child) {
for (tmp = f->child; tmp->next != NULL; tmp =tmp->next) {
if (strcmp (tmp->name, cp) == 0) {
f = tmp;
goto next;
}
}
if (strcmp (tmp->name, cp) == 0) {
f=tmp;
goto next;
}
/* add a new node. */
tmp->next = e_malloc (sizeof (*tmp->next));
f=tmp->next;
f->name = strdup (cp);
f->child = NULL;
f->next = NULL;
f->add_count = 0;
f->adds = NULL;
f->used = 0;
} else {
/* no children. */
f->child = e_malloc (sizeof (*f->child));
f = f->child;
f->name = strdup (cp);
f->child = NULL;
f->next = NULL;
f->add_count = 0;
f->adds = NULL;
f->used = 0;
}
next:
cp = strtok (NULL, SPATH_SEPARATOR);
}
/* Now f if non-null points to where we should add things */
if (f == NULL) {
root_file_adds = e_malloc (sizeof *root_file_adds);
f=root_file_adds;
f->name = NULL;
f->child = NULL;
f->next = NULL;
f->add_count = 0;
f->adds = NULL;
}
/* Now f really points to where we should add this name. */
f->add_count++;
f->adds = realloc (f->adds, sizeof (*f->adds)*f->add_count);
f->adds[f->add_count-1].path = strdup (path);
f->adds[f->add_count-1].name = strdup (name);
}
/*
* Function: add_file_list
*
* Purpose: Register an add-in file.
*
* Arguments:
*/
void
FDECL3(add_file_list, int, argc, char **,argv, int, ind)
{
char *ptr;
char *dup_arg;
while (ind < argc) {
dup_arg = strdup (argv[ind]);
ptr = strchr (dup_arg,'=');
if (ptr == NULL) {
free (dup_arg);
return;
}
*ptr = 0;
ptr++;
add_one_file (dup_arg, ptr);
free (dup_arg);
ind++;
}
}
void
FDECL1(add_file, char *, filename)
{
char buff[1024];
FILE *f;
char *ptr;
char *p2;
int count=0;
if (strcmp (filename, "-") == 0) {
f = stdin;
} else {
f = fopen (filename, "r");
if (f == NULL) {
perror ("fopen");
exit (1);
}
}
while (fgets (buff, 1024, f)) {
count++;
ptr = buff;
while (isspace (*ptr)) ptr++;
if (*ptr==0) continue;
if (*ptr=='#') continue;
if (ptr[strlen(ptr)-1]== '\n') ptr[strlen(ptr)-1]=0;
p2 = strchr (ptr, '=');
if (p2 == NULL) {
fprintf (stderr, "Error in line %d: %s\n", count, buff);
exit (1);
}
*p2 = 0;
p2++;
add_one_file (ptr, p2);
}
if (f != stdin) fclose (f);
}
/* This function looks up additions. */
char *
FDECL3(look_up_addition,char **, newpath, char *,path, struct dirent **,de)
{
char *dup_path;
char *cp;
struct file_adds *f;
struct file_adds *tmp = NULL;
f=root_file_adds;
if (!f) return NULL;
/* I don't trust strtok */
dup_path = strdup (path);
cp = strtok (dup_path, SPATH_SEPARATOR);
while (cp != NULL) {
for (tmp = f->child; tmp != NULL; tmp=tmp->next) {
if (strcmp (tmp->name, cp) == 0) break;
}
if (tmp == NULL) {
/* no match */
free (dup_path);
return (NULL);
}
f = tmp;
cp = strtok(NULL, SPATH_SEPARATOR);
}
free (dup_path);
/*
* If nothing, then return.
*/
if (tmp == NULL)
{
/* no match */
return (NULL);
}
/* looks like we found something. */
if (tmp->used >= tmp->add_count) return (NULL);
*newpath = tmp->adds[tmp->used].path;
tmp->used++;
*de = &(tmp->du.de);
return (tmp->adds[tmp->used-1].name);
}
/* This function looks up additions. */
void
FDECL2(nuke_duplicates, char *, path, struct dirent **,de)
{
char *dup_path;
char *cp;
struct file_adds *f;
struct file_adds *tmp;
f=root_file_adds;
if (!f) return;
/* I don't trust strtok */
dup_path = strdup (path);
cp = strtok (dup_path, SPATH_SEPARATOR);
while (cp != NULL) {
for (tmp = f->child; tmp != NULL; tmp=tmp->next) {
if (strcmp (tmp->name, cp) == 0) break;
}
if (tmp == NULL) {
/* no match */
free (dup_path);
return;
}
f = tmp;
cp = strtok(NULL, SPATH_SEPARATOR);
}
free (dup_path);
#if 0
/* looks like we found something. */
if (tmp->used >= tmp->add_count) return;
*newpath = tmp->adds[tmp->used].path;
tmp->used++;
*de = &(tmp->du.de);
return (tmp->adds[tmp->used-1].name);
#endif
return;
}
/* This function lets us add files from outside the standard file tree.
It is useful if we want to duplicate a cd, but add/replace things.
We should note that the real path will be used for exclusions. */
struct dirent *
FDECL3(readdir_add_files, char **, pathp, char *,path, DIR *, dir){
struct dirent *de;
char *addpath;
char *name;
de = readdir (dir);
if (de) {
nuke_duplicates(path, &de);
return (de);
}
name=look_up_addition (&addpath, path, &de);
if (!name) {
return NULL;
}
*pathp=addpath;
/* Now we must create the directory entry. */
/* fortuneately only the name seems to matter. */
/*
de->d_ino = -1;
de->d_off = 0;
de->d_reclen = strlen (name);
*/
strncpy (de->d_name, name, NAME_MAX);
de->d_name[NAME_MAX]=0;
nuke_duplicates(path, &de);
return (de);
}
#else
struct dirent *
FDECL3(readdir_add_files, char **, pathp, char *,path, DIR *, dir){
return (readdir (dir));
}
#endif