]> git.saurik.com Git - apple/libinfo.git/blame - netinfo.subproj/ni_pwdomain.c
Libinfo-222.0.4.tar.gz
[apple/libinfo.git] / netinfo.subproj / ni_pwdomain.c
CommitLineData
03fb6eb0
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
ad21edcc
A
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
03fb6eb0
A
13 *
14 * The Original Code and all software distributed under the License are
ad21edcc 15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
03fb6eb0
A
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
ad21edcc
A
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
03fb6eb0
A
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Copyright (C) 1990 by NeXT, Inc. All rights reserved.
26 */
27
28/*
29 * ni_pwdomain function: present working domain for a netinfo handle
30 *
31 * usage:
32 * ni_status ni_pwdomain(void *ni, ni_name *buf)
33 *
34 * pwd is returned in buf, which can be freed with ni_name_free
35 */
36#include <stdlib.h>
37#include <unistd.h>
38#include <sys/types.h>
39#include <sys/param.h>
40#include <stdio.h>
41#include <string.h>
42#include <netinfo/ni.h>
43#include <string.h>
44#include <sys/socket.h>
45#include <net/if.h>
46#include <sys/ioctl.h>
a0865d63 47#include "sys_interfaces.h"
03fb6eb0
A
48
49extern char *inet_ntoa();
50
51static const char NAME_NAME[] = "name";
52static const char NAME_MACHINES[] = "machines";
53static const char NAME_IP_ADDRESS[] = "ip_address";
54static const char NAME_SERVES[] = "serves";
55static const char NAME_UNKNOWN[] = "###UNKNOWN###";
56
03fb6eb0
A
57static ni_name
58escape_domain(ni_name name)
59{
60 int extra;
61 char *p;
62 char *s;
63 ni_name newname;
64
65 extra = 0;
66 for (p = name; *p; p++)
67 {
68 if ((*p == '/') || (*p == '\\')) extra++;
69 }
70
71 newname = malloc(strlen(name) + extra + 1);
72 s = newname;
73 for (p = name; *p; p++)
74 {
75 if ((*p == '/') || (*p == '\\')) *s++ = '\\';
76 *s++ = *p;
77 }
78
79 *s = 0;
80 return newname;
81
82}
83
84static char *
85finddomain(void *ni, struct in_addr addr, ni_name tag)
86{
87 ni_id nid;
88 ni_idlist idl;
89 ni_namelist nl;
90 ni_index i;
91 ni_name slash;
92 ni_name domain;
93 ni_status status;
94
95 status = ni_root(ni, &nid);
96 if (status != NI_OK) return NULL;
97
98 status = ni_lookup(ni, &nid, NAME_NAME, NAME_MACHINES, &idl);
99 if (status != NI_OK) return NULL;
100
101 nid.nii_object = idl.niil_val[0];
102 ni_idlist_free(&idl);
103
104 status = ni_lookup(ni, &nid, NAME_IP_ADDRESS, inet_ntoa(addr), &idl);
105 if (status != NI_OK) return NULL;
106
107 nid.nii_object = idl.niil_val[0];
108 ni_idlist_free(&idl);
109
110 status = ni_lookupprop(ni, &nid, NAME_SERVES, &nl);
111 if (status != NI_OK) return NULL;
112
113 for (i = 0; i < nl.ninl_len; i++)
114 {
115 slash = rindex(nl.ninl_val[i], '/');
116 if (slash == NULL) continue;
117
118 if (ni_name_match(slash + 1, tag))
119 {
120 *slash = 0;
121 domain = escape_domain(nl.ninl_val[i]);
122 ni_namelist_free(&nl);
123 return domain;
124 }
125 }
126
127 ni_namelist_free(&nl);
128
129 return NULL;
130}
131
03fb6eb0
A
132static char *
133ni_domainof(void *ni, void *parent)
134{
135 struct sockaddr_in addr;
136 ni_name tag;
137 ni_name dom;
138 ni_status status;
139 interface_list_t *ilist;
140 int i;
141
142 status = ni_addrtag(ni, &addr, &tag);
143 if (status != NI_OK) return ni_name_dup(NAME_UNKNOWN);
144
145 dom = finddomain(parent, addr.sin_addr, tag);
146 if (dom != NULL)
147 {
148 ni_name_free(&tag);
149 return dom;
150 }
151
c29f2fcc 152 ilist = _libinfo_ni_sys_interfaces();
a0865d63 153 if (ilist == NULL) return ni_name_dup(NAME_UNKNOWN);
c29f2fcc 154 if (_libinfo_ni_sys_is_my_address(ilist, &(addr.sin_addr)))
03fb6eb0
A
155 {
156 /* Try all my non-loopback interfaces */
03fb6eb0
A
157 for (i = 0; i < ilist->count; i++)
158 {
159 if (ilist->interface[i].addr.s_addr == htonl(INADDR_LOOPBACK)) continue;
160
161 addr.sin_addr.s_addr = ilist->interface[i].addr.s_addr;
162 dom = finddomain(parent, addr.sin_addr, tag);
163 if (dom != NULL)
164 {
165 ni_name_free(&tag);
c29f2fcc 166 _libinfo_ni_sys_interfaces_release(ilist);
03fb6eb0
A
167 return dom;
168 }
169 }
170 }
c29f2fcc 171 _libinfo_ni_sys_interfaces_release(ilist);
03fb6eb0
A
172
173 dom = malloc(strlen(tag) + 256);
174 sprintf(dom, "%s@%s", tag, inet_ntoa(addr.sin_addr.s_addr));
175 ni_name_free(&tag);
176 return dom;
177}
178
179static ni_status
180_ni_pwdomain(void *ni, ni_name *buf)
181{
182 void *nip;
183 ni_status status;
184 int len;
185 char *dom;
186
187 /* Open domain name */
188 nip = ni_new(ni, "..");
189 if (nip == NULL)
190 {
191 (*buf) = malloc(2);
192 (*buf)[0] = 0;
193 return NI_OK;
194 }
195
196 /* Get parent's name */
197 status = _ni_pwdomain(nip, buf);
198 if (status != NI_OK) return status;
199
200 /* Get my name relative to my parent */
201 dom = ni_domainof(ni, nip);
202
203 /* Append my relative name to my parent's name */
204 len = strlen(*buf);
205 *buf = realloc(*buf, len + 1 + strlen(dom) + 1);
206 (*buf)[len] = '/';
207 strcpy(&(*buf)[len + 1], dom);
208 ni_name_free(&dom);
209 ni_free(nip);
210
211 return NI_OK;
212}
213
214/*
215 * Just call the recursive ni_pwdomain above, and then fix for case of root
216 * domain or error
217 */
218ni_status
219ni_pwdomain(void *ni, ni_name *buf)
220{
221 ni_status status;
222
223 *buf = NULL;
224 status = _ni_pwdomain(ni, buf);
225 if (status != NI_OK)
226 {
227 if (*buf != NULL) ni_name_free(buf);
228 return status;
229 }
230
231 if ((*buf)[0] == 0)
232 {
233 (*buf)[0] = '/';
234 (*buf)[1] = 0;
235 }
236
237 return NI_OK;
238}