#include "cfga_scsi.h"
typedef struct {
char *dyncomp;
char *devlink;
int l_errno;
scfga_ret_t ret;
} dyn_t;
typedef struct {
scfga_recur_t (*devlink_to_dyncomp_p)(dyn_t *dyntp);
scfga_recur_t (*dyncomp_to_devlink_p)(dyn_t *dyntp);
} dynrules_t;
typedef struct {
dyn_t *dynp;
dynrules_t *rule_array;
int nrules;
} dyncvt_t;
typedef struct {
const char *hba_phys;
const char *dyncomp;
char *path;
int l_errno;
scfga_ret_t ret;
} devpath_t;
static int drv_to_hba_logid(di_node_t node, di_minor_t minor, void *arg);
static scfga_ret_t drv_dyn_to_devpath(const char *hba_phys,
const char *dyncomp, char **pathpp, int *l_errnop);
static int do_drv_dyn_to_devpath(di_node_t node, void *arg);
static scfga_ret_t devlink_dyn_to_devpath(const char *hba_phys,
const char *dyncomp, char **pathpp, int *l_errnop);
static scfga_recur_t disk_dyncomp_to_devlink(dyn_t *dyntp);
static scfga_recur_t tape_dyncomp_to_devlink(dyn_t *dyntp);
static scfga_recur_t def_dyncomp_to_devlink(dyn_t *dyntp);
static scfga_ret_t devlink_to_dyncomp(char *devlink,
char **dyncompp, int *l_errnop);
static scfga_recur_t disk_devlink_to_dyncomp(dyn_t *dyntp);
static scfga_recur_t tape_devlink_to_dyncomp(dyn_t *dyntp);
static scfga_recur_t def_devlink_to_dyncomp(dyn_t *dyntp);
static scfga_ret_t drv_to_dyncomp(di_node_t node, const char *phys,
char **dyncompp, int *l_errnop);
static scfga_ret_t get_hba_devlink(const char *hba_phys,
char **hba_logpp, int *l_errnop);
static scfga_ret_t path_apid_dyn_to_path(const char *hba_phys, const char *dyn,
char **pathpp, int *l_errnop);
static dynrules_t dyncvt_rules[] = {
{disk_devlink_to_dyncomp, disk_dyncomp_to_devlink},
{tape_devlink_to_dyncomp, tape_dyncomp_to_devlink},
{def_devlink_to_dyncomp, def_dyncomp_to_devlink}
};
#define N_DYNRULES (sizeof (dyncvt_rules)/sizeof (dyncvt_rules[0]))
typedef struct {
char *prefix;
int nslices;
} slice_t;
static slice_t disk_slices[] = {
{"s", 16},
{"p", 5},
};
#define N_SLICE_TYPES (sizeof (disk_slices) / sizeof (disk_slices[0]))
static const char *tape_modes[] = {
"",
"b", "bn",
"c", "cb", "cbn", "cn",
"h", "hb", "hbn", "hn",
"l", "lb", "lbn", "ln",
"m", "mb", "mbn", "mn",
"n",
"u", "ub", "ubn", "un"
};
#define N_TAPE_MODES (sizeof (tape_modes) / sizeof (tape_modes[0]))
scfga_ret_t
make_hba_logid(const char *hba_phys, char **hba_logpp, int *l_errnop)
{
walkarg_t u;
pathm_t pmt = {NULL};
scfga_ret_t ret;
if (*hba_logpp != NULL) {
return (SCFGA_ERR);
}
if (get_hba_devlink(hba_phys, hba_logpp, l_errnop) == SCFGA_OK) {
assert(*hba_logpp != NULL);
return (SCFGA_OK);
}
u.minor_args.nodetype = DDI_NT_SCSI_ATTACHMENT_POINT;
u.minor_args.fcn = drv_to_hba_logid;
pmt.phys = (char *)hba_phys;
pmt.ret = SCFGA_APID_NOEXIST;
errno = 0;
ret = walk_tree(pmt.phys, &pmt, DINFOMINOR | DINFOPROP, &u,
SCFGA_WALK_MINOR, &pmt.l_errno);
if (ret == SCFGA_OK && (ret = pmt.ret) == SCFGA_OK) {
assert(pmt.log != NULL);
*hba_logpp = pmt.log;
return (SCFGA_OK);
}
if (pmt.log != NULL) {
S_FREE(pmt.log);
}
*l_errnop = pmt.l_errno;
return (ret);
}
static scfga_ret_t
get_hba_devlink(const char *hba_phys, char **hba_logpp, int *l_errnop)
{
size_t len;
scfga_ret_t ret;
int match_minor = 1;
ret = physpath_to_devlink((char *)hba_phys, hba_logpp,
l_errnop, match_minor);
if (ret != SCFGA_OK) {
return (ret);
}
assert(*hba_logpp != NULL);
len = strlen(CFGA_DEV_DIR SLASH);
(void) memmove(*hba_logpp, *hba_logpp + len,
strlen(*hba_logpp + len) + 1);
return (SCFGA_OK);
}
static int
drv_to_hba_logid(di_node_t node, di_minor_t minor, void *arg)
{
int inst;
char *drv, *mn, *log;
pathm_t *ptp;
const size_t loglen = MAXPATHLEN;
ptp = (pathm_t *)arg;
errno = 0;
mn = di_minor_name(minor);
drv = di_driver_name(node);
inst = di_instance(node);
log = calloc(1, loglen);
if (mn != NULL && drv != NULL && inst != -1 && log != NULL) {
if (snprintf(log, loglen, "%s%d:%s", drv, inst, mn) < loglen) {
ptp->ret = SCFGA_OK;
ptp->log = log;
return (DI_WALK_TERMINATE);
}
}
S_FREE(log);
return (DI_WALK_CONTINUE);
}
scfga_ret_t
apid_to_path(
const char *hba_phys,
const char *dyncomp,
char **pathpp,
int *l_errnop)
{
scfga_ret_t ret;
if (*pathpp != NULL) {
return (SCFGA_LIB_ERR);
}
if (dyncomp == NULL) {
if ((*pathpp = strdup(hba_phys)) == NULL) {
*l_errnop = errno;
return (SCFGA_LIB_ERR);
}
return (SCFGA_OK);
}
if (strchr(dyncomp, '/') != NULL) {
ret = devlink_dyn_to_devpath(hba_phys, dyncomp, pathpp,
l_errnop);
} else if (strstr(dyncomp, PATH_APID_DYN_SEP) != NULL) {
ret = path_apid_dyn_to_path(hba_phys, dyncomp, pathpp,
l_errnop);
} else {
ret = drv_dyn_to_devpath(hba_phys, dyncomp, pathpp, l_errnop);
}
assert(ret != SCFGA_OK || *pathpp != NULL);
return (ret);
}
static scfga_ret_t
path_apid_dyn_to_path(
const char *hba_phys,
const char *dyn,
char **pathpp,
int *l_errnop)
{
di_node_t root, walk_root;
di_path_t pi_node = DI_PATH_NIL;
char *root_path, *devpath, *cp;
int len;
*l_errnop = 0;
if ((hba_phys == NULL) || (pathpp != NULL) && (*pathpp != NULL)) {
return (SCFGA_LIB_ERR);
}
if ((root_path = strdup(hba_phys)) == NULL) {
*l_errnop = errno;
return (SCFGA_LIB_ERR);
}
len = strlen(DEVICES_DIR);
if (strncmp(root_path, DEVICES_DIR SLASH,
len + strlen(SLASH)) == 0) {
cp = root_path + len;
(void) memmove(root_path, cp, strlen(cp) + 1);
} else if (*root_path != '/') {
*l_errnop = 0;
S_FREE(root_path);
return (SCFGA_ERR);
}
if ((cp = GET_DYN(root_path)) != NULL) {
*cp = '\0';
}
if ((cp = strrchr(root_path, ':')) != NULL) {
*cp = '\0';
}
if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) {
*l_errnop = errno;
S_FREE(root_path);
return (SCFGA_ERR);
}
walk_root = di_lookup_node(root, root_path);
if (walk_root == DI_NODE_NIL) {
*l_errnop = errno;
di_fini(root);
S_FREE(root_path);
return (SCFGA_LIB_ERR);
}
S_FREE(root_path);
if ((pi_node = di_path_next_client(walk_root, pi_node)) ==
DI_PATH_NIL) {
di_fini(root);
return (SCFGA_APID_NOEXIST);
}
do {
if (strlen(di_path_bus_addr(pi_node)) != strlen(dyn)) {
continue;
}
if (strcmp(di_path_bus_addr(pi_node), dyn) == 0) {
devpath = di_path_devfs_path(pi_node);
if (devpath == NULL) {
*l_errnop = errno;
di_fini(root);
return (SCFGA_ERR);
}
len = strlen(DEVICES_DIR) + strlen(devpath) + 1;
*pathpp = calloc(1, len);
if (*pathpp == NULL) {
*l_errnop = errno;
di_devfs_path_free(devpath);
di_fini(root);
return (SCFGA_ERR);
} else {
(void) snprintf(*pathpp, len, "%s%s",
DEVICES_DIR, devpath);
di_devfs_path_free(devpath);
di_fini(root);
return (SCFGA_OK);
}
}
pi_node = di_path_next_client(walk_root, pi_node);
} while (pi_node != DI_PATH_NIL);
di_fini(root);
return (SCFGA_APID_NOEXIST);
}
static scfga_ret_t
drv_dyn_to_devpath(
const char *hba_phys,
const char *dyncomp,
char **pathpp,
int *l_errnop)
{
walkarg_t u;
devpath_t dpt = {NULL};
scfga_ret_t ret;
if (dyncomp == NULL || *pathpp != NULL) {
return (SCFGA_LIB_ERR);
}
u.node_args.flags = DI_WALK_CLDFIRST;
u.node_args.fcn = do_drv_dyn_to_devpath;
dpt.hba_phys = hba_phys;
dpt.dyncomp = dyncomp;
dpt.ret = SCFGA_APID_NOEXIST;
ret = walk_tree(hba_phys, &dpt, DINFOCPYALL, &u,
SCFGA_WALK_NODE, &dpt.l_errno);
if (ret == SCFGA_OK && (ret = dpt.ret) == SCFGA_OK) {
assert(dpt.path != NULL);
*pathpp = dpt.path;
return (SCFGA_OK);
}
if (dpt.path != NULL) {
S_FREE(dpt.path);
}
*l_errnop = dpt.l_errno;
return (ret);
}
static int
do_drv_dyn_to_devpath(di_node_t node, void *arg)
{
int inst, rv, match_minor;
devpath_t *dptp;
char *physpath, *drv;
char *drvinst, *devpath;
const size_t drvlen = MAXPATHLEN;
size_t devlen;
dptp = (devpath_t *)arg;
assert(dptp->hba_phys != NULL && dptp->dyncomp != NULL);
assert(dptp->path == NULL);
if (IS_STUB_NODE(node)) {
return (DI_WALK_CONTINUE);
}
errno = 0;
drv = di_driver_name(node);
inst = di_instance(node);
physpath = di_devfs_path(node);
if (drv == NULL || inst == -1 || physpath == NULL) {
rv = DI_WALK_CONTINUE;
goto out;
}
devlen = strlen(DEVICES_DIR) + strlen(physpath) + 1;
devpath = calloc(1, devlen);
drvinst = calloc(1, drvlen);
if (devpath == NULL || drvinst == NULL) {
dptp->l_errno = errno;
dptp->ret = SCFGA_LIB_ERR;
rv = DI_WALK_TERMINATE;
goto out;
}
(void) snprintf(drvinst, drvlen, "%s%d", drv, inst);
(void) snprintf(devpath, devlen, "%s%s", DEVICES_DIR, physpath);
match_minor = 0;
if (!dev_cmp(dptp->hba_phys, devpath, match_minor)) {
rv = DI_WALK_CONTINUE;
goto out;
}
if (!hba_dev_cmp(dptp->hba_phys, devpath) &&
strcmp(dptp->dyncomp, drvinst) == 0) {
dptp->ret = SCFGA_OK;
dptp->path = devpath;
rv = DI_WALK_TERMINATE;
} else {
rv = DI_WALK_CONTINUE;
}
out:
S_FREE(drvinst);
if (physpath != NULL) di_devfs_path_free(physpath);
if (dptp->ret != SCFGA_OK) S_FREE(devpath);
return (rv);
}
static int
s_readlink(char *link, char *buf, int len)
{
int count;
count = readlink(link, buf, len - 1);
if (count != -1)
buf[count] = '\0';
return (count);
}
static scfga_ret_t
devlink_dyn_to_devpath(
const char *hba_phys,
const char *dyncomp,
char **pathpp,
int *l_errnop)
{
dyn_t dynt = {NULL};
int i;
scfga_ret_t ret;
char buf[PATH_MAX], *path;
if (*pathpp != NULL) {
return (SCFGA_LIB_ERR);
}
dynt.dyncomp = (char *)dyncomp;
dynt.ret = SCFGA_APID_NOEXIST;
for (i = 0; i < N_DYNRULES; i++) {
if (dyncvt_rules[i].dyncomp_to_devlink_p(&dynt)
!= SCFGA_CONTINUE) {
break;
}
}
if (i >= N_DYNRULES) {
dynt.ret = SCFGA_APID_NOEXIST;
}
if (dynt.ret != SCFGA_OK) {
return (dynt.ret);
}
assert(dynt.devlink != NULL);
errno = 0;
if ((s_readlink(dynt.devlink, buf, PATH_MAX) == -1) ||
((path = strstr(buf, "/devices/")) == NULL) ||
((*pathpp = strdup(path)) == NULL)) {
*l_errnop = errno;
ret = SCFGA_LIB_ERR;
goto out;
}
if (!hba_dev_cmp(hba_phys, path)) {
ret = SCFGA_OK;
} else {
*l_errnop = 0;
ret = SCFGA_APID_NOEXIST;
}
out:
S_FREE(dynt.devlink);
if (ret != SCFGA_OK) S_FREE(*pathpp);
return (ret);
}
scfga_ret_t
make_dyncomp(
di_node_t node,
const char *physpath,
char **dyncompp,
int *l_errnop)
{
char *devlink = NULL;
scfga_ret_t ret;
di_minor_t minor;
char *path;
char pathbuf[MAXPATHLEN];
int match_minor;
if (*dyncompp != NULL) {
return (SCFGA_LIB_ERR);
}
minor = di_minor_next(node, DI_MINOR_NIL);
if (minor == DI_MINOR_NIL) {
match_minor = 0;
path = (char *)physpath;
} else {
match_minor = 1;
(void) snprintf(pathbuf, MAXPATHLEN, "%s:%s", physpath,
di_minor_name(minor));
path = pathbuf;
}
ret = physpath_to_devlink(path, &devlink, l_errnop, match_minor);
if (ret == SCFGA_OK) {
assert(devlink != NULL);
ret = devlink_to_dyncomp(devlink, dyncompp, l_errnop);
S_FREE(devlink);
if (ret == SCFGA_OK) {
assert(*dyncompp != NULL);
return (SCFGA_OK);
}
}
ret = drv_to_dyncomp(node, physpath, dyncompp, l_errnop);
assert(ret != SCFGA_OK || *dyncompp != NULL);
return (ret);
}
scfga_ret_t
make_path_dyncomp(
di_path_t path,
char **dyncompp,
int *l_errnop)
{
char *pi_addr;
if ((path == DI_PATH_NIL) || (*dyncompp != NULL)) {
return (SCFGA_LIB_ERR);
}
if ((pi_addr = di_path_bus_addr(path)) != NULL) {
*dyncompp = calloc(1, strlen(pi_addr) + 1);
if (*dyncompp == NULL) {
*l_errnop = errno;
return (SCFGA_LIB_ERR);
}
(void) strncpy(*dyncompp, pi_addr, strlen(pi_addr));
} else {
return (SCFGA_LIB_ERR);
}
return (SCFGA_OK);
}
static scfga_ret_t
drv_to_dyncomp(di_node_t node, const char *phys, char **dyncompp, int *l_errnop)
{
char *drv;
int inst;
const int dynlen = MAXPATHLEN;
scfga_ret_t ret;
*l_errnop = 0;
if ((*dyncompp = calloc(1, dynlen)) == NULL) {
*l_errnop = errno;
return (SCFGA_LIB_ERR);
}
drv = di_driver_name(node);
inst = di_instance(node);
if (drv != NULL && inst != -1) {
if (snprintf(*dyncompp, dynlen, "%s%d", drv, inst) < dynlen) {
return (SCFGA_OK);
} else {
ret = SCFGA_LIB_ERR;
}
} else {
ret = SCFGA_APID_NOEXIST;
}
S_FREE(*dyncompp);
return (ret);
}
static scfga_ret_t
devlink_to_dyncomp(char *devlink, char **dyncompp, int *l_errnop)
{
int i;
dyn_t dynt = {NULL};
*l_errnop = 0;
if (*dyncompp != NULL) {
return (SCFGA_LIB_ERR);
}
dynt.devlink = devlink;
dynt.ret = SCFGA_APID_NOEXIST;
for (i = 0; i < N_DYNRULES; i++) {
if (dyncvt_rules[i].devlink_to_dyncomp_p(&dynt)
!= SCFGA_CONTINUE) {
break;
}
}
if (i >= N_DYNRULES) {
dynt.ret = SCFGA_APID_NOEXIST;
}
if (dynt.ret == SCFGA_OK) {
assert(dynt.dyncomp != NULL);
*dyncompp = dynt.dyncomp;
}
return (dynt.ret);
}
static scfga_recur_t
disk_devlink_to_dyncomp(dyn_t *dyntp)
{
char *cp = NULL, *cp1 = NULL;
assert(dyntp->devlink != NULL);
dyntp->l_errno = 0;
if (dyntp->dyncomp != NULL) {
goto lib_err;
}
if (strncmp(dyntp->devlink, DEV_DSK SLASH, strlen(DEV_DSK SLASH)) &&
strncmp(dyntp->devlink, DEV_RDSK SLASH, strlen(DEV_RDSK SLASH))) {
return (SCFGA_CONTINUE);
}
cp = dyntp->devlink + strlen(DEV_DIR SLASH);
if ((dyntp->dyncomp = strdup(cp)) == NULL) {
dyntp->l_errno = errno;
goto lib_err;
}
cp1 = strrchr(dyntp->dyncomp, '/');
dyntp->ret = SCFGA_OK;
if ((cp = strchr(cp1 + 1, 's')) != NULL) {
*cp = '\0';
} else if ((cp = strchr(cp1 + 1, 'p')) != NULL) {
*cp = '\0';
} else {
S_FREE(dyntp->dyncomp);
dyntp->ret = SCFGA_ERR;
}
return (SCFGA_TERMINATE);
lib_err:
dyntp->ret = SCFGA_LIB_ERR;
return (SCFGA_TERMINATE);
}
static scfga_recur_t
disk_dyncomp_to_devlink(dyn_t *dyntp)
{
char buf[MAXPATHLEN], *cp = NULL;
int i, j;
size_t len;
struct stat sbuf;
assert(dyntp->dyncomp != NULL);
dyntp->l_errno = 0;
if (dyntp->devlink != NULL) {
dyntp->ret = SCFGA_LIB_ERR;
return (SCFGA_TERMINATE);
}
if (strncmp(dyntp->dyncomp, DSK_DIR SLASH, strlen(DSK_DIR SLASH)) != 0)
return (SCFGA_CONTINUE);
(void) snprintf(buf, sizeof (buf), "%s%s", DEV_DIR SLASH,
dyntp->dyncomp);
len = strlen(buf);
cp = buf + len;
len = sizeof (buf) - len;
for (i = 0; i < N_SLICE_TYPES; i++) {
for (j = 0; j < disk_slices[i].nslices; j++) {
if (snprintf(cp, len, "%s%d", disk_slices[i].prefix, j)
>= len) {
continue;
}
if (lstat(buf, &sbuf) != -1 && S_ISLNK(sbuf.st_mode)) {
if ((dyntp->devlink = strdup(buf)) == NULL) {
dyntp->l_errno = errno;
dyntp->ret = SCFGA_LIB_ERR;
return (SCFGA_TERMINATE);
}
dyntp->ret = SCFGA_OK;
return (SCFGA_TERMINATE);
}
}
}
dyntp->ret = SCFGA_APID_NOEXIST;
return (SCFGA_TERMINATE);
}
static scfga_recur_t
tape_devlink_to_dyncomp(dyn_t *dyntp)
{
char *cp = NULL;
assert(dyntp->devlink != NULL);
dyntp->l_errno = 0;
if (dyntp->dyncomp != NULL) {
goto lib_err;
}
if (strncmp(dyntp->devlink, DEV_RMT SLASH, strlen(DEV_RMT SLASH))) {
return (SCFGA_CONTINUE);
}
cp = dyntp->devlink + strlen(DEV_DIR SLASH);
if ((dyntp->dyncomp = strdup(cp)) == NULL) {
dyntp->l_errno = errno;
goto lib_err;
}
cp = strrchr(dyntp->dyncomp, '/');
while (isdigit(*(++cp))) {
};
*cp = '\0';
dyntp->ret = SCFGA_OK;
return (SCFGA_TERMINATE);
lib_err:
dyntp->ret = SCFGA_LIB_ERR;
return (SCFGA_TERMINATE);
}
static scfga_recur_t
tape_dyncomp_to_devlink(dyn_t *dyntp)
{
char buf[MAXPATHLEN], *cp = NULL;
int i;
size_t len = 0;
struct stat sbuf;
assert(dyntp->dyncomp != NULL);
dyntp->l_errno = 0;
if (dyntp->devlink != NULL) {
goto lib_err;
}
if (strncmp(dyntp->dyncomp, RMT_DIR SLASH, strlen(RMT_DIR SLASH))) {
return (SCFGA_CONTINUE);
}
(void) snprintf(buf, sizeof (buf), "%s%s", DEV_DIR SLASH,
dyntp->dyncomp);
len = strlen(buf);
cp = buf + len;
len = sizeof (buf) - len;
for (i = 0; i < N_TAPE_MODES; i++) {
(void) snprintf(cp, len, "%s", tape_modes[i]);
if (lstat(buf, &sbuf) != -1 && S_ISLNK(sbuf.st_mode)) {
if ((dyntp->devlink = strdup(buf)) == NULL) {
dyntp->l_errno = errno;
goto lib_err;
}
dyntp->ret = SCFGA_OK;
return (SCFGA_TERMINATE);
}
}
dyntp->ret = SCFGA_APID_NOEXIST;
return (SCFGA_TERMINATE);
lib_err:
dyntp->ret = SCFGA_LIB_ERR;
return (SCFGA_TERMINATE);
}
static scfga_recur_t
def_devlink_to_dyncomp(dyn_t *dyntp)
{
size_t len = 0;
char *cp = NULL;
assert(dyntp->devlink != NULL);
dyntp->l_errno = 0;
if (dyntp->dyncomp != NULL) {
dyntp->ret = SCFGA_LIB_ERR;
return (SCFGA_TERMINATE);
}
len = strlen(DEV_DIR SLASH);
if (strncmp(dyntp->devlink, DEV_DIR SLASH, len)) {
return (SCFGA_CONTINUE);
}
if (strchr(dyntp->devlink + len, '/') != NULL) {
cp = dyntp->devlink + len;
} else {
cp = dyntp->devlink;
}
if ((dyntp->dyncomp = strdup(cp)) == NULL) {
dyntp->l_errno = errno;
dyntp->ret = SCFGA_LIB_ERR;
} else {
dyntp->ret = SCFGA_OK;
}
return (SCFGA_TERMINATE);
}
static scfga_recur_t
def_dyncomp_to_devlink(dyn_t *dyntp)
{
struct stat sbuf;
int top;
size_t prelen, linklen;
assert(dyntp->dyncomp != NULL);
dyntp->l_errno = 0;
if (dyntp->devlink != NULL) {
goto lib_err;
}
prelen = strlen(DEV_DIR SLASH);
linklen = strlen(dyntp->dyncomp) + 1;
if (strncmp(dyntp->dyncomp, DEV_DIR SLASH, prelen) == 0) {
top = 1;
} else if (*dyntp->dyncomp != '/' && linklen > 1 &&
strchr(dyntp->dyncomp + 1, '/') != NULL) {
top = 0;
linklen += prelen;
} else {
return (SCFGA_CONTINUE);
}
if ((dyntp->devlink = calloc(1, linklen)) == NULL) {
dyntp->l_errno = errno;
goto lib_err;
}
*dyntp->devlink = '\0';
if (!top) {
(void) strcpy(dyntp->devlink, DEV_DIR SLASH);
}
(void) strcat(dyntp->devlink, dyntp->dyncomp);
if (lstat(dyntp->devlink, &sbuf) != -1 && S_ISLNK(sbuf.st_mode)) {
dyntp->ret = SCFGA_OK;
return (SCFGA_TERMINATE);
}
S_FREE(dyntp->devlink);
return (SCFGA_CONTINUE);
lib_err:
dyntp->ret = SCFGA_LIB_ERR;
return (SCFGA_TERMINATE);
}