home *** CD-ROM | disk | FTP | other *** search
- /* Create 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 1, 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. */
-
- /*
- * Create a tar archive.
- *
- * Written 25 Aug 1985 by John Gilmore, ihnp4!hoptoad!gnu.
- *
- * @(#)create.c 1.36 11/6/87 - gnu
- */
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdio.h>
-
- #ifndef V7
- #include <fcntl.h>
- #endif
-
- #ifndef __MSDOS__
- #include <sys/file.h>
- #include <sys/param.h> /* for MAXPATHLEN */
- #include <pwd.h>
- #include <grp.h>
- #endif
-
- #ifdef BSD42
- #include <sys/dir.h>
- #else
- #ifdef __MSDOS__
- #include "msd_dir.h"
- #else
- #ifdef USG
- #ifdef NDIR
- #include <ndir.h>
- #else
- #include <dirent.h>
- #endif
- #ifndef DIRECT
- #define direct dirent
- #endif
- #define DP_NAMELEN(x) strlen((x)->d_name)
- #else
- /*
- * FIXME: On other systems there is no standard place for the header file
- * for the portable directory access routines. Change the #include line
- * below to bring it in from wherever it is.
- */
- #include "ndir.h"
- #endif
- #endif
- #endif
-
- #ifndef DP_NAMELEN
- #define DP_NAMELEN(x) (x)->d_namlen
- #endif
-
- #ifdef USG
- #include <sys/sysmacros.h> /* major() and minor() defined here */
- #endif
-
- /*
- * V7 doesn't have a #define for this.
- */
- #ifndef O_RDONLY
- #define O_RDONLY 0
- #endif
-
- /*
- * Most people don't have a #define for this.
- */
- #ifndef O_BINARY
- #define O_BINARY 0
- #endif
-
- #ifndef MAXPATHLEN
- #define MAXPATHLEN 1024
- #endif
-
- #include "tar.h"
- #include "port.h"
-
- extern struct stat hstat; /* Stat struct corresponding */
-
- #ifndef __MSDOS__
- extern dev_t ar_dev;
- extern ino_t ar_ino;
- #endif
-
- /* JF */
- extern struct name *gnu_list_name;
-
- /*
- * If there are no symbolic links, there is no lstat(). Use stat().
- */
- #ifndef S_IFLNK
- #define lstat stat
- #endif
-
- #ifndef __STDC__
- extern char *malloc();
- extern char *strcpy();
- extern char *strncpy();
- extern void bzero();
- extern void bcopy();
- #endif
- extern int errno;
-
- extern void print_header();
-
- union record *start_header();
- void finish_header();
- void finduname();
- void findgname();
- char *name_next();
- void to_oct();
- void dump_file();
-
-
- /* This code moved from tar.h since create.c is the only file that cares
- about 'struct link's. This means that other files might not have to
- include sys/types.h any more.
- */
-
- struct link {
- struct link *next;
- dev_t dev;
- ino_t ino;
- short linkcount;
- char name[1];
- };
-
- struct link *linklist; /* Points to first link in list */
-
- static nolinks; /* Gets set if we run out of RAM */
-
- /*
- * "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 sparse_array_size = 10;*/
-
- void
- create_archive()
- {
- register char *p;
- char *name_from_list();
-
- open_archive(0); /* Open for writing */
-
- if(f_gnudump) {
- char buf[MAXNAMLEN],*q,*bufp;
-
- collect_and_sort_names();
-
- while(p=name_from_list())
- dump_file(p,-1);
- /* if(!f_dironly) { */
- blank_name_list();
- while(p=name_from_list()) {
- strcpy(buf,p);
- if(p[strlen(p)-1]!='/')
- strcat(buf,"/");
- bufp=buf+strlen(buf);
- for(q=gnu_list_name->dir_contents;q && *q;q+=strlen(q)+1) {
- if(*q=='Y') {
- strcpy(bufp,q+1);
- dump_file(buf,-1);
- }
- }
- }
- /* } */
-
- } else {
- p = name_next(1);
- if(!p)
- dump_file(".", -1);
- else {
- do dump_file(p, -1);
- while (p = name_next(1));
- }
- }
-
- write_mangled();
- write_eot();
- close_archive();
- if(f_gnudump)
- write_dir_file();
- name_close();
- }
-
- /*
- * Dump a single file. If it's a directory, recurse.
- * Result is 1 for success, 0 for failure.
- * Sets global "hstat" to stat() output for this file.
- */
- void
- dump_file (p, curdev)
- char *p; /* File name to dump */
- int curdev; /* Device our parent dir was on */
- {
- union record *header;
- char type;
- extern char *save_name; /* JF for multi-volume support */
- extern long save_totsize;
- extern long save_sizeleft;
- union record *exhdr;
- char save_linkflag;
- extern time_t new_time;
- int sparse_ind = 0;
-
-
- if(f_confirm && !confirm("add",p))
- return;
-
- /*
- * Use stat if following (rather than dumping) 4.2BSD's
- * symbolic links. Otherwise, use lstat (which, on non-4.2
- * systems, is #define'd to stat anyway.
- */
- #ifdef AIX
- if (0 != f_follow_links ?
- statx (p, &hstat, STATSIZE, STX_HIDDEN):
- statx (p, &hstat, STATSIZE, STX_HIDDEN|STX_LINK))
- #else
- if (0 != f_follow_links? stat(p, &hstat): lstat(p, &hstat))
- #endif /* AIX */
- {
- badperror:
- msg_perror("can't add file %s",p);
- badfile:
- errors++;
- return;
- }
-
- #ifdef AIX
- if (S_ISHIDDEN (hstat.st_mode)) {
- char *new = (char *)allocate (strlen (p) + 2);
- if (new) {
- strcpy (new, p);
- strcat (new, "@");
- p = new;
- }
- }
- #endif /* AIX */
-
- /* See if we only want new files, and check if this one is too old to
- put in the archive. */
- if( f_new_files
- && !f_gnudump
- && new_time>hstat.st_mtime
- && (hstat.st_mode&S_IFMT)!=S_IFDIR
- && (f_new_files>1 || new_time>hstat.st_ctime)) {
- if(curdev<0) {
- msg("%s: is unchanged; not dumped",p);
- }
- return;
- }
-
- #ifndef __MSDOS__
- /* See if we are trying to dump the archive */
- if(ar_dev && hstat.st_dev==ar_dev && hstat.st_ino==ar_ino) {
- msg("%s is the archive; not dumped",p);
- return;
- }
- #endif
- /*
- * Check for multiple links.
- *
- * We maintain a list of all such files that we've written so
- * far. Any time we see another, we check the list and
- * avoid dumping the data again if we've done it once already.
- */
- if (hstat.st_nlink > 1) switch (hstat.st_mode & S_IFMT) {
- register struct link *lp;
-
- case S_IFREG: /* Regular file */
- #ifdef S_IFCTG
- case S_IFCTG: /* Contigous file */
- #endif
- #ifdef S_IFCHR
- case S_IFCHR: /* Character special file */
- #endif
-
- #ifdef S_IFBLK
- case S_IFBLK: /* Block special file */
- #endif
-
- #ifdef S_IFIFO
- case S_IFIFO: /* Fifo special file */
- #endif
-
- /* First quick and dirty. Hashing, etc later FIXME */
- for (lp = linklist; lp; lp = lp->next) {
- if (lp->ino == hstat.st_ino &&
- lp->dev == hstat.st_dev) {
- char *link_name = lp->name;
-
- /* We found a link. */
- hstat.st_size = 0;
- header = start_header(p, &hstat);
- if (header == NULL) goto badfile;
- while(!f_absolute_paths && *link_name == '/') {
- static int link_warn = 0;
-
- if (!link_warn) {
- msg("Removing leading / from absolute links");
- link_warn++;
- }
- link_name++;
- }
- strncpy(header->header.linkname,
- link_name,NAMSIZ);
- if(header->header.linkname[NAMSIZ-1]) {
- char *mangled;
- extern char *find_mangled();
-
- mangled=find_mangled(link_name);
- msg("%s: link name too long: mangled to %s",link_name,mangled);
- strncpy(header->header.linkname,mangled,NAMSIZ);
- }
- header->header.linkflag = LF_LINK;
- finish_header(header);
- /* FIXME: Maybe remove from list after all links found? */
- return; /* We dumped it */
- }
- }
-
- /* Not found. Add it to the list of possible links. */
- lp = (struct link *)malloc((unsigned)(sizeof(struct link)+strlen(p)));
- if (!lp) {
- if (!nolinks) {
- msg(
- "no memory for links, they will be dumped as separate files");
- nolinks++;
- }
- }
- lp->ino = hstat.st_ino;
- lp->dev = hstat.st_dev;
- strcpy(lp->name, p);
- lp->next = linklist;
- linklist = lp;
- }
-
- /*
- * This is not a link to a previously dumped file, so dump it.
- */
- switch (hstat.st_mode & S_IFMT) {
-
- case S_IFREG: /* Regular file */
- #ifdef S_IFCTG
- case S_IFCTG: /* Contiguous file */
- #endif
- {
- int f; /* File descriptor */
- long bufsize, count;
- long sizeleft;
- register union record *start;
- int header_moved;
- char isextended = 0;
- int upperbound;
- int end_nulls = 0;
-
- header_moved = 0;
-
- #ifdef BSD42
- if (f_sparse_files) {
- /*
- * JK - This is the test for sparseness: whether the
- * "size" of the file matches the number of blocks
- * allocated for it. If there is a smaller number
- * of blocks that would be necessary to accommodate
- * a file of this size, we have a sparse file, i.e.,
- * at least one of those records in the file is just
- * a useless hole.
- */
- #ifdef hpux /* Nice of HPUX to gratuitiously change it, huh? - mib */
- if (hstat.st_size - (hstat.st_blocks * 1024) > 1024 ) {
- #else
- if (hstat.st_size - (hstat.st_blocks * RECORDSIZE) > RECORDSIZE) {
- #endif
- int filesize = hstat.st_size;
- register int i;
-
- header = start_header(p, &hstat);
- if (header == NULL)
- goto badfile;
- header->header.linkflag = LF_SPARSE;
- header_moved++;
-
- /*
- * Call the routine that figures out the
- * layout of the sparse file in question.
- * UPPERBOUND is the index of the last
- * element of the "sparsearray," i.e.,
- * the number of elements it needed to
- * describe the file.
- */
-
- upperbound = deal_with_sparse(p, header);
-
- /*
- * See if we'll need an extended header
- * later
- */
- if (upperbound > SPARSE_IN_HDR-1)
- header->header.isextended++;
- /*
- * We store the "real" file size so
- * we can show that in case someone wants
- * to list the archive, i.e., tar tvf <file>.
- * It might be kind of disconcerting if the
- * shrunken file size was the one that showed
- * up.
- */
- to_oct((long) hstat.st_size, 1+12,
- header->header.realsize);
-
- /*
- * This will be the new "size" of the
- * file, i.e., the size of the file
- * minus the records of holes that we're
- * skipping over.
- */
-
- find_new_file_size(&filesize, upperbound);
- hstat.st_size = filesize;
- to_oct((long) filesize, 1+12,
- header->header.size);
- /* to_oct((long) end_nulls, 1+12,
- header->header.ending_blanks);*/
-
- for (i = 0; i < SPARSE_IN_HDR; i++) {
- if (!sparsearray[i].numbytes)
- break;
- to_oct(sparsearray[i].offset, 1+12,
- header->header.sp[i].offset);
- to_oct(sparsearray[i].numbytes, 1+12,
- header->header.sp[i].numbytes);
- }
-
- }
- }
- #else
- upperbound=SPARSE_IN_HDR-1;
- #endif
-
- sizeleft = hstat.st_size;
- /* Don't bother opening empty, world readable files. */
- if (sizeleft > 0 || 0444 != (0444 & hstat.st_mode)) {
- f = open(p, O_RDONLY|O_BINARY);
- if (f < 0) goto badperror;
- } else {
- f = -1;
- }
-
- /* If the file is sparse, we've already taken care of this */
- if (!header_moved) {
- header = start_header(p, &hstat);
- if (header == NULL) {
- if(f>=0)
- (void)close(f);
- goto badfile;
- }
- }
- #ifdef S_IFCTG
- /* Mark contiguous files, if we support them */
- if (f_standard && (hstat.st_mode & S_IFMT) == S_IFCTG) {
- header->header.linkflag = LF_CONTIG;
- }
- #endif
- isextended = header->header.isextended;
- save_linkflag = header->header.linkflag;
- finish_header(header);
- if (isextended) {
- int sum = 0;
- register int i;
- /* register union record *exhdr;*/
- int arraybound = SPARSE_EXT_HDR;
- /* static */ int index_offset = SPARSE_IN_HDR;
-
- extend: exhdr = findrec();
-
- if (exhdr == NULL) goto badfile;
- bzero(exhdr->charptr, RECORDSIZE);
- for (i = 0; i < SPARSE_EXT_HDR; i++) {
- if (i+index_offset > upperbound)
- break;
- to_oct((long) sparsearray[i+index_offset].numbytes,
- 1+12,
- exhdr->ext_hdr.sp[i].numbytes);
- to_oct((long) sparsearray[i+index_offset].offset,
- 1+12,
- exhdr->ext_hdr.sp[i].offset);
- }
- userec(exhdr);
- /* sum += i;
- if (sum < upperbound)
- goto extend;*/
- if (index_offset+i < upperbound) {
- index_offset += i;
- exhdr->ext_hdr.isextended++;
- goto extend;
- }
-
- }
- if (save_linkflag == LF_SPARSE) {
- if (finish_sparse_file(f, &sizeleft, hstat.st_size, p))
- goto padit;
- }
- else
- while (sizeleft > 0) {
-
- if(f_multivol) {
- save_name = p;
- save_sizeleft = sizeleft;
- save_totsize = hstat.st_size;
- }
- start = findrec();
-
- bufsize = endofrecs()->charptr - start->charptr;
-
- if (sizeleft < bufsize) {
- /* Last read -- zero out area beyond */
- bufsize = (int)sizeleft;
- count = bufsize % RECORDSIZE;
- if (count)
- bzero(start->charptr + sizeleft,
- (int)(RECORDSIZE - count));
- }
- count = read(f, start->charptr, bufsize);
- if (count < 0) {
- msg_perror("read error at byte %ld, reading\
- %d bytes, in file %s", hstat.st_size - sizeleft, bufsize,p);
- goto padit;
- }
- sizeleft -= count;
-
- /* This is nonportable (the type of userec's arg). */
- userec(start+(count-1)/RECORDSIZE);
-
- if (count == bufsize) continue;
- msg( "file %s shrunk by %d bytes, padding with zeros.", p, sizeleft);
- goto padit; /* Short read */
- }
-
- if(f_multivol)
- save_name = 0;
-
- if (f >= 0)
- (void)close(f);
-
- break;
-
- /*
- * File shrunk or gave error, pad out tape to match
- * the size we specified in the header.
- */
- padit:
- while(sizeleft>0) {
- save_sizeleft=sizeleft;
- start=findrec();
- bzero(start->charptr,RECORDSIZE);
- userec(start);
- sizeleft-=RECORDSIZE;
- }
- if(f_multivol)
- save_name=0;
- if(f>=0)
- (void)close(f);
- break;
- /* abort(); */
- }
-
- #ifdef S_IFLNK
- case S_IFLNK: /* Symbolic link */
- {
- int size;
-
- hstat.st_size = 0; /* Force 0 size on symlink */
- header = start_header(p, &hstat);
- if (header == NULL) goto badfile;
- size = readlink(p, header->header.linkname, NAMSIZ);
- if (size < 0) goto badperror;
- if (size == NAMSIZ) {
- char buf[MAXPATHLEN];
-
- readlink(p,buf,MAXPATHLEN);
- /* next_mangle(header->header.linkname); */
- add_symlink_mangle(buf,p,header->header.linkname);
- msg("symbolic link %s too long: mangling to %s",p, header->header.linkname);
- /* size=strlen(header->header.linkname); */
- } else
- header->header.linkname[size] = '\0';
- header->header.linkflag = LF_SYMLINK;
- finish_header(header); /* Nothing more to do to it */
- }
- break;
- #endif
-
- case S_IFDIR: /* Directory */
- {
- register DIR *dirp;
- register struct direct *d;
- char *namebuf;
- int buflen;
- register int len;
- int our_device = hstat.st_dev;
- extern char *ck_malloc(),*ck_realloc();
-
- /* Build new prototype name */
- len = strlen(p);
- buflen=len+NAMSIZ;
- namebuf=ck_malloc(buflen+1);
- strncpy(namebuf, p, buflen);
- while (len >= 1 && '/' == namebuf[len-1])
- len--; /* Delete trailing slashes */
- namebuf[len++] = '/'; /* Now add exactly one back */
- namebuf[len] = '\0'; /* Make sure null-terminated */
-
- /*
- * Output directory header record with permissions
- * FIXME, do this AFTER files, to avoid R/O dir problems?
- * If old archive format, don't write record at all.
- */
- if (!f_oldarch) {
- hstat.st_size = 0; /* Force 0 size on dir */
- /*
- * If people could really read standard archives,
- * this should be: (FIXME)
- header = start_header(f_standard? p: namebuf, &hstat);
- * but since they'd interpret LF_DIR records as
- * regular files, we'd better put the / on the name.
- */
- header = start_header(namebuf, &hstat);
- if (header == NULL)
- goto badfile; /* eg name too long */
-
- if (f_gnudump)
- header->header.linkflag = LF_DUMPDIR;
- else if (f_standard)
- header->header.linkflag = LF_DIR;
-
- /* If we're gnudumping, we aren't done yet so don't close it. */
- if(!f_gnudump)
- finish_header(header); /* Done with directory header */
- }
-
- if(f_gnudump) {
- int sizeleft;
- int totsize;
- int bufsize;
- union record *start;
- int count;
- char *buf,*p_buf;
-
- buf=gnu_list_name->dir_contents; /* FOO */
- totsize=0;
- for(p_buf=buf;p_buf && *p_buf;) {
- int tmp;
-
- tmp=strlen(p_buf)+1;
- totsize+=tmp;
- p_buf+=tmp;
- }
- totsize++;
- to_oct((long)totsize,1+12,header->header.size);
- finish_header(header);
- p_buf=buf;
- sizeleft=totsize;
- while(sizeleft>0) {
- if(f_multivol) {
- save_name=p;
- save_sizeleft=sizeleft;
- save_totsize=totsize;
- }
- start=findrec();
- bufsize=endofrecs()->charptr - start->charptr;
- if(sizeleft<bufsize) {
- bufsize=sizeleft;
- count=bufsize%RECORDSIZE;
- if(count)
- bzero(start->charptr+sizeleft,RECORDSIZE-count);
- }
- bcopy(p_buf,start->charptr,bufsize);
- sizeleft-=bufsize;
- p_buf+=bufsize;
- userec(start+(bufsize-1)/RECORDSIZE);
- }
- if(f_multivol)
- save_name = 0;
- break;
- }
-
- /* Now output all the files in the directory */
- /* if (f_dironly)
- break; /* Unless the cmdline said not to */
- /*
- * See if we are crossing from one file system to another,
- * and avoid doing so if the user only wants to dump one file system.
- */
- if (f_local_filesys && curdev >= 0 && curdev != hstat.st_dev) {
- if(f_verbose)
- msg("%s: is on a different filesystem; not dumped",p);
- break;
- }
-
-
- errno = 0;
- dirp = opendir(p);
- if (!dirp) {
- if (errno) {
- msg_perror ("can't open directory %s",p);
- } else {
- msg("error opening directory %s",
- p);
- }
- break;
- }
-
- /* Hack to remove "./" from the front of all the file names */
- if (len == 2 && namebuf[0] == '.' && namebuf[1]=='/')
- len = 0;
-
- /* Should speed this up by cd-ing into the dir, FIXME */
- while (NULL != (d=readdir(dirp))) {
- /* Skip . and .. */
- if(is_dot_or_dotdot(d->d_name))
- continue;
-
- if (DP_NAMELEN(d) + len >= buflen) {
- buflen=len+DP_NAMELEN(d);
- namebuf=ck_realloc(namebuf,buflen+1);
- /* namebuf[len]='\0';
- msg("file name %s%s too long",
- namebuf, d->d_name);
- continue; */
- }
- strcpy(namebuf+len, d->d_name);
- if(f_exclude && check_exclude(namebuf))
- continue;
- dump_file(namebuf, our_device);
- }
-
- closedir(dirp);
- free(namebuf);
- }
- break;
-
- #ifdef S_IFCHR
- case S_IFCHR: /* Character special file */
- type = LF_CHR;
- goto easy;
- #endif
-
- #ifdef S_IFBLK
- case S_IFBLK: /* Block special file */
- type = LF_BLK;
- goto easy;
- #endif
-
- /* Avoid screwy apollo lossage where S_IFIFO == S_IFSOCK */
- #if ((_ISP__M68K == 0) && (_ISP__A88K == 0))
- #ifdef S_IFIFO
- case S_IFIFO: /* Fifo special file */
-
- type = LF_FIFO;
- goto easy;
- #endif
- #endif
-
- #ifdef S_IFSOCK
- case S_IFSOCK: /* Socket pretend its a fifo? */
- type = LF_FIFO;
- goto easy;
- #endif
-
- easy:
- if (!f_standard) goto unknown;
-
- hstat.st_size = 0; /* Force 0 size */
- header = start_header(p, &hstat);
- if (header == NULL) goto badfile; /* eg name too long */
-
- header->header.linkflag = type;
- if (type != LF_FIFO) {
- to_oct((long) major(hstat.st_rdev), 8,
- header->header.devmajor);
- to_oct((long) minor(hstat.st_rdev), 8,
- header->header.devminor);
- }
-
- finish_header(header);
- break;
-
- default:
- unknown:
- msg("%s: Unknown file type; file ignored.", p);
- break;
- }
- }
-
- int
- finish_sparse_file(fd, sizeleft, fullsize, name)
- int fd;
- long *sizeleft,
- fullsize;
- char *name;
- {
- union record *start;
- char tempbuf[RECORDSIZE];
- int bufsize,
- sparse_ind = 0,
- count;
- long pos;
- long nwritten = 0;
-
-
- while (*sizeleft > 0) {
- start = findrec();
- bzero(start->charptr, RECORDSIZE);
- bufsize = sparsearray[sparse_ind].numbytes;
- if (!bufsize) { /* we blew it, maybe */
- msg("Wrote %ld of %ld bytes to file %s",
- fullsize - *sizeleft, fullsize, name);
- break;
- }
- pos = lseek(fd, sparsearray[sparse_ind++].offset, 0);
- /*
- * If the number of bytes to be written here exceeds
- * the size of the temporary buffer, do it in steps.
- */
- while (bufsize > RECORDSIZE) {
- /* if (amt_read) {
- count = read(fd, start->charptr+amt_read, RECORDSIZE-amt_read);
- bufsize -= RECORDSIZE - amt_read;
- amt_read = 0;
- userec(start);
- start = findrec();
- bzero(start->charptr, RECORDSIZE);
- }*/
- /* store the data */
- count = read(fd, start->charptr, RECORDSIZE);
- if (count < 0) {
- msg_perror("read error at byte %ld, reading %d bytes, in file %s",
- fullsize - *sizeleft, bufsize, name);
- return 1;
- }
- bufsize -= count;
- *sizeleft -= count;
- userec(start);
- nwritten += RECORDSIZE; /* XXX */
- start = findrec();
- bzero(start->charptr, RECORDSIZE);
- }
-
-
- clear_buffer(tempbuf);
- count = read(fd, tempbuf, bufsize);
- bcopy(tempbuf, start->charptr, RECORDSIZE);
- if (count < 0) {
- msg_perror("read error at byte %ld, reading %d bytes, in file %s",
- fullsize - *sizeleft, bufsize, name);
- return 1;
- }
- /* if (amt_read >= RECORDSIZE) {
- amt_read = 0;
- userec(start+(count-1)/RECORDSIZE);
- if (count != bufsize) {
- msg("file %s shrunk by %d bytes, padding with zeros.", name, sizeleft);
- return 1;
- }
- start = findrec();
- } else
- amt_read += bufsize;*/
- nwritten += count; /* XXX */
- *sizeleft -= count;
- userec(start);
-
- }
- free(sparsearray);
- printf ("Amount actually written is (I hope)buff * nnametten is)* abrec(start+(count-1)/RECORDSIZE);
- *surn 1;
-
-
- wint
- fit_rsearray);
- () uniister int leni }
- sp_ay);
- ze = 0; 1 u
- * ake surrothefopenurrewyh
- arse0 s--
- fitiy wri(I 10se a fg n
- /
- whrsearray);
- 0; (uct dirsp_ay);
- *ajorc(namsp_ay);
- ze = 0ize=stof(uct dirsp_ay);
- ) prifope(i0;
- i0) sp_ay);
- ze = i++
- starsearray[spaiffset, 00;
- usrsearray[spaiffbytes;
- 0;
- u
-
- int* Av
- Outpkaye'd b"./o bfifrsearrle %s"recnurrhardss-- n fe'dhbytblen thiso to is
- Outm suraddithe croughe file nam .. c crlsizyt duhere S_Ianyta */
- iin f.e.,
- Outblets t file .. houtfarto the dire namea ainndarcf thea */
- iin a.. hou
- Outm nytes;
- 0athe dare. Weore the din thmat, d recthe dirrsearray[sp,
- Outbhi awithela intbrailinsld */
- o theder == thmat, d re. ce n fe'dser o
- the sizesearray);
- 0asuntnvng filre t wh.
- th
- theA fifsi&& duh,e din rout saii fif */s. theIuld reahaformauavoi ar_bner
- Outb;
- 0so to ibufI wd reahafo. the ny withs to dume .. a n);
- rtb;
- 0so to
- this shulleeile(sp.
- th/* AvoTe S_Ii flen nampo lenihe rimm so iorc(t_rt-1)s thel-teea */
- ahe / oh/* XXXder a.. ting bytek ss-- it's tk we arey wanid doining, wtek ssh/* XXXbytcompe tral-teea */
- h/*
- findloc_h ze_rsearr(e, sizder ==,al-tes_at_if
- )har temme;
- {
- ion record *st *der ==
- i unig nwbytes;
- 0;
- ug nwset, 00;
- ug nwe_namset, 0;nt fd;
- lon fd;devt fize = 0; at.st_size = lon fd;rse_ind = 0,
- coccchar te[RECORDSIZE];
- int bud +=_hesev) */
- ;
- XXXddoiarejustad sta / ohesecord *s/
- ty lent_ridsev) */
- ;
- i ader->header.devisern nde 0;
- u
- * akCt open dir dire nam-- din blems?
- awithebracaughtela inton, * akif justad n 1;.
- /
- wh((_ISfdopendir(e, sizO_RDONLY{
- ) {
- surn 1;
-
-
- b
- fit_rsearray);
- ()charr_buffer(tem);
- chile (*si(ccread(fd, tem, star=stof ))
- buf{
- ifif (course_ind = 0> sp_ay);
- ze = /RE i/*
- * Seelloc(nae sizewyh
- aatha,nce thed b"./k btputXbytrothe-- */
- whihrsearray);
- 0; (uct dirsp_ay);
- *aj fullloc(namrsearray[sp,
- O ful2 akip_ay);
- ze = 0iz(e=stof(uct dirsp_ay);
- ) reip_ay);
- ze = 0i && }
- /* f (counc NULr=stof ))
- if (erros."_ord *s())
- if(f_mt_ridsev) */
- savesearray[sparse_ind++].offbytes;
- ful= bytes;
- if amt_ridsev) */
- ;
- i}
- stalse {
- * we !os."_ord *s())
-
- whih }
- f_mt_ridsev) */
- i}
- }
- bytes;
- 0counc i}
- e {
- msg }
- _ridsev) */
- ;
- totwbytes;
- 0;
- nc i}
- rsearray[sparse_ind].numset, 0 i}
- openet, 0;ntstals }
- stlse {
- (counc <Lr=stof ))
- if* we Tdin hao be wri / ohesecbit the teme na,kif din if (hruomedhbytshor intthare temabofo. msg(!bufos."_ord *s())
- if(f_mt!_ridsev) */
- sa }
- _ridsev) */
- ;
- totwbytes;
- 0;
- nc i}
- rsearray[sparse_ind].numset, 0 i}
- openet, 0;ntstalse {
- totwbytes;
- 0counc i}
- ls }
- stset, 00counc i}rr_buffer(tem);
- c
- sf_mt_ridsev) */
- i }
- esearray[sparse_ind++].offbytes;
- = bytes;
- ifsedir, t chiurn 1;
- rse_ind = 0-
- }* Avo
- thiJustaos."
- putX temfer(tekif aredo opentnfr ocnurselv
- h zert -=ofor
- Out) */.
- th/*rr_buffer(tem);
- har *nam;
- uniister int len i }
- fope(i0;
- i0) ORDSIZE; /* i++
- bufsizaif0;
- ';
- }ifdefsiz if I'mrt av, wt din a fif obyte t filJoy K ndoc(e'dhf ae %ldit h/*Avo
- thiJK0-
-
- thiTdin rout sait su fifcacter speay[sp, a.. tetesere S_Ih zethe dbytay[sp
- the siz) */
- 't wrimauav. tyts . pvspeanytos.",, a.. , 0se teme rst
- thenon-os."mpo lenihe temay);
- be wri / o"rt+(c", a.. tinue;
- p bnueldit
- thee ..senon-a */
- again,tbhi ain marke 0ase tem" nd." iTdin rout saiin
- Outm i wanfopeRE k(f, wthoutfarto theare namaremustaek(fd0so t */, givng
- the sbytblehaforifrsearrle %s, a.. 2) d trrm s, wt dem"llocLr=st" the te
- thee %s, f.e.,e number of bytes to the dirrsearrle typedbytaye t */, as
- Outoppdir( the diros.", are crotry, wt ots . .
- th/*re S__dot_ */(m th,e o,mfer(teint fd;*m th,*sizto;har *nam;
- f==
- uniister int le i
- ;
- iister int le e_namt 0;
- zto;ha le _ridsev) */
- ;
- i ale (*si!;
- f==aif
- bufi++;ha*m th
- ;
- i }
- f_mt*m th
- < 16)u
- do opeber,
-
- *sizm th
- ;
- u
- keep/o , wt otm sursuthe dareiin opem thelloc i a */
- ine din rrd *st *sle (*sii0) ORDSIZE; /
- (!bufsizf==aif
- if (err_ridsev) */
- sae_namt 0;
- i amt_ridsev) */
- ;
- i}
- stai++;ha
- ste {
- (cousizf==aif
- if (err!_ridsev) */
- i}
- _ridsev) */
- ;
- toi++;ha
- s sf_mti NULORDSIZE; /
- *sizto0;
- i e {
- tzto0;
- e_namt
- }ndif
-
- /* AvoN %ldedbyt din rout saii fy wancoc(*/
- of os."_ord *sad n 1;r( true
- #if ((_0 if Buytbleually wrido open thiit bytall.th/*re S__dot_ */ (m th,e o,mfer(tein msg(len*m th,
- zto;h msgr *n m;
- f==
- unsgr *n mfp,
- ztp }
- nfope(fp =mfer(te; ! mfpilep++
- b msg;
- nfope(tp =mfer(telenORDSIZE - amt1; ! mtp tp--
- b msg;
- nzm th
- ;
- fp -mfer(te;
- nzto0;
- tp -mfer(telen }*dif
-
- /* * Av
- OutT su fiford *slsi thea */
- a.. basicy wricruisehe crougheit filk(f
- of
- Outit's mr.d *e tirelyXXbytos.",, d n 1;, wta_0 dirinndarteit e ..s
- akifmezethgdedbyti fifnon-os.", f.e.,er olsi ) */.
- th/*os."_ord *s())
- (teintr *nam;
- f==
- uniister int le i }
- fope(i0;
- i0) ORDSIZE; /* i++
- buf(cousizf==aif buf';
- 00') return 1;
- iisn 1;
- }ife .._newle(fdze = (e(fde, namhighesev ..exint fd;*m(fde, n;ha le highesev ..ex uniister int len i }
- *m(fde, n
- ;
- ifope(i0;
- rsearray[spaiffbytes;
- 0(_Ii0)=mhighesev ..ex* i++
- buf*m(fde, n
- += rsearray[spaiffbytes;
- }i Av
- OutM suradder == ek nfope dire namme too'dhfseorebytihmati fore .
- th Rsn 1;
- der == po le== fopesucc*/s,LL) g
- of numb tooiso long */.
- th/*on record *st*
- rt_header(p, e, sizet)har *name;
- {
- iister intuct dirsebytart uniister inton record *st*der ==
-
- ader = sta(on record *st*)ndrec();
- } ro(stader->hearptr, RECe=stof(*der == XXX */
- sp thiup
-
- he * akChe n dire namb tooa.. put in ste dirord *s.
- /
- wh(((!f_absolute_paths
- start tict lenwa1;r(_o the;
- ((aul __MSDOS__buf(c e, s[1]==':'
- if e, s+=2 if (c(!wa1;r(_o th++
- bufsg("filRemov, wtdrivn
- sp c m th
- e, ssnihe temaychivn" }
-
-
- dif
-
- /* ((aul _rigadosbuf(c ..ex e, siz':'
-
- if e, s0;
- i..ex e, siz':'
- +1 if (c(!wa1;r(_o th++
- bufsg("filRemov, wtvolumn
- sp c m th
- e, ssnihe temaychivn" }
-
-
- dif
-
- /*hile (buf'/' NULme;
- {
- if e, s++; /* stoce cirorla ivn
- path
- whih(err!wa1;r(_o th++
- bufsg("filRemov, wtling %d / m th
- absolute
- path
- e, ssnihe temaychivn." }
-
-
-
-
-
- uctnctemder->header.deve, size, sizNAME; }
- (errder->header.deve, s[NAME; -1f
- ifr *n mm ng(*/
-
- a stonern_m ng(*rder->header.deve, s whiing_m ng(*re, sider->header.deve, s
- sg("fil%s:oiso long */: m ng(, wt ot,
- e, sizder ==eader.deve, s
- s}if to_oct((g */) (uc->sevmo.d & ~S_IFMT), totw8, zder ==eader.devmo.d);* ((aul _rigadosbu(err_rigarrorms
- bufto_oct ((g */)uc->sevamo.d, 1+12izder ==eader.devdevmajor);* if
-
- /*hto_oct((g */) uc->sevuid,w8, zder ==eader.devuid
- sto_oct((g */) uc->sevgid,w8, zder ==eader.devgid
- sto_oct((g */) uc->seve, na 1+12izder ==eader.deve);
- bcto_oct((g */) uc->sevmtimna 1+12izder ==eader.devmtimn) u
- der ==eader.dev(, kflagIi fl -= asel-tee wh(((f_gnuning
- ifto_oct((g */) uc->sevatimna 1+12izder ==eader.devatimn) ufto_oct((g */) uc->sevctimna 1+12izder ==eader.devctimn) u}ifdefnaul NONAMES u
- Fitheihenew Unix Sdarda*stfiel.se(erdde,red.
- wh((_If_sdarda*s
- ifder ==eader.dev(, kflagI= LF_NORMAL* XXXNew aulault whiuctctemder->header.devmagic, TMAGIC)* XXXMark aseUnix Sdst *s drecue, smder->header.devue, sizet->sevuid) ufdrecge, smder->header.devge, sizet->sevgid
- s
- dif
-
- /*hrsn 1;
- der == }* Avo
- thiF s,sheneteare n(*/-indder == ek na.. ttenldit out.
- th Weoalif ntf (n dire namb tooa../opelsiztihmatif vspbfseoi fy .
- th/*d dofe .,shader(p, der == niister inton record *st*der ==
- uniister int le iizeum
- iister intr *namp } d doibcop
- ()ch} rcop
- (CHKBLANKSizder ==eader.devchkeumECe=stof(der ==eader.devchkeum))ch} eum
- ;
- ip =mder->hearptr, R ifope(i0;
- e=stof(*der == ;e--i REC
- if * SeeWraca oper ocunsig;r( r *n dareibecausf theoldtcomp nars, * Seee.g. V7. */
- whieum
- += 0xFF & *p++;ha} he * akFitheihe dirche eum
- fiel.. ty's mat, d */
-
-
- /f==e tly * akm th
- direr,
-
- fiel.s: dit hao [6]
-
-
- git,, ael-te,e nun a * akise0 s-- yh
- hintthare
-
- git,, aeise0 ,e nun ael-te.
- /
- eWrausf to_oct nun ttenld numbetheihepvspeto_oct's ise0 .
- /
- eTdire nocLrse0 si fild(fdye dare,km th
- che eumm so, a..
- /
- eto_oct d"
- opem
-
- /ri(t.
- /
-
- /
- eTdin t fiffesecb;
- 0so to:
- /
- e(d do) untf (f(der ==eader.devchkeum, "%6o"izeum
- s
- whto_oct((g */) uum,w8, zder ==eader.devchkeum); ader->header.devchkeum[6]
- ;
- ';
- XXXZape dirrsece
-
- heusf();
- der == ;
- wh((_If_vspbfse
- ifern 1;
- on record *st*der ;a stoPo leo be devt fiit pedder == whiern 1;
- f (nder _sdarda*s;a stoT pedder == in th ANSI mat, d
-
- he AvoTe sf globalie crosea ton 1o be ntf (_der ==,asigh
- whider =
- der == e Avohrebyti fild(fdye, 00up
-
- hider _sdarda*s
- ;
- f_sdarda*s; hintf (_der ==(
- s}if rsn 1; }* Av
- OutQui na.. dirty octocLntnvnrsiy .
- th Ctnvnreo g */ "valut" o thear"
-
- gs"-
-
- git
- fiel. byt"re S_",
- Oute tlud, wta_ilii(, wtrsece
- a.. rothefopeael-te. r"
-
- gs"==3f *ans
- ak1e
-
- git, aeise0 ,ea.. rothefopeael-te.
- th
- theWeoassumn
- dirilii(, wtbethei fild(fdye darena.. do opefithein st.
- thiTdin fualei fuir( by rt_header(p,na.. e .,shader(p,,kif do openhargldit!
- th
- theTdin shoul. wriequivale t fi:
- th (d do) untf (f(wdare,k"%*lo "iz
-
- gs-2izvalut
- Seeexceptdedbytuntf (fefithsnihe temilii(, wtbethea.. tredo op.
- th/*d dofto_oct(valutiz
-
- gs,ere S_ niister intg nwvalut iister int le
-
- gs
- iister intr *namre S_
- uni
- --
-
- gs
- /* stoTlii(, wtbetheslotIi fl -= ag et *sle S_[--
-
- gs]
- ;
- ' ';a stoPut the dirrse0 ,e noughe
- he Producn
- dir
-
- git,s-- bytlinsec et *sdo ifle S_[--
-
- gs]
- ;
- '0'len(r *n)(valut & 7 XXX etoctocL
-
- git
-
- hivalut >REC3
- s} le (buf
-
- gs0> 00(_Ivalut buf{
- ; he Ling %d rse0 s,e((_nec*/saryt *sle (*si
-
- gs0> 0) ifle S_[--
-
- gs]
- ;
- ' ';
- }* Av
- OutWtenld numEOTcord *s(s).
- th Weoaally wrios."mbytlinsec etord *s,e croughe numif
- the temek .
- th Ol. t_h ttenls garbagldaf inttwoaos."
- dtord *s,s-- bf
- PDt_h uir( th.
- th/*rtenl_eot() union record *st*p;ha lemfere, n;had doibo(sta
- ; hep =mdrec();
- } ((_Ip
- i { i fere, n =mif
- of();s()earptr, R -mpearptr, R i fo(stapearptr, RECfere, n) i usf();
- p) i }