1ae83d1671f8732bb2e19cc187320fe08dc9c962
[openafs.git] / src / util / volparse.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 RCSID
14     ("$Header$");
15
16 #ifdef HAVE_STRING_H
17 #include <string.h>
18 #else
19 #ifdef HAVE_STRINGS_H
20 #include <strings.h>
21 #endif
22 #endif
23 #ifdef HAVE_STDLIB_H
24 #include <stdlib.h>
25 #endif
26
27 /* map a partition id from any partition-style name */
28 afs_int32
29 volutil_GetPartitionID(char *aname)
30 {
31     register char tc;
32     afs_int32 temp;
33     char ascii[3];
34
35     tc = *aname;
36     if (tc == 0)
37         return -1;              /* unknown */
38     /* numbers go straight through */
39     if (tc >= '0' && tc <= '9') {
40         temp = atoi(aname);
41         /* this next check is to make the syntax less ambiguous when discriminating
42          * between volume numbers and partition IDs.  This less things like
43          * bos salvage do some reasonability checks its input w/o checking
44          * to see if the partition is really on the server.
45          */
46         if (temp < 0 || temp > 25)
47             return -1;
48         else
49             return temp;
50     }
51     /* otherwise check for vicepa or /vicepa, or just plain "a" */
52     ascii[2] = 0;
53     if (strlen(aname) <= 2) {
54         strcpy(ascii, aname);
55     } else if (!strncmp(aname, "/vicep", 6)) {
56         strncpy(ascii, aname + 6, 2);
57     } else if (!strncmp(aname, "vicep", 5)) {
58         strncpy(ascii, aname + 5, 2);
59     } else
60         return -1;              /* bad partition name */
61     /* now partitions are named /vicepa ... /vicepz, /vicepaa, /vicepab, .../vicepzz,
62      * and are numbered from 0.  Do the appropriate conversion */
63     if (ascii[1] == 0) {
64         /* one char name, 0..25 */
65         if (ascii[0] < 'a' || ascii[0] > 'z')
66             return -1;          /* wrongo */
67         return ascii[0] - 'a';
68     } else {
69         /* two char name, 26 .. <whatever> */
70         if (ascii[0] < 'a' || ascii[0] > 'z')
71             return -1;          /* wrongo */
72         if (ascii[1] < 'a' || ascii[1] > 'z')
73             return -1;          /* just as bad */
74         return (ascii[0] - 'a') * 26 + (ascii[1] - 'a') + 26;
75     }
76 }
77
78 /* map a partition number back into a partition string */
79 #define BAD_VID "BAD VOLUME ID"
80 #define BAD_VID_LEN (sizeof(BAD_VID))
81 char *
82 volutil_PartitionName_r(int avalue, char *tbuffer, int buflen)
83 {
84     char tempString[3];
85     register int i;
86
87     if (buflen < BAD_VID_LEN) {
88         if (buflen > 3)
89             (void)strcpy(tbuffer, "SPC");
90         else
91             tbuffer[0] = '\0';
92         return tbuffer;
93     }
94     memset(tbuffer, 0, buflen);
95     tempString[1] = tempString[2] = 0;
96     strcpy(tbuffer, "/vicep");
97     if (avalue < 0 || avalue >= (26 * 26 + 26)) {
98         strcpy(tbuffer, "BAD VOLUME ID");
99     } else if (avalue <= 25) {
100         tempString[0] = 'a' + avalue;
101         strcat(tbuffer, tempString);
102     } else {
103         avalue -= 26;
104         i = (avalue / 26);
105         tempString[0] = i + 'a';
106         tempString[1] = (avalue % 26) + 'a';
107         strcat(tbuffer, tempString);
108     }
109     return tbuffer;
110 }
111
112 char *
113 volutil_PartitionName(int avalue)
114 {
115 #define VPN_TBUFLEN 64
116     static char tbuffer[VPN_TBUFLEN];
117     return volutil_PartitionName_r(avalue, tbuffer, VPN_TBUFLEN - 1);
118 }
119
120 /* is this a digit or a digit-like thing? */
121 static int
122 ismeta(register int ac, register int abase)
123 {
124 /*    if (ac == '-' || ac == 'x' || ac == 'X') return 1; */
125     if (ac >= '0' && ac <= '7')
126         return 1;
127     if (abase <= 8)
128         return 0;
129     if (ac >= '8' && ac <= '9')
130         return 1;
131     if (abase <= 10)
132         return 0;
133     if (ac >= 'a' && ac <= 'f')
134         return 1;
135     if (ac >= 'A' && ac <= 'F')
136         return 1;
137     return 0;
138 }
139
140 /* given that this is a digit or a digit-like thing, compute its value */
141 static int
142 getmeta(register int ac)
143 {
144     if (ac >= '0' && ac <= '9')
145         return ac - '0';
146     if (ac >= 'a' && ac <= 'f')
147         return ac - 'a' + 10;
148     if (ac >= 'A' && ac <= 'F')
149         return ac - 'A' + 10;
150     return 0;
151 }
152
153 afs_int32
154 util_GetInt32(register char *as, afs_int32 * aval)
155 {
156     register afs_int32 total;
157     register int tc;
158     int base;
159     int negative;
160
161     total = 0;                  /* initialize things */
162     negative = 0;
163
164     /* skip over leading spaces */
165     while ((tc = *as)) {
166         if (tc != ' ' && tc != '\t')
167             break;
168     }
169
170     /* compute sign */
171     if (*as == '-') {
172         negative = 1;
173         as++;                   /* skip over character */
174     }
175
176     /* compute the base */
177     if (*as == '0') {
178         as++;
179         if (*as == 'x' || *as == 'X') {
180             base = 16;
181             as++;
182         } else
183             base = 8;
184     } else
185         base = 10;
186
187     /* compute the # itself */
188     while ((tc = *as)) {
189         if (!ismeta(tc, base))
190             return -1;
191         total *= base;
192         total += getmeta(tc);
193         as++;
194     }
195
196     if (negative)
197         *aval = -total;
198     else
199         *aval = total;
200     return 0;
201 }
202
203 afs_uint32
204 util_GetUInt32(register char *as, afs_uint32 * aval)
205 {
206     register afs_uint32 total;
207     register int tc;
208     int base;
209
210     total = 0;                  /* initialize things */
211
212     /* skip over leading spaces */
213     while ((tc = *as)) {
214         if (tc != ' ' && tc != '\t')
215             break;
216     }
217
218     /* compute the base */
219     if (*as == '0') {
220         as++;
221         if (*as == 'x' || *as == 'X') {
222             base = 16;
223             as++;
224         } else
225             base = 8;
226     } else
227         base = 10;
228
229     /* compute the # itself */
230     while ((tc = *as)) {
231         if (!ismeta(tc, base))
232             return -1;
233         total *= base;
234         total += getmeta(tc);
235         as++;
236     }
237
238     *aval = total;
239     return 0;
240 }