/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1987-2011 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
/*
* pax { asc aschk binary cpio } formats
*/
#include "format.h"
#define CPIO_ALIGN 0
typedef struct Binary_header_s
{
short magic;
unsigned short dev;
unsigned short ino;
unsigned short mode;
unsigned short uid;
unsigned short gid;
short links;
unsigned short rdev;
short namesize;
typedef struct Localstat_s
{
long dev;
long ino;
long mode;
long uid;
long gid;
long nlink;
long rdev;
long mtime;
long dev_major;
long dev_minor;
long rdev_major;
long rdev_minor;
long checksum;
} Localstat_t;
typedef struct Cpio_s
{
int trailer;
#if CPIO_EXTENDED
#endif
} Cpio_t;
#if CPIO_EXTENDED
/*
* get and execute extended ops from input
*/
static void
{
register char* p;
register char* s;
register int c;
for (p = f->name + c; c = *p++;)
{
for (s = p; *p; p++);
p++;
switch (c)
{
case 'd':
break;
case 'g':
break;
case 's':
break;
case 'u':
break;
case 'G':
f->gidname = s;
break;
case 'U':
f->uidname = s;
break;
/*
* NOTE: ignore unknown ops for future extensions
*/
}
}
}
/*
* set end of extended ops
*/
static void
{
register int n;
{
n++;
if ((f->namesize += n) > CPIO_NAMESIZE)
}
}
/*
* output filename and extended ops
*/
static void
{
register int n;
if (n)
}
/*
* add extended op string
*/
static void
{
if (p < e)
{
*p++ = op;
while (*s && p < e)
*p++ = *s++;
*p++ = 0;
}
#if DEBUG
if (*s)
#endif
}
/*
* add extended op number
*/
static void
{
}
#endif
static int
{
{
}
else
{
nospace();
}
#if CPIO_EXTENDED
#endif
return 1;
}
static int
cpio_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
{
int magic;
if (size >= CPIO_HEADER && buf[0] == '0' && sfsscanf((char*)buf, "%6o", &magic) == 1 && magic == CPIO_MAGIC)
return 0;
}
static int
{
char* s;
f->linkpath = 0;
f->uidname = 0;
f->gidname = 0;
{
case BINARY:
break;
case ASC:
case ASCHK:
header = ASC_HEADER;
break;
default:
align = 0;
break;
}
if (align)
{
else
align = 0;
}
{
error(state.keepgoing ? 1 : 3, "%s: entry %d.%d file name terminating null missing", ap->name, ap->volume, ap->entry);
}
#if CPIO_EXTENDED
#endif
{
getdeltaheader(ap, f);
return 0;
}
{
case X_IFBLK:
case X_IFCHR:
case X_IFDIR:
case X_IFIFO:
case X_IFLNK:
case X_IFREG:
case X_IFSOCK:
break;
default:
break;
}
switch (f->type)
{
case X_IFLNK:
s = f->linkpath;
{
if (!*s++)
break;
{
*s = 0;
break;
}
}
break;
default:
break;
}
return 1;
}
static int
{
{
}
return 0;
}
static int
{
return 0;
if (state.tmp.buffer[0] == '0' && sfsscanf(state.tmp.buffer, "%6o%6lo%6lo%6lo%6lo%6lo%6lo%6lo%11lo%6o%11I*o",
&f->magic,
&f->namesize,
{
}
return 0;
}
static int
{
{
error(2, "%s: %s format corrupt -- epilogue (%s) not found", ap->name, ap->format->name, CPIO_TRAILER);
return -1;
}
return 0;
}
static int
{
}
static int
{
#if CPIO_EXTENDED
{
getidnames(f);
#endif
}
else
#endif
{
}
sfsprintf(state.tmp.buffer, state.tmp.buffersize, "%0.6lo%0.6lo%0.6lo%0.6lo%0.6lo%0.6lo%0.6lo%0.6lo%0.11lo%0.6o%0.11I*o",
(long)CPIO_TRUNCATE(CPIO_MAGIC),
(long)f->namesize,
#if CPIO_EXTENDED
#else
#endif
{
putdeltaheader(ap, f);
}
return 1;
}
static off_t
{
putinfo(ap, strcpy(buf, CPIO_TRAILER), ap->delta && !(ap->delta->format->flags & PSEUDO) ? ap->delta->index + 1 : 0, 0);
}
static int
{
off_t n;
switch (event)
{
case PAX_EVENT_BUG_19951031:
/*
* compensate for a pre 19951031 pax bug
* that added linknamesize to st_size
*/
if (f->st->st_size == f->linkpathsize && paxread(pax, ap, state.tmp.buffer, (off_t)0, n = f->st->st_size + 6, 0) > 0)
{
if (strtol(state.tmp.buffer, NiL, 8) == CPIO_MAGIC && strtol(state.tmp.buffer + f->st->st_size, NiL, 8) != CPIO_MAGIC)
{
if (!ap->warnlinkhead)
{
}
}
}
return 1;
case PAX_EVENT_DELTA_EXTEND:
return 1;
}
return 0;
}
static int
asc_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
{
unsigned int magic;
if (size >= ASC_HEADER && buf[0] == '0' && sfsscanf((char*)buf, "%6o", &magic) == 1 && magic == ASC_MAGIC)
return 0;
}
static int
{
return 0;
if (state.tmp.buffer[0] == '0' && sfsscanf(state.tmp.buffer, "%6o%8lx%8lx%8lx%8lx%8lx%8lx%8I*x%8lx%8lx%8lx%8lx%8x%8lx",
&f->magic,
&f->namesize,
{
}
return 0;
}
static int
{
int n;
f->checksum = 0;
sfsprintf(state.tmp.buffer, state.tmp.buffersize, "%0.6lo%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx%0.8lx",
(long)f->namesize,
f->checksum);
while (n++ < ASC_ALIGN)
return 1;
}
static int
aschk_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
{
unsigned int magic;
if (size >= ASC_HEADER && buf[0] == '0' && sfsscanf((char*)buf, "%6o", &magic) == 1 && magic == ASCHK_MAGIC)
return 0;
}
static int
{
return 0;
if (state.tmp.buffer[0] == '0' && sfsscanf(state.tmp.buffer, "%6o%8lx%8lx%8lx%8lx%8lx%8lx%8I*x%8lx%8lx%8lx%8lx%8x%8lx",
&f->magic,
&f->namesize,
{
}
return 0;
}
static unsigned long
aschk_checksum(Pax_t* pax, Archive_t* ap, File_t* f, void* ab, size_t n, register unsigned long sum)
{
register unsigned char* b = (unsigned char*)ab;
register unsigned char* e;
e = b + n;
while (b < e)
sum += *b++;
return sum;
}
/*
* convert binary header shorts to long
*/
static long
binary_long(register unsigned short* s)
{
Integral_t u;
u.l = 1;
if (u.c[0])
{
u.s[0] = s[1];
u.s[1] = s[0];
}
else
{
u.s[0] = s[0];
u.s[1] = s[1];
}
return u.l;
}
/*
* convert long to binary header shorts
*/
static void
binary_short(register unsigned short* s, long n)
{
Integral_t u;
u.l = 1;
if (u.c[0])
{
u.l = n;
s[0] = u.s[1];
s[1] = u.s[0];
}
else
{
u.l = n;
s[0] = u.s[0];
s[1] = u.s[1];
}
}
static int
binary_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
{
int swap;
{
}
return 0;
}
static int
{
return 0;
{
}
if (f->magic == CPIO_MAGIC)
{
}
return 0;
}
static int
{
int n;
while (n++ < BINARY_ALIGN)
{
putdeltaheader(ap, f);
}
return 1;
}
static int
{
{
return 0;
}
return 1;
}
{
"asc",
0,
"s5r4 extended cpio character",
ASC,
4,
0,
0,
0,
0,
0,
0,
0,
0
};
{
"aschk",
0,
"s5r4 extended cpio character with checksum",
4,
0,
0,
0,
0,
0,
0,
0,
};
{
"binary",
"binary-cpio",
"cpio binary with symlinks",
2,
0,
0,
0,
0,
0,
0,
0,
0,
};
{
"cpio",
0,
"cpio character with symlinks",
CPIO,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
};