1d192f3d3SKai Wang /*- 2d192f3d3SKai Wang * Copyright (c) 2007 Kai Wang 3d192f3d3SKai Wang * Copyright (c) 2007 Tim Kientzle 4d192f3d3SKai Wang * Copyright (c) 2007 Joseph Koshy 5d192f3d3SKai Wang * All rights reserved. 6d192f3d3SKai Wang * 7d192f3d3SKai Wang * Redistribution and use in source and binary forms, with or without 8d192f3d3SKai Wang * modification, are permitted provided that the following conditions 9d192f3d3SKai Wang * are met: 10d192f3d3SKai Wang * 1. Redistributions of source code must retain the above copyright 11d192f3d3SKai Wang * notice, this list of conditions and the following disclaimer 12d192f3d3SKai Wang * in this position and unchanged. 13d192f3d3SKai Wang * 2. Redistributions in binary form must reproduce the above copyright 14d192f3d3SKai Wang * notice, this list of conditions and the following disclaimer in the 15d192f3d3SKai Wang * documentation and/or other materials provided with the distribution. 16d192f3d3SKai Wang * 17d192f3d3SKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 18d192f3d3SKai Wang * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19d192f3d3SKai Wang * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20d192f3d3SKai Wang * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 21d192f3d3SKai Wang * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22d192f3d3SKai Wang * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23d192f3d3SKai Wang * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24d192f3d3SKai Wang * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25d192f3d3SKai Wang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26d192f3d3SKai Wang * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27d192f3d3SKai Wang */ 28d192f3d3SKai Wang 29d192f3d3SKai Wang /*- 30d192f3d3SKai Wang * Copyright (c) 1990, 1993, 1994 31d192f3d3SKai Wang * The Regents of the University of California. All rights reserved. 32d192f3d3SKai Wang * 33d192f3d3SKai Wang * This code is derived from software contributed to Berkeley by 34d192f3d3SKai Wang * Hugh Smith at The University of Guelph. 35d192f3d3SKai Wang * 36d192f3d3SKai Wang * Redistribution and use in source and binary forms, with or without 37d192f3d3SKai Wang * modification, are permitted provided that the following conditions 38d192f3d3SKai Wang * are met: 39d192f3d3SKai Wang * 1. Redistributions of source code must retain the above copyright 40d192f3d3SKai Wang * notice, this list of conditions and the following disclaimer. 41d192f3d3SKai Wang * 2. Redistributions in binary form must reproduce the above copyright 42d192f3d3SKai Wang * notice, this list of conditions and the following disclaimer in the 43d192f3d3SKai Wang * documentation and/or other materials provided with the distribution. 44d192f3d3SKai Wang * 3. Neither the name of the University nor the names of its contributors 45d192f3d3SKai Wang * may be used to endorse or promote products derived from this software 46d192f3d3SKai Wang * without specific prior written permission. 47d192f3d3SKai Wang * 48d192f3d3SKai Wang * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49d192f3d3SKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50d192f3d3SKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51d192f3d3SKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52d192f3d3SKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53d192f3d3SKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54d192f3d3SKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55d192f3d3SKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56d192f3d3SKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57d192f3d3SKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58d192f3d3SKai Wang * SUCH DAMAGE. 59d192f3d3SKai Wang */ 60d192f3d3SKai Wang 61d192f3d3SKai Wang #include <sys/cdefs.h> 62d192f3d3SKai Wang __FBSDID("$FreeBSD$"); 63d192f3d3SKai Wang 64d192f3d3SKai Wang #include <sys/queue.h> 65d192f3d3SKai Wang #include <sys/types.h> 66d192f3d3SKai Wang #include <archive.h> 67d192f3d3SKai Wang #include <errno.h> 68d192f3d3SKai Wang #include <getopt.h> 69d192f3d3SKai Wang #include <libgen.h> 70d192f3d3SKai Wang #include <stdio.h> 71d192f3d3SKai Wang #include <stdlib.h> 72d192f3d3SKai Wang #include <string.h> 73d192f3d3SKai Wang #include <sysexits.h> 74d192f3d3SKai Wang 75d192f3d3SKai Wang #include "ar.h" 76d192f3d3SKai Wang 77d192f3d3SKai Wang enum options 78d192f3d3SKai Wang { 79d192f3d3SKai Wang OPTION_HELP 80d192f3d3SKai Wang }; 81d192f3d3SKai Wang 82d192f3d3SKai Wang static struct option longopts[] = 83d192f3d3SKai Wang { 84d192f3d3SKai Wang {"help", no_argument, NULL, OPTION_HELP}, 85d192f3d3SKai Wang {"version", no_argument, NULL, 'V'}, 86d192f3d3SKai Wang {NULL, 0, NULL, 0} 87d192f3d3SKai Wang }; 88d192f3d3SKai Wang 89d192f3d3SKai Wang static void bsdar_usage(void); 90d192f3d3SKai Wang static void ranlib_usage(void); 91d192f3d3SKai Wang static void set_mode(struct bsdar *bsdar, char opt); 92d192f3d3SKai Wang static void only_mode(struct bsdar *bsdar, const char *opt, 93d192f3d3SKai Wang const char *valid_modes); 94d192f3d3SKai Wang static void bsdar_version(void); 95d192f3d3SKai Wang static void ranlib_version(void); 96d192f3d3SKai Wang 97d192f3d3SKai Wang int 98d192f3d3SKai Wang main(int argc, char **argv) 99d192f3d3SKai Wang { 100d192f3d3SKai Wang struct bsdar *bsdar, bsdar_storage; 101d192f3d3SKai Wang char *p; 102d192f3d3SKai Wang size_t len; 103d192f3d3SKai Wang int i, opt; 104d192f3d3SKai Wang 105d192f3d3SKai Wang bsdar = &bsdar_storage; 106d192f3d3SKai Wang memset(bsdar, 0, sizeof(*bsdar)); 107d192f3d3SKai Wang 108d192f3d3SKai Wang if ((bsdar->progname = getprogname()) == NULL) 109d192f3d3SKai Wang bsdar->progname = "ar"; 110d192f3d3SKai Wang 111f05da0e9STim Kientzle /* Act like ranlib if our name ends in "ranlib"; this 112f05da0e9STim Kientzle * accomodates arm-freebsd7.1-ranlib, bsdranlib, etc. */ 113f05da0e9STim Kientzle len = strlen(bsdar->progname); 114f05da0e9STim Kientzle if (len >= strlen("ranlib") && 115f05da0e9STim Kientzle strcmp(bsdar->progname + len - strlen("ranlib"), "ranlib") == 0) { 116d192f3d3SKai Wang while ((opt = getopt_long(argc, argv, "tV", longopts, 117d192f3d3SKai Wang NULL)) != -1) { 118d192f3d3SKai Wang switch(opt) { 119d192f3d3SKai Wang case 't': 120d192f3d3SKai Wang /* Ignored. */ 121d192f3d3SKai Wang break; 122d192f3d3SKai Wang case 'V': 123d192f3d3SKai Wang ranlib_version(); 124d192f3d3SKai Wang break; 125d192f3d3SKai Wang case OPTION_HELP: 126d192f3d3SKai Wang ranlib_usage(); 127d192f3d3SKai Wang default: 128d192f3d3SKai Wang ranlib_usage(); 129d192f3d3SKai Wang } 130d192f3d3SKai Wang } 131d192f3d3SKai Wang argv += optind; 132d192f3d3SKai Wang argc -= optind; 133d192f3d3SKai Wang 134d192f3d3SKai Wang if (*argv == NULL) 135d192f3d3SKai Wang ranlib_usage(); 136d192f3d3SKai Wang 137d192f3d3SKai Wang bsdar->options |= AR_S; 138d192f3d3SKai Wang for (;(bsdar->filename = *argv++) != NULL;) 139d192f3d3SKai Wang ar_mode_s(bsdar); 140d192f3d3SKai Wang 141d192f3d3SKai Wang exit(EX_OK); 142d192f3d3SKai Wang } else { 143d192f3d3SKai Wang if (argc < 2) 144d192f3d3SKai Wang bsdar_usage(); 145d192f3d3SKai Wang 146d192f3d3SKai Wang if (*argv[1] != '-') { 147d192f3d3SKai Wang len = strlen(argv[1]) + 2; 148d192f3d3SKai Wang if ((p = malloc(len)) == NULL) 149d192f3d3SKai Wang bsdar_errc(bsdar, EX_SOFTWARE, errno, 150d192f3d3SKai Wang "malloc failed"); 151d192f3d3SKai Wang *p = '-'; 152d192f3d3SKai Wang (void)strlcpy(p + 1, argv[1], len - 1); 153d192f3d3SKai Wang argv[1] = p; 154d192f3d3SKai Wang } 155d192f3d3SKai Wang } 156d192f3d3SKai Wang 1570c099281SKai Wang while ((opt = getopt_long(argc, argv, "abCcdfijlMmopqrSsTtuVvxz", 158d192f3d3SKai Wang longopts, NULL)) != -1) { 159d192f3d3SKai Wang switch(opt) { 160d192f3d3SKai Wang case 'a': 161d192f3d3SKai Wang bsdar->options |= AR_A; 162d192f3d3SKai Wang break; 163d192f3d3SKai Wang case 'b': 164d192f3d3SKai Wang case 'i': 165d192f3d3SKai Wang bsdar->options |= AR_B; 166d192f3d3SKai Wang break; 167d192f3d3SKai Wang case 'C': 168d192f3d3SKai Wang bsdar->options |= AR_CC; 169d192f3d3SKai Wang break; 170d192f3d3SKai Wang case 'c': 171d192f3d3SKai Wang bsdar->options |= AR_C; 172d192f3d3SKai Wang break; 173d192f3d3SKai Wang case 'd': 174d192f3d3SKai Wang set_mode(bsdar, opt); 175d192f3d3SKai Wang break; 176d192f3d3SKai Wang case 'f': 177d192f3d3SKai Wang case 'T': 178d192f3d3SKai Wang bsdar->options |= AR_TR; 179d192f3d3SKai Wang break; 180d192f3d3SKai Wang case 'j': 181d192f3d3SKai Wang bsdar->options |= AR_J; 182d192f3d3SKai Wang break; 183d192f3d3SKai Wang case 'l': 184d192f3d3SKai Wang /* ignored, for GNU ar comptibility */ 185d192f3d3SKai Wang break; 1860c099281SKai Wang case 'M': 1870c099281SKai Wang set_mode(bsdar, opt); 1880c099281SKai Wang break; 189d192f3d3SKai Wang case 'm': 190d192f3d3SKai Wang set_mode(bsdar, opt); 191d192f3d3SKai Wang break; 192d192f3d3SKai Wang case 'o': 193d192f3d3SKai Wang bsdar->options |= AR_O; 194d192f3d3SKai Wang break; 195d192f3d3SKai Wang case 'p': 196d192f3d3SKai Wang set_mode(bsdar, opt); 197d192f3d3SKai Wang break; 198d192f3d3SKai Wang case 'q': 199d192f3d3SKai Wang set_mode(bsdar, opt); 200d192f3d3SKai Wang break; 201d192f3d3SKai Wang case 'r': 202d192f3d3SKai Wang set_mode(bsdar, opt); 203d192f3d3SKai Wang break; 204d192f3d3SKai Wang case 'S': 205d192f3d3SKai Wang bsdar->options |= AR_SS; 206d192f3d3SKai Wang break; 207d192f3d3SKai Wang case 's': 208d192f3d3SKai Wang bsdar->options |= AR_S; 209d192f3d3SKai Wang break; 210d192f3d3SKai Wang case 't': 211d192f3d3SKai Wang set_mode(bsdar, opt); 212d192f3d3SKai Wang break; 213d192f3d3SKai Wang case 'u': 214d192f3d3SKai Wang bsdar->options |= AR_U; 215d192f3d3SKai Wang break; 216d192f3d3SKai Wang case 'V': 217d192f3d3SKai Wang bsdar_version(); 218d192f3d3SKai Wang break; 219d192f3d3SKai Wang case 'v': 220d192f3d3SKai Wang bsdar->options |= AR_V; 221d192f3d3SKai Wang break; 222d192f3d3SKai Wang case 'x': 223d192f3d3SKai Wang set_mode(bsdar, opt); 224d192f3d3SKai Wang break; 225d192f3d3SKai Wang case 'z': 226d192f3d3SKai Wang bsdar->options |= AR_Z; 227d192f3d3SKai Wang break; 228d192f3d3SKai Wang case OPTION_HELP: 229d192f3d3SKai Wang bsdar_usage(); 230d192f3d3SKai Wang default: 231d192f3d3SKai Wang bsdar_usage(); 232d192f3d3SKai Wang } 233d192f3d3SKai Wang } 234d192f3d3SKai Wang 235d192f3d3SKai Wang argv += optind; 236d192f3d3SKai Wang argc -= optind; 237d192f3d3SKai Wang 2380c099281SKai Wang if (*argv == NULL && bsdar->mode != 'M') 239d192f3d3SKai Wang bsdar_usage(); 240d192f3d3SKai Wang 241d192f3d3SKai Wang if (bsdar->options & AR_A && bsdar->options & AR_B) 242d192f3d3SKai Wang bsdar_errc(bsdar, EX_USAGE, 0, 243d192f3d3SKai Wang "only one of -a and -[bi] options allowed"); 244d192f3d3SKai Wang 245d192f3d3SKai Wang if (bsdar->options & AR_J && bsdar->options & AR_Z) 246d192f3d3SKai Wang bsdar_errc(bsdar, EX_USAGE, 0, 247d192f3d3SKai Wang "only one of -j and -z options allowed"); 248d192f3d3SKai Wang 249d192f3d3SKai Wang if (bsdar->options & AR_S && bsdar->options & AR_SS) 250d192f3d3SKai Wang bsdar_errc(bsdar, EX_USAGE, 0, 251d192f3d3SKai Wang "only one of -s and -S options allowed"); 252d192f3d3SKai Wang 253d192f3d3SKai Wang if (bsdar->options & (AR_A | AR_B)) { 254d192f3d3SKai Wang if ((bsdar->posarg = *argv) == NULL) 255d192f3d3SKai Wang bsdar_errc(bsdar, EX_USAGE, 0, 256d192f3d3SKai Wang "no position operand specified"); 257d192f3d3SKai Wang if ((bsdar->posarg = basename(bsdar->posarg)) == NULL) 258d192f3d3SKai Wang bsdar_errc(bsdar, EX_SOFTWARE, errno, 259d192f3d3SKai Wang "basename failed"); 260d192f3d3SKai Wang argc--; 261d192f3d3SKai Wang argv++; 262d192f3d3SKai Wang } 263d192f3d3SKai Wang 264d192f3d3SKai Wang if (bsdar->options & AR_A) 265d192f3d3SKai Wang only_mode(bsdar, "-a", "mqr"); 266d192f3d3SKai Wang if (bsdar->options & AR_B) 267d192f3d3SKai Wang only_mode(bsdar, "-b", "mqr"); 268d192f3d3SKai Wang if (bsdar->options & AR_C) 269d192f3d3SKai Wang only_mode(bsdar, "-c", "qr"); 270d192f3d3SKai Wang if (bsdar->options & AR_CC) 271d192f3d3SKai Wang only_mode(bsdar, "-C", "x"); 272d192f3d3SKai Wang if (bsdar->options & AR_O) 273d192f3d3SKai Wang only_mode(bsdar, "-o", "x"); 274d192f3d3SKai Wang if (bsdar->options & AR_SS) 275d192f3d3SKai Wang only_mode(bsdar, "-S", "mqr"); 276d192f3d3SKai Wang if (bsdar->options & AR_U) 277d192f3d3SKai Wang only_mode(bsdar, "-u", "qrx"); 278d192f3d3SKai Wang 2790c099281SKai Wang if (bsdar->mode == 'M') { 2800c099281SKai Wang ar_mode_script(bsdar); 2810c099281SKai Wang exit(EX_OK); 2820c099281SKai Wang } 2830c099281SKai Wang 284d192f3d3SKai Wang if ((bsdar->filename = *argv) == NULL) 285d192f3d3SKai Wang bsdar_usage(); 286d192f3d3SKai Wang 287d192f3d3SKai Wang bsdar->argc = --argc; 288d192f3d3SKai Wang bsdar->argv = ++argv; 289d192f3d3SKai Wang 290d192f3d3SKai Wang if ((!bsdar->mode || strchr("ptx", bsdar->mode)) && 291d192f3d3SKai Wang bsdar->options & AR_S) { 292d192f3d3SKai Wang ar_mode_s(bsdar); 293d192f3d3SKai Wang if (!bsdar->mode) 294d192f3d3SKai Wang exit(EX_OK); 295d192f3d3SKai Wang } 296d192f3d3SKai Wang 297d192f3d3SKai Wang switch(bsdar->mode) { 298d192f3d3SKai Wang case 'd': 299d192f3d3SKai Wang ar_mode_d(bsdar); 300d192f3d3SKai Wang break; 301d192f3d3SKai Wang case 'm': 302d192f3d3SKai Wang ar_mode_m(bsdar); 303d192f3d3SKai Wang break; 304d192f3d3SKai Wang case 'p': 305d192f3d3SKai Wang ar_mode_p(bsdar); 306d192f3d3SKai Wang break; 307d192f3d3SKai Wang case 'q': 308cb0dad38SKai Wang ar_mode_q(bsdar); 309d192f3d3SKai Wang break; 310d192f3d3SKai Wang case 'r': 311d192f3d3SKai Wang ar_mode_r(bsdar); 312d192f3d3SKai Wang break; 313d192f3d3SKai Wang case 't': 314d192f3d3SKai Wang ar_mode_t(bsdar); 315d192f3d3SKai Wang break; 316d192f3d3SKai Wang case 'x': 317d192f3d3SKai Wang ar_mode_x(bsdar); 318d192f3d3SKai Wang break; 319d192f3d3SKai Wang default: 320d192f3d3SKai Wang bsdar_usage(); 321d192f3d3SKai Wang /* NOTREACHED */ 322d192f3d3SKai Wang } 323d192f3d3SKai Wang 324d192f3d3SKai Wang for (i = 0; i < bsdar->argc; i++) 325d192f3d3SKai Wang if (bsdar->argv[i] != NULL) 326d192f3d3SKai Wang bsdar_warnc(bsdar, 0, "%s: not found in archive", 327d192f3d3SKai Wang bsdar->argv[i]); 328d192f3d3SKai Wang 329d192f3d3SKai Wang exit(EX_OK); 330d192f3d3SKai Wang } 331d192f3d3SKai Wang 332d192f3d3SKai Wang static void 333d192f3d3SKai Wang set_mode(struct bsdar *bsdar, char opt) 334d192f3d3SKai Wang { 335d192f3d3SKai Wang 336d192f3d3SKai Wang if (bsdar->mode != '\0' && bsdar->mode != opt) 337d192f3d3SKai Wang bsdar_errc(bsdar, EX_USAGE, 0, 338d192f3d3SKai Wang "Can't specify both -%c and -%c", opt, bsdar->mode); 339d192f3d3SKai Wang bsdar->mode = opt; 340d192f3d3SKai Wang } 341d192f3d3SKai Wang 342d192f3d3SKai Wang static void 343d192f3d3SKai Wang only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes) 344d192f3d3SKai Wang { 345d192f3d3SKai Wang 346d192f3d3SKai Wang if (strchr(valid_modes, bsdar->mode) == NULL) 347d192f3d3SKai Wang bsdar_errc(bsdar, EX_USAGE, 0, 348d192f3d3SKai Wang "Option %s is not permitted in mode -%c", opt, bsdar->mode); 349d192f3d3SKai Wang } 350d192f3d3SKai Wang 351d192f3d3SKai Wang static void 352d192f3d3SKai Wang bsdar_usage() 353d192f3d3SKai Wang { 354d192f3d3SKai Wang 355d192f3d3SKai Wang (void)fprintf(stderr, "usage: ar -d [-Tjsvz] archive file ...\n"); 356d192f3d3SKai Wang (void)fprintf(stderr, "\tar -m [-Tjsvz] archive file ...\n"); 357d192f3d3SKai Wang (void)fprintf(stderr, "\tar -m [-Tabijsvz] position archive file ...\n"); 358d192f3d3SKai Wang (void)fprintf(stderr, "\tar -p [-Tv] archive [file ...]\n"); 359cb0dad38SKai Wang (void)fprintf(stderr, "\tar -q [-Tcjsvz] archive file ...\n"); 360d192f3d3SKai Wang (void)fprintf(stderr, "\tar -r [-Tcjsuvz] archive file ...\n"); 361d192f3d3SKai Wang (void)fprintf(stderr, "\tar -r [-Tabcijsuvz] position archive file ...\n"); 362d192f3d3SKai Wang (void)fprintf(stderr, "\tar -s [-jz] archive\n"); 363d192f3d3SKai Wang (void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n"); 364d192f3d3SKai Wang (void)fprintf(stderr, "\tar -x [-CTouv] archive [file ...]\n"); 365d192f3d3SKai Wang (void)fprintf(stderr, "\tar -V\n"); 366d192f3d3SKai Wang exit(EX_USAGE); 367d192f3d3SKai Wang } 368d192f3d3SKai Wang 369d192f3d3SKai Wang static void 370d192f3d3SKai Wang ranlib_usage() 371d192f3d3SKai Wang { 372d192f3d3SKai Wang 373d192f3d3SKai Wang (void)fprintf(stderr, "usage: ranlib [-t] archive ...\n"); 374d192f3d3SKai Wang (void)fprintf(stderr, "\tranlib -V\n"); 375d192f3d3SKai Wang exit(EX_USAGE); 376d192f3d3SKai Wang } 377d192f3d3SKai Wang 378d192f3d3SKai Wang static void 379d192f3d3SKai Wang bsdar_version() 380d192f3d3SKai Wang { 381d192f3d3SKai Wang (void)printf("BSD ar %s - %s\n", BSDAR_VERSION, archive_version()); 382d192f3d3SKai Wang exit(EX_OK); 383d192f3d3SKai Wang } 384d192f3d3SKai Wang 385d192f3d3SKai Wang static void 386d192f3d3SKai Wang ranlib_version() 387d192f3d3SKai Wang { 388d192f3d3SKai Wang (void)printf("ranlib %s - %s\n", BSDAR_VERSION, archive_version()); 389d192f3d3SKai Wang exit(EX_OK); 390d192f3d3SKai Wang } 391