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 /* @(#)files.c 1.12 04/03/04 joerg */
15 * File files.c - Handle ADD_FILES related stuff.
17 * Written by Eric Youngdale (1993).
19 * Copyright 1993 Yggdrasil Computing, Incorporated
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2, or (at your option)
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
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 /* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */
39 #include "genisoimage.h"
46 void add_one_file(char *addpath, char *path);
47 void add_file_list(int argc, char **argv, int ind);
48 void add_file(char *filename);
49 char *look_up_addition(char **newpath, char *path, struct dirent **de);
50 void nuke_duplicates(char *path, struct dirent **de);
51 struct dirent *readdir_add_files(char **pathp, char *path, DIR *dir);
55 struct file_adds *child;
56 struct file_adds *next;
61 * XXX Struct dirent is not guaranteed to be any size on a POSIX
62 * XXX compliant system.
63 * XXX We need to allocate enough space here, to allow the hacky
64 * XXX code in tree.c made by Ross Biro biro@yggdrasil.com
65 * XXX to work on operating systems other than Linux :-(
66 * XXX Changes made by Joerg Schilling
67 * XXX joerg@schily.isdn.cs.tu-berlin.de
68 * XXX to prevent core dumps on Solaris.
69 * XXX Space allocated:
70 * XXX 1024 bytes == NAME_MAX
71 * XXX + 2 bytes for directory record length
72 * XXX + 2*8 bytes for inode number & offset (64 for future exp)
75 char dspace[NAME_MAX + 2 + 2 * 8];
82 extern struct file_adds *root_file_adds;
85 * FIXME(eric) - the file adding code really doesn't work very well
86 * at all. We should differentiate between adding directories, and adding
87 * single files, as adding a full directory affects how we should be
88 * searching for things. Ideally what we should do is make two passes
89 * through the local filesystem - one to figure out what trees we need
90 * to scan (and merge in any additions at that point), and the second to
91 * actually fill out each structure with the appropriate contents.
94 struct file_adds *root_file_adds = NULL;
97 add_one_file(char *addpath, char *path)
102 struct file_adds *tmp;
107 name = strrchr(addpath, PATH_SEPARATOR);
114 cp = strtok(addpath, SPATH_SEPARATOR);
116 while (cp != NULL && strcmp(name, cp)) {
118 root_file_adds = e_malloc(sizeof (*root_file_adds));
128 for (tmp = f->child; tmp->next != NULL;
130 if (strcmp(tmp->name, cp) == 0) {
135 if (strcmp(tmp->name, cp) == 0) {
139 /* add a new node. */
140 tmp->next = e_malloc(sizeof (*tmp->next));
142 f->name = strdup(cp);
150 f->child = e_malloc(sizeof (*f->child));
152 f->name = strdup(cp);
161 cp = strtok(NULL, SPATH_SEPARATOR);
163 /* Now f if non-null points to where we should add things */
165 root_file_adds = e_malloc(sizeof (*root_file_adds));
173 /* Now f really points to where we should add this name. */
175 f->adds = realloc(f->adds, sizeof (*f->adds) * f->add_count);
176 f->adds[f->add_count - 1].path = strdup(path);
177 f->adds[f->add_count - 1].name = strdup(name);
181 * Function: add_file_list
183 * Purpose: Register an add-in file.
188 add_file_list(int argc, char **argv, int ind)
194 dup_arg = strdup(argv[ind]);
195 ptr = strchr(dup_arg, '=');
202 add_one_file(dup_arg, ptr);
209 add_file(char *filename)
217 if (strcmp(filename, "-") == 0) {
220 f = fopen(filename, "r");
223 comerr("Cannot open '%s'.\n", filename);
230 while (fgets(buff, sizeof (buff), f)) {
233 while (isspace(*ptr))
240 if (ptr[strlen(ptr) - 1] == '\n')
241 ptr[strlen(ptr) - 1] = 0;
242 p2 = strchr(ptr, '=');
245 comerrno(EX_BAD, "Error in file '%s' line %d: %s\n",
246 filename, count, buff);
248 fprintf(stderr, "Error in file '%s' line %d: %s\n",
249 filename, count, buff);
255 add_one_file(ptr, p2);
261 /* This function looks up additions. */
263 look_up_addition(char **newpath, char *path, struct dirent **de)
268 struct file_adds *tmp = NULL;
274 /* I don't trust strtok */
275 dup_path = strdup(path);
277 cp = strtok(dup_path, SPATH_SEPARATOR);
279 for (tmp = f->child; tmp != NULL; tmp = tmp->next) {
280 if (strcmp(tmp->name, cp) == 0)
289 cp = strtok(NULL, SPATH_SEPARATOR);
293 /* If nothing, then return. */
298 /* looks like we found something. */
299 if (tmp->used >= tmp->add_count)
302 *newpath = tmp->adds[tmp->used].path;
305 return (tmp->adds[tmp->used - 1].name);
309 /* This function looks up additions. */
311 nuke_duplicates(char *path, struct dirent **de)
316 struct file_adds *tmp;
322 /* I don't trust strtok */
323 dup_path = strdup(path);
325 cp = strtok(dup_path, SPATH_SEPARATOR);
327 for (tmp = f->child; tmp != NULL; tmp = tmp->next) {
328 if (strcmp(tmp->name, cp) == 0)
337 cp = strtok(NULL, SPATH_SEPARATOR);
342 /* looks like we found something. */
343 if (tmp->used >= tmp->add_count)
346 *newpath = tmp->adds[tmp->used].path;
349 return (tmp->adds[tmp->used - 1].name);
354 * This function lets us add files from outside the standard file tree.
355 * It is useful if we want to duplicate a cd, but add/replace things.
356 * We should note that the real path will be used for exclusions.
360 readdir_add_files(char **pathp, char **path, DIR *dir)
369 nuke_duplicates(path, &de);
372 name = look_up_addition(&addpath, path, &de);
380 * Now we must create the directory entry.
381 * fortuneately only the name seems to matter.
383 /* de->d_ino = -1; de->d_off = 0; de->d_reclen = strlen (name); */
384 strncpy(de->d_name, name, NAME_MAX);
385 de->d_name[NAME_MAX] = 0;
386 nuke_duplicates(path, &de);
393 readdir_add_files(char **pathp, char *path, DIR *dir)
395 return (readdir(dir));