|
|
f66f53 |
/**************************************************************/
|
|
|
f66f53 |
/* tpax: a topological pax implementation */
|
|
|
f66f53 |
/* Copyright (C) 2020--2024 SysDeer Technologies, LLC */
|
|
|
f66f53 |
/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */
|
|
|
f66f53 |
/**************************************************************/
|
|
|
f66f53 |
|
|
|
f66f53 |
#include <stdint.h>
|
|
|
f66f53 |
#include <stdlib.h>
|
|
|
f66f53 |
#include <string.h>
|
|
|
f66f53 |
#include <unistd.h>
|
|
|
f66f53 |
#include <fcntl.h>
|
|
|
f66f53 |
#include <errno.h>
|
|
|
f66f53 |
#include <grp.h>
|
|
|
f66f53 |
#include <pwd.h>
|
|
|
f66f53 |
#include <sys/stat.h>
|
|
|
f66f53 |
|
|
|
f66f53 |
#include <tpax/tpax.h>
|
|
|
f66f53 |
#include <tpax/tpax_specs.h>
|
|
|
f66f53 |
#include "tpax_driver_impl.h"
|
|
|
f66f53 |
|
|
|
f66f53 |
#ifndef ssizeof
|
|
|
f66f53 |
#define ssizeof(x) (ssize_t)(sizeof(x))
|
|
|
f66f53 |
#endif
|
|
|
f66f53 |
|
|
|
f66f53 |
#define TPAX_CPIO_PERM_MASK \
|
|
|
f66f53 |
( S_ISUID | S_ISGID \
|
|
|
f66f53 |
| S_IRUSR | S_IWUSR | S_IXUSR \
|
|
|
f66f53 |
| S_IRGRP | S_IWGRP | S_IXGRP \
|
|
|
f66f53 |
| S_IROTH | S_IWOTH | S_IXOTH )
|
|
|
f66f53 |
|
|
|
f66f53 |
static void tpax_octal_write(char * ch, ssize_t len, uint64_t val)
|
|
|
f66f53 |
{
|
|
|
f66f53 |
for (; len; ) {
|
|
|
f66f53 |
ch[--len] = val % 8 + '0';
|
|
|
f66f53 |
val /= 8;
|
|
|
f66f53 |
}
|
|
|
f66f53 |
}
|
|
|
f66f53 |
|
|
|
f66f53 |
int tpax_meta_init_cpio_header(
|
|
|
f66f53 |
const char * path,
|
|
|
f66f53 |
const struct stat * st,
|
|
|
f66f53 |
const char * linkname,
|
|
|
f66f53 |
int cdev,
|
|
|
f66f53 |
int cino,
|
|
|
f66f53 |
int cnlink,
|
|
|
f66f53 |
struct tpax_cpio_header * chdr)
|
|
|
f66f53 |
{
|
|
|
f66f53 |
size_t fnsize;
|
|
|
f66f53 |
size_t lnklen;
|
|
|
f66f53 |
size_t stsize;
|
|
|
f66f53 |
int64_t stmtim;
|
|
|
f66f53 |
uint32_t typeflag;
|
|
|
f66f53 |
uint32_t permbits;
|
|
|
f66f53 |
uint32_t modebits;
|
|
|
f66f53 |
|
|
|
f66f53 |
/* filename size */
|
|
|
f66f53 |
fnsize = strlen(path) + 1;
|
|
|
f66f53 |
|
|
|
f66f53 |
/* size & mtime validation */
|
|
|
f66f53 |
stsize = S_ISREG(st->st_mode) ? st->st_size : 0;
|
|
|
f66f53 |
stmtim = st->st_mtim.tv_sec;
|
|
|
f66f53 |
|
|
|
f66f53 |
if (stsize > 077777777777)
|
|
|
f66f53 |
return -1;
|
|
|
f66f53 |
|
|
|
f66f53 |
if ((stmtim < 0) || (stmtim > 077777777777))
|
|
|
f66f53 |
return -1;
|
|
|
f66f53 |
|
|
|
f66f53 |
/* linkname validation */
|
|
|
f66f53 |
if (S_ISLNK(st->st_mode) && !linkname)
|
|
|
f66f53 |
return -1;
|
|
|
f66f53 |
|
|
|
f66f53 |
lnklen = S_ISLNK(st->st_mode)
|
|
|
f66f53 |
? strlen(linkname)
|
|
|
f66f53 |
: 0;
|
|
|
f66f53 |
|
|
|
f66f53 |
/* typeflag validation */
|
|
|
f66f53 |
if (S_ISREG(st->st_mode))
|
|
|
f66f53 |
typeflag = TPAX_CPIO_FILEMODE_ISREG;
|
|
|
f66f53 |
else if (S_ISLNK(st->st_mode))
|
|
|
f66f53 |
typeflag = TPAX_CPIO_FILEMODE_ISLNK;
|
|
|
f66f53 |
else if (S_ISDIR(st->st_mode))
|
|
|
f66f53 |
typeflag = TPAX_CPIO_FILEMODE_ISDIR;
|
|
|
f66f53 |
else if (S_ISCHR(st->st_mode))
|
|
|
f66f53 |
typeflag = TPAX_CPIO_FILEMODE_ISCHR;
|
|
|
f66f53 |
else if (S_ISBLK(st->st_mode))
|
|
|
f66f53 |
typeflag = TPAX_CPIO_FILEMODE_ISBLK;
|
|
|
f66f53 |
else if (S_ISFIFO(st->st_mode))
|
|
|
f66f53 |
typeflag = TPAX_CPIO_FILEMODE_ISFIFO;
|
|
|
f66f53 |
else if (S_ISSOCK(st->st_mode))
|
|
|
f66f53 |
typeflag = TPAX_CPIO_FILEMODE_ISSOCK;
|
|
|
f66f53 |
else
|
|
|
f66f53 |
return -1;
|
|
|
f66f53 |
|
|
|
f66f53 |
/* permbits, modeflag */
|
|
|
f66f53 |
permbits = st->st_mode & TPAX_CPIO_PERM_MASK;
|
|
|
f66f53 |
modebits = permbits | typeflag;
|
|
|
f66f53 |
|
|
|
f66f53 |
/* one shot */
|
|
|
f66f53 |
memset(chdr,0,sizeof(*chdr));
|
|
|
f66f53 |
|
|
|
f66f53 |
/* c_magic */
|
|
|
f66f53 |
chdr->c_magic[0] = '0';
|
|
|
f66f53 |
chdr->c_magic[1] = '7';
|
|
|
f66f53 |
chdr->c_magic[2] = '0';
|
|
|
f66f53 |
chdr->c_magic[3] = '7';
|
|
|
f66f53 |
chdr->c_magic[4] = '0';
|
|
|
f66f53 |
chdr->c_magic[5] = '7';
|
|
|
f66f53 |
|
|
|
f66f53 |
/* c_dev, c_ino */
|
|
|
f66f53 |
tpax_octal_write(chdr->c_dev,ssizeof(chdr->c_dev),cdev);
|
|
|
f66f53 |
tpax_octal_write(chdr->c_ino,ssizeof(chdr->c_ino),cino);
|
|
|
f66f53 |
|
|
|
f66f53 |
/* c_mode */
|
|
|
f66f53 |
tpax_octal_write(chdr->c_mode,ssizeof(chdr->c_mode),modebits);
|
|
|
f66f53 |
|
|
|
f66f53 |
/* c_uid, c_gid */
|
|
|
f66f53 |
if ((uint64_t)st->st_uid <= 0777777)
|
|
|
f66f53 |
tpax_octal_write(chdr->c_uid,ssizeof(chdr->c_uid),st->st_uid);
|
|
|
f66f53 |
else
|
|
|
f66f53 |
tpax_octal_write(chdr->c_uid,ssizeof(chdr->c_uid),0);
|
|
|
f66f53 |
|
|
|
f66f53 |
if ((uint64_t)st->st_gid <= 0777777)
|
|
|
f66f53 |
tpax_octal_write(chdr->c_gid,ssizeof(chdr->c_gid),st->st_gid);
|
|
|
f66f53 |
else
|
|
|
f66f53 |
tpax_octal_write(chdr->c_gid,ssizeof(chdr->c_gid),0);
|
|
|
f66f53 |
|
|
|
f66f53 |
/* c_nlink */
|
|
|
f66f53 |
tpax_octal_write(chdr->c_nlink,ssizeof(chdr->c_nlink),cnlink);
|
|
|
f66f53 |
|
|
|
f66f53 |
/* c_rdev */
|
|
|
f66f53 |
tpax_octal_write(chdr->c_rdev,ssizeof(chdr->c_rdev),st->st_rdev);
|
|
|
f66f53 |
|
|
|
f66f53 |
/* c_mtime */
|
|
|
f66f53 |
tpax_octal_write(chdr->c_mtime,ssizeof(chdr->c_mtime),stmtim);
|
|
|
f66f53 |
|
|
|
f66f53 |
/* c_namesize */
|
|
|
f66f53 |
tpax_octal_write(chdr->c_namesize,ssizeof(chdr->c_namesize),fnsize);
|
|
|
f66f53 |
|
|
|
f66f53 |
/* c_filesize */
|
|
|
f66f53 |
tpax_octal_write(chdr->c_filesize,ssizeof(chdr->c_filesize),lnklen ? lnklen : stsize);
|
|
|
f66f53 |
|
|
|
f66f53 |
/* all done; c_name to be written along with c_filedata */
|
|
|
f66f53 |
return 0;
|
|
|
f66f53 |
}
|