copy.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1987-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Bell Laboratories
*
* pax file copy support
*/
#include "pax.h"
/*
* copy files in from archive
*/
void
{
while (getprologue(ap))
{
{
if (selectfile(ap, f))
else
gettrailer(ap, f);
}
if (!getepilogue(ap))
break;
}
}
/*
* copy a single file out to the archive
* called by ftwalk()
*/
int
{
{
if (selectfile(ap, f))
{
}
else
}
return 0;
}
/*
* low level for copyout()
* if rfd<0 && st_size>0 then input from bread()
*/
void
{
register size_t m;
register ssize_t n;
register off_t c;
int err;
{
{
err = 0;
while (c > 0)
{
if (!err)
{
if (f->fd >= 0)
{
{
static char* buf;
if (!buf)
{
n = 1024 * 8;
nospace();
}
}
}
{
}
n = -1;
}
if (n <= 0)
{
if (n)
else
err = 1;
}
else
{
c -= n;
}
}
}
puttrailer(ap, f);
}
if (f->fd >= 0)
}
/*
* low level for copyin()
*/
void
{
register off_t c;
register int n;
register char* s;
int dfd;
int wfd;
long checksum;
if (f->skip)
goto skip;
{
{
{
while (*s)
if (*s++ == '%' && *s == '(')
break;
if (*s)
{
nospace();
break;
}
}
if (s)
if (!pp)
{
goto skip;
}
{
checksum = 0;
{
{
break;
}
{
break;
}
}
}
error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum);
/*
* explicitly ignore exit status
*/
return;
}
listentry(f);
goto skip;
}
{
case DELTA_create:
goto regular;
goto skip;
else
paxdelta(NiL, ap, f, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, f->st->st_size, 0);
break;
case DELTA_update:
goto skip;
{
paxdelta(NiL, ap, f, DELTA_SRC|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0))
paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
}
paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0))
paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
break;
case DELTA_verify:
else if (st.st_size != f->delta.base->size || state.modtime && tvcmp(tvmtime(&t1, &st), tvmtime(&t2, f->st)))
break;
case DELTA_delete:
/*FALLTHROUGH*/
default:
if (wfd >= 0)
{
{
checksum = 0;
{
{
break;
}
{
break;
}
}
}
error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum);
}
else
{
if (wfd < -1)
listentry(f);
goto skip;
}
break;
}
listentry(f);
return;
skip:
}
/*
* skip over archive member f file data
*/
void
{
Member_t* d;
off_t n;
if ((!ap->format->getdata || !(*ap->format->getdata)(&state, ap, f, -1)) && ((n = f->st->st_size) > 0 && f->type == X_IFREG || (n = f->datasize)) && bread(ap, NiL, (off_t)0, n, 1) < 0)
}
/*
* single file copyin() and copyout() smashed together
* called by ftwalk()
*/
int
{
register char* s;
register off_t c;
register ssize_t n;
register int rfd;
register int wfd;
{
s = f->name;
{
{
int more;
data = 0;
more = 1;
while (more)
{
{
more = 0;
}
{
if (c > state.buffersize)
c = state.buffersize;
{
more = 0;
break;
}
{
more = 0;
break;
}
data += n;
}
if (!more)
break;
{
if ((data = lseek(rfd, -1, SEEK_END)) < 0 || lseek(wfd, data, SEEK_SET) != data || write(wfd, "", 1) != 1)
break;
}
}
#else
{
if ((n = read(rfd, state.tmp.buffer, (size_t)((c > state.buffersize) ? state.buffersize : c))) <= 0)
{
break;
}
{
break;
}
}
#endif
listentry(f);
}
else
}
else if (wfd != -1)
listentry(f);
}
return 0;
}
/*
* compare ft1 and ft2 for ftwalk() sort
*/
int
{
}
/*
* skip to the next unquoted occurrence of d in s
*/
static char*
skip(register char* s, register int d)
{
register int c;
register int q;
q = 0;
while (c = *s++)
if (c == q)
q = 0;
else if (c == '\\')
{
if (*s)
s++;
}
else if (!q)
{
if (c == d)
return s - 1;
else if (c == '"' || c == '\'')
q = c;
}
return 0;
}
/*
* copy files out using copyfile
*/
void
{
register char* s;
register char* t;
register char* v;
register int c;
unsigned long flags;
char* mode;
char* mtime;
if (ap)
{
error(3, "%s: archive format %s does not match requested format %s", ap->name, ap->delta->format->name, ap->expected->name);
{
}
}
ftwalk((char*)state.files, copyfile, state.ftwflags|FTW_MULTIPLE, state.exact ? (Ftw_cmp_t)0 : cmpftw);
else
{
for (;;)
{
{
}
break;
else
nospace();
{
if (!(c = *s++))
continue;
if (!(s = skip(s, c)))
continue;
*s++ = 0;
if (!(s = skip(s, c)))
continue;
*s++ = 0;
if (!(s = skip(s, c)))
else
{
*s++ = 0;
if (s = skip(s, c))
*s = 0;
}
for (;;)
{
if (t = strchr(s, ','))
*t = 0;
if (v = strchr(s, '='))
{
*v++ = 0;
}
else
c = 1;
if (s[0] == 'n' && s[1] == 'o')
{
s += 2;
c = !c;
}
{
if (s[0] == 'p')
c = !c;
if (c)
else
{
flags |= FTW_PHYSICAL;
}
}
else if (streq(s, "mode"))
else if (streq(s, "mtime"))
if (!t)
break;
s = t + 1;
}
}
if (c)
{
break;
}
}
}
if (ap)
{
}
}