/* * Returns B_TRUE if the bind configuration of the two instance_cfg_t * structures are equivalent, else B_FALSE. */ boolean_t bind_config_equal(const basic_cfg_t *c1, const basic_cfg_t *c2) { proto_info_t *pi; if ((c1->iswait != c2->iswait) || (c1->istlx != c2->istlx)) return (B_FALSE); if (uu_list_numnodes(c1->proto_list) != uu_list_numnodes(c2->proto_list)) return (B_FALSE); /* * For each element in the first configuration's socket/tlx list, * check there's a matching one in the other list. */ for (pi = uu_list_first(c1->proto_list); pi != NULL; pi = uu_list_next(c1->proto_list, pi)) { uu_list_index_t idx; if (uu_list_find(c2->proto_list, pi, (void *)&c1->istlx, &idx) == NULL) return (B_FALSE); } return (B_TRUE); }
int main(int argc, char *argv[]) { int c; scf_walk_callback callback; int flags; int err; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); return_code = UU_EXIT_OK; (void) uu_setpname(argv[0]); prop_pool = uu_list_pool_create("properties", sizeof (svcprop_prop_node_t), offsetof(svcprop_prop_node_t, spn_list_node), NULL, 0); if (prop_pool == NULL) uu_die("%s\n", uu_strerror(uu_error())); prop_list = uu_list_create(prop_pool, NULL, 0); hndl = scf_handle_create(SCF_VERSION); if (hndl == NULL) scfdie(); while ((c = getopt(argc, argv, "Ccfp:qs:tvwz:")) != -1) { switch (c) { case 'C': if (cflag || sflag || wait) usage(); /* Not with -c, -s or -w */ Cflag++; snapshot = NULL; break; case 'c': if (Cflag || sflag || wait) usage(); /* Not with -C, -s or -w */ cflag++; snapshot = NULL; break; case 'f': types = 1; fmris = 1; break; case 'p': add_prop(optarg); break; case 'q': quiet = 1; warn = quiet_warn; die = quiet_die; break; case 's': if (Cflag || cflag || wait) usage(); /* Not with -C, -c or -w */ snapshot = optarg; sflag++; break; case 't': types = 1; break; case 'v': verbose = 1; break; case 'w': if (Cflag || cflag || sflag) usage(); /* Not with -C, -c or -s */ wait = 1; break; case 'z': { scf_value_t *zone; scf_handle_t *h = hndl; if (getzoneid() != GLOBAL_ZONEID) uu_die(gettext("svcprop -z may only be used " "from the global zone\n")); if ((zone = scf_value_create(h)) == NULL) scfdie(); if (scf_value_set_astring(zone, optarg) != SCF_SUCCESS) scfdie(); if (scf_handle_decorate(h, "zone", zone) != SCF_SUCCESS) uu_die(gettext("invalid zone '%s'\n"), optarg); scf_value_destroy(zone); break; } case '?': switch (optopt) { case 'p': usage(); default: break; } /* FALLTHROUGH */ default: usage(); } } if (optind == argc) usage(); max_scf_name_length = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH); max_scf_value_length = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH); max_scf_fmri_length = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if (max_scf_name_length == -1 || max_scf_value_length == -1 || max_scf_fmri_length == -1) scfdie(); if (scf_handle_bind(hndl) == -1) die(gettext("Could not connect to configuration repository: " "%s.\n"), scf_strerror(scf_error())); flags = SCF_WALK_PROPERTY | SCF_WALK_SERVICE | SCF_WALK_EXPLICIT; if (wait) { if (uu_list_numnodes(prop_list) > 1) usage(); if (argc - optind > 1) usage(); callback = do_wait; } else { callback = process_fmri; flags |= SCF_WALK_MULTIPLE; } if ((err = scf_walk_fmri(hndl, argc - optind, argv + optind, flags, callback, NULL, &return_code, warn)) != 0) { warn(gettext("failed to iterate over instances: %s\n"), scf_strerror(err)); return_code = UU_EXIT_FATAL; } scf_handle_destroy(hndl); return (return_code); }
/* ARGSUSED */ static int do_wait(void *unused, scf_walkinfo_t *wip) { scf_property_t *prop; scf_propertygroup_t *lpg, *pg; const char *propname; svcprop_prop_node_t *p; const char *emsg_not_found = gettext("Not found.\n"); if ((lpg = scf_pg_create(hndl)) == NULL || (prop = scf_property_create(hndl)) == NULL) scfdie(); if (wip->prop != NULL) { if (uu_list_numnodes(prop_list) > 0) uu_xdie(UU_EXIT_USAGE, gettext("-p cannot be used with " "property FMRIs.\n")); pg = wip->pg; assert(strrchr(wip->fmri, '/') != NULL); propname = strrchr(wip->fmri, '/') + 1; } else if (wip->pg != NULL) { p = uu_list_first(prop_list); if (p != NULL) { if (p->spn_comp2 != NULL) uu_xdie(UU_EXIT_USAGE, gettext("-p argument " "\"%s/%s\" has too many components for " "property group %s.\n"), p->spn_comp1, p->spn_comp2, wip->fmri); propname = p->spn_comp1; if (scf_pg_get_property(wip->pg, propname, prop) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid property name " "\"%s\".\n"), propname); /* NOTREACHED */ case SCF_ERROR_NOT_FOUND: die(emsg_not_found); /* NOTREACHED */ default: scfdie(); } } } else { propname = NULL; } pg = wip->pg; } else if (wip->inst != NULL) { p = uu_list_first(prop_list); if (p == NULL) uu_xdie(UU_EXIT_USAGE, gettext("Cannot wait for an instance.\n")); if (scf_instance_get_pg(wip->inst, p->spn_comp1, lpg) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid " "property group name \"%s\".\n"), p->spn_comp1); case SCF_ERROR_NOT_FOUND: die(emsg_not_found); /* NOTREACHED */ default: scfdie(); } } propname = p->spn_comp2; if (propname != NULL) { if (scf_pg_get_property(lpg, propname, prop) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid property name " "\"%s\".\n"), propname); case SCF_ERROR_NOT_FOUND: die(emsg_not_found); /* NOTREACHED */ default: scfdie(); } } } pg = lpg; } else if (wip->svc != NULL) { p = uu_list_first(prop_list); if (p == NULL) uu_xdie(UU_EXIT_USAGE, gettext("Cannot wait for a service.\n")); if (scf_service_get_pg(wip->svc, p->spn_comp1, lpg) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid " "property group name \"%s\".\n"), p->spn_comp1); case SCF_ERROR_NOT_FOUND: die(emsg_not_found); default: scfdie(); } } propname = p->spn_comp2; if (propname != NULL) { if (scf_pg_get_property(lpg, propname, prop) != SCF_SUCCESS) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_xdie(UU_EXIT_USAGE, gettext("Invalid property name " "\"%s\".\n"), propname); /* NOTREACHED */ case SCF_ERROR_NOT_FOUND: die(emsg_not_found); /* NOTREACHED */ default: scfdie(); } } } pg = lpg; } else { uu_xdie(UU_EXIT_USAGE, gettext("FMRI must specify an entity, " "property group, or property.\n")); } for (;;) { int ret; ret = _scf_pg_wait(pg, -1); if (ret != SCF_SUCCESS) scfdie(); ret = scf_pg_update(pg); if (ret < 0) { if (scf_error() != SCF_ERROR_DELETED) scfdie(); die(emsg_not_found); } if (ret == SCF_COMPLETE) break; } if (propname != NULL) { if (scf_pg_get_property(pg, propname, prop) == SCF_SUCCESS) { if (!quiet) display_prop(pg, prop); } else { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) uu_warn(emsg_not_found); return_code = UU_EXIT_FATAL; } } else { if (!quiet) display_pg(pg); } scf_property_destroy(prop); scf_pg_destroy(lpg); return (0); }
/* * Entity (service or instance): If there are -p options, * display_{pg,prop}() the named property groups and/or properties. Otherwise * display_pg() all property groups. */ static void process_ent(scf_entityp_t ent) { scf_snapshot_t *snap = NULL; scf_propertygroup_t *pg; scf_property_t *prop; scf_iter_t *iter; svcprop_prop_node_t *spn; int ret, err; if (uu_list_numnodes(prop_list) == 0) { if (quiet) return; if ((pg = scf_pg_create(hndl)) == NULL || (iter = scf_iter_create(hndl)) == NULL) scfdie(); if (cflag || Cflag || ent.type != ENT_INSTANCE) { if (scf_iter_entity_pgs(iter, ent) == -1) scfdie(); } else { if (snapshot != NULL) snap = get_snapshot(ent.u.inst, snapshot); if (scf_iter_instance_pgs_composed(iter, ent.u.inst, snap) == -1) scfdie(); if (snap) scf_snapshot_destroy(snap); } while ((ret = scf_iter_next_pg(iter, pg)) == 1) display_pg(pg); if (ret == -1) scfdie(); /* * In normal usage, i.e. against the running snapshot, * we must iterate over the current non-persistent * pg's. */ if (sflag == 0 && snap != NULL) { scf_iter_reset(iter); if (scf_iter_instance_pgs_composed(iter, ent.u.inst, NULL) == -1) scfdie(); while ((ret = scf_iter_next_pg(iter, pg)) == 1) { uint32_t flags; if (scf_pg_get_flags(pg, &flags) == -1) scfdie(); if (flags & SCF_PG_FLAG_NONPERSISTENT) display_pg(pg); } } if (ret == -1) scfdie(); scf_iter_destroy(iter); scf_pg_destroy(pg); return; } if ((pg = scf_pg_create(hndl)) == NULL || (prop = scf_property_create(hndl)) == NULL) scfdie(); if (ent.type == ENT_INSTANCE && snapshot != NULL) snap = get_snapshot(ent.u.inst, snapshot); for (spn = uu_list_first(prop_list); spn != NULL; spn = uu_list_next(prop_list, spn)) { if (ent.type == ENT_INSTANCE) { if (Cflag) ret = scf_instance_get_pg(ent.u.inst, spn->spn_comp1, pg); else ret = scf_instance_get_pg_composed(ent.u.inst, snap, spn->spn_comp1, pg); err = scf_error(); /* * If we didn't find it in the specified snapshot, use * the current values if the pg is nonpersistent. */ if (ret == -1 && !Cflag &&snap != NULL && err == SCF_ERROR_NOT_FOUND) { ret = scf_instance_get_pg_composed( ent.u.inst, NULL, spn->spn_comp1, pg); if (ret == 0) { uint32_t flags; if (scf_pg_get_flags(pg, &flags) == -1) scfdie(); if ((flags & SCF_PG_FLAG_NONPERSISTENT) == 0) { ret = -1; } } } } else { /* * If we are displaying properties for a service, * treat it as though it were a composed, current * lookup. (implicit cflag) However, if a snapshot * was specified, fail. */ if (sflag) die(gettext("Only instances have " "snapshots.\n")); ret = scf_entity_get_pg(ent, spn->spn_comp1, pg); err = scf_error(); } if (ret == -1) { if (err != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_entity_to_fmri(ent, buf, max_scf_fmri_length + 1) == -1) scfdie(); uu_warn(gettext("Couldn't find property group " "`%s' for %s `%s'.\n"), spn->spn_comp1, SCF_ENTITY_TYPE_NAME(ent), buf); free(buf); } noprop_common_action(); continue; } if (spn->spn_comp2 == NULL) { if (!quiet) display_pg(pg); continue; } if (scf_pg_get_property(pg, spn->spn_comp2, prop) == -1) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_entity_to_fmri(ent, buf, max_scf_fmri_length + 1) == -1) scfdie(); /* FMRI syntax knowledge */ uu_warn(gettext("Couldn't find property " "`%s/%s' for %s `%s'.\n"), spn->spn_comp1, spn->spn_comp2, SCF_ENTITY_TYPE_NAME(ent), buf); free(buf); } noprop_common_action(); continue; } if (!quiet) display_prop(pg, prop); } scf_property_destroy(prop); scf_pg_destroy(pg); if (snap) scf_snapshot_destroy(snap); }
/* * Display a property's values on a line. If types is true, prepend * identification (the FMRI if fmris is true, pg/prop otherwise) and the type * of the property. */ static void display_prop(scf_propertygroup_t *pg, scf_property_t *prop) { scf_value_t *val; scf_iter_t *iter; int ret, first, err; const char * const permission_denied_emsg = gettext("Permission denied.\n"); if (types) { scf_type_t ty; char *buf; size_t buf_sz; if (fmris) { buf_sz = max_scf_fmri_length + 1; buf = safe_malloc(buf_sz); if (scf_property_to_fmri(prop, buf, buf_sz) == -1) scfdie(); (void) fputs(buf, stdout); free(buf); } else { buf_sz = max_scf_name_length + 1; buf = safe_malloc(buf_sz); if (scf_pg_get_name(pg, buf, buf_sz) < 0) scfdie(); (void) fputs(buf, stdout); (void) putchar('/'); if (scf_property_get_name(prop, buf, buf_sz) < 0) scfdie(); (void) fputs(buf, stdout); free(buf); } (void) putchar(' '); if (scf_property_type(prop, &ty) == -1) scfdie(); (void) fputs(scf_type_to_string(ty), stdout); (void) putchar(' '); } if ((iter = scf_iter_create(hndl)) == NULL || (val = scf_value_create(hndl)) == NULL) scfdie(); if (scf_iter_property_values(iter, prop) == -1) scfdie(); first = 1; while ((ret = scf_iter_next_value(iter, val)) == 1) { if (first) first = 0; else (void) putchar(' '); print_value(val); } if (ret == -1) { err = scf_error(); if (err == SCF_ERROR_PERMISSION_DENIED) { if (uu_list_numnodes(prop_list) > 0) die(permission_denied_emsg); } else { scfdie(); } } (void) putchar('\n'); scf_iter_destroy(iter); (void) scf_value_destroy(val); }
int engine_import(uu_list_t *args) { int ret, argc, i, o; bundle_t *b; char *file, *pname; uchar_t hash[MHASH_SIZE]; char **argv; string_list_t *slp; boolean_t verify = B_FALSE; uint_t flags = SCI_GENERALLAST; argc = uu_list_numnodes(args); if (argc < 1) return (-2); argv = calloc(argc + 1, sizeof (char *)); if (argv == NULL) uu_die(gettext("Out of memory.\n")); for (slp = uu_list_first(args), i = 0; slp != NULL; slp = uu_list_next(args, slp), ++i) argv[i] = slp->str; argv[i] = NULL; opterr = 0; optind = 0; /* Remember, no argv[0]. */ for (;;) { o = getopt(argc, argv, "nV"); if (o == -1) break; switch (o) { case 'n': flags |= SCI_NOREFRESH; break; case 'V': verify = B_TRUE; break; case '?': free(argv); return (-2); default: bad_error("getopt", o); } } argc -= optind; if (argc != 1) { free(argv); return (-2); } file = argv[optind]; free(argv); lscf_prep_hndl(); ret = mhash_test_file(g_hndl, file, 0, &pname, hash); if (ret != MHASH_NEWFILE) return (ret); /* Load */ b = internal_bundle_new(); if (lxml_get_bundle_file(b, file, 0) != 0) { internal_bundle_free(b); return (-1); } /* Import */ if (lscf_bundle_import(b, file, flags) != 0) { internal_bundle_free(b); return (-1); } internal_bundle_free(b); if (g_verbose) warn(gettext("Successful import.\n")); if (pname) { char *errstr; if (mhash_store_entry(g_hndl, pname, hash, &errstr)) { if (errstr) semerr(errstr); else semerr(gettext("Unknown error from " "mhash_store_entry()\n")); } free(pname); } /* Verify */ if (verify) warn(gettext("import -V not implemented.\n")); return (0); }