int psexp_compile(psexp_t *psexp) { size_t nbytes; char *buf; int err; idtab_sort(&psexp->ps_euids); idtab_sort(&psexp->ps_ruids); idtab_sort(&psexp->ps_rgids); idtab_sort(&psexp->ps_ppids); idtab_sort(&psexp->ps_pgids); idtab_sort(&psexp->ps_sids); idtab_sort(&psexp->ps_ttys); idtab_sort(&psexp->ps_projids); idtab_sort(&psexp->ps_taskids); idtab_sort(&psexp->ps_zoneids); idtab_sort(&psexp->ps_ctids); if (psexp->ps_pat != NULL) { if ((err = regcomp(&psexp->ps_reg, psexp->ps_pat, REG_EXTENDED)) != 0) { nbytes = regerror(err, &psexp->ps_reg, NULL, 0); buf = alloca(nbytes + 1); (void) regerror(err, &psexp->ps_reg, buf, nbytes); (void) strcat(buf, "\n"); uu_warn(buf); return (-1); } } return (0); }
static void usage(boolean_t detailed) { uu_warn(gettext( "Usage:\n" " inetadm\n" " inetadm -?\n" " inetadm -p\n" " inetadm -l {FMRI | pattern}...\n" " inetadm -e {FMRI | pattern}...\n" " inetadm -d {FMRI | pattern}...\n" " inetadm -m {FMRI | pattern}... {name=value}...\n" " inetadm -M {name=value}...\n")); if (!detailed) exit(UU_EXIT_USAGE); (void) fprintf(stdout, gettext( "\n" "Without any options inetadm lists all inetd managed services.\n" "\n" "Options:\n" " -? Print help.\n" " -p List all default inetd property values.\n" " -l List all inetd property values for the inet " "service(s).\n" " -e Enable the inet service(s).\n" " -d Disable the inet service(s).\n" " -m Modify the inet service(s) inetd property values.\n" " -M Modify default inetd property values.\n")); }
/* * Initialize svccfg state. We recognize four environment variables: * * SVCCFG_REPOSITORY Create a private instance of svc.configd(1M) to answer * requests for the specified repository file. * SVCCFG_DOOR_PATH Directory for door creation. * * SVCCFG_DOOR Rendezvous via an alternative repository door. * * SVCCFG_CONFIGD_PATH Resolvable path to alternative svc.configd(1M) binary. */ void engine_init() { const char *cp; est = uu_zalloc(sizeof (engine_state_t)); est->sc_cmd_lineno = 1; est->sc_repo_pid = -1; cp = getenv("SVCCFG_REPOSITORY"); est->sc_repo_filename = cp ? safe_strdup(cp) : NULL; cp = getenv("SVCCFG_DOOR_PATH"); est->sc_repo_doordir = cp ? cp : "/var/run"; cp = getenv("SVCCFG_DOOR"); if (cp != NULL) { if (est->sc_repo_filename != NULL) { uu_warn(gettext("SVCCFG_DOOR unused when " "SVCCFG_REPOSITORY specified\n")); } else { est->sc_repo_doorname = safe_strdup(cp); } } cp = getenv("SVCCFG_CONFIGD_PATH"); est->sc_repo_server = cp ? cp : "/lib/svc/bin/svc.configd"; }
static void add_prop(char *property) { svcprop_prop_node_t *p, *last; char *slash; const char * const invalid_component_emsg = gettext("Invalid component name `%s'.\n"); /* FMRI syntax knowledge. */ slash = strchr(property, '/'); if (slash != NULL) { if (strchr(slash + 1, '/') != NULL) { uu_warn(gettext("-p argument `%s' has too many " "components.\n"), property); usage(); } } if (slash != NULL) *slash = '\0'; p = safe_malloc(sizeof (svcprop_prop_node_t)); uu_list_node_init(p, &p->spn_list_node, prop_pool); p->spn_comp1 = property; p->spn_comp2 = (slash == NULL) ? NULL : slash + 1; if (uu_check_name(p->spn_comp1, UU_NAME_DOMAIN) == -1) uu_xdie(UU_EXIT_USAGE, invalid_component_emsg, p->spn_comp1); if (p->spn_comp2 != NULL && uu_check_name(p->spn_comp2, UU_NAME_DOMAIN) == -1) uu_xdie(UU_EXIT_USAGE, invalid_component_emsg, p->spn_comp2); last = uu_list_last(prop_list); if (last != NULL) { if ((last->spn_comp2 == NULL) ^ (p->spn_comp2 == NULL)) { /* * The -p options have mixed numbers of components. * If they both turn out to be valid, then the * single-component ones will specify property groups, * so we need to turn on types to keep the output of * display_prop() consistent with display_pg(). */ types = 1; } } (void) uu_list_insert_after(prop_list, NULL, p); }
/* * If there are -p options, show the error. Otherwise just call * display_prop(). */ static void process_prop(scf_propertygroup_t *pg, scf_property_t *prop) { if (uu_list_first(prop_list) != NULL) { uu_warn(gettext("The -p option cannot be used with property " "operands.\n")); usage(); } if (quiet) return; display_prop(pg, prop); }
static void list_defaults() { scf_handle_t *h; scf_error_t err; int i; inetd_prop_t *proptable; size_t numprops; if (((h = scf_handle_create(SCF_VERSION)) == NULL) || (scf_handle_bind(h) == -1)) scfdie(); if ((proptable = read_default_props(h, &numprops, &err)) == NULL) { uu_die(gettext("Unexpected libscf error: %s. Exiting.\n"), scf_strerror(err)); } (void) printf("NAME=VALUE\n"); for (i = 0; i < numprops; i++) { if (!proptable[i].ip_default) continue; if (proptable[i].ip_error == IVE_UNSET) { (void) uu_warn(gettext("Error: Default property %s " "missing.\n"), proptable[i].ip_name); continue; } (void) printf("%s=", proptable[i].ip_name); print_prop_val(&proptable[i]); } free_instance_props(proptable); }
static void exec_method(const restarter_inst_t *inst, int type, const char *method, struct method_context *mcp, uint8_t need_session) { char *cmd; const char *errf; char **nenv; cmd = uu_msprintf("exec %s", method); if (inst->ri_utmpx_prefix[0] != '\0' && inst->ri_utmpx_prefix != NULL) (void) utmpx_mark_init(getpid(), inst->ri_utmpx_prefix); setlog(inst->ri_logstem); log_instance(inst, B_FALSE, "Executing %s method (\"%s\")", method_names[type], method); if (need_session) (void) setpgrp(); /* Set credentials. */ errno = restarter_set_method_context(mcp, &errf); if (errno != 0) { (void) fputs("svc.startd could not set context for method: ", stderr); if (errno == -1) { if (strcmp(errf, "core_set_process_path") == 0) { (void) fputs("Could not set corefile path.\n", stderr); } else if (strcmp(errf, "setproject") == 0) { (void) fprintf(stderr, "%s: a resource control " "assignment failed\n", errf); } else if (strcmp(errf, "pool_set_binding") == 0) { (void) fprintf(stderr, "%s: a system error " "occurred\n", errf); } else { #ifndef NDEBUG uu_warn("%s:%d: Bad function name \"%s\" for " "error %d from " "restarter_set_method_context().\n", __FILE__, __LINE__, errf, errno); #endif abort(); } exit(1); } if (errf != NULL && strcmp(errf, "pool_set_binding") == 0) { switch (errno) { case ENOENT: (void) fprintf(stderr, "%s: the pool could not " "be found\n", errf); break; case EBADF: (void) fprintf(stderr, "%s: the configuration " "is invalid\n", errf); break; case EINVAL: (void) fprintf(stderr, "%s: pool name \"%s\" " "is invalid\n", errf, mcp->resource_pool); break; default: #ifndef NDEBUG uu_warn("%s:%d: Bad error %d for function %s " "in restarter_set_method_context().\n", __FILE__, __LINE__, errno, errf); #endif abort(); } exit(SMF_EXIT_ERR_CONFIG); } if (errf != NULL) { perror(errf); switch (errno) { case EINVAL: case EPERM: case ENOENT: case ENAMETOOLONG: case ERANGE: case ESRCH: exit(SMF_EXIT_ERR_CONFIG); /* NOTREACHED */ default: exit(1); } } switch (errno) { case ENOMEM: (void) fputs("Out of memory.\n", stderr); exit(1); /* NOTREACHED */ case ENOENT: (void) fputs("Missing passwd entry for user.\n", stderr); exit(SMF_EXIT_ERR_CONFIG); /* NOTREACHED */ default: #ifndef NDEBUG uu_warn("%s:%d: Bad miscellaneous error %d from " "restarter_set_method_context().\n", __FILE__, __LINE__, errno); #endif abort(); } } nenv = set_smf_env(mcp->env, mcp->env_sz, NULL, inst, method); log_preexec(); (void) execle(SBIN_SH, SBIN_SH, "-c", cmd, NULL, nenv); exit(10); }
/* * init_env() * A clone of the work init.c does to provide as much compatibility * for startup scripts as possible. */ void init_env() { int i; char line[MAXCMDL]; FILE *fp; int inquotes, length, wslength; char *tokp, *cp1, *cp2; char **newp; glob_env_n = 16; glob_envp = startd_alloc(sizeof (*glob_envp) * glob_env_n); glob_envp[0] = startd_alloc((unsigned)(strlen(DEF_PATH)+2)); (void) strcpy(glob_envp[0], DEF_PATH); if ((fp = fopen(ENVFILE, "r")) == NULL) { uu_warn("Cannot open %s. Environment not initialized.\n", ENVFILE); glob_envp[1] = NULL; return; } i = 1; while (fgets(line, MAXCMDL - 1, fp) != NULL) { /* * Toss newline */ length = strlen(line); if (line[length - 1] == '\n') line[length - 1] = '\0'; /* * Ignore blank or comment lines. */ if (line[0] == '#' || line[0] == '\0' || (wslength = strspn(line, " \t\n")) == strlen(line) || strchr(line, '#') == line + wslength) continue; /* * First make a pass through the line and change * any non-quoted semi-colons to blanks so they * will be treated as token separators below. */ inquotes = 0; for (cp1 = line; *cp1 != '\0'; cp1++) { if (*cp1 == '"') { if (inquotes == 0) inquotes = 1; else inquotes = 0; } else if (*cp1 == ';') { if (inquotes == 0) *cp1 = ' '; } } /* * Tokens within the line are separated by blanks * and tabs. For each token in the line which * contains a '=' we strip out any quotes and then * stick the token in the environment array. */ if ((tokp = strtok(line, " \t")) == NULL) continue; do { cp1 = strchr(tokp, '='); if (cp1 == NULL || cp1 == tokp) continue; length = strlen(tokp); while ((cp1 = strpbrk(tokp, "\"\'")) != NULL) { for (cp2 = cp1; cp2 < &tokp[length]; cp2++) *cp2 = *(cp2 + 1); length--; } /* * init already started us with this umask, and we * handled it in startd.c, so just skip it. */ if (strncmp(tokp, "CMASK=", 6) == 0 || strncmp(tokp, "SMF_", 4) == 0) continue; glob_envp[i] = startd_alloc((unsigned)(length + 1)); (void) strcpy(glob_envp[i], tokp); /* * Double the environment size whenever it is * full. */ if (++i == glob_env_n) { glob_env_n *= 2; newp = startd_alloc(sizeof (*glob_envp) * glob_env_n); (void) memcpy(newp, glob_envp, sizeof (*glob_envp) * glob_env_n / 2); startd_free(glob_envp, sizeof (*glob_envp) * glob_env_n / 2); glob_envp = newp; } } while ((tokp = strtok(NULL, " \t")) != NULL); } startd_fclose(fp); /* Append a null pointer to the environment array to mark its end. */ glob_envp[i] = NULL; /* * Get the zonename once; it is used to set SMF_ZONENAME for methods. */ (void) getzonenamebyid(getzoneid(), zonename, sizeof (zonename)); }
/* 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); }
/* * Without -p options, just call display_pg(). Otherwise display_prop() the * named properties of the property group. */ static void process_pg(scf_propertygroup_t *pg) { scf_property_t *prop; svcprop_prop_node_t *spn; if (uu_list_first(prop_list) == NULL) { if (quiet) return; display_pg(pg); return; } prop = scf_property_create(hndl); if (prop == NULL) scfdie(); for (spn = uu_list_first(prop_list); spn != NULL; spn = uu_list_next(prop_list, spn)) { if (spn->spn_comp2 != NULL) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_pg_to_fmri(pg, buf, max_scf_fmri_length + 1) == -1) scfdie(); uu_xdie(UU_EXIT_USAGE, gettext("-p argument `%s/%s' " "has too many components for property " "group `%s'.\n"), spn->spn_comp1, spn->spn_comp2, buf); free(buf); } if (scf_pg_get_property(pg, spn->spn_comp1, prop) == 0) { if (!quiet) display_prop(pg, prop); continue; } if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_pg_to_fmri(pg, buf, max_scf_fmri_length + 1) == -1) scfdie(); uu_warn(gettext("Couldn't find property `%s' in " "property group `%s'.\n"), spn->spn_comp1, buf); free(buf); } noprop_common_action(); } }
/* * 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); }
int main(int argc, char *argv[]) { int opt; uint_t lflag, eflag, dflag, pflag, mflag, Mflag; uint8_t enable; scf_error_t serr; int exit_status = 0; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); if ((h = scf_handle_create(SCF_VERSION)) == NULL) scfdie(); if (scf_handle_bind(h) == -1) uu_die(gettext("Error: Couldn't bind to svc.configd.\n")); if (argc == 1) { list_services(); goto out; } lflag = eflag = dflag = pflag = mflag = Mflag = 0; while ((opt = getopt(argc, argv, "ledpMm?")) != -1) { switch (opt) { case 'l': lflag = 1; break; case 'e': eflag = 1; break; case 'd': dflag = 1; break; case 'p': pflag = 1; break; case 'M': Mflag = 1; break; case 'm': mflag = 1; break; case '?': if (optopt == '?') { usage(B_TRUE); goto out; } else { usage(B_FALSE); } default: usage(B_FALSE); } } /* * All options are mutually exclusive, and we must have an option * if we reached here. */ if (lflag + eflag + dflag + pflag + mflag + Mflag != 1) usage(B_FALSE); argv += optind; argc -= optind; if ((pflag == 0) && (argc == 0)) usage(B_FALSE); serr = 0; if (lflag) { serr = scf_walk_fmri(h, argc, argv, 0, list_props_cb, NULL, &exit_status, uu_warn); } else if (dflag) { enable = 0; serr = scf_walk_fmri(h, argc, argv, 0, set_svc_enable_cb, &enable, &exit_status, uu_warn); } else if (eflag) { enable = 1; serr = scf_walk_fmri(h, argc, argv, 0, set_svc_enable_cb, &enable, &exit_status, uu_warn); } else if (mflag) { arglist_t args; char **cpp = argv; uint_t fmri_args = 0; /* count number of fmri arguments */ while ((fmri_args < argc) && (strchr(*cpp, '=') == NULL)) { fmri_args++; cpp++; } /* if no x=y args or no fmri, show usage */ if ((fmri_args == argc) || (fmri_args == 0)) usage(B_FALSE); /* setup args for modify_inst_props_cb */ args.argc = argc - fmri_args; args.argv = argv + fmri_args; serr = scf_walk_fmri(h, fmri_args, argv, 0, modify_inst_props_cb, &args, &exit_status, uu_warn); } else if (Mflag) { modify_defaults(argc, argv); } else if (pflag) { /* ensure there's no trailing garbage */ if (argc != 0) usage(B_FALSE); list_defaults(); } if (serr != 0) { uu_warn(gettext("failed to iterate over instances: %s"), scf_strerror(serr)); exit(UU_EXIT_FATAL); } out: (void) scf_handle_unbind(h); scf_handle_destroy(h); return (exit_status); }
static void modify_defaults(int argc, char *argv[]) { int i, j; char *value; scf_instance_t *inst; inetd_prop_t *mod, *prop_table; size_t numprops; ssize_t max_val; int64_t new_int; if ((inst = scf_instance_create(h)) == NULL) scfdie(); if (scf_handle_decode_fmri(h, INETD_INSTANCE_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) == -1) { if (scf_error() == SCF_ERROR_NOT_FOUND) { uu_die(gettext("inetd instance missing in repository." "\n")); } else { scfdie(); } } if ((max_val = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH)) < 0) scfdie(); prop_table = get_prop_table(&numprops); if ((mod = malloc(numprops * sizeof (inetd_prop_t))) == NULL) uu_die(gettext("Error: Out of memory.\n")); (void) memcpy(mod, prop_table, numprops * sizeof (inetd_prop_t)); for (i = 0; i < argc; i++) { /* Separate argument into name and value pair */ if ((value = strchr(argv[i], '=')) == NULL) uu_die(gettext("Error: Malformed name=value pair \"%s" "\"\n"), argv[i]); *value = '\0'; value++; /* Find property name in array of defaults */ for (j = 0; mod[j].ip_name != NULL; j++) { if (!mod[j].ip_default) continue; if (strcmp(mod[j].ip_name, argv[i]) == 0) break; } if (mod[j].ip_name == NULL) uu_die(gettext("Error: \"%s\" is not a default inetd " "property.\n"), argv[i]); if (*value == '\0') uu_die(gettext("Cannot accept NULL values for default " "properties.\n")); switch (mod[j].ip_type) { case INET_TYPE_INTEGER: if (uu_strtoint(value, &new_int, sizeof (new_int), NULL, NULL, NULL) == -1) uu_die(gettext("Error: \"%s\" is not a valid " "integer value.\n"), value); mod[j].ip_value.iv_int = new_int; break; case INET_TYPE_STRING: if (strlen(value) >= max_val) uu_die(gettext("Error: String value is longer " "than %l characters.\n"), max_val); if ((mod[j].ip_value.iv_string = strdup(value)) == NULL) uu_die(gettext("Error: Out of memory.\n")); break; case INET_TYPE_BOOLEAN: if (strcasecmp(value, INETADM_TRUE_STR) == 0) mod[j].ip_value.iv_boolean = B_TRUE; else if (strcasecmp(value, INETADM_FALSE_STR) == 0) mod[j].ip_value.iv_boolean = B_FALSE; else uu_die(gettext("Error: \"%s\" is not a valid " "boolean value. (TRUE or FALSE)\n"), value); } /* mark property for modification */ mod[j].ip_error = IVE_VALID; } commit_props(inst, mod, B_TRUE); free(mod); scf_instance_destroy(inst); if (refresh_inetd() != 0) uu_warn(gettext("Warning: Unable to refresh inetd.\n")); }
/* ARGSUSED0 */ static int list_props_cb(void *data, scf_walkinfo_t *wip) { int i; const char *instname = wip->fmri; scf_simple_prop_t *prop; inetd_prop_t *proplist; const char *restart_str; boolean_t is_rpc = B_FALSE; size_t numprops; scf_handle_t *h; scf_error_t err; if (((h = scf_handle_create(SCF_VERSION)) == NULL) || (scf_handle_bind(h) == -1)) scfdie(); /* * Get the property that holds the name of this instance's * restarter, and make sure that it is inetd. */ if ((prop = scf_simple_prop_get(h, instname, SCF_PG_GENERAL, SCF_PROPERTY_RESTARTER)) == NULL) { if (scf_error() == SCF_ERROR_NOT_FOUND) uu_die(gettext("Error: Specified service instance " "\"%s\" has no restarter property. inetd is not " "the delegated restarter of this instance.\n"), instname); if (scf_error() == SCF_ERROR_INVALID_ARGUMENT) uu_die(gettext("Error: \"%s\" is not a valid service " "instance.\n"), instname); scfdie(); } if (((restart_str = scf_simple_prop_next_ustring(prop)) == NULL) || (strstr(restart_str, INETADM_INETD_STR) == NULL)) { uu_die(gettext("Error: inetd is not the delegated restarter of " "specified service instance \"%s\".\n"), instname); } scf_simple_prop_free(prop); /* * This instance is controlled by inetd, so now we display all * of its properties. First the mandatory properties, and then * the properties that have default values, substituting the * default values inherited from inetd as necessary (this is done * for us by read_instance_props()). */ if ((proplist = read_instance_props(h, instname, &numprops, &err)) == NULL) { uu_die(gettext("Unexpected libscf error: %s. Exiting.\n"), scf_strerror(err)); } scf_handle_destroy(h); (void) printf("%-9s%s\n", "SCOPE", "NAME=VALUE"); for (i = 0; i < numprops; i++) { /* Skip rpc version properties if it's not an RPC service */ if ((strcmp(PR_RPC_LW_VER_NAME, proplist[i].ip_name) == 0) || (strcmp(PR_RPC_HI_VER_NAME, proplist[i].ip_name) == 0)) if (!is_rpc) continue; /* If it's not an unset property, print it out. */ if (proplist[i].ip_error != IVE_UNSET) { if (strcmp(PR_ISRPC_NAME, proplist[i].ip_name) == 0) is_rpc = proplist[i].ip_value.iv_boolean; (void) printf("%-9s%s=", proplist[i].from_inetd ? INETADM_DEFAULT_STR : "", proplist[i].ip_name); print_prop_val(&proplist[i]); continue; } /* arg0 is non-default, but also doesn't have to be set. */ if (i == PT_ARG0_INDEX) continue; /* all other properties should have values. */ if (proplist[i].ip_default) { (void) uu_warn(gettext("Error: Property %s is missing " "and has no defined default value.\n"), proplist[i].ip_name); } else { (void) uu_warn(gettext("Error: Required property %s is " "missing.\n"), proplist[i].ip_name); } } free_instance_props(proplist); return (0); }
/*ARGSUSED*/ static int list_callback(scf_handle_t *hin, scf_instance_t *inst, void *buf) { ssize_t max_name_length; char *inst_name; scf_simple_prop_t *prop = NULL, *prop2 = NULL; const uint8_t *enabled; const char *state, *restart_str; max_name_length = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH); if ((inst_name = malloc(max_name_length + 1)) == NULL) uu_die(gettext("Error: Out of memory.\n")); /* * Get the FMRI of the instance, and check if its delegated restarter * is inetd. */ if (scf_instance_to_fmri(inst, inst_name, max_name_length + 1) < 0) return (SCF_FAILED); if ((prop = scf_simple_prop_get(hin, inst_name, SCF_PG_GENERAL, SCF_PROPERTY_RESTARTER)) == NULL) goto out; if ((restart_str = scf_simple_prop_next_ustring(prop)) == NULL) goto out; if (strstr(restart_str, INETADM_INETD_STR) == NULL) goto out; /* Free restarter prop so it can be reused below */ scf_simple_prop_free(prop); /* * We know that this instance is managed by inetd. * Now get the enabled and state properties. */ if (((prop = scf_simple_prop_get(hin, inst_name, SCF_PG_GENERAL, SCF_PROPERTY_ENABLED)) == NULL) || ((enabled = scf_simple_prop_next_boolean(prop)) == NULL)) { (void) uu_warn(gettext("Error: Instance %s is missing enabled " "property.\n"), inst_name); goto out; } if (((prop2 = scf_simple_prop_get(hin, inst_name, SCF_PG_RESTARTER, SCF_PROPERTY_STATE)) == NULL) || ((state = scf_simple_prop_next_astring(prop2)) == NULL)) { (void) uu_warn(gettext("Error: Instance %s is missing state " "property.\n"), inst_name); goto out; } /* Print enabled/disabled, state, and FMRI for the instance. */ if (*enabled) (void) printf("%-10s%-15s%s\n", INETADM_ENABLED_STR, state, inst_name); else (void) printf("%-10s%-15s%s\n", INETADM_DISABLED_STR, state, inst_name); out: free(inst_name); scf_simple_prop_free(prop); scf_simple_prop_free(prop2); return (SCF_SUCCESS); }