]>
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
);
266 status
= ni_lookup(ni
, id
, key
, val
, &idl
);
267 if (status
!= NI_OK
) {
272 id
->nii_object
= idl
.niil_val
[0];
275 ni_idlist_free(&idl
);
280 path
= eatslash(slash
);
281 return (ni_relsearch(ni
, path
, id
));
291 return (ni_fancyopen(ni
, domain
, newni
, NULL
));
299 ni_fancyopenargs
*args
305 if (*domain
== '/') {
306 tmp
= ni_rootopen(args
);
308 return (NI_FAILED
); /* XXX: should return real error */
310 domain
= eatslash(domain
);
315 tmp
= ni_relopen(ni
, domain
, FALSE
, args
);
324 ni_needwrite(*newni
, args
== NULL
? 0 : args
->needwrite
);
338 status
= ni_root(ni
, id
);
339 if (status
!= NI_OK
) {
343 path
= eatslash(path
);
345 status
= ni_relsearch(ni
, path
, id
);
346 if (status
!= NI_OK
) {
354 _ni_append_string(char *s
, char **l
)
358 if (s
== NULL
) return l
;
361 l
= (char **)malloc(2 * sizeof(char *));
367 for (i
= 0; l
[i
] != NULL
; i
++);
368 len
= i
+ 1; /* count the NULL on the end of the list too! */
370 l
= (char **)realloc(l
, (len
+ 1) * sizeof(char *));
372 l
[len
- 1] = strdup(s
);
378 _ni_explode_string(char *s
, char c
)
384 if (s
== NULL
) return NULL
;
389 for (i
= 0; ((p
[i
] != '\0') && p
[i
] != c
); i
++);
392 for (i
= 0; i
< n
; i
++) t
[i
] = p
[i
];
394 l
= _ni_append_string(t
, l
);
397 if (p
[i
] == '\0') return l
;
398 if (p
[i
+ 1] == '\0') l
= _ni_append_string("", l
);
405 _ni_free_list(char **l
)
409 if (l
== NULL
) return;
410 for (i
= 0; l
[i
] != NULL
; i
++)
412 if (l
[i
] != NULL
) free(l
[i
]);
415 if (l
!= NULL
) free(l
);
419 ni_host_domain(char *host
, char *domspec
, void **domain
)
422 struct sockaddr_in server
;
424 int i
, is_tag
, is_local
, is_relative
;
431 /* NULL host implies localhost */
434 server
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
439 server
.sin_addr
.s_addr
= inet_addr(host
);
440 if (server
.sin_addr
.s_addr
== -1)
442 h
= gethostbyname(host
);
445 *domain
= (void *)NULL
;
446 return NI_CANTFINDADDRESS
;
448 bcopy(h
->h_addr_list
[0], &server
.sin_addr
.s_addr
, h
->h_length
);
460 else if (domspec
[0] == '/')
465 else if (!strcmp(domspec
, ".")) is_tag
= 0;
466 else if (!strcmp(domspec
, "..")) is_tag
= 0;
467 else if (!strncmp(domspec
, "./", 2)) is_tag
= 0;
468 else if (!strncmp(domspec
, "../", 3)) is_tag
= 0;
472 d0
= ni_connect(&server
, domspec
);
473 status
= ni_addrtag(d0
, &server
, &tag
);
477 *domain
= (void *)NULL
;
487 if (domspec
== NULL
) status
= ni_open(NULL
, ".", domain
);
488 else status
= ni_open(NULL
, domspec
, domain
);
492 d0
= ni_connect(&server
, "local");
493 status
= ni_addrtag(d0
, &server
, &tag
);
497 *domain
= (void *)NULL
;
501 if ((domspec
== NULL
) || (!strcmp(domspec
, ".")))
507 if (is_relative
== 1)
509 path
= _ni_explode_string(domspec
, '/');
513 path
= _ni_explode_string(domspec
+ 1, '/');
516 while (status
== NI_OK
)
518 status
= ni_open(d0
, "..", &d1
);
526 if (!strcmp(domspec
, "/"))
533 for (i
= 0; path
[i
] != NULL
; i
++)
535 status
= ni_open(d0
, path
[i
], &d1
);
539 *domain
= (void *)NULL
;
552 _ni_parse_url_hostspec(char *s
, char **u
, char **p
, char **h
)
555 char *p_at
, *p_colon
;
556 int ulen
, plen
, hlen
;
558 if (s
== NULL
) return;
559 if (s
[0] == '\0') return;
561 /* Check for [[[user][:[passwd]]]@]host */
562 p_at
= strchr(s
, '@');
566 if (hlen
== 0) return;
568 *h
= malloc(hlen
+ 1);
578 *h
= malloc(hlen
+ 1);
582 if (s
[0] == '\0') return;
584 p_colon
= strchr(s
, ':');
588 if (ulen
== 0) return;
590 *u
= malloc(ulen
+ 1);
597 plen
= strlen(p_colon
);
600 *p
= malloc(plen
+ 1);
607 *u
= malloc(ulen
+ 1);
613 ni_parse_url(char *url
, char **user
, char **password
, char **host
,
614 char **domspec
, char **dirspec
)
626 * url ::= "netinfo://" <hostspec> [/[<domainspec>][:[<dirspec>]]]
627 * hostspec ::= [[[user][:[password]]]@]hostref
628 * hostref ::= <inet_addr> | <hostname>
629 * domainspec ::= <abs_domain> | <rel_domain>
630 * dirspec ::= <path> | <unsigned_integer>
633 x
= strlen("netinfo://");
635 if (strncmp(url
, "netinfo://", x
)) return;
638 * Look for <hostspec> part
639 * Defults to NULL user, password and host
640 * NULL host implies localhost
643 for (i
= x
; (url
[i
] != '\0') && (url
[i
] != '/'); i
++) len
++;
647 str
= malloc(len
+ 1);
648 bcopy(url
+ x
, str
, len
);
651 _ni_parse_url_hostspec(str
, user
, password
, host
);
657 * Look for <domainspec> part
658 * NULL domainspec implies "."
660 if (url
[i
] != '\0') i
++;
663 for (; (url
[i
] != '\0') && (url
[i
] != ':'); i
++) len
++;
667 *domspec
= malloc(len
+ 1);
668 bcopy(url
+ x
, *domspec
, len
);
669 (*domspec
)[len
] = '\0';
673 * Look for <dirspec> part
674 * NULL <dirspec> implies "/"
676 if (url
[i
] != '\0') i
++;
679 for (; url
[i
] != '\0'; i
++) len
++;
682 *dirspec
= malloc(len
+ 1);
683 bcopy(url
+ x
, *dirspec
, len
);
684 (*dirspec
)[len
] = '\0';
689 ni_url(char *url
, void **domain
, ni_id
*dir
)
692 char *user
, *password
, *host
;
693 char *domspec
, *dirspec
;
696 nilen
= strlen("netinfo://");
698 if (strncmp(url
, "netinfo://", nilen
))
700 *domain
= (void *)NULL
;
701 return NI_CANTFINDADDRESS
;
704 ni_parse_url(url
, &user
, &password
, &host
, &domspec
, &dirspec
);
706 status
= ni_host_domain(host
, domspec
, domain
);
707 if (host
!= NULL
) free(host
);
708 if (domspec
!= NULL
) free(domspec
);
711 if (user
!= NULL
) free(user
);
712 if (password
!= NULL
) free(password
);
713 if (dirspec
!= NULL
) free(dirspec
);
719 ni_setuser(*domain
, user
);
723 if (password
!= NULL
)
725 ni_setpassword(*domain
, password
);
731 status
= ni_root(*domain
, dir
);
735 if ((dirspec
[0] >= '0') && (dirspec
[0] <= '9'))
737 dir
->nii_object
= atoi(dirspec
);
739 status
= ni_self(*domain
, dir
);
743 status
= ni_pathsearch(*domain
, dir
, dirspec
);