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