4
0

parse.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. /*
  2. * Copyright (c) 2002-2004 MontaVista Software, Inc.
  3. *
  4. * All rights reserved.
  5. *
  6. * Author: Steven Dake (sdake@mvista.com)
  7. *
  8. * This software licensed under BSD license, the text of which follows:
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * - Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. * - Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  32. * THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <stdlib.h>
  37. #include <errno.h>
  38. #include <sys/socket.h>
  39. #include <netinet/in.h>
  40. #include <arpa/inet.h>
  41. #include "../include/ais_types.h"
  42. #include "../include/list.h"
  43. #include "util.h"
  44. #include "parse.h"
  45. #include "mempool.h"
  46. DECLARE_LIST_INIT (saAmfGroupHead);
  47. typedef enum {
  48. HEAD,
  49. GROUP,
  50. UNIT,
  51. PROTECTION,
  52. COMPONENT
  53. } SaParsingT;
  54. void setSaNameT (SaNameT *name, char *str) {
  55. strncpy ((char *)name->value, str, SA_MAX_NAME_LENGTH);
  56. if (strlen ((char *)name->value) > SA_MAX_NAME_LENGTH) {
  57. name->length = SA_MAX_NAME_LENGTH;
  58. } else {
  59. name->length = strlen (str);
  60. }
  61. }
  62. int SaNameTisEqual (SaNameT *str1, char *str2) {
  63. if (str1->length == strlen (str2)) {
  64. return ((strncmp ((char *)str1->value, (char *)str2,
  65. str1->length)) == 0);
  66. } else {
  67. return 0;
  68. }
  69. }
  70. struct saAmfComponent *findComponent (SaNameT *name)
  71. {
  72. struct list_head *AmfGroupList = 0;
  73. struct list_head *AmfUnitList = 0;
  74. struct list_head *AmfComponentList = 0;
  75. struct saAmfGroup *saAmfGroup = 0;
  76. struct saAmfUnit *AmfUnit = 0;
  77. struct saAmfComponent *AmfComponent = 0;
  78. int found = 0;
  79. /*
  80. * Search all groups
  81. */
  82. for (AmfGroupList = saAmfGroupHead.next;
  83. AmfGroupList != &saAmfGroupHead && found == 0;
  84. AmfGroupList = AmfGroupList->next) {
  85. saAmfGroup = list_entry (AmfGroupList,
  86. struct saAmfGroup, saAmfGroupList);
  87. /*
  88. * Search all units
  89. */
  90. for (AmfUnitList = saAmfGroup->saAmfUnitHead.next;
  91. AmfUnitList != &saAmfGroup->saAmfUnitHead && found == 0;
  92. AmfUnitList = AmfUnitList->next) {
  93. AmfUnit = list_entry (AmfUnitList,
  94. struct saAmfUnit, saAmfUnitList);
  95. /*
  96. * Search all components
  97. */
  98. for (AmfComponentList = AmfUnit->saAmfComponentHead.next;
  99. AmfComponentList != &AmfUnit->saAmfComponentHead && found == 0;
  100. AmfComponentList = AmfComponentList->next) {
  101. AmfComponent = list_entry (AmfComponentList,
  102. struct saAmfComponent, saAmfComponentList);
  103. if (name_match (name, &AmfComponent->name)) {
  104. found = 1;
  105. }
  106. }
  107. }
  108. }
  109. if (found) {
  110. return (AmfComponent);
  111. } else {
  112. return (0);
  113. }
  114. }
  115. char *
  116. strstr_rs (const char *haystack, const char *needle)
  117. {
  118. char *end_address;
  119. char *new_needle;
  120. new_needle = (char *)mempool_strdup (needle);
  121. new_needle[strlen(new_needle) - 1] = '\0';
  122. end_address = strstr (haystack, new_needle);
  123. if (end_address) {
  124. end_address += strlen (new_needle);
  125. end_address = strstr (end_address, needle + strlen (new_needle));
  126. }
  127. if (end_address) {
  128. end_address += 1; /* skip past { or = */
  129. do {
  130. if (*end_address == '\t' || *end_address == ' ') {
  131. end_address++;
  132. } else {
  133. break;
  134. }
  135. } while (*end_address != '\0');
  136. }
  137. mempool_free (new_needle);
  138. return (end_address);
  139. }
  140. static char error_string_response[256];
  141. int amfReadGroups (char **error_string)
  142. {
  143. char line[255];
  144. FILE *fp;
  145. SaParsingT current_parse = HEAD;
  146. int line_number = 0;
  147. char *loc;
  148. int i;
  149. struct saAmfGroup *saAmfGroup = 0;
  150. struct saAmfUnit *saAmfUnit = 0;
  151. struct saAmfProtectionGroup *saAmfProtectionGroup = 0;
  152. struct saAmfComponent *saAmfComponent = 0;
  153. struct list_head *findAmfUnitList = 0;
  154. struct list_head *findAmfComponentList = 0;
  155. struct saAmfUnit *findAmfUnit = 0;
  156. struct saAmfComponent *findAmfComponent = 0;
  157. SaNameT componentName;
  158. fp = fopen ("/etc/ais/groups.conf", "r");
  159. if (fp == 0) {
  160. sprintf (error_string_response,
  161. "ERROR: Can't read /etc/ais/groups.conf file (%s).\n", strerror (errno));
  162. *error_string = error_string_response;
  163. return (-1);
  164. }
  165. while (fgets (line, 255, fp)) {
  166. line_number += 1;
  167. line[strlen(line) - 1] = '\0';
  168. /*
  169. * Clear out white space and tabs
  170. */
  171. for (i = strlen (line) - 1; i > -1; i--) {
  172. if (line[i] == '\t' || line[i] == ' ') {
  173. line[i] = '\0';
  174. } else {
  175. break;
  176. }
  177. }
  178. /*
  179. * Clear out comments and empty lines
  180. */
  181. if (line[0] == '#' || line[0] == '\0') {
  182. continue;
  183. }
  184. switch (current_parse) {
  185. case HEAD:
  186. if (strstr_rs (line, "group{")) {
  187. saAmfGroup = (struct saAmfGroup *)mempool_malloc (sizeof (struct saAmfGroup));
  188. memset (saAmfGroup, 0, sizeof (struct saAmfGroup));
  189. list_init (&saAmfGroup->saAmfGroupList);
  190. list_init (&saAmfGroup->saAmfUnitHead);
  191. list_init (&saAmfGroup->saAmfProtectionGroupHead);
  192. list_add (&saAmfGroup->saAmfGroupList, &saAmfGroupHead);
  193. current_parse = GROUP;
  194. } else
  195. if (strcmp (line, "") == 0) {
  196. } else {
  197. goto parse_error;
  198. }
  199. break;
  200. case GROUP:
  201. if ((loc = strstr_rs (line, "name=")) != 0) {
  202. setSaNameT (&saAmfGroup->name, loc);
  203. } else
  204. if ((loc = strstr_rs (line, "model=")) != 0) {
  205. if (strcmp (loc, "2n") == 0) {
  206. saAmfGroup->model = GROUPCAPABILITYMODEL_2N;
  207. } else
  208. if (strcmp (loc, "nplusm") == 0) {
  209. saAmfGroup->model = GROUPCAPABILITYMODEL_NPLUSM;
  210. } else
  211. if (strcmp (loc, "nway") == 0) {
  212. printf ("nway redundancy model not supported.\n");
  213. goto parse_error;
  214. } else
  215. if (strcmp (loc, "nwayactive") == 0) {
  216. printf ("nway active redundancy model not supported.\n");
  217. goto parse_error;
  218. } else
  219. if (strcmp (loc, "noredundancy") == 0) {
  220. saAmfGroup->model = GROUPCAPABILITYMODEL_NOREDUNDANCY;
  221. } else {
  222. goto parse_error;
  223. }
  224. } else
  225. if ((loc = strstr_rs (line, "active-units=")) != 0) {
  226. saAmfGroup->saAmfActiveUnitsDesired = atoi (loc);
  227. } else
  228. if ((loc = strstr_rs (line, "backup-units=")) != 0) {
  229. saAmfGroup->saAmfStandbyUnitsDesired = atoi (loc);
  230. } else
  231. if (strstr_rs (line, "unit{")) {
  232. saAmfUnit = (struct saAmfUnit *)mempool_malloc (sizeof (struct saAmfUnit));
  233. memset (saAmfUnit, 0, sizeof (struct saAmfUnit));
  234. saAmfUnit->saAmfGroup = saAmfGroup;
  235. list_init (&saAmfUnit->saAmfComponentHead);
  236. list_add (&saAmfUnit->saAmfUnitList, &saAmfGroup->saAmfUnitHead);
  237. current_parse = UNIT;
  238. } else
  239. if (strstr_rs (line, "protection{")) {
  240. saAmfProtectionGroup = (struct saAmfProtectionGroup *)mempool_malloc (sizeof (struct saAmfProtectionGroup));
  241. memset (saAmfProtectionGroup, 0, sizeof (struct saAmfProtectionGroup));
  242. list_init (&saAmfProtectionGroup->saAmfMembersHead);
  243. list_init (&saAmfProtectionGroup->saAmfProtectionGroupList);
  244. list_add (&saAmfProtectionGroup->saAmfProtectionGroupList, &saAmfGroup->saAmfProtectionGroupHead);
  245. current_parse = PROTECTION;
  246. } else
  247. if (strstr_rs (line, "}")) {
  248. current_parse = HEAD;
  249. } else {
  250. goto parse_error;
  251. }
  252. break;
  253. case UNIT:
  254. if ((loc = strstr_rs (line, "name=")) != 0) {
  255. setSaNameT (&saAmfUnit->name, loc);
  256. } else
  257. if ((loc = strstr_rs (line, "component{")) != 0) {
  258. saAmfComponent = (struct saAmfComponent *)mempool_malloc (sizeof (struct saAmfComponent));
  259. memset (saAmfComponent, 0, sizeof (struct saAmfComponent));
  260. saAmfComponent->saAmfUnit = saAmfUnit;
  261. saAmfComponent->currentReadinessState = SA_AMF_OUT_OF_SERVICE;
  262. saAmfComponent->newReadinessState = SA_AMF_OUT_OF_SERVICE;
  263. saAmfComponent->currentHAState = SA_AMF_QUIESCED;
  264. saAmfComponent->newHAState = SA_AMF_QUIESCED;
  265. saAmfComponent->healthcheckInterval = 100;
  266. list_init (&saAmfComponent->saAmfComponentList);
  267. list_init (&saAmfComponent->saAmfProtectionGroupList);
  268. list_add (&saAmfComponent->saAmfComponentList, &saAmfUnit->saAmfComponentHead);
  269. current_parse = COMPONENT;
  270. } else
  271. if (strstr_rs (line, "}")) {
  272. current_parse = GROUP;
  273. } else {
  274. goto parse_error;
  275. }
  276. break;
  277. case COMPONENT:
  278. if ((loc = strstr_rs (line, "name=")) != 0) {
  279. setSaNameT (&saAmfComponent->name, loc);
  280. } else
  281. if ((loc = strstr_rs (line, "model=")) != 0) {
  282. if (strcmp (loc, "x_active_and_y_standby") == 0) {
  283. saAmfComponent->componentCapabilityModel = SA_AMF_COMPONENT_CAPABILITY_X_ACTIVE_AND_Y_STANDBY;
  284. } else
  285. if (strcmp (loc, "x_active_or_y_standby") == 0) {
  286. saAmfComponent->componentCapabilityModel = SA_AMF_COMPONENT_CAPABILITY_X_ACTIVE_OR_Y_STANDBY;
  287. } else
  288. if (strcmp (loc, "1_active_or_y_standby") == 0) {
  289. saAmfComponent->componentCapabilityModel = SA_AMF_COMPONENT_CAPABILITY_1_ACTIVE_OR_Y_STANDBY;
  290. } else
  291. if (strcmp (loc, "1_active_or_1_standby") == 0) {
  292. saAmfComponent->componentCapabilityModel = SA_AMF_COMPONENT_CAPABILITY_1_ACTIVE_OR_1_STANDBY;
  293. } else
  294. if (strcmp (loc, "x_active") == 0) {
  295. saAmfComponent->componentCapabilityModel = SA_AMF_COMPONENT_CAPABILITY_X_ACTIVE;
  296. } else
  297. if (strcmp (loc, "1_active") == 0) {
  298. saAmfComponent->componentCapabilityModel = SA_AMF_COMPONENT_CAPABILITY_1_ACTIVE;
  299. } else
  300. if (strcmp (loc, "no_active") == 0) {
  301. saAmfComponent->componentCapabilityModel = SA_AMF_COMPONENT_CAPABILITY_NO_ACTIVE;
  302. } else {
  303. goto parse_error;
  304. }
  305. } else
  306. if (strstr_rs (line, "}")) {
  307. current_parse = UNIT;
  308. } else {
  309. goto parse_error;
  310. }
  311. break;
  312. case PROTECTION:
  313. if ((loc = strstr_rs (line, "name=")) != 0) {
  314. setSaNameT (&saAmfProtectionGroup->name, loc);
  315. } else
  316. if ((loc = strstr_rs (line, "member=")) != 0) {
  317. for (findAmfUnitList = saAmfGroup->saAmfUnitHead.next;
  318. findAmfUnitList != &saAmfGroup->saAmfUnitHead;
  319. findAmfUnitList = findAmfUnitList->next) {
  320. findAmfUnit = list_entry (findAmfUnitList,
  321. struct saAmfUnit, saAmfUnitList);
  322. for (findAmfComponentList = findAmfUnit->saAmfComponentHead.next;
  323. findAmfComponentList != &findAmfUnit->saAmfComponentHead;
  324. findAmfComponentList = findAmfComponentList->next) {
  325. findAmfComponent = list_entry (findAmfComponentList,
  326. struct saAmfComponent, saAmfComponentList);
  327. if (SaNameTisEqual (&findAmfComponent->name, loc)) {
  328. list_add (&findAmfComponent->saAmfProtectionGroupList,
  329. &saAmfProtectionGroup->saAmfMembersHead);
  330. }
  331. }
  332. /*
  333. * Connect component to protection group
  334. */
  335. setSaNameT (&componentName, loc);
  336. saAmfComponent = findComponent (&componentName);
  337. saAmfComponent->saAmfProtectionGroup = saAmfProtectionGroup;
  338. }
  339. } else
  340. if (strstr_rs (line, "}")) {
  341. current_parse = GROUP;
  342. } else {
  343. goto parse_error;
  344. }
  345. break;
  346. default:
  347. printf ("Invalid state\n");
  348. goto parse_error;
  349. break;
  350. }
  351. }
  352. fclose (fp);
  353. return (0);
  354. parse_error:
  355. sprintf (error_string_response,
  356. "ERROR: parse error at /etc/groups.conf:%d.\n", line_number);
  357. *error_string = error_string_response;
  358. fclose (fp);
  359. return (-1);
  360. }
  361. int readNetwork (char **error_string,
  362. struct sockaddr_in *mcast_addr,
  363. struct gmi_interface *interfaces,
  364. int interface_count)
  365. {
  366. char line[255];
  367. FILE *fp;
  368. int res = 0;
  369. int line_number = 0;
  370. int interface_no = 0;
  371. memset (mcast_addr, 0, sizeof (struct sockaddr_in));
  372. memset (interfaces, 0, sizeof (struct gmi_interface) * interface_count);
  373. mcast_addr->sin_family = AF_INET;
  374. fp = fopen ("/etc/ais/network.conf", "r");
  375. if (fp == 0) {
  376. sprintf (error_string_response,
  377. "ERROR: Can't read /etc/ais/network.conf file (%s).\n", strerror (errno));
  378. *error_string = error_string_response;
  379. return (-1);
  380. }
  381. while (fgets (line, 255, fp)) {
  382. line_number += 1;
  383. if (strncmp ("mcastaddr:", line, strlen ("mcastaddr:")) == 0) {
  384. res = inet_aton (&line[strlen("mcastaddr:")], &mcast_addr->sin_addr);
  385. } else
  386. if (strncmp ("mcastport:", line, strlen ("mcastport:")) == 0) {
  387. res = mcast_addr->sin_port = htons (atoi (&line[strlen("mcastport:")]));
  388. } else
  389. if (strncmp ("bindnetaddr:", line, strlen ("bindnetaddr:")) == 0) {
  390. if (interface_count == interface_no) {
  391. sprintf (error_string_response,
  392. "ERROR: %d is too many interfaces in /etc/ais/network.conf %d.\n", interface_no, line_number);
  393. *error_string = error_string_response;
  394. res = -1;
  395. break;
  396. }
  397. res = inet_aton (&line[strlen("bindnetaddr:")], &interfaces[interface_no].bindnet.sin_addr);
  398. interface_no += 1;
  399. } else {
  400. res = 0;
  401. break;
  402. }
  403. if (res == 0) {
  404. sprintf (error_string_response,
  405. "ERROR: parse error at /etc/ais/network.conf:%d.\n", line_number);
  406. *error_string = error_string_response;
  407. res = -1;
  408. break;
  409. }
  410. res = 0;
  411. }
  412. fclose (fp);
  413. return (res);
  414. }