xref: /inferno-os/appl/lib/cfgfile.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement CfgFile;
2
3#
4# Copyright © 1996-1999 Lucent Technologies Inc.  All rights reserved.
5# Revisions Copyright © 2000 Vita Nuova Limited.  All rights reserved.
6#
7
8include "sys.m";
9	sys: Sys;
10	Dir: import sys;
11
12include "draw.m";
13
14include "bufio.m";
15	bufio: Bufio;
16	Iobuf: import bufio;
17
18include "cfgfile.m";
19
20# Detect/Copy/Create
21verify(default: string, path: string): ref Sys->FD
22{
23	if(sys == nil)
24		sys = load Sys Sys->PATH;
25
26	fd := sys->open(path, Sys->ORDWR);
27	if(fd == nil) {
28		fd = sys->create(path, Sys->ORDWR, 8r666);
29		if(fd == nil)
30			return nil;
31		# copy default configuration file (if present)
32		ifd := sys->open(default, Sys->OREAD);
33		if(ifd != nil){
34			buf := array[Sys->ATOMICIO] of byte;
35			while((n := sys->read(ifd, buf, len buf)) > 0)
36				if(sys->write(fd, buf, n) != n)
37					return nil;
38			ifd = nil;
39		}
40	}
41	return fd;
42}
43
44init(file: string): ref ConfigFile
45{
46	sys = load Sys Sys->PATH;
47	bufio = load Bufio Bufio->PATH;
48
49	if(sys == nil || bufio == nil)
50		return nil;
51
52	me := ref ConfigFile;
53	me.file = file;
54	me.readonly = 0;
55	f := bufio->open(file, Sys->ORDWR);
56	if(f == nil) {
57		f = bufio->open(file, Sys->OREAD);
58		if (f == nil)
59			return nil;
60		me.readonly = 1;
61	}
62
63	while((l := f.gett("\r\n")) != nil) {
64		if(l[(len l)-1] == '\n')
65			l = l[0:(len l)-1];
66		me.lines = l :: me.lines;
67	}
68
69	return me;
70}
71
72ConfigFile.flush(me: self ref ConfigFile): string
73{
74	if(me.readonly)
75		return "file is read only";
76	if((fd := sys->create(me.file,Sys->OWRITE,0644)) == nil)
77		return sys->sprint("%r");
78	if((f := bufio->fopen(fd,Sys->OWRITE)) == nil)
79		return sys->sprint("%r");
80
81	l := me.lines;
82	while(l != nil) {
83		f.puts(hd l+"\n");
84		l = tl l;
85	}
86	if(f.flush() == -1)
87		return sys->sprint("%r");
88
89	return nil;
90}
91
92ConfigFile.getcfg(me:self ref ConfigFile, field:string): list of string
93{
94	l := me.lines;
95
96	while(l != nil) {
97		(n,fields) := sys->tokenize(hd l," \t");
98		if(n >= 1 && field == hd fields)
99			return tl fields;
100		l = tl l;
101	}
102	return nil;
103}
104
105ConfigFile.setcfg(me:self ref ConfigFile, field:string, val:string)
106{
107	l := me.lines;
108	newlist: list of string;
109
110	if(me.readonly)
111		return; # should return "file is read only";
112
113	matched := 0;
114
115	while(l != nil) {
116		(n,fields) := sys->tokenize(hd l," \t");
117		if(!matched && n >= 1 && field == hd fields) {
118			newlist = field+"\t"+val::newlist;
119			matched = 1;
120		}
121		else
122			newlist = hd l::newlist;
123		l = tl l;
124	}
125	if(!matched)
126		newlist = field+"\t"+val::newlist;
127
128	me.lines = newlist;
129}
130
131ConfigFile.delete(me:self ref ConfigFile, field:string)
132{
133	l := me.lines;
134	newlist: list of string;
135
136	if(me.readonly)
137		return; # should return "file is read only";
138
139	matched := 0;
140
141	while(l != nil) {
142		(n,fields) := sys->tokenize(hd l," \t");
143		if(!matched && n >= 1 && field == hd fields) {
144			matched = 1;
145		}
146		else
147			newlist = hd l::newlist;
148		l = tl l;
149	}
150
151	me.lines = newlist;
152}
153