4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
28 * svccfg(1) interpreter and command execution engine.
33 #include <sys/types.h>
44 #include "manifest_find.h"
45 #include "manifest_hash.h"
48 #define MS_PER_US 1000
53 * Replacement lex(1) character retrieval routines.
56 engine_cmd_getc(engine_state_t
*E
)
58 if (E
->sc_cmd_file
!= NULL
)
59 return (getc(E
->sc_cmd_file
));
61 if (E
->sc_cmd_flags
& SC_CMD_EOF
)
64 if (E
->sc_cmd_bufoff
< E
->sc_cmd_bufsz
)
65 return (*(E
->sc_cmd_buf
+ E
->sc_cmd_bufoff
++));
67 if (!(E
->sc_cmd_flags
& SC_CMD_IACTIVE
)) {
68 E
->sc_cmd_flags
|= SC_CMD_EOF
;
78 E
->sc_cmd_flags
|= SC_CMD_EOF
;
83 E
->sc_cmd_buf
= gl_get_line(E
->sc_gl
, "> ", NULL
, -1);
84 if (E
->sc_cmd_buf
!= NULL
)
87 switch (gl_return_status(E
->sc_gl
)) {
89 gl_abandon_line(E
->sc_gl
);
93 E
->sc_cmd_flags
|= SC_CMD_EOF
;
97 uu_die(gettext("Error reading terminal: %s.\n"),
98 gl_error_message(E
->sc_gl
, NULL
, 0));
103 (void) fprintf(stderr
, "%s:%d: gl_get_line() "
104 "returned unexpected value %d.\n", __FILE__
,
105 __LINE__
, gl_return_status(E
->sc_gl
));
111 E
->sc_cmd_bufsz
= strlen(E
->sc_cmd_buf
);
112 E
->sc_cmd_bufoff
= 1;
114 return (E
->sc_cmd_buf
[0]);
115 #endif /* NATIVE_BUILD */
120 engine_cmd_ungetc(engine_state_t
*E
, char c
)
122 if (E
->sc_cmd_file
!= NULL
)
123 return (ungetc(c
, E
->sc_cmd_file
));
125 if (E
->sc_cmd_buf
!= NULL
)
126 *(E
->sc_cmd_buf
+ --E
->sc_cmd_bufoff
) = c
;
133 engine_cmd_nputs(engine_state_t
*E
, char *c
, size_t n
)
135 /* our lexer shouldn't need this state */
140 engine_exec(char *cmd
)
142 est
->sc_cmd_buf
= cmd
;
143 est
->sc_cmd_bufsz
= strlen(cmd
) + 1;
144 est
->sc_cmd_bufoff
= 0;
154 CPL_CHECK_FN(check_xml
)
158 if (strlen(pathname
) < 4)
161 ext
= pathname
+ strlen(pathname
) - 4;
163 return (strcmp(ext
, ".xml") == 0 ? 1 : 0);
166 static const char * const whitespace
= " \t";
169 CPL_MATCH_FN(complete_single_xml_file_arg
)
171 const char *arg1
= data
;
175 arg1end_i
= arg1
+ strcspn(arg1
, whitespace
) - line
;
176 if (arg1end_i
< word_end
)
179 cfc
= new_CplFileConf();
181 cpl_record_error(cpl
, "Out of memory.");
185 cfc_set_check_fn(cfc
, check_xml
, NULL
);
187 ret
= cpl_file_completions(cpl
, cfc
, line
, word_end
);
189 (void) del_CplFileConf(cfc
);
193 static struct cmd_info
{
196 CplMatchFn
*complete_args_f
;
198 { "validate", CS_GLOBAL
, complete_single_xml_file_arg
},
199 { "import", CS_GLOBAL
, complete_single_xml_file_arg
},
200 { "cleanup", CS_GLOBAL
, NULL
},
201 { "export", CS_GLOBAL
, NULL
},
202 { "archive", CS_GLOBAL
, NULL
},
203 { "apply", CS_GLOBAL
, complete_single_xml_file_arg
},
204 { "extract", CS_GLOBAL
, NULL
},
205 { "repository", CS_GLOBAL
, NULL
},
206 { "inventory", CS_GLOBAL
, complete_single_xml_file_arg
},
207 { "set", CS_GLOBAL
, NULL
},
208 { "end", CS_GLOBAL
, NULL
},
209 { "exit", CS_GLOBAL
, NULL
},
210 { "quit", CS_GLOBAL
, NULL
},
211 { "help", CS_GLOBAL
, NULL
},
212 { "delete", CS_GLOBAL
, NULL
},
213 { "select", CS_GLOBAL
, complete_select
},
214 { "unselect", CS_SVC
| CS_INST
| CS_SNAP
, NULL
},
215 { "list", CS_SCOPE
| CS_SVC
| CS_SNAP
, NULL
},
216 { "add", CS_SCOPE
| CS_SVC
, NULL
},
217 { "listpg", CS_SVC
| CS_INST
| CS_SNAP
, NULL
},
218 { "addpg", CS_SVC
| CS_INST
, NULL
},
219 { "delpg", CS_SVC
| CS_INST
, NULL
},
220 { "delhash", CS_GLOBAL
, complete_single_xml_file_arg
},
221 { "listprop", CS_SVC
| CS_INST
| CS_SNAP
, NULL
},
222 { "setprop", CS_SVC
| CS_INST
, NULL
},
223 { "delprop", CS_SVC
| CS_INST
, NULL
},
224 { "editprop", CS_SVC
| CS_INST
, NULL
},
225 { "describe", CS_SVC
| CS_INST
| CS_SNAP
, NULL
},
226 { "listsnap", CS_INST
| CS_SNAP
, NULL
},
227 { "selectsnap", CS_INST
| CS_SNAP
, NULL
},
228 { "revert", CS_INST
| CS_SNAP
, NULL
},
229 { "refresh", CS_INST
, NULL
},
234 add_cmd_matches(WordCompletion
*cpl
, const char *line
, int word_end
,
240 struct cmd_info
*cip
;
242 word_start
= strspn(line
, whitespace
);
243 len
= word_end
- word_start
;
244 bol
= line
+ word_end
- len
;
246 for (cip
= cmds
; cip
->name
!= NULL
; ++cip
) {
247 if ((cip
->flags
& scope
) == 0)
250 if (strncmp(cip
->name
, bol
, len
) == 0) {
251 err
= cpl_add_completion(cpl
, line
, word_start
,
252 word_end
, cip
->name
+ len
, "", " ");
262 * Suggest completions. We must first determine if the cursor is in command
263 * position or in argument position. If the former, complete_command() finds
264 * matching commands. If the latter, we tail-call the command-specific
265 * argument-completion routine in the cmds table.
269 CPL_MATCH_FN(complete
)
271 const char *arg0
, *arg1
;
273 struct cmd_info
*cip
;
275 arg0
= line
+ strspn(line
, whitespace
);
276 arg0len
= strcspn(arg0
, whitespace
);
277 if ((arg0
+ arg0len
) - line
>= word_end
||
278 (arg0
[arg0len
] != ' ' && arg0
[arg0len
] != '\t'))
279 return (complete_command(cpl
, (void *)arg0
, line
, word_end
));
281 arg1
= arg0
+ arg0len
;
282 arg1
+= strspn(arg1
, whitespace
);
284 for (cip
= cmds
; cip
->name
!= NULL
; ++cip
) {
285 if (strlen(cip
->name
) != arg0len
)
288 if (strncmp(cip
->name
, arg0
, arg0len
) != 0)
291 if (cip
->complete_args_f
== NULL
)
294 return (cip
->complete_args_f(cpl
, (void *)arg1
, line
,
300 #endif /* NATIVE_BUILD */
306 uu_die("native build does not support interactive mode.");
314 (void) sigset(SIGINT
, SIG_IGN
);
316 est
->sc_gl
= new_GetLine(512, 8000);
317 if (est
->sc_gl
== NULL
)
318 uu_die(gettext("Out of memory.\n"));
320 /* The longest string is "[snapname]fmri[:instname]> ". */
321 sfsz
= 1 + max_scf_name_len
+ 1 + max_scf_fmri_len
+ 2 +
322 max_scf_name_len
+ 1 + 2 + 1;
323 selfmri
= safe_malloc(sfsz
);
325 r
= gl_customize_completion(est
->sc_gl
, NULL
, complete
);
329 lscf_get_selection_str(selfmri
, sfsz
- 2);
330 (void) strcat(selfmri
, "> ");
331 est
->sc_cmd_buf
= gl_get_line(est
->sc_gl
, selfmri
, NULL
, -1);
333 if (est
->sc_cmd_buf
== NULL
) {
334 switch (gl_return_status(est
->sc_gl
)) {
336 gl_abandon_line(est
->sc_gl
);
343 uu_die(gettext("Error reading terminal: %s.\n"),
344 gl_error_message(est
->sc_gl
, NULL
, 0));
349 (void) fprintf(stderr
, "%s:%d: gl_get_line() "
350 "returned unexpected value %d.\n", __FILE__
,
351 __LINE__
, gl_return_status(est
->sc_gl
));
360 est
->sc_cmd_bufsz
= strlen(est
->sc_cmd_buf
);
361 est
->sc_cmd_bufoff
= 0;
362 est
->sc_cmd_flags
= SC_CMD_IACTIVE
;
368 est
->sc_gl
= del_GetLine(est
->sc_gl
); /* returns NULL */
370 #endif /* NATIVE_BUILD */
375 engine_source(const char *name
, boolean_t dont_exit
)
377 engine_state_t
*old
= est
;
381 est
= uu_zalloc(sizeof (engine_state_t
));
383 /* first, copy the stuff set up in engine_init */
384 est
->sc_repo_pid
= old
->sc_repo_pid
;
385 if (old
->sc_repo_filename
!= NULL
)
386 est
->sc_repo_filename
= safe_strdup(old
->sc_repo_filename
);
387 if (old
->sc_repo_doordir
!= NULL
)
388 est
->sc_repo_doordir
= safe_strdup(old
->sc_repo_doordir
);
389 if (old
->sc_repo_doorname
!= NULL
)
390 est
->sc_repo_doorname
= safe_strdup(old
->sc_repo_doorname
);
391 if (old
->sc_repo_server
!= NULL
)
392 est
->sc_repo_server
= safe_strdup(old
->sc_repo_server
);
394 /* set up the new guy */
395 est
->sc_cmd_lineno
= 1;
398 est
->sc_cmd_flags
|= SC_CMD_DONT_EXIT
;
400 if (strcmp(name
, "-") == 0) {
401 est
->sc_cmd_file
= stdin
;
402 est
->sc_cmd_filename
= "<stdin>";
405 est
->sc_cmd_filename
= name
;
406 est
->sc_cmd_file
= fopen(name
, "r");
407 if (est
->sc_cmd_file
== NULL
) {
409 semerr(gettext("No free stdio streams.\n"));
411 semerr(gettext("Could not open %s"), name
);
418 ret
= fstat(fileno(est
->sc_cmd_file
), &st
);
419 } while (ret
!= 0 && errno
== EINTR
);
421 (void) fclose(est
->sc_cmd_file
);
422 est
->sc_cmd_file
= NULL
; /* for semerr() */
424 semerr(gettext("Could not stat %s"), name
);
430 if (!S_ISREG(st
.st_mode
)) {
431 (void) fclose(est
->sc_cmd_file
);
432 est
->sc_cmd_file
= NULL
; /* for semerr() */
434 semerr(gettext("%s is not a regular file.\n"), name
);
443 if (est
->sc_cmd_file
!= stdin
)
444 (void) fclose(est
->sc_cmd_file
);
449 if (est
->sc_repo_pid
!= old
->sc_repo_pid
)
450 lscf_cleanup(); /* clean up any new repository */
452 if (est
->sc_repo_filename
!= NULL
)
453 free((void *)est
->sc_repo_filename
);
454 if (est
->sc_repo_doordir
!= NULL
)
455 free((void *)est
->sc_repo_doordir
);
456 if (est
->sc_repo_doorname
!= NULL
)
457 free((void *)est
->sc_repo_doorname
);
458 if (est
->sc_repo_server
!= NULL
)
459 free((void *)est
->sc_repo_server
);
468 * Initialize svccfg state. We recognize four environment variables:
470 * SVCCFG_REPOSITORY Create a private instance of svc.configd(1M) to answer
471 * requests for the specified repository file.
472 * SVCCFG_DOOR_PATH Directory for door creation.
474 * SVCCFG_DOOR Rendezvous via an alternative repository door.
476 * SVCCFG_CONFIGD_PATH Resolvable path to alternative svc.configd(1M) binary.
483 est
= uu_zalloc(sizeof (engine_state_t
));
485 est
->sc_cmd_lineno
= 1;
486 est
->sc_repo_pid
= -1;
488 cp
= getenv("SVCCFG_REPOSITORY");
489 est
->sc_repo_filename
= cp
? safe_strdup(cp
) : NULL
;
491 cp
= getenv("SVCCFG_DOOR_PATH");
492 est
->sc_repo_doordir
= cp
? cp
: "/var/run";
494 cp
= getenv("SVCCFG_DOOR");
496 if (est
->sc_repo_filename
!= NULL
) {
497 uu_warn(gettext("SVCCFG_DOOR unused when "
498 "SVCCFG_REPOSITORY specified\n"));
500 est
->sc_repo_doorname
= safe_strdup(cp
);
504 cp
= getenv("SVCCFG_CONFIGD_PATH");
505 est
->sc_repo_server
= cp
? cp
: "/lib/svc/bin/svc.configd";
507 est
->sc_miss_type
= B_FALSE
;
509 cp
= getenv("SMF_FMRI");
510 if ((cp
!= NULL
) && (strcmp(cp
, SCF_INSTANCE_EMI
) == 0))
513 cp
= smf_get_state(SCF_INSTANCE_FS_MINIMAL
);
514 if (cp
&& (strcmp(cp
, SCF_STATE_STRING_ONLINE
) == 0))
515 est
->sc_fs_minimal
= B_TRUE
;
520 import_manifest_file(manifest_info_t
*info
, boolean_t validate
, FILE *pout
,
526 tmpl_validate_status_t vr
;
528 file
= info
->mi_path
;
530 /* Load the manifest */
531 b
= internal_bundle_new();
533 if (lxml_get_bundle_file(b
, file
, SVCCFG_OP_IMPORT
) != 0) {
534 internal_bundle_free(b
);
539 if ((vr
= tmpl_validate_bundle(b
, &errs
)) != TVS_SUCCESS
) {
542 if ((validate
== 0) || (vr
== TVS_WARN
)) {
543 prefix
= gettext("Warning: ");
547 tmpl_errors_print(stderr
, errs
, prefix
);
548 if (validate
&& (vr
!= TVS_WARN
)) {
549 tmpl_errors_destroy(errs
);
550 semerr(gettext("Import of %s failed.\n"),
553 (void) fprintf(pout
, gettext("WARNING: svccfg "
554 "import of %s failed.\n"), info
->mi_path
);
560 tmpl_errors_destroy(errs
);
563 if (lscf_bundle_import(b
, file
, flags
) != 0) {
564 internal_bundle_free(b
);
565 semerr(gettext("Import of %s failed.\n"), info
->mi_path
);
567 (void) fprintf(pout
, gettext("WARNING: svccfg import "
568 "of %s failed.\n"), info
->mi_path
);
573 internal_bundle_free(b
);
578 if (mhash_store_entry(g_hndl
, info
->mi_prop
, file
,
579 info
->mi_hash
, APPLY_NONE
, &errstr
)) {
581 semerr(gettext("Could not store hash for %s. "
582 "%s\n"), info
->mi_path
, errstr
);
584 semerr(gettext("Unknown error from "
585 "mhash_store_entry() for %s\n"),
596 * 1 No manifests need to be imported.
602 engine_import(uu_list_t
*args
)
606 int failed_manifests
;
611 boolean_t validate
= B_FALSE
;
612 uint_t flags
= SCI_GENERALLAST
;
618 manifest_info_t
***manifest_sets
= NULL
;
619 manifest_info_t
**manifests
;
620 char *progress_file
= NULL
;
621 FILE *progress_out
= NULL
;
627 argc
= uu_list_numnodes(args
);
631 argv
= calloc(argc
+ 1, sizeof (char *));
633 uu_die(gettext("Out of memory.\n"));
635 for (slp
= uu_list_first(args
), i
= 0;
637 slp
= uu_list_next(args
, slp
), ++i
)
643 optind
= 0; /* Remember, no argv[0]. */
645 o
= getopt(argc
, argv
, "np:V");
651 flags
|= SCI_NOREFRESH
;
655 progress_file
= optarg
;
667 bad_error("getopt", o
);
677 /* Open device for progress messages */
678 if (progress_file
!= NULL
) {
679 if (strcmp(progress_file
, "-") == 0) {
680 progress_out
= stdout
;
682 progress_out
= fopen(progress_file
, "w");
683 if (progress_out
== NULL
) {
684 semerr(gettext("Unable to open %s for "
685 "progress reporting. %s\n"),
686 progress_file
, strerror(errno
));
689 setbuf(progress_out
, NULL
);
694 manifest_sets
= safe_malloc(argc
* sizeof (*manifest_sets
));
696 /* If we're in interactive mode, force strict validation. */
697 if (est
->sc_cmd_flags
& SC_CMD_IACTIVE
)
702 /* Determine which manifests must be imported. */
705 for (i
= 0; i
< argc
; i
++) {
707 fm_flags
= CHECKHASH
;
709 /* Determine if argument is a directory or file. */
710 if (stat(file
, &sb
) == -1) {
711 semerr(gettext("Unable to stat file %s. %s\n"), file
,
715 if (sb
.st_mode
& S_IFDIR
) {
716 fm_flags
|= CHECKEXT
;
719 } else if (sb
.st_mode
& S_IFREG
) {
722 semerr(gettext("%s is not a directory or regular "
727 /* Get list of manifests that we should import for this path. */
728 if ((count
= find_manifests(g_hndl
, file
, &manifests
,
731 semerr(gettext("Could not hash directory %s\n"),
734 semerr(gettext("Could not hash file %s\n"),
737 free_manifest_array(manifests
);
740 total_manifests
+= count
;
741 manifest_sets
[i
] = manifests
;
744 if (total_manifests
== 0) {
745 /* No manifests to process. */
747 warn(gettext("No changes were necessary\n"));
754 * If we're processing more than one file, we don't want to exit if
755 * we encounter an error. We should go ahead and process all of
758 dont_exit
= est
->sc_cmd_flags
& SC_CMD_DONT_EXIT
;
759 if (total_manifests
> 1)
760 est
->sc_cmd_flags
|= SC_CMD_DONT_EXIT
;
762 if (progress_out
!= NULL
)
763 (void) fprintf(progress_out
,
764 "Loading smf(5) service descriptions: ");
766 failed_manifests
= 0;
768 for (i
= 0; i
< argc
; i
++) {
769 manifests
= manifest_sets
[i
];
770 if (manifests
== NULL
)
772 for (; *manifests
!= NULL
; manifests
++) {
774 if (progress_out
!= NULL
) {
775 back_count
= fprintf(progress_out
, "%d/%d",
776 progress_count
, total_manifests
);
777 while (back_count
-- > 0) {
778 (void) fputc('\b', progress_out
);
781 if (import_manifest_file(*manifests
, validate
,
782 progress_out
, flags
) != 0) {
787 if (progress_out
!= NULL
)
788 (void) fputc('\n', progress_out
);
790 if ((total_manifests
> 1) && (dont_exit
== 0))
791 est
->sc_cmd_flags
&= ~SC_CMD_DONT_EXIT
;
793 if (dirarg
&& total_manifests
> 0) {
796 msg
= "Loaded %d smf(5) service descriptions\n";
797 warn(gettext(msg
), progress_count
);
799 if (failed_manifests
) {
800 msg
= "%d smf(5) service descriptions failed to load\n";
801 warn(gettext(msg
), failed_manifests
);
805 if (failed_manifests
> 0)
809 warn(gettext("Successful import.\n"));
813 if ((progress_out
!= NULL
) && (progress_out
!= stdout
))
814 (void) fclose(progress_out
);
816 if (manifest_sets
!= NULL
) {
817 for (i
= 0; i
< argc
; i
++) {
818 free_manifest_array(manifest_sets
[i
]);
826 * Walk each service and get its manifest file.
828 * If the file exists check instance support, and cleanup any
831 * If the file doesn't exist tear down the service and/or instances
832 * that are no longer supported by files.
835 engine_cleanup(int flags
)
837 boolean_t activity
= B_TRUE
;
847 dont_exit
= est
->sc_cmd_flags
& SC_CMD_DONT_EXIT
;
848 est
->sc_cmd_flags
|= SC_CMD_DONT_EXIT
;
850 if (scf_walk_fmri(g_hndl
, 0, NULL
, SCF_WALK_SERVICE
|SCF_WALK_NOINSTANCE
,
851 lscf_service_cleanup
, (void *)activity
, NULL
,
852 uu_warn
) == SCF_SUCCESS
)
856 est
->sc_cmd_flags
&= ~SC_CMD_DONT_EXIT
;
858 (void) lscf_hash_cleanup();
864 apply_profile(manifest_info_t
*info
, int apply_changes
)
866 bundle_t
*b
= internal_bundle_new();
868 if (lxml_get_bundle_file(b
, info
->mi_path
, SVCCFG_OP_APPLY
) != 0) {
869 internal_bundle_free(b
);
873 if (!apply_changes
) { /* we don't want to apply, just test */
874 internal_bundle_free(b
);
878 if (lscf_bundle_apply(b
, info
->mi_path
) != 0) {
879 internal_bundle_free(b
);
883 internal_bundle_free(b
);
886 apply_action_t apply
;
889 apply
= (est
->sc_in_emi
== 1) ? APPLY_LATE
: APPLY_NONE
;
890 if (mhash_store_entry(g_hndl
, info
->mi_prop
, info
->mi_path
,
891 info
->mi_hash
, apply
, &errstr
)) {
900 engine_apply(const char *file
, int apply_changes
)
908 manifest_info_t
**profiles
= NULL
;
909 manifest_info_t
**entry
;
910 manifest_info_t
*pfile
;
914 /* Determine which profile(s) must be applied. */
917 fm_flags
= BUNDLE_PROF
| CHECKHASH
;
919 /* Determine if argument is a directory or file. */
920 if (stat(file
, &sb
) == -1) {
921 semerr(gettext("Unable to stat file %s. %s\n"), file
,
927 if (sb
.st_mode
& S_IFDIR
) {
928 fm_flags
|= CHECKEXT
;
930 } else if (sb
.st_mode
& S_IFREG
) {
933 semerr(gettext("%s is not a directory or regular "
939 /* Get list of profiles to be applied. */
940 if ((profile_count
= find_manifests(g_hndl
, file
, &profiles
,
944 semerr(gettext("Could not hash directory %s\n"), file
);
946 semerr(gettext("Could not hash file %s\n"), file
);
952 if (profile_count
== 0) {
953 /* No profiles to process. */
955 warn(gettext("No changes were necessary\n"));
961 * We don't want to exit if we encounter an error. We should go ahead
962 * and process all of the profiles.
964 dont_exit
= est
->sc_cmd_flags
& SC_CMD_DONT_EXIT
;
965 est
->sc_cmd_flags
|= SC_CMD_DONT_EXIT
;
967 for (entry
= profiles
; *entry
!= NULL
; entry
++) {
970 if (apply_profile(pfile
, apply_changes
) == 0) {
972 warn(gettext("Successfully applied: %s\n"),
976 warn(gettext("WARNING: Failed to apply %s\n"),
983 est
->sc_cmd_flags
&= ~SC_CMD_DONT_EXIT
;
985 /* exit(1) appropriately if any profile failed to be applied. */
987 (est
->sc_cmd_flags
& (SC_CMD_IACTIVE
| SC_CMD_DONT_EXIT
)) == 0) {
988 free_manifest_array(profiles
);
993 free_manifest_array(profiles
);
998 engine_restore(const char *file
)
1004 b
= internal_bundle_new();
1006 if (lxml_get_bundle_file(b
, file
, SVCCFG_OP_RESTORE
) != 0) {
1007 internal_bundle_free(b
);
1011 if (lscf_bundle_import(b
, file
, SCI_NOSNAP
) != 0) {
1012 internal_bundle_free(b
);
1016 internal_bundle_free(b
);
1022 engine_set(uu_list_t
*args
)
1024 uu_list_walk_t
*walk
;
1027 if (uu_list_first(args
) == NULL
) {
1028 /* Display current options. */
1030 (void) fputs("no", stdout
);
1031 (void) puts("verbose");
1036 walk
= uu_list_walk_start(args
, UU_DEFAULT
);
1038 uu_die(gettext("Couldn't read arguments"));
1041 for (slp
= uu_list_walk_next(walk
);
1043 slp
= uu_list_walk_next(walk
)) {
1044 if (slp
->str
[0] == '-') {
1047 for (op
= &slp
->str
[1]; *op
!= '\0'; ++op
) {
1058 warn(gettext("Unknown option -%c.\n"),
1063 warn(gettext("No non-flag arguments defined.\n"));
1076 warn(gettext("General commands: help set repository end\n"
1077 "Manifest commands: inventory validate import export "
1079 "Profile commands: apply extract\n"
1080 "Entity commands: list select unselect add delete "
1082 "Snapshot commands: listsnap selectsnap revert\n"
1083 "Instance commands: refresh\n"
1084 "Property group commands: listpg addpg delpg\n"
1085 "Property commands: listprop setprop delprop editprop\n"
1086 "Property value commands: addpropvalue delpropvalue "
1088 "Notification parameters: "
1089 "listnotify setnotify delnotify\n"));
1093 for (i
= 0; help_messages
[i
].message
!= NULL
; ++i
) {
1094 if (help_messages
[i
].token
== com
) {
1095 warn(gettext("Usage: %s\n"),
1096 gettext(help_messages
[i
].message
));
1101 warn(gettext("Unknown command.\n"));