1 /******************************************************************************
2 * Copyright (c) 2004, 2008 IBM Corporation
3 * All rights reserved.
4 * This program and the accompanying materials
5 * are made available under the terms of the BSD License
6 * which accompanies this distribution, and is available at
7 * http://www.opensource.org/licenses/bsd-license.php
8 *
9 * Contributors:
10 * IBM Corporation - initial implementation
11 *****************************************************************************/
12
13 #include <stdint.h>
14 #include <ctype.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "args.h"
18
19 /**
20 * Returns pointer of the n'th argument within a string.
21 *
22 * @param arg_str string with arguments, separated with ','
23 * @param index index of the requested arguments within arg_str
24 * @return pointer of argument[index] on success
25 * NULL if index is out of range
26 */
27 const char *
get_arg_ptr(const char * arg_str,unsigned int index)28 get_arg_ptr(const char *arg_str, unsigned int index)
29 {
30 unsigned int i;
31
32 for (i = 0; i < index; ++i) {
33 for (; *arg_str != ',' && *arg_str != 0; ++arg_str);
34 if (*arg_str == 0)
35 return 0;
36 ++arg_str;
37 }
38 return arg_str;
39 }
40
41 /**
42 * Returns number of arguments within a string.
43 *
44 * @param arg_str string with arguments, separated with ','
45 * @return number of arguments
46 */
47 unsigned int
get_args_count(const char * arg_str)48 get_args_count(const char *arg_str)
49 {
50 unsigned int count = 1;
51
52 while ((arg_str = get_arg_ptr(arg_str, 1)) != 0)
53 ++count;
54 return count;
55 }
56
57 /**
58 * Returns the length of the first argument.
59 *
60 * @param arg_str string with arguments, separated with ','
61 * @return length of first argument
62 */
63 unsigned int
get_arg_length(const char * arg_str)64 get_arg_length(const char *arg_str)
65 {
66 unsigned int i;
67
68 for (i = 0; *arg_str != ',' && *arg_str != 0; ++i)
69 ++arg_str;
70 return i;
71 }
72
73 /**
74 * Copy the n'th argument within a string into a buffer in respect
75 * to a limited buffer size
76 *
77 * @param arg_str string with arguments, separated with ','
78 * @param index index of the requested arguments within arg_str
79 * @param buffer pointer to the buffer
80 * @param length size of the buffer
81 * @return pointer of buffer on success
82 * NULL if index is out of range.
83 */
84 char *
argncpy(const char * arg_str,unsigned int index,char * buffer,unsigned int length)85 argncpy(const char *arg_str, unsigned int index, char *buffer,
86 unsigned int length)
87 {
88 const char *ptr = get_arg_ptr(arg_str, index);
89 unsigned int len;
90
91 if (!ptr)
92 return 0;
93 len = get_arg_length(ptr);
94 if (!strncpy(buffer, ptr, length))
95 return 0;
96 buffer[len] = 0;
97 return buffer;
98 }
99
100 /**
101 * Converts "255.255.255.255\nn" -> char[4] = { 0xff, 0xff, 0xff, 0xff }
102 * *netmask = subnet_netmask(nn)
103 *
104 * @param str string to be converted
105 * @param ip in case of SUCCESS - 32-bit long IP
106 * in case of FAULT - zero
107 * @param netmask return netmask if there is a valid /nn encoding in IP
108 * @return TRUE - IP converted successfully;
109 * FALSE - error condition occurs (e.g. bad format)
110 */
111 int
strtoip_netmask(const char * str,char ip[4],unsigned int * netmask)112 strtoip_netmask(const char *str, char ip[4], unsigned int *netmask)
113 {
114 char octet[10];
115 int res;
116 unsigned int i = 0, len, has_nn = 0;
117
118 while (*str != 0) {
119 if (i > 3 || !isdigit(*str))
120 return 0;
121 if (strstr(str, ".") != NULL) {
122 len = (int16_t) (strstr(str, ".") - str);
123 if (len >= 10)
124 return 0;
125 strncpy(octet, str, len);
126 octet[len] = 0;
127 str += len;
128 } else if (strchr(str, '\\') != NULL) {
129 len = (short) (strchr(str, '\\') - str);
130 if (len >= 10)
131 return 0;
132 strncpy(octet, str, len);
133 octet[len] = 0;
134 str += len;
135 has_nn = 1;
136 } else {
137 strncpy(octet, str, 9);
138 octet[9] = 0;
139 str += strlen(octet);
140 }
141 res = strtol(octet, NULL, 10);
142 if ((res > 255) || (res < 0))
143 return 0;
144 ip[i] = (char) res;
145 i++;
146 if (*str == '.')
147 str++;
148 if(has_nn) {
149 str++;
150 strncpy(octet, str, 9);
151 octet[9] = 0;
152 res = strtol(octet, NULL, 10);
153 str += strlen(octet);
154 if (res > 31 || res < 1)
155 return 0;
156 if (netmask)
157 *netmask = 0xFFFFFFFF << (32 - res);
158 }
159 }
160
161 if (i != 4)
162 return 0;
163 return -1;
164 }
165
166 /**
167 * Converts "255.255.255.255" -> char[4] = { 0xff, 0xff, 0xff, 0xff }
168 *
169 * @param str string to be converted
170 * @param ip in case of SUCCESS - 32-bit long IP
171 * in case of FAULT - zero
172 * @return TRUE - IP converted successfully;
173 * FALSE - error condition occurs (e.g. bad format)
174 */
175 int
strtoip(const char * str,char ip[4])176 strtoip(const char *str, char ip[4])
177 {
178 return strtoip_netmask(str, ip, NULL);
179 }
180