]> arthur.barton.de Git - netatalk.git/blob - libatalk/util/atalk_addr.c
Remove bdb env on exit
[netatalk.git] / libatalk / util / atalk_addr.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #ifndef NO_DDP
6
7 #include <sys/types.h>
8 #include <netatalk/at.h>
9 #include <netatalk/endian.h>
10 #include <atalk/util.h>
11 #include <ctype.h>
12
13 /* 
14  * Check whether "cp" is a valid ascii representation
15  * of an AppleTalk address and convert to a binary address.
16  * Examples of accepted forms are (in decimal, net of 4321,
17  * node of 65):
18  *
19  *      4321.65
20  *      0x10E1.41
21  *      16.225.65
22  *      0x10.E1.41
23  *
24  * If hex is used, and the first digit is one of A-F, the leading
25  * 0x is redundant. Returns 1 if the address is valid, 0 if not.
26  *
27  * Unlike Internet addresses, AppleTalk addresses can have leading
28  * 0's. This means that we can't support octal addressing.
29  */
30
31 int atalk_aton(char *cp, struct at_addr *addr)
32 {
33     u_int32_t val, base, n;
34     char c;
35
36     val = 0; base = 10;
37     if ( *cp == '0' && ( *++cp == 'x' || *cp == 'X' )) {
38         base = 16, cp++;
39     }
40     if ( !isdigit( *cp ) && isxdigit( *cp )) {
41         base = 16;
42     }
43
44     for ( n = 0;; n++ ) {
45         while (( c = *cp ) != '\0') {
46             if ( isascii( c ) && isdigit( c )) {
47                 val = (val * base) + (c - '0');
48                 cp++;
49                 continue;
50             }
51
52             if ( base == 16 && isascii( c ) && isxdigit( c )) {
53                 val = ( val << 4 ) + ( c + 10 - ( islower( c ) ? 'a' : 'A' ));
54                 cp++;
55                 continue;
56             }
57             break;
58         }
59
60         if ( c != '.' && c != '\0' ) {
61             return( 0 );
62         }
63
64         switch ( n ) {
65         case 0:
66             if ( addr ) {
67                 if ( val > 65535 ) {
68                     return( 0 );
69                 }
70                 addr->s_net = val;
71             }
72             if ( *cp++ ) {
73                 val = 0;
74             } else {
75                 break;
76             }
77             continue;
78
79         case 2:
80             if ( addr ) {
81                 if ( addr->s_net > 255 ) {
82                     return( 0 );
83                 }
84                 addr->s_net <<= 8;
85                 addr->s_net += addr->s_node;
86             }
87             /*FALLTHROUGH*/
88
89         case 1:
90             if ( addr ) {
91                 if ( val > 255 ) {
92                     return( 0 );
93                 }
94                 addr->s_node = val;
95             }
96             if ( *cp++ ) {
97                 val = 0;
98             } else {
99                 break;
100             }
101             continue;
102
103         default:
104             return( 0 );
105         }
106         break;
107     }
108
109     if ( n < 1 ) {
110         return( 0 );
111     }
112     if ( addr ) {
113         addr->s_net = htons( addr->s_net );
114     }
115     return (1);
116 }
117
118 #endif  /* NO_DDP */