📄 files.c
字号:
/* @(#)files.c 1.8 00/04/02 joerg */#ifndef lintstatic char sccsid[] = "@(#)files.c 1.8 00/04/02 joerg";#endif/* * 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 */#include "config.h"#include <errno.h>#include "mkisofs.h"#include <stdxlib.h>#include <ctype.h>#ifdef USE_LIBSCHILY#include <standard.h>#endif#ifdef ADD_FILESvoid add_one_file __PR((char *addpath, char *path));void add_file_list __PR((int argc, char **argv, int ind));void add_file __PR((char *filename));char * look_up_addition __PR((char **newpath, char *path, struct dirent **de));void nuke_duplicates __PR((char *path, struct dirent **de));struct dirent *readdir_add_files __PR((char **pathp, char *path, DIR *dir));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 * XXX 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;voidadd_one_file(addpath, path) 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: */voidadd_file_list(argc, argv, ind) 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++; }}voidadd_file(filename) 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) {#ifdef USE_LIBSCHILY comerr("Cannot open '%s'.\n", filename);#else perror("fopen"); exit(1);#endif } } 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) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Error in file '%s' line %d: %s\n", filename, count, buff);#else fprintf(stderr, "Error in file '%s' line %d: %s\n", filename, count, buff); exit(1);#endif } *p2 = 0; p2++; add_one_file(ptr, p2); } if (f != stdin) fclose(f);}/* This function looks up additions. */char *look_up_addition(newpath, path, de) 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. */voidnuke_duplicates(path, de) 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 *readdir_add_files(pathp, path, dir) 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);}#elsestruct dirent *readdir_add_files(pathp, path, dir) char **pathp; char *path; DIR *dir;{ return (readdir(dir));}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -