/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
-/*
- * ALL RIGHTS RESERVED
- */
-
-#include <afs/param.h>
#include <afsconfig.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#else
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-/* map a partition id from any partition-style name */
-afs_int32 volutil_GetPartitionID(aname)
-char *aname; {
- register char tc;
+#include <afs/param.h>
+
+#include <roken.h>
+
+#include "afsutil.h"
+
+/* maximum number of partitions - must match vol/voldefs.h */
+#define VOLMAXPARTS 255
+
+/**
+ * map a partition id from any partition-style name.
+ *
+ * @param[in] aname partition name string
+ *
+ * @return partition index number
+ * @retval -1 invalid partition name
+ *
+ * @see volutil_PartitionName2_r
+ * @see volutil_PartitionName_r
+ * @see volutil_PartitionName
+ */
+afs_int32
+volutil_GetPartitionID(char *aname)
+{
+ char tc;
afs_int32 temp;
char ascii[3];
tc = *aname;
- if (tc == 0) return -1; /* unknown */
+ if (tc == 0)
+ return -1; /* unknown */
/* numbers go straight through */
if (tc >= '0' && tc <= '9') {
temp = atoi(aname);
/* this next check is to make the syntax less ambiguous when discriminating
- * between volume numbers and partition IDs. This less things like
- * bos salvage do some reasonability checks its input w/o checking
+ * between volume numbers and partition IDs. This lets things like
+ * bos salvage do some reasonability checks on its input w/o checking
* to see if the partition is really on the server.
*/
- if (temp < 0 || temp > 25) return -1;
- else return temp;
+ if (temp < 0 || temp >= VOLMAXPARTS)
+ return -1;
+ else
+ return temp;
}
/* otherwise check for vicepa or /vicepa, or just plain "a" */
ascii[2] = 0;
if (strlen(aname) <= 2) {
strcpy(ascii, aname);
- }
- else if (!strncmp(aname, "/vicep", 6)) {
- strncpy(ascii, aname+6, 2);
- }
- else if (!strncmp(aname, "vicep", 5)) {
- strncpy(ascii, aname+5, 2);
- }
- else return -1; /* bad partition name */
+ } else if (!strncmp(aname, "/vicep", 6)) {
+ if(strlcpy(ascii, aname + 6, sizeof(ascii)) >= sizeof(ascii))
+ return -1; /* bad partition name: trailing characters */
+ } else if (!strncmp(aname, "vicep", 5)) {
+ if(strlcpy(ascii, aname + 5, sizeof(ascii)) >= sizeof(ascii))
+ return -1; /* bad partition name: trailing characters */
+ } else
+ return -1; /* bad partition name */
/* now partitions are named /vicepa ... /vicepz, /vicepaa, /vicepab, .../vicepzz,
- and are numbered from 0. Do the appropriate conversion */
+ * and are numbered from 0. Do the appropriate conversion */
if (ascii[1] == 0) {
/* one char name, 0..25 */
- if (ascii[0] < 'a' || ascii[0] > 'z') return -1; /* wrongo */
+ if (ascii[0] < 'a' || ascii[0] > 'z')
+ return -1; /* wrongo */
return ascii[0] - 'a';
- }
- else {
+ } else {
/* two char name, 26 .. <whatever> */
- if (ascii[0] < 'a' || ascii[0] > 'z') return -1; /* wrongo */
- if (ascii[1] < 'a' || ascii[1] > 'z') return -1; /* just as bad */
- return (ascii[0] - 'a') * 26 + (ascii[1] - 'a') + 26;
+ if (ascii[0] < 'a' || ascii[0] > 'z')
+ return -1; /* wrongo */
+ if (ascii[1] < 'a' || ascii[1] > 'z')
+ return -1; /* just as bad */
+ temp = (ascii[0] - 'a') * 26 + (ascii[1] - 'a') + 26;
+ return (temp >= VOLMAXPARTS ? -1 : temp);
}
}
-/* map a partition number back into a partition string */
-#define BAD_VID "BAD VOLUME ID"
-#define BAD_VID_LEN (sizeof(BAD_VID))
-char *volutil_PartitionName_r(int avalue, char *tbuffer, int buflen)
+/**
+ * convert a partition index number into a partition name string (/vicepXX).
+ *
+ * @param[in] part partition index number
+ * @param[out] tbuffer buffer in which to store name
+ * @param[in] buflen length of tbuffer
+ *
+ * @return operation status
+ * @retval 0 success
+ * @retval -1 buffer too short
+ * @retval -2 invalid partition id
+ *
+ * @see volutil_PartitionName_r
+ * @see volutil_PartitionName
+ * @see volutil_GetPartitionID
+ */
+afs_int32
+volutil_PartitionName2_r(afs_int32 part, char *tbuffer, size_t buflen)
{
char tempString[3];
- register int i;
+ int i;
- if (buflen < BAD_VID_LEN) {
- if (buflen > 3)
- (void) strcpy(tbuffer, "SPC");
- else
- tbuffer[0] = '\0';
- return tbuffer;
+ if (part < 0 || part >= VOLMAXPARTS) {
+ return -2;
}
- bzero(tbuffer, buflen);
+
tempString[1] = tempString[2] = 0;
- strcpy(tbuffer, "/vicep");
- if (avalue < 0 || avalue >= (26*26+26)) {
- strcpy(tbuffer, "BAD VOLUME ID");
+ strncpy(tbuffer, "/vicep", buflen);
+ if (part <= 25) {
+ tempString[0] = 'a' + part;
+ } else {
+ part -= 26;
+ i = (part / 26);
+ tempString[0] = i + 'a';
+ tempString[1] = (part % 26) + 'a';
}
- else if (avalue <= 25) {
- tempString[0] = 'a'+avalue;
- strcat(tbuffer, tempString);
+ if (strlcat(tbuffer, tempString, buflen) >= buflen) {
+ return -1;
}
- else {
- avalue -= 26;
- i = (avalue / 26 );
- tempString[0] = i + 'a';
- tempString[1] = (avalue % 26) + 'a';
- strcat(tbuffer, tempString);
+ return 0;
+}
+
+#define BAD_VID "BAD VOLUME ID"
+#define BAD_VID_LEN (sizeof(BAD_VID))
+/**
+ * convert a partition index number into a partition name string (/vicepXX).
+ *
+ * @param[in] part partition index number
+ * @param[out] tbuffer buffer in which to store name
+ * @param[in] buflen length of tbuffer
+ *
+ * @return partition name string
+ * @retval "" buffer too short
+ * @retval "SPC" buffer too short
+ * @retval "BAD VOLUME ID" avalue contains an invalid partition index
+ *
+ * @note you may wish to consider using volutil_PartitionName2_r, as its
+ * error handling is more standard
+ *
+ * @see volutil_PartitionName2_r
+ * @see volutil_PartitionName
+ * @see volutil_GetPartitionID
+ */
+char *
+volutil_PartitionName_r(int part, char *tbuffer, int buflen)
+{
+ afs_int32 code;
+
+ if (buflen < BAD_VID_LEN) {
+ strlcpy(tbuffer, "SPC", buflen);
+ return tbuffer;
+ }
+
+ code = volutil_PartitionName2_r(part, tbuffer, buflen);
+
+ if (code == -2) {
+ strlcpy(tbuffer, BAD_VID, buflen);
}
+
return tbuffer;
}
-char *volutil_PartitionName(int avalue)
+/**
+ * convert a partition index number into a partition name string (/vicepXX).
+ *
+ * @param[in] avalue partition index number
+ *
+ * @return partition name string
+ * @retval "BAD VOLUME ID" avalue contains an invalid partition index
+ *
+ * @warning this interface is not re-entrant
+ *
+ * @see volutil_PartitionName2_r
+ * @see volutil_PartitionName_r
+ * @see volutil_GetPartitionID
+ */
+char *
+volutil_PartitionName(int avalue)
{
#define VPN_TBUFLEN 64
- static char tbuffer[VPN_TBUFLEN];
- return volutil_PartitionName_r(avalue, tbuffer, VPN_TBUFLEN-1);
+ static char tbuffer[VPN_TBUFLEN];
+ return volutil_PartitionName_r(avalue, tbuffer, VPN_TBUFLEN - 1);
}
/* is this a digit or a digit-like thing? */
-static int ismeta(ac, abase)
-register int abase;
-register int ac; {
+static int
+ismeta(int ac, int abase)
+{
/* if (ac == '-' || ac == 'x' || ac == 'X') return 1; */
- if (ac >= '0' && ac <= '7') return 1;
- if (abase <= 8) return 0;
- if (ac >= '8' && ac <= '9') return 1;
- if (abase <= 10) return 0;
- if (ac >= 'a' && ac <= 'f') return 1;
- if (ac >= 'A' && ac <= 'F') return 1;
+ if (ac >= '0' && ac <= '7')
+ return 1;
+ if (abase <= 8)
+ return 0;
+ if (ac >= '8' && ac <= '9')
+ return 1;
+ if (abase <= 10)
+ return 0;
+ if (ac >= 'a' && ac <= 'f')
+ return 1;
+ if (ac >= 'A' && ac <= 'F')
+ return 1;
return 0;
}
/* given that this is a digit or a digit-like thing, compute its value */
-static int getmeta(ac)
-register int ac; {
- if (ac >= '0' && ac <= '9') return ac - '0';
- if (ac >= 'a' && ac <= 'f') return ac - 'a' + 10;
- if (ac >= 'A' && ac <= 'F') return ac - 'A' + 10;
+static int
+getmeta(int ac)
+{
+ if (ac >= '0' && ac <= '9')
+ return ac - '0';
+ if (ac >= 'a' && ac <= 'f')
+ return ac - 'a' + 10;
+ if (ac >= 'A' && ac <= 'F')
+ return ac - 'A' + 10;
return 0;
}
-afs_int32 util_GetInt32 (as, aval)
-register char *as;
-afs_int32 *aval;
+afs_int32
+util_GetInt32(char *as, afs_int32 * aval)
{
- register afs_int32 total;
- register int tc;
+ afs_int32 total;
+ int tc;
int base;
int negative;
- total = 0; /* initialize things */
+ total = 0; /* initialize things */
negative = 0;
/* skip over leading spaces */
- while ((tc = *as)) {
- if (tc != ' ' && tc != '\t') break;
+ for (tc = *as; tc !='\0'; as++, tc = *as) {
+ if (tc != ' ' && tc != '\t')
+ break;
}
/* compute sign */
if (*as == '-') {
negative = 1;
- as++; /* skip over character */
+ as++; /* skip over character */
+ }
+
+ /* compute the base */
+ if (*as == '0') {
+ as++;
+ if (*as == 'x' || *as == 'X') {
+ base = 16;
+ as++;
+ } else
+ base = 8;
+ } else
+ base = 10;
+
+ /* compute the # itself */
+ for (tc = *as; tc !='\0'; as++, tc = *as) {
+ if (!ismeta(tc, base))
+ return -1;
+ total *= base;
+ total += getmeta(tc);
+ }
+
+ if (negative)
+ *aval = -total;
+ else
+ *aval = total;
+ return 0;
+}
+
+afs_uint32
+util_GetUInt32(char *as, afs_uint32 * aval)
+{
+ afs_uint32 total;
+ int tc;
+ int base;
+
+ total = 0; /* initialize things */
+
+ /* skip over leading spaces */
+ for (tc = *as; tc !='\0'; as++, tc = *as) {
+ if (tc != ' ' && tc != '\t')
+ break;
}
/* compute the base */
if (*as == 'x' || *as == 'X') {
base = 16;
as++;
+ } else
+ base = 8;
+ } else
+ base = 10;
+
+ /* compute the # itself */
+ for (tc = *as; tc !='\0'; as++, tc = *as) {
+ if (!ismeta(tc, base))
+ return -1;
+ total *= base;
+ total += getmeta(tc);
+ }
+
+ *aval = total;
+ return 0;
+}
+
+static const char power_letter[] = {
+ 'K', /* kibi */
+ 'M', /* mebi */
+ 'G', /* gibi */
+ 'T', /* tebi */
+};
+
+afs_int32
+util_GetHumanInt32(char *as, afs_int32 * aval)
+{
+ long value;
+ char * unit;
+ long mult = 1;
+ int exponent = 0;
+
+ errno = 0;
+ value = strtol(as, &unit, 0);
+ if (errno)
+ return -1;
+ if (unit[0] != 0) {
+ for (exponent = 0; exponent < sizeof(power_letter) && power_letter[exponent] != unit[0]; exponent++) {
+ mult *= 1024;
}
- else base = 8;
+ if (exponent == sizeof(power_letter))
+ return -1;
}
- else base = 10;
+ if (value > MAX_AFS_INT32 / mult || value < MIN_AFS_INT32 / mult)
+ return -1;
+
+ *aval = value * mult;
+
+ return 0;
+}
+
+afs_int32
+util_GetInt64(char *as, afs_int64 * aval)
+{
+ afs_int64 total;
+ int tc;
+ int base;
+ int negative;
+
+ total = 0; /* initialize things */
+ negative = 0;
+
+ /* skip over leading spaces */
+ while ((tc = *as)) {
+ if (tc != ' ' && tc != '\t')
+ break;
+ }
+
+ /* compute sign */
+ if (*as == '-') {
+ negative = 1;
+ as++; /* skip over character */
+ }
+
+ /* compute the base */
+ if (*as == '0') {
+ as++;
+ if (*as == 'x' || *as == 'X') {
+ base = 16;
+ as++;
+ } else
+ base = 8;
+ } else
+ base = 10;
/* compute the # itself */
- while((tc = *as)) {
- if (!ismeta(tc, base)) return -1;
+ while ((tc = *as)) {
+ if (!ismeta(tc, base))
+ return -1;
total *= base;
total += getmeta(tc);
as++;
}
- if (negative) *aval = -total;
- else *aval = total;
+ if (negative)
+ *aval = -total;
+ else
+ *aval = total;
return 0;
}
afs_uint32
-GetUInt32 (as, aval)
-register char *as;
-afs_uint32 *aval;
+util_GetUInt64(char *as, afs_uint64 * aval)
{
- register afs_uint32 total;
- register int tc;
+ afs_uint64 total;
+ int tc;
int base;
- total = 0; /* initialize things */
+ total = 0; /* initialize things */
/* skip over leading spaces */
while ((tc = *as)) {
- if (tc != ' ' && tc != '\t') break;
+ if (tc != ' ' && tc != '\t')
+ break;
}
/* compute the base */
if (*as == '0') {
- as++;
- if (*as == 'x' || *as == 'X') {
- base = 16;
- as++;
- }
- else base = 8;
- }
- else base = 10;
+ as++;
+ if (*as == 'x' || *as == 'X') {
+ base = 16;
+ as++;
+ } else
+ base = 8;
+ } else
+ base = 10;
/* compute the # itself */
- while((tc = *as)) {
- if (!ismeta(tc, base)) return -1;
- total *= base;
- total += getmeta(tc);
- as++;
+ while ((tc = *as)) {
+ if (!ismeta(tc, base))
+ return -1;
+ total *= base;
+ total += getmeta(tc);
+ as++;
}
-
+
*aval = total;
return 0;
}
-