/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <stdio.h>
#include <ctype.h>
#include <dirent.h>
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pkgstrct.h>
#include <errno.h>
#include <locale.h>
#include <libintl.h>
#include <pkglib.h>
#include "libadm.h"
#include "libinst.h"
extern int holdcinfo;
struct link {
char *path;
};
static int errflg = 0;
static int nflag = 0;
static void usage(void);
int
{
int c;
char *abi_sym_ptr;
extern char *optarg;
extern int optind;
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#endif
(void) textdomain(TEXT_DOMAIN);
(void) set_prog_name(argv[0]);
switch (c) {
case 'x': /* include content info */
xflag++;
break;
case 'n':
nflag++;
break;
case 'c': /* assign class */
/* validate that classname is acceptable */
exit(1);
}
exit(1);
}
}
break;
case 'i': /* follow symlinks */
iflag++;
break;
default:
usage();
}
}
if (iflag) {
/* follow symlinks */
} else {
/* bug id 4244631, not ABI compliant */
}
}
/* take path list from stdin */
}
} else {
}
}
return (errflg ? 1 : 0);
}
static void
{
int len;
int s;
/*
* remove any trailing newline characters from the end of path
*/
}
errflg = 0;
if (xflag) {
errflg++;
logerr(getErrbufAddr());
return;
}
}
/*
* Use averify to figure out the attributes. This has trouble
* divining the identity of a symlink which points to a
* non-existant target. For that reason, if it comes back as
* an existence problem, we fake in a symlink and see if averify
* likes that. If it does, all we have is a risky symlink.
*/
!iflag) {
/* try to read what it points to */
errflg++;
} else
/* It's a link to a file not in this package. */
} else {
errflg++;
}
} else if (s != 0 && s != VE_CONT)
errflg++;
if (errflg) {
logerr(getErrbufAddr());
return;
}
if (n) {
/* replace first n characters with 'local' */
PATH_MAX);
}
if (local[0]) {
} else
PATH_MAX);
}
exit(99);
}
}
}
static void
{
char *pt,
int n;
errflg = 0;
*pt++ = '\0';
if (n >= PATH_MAX) {
errflg++;
return;
}
if (n < PATH_MAX) {
} else {
errflg++;
return;
}
} else {
n = 0;
local[0] = '\0';
}
errflg++;
return;
}
exit(1);
}
errflg++;
}
} else
}
/*
* Scan a raw link for origination errors. Given
* and
* we don't want the link to be verbatim since link_name must be relative
* to it's source. This functions checks for identical directory paths
* and if it's clearly a misplaced relative path, the duplicate
* directories are stripped. This is necessary because pkgadd is actually
*
* NOTE : The buffer we get with targ_name is going to be used later
* and cannot be modified. That's why we have yet another PATH_MAX
* size buffer in this function.
*/
static char *
{
/*
* If the link is absolute or it is in the current directory, no
* further testing necessary.
*/
/*
* This will be walked down to the highest directory
* not common to both the link and the target.
*/
/*
* At this point targ_name is a relative path through at
* least one directory.
*/
file_name++; /* point to the name not the '/' */
/*
* Scan across the pathname until we reach a different
* directory or the final file name.
*/
do {
if (next_dir)
next_dir++; /* point to name not '/' */
else /* point to the end of the string */
/* length to compare */
/*
* If both paths begin with the same directory, then
* skip that common directory in both the link and
* the target.
*/
/* point to the target so far */
/* Skip past it in the target */
/* Skip past it in the link */
/*
* If these directories don't match then the
* directory above is the lowest common directory. We
* need to construct a relative path from the lowest
* child up to that directory.
*/
} else {
int d = 0;
/* Count the intermediate directories. */
dptr++;
d++;
}
/*
* Now targ_ptr is pointing to the fork in
* the path and dptr is pointing to the lowest
* child in the link. We now insert the
* appropriate number of "../'s" to get to
* the first common directory. We'll
* construct this in the construction
* buffer.
*/
if (d) {
char *tptr;
while (d--) {
"../", PATH_MAX);
tptr += 3;
}
PATH_MAX);
}
break; /* done */
}
}
return (const_ptr);
}
static void
{
int n;
errflg++;
}
if (!iflag) {
if (n <= 0) {
errflg++;
"unknown", PATH_MAX);
} else {
}
}
return;
}
return;
return;
PATH_MAX);
return;
}
}
exit(1);
}
if (firstlink) {
} else
}
static void
usage(void)
{
exit(1);
/*NOTREACHED*/
}