home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / unix / unixports / tarsrc / tar1112 / c / create < prev    next >
Encoding:
Text File  |  1994-02-07  |  33.1 KB  |  1,457 lines

  1. /* Create a tar archive.
  2.    Copyright (C) 1985, 1992, 1993 Free Software Foundation
  3.  
  4. This file is part of GNU Tar.
  5.  
  6. GNU Tar is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU Tar is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Tar; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  * Create a tar archive.
  22.  *
  23.  * Written 25 Aug 1985 by John Gilmore, ihnp4!hoptoad!gnu.
  24.  */
  25.  
  26. #ifdef _AIX
  27.  #pragma alloca
  28. #endif
  29. #include <sys/types.h>
  30. #include <stdio.h>
  31. #include <errno.h>
  32. #ifndef STDC_HEADERS
  33. extern int errno;
  34. #endif
  35.  
  36. #ifdef BSD42
  37. #include <sys/file.h>
  38. #else
  39. #ifndef V7
  40. #include <fcntl.h>
  41. #endif
  42. #endif
  43.  
  44. #include "tar.h"
  45. #include "port.h"
  46.  
  47. #ifndef    __MSDOS__
  48. #include <pwd.h>
  49. #ifndef ARCH
  50. #include <grp.h>
  51. #endif
  52. #endif
  53.  
  54. #if defined (_POSIX_VERSION)
  55. #include <utime.h>
  56. #else
  57. struct utimbuf
  58. {
  59.   long actime;
  60.   long modtime;
  61. };
  62.  
  63. #endif
  64.  
  65. extern struct stat hstat;    /* Stat struct corresponding */
  66.  
  67. #ifndef __MSDOS__
  68. extern dev_t ar_dev;
  69. extern ino_t ar_ino;
  70. #endif
  71.  
  72. /* JF */
  73. extern struct name *gnu_list_name;
  74.  
  75. /*
  76.  * If there are no symbolic links, there is no lstat().  Use stat().
  77.  */
  78. #ifndef S_ISLNK
  79. #define lstat stat
  80. #endif
  81.  
  82. extern void print_header ();
  83.  
  84. union record *start_header ();
  85. void blank_name_list ();
  86. int check_exclude ();
  87. PTR ck_malloc ();
  88. PTR ck_realloc ();
  89. void clear_buffer ();
  90. void close_archive ();
  91. void collect_and_sort_names ();
  92. int confirm ();
  93. int deal_with_sparse ();
  94. void find_new_file_size ();
  95. void finish_header ();
  96. int finish_sparse_file ();
  97. void finduname ();
  98. void findgname ();
  99. int is_dot_or_dotdot ();
  100. void open_archive ();
  101. char *name_next ();
  102. void name_close ();
  103. void to_oct ();
  104. void dump_file ();
  105. void write_dir_file ();
  106. void write_eot ();
  107. void write_long ();
  108. int zero_record ();
  109.  
  110. /* This code moved from tar.h since create.c is the only file that cares
  111.    about 'struct link's.  This means that other files might not have to
  112.    include sys/types.h any more. */
  113.  
  114. struct link
  115.   {
  116.     struct link *next;
  117.     dev_t dev;
  118.     ino_t ino;
  119.     short linkcount;
  120.     char name[1];
  121.   };
  122.  
  123. struct link *linklist;        /* Points to first link in list */
  124.  
  125. static nolinks;            /* Gets set if we run out of RAM */
  126.  
  127. /*
  128.  * "Scratch" space to store the information about a sparse file before
  129.  * writing the info into the header or extended header
  130.  */
  131. /* struct sp_array     *sparsearray;*/
  132.  
  133. /* number of elts storable in the sparsearray */
  134. /*int     sparse_array_size = 10;*/
  135.  
  136. void
  137. create_archive ()
  138. {
  139.   register char *p;
  140.   char *name_from_list ();
  141.  
  142.   open_archive (0);        /* Open for writing */
  143.  
  144.   if (f_gnudump)
  145.     {
  146.       char *buf = ck_malloc (PATH_MAX);
  147.       char *q, *bufp;
  148.  
  149.       collect_and_sort_names ();
  150.  
  151.       while (p = name_from_list ())
  152.     dump_file (p, -1, 1);
  153.       /* if(!f_dironly) { */
  154.       blank_name_list ();
  155.       while (p = name_from_list ())
  156.     {
  157.       strcpy (buf, p);
  158.       if (p[strlen (p) - 1] != '/')
  159.         strcat (buf, "/");
  160.       bufp = buf + strlen (buf);
  161.       for (q = gnu_list_name->dir_contents; q && *q; q += strlen (q) + 1)
  162.         {
  163.           if (*q == 'Y')
  164.         {
  165.           strcpy (bufp, q + 1);
  166.           dump_file (buf, -1, 1);
  167.         }
  168.         }
  169.     }
  170.       /* } */
  171.       free (buf);
  172.     }
  173.   else
  174.     {
  175.       while (p = name_next (1))
  176.     dump_file (p, -1, 1);
  177.     }
  178.  
  179.   write_eot ();
  180.   close_archive ();
  181.   if (f_gnudump)
  182.     write_dir_file ();
  183.   name_close ();
  184. }
  185.  
  186. /*
  187.  * Dump a single file.  If it's a directory, recurse.
  188.  * Result is 1 for success, 0 for failure.
  189.  * Sets global "hstat" to stat() output for this file.
  190.  */
  191. void
  192. dump_file (p, curdev, toplevel)
  193.      char *p;            /* File name to dump */
  194.      int curdev;        /* Device our parent dir was on */
  195.      int toplevel;        /* Whether we are a toplevel call */
  196. {
  197.   union record *header;
  198.   char type;
  199.   extern char *save_name;    /* JF for multi-volume support */
  200.   extern long save_totsize;
  201.   extern long save_sizeleft;
  202.   union record *exhdr;
  203.   char save_linkflag;
  204.   extern time_t new_time;
  205.   int critical_error = 0;
  206.   struct utimbuf restore_times;
  207.   /*    int sparse_ind = 0;*/
  208.  
  209.  
  210.   if (f_confirm && !confirm ("add", p))
  211.     return;
  212.  
  213.   /*
  214.      * Use stat if following (rather than dumping) 4.2BSD's
  215.      * symbolic links.  Otherwise, use lstat (which, on non-4.2
  216.      * systems, is #define'd to stat anyway.
  217.      */
  218. #ifdef STX_HIDDEN        /* AIX */
  219.   if (0 != f_follow_links ?
  220.       statx (p, &hstat, STATSIZE, STX_HIDDEN) :
  221.       statx (p, &hstat, STATSIZE, STX_HIDDEN | STX_LINK))
  222. #else
  223.   if (0 != f_follow_links ? stat (p, &hstat) : lstat (p, &hstat))
  224. #endif
  225.     {
  226.     badperror:
  227.       msg_perror ("can't add file %s", p);
  228.     badfile:
  229.       if (!f_ignore_failed_read || critical_error)
  230.     errors++;
  231.       return;
  232.     }
  233.  
  234.   restore_times.actime = hstat.st_atime;
  235.   restore_times.modtime = hstat.st_mtime;
  236.  
  237. #ifdef S_ISHIDDEN
  238.   if (S_ISHIDDEN (hstat.st_mode))
  239.     {
  240.       char *new = (char *) alloca (strlen (p) + 2);
  241.       if (new)
  242.     {
  243.       strcpy (new, p);
  244.       strcat (new, "@");
  245.       p = new;
  246.     }
  247.     }
  248. #endif
  249.  
  250.   /* See if we only want new files, and check if this one is too old to
  251.        put in the archive. */
  252.   if (f_new_files
  253.       && !f_gnudump
  254.       && new_time > hstat.st_mtime
  255.       && !S_ISDIR (hstat.st_mode)
  256.       && (f_new_files > 1 || new_time > hstat.st_ctime))
  257.     {
  258.       if (curdev == -1)
  259.     {
  260.       msg ("%s: is unchanged; not dumped", p);
  261.     }
  262.       return;
  263.     }
  264.  
  265. #ifndef __MSDOS__
  266.   /* See if we are trying to dump the archive */
  267.   if (ar_dev && hstat.st_dev == ar_dev && hstat.st_ino == ar_ino)
  268.     {
  269.       msg ("%s is the archive; not dumped", p);
  270.       return;
  271.     }
  272. #endif
  273.   /*
  274.      * Check for multiple links.
  275.      *
  276.      * We maintain a list of all such files that we've written so
  277.      * far.  Any time we see another, we check the list and
  278.      * avoid dumping the data again if we've done it once already.
  279.      */
  280.   if (hstat.st_nlink > 1
  281.       && (S_ISREG (hstat.st_mode)
  282. #ifdef S_ISCTG
  283.       || S_ISCTG (hstat.st_mode)
  284. #endif
  285. #ifdef S_ISCHR
  286.       || S_ISCHR (hstat.st_mode)
  287. #endif
  288. #ifdef S_ISBLK
  289.       || S_ISBLK (hstat.st_mode)
  290. #endif
  291. #ifdef S_ISFIFO
  292.       || S_ISFIFO (hstat.st_mode)
  293. #endif
  294.       ))
  295.     {
  296.       register struct link *lp;
  297.  
  298.       /* First quick and dirty.  Hashing, etc later FIXME */
  299.       for (lp = linklist; lp; lp = lp->next)
  300.     {
  301.       if (lp->ino == hstat.st_ino &&
  302.           lp->dev == hstat.st_dev)
  303.         {
  304.           char *link_name = lp->name;
  305.  
  306.           /* We found a link. */
  307.           while (!f_absolute_paths && *link_name == '/')
  308.         {
  309.           static int link_warn = 0;
  310.  
  311.           if (!link_warn)
  312.             {
  313.               msg ("Removing leading / from absolute links");
  314.               link_warn++;
  315.             }
  316.           link_name++;
  317.         }
  318.           if (link_name - lp->name >= NAMSIZ)
  319.         write_long (link_name, LF_LONGLINK);
  320.           current_link_name = link_name;
  321.  
  322.           hstat.st_size = 0;
  323.           header = start_header (p, &hstat);
  324.           if (header == NULL)
  325.         {
  326.           critical_error = 1;
  327.           goto badfile;
  328.         }
  329.           strncpy (header->header.arch_linkname,
  330.                link_name, NAMSIZ);
  331.  
  332.           /* Force null truncated */
  333.           header->header.arch_linkname[NAMSIZ - 1] = 0;
  334.  
  335.           header->header.linkflag = LF_LINK;
  336.           finish_header (header);
  337.           /* FIXME: Maybe remove from list after all links found? */
  338.           if (f_remove_files)
  339.         {
  340.           if (unlink (p) == -1)
  341.             msg_perror ("cannot remove %s", p);
  342.         }
  343.           return;        /* We dumped it */
  344.         }
  345.     }
  346.  
  347.       /* Not found.  Add it to the list of possible links. */
  348.       lp = (struct link *) ck_malloc ((unsigned) (sizeof (struct link) + strlen (p)));
  349.       if (!lp)
  350.     {
  351.       if (!nolinks)
  352.         {
  353.           msg (
  354.           "no memory for links, they will be dumped as separate files");
  355.           nolinks++;
  356.         }
  357.     }
  358.       lp->ino = hstat.st_ino;
  359.       lp->dev = hstat.st_dev;
  360.       strcpy (lp->name, p);
  361.       lp->next = linklist;
  362.       linklist = lp;
  363.     }
  364.  
  365.   /*
  366.      * This is not a link to a previously dumped file, so dump it.
  367.      */
  368.   if (S_ISREG (hstat.st_mode)
  369. #ifdef S_ISCTG
  370.       || S_ISCTG (hstat.st_mode)
  371. #endif
  372.     )
  373.     {
  374.       int f;            /* File descriptor */
  375.       long bufsize, count;
  376.       long sizeleft;
  377.       register union record *start;
  378.       int header_moved;
  379.       char isextended = 0;
  380.       int upperbound;
  381.       /*        int    end_nulls = 0; */
  382.  
  383.       header_moved = 0;
  384.  
  385. #ifdef BSD42
  386.       if (f_sparse_files)
  387.     {
  388.       /*
  389.           * JK - This is the test for sparseness: whether the
  390.          * "size" of the file matches the number of blocks
  391.          * allocated for it.  If there is a smaller number
  392.          * of blocks that would be necessary to accommodate
  393.          * a file of this size, we have a sparse file, i.e.,
  394.          * at least one of those records in the file is just
  395.          * a useless hole.
  396.          */
  397. #ifdef hpux            /* Nice of HPUX to gratuitiously change it, huh?  - mib */
  398.       if (hstat.st_size - (hstat.st_blocks * 1024) > 1024)
  399. #else
  400.       if (hstat.st_size - (hstat.st_blocks * RECORDSIZE) > RECORDSIZE)
  401. #endif
  402.         {
  403.           int filesize = hstat.st_size;
  404.           register int i;
  405.  
  406.           header = start_header (p, &hstat);
  407.           if (header == NULL)
  408.         {
  409.           critical_error = 1;
  410.           goto badfile;
  411.         }
  412.           header->header.linkflag = LF_SPARSE;
  413.           header_moved++;
  414.  
  415.           /*
  416.              * Call the routine that figures out the
  417.              * layout of the sparse file in question.
  418.              * UPPERBOUND is the index of the last
  419.              * element of the "sparsearray," i.e.,
  420.              * the number of elements it needed to
  421.              * describe the file.
  422.              */
  423.  
  424.           upperbound = deal_with_sparse (p, header);
  425.  
  426.           /*
  427.              * See if we'll need an extended header
  428.              * later
  429.              */
  430.           if (upperbound > SPARSE_IN_HDR - 1)
  431.         header->header.isextended++;
  432.           /*
  433.              * We store the "real" file size so
  434.              * we can show that in case someone wants
  435.              * to list the archive, i.e., tar tvf <file>.
  436.              * It might be kind of disconcerting if the
  437.              * shrunken file size was the one that showed
  438.              * up.
  439.              */
  440.           to_oct ((long) hstat.st_size, 1 + 12,
  441.               header->header.realsize);
  442.  
  443.           /*
  444.              * This will be the new "size" of the
  445.              * file, i.e., the size of the file
  446.              * minus the records of holes that we're
  447.              * skipping over.
  448.              */
  449.  
  450.           find_new_file_size (&filesize, upperbound);
  451.           hstat.st_size = filesize;
  452.           to_oct ((long) filesize, 1 + 12,
  453.               header->header.size);
  454.           /*                to_oct((long) end_nulls, 1+12,
  455.                         header->header.ending_blanks);*/
  456.  
  457.           for (i = 0; i < SPARSE_IN_HDR; i++)
  458.         {
  459.           if (!sparsearray[i].numbytes)
  460.             break;
  461.           to_oct (sparsearray[i].offset, 1 + 12,
  462.               header->header.sp[i].offset);
  463.           to_oct (sparsearray[i].numbytes, 1 + 12,
  464.               header->header.sp[i].numbytes);
  465.         }
  466.  
  467.         }
  468.     }
  469. #else
  470.       upperbound = SPARSE_IN_HDR - 1;
  471. #endif
  472.  
  473.       sizeleft = hstat.st_size;
  474.       /* Don't bother opening empty, world readable files. */
  475.       if (sizeleft > 0 || 0444 != (0444 & hstat.st_mode))
  476.     {
  477.       f = open (p, O_RDONLY | O_BINARY);
  478.       if (f < 0)
  479.         goto badperror;
  480.     }
  481.       else
  482.     {
  483.       f = -1;
  484.     }
  485.  
  486.       /* If the file is sparse, we've already taken care of this */
  487.       if (!header_moved)
  488.     {
  489.       header = start_header (p, &hstat);
  490.       if (header == NULL)
  491.         {
  492.           if (f >= 0)
  493.         (void) close (f);
  494.           critical_error = 1;
  495.           goto badfile;
  496.         }
  497.     }
  498. #ifdef S_ISCTG
  499.       /* Mark contiguous files, if we support them */
  500.       if (f_standard && S_ISCTG (hstat.st_mode))
  501.     {
  502.       header->header.linkflag = LF_CONTIG;
  503.     }
  504. #endif
  505.       isextended = header->header.isextended;
  506.       save_linkflag = header->header.linkflag;
  507.       finish_header (header);
  508.       if (isextended)
  509.     {
  510.       /*            int     sum = 0;*/
  511.       register int i;
  512.       /*            register union record *exhdr;*/
  513.       /*            int     arraybound = SPARSE_EXT_HDR;*/
  514.       /* static */ int index_offset = SPARSE_IN_HDR;
  515.  
  516.     extend:exhdr = findrec ();
  517.  
  518.       if (exhdr == NULL)
  519.         {
  520.           critical_error = 1;
  521.           goto badfile;
  522.         }
  523.       bzero (exhdr->charptr, RECORDSIZE);
  524.       for (i = 0; i < SPARSE_EXT_HDR; i++)
  525.         {
  526.           if (i + index_offset > upperbound)
  527.         break;
  528.           to_oct ((long) sparsearray[i + index_offset].numbytes,
  529.               1 + 12,
  530.               exhdr->ext_hdr.sp[i].numbytes);
  531.           to_oct ((long) sparsearray[i + index_offset].offset,
  532.               1 + 12,
  533.               exhdr->ext_hdr.sp[i].offset);
  534.         }
  535.       userec (exhdr);
  536.       /*            sum += i;
  537.             if (sum < upperbound)
  538.                 goto extend;*/
  539.       if (index_offset + i <= upperbound)
  540.         {
  541.           index_offset += i;
  542.           exhdr->ext_hdr.isextended++;
  543.           goto extend;
  544.         }
  545.  
  546.     }
  547.       if (save_linkflag == LF_SPARSE)
  548.     {
  549.       if (finish_sparse_file (f, &sizeleft, hstat.st_size, p))
  550.         goto padit;
  551.     }
  552.       else
  553.     while (sizeleft > 0)
  554.       {
  555.  
  556.         if (f_multivol)
  557.           {
  558.         save_name = p;
  559.         save_sizeleft = sizeleft;
  560.         save_totsize = hstat.st_size;
  561.           }
  562.         start = findrec ();
  563.  
  564.         bufsize = endofrecs ()->charptr - start->charptr;
  565.  
  566.         if (sizeleft < bufsize)
  567.           {
  568.         /* Last read -- zero out area beyond */
  569.         bufsize = (int) sizeleft;
  570.         count = bufsize % RECORDSIZE;
  571.         if (count)
  572.           bzero (start->charptr + sizeleft,
  573.              (int) (RECORDSIZE - count));
  574.           }
  575.         count = read (f, start->charptr, bufsize);
  576.         if (count < 0)
  577.           {
  578.         msg_perror ("read error at byte %ld, reading\
  579.  %d bytes, in file %s", hstat.st_size - sizeleft, bufsize, p);
  580.         goto padit;
  581.           }
  582.         sizeleft -= count;
  583.  
  584.         /* This is nonportable (the type of userec's arg). */
  585.         userec (start + (count - 1) / RECORDSIZE);
  586.  
  587.         if (count == bufsize)
  588.           continue;
  589.         msg ("file %s shrunk by %d bytes, padding with zeros.", p, sizeleft);
  590.         goto padit;        /* Short read */
  591.       }
  592.  
  593.       if (f_multivol)
  594.     save_name = 0;
  595.  
  596.       if (f >= 0)
  597.     (void) close (f);
  598.  
  599.       if (f_remove_files)
  600.     {
  601.       if (unlink (p) == -1)
  602.         msg_perror ("cannot remove %s", p);
  603.     }
  604.       if (f_atime_preserve)
  605.     utime (p, &restore_times);
  606.       return;
  607.  
  608.       /*
  609.          * File shrunk or gave error, pad out tape to match
  610.          * the size we specified in the header.
  611.          */
  612.     padit:
  613.       while (sizeleft > 0)
  614.     {
  615.       save_sizeleft = sizeleft;
  616.       start = findrec ();
  617.       bzero (start->charptr, RECORDSIZE);
  618.       userec (start);
  619.       sizeleft -= RECORDSIZE;
  620.     }
  621.       if (f_multivol)
  622.     save_name = 0;
  623.       if (f >= 0)
  624.     (void) close (f);
  625.       if (f_atime_preserve)
  626.     utime (p, &restore_times);
  627.       return;
  628.     }
  629.  
  630. #ifdef S_ISLNK
  631.   else if (S_ISLNK (hstat.st_mode))
  632.     {
  633.       int size;
  634.       char *buf = alloca (PATH_MAX + 1);
  635.  
  636.       size = readlink (p, buf, PATH_MAX + 1);
  637.       if (size < 0)
  638.     goto badperror;
  639.       buf[size] = '\0';
  640.       if (size >= NAMSIZ)
  641.     write_long (buf, LF_LONGLINK);
  642.       current_link_name = buf;
  643.  
  644.       hstat.st_size = 0;    /* Force 0 size on symlink */
  645.       header = start_header (p, &hstat);
  646.       if (header == NULL)
  647.     {
  648.       critical_error = 1;
  649.       goto badfile;
  650.     }
  651.       strncpy (header->header.arch_linkname, buf, NAMSIZ);
  652.       header->header.arch_linkname[NAMSIZ - 1] = '\0';
  653.       header->header.linkflag = LF_SYMLINK;
  654.       finish_header (header);    /* Nothing more to do to it */
  655.       if (f_remove_files)
  656.     {
  657.       if (unlink (p) == -1)
  658.         msg_perror ("cannot remove %s", p);
  659.     }
  660.       return;
  661.     }
  662. #endif
  663.  
  664.   else if (S_ISDIR (hstat.st_mode))
  665.     {
  666.       register DIR *dirp;
  667.       register struct dirent *d;
  668.       char *namebuf;
  669.       int buflen;
  670.       register int len;
  671.       int our_device = hstat.st_dev;
  672.  
  673.       /* Build new prototype name */
  674.       len = strlen (p);
  675.       buflen = len + NAMSIZ;
  676.       namebuf = ck_malloc (buflen + 1);
  677.       strncpy (namebuf, p, buflen);
  678.       while (len >= 1 && '/' == namebuf[len - 1])
  679.     len--;            /* Delete trailing slashes */
  680.       namebuf[len++] = '/';    /* Now add exactly one back */
  681.       namebuf[len] = '\0';    /* Make sure null-terminated */
  682.  
  683.       /*
  684.          * Output directory header record with permissions
  685.          * FIXME, do this AFTER files, to avoid R/O dir problems?
  686.          * If old archive format, don't write record at all.
  687.          */
  688.       if (!f_oldarch)
  689.     {
  690.       hstat.st_size = 0;    /* Force 0 size on dir */
  691.       /*
  692.              * If people could really read standard archives,
  693.              * this should be:        (FIXME)
  694.             header = start_header(f_standard? p: namebuf, &hstat);
  695.              * but since they'd interpret LF_DIR records as
  696.              * regular files, we'd better put the / on the name.
  697.              */
  698.       header = start_header (namebuf, &hstat);
  699.       if (header == NULL)
  700.         {
  701.           critical_error = 1;
  702.           goto badfile;    /* eg name too long */
  703.         }
  704.  
  705.       if (f_gnudump)
  706.         header->header.linkflag = LF_DUMPDIR;
  707.       else if (f_standard)
  708.         header->header.linkflag = LF_DIR;
  709.  
  710.       /* If we're gnudumping, we aren't done yet so don't close it. */
  711.       if (!f_gnudump)
  712.         finish_header (header);    /* Done with directory header */
  713.     }
  714.  
  715.       if (f_gnudump)
  716.     {
  717.       int sizeleft;
  718.       int totsize;
  719.       int bufsize;
  720.       union record *start;
  721.       int count;
  722.       char *buf, *p_buf;
  723.  
  724.       buf = gnu_list_name->dir_contents;    /* FOO */
  725.       totsize = 0;
  726.       for (p_buf = buf; p_buf && *p_buf;)
  727.         {
  728.           int tmp;
  729.  
  730.           tmp = strlen (p_buf) + 1;
  731.           totsize += tmp;
  732.           p_buf += tmp;
  733.         }
  734.       totsize++;
  735.       to_oct ((long) totsize, 1 + 12, header->header.size);
  736.       finish_header (header);
  737.       p_buf = buf;
  738.       sizeleft = totsize;
  739.       while (sizeleft > 0)
  740.         {
  741.           if (f_multivol)
  742.         {
  743.           save_name = p;
  744.           save_sizeleft = sizeleft;
  745.           save_totsize = totsize;
  746.         }
  747.           start = findrec ();
  748.           bufsize = endofrecs ()->charptr - start->charptr;
  749.           if (sizeleft < bufsize)
  750.         {
  751.           bufsize = sizeleft;
  752.           count = bufsize % RECORDSIZE;
  753.           if (count)
  754.             bzero (start->charptr + sizeleft, RECORDSIZE - count);
  755.         }
  756.           bcopy (p_buf, start->charptr, bufsize);
  757.           sizeleft -= bufsize;
  758.           p_buf += bufsize;
  759.           userec (start + (bufsize - 1) / RECORDSIZE);
  760.         }
  761.       if (f_multivol)
  762.         save_name = 0;
  763.       if (f_atime_preserve)
  764.         utime (p, &restore_times);
  765.       return;
  766.     }
  767.  
  768.       /* Now output all the files in the directory */
  769. #if 0
  770.       if (f_dironly)
  771.     return;            /* Unless the cmdline said not to */
  772. #endif
  773.       /*
  774.          * See if we are crossing from one file system to another,
  775.          * and avoid doing so if the user only wants to dump one file system.
  776.          */
  777.       if (f_local_filesys && !toplevel && curdev != hstat.st_dev)
  778.     {
  779.       if (f_verbose)
  780.         msg ("%s: is on a different filesystem; not dumped", p);
  781.       return;
  782.     }
  783.  
  784.  
  785.       errno = 0;
  786.       dirp = opendir (p);
  787.       if (!dirp)
  788.     {
  789.       if (errno)
  790.         {
  791.           msg_perror ("can't open directory %s", p);
  792.         }
  793.       else
  794.         {
  795.           msg ("error opening directory %s",
  796.            p);
  797.         }
  798.       return;
  799.     }
  800.  
  801.       /* Hack to remove "./" from the front of all the file names */
  802.       if (len == 2 && namebuf[0] == '.' && namebuf[1] == '/')
  803.     len = 0;
  804.  
  805.       /* Should speed this up by cd-ing into the dir, FIXME */
  806.       while (NULL != (d = readdir (dirp)))
  807.     {
  808.       /* Skip . and .. */
  809.       if (is_dot_or_dotdot (d->d_name))
  810.         continue;
  811.  
  812.       if (NLENGTH (d) + len >= buflen)
  813.         {
  814.           buflen = len + NLENGTH (d);
  815.           namebuf = ck_realloc (namebuf, buflen + 1);
  816.           /* namebuf[len]='\0';
  817.                 msg("file name %s%s too long",
  818.                     namebuf, d->d_name);
  819.                 continue; */
  820.         }
  821.       strcpy (namebuf + len, d->d_name);
  822.       if (f_exclude && check_exclude (namebuf))
  823.         continue;
  824.       dump_file (namebuf, our_device, 0);
  825.     }
  826.  
  827.       closedir (dirp);
  828.       free (namebuf);
  829.       if (f_atime_preserve)
  830.     utime (p, &restore_times);
  831.       return;
  832.     }
  833.  
  834. #ifdef S_ISCHR
  835.   else if (S_ISCHR (hstat.st_mode))
  836.     {
  837.       type = LF_CHR;
  838.     }
  839. #endif
  840.  
  841. #ifdef S_ISBLK
  842.   else if (S_ISBLK (hstat.st_mode))
  843.     {
  844.       type = LF_BLK;
  845.     }
  846. #endif
  847.  
  848.   /* Avoid screwy apollo lossage where S_IFIFO == S_IFSOCK */
  849. #if (_ISP__M68K == 0) && (_ISP__A88K == 0) && defined(S_ISFIFO)
  850.   else if (S_ISFIFO (hstat.st_mode))
  851.     {
  852.       type = LF_FIFO;
  853.     }
  854. #endif
  855.  
  856. #ifdef S_ISSOCK
  857.   else if (S_ISSOCK (hstat.st_mode))
  858.     {
  859.       type = LF_FIFO;
  860.     }
  861. #endif
  862.   else
  863.     goto unknown;
  864.  
  865.   if (!f_standard)
  866.     goto unknown;
  867.  
  868.   hstat.st_size = 0;        /* Force 0 size */
  869.   header = start_header (p, &hstat);
  870.   if (header == NULL)
  871.     {
  872.       critical_error = 1;
  873.       goto badfile;        /* eg name too long */
  874.     }
  875.  
  876.   header->header.linkflag = type;
  877. #if defined(S_IFBLK) || defined(S_IFCHR)
  878.   if (type != LF_FIFO)
  879.     {
  880.       to_oct ((long) major (hstat.st_rdev), 8,
  881.           header->header.devmajor);
  882.       to_oct ((long) minor (hstat.st_rdev), 8,
  883.           header->header.devminor);
  884.     }
  885. #endif
  886.  
  887.   finish_header (header);
  888.   if (f_remove_files)
  889.     {
  890.       if (unlink (p) == -1)
  891.     msg_perror ("cannot remove %s", p);
  892.     }
  893.   return;
  894.  
  895. unknown:
  896.   msg ("%s: Unknown file type; file ignored.", p);
  897. }
  898.  
  899. int
  900. finish_sparse_file (fd, sizeleft, fullsize, name)
  901.      int fd;
  902.      long *sizeleft, fullsize;
  903.      char *name;
  904. {
  905.   union record *start;
  906.   char tempbuf[RECORDSIZE];
  907.   int bufsize, sparse_ind = 0, count;
  908.   long pos;
  909.   long nwritten = 0;
  910.  
  911.  
  912.   while (*sizeleft > 0)
  913.     {
  914.       start = findrec ();
  915.       bzero (start->charptr, RECORDSIZE);
  916.       bufsize = sparsearray[sparse_ind].numbytes;
  917.       if (!bufsize)
  918.     {            /* we blew it, maybe */
  919.       msg ("Wrote %ld of %ld bytes to file %s",
  920.            fullsize - *sizeleft, fullsize, name);
  921.       break;
  922.     }
  923.       pos = lseek (fd, sparsearray[sparse_ind++].offset, 0);
  924.       /*
  925.          * If the number of bytes to be written here exceeds
  926.          * the size of the temporary buffer, do it in steps.
  927.          */
  928.       while (bufsize > RECORDSIZE)
  929.     {
  930.       /*            if (amt_read) {
  931.                 count = read(fd, start->charptr+amt_read, RECORDSIZE-amt_read);
  932.                 bufsize -= RECORDSIZE - amt_read;
  933.                 amt_read = 0;
  934.                 userec(start);
  935.                 start = findrec();
  936.                 bzero(start->charptr, RECORDSIZE);
  937.             }*/
  938.       /* store the data */
  939.       count = read (fd, start->charptr, RECORDSIZE);
  940.       if (count < 0)
  941.         {
  942.           msg_perror ("read error at byte %ld, reading %d bytes, in file %s",
  943.               fullsize - *sizeleft, bufsize, name);
  944.           return 1;
  945.         }
  946.       bufsize -= count;
  947.       *sizeleft -= count;
  948.       userec (start);
  949.       nwritten += RECORDSIZE;    /* XXX */
  950.       start = findrec ();
  951.       bzero (start->charptr, RECORDSIZE);
  952.     }
  953.  
  954.  
  955.       clear_buffer (tempbuf);
  956.       count = read (fd, tempbuf, bufsize);
  957.       bcopy (tempbuf, start->charptr, RECORDSIZE);
  958.       if (count < 0)
  959.     {
  960.       msg_perror ("read error at byte %ld, reading %d bytes, in file %s",
  961.               fullsize - *sizeleft, bufsize, name);
  962.       return 1;
  963.     }
  964.       /*        if (amt_read >= RECORDSIZE) {
  965.             amt_read = 0;
  966.             userec(start+(count-1)/RECORDSIZE);
  967.             if (count != bufsize) {
  968.                 msg("file %s shrunk by %d bytes, padding with zeros.", name, sizeleft);
  969.                 return 1;
  970.             }
  971.             start = findrec();
  972.         } else
  973.             amt_read += bufsize;*/
  974.       nwritten += count;    /* XXX */
  975.       *sizeleft -= count;
  976.       userec (start);
  977.  
  978.     }
  979.   free (sparsearray);
  980.   /*    printf ("Amount actually written is (I hope) %d.\n", nwritten); */
  981.   /*    userec(start+(count-1)/RECORDSIZE);*/
  982.   return 0;
  983.  
  984. }
  985.  
  986. void
  987. init_sparsearray ()
  988. {
  989.   register int i;
  990.  
  991.   sp_array_size = 10;
  992.   /*
  993.      * Make room for our scratch space -- initially is 10 elts long
  994.      */
  995.   sparsearray = (struct sp_array *) ck_malloc (sp_array_size * sizeof (struct sp_array));
  996.   for (i = 0; i < sp_array_size; i++)
  997.     {
  998.       sparsearray[i].offset = 0;
  999.       sparsearray[i].numbytes = 0;
  1000.     }
  1001. }
  1002.  
  1003.  
  1004.  
  1005. /*
  1006.  * Okay, we've got a sparse file on our hands -- now, what we need to do is
  1007.  * make a pass through the file and carefully note where any data is, i.e.,
  1008.  * we want to find how far into the file each instance of data is, and how
  1009.  * many bytes are there.  We store this information in the sparsearray,
  1010.  * which will later be translated into header information.  For now, we use
  1011.  * the sparsearray as convenient storage.
  1012.  *
  1013.  * As a side note, this routine is a mess.  If I could have found a cleaner
  1014.  * way to do it, I would have.  If anyone wants to find a nicer way to do
  1015.  * this, feel free.
  1016.  */
  1017.  
  1018. /* There is little point in trimming small amounts of null data at the */
  1019. /* head and tail of blocks -- it's ok if we only avoid dumping blocks */
  1020. /* of complete null data */
  1021. int
  1022. deal_with_sparse (name, header, nulls_at_end)
  1023.      char *name;
  1024.      union record *header;
  1025.      int nulls_at_end;
  1026. {
  1027.   long numbytes = 0;
  1028.   long offset = 0;
  1029.   /*    long    save_offset;*/
  1030.   int fd;
  1031.   /*    int    current_size = hstat.st_size;*/
  1032.   int sparse_ind = 0, cc;
  1033.   char buf[RECORDSIZE];
  1034. #if 0
  1035.   int read_last_data = 0;    /* did we just read the last record? */
  1036. #endif
  1037.   int amidst_data = 0;
  1038.  
  1039.   header->header.isextended = 0;
  1040.   /*
  1041.      * Can't open the file -- this problem will be caught later on,
  1042.      * so just return.
  1043.      */
  1044.   if ((fd = open (name, O_RDONLY)) < 0)
  1045.     return 0;
  1046.  
  1047.   init_sparsearray ();
  1048.   clear_buffer (buf);
  1049.  
  1050.   while ((cc = read (fd, buf, sizeof buf)) != 0)
  1051.     {
  1052.  
  1053.       if (sparse_ind > sp_array_size - 1)
  1054.     {
  1055.  
  1056.       /*
  1057.          * realloc the scratch area, since we've run out of room --
  1058.          */
  1059.       sparsearray = (struct sp_array *)
  1060.         ck_realloc (sparsearray,
  1061.              2 * sp_array_size * (sizeof (struct sp_array)));
  1062.       sp_array_size *= 2;
  1063.     }
  1064.       if (cc == sizeof buf)
  1065.     {
  1066.       if (zero_record (buf))
  1067.         {
  1068.           if (amidst_data)
  1069.         {
  1070.           sparsearray[sparse_ind++].numbytes
  1071.             = numbytes;
  1072.           amidst_data = 0;
  1073.         }
  1074.         }
  1075.       else
  1076.         {            /* !zero_record(buf) */
  1077.           if (amidst_data)
  1078.         numbytes += cc;
  1079.           else
  1080.         {
  1081.           amidst_data = 1;
  1082.           numbytes = cc;
  1083.           sparsearray[sparse_ind].offset
  1084.             = offset;
  1085.         }
  1086.         }
  1087.     }
  1088.       else if (cc < sizeof buf)
  1089.     {
  1090.       /* This has to be the last bit of the file, so this */
  1091.       /* is somewhat shorter than the above. */
  1092.       if (!zero_record (buf))
  1093.         {
  1094.           if (!amidst_data)
  1095.         {
  1096.           amidst_data = 1;
  1097.           numbytes = cc;
  1098.           sparsearray[sparse_ind].offset
  1099.             = offset;
  1100.         }
  1101.           else
  1102.         numbytes += cc;
  1103.         }
  1104.     }
  1105.       offset += cc;
  1106.       clear_buffer (buf);
  1107.     }
  1108.   if (amidst_data)
  1109.     sparsearray[sparse_ind++].numbytes = numbytes;
  1110.   else
  1111.     {
  1112.       sparsearray[sparse_ind].offset = offset-1;
  1113.       sparsearray[sparse_ind++].numbytes = 1;
  1114.     }
  1115.   close (fd);
  1116.  
  1117.   return sparse_ind - 1;
  1118. }
  1119.  
  1120. /*
  1121.  * Just zeroes out the buffer so we don't confuse ourselves with leftover
  1122.  * data.
  1123.  */
  1124. void
  1125. clear_buffer (buf)
  1126.      char *buf;
  1127. {
  1128.   register int i;
  1129.  
  1130.   for (i = 0; i < RECORDSIZE; i++)
  1131.     buf[i] = '\0';
  1132. }
  1133.  
  1134. #if 0                /* I'm leaving this as a monument to Joy Kendall, who wrote it -mib */
  1135. /*
  1136.  * JK -
  1137.  * This routine takes a character array, and tells where within that array
  1138.  * the data can be found.  It skips over any zeros, and sets the first
  1139.  * non-zero point in the array to be the "start", and continues until it
  1140.  * finds non-data again, which is marked as the "end."  This routine is
  1141.  * mainly for 1) seeing how far into a file we must lseek to data, given
  1142.  * that we have a sparse file, and 2) determining the "real size" of the
  1143.  * file, i.e., the number of bytes in the sparse file that are data, as
  1144.  * opposed to the zeros we are trying to skip.
  1145.  */
  1146. where_is_data (from, to, buffer)
  1147.      int *from, *to;
  1148.      char *buffer;
  1149. {
  1150.   register int i = 0;
  1151.   register int save_to = *to;
  1152.   int amidst_data = 0;
  1153.  
  1154.  
  1155.   while (!buffer[i])
  1156.     i++;
  1157.   *from = i;
  1158.  
  1159.   if (*from < 16)        /* don't bother */
  1160.     *from = 0;
  1161.   /* keep going to make sure there isn't more real
  1162.        data in this record */
  1163.   while (i < RECORDSIZE)
  1164.     {
  1165.       if (!buffer[i])
  1166.     {
  1167.       if (amidst_data)
  1168.         {
  1169.           save_to = i;
  1170.           amidst_data = 0;
  1171.         }
  1172.       i++;
  1173.     }
  1174.       else if (buffer[i])
  1175.     {
  1176.       if (!amidst_data)
  1177.         amidst_data = 1;
  1178.       i++;
  1179.     }
  1180.     }
  1181.   if (i == RECORDSIZE)
  1182.     *to = i;
  1183.   else
  1184.     *to = save_to;
  1185.  
  1186. }
  1187.  
  1188. #endif
  1189.  
  1190. /* Note that this routine is only called if zero_record returned true */
  1191. #if 0                /* But we actually don't need it at all. */
  1192. where_is_data (from, to, buffer)
  1193.      int *from, *to;
  1194.      char *buffer;
  1195. {
  1196.   char *fp, *tp;
  1197.  
  1198.   for (fp = buffer; !*fp; fp++)
  1199.     ;
  1200.   for (tp = buffer + RECORDSIZE - 1; !*tp; tp--)
  1201.     ;
  1202.   *from = fp - buffer;
  1203.   *to = tp - buffer + 1;
  1204. }
  1205.  
  1206. #endif
  1207.  
  1208.  
  1209.  
  1210. /*
  1211.  * Takes a recordful of data and basically cruises through it to see if
  1212.  * it's made *entirely* of zeros, returning a 0 the instant it finds
  1213.  * something that is a non-zero, i.e., useful data.
  1214.  */
  1215. int
  1216. zero_record (buffer)
  1217.      char *buffer;
  1218. {
  1219.   register int i;
  1220.  
  1221.   for (i = 0; i < RECORDSIZE; i++)
  1222.     if (buffer[i] != '\000')
  1223.       return 0;
  1224.   return 1;
  1225. }
  1226.  
  1227. void
  1228. find_new_file_size (filesize, highest_index)
  1229.      int *filesize;
  1230.      int highest_index;
  1231. {
  1232.   register int i;
  1233.  
  1234.   *filesize = 0;
  1235.   for (i = 0; sparsearray[i].numbytes && i <= highest_index; i++)
  1236.     *filesize += sparsearray[i].numbytes;
  1237. }
  1238.  
  1239. /*
  1240.  * Make a header block for the file  name  whose stat info is  st .
  1241.  * Return header pointer for success, NULL if the name is too long.
  1242.  */
  1243. union record *
  1244. start_header (name, st)
  1245.      char *name;
  1246.      register struct stat *st;
  1247. {
  1248.   register union record *header;
  1249.  
  1250.   if (strlen (name) >= NAMSIZ)
  1251.     write_long (name, LF_LONGNAME);
  1252.  
  1253.   header = (union record *) findrec ();
  1254.   bzero (header->charptr, sizeof (*header));    /* XXX speed up */
  1255.  
  1256.   /*
  1257.      * Check the file name and put it in the record.
  1258.      */
  1259.   if (!f_absolute_paths)
  1260.     {
  1261.       static int warned_once = 0;
  1262. #ifdef __MSDOS__
  1263.       if (name[1] == ':')
  1264.     {
  1265.       name += 2;
  1266.       if (!warned_once++)
  1267.         msg ("Removing drive spec from names in the archive");
  1268.     }
  1269. #endif
  1270.       while ('/' == *name)
  1271.     {
  1272.       name++;        /* Force relative path */
  1273.       if (!warned_once++)
  1274.         msg ("Removing leading / from absolute path names in the archive.");
  1275.     }
  1276.     }
  1277.   current_file_name = name;
  1278.   strncpy (header->header.arch_name, name, NAMSIZ);
  1279.   header->header.arch_name[NAMSIZ - 1] = '\0';
  1280.  
  1281.   to_oct ((long) (f_oldarch ? (st->st_mode & 07777) : st->st_mode),
  1282.       8, header->header.mode);
  1283.   to_oct ((long) st->st_uid, 8, header->header.uid);
  1284.   to_oct ((long) st->st_gid, 8, header->header.gid);
  1285.   to_oct ((long) st->st_size, 1 + 12, header->header.size);
  1286.   to_oct ((long) st->st_mtime, 1 + 12, header->header.mtime);
  1287.   /* header->header.linkflag is left as null */
  1288.   if (f_gnudump)
  1289.     {
  1290.       to_oct ((long) st->st_atime, 1 + 12, header->header.atime);
  1291.       to_oct ((long) st->st_ctime, 1 + 12, header->header.ctime);
  1292.     }
  1293.  
  1294. #ifndef NONAMES
  1295.   /* Fill in new Unix Standard fields if desired. */
  1296.   if (f_standard)
  1297.     {
  1298.       header->header.linkflag = LF_NORMAL;    /* New default */
  1299.       strcpy (header->header.magic, TMAGIC);    /* Mark as Unix Std */
  1300.       finduname (header->header.uname, st->st_uid);
  1301.       findgname (header->header.gname, st->st_gid);
  1302.     }
  1303. #endif
  1304.   return header;
  1305. }
  1306.  
  1307. /*
  1308.  * Finish off a filled-in header block and write it out.
  1309.  * We also print the file name and/or full info if verbose is on.
  1310.  */
  1311. void
  1312. finish_header (header)
  1313.      register union record *header;
  1314. {
  1315.   register int i, sum;
  1316.   register char *p;
  1317.  
  1318.   bcopy (CHKBLANKS, header->header.chksum, sizeof (header->header.chksum));
  1319.  
  1320.   sum = 0;
  1321.   p = header->charptr;
  1322.   for (i = sizeof (*header); --i >= 0;)
  1323.     {
  1324.       /*
  1325.          * We can't use unsigned char here because of old compilers,
  1326.          * e.g. V7.
  1327.          */
  1328.       sum += 0xFF & *p++;
  1329.     }
  1330.  
  1331.   /*
  1332.      * Fill in the checksum field.  It's formatted differently
  1333.      * from the other fields:  it has [6] digits, a null, then a
  1334.      * space -- rather than digits, a space, then a null.
  1335.      * We use to_oct then write the null in over to_oct's space.
  1336.      * The final space is already there, from checksumming, and
  1337.      * to_oct doesn't modify it.
  1338.      *
  1339.      * This is a fast way to do:
  1340.      * (void) sprintf(header->header.chksum, "%6o", sum);
  1341.      */
  1342.   to_oct ((long) sum, 8, header->header.chksum);
  1343.   header->header.chksum[6] = '\0';    /* Zap the space */
  1344.  
  1345.   userec (header);
  1346.  
  1347.   if (f_verbose)
  1348.     {
  1349.       extern union record *head;/* Points to current tape header */
  1350.       extern int head_standard;    /* Tape header is in ANSI format */
  1351.  
  1352.       /* These globals are parameters to print_header, sigh */
  1353.       head = header;
  1354.       /* hstat is already set up */
  1355.       head_standard = f_standard;
  1356.       print_header ();
  1357.     }
  1358.  
  1359.   return;
  1360. }
  1361.  
  1362.  
  1363. /*
  1364.  * Quick and dirty octal conversion.
  1365.  * Converts long "value" into a "digs"-digit field at "where",
  1366.  * including a trailing space and room for a null.  "digs"==3 means
  1367.  * 1 digit, a space, and room for a null.
  1368.  *
  1369.  * We assume the trailing null is already there and don't fill it in.
  1370.  * This fact is used by start_header and finish_header, so don't change it!
  1371.  *
  1372.  * This should be equivalent to:
  1373.  *    (void) sprintf(where, "%*lo ", digs-2, value);
  1374.  * except that sprintf fills in the trailing null and we don't.
  1375.  */
  1376. void
  1377. to_oct (value, digs, where)
  1378.      register long value;
  1379.      register int digs;
  1380.      register char *where;
  1381. {
  1382.  
  1383.   --digs;            /* Trailing null slot is left alone */
  1384.   where[--digs] = ' ';        /* Put in the space, though */
  1385.  
  1386.   /* Produce the digits -- at least one */
  1387.   do
  1388.     {
  1389.       where[--digs] = '0' + (char) (value & 7);    /* one octal digit */
  1390.       value >>= 3;
  1391.     }
  1392.   while (digs > 0 && value != 0);
  1393.  
  1394.   /* Leading spaces, if necessary */
  1395.   while (digs > 0)
  1396.     where[--digs] = ' ';
  1397.  
  1398. }
  1399.  
  1400.  
  1401. /*
  1402.  * Write the EOT record(s).
  1403.  * We actually zero at least one record, through the end of the block.
  1404.  * Old tar writes garbage after two zeroed records -- and PDtar used to.
  1405.  */
  1406. void
  1407. write_eot ()
  1408. {
  1409.   union record *p;
  1410.   int bufsize;
  1411.  
  1412.   p = findrec ();
  1413.   if (p)
  1414.     {
  1415.       bufsize = endofrecs ()->charptr - p->charptr;
  1416.       bzero (p->charptr, bufsize);
  1417.       userec (p);
  1418.     }
  1419. }
  1420.  
  1421. /* Write a LF_LONGLINK or LF_LONGNAME record. */
  1422. void
  1423. write_long (p, type)
  1424.      char *p;
  1425.      char type;
  1426. {
  1427.   int size = strlen (p) + 1;
  1428.   int bufsize;
  1429.   union record *header;
  1430.   struct stat foo;
  1431.  
  1432.  
  1433.   bzero (&foo, sizeof foo);
  1434.   foo.st_size = size;
  1435.  
  1436.   header = start_header ("././@LongLink", &foo);
  1437.   header->header.linkflag = type;
  1438.   finish_header (header);
  1439.  
  1440.   header = findrec ();
  1441.  
  1442.   bufsize = endofrecs ()->charptr - header->charptr;
  1443.  
  1444.   while (bufsize < size)
  1445.     {
  1446.       bcopy (p, header->charptr, bufsize);
  1447.       p += bufsize;
  1448.       size -= bufsize;
  1449.       userec (header + (bufsize - 1) / RECORDSIZE);
  1450.       header = findrec ();
  1451.       bufsize = endofrecs ()->charptr - header->charptr;
  1452.     }
  1453.   bcopy (p, header->charptr, size);
  1454.   bzero (header->charptr + size, bufsize - size);
  1455.   userec (header + (size - 1) / RECORDSIZE);
  1456. }
  1457.