cpiotranslate.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* This utility takes a list of arguments specifying directories with
* packages, and a cpio archive on standard input. Standard output
* will have a modified version of the cpio archive with mode, uid,
* and gid fixed according to the packaging. Standard error will list
* the files that don't have corresponding packaging information.
*
* This utility supports "ASC" (cpio -c; "070701") type archives only.
* This is what the mkbfu utility uses.
*
* It assumes that the local system architecture and the proto area
* architecture are the same. The wrong packages will be used if this
* is not true.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <archives.h>
#include <string.h>
#include "list.h"
#include "protodir.h"
#include "proto_list.h"
#include "exception_list.h"
#include "stdusers.h"
static const char *myname;
#define MAX_EXCEPT_LIST 5
static const char *except_file[MAX_EXCEPT_LIST];
static int except_count;
static void
usage(void)
{
myname);
exit(1);
}
int
{
char buffer[65536];
int hsize;
char extra;
int chr;
int errflg = 0;
int verbose = 0;
myname = "cpiotranslate";
switch (chr) {
case 'v':
verbose++;
break;
case 'e':
if (except_count >= MAX_EXCEPT_LIST)
errflg++;
else
break;
default:
errflg++;
break;
}
}
if (errflg != 0)
usage();
/* Allows selection of previous BFU behavior */
while (--except_count >= 0) {
}
/* Read in all the packaging information */
} else {
return (1);
}
optind++;
}
/* Process the cpio stream, one file at a time. */
inoffset = 0;
for (;;) {
/* Read the next cpio header */
return (0);
}
if (hsize == -1) {
perror("cpio input");
break;
}
"%s: bad cpio header; only %d bytes\n",
break;
}
/* Get the data we care about: mode and name sizes */
"%s: bad cpio header; cannot read file size\n",
myname);
if (verbose != 0)
break;
}
/* Read in file name; account for padding */
"%s: bad cpio header; file name size %lu\n",
break;
}
if ((nsize & 3) != 0)
if (hsize == -1) {
"%s: missing file name\n", myname);
} else {
perror("cpio input");
}
break;
}
myname);
break;
}
#ifdef DEBUG
if (verbose) {
"'%s' at offset %d: nlen %lu flen %lu\n",
filesize);
}
#endif
/* Locate file name in packaging information database */
goto skip_update;
}
}
/*
* If it's on the exception list, remove it
* from the archive. It's not part of the
* system.
*/
if (verbose) {
"%s: %s: removed; exception list\n",
}
/*
* Cannot use fseek here because input
* is usually a pipeline.
*/
if (filesize & 3)
while (filesize > 0) {
perror("cpio read");
goto failure;
}
if (hsize != -1)
"%s: cpio file truncated\n",
myname);
goto failure;
}
}
continue;
}
}
/*
* No mode, user, group on symlinks in the packaging
* information. Leave mode alone and set user and
* group to 'root' (0). This is what a netinstall
* would do.
*/
uid = 0;
gid = 3;
if (!no_unknowns) {
"%s: %s: no packaging info\n", myname,
goto skip_update;
}
} else {
"%s: %s: user '%s' unknown\n", myname,
uid = 0;
}
"%s: %s: group '%s' unknown\n", myname,
gid = 3;
}
}
/* save character overwritten by sprintf's NUL terminator. */
/* snprintf not needed; cannot possibly overflow */
/* recover char overwritten with NUL by sprintf above. */
/* Write out the updated header information */
if (hsize == -1) {
perror("cpio output");
break;
}
myname);
break;
}
if (trailer_copy) {
if (chr == '0')
continue;
}
/* Copy the file data */
while (filesize > 0) {
if (nsize & 3)
perror("cpio read");
goto failure;
}
if (hsize != -1)
"%s: cpio file truncated\n",
myname);
goto failure;
}
if (hsize == -1) {
perror("cpio output");
goto failure;
}
"%s: cpio output disk full\n", myname);
goto failure;
}
break;
}
}
if (verbose != 0) {
}
return (1);
}