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 >
C/C++ Source or Header  |  1997-04-09  |  8KB  |  363 lines

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