?? config.c
字號:
/* * This source code is a part of coLinux source package. * * Dan Aloni <da-x@colinux.org>, 2003 (c) * * The code is licensed under the GPL. See the COPYING file at * the root directory. * */ #include <string.h>#include <colinux/common/libc.h>#include <colinux/common/config.h>#include <colinux/user/cmdline.h>#include <colinux/os/user/file.h>#include <colinux/os/user/misc.h>#include <colinux/os/user/cobdpath.h>#include <colinux/os/alloc.h>#include "macaddress.h"#include "daemon.h"typedef struct { int size; char * buffer; } comma_buffer_t; /* only for split_comma_separated here *//* * "New" command line configuration gathering scheme. It existed a long time in * User Mode Linux and should be less hussle than handling XML files for the * novice users. */static co_rc_t check_cobd_file (co_pathname_t pathname, int index){ co_rc_t rc; char *buf; unsigned long size; static const char magic_bz2 [3] = "BZh"; /* bzip2 compressed data */ static const char magic_7z [6] = "7z\274\257\047\034"; /* 7z archive data */ if (co_global_debug_levels.misc_level < 2) return CO_RC(OK); /* verbose is not enabled */ co_remove_quotation_marks(pathname); if (co_strncmp(pathname, "\\Device\\", 8) == 0 || co_strncmp(pathname, "\\DosDevices\\", 12) == 0 || co_strncmp(pathname, "\\Volume{", 8) == 0 || co_strncmp(pathname, "\\\\.\\", 4) == 0) return CO_RC(OK); /* Can't check partitions or raw devices */ rc = co_os_file_load(pathname, &buf, &size, 1024); if (!CO_OK(rc)) { co_terminal_print("cobd%d: error reading file\n", index); return rc; } if (size != 1024) { co_terminal_print("cobd%d: file to small (%s)\n", index, pathname); rc = CO_RC(INVALID_PARAMETER); } else if (memcmp(buf, magic_bz2, sizeof(magic_bz2)) == 0 || memcmp(buf, magic_7z, sizeof(magic_7z)) == 0) { co_terminal_print("cobd%d: Image file must be unpack before (%s)\n", index, pathname); rc = CO_RC(INVALID_PARAMETER); } co_os_file_free(buf); return rc;}static co_rc_t parse_args_config_cobd(co_command_line_params_t cmdline, co_config_t *conf){ bool_t exists; char *param; co_rc_t rc; do { int index; co_block_dev_desc_t *cobd; rc = co_cmdline_get_next_equality_int_prefix(cmdline, "cobd", &index, CO_MODULE_MAX_COBD, ¶m, &exists); if (!CO_OK(rc)) return rc; if (!exists) break; cobd = &conf->block_devs[index]; if (cobd->enabled) { co_terminal_print("cobd%d double defined\n", index); return CO_RC(INVALID_PARAMETER); } cobd->enabled = PTRUE; co_snprintf(cobd->pathname, sizeof(cobd->pathname), "%s", param); rc = check_cobd_file(cobd->pathname, index); if (!CO_OK(rc)) return rc; co_canonize_cobd_path(&cobd->pathname); co_debug_info("mapping cobd%d to %s", index, cobd->pathname); } while (1); return CO_RC(OK);}static co_rc_t allocate_by_alias(co_config_t *conf, const char *prefix, const char *suffix, const char *param){ co_block_dev_desc_t *cobd; int i; co_rc_t rc; for (i=0; i < CO_MODULE_MAX_COBD; i++) { cobd = &conf->block_devs[i]; if (!cobd->enabled) break; } if (i == CO_MODULE_MAX_COBD) { co_terminal_print("no available cobd for new alias\n"); return CO_RC(ERROR); } cobd->enabled = PTRUE; co_snprintf(cobd->pathname, sizeof(cobd->pathname), "%s", param); rc = check_cobd_file (cobd->pathname, i); if (!CO_OK(rc)) return rc; co_canonize_cobd_path(&cobd->pathname); cobd->alias_used = PTRUE; co_snprintf(cobd->alias, sizeof(cobd->alias), "%s%s", prefix, suffix); co_debug_info("selected cobd%d for %s, mapping to '%s'", i, cobd->alias, cobd->pathname); return CO_RC(OK);}static co_rc_t parse_args_config_aliases(co_command_line_params_t cmdline, co_config_t *conf){ const char *prefixes[] = {"sd", "hd"}; const char *prefix; bool_t exists; char *param; co_rc_t rc; int i; for (i=0; i < sizeof(prefixes)/sizeof(char *); i++) { prefix = prefixes[i]; char suffix[5]; do { rc = co_cmdline_get_next_equality_alloc(cmdline, prefix, sizeof(suffix)-1, suffix, sizeof(suffix), ¶m, &exists); if (!CO_OK(rc)) return rc; if (!exists) break; if (!co_strncmp(":cobd", param, 5)) { char *index_str = ¶m[5]; char *number_parse = NULL; int index; co_block_dev_desc_t *cobd; index = co_strtol(index_str, &number_parse, 10); if (number_parse == index_str) { co_terminal_print("invalid alias: %s%s=%s\n", prefix, suffix, param); return CO_RC(INVALID_PARAMETER); } if (index < 0 || index >= CO_MODULE_MAX_COBD) { co_terminal_print("invalid cobd index %d in alias %s%s\n", index, prefix, suffix); return CO_RC(INVALID_PARAMETER); } cobd = &conf->block_devs[index]; if (!cobd->enabled) { co_terminal_print("alias on unused cobd%d\n", index); return CO_RC(INVALID_PARAMETER); } if (cobd->alias_used) { co_terminal_print("error, alias cannot be used twice for cobd%d\n", index); return CO_RC(INVALID_PARAMETER); } cobd->alias_used = PTRUE; co_snprintf(cobd->alias, sizeof(cobd->alias), "%s%s", prefix, suffix); co_debug_info("mapping %s%s to %s", prefix, suffix, ¶m[1]); } else { rc = allocate_by_alias(conf, prefix, suffix, param); if (!CO_OK(rc)) return rc; } } while (1); } return CO_RC(OK);}static bool_t strmatch_identifier(const char *str, const char *identifier, const char **end){ while (*str == *identifier && *str != '\0') { str++; identifier++; } if (end) *end = str; if (*identifier != '\0') return PFALSE; if (!((*str >= 'a' && *str <= 'z') || (*str >= 'A' && *str <= 'Z'))) { if (end) { if (*str != '\0') (*end)++; } return PTRUE; } return PFALSE;}static void split_comma_separated(const char *source, comma_buffer_t *array){ int j; bool_t quotation_marks; for (; array->buffer != NULL; array++) { j = 0; quotation_marks = PFALSE; // quotation marks detection in config file, sample: // eth0=tuntap,"LAN-Connection 14",00:11:22:33:44:55 // String store without quotation marks. while (j < array->size - 1 && *source != '\0') { if (*source == '"') { if (*++source != '"') { quotation_marks = !quotation_marks; continue; } } else if (*source == ',' && !quotation_marks) break; array->buffer[j++] = *source++; } // End for destination buffers array->buffer[j] = '\0'; // Skip, if end of source, but go away for _all_ buffers if (*source != '\0') source++; }}static co_rc_t config_parse_mac_address(const char *text, co_netdev_desc_t *net_dev){ co_rc_t rc; if (*text) { rc = co_parse_mac_address(text, net_dev->mac_address); if (!CO_OK(rc)) { co_terminal_print("error parsing MAC address: %s\n", text); return rc; } net_dev->manual_mac_address = PTRUE; co_debug_info("MAC address: %s", text); } else { co_debug("MAC address: auto generated"); } return CO_RC(OK);}static co_rc_t parse_args_networking_device_tap(co_config_t *conf, int index, const char *param){ co_netdev_desc_t *net_dev = &conf->net_devs[index]; char mac_address[40]; char host_ip[40]; co_rc_t rc; comma_buffer_t array [] = { { sizeof(net_dev->desc), net_dev->desc }, { sizeof(mac_address), mac_address }, { sizeof(host_ip), host_ip }, { 0, NULL } }; split_comma_separated(param, array); net_dev->type = CO_NETDEV_TYPE_TAP; net_dev->enabled = PTRUE; co_debug_info("configured TAP at '%s' device as eth%d", net_dev->desc, index); rc = config_parse_mac_address(mac_address, net_dev); if (!CO_OK(rc)) return rc; if (*host_ip) co_debug_info("Host IP address: %s (currently ignored)", host_ip); return CO_RC(OK);}static co_rc_t parse_args_networking_device_pcap(co_config_t *conf, int index, const char *param){ co_netdev_desc_t *net_dev = &conf->net_devs[index]; char mac_address[40]; char promisc_mode[10]; co_rc_t rc; comma_buffer_t array [] = { { sizeof(net_dev->desc), net_dev->desc }, { sizeof(mac_address), mac_address }, { sizeof(promisc_mode), promisc_mode }, { 0, NULL } }; split_comma_separated(param, array); net_dev->type = CO_NETDEV_TYPE_BRIDGED_PCAP; net_dev->enabled = PTRUE; net_dev->promisc_mode = 1; co_debug_info("configured PCAP bridge at '%s' device as eth%d", net_dev->desc, index); rc = config_parse_mac_address(mac_address, net_dev); if (!CO_OK(rc)) return rc; if (*promisc_mode) { if (strcmp(promisc_mode, "nopromisc") == 0) { net_dev->promisc_mode = 0; co_debug_info("Pcap mode: nopromisc"); } else if (strcmp(promisc_mode, "promisc") == 0) { net_dev->promisc_mode = 1; co_debug_info("Pcap mode: promisc"); } else { co_terminal_print("error: PCAP bridge option only allowed 'promisc' or 'nopromisc'\n"); return CO_RC(INVALID_PARAMETER); } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -