* Given a path, which may be absolute or relative, and a starting node, * return the destination node. */
| 1721 | * return the destination node. |
| 1722 | */ |
| 1723 | int |
| 1724 | ng_path2noderef(node_p here, const char *address, node_p *destp, |
| 1725 | hook_p *lasthook) |
| 1726 | { |
| 1727 | char fullpath[NG_PATHSIZ]; |
| 1728 | char *nodename, *path; |
| 1729 | node_p node, oldnode; |
| 1730 | |
| 1731 | /* Initialize */ |
| 1732 | if (destp == NULL) { |
| 1733 | TRAP_ERROR(); |
| 1734 | return EINVAL; |
| 1735 | } |
| 1736 | *destp = NULL; |
| 1737 | |
| 1738 | /* Make a writable copy of address for ng_path_parse() */ |
| 1739 | strncpy(fullpath, address, sizeof(fullpath) - 1); |
| 1740 | fullpath[sizeof(fullpath) - 1] = '\0'; |
| 1741 | |
| 1742 | /* Parse out node and sequence of hooks */ |
| 1743 | if (ng_path_parse(fullpath, &nodename, &path, NULL) < 0) { |
| 1744 | TRAP_ERROR(); |
| 1745 | return EINVAL; |
| 1746 | } |
| 1747 | |
| 1748 | /* |
| 1749 | * For an absolute address, jump to the starting node. |
| 1750 | * Note that this holds a reference on the node for us. |
| 1751 | * Don't forget to drop the reference if we don't need it. |
| 1752 | */ |
| 1753 | if (nodename) { |
| 1754 | node = ng_name2noderef(here, nodename); |
| 1755 | if (node == NULL) { |
| 1756 | TRAP_ERROR(); |
| 1757 | return (ENOENT); |
| 1758 | } |
| 1759 | } else { |
| 1760 | if (here == NULL) { |
| 1761 | TRAP_ERROR(); |
| 1762 | return (EINVAL); |
| 1763 | } |
| 1764 | node = here; |
| 1765 | NG_NODE_REF(node); |
| 1766 | } |
| 1767 | |
| 1768 | if (path == NULL) { |
| 1769 | if (lasthook != NULL) |
| 1770 | *lasthook = NULL; |
| 1771 | *destp = node; |
| 1772 | return (0); |
| 1773 | } |
| 1774 | |
| 1775 | /* |
| 1776 | * Now follow the sequence of hooks |
| 1777 | * |
| 1778 | * XXXGL: The path may demolish as we go the sequence, but if |
| 1779 | * we hold the topology mutex at critical places, then, I hope, |
| 1780 | * we would always have valid pointers in hand, although the |
no test coverage detected