#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
-
-#ifdef HAVE_STRING_H
#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
+#include <errno.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
-/* map a partition id from any partition-style name */
+#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)
{
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)
+ if (temp < 0 || temp >= VOLMAXPARTS)
return -1;
else
return temp;
return -1; /* wrongo */
if (ascii[1] < 'a' || ascii[1] > 'z')
return -1; /* just as bad */
- return (ascii[0] - 'a') * 26 + (ascii[1] - 'a') + 26;
+ 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;
- 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;
}
- memset(tbuffer, 0, buflen);
+
tempString[1] = tempString[2] = 0;
- strcpy(tbuffer, "/vicep");
- if (avalue < 0 || avalue >= (26 * 26 + 26)) {
- strcpy(tbuffer, "BAD VOLUME ID");
- } else if (avalue <= 25) {
- tempString[0] = 'a' + avalue;
- strcat(tbuffer, tempString);
+ strncpy(tbuffer, "/vicep", buflen);
+ if (part <= 25) {
+ tempString[0] = 'a' + part;
} else {
- avalue -= 26;
- i = (avalue / 26);
+ part -= 26;
+ i = (part / 26);
tempString[0] = i + 'a';
- tempString[1] = (avalue % 26) + 'a';
- strcat(tbuffer, tempString);
+ tempString[1] = (part % 26) + 'a';
+ }
+ if (strlcat(tbuffer, tempString, buflen) >= buflen) {
+ return -1;
+ }
+ 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;
}
+/**
+ * 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)
{
negative = 0;
/* skip over leading spaces */
- while ((tc = *as)) {
+ for (tc = *as; tc !='\0'; as++, tc = *as) {
if (tc != ' ' && tc != '\t')
break;
}
base = 10;
/* compute the # itself */
- while ((tc = *as)) {
+ for (tc = *as; tc !='\0'; as++, tc = *as) {
if (!ismeta(tc, base))
return -1;
total *= base;
total += getmeta(tc);
- as++;
}
if (negative)
total = 0; /* initialize things */
/* skip over leading spaces */
- while ((tc = *as)) {
+ for (tc = *as; tc !='\0'; as++, tc = *as) {
if (tc != ' ' && tc != '\t')
break;
}
base = 10;
/* compute the # itself */
- while ((tc = *as)) {
+ for (tc = *as; tc !='\0'; as++, tc = *as) {
if (!ismeta(tc, base))
return -1;
total *= base;
total += getmeta(tc);
- as++;
}
*aval = total;
return 0;
}
+
+static const char power_letter[] = {
+ 'K', /* kibi */
+ 'M', /* mebi */
+ 'G', /* gibi */
+ 'T', /* tebi */
+};
+
+afs_int32
+util_GetHumanInt32(register 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;
+ }
+ if (exponent == sizeof(power_letter))
+ return -1;
+ }
+ if (value > MAX_AFS_INT32 / mult || value < MIN_AFS_INT32 / mult)
+ return -1;
+
+ *aval = value * mult;
+
+ return 0;
+}