hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

load.ha (1663B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use bufio;
      5 use fmt;
      6 use io;
      7 use memio;
      8 use net::ip;
      9 use os;
     10 use strings;
     11 
     12 let cache_valid = false;
     13 let cache: config = config {
     14 	options = DEFAULT_OPTIONS,
     15 	...
     16 };
     17 
     18 @fini fn fini() void = {
     19 	if (!cache_valid) {
     20 		return;
     21 	};
     22 
     23 	strings::freeall(cache.search);
     24 	free(cache.nameservers);
     25 	free(cache.sortlist);
     26 };
     27 
     28 // Reads /etc/resolv.conf (or the platform-specific equivalent path) and returns
     29 // the configuration therein. If the file does not exist, or is poorly
     30 // formatted, returns the default resolver configuration.
     31 export fn load() *config = {
     32 	if (cache_valid) {
     33 		return &cache;
     34 	};
     35 
     36 	const file = match (os::open("/etc/resolv.conf")) {
     37 	case let file: io::file =>
     38 		yield file;
     39 	case =>
     40 		cache_valid = true;
     41 		return &cache;
     42 	};
     43 	defer io::close(file)!;
     44 
     45 	match (parse(&cache, file)) {
     46 	case let err: error =>
     47 		fmt::errorfln("Error parsing /etc/resolv.conf: {}",
     48 			strerror(err)): void;
     49 		return &cache;
     50 	case void =>
     51 		cache_valid = true;
     52 		return &cache;
     53 	};
     54 };
     55 
     56 // Parses a resolv.conf-formatted file and populates the given config object.
     57 fn parse(conf: *config, in: io::handle) (void | error) = {
     58 	const rd = read(in);
     59 	for (const param => next(&rd)!) {
     60 		switch (param.name) {
     61 		case "nameserver" =>
     62 			append(conf.nameservers, param.value as ip::addr)!;
     63 		case "search" =>
     64 			strings::freeall(conf.search);
     65 			conf.search = strings::dupall(param.value as []str);
     66 		case "sortlist" =>
     67 			free(conf.sortlist);
     68 			conf.sortlist = alloc((param.value as []ip::subnet)...)!;
     69 		case "options" =>
     70 			conf.options = *(param.value as *options);
     71 		case => void;
     72 		};
     73 	};
     74 };