files.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:8k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /*
  2.  * File files.c - Handle ADD_FILES related stuff.
  3.    Written by Eric Youngdale (1993).
  4.    Copyright 1993 Yggdrasil Computing, Incorporated
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16. /* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */
  17. static char rcsid[] ="$Id: files.c,v 1.6 1998/02/16 17:56:54 eric Exp $";
  18. #include "config.h"
  19. #include <errno.h>
  20. #include "mkisofs.h"
  21. #include <stdlib.h>
  22. #include <ctype.h>
  23. #ifdef USE_LIBSCHILY
  24. #icnclude <standard.h>
  25. #endif
  26. #ifdef ADD_FILES
  27. struct file_adds {
  28.   char *name;
  29.   struct file_adds *child;
  30.   struct file_adds *next;
  31.   int add_count;
  32.   int used;
  33.   union diru {
  34. /*
  35.  * XXX Struct dirent is not guaranteed to be any size on a POSIX
  36.  * XXX compliant system.
  37.  * XXX We need to allocate enough space here, to allow the hacky
  38.  * XXX code in tree.c made by Ross Biro biro@yggdrasil.com
  39.  * XXX to work on operating systems other than Linux :-(
  40.  * XXX Changes made by Joerg Schilling joerg@schily.isdn.cs.tu-berlin.de
  41.  * XXX to prevent core dumps on Solaris.
  42.  * XXX Space allocated:
  43.  * XXX 1024 bytes == NAME_MAX
  44.  * XXX + 2   bytes for directory record length 
  45.  * XXX + 2*8 bytes for inode number & offset (64 for future exp)
  46.  */
  47.    struct dirent de;
  48.    char dspace[NAME_MAX+2+2*8];
  49.   } du;
  50.   struct {
  51.     char *path;
  52.     char *name;
  53.   } *adds;
  54. };
  55. extern struct file_adds *root_file_adds;
  56. /*
  57.  * FIXME(eric) - the file adding code really doesn't work very well
  58.  * at all.  We should differentiate between adding directories, and adding
  59.  * single files, as adding a full directory affects how we should be
  60.  * searching for things.  Ideally what we should do is make two passes
  61.  * through the local filesystem - one to figure out what trees we need
  62.  * to scan (and merge in any additions at that point), and the second to
  63.  * actually fill out each structure with the appropriate contents.
  64.  *
  65.  * 
  66.  */
  67. struct file_adds *root_file_adds = NULL;
  68. void
  69. FDECL2(add_one_file, char *, addpath, char *, path )
  70. {
  71.   char *cp;
  72.   char *name;
  73.   struct file_adds *f;
  74.   struct file_adds *tmp;
  75.   f = root_file_adds;
  76.   tmp = NULL;
  77.   name = strrchr (addpath, PATH_SEPARATOR);
  78.   if (name == NULL) {
  79.     name = addpath;
  80.   } else {
  81.     name++;
  82.   }
  83.   cp = strtok (addpath, SPATH_SEPARATOR);
  84.   while (cp != NULL && strcmp (name, cp)) {
  85.      if (f == NULL) {
  86.         root_file_adds = e_malloc (sizeof *root_file_adds);
  87.         f=root_file_adds;
  88.         f->name = NULL;
  89.         f->child = NULL;
  90.         f->next = NULL;
  91.         f->add_count = 0;
  92.         f->adds = NULL;
  93. f->used = 0;
  94.      }
  95.     if (f->child) {
  96.       for (tmp = f->child; tmp->next != NULL; tmp =tmp->next) {
  97.          if (strcmp (tmp->name, cp) == 0) {
  98.            f = tmp;
  99.            goto next;
  100.          }
  101.       }
  102.       if (strcmp (tmp->name, cp) == 0) {
  103.           f=tmp;
  104.           goto next;
  105.       }
  106.       /* add a new node. */
  107.       tmp->next = e_malloc (sizeof (*tmp->next));
  108.       f=tmp->next;
  109.       f->name = strdup (cp);
  110.       f->child = NULL;
  111.       f->next = NULL;
  112.       f->add_count = 0;
  113.       f->adds = NULL;
  114.       f->used = 0;
  115.     } else {
  116.       /* no children. */
  117.       f->child = e_malloc (sizeof (*f->child));
  118.       f = f->child;
  119.       f->name = strdup (cp);
  120.       f->child = NULL;
  121.       f->next = NULL;
  122.       f->add_count = 0;
  123.       f->adds = NULL;
  124.       f->used = 0;
  125.     }
  126.    next:
  127.      cp = strtok (NULL, SPATH_SEPARATOR);
  128.    }
  129.   /* Now f if non-null points to where we should add things */
  130.   if (f == NULL) {
  131.      root_file_adds = e_malloc (sizeof *root_file_adds);
  132.      f=root_file_adds;
  133.      f->name = NULL;
  134.      f->child = NULL;
  135.      f->next = NULL;
  136.      f->add_count = 0;
  137.      f->adds = NULL;
  138.    }
  139.   /* Now f really points to where we should add this name. */
  140.   f->add_count++;
  141.   f->adds = realloc (f->adds, sizeof (*f->adds)*f->add_count);
  142.   f->adds[f->add_count-1].path = strdup (path);
  143.   f->adds[f->add_count-1].name = strdup (name);
  144. }
  145. /*
  146.  * Function: add_file_list
  147.  *
  148.  * Purpose: Register an add-in file.
  149.  *
  150.  * Arguments:
  151.  */
  152. void
  153. FDECL3(add_file_list, int, argc, char **,argv, int, ind)
  154. {
  155.   char *ptr;
  156.   char *dup_arg;
  157.   while (ind < argc) {
  158.      dup_arg = strdup (argv[ind]);
  159.      ptr = strchr (dup_arg,'=');
  160.      if (ptr == NULL) {
  161.         free (dup_arg);
  162.         return;
  163.      }
  164.      *ptr = 0;
  165.      ptr++;
  166.      add_one_file (dup_arg, ptr);
  167.      free (dup_arg);
  168.      ind++;
  169.   }
  170. }
  171. void
  172. FDECL1(add_file, char *, filename)
  173. {
  174.   char buff[1024];
  175.   FILE *f;
  176.   char *ptr;
  177.   char *p2;
  178.   int count=0;
  179.   if (strcmp (filename, "-") == 0) {
  180.     f = stdin;
  181.   } else {
  182.     f = fopen (filename, "r");
  183.     if (f == NULL) {
  184. #ifdef USE_LIBSCHILY
  185. comerr(Cannot open '%s'.n", filename); 
  186. #endif
  187.       perror ("fopen");
  188.       exit (1);
  189. #endif
  190.     }
  191.   }
  192.   while (fgets (buff, 1024, f)) {
  193.     count++;
  194.     ptr = buff;
  195.     while (isspace (*ptr)) ptr++;
  196.     if (*ptr==0) continue;
  197.     if (*ptr=='#') continue;
  198.     if (ptr[strlen(ptr)-1]== 'n') ptr[strlen(ptr)-1]=0;
  199.     p2 = strchr (ptr, '=');
  200.     if (p2 == NULL) {
  201. #ifdef USE_LIBSCHILY
  202.       comerrno(EX_BAD, "Error in file '%s' line %d: %sn", filename, count, buff);
  203. #else
  204.       fprintf (stderr, "Error in file '%s' line %d: %sn", filename, count, buff);
  205.       exit (1);
  206. #endif
  207.     }
  208.     *p2 = 0;
  209.     p2++;
  210.     add_one_file (ptr, p2);
  211.   }
  212.   if (f != stdin) fclose (f);
  213. }
  214. /* This function looks up additions. */
  215. char *
  216. FDECL3(look_up_addition,char **, newpath, char *,path, struct dirent **,de)
  217. {
  218.   char *dup_path;
  219.   char *cp;
  220.   struct file_adds *f;
  221.   struct file_adds *tmp = NULL;
  222.   f=root_file_adds;
  223.   if (!f) return NULL;
  224.   /* I don't trust strtok */
  225.   dup_path = strdup (path);
  226.   cp = strtok (dup_path, SPATH_SEPARATOR);
  227.   while (cp != NULL) {
  228.     for (tmp = f->child; tmp != NULL; tmp=tmp->next) {
  229.       if (strcmp (tmp->name, cp) == 0) break;
  230.     }
  231.     if (tmp == NULL) {
  232.       /* no match */
  233.       free (dup_path);
  234.       return (NULL);
  235.     }
  236.     f = tmp;
  237.     cp = strtok(NULL, SPATH_SEPARATOR);
  238.   }
  239.   free (dup_path);
  240.   /*
  241.    * If nothing, then return.
  242.    */
  243.   if (tmp == NULL) 
  244.     {
  245.       /* no match */
  246.       return (NULL);
  247.     }
  248.   /* looks like we found something. */
  249.   if (tmp->used >= tmp->add_count) return (NULL);
  250.   *newpath = tmp->adds[tmp->used].path;
  251.   tmp->used++;
  252.   *de = &(tmp->du.de);
  253.   return (tmp->adds[tmp->used-1].name);
  254.   
  255. }
  256. /* This function looks up additions. */
  257. void
  258. FDECL2(nuke_duplicates, char *, path, struct dirent **,de) 
  259. {
  260.   char *dup_path;
  261.   char *cp;
  262.   struct file_adds *f;
  263.   struct file_adds *tmp;
  264.   f=root_file_adds;
  265.   if (!f) return;
  266.   /* I don't trust strtok */
  267.   dup_path = strdup (path);
  268.   cp = strtok (dup_path, SPATH_SEPARATOR);
  269.   while (cp != NULL) {
  270.     for (tmp = f->child; tmp != NULL; tmp=tmp->next) {
  271.       if (strcmp (tmp->name, cp) == 0) break;
  272.     }
  273.     if (tmp == NULL) {
  274.       /* no match */
  275.       free (dup_path);
  276.       return;
  277.     }
  278.     f = tmp;
  279.     cp = strtok(NULL, SPATH_SEPARATOR);
  280.   }
  281.   free (dup_path);
  282. #if 0
  283.   /* looks like we found something. */
  284.   if (tmp->used >= tmp->add_count) return;
  285.   *newpath = tmp->adds[tmp->used].path;
  286.   tmp->used++;
  287.   *de = &(tmp->du.de);
  288.   return (tmp->adds[tmp->used-1].name);
  289. #endif
  290.   return;
  291. }
  292. /* This function lets us add files from outside the standard file tree.
  293.    It is useful if we want to duplicate a cd, but add/replace things.
  294.    We should note that the real path will be used for exclusions. */
  295. struct dirent *
  296. FDECL3(readdir_add_files, char **, pathp, char *,path, DIR *, dir){
  297.   struct dirent *de;
  298.   char *addpath;
  299.   char *name;
  300.   de = readdir (dir);
  301.   if (de) {
  302.     nuke_duplicates(path, &de);
  303.     return (de);
  304.   }
  305.   name=look_up_addition (&addpath, path, &de);
  306.   if (!name) {
  307.     return NULL;
  308.   }
  309.   *pathp=addpath;
  310.   
  311.   /* Now we must create the directory entry. */
  312.   /* fortuneately only the name seems to matter. */
  313.   /*
  314.   de->d_ino = -1;
  315.   de->d_off = 0;
  316.   de->d_reclen = strlen (name);
  317.   */
  318.   strncpy (de->d_name, name, NAME_MAX);
  319.   de->d_name[NAME_MAX]=0;
  320.   nuke_duplicates(path, &de);
  321.   return (de);
  322. }
  323. #else
  324. struct dirent *
  325. FDECL3(readdir_add_files, char **, pathp, char *,path, DIR *, dir){
  326.   return (readdir (dir));
  327. }
  328. #endif