5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER START
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The contents of this file are subject to the terms of the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Common Development and Distribution License (the "License").
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You may not use this file except in compliance with the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * or http://www.opensolaris.org/os/licensing.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * See the License for the specific language governing permissions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and limitations under the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If applicable, add the following below this CDDL HEADER, with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER END
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* All Rights Reserved */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore/*
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <locale.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libintl.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdio.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <signal.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdlib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <unistd.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <string.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <pkgtrans.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <pkglib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <pkglocs.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libadm.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libinst.h>
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore#include <messages.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int options;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic keystore_handle_t keystore = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void usage(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void trap(int signo);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define KEYSTORE_OPEN "Retrieving signing certificates from keystore <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandmain(int argc, char *argv[])
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int c;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland void (*func)();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland extern char *optarg;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland extern int optind;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *keystore_alias = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *keystore_file = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland boolean_t create_sig = B_FALSE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *homedir = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKG_ERR *err;
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore int ret, len;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) setlocale(LC_ALL, "");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define TEXT_DOMAIN "SYS_TEST"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#endif
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) textdomain(TEXT_DOMAIN);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) set_prog_name(argv[0]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while ((c = getopt(argc, argv, "ga:P:k:snio?")) != EOF) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland switch (c) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 'n':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland options |= PT_RENAME;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 'i':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland options |= PT_INFO_ONLY;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 'o':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland options |= PT_OVERWRITE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 's':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland options |= PT_ODTSTREAM;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 'g':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* this should eventually be a PT_ option */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland create_sig = B_TRUE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 'k':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keystore_file = optarg;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 'a':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keystore_alias = optarg;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case 'P':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland set_passphrase_passarg(optarg);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ci_strneq(optarg, "pass:", 5)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * passwords on the command line are highly
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * insecure. complain.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore logerr(PASSWD_CMDLINE, "pass:<pass>");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland default:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland usage();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland func = signal(SIGINT, trap);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (func != SIG_DFL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGINT, func);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGHUP, trap);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGQUIT, trap);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGTERM, trap);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGPIPE, trap);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGPWR, trap);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((argc-optind) < 2) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland usage();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (create_sig) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sec_init();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland err = pkgerr_new();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* figure out which keystore to use */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keystore_file == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (geteuid() == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* we are superuser, so use their keystore */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keystore_file = PKGSEC;
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore } else if ((homedir = getenv("HOME")) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * not superuser, but no home dir, so
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * use superuser's keystore
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore keystore_file = PKGSEC;
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore } else if (asprintf(&keystore_file, "%s/.pkg/security",
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore homedir) < 0) {
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore logerr(ERR_MEM);
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext(KEYSTORE_OPEN), keystore_file);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
382f00c9f2bd34208f10bb7d2be96bc6696eb8c4Garrett D'Amore set_passphrase_prompt(MSG_PASSPROMPT);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* open keystore for reading */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (open_keystore(err, keystore_file, get_prog_name(),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkg_passphrase_cb, KEYSTORE_DFLT_FLAGS, &keystore) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgerr(err);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgerr_free(err);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* no signature, so don't use a keystore */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keystore = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ret = pkgtrans(flex_device(argv[optind], 1),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland flex_device(argv[optind+1], 1), &argv[optind+2], options,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keystore, keystore_alias);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (create_sig) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* close keystore */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (close_keystore(err, keystore, NULL) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgerr(err);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgerr_free(err);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keystore = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(ret);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*NOTREACHED*/
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandquit(int retcode)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKG_ERR *err;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland err = pkgerr_new();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGINT, SIG_IGN);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGHUP, SIG_IGN);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) pkghead(NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keystore != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) close_keystore(err, keystore, NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgerr_free(err);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland exit(retcode);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandtrap(int signo)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGINT, SIG_IGN);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) signal(SIGHUP, SIG_IGN);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (signo == SIGINT) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext("aborted at user request.\n"));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(3);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext("aborted by signal %d\n"), signo);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandusage(void)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fprintf(stderr,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland gettext("usage: %s [-ionsg] [-k keystore] " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "[-a alias] [-P password] srcdev dstdev [pkg [pkg...]]\n"),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland get_prog_name());
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}