]>
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 * 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
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Useful stuff for programming netinfo
26 * Copyright (C) 1989 by NeXT, Inc.
29 #include <netinfo/ni.h>
34 #include <arpa/inet.h>
36 extern void *_ni_dup(void *);
43 while (*path
== '/') {
61 newname
= malloc(len
+ 1);
62 for (i
= 0; *p
!= 0; i
++) {
89 return (escindex(p
+ 1, ch
));
97 ni_fancyopenargs
*args
101 ni_setabort(ni
, args
->abort
);
102 if (args
->rtimeout
) {
103 ni_setreadtimeout(ni
, args
->rtimeout
);
105 if (args
->wtimeout
) {
106 ni_setwritetimeout(ni
, args
->wtimeout
);
116 ni_fancyopenargs
*args
125 /* look for <tag>@<address> in last component of domain */
126 start
= (char *)domain
;
127 while ((slash
= (char *)escindex(start
, '/')) != NULL
) {
128 /* found a slash, keep looking for the last one */
131 if (index(start
, '@') != NULL
) {
133 * last component in <tag>@<address> form, skip
134 * all of the leading components.
136 component
= ni_name_dup(start
);
137 newni
= ni_new(NULL
, component
);
139 if (newni
!= NULL
&& args
!= NULL
)
140 setstuff(newni
, args
);
141 if (ni
!= NULL
&& freeold
)
146 component
= ni_name_dup(domain
);
147 slash
= (char *)escindex(component
, '/');
151 unescape(&component
);
154 if (ni
!= NULL
&& args
!= NULL
) {
163 newni
= ni_new(ni
, component
);
171 if (ni
!= NULL
&& freeold
) {
179 setstuff(newni
, args
);
182 slash
= (char *)escindex(domain
, '/');
183 domain
= eatslash(slash
+ 1);
184 return (ni_relopen(ni
, domain
, TRUE
, NULL
));
192 ni_fancyopenargs
*args
198 ni
= ni_new(NULL
, ".");
204 newni
= ni_new(ni
, "..");
228 new = malloc(len
+ 1);
229 bcopy(start
, new, len
);
249 slash
= (char *)escindex(path
, '/');
250 equal
= (char *)escindex(path
, '=');
251 if (equal
!= NULL
&& (slash
== NULL
|| equal
< slash
)) {
252 key
= ni_name_dupn(path
, equal
);
253 val
= ni_name_dupn(equal
+ 1, slash
);
255 if (equal
== NULL
|| (slash
!= NULL
&& slash
< equal
)) {
256 key
= ni_name_dup("name");
257 val
= ni_name_dupn(path
, slash
);
259 key
= ni_name_dupn(path
, equal
);
260 val
= ni_name_dupn(equal
+ 1, slash
);
265 status
= ni_lookup(ni
, id
, key
, val
, &idl
);
266 if (status
!= NI_OK
) {
271 id
->nii_object
= idl
.niil_val
[0];
274 ni_idlist_free(&idl
);
279 path
= eatslash(slash
);
280 return (ni_relsearch(ni
, path
, id
));
290 return (ni_fancyopen(ni
, domain
, newni
, NULL
));
298 ni_fancyopenargs
*args
304 if (*domain
== '/') {
305 tmp
= ni_rootopen(args
);
307 return (NI_FAILED
); /* XXX: should return real error */
309 domain
= eatslash(domain
);
314 tmp
= ni_relopen(ni
, domain
, FALSE
, args
);
323 ni_needwrite(*newni
, args
== NULL
? 0 : args
->needwrite
);
337 status
= ni_root(ni
, id
);
338 if (status
!= NI_OK
) {
342 path
= eatslash(path
);
344 status
= ni_relsearch(ni
, path
, id
);
345 if (status
!= NI_OK
) {
353 _ni_append_string(char *s
, char **l
)
357 if (s
== NULL
) return l
;
360 l
= (char **)malloc(2 * sizeof(char *));
366 for (i
= 0; l
[i
] != NULL
; i
++);
367 len
= i
+ 1; /* count the NULL on the end of the list too! */
369 l
= (char **)realloc(l
, (len
+ 1) * sizeof(char *));
371 l
[len
- 1] = strdup(s
);
377 _ni_explode_string(char *s
, char c
)
383 if (s
== NULL
) return NULL
;
388 for (i
= 0; ((p
[i
] != '\0') && p
[i
] != c
); i
++);
391 for (i
= 0; i
< n
; i
++) t
[i
] = p
[i
];
393 l
= _ni_append_string(t
, l
);
396 if (p
[i
] == '\0') return l
;
397 if (p
[i
+ 1] == '\0') l
= _ni_append_string("", l
);
404 _ni_free_list(char **l
)
408 if (l
== NULL
) return;
409 for (i
= 0; l
[i
] != NULL
; i
++)
411 if (l
[i
] != NULL
) free(l
[i
]);
414 if (l
!= NULL
) free(l
);
418 ni_host_domain(char *host
, char *domspec
, void **domain
)
421 struct sockaddr_in server
;
423 int i
, is_tag
, is_local
, is_relative
;
430 /* NULL host implies localhost */
433 server
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
438 server
.sin_addr
.s_addr
= inet_addr(host
);
439 if (server
.sin_addr
.s_addr
== -1)
441 h
= gethostbyname(host
);
444 *domain
= (void *)NULL
;
445 return NI_CANTFINDADDRESS
;
447 bcopy(h
->h_addr_list
[0], &server
.sin_addr
.s_addr
, h
->h_length
);
459 else if (domspec
[0] == '/')
464 else if (!strcmp(domspec
, ".")) is_tag
= 0;
465 else if (!strcmp(domspec
, "..")) is_tag
= 0;
466 else if (!strncmp(domspec
, "./", 2)) is_tag
= 0;
467 else if (!strncmp(domspec
, "../", 3)) is_tag
= 0;
471 d0
= ni_connect(&server
, domspec
);
472 status
= ni_addrtag(d0
, &server
, &tag
);
476 *domain
= (void *)NULL
;
486 if (domspec
== NULL
) status
= ni_open(NULL
, ".", domain
);
487 else status
= ni_open(NULL
, domspec
, domain
);
491 d0
= ni_connect(&server
, "local");
492 status
= ni_addrtag(d0
, &server
, &tag
);
496 *domain
= (void *)NULL
;
500 if ((domspec
== NULL
) || (!strcmp(domspec
, ".")))
506 if (is_relative
== 1)
508 path
= _ni_explode_string(domspec
, '/');
512 path
= _ni_explode_string(domspec
+ 1, '/');
515 while (status
== NI_OK
)
517 status
= ni_open(d0
, "..", &d1
);
525 if (!strcmp(domspec
, "/"))
532 for (i
= 0; path
[i
] != NULL
; i
++)
534 status
= ni_open(d0
, path
[i
], &d1
);
538 *domain
= (void *)NULL
;
551 _ni_parse_url_hostspec(char *s
, char **u
, char **p
, char **h
)
554 char *p_at
, *p_colon
;
555 int ulen
, plen
, hlen
;
557 if (s
== NULL
) return;
558 if (s
[0] == '\0') return;
560 /* Check for [[[user][:[passwd]]]@]host */
561 p_at
= strchr(s
, '@');
565 if (hlen
== 0) return;
567 *h
= malloc(hlen
+ 1);
577 *h
= malloc(hlen
+ 1);
581 if (s
[0] == '\0') return;
583 p_colon
= strchr(s
, ':');
587 if (ulen
== 0) return;
589 *u
= malloc(ulen
+ 1);
596 plen
= strlen(p_colon
);
599 *p
= malloc(plen
+ 1);
606 *u
= malloc(ulen
+ 1);
612 ni_parse_url(char *url
, char **user
, char **password
, char **host
,
613 char **domspec
, char **dirspec
)
625 * url ::= "netinfo://" <hostspec> [/[<domainspec>][:[<dirspec>]]]
626 * hostspec ::= [[[user][:[password]]]@]hostref
627 * hostref ::= <inet_addr> | <hostname>
628 * domainspec ::= <abs_domain> | <rel_domain>
629 * dirspec ::= <path> | <unsigned_integer>
632 x
= strlen("netinfo://");
634 if (strncmp(url
, "netinfo://", x
)) return;
637 * Look for <hostspec> part
638 * Defults to NULL user, password and host
639 * NULL host implies localhost
642 for (i
= x
; (url
[i
] != '\0') && (url
[i
] != '/'); i
++) len
++;
646 str
= malloc(len
+ 1);
647 bcopy(url
+ x
, str
, len
);
650 _ni_parse_url_hostspec(str
, user
, password
, host
);
656 * Look for <domainspec> part
657 * NULL domainspec implies "."
659 if (url
[i
] != '\0') i
++;
662 for (; (url
[i
] != '\0') && (url
[i
] != ':'); i
++) len
++;
666 *domspec
= malloc(len
+ 1);
667 bcopy(url
+ x
, *domspec
, len
);
668 (*domspec
)[len
] = '\0';
672 * Look for <dirspec> part
673 * NULL <dirspec> implies "/"
675 if (url
[i
] != '\0') i
++;
678 for (; url
[i
] != '\0'; i
++) len
++;
681 *dirspec
= malloc(len
+ 1);
682 bcopy(url
+ x
, *dirspec
, len
);
683 (*dirspec
)[len
] = '\0';
688 ni_url(char *url
, void **domain
, ni_id
*dir
)
691 char *user
, *password
, *host
;
692 char *domspec
, *dirspec
;
695 nilen
= strlen("netinfo://");
697 if (strncmp(url
, "netinfo://", nilen
))
699 *domain
= (void *)NULL
;
700 return NI_CANTFINDADDRESS
;
703 ni_parse_url(url
, &user
, &password
, &host
, &domspec
, &dirspec
);
705 status
= ni_host_domain(host
, domspec
, domain
);
706 if (host
!= NULL
) free(host
);
707 if (domspec
!= NULL
) free(domspec
);
710 if (user
!= NULL
) free(user
);
711 if (password
!= NULL
) free(password
);
712 if (dirspec
!= NULL
) free(dirspec
);
718 ni_setuser(*domain
, user
);
722 if (password
!= NULL
)
724 ni_setpassword(*domain
, password
);
730 status
= ni_root(*domain
, dir
);
734 if ((dirspec
[0] >= '0') && (dirspec
[0] <= '9'))
736 dir
->nii_object
= atoi(dirspec
);
738 status
= ni_self(*domain
, dir
);
742 status
= ni_pathsearch(*domain
, dir
, dirspec
);