2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (C) 1990 by NeXT, Inc. All rights reserved.
30 * ni_pwdomain function: present working domain for a netinfo handle
33 * ni_status ni_pwdomain(void *ni, ni_name *buf)
35 * pwd is returned in buf, which can be freed with ni_name_free
39 #include <sys/types.h>
40 #include <sys/param.h>
43 #include <netinfo/ni.h>
45 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48 #include "sys_interfaces.h"
50 extern char *inet_ntoa();
52 static const char NAME_NAME
[] = "name";
53 static const char NAME_MACHINES
[] = "machines";
54 static const char NAME_IP_ADDRESS
[] = "ip_address";
55 static const char NAME_SERVES
[] = "serves";
56 static const char NAME_UNKNOWN
[] = "###UNKNOWN###";
59 escape_domain(ni_name name
)
67 for (p
= name
; *p
; p
++)
69 if ((*p
== '/') || (*p
== '\\')) extra
++;
72 newname
= malloc(strlen(name
) + extra
+ 1);
74 for (p
= name
; *p
; p
++)
76 if ((*p
== '/') || (*p
== '\\')) *s
++ = '\\';
86 finddomain(void *ni
, struct in_addr addr
, ni_name tag
)
96 status
= ni_root(ni
, &nid
);
97 if (status
!= NI_OK
) return NULL
;
99 status
= ni_lookup(ni
, &nid
, NAME_NAME
, NAME_MACHINES
, &idl
);
100 if (status
!= NI_OK
) return NULL
;
102 nid
.nii_object
= idl
.niil_val
[0];
103 ni_idlist_free(&idl
);
105 status
= ni_lookup(ni
, &nid
, NAME_IP_ADDRESS
, inet_ntoa(addr
), &idl
);
106 if (status
!= NI_OK
) return NULL
;
108 nid
.nii_object
= idl
.niil_val
[0];
109 ni_idlist_free(&idl
);
111 status
= ni_lookupprop(ni
, &nid
, NAME_SERVES
, &nl
);
112 if (status
!= NI_OK
) return NULL
;
114 for (i
= 0; i
< nl
.ninl_len
; i
++)
116 slash
= rindex(nl
.ninl_val
[i
], '/');
117 if (slash
== NULL
) continue;
119 if (ni_name_match(slash
+ 1, tag
))
122 domain
= escape_domain(nl
.ninl_val
[i
]);
123 ni_namelist_free(&nl
);
128 ni_namelist_free(&nl
);
134 ni_domainof(void *ni
, void *parent
)
136 struct sockaddr_in addr
;
140 interface_list_t
*ilist
;
143 status
= ni_addrtag(ni
, &addr
, &tag
);
144 if (status
!= NI_OK
) return ni_name_dup(NAME_UNKNOWN
);
146 dom
= finddomain(parent
, addr
.sin_addr
, tag
);
153 ilist
= sys_interfaces();
154 if (ilist
== NULL
) return ni_name_dup(NAME_UNKNOWN
);
155 if (sys_is_my_address(ilist
, &(addr
.sin_addr
)))
157 /* Try all my non-loopback interfaces */
158 for (i
= 0; i
< ilist
->count
; i
++)
160 if (ilist
->interface
[i
].addr
.s_addr
== htonl(INADDR_LOOPBACK
)) continue;
162 addr
.sin_addr
.s_addr
= ilist
->interface
[i
].addr
.s_addr
;
163 dom
= finddomain(parent
, addr
.sin_addr
, tag
);
167 sys_interfaces_release(ilist
);
172 sys_interfaces_release(ilist
);
174 dom
= malloc(strlen(tag
) + 256);
175 sprintf(dom
, "%s@%s", tag
, inet_ntoa(addr
.sin_addr
.s_addr
));
181 _ni_pwdomain(void *ni
, ni_name
*buf
)
188 /* Open domain name */
189 nip
= ni_new(ni
, "..");
197 /* Get parent's name */
198 status
= _ni_pwdomain(nip
, buf
);
199 if (status
!= NI_OK
) return status
;
201 /* Get my name relative to my parent */
202 dom
= ni_domainof(ni
, nip
);
204 /* Append my relative name to my parent's name */
206 *buf
= realloc(*buf
, len
+ 1 + strlen(dom
) + 1);
208 strcpy(&(*buf
)[len
+ 1], dom
);
216 * Just call the recursive ni_pwdomain above, and then fix for case of root
220 ni_pwdomain(void *ni
, ni_name
*buf
)
225 status
= _ni_pwdomain(ni
, buf
);
228 if (*buf
!= NULL
) ni_name_free(buf
);