0
|
1 /*
|
|
2 * CDDL HEADER START
|
|
3 *
|
|
4 * The contents of this file are subject to the terms of the
|
|
5 * Common Development and Distribution License, Version 1.0 only
|
|
6 * (the "License"). You may not use this file except in compliance
|
|
7 * with the License.
|
|
8 *
|
|
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
10 * or http://www.opensolaris.org/os/licensing.
|
|
11 * See the License for the specific language governing permissions
|
|
12 * and limitations under the License.
|
|
13 *
|
|
14 * When distributing Covered Code, include this CDDL HEADER in each
|
|
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
16 * If applicable, add the following below this CDDL HEADER, with the
|
|
17 * fields enclosed by brackets "[]" replaced with your own identifying
|
|
18 * information: Portions Copyright [yyyy] [name of copyright owner]
|
|
19 *
|
|
20 * CDDL HEADER END
|
|
21 */
|
|
22 /*
|
|
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
|
24 * Use is subject to license terms.
|
|
25 */
|
|
26
|
|
27 #pragma ident "@(#)scheme.c 1.3 05/06/08 SMI"
|
|
28
|
|
29 #include <fm/fmd_fmri.h>
|
|
30
|
|
31 /*
|
|
32 * buf_append -- Append str to buf (if it's non-NULL). Place prepend
|
|
33 * in buf in front of str and append behind it (if they're non-NULL).
|
|
34 * Continue to update size even if we run out of space to actually
|
|
35 * stuff characters in the buffer.
|
|
36 */
|
|
37 static void
|
|
38 buf_append(ssize_t *sz, char *buf, size_t buflen, char *str,
|
|
39 char *prepend, char *append)
|
|
40 {
|
|
41 ssize_t left;
|
|
42
|
|
43 if (str == NULL)
|
|
44 return;
|
|
45
|
|
46 if (buflen == 0 || (left = buflen - *sz) < 0)
|
|
47 left = 0;
|
|
48
|
|
49 if (buf != NULL && left != 0)
|
|
50 buf += *sz;
|
|
51
|
|
52 if (prepend == NULL && append == NULL)
|
|
53 *sz += snprintf(buf, left, "%s", str);
|
|
54 else if (append == NULL)
|
|
55 *sz += snprintf(buf, left, "%s%s", prepend, str);
|
|
56 else if (prepend == NULL)
|
|
57 *sz += snprintf(buf, left, "%s%s", str, append);
|
|
58 else
|
|
59 *sz += snprintf(buf, left, "%s%s%s", prepend, str, append);
|
|
60 }
|
|
61
|
|
62 ssize_t
|
|
63 fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen)
|
|
64 {
|
|
65 nvlist_t *anvl = NULL;
|
|
66 uint8_t version;
|
|
67 ssize_t size = 0;
|
|
68 char *pkgname = NULL;
|
|
69 char *achas = NULL;
|
|
70 char *adom = NULL;
|
|
71 char *aprod = NULL;
|
|
72 char *asrvr = NULL;
|
|
73 char *ahost = NULL;
|
|
74 int more_auth = 0;
|
|
75 int err;
|
|
76
|
|
77 if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 ||
|
|
78 version > FM_PKG_SCHEME_VERSION)
|
|
79 return (fmd_fmri_set_errno(EINVAL));
|
|
80
|
|
81 /* Get authority, if present */
|
|
82 err = nvlist_lookup_nvlist(nvl, FM_FMRI_AUTHORITY, &anvl);
|
|
83 if (err != 0 && err != ENOENT)
|
|
84 return (fmd_fmri_set_errno(err));
|
|
85
|
|
86 /*
|
|
87 * For brevity, we only include the pkgname and any authority
|
|
88 * info present in the FMRI in our output string. The FMRI
|
|
89 * also has data on the package directory and version.
|
|
90 */
|
|
91 err = nvlist_lookup_string(nvl, FM_FMRI_PKG_INST, &pkgname);
|
|
92 if (err != 0 || pkgname == NULL)
|
|
93 return (fmd_fmri_set_errno(EINVAL));
|
|
94
|
|
95 if (anvl != NULL) {
|
|
96 (void) nvlist_lookup_string(anvl,
|
|
97 FM_FMRI_AUTH_PRODUCT, &aprod);
|
|
98 (void) nvlist_lookup_string(anvl,
|
|
99 FM_FMRI_AUTH_CHASSIS, &achas);
|
|
100 (void) nvlist_lookup_string(anvl,
|
|
101 FM_FMRI_AUTH_DOMAIN, &adom);
|
|
102 (void) nvlist_lookup_string(anvl,
|
|
103 FM_FMRI_AUTH_SERVER, &asrvr);
|
|
104 (void) nvlist_lookup_string(anvl,
|
|
105 FM_FMRI_AUTH_HOST, &ahost);
|
|
106 if (aprod != NULL)
|
|
107 more_auth++;
|
|
108 if (achas != NULL)
|
|
109 more_auth++;
|
|
110 if (adom != NULL)
|
|
111 more_auth++;
|
|
112 if (asrvr != NULL)
|
|
113 more_auth++;
|
|
114 if (ahost != NULL)
|
|
115 more_auth++;
|
|
116 }
|
|
117
|
|
118 /* pkg:// */
|
|
119 buf_append(&size, buf, buflen, FM_FMRI_SCHEME_PKG, NULL, "://");
|
|
120
|
|
121 /* authority, if any */
|
|
122 if (aprod != NULL)
|
|
123 buf_append(&size, buf, buflen, aprod, FM_FMRI_AUTH_PRODUCT "=",
|
|
124 --more_auth > 0 ? "," : NULL);
|
|
125 if (achas != NULL)
|
|
126 buf_append(&size, buf, buflen, achas, FM_FMRI_AUTH_CHASSIS "=",
|
|
127 --more_auth > 0 ? "," : NULL);
|
|
128 if (adom != NULL)
|
|
129 buf_append(&size, buf, buflen, adom, FM_FMRI_AUTH_DOMAIN "=",
|
|
130 --more_auth > 0 ? "," : NULL);
|
|
131 if (asrvr != NULL)
|
|
132 buf_append(&size, buf, buflen, asrvr, FM_FMRI_AUTH_SERVER "=",
|
|
133 --more_auth > 0 ? "," : NULL);
|
|
134 if (ahost != NULL)
|
|
135 buf_append(&size, buf, buflen, ahost, FM_FMRI_AUTH_HOST "=",
|
|
136 NULL);
|
|
137
|
|
138 /* pkg-name part */
|
|
139 buf_append(&size, buf, buflen, pkgname, "/", NULL);
|
|
140
|
|
141 return (size);
|
|
142 }
|
|
143
|
|
144 /*
|
|
145 * fmd_fmri_present() is called by fmadm to determine if a faulty ASRU
|
|
146 * is still present in the system. In general we don't expect to get
|
|
147 * ASRUs in this scheme, so it's unlikely this routine will get called.
|
|
148 * In case it does, though, we just return true by default, as we have no
|
|
149 * real way to look up the component in the system configuration.
|
|
150 */
|
|
151 /*ARGSUSED*/
|
|
152 int
|
|
153 fmd_fmri_present(nvlist_t *nvl)
|
|
154 {
|
|
155 return (1);
|
|
156 }
|
|
157
|
|
158 /*
|
|
159 * fmd_fmri_unusable() is called by fmadm to determine if a faulty ASRU
|
|
160 * is usable. In general we don't expect to get ASRUs in this scheme,
|
|
161 * so it's unlikely this routine will get called. In case it does,
|
|
162 * though, we just return false by default, as we have no real way to
|
|
163 * find the component or determine the component's usability.
|
|
164 */
|
|
165 /*ARGSUSED*/
|
|
166 int
|
|
167 fmd_fmri_unusable(nvlist_t *nvl)
|
|
168 {
|
|
169 return (0);
|
|
170 }
|