|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2010 Piotr JaroszyĆski <[email protected]> ! 3: * ! 4: * This program is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2 of the ! 7: * License, or any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, but ! 10: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 12: * General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with this program; if not, write to the Free Software ! 16: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ! 17: */ ! 18: ! 19: FILE_LICENCE(GPL2_OR_LATER); ! 20: ! 21: #include <hci/linux_args.h> ! 22: #include <getopt.h> ! 23: #include <string.h> ! 24: #include <stdio.h> ! 25: #include <ipxe/settings.h> ! 26: #include <ipxe/linux.h> ! 27: #include <ipxe/malloc.h> ! 28: #include <ipxe/init.h> ! 29: ! 30: /** Saved argc */ ! 31: static int saved_argc = 0; ! 32: /** Saved argv */ ! 33: static char ** saved_argv; ! 34: ! 35: /** ! 36: * Save argc and argv for later access. ! 37: * ! 38: * To be called by linuxprefix ! 39: */ ! 40: __asmcall void save_args(int argc, char **argv) ! 41: { ! 42: saved_argc = argc; ! 43: saved_argv = argv; ! 44: } ! 45: ! 46: /** Supported command-line options */ ! 47: static struct option options[] = { ! 48: {"net", 1, 0, 'n'}, ! 49: {"settings", 1, 0, 's'}, ! 50: {0, 0, 0, 0} ! 51: }; ! 52: ! 53: /** ! 54: * Parse k1=v1[,k2=v2]* into linux_settings ! 55: */ ! 56: static int parse_kv(char *kv, struct list_head *list) ! 57: { ! 58: char *token; ! 59: char *name; ! 60: char *value; ! 61: struct linux_setting *setting; ! 62: ! 63: while ((token = strsep(&kv, ",")) != NULL) { ! 64: name = strsep(&token, "="); ! 65: if (name == NULL) ! 66: continue; ! 67: value = token; ! 68: if (value == NULL) { ! 69: DBG("Bad parameter: '%s'\n", name); ! 70: continue; ! 71: } ! 72: ! 73: setting = malloc(sizeof(*setting)); ! 74: ! 75: if (! setting) ! 76: return -1; ! 77: ! 78: setting->name = name; ! 79: setting->value = value; ! 80: setting->applied = 0; ! 81: list_add(&setting->list, list); ! 82: } ! 83: ! 84: return 0; ! 85: } ! 86: ! 87: /** ! 88: * Parse --net arguments ! 89: * ! 90: * Format is --net driver_name[,name=value]* ! 91: */ ! 92: static int parse_net_args(char *args) ! 93: { ! 94: char *driver; ! 95: struct linux_device_request *dev_request; ! 96: int rc; ! 97: ! 98: driver = strsep(&args, ","); ! 99: ! 100: if (strlen(driver) == 0) { ! 101: printf("Missing driver name"); ! 102: return -1; ! 103: } ! 104: ! 105: dev_request = malloc(sizeof(*dev_request)); ! 106: ! 107: dev_request->driver = driver; ! 108: INIT_LIST_HEAD(&dev_request->settings); ! 109: list_add_tail(&dev_request->list, &linux_device_requests); ! 110: ! 111: /* Parse rest of the settings */ ! 112: rc = parse_kv(args, &dev_request->settings); ! 113: ! 114: if (rc) ! 115: printf("Parsing net settings failed"); ! 116: ! 117: return rc; ! 118: } ! 119: ! 120: /** ! 121: * Parse --settings arguments ! 122: * ! 123: * Format is --settings name=value[,name=value]* ! 124: */ ! 125: static int parse_settings_args(char *args) ! 126: { ! 127: return parse_kv(args, &linux_global_settings); ! 128: } ! 129: ! 130: ! 131: /** Parse passed command-line arguments */ ! 132: void linux_args_parse() ! 133: { ! 134: int c; ! 135: int rc; ! 136: ! 137: reset_getopt(); ! 138: while (1) { ! 139: int option_index = 0; ! 140: ! 141: c = getopt_long(saved_argc, saved_argv, "", options, &option_index); ! 142: if (c == -1) ! 143: break; ! 144: ! 145: switch (c) { ! 146: case 'n': ! 147: if ((rc = parse_net_args(optarg)) != 0) ! 148: return; ! 149: break; ! 150: case 's': ! 151: if ((rc = parse_settings_args(optarg)) != 0) ! 152: return; ! 153: break; ! 154: default: ! 155: return; ! 156: } ! 157: } ! 158: ! 159: return; ! 160: } ! 161: ! 162: /** Clean up requests and settings */ ! 163: void linux_args_cleanup(int flags __unused) ! 164: { ! 165: struct linux_device_request *request; ! 166: struct linux_device_request *rtmp; ! 167: struct linux_setting *setting; ! 168: struct linux_setting *stmp; ! 169: ! 170: /* Clean up requests and their settings */ ! 171: list_for_each_entry_safe(request, rtmp, &linux_device_requests, list) { ! 172: list_for_each_entry_safe(setting, stmp, &request->settings, list) { ! 173: list_del(&setting->list); ! 174: free(setting); ! 175: } ! 176: list_del(&request->list); ! 177: free(request); ! 178: } ! 179: ! 180: /* Clean up global settings */ ! 181: list_for_each_entry_safe(setting, stmp, &linux_global_settings, list) { ! 182: list_del(&setting->list); ! 183: free(setting); ! 184: } ! 185: } ! 186: ! 187: struct startup_fn startup_linux_args __startup_fn(STARTUP_EARLY) = { ! 188: .startup = linux_args_parse, ! 189: .shutdown = linux_args_cleanup, ! 190: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.