]>
git.saurik.com Git - apple/libinfo.git/blob - netinfo.subproj/ni_useful.c
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 * Useful stuff for programming netinfo
27 * Copyright (C) 1989 by NeXT, Inc.
30 #include <netinfo/ni.h>
35 #include <arpa/inet.h>
37 extern void *_ni_dup(void *);
44 while (*path
== '/') {
62 newname
= malloc(len
+ 1);
63 for (i
= 0; *p
!= 0; i
++) {
90 return (escindex(p
+ 1, ch
));
98 ni_fancyopenargs
*args
102 ni_setabort(ni
, args
->abort
);
103 if (args
->rtimeout
) {
104 ni_setreadtimeout(ni
, args
->rtimeout
);
106 if (args
->wtimeout
) {
107 ni_setwritetimeout(ni
, args
->wtimeout
);
117 ni_fancyopenargs
*args
126 /* look for <tag>@<address> in last component of domain */
127 start
= (char *)domain
;
128 while ((slash
= (char *)escindex(start
, '/')) != NULL
) {
129 /* found a slash, keep looking for the last one */
132 if (index(start
, '@') != NULL
) {
134 * last component in <tag>@<address> form, skip
135 * all of the leading components.
137 component
= ni_name_dup(start
);
138 newni
= ni_new(NULL
, component
);
140 if (newni
!= NULL
&& args
!= NULL
)
141 setstuff(newni
, args
);
142 if (ni
!= NULL
&& freeold
)
147 component
= ni_name_dup(domain
);
148 slash
= (char *)escindex(component
, '/');
152 unescape(&component
);
155 if (ni
!= NULL
&& args
!= NULL
) {
164 newni
= ni_new(ni
, component
);
172 if (ni
!= NULL
&& freeold
) {
180 setstuff(newni
, args
);
183 slash
= (char *)escindex(domain
, '/');
184 domain
= eatslash(slash
+ 1);
185 return (ni_relopen(ni
, domain
, TRUE
, NULL
));
193 ni_fancyopenargs
*args
199 ni
= ni_new(NULL
, ".");
205 newni
= ni_new(ni
, "..");
229 new = malloc(len
+ 1);
230 bcopy(start
, new, len
);
250 slash
= (char *)escindex(path
, '/');
251 equal
= (char *)escindex(path
, '=');
252 if (equal
!= NULL
&& (slash
== NULL
|| equal
< slash
)) {
253 key
= ni_name_dupn(path
, equal
);
254 val
= ni_name_dupn(equal
+ 1, slash
);
256 if (equal
== NULL
|| (slash
!= NULL
&& slash
< equal
)) {
257 key
= ni_name_dup("name");
258 val
= ni_name_dupn(path
, slash
);
260 key
= ni_name_dupn(path
, equal
);
261 val
= ni_name_dupn(equal
+ 1, slash
);
267 status
= ni_lookup(ni
, id
, key
, val
, &idl
);
268 if (status
!= NI_OK
) {
273 id
->nii_object
= idl
.niil_val
[0];
276 ni_idlist_free(&idl
);
281 path
= eatslash(slash
);
282 return (ni_relsearch(ni
, path
, id
));
292 return (ni_fancyopen(ni
, domain
, newni
, NULL
));
300 ni_fancyopenargs
*args
306 if (*domain
== '/') {
307 tmp
= ni_rootopen(args
);
309 return (NI_FAILED
); /* XXX: should return real error */
311 domain
= eatslash(domain
);
316 tmp
= ni_relopen(ni
, domain
, FALSE
, args
);
325 ni_needwrite(*newni
, args
== NULL
? 0 : args
->needwrite
);
339 status
= ni_root(ni
, id
);
340 if (status
!= NI_OK
) {
344 path
= eatslash(path
);
346 status
= ni_relsearch(ni
, path
, id
);
347 if (status
!= NI_OK
) {
355 _ni_append_string(char *s
, char **l
)
359 if (s
== NULL
) return l
;
362 l
= (char **)malloc(2 * sizeof(char *));
368 for (i
= 0; l
[i
] != NULL
; i
++);
369 len
= i
+ 1; /* count the NULL on the end of the list too! */
371 l
= (char **)realloc(l
, (len
+ 1) * sizeof(char *));
373 l
[len
- 1] = strdup(s
);
379 _ni_explode_string(char *s
, char c
)
385 if (s
== NULL
) return NULL
;
390 for (i
= 0; ((p
[i
] != '\0') && p
[i
] != c
); i
++);
393 for (i
= 0; i
< n
; i
++) t
[i
] = p
[i
];
395 l
= _ni_append_string(t
, l
);
398 if (p
[i
] == '\0') return l
;
399 if (p
[i
+ 1] == '\0') l
= _ni_append_string("", l
);
406 _ni_free_list(char **l
)
410 if (l
== NULL
) return;
411 for (i
= 0; l
[i
] != NULL
; i
++)
413 if (l
[i
] != NULL
) free(l
[i
]);
416 if (l
!= NULL
) free(l
);
420 ni_host_domain(char *host
, char *domspec
, void **domain
)
423 struct sockaddr_in server
;
425 int i
, is_tag
, is_local
, is_relative
;
432 /* NULL host implies localhost */
435 server
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
440 server
.sin_addr
.s_addr
= inet_addr(host
);
441 if (server
.sin_addr
.s_addr
== -1)
443 h
= gethostbyname(host
);
446 *domain
= (void *)NULL
;
447 return NI_CANTFINDADDRESS
;
449 bcopy(h
->h_addr_list
[0], &server
.sin_addr
.s_addr
, h
->h_length
);
461 else if (domspec
[0] == '/')
466 else if (!strcmp(domspec
, ".")) is_tag
= 0;
467 else if (!strcmp(domspec
, "..")) is_tag
= 0;
468 else if (!strncmp(domspec
, "./", 2)) is_tag
= 0;
469 else if (!strncmp(domspec
, "../", 3)) is_tag
= 0;
473 d0
= ni_connect(&server
, domspec
);
474 status
= ni_addrtag(d0
, &server
, &tag
);
478 *domain
= (void *)NULL
;
488 if (domspec
== NULL
) status
= ni_open(NULL
, ".", domain
);
489 else status
= ni_open(NULL
, domspec
, domain
);
493 d0
= ni_connect(&server
, "local");
494 status
= ni_addrtag(d0
, &server
, &tag
);
498 *domain
= (void *)NULL
;
502 if ((domspec
== NULL
) || (!strcmp(domspec
, ".")))
508 if (is_relative
== 1)
510 path
= _ni_explode_string(domspec
, '/');
514 path
= _ni_explode_string(domspec
+ 1, '/');
517 while (status
== NI_OK
)
519 status
= ni_open(d0
, "..", &d1
);
527 if (!strcmp(domspec
, "/"))
534 for (i
= 0; path
[i
] != NULL
; i
++)
536 status
= ni_open(d0
, path
[i
], &d1
);
540 *domain
= (void *)NULL
;
553 _ni_parse_url_hostspec(char *s
, char **u
, char **p
, char **h
)
556 char *p_at
, *p_colon
;
557 int ulen
, plen
, hlen
;
559 if (s
== NULL
) return;
560 if (s
[0] == '\0') return;
562 /* Check for [[[user][:[passwd]]]@]host */
563 p_at
= strchr(s
, '@');
567 if (hlen
== 0) return;
569 *h
= malloc(hlen
+ 1);
579 *h
= malloc(hlen
+ 1);
583 if (s
[0] == '\0') return;
585 p_colon
= strchr(s
, ':');
589 if (ulen
== 0) return;
591 *u
= malloc(ulen
+ 1);
598 plen
= strlen(p_colon
);
601 *p
= malloc(plen
+ 1);
608 *u
= malloc(ulen
+ 1);
614 ni_parse_url(char *url
, char **user
, char **password
, char **host
,
615 char **domspec
, char **dirspec
)
627 * url ::= "netinfo://" <hostspec> [/[<domainspec>][:[<dirspec>]]]
628 * hostspec ::= [[[user][:[password]]]@]hostref
629 * hostref ::= <inet_addr> | <hostname>
630 * domainspec ::= <abs_domain> | <rel_domain>
631 * dirspec ::= <path> | <unsigned_integer>
634 x
= strlen("netinfo://");
636 if (strncmp(url
, "netinfo://", x
)) return;
639 * Look for <hostspec> part
640 * Defults to NULL user, password and host
641 * NULL host implies localhost
644 for (i
= x
; (url
[i
] != '\0') && (url
[i
] != '/'); i
++) len
++;
648 str
= malloc(len
+ 1);
649 bcopy(url
+ x
, str
, len
);
652 _ni_parse_url_hostspec(str
, user
, password
, host
);
658 * Look for <domainspec> part
659 * NULL domainspec implies "."
661 if (url
[i
] != '\0') i
++;
664 for (; (url
[i
] != '\0') && (url
[i
] != ':'); i
++) len
++;
668 *domspec
= malloc(len
+ 1);
669 bcopy(url
+ x
, *domspec
, len
);
670 (*domspec
)[len
] = '\0';
674 * Look for <dirspec> part
675 * NULL <dirspec> implies "/"
677 if (url
[i
] != '\0') i
++;
680 for (; url
[i
] != '\0'; i
++) len
++;
683 *dirspec
= malloc(len
+ 1);
684 bcopy(url
+ x
, *dirspec
, len
);
685 (*dirspec
)[len
] = '\0';
690 ni_url(char *url
, void **domain
, ni_id
*dir
)
693 char *user
, *password
, *host
;
694 char *domspec
, *dirspec
;
697 nilen
= strlen("netinfo://");
699 if (strncmp(url
, "netinfo://", nilen
))
701 *domain
= (void *)NULL
;
702 return NI_CANTFINDADDRESS
;
705 ni_parse_url(url
, &user
, &password
, &host
, &domspec
, &dirspec
);
707 status
= ni_host_domain(host
, domspec
, domain
);
708 if (host
!= NULL
) free(host
);
709 if (domspec
!= NULL
) free(domspec
);
712 if (user
!= NULL
) free(user
);
713 if (password
!= NULL
) free(password
);
714 if (dirspec
!= NULL
) free(dirspec
);
720 ni_setuser(*domain
, user
);
724 if (password
!= NULL
)
726 ni_setpassword(*domain
, password
);
732 status
= ni_root(*domain
, dir
);
736 if ((dirspec
[0] >= '0') && (dirspec
[0] <= '9'))
738 dir
->nii_object
= atoi(dirspec
);
740 status
= ni_self(*domain
, dir
);
744 status
= ni_pathsearch(*domain
, dir
, dirspec
);