Magellan Linux

Diff of /trunk/mkinitrd-magellan/klibc/usr/utils/cpio.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 1297 by niro, Fri May 27 15:12:11 2011 UTC
# Line 43  Line 43 
43  #  define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)  #  define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
44  # endif  # endif
45    
 # ifndef FILE_SYSTEM_PREFIX_LEN  
 #  define FILE_SYSTEM_PREFIX_LEN(Filename) 0  
 # endif  
   
 #ifndef SYMLINK_USES_UMASK  
 # define UMASKED_SYMLINK(name1,name2,mode)    symlink(name1,name2)  
 #else  
 # define UMASKED_SYMLINK(name1,name2,mode)    umasked_symlink(name1,name2,mode)  
 #endif /* SYMLINK_USES_UMASK */  
   
46  /* Return 1 if an array of N objects, each of size S, cannot exist due  /* Return 1 if an array of N objects, each of size S, cannot exist due
47     to size arithmetic overflow.  S must be positive and N must be     to size arithmetic overflow.  S must be positive and N must be
48     nonnegative.  This is a macro, not an inline function, so that it     nonnegative.  This is a macro, not an inline function, so that it
# Line 92  int io_block_size = 512; Line 82  int io_block_size = 512;
82    
83  struct new_cpio_header {  struct new_cpio_header {
84   unsigned short c_magic;   unsigned short c_magic;
85   unsigned long c_ino;   union {
86   unsigned long c_mode;   struct {
87   unsigned long c_uid;   unsigned long c_ino;
88   unsigned long c_gid;   unsigned long c_mode;
89   unsigned long c_nlink;   unsigned long c_uid;
90   unsigned long c_mtime;   unsigned long c_gid;
91   unsigned long c_filesize;   unsigned long c_nlink;
92   long c_dev_maj;   unsigned long c_mtime;
93   long c_dev_min;   unsigned long c_filesize;
94   long c_rdev_maj;   long c_dev_maj;
95   long c_rdev_min;   long c_dev_min;
96   unsigned long c_namesize;   long c_rdev_maj;
97   unsigned long c_chksum;   long c_rdev_min;
98     unsigned long c_namesize;
99     unsigned long c_chksum;
100     };
101     unsigned long c_hdr[13];
102     };
103   char *c_name;   char *c_name;
104   char *c_tar_linkname;   char *c_tar_linkname;
105  };  };
106    
107  /* Total number of bytes read and written for all files.    /* Total number of bytes read and written for all files.
108     Now that many tape drives hold more than 4Gb we need more than 32   * Now that many tape drives hold more than 4Gb we need more than 32
109     bits to hold input_bytes and output_bytes.  But it's not worth   *  bits to hold input_bytes and output_bytes.
110     the trouble of adding special multi-precision arithmetic if the   */
    compiler doesn't support 64 bit ints since input_bytes and  
    output_bytes are only used to print the number of blocks copied.  */  
 #ifdef __GNUC__  
111  long long input_bytes, output_bytes;  long long input_bytes, output_bytes;
 #else  
 long input_bytes, output_bytes;  
 #endif  
112    
113  /* Allocate N bytes of memory dynamically, with error checking.  */  /* Allocate N bytes of memory dynamically, with error checking.  */
114    
115  void *xmalloc(size_t n)  static void *xmalloc(size_t n)
116  {  {
117   void *p;   void *p;
118   if (xalloc_oversized(n, 1) || (!(p = malloc(n)) && n != 0)) {   if (xalloc_oversized(n, 1) || (!(p = malloc(n)) && n != 0)) {
# Line 134  void *xmalloc(size_t n) Line 123  void *xmalloc(size_t n)
123  /*   return xnmalloc_inline (n, 1); */  /*   return xnmalloc_inline (n, 1); */
124  }  }
125    
 /* Change the size of an allocated block of memory P to N bytes,  
    with error checking.  */  
   
 void *xrealloc(void *p, size_t n)  
 {  
  if (xalloc_oversized(n, 1) || (!(p = realloc(p, n)) && n != 0)) {  
  fprintf(stderr, "%s: memory exhausted\n", progname);  
  exit(1);  
  }  
  return p;  
 /*   return xnrealloc_inline (p, n, 1); */  
 }  
   
126  /* Clone STRING.  */  /* Clone STRING.  */
127    
128  char *xstrdup(char const *string)  static char *xstrdup(char const *string)
129  {  {
130   size_t s = strlen(string) + 1;   size_t s = strlen(string) + 1;
131   return memcpy(xmalloc(s), string, s);   return memcpy(xmalloc(s), string, s);
# Line 181  static void tape_fill_input_buffer(int i Line 157  static void tape_fill_input_buffer(int i
157     descriptor OUT_DES and reset `output_size' and `out_buff'.     descriptor OUT_DES and reset `output_size' and `out_buff'.
158     If `swapping_halfwords' or `swapping_bytes' is set,     If `swapping_halfwords' or `swapping_bytes' is set,
159     do the appropriate swapping first.  Our callers have     do the appropriate swapping first.  Our callers have
160     to make sure to only set these flags if `output_size'     to make sure to only set these flags if `output_size'
161     is appropriate (a multiple of 4 for `swapping_halfwords',     is appropriate (a multiple of 4 for `swapping_halfwords',
162     2 for `swapping_bytes').  The fact that DISK_IO_BLOCK_SIZE     2 for `swapping_bytes').  The fact that DISK_IO_BLOCK_SIZE
163     must always be a multiple of 4 helps us (and our callers)     must always be a multiple of 4 helps us (and our callers)
164     insure this.  */     insure this.  */
165    
166  void disk_empty_output_buffer(int out_des)  static void disk_empty_output_buffer(int out_des)
167  {  {
168   int bytes_written;   int bytes_written;
169    
# Line 206  void disk_empty_output_buffer(int out_de Line 182  void disk_empty_output_buffer(int out_de
182  /* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full.  /* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full.
183     When `out_buff' fills up, flush it to file descriptor OUT_DES.  */     When `out_buff' fills up, flush it to file descriptor OUT_DES.  */
184    
185  void disk_buffered_write(char *in_buf, int out_des, long num_bytes)  static void disk_buffered_write(char *in_buf, int out_des, long num_bytes)
186  {  {
187   register long bytes_left = num_bytes; /* Bytes needing to be copied.  */   register long bytes_left = num_bytes; /* Bytes needing to be copied.  */
188   register long space_left; /* Room left in output buffer.  */   register long space_left; /* Room left in output buffer.  */
# Line 235  void disk_buffered_write(char *in_buf, i Line 211  void disk_buffered_write(char *in_buf, i
211     OUT_DES is the file descriptor for output;     OUT_DES is the file descriptor for output;
212     NUM_BYTES is the number of bytes to copy.  */     NUM_BYTES is the number of bytes to copy.  */
213    
214  void copy_files_tape_to_disk(int in_des, int out_des, long num_bytes)  static void copy_files_tape_to_disk(int in_des, int out_des, long num_bytes)
215  {  {
216   long size;   long size;
217    
# Line 251  void copy_files_tape_to_disk(int in_des, Line 227  void copy_files_tape_to_disk(int in_des,
227  }  }
228    
229  /* if IN_BUF is NULL, Skip the next NUM_BYTES bytes of file descriptor IN_DES. */  /* if IN_BUF is NULL, Skip the next NUM_BYTES bytes of file descriptor IN_DES. */
230  void tape_buffered_read(char *in_buf, int in_des, long num_bytes)  static void tape_buffered_read(char *in_buf, int in_des, long num_bytes)
231  {  {
232   register long bytes_left = num_bytes; /* Bytes needing to be copied.  */   register long bytes_left = num_bytes; /* Bytes needing to be copied.  */
233   register long space_left; /* Bytes to copy from input buffer.  */   register long space_left; /* Bytes to copy from input buffer.  */
# Line 282  struct deferment { Line 258  struct deferment {
258   struct new_cpio_header header;   struct new_cpio_header header;
259  };  };
260    
261  struct deferment *create_deferment(struct new_cpio_header *file_hdr)  static struct deferment *create_deferment(struct new_cpio_header *file_hdr)
262  {  {
263   struct deferment *d;   struct deferment *d;
264   d = (struct deferment *)xmalloc(sizeof(struct deferment));   d = (struct deferment *)xmalloc(sizeof(struct deferment));
# Line 292  struct deferment *create_deferment(struc Line 268  struct deferment *create_deferment(struc
268   return d;   return d;
269  }  }
270    
271  void free_deferment(struct deferment *d)  static void free_deferment(struct deferment *d)
272  {  {
273   free(d->header.c_name);   free(d->header.c_name);
274   free(d);   free(d);
275  }  }
276    
277  int link_to_name(char *link_name, char *link_target)  static int link_to_name(char *link_name, char *link_target)
278  {  {
279   int res = link(link_target, link_name);   int res = link(link_target, link_name);
280   return res;   return res;
# Line 352  static void hash_insert(struct inode_val Line 328  static void hash_insert(struct inode_val
328    
329  /* Associate FILE_NAME with the inode NODE_NUM.  (Insert into hash table.)  */  /* Associate FILE_NAME with the inode NODE_NUM.  (Insert into hash table.)  */
330    
331  void  static void
332  add_inode(unsigned long node_num, char *file_name, unsigned long major_num,  add_inode(unsigned long node_num, char *file_name, unsigned long major_num,
333    unsigned long minor_num)    unsigned long minor_num)
334  {  {
# Line 389  add_inode(unsigned long node_num, char * Line 365  add_inode(unsigned long node_num, char *
365   for (i = 0; i < hash_num; i++)   for (i = 0; i < hash_num; i++)
366   hash_insert(old_table[i]);   hash_insert(old_table[i]);
367    
368   if (old_table != NULL)   free(old_table);
  free(old_table);  
369   }   }
370    
371   /* Insert the new record and increment the count of elements in the   /* Insert the new record and increment the count of elements in the
# Line 399  add_inode(unsigned long node_num, char * Line 374  add_inode(unsigned long node_num, char *
374   hash_num++;   hash_num++;
375  }  }
376    
377  char *find_inode_file(unsigned long node_num, unsigned long major_num,  static char *find_inode_file(unsigned long node_num, unsigned long major_num,
378        unsigned long minor_num)        unsigned long minor_num)
379  {  {
380   int start; /* Initial hash location.  */   int start; /* Initial hash location.  */
# Line 431  char *find_inode_file(unsigned long node Line 406  char *find_inode_file(unsigned long node
406   return NULL;   return NULL;
407  }  }
408    
409  /* Try and create a hard link from FILE_NAME to another file  /* Try and create a hard link from FILE_NAME to another file
410     with the given major/minor device number and inode.  If no other     with the given major/minor device number and inode.  If no other
411     file with the same major/minor/inode numbers is known, add this file     file with the same major/minor/inode numbers is known, add this file
412     to the list of known files and associated major/minor/inode numbers     to the list of known files and associated major/minor/inode numbers
# Line 439  char *find_inode_file(unsigned long node Line 414  char *find_inode_file(unsigned long node
414     numbers is found, try and create another link to it using     numbers is found, try and create another link to it using
415     link_to_name, and return 0 for success and -1 for failure.  */     link_to_name, and return 0 for success and -1 for failure.  */
416    
417  int  static int
418  link_to_maj_min_ino(char *file_name, int st_dev_maj, int st_dev_min, int st_ino)  link_to_maj_min_ino(char *file_name, int st_dev_maj, int st_dev_min, int st_ino)
419  {  {
420   int link_res;   int link_res;
# Line 457  link_to_maj_min_ino(char *file_name, int Line 432  link_to_maj_min_ino(char *file_name, int
432  static void copyin_regular_file(struct new_cpio_header *file_hdr,  static void copyin_regular_file(struct new_cpio_header *file_hdr,
433   int in_file_des);   int in_file_des);
434    
435  void warn_junk_bytes(long bytes_skipped)  static void warn_junk_bytes(long bytes_skipped)
436  {  {
437   fprintf(stderr, "%s: warning: skipped %ld byte(s) of junk\n",   fprintf(stderr, "%s: warning: skipped %ld byte(s) of junk\n",
438   progname, bytes_skipped);   progname, bytes_skipped);
# Line 506  try_existing_file(struct new_cpio_header Line 481  try_existing_file(struct new_cpio_header
481   return 0;   return 0;
482  }  }
483    
484  /* The newc and crc formats store multiply linked copies of the same file  /* The newc and crc formats store multiply linked copies of the same file
485     in the archive only once.  The actual data is attached to the last link     in the archive only once.  The actual data is attached to the last link
486     in the archive, and the other links all have a filesize of 0.  When a     in the archive, and the other links all have a filesize of 0.  When a
487     file in the archive has multiple links and a filesize of 0, its data is     file in the archive has multiple links and a filesize of 0, its data is
488     probably "attatched" to another file in the archive, so we can't create     probably "attatched" to another file in the archive, so we can't create
489     it right away.  We have to "defer" creating it until we have created     it right away.  We have to "defer" creating it until we have created
490     the file that has the data "attatched" to it.  We keep a list of the     the file that has the data "attatched" to it.  We keep a list of the
# Line 578  static void create_defered_links(struct Line 553  static void create_defered_links(struct
553     we are done reading the whole archive.  Write out all of these     we are done reading the whole archive.  Write out all of these
554     empty links that are still on the deferments list.  */     empty links that are still on the deferments list.  */
555    
556  static void create_final_defers()  static void create_final_defers(void)
557  {  {
558   struct deferment *d;   struct deferment *d;
559   int link_res;   int link_res;
# Line 704  copyin_regular_file(struct new_cpio_head Line 679  copyin_regular_file(struct new_cpio_head
679    
680   tape_skip_padding(in_file_des, file_hdr->c_filesize);   tape_skip_padding(in_file_des, file_hdr->c_filesize);
681   if (file_hdr->c_nlink > 1) {   if (file_hdr->c_nlink > 1) {
682   /* (see comment above for how the newc and crc formats   /* (see comment above for how the newc and crc formats
683     store multiple links).  Now that we have the data     store multiple links).  Now that we have the data
684     for this file, create any other links to it which     for this file, create any other links to it which
685     we defered.  */     we defered.  */
686   create_defered_links(file_hdr);   create_defered_links(file_hdr);
# Line 720  copyin_regular_file(struct new_cpio_head Line 695  copyin_regular_file(struct new_cpio_head
695     NAME has no file name components because it is all slashes, return     NAME has no file name components because it is all slashes, return
696     NAME if it is empty, the address of its last slash otherwise.  */     NAME if it is empty, the address of its last slash otherwise.  */
697    
698  char *base_name(char const *name)  static char *base_name(char const *name)
699  {  {
700   char const *base = name + FILE_SYSTEM_PREFIX_LEN(name);   char const *base = name;
701   char const *p;   char const *p;
702    
703   for (p = base; *p; p++) {   for (p = base; *p; p++) {
# Line 752  char *base_name(char const *name) Line 727  char *base_name(char const *name)
727     value returned by base_name.  Act like strlen (NAME), except omit     value returned by base_name.  Act like strlen (NAME), except omit
728     redundant trailing slashes.  */     redundant trailing slashes.  */
729    
730  size_t base_len(char const *name)  static size_t base_len(char const *name)
731  {  {
732   size_t len;   size_t len;
733    
# Line 769  size_t base_len(char const *name) Line 744  size_t base_len(char const *name)
744     the Unix rename and rmdir system calls return an "Invalid argument" error     the Unix rename and rmdir system calls return an "Invalid argument" error
745     when given a path that ends in "/" (except for the root directory).  */     when given a path that ends in "/" (except for the root directory).  */
746    
747  bool strip_trailing_slashes(char *path)  static bool strip_trailing_slashes(char *path)
748  {  {
749   char *base = base_name(path);   char *base = base_name(path);
750   char *base_lim = base + base_len(base);   char *base_lim = base + base_len(base);
# Line 869  static void copyin_link(struct new_cpio_ Line 844  static void copyin_link(struct new_cpio_
844   tape_buffered_read(link_name, in_file_des, file_hdr->c_filesize);   tape_buffered_read(link_name, in_file_des, file_hdr->c_filesize);
845   tape_skip_padding(in_file_des, file_hdr->c_filesize);   tape_skip_padding(in_file_des, file_hdr->c_filesize);
846    
847   res = UMASKED_SYMLINK(link_name, file_hdr->c_name, file_hdr->c_mode);   res = symlink(link_name, file_hdr->c_name);
848   if (res < 0) {   if (res < 0) {
849   fprintf(stderr, "%s: UMASKED_SYMLINK %s: %s\n",   fprintf(stderr, "%s: symlink %s: %s\n",
850   progname, file_hdr->c_name, strerror(errno));   progname, file_hdr->c_name, strerror(errno));
851   free(link_name);   free(link_name);
852   return;   return;
# Line 903  static void copyin_file(struct new_cpio_ Line 878  static void copyin_file(struct new_cpio_
878    
879   case S_IFCHR:   case S_IFCHR:
880   case S_IFBLK:   case S_IFBLK:
 #ifdef S_IFSOCK  
881   case S_IFSOCK:   case S_IFSOCK:
 #endif  
 #ifdef S_IFIFO  
882   case S_IFIFO:   case S_IFIFO:
 #endif  
883   copyin_device(file_hdr);   copyin_device(file_hdr);
884   break;   break;
885    
 #ifdef S_IFLNK  
886   case S_IFLNK:   case S_IFLNK:
887   copyin_link(file_hdr, in_file_des);   copyin_link(file_hdr, in_file_des);
888   break;   break;
 #endif  
889    
890   default:   default:
891   fprintf(stderr, "%s: %s: unknown file type\n",   fprintf(stderr, "%s: %s: unknown file type\n",
# Line 930  static void copyin_file(struct new_cpio_ Line 899  static void copyin_file(struct new_cpio_
899     file descriptor IN_DES, except for the magic number, which is     file descriptor IN_DES, except for the magic number, which is
900     already filled in.  */     already filled in.  */
901    
902  void read_in_new_ascii(struct new_cpio_header *file_hdr, int in_des)  static void read_in_new_ascii(struct new_cpio_header *file_hdr, int in_des)
903  {  {
904   char ascii_header[112];   char ascii_header[13*8], *ah, hexbuf[9];
905     int i;
906    
907   tape_buffered_read(ascii_header, in_des, 104L);   tape_buffered_read(ascii_header, in_des, 13*8);
908   ascii_header[104] = '\0';   ah = ascii_header;
909   sscanf(ascii_header,   hexbuf[8] = '\0';
910         "%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx",   for (i = 0; i < 13; i++) {
911         &file_hdr->c_ino, &file_hdr->c_mode, &file_hdr->c_uid,   memcpy(hexbuf, ah, 8);
912         &file_hdr->c_gid, &file_hdr->c_nlink, &file_hdr->c_mtime,   file_hdr->c_hdr[i] = strtoul(hexbuf, NULL, 16);
913         &file_hdr->c_filesize, &file_hdr->c_dev_maj,   ah += 8;
914         &file_hdr->c_dev_min, &file_hdr->c_rdev_maj,   }
        &file_hdr->c_rdev_min, &file_hdr->c_namesize,  
        &file_hdr->c_chksum);  
915   /* Read file name from input.  */   /* Read file name from input.  */
916   if (file_hdr->c_name != NULL)   free(file_hdr->c_name);
  free(file_hdr->c_name);  
917   file_hdr->c_name = (char *)xmalloc(file_hdr->c_namesize);   file_hdr->c_name = (char *)xmalloc(file_hdr->c_namesize);
918   tape_buffered_read(file_hdr->c_name, in_des,   tape_buffered_read(file_hdr->c_name, in_des,
919     (long)file_hdr->c_namesize);     (long)file_hdr->c_namesize);
# Line 963  void read_in_new_ascii(struct new_cpio_h Line 930  void read_in_new_ascii(struct new_cpio_h
930  /* Read the header, including the name of the file, from file  /* Read the header, including the name of the file, from file
931     descriptor IN_DES into FILE_HDR.  */     descriptor IN_DES into FILE_HDR.  */
932    
933  void read_in_header(struct new_cpio_header *file_hdr, int in_des)  static void read_in_header(struct new_cpio_header *file_hdr, int in_des)
934  {  {
935   long bytes_skipped = 0; /* Bytes of junk found before magic number.  */   long bytes_skipped = 0; /* Bytes of junk found before magic number.  */
936    
# Line 991  void read_in_header(struct new_cpio_head Line 958  void read_in_header(struct new_cpio_head
958  /* Read the collection from standard input and create files  /* Read the collection from standard input and create files
959     in the file system.  */     in the file system.  */
960    
961  void process_copy_in()  static void process_copy_in(void)
962  {  {
963   char done = false; /* True if trailer reached.  */   char done = false; /* True if trailer reached.  */
964   struct new_cpio_header file_hdr; /* Output header information.  */   struct new_cpio_header file_hdr; /* Output header information.  */
# Line 1033  void process_copy_in() Line 1000  void process_copy_in()
1000     initialize all variables associated with the input and output     initialize all variables associated with the input and output
1001     buffers.  */     buffers.  */
1002    
1003  void initialize_buffers()  static void initialize_buffers(void)
1004  {  {
1005   int in_buf_size, out_buf_size;   int in_buf_size, out_buf_size;
1006    

Legend:
Removed from v.532  
changed lines
  Added in v.1297