blob: 3f057c3d5490621b1243c696d980b15f4f955cd7 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation
* All rights reserved.
* This program and the accompanying materials
* are made available under the terms of the BSD License
* which accompanies this distribution, and is available at
* http://www.opensource.org/licenses/bsd-license.php
*
* Contributors:
* IBM Corporation - initial implementation
*****************************************************************************/
#include <stdint.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "args.h"
/**
* Returns pointer of the n'th argument within a string.
*
* @param arg_str string with arguments, separated with ','
* @param index index of the requested arguments within arg_str
* @return pointer of argument[index] on success
* NULL if index is out of range
*/
const char *
get_arg_ptr(const char *arg_str, unsigned int index)
{
unsigned int i;
for (i = 0; i < index; ++i) {
for (; *arg_str != ',' && *arg_str != 0; ++arg_str);
if (*arg_str == 0)
return 0;
++arg_str;
}
return arg_str;
}
/**
* Returns number of arguments within a string.
*
* @param arg_str string with arguments, separated with ','
* @return number of arguments
*/
unsigned int
get_args_count(const char *arg_str)
{
unsigned int count = 1;
while ((arg_str = get_arg_ptr(arg_str, 1)) != 0)
++count;
return count;
}
/**
* Returns the length of the first argument.
*
* @param arg_str string with arguments, separated with ','
* @return length of first argument
*/
unsigned int
get_arg_length(const char *arg_str)
{
unsigned int i;
for (i = 0; *arg_str != ',' && *arg_str != 0; ++i)
++arg_str;
return i;
}
/**
* Copy the n'th argument within a string into a buffer in respect
* to a limited buffer size
*
* @param arg_str string with arguments, separated with ','
* @param index index of the requested arguments within arg_str
* @param buffer pointer to the buffer
* @param length size of the buffer
* @return pointer of buffer on success
* NULL if index is out of range.
*/
char *
argncpy(const char *arg_str, unsigned int index, char *buffer,
unsigned int length)
{
const char *ptr = get_arg_ptr(arg_str, index);
unsigned int len;
if (!ptr)
return 0;
len = get_arg_length(ptr);
if (!strncpy(buffer, ptr, length))
return 0;
buffer[len] = 0;
return buffer;
}
/**
* Converts "255.255.255.255\nn" -> char[4] = { 0xff, 0xff, 0xff, 0xff }
* *netmask = subnet_netmask(nn)
*
* @param str string to be converted
* @param ip in case of SUCCESS - 32-bit long IP
* in case of FAULT - zero
* @param netmask return netmask if there is a valid /nn encoding in IP
* @return TRUE - IP converted successfully;
* FALSE - error condition occurs (e.g. bad format)
*/
int
strtoip_netmask(const char *str, char ip[4], unsigned int *netmask)
{
char octet[10];
int res;
unsigned int i = 0, len, has_nn = 0;
while (*str != 0) {
if (i > 3 || !isdigit(*str))
return 0;
if (strstr(str, ".") != NULL) {
len = (int16_t) (strstr(str, ".") - str);
if (len >= 10)
return 0;
strncpy(octet, str, len);
octet[len] = 0;
str += len;
} else if (strchr(str, '\\') != NULL) {
len = (short) (strchr(str, '\\') - str);
if (len >= 10)
return 0;
strncpy(octet, str, len);
octet[len] = 0;
str += len;
has_nn = 1;
} else {
strncpy(octet, str, 9);
octet[9] = 0;
str += strlen(octet);
}
res = strtol(octet, NULL, 10);
if ((res > 255) || (res < 0))
return 0;
ip[i] = (char) res;
i++;
if (*str == '.')
str++;
if(has_nn) {
str++;
strncpy(octet, str, 9);
octet[9] = 0;
res = strtol(octet, NULL, 10);
str += strlen(octet);
if (res > 31 || res < 1)
return 0;
if (netmask)
*netmask = 0xFFFFFFFF << (32 - res);
}
}
if (i != 4)
return 0;
return -1;
}
/**
* Converts "255.255.255.255" -> char[4] = { 0xff, 0xff, 0xff, 0xff }
*
* @param str string to be converted
* @param ip in case of SUCCESS - 32-bit long IP
* in case of FAULT - zero
* @return TRUE - IP converted successfully;
* FALSE - error condition occurs (e.g. bad format)
*/
int
strtoip(const char *str, char ip[4])
{
return strtoip_netmask(str, ip, NULL);
}