1 #include <nm_core.h>
2 #include <nm_form.h>
3 #include <nm_menu.h>
4 #include <nm_utils.h>
5 #include <nm_string.h>
6 #include <nm_vector.h>
7 #include <nm_window.h>
8 #include <nm_network.h>
9 #include <nm_svg_map.h>
10 #include <nm_database.h>
11 #include <nm_cfg_file.h>
12 #include <nm_lan_settings.h>
13
14 #if defined (NM_OS_LINUX)
15
16 const char NM_LC_LAN_FORM_LNAME[] = "Name";
17 const char NM_LC_LAN_FORM_RNAME[] = "Peer name";
18
19 static void nm_lan_init_main_windows(bool redraw);
20 static void nm_lan_init_add_windows(nm_form_t *form);
21 static size_t nm_lan_labels_setup();
22 static void nm_lan_add_veth(void);
23 static void nm_lan_del_veth(const nm_str_t *name);
24 static void nm_lan_up_veth(const nm_str_t *name);
25 static void nm_lan_down_veth(const nm_str_t *name);
26 static void nm_lan_veth_info(const nm_str_t *name);
27 static int nm_lan_add_get_data(nm_str_t *ln, nm_str_t *rn);
28
29 enum {
30 NM_LAN_LBL_LNAME = 0, NM_LAN_FLD_LNAME,
31 NM_LAN_LBL_RNAME, NM_LAN_FLD_RNAME,
32 NM_LAN_FLD_COUNT
33 };
34
35 static nm_field_t *fields_lan[NM_LAN_FLD_COUNT + 1];
36
37 #if defined (NM_WITH_NETWORK_MAP)
38 const char *nm_form_svg_state[] = {
39 "UP",
40 "DOWN",
41 "ALL",
42 NULL
43 };
44
45 const char *nm_form_svg_layout[] = {
46 "neato",
47 "dot",
48 NULL
49 };
50
51 const char NM_LC_SVG_FORM_PATH[] = "Export path";
52 const char NM_LC_SVG_FORM_TYPE[] = "State";
53 const char NM_LC_SVG_FORM_LAYT[] = "Layout";
54 const char NM_LC_SVG_FORM_GROUP[] = "Group";
55
56 static void nm_svg_init_windows(nm_form_t *form);
57 static void nm_svg_fields_setup();
58 static size_t nm_svg_labels_setup();
59 static void nm_lan_export_svg(const nm_vect_t *veths);
60
61 enum {
62 NM_SVG_LBL_PATH = 0, NM_SVG_FLD_PATH,
63 NM_SVG_LBL_TYPE, NM_SVG_FLD_TYPE,
64 NM_SVG_LBL_LAYT, NM_SVG_FLD_LAYT,
65 NM_SVG_LBL_GROUP, NM_SVG_FLD_GROUP,
66 NM_SVG_FLD_COUNT
67 };
68
69 static nm_field_t *fields_svg[NM_SVG_FLD_COUNT + 1];
70 #endif /* NM_WITH_NETWORK_MAP */
71
nm_lan_init_main_windows(bool redraw)72 static void nm_lan_init_main_windows(bool redraw)
73 {
74 if (redraw) {
75 nm_form_window_init();
76 } else {
77 werase(action_window);
78 werase(help_window);
79 werase(side_window);
80 }
81
82 nm_init_help_lan();
83 nm_init_action(_(NM_MSG_LAN));
84 nm_init_side_lan();
85
86 nm_print_veth_menu(NULL, 1);
87 }
88
nm_lan_init_add_windows(nm_form_t * form)89 static void nm_lan_init_add_windows(nm_form_t *form)
90 {
91 if (form) {
92 nm_form_window_init();
93 nm_form_data_t *form_data = (nm_form_data_t *)form_userptr(form);
94 if(form_data)
95 form_data->parent_window = action_window;
96 } else {
97 werase(action_window);
98 werase(help_window);
99 }
100
101 nm_init_help_edit();
102 nm_init_action(_(NM_MSG_ADD_VETH));
103 nm_init_side_lan();
104
105 nm_print_veth_menu(NULL, 1);
106 }
107
nm_lan_settings(void)108 void nm_lan_settings(void)
109 {
110 int ch = 0, regen_data = 1, renew_status = 0;
111 nm_str_t query = NM_INIT_STR;
112 nm_vect_t veths = NM_INIT_VECT;
113 nm_vect_t veths_list = NM_INIT_VECT;
114 nm_menu_data_t veths_data = NM_INIT_MENU_DATA;
115 size_t veth_list_len, old_hl;
116
117 veth_list_len = old_hl = 0;
118
119 nm_lan_create_veth(NM_FALSE);
120
121 nm_lan_init_main_windows(false);
122
123 do {
124 if (ch == NM_KEY_QUESTION) {
125 nm_lan_help();
126 } else if (ch == NM_KEY_A) {
127 nm_lan_add_veth();
128 regen_data = 1;
129 old_hl = veths_data.highlight;
130 } else if (ch == NM_KEY_R) {
131 if (veths.n_memb > 0) {
132 nm_lan_del_veth(nm_vect_item_name_cur(&veths_data));
133 regen_data = 1;
134 old_hl = veths_data.highlight;
135
136 if (veths_data.item_first != 0) {
137 veths_data.item_first--;
138 veths_data.item_last--;
139 }
140 werase(side_window);
141 nm_init_side_lan();
142 }
143 } else if (ch == NM_KEY_D) {
144 if (veths.n_memb > 0) {
145 nm_lan_down_veth(nm_vect_item_name_cur(&veths_data));
146 renew_status = 1;
147 }
148 } else if (ch == NM_KEY_U) {
149 if (veths.n_memb > 0) {
150 nm_lan_up_veth(nm_vect_item_name_cur(&veths_data));
151 renew_status = 1;
152 }
153 }
154 #if defined (NM_WITH_NETWORK_MAP)
155 else if (ch == NM_KEY_E) {
156 if (veths.n_memb > 0)
157 nm_lan_export_svg(&veths);
158 }
159 #endif
160
161 if (regen_data) {
162 nm_vect_free(&veths_list, NULL);
163 nm_vect_free(&veths, nm_str_vect_free_cb);
164 nm_db_select(NM_LAN_GET_VETH_SQL, &veths);
165 veth_list_len = (getmaxy(side_window) - 4);
166
167 veths_data.highlight = 1;
168
169 if (old_hl > 1) {
170 if (veths.n_memb < old_hl)
171 veths_data.highlight = (old_hl - 1);
172 else
173 veths_data.highlight = old_hl;
174 old_hl = 0;
175 }
176
177 if (veth_list_len < veths.n_memb)
178 veths_data.item_last = veth_list_len;
179 else
180 veths_data.item_last = veth_list_len = veths.n_memb;
181
182 for (size_t n = 0; n < veths.n_memb; n++) {
183 nm_menu_item_t veth = NM_INIT_MENU_ITEM;
184 veth.name = (nm_str_t *) nm_vect_at(&veths, n);
185 nm_vect_insert(&veths_list, &veth, sizeof(veth), NULL);
186 }
187
188 veths_data.v = &veths_list;
189
190 regen_data = 0;
191 renew_status = 1;
192 }
193
194 if (veths.n_memb > 0) {
195 nm_menu_scroll(&veths_data, veth_list_len, ch);
196 werase(action_window);
197 nm_init_action(_(NM_MSG_LAN));
198 nm_print_veth_menu(&veths_data, renew_status);
199 nm_lan_veth_info(nm_vect_item_name_cur(&veths_data));
200
201 if (renew_status)
202 renew_status = 0;
203 } else {
204 werase(action_window);
205 nm_init_action(_(NM_MSG_LAN));
206 }
207
208 if (redraw_window) {
209 nm_lan_init_main_windows(true);
210
211 veth_list_len = (getmaxy(side_window) - 4);
212 /* TODO save last pos */
213 if (veth_list_len < veths.n_memb) {
214 veths_data.item_last = veth_list_len;
215 veths_data.item_first = 0;
216 veths_data.highlight = 1;
217 } else {
218 veths_data.item_last = veth_list_len = veths.n_memb;
219 }
220
221 redraw_window = 0;
222 }
223 } while ((ch = wgetch(action_window)) != NM_KEY_Q);
224
225 werase(side_window);
226 werase(help_window);
227 nm_init_help_main();
228 nm_vect_free(&veths, nm_str_vect_free_cb);
229 nm_vect_free(&veths_list, NULL);
230 nm_str_free(&query);
231 }
232
nm_lan_add_veth(void)233 static void nm_lan_add_veth(void)
234 {
235 nm_form_data_t *form_data = NULL;
236 nm_form_t *form = NULL;
237 nm_str_t l_name = NM_INIT_STR;
238 nm_str_t r_name = NM_INIT_STR;
239 nm_str_t query = NM_INIT_STR;
240 size_t msg_len;
241
242 nm_lan_init_add_windows(NULL);
243
244 msg_len = nm_lan_labels_setup();
245
246 form_data = nm_form_data_new(
247 action_window, nm_lan_init_add_windows, msg_len, NM_LAN_FLD_COUNT / 2, NM_TRUE);
248
249 if (nm_form_data_update(form_data, 0, 0) != NM_OK)
250 goto out;
251
252 for (size_t n = 0; n < NM_LAN_FLD_COUNT; n++) {
253 switch (n) {
254 case NM_LAN_FLD_LNAME:
255 fields_lan[n] = nm_field_regexp_new(
256 n / 2, form_data, "^[a-zA-Z0-9_-]{1,15} *$");
257 break;
258 case NM_LAN_FLD_RNAME:
259 fields_lan[n] = nm_field_regexp_new(
260 n / 2, form_data, "^[a-zA-Z0-9_-]{1,15} *$");
261 break;
262 default:
263 fields_lan[n] = nm_field_label_new(n / 2, form_data);
264 break;
265 }
266 }
267 fields_lan[NM_LAN_FLD_COUNT] = NULL;
268
269 nm_lan_labels_setup();
270 nm_fields_unset_status(fields_lan);
271
272 form = nm_form_new(form_data, fields_lan);
273 nm_form_post(form);
274
275 if (nm_form_draw(&form) != NM_OK)
276 goto out;
277
278 if (nm_lan_add_get_data(&l_name, &r_name) != NM_OK)
279 goto out;
280
281 nm_net_add_veth(&l_name, &r_name);
282 nm_net_link_up(&l_name);
283 nm_net_link_up(&r_name);
284
285 nm_str_format(&query, NM_LAN_ADD_VETH_SQL, l_name.data, r_name.data);
286 nm_db_edit(query.data);
287
288 out:
289 wtimeout(action_window, -1);
290 werase(help_window);
291 nm_init_help_lan();
292 nm_form_free(form);
293 nm_form_data_free(form_data);
294 nm_fields_free(fields_lan);
295 nm_str_free(&l_name);
296 nm_str_free(&r_name);
297 nm_str_free(&query);
298 }
299
nm_lan_labels_setup()300 static size_t nm_lan_labels_setup()
301 {
302 nm_str_t buf = NM_INIT_STR;
303 size_t max_label_len = 0;
304 size_t msg_len = 0;
305
306 for (size_t n = 0; n < NM_LAN_FLD_COUNT; n++) {
307 switch (n) {
308 case NM_LAN_LBL_LNAME:
309 nm_str_format(&buf, "%s", _(NM_LC_LAN_FORM_LNAME));
310 break;
311 case NM_LAN_LBL_RNAME:
312 nm_str_format(&buf, "%s", _(NM_LC_LAN_FORM_RNAME));
313 break;
314 default:
315 continue;
316 }
317
318 msg_len = mbstowcs(NULL, buf.data, buf.len);
319 if (msg_len > max_label_len)
320 max_label_len = msg_len;
321
322 if (fields_lan[n])
323 set_field_buffer(fields_lan[n], 0, buf.data);
324 }
325
326 nm_str_free(&buf);
327 return max_label_len;
328 }
329
nm_lan_add_get_data(nm_str_t * ln,nm_str_t * rn)330 static int nm_lan_add_get_data(nm_str_t *ln, nm_str_t *rn)
331 {
332 int rc;
333 nm_str_t query = NM_INIT_STR;
334 nm_vect_t err = NM_INIT_VECT;
335 nm_vect_t names = NM_INIT_VECT;
336
337 nm_get_field_buf(fields_lan[NM_LAN_FLD_LNAME], ln);
338 nm_get_field_buf(fields_lan[NM_LAN_FLD_RNAME], rn);
339
340 nm_form_check_datap(_("Name"), ln, err);
341 nm_form_check_datap(_("Peer name"), rn, err);
342
343 if ((rc = nm_print_empty_fields(&err)) == NM_ERR) {
344 nm_vect_free(&err, NULL);
345 goto out;
346 }
347
348 nm_str_format(&query, NM_LAN_CHECK_NAME_SQL, ln->data, ln->data);
349 nm_db_select(query.data, &names);
350 if (names.n_memb > 0) {
351 nm_warn(_(NM_MSG_NAME_BUSY));
352 rc = NM_ERR;
353 goto out;
354 }
355
356 nm_str_format(&query, NM_LAN_CHECK_NAME_SQL, rn->data, rn->data);
357 nm_db_select(query.data, &names);
358 if (names.n_memb > 0) {
359 nm_warn(_(NM_MSG_NAME_BUSY));
360 rc = NM_ERR;
361 goto out;
362 }
363
364 if (nm_str_cmp_ss(ln, rn) == NM_OK) {
365 nm_warn(_(NM_MSG_NAME_DIFF));
366 rc = NM_ERR;
367 }
368
369 out:
370 nm_vect_free(&names, nm_str_vect_free_cb);
371 nm_str_free(&query);
372 return rc;
373 }
374
nm_lan_del_veth(const nm_str_t * name)375 static void nm_lan_del_veth(const nm_str_t *name)
376 {
377 nm_str_t lname = NM_INIT_STR;
378 nm_str_t rname = NM_INIT_STR;
379 nm_str_t query = NM_INIT_STR;
380
381 nm_lan_parse_name(name, &lname, &rname);
382 nm_net_del_iface(&lname);
383
384 nm_str_format(&query, NM_LAN_DEL_VETH_SQL, lname.data);
385 nm_db_edit(query.data);
386
387 nm_str_format(&query, NM_LAN_VETH_DEP_SQL, lname.data, rname.data);
388 nm_db_edit(query.data);
389
390 nm_str_free(&lname);
391 nm_str_free(&rname);
392 nm_str_free(&query);
393 }
394
nm_lan_up_veth(const nm_str_t * name)395 static void nm_lan_up_veth(const nm_str_t *name)
396 {
397 nm_str_t lname = NM_INIT_STR;
398 nm_str_t rname = NM_INIT_STR;
399
400 nm_lan_parse_name(name, &lname, &rname);
401
402 nm_net_link_up(&lname);
403 nm_net_link_up(&rname);
404
405 nm_str_free(&lname);
406 nm_str_free(&rname);
407 }
408
nm_lan_down_veth(const nm_str_t * name)409 static void nm_lan_down_veth(const nm_str_t *name)
410 {
411 nm_str_t lname = NM_INIT_STR;
412 nm_str_t rname = NM_INIT_STR;
413
414 nm_lan_parse_name(name, &lname, &rname);
415
416 nm_net_link_down(&lname);
417 nm_net_link_down(&rname);
418
419 nm_str_free(&lname);
420 nm_str_free(&rname);
421 }
422
nm_lan_veth_info(const nm_str_t * name)423 static void nm_lan_veth_info(const nm_str_t *name)
424 {
425 chtype ch1, ch2;
426 size_t y = 3, x = 2;
427 size_t cols, rows;
428 nm_str_t rname = NM_INIT_STR;
429 nm_str_t query = NM_INIT_STR;
430 nm_str_t buf = NM_INIT_STR;
431 nm_vect_t ifs = NM_INIT_VECT;
432
433 ch1 = ch2 = 0;
434 getmaxyx(action_window, rows, cols);
435 nm_lan_parse_name(name, &buf, &rname);
436
437 nm_str_format(&query, NM_LAN_VETH_INF_SQL, buf.data);
438 nm_db_select(query.data, &ifs);
439
440 nm_str_add_char(&buf, ':');
441 if (ifs.n_memb > 0)
442 for (size_t n = 0; n < ifs.n_memb; n++)
443 nm_str_append_format(&buf, " %s", nm_vect_str_ctx(&ifs, n));
444 else
445 nm_str_add_text(&buf, _(" [none]"));
446
447 NM_PR_VM_INFO();
448 nm_str_trunc(&buf, 0);
449
450 nm_vect_free(&ifs, nm_str_vect_free_cb);
451 nm_str_copy(&buf, &rname);
452
453 nm_str_format(&query, NM_LAN_VETH_INF_SQL, buf.data);
454 nm_db_select(query.data, &ifs);
455
456 nm_str_add_char(&buf, ':');
457 if (ifs.n_memb > 0)
458 for (size_t n = 0; n < ifs.n_memb; n++)
459 nm_str_append_format(&buf, " %s", nm_vect_str_ctx(&ifs, n));
460 else
461 nm_str_add_text(&buf, _(" [none]"));
462 NM_PR_VM_INFO();
463
464 nm_vect_free(&ifs, nm_str_vect_free_cb);
465 nm_str_free(&rname);
466 nm_str_free(&query);
467
468 nm_str_free(&buf);
469 }
470
nm_lan_parse_name(const nm_str_t * name,nm_str_t * ln,nm_str_t * rn)471 void nm_lan_parse_name(const nm_str_t *name, nm_str_t *ln, nm_str_t *rn)
472 {
473 nm_str_t name_copy = NM_INIT_STR;
474 char *cp = NULL;
475
476 nm_str_copy(&name_copy, name);
477
478 if (rn != NULL) {
479 cp = strchr(name_copy.data, '>');
480 nm_str_alloc_text(rn, ++cp);
481 cp = NULL;
482 }
483
484 cp = strchr(name_copy.data, '<');
485 if (cp) {
486 *cp = '\0';
487 nm_str_alloc_text(ln, name_copy.data);
488 }
489
490 nm_str_free(&name_copy);
491 }
492
nm_lan_create_veth(int info)493 void nm_lan_create_veth(int info)
494 {
495 nm_vect_t veths = NM_INIT_VECT;
496 size_t veth_count, veth_created = 0;
497
498 nm_db_select(NM_GET_VETH_SQL, &veths);
499 veth_count = veths.n_memb / 2;
500
501 for (size_t n = 0; n < veth_count; n++) {
502 size_t idx_shift = n * 2;
503 const nm_str_t *l_name = nm_vect_str(&veths, idx_shift);
504 const nm_str_t *r_name = nm_vect_str(&veths, idx_shift + 1);
505
506 if (info)
507 printf("Checking \"%s <-> %s\"...", l_name->data, r_name->data);
508
509 if (nm_net_iface_exists(l_name) != NM_OK) {
510 if (info)
511 printf("\t[not found]\n");
512
513 nm_net_add_veth(l_name, r_name);
514 nm_net_link_up(l_name);
515 nm_net_link_up(r_name);
516
517 veth_created++;
518 } else {
519 if (info)
520 printf("\t[found]\n");
521 }
522 }
523
524 if (info && !veth_created)
525 printf("Nothing to do.\n");
526 else if (info && veth_created)
527 printf("%zu VETH interface[s] was created.\n", veth_created);
528
529 nm_vect_free(&veths, nm_str_vect_free_cb);
530 }
531
532 #if defined (NM_WITH_NETWORK_MAP)
nm_svg_init_windows(nm_form_t * form)533 static void nm_svg_init_windows(nm_form_t *form)
534 {
535 if (form) {
536 nm_form_window_init();
537 nm_form_data_t *form_data = (nm_form_data_t *)form_userptr(form);
538 if (form_data)
539 form_data->parent_window = action_window;
540 } else {
541 werase(action_window);
542 werase(help_window);
543 }
544
545 nm_init_help_export();
546 nm_init_action(_(NM_MSG_EXPORT_MAP));
547 nm_init_side_lan();
548
549 nm_print_veth_menu(NULL, 1);
550 }
551
nm_lan_export_svg(const nm_vect_t * veths)552 static void nm_lan_export_svg(const nm_vect_t *veths)
553 {
554 nm_form_data_t *form_data = NULL;
555 nm_form_t *form = NULL;
556 nm_vect_t err = NM_INIT_VECT;
557 nm_str_t path = NM_INIT_STR;
558 nm_str_t type = NM_INIT_STR;
559 nm_str_t layout = NM_INIT_STR;
560 nm_str_t group = NM_INIT_STR;
561 int state = NM_SVG_STATE_ALL;
562 char **states = (char **) nm_form_svg_state;
563 size_t msg_len;
564
565 nm_svg_init_windows(NULL);
566
567 msg_len = nm_svg_labels_setup();
568
569 form_data = nm_form_data_new(
570 action_window, nm_svg_init_windows, msg_len, NM_SVG_FLD_COUNT / 2, NM_TRUE);
571
572 if (nm_form_data_update(form_data, 0, 0) != NM_OK)
573 goto out;
574
575 for (size_t n = 0; n < NM_SVG_FLD_COUNT; n++) {
576 switch (n) {
577 case NM_SVG_FLD_PATH:
578 fields_svg[n] = nm_field_regexp_new(n / 2, form_data, "^/.*");
579 break;
580 case NM_SVG_FLD_TYPE:
581 fields_svg[n] = nm_field_enum_new(
582 n / 2, form_data, nm_form_svg_state, false, false);
583 break;
584 case NM_SVG_FLD_LAYT:
585 fields_svg[n] = nm_field_enum_new(
586 n / 2, form_data, nm_form_svg_layout, false, false);
587 break;
588 case NM_SVG_FLD_GROUP:
589 fields_svg[n] = nm_field_default_new(n / 2, form_data);
590 break;
591 default:
592 fields_svg[n] = nm_field_label_new(n / 2, form_data);
593 break;
594 }
595 }
596 fields_svg[NM_SVG_FLD_COUNT] = NULL;
597
598 nm_svg_labels_setup();
599 nm_svg_fields_setup();
600 nm_fields_unset_status(fields_svg);
601
602 form = nm_form_new(form_data, fields_svg);
603 nm_form_post(form);
604
605 if (nm_form_draw(&form) != NM_OK)
606 goto out;
607
608 nm_get_field_buf(fields_svg[NM_SVG_FLD_PATH], &path);
609 nm_get_field_buf(fields_svg[NM_SVG_FLD_TYPE], &type);
610 nm_get_field_buf(fields_svg[NM_SVG_FLD_LAYT], &layout);
611 nm_get_field_buf(fields_svg[NM_SVG_FLD_GROUP], &group);
612 nm_form_check_data(_(NM_LC_SVG_FORM_PATH), path, err);
613 nm_form_check_data(_(NM_LC_SVG_FORM_TYPE), type, err);
614 nm_form_check_data(_(NM_LC_SVG_FORM_LAYT), layout, err);
615
616 if (nm_print_empty_fields(&err) == NM_ERR) {
617 nm_vect_free(&err, NULL);
618 goto out;
619 }
620
621 for (size_t n = 0; *states; n++, states++) {
622 if (nm_str_cmp_st(&type, *states) == NM_OK) {
623 state = n;
624 break;
625 }
626 }
627
628 nm_svg_map(path.data, veths, state, &layout, &group);
629
630 out:
631 wtimeout(action_window, -1);
632 werase(help_window);
633 nm_init_help_lan();
634 nm_init_action(_(NM_MSG_LAN));
635 nm_str_free(&path);
636 nm_str_free(&type);
637 nm_str_free(&layout);
638 nm_str_free(&group);
639 nm_form_free(form);
640 nm_form_data_free(form_data);
641 nm_fields_free(fields_svg);
642 }
643
nm_svg_fields_setup()644 static void nm_svg_fields_setup()
645 {
646 nm_vect_t vgroup = NM_INIT_VECT;
647 const char **groups;
648 nm_field_type_args_t groups_args = {0};
649
650 nm_db_select(NM_GET_GROUPS_SQL, &vgroup);
651 groups = nm_calloc(vgroup.n_memb + 1, sizeof(char *));
652 for (size_t n = 0; n < vgroup.n_memb; n++)
653 groups[n] = strdup(nm_vect_str_ctx(&vgroup, n));
654 groups[vgroup.n_memb] = NULL;
655
656 groups_args.enum_arg.strings = groups;
657 groups_args.enum_arg.case_sens = false;
658 groups_args.enum_arg.uniq_match = false;
659
660 nm_set_field_type(fields_svg[NM_SVG_FLD_GROUP], NM_FIELD_ENUM, groups_args);
661
662 set_field_buffer(fields_svg[NM_SVG_FLD_TYPE], 0, nm_form_svg_state[0]);
663 set_field_buffer(fields_svg[NM_SVG_FLD_LAYT], 0, nm_form_svg_layout[0]);
664
665 if (vgroup.n_memb == 1) {
666 field_opts_off(fields_svg[NM_SVG_FLD_GROUP], O_ACTIVE);
667 }
668
669 nm_vect_free(&vgroup, nm_str_vect_free_cb);
670 }
671
nm_svg_labels_setup()672 static size_t nm_svg_labels_setup()
673 {
674 nm_str_t buf = NM_INIT_STR;
675 size_t max_label_len = 0;
676 size_t msg_len = 0;
677
678 for (size_t n = 0; n < NM_SVG_FLD_COUNT; n++) {
679 switch (n) {
680 case NM_SVG_LBL_PATH:
681 nm_str_format(&buf, "%s", _(NM_LC_SVG_FORM_PATH));
682 break;
683 case NM_SVG_LBL_TYPE:
684 nm_str_format(&buf, "%s", _(NM_LC_SVG_FORM_TYPE));
685 break;
686 case NM_SVG_LBL_LAYT:
687 nm_str_format(&buf, "%s", _(NM_LC_SVG_FORM_LAYT));
688 break;
689 case NM_SVG_LBL_GROUP:
690 nm_str_format(&buf, "%s", _(NM_LC_SVG_FORM_GROUP));
691 break;
692 default:
693 continue;
694 }
695
696 msg_len = mbstowcs(NULL, buf.data, buf.len);
697 if (msg_len > max_label_len)
698 max_label_len = msg_len;
699
700 if (fields_svg[n])
701 set_field_buffer(fields_svg[n], 0, buf.data);
702 }
703
704 nm_str_free(&buf);
705 return max_label_len;
706 }
707
708 #endif /* NM_WITH_NETWORK_MAP */
709 #endif /* NM_OS_LINUX */
710 /* vim:set ts=4 sw=4: */
711