]> Dogcows Code - chaz/tar/commitdiff
*** empty log message ***
authorFrançois Pinard <pinard@iro.umontreal.ca>
Wed, 16 Nov 1994 02:45:29 +0000 (02:45 +0000)
committerFrançois Pinard <pinard@iro.umontreal.ca>
Wed, 16 Nov 1994 02:45:29 +0000 (02:45 +0000)
src/extract.c [new file with mode: 0644]
src/rmt.c
src/rmt.h

diff --git a/src/extract.c b/src/extract.c
new file mode 100644 (file)
index 0000000..a4f8ca9
--- /dev/null
@@ -0,0 +1,747 @@
+/* Extract files from a tar archive.
+   Copyright (C) 1988 Free Software Foundation
+
+This file is part of GNU Tar.
+
+GNU Tar 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.
+
+GNU Tar 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 GNU Tar; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+ * Extract files from a tar archive.
+ *
+ * Written 19 Nov 1985 by John Gilmore, ihnp4!hoptoad!gnu.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#ifndef STDC_HEADERS
+extern int errno;
+#endif
+#include <sys/types.h>
+#include <time.h>
+time_t time();
+
+#ifdef BSD42
+#include <sys/file.h>
+#else
+#ifndef V7
+#include <fcntl.h>
+#endif
+#endif
+
+#ifdef NO_OPEN3
+/* We need the #define's even though we don't use them. */
+#include "open3.h"
+#endif
+
+#ifdef EMUL_OPEN3
+/* Simulated 3-argument open for systems that don't have it */
+#include "open3.h"
+#endif
+
+#include "tar.h"
+#include "port.h"
+
+#if defined(_POSIX_VERSION)
+#include <utime.h>
+#endif
+
+extern FILE *msg_file;
+
+extern union record *head;             /* Points to current tape header */
+extern struct stat hstat;              /* Stat struct corresponding */
+extern int head_standard;              /* Tape header is in ANSI format */
+
+extern char *save_name;
+extern long save_totsize;
+extern long save_sizeleft;
+
+int confirm();
+void decode_header();
+void extract_mangle();
+void extract_sparse_file();
+long from_oct();
+void gnu_restore();
+extern void print_header();
+extern void skip_file();
+extern void skip_extended_headers();
+extern void pr_mkdir();
+void saverec();
+
+int make_dirs();                       /* Makes required directories */
+
+static time_t now = 0;                 /* Current time */
+static we_are_root = 0;                        /* True if our effective uid == 0 */
+static int notumask = ~0;              /* Masks out bits user doesn't want */
+
+/*
+ * "Scratch" space to store the information about a sparse file before
+ * writing the info into the header or extended header
+ */
+/*struct sp_array      *sparsearray;*/
+
+/* number of elts storable in the sparsearray */
+/*int  sp_array_size = 10;*/
+
+/*
+ * Set up to extract files.
+ */
+void
+extr_init()
+{
+       int ourmask;
+
+       now = time((time_t *)0);
+       if (geteuid() == 0)
+               we_are_root = 1;
+
+       /*
+        * We need to know our umask.  But if f_use_protection is set,
+        * leave our kernel umask at 0, and our "notumask" at ~0.
+        */
+       ourmask = umask(0);             /* Read it */
+       if (!f_use_protection) {
+               (void) umask (ourmask); /* Set it back how it was */
+               notumask = ~ourmask;    /* Make umask override permissions */
+       }
+}
+
+
+/*
+ * Extract a file from the archive.
+ */
+void
+extract_archive()
+{
+       register char *data;
+       int fd, check, namelen, written, openflag;
+       long size;
+       time_t acc_upd_times[2];
+       register int skipcrud;
+       register int i;
+/*     int sparse_ind = 0;*/
+       union record *exhdr;    
+/*     int end_nulls; */
+       
+       saverec(&head);                 /* Make sure it sticks around */
+       userec(head);                   /* And go past it in the archive */
+       decode_header(head, &hstat, &head_standard, 1); /* Snarf fields */
+
+       if(f_confirm && !confirm("extract",head->header.name)) {
+               if (head->header.isextended)
+                       skip_extended_headers();
+               skip_file((long)hstat.st_size);
+               saverec((union record **)0);
+               return;
+       }
+
+       /* Print the record from 'head' and 'hstat' */
+       if (f_verbose)
+               print_header();
+
+       /*
+        * Check for fully specified pathnames and other atrocities.
+        *
+        * Note, we can't just make a pointer to the new file name,
+        * since saverec() might move the header and adjust "head".
+        * We have to start from "head" every time we want to touch
+        * the header record.
+        */
+       skipcrud = 0;
+       while (!f_absolute_paths && '/' == head->header.name[skipcrud]) {
+               static int warned_once = 0;
+
+               skipcrud++;     /* Force relative path */
+               if (!warned_once++) {
+                       msg("Removing leading / from absolute path names in the archive.");
+               }
+       }
+
+       switch (head->header.linkflag) {
+
+       default:
+               msg("Unknown file type '%c' for %s, extracted as normal file",
+                       head->header.linkflag, skipcrud+head->header.name);
+               /* FALL THRU */
+
+       /* 
+        * JK - What we want to do if the file is sparse is loop through
+        * the array of sparse structures in the header and read in
+        * and translate the character strings representing  1) the offset
+        * at which to write and 2) how many bytes to write into numbers,
+        * which we store into the scratch array, "sparsearray".  This
+        * array makes our life easier the same way it did in creating
+        * the tar file that had to deal with a sparse file.
+        *
+        * After we read in the first five (at most) sparse structures,
+        * we check to see if the file has an extended header, i.e., 
+        * if more sparse structures are needed to describe the contents
+        * of the new file.  If so, we read in the extended headers
+        * and continue to store their contents into the sparsearray.
+        */
+       case LF_SPARSE:
+               sp_array_size = 10;
+               sparsearray = (struct sp_array *) malloc(sp_array_size * sizeof(struct sp_array));
+               for (i = 0; i < SPARSE_IN_HDR; i++) {
+                       sparsearray[i].offset = 
+                               from_oct(1+12, head->header.sp[i].offset);
+                       sparsearray[i].numbytes = 
+                               from_oct(1+12, head->header.sp[i].numbytes);
+                       if (!sparsearray[i].numbytes)
+                               break;
+               }
+               
+/*             end_nulls = from_oct(1+12, head->header.ending_blanks);*/
+               
+               if (head->header.isextended) {
+                       /* read in the list of extended headers
+                          and translate them into the sparsearray 
+                          as before */
+
+                       /* static */ int ind = SPARSE_IN_HDR;
+                       
+                       for (;;) {
+                               
+                               exhdr = findrec();
+                               for (i = 0; i < SPARSE_EXT_HDR; i++) {
+                                       
+                                       if (i+ind > sp_array_size-1) {
+                                       /*
+                                        * realloc the scratch area
+                                        * since we've run out of room --
+                                        */
+                                               sparsearray = (struct sp_array *) 
+                                                               realloc(sparsearray,
+                                                               2 * sp_array_size * (sizeof(struct sp_array)));
+                                               sp_array_size *= 2;
+                                       }
+                                       if (!exhdr->ext_hdr.sp[i].numbytes)
+                                               break;
+                                       sparsearray[i+ind].offset = 
+                                               from_oct(1+12, exhdr->ext_hdr.sp[i].offset);
+                                       sparsearray[i+ind].numbytes = 
+                                               from_oct(1+12, exhdr->ext_hdr.sp[i].numbytes);
+                               }
+                               if (!exhdr->ext_hdr.isextended) 
+                                       break;
+                               else {
+                                       ind += SPARSE_EXT_HDR;
+                                       userec(exhdr);
+                               }
+                       }
+                       userec(exhdr);
+               }
+               
+               /* FALL THRU */
+       case LF_OLDNORMAL:
+       case LF_NORMAL:
+       case LF_CONTIG:
+               /*
+                * Appears to be a file.
+                * See if it's really a directory.
+                */
+               namelen = strlen(skipcrud+head->header.name)-1;
+               if (head->header.name[skipcrud+namelen] == '/')
+                       goto really_dir;
+
+               /* FIXME, deal with protection issues */
+       again_file:
+               openflag = (f_keep?
+                       O_BINARY|O_NDELAY|O_WRONLY|O_CREAT|O_EXCL:
+                       O_BINARY|O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC)
+                       | ((head->header.linkflag == LF_SPARSE) ? 0 : O_APPEND);                        
+                       /*
+                        * JK - The last | is a kludge to solve the problem
+                        * the O_APPEND flag  causes with files we are
+                        * trying to make sparse:  when a file is opened
+                        * with O_APPEND, it writes  to the last place
+                        * that something was written, thereby ignoring
+                        * any lseeks that we have done.  We add this
+                        * extra condition to make it able to lseek when
+                        * a file is sparse, i.e., we don't open the new
+                        * file with this flag.  (Grump -- this bug caused
+                        * me to waste a good deal of time, I might add)
+                        */
+
+               if(f_exstdout) {
+                       fd = 1;
+                       goto extract_file;
+               }
+#ifdef O_CTG
+               /*
+                * Contiguous files (on the Masscomp) have to specify
+                * the size in the open call that creates them.
+                */
+               if (head->header.linkflag == LF_CONTIG)
+                       fd = open(skipcrud+head->header.name, openflag | O_CTG,
+                               hstat.st_mode, hstat.st_size);
+               else
+#endif
+               {
+#ifdef NO_OPEN3
+                       /*
+                        * On raw V7 we won't let them specify -k (f_keep), but
+                        * we just bull ahead and create the files.
+                        */
+                       fd = creat(skipcrud+head->header.name, 
+                               hstat.st_mode);
+#else
+                       /*
+                        * With 3-arg open(), we can do this up right.
+                        */
+                       fd = open(skipcrud+head->header.name, openflag,
+                               hstat.st_mode);
+#endif
+               }
+
+               if (fd < 0) {
+                       if (make_dirs(skipcrud+head->header.name))
+                               goto again_file;
+                       msg_perror("Could not create file %s",skipcrud+head->header.name);
+                       if (head->header.isextended)
+                               skip_extended_headers();
+                       skip_file((long)hstat.st_size);
+                       goto quit;
+               }
+
+       extract_file:
+               if (head->header.linkflag == LF_SPARSE) {
+                       char    *name;
+                       int     namelen;
+
+                       /*
+                        * Kludge alert.  NAME is assigned to header.name
+                        * because during the extraction, the space that
+                        * contains the header will get scribbled on, and
+                        * the name will get munged, so any error messages
+                        * that happen to contain the filename will look
+                        * REAL interesting unless we do this.
+                        */
+                       namelen = strlen(skipcrud+head->header.name);
+                       name = (char *) malloc((sizeof(char)) * namelen);
+                       bcopy(skipcrud+head->header.name, name, namelen);
+                       size = hstat.st_size;
+                       extract_sparse_file(fd, &size, hstat.st_size,
+                                               name);
+               }                       
+               else            
+                 for (size = hstat.st_size;
+                      size > 0;
+                      size -= written) {
+
+/*                     long    offset,
+                               numbytes;*/
+
+                       if(f_multivol) {
+                               save_name=head->header.name;
+                               save_totsize=hstat.st_size;
+                               save_sizeleft=size;
+                       }
+                       
+                       /*
+                        * Locate data, determine max length
+                        * writeable, write it, record that
+                        * we have used the data, then check
+                        * if the write worked.
+                        */
+                       data = findrec()->charptr;
+                       if (data == NULL) {     /* Check it... */
+                               msg("Unexpected EOF on archive file");
+                               break;
+                       }
+                       /*
+                        * JK - If the file is sparse, use the sparsearray
+                        * that we created before to lseek into the new
+                        * file the proper amount, and to see how many
+                        * bytes we want to write at that position.
+                        */
+/*                     if (head->header.linkflag == LF_SPARSE) {
+                               off_t pos;
+                               
+                               pos = lseek(fd, (off_t) sparsearray[sparse_ind].offset, 0);
+                               printf("%d at %d\n", (int) pos, sparse_ind);
+                               written = sparsearray[sparse_ind++].numbytes;
+                       } else*/
+                       written = endofrecs()->charptr - data;
+                       if (written > size)
+                               written = size;
+                       errno = 0;
+                       check = write(fd, data, written);
+                       /*
+                        * The following is in violation of strict
+                        * typing, since the arg to userec
+                        * should be a struct rec *.  FIXME.
+                        */
+                       userec((union record *)(data + written - 1));
+                       if (check == written) continue;
+                       /*
+                        * Error in writing to file.
+                        * Print it, skip to next file in archive.
+                        */
+                       if(check<0)
+                               msg_perror("couldn't write to file %s",skipcrud+head->header.name);
+                       else
+                               msg("could only write %d of %d bytes to file %s",written,check,skipcrud+head->header.name);
+                       skip_file((long)(size - written));
+                       break;  /* Still do the close, mod time, chmod, etc */
+               }
+
+               if(f_multivol)
+                       save_name = 0;
+
+                       /* If writing to stdout, don't try to do anything
+                          to the filename; it doesn't exist, or we don't
+                          want to touch it anyway */
+               if(f_exstdout)
+                       break;
+                       
+/*             if (head->header.isextended) {
+                       register union record *exhdr;
+                       register int i;
+                       
+                       for (i = 0; i < 21; i++) {
+                               long offset;
+                               
+                               if (!exhdr->ext_hdr.sp[i].numbytes)
+                                       break;
+                               offset = from_oct(1+12,
+                                               exhdr->ext_hdr.sp[i].offset);
+                               written = from_oct(1+12,
+                                               exhdr->ext_hdr.sp[i].numbytes);
+                               lseek(fd, offset, 0);
+                               check = write(fd, data, written);
+                               if (check == written) continue;
+
+                       }
+                       
+
+               }*/
+               check = close(fd);
+               if (check < 0) {
+                       msg_perror("Error while closing %s",skipcrud+head->header.name);
+               }
+
+               
+       set_filestat:
+
+               /*
+                * If we are root, set the owner and group of the extracted
+                * file.  This does what is wanted both on real Unix and on
+                * System V.  If we are running as a user, we extract as that
+                * user; if running as root, we extract as the original owner.
+                */
+               if (we_are_root || f_do_chown) {
+                       if (chown(skipcrud+head->header.name, hstat.st_uid,
+                                 hstat.st_gid) < 0) {
+                               msg_perror("cannot chown file %s to uid %d gid %d",skipcrud+head->header.name,hstat.st_uid,hstat.st_gid);
+                       }
+               }
+
+               /*
+                * Set the modified time of the file.
+                * 
+                * Note that we set the accessed time to "now", which
+                * is really "the time we started extracting files".
+                * unless f_gnudump is used, in which case .st_atime is used
+                */
+               if (!f_modified) {
+                       /* fixme if f_gnudump should set ctime too, but how? */
+                       if(f_gnudump)
+                               acc_upd_times[0]=hstat.st_atime;
+                       else acc_upd_times[0] = now;             /* Accessed now */
+                       acc_upd_times[1] = hstat.st_mtime; /* Mod'd */
+                       if (utime(skipcrud+head->header.name,
+                           acc_upd_times) < 0) {
+                               msg_perror("couldn't change access and modification times of %s",skipcrud+head->header.name);
+                       }
+               }
+               /* We do the utime before the chmod because some versions of
+                  utime are broken and trash the modes of the file.  Since
+                  we then change the mode anyway, we don't care. . . */
+
+               /*
+                * If '-k' is not set, open() or creat() could have saved
+                * the permission bits from a previously created file,
+                * ignoring the ones we specified.
+                * Even if -k is set, if the file has abnormal
+                * mode bits, we must chmod since writing or chown() has
+                * probably reset them.
+                *
+                * If -k is set, we know *we* created this file, so the mode
+                * bits were set by our open().   If the file is "normal", we
+                * skip the chmod.  This works because we did umask(0) if -p
+                * is set, so umask will have left the specified mode alone.
+                */
+               if ((!f_keep)
+                   || (hstat.st_mode & (S_ISUID|S_ISGID|S_ISVTX))) {
+                       if (chmod(skipcrud+head->header.name,
+                                 notumask & (int)hstat.st_mode) < 0) {
+                               msg_perror("cannot change mode of file %s to %ld",skipcrud+head->header.name,notumask & (int)hstat.st_mode);
+                       }
+               }
+
+       quit:
+               break;
+
+       case LF_LINK:
+       again_link:
+       {
+               struct stat st1,st2;
+
+               check = link (head->header.linkname,
+                             skipcrud+head->header.name);
+               if (check == 0)
+                       break;
+               if (make_dirs(skipcrud+head->header.name))
+                       goto again_link;
+               if(f_gnudump && errno==EEXIST)
+                       break;
+               if(   stat(head->header.linkname, &st1) == 0
+                  && stat(skipcrud+head->header.name, &st2)==0
+                  && st1.st_dev==st2.st_dev
+                  && st1.st_ino==st2.st_ino)
+                       break;
+               msg_perror("Could not link %s to %s",
+                       skipcrud+head->header.name,head->header.linkname);
+       }
+               break;
+
+#ifdef S_ISLNK
+       case LF_SYMLINK:
+       again_symlink:
+               check = symlink(head->header.linkname,
+                               skipcrud+head->header.name);
+               /* FIXME, don't worry uid, gid, etc... */
+               if (check == 0)
+                       break;
+               if (make_dirs(skipcrud+head->header.name))
+                       goto again_symlink;
+               msg_perror("Could not create symlink to %s",head->header.linkname);
+               break;
+#endif
+
+#ifdef S_IFCHR
+       case LF_CHR:
+               hstat.st_mode |= S_IFCHR;
+               goto make_node;
+#endif
+
+#ifdef S_IFBLK
+       case LF_BLK:
+               hstat.st_mode |= S_IFBLK;
+#endif
+#if defined(S_IFCHR) || defined(S_IFBLK)
+       make_node:
+               check = mknod(skipcrud+head->header.name,
+                             (int) hstat.st_mode, (int) hstat.st_rdev);
+               if (check != 0) {
+                       if (make_dirs(skipcrud+head->header.name))
+                               goto make_node;
+                       msg_perror("Could not make %s",skipcrud+head->header.name);
+                       break;
+               };
+               goto set_filestat;
+#endif
+
+#ifdef S_ISFIFO
+       /* If local system doesn't support FIFOs, use default case */
+       case LF_FIFO:
+       make_fifo:
+               check = mkfifo(skipcrud+head->header.name,
+                              (int) hstat.st_mode);
+               if (check != 0) {
+                       if (make_dirs(skipcrud+head->header.name))
+                               goto make_fifo;
+                       msg_perror("Could not make %s",skipcrud+head->header.name);
+                       break;
+               };
+               goto set_filestat;
+#endif
+
+       case LF_DIR:
+       case LF_DUMPDIR:
+               namelen = strlen(skipcrud+head->header.name)-1;
+       really_dir:
+               /* Check for trailing /, and zap as many as we find. */
+               while (namelen && head->header.name[skipcrud+namelen] == '/')
+                       head->header.name[skipcrud+namelen--] = '\0';
+               if(f_gnudump) {         /* Read the entry and delete files
+                                          that aren't listed in the archive */
+                       gnu_restore(skipcrud);
+               
+               } else if(head->header.linkflag==LF_DUMPDIR)
+                       skip_file((long)(hstat.st_size));
+
+       
+       again_dir:
+               check = mkdir(skipcrud+head->header.name,
+                             (we_are_root ? 0 : 0300) | (int)hstat.st_mode);
+               if (check != 0) {
+                       struct stat st1;
+
+                       if (make_dirs(skipcrud+head->header.name))
+                               goto again_dir;
+                       /* If we're trying to create '.', let it be. */
+                       if (head->header.name[skipcrud+namelen] == '.' && 
+                           (namelen==0 ||
+                            head->header.name[skipcrud+namelen-1]=='/'))
+                               goto check_perms;
+                       if(   errno==EEXIST
+                          && stat(skipcrud+head->header.name,&st1)==0
+                          && (S_ISDIR(st1.st_mode)))
+                               break;
+                       msg_perror("Could not create directory %s",skipcrud+head->header.name);
+                       break;
+               }
+               
+       check_perms:
+               if (!we_are_root && 0300 != (0300 & (int) hstat.st_mode)) {
+                       hstat.st_mode |= 0300;
+                       msg("Added write and execute permission to directory %s",
+                         skipcrud+head->header.name);
+               }
+
+               goto set_filestat;
+               /* FIXME, Remember timestamps for after files created? */
+               /* FIXME, change mode after files created (if was R/O dir) */
+       case LF_VOLHDR:
+               if(f_verbose) {
+                       printf("Reading %s\n",head->header.name);
+               }
+               break;
+
+       case LF_NAMES:
+               extract_mangle(head);
+               break;
+
+       case LF_MULTIVOL:
+               msg("Can't extract '%s'--file is continued from another volume\n",head->header.name);
+               skip_file((long)hstat.st_size);
+               break;
+
+       }
+
+       /* We don't need to save it any longer. */
+       saverec((union record **) 0);   /* Unsave it */
+}
+
+/*
+ * After a file/link/symlink/dir creation has failed, see if
+ * it's because some required directory was not present, and if
+ * so, create all required dirs.
+ */
+int
+make_dirs(pathname)
+       char *pathname;
+{
+       char *p;                        /* Points into path */
+       int madeone = 0;                /* Did we do anything yet? */
+       int save_errno = errno;         /* Remember caller's errno */
+       int check;
+
+       if (errno != ENOENT)
+               return 0;               /* Not our problem */
+
+       for (p = index(pathname, '/'); p != NULL; p = index(p+1, '/')) {
+               /* Avoid mkdir of empty string, if leading or double '/' */
+               if (p == pathname || p[-1] == '/')
+                       continue;
+               /* Avoid mkdir where last part of path is '.' */
+               if (p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
+                       continue;
+               *p = 0;                         /* Truncate the path there */
+               check = mkdir (pathname, 0777); /* Try to create it as a dir */
+               if (check == 0) {
+                       /* Fix ownership */
+                       if (we_are_root) {
+                               if (chown(pathname, hstat.st_uid,
+                                         hstat.st_gid) < 0) {
+                                       msg_perror("cannot change owner of %s to uid %d gid %d",pathname,hstat.st_uid,hstat.st_gid);
+                               }
+                       }
+                       pr_mkdir(pathname, p-pathname, notumask&0777);
+                       madeone++;              /* Remember if we made one */
+                       *p = '/';
+                       continue;
+               }
+               *p = '/';
+               if (errno == EEXIST)            /* Directory already exists */
+                       continue;
+               /*
+                * Some other error in the mkdir.  We return to the caller.
+                */
+               break;
+       }
+
+       errno = save_errno;             /* Restore caller's errno */
+       return madeone;                 /* Tell them to retry if we made one */
+}
+
+void
+extract_sparse_file(fd, sizeleft, totalsize, name)
+       int     fd;
+       long    *sizeleft,
+               totalsize;
+       char    *name;
+{              
+/*     register char   *data;*/
+       union record    *datarec;
+       int     sparse_ind = 0;
+       int     written,
+               count;
+       
+       /* assuming sizeleft is initially totalsize */
+
+
+       while (*sizeleft > 0) {
+               datarec = findrec();
+               if (datarec == NULL) {
+                       msg("Unexpected EOF on archive file");
+                       return;
+               }
+               lseek(fd, sparsearray[sparse_ind].offset, 0);
+               written = sparsearray[sparse_ind++].numbytes;
+               while (written > RECORDSIZE) {
+                       count = write(fd, datarec->charptr, RECORDSIZE);
+                       if (count < 0) 
+                               msg_perror("couldn't write to file %s", name);
+                       written -= count;
+                       *sizeleft -= count;
+                       userec(datarec);
+                       datarec = findrec();
+               }
+
+               count = write(fd, datarec->charptr, written);
+               
+               if (count < 0) {
+                       msg_perror("couldn't write to file %s", name);
+               } else if (count != written) {
+                       msg("could only write %d of %d bytes to file %s", totalsize - *sizeleft, totalsize, name);
+                       skip_file((long) (*sizeleft));
+               }
+
+               written -= count;
+               *sizeleft -= count;             
+               userec(datarec);
+       }
+       free(sparsearray);
+/*     if (end_nulls) {
+               register int i;
+
+               printf("%d\n", (int) end_nulls);
+               for (i = 0; i < end_nulls; i++)
+                       write(fd, "\000", 1);
+       }*/
+       userec(datarec);
+}
index 442a8310740aecc0de24d65cc33c52b25d4d4eb0..b2415fba75d5ab6fdf854f202d2b4c7ccb44fc6c 100644 (file)
--- a/src/rmt.c
+++ b/src/rmt.c
@@ -31,8 +31,12 @@ char copyright[] =
 #ifdef HAVE_SYS_GENTAPE_H      /* e.g., ISC UNIX */
 #include <sys/gentape.h>
 #else
+#ifdef M_UNIX
+#include <sys/tape.h>
+#else
 #include <sys/mtio.h>
 #endif
+#endif
 #include <errno.h>
 
 #if defined (_I386) && defined (_AIX)
index 6260c0855ecf1bf904f3369e58904b25360fcda8..c97e3b25a943a398fad8a1a66caa17101ee7c89e 100644 (file)
--- a/src/rmt.h
+++ b/src/rmt.h
@@ -23,7 +23,7 @@
 #ifdef __MSDOS__
 #include <io.h>
 #else /* !__MSDOS__ */
-extern off_t lseek();
+extern off_t lseek ();
 #endif /* __MSDOS__ */
 #endif /* _POSIX_VERSION */
 
@@ -59,7 +59,7 @@ extern char *__rmt_path;
 #include <string.h>
 #define index strchr
 #else
-extern char *index();
+extern char *index ();
 #endif
 
 #define _remdev(path)  (!f_force_local && (__rmt_path=index(path, ':')))
@@ -91,6 +91,6 @@ int __rmt_open ();
 int __rmt_close ();
 int __rmt_read ();
 int __rmt_write ();
-long __rmt_lseek();
+long __rmt_lseek ();
 int __rmt_ioctl ();
 #endif /* !NO_REMOTE */
This page took 0.042943 seconds and 4 git commands to generate.