/libax25-0.0.12-rc2/procutils.c

# · C · 681 lines · 559 code · 101 blank · 21 comment · 143 complexity · 310644f2f3c181ddb0d0c8e6b5bca5bf MD5 · raw file

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <config.h>
  6. #include <netax25/ax25.h> /* Needed by nrconfig.h */
  7. #include <netax25/nrconfig.h>
  8. #include <netax25/procutils.h>
  9. #include "pathnames.h"
  10. #define min(a,b) ((a) < (b) ? (a) : (b))
  11. static char *space = " \t\n\r";
  12. /*
  13. * Version of atoi() that returns zero if s == NULL.
  14. */
  15. static int safe_atoi(const char *s)
  16. {
  17. return s ? atoi(s) : 0;
  18. }
  19. /*
  20. * Version of atox() that returns zero if s == NULL.
  21. */
  22. static unsigned long safe_atox(const char *s)
  23. {
  24. return s ? strtoul(s, NULL, 16) : 0;
  25. }
  26. /*
  27. * Version of strncpy() that returns NULL if either src or dest is NULL
  28. * and also makes sure destination string is always terminated.
  29. */
  30. static char *safe_strncpy(char *dest, char *src, int n)
  31. {
  32. if (!dest || !src)
  33. return NULL;
  34. dest[n] = 0;
  35. return strncpy(dest, src, n);
  36. }
  37. /*
  38. * Our version of strtok(). This one does not touch the original string,
  39. * reports the identity of the delimitting character and does not
  40. * retain any state info.
  41. */
  42. static char *token(char **ptr, const char *delim)
  43. {
  44. static char buf[256];
  45. char *start;
  46. int len;
  47. if (!ptr || !*ptr || !delim)
  48. return NULL;
  49. start = *ptr + strspn(*ptr, delim);
  50. len = strcspn(start, delim);
  51. *ptr = start + len;
  52. if (len == 0)
  53. return NULL;
  54. len = min(len, sizeof(buf) - 1);
  55. memcpy(buf, start, len);
  56. buf[len] = 0;
  57. return buf;
  58. }
  59. static char *strip_zero_ssid(char *call)
  60. {
  61. char *cp;
  62. if ((cp = strstr(call, "-0")) != NULL)
  63. *cp = 0;
  64. return call;
  65. }
  66. struct proc_ax25 *read_proc_ax25(void)
  67. {
  68. FILE *fp;
  69. char buffer[256], *cp;
  70. struct proc_ax25 *p;
  71. struct proc_ax25 *list = NULL;
  72. errno = 0;
  73. if ((fp = fopen(PROC_AX25_FILE, "r")) == NULL)
  74. return NULL;
  75. while (fgets(buffer, 256, fp) != NULL) {
  76. if ((p = calloc(1, sizeof(struct proc_ax25))) == NULL)
  77. break;
  78. cp = buffer;
  79. p->magic = safe_atox(token(&cp, space));
  80. safe_strncpy(p->dev, token(&cp, space), 13);
  81. safe_strncpy(p->src_addr, token(&cp, space), 9);
  82. safe_strncpy(p->dest_addr, token(&cp, ", \t\r\n"), 9);
  83. p->ndigi = 0;
  84. while (*cp == ',' && p->ndigi < 9) {
  85. safe_strncpy(p->digi_addr[p->ndigi],
  86. token(&cp, ", \t\r\n"), 10);
  87. p->ndigi++;
  88. }
  89. p->st = safe_atoi(token(&cp, space));
  90. p->vs = safe_atoi(token(&cp, space));
  91. p->vr = safe_atoi(token(&cp, space));
  92. p->va = safe_atoi(token(&cp, space));
  93. p->t1timer = safe_atoi(token(&cp, space));
  94. p->t1 = safe_atoi(token(&cp, space));
  95. p->t2timer = safe_atoi(token(&cp, space));
  96. p->t2 = safe_atoi(token(&cp, space));
  97. p->t3timer = safe_atoi(token(&cp, space));
  98. p->t3 = safe_atoi(token(&cp, space));
  99. p->idletimer = safe_atoi(token(&cp, space));
  100. p->idle = safe_atoi(token(&cp, space));
  101. p->n2count = safe_atoi(token(&cp, space));
  102. p->n2 = safe_atoi(token(&cp, space));
  103. p->rtt = safe_atoi(token(&cp, space));
  104. p->window = safe_atoi(token(&cp, space));
  105. p->paclen = safe_atoi(token(&cp, space));
  106. p->sndq = safe_atoi(token(&cp, space));
  107. p->rcvq = safe_atoi(token(&cp, space));
  108. p->inode = safe_atoi(token(&cp, space));
  109. p->next = list;
  110. list = p;
  111. }
  112. fclose(fp);
  113. return list;
  114. }
  115. void free_proc_ax25(struct proc_ax25 *ap)
  116. {
  117. struct proc_ax25 *p;
  118. while (ap != NULL) {
  119. p = ap->next;
  120. free(ap);
  121. ap = p;
  122. }
  123. }
  124. struct proc_ax25_route *read_proc_ax25_route(void)
  125. {
  126. FILE *fp;
  127. char buffer[256], *cp;
  128. struct proc_ax25_route *new, *tmp, *p;
  129. struct proc_ax25_route *list = NULL;
  130. int i = 0;
  131. errno = 0;
  132. if ((fp = fopen(PROC_AX25_ROUTE_FILE, "r")) == NULL)
  133. return NULL;
  134. while (fgets(buffer, 256, fp) != NULL) {
  135. if (!i++) continue;
  136. if ((new = calloc(1, sizeof(struct proc_ax25_route))) == NULL)
  137. break;
  138. cp = buffer;
  139. safe_strncpy(new->call, token(&cp, space), 9);
  140. safe_strncpy(new->dev, token(&cp, space), 13);
  141. new->cnt = safe_atoi(token(&cp, space));
  142. new->t = safe_atoi(token(&cp, space));
  143. if (list == NULL || new->t > list->t) {
  144. tmp = list;
  145. list = new;
  146. new->next = tmp;
  147. } else {
  148. for (p = list; p->next != NULL; p = p->next)
  149. if (new->t > p->next->t)
  150. break;
  151. tmp = p->next;
  152. p->next = new;
  153. new->next = tmp;
  154. }
  155. }
  156. fclose(fp);
  157. return list;
  158. }
  159. void free_proc_ax25_route(struct proc_ax25_route *rp)
  160. {
  161. struct proc_ax25_route *p;
  162. while (rp != NULL) {
  163. p = rp->next;
  164. free(rp);
  165. rp = p;
  166. }
  167. }
  168. struct proc_nr *read_proc_nr(void)
  169. {
  170. FILE *fp;
  171. char buffer[256], *cp;
  172. struct proc_nr *p;
  173. struct proc_nr *list = NULL;
  174. int i = 0;
  175. errno = 0;
  176. if ((fp = fopen(PROC_NR_FILE, "r")) == NULL)
  177. return NULL;
  178. while (fgets(buffer, 256, fp) != NULL) {
  179. if (!i++) continue;
  180. if ((p = calloc(1, sizeof(struct proc_nr))) == NULL)
  181. break;
  182. cp = buffer;
  183. safe_strncpy(p->user_addr, token(&cp, space), 9);
  184. safe_strncpy(p->dest_node, token(&cp, space), 9);
  185. safe_strncpy(p->src_node, token(&cp, space), 9);
  186. safe_strncpy(p->dev, token(&cp, space), 13);
  187. safe_strncpy(p->my_circuit, token(&cp, space), 5);
  188. safe_strncpy(p->ur_circuit, token(&cp, space), 5);
  189. p->st = safe_atoi(token(&cp, space));
  190. p->vs = safe_atoi(token(&cp, space));
  191. p->vr = safe_atoi(token(&cp, space));
  192. p->va = safe_atoi(token(&cp, space));
  193. p->t1timer = safe_atoi(token(&cp, "/"));
  194. p->t1 = safe_atoi(token(&cp, "/ \t\r\n"));
  195. p->t2timer = safe_atoi(token(&cp, "/"));
  196. p->t2 = safe_atoi(token(&cp, "/ \t\r\n"));
  197. p->t4timer = safe_atoi(token(&cp, "/"));
  198. p->t4 = safe_atoi(token(&cp, "/ \t\r\n"));
  199. p->idletimer = safe_atoi(token(&cp, "/"));
  200. p->idle = safe_atoi(token(&cp, "/ \t\r\n"));
  201. p->n2count = safe_atoi(token(&cp, "/"));
  202. p->n2 = safe_atoi(token(&cp, "/ \t\r\n"));
  203. p->window = safe_atoi(token(&cp, space));
  204. p->sndq = safe_atoi(token(&cp, space));
  205. p->rcvq = safe_atoi(token(&cp, space));
  206. p->inode = safe_atoi(token(&cp, space));
  207. p->next = list;
  208. list = p;
  209. }
  210. fclose(fp);
  211. return list;
  212. }
  213. void free_proc_nr(struct proc_nr *np)
  214. {
  215. struct proc_nr *p;
  216. while (np != NULL) {
  217. p = np->next;
  218. free(np);
  219. np = p;
  220. }
  221. }
  222. struct proc_nr_neigh *read_proc_nr_neigh(void)
  223. {
  224. FILE *fp;
  225. char buffer[256], *cp;
  226. struct proc_nr_neigh *p;
  227. struct proc_nr_neigh *list = NULL;
  228. int i = 0;
  229. errno = 0;
  230. if ((fp = fopen(PROC_NR_NEIGH_FILE, "r")) == NULL)
  231. return NULL;
  232. while (fgets(buffer, 256, fp) != NULL) {
  233. if (!i++) continue;
  234. if ((p = calloc(1, sizeof(struct proc_nr_neigh))) == NULL)
  235. break;
  236. cp = buffer;
  237. p->addr = safe_atoi(token(&cp, space));
  238. safe_strncpy(p->call, token(&cp, space), 9);
  239. safe_strncpy(p->dev, token(&cp, space), 13);
  240. p->qual = safe_atoi(token(&cp, space));
  241. p->lock = safe_atoi(token(&cp, space));
  242. p->cnt = safe_atoi(token(&cp, space));
  243. p->next = list;
  244. list = p;
  245. }
  246. fclose(fp);
  247. return list;
  248. }
  249. void free_proc_nr_neigh(struct proc_nr_neigh *np)
  250. {
  251. struct proc_nr_neigh *p;
  252. while (np != NULL) {
  253. p = np->next;
  254. free(np);
  255. np = p;
  256. }
  257. }
  258. struct proc_nr_nodes *read_proc_nr_nodes(void)
  259. {
  260. FILE *fp;
  261. char buffer[256], *cp;
  262. struct proc_nr_nodes *new, *tmp, *p;
  263. struct proc_nr_nodes *list = NULL;
  264. char *name;
  265. int i = 0;
  266. errno = 0;
  267. if ((fp = fopen(PROC_NR_NODES_FILE, "r")) == NULL)
  268. return NULL;
  269. while (fgets(buffer, 256, fp) != NULL) {
  270. if (!i++) continue;
  271. if ((new = calloc(1, sizeof(struct proc_nr_nodes))) == NULL)
  272. break;
  273. cp = buffer;
  274. safe_strncpy(new->call, token(&cp, space), 9);
  275. strip_zero_ssid(new->call);
  276. safe_strncpy(new->alias, token(&cp, space), 6);
  277. new->w = safe_atoi(token(&cp, space));
  278. new->n = safe_atoi(token(&cp, space));
  279. new->qual1 = safe_atoi(token(&cp, space));
  280. new->obs1 = safe_atoi(token(&cp, space));
  281. new->addr1 = safe_atoi(token(&cp, space));
  282. if (new->n > 1) {
  283. new->qual2 = safe_atoi(token(&cp, space));
  284. new->obs2 = safe_atoi(token(&cp, space));
  285. new->addr2 = safe_atoi(token(&cp, space));
  286. }
  287. if (new->n > 2) {
  288. new->qual3 = safe_atoi(token(&cp, space));
  289. new->obs3 = safe_atoi(token(&cp, space));
  290. new->addr3 = safe_atoi(token(&cp, space));
  291. }
  292. if (list == NULL || strcmp(new->alias, list->alias) < 0) {
  293. tmp = list;
  294. list = new;
  295. new->next = tmp;
  296. } else {
  297. for (p = list; p->next != NULL; p = p->next)
  298. if (strcmp(new->alias, p->next->alias) < 0)
  299. break;
  300. tmp = p->next;
  301. p->next = new;
  302. new->next = tmp;
  303. }
  304. }
  305. /*
  306. * Now load the local nodes.
  307. */
  308. name = NULL;
  309. while ((name = nr_config_get_next(name)) != NULL) {
  310. if ((new = calloc(1, sizeof(struct proc_nr_nodes))) == NULL)
  311. break;
  312. if ((cp = nr_config_get_addr(name)) == NULL)
  313. break;
  314. strip_zero_ssid(cp);
  315. safe_strncpy(new->call, cp, 9);
  316. if ((cp = nr_config_get_alias(name)) == NULL)
  317. break;
  318. safe_strncpy(new->alias, cp, 6);
  319. /*
  320. * n == 0 indicates a local node.
  321. */
  322. new->n = 0;
  323. if (list == NULL || strcmp(new->alias, list->alias) < 0) {
  324. tmp = list;
  325. list = new;
  326. new->next = tmp;
  327. } else {
  328. for (p = list; p->next != NULL; p = p->next)
  329. if (strcmp(new->alias, p->next->alias) < 0)
  330. break;
  331. tmp = p->next;
  332. p->next = new;
  333. new->next = tmp;
  334. }
  335. }
  336. fclose(fp);
  337. return list;
  338. }
  339. void free_proc_nr_nodes(struct proc_nr_nodes *np)
  340. {
  341. struct proc_nr_nodes *p;
  342. while (np != NULL) {
  343. p = np->next;
  344. free(np);
  345. np = p;
  346. }
  347. }
  348. struct proc_rs *read_proc_rs(void)
  349. {
  350. FILE *fp;
  351. char buffer[256];
  352. struct proc_rs *p;
  353. struct proc_rs *list = NULL;
  354. int i = 0;
  355. errno = 0;
  356. if ((fp = fopen(PROC_RS_FILE, "r")) == NULL)
  357. return NULL;
  358. while (fgets(buffer, 256, fp) != NULL)
  359. {
  360. if (!i++) continue;
  361. if ((p = calloc(1, sizeof(struct proc_rs))) == NULL)
  362. break;
  363. safe_strncpy(p->dest_addr, strtok(buffer, " \t\n\r"), 10);
  364. safe_strncpy(p->dest_call, strtok(NULL, " \t\n\r"), 9);
  365. safe_strncpy(p->src_addr, strtok(NULL, " \t\n\r"), 10);
  366. safe_strncpy(p->src_call, strtok(NULL, " \t\n\r"), 9);
  367. safe_strncpy(p->dev, strtok(NULL, " \t\n\r"), 13);
  368. p->lci = safe_atox(strtok(NULL, " \t\n\r"));
  369. p->neigh = safe_atoi(strtok(NULL, " \t\n\r"));
  370. p->st = safe_atoi(strtok(NULL, " \t\n\r"));
  371. p->vs = safe_atoi(strtok(NULL, " \t\n\r"));
  372. p->vr = safe_atoi(strtok(NULL, " \t\n\r"));
  373. p->va = safe_atoi(strtok(NULL, " \t\n\r"));
  374. p->t = safe_atoi(strtok(NULL, " \t\n\r"));
  375. p->t1 = safe_atoi(strtok(NULL, " \t\n\r"));
  376. p->t2 = safe_atoi(strtok(NULL, " \t\n\r"));
  377. p->t3 = safe_atoi(strtok(NULL, " \t\n\r"));
  378. p->hb = safe_atoi(strtok(NULL, " \t\n\r"));
  379. p->sndq = safe_atoi(strtok(NULL, " \t\n\r"));
  380. p->rcvq = safe_atoi(strtok(NULL, " \t\n\r"));
  381. p->next = list;
  382. list = p;
  383. }
  384. fclose(fp);
  385. return list;
  386. }
  387. void free_proc_rs(struct proc_rs *ap)
  388. {
  389. struct proc_rs *p;
  390. while (ap != NULL) {
  391. p = ap->next;
  392. free(ap);
  393. ap = p;
  394. }
  395. }
  396. struct proc_rs_neigh *read_proc_rs_neigh(void)
  397. {
  398. FILE *fp;
  399. char buffer[256];
  400. struct proc_rs_neigh *p;
  401. struct proc_rs_neigh *list = NULL;
  402. int i = 0;
  403. errno = 0;
  404. if ((fp = fopen(PROC_RS_NEIGH_FILE, "r")) == NULL)
  405. return NULL;
  406. while (fgets(buffer, 256, fp) != NULL)
  407. {
  408. if (!i++) continue;
  409. if ((p = calloc(1, sizeof(struct proc_rs_neigh))) == NULL)
  410. break;
  411. p->addr = safe_atoi(strtok(buffer, " \t\n\r"));
  412. safe_strncpy(p->call, strtok(NULL, " \t\n\r"), 9);
  413. safe_strncpy(p->dev, strtok(NULL, " \t\n\r"), 13);
  414. p->count = safe_atoi(strtok(NULL, " \t\n\r"));
  415. safe_strncpy(p->mode, strtok(NULL, " \t\n\r"), 3);
  416. safe_strncpy(p->restart, strtok(NULL, " \t\n\r"), 3);
  417. p->t0 = safe_atoi(strtok(NULL, " \t\n\r"));
  418. p->tf = safe_atoi(strtok(NULL, " \t\n\r"));
  419. p->next = list;
  420. list = p;
  421. }
  422. fclose(fp);
  423. return list;
  424. }
  425. void free_proc_rs_neigh(struct proc_rs_neigh *np)
  426. {
  427. struct proc_rs_neigh *p;
  428. while (np != NULL) {
  429. p = np->next;
  430. free(np);
  431. np = p;
  432. }
  433. }
  434. struct proc_rs_nodes *read_proc_rs_nodes(void)
  435. {
  436. FILE *fp;
  437. char buffer[256];
  438. struct proc_rs_nodes *p;
  439. struct proc_rs_nodes *list = NULL;
  440. int i = 0;
  441. errno = 0;
  442. if ((fp = fopen(PROC_RS_NODES_FILE, "r")) == NULL)
  443. return NULL;
  444. while (fgets(buffer, 256, fp) != NULL)
  445. {
  446. if (!i++) continue;
  447. if ((p = calloc(1, sizeof(struct proc_rs_nodes))) == NULL)
  448. break;
  449. safe_strncpy(p->address, strtok(buffer, " \t\n\r"), 10);
  450. p->mask = safe_atoi(strtok(NULL, " \t\n\r"));
  451. p->n = safe_atoi(strtok(NULL, " \t\n\r"));
  452. p->neigh1 = safe_atoi(strtok(NULL, " \t\n\r"));
  453. p->neigh2 = safe_atoi(strtok(NULL, " \t\n\r"));
  454. p->neigh3 = safe_atoi(strtok(NULL, " \t\n\r"));
  455. p->next = list;
  456. list = p;
  457. }
  458. fclose(fp);
  459. return list;
  460. }
  461. void free_proc_rs_nodes(struct proc_rs_nodes *np)
  462. {
  463. struct proc_rs_nodes *p;
  464. while (np != NULL) {
  465. p = np->next;
  466. free(np);
  467. np = p;
  468. }
  469. }
  470. struct proc_rs_route *read_proc_rs_routes(void)
  471. {
  472. FILE *fp;
  473. char buffer[256];
  474. struct proc_rs_route *p;
  475. struct proc_rs_route *list = NULL;
  476. int i = 0;
  477. errno = 0;
  478. if ((fp = fopen(PROC_RS_ROUTES_FILE, "r")) == NULL)
  479. return NULL;
  480. while (fgets(buffer, 256, fp) != NULL)
  481. {
  482. if (!i++) continue;
  483. if ((p = calloc(1, sizeof(struct proc_rs_route))) == NULL)
  484. break;
  485. p->lci1 = safe_atox(strtok(buffer, " \t\n\r"));
  486. safe_strncpy(p->address1, strtok(NULL, " \t\n\r"), 10);
  487. safe_strncpy(p->call1, strtok(NULL, " \t\n\r"), 9);
  488. p->neigh1 = safe_atoi(strtok(NULL, " \t\n\r"));
  489. p->lci2 = safe_atox(strtok(NULL, " \t\n\r"));
  490. safe_strncpy(p->address2, strtok(NULL, " \t\n\r"), 10);
  491. safe_strncpy(p->call2, strtok(NULL, " \t\n\r"), 9);
  492. p->neigh2 = safe_atoi(strtok(NULL, " \t\n\r"));
  493. p->next = list;
  494. list = p;
  495. }
  496. fclose(fp);
  497. return list;
  498. }
  499. void free_proc_rs_routes(struct proc_rs_route *np)
  500. {
  501. struct proc_rs_route *p;
  502. while (np != NULL) {
  503. p = np->next;
  504. free(np);
  505. np = p;
  506. }
  507. }
  508. char *get_call(int uid)
  509. {
  510. FILE *fp;
  511. char buf[256];
  512. static char call[10];
  513. int i = 0;
  514. errno = 0;
  515. if ((fp = fopen(PROC_AX25_CALLS_FILE, "r")) == NULL)
  516. return NULL;
  517. while (fgets(buf, 256, fp) != NULL) {
  518. if (!i++) continue;
  519. if (safe_atoi(strtok(buf, " \t\r\n")) == uid) {
  520. fclose(fp);
  521. safe_strncpy(call, strtok(NULL, " \t\r\n"), 9);
  522. return call;
  523. }
  524. }
  525. fclose(fp);
  526. return NULL;
  527. }
  528. struct proc_ax25 *find_link(const char *src, const char *dest, const char *dev)
  529. {
  530. static struct proc_ax25 a;
  531. struct proc_ax25 *p, *list;
  532. list = read_proc_ax25();
  533. for (p = list; p != NULL; p = p->next) {
  534. if (!strcmp(src, p->src_addr) &&
  535. !strcmp(dest, p->dest_addr) &&
  536. !strcmp(dev, p->dev)) {
  537. a = *p;
  538. a.next = NULL;
  539. free_proc_ax25(list);
  540. return &a;
  541. }
  542. }
  543. free_proc_ax25(list);
  544. return NULL;
  545. }
  546. struct proc_nr_neigh *find_neigh(int addr, struct proc_nr_neigh *neighs)
  547. {
  548. static struct proc_nr_neigh n;
  549. struct proc_nr_neigh *p, *list;
  550. list = neighs ? neighs : read_proc_nr_neigh();
  551. for (p = list; p != NULL; p = p->next) {
  552. if (addr == p->addr) {
  553. n = *p;
  554. n.next = NULL;
  555. p = &n;
  556. break;
  557. }
  558. }
  559. if (!neighs)
  560. free_proc_nr_neigh(list);
  561. return p;
  562. }
  563. struct proc_nr_nodes *find_node(char *addr, struct proc_nr_nodes *nodes)
  564. {
  565. static struct proc_nr_nodes n;
  566. struct proc_nr_nodes *p, *list;
  567. strip_zero_ssid(addr);
  568. list = nodes ? nodes : read_proc_nr_nodes();
  569. for (p = list; p != NULL; p = p->next) {
  570. if (!strcasecmp(addr, p->call) || !strcasecmp(addr, p->alias)) {
  571. n = *p;
  572. n.next = NULL;
  573. p = &n;
  574. break;
  575. }
  576. }
  577. if (!nodes)
  578. free_proc_nr_nodes(list);
  579. return p;
  580. }